Skip to content

Commit

Permalink
WIP port of the C extension.
Browse files Browse the repository at this point in the history
  • Loading branch information
hannosch committed Jan 19, 2017
1 parent 342fa8c commit 7b81700
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 31 deletions.
49 changes: 49 additions & 0 deletions include/ExtensionClass/_compat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*****************************************************************************
Copyright (c) 2012 Zope Foundation and Contributors.
All Rights Reserved.
This software is subject to the provisions of the Zope Public License,
Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
FOR A PARTICULAR PURPOSE
****************************************************************************/

#ifndef PERSISTENT__COMPAT_H
#define PERSISTENT__COMPAT_H

#include "Python.h"

#if PY_MAJOR_VERSION >= 3
#define PY3K
#endif

#ifdef PY3K
#define INTERN PyUnicode_InternFromString
#define INTERN_INPLACE PyUnicode_InternInPlace
#define NATIVE_CHECK PyUnicode_Check
#define NATIVE_CHECK_EXACT PyUnicode_CheckExact
#define NATIVE_FROM_STRING PyUnicode_FromString
#define NATIVE_FROM_STRING_AND_SIZE PyUnicode_FromStringAndSize

#define INT_FROM_LONG(x) PyLong_FromLong(x)
#define INT_CHECK(x) PyLong_Check(x)
#define INT_AS_LONG(x) PyLong_AS_LONG(x)

#else
#define INTERN PyString_InternFromString
#define INTERN_INPLACE PyString_InternInPlace
#define NATIVE_CHECK PyString_Check
#define NATIVE_CHECK_EXACT PyString_CheckExact
#define NATIVE_FROM_STRING PyString_FromString
#define NATIVE_FROM_STRING_AND_SIZE PyString_FromStringAndSize

#define INT_FROM_LONG(x) PyInt_FromLong(x)
#define INT_CHECK(x) PyInt_Check(x)
#define INT_AS_LONG(x) PyInt_AS_LONG(x)
#endif

#endif
4 changes: 1 addition & 3 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import os
import platform
import sys

from setuptools import setup, find_packages, Extension

Expand All @@ -11,8 +10,7 @@
py_impl = getattr(platform, 'python_implementation', lambda: None)
is_pypy = py_impl() == 'PyPy'
is_pure = 'PURE_PYTHON' in os.environ
py3k = sys.version_info >= (3, )
if is_pypy or is_pure or py3k:
if is_pypy or is_pure:
ext_modules = []
else:
ext_modules = [
Expand Down
92 changes: 64 additions & 28 deletions src/Persistence/_Persistence.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ static char _Persistence_module_documentation[] =
;

#include "ExtensionClass/ExtensionClass.h"
#include "ExtensionClass/_compat.h"
#include "persistent/cPersistence.h"


Expand All @@ -31,15 +32,15 @@ convert_name(PyObject *name)
existing tp_setattro slots expect a string object as name
and we wouldn't want to break those. */
if (PyUnicode_Check(name)) {
name = PyUnicode_AsEncodedString(name, NULL, NULL);
name = PyUnicode_AsEncodedString(name, NULL, NULL);
}
else
#endif
if (!PyString_Check(name)) {
PyErr_SetString(PyExc_TypeError, "attribute name must be a string");
if (!NATIVE_CHECK(name)) {
PyErr_SetString(PyExc_TypeError, "attribute name must be a string");
return NULL;
} else
Py_INCREF(name);
Py_INCREF(name);
return name;
}

Expand Down Expand Up @@ -99,7 +100,11 @@ P_getattr(cPersistentObject *self, PyObject *name)
if (!name)
return NULL;

#ifdef PY3K
s = PyBytes_AS_STRING(name);
#else
s = PyString_AS_STRING(name);
#endif

if (*s != '_' || unghost_getattr(s))
{
Expand All @@ -120,59 +125,90 @@ P_getattr(cPersistentObject *self, PyObject *name)


static PyTypeObject Ptype = {
PyObject_HEAD_INIT(NULL)
/* ob_size */ 0,
/* tp_name */ "Persistence.Persistent",
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* tp_getattro */ (getattrofunc)P_getattr,
0, 0,
/* tp_flags */ Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
#ifdef Py_TPFLAGS_HAVE_VERSION_TAG
| Py_TPFLAGS_HAVE_VERSION_TAG
#endif
,
/* tp_doc */ "Persistent ExtensionClass",
PyVarObject_HEAD_INIT(NULL, 0)
"Persistence.Persistent", /* tp_name */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
(getattrofunc)P_getattr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT |
Py_TPFLAGS_BASETYPE |
Py_TPFLAGS_HAVE_VERSION_TAG, /* tp_flags */
"Persistent ExtensionClass", /* tp_doc */
};

static struct PyMethodDef _Persistence_methods[] = {
{NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
};

#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#ifdef PY3K
static struct PyModuleDef moduledef =
{
PyModuleDef_HEAD_INIT,
"_Persistence", /* m_name */
_Persistence_module_documentation, /* m_doc */
-1, /* m_size */
_Persistence_methods, /* m_methods */
NULL, /* m_reload */
NULL, /* m_traverse */
NULL, /* m_clear */
NULL, /* m_free */
};
#endif
PyMODINIT_FUNC
init_Persistence(void)

static PyObject*
module_init(void)
{
PyObject *m;

if (! ExtensionClassImported)
return;
return NULL;

#ifdef PY3K
cPersistenceCAPI = PyCapsule_Import("persistent.cPersistence.CAPI", 0);
#else
cPersistenceCAPI = PyCObject_Import("persistent.cPersistence", "CAPI");
#endif
if (cPersistenceCAPI == NULL)
return;
return NULL;

Ptype.tp_bases = Py_BuildValue("OO", cPersistenceCAPI->pertype, ECBaseType);
if (Ptype.tp_bases == NULL)
return;
return NULL;
Ptype.tp_base = cPersistenceCAPI->pertype;
Ptype.tp_basicsize = cPersistenceCAPI->pertype->tp_basicsize;

Ptype.ob_type = ECExtensionClassType;
Py_TYPE(&Ptype) = ECExtensionClassType;

if (PyType_Ready(&Ptype) < 0)
return;
return NULL;

/* Create the module and add the functions */
#ifdef PY3K
m = PyModule_Create(&moduledef);
#else
m = Py_InitModule3("_Persistence", _Persistence_methods,
_Persistence_module_documentation);
#endif

if (m == NULL)
return;
return NULL;

/* Add types: */
if (PyModule_AddObject(m, "Persistent", (PyObject *)&Ptype) < 0)
return;
return NULL;

return m;
}

#ifdef PY3K
PyMODINIT_FUNC PyInit__Persistence(void)
{
return module_init();
}
#else
PyMODINIT_FUNC init_Persistence(void)
{
module_init();
}
#endif

0 comments on commit 7b81700

Please sign in to comment.