diff options
34 files changed, 1749 insertions, 701 deletions
diff --git a/apt/cache.py b/apt/cache.py index cc425ccb..d13010af 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -20,6 +20,7 @@ # USA import os +import weakref import apt_pkg from apt import Package @@ -80,7 +81,8 @@ class Cache(object): self._records = apt_pkg.GetPkgRecords(self._cache) self._list = apt_pkg.GetPkgSourceList() self._list.ReadMainList() - self._dict = {} + self._set = set() + self._weakref = weakref.WeakValueDictionary() progress.Op = "Building data structures" i=last=0 @@ -91,7 +93,7 @@ class Cache(object): last=i # drop stuff with no versions (cruft) if len(pkg.VersionList) > 0: - self._dict[pkg.Name] = Package(self, pkg) + self._set.add(pkg.Name) i += 1 @@ -100,30 +102,36 @@ class Cache(object): def __getitem__(self, key): """ look like a dictionary (get key) """ - return self._dict[key] + try: + return self._weakref[key] + except KeyError: + if key in self._set: + pkg = self._weakref[key] = Package(self, self._cache[key]) + return pkg + else: + raise KeyError('The cache has no package named %r' % key) def __iter__(self): - for pkgname in self._dict.keys(): - yield self._dict[pkgname] + for pkgname in self._set: + yield self[pkgname] raise StopIteration def has_key(self, key): - return (key in self._dict) + return (key in self._set) def __contains__(self, key): - return (key in self._dict) + return (key in self._set) def __len__(self): - return len(self._dict) + return len(self._set) def keys(self): - return self._dict.keys() + return list(self._set) def getChanges(self): """ Get the marked changes """ changes = [] - for name in self._dict.keys(): - p = self._dict[name] + for p in self: if p.markedUpgrade or p.markedInstall or p.markedDelete or \ p.markedDowngrade or p.markedReinstall: changes.append(p) @@ -348,7 +356,7 @@ class FilteredCache(object): return len(self._filtered) def __getitem__(self, key): - return self.cache._dict[key] + return self.cache[key] def __iter__(self): for pkgname in self._filtered: @@ -366,10 +374,10 @@ class FilteredCache(object): def _reapplyFilter(self): " internal helper to refilter " self._filtered = {} - for pkg in self.cache._dict.keys(): + for pkg in self.cache: for f in self._filters: - if f.apply(self.cache._dict[pkg]): - self._filtered[pkg] = 1 + if f.apply(pkg): + self._filtered[pkg.name] = 1 break def setFilter(self, filter): diff --git a/apt/debfile.py b/apt/debfile.py index 0406a250..8d4f534c 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -463,18 +463,18 @@ class DscSrcPackage(DebPackage): try: while tagfile.Step() == 1: for tag in depends_tags: - if not sec.has_key(tag): + if not tag in sec: continue self._depends.extend(apt_pkg.ParseSrcDepends(sec[tag])) for tag in conflicts_tags: - if not sec.has_key(tag): + if not tag in sec: continue self._conflicts.extend(apt_pkg.ParseSrcDepends(sec[tag])) - if sec.has_key('Source'): + if 'Source' in sec: self.pkgname = sec['Source'] - if sec.has_key('Binary'): + if 'Binary' in sec: self.binaries = sec['Binary'].split(', ') - if sec.has_key('Version'): + if 'Version' in sec: self._sections['Version'] = sec['Version'] finally: del sec diff --git a/apt/package.py b/apt/package.py index ec88a456..db5696ae 100644 --- a/apt/package.py +++ b/apt/package.py @@ -42,7 +42,7 @@ def _(string): def _file_is_same(path, size, md5): - """Return True if the file is the same.""" + """Return ``True`` if the file is the same.""" if (os.path.exists(path) and os.path.getsize(path) == size and apt_pkg.md5sum(open(path)) == md5): return True @@ -96,7 +96,7 @@ class DeprecatedProperty(property): def __init__(self, fget=None, fset=None, fdel=None, doc=None): property.__init__(self, fget, fset, fdel, doc) - self.__doc__ = ':Deprecated: ' + (doc or fget.__doc__ or '') + self.__doc__ = (doc or fget.__doc__ or '') def __get__(self, obj, type=None): if obj is not None: @@ -157,7 +157,7 @@ class Record(object): return self._rec[key] def __contains__(self, key): - return self._rec.has_key(key) + return key in self._rec def __iter__(self): return iter(self._rec.keys()) @@ -168,21 +168,21 @@ class Record(object): yield key, self._rec[key] def get(self, key, default=None): - """Return record[key] if key in record, else `default`. + """Return record[key] if key in record, else *default*. - The parameter `default` must be either a string or None. + The parameter *default* must be either a string or None. """ return self._rec.get(key, default) def has_key(self, key): - """deprecated form of 'key in x'.""" - return self._rec.has_key(key) + """deprecated form of ``key in x``.""" + return key in self._rec class Version(object): """Representation of a package version. - :since: 0.7.9 + .. versionadded:: 0.7.9 """ def __init__(self, package, cand): @@ -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) @@ -352,26 +356,41 @@ class Version(object): @property def filename(self): - """Return the path to the file inside the archive.""" + """Return the path to the file inside the archive. + + .. versionadded:: 0.7.10 + """ return self._records.FileName @property def md5(self): - """Return the md5sum of the binary.""" + """Return the md5sum of the binary. + + .. versionadded:: 0.7.10 + """ return self._records.MD5Hash @property def sha1(self): - """Return the sha1sum of the binary.""" + """Return the sha1sum of the binary. + + .. versionadded:: 0.7.10 + """ return self._records.SHA1Hash @property def sha256(self): - """Return the sha1sum of the binary.""" + """Return the sha256sum of the binary. + + .. versionadded:: 0.7.10 + """ return self._records.SHA256Hash def _uris(self): - """Return an iterator over all available urls.""" + """Return an iterator over all available urls. + + .. versionadded:: 0.7.10 + """ for (packagefile, index) in self._cand.FileList: indexfile = self.package._pcache._list.FindIndex(packagefile) if indexfile: @@ -379,23 +398,31 @@ class Version(object): @property def uris(self): - """Return a list of all available uris for the binary.""" + """Return a list of all available uris for the binary. + + .. versionadded:: 0.7.10 + """ return list(self._uris()) @property def uri(self): - """Return a single URI for the binary.""" + """Return a single URI for the binary. + + .. versionadded:: 0.7.10 + """ return self._uris().next() def fetch_binary(self, destdir='', progress=None): """Fetch the binary version of the package. - The parameter 'destdir' specifies the directory where the package will + The parameter *destdir* specifies the directory where the package will be fetched to. - The parameter 'progress' may refer to an apt.progress.FetchProgress() + The parameter *progress* may refer to an apt.progress.FetchProgress() object. If not specified or None, apt.progress.TextFetchProgress() is used. + + .. versionadded:: 0.7.10 """ base = os.path.basename(self._records.FileName) destfile = os.path.join(destdir, base) @@ -415,18 +442,18 @@ class Version(object): def fetch_source(self, destdir="", progress=None, unpack=True): """Get the source code of a package. - The parameter 'destdir' specifies the directory where the source will + The parameter *destdir* specifies the directory where the source will be fetched to. - The parameter 'progress' may refer to an apt.progress.FetchProgress() + The parameter *progress* may refer to an apt.progress.FetchProgress() object. If not specified or None, apt.progress.TextFetchProgress() is used. - The parameter 'unpack' describes whether the source should be unpacked - (True) or not (False). By default, it is unpacked. + The parameter *unpack* describes whether the source should be unpacked + (``True``) or not (``False``). By default, it is unpacked. - If 'unpack' is True, the path to the extracted directory is returned. - Otherwise, the path to the .dsc file is returned. + If *unpack* is ``True``, the path to the extracted directory is + returned. Otherwise, the path to the .dsc file is returned. """ src = apt_pkg.GetPkgSrcRecords() acq = apt_pkg.GetAcquire(progress or apt.progress.TextFetchProgress()) @@ -486,20 +513,33 @@ class Package(object): def __repr__(self): return '<Package: name:%r id:%r>' % (self._pkg.Name, self._pkg.ID) - @property def candidate(self): """Return the candidate version of the package. - :since: 0.7.9""" + This property is writeable to allow you to set the candidate version + of the package. Just assign a Version() object, and it will be set as + the candidate version. + + .. versionadded:: 0.7.9 + """ cand = self._pcache._depcache.GetCandidateVer(self._pkg) if cand is not None: return Version(self, cand) + def __set_candidate(self, version): + """Set the candidate version of the package.""" + self._pcache.cachePreChange() + self._pcache._depcache.SetCandidateVer(self._pkg, version._cand) + self._pcache.cachePostChange() + + candidate = property(candidate, __set_candidate) + @property def installed(self): """Return the currently installed version of the package. - :since: 0.7.9""" + .. versionadded:: 0.7.9 + """ if self._pkg.CurrentVer is not None: return Version(self, self._pkg.CurrentVer) @@ -525,42 +565,62 @@ class Package(object): def installedVersion(self): """Return the installed version as string. - Deprecated, please use installed.version instead.""" + .. deprecated:: 0.7.9""" return getattr(self.installed, 'version', None) @DeprecatedProperty def candidateVersion(self): - """Return the candidate version as string.""" + """Return the candidate version as string. + + .. deprecated:: 0.7.9""" return getattr(self.candidate, "version", None) @DeprecatedProperty def candidateDependencies(self): - """Return a list of candidate dependencies.""" + """Return a list of candidate dependencies. + + .. deprecated:: 0.7.9 + """ return getattr(self.candidate, "dependencies", None) @DeprecatedProperty def installedDependencies(self): - """Return a list of installed dependencies.""" + """Return a list of installed dependencies. + + .. deprecated:: 0.7.9 + """ return getattr(self.installed, 'dependencies', []) @DeprecatedProperty def architecture(self): - """Return the Architecture of the package""" + """Return the Architecture of the package. + + .. deprecated:: 0.7.9 + """ return getattr(self.candidate, "architecture", None) @DeprecatedProperty def candidateDownloadable(self): - """Return True if the candidate is downloadable.""" + """Return ``True`` if the candidate is downloadable. + + .. deprecated:: 0.7.9 + """ return getattr(self.candidate, "downloadable", None) @DeprecatedProperty def installedDownloadable(self): - """Return True if the installed version is downloadable.""" + """Return ``True`` if the installed version is downloadable. + + .. deprecated:: 0.7.9 + """ return getattr(self.installed, 'downloadable', False) @DeprecatedProperty def sourcePackageName(self): - """Return the source package name as string.""" + """Return the source package name as string. + + .. deprecated:: 0.7.9 + """ try: return self.candidate._records.SourcePkg or self._pkg.Name except AttributeError: @@ -571,7 +631,10 @@ class Package(object): @DeprecatedProperty def homepage(self): - """Return the homepage field as string.""" + """Return the homepage field as string. + + .. deprecated:: 0.7.9 + """ return getattr(self.candidate, "homepage", None) @property @@ -581,17 +644,26 @@ class Package(object): @DeprecatedProperty def priority(self): - """Return the priority (of the candidate version).""" + """Return the priority (of the candidate version). + + .. deprecated:: 0.7.9 + """ return getattr(self.candidate, "priority", None) @DeprecatedProperty def installedPriority(self): - """Return the priority (of the installed version).""" + """Return the priority (of the installed version). + + .. deprecated:: 0.7.9 + """ return getattr(self.installed, 'priority', None) @DeprecatedProperty def summary(self): - """Return the short description (one line summary).""" + """Return the short description (one line summary). + + .. deprecated:: 0.7.9 + """ return getattr(self.candidate, "summary", None) @DeprecatedProperty @@ -602,44 +674,52 @@ class Package(object): (Chapter 5.6.13). See http://www.debian.org/doc/debian-policy/ch-controlfields.html for more information. + + .. deprecated:: 0.7.9 """ return getattr(self.candidate, "description", None) @DeprecatedProperty def rawDescription(self): - """return the long description (raw).""" + """return the long description (raw). + + .. deprecated:: 0.7.9""" return getattr(self.candidate, "raw_description", None) @DeprecatedProperty def candidateRecord(self): - """Return the Record of the candidate version of the package.""" + """Return the Record of the candidate version of the package. + + .. deprecated:: 0.7.9""" return getattr(self.candidate, "record", None) @DeprecatedProperty def installedRecord(self): - """Return the Record of the candidate version of the package.""" + """Return the Record of the candidate version of the package. + + .. deprecated:: 0.7.9""" return getattr(self.installed, 'record', '') # depcache states @property def markedInstall(self): - """Return True if the package is marked for install.""" + """Return ``True`` if the package is marked for install.""" return self._pcache._depcache.MarkedInstall(self._pkg) @property def markedUpgrade(self): - """Return True if the package is marked for upgrade.""" + """Return ``True`` if the package is marked for upgrade.""" return self._pcache._depcache.MarkedUpgrade(self._pkg) @property def markedDelete(self): - """Return True if the package is marked for delete.""" + """Return ``True`` if the package is marked for delete.""" return self._pcache._depcache.MarkedDelete(self._pkg) @property def markedKeep(self): - """Return True if the package is marked for keep.""" + """Return ``True`` if the package is marked for keep.""" return self._pcache._depcache.MarkedKeep(self._pkg) @property @@ -649,23 +729,23 @@ class Package(object): @property def markedReinstall(self): - """Return True if the package is marked for reinstall.""" + """Return ``True`` if the package is marked for reinstall.""" return self._pcache._depcache.MarkedReinstall(self._pkg) @property def isInstalled(self): - """Return True if the package is installed.""" + """Return ``True`` if the package is installed.""" return (self._pkg.CurrentVer is not None) @property def isUpgradable(self): - """Return True if the package is upgradable.""" + """Return ``True`` if the package is upgradable.""" return (self.isInstalled and self._pcache._depcache.IsUpgradable(self._pkg)) @property def isAutoRemovable(self): - """Return True if the package is no longer required. + """Return ``True`` if the package is no longer required. If the package has been installed automatically as a dependency of another package, and if no packages depend on it anymore, the package @@ -677,22 +757,35 @@ class Package(object): @DeprecatedProperty def packageSize(self): - """Return the size of the candidate deb package.""" + """Return the size of the candidate deb package. + + .. deprecated:: 0.7.9 + """ return getattr(self.candidate, "size", None) @DeprecatedProperty def installedPackageSize(self): - """Return the size of the installed deb package.""" + """Return the size of the installed deb package. + + .. deprecated:: 0.7.9 + """ return getattr(self.installed, 'size', 0) @DeprecatedProperty def candidateInstalledSize(self): - """Return the size of the candidate installed package.""" + """Return the size of the candidate installed package. + + .. deprecated:: 0.7.9 + """ return getattr(self.candidate, "installed_size", None) @DeprecatedProperty def installedSize(self): - """Return the size of the currently installed package.""" + """Return the size of the currently installed package. + + + .. deprecated:: 0.7.9 + """ return getattr(self.installed, 'installed_size', 0) @property @@ -717,15 +810,16 @@ class Package(object): Download the changelog of the package and return it as unicode string. - The parameter `uri` refers to the uri of the changelog file. It may + The parameter *uri* refers to the uri of the changelog file. It may contain multiple named variables which will be substitued. These variables are (src_section, prefix, src_pkg, src_ver). An example is - the Ubuntu changelog: + the Ubuntu changelog:: + "http://changelogs.ubuntu.com/changelogs/pool" \\ "/%(src_section)s/%(prefix)s/%(src_pkg)s" \\ "/%(src_pkg)s_%(src_ver)s/changelog" - The parameter `cancel_lock` refers to an instance of threading.Lock, + The parameter *cancel_lock* refers to an instance of threading.Lock, which if set, prevents the download. """ # Return a cached changelog if available @@ -866,14 +960,17 @@ class Package(object): @DeprecatedProperty def candidateOrigin(self): - """Return a list of Origin() objects for the candidate version.""" + """Return a list of `Origin()` objects for the candidate version. + + .. deprecated:: 0.7.9 + """ return getattr(self.candidate, "origins", None) @property def versions(self): """Return a list of versions. - :since: 0.7.9 + .. versionadded:: 0.7.9 """ return [Version(self, ver) for ver in self._pkg.VersionList] @@ -888,11 +985,11 @@ class Package(object): def markDelete(self, autoFix=True, purge=False): """Mark a package for install. - If autoFix is True, the resolver will be run, trying to fix broken - packages. This is the default. + If *autoFix* is ``True``, the resolver will be run, trying to fix + broken packages. This is the default. - If purge is True, remove the configuration files of the package as - well. The default is to keep the configuration. + If *purge* is ``True``, remove the configuration files of the package + as well. The default is to keep the configuration. """ self._pcache.cachePreChange() self._pcache._depcache.MarkDelete(self._pkg, purge) @@ -909,16 +1006,16 @@ class Package(object): def markInstall(self, autoFix=True, autoInst=True, fromUser=True): """Mark a package for install. - If autoFix is True, the resolver will be run, trying to fix broken - packages. This is the default. + If *autoFix* is ``True``, the resolver will be run, trying to fix + broken packages. This is the default. - If autoInst is True, the dependencies of the packages will be installed - automatically. This is the default. + If *autoInst* is ``True``, the dependencies of the packages will be + installed automatically. This is the default. - If fromUser is True, this package will not be marked as automatically - installed. This is the default. Set it to False if you want to be able - to remove the package at a later stage if no other package depends on - it. + If *fromUser* is ``True``, this package will not be marked as + automatically installed. This is the default. Set it to False if you + want to be able to automatically remove the package at a later stage + when no other package depends on it. """ self._pcache.cachePreChange() self._pcache._depcache.MarkInstall(self._pkg, autoInst, fromUser) @@ -942,10 +1039,10 @@ class Package(object): def commit(self, fprogress, iprogress): """Commit the changes. - The parameter `fprogress` refers to a FetchProgress() object, as + The parameter *fprogress* refers to a FetchProgress() object, as found in apt.progress. - The parameter `iprogress` refers to an InstallProgress() object, as + The parameter *iprogress* refers to an InstallProgress() object, as found in apt.progress. """ self._pcache._depcache.Commit(fprogress, iprogress) diff --git a/debian/changelog b/debian/changelog index 83b00150..b2f2b965 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,20 @@ +python-apt (0.7.90) experimental; 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 + providing a fileno() method and for file descriptors (integers). + * Add support for the Breaks fields + * Only create Package objects when they are requested, do not keep them in + a dict. Saves 10MB for 25,000 packages on my machine. + * apt/package.py: Allow to set the candidate of a package (Closes: #523997) + - Support assignments to the 'candidate' property of Package objects. + - Initial patch by Sebastian Heinlein + + -- Julian Andres Klode <jak@debian.org> Wed, 15 Apr 2009 13:47:42 +0200 + python-apt (0.7.10.3) unstable; urgency=low * apt/package.py: Handle cases where no candidate is available, by returning diff --git a/debian/control b/debian/control index 4c7b542f..08ee329f 100644 --- a/debian/control +++ b/debian/control @@ -11,8 +11,9 @@ 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-debian, python-distutils-extra (>= 1.9.0), python-gtk2, python-sphinx (>= 0.5), diff --git a/debian/rules b/debian/rules index 6d709ecd..9d0219e2 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/doc/source/apt_inst.rst b/doc/source/apt_inst.rst index 97705f61..cd371e36 100644 --- a/doc/source/apt_inst.rst +++ b/doc/source/apt_inst.rst @@ -11,7 +11,12 @@ Checking packages .. function:: arCheckMember(file, membername) Check if the member specified by the parameter *membername* exists in - the AR file referenced by the :class:`file` object *file*. + the AR file referenced by the parameter *file*, which may be a + :class:`file()` object, a file descriptor, or anything implementing a + :meth:`fileno` method. + + .. versionchanged:: 0.8.0 + Added support for file descriptors and objects implementing a :meth:`fileno` method. Listing contents @@ -19,8 +24,9 @@ Listing contents .. function:: debExtract(file, func, chunk) Call the function referenced by *func* for each member of the tar file - *chunk* which is contained in the AR file referenced by the file object - *file*. + *chunk* which is contained in the AR file referenced by the parameter + *file*, which may be a :class:`file()` object, a file descriptor, or + anything implementing a :meth:`fileno` method. An example would be:: @@ -28,12 +34,21 @@ Listing contents See :ref:`emulating-dpkg-contents` for a more detailed example. + .. versionchanged:: 0.8.0 + Added support for file descriptors and objects implementing a :meth:`fileno` method. + .. function:: tarExtract(file,func,comp) Call the function *func* for each member of the tar file *file*. - *Comp* is a string determining the compressor used. Possible options are - "lzma", "bzip2" and "gzip". + The parameter *comp* is a string determining the compressor used. Possible + options are "lzma", "bzip2" and "gzip". + + The parameter *file* may be a :class:`file()` object, a file descriptor, or + anything implementing a :meth:`fileno` method. + + .. versionchanged:: 0.8.0 + Added support for file descriptors and objects implementing a :meth:`fileno` method. Callback @@ -56,6 +71,9 @@ Extracting contents Extract the archive referenced by the :class:`file` object *file* into the directory specified by *rootdir*. + The parameter *file* may be a :class:`file()` object, a file descriptor, or + anything implementing a :meth:`fileno` method. + See :ref:`emulating-dpkg-extract` for an example. .. warning:: @@ -63,16 +81,24 @@ Extracting contents If the directory given by *rootdir* does not exist, the package is extracted into the current directory. + .. versionchanged:: 0.8.0 + Added support for file descriptors and objects implementing a :meth:`fileno` method. + .. function:: debExtractControl(file[, member='control']) - Return the indicated file from the control tar. The default is 'control'. + Return the indicated file as a string from the control tar. The default + is 'control'. + + The parameter *file* may be a :class:`file()` object, a file descriptor, or + anything implementing a :meth:`fileno` method. If you want to print the control file of a given package, you could do something like:: print debExtractControl(open("package.deb")) - :return: The contents of the file, as :class:`str`. + .. versionchanged:: 0.8.0 + Added support for file descriptors and objects implementing a :meth:`fileno` method. .. _emulating-dpkg-extract: diff --git a/doc/source/apt_pkg/cache.rst b/doc/source/apt_pkg/cache.rst index af67d82f..a58f1356 100644 --- a/doc/source/apt_pkg/cache.rst +++ b/doc/source/apt_pkg/cache.rst @@ -117,6 +117,12 @@ Classes in apt_pkg The Configuration objects store the configuration of apt. + .. describe:: key in conf + + Return ``True`` if *conf* has a key *key*, else ``False``. + + .. versionadded:: 0.8.0 + .. describe:: conf[key] Return the value of the option given key *key*. If it does not @@ -201,6 +207,8 @@ Classes in apt_pkg Return whether the configuration contains the key *key*. + .. deprecated:: 0.8.0 + .. method:: get(key[, default='']) This behaves just like :meth:`dict.get` and :meth:`Configuration.Find`, @@ -1199,6 +1207,12 @@ broken dependencies: Return the value of the field at *key*. If *key* is not available, raise :exc:`KeyError`. + .. describe:: key in section + + Return ``True`` if *section* has a key *key*, else ``False``. + + .. versionadded:: 0.8.0 + .. method:: Bytes The number of bytes in the section. @@ -1222,6 +1236,8 @@ broken dependencies: Check whether the field with named by *key* exists. + .. deprecated:: 0.8.0 + .. method:: keys() Return a list of keys in the section. diff --git a/doc/source/apt_pkg/index.rst b/doc/source/apt_pkg/index.rst index 6e7b772e..47923c23 100644 --- a/doc/source/apt_pkg/index.rst +++ b/doc/source/apt_pkg/index.rst @@ -17,6 +17,8 @@ the beginning. Module Initialization --------------------- +Initialization is needed for most functions, but not for all of them. Some can +be called without having run init*(), but will not return the expected value. .. function:: initConfig @@ -89,9 +91,6 @@ Object initialization Return a new :class:`PkgSrcRecords` object. -.. function:: newConfiguration() - - Return a new :class:`Configuration` object. The Acquire interface @@ -164,46 +163,197 @@ of the ones provides in Python's :mod:`hashlib` module. Return the md5sum of the object. *object* may either be a string, in which case the md5sum of the string is returned, or a :class:`file()` - object, in which case the md5sum of its contents is returned. + object (or a file descriptor), in which case the md5sum of its contents is + returned. + + .. versionchanged:: 0.8.0 + Added support for using file descriptors. .. function:: sha1sum(object) Return the sha1sum of the object. *object* may either be a string, in which case the sha1sum of the string is returned, or a :class:`file()` - object, in which case the sha1sum of its contents is returned. + object (or a file descriptor), in which case the sha1sum of its contents + is returned. + + .. versionchanged:: 0.8.0 + Added support for using file descriptors. .. function:: sha256sum(object) Return the sha256sum of the object. *object* may either be a string, in which case the sha256sum of the string is returned, or a :class:`file()` - object, in which case the sha256sum of its contents is returned. + object (or a file descriptor), in which case the sha256sum of its contents + is returned. + + .. versionchanged:: 0.8.0 + Added support for using file descriptors. + +Debian control files +-------------------- +.. function:: ParseSection(text) + + Parse the string given in the parameter *text* and return a + :class:`TagSection` object. + +.. function:: ParseTagFile(file) + + Parse the given *file* and return a :class:`TagFile()` object. *file* may + be a :class:`file()` object, a file descriptor, or anything providing a + :meth:`fileno()` method. + + .. versionchanged:: 0.8.0 + Added support for using file descriptors. + +.. autofunction:: RewriteSection(section, order, rewrite_list) + +.. data:: RewritePackageOrder + + The order in which the information for binary packages should be rewritten, + i.e. the order in which the fields should appear. + +.. data:: RewriteSourceOrder + + The order in which the information for source packages should be rewritten, + i.e. the order in which the fields should appear. + +Dependencies +------------ +.. function:: CheckDep(pkgver, op, depver) + + Check that the dependency requirements consisting of op and depver can be + satisfied by the version pkgver. + + Example:: + + >>> bool(apt_pkg.CheckDep("1.0", ">=", "1")) + True + +.. function:: ParseDepends(depends) + + Parse the string *depends* which contains dependency information as + specified in Debian Policy, Section 7.1. + + Returns a list. The members of this list are lists themselves and contain + one or more tuples in the format ``(package,version,operation)`` for every + 'or'-option given, e.g.:: + + >>> apt_pkg.ParseDepends("PkgA (>= VerA) | PkgB (>= VerB)") + [[('PkgA', 'VerA', '>='), ('PkgB', 'VerB', '>=')]] + +.. function:: ParseSrcDepends(depends) + + Parse the string *depends* which contains dependency information as + specified in Debian Policy, Section 7.1. + + Returns a list. The members of this list are lists themselves and contain + one or more tuples in the format ``(package,version,operation)`` for every + 'or'-option given, e.g.:: + + >>> apt_pkg.ParseDepends("PkgA (>= VerA) | PkgB (>= VerB)") + [[('PkgA', 'VerA', '>='), ('PkgB', 'VerB', '>=')]] + + + Furthemore, this function also supports to limit the architectures, as + used in e.g. Build-Depends:: + + >>> apt_pkg.ParseSrcDepends("a (>= 01) [i386 amd64]") + [[('a', '01', '>=')]] + + +Configuration +------------- + +.. data:: Config + + A :class:`Configuration()`-like object with the default configuration. This + is implemented in the :class:`ConfigurationPtr` class, which has the same + API like the :class:`Configuration` class. + +.. function:: newConfiguration() + + Return a new :class:`Configuration` object. + +.. function:: ReadConfigFile(configuration, filename) + + Read the configuration file specified by the parameter *filename* and add + the settings therein to the :class:`Configuration()` object specified by + the parameter *configuration* + +.. function:: ReadConfigDir(configuration, dirname) + + Read configuration files in the directory specified by the parameter + *dirname* and add the settings therein to the :class:`Configuration()` + object specified by the parameter *configuration*. + +.. function:: ReadConfigFileISC(configuration, filename) + + Read the configuration file specified by the parameter *filename* and add + the settings therein to the :class:`Configuration()` object specified by + the parameter *configuration* + +.. function:: ParseCommandLine(configuration,options,argv) + + This function is like getopt except it manipulates a configuration space. + output is a list of non-option arguments (filenames, etc). *options* is a + list of tuples of the form ``(‘c’,”long-opt or None”, + ”Configuration::Variable”,”optional type”)``. + + Where ``type`` may be one of HasArg, IntLevel, Boolean, InvBoolean, + ConfigFile, or ArbItem. The default is Boolean. + +Locking +-------- + +.. function:: GetLock(filename) + + Create an empty file at the path specified by the parameter *filename* and + lock it. + + While the file is locked by a process, calling this function in another + process returns ``-1``. + + When the lock is not required anymore, the file descriptor should be closed + using :func:`os.close`. + +.. function:: PkgSystemLock() + + Lock the global pkgsystem. + +.. function:: PkgSystemUnLock() + + Unlock the global pkgsystem. Other functions ---------------- +.. function:: Base64Encode(string) + + Encode the given string using base64, e.g:: + + >>> apt_pkg.Base64Encode(u"A") + 'QQ==' -.. note:: - - This documentation is (in parts) created automatically, and still needs to - be improved. - -.. autofunction:: Base64Encode -.. autofunction:: CheckDep -.. autofunction:: CheckDomainList -.. autofunction:: DeQuoteString -.. autofunction:: GetLock - -.. autofunction:: ParseCommandLine -.. autofunction:: ParseDepends -.. autofunction:: ParseSection -.. autofunction:: ParseSrcDepends -.. autofunction:: ParseTagFile -.. autofunction:: PkgSystemLock -.. autofunction:: PkgSystemUnLock -.. autofunction:: QuoteString -.. autofunction:: ReadConfigFile -.. autofunction:: ReadConfigDir() -.. autofunction:: ReadConfigFileISC -.. autofunction:: RewriteSection + +.. function:: CheckDomainList(host, list) + + See if Host is in a ',' seperated list, e.g.:: + + apt_pkg.CheckDomainList("alioth.debian.org","debian.net,debian.org") + +.. function:: DeQuoteString(string) + + Dequote the string specified by the parameter *string*, e.g.:: + + >>> apt_pkg.DeQuoteString("%61%70%74%20is%20cool") + 'apt is cool' + +.. function:: QuoteString(string, repl) + + For every character listed in the string *repl*, replace all occurences in + the string *string* with the correct HTTP encoded value: + + >>> apt_pkg.QuoteString("apt is cool","apt") + '%61%70%74%20is%20cool' .. function:: SizeToStr(size) @@ -271,8 +421,6 @@ Other functions >>> apt_pkg.TimeToStr(3601) '1h0min1s' - - .. function:: UpstreamVersion(version) Return the string *version*, eliminating everything following the last @@ -305,23 +453,12 @@ Other functions ===== ============================================= -Data ------ - -.. data:: Config - - An :class:`Configuration()` object with the default configuration. Actually, - this is a bit different object, but it is compatible. - -.. data:: RewritePackageOrder - -.. data:: RewriteSourceOrder .. _CurStates: Package States -^^^^^^^^^^^^^^^ +--------------- .. data:: CurStateConfigFiles .. data:: CurStateHalfConfigured .. data:: CurStateHalfInstalled @@ -333,7 +470,7 @@ Package States Dependency types -^^^^^^^^^^^^^^^^ +---------------- .. data:: DepConflicts .. data:: DepDepends .. data:: DepObsoletes @@ -345,7 +482,7 @@ Dependency types .. _InstStates: Installed states -^^^^^^^^^^^^^^^^^ +----------------- .. data:: InstStateHold .. data:: InstStateHoldReInstReq .. data:: InstStateOk @@ -354,7 +491,7 @@ Installed states .. _Priorities: Priorities -^^^^^^^^^^ +---------- .. data:: PriExtra .. data:: PriImportant .. data:: PriOptional @@ -365,7 +502,7 @@ Priorities .. _SelStates: Select states -^^^^^^^^^^^^^^ +-------------- .. data:: SelStateDeInstall .. data:: SelStateHold .. data:: SelStateInstall @@ -374,7 +511,7 @@ Select states Build information -^^^^^^^^^^^^^^^^^ +----------------- .. data:: Date The date on which this extension has been compiled. diff --git a/doc/source/conf.py b/doc/source/conf.py index 40154a6f..52c8a21b 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -60,13 +60,16 @@ copyright = u'2009, Julian Andres Klode <jak@debian.org>' # |version| and |release|, also used in various other places throughout the # built documents. # -from debian_bundle.changelog import Changelog -changes = Changelog(open('../../debian/changelog')) -# The short X.Y version. -version = '.'.join(changes.full_version.split('.')[:2]) -# The full version, including alpha/beta/rc tags. -release = changes.full_version +try: + release=os.environ['DEBVER'] +except KeyError: + from debian_bundle.changelog import Changelog + changes = Changelog(open('../../debian/changelog')) + # The full version, including alpha/beta/rc tags. + release = changes.full_version + +version = '.'.join(release.split('.')[:3]) # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/doc/source/coding.rst b/doc/source/contributing.rst index 1357ce14..04933b73 100644 --- a/doc/source/coding.rst +++ b/doc/source/contributing.rst @@ -1,5 +1,5 @@ -Coding for python-apt -====================== +Contributing to python-apt +========================== Let's say you need a new feature, you can develop it, and you want to get it included in python-apt. Then be sure to follow the following guidelines. @@ -61,30 +61,22 @@ attributes, etc. This coding style guidelines are incomplete. If you have any questions send an email to deity@lists.debian.org. -.. note:: - - The coding style may be changed completely during the port to Python 3.0. - But this will not happen very soon. - Python Coding Style ------------------- -The coding style for all code written in python is :PEP:`8`. For modules added -from version 0.7.9 on, there are no exceptions. +The coding style for all code written in python is :PEP:`8`. For modules and +classes added from version 0.7.9 on, there are no exceptions. -Modules introduced prior to 0.7.9 use mixedCase names for methods, functions +Classes introduced prior to 0.7.9 use mixedCase names for methods, functions and variables. These names will be replaced by names conforming to :PEP:`8` in a future release of python-apt. Therefore, try to reduce the introduction of the mixedName code to the absolute minimum (sometimes you can also use shorter names). -To prepare the port to Python 3.0, code should not use any functionality which -is deprecated as of Python 2.6. - -The has_key() functionality may be used only on TagSection objects; as they -provide no other way to do this. If someone is willing to adapt TagSection to -support ``key in mapping`` and ``iter(mapping)``, this would be great. +In order to make the automatic generation of Python 3 code using 2to possible, +code written in Python may not utilize any functionality unsupported by 2to3 or +deprecated as of Python 2.6. .. note:: diff --git a/doc/source/index.rst b/doc/source/index.rst index 23ea4cca..930ff55c 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -24,7 +24,7 @@ Contents: apt_pkg/index apt_inst aptsources/index - coding + contributing 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 <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\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 1ecf55a5..abd3884d 100644 --- a/python/acquire.cc +++ b/python/acquire.cc @@ -12,46 +12,50 @@ #include <apt-pkg/acquire-item.h> -// pkgAcquire::Item -static PyObject *AcquireItemAttr(PyObject *Self,char *Name) -{ - pkgAcquire::ItemIterator &I = GetCpp<pkgAcquire::ItemIterator>(Self); - - if (strcmp("ID",Name) == 0) - return Py_BuildValue("i",(*I)->ID); - else if (strcmp("Status",Name) == 0) - return Py_BuildValue("i",(*I)->Status); - else if (strcmp("Complete",Name) == 0) - return Py_BuildValue("i",(*I)->Complete); - else if (strcmp("Local",Name) == 0) - return Py_BuildValue("i",(*I)->Local); - else if (strcmp("IsTrusted",Name) == 0) - return Py_BuildValue("i",(*I)->IsTrusted()); - else if (strcmp("FileSize",Name) == 0) - return Py_BuildValue("i",(*I)->FileSize); - else if (strcmp("ErrorText",Name) == 0) - return Safe_FromString((*I)->ErrorText.c_str()); - else if (strcmp("DestFile",Name) == 0) - return Safe_FromString((*I)->DestFile.c_str()); - else if (strcmp("DescURI",Name) == 0) - return Safe_FromString((*I)->DescURI().c_str()); - // constants - else if (strcmp("StatIdle",Name) == 0) - return Py_BuildValue("i", pkgAcquire::Item::StatIdle); - else if (strcmp("StatFetching",Name) == 0) - return Py_BuildValue("i", pkgAcquire::Item::StatFetching); - else if (strcmp("StatDone",Name) == 0) - return Py_BuildValue("i", pkgAcquire::Item::StatDone); - else if (strcmp("StatError",Name) == 0) - return Py_BuildValue("i", pkgAcquire::Item::StatError); - else if (strcmp("StatAuthError",Name) == 0) - return Py_BuildValue("i", pkgAcquire::Item::StatAuthError); - - - PyErr_SetString(PyExc_AttributeError,Name); - return 0; +#define MkGet(PyFunc,Ret) static PyObject *PyFunc(PyObject *Self,void*) \ +{ \ + pkgAcquire::ItemIterator &I = GetCpp<pkgAcquire::ItemIterator>(Self); \ + return Ret; \ } +// Define our getters +MkGet(AcquireItemGetComplete,Py_BuildValue("i",(*I)->Complete)); +MkGet(AcquireItemGetDescURI,Safe_FromString((*I)->DescURI().c_str())); +MkGet(AcquireItemGetDestFile,Safe_FromString((*I)->DestFile.c_str())); +MkGet(AcquireItemGetErrorText,Safe_FromString((*I)->ErrorText.c_str())); +MkGet(AcquireItemGetFileSize,Py_BuildValue("i",(*I)->FileSize)); +MkGet(AcquireItemGetID,Py_BuildValue("i",(*I)->ID)); +MkGet(AcquireItemGetIsTrusted,Py_BuildValue("i",(*I)->IsTrusted())); +MkGet(AcquireItemGetLocal,Py_BuildValue("i",(*I)->Local)); +MkGet(AcquireItemGetStatus,Py_BuildValue("i",(*I)->Status)); + +// Constants +MkGet(AcquireItemGetStatIdle,Py_BuildValue("i", pkgAcquire::Item::StatIdle)); +MkGet(AcquireItemGetStatFetching,Py_BuildValue("i", pkgAcquire::Item::StatFetching)); +MkGet(AcquireItemGetStatDone,Py_BuildValue("i", pkgAcquire::Item::StatDone)); +MkGet(AcquireItemGetStatError,Py_BuildValue("i", pkgAcquire::Item::StatError)); +MkGet(AcquireItemGetStatAuthError,Py_BuildValue("i", pkgAcquire::Item::StatAuthError)); +#undef MkGet + +static PyGetSetDef AcquireItemGetSet[] = { + {"Complete",AcquireItemGetComplete}, + {"DescURI",AcquireItemGetDescURI}, + {"DestFile",AcquireItemGetDestFile}, + {"ErrorText",AcquireItemGetErrorText}, + {"FileSize",AcquireItemGetFileSize}, + {"ID",AcquireItemGetID}, + {"IsTrusted",AcquireItemGetIsTrusted}, + {"Local",AcquireItemGetLocal}, + {"Status",AcquireItemGetStatus}, + {"StatIdle",AcquireItemGetStatIdle}, + {"StatFetching",AcquireItemGetStatFetching}, + {"StatDone",AcquireItemGetStatDone}, + {"StatError",AcquireItemGetStatError}, + {"StatAuthError",AcquireItemGetStatAuthError}, + {} +}; + + static PyObject *AcquireItemRepr(PyObject *Self) { @@ -72,21 +76,39 @@ 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<pkgAcquire::ItemIterator>), // tp_basicsize 0, // tp_itemsize // Methods CppOwnedDealloc<pkgAcquire::ItemIterator>, // tp_dealloc 0, // tp_print - AcquireItemAttr, // tp_getattr + 0, // tp_getattr 0, // tp_setattr 0, // tp_compare AcquireItemRepr, // tp_repr 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping + 0, // tp_as_sequence + 0, // tp_as_mapping 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "AcquireItem Object", // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + 0, // tp_methods + 0, // tp_members + AcquireItemGetSet, // tp_getset }; @@ -123,63 +145,91 @@ static PyMethodDef PkgAcquireMethods[] = {} }; - -static PyObject *AcquireAttr(PyObject *Self,char *Name) +#define fetcher (GetCpp<pkgAcquire*>(Self)) +static PyObject *PkgAcquireGetTotalNeeded(PyObject *Self,void*) { + return Py_BuildValue("d", fetcher->TotalNeeded()); +} +static PyObject *PkgAcquireGetFetchNeeded(PyObject *Self,void*) { + return Py_BuildValue("d", fetcher->FetchNeeded()); +} +static PyObject *PkgAcquireGetPartialPresent(PyObject *Self,void*) { + return Py_BuildValue("d", fetcher->PartialPresent()); +} +#undef fetcher +static PyObject *PkgAcquireGetItems(PyObject *Self,void*) { pkgAcquire *fetcher = GetCpp<pkgAcquire*>(Self); - - if(strcmp("TotalNeeded",Name) == 0) - return Py_BuildValue("d", fetcher->TotalNeeded()); - if(strcmp("FetchNeeded",Name) == 0) - return Py_BuildValue("d", fetcher->FetchNeeded()); - if(strcmp("PartialPresent",Name) == 0) - return Py_BuildValue("d", fetcher->PartialPresent()); - if(strcmp("Items",Name) == 0) + PyObject *List = PyList_New(0); + for (pkgAcquire::ItemIterator I = fetcher->ItemsBegin(); + I != fetcher->ItemsEnd(); I++) { - PyObject *List = PyList_New(0); - for (pkgAcquire::ItemIterator I = fetcher->ItemsBegin(); - I != fetcher->ItemsEnd(); I++) - { - PyObject *Obj; - Obj = CppOwnedPyObject_NEW<pkgAcquire::ItemIterator>(Self,&AcquireItemType,I); - PyList_Append(List,Obj); - Py_DECREF(Obj); - - } - return List; + PyObject *Obj; + Obj = CppOwnedPyObject_NEW<pkgAcquire::ItemIterator>(Self, + &AcquireItemType,I); + PyList_Append(List,Obj); + Py_DECREF(Obj); + } - // some constants - if(strcmp("ResultContinue",Name) == 0) + return List; +} +// some constants +static PyObject *PkgAcquireGetResultContinue(PyObject *Self,void*) { return Py_BuildValue("i", pkgAcquire::Continue); - if(strcmp("ResultFailed",Name) == 0) +} +static PyObject *PkgAcquireGetResultFailed(PyObject *Self,void*) { return Py_BuildValue("i", pkgAcquire::Failed); - if(strcmp("ResultCancelled",Name) == 0) +} +static PyObject *PkgAcquireGetResultCancelled(PyObject *Self,void*) { return Py_BuildValue("i", pkgAcquire::Cancelled); - - return Py_FindMethod(PkgAcquireMethods,Self,Name); } - - +static PyGetSetDef PkgAcquireGetSet[] = { + {"FetchNeeded",PkgAcquireGetFetchNeeded}, + {"Items",PkgAcquireGetItems}, + {"PartialPresent",PkgAcquireGetPartialPresent}, + {"ResultCancelled",PkgAcquireGetResultCancelled}, + {"ResultContinue",PkgAcquireGetResultContinue}, + {"ResultFailed",PkgAcquireGetResultFailed}, + {"TotalNeeded",PkgAcquireGetTotalNeeded}, + {} +}; PyTypeObject PkgAcquireType = { PyObject_HEAD_INIT(&PyType_Type) - 0, // ob_size - "Acquire", // tp_name - sizeof(CppPyObject<pkgAcquire*>), // tp_basicsize + #if PY_MAJOR_VERSION < 3 + 0, // ob_size + #endif + "Acquire", // tp_name + sizeof(CppPyObject<pkgAcquire*>), // tp_basicsize 0, // tp_itemsize // Methods - CppDealloc<pkgAcquire*>, // tp_dealloc + CppDealloc<pkgAcquire*>, // tp_dealloc 0, // tp_print - AcquireAttr, // tp_getattr + 0, // tp_getattr 0, // tp_setattr 0, // tp_compare 0, // tp_repr 0, // tp_as_number 0, // tp_as_sequence - 0, // tp_as_mapping + 0, // tp_as_mapping 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "pkgAcquire Object", // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + PkgAcquireMethods, // tp_methods + 0, // tp_members + PkgAcquireGetSet, // tp_getset }; PyObject *GetAcquire(PyObject *Self,PyObject *Args) @@ -205,34 +255,19 @@ PyObject *GetAcquire(PyObject *Self,PyObject *Args) return FetcherObj; } - - - - -// pkgAcquireFile - -static PyObject *AcquireFileAttr(PyObject *Self,char *Name) -{ - pkgAcqFile *acqFile = GetCpp<pkgAcqFile*>(Self); - - PyErr_SetString(PyExc_AttributeError,Name); - return 0; -} - - - - PyTypeObject PkgAcquireFileType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgAcquireFile", // tp_name sizeof(CppPyObject<pkgAcqFile*>),// tp_basicsize 0, // tp_itemsize // Methods CppDealloc<pkgAcqFile*>, // tp_dealloc 0, // tp_print - AcquireFileAttr, // tp_getattr + 0, // tp_getattr 0, // tp_setattr 0, // tp_compare 0, // tp_repr diff --git a/python/apt_instmodule.cc b/python/apt_instmodule.cc index 48868d86..09e3937e 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)); @@ -153,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 86732781..3beec747 100644 --- a/python/apt_pkgmodule.cc +++ b/python/apt_pkgmodule.cc @@ -173,21 +173,21 @@ 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()); } // Digest of a file - if (PyFile_Check(Obj) != 0) + int Fd = PyObject_AsFileDescriptor(Obj); + if (Fd != -1) { MD5Summation Sum; - int Fd = fileno(PyFile_AsFile(Obj)); struct stat St; if (fstat(Fd,&St) != 0 || Sum.AddFD(Fd,St.st_size) == false) @@ -213,21 +213,21 @@ 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()); } // Digest of a file - if (PyFile_Check(Obj) != 0) + int Fd = PyObject_AsFileDescriptor(Obj); + if (Fd != -1) { SHA1Summation Sum; - int Fd = fileno(PyFile_AsFile(Obj)); struct stat St; if (fstat(Fd,&St) != 0 || Sum.AddFD(Fd,St.st_size) == false) @@ -253,21 +253,21 @@ 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()); } // Digest of a file - if (PyFile_Check(Obj) != 0) + int Fd = PyObject_AsFileDescriptor(Obj); + if (Fd != -1) { SHA256Summation Sum; - int Fd = fileno(PyFile_AsFile(Obj)); struct stat St; if (fstat(Fd,&St) != 0 || Sum.AddFD(Fd,St.st_size) == false) @@ -470,9 +470,70 @@ 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) 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; + if (PyType_Ready(&AcquireItemType) == -1) INIT_ERROR; + if (PyType_Ready(&PackageType) == -1) INIT_ERROR; + if (PyType_Ready(&DescriptionType) == -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 @@ -528,6 +589,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/apt_pkgmodule.h b/python/apt_pkgmodule.h index e047bcd8..424c4788 100644 --- a/python/apt_pkgmodule.h +++ b/python/apt_pkgmodule.h @@ -56,6 +56,7 @@ PyObject *StrCheckDomainList(PyObject *Self,PyObject *Args); extern PyTypeObject PkgCacheType; extern PyTypeObject PkgCacheFileType; extern PyTypeObject PkgListType; +extern PyTypeObject DescriptionType; extern PyTypeObject PackageType; extern PyTypeObject PackageFileType; extern PyTypeObject DependencyType; @@ -71,11 +72,13 @@ extern PyTypeObject PkgProblemResolverType; PyObject *GetPkgProblemResolver(PyObject *Self, PyObject *Args); PyObject *GetPkgActionGroup(PyObject *Self, PyObject *Args); +extern PyTypeObject PkgActionGroupType; // cdrom extern PyTypeObject PkgCdromType; PyObject *GetCdrom(PyObject *Self,PyObject *Args); // acquire +extern PyTypeObject AcquireItemType; extern PyTypeObject PkgAcquireType; extern char *doc_GetPkgAcqFile; PyObject *GetAcquire(PyObject *Self,PyObject *Args); @@ -88,6 +91,7 @@ PyObject *GetPkgManager(PyObject *Self,PyObject *Args); // PkgRecords Stuff extern PyTypeObject PkgRecordsType; +extern PyTypeObject PkgSrcRecordsType; PyObject *GetPkgRecords(PyObject *Self,PyObject *Args); PyObject *GetPkgSrcRecords(PyObject *Self,PyObject *Args); diff --git a/python/cache.cc b/python/cache.cc index 0c59f561..52c5982e 100644 --- a/python/cache.cc +++ b/python/cache.cc @@ -142,40 +142,65 @@ static PyMethodDef PkgCacheMethods[] = {} }; -static PyObject *CacheAttr(PyObject *Self,char *Name) -{ +static PyObject *PkgCacheGetPackages(PyObject *Self, void*) { pkgCache *Cache = GetCpp<pkgCache *>(Self); + return CppOwnedPyObject_NEW<PkgListStruct>(Self,&PkgListType,Cache->PkgBegin()); +} - if (strcmp("Packages",Name) == 0) - return CppOwnedPyObject_NEW<PkgListStruct>(Self,&PkgListType,Cache->PkgBegin()); - else if (strcmp("PackageCount",Name) == 0) - return Py_BuildValue("i",Cache->HeaderP->PackageCount); - else if (strcmp("VersionCount",Name) == 0) - return Py_BuildValue("i",Cache->HeaderP->VersionCount); - else if (strcmp("DependsCount",Name) == 0) - return Py_BuildValue("i",Cache->HeaderP->DependsCount); - else if (strcmp("PackageFileCount",Name) == 0) - return Py_BuildValue("i",Cache->HeaderP->PackageFileCount); - else if (strcmp("VerFileCount",Name) == 0) - return Py_BuildValue("i",Cache->HeaderP->VerFileCount); - else if (strcmp("ProvidesCount",Name) == 0) - return Py_BuildValue("i",Cache->HeaderP->ProvidesCount); - else if (strcmp("FileList",Name) == 0) +static PyObject *PkgCacheGetPackageCount(PyObject *Self, void*) { + pkgCache *Cache = GetCpp<pkgCache *>(Self); + return Py_BuildValue("i",Cache->HeaderP->PackageCount); +} + +static PyObject *PkgCacheGetVersionCount(PyObject *Self, void*) { + pkgCache *Cache = GetCpp<pkgCache *>(Self); + return Py_BuildValue("i",Cache->HeaderP->VersionCount); +} +static PyObject *PkgCacheGetDependsCount(PyObject *Self, void*) { + pkgCache *Cache = GetCpp<pkgCache *>(Self); + return Py_BuildValue("i",Cache->HeaderP->DependsCount); +} + +static PyObject *PkgCacheGetPackageFileCount(PyObject *Self, void*) { + pkgCache *Cache = GetCpp<pkgCache *>(Self); + return Py_BuildValue("i",Cache->HeaderP->PackageFileCount); +} + +static PyObject *PkgCacheGetVerFileCount(PyObject *Self, void*) { + pkgCache *Cache = GetCpp<pkgCache *>(Self); + return Py_BuildValue("i",Cache->HeaderP->VerFileCount); +} + +static PyObject *PkgCacheGetProvidesCount(PyObject *Self, void*) { + pkgCache *Cache = GetCpp<pkgCache *>(Self); + return Py_BuildValue("i",Cache->HeaderP->ProvidesCount); +} + +static PyObject *PkgCacheGetFileList(PyObject *Self, void*) { + pkgCache *Cache = GetCpp<pkgCache *>(Self); + PyObject *List = PyList_New(0); + for (pkgCache::PkgFileIterator I = Cache->FileBegin(); I.end() == false; I++) { - PyObject *List = PyList_New(0); - for (pkgCache::PkgFileIterator I = Cache->FileBegin(); I.end() == false; I++) - { - PyObject *Obj; - Obj = CppOwnedPyObject_NEW<pkgCache::PkgFileIterator>(Self,&PackageFileType,I); - PyList_Append(List,Obj); - Py_DECREF(Obj); - } - return List; + PyObject *Obj; + Obj = CppOwnedPyObject_NEW<pkgCache::PkgFileIterator>(Self,&PackageFileType,I); + PyList_Append(List,Obj); + Py_DECREF(Obj); } - - return Py_FindMethod(PkgCacheMethods,Self,Name); + return List; } +static PyGetSetDef PkgCacheGetSet[] = { + {"DependsCount",PkgCacheGetDependsCount}, + {"FileList",PkgCacheGetFileList}, + {"PackageCount",PkgCacheGetPackageCount}, + {"PackageFileCount",PkgCacheGetPackageFileCount}, + {"Packages",PkgCacheGetPackages}, + {"ProvidesCount",PkgCacheGetProvidesCount}, + {"VerFileCount",PkgCacheGetVerFileCount}, + {"VersionCount",PkgCacheGetVersionCount}, + {} +}; + // Map access, operator [] static PyObject *CacheMapOp(PyObject *Self,PyObject *Arg) { @@ -214,14 +239,16 @@ 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<pkgCache *>), // tp_basicsize 0, // tp_itemsize // Methods PkgCacheFileDealloc, // tp_dealloc 0, // tp_print - CacheAttr, // tp_getattr + 0, // tp_getattr 0, // tp_setattr 0, // tp_compare 0, // tp_repr @@ -229,6 +256,22 @@ PyTypeObject PkgCacheType = 0, // tp_as_sequence &CacheMap, // tp_as_mapping 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT , // tp_flags + "Cache Object", // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + PkgCacheMethods, // tp_methods + 0, // tp_members + PkgCacheGetSet, // tp_getset }; /*}}}*/ // PkgCacheFile Class /*{{{*/ @@ -236,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<pkgCacheFile*>), // tp_basicsize 0, // tp_itemsize @@ -304,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<PkgListStruct>), // tp_basicsize 0, // tp_itemsize @@ -321,65 +368,73 @@ PyTypeObject PkgListType = 0, // tp_hash }; - /*}}}*/ -// Package Class /*{{{*/ -// --------------------------------------------------------------------- -static PyObject *PackageAttr(PyObject *Self,char *Name) +#define MkGet(PyFunc,Ret) static PyObject *PyFunc(PyObject *Self,void*) \ +{ \ + pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(Self); \ + PyObject *Owner = GetOwner<pkgCache::PkgIterator>(Self); \ + return Ret; \ +} + +MkGet(PackageGetName,PyString_FromString(Pkg.Name())); +MkGet(PackageGetSection,Safe_FromString(Pkg.Section())); +MkGet(PackageGetRevDependsList,CppOwnedPyObject_NEW<RDepListStruct>(Owner, + &RDepListType, Pkg.RevDependsList())); +MkGet(PackageGetProvidesList,CreateProvides(Owner,Pkg.ProvidesList())); +MkGet(PackageGetSelectedState,Py_BuildValue("i",Pkg->SelectedState)); +MkGet(PackageGetInstState,Py_BuildValue("i",Pkg->InstState)); +MkGet(PackageGetCurrentState,Py_BuildValue("i",Pkg->CurrentState)); +MkGet(PackageGetID,Py_BuildValue("i",Pkg->ID)); +# +MkGet(PackageGetAuto,Py_BuildValue("i",(Pkg->Flags & pkgCache::Flag::Auto) != 0)); +MkGet(PackageGetEssential,Py_BuildValue("i",(Pkg->Flags & pkgCache::Flag::Essential) != 0)); +MkGet(PackageGetImportant,Py_BuildValue("i",(Pkg->Flags & pkgCache::Flag::Important) != 0)); +#undef MkGet + +static PyObject *PackageGetVersionList(PyObject *Self,void*) { pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(Self); PyObject *Owner = GetOwner<pkgCache::PkgIterator>(Self); - if (strcmp("Name",Name) == 0) - return PyString_FromString(Pkg.Name()); - else if (strcmp("VersionList",Name) == 0) + PyObject *List = PyList_New(0); + for (pkgCache::VerIterator I = Pkg.VersionList(); I.end() == false; I++) { - PyObject *List = PyList_New(0); - for (pkgCache::VerIterator I = Pkg.VersionList(); I.end() == false; I++) - { - PyObject *Obj; - Obj = CppOwnedPyObject_NEW<pkgCache::VerIterator>(Owner,&VersionType,I); - PyList_Append(List,Obj); - Py_DECREF(Obj); - } - return List; + PyObject *Obj; + Obj = CppOwnedPyObject_NEW<pkgCache::VerIterator>(Owner,&VersionType,I); + PyList_Append(List,Obj); + Py_DECREF(Obj); } - else if (strcmp("CurrentVer",Name) == 0) + return List; +} +static PyObject *PackageGetCurrentVer(PyObject *Self,void*) +{ + pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(Self); + PyObject *Owner = GetOwner<pkgCache::PkgIterator>(Self); + if (Pkg->CurrentVer == 0) { - if (Pkg->CurrentVer == 0) - { - Py_INCREF(Py_None); - return Py_None; - } - - return CppOwnedPyObject_NEW<pkgCache::VerIterator>(Owner,&VersionType, - Pkg.CurrentVer()); + Py_INCREF(Py_None); + return Py_None; } - else if (strcmp("Section",Name) == 0) - return Safe_FromString(Pkg.Section()); - else if (strcmp("RevDependsList",Name) == 0) - return CppOwnedPyObject_NEW<RDepListStruct>(Owner,&RDepListType, - Pkg.RevDependsList()); - else if (strcmp("ProvidesList",Name) == 0) - return CreateProvides(Owner,Pkg.ProvidesList()); - else if (strcmp("SelectedState",Name) == 0) - return Py_BuildValue("i",Pkg->SelectedState); - else if (strcmp("InstState",Name) == 0) - return Py_BuildValue("i",Pkg->InstState); - else if (strcmp("CurrentState",Name) == 0) - return Py_BuildValue("i",Pkg->CurrentState); - else if (strcmp("ID",Name) == 0) - return Py_BuildValue("i",Pkg->ID); - else if (strcmp("Auto",Name) == 0) - return Py_BuildValue("i",(Pkg->Flags & pkgCache::Flag::Auto) != 0); - else if (strcmp("Essential",Name) == 0) - return Py_BuildValue("i",(Pkg->Flags & pkgCache::Flag::Essential) != 0); - else if (strcmp("Important",Name) == 0) - return Py_BuildValue("i",(Pkg->Flags & pkgCache::Flag::Important) != 0); - - PyErr_SetString(PyExc_AttributeError,Name); - return 0; + return CppOwnedPyObject_NEW<pkgCache::VerIterator>(Owner,&VersionType, + Pkg.CurrentVer()); } +static PyGetSetDef PackageGetSet[] = { + {"Name",PackageGetName}, + {"Section",PackageGetSection}, + {"RevDependsList",PackageGetRevDependsList}, + {"ProvidesList",PackageGetProvidesList}, + {"SelectedState",PackageGetSelectedState}, + {"InstState",PackageGetInstState}, + {"CurrentState",PackageGetCurrentState}, + {"ID",PackageGetID}, + {"Auto",PackageGetID}, + {"Essential",PackageGetEssential}, + {"Important",PackageGetImportant}, + {"VersionList",PackageGetVersionList}, + {"CurrentVer",PackageGetCurrentVer}, + {} +}; + static PyObject *PackageRepr(PyObject *Self) { pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(Self); @@ -394,14 +449,16 @@ 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<pkgCache::PkgIterator>), // tp_basicsize 0, // tp_itemsize // Methods CppOwnedDealloc<pkgCache::PkgIterator>, // tp_dealloc 0, // tp_print - PackageAttr, // tp_getattr + 0, // tp_getattr 0, // tp_setattr 0, // tp_compare PackageRepr, // tp_repr @@ -409,40 +466,62 @@ PyTypeObject PackageType = 0, // tp_as_sequence 0, // tp_as_mapping 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "Package Object", // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + 0, // tp_methods + 0, // tp_members + PackageGetSet, // tp_getset }; - /*}}}*/ -// Description Class /*{{{*/ -// --------------------------------------------------------------------- -static PyObject *DescriptionAttr(PyObject *Self,char *Name) + +#define Description_MkGet(PyFunc,Ret) static PyObject \ + *PyFunc(PyObject *Self,void*) { \ + pkgCache::DescIterator &Desc = GetCpp<pkgCache::DescIterator>(Self); \ + return Ret; } + +Description_MkGet(DescriptionGetLanguageCode, + PyString_FromString(Desc.LanguageCode())); +Description_MkGet(DescriptionGetMd5,Safe_FromString(Desc.md5())); +#undef Description_MkGet + +static PyObject *DescriptionGetFileList(PyObject *Self,void*) { pkgCache::DescIterator &Desc = GetCpp<pkgCache::DescIterator>(Self); PyObject *Owner = GetOwner<pkgCache::DescIterator>(Self); - if (strcmp("LanguageCode",Name) == 0) - return PyString_FromString(Desc.LanguageCode()); - else if (strcmp("md5",Name) == 0) - return Safe_FromString(Desc.md5()); - else if (strcmp("FileList",Name) == 0) + /* The second value in the tuple is the index of the VF item. If the + user wants to request a lookup then that number will be used. + Maybe later it can become an object. */ + PyObject *List = PyList_New(0); + for (pkgCache::DescFileIterator I = Desc.FileList(); I.end() == false; I++) { - /* The second value in the tuple is the index of the VF item. If the - user wants to request a lookup then that number will be used. - Maybe later it can become an object. */ - PyObject *List = PyList_New(0); - for (pkgCache::DescFileIterator I = Desc.FileList(); I.end() == false; I++) - { - PyObject *DescFile; - PyObject *Obj; - DescFile = CppOwnedPyObject_NEW<pkgCache::PkgFileIterator>(Owner,&PackageFileType,I.File()); - Obj = Py_BuildValue("Nl",DescFile,I.Index()); - PyList_Append(List,Obj); - Py_DECREF(Obj); - } - return List; + PyObject *DescFile; + PyObject *Obj; + DescFile = CppOwnedPyObject_NEW<pkgCache::PkgFileIterator>(Owner,&PackageFileType,I.File()); + Obj = Py_BuildValue("Nl",DescFile,I.Index()); + PyList_Append(List,Obj); + Py_DECREF(Obj); } - PyErr_SetString(PyExc_AttributeError,Name); - return 0; + return List; } +static PyGetSetDef DescriptionGetSet[] = { + {"LanguageCode",DescriptionGetLanguageCode}, + {"md5",DescriptionGetMd5}, + {"FileList",DescriptionGetFileList}, + {} +}; + static PyObject *DescriptionRepr(PyObject *Self) { pkgCache::DescIterator &Desc = GetCpp<pkgCache::DescIterator>(Self); @@ -457,14 +536,16 @@ 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<pkgCache::DescIterator>), // tp_basicsize 0, // tp_itemsize // Methods CppOwnedDealloc<pkgCache::DescIterator>, // tp_dealloc 0, // tp_print - DescriptionAttr, // tp_getattr + 0, // tp_getattr 0, // tp_setattr 0, // tp_compare DescriptionRepr, // tp_repr @@ -472,6 +553,22 @@ PyTypeObject DescriptionType = 0, // tp_as_sequence 0, // tp_as_mapping 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "AcquireItem Object", // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + 0, // tp_methods + 0, // tp_members + DescriptionGetSet, // tp_getset }; /*}}}*/ // Version Class /*{{{*/ @@ -502,7 +599,7 @@ static PyObject *MakeDepends(PyObject *Owner,pkgCache::VerIterator &Ver, { "", "Depends","PreDepends","Suggests", "Recommends","Conflicts","Replaces", - "Obsoletes" + "Obsoletes", "Breaks" }; PyObject *Dep = PyString_FromString(Types[Start->Type]); LastDepType = Start->Type; @@ -643,7 +740,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<pkgCache::VerIterator>), // tp_basicsize 0, // tp_itemsize @@ -718,7 +817,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<pkgCache::PkgFileIterator>), // tp_basicsize 0, // tp_itemsize @@ -799,53 +900,104 @@ static PyMethodDef DependencyMethods[] = // Dependency Class /*{{{*/ // --------------------------------------------------------------------- -static PyObject *DependencyAttr(PyObject *Self,char *Name) +static PyObject *DependencyGetTargetVer(PyObject *Self,void*) +{ + pkgCache::DepIterator &Dep = GetCpp<pkgCache::DepIterator>(Self); + if (Dep->Version == 0) + return PyString_FromString(""); + return PyString_FromString(Dep.TargetVer()); +} + +static PyObject *DependencyGetTargetPkg(PyObject *Self,void*) { pkgCache::DepIterator &Dep = GetCpp<pkgCache::DepIterator>(Self); PyObject *Owner = GetOwner<pkgCache::DepIterator>(Self); + return CppOwnedPyObject_NEW<pkgCache::PkgIterator>(Owner,&PackageType, + Dep.TargetPkg()); +} - if (strcmp("TargetVer",Name) == 0) - { - if (Dep->Version == 0) - return PyString_FromString(""); - return PyString_FromString(Dep.TargetVer()); - } - else if (strcmp("TargetPkg",Name) == 0) - return CppOwnedPyObject_NEW<pkgCache::PkgIterator>(Owner,&PackageType, - Dep.TargetPkg()); - else if (strcmp("ParentVer",Name) == 0) - return CppOwnedPyObject_NEW<pkgCache::VerIterator>(Owner,&VersionType, - Dep.ParentVer()); - else if (strcmp("ParentPkg",Name) == 0) - return CppOwnedPyObject_NEW<pkgCache::PkgIterator>(Owner,&PackageType, Dep.ParentPkg()); - else if (strcmp("CompType",Name) == 0) - return PyString_FromString(Dep.CompType()); - else if (strcmp("DepType",Name) == 0) - return PyString_FromString(Dep.DepType()); - else if (strcmp("ID",Name) == 0) - return Py_BuildValue("i",Dep->ID); +static PyObject *DependencyGetParentVer(PyObject *Self,void*) +{ + pkgCache::DepIterator &Dep = GetCpp<pkgCache::DepIterator>(Self); + PyObject *Owner = GetOwner<pkgCache::DepIterator>(Self); + return CppOwnedPyObject_NEW<pkgCache::VerIterator>(Owner,&VersionType, + Dep.ParentVer()); +} - return Py_FindMethod(DependencyMethods,Self,Name); +static PyObject *DependencyGetParentPkg(PyObject *Self,void*) +{ + pkgCache::DepIterator &Dep = GetCpp<pkgCache::DepIterator>(Self); + PyObject *Owner = GetOwner<pkgCache::DepIterator>(Self); + return CppOwnedPyObject_NEW<pkgCache::PkgIterator>(Owner,&PackageType, + Dep.ParentPkg()); } +static PyObject *DependencyGetCompType(PyObject *Self,void*) +{ + pkgCache::DepIterator &Dep = GetCpp<pkgCache::DepIterator>(Self); + return PyString_FromString(Dep.CompType()); +} + +static PyObject *DependencyGetDepType(PyObject *Self,void*) +{ + pkgCache::DepIterator &Dep = GetCpp<pkgCache::DepIterator>(Self); + return PyString_FromString(Dep.DepType()); +} + +static PyObject *DependencyGetID(PyObject *Self,void*) +{ + pkgCache::DepIterator &Dep = GetCpp<pkgCache::DepIterator>(Self); + return Py_BuildValue("i",Dep->ID); +} + +static PyGetSetDef DependencyGetSet[] = { + {"CompType",DependencyGetCompType}, + {"DepType",DependencyGetDepType}, + {"ID",DependencyGetID}, + {"ParentPkg",DependencyGetParentPkg}, + {"ParentVer",DependencyGetParentVer}, + {"TargetPkg",DependencyGetTargetPkg}, + {"TargetVer",DependencyGetTargetVer}, + {} +}; + + PyTypeObject DependencyType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgCache::DepIterator", // tp_name sizeof(CppOwnedPyObject<pkgCache::DepIterator>), // tp_basicsize 0, // tp_itemsize // Methods CppOwnedDealloc<pkgCache::DepIterator>, // tp_dealloc 0, // tp_print - DependencyAttr, // tp_getattr + 0, // tp_getattr 0, // tp_setattr 0, // tp_compare - DependencyRepr, // tp_repr + DependencyRepr, // tp_repr 0, // tp_as_number 0, // tp_as_sequence 0, // tp_as_mapping 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "Dependency Object", // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + DependencyMethods, // tp_methods + 0, // tp_members + DependencyGetSet, // tp_getset }; /*}}}*/ @@ -901,7 +1053,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<RDepListStruct>), // tp_basicsize 0, // tp_itemsize @@ -951,7 +1105,7 @@ PyObject *TmpGetCache(PyObject *Self,PyObject *Args) progress.setCallbackInst(pyCallbackInst); if (Cache->Open(progress,false) == false) return HandleErrors(); - } + } else { OpTextProgress Prog; if (Cache->Open(Prog,false) == false) diff --git a/python/cdrom.cc b/python/cdrom.cc index 0831548e..b3a38438 100644 --- a/python/cdrom.cc +++ b/python/cdrom.cc @@ -64,27 +64,19 @@ static PyMethodDef PkgCdromMethods[] = }; -static PyObject *CdromAttr(PyObject *Self,char *Name) -{ - PkgCdromStruct &Struct = GetCpp<PkgCdromStruct>(Self); - - return Py_FindMethod(PkgCdromMethods,Self,Name); -} - - - - PyTypeObject PkgCdromType = { PyObject_HEAD_INIT(&PyType_Type) - 0, // ob_size - "Cdrom", // tp_name + #if PY_MAJOR_VERSION < 3 + 0, // ob_size + #endif + "Cdrom", // tp_name sizeof(CppOwnedPyObject<PkgCdromStruct>), // tp_basicsize 0, // tp_itemsize // Methods - CppOwnedDealloc<PkgCdromStruct>, // tp_dealloc + CppOwnedDealloc<PkgCdromStruct>, // tp_dealloc 0, // tp_print - CdromAttr, // tp_getattr + 0, // tp_getattr 0, // tp_setattr 0, // tp_compare 0, // tp_repr @@ -92,6 +84,20 @@ PyTypeObject PkgCdromType = 0, // tp_as_sequence 0, // tp_as_mapping 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "Cdrom Object", // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + PkgCdromMethods, // tp_methods }; PyObject *GetCdrom(PyObject *Self,PyObject *Args) diff --git a/python/configuration.cc b/python/configuration.cc index 21f70bc1..eaac48ec 100644 --- a/python/configuration.cc +++ b/python/configuration.cc @@ -128,6 +128,11 @@ static PyObject *CnfExists(PyObject *Self,PyObject *Args) return Py_BuildValue("i",(int)GetSelf(Self).Exists(Name)); } +static int CnfContains(PyObject *Self,PyObject *Arg) +{ + return (int)GetSelf(Self).Exists(PyString_AsString(Arg)); +} + static char *doc_Clear = "Clear(Name) -> None"; static PyObject *CnfClear(PyObject *Self,PyObject *Args) { @@ -470,73 +475,114 @@ static PyMethodDef CnfMethods[] = {} }; -// CnfGetAttr - Get an attribute - variable/method /*{{{*/ -// --------------------------------------------------------------------- -/* */ -static PyObject *CnfGetAttr(PyObject *Self,char *Name) -{ - return Py_FindMethod(CnfMethods,Self,Name); -} - // Type for a Normal Configuration object +static PySequenceMethods ConfigurationSeq = {0,0,0,0,0,0,0,CnfContains,0,0}; static PyMappingMethods ConfigurationMap = {0,CnfMap,CnfMapSet}; PyTypeObject ConfigurationType = { PyObject_HEAD_INIT(&PyType_Type) - 0, // ob_size + #if PY_MAJOR_VERSION < 3 + 0, // ob_size + #endif "Configuration", // tp_name sizeof(CppPyObject<Configuration>), // tp_basicsize 0, // tp_itemsize // Methods CppDealloc<Configuration>, // tp_dealloc 0, // tp_print - CnfGetAttr, // tp_getattr + 0, // tp_getattr 0, // tp_setattr 0, // tp_compare 0, // tp_repr 0, // tp_as_number - 0, // tp_as_sequence + &ConfigurationSeq, // tp_as_sequence &ConfigurationMap, // tp_as_mapping 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "Configuration Object", // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + CnfMethods, // tp_methods }; PyTypeObject ConfigurationPtrType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "ConfigurationPtr", // tp_name sizeof(CppPyObject<Configuration *>), // tp_basicsize 0, // tp_itemsize // Methods (destructor)PyObject_Free, // tp_dealloc 0, // tp_print - CnfGetAttr, // tp_getattr + 0, // tp_getattr 0, // tp_setattr 0, // tp_compare 0, // tp_repr 0, // tp_as_number - 0, // tp_as_sequence + &ConfigurationSeq, // tp_as_sequence &ConfigurationMap, // tp_as_mapping 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "ConfigurationPtr Object", // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + CnfMethods, // tp_methods }; 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 // Methods CnfSubFree, // tp_dealloc 0, // tp_print - CnfGetAttr, // tp_getattr + 0, // tp_getattr 0, // tp_setattr 0, // tp_compare 0, // tp_repr 0, // tp_as_number - 0, // tp_as_sequence + &ConfigurationSeq, // tp_as_sequence &ConfigurationMap, // tp_as_mapping 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "ConfigurationSub Object", // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + CnfMethods, // tp_methods }; diff --git a/python/depcache.cc b/python/depcache.cc index 0e83c956..1c9eeff7 100644 --- a/python/depcache.cc +++ b/python/depcache.cc @@ -560,50 +560,73 @@ static PyMethodDef PkgDepCacheMethods[] = {} }; - -static PyObject *DepCacheAttr(PyObject *Self,char *Name) -{ - pkgDepCache *depcache = GetCpp<pkgDepCache *>(Self); - - // size querries - if(strcmp("KeepCount",Name) == 0) - return Py_BuildValue("l", depcache->KeepCount()); - else if(strcmp("InstCount",Name) == 0) - return Py_BuildValue("l", depcache->InstCount()); - else if(strcmp("DelCount",Name) == 0) - return Py_BuildValue("l", depcache->DelCount()); - else if(strcmp("BrokenCount",Name) == 0) - return Py_BuildValue("l", depcache->BrokenCount()); - else if(strcmp("UsrSize",Name) == 0) - return Py_BuildValue("d", depcache->UsrSize()); - else if(strcmp("DebSize",Name) == 0) - return Py_BuildValue("d", depcache->DebSize()); - - - return Py_FindMethod(PkgDepCacheMethods,Self,Name); +#define depcache (GetCpp<pkgDepCache *>(Self)) +static PyObject *PkgDepCacheGetKeepCount(PyObject *Self,void*) { + return Py_BuildValue("l", depcache->KeepCount()); } +static PyObject *PkgDepCacheGetInstCount(PyObject *Self,void*) { + return Py_BuildValue("l", depcache->InstCount()); +} +static PyObject *PkgDepCacheGetDelCount(PyObject *Self,void*) { + return Py_BuildValue("l", depcache->DelCount()); +} +static PyObject *PkgDepCacheGetBrokenCount(PyObject *Self,void*) { + return Py_BuildValue("l", depcache->BrokenCount()); +} +static PyObject *PkgDepCacheGetUsrSize(PyObject *Self,void*) { + return Py_BuildValue("d", depcache->UsrSize()); +} +static PyObject *PkgDepCacheGetDebSize(PyObject *Self,void*) { + return Py_BuildValue("d", depcache->DebSize()); +} +#undef depcache - - +static PyGetSetDef PkgDepCacheGetSet[] = { + {"BrokenCount",PkgDepCacheGetBrokenCount}, + {"DebSize",PkgDepCacheGetDebSize}, + {"DelCount",PkgDepCacheGetDelCount}, + {"InstCount",PkgDepCacheGetInstCount}, + {"KeepCount",PkgDepCacheGetKeepCount}, + {"UsrSize",PkgDepCacheGetUsrSize}, + {} +}; PyTypeObject PkgDepCacheType = { PyObject_HEAD_INIT(&PyType_Type) - 0, // ob_size - "pkgDepCache", // tp_name + #if PY_MAJOR_VERSION < 3 + 0, // ob_size + #endif + "pkgDepCache", // tp_name sizeof(CppOwnedPyObject<pkgDepCache *>), // tp_basicsize 0, // tp_itemsize // Methods - CppOwnedDealloc<pkgDepCache *>, // tp_dealloc + CppOwnedDealloc<pkgDepCache *>, // tp_dealloc 0, // tp_print - DepCacheAttr, // tp_getattr + 0, // tp_getattr 0, // tp_setattr 0, // tp_compare 0, // tp_repr 0, // tp_as_number 0, // tp_as_sequence - 0, // tp_as_mapping + 0, // tp_as_mapping 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "pkgDepCache Object", // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + PkgDepCacheMethods, // tp_methods + 0, // tp_members + PkgDepCacheGetSet, // tp_getset }; @@ -749,26 +772,19 @@ static PyMethodDef PkgProblemResolverMethods[] = {} }; - -static PyObject *ProblemResolverAttr(PyObject *Self,char *Name) -{ - pkgProblemResolver *fixer = GetCpp<pkgProblemResolver *>(Self); - - return Py_FindMethod(PkgProblemResolverMethods,Self,Name); -} - - PyTypeObject PkgProblemResolverType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgProblemResolver", // tp_name sizeof(CppOwnedPyObject<pkgProblemResolver *>), // tp_basicsize 0, // tp_itemsize // Methods CppOwnedDealloc<pkgProblemResolver *>, // tp_dealloc 0, // tp_print - ProblemResolverAttr, // tp_getattr + 0, // tp_getattr 0, // tp_setattr 0, // tp_compare 0, // tp_repr @@ -776,6 +792,20 @@ PyTypeObject PkgProblemResolverType = 0, // tp_as_sequence 0, // tp_as_mapping 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "ProblemResolver Object", // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + PkgProblemResolverMethods, // tp_methods }; /*}}}*/ @@ -800,26 +830,19 @@ static PyMethodDef PkgActionGroupMethods[] = {} }; - -static PyObject *ActionGroupAttr(PyObject *Self,char *Name) -{ - pkgDepCache::ActionGroup *ag = GetCpp<pkgDepCache::ActionGroup*>(Self); - - return Py_FindMethod(PkgActionGroupMethods,Self,Name); -} - - PyTypeObject PkgActionGroupType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgActionGroup", // tp_name sizeof(CppOwnedPyObject<pkgDepCache::ActionGroup*>), // tp_basicsize 0, // tp_itemsize // Methods CppOwnedDealloc<pkgDepCache::ActionGroup*>, // tp_dealloc 0, // tp_print - ActionGroupAttr, // tp_getattr + 0, // tp_getattr 0, // tp_setattr 0, // tp_compare 0, // tp_repr @@ -827,6 +850,20 @@ PyTypeObject PkgActionGroupType = 0, // tp_as_sequence 0, // tp_as_mapping 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "ActionGroup Object", // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + PkgActionGroupMethods, // tp_methods }; PyObject *GetPkgActionGroup(PyObject *Self,PyObject *Args) 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 <class T> 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 107eae27..bb40cdd0 100644 --- a/python/indexfile.cc +++ b/python/indexfile.cc @@ -32,25 +32,26 @@ static PyMethodDef PackageIndexFileMethods[] = {} }; - -static PyObject *PackageIndexFileAttr(PyObject *Self,char *Name) -{ - pkgIndexFile *File = GetCpp<pkgIndexFile*>(Self); - if (strcmp("Label",Name) == 0) - return Safe_FromString(File->GetType()->Label); - else if (strcmp("Describe",Name) == 0) - return Safe_FromString(File->Describe().c_str()); - else if (strcmp("Exists",Name) == 0) - return Py_BuildValue("i",(File->Exists())); - else if (strcmp("HasPackages",Name) == 0) - return Py_BuildValue("i",(File->HasPackages())); - else if (strcmp("Size",Name) == 0) - return Py_BuildValue("i",(File->Size())); - else if (strcmp("IsTrusted",Name) == 0) - return Py_BuildValue("i",(File->IsTrusted())); - - return Py_FindMethod(PackageIndexFileMethods,Self,Name); +#define File (GetCpp<pkgIndexFile*>(Self)) +static PyObject *PackageIndexFileGetLabel(PyObject *Self,void*) { + return Safe_FromString(File->GetType()->Label); +} +static PyObject *PackageIndexFileGetDescribe(PyObject *Self,void*) { + return Safe_FromString(File->Describe().c_str()); +} +static PyObject *PackageIndexFileGetExists(PyObject *Self,void*) { + return Py_BuildValue("i",(File->Exists())); } +static PyObject *PackageIndexFileGetHasPackages(PyObject *Self,void*) { + return Py_BuildValue("i",(File->HasPackages())); +} +static PyObject *PackageIndexFileGetSize(PyObject *Self,void*) { + return Py_BuildValue("i",(File->Size())); +} +static PyObject *PackageIndexFileGetIsTrusted(PyObject *Self,void*) { + return Py_BuildValue("i",(File->IsTrusted())); +} +#undef File static PyObject *PackageIndexFileRepr(PyObject *Self) { @@ -67,24 +68,52 @@ static PyObject *PackageIndexFileRepr(PyObject *Self) return PyString_FromString(S); } +static PyGetSetDef PackageIndexFileGetSet[] = { + {"Describe",PackageIndexFileGetDescribe}, + {"Exists",PackageIndexFileGetExists}, + {"HasPackages",PackageIndexFileGetHasPackages}, + {"IsTrusted",PackageIndexFileGetIsTrusted}, + {"Label",PackageIndexFileGetLabel}, + {"Size",PackageIndexFileGetSize}, + {} +}; + PyTypeObject PackageIndexFileType = { PyObject_HEAD_INIT(&PyType_Type) - 0, // ob_size - "pkgIndexFile", // tp_name + #if PY_MAJOR_VERSION < 3 + 0, // ob_size + #endif + "pkgIndexFile", // tp_name sizeof(CppOwnedPyObject<pkgIndexFile*>), // tp_basicsize 0, // tp_itemsize // Methods - CppOwnedDealloc<pkgIndexFile*>, // tp_dealloc + CppOwnedDealloc<pkgIndexFile*>, // tp_dealloc 0, // tp_print - PackageIndexFileAttr, // tp_getattr + 0, // tp_getattr 0, // tp_setattr 0, // tp_compare - PackageIndexFileRepr, // tp_repr + PackageIndexFileRepr, // tp_repr 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping + 0, // tp_as_sequence + 0, // tp_as_mapping 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "pkgIndexFile Object", // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + PackageIndexFileMethods, // tp_methods + 0, // tp_members + PackageIndexFileGetSet, // tp_getset }; 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<metaIndex*>), // tp_basicsize 0, // tp_itemsize diff --git a/python/pkgmanager.cc b/python/pkgmanager.cc index 0eaa28cd..8f56cddc 100644 --- a/python/pkgmanager.cc +++ b/python/pkgmanager.cc @@ -75,41 +75,59 @@ static PyMethodDef PkgManagerMethods[] = }; -static PyObject *PkgManagerAttr(PyObject *Self,char *Name) -{ - //PkgManagerStruct &Struct = GetCpp<PkgManagerStruct>(Self); - pkgPackageManager *pm = GetCpp<pkgPackageManager*>(Self); - - // some constants - if(strcmp("ResultCompleted",Name) == 0) - return Py_BuildValue("i", pkgPackageManager::Completed); - if(strcmp("ResultFailed",Name) == 0) - return Py_BuildValue("i", pkgPackageManager::Failed); - if(strcmp("ResultIncomplete",Name) == 0) - return Py_BuildValue("i", pkgPackageManager::Incomplete); - - return Py_FindMethod(PkgManagerMethods,Self,Name); +static PyObject *PkgManagerGetResultCompleted(PyObject *Self,void*) { + return Py_BuildValue("i", pkgPackageManager::Completed); +} +static PyObject *PkgManagerGetResultFailed(PyObject *Self,void*) { + return Py_BuildValue("i", pkgPackageManager::Failed); +} +static PyObject *PkgManagerGetResultIncomplete(PyObject *Self,void*) { + return Py_BuildValue("i", pkgPackageManager::Incomplete); } +static PyGetSetDef PkgManagerGetSet[] = { + {"ResultCompleted",PkgManagerGetResultCompleted}, + {"ResultFailed",PkgManagerGetResultFailed}, + {"ResultIncomplete",PkgManagerGetResultIncomplete}, + {} +}; PyTypeObject PkgManagerType = { PyObject_HEAD_INIT(&PyType_Type) - 0, // ob_size + #if PY_MAJOR_VERSION < 3 + 0, // ob_size + #endif "PackageManager", // tp_name sizeof(CppPyObject<pkgPackageManager*>), // tp_basicsize 0, // tp_itemsize // Methods - CppDealloc<pkgPackageManager*>, // tp_dealloc + CppDealloc<pkgPackageManager*>, // tp_dealloc 0, // tp_print - PkgManagerAttr, // tp_getattr + 0, // tp_getattr 0, // tp_setattr 0, // tp_compare 0, // tp_repr 0, // tp_as_number 0, // tp_as_sequence - 0, // tp_as_mapping + 0, // tp_as_mapping 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "PackageManager Object", // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + PkgManagerMethods, // tp_methods + 0, // tp_members + PkgManagerGetSet, // tp_getset }; #include <apt-pkg/init.h> diff --git a/python/pkgrecords.cc b/python/pkgrecords.cc index 5359ee6f..978de6b7 100644 --- a/python/pkgrecords.cc +++ b/python/pkgrecords.cc @@ -53,55 +53,98 @@ static PyMethodDef PkgRecordsMethods[] = {} }; -static PyObject *PkgRecordsAttr(PyObject *Self,char *Name) -{ +/** + * Get the PkgSrcRecordsStruct from a PyObject. If no package has been looked + * up, set an AttributeError using the given name. + */ +static inline PkgRecordsStruct &GetStruct(PyObject *Self,char *name) { PkgRecordsStruct &Struct = GetCpp<PkgRecordsStruct>(Self); + if (Struct.Last == 0) + PyErr_SetString(PyExc_AttributeError,name); + return Struct; +} - if (Struct.Last != 0) - { - if (strcmp("FileName",Name) == 0) - return CppPyString(Struct.Last->FileName()); - else if (strcmp("MD5Hash",Name) == 0) - return CppPyString(Struct.Last->MD5Hash()); - else if (strcmp("SHA1Hash",Name) == 0) - return CppPyString(Struct.Last->SHA1Hash()); - else if (strcmp("SHA256Hash",Name) == 0) - return CppPyString(Struct.Last->SHA256Hash()); - else if (strcmp("SourcePkg",Name) == 0) - return CppPyString(Struct.Last->SourcePkg()); - else if (strcmp("SourceVer",Name) == 0) - return CppPyString(Struct.Last->SourceVer()); - else if (strcmp("Maintainer",Name) == 0) - return CppPyString(Struct.Last->Maintainer()); - else if (strcmp("ShortDesc",Name) == 0) - return CppPyString(Struct.Last->ShortDesc()); - else if (strcmp("LongDesc",Name) == 0) - return CppPyString(Struct.Last->LongDesc()); - else if (strcmp("Name",Name) == 0) - return CppPyString(Struct.Last->Name()); - else if (strcmp("Homepage",Name) == 0) - return CppPyString(Struct.Last->Homepage()); - else if (strcmp("Record", Name) == 0) - { - const char *start, *stop; - Struct.Last->GetRec(start, stop); - return PyString_FromStringAndSize(start,stop-start); - } - } - - return Py_FindMethod(PkgRecordsMethods,Self,Name); +static PyObject *PkgRecordsGetFileName(PyObject *Self,void*) { + PkgRecordsStruct &Struct = GetStruct(Self,"FileName"); + return (Struct.Last != 0) ? CppPyString(Struct.Last->FileName()) : 0; +} +static PyObject *PkgRecordsGetMD5Hash(PyObject *Self,void*) { + PkgRecordsStruct &Struct = GetStruct(Self,"MD5Hash"); + return (Struct.Last != 0) ? CppPyString(Struct.Last->MD5Hash()) : 0; +} +static PyObject *PkgRecordsGetSHA1Hash(PyObject *Self,void*) { + PkgRecordsStruct &Struct = GetStruct(Self,"SHA1Hash"); + return (Struct.Last != 0) ? CppPyString(Struct.Last->SHA1Hash()) : 0; +} +static PyObject *PkgRecordsGetSHA256Hash(PyObject *Self,void*) { + PkgRecordsStruct &Struct = GetStruct(Self,"SHA256Hash"); + return (Struct.Last != 0) ? CppPyString(Struct.Last->SHA256Hash()) : 0; +} +static PyObject *PkgRecordsGetSourcePkg(PyObject *Self,void*) { + PkgRecordsStruct &Struct = GetStruct(Self,"SourcePkg"); + return (Struct.Last != 0) ? CppPyString(Struct.Last->SourcePkg()) : 0; +} +static PyObject *PkgRecordsGetSourceVer(PyObject *Self,void*) { + PkgRecordsStruct &Struct = GetStruct(Self,"SourceVer"); + return (Struct.Last != 0) ? CppPyString(Struct.Last->SourceVer()) : 0; } +static PyObject *PkgRecordsGetMaintainer(PyObject *Self,void*) { + PkgRecordsStruct &Struct = GetStruct(Self,"Maintainer"); + return (Struct.Last != 0) ? CppPyString(Struct.Last->Maintainer()) : 0; +} +static PyObject *PkgRecordsGetShortDesc(PyObject *Self,void*) { + PkgRecordsStruct &Struct = GetStruct(Self,"ShortDesc"); + return (Struct.Last != 0) ? CppPyString(Struct.Last->ShortDesc()) : 0; +} +static PyObject *PkgRecordsGetLongDesc(PyObject *Self,void*) { + PkgRecordsStruct &Struct = GetStruct(Self,"LongDesc"); + return (Struct.Last != 0) ? CppPyString(Struct.Last->LongDesc()) : 0; +} +static PyObject *PkgRecordsGetName(PyObject *Self,void*) { + PkgRecordsStruct &Struct = GetStruct(Self,"Name"); + return (Struct.Last != 0) ? CppPyString(Struct.Last->Name()) : 0; +} +static PyObject *PkgRecordsGetHomepage(PyObject *Self,void*) { + PkgRecordsStruct &Struct = GetStruct(Self,"Homepage"); + return (Struct.Last != 0) ? CppPyString(Struct.Last->Homepage()) : 0; +} +static PyObject *PkgRecordsGetRecord(PyObject *Self,void*) { + const char *start, *stop; + PkgRecordsStruct &Struct = GetStruct(Self,"Record"); + if (Struct.Last == 0) + return 0; + Struct.Last->GetRec(start, stop); + return PyString_FromStringAndSize(start,stop-start); +} +static PyGetSetDef PkgRecordsGetSet[] = { + {"FileName",PkgRecordsGetFileName}, + {"Homepage",PkgRecordsGetHomepage}, + {"LongDesc",PkgRecordsGetLongDesc}, + {"MD5Hash",PkgRecordsGetMD5Hash}, + {"Maintainer",PkgRecordsGetMaintainer}, + {"Name",PkgRecordsGetName}, + {"Record",PkgRecordsGetRecord}, + {"SHA1Hash",PkgRecordsGetSHA1Hash}, + {"SHA256Hash",PkgRecordsGetSHA256Hash}, + {"ShortDesc",PkgRecordsGetShortDesc}, + {"SourcePkg",PkgRecordsGetSourcePkg}, + {"SourceVer",PkgRecordsGetSourceVer}, + {} +}; + PyTypeObject PkgRecordsType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgRecords", // tp_name sizeof(CppOwnedPyObject<PkgRecordsStruct>), // tp_basicsize 0, // tp_itemsize // Methods CppOwnedDealloc<PkgRecordsStruct>, // tp_dealloc 0, // tp_print - PkgRecordsAttr, // tp_getattr + 0, // tp_getattr 0, // tp_setattr 0, // tp_compare 0, // tp_repr @@ -109,6 +152,22 @@ PyTypeObject PkgRecordsType = 0, // tp_as_sequence 0, // tp_as_mapping 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "Records Object", // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + PkgRecordsMethods, // tp_methods + 0, // tp_members + PkgRecordsGetSet, // tp_getset }; /*}}}*/ diff --git a/python/pkgsrcrecords.cc b/python/pkgsrcrecords.cc index f7f5d7a2..97667d7a 100644 --- a/python/pkgsrcrecords.cc +++ b/python/pkgsrcrecords.cc @@ -75,82 +75,124 @@ static PyMethodDef PkgSrcRecordsMethods[] = {} }; -static PyObject *PkgSrcRecordsAttr(PyObject *Self,char *Name) -{ +/** + * Get the PkgSrcRecordsStruct from a PyObject. If no package has been looked + * up, set an AttributeError using the given name. + */ +static inline PkgSrcRecordsStruct &GetStruct(PyObject *Self,char *name) { PkgSrcRecordsStruct &Struct = GetCpp<PkgSrcRecordsStruct>(Self); + if (Struct.Last == 0) + PyErr_SetString(PyExc_AttributeError,name); + return Struct; +} + +static PyObject *PkgSrcRecordsGetPackage(PyObject *Self,void*) { + PkgSrcRecordsStruct &Struct = GetStruct(Self,"Package"); + return (Struct.Last != 0) ? CppPyString(Struct.Last->Package()) : 0; +} +static PyObject *PkgSrcRecordsGetVersion(PyObject *Self,void*) { + PkgSrcRecordsStruct &Struct = GetStruct(Self,"Version"); + return (Struct.Last != 0) ? CppPyString(Struct.Last->Version()) : 0; +} +static PyObject *PkgSrcRecordsGetMaintainer(PyObject *Self,void*) { + PkgSrcRecordsStruct &Struct = GetStruct(Self,"Maintainer"); + return (Struct.Last != 0) ? CppPyString(Struct.Last->Maintainer()) : 0; +} +static PyObject *PkgSrcRecordsGetSection(PyObject *Self,void*) { + PkgSrcRecordsStruct &Struct = GetStruct(Self,"Section"); + return (Struct.Last != 0) ? CppPyString(Struct.Last->Section()) : 0; +} +static PyObject *PkgSrcRecordsGetRecord(PyObject *Self,void*) { + PkgSrcRecordsStruct &Struct = GetStruct(Self,"Record"); + return (Struct.Last != 0) ? CppPyString(Struct.Last->AsStr()) : 0; +} +static PyObject *PkgSrcRecordsGetBinaries(PyObject *Self,void*) { + PkgSrcRecordsStruct &Struct = GetStruct(Self,"Binaries"); + if (Struct.Last == 0) + return 0; + PyObject *List = PyList_New(0); + for(const char **b = Struct.Last->Binaries(); *b != 0; ++b) + PyList_Append(List, CppPyString(*b)); + return List; // todo +} +static PyObject *PkgSrcRecordsGetIndex(PyObject *Self,void*) { + PkgSrcRecordsStruct &Struct = GetStruct(Self,"Index"); + if (Struct.Last == 0) + return 0; + const pkgIndexFile &tmp = Struct.Last->Index(); + return CppOwnedPyObject_NEW<pkgIndexFile*>(Self,&PackageIndexFileType, + (pkgIndexFile*)&tmp); +} - if (Struct.Last != 0) - { - if (strcmp("Package",Name) == 0) - return CppPyString(Struct.Last->Package()); - else if (strcmp("Version",Name) == 0) - return CppPyString(Struct.Last->Version()); - else if (strcmp("Maintainer",Name) == 0) - return CppPyString(Struct.Last->Maintainer()); - else if (strcmp("Section",Name) == 0) - return CppPyString(Struct.Last->Section()); - else if (strcmp("Record",Name) == 0) - return CppPyString(Struct.Last->AsStr()); - else if (strcmp("Binaries",Name) == 0) { - PyObject *List = PyList_New(0); - - for(const char **b = Struct.Last->Binaries(); - *b != 0; - ++b) - PyList_Append(List, CppPyString(*b)); - return List; // todo - } else if (strcmp("Index",Name) == 0) { - const pkgIndexFile &tmp = Struct.Last->Index(); - return CppOwnedPyObject_NEW<pkgIndexFile*>(Self,&PackageIndexFileType, (pkgIndexFile*)&tmp); - } else if (strcmp("Files",Name) == 0) { - PyObject *List = PyList_New(0); - - vector<pkgSrcRecords::File> f; - if(!Struct.Last->Files(f)) - return NULL; // error - - PyObject *v; - for(unsigned int i=0;i<f.size();i++) { - v = Py_BuildValue("(siss)", - f[i].MD5Hash.c_str(), - f[i].Size, - f[i].Path.c_str(), - f[i].Type.c_str()); - PyList_Append(List, v); - Py_DECREF(v); - } - return List; - } else if (strcmp("BuildDepends",Name) == 0) { - PyObject *List = PyList_New(0); - - vector<pkgSrcRecords::Parser::BuildDepRec> bd; - if(!Struct.Last->BuildDepends(bd, false /* arch-only*/)) - return NULL; // error - - PyObject *v; - for(unsigned int i=0;i<bd.size();i++) { - v = Py_BuildValue("(ssii)", bd[i].Package.c_str(), - bd[i].Version.c_str(), bd[i].Op, bd[i].Type); - PyList_Append(List, v); - Py_DECREF(v); - } - return List; - } +static PyObject *PkgSrcRecordsGetFiles(PyObject *Self,void*) { + PkgSrcRecordsStruct &Struct = GetStruct(Self,"Files"); + if (Struct.Last == 0) + return 0; + PyObject *List = PyList_New(0); + + vector<pkgSrcRecords::File> f; + if(!Struct.Last->Files(f)) + return NULL; // error + + PyObject *v; + for(unsigned int i=0;i<f.size();i++) { + v = Py_BuildValue("(siss)", + f[i].MD5Hash.c_str(), + f[i].Size, + f[i].Path.c_str(), + f[i].Type.c_str()); + PyList_Append(List, v); + Py_DECREF(v); } + return List; +} - return Py_FindMethod(PkgSrcRecordsMethods,Self,Name); +static PyObject *PkgSrcRecordsGetBuildDepends(PyObject *Self,void*) { + PkgSrcRecordsStruct &Struct = GetStruct(Self,"BuildDepends"); + if (Struct.Last == 0) + return 0; + PyObject *List = PyList_New(0); + + vector<pkgSrcRecords::Parser::BuildDepRec> bd; + if(!Struct.Last->BuildDepends(bd, false /* arch-only*/)) + return NULL; // error + + PyObject *v; + for(unsigned int i=0;i<bd.size();i++) { + v = Py_BuildValue("(ssii)", bd[i].Package.c_str(), + bd[i].Version.c_str(), bd[i].Op, bd[i].Type); + PyList_Append(List, v); + Py_DECREF(v); + } + return List; } + +static PyGetSetDef PkgSrcRecordsGetSet[] = { + {"Binaries",PkgSrcRecordsGetBinaries}, + {"BuildDepends",PkgSrcRecordsGetBuildDepends}, + {"Files",PkgSrcRecordsGetFiles}, + {"Index",PkgSrcRecordsGetIndex}, + {"Maintainer",PkgSrcRecordsGetMaintainer}, + {"Package",PkgSrcRecordsGetPackage}, + {"Record",PkgSrcRecordsGetRecord}, + {"Section",PkgSrcRecordsGetSection}, + {"Version",PkgSrcRecordsGetVersion}, + {} +}; + PyTypeObject PkgSrcRecordsType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgSrcRecords", // tp_name sizeof(CppPyObject<PkgSrcRecordsStruct>), // tp_basicsize 0, // tp_itemsize // Methods CppDealloc<PkgSrcRecordsStruct>, // tp_dealloc 0, // tp_print - PkgSrcRecordsAttr, // tp_getattr + 0, // tp_getattr 0, // tp_setattr 0, // tp_compare 0, // tp_repr @@ -158,6 +200,22 @@ PyTypeObject PkgSrcRecordsType = 0, // tp_as_sequence 0, // tp_as_mapping 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "SourceRecords Object", // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + PkgSrcRecordsMethods, // tp_methods + 0, // tp_members + PkgSrcRecordsGetSet, // tp_getset }; /*}}}*/ diff --git a/python/progress.cc b/python/progress.cc index c5a1c138..bec40ce9 100644 --- a/python/progress.cc +++ b/python/progress.cc @@ -185,7 +185,7 @@ bool PyFetchProgress::Pulse(pkgAcquire * Owner) bool res = true; if(!PyArg_Parse(result, "b", &res)) { - // most of the time the user who subclasses the pulse() + // most of the time the user who subclasses the pulse() // method forgot to add a return {True,False} so we just // assume he wants a True return true; diff --git a/python/sourcelist.cc b/python/sourcelist.cc index 5dcaf86b..48b3b7c8 100644 --- a/python/sourcelist.cc +++ b/python/sourcelist.cc @@ -74,39 +74,42 @@ static PyMethodDef PkgSourceListMethods[] = { {"FindIndex",PkgSourceListFindIndex,METH_VARARGS,doc_PkgSourceListFindIndex}, {"ReadMainList",PkgSourceListReadMainList,METH_VARARGS,doc_PkgSourceListReadMainList}, - {"GetIndexes",PkgSourceListGetIndexes,METH_VARARGS,doc_PkgSourceListReadMainList}, + {"GetIndexes",PkgSourceListGetIndexes,METH_VARARGS,doc_PkgSourceListGetIndexes}, {} }; -static PyObject *PkgSourceListAttr(PyObject *Self,char *Name) +static PyObject *PkgSourceListGetList(PyObject *Self,void*) { pkgSourceList *list = GetCpp<pkgSourceList*>(Self); - - if (strcmp("List",Name) == 0) + PyObject *List = PyList_New(0); + for (vector<metaIndex *>::const_iterator I = list->begin(); + I != list->end(); I++) { - PyObject *List = PyList_New(0); - for (vector<metaIndex *>::const_iterator I = list->begin(); - I != list->end(); I++) - { - PyObject *Obj; - Obj = CppPyObject_NEW<metaIndex*>(&MetaIndexType,*I); - PyList_Append(List,Obj); - } - return List; + PyObject *Obj; + Obj = CppPyObject_NEW<metaIndex*>(&MetaIndexType,*I); + PyList_Append(List,Obj); } - return Py_FindMethod(PkgSourceListMethods,Self,Name); + return List; } + +static PyGetSetDef PkgSourceListGetSet[] = { + {"List",PkgSourceListGetList,0,"A list of MetaIndex() objects.",0}, + {} +}; + PyTypeObject PkgSourceListType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgSourceList", // tp_name sizeof(CppPyObject<pkgSourceList*>), // tp_basicsize 0, // tp_itemsize // Methods CppDealloc<pkgSourceList*>, // tp_dealloc 0, // tp_print - PkgSourceListAttr, // tp_getattr + 0, // tp_getattr 0, // tp_setattr 0, // tp_compare 0, // tp_repr @@ -114,6 +117,22 @@ PyTypeObject PkgSourceListType = 0, // tp_as_sequence 0, // tp_as_mapping 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "pkgSourceList Object", // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + PkgSourceListMethods, // tp_methods + 0, // tp_members + PkgSourceListGetSet, // tp_getset }; PyObject *GetPkgSourceList(PyObject *Self,PyObject *Args) 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 217be290..18d08580 100644 --- a/python/tag.cc +++ b/python/tag.cc @@ -174,6 +174,16 @@ static PyObject *TagSecExists(PyObject *Self,PyObject *Args) return Py_BuildValue("i",1); } +static int TagSecContains(PyObject *Self,PyObject *Arg) +{ + char *Name = PyString_AsString(Arg); + const char *Start; + const char *Stop; + if (GetCpp<pkgTagSection>(Self).Find(Name,Start,Stop) == false) + return 0; + return 1; +} + static char *doc_Bytes = "Bytes() -> integer"; static PyObject *TagSecBytes(PyObject *Self,PyObject *Args) { @@ -262,11 +272,14 @@ char *doc_ParseTagFile = "ParseTagFile(File) -> TagFile"; PyObject *ParseTagFile(PyObject *self,PyObject *Args) { PyObject *File; - if (PyArg_ParseTuple(Args,"O!",&PyFile_Type,&File) == 0) + if (PyArg_ParseTuple(Args,"O",&File) == 0) + return 0; + int fileno = PyObject_AsFileDescriptor(File); + if (fileno == -1) return 0; TagFileData *New = PyObject_NEW(TagFileData,&TagFileType); - new (&New->Fd) FileFd(fileno(PyFile_AsFile(File)),false); + new (&New->Fd) FileFd(fileno,false); New->File = File; Py_INCREF(New->File); new (&New->Object) pkgTagFile(&New->Fd); @@ -365,36 +378,43 @@ static PyMethodDef TagSecMethods[] = {} }; -// TagSecGetAttr - Get an attribute - variable/method /*{{{*/ -// --------------------------------------------------------------------- -/* */ -static PyObject *TagSecGetAttr(PyObject *Self,char *Name) -{ - return Py_FindMethod(TagSecMethods,Self,Name); -} - /*}}}*/ -// Type for a Tag Section + +PySequenceMethods TagSecSeqMeth = {0,0,0,0,0,0,0,TagSecContains,0,0}; PyMappingMethods TagSecMapMeth = {TagSecLength,TagSecMap,0}; PyTypeObject TagSecType = { PyObject_HEAD_INIT(&PyType_Type) - 0, // ob_size - "TagSection", // tp_name + #if PY_MAJOR_VERSION < 3 + 0, // ob_size + #endif + "TagSection", // tp_name sizeof(TagSecData), // tp_basicsize 0, // tp_itemsize // Methods TagSecFree, // tp_dealloc - 0, // tp_print - TagSecGetAttr, // tp_getattr + 0, // tp_print + 0, // tp_getattr 0, // tp_setattr 0, // tp_compare 0, // tp_repr 0, // tp_as_number - 0, // tp_as_sequence + &TagSecSeqMeth, // tp_as_sequence &TagSecMapMeth, // tp_as_mapping 0, // tp_hash - 0, // tp_call - TagSecStr, // tp_str + 0, // tp_call + TagSecStr, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "TagSection Object", // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + TagSecMethods // tp_methods }; // Method table for the Tag File object @@ -408,38 +428,53 @@ static PyMethodDef TagFileMethods[] = {} }; -// TagFileGetAttr - Get an attribute - variable/method /*{{{*/ -// --------------------------------------------------------------------- -/* */ -static PyObject *TagFileGetAttr(PyObject *Self,char *Name) -{ - if (strcmp("Section",Name) == 0) - { - PyObject *Obj = ((TagFileData *)Self)->Section; - Py_INCREF(Obj); - return Obj; - } - - return Py_FindMethod(TagFileMethods,Self,Name); +// Return the current section. +static PyObject *TagFileGetSection(PyObject *Self,void*) { + PyObject *Obj = ((TagFileData *)Self)->Section; + Py_INCREF(Obj); + return Obj; } +static PyGetSetDef TagFileGetSet[] = { + {"Section",TagFileGetSection,0,"Return a TagSection.",0}, + {} +}; + // Type for a Tag File PyTypeObject TagFileType = { PyObject_HEAD_INIT(&PyType_Type) - 0, // ob_size - "TagFile", // tp_name + #if PY_MAJOR_VERSION < 3 + 0, // ob_size + #endif + "TagFile", // tp_name sizeof(TagFileData), // tp_basicsize 0, // tp_itemsize // Methods TagFileFree, // tp_dealloc 0, // tp_print - TagFileGetAttr, // tp_getattr + 0, // tp_getattr 0, // tp_setattr 0, // tp_compare 0, // tp_repr 0, // tp_as_number 0, // tp_as_sequence - 0, // tp_as_mapping + 0, // tp_as_mapping 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "TagFile Object", // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + TagFileMethods, // tp_methods + 0, // tp_members + TagFileGetSet // tp_getset }; diff --git a/python/tar.cc b/python/tar.cc index e5aaee6f..217554c2 100644 --- a/python/tar.cc +++ b/python/tar.cc @@ -97,8 +97,7 @@ PyObject *tarExtract(PyObject *Self,PyObject *Args) PyObject *Function; char *Comp; - if (PyArg_ParseTuple(Args,"O!Os",&PyFile_Type,&File, - &Function,&Comp) == 0) + if (PyArg_ParseTuple(Args,"OOs",&File, &Function,&Comp) == 0) return 0; if (PyCallable_Check(Function) == 0) @@ -109,7 +108,11 @@ PyObject *tarExtract(PyObject *Self,PyObject *Args) { // Open the file and associate the tar - FileFd Fd(fileno(PyFile_AsFile(File)),false); + int fileno = PyObject_AsFileDescriptor(File); + if (fileno == -1) + return 0; + + FileFd Fd(fileno,false); ExtractTar Tar(Fd,0xFFFFFFFF,Comp); if (_error->PendingError() == true) return HandleErrors(); @@ -139,8 +142,7 @@ PyObject *debExtract(PyObject *Self,PyObject *Args) char *Chunk; const char *Comp = "gzip"; - if (PyArg_ParseTuple(Args,"O!Os",&PyFile_Type,&File, - &Function,&Chunk) == 0) + if (PyArg_ParseTuple(Args,"OOs",&File,&Function,&Chunk) == 0) return 0; if (PyCallable_Check(Function) == 0) @@ -149,10 +151,13 @@ PyObject *debExtract(PyObject *Self,PyObject *Args) return 0; } + int fileno = PyObject_AsFileDescriptor(File); + if (fileno == -1) + return 0; { // Open the file and associate the tar // Open the file and associate the .deb - FileFd Fd(fileno(PyFile_AsFile(File)),false); + FileFd Fd(fileno,false); debDebFile Deb(Fd); if (_error->PendingError() == true) return HandleErrors(); 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"]) diff --git a/tests/getcache_mem_corruption.py b/tests/getcache_mem_corruption.py index 42e9af00..c3f6eff3 100644 --- a/tests/getcache_mem_corruption.py +++ b/tests/getcache_mem_corruption.py @@ -6,16 +6,16 @@ import re import unittest class TestGetCache(unittest.TestCase): - + def setUp(self): apt_pkg.InitConfig() apt_pkg.InitSystem() - + def testWrongInvocation(self): # wrongly invoke GetCache() rather than GetDepCache() apt_cache = apt_pkg.GetCache() self.assertRaises(ValueError, apt_pkg.GetCache, apt_cache) - + def testProperInvocation(self): apt_cache = apt_pkg.GetCache(apt.progress.OpTextProgress()) apt_depcache = apt_pkg.GetDepCache(apt_cache) |
