From 62d7f4b80d56ef1e27039441cd6584cfb71d6502 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 13 Apr 2009 19:13:25 +0200 Subject: * python/*.cc: Use PyObject_AsFileDescriptor instead of fileno(PyFile_AsFile) Replace support for file objects with a more generic support for any object providing a fileno() method and for file descriptors (integers). This also helps us to port to Python 3, where the previously used PyFile_ functions are not available anymore. --- python/apt_instmodule.cc | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'python/apt_instmodule.cc') diff --git a/python/apt_instmodule.cc b/python/apt_instmodule.cc index 48868d86..a9d81be4 100644 --- a/python/apt_instmodule.cc +++ b/python/apt_instmodule.cc @@ -35,14 +35,17 @@ static PyObject *debExtractControl(PyObject *Self,PyObject *Args) { char *Member = "control"; PyObject *File; - if (PyArg_ParseTuple(Args,"O!|s",&PyFile_Type,&File,&Member) == 0) + if (PyArg_ParseTuple(Args,"O|s",&File,&Member) == 0) return 0; // Subscope makes sure any clean up errors are properly handled. PyObject *Res = 0; { // Open the file and associate the .deb - FileFd Fd(fileno(PyFile_AsFile(File)),false); + int fileno = PyObject_AsFileDescriptor(File); + if (fileno == -1) + return 0; + FileFd Fd(fileno,false); debDebFile Deb(Fd); if (_error->PendingError() == true) return HandleErrors(); @@ -76,7 +79,7 @@ static PyObject *debExtractArchive(PyObject *Self,PyObject *Args) char *Rootdir = NULL; char cwd[512]; PyObject *File; - if (PyArg_ParseTuple(Args,"O!|s",&PyFile_Type,&File,&Rootdir) == 0) + if (PyArg_ParseTuple(Args,"O|s",&File,&Rootdir) == 0) return 0; // Subscope makes sure any clean up errors are properly handled. @@ -89,7 +92,10 @@ static PyObject *debExtractArchive(PyObject *Self,PyObject *Args) } // Open the file and associate the .deb - FileFd Fd(fileno(PyFile_AsFile(File)),false); + int fileno = PyObject_AsFileDescriptor(File); + if (fileno == -1) + return 0; + FileFd Fd(fileno,false); debDebFile Deb(Fd); if (_error->PendingError() == true) { if (Rootdir != NULL) @@ -118,11 +124,14 @@ static PyObject *arCheckMember(PyObject *Self,PyObject *Args) char *Member = NULL; bool res = false; PyObject *File; - if (PyArg_ParseTuple(Args,"O!s",&PyFile_Type,&File,&Member) == 0) + if (PyArg_ParseTuple(Args,"Os",&File,&Member) == 0) return 0; // Open the file and associate the .deb - FileFd Fd(fileno(PyFile_AsFile(File)),false); + int fileno = PyObject_AsFileDescriptor(File); + if (fileno == -1) + return 0; + FileFd Fd(fileno,false); ARArchive AR(Fd); if (_error->PendingError() == true) return HandleErrors(Py_BuildValue("b",res)); -- cgit v1.2.3 From c876c5095673a2f1c0f2c0eef6eadef2ce200e19 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Wed, 15 Apr 2009 16:19:12 +0200 Subject: * Introduce support for Python 3 (Closes: #523645) This is the first initial port to Python 3. The API is almost completely identical to the one found in Python 2, except that functions working with binary data require bytes (md5sum,sha1sum,sha256sum,Base64Encode). Using setup3.py to install the modules will not work, because the apt package still has to be converted to Python 3. For the package, we call 2to3-3.1 in debian/rules to do this automatically. --- apt/package.py | 6 +++- debian/changelog | 2 ++ debian/control | 2 ++ debian/rules | 26 +++++++++++++-- po/python-apt.pot | 10 +++--- python/acquire.cc | 6 ++++ python/apt_instmodule.cc | 35 ++++++++++++++++++- python/apt_pkgmodule.cc | 87 +++++++++++++++++++++++++++++++++++------------- python/cache.cc | 18 ++++++++++ python/cdrom.cc | 2 ++ python/configuration.cc | 6 ++++ python/depcache.cc | 6 ++++ python/generic.h | 25 ++++++++++++++ python/indexfile.cc | 2 ++ python/metaindex.cc | 2 ++ python/pkgmanager.cc | 2 ++ python/pkgrecords.cc | 2 ++ python/pkgsrcrecords.cc | 2 ++ python/sourcelist.cc | 2 ++ python/string.cc | 16 ++++++++- python/tag.cc | 4 +++ setup3.py | 77 ++++++++++++++++++++++++++++++++++++++++++ 22 files changed, 307 insertions(+), 33 deletions(-) create mode 100644 setup3.py (limited to 'python/apt_instmodule.cc') diff --git a/apt/package.py b/apt/package.py index 3ea1105d..f12f5559 100644 --- a/apt/package.py +++ b/apt/package.py @@ -272,8 +272,12 @@ class Version(object): """ self.summary # This does the lookup for us. desc = '' + + dsc = self.package._pcache._records.LongDesc try: - dsc = unicode(self.package._pcache._records.LongDesc, "utf-8") + if not isinstance(dsc, unicode): + # Only convert where needed (i.e. Python 2.X) + dsc = unicode(dsc, "utf-8") except UnicodeDecodeError, err: return _("Invalid unicode in description for '%s' (%s). " "Please report.") % (self.package.name, err) diff --git a/debian/changelog b/debian/changelog index 6cbdaac7..a9518d7d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,7 @@ python-apt (0.7.11) UNRELEASED; urgency=low + * Introduce support for Python 3 (Closes: #523645) + * Support the 'in' operator (e.g. "k in d") in Configuration{,Ptr,Sub} objects (e.g. apt_pkg.Config) and in TagSections (apt_pkg.ParseSection()) * Replace support for file objects with a more generic support for any object diff --git a/debian/control b/debian/control index 72476c58..08ee329f 100644 --- a/debian/control +++ b/debian/control @@ -11,6 +11,8 @@ Build-Depends: apt-utils, libapt-pkg-dev (>= 0.7.10), python-all-dbg, python-all-dev, + python3.1-dev, + python3.1-dbg, python-central (>= 0.5), python-distutils-extra (>= 1.9.0), python-gtk2, diff --git a/debian/rules b/debian/rules index 6d709ecd..7de945f2 100755 --- a/debian/rules +++ b/debian/rules @@ -11,22 +11,44 @@ DEB_PYTHON_PACKAGES_EXCLUDE=python-apt-dbg include /usr/share/cdbs/1/rules/debhelper.mk include /usr/share/cdbs/1/class/python-distutils.mk +PY3K = y PKG=python-apt DEBVER=$(shell dpkg-parsechangelog |sed -n -e '/^Version:/s/^Version: //p') DEB_COMPRESS_EXCLUDE:=.html .js _static/* _sources/* _sources/*/* .inv DEB_BUILD_PROG:=debuild --preserve-envvar PATH --preserve-envvar CCACHE_DIR -us -uc $(DEB_BUILD_PROG_OPTS) export DEBVER + +ifeq ($(PY3K),y) +build/python-apt:: + python3.1 setup3.py build + +install/python-apt:: + python3.1 ./setup3.py install --root $(CURDIR)/debian/python-apt \ + --install-layout=deb --no-compile + + find $(CURDIR)/debian/python-apt/usr/lib/python3.1/dist-packages/ -name '*.py' \ + | xargs 2to3-3.1 | patch -p0 +endif + build/python-apt-dbg:: set -e; \ for i in $(cdbs_python_build_versions); do \ python$$i-dbg ./setup.py build; \ done + ifeq($(PY3K),y) + python3.1-dbg ./setup3.py build + endif install/python-apt-dbg:: for i in $(cdbs_python_build_versions); do \ - python$$i-dbg ./setup.py install --root $(CURDIR)/debian/python-apt-dbg; \ + python$$i-dbg ./setup.py install --root $(CURDIR)/debian/python-apt-dbg \ + --no-compile; \ done + ifeq($(PY3K),y) + python3.1-dbg ./setup3.py install --root $(CURDIR)/debian/python-apt-dbg \ + --install-layout=deb --no-compile + endif find debian/python-apt-dbg \ ! -type d ! -name '*_d.so' | xargs rm -f find debian/python-apt-dbg -depth -empty -exec rmdir {} \; @@ -39,4 +61,4 @@ binary-predeb/python-apt-dbg:: ln -s python-apt debian/python-apt-dbg/usr/share/doc/python-apt-dbg clean:: - rm -rf build/lib* build/temp* + rm -rf build/lib* build/temp* build diff --git a/po/python-apt.pot b/po/python-apt.pot index 9c23c579..d12ae967 100644 --- a/po/python-apt.pot +++ b/po/python-apt.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-04-12 19:07+0200\n" +"POT-Creation-Date: 2009-04-15 16:10+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -354,16 +354,16 @@ msgstr "" msgid "Complete" msgstr "" -#: ../apt/package.py:278 +#: ../apt/package.py:282 #, python-format msgid "Invalid unicode in description for '%s' (%s). Please report." msgstr "" -#: ../apt/package.py:745 ../apt/package.py:849 +#: ../apt/package.py:830 ../apt/package.py:934 msgid "The list of changes is not available" msgstr "" -#: ../apt/package.py:853 +#: ../apt/package.py:938 #, python-format msgid "" "The list of changes is not available yet.\n" @@ -372,7 +372,7 @@ msgid "" "until the changes become available or try again later." msgstr "" -#: ../apt/package.py:859 +#: ../apt/package.py:944 msgid "" "Failed to download the list of changes. \n" "Please check your Internet connection." diff --git a/python/acquire.cc b/python/acquire.cc index d39ee495..053753cd 100644 --- a/python/acquire.cc +++ b/python/acquire.cc @@ -72,7 +72,9 @@ static PyObject *AcquireItemRepr(PyObject *Self) PyTypeObject AcquireItemType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgAcquire::ItemIterator", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize @@ -175,7 +177,9 @@ static PyGetSetDef PkgAcquireGetSet[] = { PyTypeObject PkgAcquireType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "Acquire", // tp_name sizeof(CppPyObject), // tp_basicsize 0, // tp_itemsize @@ -234,7 +238,9 @@ PyObject *GetAcquire(PyObject *Self,PyObject *Args) PyTypeObject PkgAcquireFileType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgAcquireFile", // tp_name sizeof(CppPyObject),// tp_basicsize 0, // tp_itemsize diff --git a/python/apt_instmodule.cc b/python/apt_instmodule.cc index a9d81be4..09e3937e 100644 --- a/python/apt_instmodule.cc +++ b/python/apt_instmodule.cc @@ -162,8 +162,41 @@ static PyMethodDef methods[] = {} }; +#if PY_MAJOR_VERSION >= 3 +struct module_state { + PyObject *error; +}; +#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m)) + +static int apt_inst_traverse(PyObject *m, visitproc visit, void *arg) { + Py_VISIT(GETSTATE(m)->error); + return 0; +} + +static int apt_inst_clear(PyObject *m) { + Py_CLEAR(GETSTATE(m)->error); + return 0; +} + +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "apt_inst", + NULL, + sizeof(struct module_state), + methods, + NULL, + apt_inst_traverse, + apt_inst_clear, + NULL +}; + +extern "C" PyObject * PyInit_apt_inst() +{ + return PyModule_Create(&moduledef); +} +#else extern "C" void initapt_inst() { Py_InitModule("apt_inst",methods); } - /*}}}*/ +#endif /*}}}*/ diff --git a/python/apt_pkgmodule.cc b/python/apt_pkgmodule.cc index fe6a739e..e71d8ee6 100644 --- a/python/apt_pkgmodule.cc +++ b/python/apt_pkgmodule.cc @@ -173,12 +173,12 @@ static PyObject *md5sum(PyObject *Self,PyObject *Args) return 0; // Digest of a string. - if (PyString_Check(Obj) != 0) + if (PyBytes_Check(Obj) != 0) { char *s; Py_ssize_t len; MD5Summation Sum; - PyString_AsStringAndSize(Obj, &s, &len); + PyBytes_AsStringAndSize(Obj, &s, &len); Sum.Add((const unsigned char*)s, len); return CppPyString(Sum.Result().Value()); } @@ -213,12 +213,12 @@ static PyObject *sha1sum(PyObject *Self,PyObject *Args) return 0; // Digest of a string. - if (PyString_Check(Obj) != 0) + if (PyBytes_Check(Obj) != 0) { char *s; Py_ssize_t len; SHA1Summation Sum; - PyString_AsStringAndSize(Obj, &s, &len); + PyBytes_AsStringAndSize(Obj, &s, &len); Sum.Add((const unsigned char*)s, len); return CppPyString(Sum.Result().Value()); } @@ -253,12 +253,12 @@ static PyObject *sha256sum(PyObject *Self,PyObject *Args) return 0; // Digest of a string. - if (PyString_Check(Obj) != 0) + if (PyBytes_Check(Obj) != 0) { char *s; Py_ssize_t len; SHA256Summation Sum; - PyString_AsStringAndSize(Obj, &s, &len); + PyBytes_AsStringAndSize(Obj, &s, &len); Sum.Add((const unsigned char*)s, len); return CppPyString(Sum.Result().Value()); } @@ -470,30 +470,68 @@ static void AddInt(PyObject *Dict,const char *Itm,unsigned long I) Py_DECREF(Obj); } +#if PY_MAJOR_VERSION >= 3 +struct module_state { + PyObject *error; +}; + +#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m)) + +static int apt_inst_traverse(PyObject *m, visitproc visit, void *arg) { + Py_VISIT(GETSTATE(m)->error); + return 0; +} + +static int apt_inst_clear(PyObject *m) { + Py_CLEAR(GETSTATE(m)->error); + return 0; +} + +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "apt_inst", + NULL, + sizeof(struct module_state), + methods, + NULL, + apt_inst_traverse, + apt_inst_clear, + NULL +}; + +#define INIT_ERROR return 0 +extern "C" PyObject * PyInit_apt_pkg() +#else +#define INIT_ERROR return extern "C" void initapt_pkg() +#endif { // Finalize our types to add slots, etc. - if (PyType_Ready(&TagSecType) == -1) return; - if (PyType_Ready(&TagFileType) == -1) return; - if (PyType_Ready(&ConfigurationType) == -1) return; - if (PyType_Ready(&ConfigurationPtrType) == -1) return; - if (PyType_Ready(&ConfigurationSubType) == -1) return; - if (PyType_Ready(&PkgCdromType) == -1) return; - if (PyType_Ready(&PkgProblemResolverType) == -1) return; - if (PyType_Ready(&PkgActionGroupType) == -1) return; - if (PyType_Ready(&PkgSourceListType) == -1) return; - if (PyType_Ready(&PkgCacheType) == -1) return; - if (PyType_Ready(&DependencyType) == -1) return; - if (PyType_Ready(&PkgDepCacheType) == -1) return; - if (PyType_Ready(&PkgAcquireType) == -1) return; - if (PyType_Ready(&PackageIndexFileType) == -1) return; - if (PyType_Ready(&PkgManagerType) == -1) return; - if (PyType_Ready(&PkgSrcRecordsType) == -1) return; - if (PyType_Ready(&PkgRecordsType) == -1) return; + if (PyType_Ready(&TagSecType) == -1) INIT_ERROR; + if (PyType_Ready(&TagFileType) == -1) INIT_ERROR; + if (PyType_Ready(&ConfigurationType) == -1) INIT_ERROR; + if (PyType_Ready(&ConfigurationPtrType) == -1) INIT_ERROR; + if (PyType_Ready(&ConfigurationSubType) == -1) INIT_ERROR; + if (PyType_Ready(&PkgCdromType) == -1) INIT_ERROR; + if (PyType_Ready(&PkgProblemResolverType) == -1) INIT_ERROR; + if (PyType_Ready(&PkgActionGroupType) == -1) INIT_ERROR; + if (PyType_Ready(&PkgSourceListType) == -1) INIT_ERROR; + if (PyType_Ready(&PkgCacheType) == -1) INIT_ERROR; + if (PyType_Ready(&DependencyType) == -1) INIT_ERROR; + if (PyType_Ready(&PkgDepCacheType) == -1) INIT_ERROR; + if (PyType_Ready(&PkgAcquireType) == -1) INIT_ERROR; + if (PyType_Ready(&PackageIndexFileType) == -1) INIT_ERROR; + if (PyType_Ready(&PkgManagerType) == -1) INIT_ERROR; + if (PyType_Ready(&PkgSrcRecordsType) == -1) INIT_ERROR; + if (PyType_Ready(&PkgRecordsType) == -1) INIT_ERROR; // Initialize the module + #if PY_MAJOR_VERSION >= 3 + PyObject *Module = PyModule_Create(&moduledef); + #else PyObject *Module = Py_InitModule("apt_pkg",methods); + #endif PyObject *Dict = PyModule_GetDict(Module); // Global variable linked to the global configuration class @@ -549,6 +587,9 @@ extern "C" void initapt_pkg() AddInt(Dict,"InstStateReInstReq",pkgCache::State::ReInstReq); AddInt(Dict,"InstStateHold",pkgCache::State::Hold); AddInt(Dict,"InstStateHoldReInstReq",pkgCache::State::HoldReInstReq); + #if PY_MAJOR_VERSION >= 3 + return Module; + #endif } /*}}}*/ diff --git a/python/cache.cc b/python/cache.cc index 2d8b8db7..957681ba 100644 --- a/python/cache.cc +++ b/python/cache.cc @@ -239,7 +239,9 @@ static PyMappingMethods CacheMap = {0,CacheMapOp,0}; PyTypeObject PkgCacheType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgCache", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize @@ -277,7 +279,9 @@ PyTypeObject PkgCacheType = PyTypeObject PkgCacheFileType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgCacheFile", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize @@ -345,7 +349,9 @@ static PySequenceMethods PkgListSeq = PyTypeObject PkgListType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgCache::PkgIterator", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize @@ -435,7 +441,9 @@ static PyObject *PackageRepr(PyObject *Self) PyTypeObject PackageType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgCache::Package", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize @@ -498,7 +506,9 @@ static PyObject *DescriptionRepr(PyObject *Self) PyTypeObject DescriptionType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgCache::DescIterator", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize @@ -684,7 +694,9 @@ static PyObject *VersionRepr(PyObject *Self) PyTypeObject VersionType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgCache::VerIterator", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize @@ -759,7 +771,9 @@ static PyObject *PackageFileRepr(PyObject *Self) PyTypeObject PackageFileType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgCache::PkgFileIterator", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize @@ -905,7 +919,9 @@ static PyGetSetDef DependencyGetSet[] = { PyTypeObject DependencyType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgCache::DepIterator", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize @@ -991,7 +1007,9 @@ static PySequenceMethods RDepListSeq = PyTypeObject RDepListType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgCache::DepIterator", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize diff --git a/python/cdrom.cc b/python/cdrom.cc index 0816d93e..b3a38438 100644 --- a/python/cdrom.cc +++ b/python/cdrom.cc @@ -67,7 +67,9 @@ static PyMethodDef PkgCdromMethods[] = PyTypeObject PkgCdromType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "Cdrom", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize diff --git a/python/configuration.cc b/python/configuration.cc index b4adf357..eaac48ec 100644 --- a/python/configuration.cc +++ b/python/configuration.cc @@ -481,7 +481,9 @@ static PyMappingMethods ConfigurationMap = {0,CnfMap,CnfMapSet}; PyTypeObject ConfigurationType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "Configuration", // tp_name sizeof(CppPyObject), // tp_basicsize 0, // tp_itemsize @@ -515,7 +517,9 @@ PyTypeObject ConfigurationType = PyTypeObject ConfigurationPtrType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "ConfigurationPtr", // tp_name sizeof(CppPyObject), // tp_basicsize 0, // tp_itemsize @@ -549,7 +553,9 @@ PyTypeObject ConfigurationPtrType = PyTypeObject ConfigurationSubType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "ConfigurationSub", // tp_name sizeof(SubConfiguration), // tp_basicsize 0, // tp_itemsize diff --git a/python/depcache.cc b/python/depcache.cc index ade3d4f5..1c9eeff7 100644 --- a/python/depcache.cc +++ b/python/depcache.cc @@ -594,7 +594,9 @@ static PyGetSetDef PkgDepCacheGetSet[] = { PyTypeObject PkgDepCacheType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgDepCache", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize @@ -773,7 +775,9 @@ static PyMethodDef PkgProblemResolverMethods[] = PyTypeObject PkgProblemResolverType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgProblemResolver", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize @@ -829,7 +833,9 @@ static PyMethodDef PkgActionGroupMethods[] = PyTypeObject PkgActionGroupType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgActionGroup", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize diff --git a/python/generic.h b/python/generic.h index ce79a54c..6e66d24c 100644 --- a/python/generic.h +++ b/python/generic.h @@ -35,6 +35,31 @@ typedef int Py_ssize_t; #endif +/* Define compatibility for Python 3. + * + * We will use the names PyString_* to refer to the default string type + * of the current Python version (PyString on 2.X, PyUnicode on 3.X). + * + * When we really need unicode strings, we will use PyUnicode_* directly, as + * long as it exists in Python 2 and Python 3. + * + * When we want bytes in Python 3, we use PyBytes*_ instead of PyString_* and + * define aliases from PyBytes_* to PyString_* for Python 2. + */ + +#if PY_MAJOR_VERSION >= 3 +#define PyString_Check PyUnicode_Check +#define PyString_FromString PyUnicode_FromString +#define PyString_FromStringAndSize PyUnicode_FromStringAndSize +#define PyString_AsString(op) PyBytes_AsString(PyUnicode_AsUTF8String(op)) +#define PyInt_Check PyLong_Check +#define PyInt_AsLong PyLong_AsLong +#else +#define PyBytes_Check PyString_Check +#define PyBytes_AsString PyString_AsString +#define PyBytes_AsStringAndSize PyString_AsStringAndSize +#endif + template struct CppPyObject : public PyObject { // We are only using CppPyObject and friends as dumb structs only, ie the diff --git a/python/indexfile.cc b/python/indexfile.cc index dc55634f..bb40cdd0 100644 --- a/python/indexfile.cc +++ b/python/indexfile.cc @@ -81,7 +81,9 @@ static PyGetSetDef PackageIndexFileGetSet[] = { PyTypeObject PackageIndexFileType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgIndexFile", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize diff --git a/python/metaindex.cc b/python/metaindex.cc index efbc38af..cbaeafbd 100644 --- a/python/metaindex.cc +++ b/python/metaindex.cc @@ -59,7 +59,9 @@ static PyObject *MetaIndexRepr(PyObject *Self) PyTypeObject MetaIndexType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "metaIndex", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize diff --git a/python/pkgmanager.cc b/python/pkgmanager.cc index 52f86228..8f56cddc 100644 --- a/python/pkgmanager.cc +++ b/python/pkgmanager.cc @@ -95,7 +95,9 @@ static PyGetSetDef PkgManagerGetSet[] = { PyTypeObject PkgManagerType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "PackageManager", // tp_name sizeof(CppPyObject), // tp_basicsize 0, // tp_itemsize diff --git a/python/pkgrecords.cc b/python/pkgrecords.cc index 577aaf1c..978de6b7 100644 --- a/python/pkgrecords.cc +++ b/python/pkgrecords.cc @@ -135,7 +135,9 @@ static PyGetSetDef PkgRecordsGetSet[] = { PyTypeObject PkgRecordsType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgRecords", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize diff --git a/python/pkgsrcrecords.cc b/python/pkgsrcrecords.cc index c830f8d2..97667d7a 100644 --- a/python/pkgsrcrecords.cc +++ b/python/pkgsrcrecords.cc @@ -183,7 +183,9 @@ static PyGetSetDef PkgSrcRecordsGetSet[] = { PyTypeObject PkgSrcRecordsType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgSrcRecords", // tp_name sizeof(CppPyObject), // tp_basicsize 0, // tp_itemsize diff --git a/python/sourcelist.cc b/python/sourcelist.cc index 9f8f8878..48b3b7c8 100644 --- a/python/sourcelist.cc +++ b/python/sourcelist.cc @@ -100,7 +100,9 @@ static PyGetSetDef PkgSourceListGetSet[] = { PyTypeObject PkgSourceListType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgSourceList", // tp_name sizeof(CppPyObject), // tp_basicsize 0, // tp_itemsize diff --git a/python/string.cc b/python/string.cc index 8168ea5b..b95ee3eb 100644 --- a/python/string.cc +++ b/python/string.cc @@ -38,7 +38,21 @@ PyObject *Python(PyObject *Self,PyObject *Args) \ } MkStr(StrDeQuote,DeQuoteString); -MkStr(StrBase64Encode,Base64Encode); + +/* + * Input bytes(Py3k)/str(Py2), output str. + */ +PyObject *StrBase64Encode(PyObject *Self,PyObject *Args) { + char *Str = 0; + #if PY_MAJOR_VERSION >= 3 + if (PyArg_ParseTuple(Args,"y",&Str) == 0) + #else + if (PyArg_ParseTuple(Args,"s",&Str) == 0) + #endif + return 0; + return CppPyString(Base64Encode(Str)); +} + MkStr(StrURItoFileName,URItoFileName); //MkFloat(StrSizeToStr,SizeToStr); diff --git a/python/tag.cc b/python/tag.cc index cdea3e03..18d08580 100644 --- a/python/tag.cc +++ b/python/tag.cc @@ -384,7 +384,9 @@ PyMappingMethods TagSecMapMeth = {TagSecLength,TagSecMap,0}; PyTypeObject TagSecType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "TagSection", // tp_name sizeof(TagSecData), // tp_basicsize 0, // tp_itemsize @@ -442,7 +444,9 @@ static PyGetSetDef TagFileGetSet[] = { PyTypeObject TagFileType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "TagFile", // tp_name sizeof(TagFileData), // tp_basicsize 0, // tp_itemsize diff --git a/setup3.py b/setup3.py new file mode 100644 index 00000000..a3cbdc8e --- /dev/null +++ b/setup3.py @@ -0,0 +1,77 @@ +#! /usr/bin/env python3 +# $Id: setup.py,v 1.2 2002/01/08 07:13:21 jgg Exp $ +import glob +import os +import shutil +import sys + +from distutils.core import setup, Extension +from distutils.sysconfig import parse_makefile +#from DistUtilsExtra.command import build_extra, build_i18n + + +# The apt_pkg module +files = ["python/"+source for source in parse_makefile("python/makefile")["APT_PKG_SRC"].split()] +apt_pkg = Extension("apt_pkg", files, libraries=["apt-pkg"]) + +# The apt_inst module +files = ["python/"+source for source in parse_makefile("python/makefile")["APT_INST_SRC"].split()] +apt_inst = Extension("apt_inst", files, libraries=["apt-pkg", "apt-inst"]) + +# Replace the leading _ that is used in the templates for translation +templates = [] + +# build doc +if len(sys.argv) > 1 and sys.argv[1] == "build": + if not os.path.exists("build/data/templates/"): + os.makedirs("build/data/templates") + for template in glob.glob('data/templates/*.info.in'): + source = open(template, "r") + build = open(os.path.join("build", template[:-3]), "w") + lines = source.readlines() + for line in lines: + build.write(line.lstrip("_")) + source.close() + build.close() + + +if len(sys.argv) > 1 and sys.argv[1] == "clean" and '-a' in sys.argv: + for dirname in "build/doc", "doc/build", "build/data", "build/mo": + if os.path.exists(dirname): + print("Removing", dirname) + shutil.rmtree(dirname) + else: + print("Not removing", dirname, "because it does not exist") + +setup(name="python-apt", + description="Python bindings for APT", + version=os.environ.get('DEBVER'), + author="APT Development Team", + author_email="deity@lists.debian.org", + ext_modules=[apt_pkg, apt_inst], + packages=['apt', 'apt.progress', 'aptsources'], + data_files = [('share/python-apt/templates', + glob.glob('build/data/templates/*.info')), + ('share/python-apt/templates', + glob.glob('data/templates/*.mirrors'))], +# cmdclass = {"build": build_extra.build_extra, +# "build_i18n": build_i18n.build_i18n}, + license = 'GNU GPL', + platforms = 'posix') + +if len(sys.argv) > 1 and sys.argv[1] == "build": + try: + import sphinx + except ImportError: + print(('W: Sphinx not available - Not building' + 'documentation'), file=sys.stderr) + try: + import pygtk + except ImportError: + print(('W: Not building documentation because python-' + 'gtk2 is not available at the moment.'), file=sys.stderr) + sys.exit(0) + sphinx.main(["sphinx", "-b", "html", "-d", "build/doc/doctrees", + os.path.abspath("doc/source"), "build/doc/html"]) + sphinx.main(["sphinx", "-b", "text", "-d", "build/doc/doctrees", + os.path.abspath("doc/source"), "build/doc/text"]) -- cgit v1.2.3