From 5bdb4d5c14598069856034232e0057a4995af8c1 Mon Sep 17 00:00:00 2001 From: Sebastian Heinlein Date: Fri, 10 Apr 2009 22:27:03 +0200 Subject: Allow to change the candidate version of a package --- apt/package.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'apt') diff --git a/apt/package.py b/apt/package.py index 9afe1674..c13c0ef0 100644 --- a/apt/package.py +++ b/apt/package.py @@ -874,6 +874,12 @@ class Package(object): # depcache actions + 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() + def markKeep(self): """Mark a package for keep.""" self._pcache.cachePreChange() -- cgit v1.2.3 From 6f9513ed04d9357ca55895d32a312c0538a8dda2 Mon Sep 17 00:00:00 2001 From: Sebastian Heinlein Date: Fri, 10 Apr 2009 22:42:37 +0200 Subject: Add Package.get_version() which returns a Version instance for the given version string or None --- apt/package.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'apt') diff --git a/apt/package.py b/apt/package.py index 9afe1674..1dfabd46 100644 --- a/apt/package.py +++ b/apt/package.py @@ -872,6 +872,13 @@ class Package(object): """ return [Version(self, ver) for ver in self._pkg.VersionList] + def get_version(self, version): + """Get the Version instance matching the given version string.""" + for ver in self.versions: + if ver.version == version: + return ver + return None + # depcache actions def markKeep(self): -- cgit v1.2.3 From 506cb021d62e643fba38ddb4b84572a86cb3a3ba Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 13 Apr 2009 18:27:43 +0200 Subject: * python/tag.cc: Support 'key in mapping' for TagSections Support the replacement of mapping.has_key() for sections, and update the usage in apt/package.py and apt/debfile accordingly. This is implemented by extending the TagSecType with sequence methods, but only settings the contains method there. The TagSecGetAttr() function has been removed and replaced by the use of the tp_methods slot. --- apt/debfile.py | 10 +++++----- apt/package.py | 4 ++-- debian/changelog | 7 +++++++ doc/source/apt_pkg/cache.rst | 4 ++++ python/apt_pkgmodule.cc | 4 ++++ python/tag.cc | 47 +++++++++++++++++++++++++++++--------------- 6 files changed, 53 insertions(+), 23 deletions(-) (limited to 'apt') 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..e308da4b 100644 --- a/apt/package.py +++ b/apt/package.py @@ -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()) @@ -176,7 +176,7 @@ class Record(object): def has_key(self, key): """deprecated form of 'key in x'.""" - return self._rec.has_key(key) + return key in self._rec class Version(object): diff --git a/debian/changelog b/debian/changelog index 83b00150..f623254e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +python-apt (0.7.11) UNRELEASED; urgency=low + + * python/tag.cc: + - Support 'key in mapping' for TagSections + + -- Julian Andres Klode Mon, 13 Apr 2009 18:08:10 +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/doc/source/apt_pkg/cache.rst b/doc/source/apt_pkg/cache.rst index af67d82f..146c2c2a 100644 --- a/doc/source/apt_pkg/cache.rst +++ b/doc/source/apt_pkg/cache.rst @@ -1199,6 +1199,10 @@ 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``. + .. method:: Bytes The number of bytes in the section. diff --git a/python/apt_pkgmodule.cc b/python/apt_pkgmodule.cc index 86732781..34669fd5 100644 --- a/python/apt_pkgmodule.cc +++ b/python/apt_pkgmodule.cc @@ -472,6 +472,10 @@ static void AddInt(PyObject *Dict,const char *Itm,unsigned long I) extern "C" void initapt_pkg() { + // Finalize our types to add slots, etc. + if (PyType_Ready(&TagSecType) == -1) return; + + // Initialize the module PyObject *Module = Py_InitModule("apt_pkg",methods); PyObject *Dict = PyModule_GetDict(Module); diff --git a/python/tag.cc b/python/tag.cc index 217be290..cab32370 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(Self).Find(Name,Start,Stop) == false) + return 0; + return 1; +} + static char *doc_Bytes = "Bytes() -> integer"; static PyObject *TagSecBytes(PyObject *Self,PyObject *Args) { @@ -365,36 +375,41 @@ 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 + 0, // ob_size + "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 -- cgit v1.2.3 From ae7f143f8162d10c7bd834e8877e42674fdb646f Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 13 Apr 2009 22:37:20 +0200 Subject: * doc: Documentation updates Extended the documentation, renamed 'Coding for python-apt' to 'Contributing to python-apt' and other stuff. --- apt/package.py | 221 +++++++++++++++++++++++++++------------- doc/source/apt_inst.rst | 40 ++++++-- doc/source/apt_pkg/cache.rst | 4 + doc/source/apt_pkg/index.rst | 233 ++++++++++++++++++++++++++++++++++--------- doc/source/coding.rst | 168 ------------------------------- doc/source/contributing.rst | 160 +++++++++++++++++++++++++++++ doc/source/index.rst | 2 +- 7 files changed, 535 insertions(+), 293 deletions(-) delete mode 100644 doc/source/coding.rst create mode 100644 doc/source/contributing.rst (limited to 'apt') diff --git a/apt/package.py b/apt/package.py index e308da4b..5adef15c 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: @@ -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'.""" + """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): @@ -352,26 +352,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 +394,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 +438,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()) @@ -490,7 +513,8 @@ class Package(object): def candidate(self): """Return the candidate version of the package. - :since: 0.7.9""" + .. versionadded:: 0.7.9 + """ cand = self._pcache._depcache.GetCandidateVer(self._pkg) if cand is not None: return Version(self, cand) @@ -499,7 +523,8 @@ class Package(object): 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 +550,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 +616,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 +629,27 @@ 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 +660,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 +715,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 +743,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 +796,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 +946,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 +971,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 +992,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 +1025,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/doc/source/apt_inst.rst b/doc/source/apt_inst.rst index 97705f61..999d074e 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.7.11 + 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.7.11 + 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.7.11 + 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.7.11 + 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.7.11 + 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 93f8dc2d..86515569 100644 --- a/doc/source/apt_pkg/cache.rst +++ b/doc/source/apt_pkg/cache.rst @@ -207,6 +207,8 @@ Classes in apt_pkg Return whether the configuration contains the key *key*. + .. deprecated:: 0.7.11 + .. method:: get(key[, default='']) This behaves just like :meth:`dict.get` and :meth:`Configuration.Find`, @@ -1234,6 +1236,8 @@ broken dependencies: Check whether the field with named by *key* exists. + .. deprecated:: 0.7.11 + .. 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..38310bb5 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.7.11 + 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.7.11 + 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.7.11 + 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.7.11 + 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/coding.rst b/doc/source/coding.rst deleted file mode 100644 index 1357ce14..00000000 --- a/doc/source/coding.rst +++ /dev/null @@ -1,168 +0,0 @@ -Coding for 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. - -Available branches -------------------- -First of all, let's talk a bit about the bzr branches of python-apt. In the -following parts, we will assume that you use bzr to create your changes and -submit them. - -**mvo:** http://people.ubuntu.com/~mvo/bzr/python-apt/mvo - This is Michael Vogt's branch. Most of the development of apt happens here, - as he is the lead maintainer of python-apt. - - This branch is also available from Launchpads super mirror, via - ``lp:python-apt``. Checkouts from Launchpad are generally faster and can - use the bzr protocoll. - - VCS-Browser: https://code.launchpad.net/~mvo/python-apt/python-apt--mvo - -**debian-sid:** http://bzr.debian.org/apt/python-apt/debian-sid - This is the official Debian branch of python-apt. All code which will be - uploaded to Debian is here. It is not as up-to-date as the mvo branch, - because this branch often gets updated just right before the release - happens. - - VCS-Browser: http://bzr.debian.org/loggerhead/apt/python-apt/debian-sid/changes - -**jak:** http://bzr.debian.org/users/jak/python-apt/jak - This is Julian Andres Klode's (the documentation author's) branch. This - is the place where cleanup and documentation updates happen. It is based - off debian-sid or mvo. - - VCS-Browser: http://bzr.debian.org/loggerhead/users/jak/python-apt/jak/changes - -**ubuntu:** ``lp:~ubuntu-core-dev/python-apt/ubuntu`` - This is the official Ubuntu development branch. The same notes apply as - for the debian-sid branch above. - - VCS-Browser: https://code.launchpad.net/~ubuntu-core-dev/python-apt/ubuntu - - -C++ Coding style ----------------- -When you work on the C++ code in the python/ directory, you should follow some -basic rules. - -The indentation of the code is a bit non-standard. We currently use 3 spaces -indentation for the C++ code. - -When you create new functions, you should follow some naming conventions. All -C++ functions are named according to the ``CamelCase`` convention. - -The resulting Python functions should be ``CamelCase`` as well in apt_pkg, or -``mixedCase`` in apt_inst. The same applies for variables, parameters, -attributes, etc. - -.. note:: - - 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. - -Modules 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. - -.. note:: - - You can use the tool pep8.py from http://svn.browsershots.org/trunk/devtools/pep8/ - to validate your code. Please also run pylint, pychecker, and pyflakes and - fix all new **errors** they report (undefined names, etc.). - -Submitting your patch ---------------------- -First of all, the patch you create should be based against the debian-sid -branch of python-apt. - -Once you have made your change, check that it: - - * conforms to :PEP:`8` (checked with pep8.py). It should, at least not - introduce new errors. (and never have whitespace at end of line) - * produces no new errors in pychecker, pyflakes and pylint (unless you - can't fix them, but please tell so when requesting the merge, so it can - be fixed before hitting one of the main branches). - * does not change the behaviour of existing code in a non-compatible way. - -If your change follows all points of the checklist, you can commit it to your -repository. (You could commit it first, and check later, and then commit the -fixes, but commits should be logical and it makes no sense to have to commits -for one logical unit). - -Once you have made all your changes, you can run ``bzr send -o patch-name`` -to create a so called *merge-directive*, which contains your changes and -allows us to preserve the history of your changes. (But please replace patch-name -with something useful). - -Now report a bug against the python-apt package, attach the merge directive -you created in the previous step, and tag it with 'patch'. It might also be -a good idea to prefix the bug report with '[PATCH]'. - -If your patch introduces new functions, parameters, etc. , but does not update -the content of this documentation, please CC. jak@debian.org, and add a short -notice to the bug report. Also see `Documentation updates` - -Once your patch got merged, you can *pull* the branch into which it has been -merged into your local one. If you have made changes since you submitted your -patch, you may need to *merge* the branch instead. - -.. note:: - - If you plan to work on python-apt for a longer time, it may be a good - idea to publish your branch somewhere. Alioth (http://alioth.debian.org) - and Launchpad (https://launchpad.net) provide bzr hosting. You can also - use any webspace with ftp or sftp connection (for the upload). Then you do - not need to send *merge directives*, but you can point to your branch - instead. - - -Documentation updates ---------------------- -If you want to update the documentation, please follow the procedure as written -above. But please CC: jak@debian.org in the bug report. - -You can send your content in plain text, but reStructuredText is the preferred -format. I (Julian Andres Klode) will review your patch and will forward them to -Michael Vogt, for inclusion in his branch. On release, this will be merged into -the debian-sid branch. - - -Example patch session ----------------------- -In the following example, we edit a file, create a merge directive (an enhanced -patch), and report a wishlist bug with this patch against the python-apt -package:: - - user@pc:~$ bzr clone http://bzr.debian.org/apt/python-apt/debian-sid/ - user@pc:~$ cd debian-sid - user@pc:~/debian-sid$ editor FILES - user@pc:~/debian-sid$ pep8.py FILES # PEP 8 check, see above. - user@pc:~/debian-sid$ pylint -e FILES # Check with pylint - user@pc:~/debian-sid$ pyflakes FILES # Check with pyflakes - user@pc:~/debian-sid$ pychecker FILES # Check with pychecker - user@pc:~/debian-sid$ bzr commit - user@pc:~/debian-sid$ bzr send -o my-patch - user@pc:~/debian-sid$ reportbug --severity=wishlist --tag=patch --attach=my-patch python-apt - user@pc:~/debian-sid$ # Add --list-cc=jak@debian.org if you change docs. diff --git a/doc/source/contributing.rst b/doc/source/contributing.rst new file mode 100644 index 00000000..04933b73 --- /dev/null +++ b/doc/source/contributing.rst @@ -0,0 +1,160 @@ +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. + +Available branches +------------------- +First of all, let's talk a bit about the bzr branches of python-apt. In the +following parts, we will assume that you use bzr to create your changes and +submit them. + +**mvo:** http://people.ubuntu.com/~mvo/bzr/python-apt/mvo + This is Michael Vogt's branch. Most of the development of apt happens here, + as he is the lead maintainer of python-apt. + + This branch is also available from Launchpads super mirror, via + ``lp:python-apt``. Checkouts from Launchpad are generally faster and can + use the bzr protocoll. + + VCS-Browser: https://code.launchpad.net/~mvo/python-apt/python-apt--mvo + +**debian-sid:** http://bzr.debian.org/apt/python-apt/debian-sid + This is the official Debian branch of python-apt. All code which will be + uploaded to Debian is here. It is not as up-to-date as the mvo branch, + because this branch often gets updated just right before the release + happens. + + VCS-Browser: http://bzr.debian.org/loggerhead/apt/python-apt/debian-sid/changes + +**jak:** http://bzr.debian.org/users/jak/python-apt/jak + This is Julian Andres Klode's (the documentation author's) branch. This + is the place where cleanup and documentation updates happen. It is based + off debian-sid or mvo. + + VCS-Browser: http://bzr.debian.org/loggerhead/users/jak/python-apt/jak/changes + +**ubuntu:** ``lp:~ubuntu-core-dev/python-apt/ubuntu`` + This is the official Ubuntu development branch. The same notes apply as + for the debian-sid branch above. + + VCS-Browser: https://code.launchpad.net/~ubuntu-core-dev/python-apt/ubuntu + + +C++ Coding style +---------------- +When you work on the C++ code in the python/ directory, you should follow some +basic rules. + +The indentation of the code is a bit non-standard. We currently use 3 spaces +indentation for the C++ code. + +When you create new functions, you should follow some naming conventions. All +C++ functions are named according to the ``CamelCase`` convention. + +The resulting Python functions should be ``CamelCase`` as well in apt_pkg, or +``mixedCase`` in apt_inst. The same applies for variables, parameters, +attributes, etc. + +.. note:: + + This coding style guidelines are incomplete. If you have any questions + send an email to deity@lists.debian.org. + + +Python Coding Style +------------------- +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. + +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). + +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:: + + You can use the tool pep8.py from http://svn.browsershots.org/trunk/devtools/pep8/ + to validate your code. Please also run pylint, pychecker, and pyflakes and + fix all new **errors** they report (undefined names, etc.). + +Submitting your patch +--------------------- +First of all, the patch you create should be based against the debian-sid +branch of python-apt. + +Once you have made your change, check that it: + + * conforms to :PEP:`8` (checked with pep8.py). It should, at least not + introduce new errors. (and never have whitespace at end of line) + * produces no new errors in pychecker, pyflakes and pylint (unless you + can't fix them, but please tell so when requesting the merge, so it can + be fixed before hitting one of the main branches). + * does not change the behaviour of existing code in a non-compatible way. + +If your change follows all points of the checklist, you can commit it to your +repository. (You could commit it first, and check later, and then commit the +fixes, but commits should be logical and it makes no sense to have to commits +for one logical unit). + +Once you have made all your changes, you can run ``bzr send -o patch-name`` +to create a so called *merge-directive*, which contains your changes and +allows us to preserve the history of your changes. (But please replace patch-name +with something useful). + +Now report a bug against the python-apt package, attach the merge directive +you created in the previous step, and tag it with 'patch'. It might also be +a good idea to prefix the bug report with '[PATCH]'. + +If your patch introduces new functions, parameters, etc. , but does not update +the content of this documentation, please CC. jak@debian.org, and add a short +notice to the bug report. Also see `Documentation updates` + +Once your patch got merged, you can *pull* the branch into which it has been +merged into your local one. If you have made changes since you submitted your +patch, you may need to *merge* the branch instead. + +.. note:: + + If you plan to work on python-apt for a longer time, it may be a good + idea to publish your branch somewhere. Alioth (http://alioth.debian.org) + and Launchpad (https://launchpad.net) provide bzr hosting. You can also + use any webspace with ftp or sftp connection (for the upload). Then you do + not need to send *merge directives*, but you can point to your branch + instead. + + +Documentation updates +--------------------- +If you want to update the documentation, please follow the procedure as written +above. But please CC: jak@debian.org in the bug report. + +You can send your content in plain text, but reStructuredText is the preferred +format. I (Julian Andres Klode) will review your patch and will forward them to +Michael Vogt, for inclusion in his branch. On release, this will be merged into +the debian-sid branch. + + +Example patch session +---------------------- +In the following example, we edit a file, create a merge directive (an enhanced +patch), and report a wishlist bug with this patch against the python-apt +package:: + + user@pc:~$ bzr clone http://bzr.debian.org/apt/python-apt/debian-sid/ + user@pc:~$ cd debian-sid + user@pc:~/debian-sid$ editor FILES + user@pc:~/debian-sid$ pep8.py FILES # PEP 8 check, see above. + user@pc:~/debian-sid$ pylint -e FILES # Check with pylint + user@pc:~/debian-sid$ pyflakes FILES # Check with pyflakes + user@pc:~/debian-sid$ pychecker FILES # Check with pychecker + user@pc:~/debian-sid$ bzr commit + user@pc:~/debian-sid$ bzr send -o my-patch + user@pc:~/debian-sid$ reportbug --severity=wishlist --tag=patch --attach=my-patch python-apt + user@pc:~/debian-sid$ # Add --list-cc=jak@debian.org if you change docs. 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 -- cgit v1.2.3 From 8413810c46f802490280b0be1beebaaadf1aa9f2 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 14 Apr 2009 00:47:23 +0200 Subject: * Remove any trailing whitespace --- apt/package.py | 3 +-- doc/source/apt_pkg/index.rst | 2 +- python/apt_pkgmodule.cc | 2 +- python/cache.cc | 2 +- python/cdrom.cc | 6 +++--- python/configuration.cc | 18 +++++++++--------- python/depcache.cc | 12 ++++++------ python/progress.cc | 2 +- python/tag.cc | 12 ++++++------ python/tar.cc | 2 +- tests/getcache_mem_corruption.py | 6 +++--- 11 files changed, 33 insertions(+), 34 deletions(-) (limited to 'apt') diff --git a/apt/package.py b/apt/package.py index 5adef15c..3ea1105d 100644 --- a/apt/package.py +++ b/apt/package.py @@ -639,7 +639,6 @@ class Package(object): def installedPriority(self): """Return the priority (of the installed version). - .. deprecated:: 0.7.9 """ return getattr(self.installed, 'priority', None) @@ -800,7 +799,7 @@ class Package(object): contain multiple named variables which will be substitued. These variables are (src_section, prefix, src_pkg, src_ver). An example is the Ubuntu changelog:: - + "http://changelogs.ubuntu.com/changelogs/pool" \\ "/%(src_section)s/%(prefix)s/%(src_pkg)s" \\ "/%(src_pkg)s_%(src_ver)s/changelog" diff --git a/doc/source/apt_pkg/index.rst b/doc/source/apt_pkg/index.rst index 38310bb5..60c3ba9b 100644 --- a/doc/source/apt_pkg/index.rst +++ b/doc/source/apt_pkg/index.rst @@ -252,7 +252,7 @@ Dependencies >>> 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:: diff --git a/python/apt_pkgmodule.cc b/python/apt_pkgmodule.cc index 5d0b2c0a..145a2bab 100644 --- a/python/apt_pkgmodule.cc +++ b/python/apt_pkgmodule.cc @@ -481,7 +481,7 @@ extern "C" void initapt_pkg() if (PyType_Ready(&PkgCdromType) == -1) return; if (PyType_Ready(&PkgProblemResolverType) == -1) return; if (PyType_Ready(&PkgActionGroupType) == -1) return; - + // Initialize the module PyObject *Module = Py_InitModule("apt_pkg",methods); diff --git a/python/cache.cc b/python/cache.cc index 4db097c7..31d8c45d 100644 --- a/python/cache.cc +++ b/python/cache.cc @@ -951,7 +951,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 1278d6b7..0816d93e 100644 --- a/python/cdrom.cc +++ b/python/cdrom.cc @@ -84,16 +84,16 @@ PyTypeObject PkgCdromType = 0, // tp_hash 0, // tp_call 0, // tp_str - 0, // tp_getattro + 0, // tp_getattro 0, // tp_setattro - 0, // tp_as_buffer + 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_iter 0, // tp_iternext PkgCdromMethods, // tp_methods }; diff --git a/python/configuration.cc b/python/configuration.cc index a95ac029..b4adf357 100644 --- a/python/configuration.cc +++ b/python/configuration.cc @@ -498,16 +498,16 @@ PyTypeObject ConfigurationType = 0, // tp_hash 0, // tp_call 0, // tp_str - 0, // tp_getattro + 0, // tp_getattro 0, // tp_setattro - 0, // tp_as_buffer + 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_iter 0, // tp_iternext CnfMethods, // tp_methods }; @@ -532,16 +532,16 @@ PyTypeObject ConfigurationPtrType = 0, // tp_hash 0, // tp_call 0, // tp_str - 0, // tp_getattro + 0, // tp_getattro 0, // tp_setattro - 0, // tp_as_buffer + 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_iter 0, // tp_iternext CnfMethods, // tp_methods }; @@ -566,16 +566,16 @@ PyTypeObject ConfigurationSubType = 0, // tp_hash 0, // tp_call 0, // tp_str - 0, // tp_getattro + 0, // tp_getattro 0, // tp_setattro - 0, // tp_as_buffer + 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_iter 0, // tp_iternext CnfMethods, // tp_methods }; diff --git a/python/depcache.cc b/python/depcache.cc index b23eecd9..2c73a1a9 100644 --- a/python/depcache.cc +++ b/python/depcache.cc @@ -769,16 +769,16 @@ PyTypeObject PkgProblemResolverType = 0, // tp_hash 0, // tp_call 0, // tp_str - 0, // tp_getattro + 0, // tp_getattro 0, // tp_setattro - 0, // tp_as_buffer + 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_iter 0, // tp_iternext PkgProblemResolverMethods, // tp_methods }; @@ -825,16 +825,16 @@ PyTypeObject PkgActionGroupType = 0, // tp_hash 0, // tp_call 0, // tp_str - 0, // tp_getattro + 0, // tp_getattro 0, // tp_setattro - 0, // tp_as_buffer + 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_iter 0, // tp_iternext PkgActionGroupMethods, // tp_methods }; 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/tag.cc b/python/tag.cc index baf97b59..cdea3e03 100644 --- a/python/tag.cc +++ b/python/tag.cc @@ -401,16 +401,16 @@ PyTypeObject TagSecType = 0, // tp_hash 0, // tp_call TagSecStr, // tp_str - 0, // tp_getattro + 0, // tp_getattro 0, // tp_setattro - 0, // tp_as_buffer + 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_iter 0, // tp_iternext TagSecMethods // tp_methods }; @@ -459,16 +459,16 @@ PyTypeObject TagFileType = 0, // tp_hash 0, // tp_call 0, // tp_str - 0, // tp_getattro + 0, // tp_getattro 0, // tp_setattro - 0, // tp_as_buffer + 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_iter 0, // tp_iternext TagFileMethods, // tp_methods 0, // tp_members diff --git a/python/tar.cc b/python/tar.cc index f0d57823..217554c2 100644 --- a/python/tar.cc +++ b/python/tar.cc @@ -111,7 +111,7 @@ PyObject *tarExtract(PyObject *Self,PyObject *Args) int fileno = PyObject_AsFileDescriptor(File); if (fileno == -1) return 0; - + FileFd Fd(fileno,false); ExtractTar Tar(Fd,0xFFFFFFFF,Comp); if (_error->PendingError() == true) 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) -- cgit v1.2.3 From 2b867aebe32d59b7450f3a7fb22390e0dd9f8cc7 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Wed, 15 Apr 2009 14:16:28 +0200 Subject: * apt/cache.py: Use set() and WeakValueDictionary() for holding packages. Only create Package objects when they are requested, do not keep them in a dict. Saves 10MB for 25,000 packages on my machine. The set holds the names of all packages which have at least one version, and the WeakValueDictionary() holds weak references to created Package objects. This way accessing the same package two times should return the same object, kept by the WeakValueDictionary(). --- apt/cache.py | 38 +++++++++++++++++++++++--------------- debian/changelog | 4 +++- 2 files changed, 26 insertions(+), 16 deletions(-) (limited to 'apt') 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/debian/changelog b/debian/changelog index 261ff7bd..6cbdaac7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -5,8 +5,10 @@ python-apt (0.7.11) UNRELEASED; urgency=low * 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. - -- Julian Andres Klode Mon, 13 Apr 2009 18:08:10 +0200 + -- Julian Andres Klode Wed, 15 Apr 2009 13:47:42 +0200 python-apt (0.7.10.3) unstable; urgency=low -- cgit v1.2.3 From c876c5095673a2f1c0f2c0eef6eadef2ce200e19 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Wed, 15 Apr 2009 16:19:12 +0200 Subject: * Introduce support for Python 3 (Closes: #523645) This is the first initial port to Python 3. The API is almost completely identical to the one found in Python 2, except that functions working with binary data require bytes (md5sum,sha1sum,sha256sum,Base64Encode). Using setup3.py to install the modules will not work, because the apt package still has to be converted to Python 3. For the package, we call 2to3-3.1 in debian/rules to do this automatically. --- apt/package.py | 6 +++- debian/changelog | 2 ++ debian/control | 2 ++ debian/rules | 26 +++++++++++++-- po/python-apt.pot | 10 +++--- python/acquire.cc | 6 ++++ python/apt_instmodule.cc | 35 ++++++++++++++++++- python/apt_pkgmodule.cc | 87 +++++++++++++++++++++++++++++++++++------------- python/cache.cc | 18 ++++++++++ python/cdrom.cc | 2 ++ python/configuration.cc | 6 ++++ python/depcache.cc | 6 ++++ python/generic.h | 25 ++++++++++++++ python/indexfile.cc | 2 ++ python/metaindex.cc | 2 ++ python/pkgmanager.cc | 2 ++ python/pkgrecords.cc | 2 ++ python/pkgsrcrecords.cc | 2 ++ python/sourcelist.cc | 2 ++ python/string.cc | 16 ++++++++- python/tag.cc | 4 +++ setup3.py | 77 ++++++++++++++++++++++++++++++++++++++++++ 22 files changed, 307 insertions(+), 33 deletions(-) create mode 100644 setup3.py (limited to 'apt') diff --git a/apt/package.py b/apt/package.py index 3ea1105d..f12f5559 100644 --- a/apt/package.py +++ b/apt/package.py @@ -272,8 +272,12 @@ class Version(object): """ self.summary # This does the lookup for us. desc = '' + + dsc = self.package._pcache._records.LongDesc try: - dsc = unicode(self.package._pcache._records.LongDesc, "utf-8") + if not isinstance(dsc, unicode): + # Only convert where needed (i.e. Python 2.X) + dsc = unicode(dsc, "utf-8") except UnicodeDecodeError, err: return _("Invalid unicode in description for '%s' (%s). " "Please report.") % (self.package.name, err) diff --git a/debian/changelog b/debian/changelog index 6cbdaac7..a9518d7d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,7 @@ python-apt (0.7.11) UNRELEASED; urgency=low + * Introduce support for Python 3 (Closes: #523645) + * Support the 'in' operator (e.g. "k in d") in Configuration{,Ptr,Sub} objects (e.g. apt_pkg.Config) and in TagSections (apt_pkg.ParseSection()) * Replace support for file objects with a more generic support for any object diff --git a/debian/control b/debian/control index 72476c58..08ee329f 100644 --- a/debian/control +++ b/debian/control @@ -11,6 +11,8 @@ Build-Depends: apt-utils, libapt-pkg-dev (>= 0.7.10), python-all-dbg, python-all-dev, + python3.1-dev, + python3.1-dbg, python-central (>= 0.5), python-distutils-extra (>= 1.9.0), python-gtk2, diff --git a/debian/rules b/debian/rules index 6d709ecd..7de945f2 100755 --- a/debian/rules +++ b/debian/rules @@ -11,22 +11,44 @@ DEB_PYTHON_PACKAGES_EXCLUDE=python-apt-dbg include /usr/share/cdbs/1/rules/debhelper.mk include /usr/share/cdbs/1/class/python-distutils.mk +PY3K = y PKG=python-apt DEBVER=$(shell dpkg-parsechangelog |sed -n -e '/^Version:/s/^Version: //p') DEB_COMPRESS_EXCLUDE:=.html .js _static/* _sources/* _sources/*/* .inv DEB_BUILD_PROG:=debuild --preserve-envvar PATH --preserve-envvar CCACHE_DIR -us -uc $(DEB_BUILD_PROG_OPTS) export DEBVER + +ifeq ($(PY3K),y) +build/python-apt:: + python3.1 setup3.py build + +install/python-apt:: + python3.1 ./setup3.py install --root $(CURDIR)/debian/python-apt \ + --install-layout=deb --no-compile + + find $(CURDIR)/debian/python-apt/usr/lib/python3.1/dist-packages/ -name '*.py' \ + | xargs 2to3-3.1 | patch -p0 +endif + build/python-apt-dbg:: set -e; \ for i in $(cdbs_python_build_versions); do \ python$$i-dbg ./setup.py build; \ done + ifeq($(PY3K),y) + python3.1-dbg ./setup3.py build + endif install/python-apt-dbg:: for i in $(cdbs_python_build_versions); do \ - python$$i-dbg ./setup.py install --root $(CURDIR)/debian/python-apt-dbg; \ + python$$i-dbg ./setup.py install --root $(CURDIR)/debian/python-apt-dbg \ + --no-compile; \ done + ifeq($(PY3K),y) + python3.1-dbg ./setup3.py install --root $(CURDIR)/debian/python-apt-dbg \ + --install-layout=deb --no-compile + endif find debian/python-apt-dbg \ ! -type d ! -name '*_d.so' | xargs rm -f find debian/python-apt-dbg -depth -empty -exec rmdir {} \; @@ -39,4 +61,4 @@ binary-predeb/python-apt-dbg:: ln -s python-apt debian/python-apt-dbg/usr/share/doc/python-apt-dbg clean:: - rm -rf build/lib* build/temp* + rm -rf build/lib* build/temp* build diff --git a/po/python-apt.pot b/po/python-apt.pot index 9c23c579..d12ae967 100644 --- a/po/python-apt.pot +++ b/po/python-apt.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-04-12 19:07+0200\n" +"POT-Creation-Date: 2009-04-15 16:10+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -354,16 +354,16 @@ msgstr "" msgid "Complete" msgstr "" -#: ../apt/package.py:278 +#: ../apt/package.py:282 #, python-format msgid "Invalid unicode in description for '%s' (%s). Please report." msgstr "" -#: ../apt/package.py:745 ../apt/package.py:849 +#: ../apt/package.py:830 ../apt/package.py:934 msgid "The list of changes is not available" msgstr "" -#: ../apt/package.py:853 +#: ../apt/package.py:938 #, python-format msgid "" "The list of changes is not available yet.\n" @@ -372,7 +372,7 @@ msgid "" "until the changes become available or try again later." msgstr "" -#: ../apt/package.py:859 +#: ../apt/package.py:944 msgid "" "Failed to download the list of changes. \n" "Please check your Internet connection." diff --git a/python/acquire.cc b/python/acquire.cc index d39ee495..053753cd 100644 --- a/python/acquire.cc +++ b/python/acquire.cc @@ -72,7 +72,9 @@ static PyObject *AcquireItemRepr(PyObject *Self) PyTypeObject AcquireItemType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgAcquire::ItemIterator", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize @@ -175,7 +177,9 @@ static PyGetSetDef PkgAcquireGetSet[] = { PyTypeObject PkgAcquireType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "Acquire", // tp_name sizeof(CppPyObject), // tp_basicsize 0, // tp_itemsize @@ -234,7 +238,9 @@ PyObject *GetAcquire(PyObject *Self,PyObject *Args) PyTypeObject PkgAcquireFileType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgAcquireFile", // tp_name sizeof(CppPyObject),// tp_basicsize 0, // tp_itemsize diff --git a/python/apt_instmodule.cc b/python/apt_instmodule.cc index a9d81be4..09e3937e 100644 --- a/python/apt_instmodule.cc +++ b/python/apt_instmodule.cc @@ -162,8 +162,41 @@ static PyMethodDef methods[] = {} }; +#if PY_MAJOR_VERSION >= 3 +struct module_state { + PyObject *error; +}; +#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m)) + +static int apt_inst_traverse(PyObject *m, visitproc visit, void *arg) { + Py_VISIT(GETSTATE(m)->error); + return 0; +} + +static int apt_inst_clear(PyObject *m) { + Py_CLEAR(GETSTATE(m)->error); + return 0; +} + +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "apt_inst", + NULL, + sizeof(struct module_state), + methods, + NULL, + apt_inst_traverse, + apt_inst_clear, + NULL +}; + +extern "C" PyObject * PyInit_apt_inst() +{ + return PyModule_Create(&moduledef); +} +#else extern "C" void initapt_inst() { Py_InitModule("apt_inst",methods); } - /*}}}*/ +#endif /*}}}*/ diff --git a/python/apt_pkgmodule.cc b/python/apt_pkgmodule.cc index fe6a739e..e71d8ee6 100644 --- a/python/apt_pkgmodule.cc +++ b/python/apt_pkgmodule.cc @@ -173,12 +173,12 @@ static PyObject *md5sum(PyObject *Self,PyObject *Args) return 0; // Digest of a string. - if (PyString_Check(Obj) != 0) + if (PyBytes_Check(Obj) != 0) { char *s; Py_ssize_t len; MD5Summation Sum; - PyString_AsStringAndSize(Obj, &s, &len); + PyBytes_AsStringAndSize(Obj, &s, &len); Sum.Add((const unsigned char*)s, len); return CppPyString(Sum.Result().Value()); } @@ -213,12 +213,12 @@ static PyObject *sha1sum(PyObject *Self,PyObject *Args) return 0; // Digest of a string. - if (PyString_Check(Obj) != 0) + if (PyBytes_Check(Obj) != 0) { char *s; Py_ssize_t len; SHA1Summation Sum; - PyString_AsStringAndSize(Obj, &s, &len); + PyBytes_AsStringAndSize(Obj, &s, &len); Sum.Add((const unsigned char*)s, len); return CppPyString(Sum.Result().Value()); } @@ -253,12 +253,12 @@ static PyObject *sha256sum(PyObject *Self,PyObject *Args) return 0; // Digest of a string. - if (PyString_Check(Obj) != 0) + if (PyBytes_Check(Obj) != 0) { char *s; Py_ssize_t len; SHA256Summation Sum; - PyString_AsStringAndSize(Obj, &s, &len); + PyBytes_AsStringAndSize(Obj, &s, &len); Sum.Add((const unsigned char*)s, len); return CppPyString(Sum.Result().Value()); } @@ -470,30 +470,68 @@ static void AddInt(PyObject *Dict,const char *Itm,unsigned long I) Py_DECREF(Obj); } +#if PY_MAJOR_VERSION >= 3 +struct module_state { + PyObject *error; +}; + +#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m)) + +static int apt_inst_traverse(PyObject *m, visitproc visit, void *arg) { + Py_VISIT(GETSTATE(m)->error); + return 0; +} + +static int apt_inst_clear(PyObject *m) { + Py_CLEAR(GETSTATE(m)->error); + return 0; +} + +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "apt_inst", + NULL, + sizeof(struct module_state), + methods, + NULL, + apt_inst_traverse, + apt_inst_clear, + NULL +}; + +#define INIT_ERROR return 0 +extern "C" PyObject * PyInit_apt_pkg() +#else +#define INIT_ERROR return extern "C" void initapt_pkg() +#endif { // Finalize our types to add slots, etc. - if (PyType_Ready(&TagSecType) == -1) return; - if (PyType_Ready(&TagFileType) == -1) return; - if (PyType_Ready(&ConfigurationType) == -1) return; - if (PyType_Ready(&ConfigurationPtrType) == -1) return; - if (PyType_Ready(&ConfigurationSubType) == -1) return; - if (PyType_Ready(&PkgCdromType) == -1) return; - if (PyType_Ready(&PkgProblemResolverType) == -1) return; - if (PyType_Ready(&PkgActionGroupType) == -1) return; - if (PyType_Ready(&PkgSourceListType) == -1) return; - if (PyType_Ready(&PkgCacheType) == -1) return; - if (PyType_Ready(&DependencyType) == -1) return; - if (PyType_Ready(&PkgDepCacheType) == -1) return; - if (PyType_Ready(&PkgAcquireType) == -1) return; - if (PyType_Ready(&PackageIndexFileType) == -1) return; - if (PyType_Ready(&PkgManagerType) == -1) return; - if (PyType_Ready(&PkgSrcRecordsType) == -1) return; - if (PyType_Ready(&PkgRecordsType) == -1) return; + if (PyType_Ready(&TagSecType) == -1) INIT_ERROR; + if (PyType_Ready(&TagFileType) == -1) INIT_ERROR; + if (PyType_Ready(&ConfigurationType) == -1) INIT_ERROR; + if (PyType_Ready(&ConfigurationPtrType) == -1) INIT_ERROR; + if (PyType_Ready(&ConfigurationSubType) == -1) INIT_ERROR; + if (PyType_Ready(&PkgCdromType) == -1) INIT_ERROR; + if (PyType_Ready(&PkgProblemResolverType) == -1) INIT_ERROR; + if (PyType_Ready(&PkgActionGroupType) == -1) INIT_ERROR; + if (PyType_Ready(&PkgSourceListType) == -1) INIT_ERROR; + if (PyType_Ready(&PkgCacheType) == -1) INIT_ERROR; + if (PyType_Ready(&DependencyType) == -1) INIT_ERROR; + if (PyType_Ready(&PkgDepCacheType) == -1) INIT_ERROR; + if (PyType_Ready(&PkgAcquireType) == -1) INIT_ERROR; + if (PyType_Ready(&PackageIndexFileType) == -1) INIT_ERROR; + if (PyType_Ready(&PkgManagerType) == -1) INIT_ERROR; + if (PyType_Ready(&PkgSrcRecordsType) == -1) INIT_ERROR; + if (PyType_Ready(&PkgRecordsType) == -1) INIT_ERROR; // Initialize the module + #if PY_MAJOR_VERSION >= 3 + PyObject *Module = PyModule_Create(&moduledef); + #else PyObject *Module = Py_InitModule("apt_pkg",methods); + #endif PyObject *Dict = PyModule_GetDict(Module); // Global variable linked to the global configuration class @@ -549,6 +587,9 @@ extern "C" void initapt_pkg() AddInt(Dict,"InstStateReInstReq",pkgCache::State::ReInstReq); AddInt(Dict,"InstStateHold",pkgCache::State::Hold); AddInt(Dict,"InstStateHoldReInstReq",pkgCache::State::HoldReInstReq); + #if PY_MAJOR_VERSION >= 3 + return Module; + #endif } /*}}}*/ diff --git a/python/cache.cc b/python/cache.cc index 2d8b8db7..957681ba 100644 --- a/python/cache.cc +++ b/python/cache.cc @@ -239,7 +239,9 @@ static PyMappingMethods CacheMap = {0,CacheMapOp,0}; PyTypeObject PkgCacheType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgCache", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize @@ -277,7 +279,9 @@ PyTypeObject PkgCacheType = PyTypeObject PkgCacheFileType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgCacheFile", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize @@ -345,7 +349,9 @@ static PySequenceMethods PkgListSeq = PyTypeObject PkgListType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgCache::PkgIterator", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize @@ -435,7 +441,9 @@ static PyObject *PackageRepr(PyObject *Self) PyTypeObject PackageType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgCache::Package", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize @@ -498,7 +506,9 @@ static PyObject *DescriptionRepr(PyObject *Self) PyTypeObject DescriptionType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgCache::DescIterator", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize @@ -684,7 +694,9 @@ static PyObject *VersionRepr(PyObject *Self) PyTypeObject VersionType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgCache::VerIterator", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize @@ -759,7 +771,9 @@ static PyObject *PackageFileRepr(PyObject *Self) PyTypeObject PackageFileType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgCache::PkgFileIterator", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize @@ -905,7 +919,9 @@ static PyGetSetDef DependencyGetSet[] = { PyTypeObject DependencyType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgCache::DepIterator", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize @@ -991,7 +1007,9 @@ static PySequenceMethods RDepListSeq = PyTypeObject RDepListType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgCache::DepIterator", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize diff --git a/python/cdrom.cc b/python/cdrom.cc index 0816d93e..b3a38438 100644 --- a/python/cdrom.cc +++ b/python/cdrom.cc @@ -67,7 +67,9 @@ static PyMethodDef PkgCdromMethods[] = PyTypeObject PkgCdromType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "Cdrom", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize diff --git a/python/configuration.cc b/python/configuration.cc index b4adf357..eaac48ec 100644 --- a/python/configuration.cc +++ b/python/configuration.cc @@ -481,7 +481,9 @@ static PyMappingMethods ConfigurationMap = {0,CnfMap,CnfMapSet}; PyTypeObject ConfigurationType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "Configuration", // tp_name sizeof(CppPyObject), // tp_basicsize 0, // tp_itemsize @@ -515,7 +517,9 @@ PyTypeObject ConfigurationType = PyTypeObject ConfigurationPtrType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "ConfigurationPtr", // tp_name sizeof(CppPyObject), // tp_basicsize 0, // tp_itemsize @@ -549,7 +553,9 @@ PyTypeObject ConfigurationPtrType = PyTypeObject ConfigurationSubType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "ConfigurationSub", // tp_name sizeof(SubConfiguration), // tp_basicsize 0, // tp_itemsize diff --git a/python/depcache.cc b/python/depcache.cc index ade3d4f5..1c9eeff7 100644 --- a/python/depcache.cc +++ b/python/depcache.cc @@ -594,7 +594,9 @@ static PyGetSetDef PkgDepCacheGetSet[] = { PyTypeObject PkgDepCacheType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgDepCache", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize @@ -773,7 +775,9 @@ static PyMethodDef PkgProblemResolverMethods[] = PyTypeObject PkgProblemResolverType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgProblemResolver", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize @@ -829,7 +833,9 @@ static PyMethodDef PkgActionGroupMethods[] = PyTypeObject PkgActionGroupType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgActionGroup", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize diff --git a/python/generic.h b/python/generic.h index ce79a54c..6e66d24c 100644 --- a/python/generic.h +++ b/python/generic.h @@ -35,6 +35,31 @@ typedef int Py_ssize_t; #endif +/* Define compatibility for Python 3. + * + * We will use the names PyString_* to refer to the default string type + * of the current Python version (PyString on 2.X, PyUnicode on 3.X). + * + * When we really need unicode strings, we will use PyUnicode_* directly, as + * long as it exists in Python 2 and Python 3. + * + * When we want bytes in Python 3, we use PyBytes*_ instead of PyString_* and + * define aliases from PyBytes_* to PyString_* for Python 2. + */ + +#if PY_MAJOR_VERSION >= 3 +#define PyString_Check PyUnicode_Check +#define PyString_FromString PyUnicode_FromString +#define PyString_FromStringAndSize PyUnicode_FromStringAndSize +#define PyString_AsString(op) PyBytes_AsString(PyUnicode_AsUTF8String(op)) +#define PyInt_Check PyLong_Check +#define PyInt_AsLong PyLong_AsLong +#else +#define PyBytes_Check PyString_Check +#define PyBytes_AsString PyString_AsString +#define PyBytes_AsStringAndSize PyString_AsStringAndSize +#endif + template struct CppPyObject : public PyObject { // We are only using CppPyObject and friends as dumb structs only, ie the diff --git a/python/indexfile.cc b/python/indexfile.cc index dc55634f..bb40cdd0 100644 --- a/python/indexfile.cc +++ b/python/indexfile.cc @@ -81,7 +81,9 @@ static PyGetSetDef PackageIndexFileGetSet[] = { PyTypeObject PackageIndexFileType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgIndexFile", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize diff --git a/python/metaindex.cc b/python/metaindex.cc index efbc38af..cbaeafbd 100644 --- a/python/metaindex.cc +++ b/python/metaindex.cc @@ -59,7 +59,9 @@ static PyObject *MetaIndexRepr(PyObject *Self) PyTypeObject MetaIndexType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "metaIndex", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize diff --git a/python/pkgmanager.cc b/python/pkgmanager.cc index 52f86228..8f56cddc 100644 --- a/python/pkgmanager.cc +++ b/python/pkgmanager.cc @@ -95,7 +95,9 @@ static PyGetSetDef PkgManagerGetSet[] = { PyTypeObject PkgManagerType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "PackageManager", // tp_name sizeof(CppPyObject), // tp_basicsize 0, // tp_itemsize diff --git a/python/pkgrecords.cc b/python/pkgrecords.cc index 577aaf1c..978de6b7 100644 --- a/python/pkgrecords.cc +++ b/python/pkgrecords.cc @@ -135,7 +135,9 @@ static PyGetSetDef PkgRecordsGetSet[] = { PyTypeObject PkgRecordsType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgRecords", // tp_name sizeof(CppOwnedPyObject), // tp_basicsize 0, // tp_itemsize diff --git a/python/pkgsrcrecords.cc b/python/pkgsrcrecords.cc index c830f8d2..97667d7a 100644 --- a/python/pkgsrcrecords.cc +++ b/python/pkgsrcrecords.cc @@ -183,7 +183,9 @@ static PyGetSetDef PkgSrcRecordsGetSet[] = { PyTypeObject PkgSrcRecordsType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgSrcRecords", // tp_name sizeof(CppPyObject), // tp_basicsize 0, // tp_itemsize diff --git a/python/sourcelist.cc b/python/sourcelist.cc index 9f8f8878..48b3b7c8 100644 --- a/python/sourcelist.cc +++ b/python/sourcelist.cc @@ -100,7 +100,9 @@ static PyGetSetDef PkgSourceListGetSet[] = { PyTypeObject PkgSourceListType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "pkgSourceList", // tp_name sizeof(CppPyObject), // tp_basicsize 0, // tp_itemsize diff --git a/python/string.cc b/python/string.cc index 8168ea5b..b95ee3eb 100644 --- a/python/string.cc +++ b/python/string.cc @@ -38,7 +38,21 @@ PyObject *Python(PyObject *Self,PyObject *Args) \ } MkStr(StrDeQuote,DeQuoteString); -MkStr(StrBase64Encode,Base64Encode); + +/* + * Input bytes(Py3k)/str(Py2), output str. + */ +PyObject *StrBase64Encode(PyObject *Self,PyObject *Args) { + char *Str = 0; + #if PY_MAJOR_VERSION >= 3 + if (PyArg_ParseTuple(Args,"y",&Str) == 0) + #else + if (PyArg_ParseTuple(Args,"s",&Str) == 0) + #endif + return 0; + return CppPyString(Base64Encode(Str)); +} + MkStr(StrURItoFileName,URItoFileName); //MkFloat(StrSizeToStr,SizeToStr); diff --git a/python/tag.cc b/python/tag.cc index cdea3e03..18d08580 100644 --- a/python/tag.cc +++ b/python/tag.cc @@ -384,7 +384,9 @@ PyMappingMethods TagSecMapMeth = {TagSecLength,TagSecMap,0}; PyTypeObject TagSecType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "TagSection", // tp_name sizeof(TagSecData), // tp_basicsize 0, // tp_itemsize @@ -442,7 +444,9 @@ static PyGetSetDef TagFileGetSet[] = { PyTypeObject TagFileType = { PyObject_HEAD_INIT(&PyType_Type) + #if PY_MAJOR_VERSION < 3 0, // ob_size + #endif "TagFile", // tp_name sizeof(TagFileData), // tp_basicsize 0, // tp_itemsize diff --git a/setup3.py b/setup3.py new file mode 100644 index 00000000..a3cbdc8e --- /dev/null +++ b/setup3.py @@ -0,0 +1,77 @@ +#! /usr/bin/env python3 +# $Id: setup.py,v 1.2 2002/01/08 07:13:21 jgg Exp $ +import glob +import os +import shutil +import sys + +from distutils.core import setup, Extension +from distutils.sysconfig import parse_makefile +#from DistUtilsExtra.command import build_extra, build_i18n + + +# The apt_pkg module +files = ["python/"+source for source in parse_makefile("python/makefile")["APT_PKG_SRC"].split()] +apt_pkg = Extension("apt_pkg", files, libraries=["apt-pkg"]) + +# The apt_inst module +files = ["python/"+source for source in parse_makefile("python/makefile")["APT_INST_SRC"].split()] +apt_inst = Extension("apt_inst", files, libraries=["apt-pkg", "apt-inst"]) + +# Replace the leading _ that is used in the templates for translation +templates = [] + +# build doc +if len(sys.argv) > 1 and sys.argv[1] == "build": + if not os.path.exists("build/data/templates/"): + os.makedirs("build/data/templates") + for template in glob.glob('data/templates/*.info.in'): + source = open(template, "r") + build = open(os.path.join("build", template[:-3]), "w") + lines = source.readlines() + for line in lines: + build.write(line.lstrip("_")) + source.close() + build.close() + + +if len(sys.argv) > 1 and sys.argv[1] == "clean" and '-a' in sys.argv: + for dirname in "build/doc", "doc/build", "build/data", "build/mo": + if os.path.exists(dirname): + print("Removing", dirname) + shutil.rmtree(dirname) + else: + print("Not removing", dirname, "because it does not exist") + +setup(name="python-apt", + description="Python bindings for APT", + version=os.environ.get('DEBVER'), + author="APT Development Team", + author_email="deity@lists.debian.org", + ext_modules=[apt_pkg, apt_inst], + packages=['apt', 'apt.progress', 'aptsources'], + data_files = [('share/python-apt/templates', + glob.glob('build/data/templates/*.info')), + ('share/python-apt/templates', + glob.glob('data/templates/*.mirrors'))], +# cmdclass = {"build": build_extra.build_extra, +# "build_i18n": build_i18n.build_i18n}, + license = 'GNU GPL', + platforms = 'posix') + +if len(sys.argv) > 1 and sys.argv[1] == "build": + try: + import sphinx + except ImportError: + print(('W: Sphinx not available - Not building' + 'documentation'), file=sys.stderr) + try: + import pygtk + except ImportError: + print(('W: Not building documentation because python-' + 'gtk2 is not available at the moment.'), file=sys.stderr) + sys.exit(0) + sphinx.main(["sphinx", "-b", "html", "-d", "build/doc/doctrees", + os.path.abspath("doc/source"), "build/doc/html"]) + sphinx.main(["sphinx", "-b", "text", "-d", "build/doc/doctrees", + os.path.abspath("doc/source"), "build/doc/text"]) -- cgit v1.2.3 From 337c885e7dd531858c35b256d974989bac6463df Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Thu, 16 Apr 2009 20:06:14 +0200 Subject: * apt/*.py: Initial rename work for Bug#481061 A new module, apt.deprecation, is introduced containing functions and classes which assist in the deprecation. The apt_pkg extension gets a new attribute, _COMPAT_0_7 which can be set by defining COMPAT_0_7 at compile time (-DCOMPAT_0_7). The names are changed, and compatibility functions are enabled if bool(apt_pkg._COMPAT_0_7) == True, i.e. if the package has been built with backward compatibility fixes. This commit changes the apt and aptsources packages, the apt_pkg and apt_inst extensions will be the next renames. --- apt/__init__.py | 15 ++++-- apt/cache.py | 108 +++++++++++++++++++++++++-------------- apt/cdrom.py | 6 ++- apt/debfile.py | 32 ++++++------ apt/deprecation.py | 76 ++++++++++++++++++++++++++++ apt/package.py | 126 +++++++++++++++++++++++++++++++--------------- apt/progress/gtk2.py | 6 +-- aptsources/sourceslist.py | 6 ++- debian/changelog | 6 +++ debian/control | 2 +- debian/rules | 3 ++ po/python-apt.pot | 10 ++-- python/apt_pkgmodule.cc | 6 +++ 13 files changed, 290 insertions(+), 112 deletions(-) create mode 100644 apt/deprecation.py (limited to 'apt') diff --git a/apt/__init__.py b/apt/__init__.py index ae2abbf2..734b3240 100644 --- a/apt/__init__.py +++ b/apt/__init__.py @@ -17,17 +17,21 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # USA # import the core of apt_pkg +"""High-Level Interface for working with apt.""" import apt_pkg -import sys -import os # import some fancy classes from apt.package import Package from apt.cache import Cache -from apt.progress import ( - OpProgress, FetchProgress, InstallProgress, CdromProgress) from apt.cdrom import Cdrom -from apt_pkg import SizeToStr, TimeToStr, VersionCompare + +if apt_pkg._COMPAT_0_7: + from apt.progress import (OpProgress, FetchProgress, InstallProgress, + CdromProgress) + + +if apt_pkg._COMPAT_0_7: + from apt_pkg import SizeToStr, TimeToStr, VersionCompare # init the package system apt_pkg.init() @@ -36,3 +40,4 @@ apt_pkg.init() #import warnings #warnings.warn("apt API not stable yet", FutureWarning) #del warnings +__all__ = ['Cache', 'Cdrom', 'Package'] diff --git a/apt/cache.py b/apt/cache.py index d13010af..928322d2 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -24,6 +24,7 @@ import weakref import apt_pkg from apt import Package +from apt.deprecation import AttributeDeprecatedBy, function_deprecated_by import apt.progress @@ -63,7 +64,7 @@ class Cache(object): rootdir + "/var/lib/dpkg/status") self.open(progress) - def _runCallbacks(self, name): + def _run_callbacks(self, name): """ internal helper to run a callback """ if name in self._callbacks: for callback in self._callbacks[name]: @@ -75,7 +76,7 @@ class Cache(object): """ if progress is None: progress = apt.progress.OpProgress() - self._runCallbacks("cache_pre_open") + self._run_callbacks("cache_pre_open") self._cache = apt_pkg.GetCache(progress) self._depcache = apt_pkg.GetDepCache(self._cache) self._records = apt_pkg.GetPkgRecords(self._cache) @@ -98,7 +99,7 @@ class Cache(object): i += 1 progress.done() - self._runCallbacks("cache_post_open") + self._run_callbacks("cache_post_open") def __getitem__(self, key): """ look like a dictionary (get key) """ @@ -128,12 +129,12 @@ class Cache(object): def keys(self): return list(self._set) - def getChanges(self): + def get_changes(self): """ Get the marked changes """ changes = [] for p in self: - if p.markedUpgrade or p.markedInstall or p.markedDelete or \ - p.markedDowngrade or p.markedReinstall: + if p.marked_upgrade or p.marked_install or p.marked_delete or \ + p.marked_downgrade or p.marked_reinstall: changes.append(p) return changes @@ -141,12 +142,12 @@ class Cache(object): """ Upgrade the all package, DistUpgrade will also install new dependencies """ - self.cachePreChange() + self.cache_pre_change() self._depcache.Upgrade(distUpgrade) - self.cachePostChange() + self.cache_post_change() @property - def requiredDownload(self): + def required_download(self): """Get the size of the packages that are required to download.""" pm = apt_pkg.GetPackageManager(self._depcache) fetcher = apt_pkg.GetAcquire() @@ -154,12 +155,12 @@ class Cache(object): return fetcher.FetchNeeded @property - def additionalRequiredSpace(self): + def required_space(self): """Get the size of the additional required space on the fs.""" return self._depcache.UsrSize @property - def reqReinstallPkgs(self): + def req_reinstall_pkgs(self): """Return the packages not downloadable packages in reqreinst state.""" reqreinst = set() for pkg in self: @@ -169,7 +170,7 @@ class Cache(object): reqreinst.add(pkg.name) return reqreinst - def _runFetcher(self, fetcher): + def _run_fetcher(self, fetcher): # do the actual fetching res = fetcher.Run() @@ -194,7 +195,7 @@ class Cache(object): raise FetchFailedException(errMsg) return res - def _fetchArchives(self, fetcher, pm): + def _fetch_archives(self, fetcher, pm): """ fetch the needed archives """ # get lock @@ -209,16 +210,16 @@ class Cache(object): return False # now run the fetcher, throw exception if something fails to be # fetched - return self._runFetcher(fetcher) + return self._run_fetcher(fetcher) finally: os.close(lock) - def isVirtualPackage(self, pkgname): + def is_virtual_package(self, pkgname): """Return whether the package is a virtual package.""" pkg = self._cache[pkgname] return bool(pkg.ProvidesList and not pkg.VersionList) - def getProvidingPackages(self, virtual): + def get_providing_packages(self, virtual): """ Return a list of packages which provide the virtual package of the specified name @@ -254,10 +255,16 @@ class Cache(object): finally: os.close(lock) - def installArchives(self, pm, installProgress): - installProgress.startUpdate() + def install_archives(self, pm, installProgress): + try: + installProgress.start_update() + except AttributeError: + installProgress.startUpdate() res = installProgress.run(pm) - installProgress.finishUpdate() + try: + installProgress.finish_update() + except AttributeError: + installProgress.finishUpdate() return res def commit(self, fetchProgress=None, installProgress=None): @@ -278,10 +285,10 @@ class Cache(object): fetcher = apt_pkg.GetAcquire(fetchProgress) while True: # fetch archives first - res = self._fetchArchives(fetcher, pm) + res = self._fetch_archives(fetcher, pm) # then install - res = self.installArchives(pm, installProgress) + res = self.install_archives(pm, installProgress) if res == pm.ResultCompleted: break if res == pm.ResultFailed: @@ -296,14 +303,14 @@ class Cache(object): # cache changes - def cachePostChange(self): + def cache_post_change(self): " called internally if the cache has changed, emit a signal then " - self._runCallbacks("cache_post_change") + self._run_callbacks("cache_post_change") - def cachePreChange(self): + def cache_pre_change(self): """ called internally if the cache is about to change, emit a signal then """ - self._runCallbacks("cache_pre_change") + self._run_callbacks("cache_pre_change") def connect(self, name, callback): """ connect to a signal, currently only used for @@ -312,6 +319,20 @@ class Cache(object): self._callbacks[name] = [] self._callbacks[name].append(callback) + if apt_pkg._COMPAT_0_7: + _runCallbacks = function_deprecated_by(_run_callbacks) + getChanges = function_deprecated_by(get_changes) + requiredDownload = AttributeDeprecatedBy('required_download') + additionalRequiredSpace = AttributeDeprecatedBy('required_space') + reqReinstallPkgs = AttributeDeprecatedBy('req_reinstall_pkgs') + _runFetcher = function_deprecated_by(_run_fetcher) + _fetchArchives = function_deprecated_by(_fetch_archives) + isVirtualPackage = function_deprecated_by(is_virtual_package) + getProvidingPackages = function_deprecated_by(get_providing_packages) + installArchives = function_deprecated_by(install_archives) + cachePostChange = function_deprecated_by(cache_post_change) + cachePreChange = function_deprecated_by(cache_pre_change) + # ----------------------------- experimental interface @@ -330,7 +351,7 @@ class MarkedChangesFilter(Filter): """ Filter that returns all marked changes """ def apply(self, pkg): - if pkg.markedInstall or pkg.markedDelete or pkg.markedUpgrade: + if pkg.marked_install or pkg.marked_delete or pkg.marked_upgrade: return True else: return False @@ -347,8 +368,8 @@ class FilteredCache(object): self.cache = Cache(progress) else: self.cache = cache - self.cache.connect("cache_post_change", self.filterCachePostChange) - self.cache.connect("cache_post_open", self.filterCachePostChange) + self.cache.connect("cache_post_change", self.filter_cache_post_change) + self.cache.connect("cache_post_open", self.filter_cache_post_change) self._filtered = {} self._filters = [] @@ -371,7 +392,7 @@ class FilteredCache(object): def __contains__(self, key): return (key in self._filtered) - def _reapplyFilter(self): + def _reapply_filter(self): " internal helper to refilter " self._filtered = {} for pkg in self.cache: @@ -380,18 +401,19 @@ class FilteredCache(object): self._filtered[pkg.name] = 1 break - def setFilter(self, filter): + def set_filter(self, filter): """Set the current active filter.""" self._filters = [] self._filters.append(filter) #self._reapplyFilter() # force a cache-change event that will result in a refiltering - self.cache.cachePostChange() + self.cache.cache_post_change() - def filterCachePostChange(self): + def filter_cache_post_change(self): """Called internally if the cache changes, emit a signal then.""" #print "filterCachePostChange()" - self._reapplyFilter() + self._reapply_filter() + # def connect(self, name, callback): # self.cache.connect(name, callback) @@ -401,6 +423,12 @@ class FilteredCache(object): #print "getattr: %s " % key return getattr(self.cache, key) + if apt_pkg._COMPAT_0_7: + _reapplyFilter = function_deprecated_by(_reapply_filter) + setFilter = function_deprecated_by(set_filter) + filterCachePostChange = function_deprecated_by(\ + filter_cache_post_change) + def cache_pre_changed(): print "cache pre changed" @@ -410,8 +438,8 @@ def cache_post_changed(): print "cache post changed" -# internal test code -if __name__ == "__main__": +def _test(): + """Internal test code.""" print "Cache self test" apt_pkg.init() c = Cache(apt.progress.OpTextProgress()) @@ -426,7 +454,7 @@ if __name__ == "__main__": x= c[pkg].name c.upgrade() - changes = c.getChanges() + changes = c.get_changes() print len(changes) for p in changes: #print p.name @@ -440,7 +468,7 @@ if __name__ == "__main__": apt_pkg.Config.Set("Dir::Cache::Archives", "/tmp/pytest") pm = apt_pkg.GetPackageManager(c._depcache) fetcher = apt_pkg.GetAcquire(apt.progress.TextFetchProgress()) - c._fetchArchives(fetcher, pm) + c._fetch_archives(fetcher, pm) #sys.exit(1) print "Testing filtered cache (argument is old cache)" @@ -448,7 +476,7 @@ if __name__ == "__main__": f.cache.connect("cache_pre_change", cache_pre_changed) f.cache.connect("cache_post_change", cache_post_changed) f.cache.upgrade() - f.setFilter(MarkedChangesFilter()) + f.set_filter(MarkedChangesFilter()) print len(f) for pkg in f.keys(): #print c[pkg].name @@ -461,10 +489,12 @@ if __name__ == "__main__": f.cache.connect("cache_pre_change", cache_pre_changed) f.cache.connect("cache_post_change", cache_post_changed) f.cache.upgrade() - f.setFilter(MarkedChangesFilter()) + f.set_filter(MarkedChangesFilter()) print len(f) for pkg in f.keys(): #print c[pkg].name x = f[pkg].name print len(f) +if __name__ == '__main__': + _test() diff --git a/apt/cdrom.py b/apt/cdrom.py index b52762ad..907ac622 100644 --- a/apt/cdrom.py +++ b/apt/cdrom.py @@ -24,6 +24,7 @@ import glob import apt_pkg from apt.progress import CdromProgress +from apt.deprecation import AttributeDeprecatedBy class Cdrom(object): @@ -69,7 +70,7 @@ class Cdrom(object): return ident @property - def inSourcesList(self): + def in_sources_list(self): """Check if the cdrom is already in the current sources.list.""" cd_id = self.ident() if cd_id is None: @@ -84,3 +85,6 @@ class Cdrom(object): if not line.lstrip().startswith("#") and cd_id in line: return True return False + + if apt_pkg._COMPAT_0_7: + inSourcesList = AttributeDeprecatedBy('in_sources_list') diff --git a/apt/debfile.py b/apt/debfile.py index 8d4f534c..c60fc92d 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -97,11 +97,11 @@ class DebPackage(object): # check for virtual pkgs if not depname in self._cache: - if self._cache.isVirtualPackage(depname): + if self._cache.is_virtual_package(depname): self._dbg(3, "_isOrGroupSatisfied(): %s is virtual dep" % depname) - for pkg in self._cache.getProvidingPackages(depname): - if pkg.isInstalled: + for pkg in self._cache.get_providing_packages(depname): + if pkg.is_installed: return True continue @@ -117,9 +117,9 @@ class DebPackage(object): # if we don't have it in the cache, it may be virtual if not depname in self._cache: - if not self._cache.isVirtualPackage(depname): + if not self._cache.is_virtual_package(depname): continue - providers = self._cache.getProvidingPackages(depname) + providers = self._cache.get_providing_packages(depname) # if a package just has a single virtual provider, we # just pick that (just like apt) if len(providers) != 1: @@ -158,9 +158,9 @@ class DebPackage(object): (pkgname, ver, oper)) pkg = self._cache[pkgname] - if pkg.isInstalled: + if pkg.is_installed: pkgver = pkg.installed.version - elif pkg.markedInstall: + elif pkg.marked_install: pkgver = pkg.candidate.version else: return False @@ -191,8 +191,8 @@ class DebPackage(object): if not depname in self._cache: # FIXME: we have to check for virtual replaces here as # well (to pass tests/gdebi-test8.deb) - if self._cache.isVirtualPackage(depname): - for pkg in self._cache.getProvidingPackages(depname): + if self._cache.is_virtual_package(depname): + for pkg in self._cache.get_providing_packages(depname): self._dbg(3, "conflicts virtual check: %s" % pkg.name) # P/C/R on virtal pkg, e.g. ftpd if self.pkgname == pkg.name: @@ -253,9 +253,9 @@ class DebPackage(object): """ self._dbg(3, "replacesPkg() %s %s %s" % (pkgname, oper, ver)) pkg = self._cache[pkgname] - if pkg.isInstalled: + if pkg.is_installed: pkgver = pkg.installed.version - elif pkg.markedInstall: + elif pkg.marked_install: pkgver = pkg.candidate.version else: pkgver = None @@ -371,7 +371,7 @@ class DebPackage(object): # now try it out in the cache for pkg in self._need_pkgs: try: - self._cache[pkg].markInstall(fromUser=False) + self._cache[pkg].mark_install(fromUser=False) except SystemError, e: self._failure_string = _("Cannot install '%s'" % pkg) self._cache.clear() @@ -396,7 +396,7 @@ class DebPackage(object): remove = [] unauthenticated = [] for pkg in self._cache: - if pkg.markedInstall or pkg.markedUpgrade: + if pkg.marked_install or pkg.marked_upgrade: install.append(pkg.name) # check authentication, one authenticated origin is enough # libapt will skip non-authenticated origins then @@ -405,7 +405,7 @@ class DebPackage(object): authenticated |= origin.trusted if not authenticated: unauthenticated.append(pkg.name) - if pkg.markedDelete: + if pkg.marked_delete: remove.append(pkg.name) return (install, remove, unauthenticated) @@ -492,7 +492,7 @@ class DscSrcPackage(DebPackage): for pkgname in self._installed_conflicts: if self._cache[pkgname]._pkg.Essential: raise Exception(_("An essential package would be removed")) - self._cache[pkgname].markDelete() + self._cache[pkgname].mark_delete() # FIXME: a additional run of the checkConflicts() # after _satisfyDepends() should probably be done return self._satisfy_depends(self.depends) @@ -507,7 +507,7 @@ def _test(): vp = "www-browser" #print "%s virtual: %s" % (vp, cache.isVirtualPackage(vp)) - providers = cache.getProvidingPackages(vp) + providers = cache.get_providing_packages(vp) print "Providers for %s :" % vp for pkg in providers: print " %s" % pkg.name diff --git a/apt/deprecation.py b/apt/deprecation.py new file mode 100644 index 00000000..a14d49e6 --- /dev/null +++ b/apt/deprecation.py @@ -0,0 +1,76 @@ +# deprecation.py - Module providing classes and functions for deprecation. +# +# Copyright (c) 2009 Julian Andres Klode +# Copyright (c) 2009 Ben Finney +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA +"""Classes and functions for deprecating features. + +This is used for internal purposes only and not part of the official API. Do +not use it for anything outside the apt package. +""" +import re +import operator +import warnings + +__all__ = [] + + +class AttributeDeprecatedBy(object): + """Property acting as a proxy for a new attribute. + + When accessed, the property issues a DeprecationWarning and (on get) calls + attrgetter() for the attribute 'attribute' on the current object or (on + set) uses setattr to set the value of the wrapped attribute. + """ + + def __init__(self, attribute): + """Initialize the property.""" + self.attribute = attribute + self.__doc__ = 'Deprecated, please use \'%s\' instead' % attribute + self.getter = operator.attrgetter(attribute) + + def __get__(self, obj, type=None): + """Issue a DeprecationWarning and return the requested value.""" + if obj is None: + return getattr(type, self.attribute, self) + warnings.warn(self.__doc__, DeprecationWarning, stacklevel=2) + return self.getter(obj or type) + + def __set__(self, obj, value): + """Issue a DeprecationWarning and set the requested value.""" + warnings.warn(self.__doc__, DeprecationWarning, stacklevel=2) + setattr(obj, self.attribute, value) + + +def function_deprecated_by(func, convert_names=True): + """Return a function that warns it is deprecated by another function. + + Returns a new function that warns it is deprecated by function 'func', + then acts as a pass-through wrapper for 'func'. + + This function also converts all keyword argument names from mixedCase to + lowercase_with_underscores, but only if 'convert_names' is True (default). + """ + warning = 'Deprecated, please use \'%s\' instead' % func.func_name + + def deprecated_function(*args, **kwds): + warnings.warn(warning, DeprecationWarning, stacklevel=2) + if convert_names: + for key in kwds.keys(): + kwds[re.sub('([A-Z])', '_\\1', key).lower()] = kwds.pop(key) + return func(*args, **kwds) + return deprecated_function diff --git a/apt/package.py b/apt/package.py index db5696ae..70997383 100644 --- a/apt/package.py +++ b/apt/package.py @@ -31,6 +31,7 @@ import warnings import apt_pkg import apt.progress +from apt.deprecation import function_deprecated_by, AttributeDeprecatedBy __all__ = ('BaseDependency', 'Dependency', 'Origin', 'Package', 'Record', 'Version') @@ -56,21 +57,24 @@ class BaseDependency(object): """A single dependency. Attributes defined here: - name - The name of the dependency - relation - The relation (>>,>=,==,<<,<=,) - version - The version depended on - preDepend - Boolean value whether this is a pre-dependency. + name - The name of the dependency + relation - The relation (>>,>=,==,<<,<=,) + version - The version depended on + pre_depend - Boolean value whether this is a pre-dependency. """ def __init__(self, name, rel, ver, pre): self.name = name self.relation = rel self.version = ver - self.preDepend = pre + self.pre_depend = pre def __repr__(self): return ('' - % (self.name, self.relation, self.version, self.preDepend)) + % (self.name, self.relation, self.version, self.pre_depend)) + + if apt_pkg._COMPAT_0_7: + preDepend = AttributeDeprecatedBy('pre_depend') class Dependency(object): @@ -103,7 +107,7 @@ class DeprecatedProperty(property): warnings.warn("Accessed deprecated property %s.%s, please see the " "Version class for alternatives." % ((obj.__class__.__name__ or type.__name__), - self.fget.func_name), DeprecationWarning, 2) + self.fget.__name__), DeprecationWarning, 2) return property.__get__(self, obj, type) @@ -528,9 +532,9 @@ class Package(object): def __set_candidate(self, version): """Set the candidate version of the package.""" - self._pcache.cachePreChange() + self._pcache.cache_pre_change() self._pcache._depcache.SetCandidateVer(self._pkg, version._cand) - self._pcache.cachePostChange() + self._pcache.cache_post_change() candidate = property(candidate, __set_candidate) @@ -703,55 +707,56 @@ class Package(object): # depcache states @property - def markedInstall(self): + def marked_install(self): """Return ``True`` if the package is marked for install.""" return self._pcache._depcache.MarkedInstall(self._pkg) @property - def markedUpgrade(self): + def marked_upgrade(self): """Return ``True`` if the package is marked for upgrade.""" return self._pcache._depcache.MarkedUpgrade(self._pkg) @property - def markedDelete(self): + def marked_delete(self): """Return ``True`` if the package is marked for delete.""" return self._pcache._depcache.MarkedDelete(self._pkg) @property - def markedKeep(self): + def marked_keep(self): """Return ``True`` if the package is marked for keep.""" return self._pcache._depcache.MarkedKeep(self._pkg) @property - def markedDowngrade(self): + def marked_downgrade(self): """ Package is marked for downgrade """ return self._pcache._depcache.MarkedDowngrade(self._pkg) @property - def markedReinstall(self): + def marked_reinstall(self): """Return ``True`` if the package is marked for reinstall.""" return self._pcache._depcache.MarkedReinstall(self._pkg) @property - def isInstalled(self): + def is_installed(self): """Return ``True`` if the package is installed.""" return (self._pkg.CurrentVer is not None) @property - def isUpgradable(self): + def is_upgradable(self): """Return ``True`` if the package is upgradable.""" - return (self.isInstalled and + return (self.is_installed and self._pcache._depcache.IsUpgradable(self._pkg)) @property - def isAutoRemovable(self): + def is_auto_removable(self): """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 is no longer required. """ - return self.isInstalled and self._pcache._depcache.IsGarbage(self._pkg) + return self.is_installed and \ + self._pcache._depcache.IsGarbage(self._pkg) # sizes @@ -789,7 +794,7 @@ class Package(object): return getattr(self.installed, 'installed_size', 0) @property - def installedFiles(self): + def installed_files(self): """Return a list of files installed by the package. Return a list of unicode names of the files which have @@ -805,7 +810,7 @@ class Package(object): except EnvironmentError: return [] - def getChangelog(self, uri=None, cancel_lock=None): + def get_changelog(self, uri=None, cancel_lock=None): """ Download the changelog of the package and return it as unicode string. @@ -928,7 +933,7 @@ class Package(object): if match: # strip epoch from installed version # and from changelog too - installed = self.installedVersion + installed = getattr(self.installed, 'version', None) if installed and ":" in installed: installed = installed.split(":", 1)[1] changelog_ver = match.group(1) @@ -976,13 +981,13 @@ class Package(object): # depcache actions - def markKeep(self): + def mark_keep(self): """Mark a package for keep.""" - self._pcache.cachePreChange() + self._pcache.cache_pre_change() self._pcache._depcache.MarkKeep(self._pkg) - self._pcache.cachePostChange() + self._pcache.cache_post_change() - def markDelete(self, autoFix=True, purge=False): + def mark_delete(self, autoFix=True, purge=False): """Mark a package for install. If *autoFix* is ``True``, the resolver will be run, trying to fix @@ -991,7 +996,7 @@ class Package(object): 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.cache_pre_change() self._pcache._depcache.MarkDelete(self._pkg, purge) # try to fix broken stuffsta if autoFix and self._pcache._depcache.BrokenCount > 0: @@ -1001,9 +1006,9 @@ class Package(object): Fix.Remove(self._pkg) Fix.InstallProtect() Fix.Resolve() - self._pcache.cachePostChange() + self._pcache.cache_post_change() - def markInstall(self, autoFix=True, autoInst=True, fromUser=True): + def mark_install(self, autoFix=True, autoInst=True, fromUser=True): """Mark a package for install. If *autoFix* is ``True``, the resolver will be run, trying to fix @@ -1017,7 +1022,7 @@ class Package(object): 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.cache_pre_change() self._pcache._depcache.MarkInstall(self._pkg, autoInst, fromUser) # try to fix broken stuff if autoFix and self._pcache._depcache.BrokenCount > 0: @@ -1025,12 +1030,12 @@ class Package(object): fixer.Clear(self._pkg) fixer.Protect(self._pkg) fixer.Resolve(True) - self._pcache.cachePostChange() + self._pcache.cache_post_change() - def markUpgrade(self): + def mark_upgrade(self): """Mark a package for upgrade.""" - if self.isUpgradable: - self.markInstall() + if self.is_upgradable: + self.mark_install() else: # FIXME: we may want to throw a exception here sys.stderr.write(("MarkUpgrade() called on a non-upgrable pkg: " @@ -1048,11 +1053,50 @@ class Package(object): self._pcache._depcache.Commit(fprogress, iprogress) + if not apt_pkg._COMPAT_0_7: + del installedVersion + del candidateVersion + del candidateDependencies + del installedDependencies + del architecture + del candidateDownloadable + del installedDownloadable + del sourcePackageName + del homepage + del priority + del installedPriority + del summary + del description + del rawDescription + del candidateRecord + del installedRecord + del packageSize + del installedPackageSize + del candidateInstalledSize + del installedSize + del candidateOrigin + else: + markedInstalled = AttributeDeprecatedBy('marked_installed') + markedUpgrade = AttributeDeprecatedBy('marked_upgrade') + markedDelete = AttributeDeprecatedBy('marked_delete') + markedKeep = AttributeDeprecatedBy('marked_keep') + markedDowngrade = AttributeDeprecatedBy('marked_downgrade') + markedReinstall = AttributeDeprecatedBy('marked_reinstall') + isInstalled = AttributeDeprecatedBy('is_installed') + isUpgradable = AttributeDeprecatedBy('is_upgradable') + isAutoRemovable = AttributeDeprecatedBy('is_auto_removable') + installedFiles = AttributeDeprecatedBy('installed_files') + getChangelog = function_deprecated_by(get_changelog) + markDelete = function_deprecated_by(mark_delete) + markInstall = function_deprecated_by(mark_install) + markKeep = function_deprecated_by(mark_keep) + markUpgrade = function_deprecated_by(mark_upgrade) + + def _test(): """Self-test.""" print "Self-test for the Package modul" import random - import apt apt_pkg.init() progress = apt.progress.OpTextProgress() cache = apt.Cache(progress) @@ -1075,19 +1119,19 @@ def _test(): print "Dependencies: %s" % pkg.installed.dependencies for dep in pkg.candidate.dependencies: print ",".join("%s (%s) (%s) (%s)" % (o.name, o.version, o.relation, - o.preDepend) for o in dep.or_dependencies) + o.pre_depend) for o in dep.or_dependencies) print "arch: %s" % pkg.candidate.architecture print "homepage: %s" % pkg.candidate.homepage print "rec: ", pkg.candidate.record - print cache["2vcard"].getChangelog() + print cache["2vcard"].get_changelog() for i in True, False: print "Running install on random upgradable pkgs with AutoFix: %s " % i for pkg in cache: - if pkg.isUpgradable: + if pkg.is_upgradable: if random.randint(0, 1) == 1: - pkg.markInstall(i) + pkg.mark_install(i) print "Broken: %s " % cache._depcache.BrokenCount print "InstCount: %s " % cache._depcache.InstCount @@ -1099,7 +1143,7 @@ def _test(): for name in cache.keys(): if random.randint(0, 1) == 1: try: - cache[name].markDelete(i) + cache[name].mark_delete(i) except SystemError: print "Error trying to remove: %s " % name print "Broken: %s " % cache._depcache.BrokenCount diff --git a/apt/progress/gtk2.py b/apt/progress/gtk2.py index f872e34f..36d459bc 100644 --- a/apt/progress/gtk2.py +++ b/apt/progress/gtk2.py @@ -422,10 +422,10 @@ def _test(): win.show() cache = apt.cache.Cache(apt_progress.open) pkg = cache["xterm"] - if pkg.isInstalled: - pkg.markDelete() + if pkg.is_installed: + pkg.mark_delete() else: - pkg.markInstall() + pkg.mark_install() apt_progress.show_terminal(True) try: cache.commit(apt_progress.fetch, apt_progress.install) diff --git a/aptsources/sourceslist.py b/aptsources/sourceslist.py index 1dfd870f..fdc0f029 100644 --- a/aptsources/sourceslist.py +++ b/aptsources/sourceslist.py @@ -33,6 +33,7 @@ import time import apt_pkg from aptsources.distinfo import DistInfo +from apt.deprecation import function_deprecated_by # some global helpers @@ -309,7 +310,7 @@ class SourcesList(object): """ remove the specified entry from the sources.list """ self.list.remove(source_entry) - def restoreBackup(self, backup_ext): + def restore_backup(self, backup_ext): " restore sources.list files based on the backup extension " file = apt_pkg.Config.FindFile("Dir::Etc::sourcelist") if os.path.exists(file+backup_ext) and \ @@ -321,6 +322,9 @@ class SourcesList(object): if os.path.exists(file+backup_ext): shutil.copy(file+backup_ext, file) + if apt_pkg._COMPAT_0_7: + restoreBackup = function_deprecated_by(restore_backup) + def backup(self, backup_ext=None): """ make a backup of the current source files, if no backup extension is given, the current date/time is used (and returned) """ diff --git a/debian/changelog b/debian/changelog index b2f2b965..e344c145 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +python-apt (0.7.91) UNRELEASED; urgency=low + + * Rename all methods,functions,attributes to conform to PEP 8 (Closes: #481061) + + -- Julian Andres Klode Thu, 16 Apr 2009 18:54:29 +0200 + python-apt (0.7.90) experimental; urgency=low * Introduce support for Python 3 (Closes: #523645) diff --git a/debian/control b/debian/control index 08ee329f..374a177c 100644 --- a/debian/control +++ b/debian/control @@ -4,7 +4,7 @@ Priority: optional Maintainer: APT Development Team Uploaders: Michael Vogt , Julian Andres Klode Standards-Version: 3.8.1 -XS-Python-Version: all +XS-Python-Version: >= 2.5 Build-Depends: apt-utils, cdbs, debhelper (>= 5.0.37.1), diff --git a/debian/rules b/debian/rules index 9d0219e2..5fc6e13b 100755 --- a/debian/rules +++ b/debian/rules @@ -16,6 +16,9 @@ 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) + +# Define COMPAT_0_7 to get all the deprecated interfaces. +export CFLAGS+=-DCOMPAT_0_7 export DEBVER diff --git a/po/python-apt.pot b/po/python-apt.pot index d12ae967..3fcd395a 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-15 16:10+0200\n" +"POT-Creation-Date: 2009-04-16 19:54+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -354,16 +354,16 @@ msgstr "" msgid "Complete" msgstr "" -#: ../apt/package.py:282 +#: ../apt/package.py:286 #, python-format msgid "Invalid unicode in description for '%s' (%s). Please report." msgstr "" -#: ../apt/package.py:830 ../apt/package.py:934 +#: ../apt/package.py:846 ../apt/package.py:950 msgid "The list of changes is not available" msgstr "" -#: ../apt/package.py:938 +#: ../apt/package.py:954 #, 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:944 +#: ../apt/package.py:960 msgid "" "Failed to download the list of changes. \n" "Please check your Internet connection." diff --git a/python/apt_pkgmodule.cc b/python/apt_pkgmodule.cc index 3beec747..a056b0bc 100644 --- a/python/apt_pkgmodule.cc +++ b/python/apt_pkgmodule.cc @@ -589,6 +589,12 @@ extern "C" void initapt_pkg() AddInt(Dict,"InstStateReInstReq",pkgCache::State::ReInstReq); AddInt(Dict,"InstStateHold",pkgCache::State::Hold); AddInt(Dict,"InstStateHoldReInstReq",pkgCache::State::HoldReInstReq); + + #ifdef COMPAT_0_7 + AddInt(Dict,"_COMPAT_0_7",1); + #else + AddInt(Dict,"_COMPAT_0_7",0); + #endif #if PY_MAJOR_VERSION >= 3 return Module; #endif -- cgit v1.2.3 From 43605018bd3b0f6b0bf26736b7e13c170131883a Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 17 Apr 2009 17:00:29 +0200 Subject: * apt/deprecation.py: Add deprecated_args() The function deprecated_args() is used in case a function name is kept, but the function previously had parameters in mixedCase names. --- apt/deprecation.py | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) (limited to 'apt') diff --git a/apt/deprecation.py b/apt/deprecation.py index a14d49e6..6827a8b9 100644 --- a/apt/deprecation.py +++ b/apt/deprecation.py @@ -26,6 +26,8 @@ import re import operator import warnings +import apt_pkg + __all__ = [] @@ -43,12 +45,12 @@ class AttributeDeprecatedBy(object): self.__doc__ = 'Deprecated, please use \'%s\' instead' % attribute self.getter = operator.attrgetter(attribute) - def __get__(self, obj, type=None): + def __get__(self, obj, type_=None): """Issue a DeprecationWarning and return the requested value.""" if obj is None: - return getattr(type, self.attribute, self) + return getattr(type_, self.attribute, self) warnings.warn(self.__doc__, DeprecationWarning, stacklevel=2) - return self.getter(obj or type) + return self.getter(obj or type_) def __set__(self, obj, value): """Issue a DeprecationWarning and set the requested value.""" @@ -65,12 +67,40 @@ def function_deprecated_by(func, convert_names=True): This function also converts all keyword argument names from mixedCase to lowercase_with_underscores, but only if 'convert_names' is True (default). """ - warning = 'Deprecated, please use \'%s\' instead' % func.func_name + warning = 'Deprecated, please use \'%s\' instead' % func.__name__ def deprecated_function(*args, **kwds): + """Wrapper around a deprecated function.""" warnings.warn(warning, DeprecationWarning, stacklevel=2) if convert_names: for key in kwds.keys(): kwds[re.sub('([A-Z])', '_\\1', key).lower()] = kwds.pop(key) return func(*args, **kwds) return deprecated_function + + +def deprecated_args(func): + """A function with deprecated arguments. + + Similar to function_deprecated_by() but warns on every deprecated argument + instead of function calls. + """ + if not apt_pkg._COMPAT_0_7: + return func + + def deprecated_function(*args, **kwds): + """Wrapper around a function with deprecated arguments.""" + for key in kwds.keys(): + new_key = re.sub('([A-Z])', '_\\1', key).lower() + if new_key != key: + warnings.warn("Deprecated parameter %r" % key) + kwds[new_key] = kwds.pop(key) + return func(*args, **kwds) + + # Wrap the function completely (same as functools.wraps) + # pylint: disable-msg=W0622 + deprecated_function.__name__ = func.__name__ + deprecated_function.__doc__ = func.__doc__ + deprecated_function.__module__ = func.__module__ + deprecated_function.__dict__.update(func.__dict__) + return deprecated_function -- cgit v1.2.3 From 5b6ecbeef7e5a2dbc02e026f086ac2d9f185a546 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 17 Apr 2009 17:12:35 +0200 Subject: * apt/cache.py, apt/package.py: Rename the remaining arguments and variables. --- apt/cache.py | 176 +++++++++++++++++++++++++++++++++------------------------ apt/package.py | 92 +++++++++++++++--------------- 2 files changed, 148 insertions(+), 120 deletions(-) (limited to 'apt') diff --git a/apt/cache.py b/apt/cache.py index 928322d2..05d8d1a9 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -24,7 +24,8 @@ import weakref import apt_pkg from apt import Package -from apt.deprecation import AttributeDeprecatedBy, function_deprecated_by +from apt.deprecation import (AttributeDeprecatedBy, function_deprecated_by, + deprecated_args) import apt.progress @@ -132,18 +133,22 @@ class Cache(object): def get_changes(self): """ Get the marked changes """ changes = [] - for p in self: - if p.marked_upgrade or p.marked_install or p.marked_delete or \ - p.marked_downgrade or p.marked_reinstall: - changes.append(p) + for pkg in self: + if (pkg.marked_upgrade or pkg.marked_install or pkg.marked_delete + or pkg.marked_downgrade or pkg.marked_reinstall): + changes.append(pkg) return changes - def upgrade(self, distUpgrade=False): - """ Upgrade the all package, DistUpgrade will also install - new dependencies + @deprecated_args + def upgrade(self, dist_upgrade=False): + """Upgrade all packages. + + If the parameter *dist_upgrade* is True, new dependencies will be + installed as well (and conflicting packages may be removed). The + default value is False. """ self.cache_pre_change() - self._depcache.Upgrade(distUpgrade) + self._depcache.Upgrade(dist_upgrade) self.cache_post_change() @property @@ -177,22 +182,22 @@ class Cache(object): # now check the result (this is the code from apt-get.cc) failed = False transient = False - errMsg = "" + err_msg = "" for item in fetcher.Items: if item.Status == item.StatDone: continue if item.StatIdle: transient = True continue - errMsg += "Failed to fetch %s %s\n" % (item.DescURI, + err_msg += "Failed to fetch %s %s\n" % (item.DescURI, item.ErrorText) failed = True # we raise a exception if the download failed or it was cancelt if res == fetcher.ResultCancelled: - raise FetchCancelledException(errMsg) + raise FetchCancelledException(err_msg) elif failed: - raise FetchFailedException(errMsg) + raise FetchFailedException(err_msg) return res def _fetch_archives(self, fetcher, pm): @@ -241,34 +246,57 @@ class Cache(object): providers.append(pkg) return providers - def update(self, fetchProgress=None): - " run the equivalent of apt-get update " + @deprecated_args + def update(self, fetch_progress=None): + """Run the equivalent of apt-get update. + + The first parameter *fetch_progress* may be set to an instance of + apt.progress.FetchProgress, the default is apt.progress.FetchProgress() + . + """ lockfile = apt_pkg.Config.FindDir("Dir::State::Lists") + "lock" lock = apt_pkg.GetLock(lockfile) if lock < 0: raise LockFailedException("Failed to lock %s" % lockfile) try: - if fetchProgress is None: - fetchProgress = apt.progress.FetchProgress() - return self._cache.Update(fetchProgress, self._list) + if fetch_progress is None: + fetch_progress = apt.progress.FetchProgress() + return self._cache.Update(fetch_progress, self._list) finally: os.close(lock) - def install_archives(self, pm, installProgress): + @deprecated_args + def install_archives(self, pm, install_progress): + """ + The first parameter *pm* refers to an object returned by + apt_pkg.GetPackageManager(). + + The second parameter *install_progress* refers to an InstallProgress() + object of the module apt.progress. + """ try: - installProgress.start_update() + install_progress.start_update() except AttributeError: - installProgress.startUpdate() - res = installProgress.run(pm) + install_progress.startUpdate() + res = install_progress.run(pm) try: - installProgress.finish_update() + install_progress.finish_update() except AttributeError: - installProgress.finishUpdate() + install_progress.finishUpdate() return res - def commit(self, fetchProgress=None, installProgress=None): - """ Apply the marked changes to the cache """ + @deprecated_args + def commit(self, fetch_progress=None, install_progress=None): + """Apply the marked changes to the cache. + + The first parameter, *fetch_progress*, refers to a FetchProgress() + object as found in apt.progress, the default being + apt.progress.FetchProgress(). + + The second parameter, *install_progress*, is a + apt.progress.InstallProgress() object. + """ # FIXME: # use the new acquire/pkgmanager interface here, # raise exceptions when a download or install fails @@ -276,19 +304,19 @@ class Cache(object): # Current a failed download will just display "error" # which is less than optimal! - if fetchProgress is None: - fetchProgress = apt.progress.FetchProgress() - if installProgress is None: - installProgress = apt.progress.InstallProgress() + if fetch_progress is None: + fetch_progress = apt.progress.FetchProgress() + if install_progress is None: + install_progress = apt.progress.InstallProgress() pm = apt_pkg.GetPackageManager(self._depcache) - fetcher = apt_pkg.GetAcquire(fetchProgress) + fetcher = apt_pkg.GetAcquire(fetch_progress) while True: # fetch archives first res = self._fetch_archives(fetcher, pm) # then install - res = self.install_archives(pm, installProgress) + res = self.install_archives(pm, install_progress) if res == pm.ResultCompleted: break if res == pm.ResultFailed: @@ -442,59 +470,57 @@ def _test(): """Internal test code.""" print "Cache self test" apt_pkg.init() - c = Cache(apt.progress.OpTextProgress()) - c.connect("cache_pre_change", cache_pre_changed) - c.connect("cache_post_change", cache_post_changed) - print ("aptitude" in c) - p = c["aptitude"] - print p.name - print len(c) - - for pkg in c.keys(): - x= c[pkg].name - - c.upgrade() - changes = c.get_changes() + cache = Cache(apt.progress.OpTextProgress()) + cache.connect("cache_pre_change", cache_pre_changed) + cache.connect("cache_post_change", cache_post_changed) + print ("aptitude" in cache) + pkg = cache["aptitude"] + print pkg.name + print len(cache) + + for pkgname in cache.keys(): + assert cache[pkgname].name == pkgname + + cache.upgrade() + changes = cache.get_changes() print len(changes) - for p in changes: - #print p.name - x = p.name + for pkg in changes: + assert pkg.name + # see if fetching works - for d in ["/tmp/pytest", "/tmp/pytest/partial"]: - if not os.path.exists(d): - os.mkdir(d) + for dir in ["/tmp/pytest", "/tmp/pytest/partial"]: + if not os.path.exists(dir): + os.mkdir(dir) apt_pkg.Config.Set("Dir::Cache::Archives", "/tmp/pytest") - pm = apt_pkg.GetPackageManager(c._depcache) + pm = apt_pkg.GetPackageManager(cache._depcache) fetcher = apt_pkg.GetAcquire(apt.progress.TextFetchProgress()) - c._fetch_archives(fetcher, pm) + cache._fetch_archives(fetcher, pm) #sys.exit(1) print "Testing filtered cache (argument is old cache)" - f = FilteredCache(c) - f.cache.connect("cache_pre_change", cache_pre_changed) - f.cache.connect("cache_post_change", cache_post_changed) - f.cache.upgrade() - f.set_filter(MarkedChangesFilter()) - print len(f) - for pkg in f.keys(): - #print c[pkg].name - x = f[pkg].name - - print len(f) + filtered = FilteredCache(cache) + filtered.cache.connect("cache_pre_change", cache_pre_changed) + filtered.cache.connect("cache_post_change", cache_post_changed) + filtered.cache.upgrade() + filtered.set_filter(MarkedChangesFilter()) + print len(filtered) + for pkgname in filtered.keys(): + assert pkgname == filtered[pkg].name + + print len(filtered) print "Testing filtered cache (no argument)" - f = FilteredCache(progress=apt.progress.OpTextProgress()) - f.cache.connect("cache_pre_change", cache_pre_changed) - f.cache.connect("cache_post_change", cache_post_changed) - f.cache.upgrade() - f.set_filter(MarkedChangesFilter()) - print len(f) - for pkg in f.keys(): - #print c[pkg].name - x = f[pkg].name - - print len(f) + filtered = FilteredCache(progress=apt.progress.OpTextProgress()) + filtered.cache.connect("cache_pre_change", cache_pre_changed) + filtered.cache.connect("cache_post_change", cache_post_changed) + filtered.cache.upgrade() + filtered.set_filter(MarkedChangesFilter()) + print len(filtered) + for pkgname in filtered.keys(): + assert pkgname == filtered[pkgname].name + + print len(filtered) if __name__ == '__main__': _test() diff --git a/apt/package.py b/apt/package.py index 70997383..cf1ff2ae 100644 --- a/apt/package.py +++ b/apt/package.py @@ -31,7 +31,8 @@ import warnings import apt_pkg import apt.progress -from apt.deprecation import function_deprecated_by, AttributeDeprecatedBy +from apt.deprecation import (function_deprecated_by, AttributeDeprecatedBy, + deprecated_args) __all__ = ('BaseDependency', 'Dependency', 'Origin', 'Package', 'Record', 'Version') @@ -123,15 +124,15 @@ class Origin(object): trusted - Boolean value whether this is trustworthy. """ - def __init__(self, pkg, VerFileIter): - self.archive = VerFileIter.Archive - self.component = VerFileIter.Component - self.label = VerFileIter.Label - self.origin = VerFileIter.Origin - self.site = VerFileIter.Site - self.not_automatic = VerFileIter.NotAutomatic + def __init__(self, pkg, packagefile): + self.archive = packagefile.Archive + self.component = packagefile.Component + self.label = packagefile.Label + self.origin = packagefile.Origin + self.site = packagefile.Site + self.not_automatic = packagefile.NotAutomatic # check the trust - indexfile = pkg._pcache._list.FindIndex(VerFileIter) + indexfile = pkg._pcache._list.FindIndex(packagefile) if indexfile and indexfile.IsTrusted: self.trusted = True else: @@ -266,7 +267,7 @@ class Version(object): return self._cand.Section @property - def description(self, format=True, useDots=False): + def description(self): """Return the formatted long description. Return the formated long description according to the Debian policy @@ -276,7 +277,6 @@ class Version(object): """ self.summary # This does the lookup for us. desc = '' - dsc = self.package._pcache._records.LongDesc try: if not isinstance(dsc, unicode): @@ -339,11 +339,11 @@ class Version(object): depends = self._cand.DependsList for t in ["PreDepends", "Depends"]: try: - for depVerList in depends[t]: + for dep_ver_list in depends[t]: base_deps = [] - for depOr in depVerList: - base_deps.append(BaseDependency(depOr.TargetPkg.Name, - depOr.CompType, depOr.TargetVer, + for dep_or in dep_ver_list: + base_deps.append(BaseDependency(dep_or.TargetPkg.Name, + dep_or.CompType, dep_or.TargetVer, (t == "PreDepends"))) depends_list.append(Dependency(base_deps)) except KeyError: @@ -354,8 +354,8 @@ class Version(object): def origins(self): """Return a list of origins for the package version.""" origins = [] - for (verFileIter, index) in self._cand.FileList: - origins.append(Origin(self.package, verFileIter)) + for (packagefile, index) in self._cand.FileList: + origins.append(Origin(self.package, packagefile)) return origins @property @@ -566,21 +566,21 @@ class Package(object): return self._pkg.ID @DeprecatedProperty - def installedVersion(self): + def installedVersion(self): #pylint: disable-msg=C0103 """Return the installed version as string. .. deprecated:: 0.7.9""" return getattr(self.installed, 'version', None) @DeprecatedProperty - def candidateVersion(self): + def candidateVersion(self): #pylint: disable-msg=C0103 """Return the candidate version as string. .. deprecated:: 0.7.9""" return getattr(self.candidate, "version", None) @DeprecatedProperty - def candidateDependencies(self): + def candidateDependencies(self): #pylint: disable-msg=C0103 """Return a list of candidate dependencies. .. deprecated:: 0.7.9 @@ -588,7 +588,7 @@ class Package(object): return getattr(self.candidate, "dependencies", None) @DeprecatedProperty - def installedDependencies(self): + def installedDependencies(self): #pylint: disable-msg=C0103 """Return a list of installed dependencies. .. deprecated:: 0.7.9 @@ -604,7 +604,7 @@ class Package(object): return getattr(self.candidate, "architecture", None) @DeprecatedProperty - def candidateDownloadable(self): + def candidateDownloadable(self): #pylint: disable-msg=C0103 """Return ``True`` if the candidate is downloadable. .. deprecated:: 0.7.9 @@ -612,7 +612,7 @@ class Package(object): return getattr(self.candidate, "downloadable", None) @DeprecatedProperty - def installedDownloadable(self): + def installedDownloadable(self): #pylint: disable-msg=C0103 """Return ``True`` if the installed version is downloadable. .. deprecated:: 0.7.9 @@ -620,7 +620,7 @@ class Package(object): return getattr(self.installed, 'downloadable', False) @DeprecatedProperty - def sourcePackageName(self): + def sourcePackageName(self): #pylint: disable-msg=C0103 """Return the source package name as string. .. deprecated:: 0.7.9 @@ -655,7 +655,7 @@ class Package(object): return getattr(self.candidate, "priority", None) @DeprecatedProperty - def installedPriority(self): + def installedPriority(self): #pylint: disable-msg=C0103 """Return the priority (of the installed version). .. deprecated:: 0.7.9 @@ -684,21 +684,21 @@ class Package(object): return getattr(self.candidate, "description", None) @DeprecatedProperty - def rawDescription(self): + def rawDescription(self): #pylint: disable-msg=C0103 """return the long description (raw). .. deprecated:: 0.7.9""" return getattr(self.candidate, "raw_description", None) @DeprecatedProperty - def candidateRecord(self): + def candidateRecord(self): #pylint: disable-msg=C0103 """Return the Record of the candidate version of the package. .. deprecated:: 0.7.9""" return getattr(self.candidate, "record", None) @DeprecatedProperty - def installedRecord(self): + def installedRecord(self): #pylint: disable-msg=C0103 """Return the Record of the candidate version of the package. .. deprecated:: 0.7.9""" @@ -761,7 +761,7 @@ class Package(object): # sizes @DeprecatedProperty - def packageSize(self): + def packageSize(self): #pylint: disable-msg=C0103 """Return the size of the candidate deb package. .. deprecated:: 0.7.9 @@ -769,7 +769,7 @@ class Package(object): return getattr(self.candidate, "size", None) @DeprecatedProperty - def installedPackageSize(self): + def installedPackageSize(self): #pylint: disable-msg=C0103 """Return the size of the installed deb package. .. deprecated:: 0.7.9 @@ -777,7 +777,7 @@ class Package(object): return getattr(self.installed, 'size', 0) @DeprecatedProperty - def candidateInstalledSize(self): + def candidateInstalledSize(self): #pylint: disable-msg=C0103 """Return the size of the candidate installed package. .. deprecated:: 0.7.9 @@ -785,7 +785,7 @@ class Package(object): return getattr(self.candidate, "installed_size", None) @DeprecatedProperty - def installedSize(self): + def installedSize(self): #pylint: disable-msg=C0103 """Return the size of the currently installed package. @@ -964,7 +964,7 @@ class Package(object): return self._changelog @DeprecatedProperty - def candidateOrigin(self): + def candidateOrigin(self): #pylint: disable-msg=C0103 """Return a list of `Origin()` objects for the candidate version. .. deprecated:: 0.7.9 @@ -987,10 +987,11 @@ class Package(object): self._pcache._depcache.MarkKeep(self._pkg) self._pcache.cache_post_change() - def mark_delete(self, autoFix=True, purge=False): + @deprecated_args + def mark_delete(self, auto_fix=True, purge=False): """Mark a package for install. - If *autoFix* is ``True``, the resolver will be run, trying to fix + If *auto_fix* 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 @@ -999,16 +1000,17 @@ class Package(object): self._pcache.cache_pre_change() self._pcache._depcache.MarkDelete(self._pkg, purge) # try to fix broken stuffsta - if autoFix and self._pcache._depcache.BrokenCount > 0: - Fix = apt_pkg.GetPkgProblemResolver(self._pcache._depcache) - Fix.Clear(self._pkg) - Fix.Protect(self._pkg) - Fix.Remove(self._pkg) - Fix.InstallProtect() - Fix.Resolve() + if auto_fix and self._pcache._depcache.BrokenCount > 0: + fix = apt_pkg.GetPkgProblemResolver(self._pcache._depcache) + fix.Clear(self._pkg) + fix.Protect(self._pkg) + fix.Remove(self._pkg) + fix.InstallProtect() + fix.Resolve() self._pcache.cache_post_change() - def mark_install(self, autoFix=True, autoInst=True, fromUser=True): + @deprecated_args + def mark_install(self, auto_fix=True, auto_inst=True, from_user=True): """Mark a package for install. If *autoFix* is ``True``, the resolver will be run, trying to fix @@ -1023,9 +1025,9 @@ class Package(object): when no other package depends on it. """ self._pcache.cache_pre_change() - self._pcache._depcache.MarkInstall(self._pkg, autoInst, fromUser) + self._pcache._depcache.MarkInstall(self._pkg, auto_inst, from_user) # try to fix broken stuff - if autoFix and self._pcache._depcache.BrokenCount > 0: + if auto_fix and self._pcache._depcache.BrokenCount > 0: fixer = apt_pkg.GetPkgProblemResolver(self._pcache._depcache) fixer.Clear(self._pkg) fixer.Protect(self._pkg) -- cgit v1.2.3 From 79cba28b2346909a12e4ce225bc25b164c33f062 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 17 Apr 2009 17:20:35 +0200 Subject: * apt/package.py: Introduce Version._translated_records. This new property allows us to get the translated record. This was previously done in 'summary', but because 'description' also uses translated descriptions, the lookup has been moved in this property. --- apt/package.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'apt') diff --git a/apt/package.py b/apt/package.py index cf1ff2ae..1a2626fa 100644 --- a/apt/package.py +++ b/apt/package.py @@ -219,6 +219,13 @@ class Version(object): if self.package._pcache._records.Lookup(self._cand.FileList[0]): return self.package._pcache._records + @property + def _translated_records(self): + """Internal helper to get the translated description.""" + desc_iter = self._cand.TranslatedDescription + self.package._pcache._records.Lookup(desc_iter.FileList.pop(0)) + return self.package._pcache._records + @property def installed_size(self): """Return the size of the package when installed.""" @@ -252,9 +259,7 @@ class Version(object): @property def summary(self): """Return the short description (one line summary).""" - desc_iter = self._cand.TranslatedDescription - self.package._pcache._records.Lookup(desc_iter.FileList.pop(0)) - return self.package._pcache._records.ShortDesc + return self._translated_records.ShortDesc @property def raw_description(self): @@ -275,9 +280,8 @@ class Version(object): See http://www.debian.org/doc/debian-policy/ch-controlfields.html for more information. """ - self.summary # This does the lookup for us. desc = '' - dsc = self.package._pcache._records.LongDesc + dsc = self._translated_records.LongDesc try: if not isinstance(dsc, unicode): # Only convert where needed (i.e. Python 2.X) -- cgit v1.2.3 From 6bc61a050bd278b28e883b91cfa5999a7cf76d9d Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 17 Apr 2009 18:01:30 +0200 Subject: * apt/package.py: Where possible, derive apt.package.Record from collections.Mapping. This works on Python 2.6 and newer and enhances the Record class with some new methods on these platforms, e.g. keys(). --- apt/package.py | 13 ++++++++++++- debian/changelog | 3 ++- 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'apt') diff --git a/apt/package.py b/apt/package.py index 1a2626fa..411f9635 100644 --- a/apt/package.py +++ b/apt/package.py @@ -28,6 +28,11 @@ import socket import subprocess import urllib2 import warnings +try: + from collections import Mapping +except ImportError: + # (for Python < 2.6) pylint: disable-msg=C0103 + Mapping = object import apt_pkg import apt.progress @@ -145,7 +150,7 @@ class Origin(object): self.site, self.trusted) -class Record(object): +class Record(Mapping): """Represent a pkgRecord. It can be accessed like a dictionary and can also give the original package @@ -155,6 +160,9 @@ class Record(object): def __init__(self, record_str): self._rec = apt_pkg.ParseSection(record_str) + def __hash__(self): + return hash(self._rec) + def __str__(self): return str(self._rec) @@ -183,6 +191,9 @@ class Record(object): """deprecated form of ``key in x``.""" return key in self._rec + def __len__(self): + return len(self._rec) + class Version(object): """Representation of a package version. diff --git a/debian/changelog b/debian/changelog index e344c145..e8e14306 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,9 @@ python-apt (0.7.91) UNRELEASED; urgency=low * Rename all methods,functions,attributes to conform to PEP 8 (Closes: #481061) + * Where possible, derive apt.package.Record from collections.Mapping. - -- Julian Andres Klode Thu, 16 Apr 2009 18:54:29 +0200 + -- Julian Andres Klode Fri, 17 Apr 2009 17:48:27 +0200 python-apt (0.7.90) experimental; urgency=low -- cgit v1.2.3 From d19943ea8489e06a1f5cd0bd545e0a0aeb4b8551 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Sun, 19 Apr 2009 17:30:57 +0200 Subject: * Update the code to use the new classes. --- apt/cache.py | 22 +++++++++++----------- apt/cdrom.py | 2 +- apt/debfile.py | 6 +++--- apt/package.py | 22 +++++++++++----------- doc/examples/acquire.py | 26 +++++++++++++------------- doc/examples/action.py | 4 ++-- doc/examples/build-deps.py | 8 ++++---- doc/examples/cdrom.py | 2 +- doc/examples/checkstate.py | 2 +- doc/examples/config.py | 2 +- doc/examples/configisc.py | 2 +- doc/examples/deb_inspect.py | 2 +- doc/examples/depcache.py | 4 ++-- doc/examples/desc.py | 6 +++--- doc/examples/indexfile.py | 6 +++--- doc/examples/metaindex.py | 2 +- doc/examples/print_uris.py | 2 +- doc/examples/recommends.py | 2 +- doc/examples/sources.py | 6 +++--- doc/examples/tagfile.py | 2 +- doc/source/examples/cache-packages.py | 2 +- doc/source/examples/cache-pkgfile.py | 2 +- doc/source/examples/missing-deps.py | 2 +- tests/cache.py | 4 ++-- tests/depcache.py | 4 ++-- tests/getcache_mem_corruption.py | 8 ++++---- tests/memleak.py | 8 ++++---- tests/pkgproblemresolver.py | 6 +++--- tests/pkgrecords.py | 6 +++--- tests/pkgsrcrecords.py | 4 ++-- 30 files changed, 88 insertions(+), 88 deletions(-) (limited to 'apt') diff --git a/apt/cache.py b/apt/cache.py index 05d8d1a9..60fd6553 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -78,10 +78,10 @@ class Cache(object): if progress is None: progress = apt.progress.OpProgress() self._run_callbacks("cache_pre_open") - self._cache = apt_pkg.GetCache(progress) - self._depcache = apt_pkg.GetDepCache(self._cache) - self._records = apt_pkg.GetPkgRecords(self._cache) - self._list = apt_pkg.GetPkgSourceList() + self._cache = apt_pkg.Cache(progress) + self._depcache = apt_pkg.DepCache(self._cache) + self._records = apt_pkg.PackageRecords(self._cache) + self._list = apt_pkg.SourceList() self._list.ReadMainList() self._set = set() self._weakref = weakref.WeakValueDictionary() @@ -154,8 +154,8 @@ class Cache(object): @property def required_download(self): """Get the size of the packages that are required to download.""" - pm = apt_pkg.GetPackageManager(self._depcache) - fetcher = apt_pkg.GetAcquire() + pm = apt_pkg.PackageManager(self._depcache) + fetcher = apt_pkg.Acquire() pm.GetArchives(fetcher, self._list, self._records) return fetcher.FetchNeeded @@ -270,7 +270,7 @@ class Cache(object): def install_archives(self, pm, install_progress): """ The first parameter *pm* refers to an object returned by - apt_pkg.GetPackageManager(). + apt_pkg.PackageManager(). The second parameter *install_progress* refers to an InstallProgress() object of the module apt.progress. @@ -309,8 +309,8 @@ class Cache(object): if install_progress is None: install_progress = apt.progress.InstallProgress() - pm = apt_pkg.GetPackageManager(self._depcache) - fetcher = apt_pkg.GetAcquire(fetch_progress) + pm = apt_pkg.PackageManager(self._depcache) + fetcher = apt_pkg.Acquire(fetch_progress) while True: # fetch archives first res = self._fetch_archives(fetcher, pm) @@ -494,8 +494,8 @@ def _test(): if not os.path.exists(dir): os.mkdir(dir) apt_pkg.Config.Set("Dir::Cache::Archives", "/tmp/pytest") - pm = apt_pkg.GetPackageManager(cache._depcache) - fetcher = apt_pkg.GetAcquire(apt.progress.TextFetchProgress()) + pm = apt_pkg.PackageManager(cache._depcache) + fetcher = apt_pkg.Acquire(apt.progress.TextFetchProgress()) cache._fetch_archives(fetcher, pm) #sys.exit(1) diff --git a/apt/cdrom.py b/apt/cdrom.py index 907ac622..b9625ebf 100644 --- a/apt/cdrom.py +++ b/apt/cdrom.py @@ -45,7 +45,7 @@ class Cdrom(object): """ def __init__(self, progress=None, mountpoint=None, nomount=True): - self._cdrom = apt_pkg.GetCdrom() + self._cdrom = apt_pkg.Cdrom() if progress is None: self._progress = CdromProgress() else: diff --git a/apt/debfile.py b/apt/debfile.py index c60fc92d..6e4adb39 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -57,7 +57,7 @@ class DebPackage(object): "missing '%s' member" % "debian-binary")) control = apt_inst.debExtractControl(open(self.filename)) - self._sections = apt_pkg.ParseSection(control) + self._sections = apt_pkg.TagSection(control) self.pkgname = self._sections["Package"] def __getitem__(self, key): @@ -357,7 +357,7 @@ class DebPackage(object): """Satisfy the dependencies.""" # turn off MarkAndSweep via a action group (if available) try: - _actiongroup = apt_pkg.GetPkgActionGroup(self._cache._depcache) + _actiongroup = apt_pkg.ActionGroup(self._cache._depcache) except AttributeError: pass # check depends @@ -458,7 +458,7 @@ class DscSrcPackage(DebPackage): conflicts_tags = ["Build-Conflicts", "Build-Conflicts-Indep"] fobj = open(file) - tagfile = apt_pkg.ParseTagFile(fobj) + tagfile = apt_pkg.TagFile(fobj) sec = tagfile.Section try: while tagfile.Step() == 1: diff --git a/apt/package.py b/apt/package.py index 411f9635..3dbdf058 100644 --- a/apt/package.py +++ b/apt/package.py @@ -158,7 +158,7 @@ class Record(Mapping): """ def __init__(self, record_str): - self._rec = apt_pkg.ParseSection(record_str) + self._rec = apt_pkg.TagSection(record_str) def __hash__(self): return hash(self._rec) @@ -448,9 +448,9 @@ class Version(object): if _file_is_same(destfile, self.size, self._records.MD5Hash): print 'Ignoring already existing file:', destfile return - acq = apt_pkg.GetAcquire(progress or apt.progress.TextFetchProgress()) - apt_pkg.GetPkgAcqFile(acq, self.uri, self._records.MD5Hash, self.size, - base, destFile=destfile) + acq = apt_pkg.Acquire(progress or apt.progress.TextFetchProgress()) + apt_pkg.AcquireFile(acq, self.uri, self._records.MD5Hash, self.size, + base, destfile=destfile) acq.Run() for item in acq.Items: if item.Status != item.StatDone: @@ -474,8 +474,8 @@ class Version(object): 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()) + src = apt_pkg.SourceRecords() + acq = apt_pkg.Acquire(progress or apt.progress.TextFetchProgress()) dsc = None src.Lookup(self.package.name) @@ -497,8 +497,8 @@ class Version(object): continue finally: fobj.close() - apt_pkg.GetPkgAcqFile(acq, src.Index.ArchiveURI(path), md5, size, - base, destFile=destfile) + apt_pkg.AcquireFile(acq, src.Index.ArchiveURI(path), md5, size, + base, destfile=destfile) acq.Run() for item in acq.Items: @@ -879,7 +879,7 @@ class Package(object): # this feature only works if the correct deb-src are in the # sources.list # otherwise we fall back to the binary version number - src_records = apt_pkg.GetPkgSrcRecords() + src_records = apt_pkg.SourceRecords() src_rec = src_records.Lookup(src_pkg) if src_rec: src_ver = src_records.Version @@ -1016,7 +1016,7 @@ class Package(object): self._pcache._depcache.MarkDelete(self._pkg, purge) # try to fix broken stuffsta if auto_fix and self._pcache._depcache.BrokenCount > 0: - fix = apt_pkg.GetPkgProblemResolver(self._pcache._depcache) + fix = apt_pkg.ProblemResolver(self._pcache._depcache) fix.Clear(self._pkg) fix.Protect(self._pkg) fix.Remove(self._pkg) @@ -1043,7 +1043,7 @@ class Package(object): self._pcache._depcache.MarkInstall(self._pkg, auto_inst, from_user) # try to fix broken stuff if auto_fix and self._pcache._depcache.BrokenCount > 0: - fixer = apt_pkg.GetPkgProblemResolver(self._pcache._depcache) + fixer = apt_pkg.ProblemResolver(self._pcache._depcache) fixer.Clear(self._pkg) fixer.Protect(self._pkg) fixer.Resolve(True) diff --git a/doc/examples/acquire.py b/doc/examples/acquire.py index 41a38588..96426a32 100644 --- a/doc/examples/acquire.py +++ b/doc/examples/acquire.py @@ -4,10 +4,10 @@ import apt_pkg import os -def get_file(fetcher, uri, destFile): +def get_file(fetcher, uri, destfile): # get the file - af = apt_pkg.GetPkgAcqFile(fetcher, uri=uri, descr="sample descr", - destFile=destFile) + af = apt_pkg.AcquireFile(fetcher, uri=uri, descr="sample descr", + destfile=destfile) res = fetcher.Run() if res != fetcher.ResultContinue: return False @@ -19,21 +19,21 @@ apt_pkg.init() #apt_pkg.Config.Set("Debug::pkgPackageManager","1"); #apt_pkg.Config.Set("Debug::pkgDPkgProgressReporting","1"); -cache = apt_pkg.GetCache() -depcache = apt_pkg.GetDepCache(cache) +cache = apt_pkg.Cache() +depcache = apt_pkg.DepCache(cache) -recs = apt_pkg.GetPkgRecords(cache) -list = apt_pkg.GetPkgSourceList() +recs = apt_pkg.PackageRecords(cache) +list = apt_pkg.SourceList() list.ReadMainList() # show the amount fetch needed for a dist-upgrade depcache.Upgrade(True) progress = apt.progress.TextFetchProgress() -fetcher = apt_pkg.GetAcquire(progress) -pm = apt_pkg.GetPackageManager(depcache) +fetcher = apt_pkg.Acquire(progress) +pm = apt_pkg.PackageManager(depcache) pm.GetArchives(fetcher, list, recs) print "%s (%s)" % (apt_pkg.SizeToStr(fetcher.FetchNeeded), fetcher.FetchNeeded) -actiongroup = apt_pkg.GetPkgActionGroup(depcache) +actiongroup = apt_pkg.ActionGroup(depcache) for pkg in cache.Packages: depcache.MarkKeep(pkg) @@ -48,9 +48,9 @@ pkg = cache["3ddesktop"] depcache.MarkInstall(pkg) progress = apt.progress.TextFetchProgress() -fetcher = apt_pkg.GetAcquire(progress) -#fetcher = apt_pkg.GetAcquire() -pm = apt_pkg.GetPackageManager(depcache) +fetcher = apt_pkg.Acquire(progress) +#fetcher = apt_pkg.Acquire() +pm = apt_pkg.PackageManager(depcache) print pm print fetcher diff --git a/doc/examples/action.py b/doc/examples/action.py index 8ee86eb7..512945df 100644 --- a/doc/examples/action.py +++ b/doc/examples/action.py @@ -10,7 +10,7 @@ from progress import TextFetchProgress apt_pkg.init() progress = OpTextProgress() -cache = apt_pkg.GetCache(progress) +cache = apt_pkg.Cache(progress) print "Available packages: %s " % cache.PackageCount print "Fetching" @@ -25,7 +25,7 @@ print "example package iter: %s" % iter # get depcache print "\n\n depcache" -depcache = apt_pkg.GetDepCache(cache, progress) +depcache = apt_pkg.DepCache(cache, progress) depcache.ReadPinFile() print "got a depcache: %s " % depcache print "Marked for install: %s " % depcache.InstCount diff --git a/doc/examples/build-deps.py b/doc/examples/build-deps.py index b5ac88a2..656f1361 100755 --- a/doc/examples/build-deps.py +++ b/doc/examples/build-deps.py @@ -21,11 +21,11 @@ def get_source_pkg(pkg, records, depcache): # main apt_pkg.init() -cache = apt_pkg.GetCache() -depcache = apt_pkg.GetDepCache(cache) +cache = apt_pkg.Cache() +depcache = apt_pkg.DepCache(cache) depcache.Init() -records = apt_pkg.GetPkgRecords(cache) -srcrecords = apt_pkg.GetPkgSrcRecords() +records = apt_pkg.PackageRecords(cache) +srcrecords = apt_pkg.SourceRecords() # base package that we use for build-depends calculation if len(sys.argv) < 2: diff --git a/doc/examples/cdrom.py b/doc/examples/cdrom.py index 408bd720..78f2a8af 100644 --- a/doc/examples/cdrom.py +++ b/doc/examples/cdrom.py @@ -10,7 +10,7 @@ from progress import TextCdromProgress # init apt_pkg.init() -cdrom = apt_pkg.GetCdrom() +cdrom = apt_pkg.Cdrom() print cdrom progress = TextCdromProgress() diff --git a/doc/examples/checkstate.py b/doc/examples/checkstate.py index 3368d500..41040b6c 100755 --- a/doc/examples/checkstate.py +++ b/doc/examples/checkstate.py @@ -8,7 +8,7 @@ import apt_pkg apt_pkg.init() -cache = apt_pkg.GetCache() +cache = apt_pkg.Cache() packages = cache.Packages uninstalled, updated, upgradable = {}, {}, {} diff --git a/doc/examples/config.py b/doc/examples/config.py index 9d4e51fc..0dff4cac 100755 --- a/doc/examples/config.py +++ b/doc/examples/config.py @@ -21,7 +21,7 @@ import posixpath # configuration object apt_pkg.Config which is used interally by apt-pkg # routines to control unusual situations. I recommend using the sytem global # whenever possible.. -Cnf = apt_pkg.newConfiguration() +Cnf = apt_pkg.Configuration() print "Command line is", sys.argv diff --git a/doc/examples/configisc.py b/doc/examples/configisc.py index 8da1ad0a..fe3d161b 100755 --- a/doc/examples/configisc.py +++ b/doc/examples/configisc.py @@ -17,7 +17,7 @@ if len(ConfigFile) != 1: print "Must have exactly 1 file name" sys.exit(0) -Cnf = apt_pkg.newConfiguration() +Cnf = apt_pkg.Configuration() apt_pkg.ReadConfigFileISC(Cnf, ConfigFile[0]) # Print the configuration space diff --git a/doc/examples/deb_inspect.py b/doc/examples/deb_inspect.py index cc0d04be..54c52b7b 100755 --- a/doc/examples/deb_inspect.py +++ b/doc/examples/deb_inspect.py @@ -25,7 +25,7 @@ if __name__ == "__main__": print "Now extracting the control file:" control = apt_inst.debExtractControl(open(file)) - sections = apt_pkg.ParseSection(control) + sections = apt_pkg.TagSection(control) print "Maintainer is: " print sections["Maintainer"] diff --git a/doc/examples/depcache.py b/doc/examples/depcache.py index de038fe8..858e45a4 100644 --- a/doc/examples/depcache.py +++ b/doc/examples/depcache.py @@ -9,7 +9,7 @@ from progress import TextProgress apt_pkg.init() progress = TextProgress() -cache = apt_pkg.GetCache(progress) +cache = apt_pkg.Cache(progress) print "Available packages: %s " % cache.PackageCount iter = cache["base-config"] @@ -17,7 +17,7 @@ print "example package iter: %s" % iter # get depcache print "\n\n depcache" -depcache = apt_pkg.GetDepCache(cache) +depcache = apt_pkg.DepCache(cache) depcache.ReadPinFile() # init is needed after the creation/pin file reading depcache.Init(progress) diff --git a/doc/examples/desc.py b/doc/examples/desc.py index 2febf348..d50aa0ce 100644 --- a/doc/examples/desc.py +++ b/doc/examples/desc.py @@ -6,8 +6,8 @@ apt_pkg.init() apt_pkg.Config.Set("APT::Acquire::Translation", "de") -cache = apt_pkg.GetCache() -depcache = apt_pkg.GetDepCache(cache) +cache = apt_pkg.Cache() +depcache = apt_pkg.DepCache(cache) pkg = cache["gcc"] cand = depcache.GetCandidateVer(pkg) @@ -18,7 +18,7 @@ print desc print desc.FileList (f, index) = desc.FileList.pop(0) -records = apt_pkg.GetPkgRecords(cache) +records = apt_pkg.PackageRecords(cache) records.Lookup((f, index)) desc = records.LongDesc print len(desc) diff --git a/doc/examples/indexfile.py b/doc/examples/indexfile.py index 2f1f27f8..cc5070aa 100644 --- a/doc/examples/indexfile.py +++ b/doc/examples/indexfile.py @@ -4,11 +4,11 @@ import apt_pkg apt_pkg.init() -sources = apt_pkg.GetPkgSourceList() +sources = apt_pkg.SourceList() sources.ReadMainList() -cache = apt_pkg.GetCache() -depcache = apt_pkg.GetDepCache(cache) +cache = apt_pkg.Cache() +depcache = apt_pkg.DepCache(cache) pkg = cache["libimlib2"] cand = depcache.GetCandidateVer(pkg) for (f, i) in cand.FileList: diff --git a/doc/examples/metaindex.py b/doc/examples/metaindex.py index 816a3fd7..bbb4ac47 100644 --- a/doc/examples/metaindex.py +++ b/doc/examples/metaindex.py @@ -4,7 +4,7 @@ import apt_pkg apt_pkg.init() -sources = apt_pkg.GetPkgSourceList() +sources = apt_pkg.SourceList() sources.ReadMainList() diff --git a/doc/examples/print_uris.py b/doc/examples/print_uris.py index 3b678e83..c64a4b54 100755 --- a/doc/examples/print_uris.py +++ b/doc/examples/print_uris.py @@ -13,7 +13,7 @@ upgradable = filter(lambda p: p.isUpgradable, cache) for pkg in upgradable: pkg._lookupRecord(True) - path = apt_pkg.ParseSection(pkg._records.Record)["Filename"] + path = apt_pkg.TagSection(pkg._records.Record)["Filename"] cand = pkg._depcache.GetCandidateVer(pkg._pkg) for (packagefile, i) in cand.FileList: indexfile = cache._list.FindIndex(packagefile) diff --git a/doc/examples/recommends.py b/doc/examples/recommends.py index f0b3b1be..0ecd5882 100755 --- a/doc/examples/recommends.py +++ b/doc/examples/recommends.py @@ -3,7 +3,7 @@ import apt_pkg apt_pkg.init() -cache = apt_pkg.GetCache() +cache = apt_pkg.Cache() class Wanted: diff --git a/doc/examples/sources.py b/doc/examples/sources.py index 49652982..bc08ad69 100644 --- a/doc/examples/sources.py +++ b/doc/examples/sources.py @@ -4,10 +4,10 @@ import apt_pkg apt_pkg.init() -#cache = apt_pkg.GetCache() -#sources = apt_pkg.GetPkgSrcRecords(cache) +#cache = apt_pkg.Cache() +#sources = apt_pkg.SourceRecords(cache) -sources = apt_pkg.GetPkgSrcRecords() +sources = apt_pkg.SourceRecords() sources.Restart() while sources.Lookup('hello'): print sources.Package, sources.Version, sources.Maintainer, \ diff --git a/doc/examples/tagfile.py b/doc/examples/tagfile.py index 4faf08ac..770e40de 100755 --- a/doc/examples/tagfile.py +++ b/doc/examples/tagfile.py @@ -1,7 +1,7 @@ #!/usr/bin/env python import apt_pkg -Parse = apt_pkg.ParseTagFile(open("/var/lib/dpkg/status", "r")) +Parse = apt_pkg.TagFile(open("/var/lib/dpkg/status", "r")) while Parse.Step() == 1: print Parse.Section.get("Package") diff --git a/doc/source/examples/cache-packages.py b/doc/source/examples/cache-packages.py index 1abe7cf2..0af96f7d 100644 --- a/doc/source/examples/cache-packages.py +++ b/doc/source/examples/cache-packages.py @@ -8,7 +8,7 @@ def main(): """Main.""" apt_pkg.InitConfig() apt_pkg.InitSystem() - cache = apt_pkg.GetCache() + cache = apt_pkg.Cache() print "Essential packages:" for pkg in cache.Packages: if pkg.Essential: diff --git a/doc/source/examples/cache-pkgfile.py b/doc/source/examples/cache-pkgfile.py index f25975d3..a7c22c97 100644 --- a/doc/source/examples/cache-pkgfile.py +++ b/doc/source/examples/cache-pkgfile.py @@ -5,7 +5,7 @@ import apt_pkg def main(): """Example for PackageFile()""" apt_pkg.init() - cache = apt_pkg.GetCache() + cache = apt_pkg.Cache() for pkgfile in cache.FileList: print 'Package-File:', pkgfile.FileName print 'Index-Type:', pkgfile.IndexType # 'Debian Package Index' diff --git a/doc/source/examples/missing-deps.py b/doc/source/examples/missing-deps.py index 3ca16e45..dd5eeb8a 100644 --- a/doc/source/examples/missing-deps.py +++ b/doc/source/examples/missing-deps.py @@ -35,7 +35,7 @@ def main(): apt_pkg.InitConfig() apt_pkg.InitSystem() - cache = apt_pkg.GetCache() + cache = apt_pkg.Cache() for pkg in sorted(cache.Packages, key=lambda pkg: pkg.Name): # pkg is from a list of packages, sorted by name. diff --git a/tests/cache.py b/tests/cache.py index 87a544e8..f0bf6761 100644 --- a/tests/cache.py +++ b/tests/cache.py @@ -9,8 +9,8 @@ import sys def main(): apt_pkg.init() - cache = apt_pkg.GetCache() - depcache = apt_pkg.GetDepCache(cache) + cache = apt_pkg.Cache() + depcache = apt_pkg.DepCache(cache) depcache.Init() i=0 all=cache.PackageCount diff --git a/tests/depcache.py b/tests/depcache.py index 19aba680..0d59648e 100644 --- a/tests/depcache.py +++ b/tests/depcache.py @@ -9,8 +9,8 @@ import sys def main(): apt_pkg.init() - cache = apt_pkg.GetCache() - depcache = apt_pkg.GetDepCache(cache) + cache = apt_pkg.Cache() + depcache = apt_pkg.DepCache(cache) depcache.Init() i=0 all=cache.PackageCount diff --git a/tests/getcache_mem_corruption.py b/tests/getcache_mem_corruption.py index c3f6eff3..c6e5ff80 100644 --- a/tests/getcache_mem_corruption.py +++ b/tests/getcache_mem_corruption.py @@ -13,12 +13,12 @@ class TestGetCache(unittest.TestCase): def testWrongInvocation(self): # wrongly invoke GetCache() rather than GetDepCache() - apt_cache = apt_pkg.GetCache() - self.assertRaises(ValueError, apt_pkg.GetCache, apt_cache) + apt_cache = apt_pkg.Cache() + self.assertRaises(ValueError, apt_pkg.Cache, apt_cache) def testProperInvocation(self): - apt_cache = apt_pkg.GetCache(apt.progress.OpTextProgress()) - apt_depcache = apt_pkg.GetDepCache(apt_cache) + apt_cache = apt_pkg.Cache(apt.progress.OpTextProgress()) + apt_depcache = apt_pkg.DepCache(apt_cache) if __name__ == "__main__": unittest.main() diff --git a/tests/memleak.py b/tests/memleak.py index 659091fc..5299f35f 100755 --- a/tests/memleak.py +++ b/tests/memleak.py @@ -29,10 +29,10 @@ for i in range(100): # no memleak, but more or less the apt.Cache.open() code for i in range(100): - cache = apt_pkg.GetCache() - depcache = apt_pkg.GetDepCache(cache) - records = apt_pkg.GetPkgRecords(cache) - list = apt_pkg.GetPkgSourceList() + cache = apt_pkg.Cache() + depcache = apt_pkg.DepCache(cache) + records = apt_pkg.PackageRecords(cache) + list = apt_pkg.SourceList() list.ReadMainList() dict = {} for pkg in cache.Packages: diff --git a/tests/pkgproblemresolver.py b/tests/pkgproblemresolver.py index a21d8d9d..0d6d0611 100644 --- a/tests/pkgproblemresolver.py +++ b/tests/pkgproblemresolver.py @@ -9,8 +9,8 @@ import sys def main(): apt_pkg.init() - cache = apt_pkg.GetCache() - depcache = apt_pkg.GetDepCache(cache) + cache = apt_pkg.Cache() + depcache = apt_pkg.DepCache(cache) depcache.Init() i=0 all=cache.PackageCount @@ -25,7 +25,7 @@ def main(): if ver is not None: depcache.MarkInstall(pkg) if depcache.BrokenCount > 0: - fixer = apt_pkg.GetPkgProblemResolver(depcache) + fixer = apt_pkg.ProblemResolver(depcache) fixer.Clear(pkg) fixer.Protect(pkg) # we first try to resolve the problem diff --git a/tests/pkgrecords.py b/tests/pkgrecords.py index 5866847d..2fe6ad20 100644 --- a/tests/pkgrecords.py +++ b/tests/pkgrecords.py @@ -10,14 +10,14 @@ import sys def main(): apt_pkg.init() - cache = apt_pkg.GetCache() - depcache = apt_pkg.GetDepCache(cache) + cache = apt_pkg.Cache() + depcache = apt_pkg.DepCache(cache) depcache.Init() i=0 print "Running PkgRecords test on all packages:" for pkg in cache.Packages: i += 1 - records = apt_pkg.GetPkgRecords(cache) + records = apt_pkg.PackageRecords(cache) if len(pkg.VersionList) == 0: #print "no available version, cruft" continue diff --git a/tests/pkgsrcrecords.py b/tests/pkgsrcrecords.py index 77670540..2ea9dd3a 100644 --- a/tests/pkgsrcrecords.py +++ b/tests/pkgsrcrecords.py @@ -10,12 +10,12 @@ import sys def main(): apt_pkg.init() - cache = apt_pkg.GetCache() + cache = apt_pkg.Cache() i=0 print "Running PkgSrcRecords test on all packages:" for x in cache.Packages: i += 1 - src = apt_pkg.GetPkgSrcRecords() + src = apt_pkg.SourceRecords() if src.Lookup(x.Name): #print src.Package pass -- cgit v1.2.3 From 8ca43939eb2f608cf0250d90894b470e785713b9 Mon Sep 17 00:00:00 2001 From: Sebastian Heinlein Date: Sun, 31 May 2009 01:03:54 +0200 Subject: Extract the package name from the status message --- apt/progress/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'apt') diff --git a/apt/progress/__init__.py b/apt/progress/__init__.py index 47d2a861..fddc7486 100644 --- a/apt/progress/__init__.py +++ b/apt/progress/__init__.py @@ -399,10 +399,11 @@ class DpkgInstallProgress(InstallProgress): print "got garbage from dpkg: '%s'" % self.read self.read = "" break + pkg_name = statusl[1].strip() status = statusl[2].strip() #print status if status == "error": - self.error(self.debname, status) + self.error(pkg_name, status) elif status == "conffile-prompt": # we get a string like this: # 'current-conffile' 'new-conffile' useredited distedited -- cgit v1.2.3 From 81a030505cb46a35f670150929fad5862cd12767 Mon Sep 17 00:00:00 2001 From: Sebastian Heinlein Date: Sun, 31 May 2009 01:05:48 +0200 Subject: Do not store the the Deb path and package name as an attribute of the progress class. Furthermore allow to specify more than one file. --- apt/progress/__init__.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'apt') diff --git a/apt/progress/__init__.py b/apt/progress/__init__.py index fddc7486..6b170fc7 100644 --- a/apt/progress/__init__.py +++ b/apt/progress/__init__.py @@ -367,13 +367,11 @@ class DpkgInstallProgress(InstallProgress): def run(self, debfile): """Start installing the given Debian package.""" - self.debfile = debfile - self.debname = os.path.basename(debfile).split("_")[0] pid = self.fork() if pid == 0: # child res = os.system("/usr/bin/dpkg --status-fd %s -i %s" % \ - (self.writefd, self.debfile)) + (self.writefd, debfile)) os._exit(os.WEXITSTATUS(res)) self.child_pid = pid res = self.wait_child() -- cgit v1.2.3 From cdabff6d329baba8024224b362f79d822ddd943e Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Thu, 4 Jun 2009 18:54:50 +0200 Subject: apt, aptsources, doc: Update to use the new names. --- apt/__init__.py | 4 +- apt/cache.py | 78 ++--- apt/cdrom.py | 14 +- apt/debfile.py | 50 +-- apt/package.py | 208 ++++++------ apt/progress/__init__.py | 8 +- apt/progress/gtk2.py | 2 +- aptsources/distinfo.py | 2 +- aptsources/sourceslist.py | 16 +- doc/source/apt_pkg.rst | 608 +++++++++++++++++----------------- doc/source/examples/cache-packages.py | 16 +- doc/source/examples/cache-pkgfile.py | 14 +- doc/source/examples/dpkg-contents.py | 4 +- doc/source/examples/dpkg-extract.py | 2 +- doc/source/examples/dpkg-info.py | 4 +- doc/source/examples/missing-deps.py | 30 +- 16 files changed, 531 insertions(+), 529 deletions(-) (limited to 'apt') diff --git a/apt/__init__.py b/apt/__init__.py index 734b3240..41c0a30f 100644 --- a/apt/__init__.py +++ b/apt/__init__.py @@ -31,7 +31,9 @@ if apt_pkg._COMPAT_0_7: if apt_pkg._COMPAT_0_7: - from apt_pkg import SizeToStr, TimeToStr, VersionCompare + from apt_pkg import (size_to_str as SizeToStr, + time_to_str as TimeToStr, + version_compare as VersionCompare) # init the package system apt_pkg.init() diff --git a/apt/cache.py b/apt/cache.py index 60fd6553..56b32d45 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -52,16 +52,16 @@ class Cache(object): self._callbacks = {} if memonly: # force apt to build its caches in memory - apt_pkg.Config.Set("Dir::Cache::pkgcache", "") + apt_pkg.config.set("Dir::Cache::pkgcache", "") if rootdir: if os.path.exists(rootdir+"/etc/apt/apt.conf"): - apt_pkg.ReadConfigFile(apt_pkg.Config, + apt_pkg.read_config_file(apt_pkg.config, rootdir + "/etc/apt/apt.conf") if os.path.isdir(rootdir+"/etc/apt/apt.conf.d"): - apt_pkg.ReadConfigDir(apt_pkg.Config, + apt_pkg.read_config_dir(apt_pkg.config, rootdir + "/etc/apt/apt.conf.d") - apt_pkg.Config.Set("Dir", rootdir) - apt_pkg.Config.Set("Dir::State::status", + apt_pkg.config.set("Dir", rootdir) + apt_pkg.config.set("Dir::State::status", rootdir + "/var/lib/dpkg/status") self.open(progress) @@ -82,20 +82,20 @@ class Cache(object): self._depcache = apt_pkg.DepCache(self._cache) self._records = apt_pkg.PackageRecords(self._cache) self._list = apt_pkg.SourceList() - self._list.ReadMainList() + self._list.read_main_list() self._set = set() self._weakref = weakref.WeakValueDictionary() progress.Op = "Building data structures" i=last=0 - size=len(self._cache.Packages) - for pkg in self._cache.Packages: + size=len(self._cache.packages) + for pkg in self._cache.packages: if progress is not None and last+100 < i: progress.update(i/float(size)*100) last=i # drop stuff with no versions (cruft) - if len(pkg.VersionList) > 0: - self._set.add(pkg.Name) + if len(pkg.version_list) > 0: + self._set.add(pkg.name) i += 1 @@ -148,7 +148,7 @@ class Cache(object): default value is False. """ self.cache_pre_change() - self._depcache.Upgrade(dist_upgrade) + self._depcache.upgrade(dist_upgrade) self.cache_post_change() @property @@ -156,13 +156,13 @@ class Cache(object): """Get the size of the packages that are required to download.""" pm = apt_pkg.PackageManager(self._depcache) fetcher = apt_pkg.Acquire() - pm.GetArchives(fetcher, self._list, self._records) - return fetcher.FetchNeeded + pm.get_archives(fetcher, self._list, self._records) + return fetcher.fetch_needed @property def required_space(self): """Get the size of the additional required space on the fs.""" - return self._depcache.UsrSize + return self._depcache.usr_size @property def req_reinstall_pkgs(self): @@ -170,31 +170,31 @@ class Cache(object): reqreinst = set() for pkg in self: if (not pkg.candidate.downloadable and - (pkg._pkg.InstState == apt_pkg.InstStateReInstReq or - pkg._pkg.InstState == apt_pkg.InstStateHoldReInstReq)): + (pkg._pkg.inst_state == apt_pkg.INSTSTATE_RE_INST_REQ or + pkg._pkg.inst_state == apt_pkg.INSTSTATE_HOLD_RE_INST_REQ)): reqreinst.add(pkg.name) return reqreinst def _run_fetcher(self, fetcher): # do the actual fetching - res = fetcher.Run() + res = fetcher.run() # now check the result (this is the code from apt-get.cc) failed = False transient = False err_msg = "" - for item in fetcher.Items: - if item.Status == item.StatDone: + for item in fetcher.items: + if item.status == item.stat_done: continue - if item.StatIdle: + if item.stat_idle: transient = True continue - err_msg += "Failed to fetch %s %s\n" % (item.DescURI, - item.ErrorText) + err_msg += "Failed to fetch %s %s\n" % (item.desc_uri, + item.error_text) failed = True # we raise a exception if the download failed or it was cancelt - if res == fetcher.ResultCancelled: + if res == fetcher.result_cancelled: raise FetchCancelledException(err_msg) elif failed: raise FetchFailedException(err_msg) @@ -204,14 +204,14 @@ class Cache(object): """ fetch the needed archives """ # get lock - lockfile = apt_pkg.Config.FindDir("Dir::Cache::Archives") + "lock" - lock = apt_pkg.GetLock(lockfile) + lockfile = apt_pkg.config.find_dir("Dir::Cache::Archives") + "lock" + lock = apt_pkg.get_lock(lockfile) if lock < 0: raise LockFailedException("Failed to lock %s" % lockfile) try: # this may as well throw a SystemError exception - if not pm.GetArchives(fetcher, self._list, self._records): + if not pm.get_archives(fetcher, self._list, self._records): return False # now run the fetcher, throw exception if something fails to be # fetched @@ -222,7 +222,7 @@ class Cache(object): def is_virtual_package(self, pkgname): """Return whether the package is a virtual package.""" pkg = self._cache[pkgname] - return bool(pkg.ProvidesList and not pkg.VersionList) + return bool(pkg.provides_list and not pkg.version_list) def get_providing_packages(self, virtual): """ @@ -232,15 +232,15 @@ class Cache(object): providers = [] try: vp = self._cache[virtual] - if len(vp.VersionList) != 0: + if len(vp.version_list) != 0: return providers except KeyError: return providers for pkg in self: - v = self._depcache.GetCandidateVer(pkg._pkg) + v = self._depcache.get_candidate_ver(pkg._pkg) if v is None: continue - for p in v.ProvidesList: + for p in v.provides_list: if virtual == p[0]: # we found a pkg that provides this virtual pkg providers.append(pkg) @@ -254,15 +254,15 @@ class Cache(object): apt.progress.FetchProgress, the default is apt.progress.FetchProgress() . """ - lockfile = apt_pkg.Config.FindDir("Dir::State::Lists") + "lock" - lock = apt_pkg.GetLock(lockfile) + lockfile = apt_pkg.config.find_dir("Dir::State::Lists") + "lock" + lock = apt_pkg.get_lock(lockfile) if lock < 0: raise LockFailedException("Failed to lock %s" % lockfile) try: if fetch_progress is None: fetch_progress = apt.progress.FetchProgress() - return self._cache.Update(fetch_progress, self._list) + return self._cache.update(fetch_progress, self._list) finally: os.close(lock) @@ -317,17 +317,17 @@ class Cache(object): # then install res = self.install_archives(pm, install_progress) - if res == pm.ResultCompleted: + if res == pm.result_completed: break - if res == pm.ResultFailed: + if res == pm.result_failed: raise SystemError("installArchives() failed") # reload the fetcher for media swaping - fetcher.Shutdown() - return (res == pm.ResultCompleted) + fetcher.shutdown() + return (res == pm.result_completed) def clear(self): """ Unmark all changes """ - self._depcache.Init() + self._depcache.init() # cache changes @@ -493,7 +493,7 @@ def _test(): for dir in ["/tmp/pytest", "/tmp/pytest/partial"]: if not os.path.exists(dir): os.mkdir(dir) - apt_pkg.Config.Set("Dir::Cache::Archives", "/tmp/pytest") + apt_pkg.config.set("Dir::Cache::Archives", "/tmp/pytest") pm = apt_pkg.PackageManager(cache._depcache) fetcher = apt_pkg.Acquire(apt.progress.TextFetchProgress()) cache._fetch_archives(fetcher, pm) diff --git a/apt/cdrom.py b/apt/cdrom.py index b9625ebf..a98b5d99 100644 --- a/apt/cdrom.py +++ b/apt/cdrom.py @@ -52,20 +52,20 @@ class Cdrom(object): self._progress = progress # see if we have a alternative mountpoint if mountpoint is not None: - apt_pkg.Config.Set("Acquire::cdrom::mount", mountpoint) + apt_pkg.config.set("Acquire::cdrom::mount", mountpoint) # do not mess with mount points by default if nomount: - apt_pkg.Config.Set("APT::CDROM::NoMount", "true") + apt_pkg.config.set("APT::CDROM::NoMount", "true") else: - apt_pkg.Config.Set("APT::CDROM::NoMount", "false") + apt_pkg.config.set("APT::CDROM::NoMount", "false") def add(self): """Add cdrom to the sources.list.""" - return self._cdrom.Add(self._progress) + return self._cdrom.add(self._progress) def ident(self): """Identify the cdrom.""" - (res, ident) = self._cdrom.Ident(self._progress) + (res, ident) = self._cdrom.ident(self._progress) if res: return ident @@ -77,8 +77,8 @@ class Cdrom(object): # FIXME: throw exception instead return False # Get a list of files - src = glob.glob(apt_pkg.Config.FindDir("Dir::Etc::sourceparts") + '*') - src.append(apt_pkg.Config.FindFile("Dir::Etc::sourcelist")) + src = glob.glob(apt_pkg.config.find_dir("Dir::Etc::sourceparts") + '*') + src.append(apt_pkg.config.find_file("Dir::Etc::sourcelist")) # Check each file for fname in src: for line in open(fname): diff --git a/apt/debfile.py b/apt/debfile.py index 6e4adb39..84bbe3ab 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -52,11 +52,11 @@ class DebPackage(object): def open(self, filename): " open given debfile " self.filename = filename - if not apt_inst.arCheckMember(open(self.filename), "debian-binary"): + if not apt_inst.ar_check_member(open(self.filename), "debian-binary"): raise NoDebArchiveException(_("This is not a valid DEB archive, " "missing '%s' member" % "debian-binary")) - control = apt_inst.debExtractControl(open(self.filename)) + control = apt_inst.deb_extract_control(open(self.filename)) self._sections = apt_pkg.TagSection(control) self.pkgname = self._sections["Package"] @@ -72,9 +72,9 @@ class DebPackage(object): files.append(name) for member in self._supported_data_members: - if apt_inst.arCheckMember(open(self.filename), member): + if apt_inst.ar_check_member(open(self.filename), member): try: - apt_inst.debExtract(open(self.filename), extract_cb, + apt_inst.deb_extract(open(self.filename), extract_cb, member) break except SystemError: @@ -106,7 +106,7 @@ class DebPackage(object): continue inst = self._cache[depname].installed - if inst is not None and apt_pkg.CheckDep(inst.version, oper, ver): + if inst is not None and apt_pkg.check_dep(inst.version, oper, ver): return True return False @@ -129,10 +129,10 @@ class DebPackage(object): # now check if we can satisfy the deps with the candidate(s) # in the cache pkg = self._cache[depname] - cand = self._cache._depcache.GetCandidateVer(pkg._pkg) + cand = self._cache._depcache.get_candidate_ver(pkg._pkg) if not cand: continue - if not apt_pkg.CheckDep(cand.VerStr, oper, ver): + if not apt_pkg.check_dep(cand.ver_str, oper, ver): continue # check if we need to install it @@ -168,7 +168,7 @@ class DebPackage(object): #print "ver: %s" % ver #print "pkgver: %s " % pkgver #print "oper: %s " % oper - if (apt_pkg.CheckDep(pkgver, oper, ver) and not + if (apt_pkg.check_dep(pkgver, oper, ver) and not self.replaces_real_pkg(pkgname, oper, ver)): self._failure_string += _("Conflicts with the installed package " "'%s'" % pkg.name) @@ -211,7 +211,7 @@ class DebPackage(object): """List of package names conflicting with this package.""" key = "Conflicts" try: - return apt_pkg.ParseDepends(self._sections[key]) + return apt_pkg.parse_depends(self._sections[key]) except KeyError: return [] @@ -222,7 +222,7 @@ class DebPackage(object): # find depends for key in "Depends", "PreDepends": try: - depends.extend(apt_pkg.ParseDepends(self._sections[key])) + depends.extend(apt_pkg.parse_depends(self._sections[key])) except KeyError: pass return depends @@ -232,7 +232,7 @@ class DebPackage(object): """List of virtual packages which are provided by this package.""" key = "Provides" try: - return apt_pkg.ParseDepends(self._sections[key]) + return apt_pkg.parse_depends(self._sections[key]) except KeyError: return [] @@ -241,7 +241,7 @@ class DebPackage(object): """List of packages which are replaced by this package.""" key = "Replaces" try: - return apt_pkg.ParseDepends(self._sections[key]) + return apt_pkg.parse_depends(self._sections[key]) except KeyError: return [] @@ -261,7 +261,7 @@ class DebPackage(object): pkgver = None for or_group in self.replaces: for (name, ver, oper) in or_group: - if (name == pkgname and apt_pkg.CheckDep(pkgver, oper, ver)): + if (name == pkgname and apt_pkg.check_dep(pkgver, oper, ver)): self._dbg(3, "we have a replaces in our package for the " "conflict against '%s'" % (pkgname)) return True @@ -298,7 +298,7 @@ class DebPackage(object): else: cachever = self._cache[pkgname].candidate.version if cachever is not None: - cmp = apt_pkg.VersionCompare(cachever, debver) + cmp = apt_pkg.version_compare(cachever, debver) self._dbg(1, "CompareVersion(debver,instver): %s" % cmp) if cmp == 0: return VERSION_SAME @@ -310,11 +310,11 @@ class DebPackage(object): def check(self): """Check if the package is installable.""" - self._dbg(3, "checkDepends") + self._dbg(3, "check_depends") # check arch arch = self._sections["Architecture"] - if arch != "all" and arch != apt_pkg.Config.Find("APT::Architecture"): + if arch != "all" and arch != apt_pkg.config.find("APT::Architecture"): self._dbg(1, "ERROR: Wrong architecture dude!") self._failure_string = _("Wrong architecture '%s'" % arch) return False @@ -341,7 +341,7 @@ class DebPackage(object): if not self.check_conflicts(): return False - if self._cache._depcache.BrokenCount > 0: + if self._cache._depcache.broken_count > 0: self._failure_string = _("Failed to satisfy all dependencies " "(broken cache)") # clean the cache again @@ -351,7 +351,7 @@ class DebPackage(object): def satisfy_depends_str(self, dependsstr): """Satisfy the dependencies in the given string.""" - return self._satisfy_depends(apt_pkg.ParseDepends(dependsstr)) + return self._satisfy_depends(apt_pkg.parse_depends(dependsstr)) def _satisfy_depends(self, depends): """Satisfy the dependencies.""" @@ -459,17 +459,17 @@ class DscSrcPackage(DebPackage): fobj = open(file) tagfile = apt_pkg.TagFile(fobj) - sec = tagfile.Section + sec = tagfile.section try: - while tagfile.Step() == 1: + while tagfile.step() == 1: for tag in depends_tags: if not tag in sec: continue - self._depends.extend(apt_pkg.ParseSrcDepends(sec[tag])) + self._depends.extend(apt_pkg.parse_src_depends(sec[tag])) for tag in conflicts_tags: if not tag in sec: continue - self._conflicts.extend(apt_pkg.ParseSrcDepends(sec[tag])) + self._conflicts.extend(apt_pkg.parse_src_depends(sec[tag])) if 'Source' in sec: self.pkgname = sec['Source'] if 'Binary' in sec: @@ -490,7 +490,7 @@ class DscSrcPackage(DebPackage): """Check if the package is installable..""" if not self.check_conflicts(): for pkgname in self._installed_conflicts: - if self._cache[pkgname]._pkg.Essential: + if self._cache[pkgname]._pkg.essential: raise Exception(_("An essential package would be removed")) self._cache[pkgname].mark_delete() # FIXME: a additional run of the checkConflicts() @@ -525,13 +525,13 @@ def _test(): print ret #s = DscSrcPackage(cache, "../tests/3ddesktop_0.2.9-6.dsc") - #s.checkDep() + #s.check_dep() #print "Missing deps: ",s.missingDeps #print "Print required changes: ", s.requiredChanges s = DscSrcPackage(cache=cache) d = "libc6 (>= 2.3.2), libaio (>= 0.3.96) | libaio1 (>= 0.3.96)" - print s._satisfy_depends(apt_pkg.ParseDepends(d)) + print s._satisfy_depends(apt_pkg.parse_depends(d)) if __name__ == "__main__": _test() diff --git a/apt/package.py b/apt/package.py index 3dbdf058..a24486e1 100644 --- a/apt/package.py +++ b/apt/package.py @@ -130,15 +130,15 @@ class Origin(object): """ def __init__(self, pkg, packagefile): - self.archive = packagefile.Archive - self.component = packagefile.Component - self.label = packagefile.Label - self.origin = packagefile.Origin - self.site = packagefile.Site - self.not_automatic = packagefile.NotAutomatic + self.archive = packagefile.archive + self.component = packagefile.component + self.label = packagefile.label + self.origin = packagefile.origin + self.site = packagefile.site + self.not_automatic = packagefile.not_automatic # check the trust - indexfile = pkg._pcache._list.FindIndex(packagefile) - if indexfile and indexfile.IsTrusted: + indexfile = pkg._pcache._list.find_index(packagefile) + if indexfile and indexfile.is_trusted: self.trusted = True else: self.trusted = False @@ -206,19 +206,19 @@ class Version(object): self._cand = cand def __eq__(self, other): - return self._cand.ID == other._cand.ID + return self._cand.id == other._cand.id def __gt__(self, other): - return apt_pkg.VersionCompare(self.version, other.version) > 0 + return apt_pkg.version_compare(self.version, other.version) > 0 def __lt__(self, other): - return apt_pkg.VersionCompare(self.version, other.version) < 0 + return apt_pkg.version_compare(self.version, other.version) < 0 def __ne__(self, other): return not self.__eq__(other) def __hash__(self): - return self._cand.Hash + return self._cand.hash def __repr__(self): return '' % (self.package.name, @@ -227,60 +227,60 @@ class Version(object): @property def _records(self): """Internal helper that moves the Records to the right position.""" - if self.package._pcache._records.Lookup(self._cand.FileList[0]): + if self.package._pcache._records.lookup(self._cand.file_list[0]): return self.package._pcache._records @property def _translated_records(self): """Internal helper to get the translated description.""" - desc_iter = self._cand.TranslatedDescription - self.package._pcache._records.Lookup(desc_iter.FileList.pop(0)) + desc_iter = self._cand.translated_description + self.package._pcache._records.lookup(desc_iter.file_list.pop(0)) return self.package._pcache._records @property def installed_size(self): """Return the size of the package when installed.""" - return self._cand.InstalledSize + return self._cand.installed_size @property def homepage(self): """Return the homepage for the package.""" - return self._records.Homepage + return self._records.homepage @property def size(self): """Return the size of the package.""" - return self._cand.Size + return self._cand.size @property def architecture(self): """Return the architecture of the package version.""" - return self._cand.Arch + return self._cand.arch @property def downloadable(self): """Return whether the version of the package is downloadable.""" - return bool(self._cand.Downloadable) + return bool(self._cand.downloadable) @property def version(self): """Return the version as a string.""" - return self._cand.VerStr + return self._cand.ver_str @property def summary(self): """Return the short description (one line summary).""" - return self._translated_records.ShortDesc + return self._translated_records.short_desc @property def raw_description(self): """return the long description (raw).""" - return self._records.LongDesc + return self._records.long_desc @property def section(self): """Return the section of the package.""" - return self._cand.Section + return self._cand.section @property def description(self): @@ -292,7 +292,7 @@ class Version(object): for more information. """ desc = '' - dsc = self._translated_records.LongDesc + dsc = self._translated_records.long_desc try: if not isinstance(dsc, unicode): # Only convert where needed (i.e. Python 2.X) @@ -333,32 +333,32 @@ class Version(object): def source_name(self): """Return the name of the source package.""" try: - return self._records.SourcePkg or self.package.name + return self._records.source_pkg or self.package.name except IndexError: return self.package.name @property def priority(self): """Return the priority of the package, as string.""" - return self._cand.PriorityStr + return self._cand.priority_str @property def record(self): """Return a Record() object for this version.""" - return Record(self._records.Record) + return Record(self._records.record) @property def dependencies(self): """Return the dependencies of the package version.""" depends_list = [] - depends = self._cand.DependsList + depends = self._cand.depends_list for t in ["PreDepends", "Depends"]: try: for dep_ver_list in depends[t]: base_deps = [] for dep_or in dep_ver_list: - base_deps.append(BaseDependency(dep_or.TargetPkg.Name, - dep_or.CompType, dep_or.TargetVer, + base_deps.append(BaseDependency(dep_or.target_pkg.name, + dep_or.comp_type, dep_or.target_ver, (t == "PreDepends"))) depends_list.append(Dependency(base_deps)) except KeyError: @@ -369,7 +369,7 @@ class Version(object): def origins(self): """Return a list of origins for the package version.""" origins = [] - for (packagefile, index) in self._cand.FileList: + for (packagefile, index) in self._cand.file_list: origins.append(Origin(self.package, packagefile)) return origins @@ -379,7 +379,7 @@ class Version(object): .. versionadded:: 0.7.10 """ - return self._records.FileName + return self._records.file_name @property def md5(self): @@ -387,7 +387,7 @@ class Version(object): .. versionadded:: 0.7.10 """ - return self._records.MD5Hash + return self._records.md5_hash @property def sha1(self): @@ -395,7 +395,7 @@ class Version(object): .. versionadded:: 0.7.10 """ - return self._records.SHA1Hash + return self._records.sha1_hash @property def sha256(self): @@ -403,17 +403,17 @@ class Version(object): .. versionadded:: 0.7.10 """ - return self._records.SHA256Hash + return self._records.sha256_hash def _uris(self): """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) + for (packagefile, index) in self._cand.file_list: + indexfile = self.package._pcache._list.find_index(packagefile) if indexfile: - yield indexfile.ArchiveURI(self._records.FileName) + yield indexfile.archive_uri(self._records.file_name) @property def uris(self): @@ -443,19 +443,19 @@ class Version(object): .. versionadded:: 0.7.10 """ - base = os.path.basename(self._records.FileName) + base = os.path.basename(self._records.file_name) destfile = os.path.join(destdir, base) - if _file_is_same(destfile, self.size, self._records.MD5Hash): + if _file_is_same(destfile, self.size, self._records.md5_hash): print 'Ignoring already existing file:', destfile return acq = apt_pkg.Acquire(progress or apt.progress.TextFetchProgress()) - apt_pkg.AcquireFile(acq, self.uri, self._records.MD5Hash, self.size, - base, destfile=destfile) - acq.Run() - for item in acq.Items: - if item.Status != item.StatDone: + apt_pkg.AcquireFile(acq, self.uri, self._records.md5_hash, self.size, + base, dest_file=destfile) + acq.run() + for item in acq.items: + if item.status != item.stat_done: raise FetchError("The item %r could not be fetched: %s" % - (item.DestFile, item.ErrorText)) + (item.dest_file, item.error_text)) return os.path.abspath(destfile) def fetch_source(self, destdir="", progress=None, unpack=True): @@ -478,13 +478,13 @@ class Version(object): acq = apt_pkg.Acquire(progress or apt.progress.TextFetchProgress()) dsc = None - src.Lookup(self.package.name) + src.lookup(self.package.name) try: - while self.version != src.Version: - src.Lookup(self.package.name) + while self.version != src.version: + src.lookup(self.package.name) except AttributeError: raise ValueError("No source for %r" % self) - for md5, size, path, type in src.Files: + for md5, size, path, type in src.files: base = os.path.basename(path) destfile = os.path.join(destdir, base) if type == 'dsc': @@ -497,17 +497,17 @@ class Version(object): continue finally: fobj.close() - apt_pkg.AcquireFile(acq, src.Index.ArchiveURI(path), md5, size, - base, destfile=destfile) - acq.Run() + apt_pkg.AcquireFile(acq, src.index.archive_uri(path), md5, size, + base, dest_file=destfile) + acq.run() - for item in acq.Items: - if item.Status != item.StatDone: + for item in acq.items: + if item.status != item.stat_done: raise FetchError("The item %r could not be fetched: %s" % - (item.DestFile, item.ErrorText)) + (item.dest_file, item.error_text)) if unpack: - outdir = src.Package + '-' + apt_pkg.UpstreamVersion(src.Version) + outdir = src.package + '-' + apt_pkg.upstream_version(src.version) outdir = os.path.join(destdir, outdir) subprocess.check_call(["dpkg-source", "-x", dsc, outdir]) return os.path.abspath(outdir) @@ -530,7 +530,7 @@ class Package(object): self._changelog = "" # Cached changelog def __repr__(self): - return '' % (self._pkg.Name, self._pkg.ID) + return '' % (self._pkg.name, self._pkg.id) def candidate(self): """Return the candidate version of the package. @@ -541,14 +541,14 @@ class Package(object): .. versionadded:: 0.7.9 """ - cand = self._pcache._depcache.GetCandidateVer(self._pkg) + cand = self._pcache._depcache.get_candidate_ver(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.cache_pre_change() - self._pcache._depcache.SetCandidateVer(self._pkg, version._cand) + self._pcache._depcache.set_candidate_ver(self._pkg, version._cand) self._pcache.cache_post_change() candidate = property(candidate, __set_candidate) @@ -559,26 +559,26 @@ class Package(object): .. versionadded:: 0.7.9 """ - if self._pkg.CurrentVer is not None: - return Version(self, self._pkg.CurrentVer) + if self._pkg.current_ver is not None: + return Version(self, self._pkg.current_ver) @property def name(self): """Return the name of the package.""" - return self._pkg.Name + return self._pkg.name @property def id(self): """Return a uniq ID for the package. This can be used eg. to store additional information about the pkg.""" - return self._pkg.ID + return self._pkg.id def __hash__(self): """Return the hash of the object. This returns the same value as ID, which is unique.""" - return self._pkg.ID + return self._pkg.id @DeprecatedProperty def installedVersion(self): #pylint: disable-msg=C0103 @@ -641,12 +641,12 @@ class Package(object): .. deprecated:: 0.7.9 """ try: - return self.candidate._records.SourcePkg or self._pkg.Name + return self.candidate._records.source_pkg or self._pkg.name except AttributeError: try: - return self.installed._records.SourcePkg or self._pkg.Name + return self.installed._records.source_pkg or self._pkg.name except AttributeError: - return self._pkg.Name + return self._pkg.name @DeprecatedProperty def homepage(self): @@ -659,7 +659,7 @@ class Package(object): @property def section(self): """Return the section of the package.""" - return self._pkg.Section + return self._pkg.section @DeprecatedProperty def priority(self): @@ -724,43 +724,43 @@ class Package(object): @property def marked_install(self): """Return ``True`` if the package is marked for install.""" - return self._pcache._depcache.MarkedInstall(self._pkg) + return self._pcache._depcache.marked_install(self._pkg) @property def marked_upgrade(self): """Return ``True`` if the package is marked for upgrade.""" - return self._pcache._depcache.MarkedUpgrade(self._pkg) + return self._pcache._depcache.marked_upgrade(self._pkg) @property def marked_delete(self): """Return ``True`` if the package is marked for delete.""" - return self._pcache._depcache.MarkedDelete(self._pkg) + return self._pcache._depcache.marked_delete(self._pkg) @property def marked_keep(self): """Return ``True`` if the package is marked for keep.""" - return self._pcache._depcache.MarkedKeep(self._pkg) + return self._pcache._depcache.marked_keep(self._pkg) @property def marked_downgrade(self): """ Package is marked for downgrade """ - return self._pcache._depcache.MarkedDowngrade(self._pkg) + return self._pcache._depcache.marked_downgrade(self._pkg) @property def marked_reinstall(self): """Return ``True`` if the package is marked for reinstall.""" - return self._pcache._depcache.MarkedReinstall(self._pkg) + return self._pcache._depcache.marked_reinstall(self._pkg) @property def is_installed(self): """Return ``True`` if the package is installed.""" - return (self._pkg.CurrentVer is not None) + return (self._pkg.current_ver is not None) @property def is_upgradable(self): """Return ``True`` if the package is upgradable.""" return (self.is_installed and - self._pcache._depcache.IsUpgradable(self._pkg)) + self._pcache._depcache.is_upgradable(self._pkg)) @property def is_auto_removable(self): @@ -771,7 +771,7 @@ class Package(object): is no longer required. """ return self.is_installed and \ - self._pcache._depcache.IsGarbage(self._pkg) + self._pcache._depcache.is_garbage(self._pkg) # sizes @@ -880,15 +880,15 @@ class Package(object): # sources.list # otherwise we fall back to the binary version number src_records = apt_pkg.SourceRecords() - src_rec = src_records.Lookup(src_pkg) + src_rec = src_records.lookup(src_pkg) if src_rec: - src_ver = src_records.Version + src_ver = src_records.version #if apt_pkg.VersionCompare(binver, srcver) > 0: # srcver = binver if not src_ver: src_ver = bin_ver #print "srcver: %s" % src_ver - section = src_records.Section + section = src_records.section #print "srcsect: %s" % section else: # fail into the error handler @@ -954,8 +954,8 @@ class Package(object): changelog_ver = match.group(1) if changelog_ver and ":" in changelog_ver: changelog_ver = changelog_ver.split(":", 1)[1] - if (installed and apt_pkg.VersionCompare(changelog_ver, - installed) <= 0): + if (installed and apt_pkg.version_compare( + changelog_ver, installed) <= 0): break # EOF (shouldn't really happen) changelog += line @@ -992,14 +992,14 @@ class Package(object): .. versionadded:: 0.7.9 """ - return [Version(self, ver) for ver in self._pkg.VersionList] + return [Version(self, ver) for ver in self._pkg.version_list] # depcache actions def mark_keep(self): """Mark a package for keep.""" self._pcache.cache_pre_change() - self._pcache._depcache.MarkKeep(self._pkg) + self._pcache._depcache.mark_keep(self._pkg) self._pcache.cache_post_change() @deprecated_args @@ -1013,15 +1013,15 @@ class Package(object): as well. The default is to keep the configuration. """ self._pcache.cache_pre_change() - self._pcache._depcache.MarkDelete(self._pkg, purge) + self._pcache._depcache.mark_delete(self._pkg, purge) # try to fix broken stuffsta - if auto_fix and self._pcache._depcache.BrokenCount > 0: + if auto_fix and self._pcache._depcache.broken_count > 0: fix = apt_pkg.ProblemResolver(self._pcache._depcache) - fix.Clear(self._pkg) - fix.Protect(self._pkg) - fix.Remove(self._pkg) - fix.InstallProtect() - fix.Resolve() + fix.clear(self._pkg) + fix.protect(self._pkg) + fix.remove(self._pkg) + fix.install_protect() + fix.resolve() self._pcache.cache_post_change() @deprecated_args @@ -1040,13 +1040,13 @@ class Package(object): when no other package depends on it. """ self._pcache.cache_pre_change() - self._pcache._depcache.MarkInstall(self._pkg, auto_inst, from_user) + self._pcache._depcache.mark_install(self._pkg, auto_inst, from_user) # try to fix broken stuff - if auto_fix and self._pcache._depcache.BrokenCount > 0: + if auto_fix and self._pcache._depcache.broken_count > 0: fixer = apt_pkg.ProblemResolver(self._pcache._depcache) - fixer.Clear(self._pkg) - fixer.Protect(self._pkg) - fixer.Resolve(True) + fixer.clear(self._pkg) + fixer.protect(self._pkg) + fixer.resolve(True) self._pcache.cache_post_change() def mark_upgrade(self): @@ -1056,7 +1056,7 @@ class Package(object): else: # FIXME: we may want to throw a exception here sys.stderr.write(("MarkUpgrade() called on a non-upgrable pkg: " - "'%s'\n") % self._pkg.Name) + "'%s'\n") % self._pkg.name) def commit(self, fprogress, iprogress): """Commit the changes. @@ -1067,7 +1067,7 @@ class Package(object): The parameter *iprogress* refers to an InstallProgress() object, as found in apt.progress. """ - self._pcache._depcache.Commit(fprogress, iprogress) + self._pcache._depcache.commit(fprogress, iprogress) if not apt_pkg._COMPAT_0_7: @@ -1149,8 +1149,8 @@ def _test(): if pkg.is_upgradable: if random.randint(0, 1) == 1: pkg.mark_install(i) - print "Broken: %s " % cache._depcache.BrokenCount - print "InstCount: %s " % cache._depcache.InstCount + print "Broken: %s " % cache._depcache.broken_count + print "InstCount: %s " % cache._depcache.inst_count print # get a new cache @@ -1163,8 +1163,8 @@ def _test(): cache[name].mark_delete(i) except SystemError: print "Error trying to remove: %s " % name - print "Broken: %s " % cache._depcache.BrokenCount - print "DelCount: %s " % cache._depcache.DelCount + print "Broken: %s " % cache._depcache.broken_count + print "DelCount: %s " % cache._depcache.del_count # self-test if __name__ == "__main__": diff --git a/apt/progress/__init__.py b/apt/progress/__init__.py index 769942ce..d2a9d497 100644 --- a/apt/progress/__init__.py +++ b/apt/progress/__init__.py @@ -153,8 +153,8 @@ class TextFetchProgress(FetchProgress): FetchProgress.pulse(self) if self.currentCPS > 0: s = "[%2.f%%] %sB/s %s" % (self.percent, - apt_pkg.SizeToStr(int(self.currentCPS)), - apt_pkg.TimeToStr(int(self.eta))) + apt_pkg.size_to_str(int(self.currentCPS)), + apt_pkg.time_to_str(int(self.eta))) else: s = "%2.f%% [Working]" % (self.percent) print "\r%s" % (s), @@ -184,7 +184,7 @@ class DumbInstallProgress(object): def run(self, pm): """Start installation.""" - return pm.DoInstall() + return pm.do_install() def finishUpdate(self): """Called when update has finished.""" @@ -278,7 +278,7 @@ class InstallProgress(DumbInstallProgress): pid = self.fork() if pid == 0: # child - res = pm.DoInstall(self.writefd) + res = pm.do_install(self.writefd) os._exit(res) self.child_pid = pid res = self.waitChild() diff --git a/apt/progress/gtk2.py b/apt/progress/gtk2.py index 36d459bc..06ece2d5 100644 --- a/apt/progress/gtk2.py +++ b/apt/progress/gtk2.py @@ -247,7 +247,7 @@ class GFetchProgress(gobject.GObject, apt.progress.FetchProgress): "%(speed)s/s") % \ {"current": currentItem, "total": self.totalItems, - "speed": apt_pkg.SizeToStr(self.currentCPS)}) + "speed": apt_pkg.size_to_str(self.currentCPS)}) else: text = (_("Downloading file %(current)li of %(total)li") % \ {"current": currentItem, diff --git a/aptsources/distinfo.py b/aptsources/distinfo.py index ce44e48b..268d9b9f 100644 --- a/aptsources/distinfo.py +++ b/aptsources/distinfo.py @@ -148,7 +148,7 @@ class DistInfo: base_dir = "/usr/share/python-apt/templates"): self.metarelease_uri = '' self.templates = [] - self.arch = apt_pkg.Config.Find("APT::Architecture") + self.arch = apt_pkg.config.find("APT::Architecture") location = None match_loc = re.compile(r"^#LOC:(.+)$") diff --git a/aptsources/sourceslist.py b/aptsources/sourceslist.py index fdc0f029..710bfe15 100644 --- a/aptsources/sourceslist.py +++ b/aptsources/sourceslist.py @@ -88,8 +88,8 @@ class SourceEntry: self.comment = "" # (optional) comment self.line = line # the original sources.list line if file is None: - file = apt_pkg.Config.FindDir( - "Dir::Etc")+apt_pkg.Config.Find("Dir::Etc::sourcelist") + file = apt_pkg.config.find_dir( + "Dir::Etc")+apt_pkg.config.find("Dir::Etc::sourcelist") self.file = file # the file that the entry is located in self.parse(line) self.template = None # type DistInfo.Suite @@ -237,10 +237,10 @@ class SourcesList(object): """ update the list of known entries """ self.list = [] # read sources.list - file = apt_pkg.Config.FindFile("Dir::Etc::sourcelist") + file = apt_pkg.config.find_file("Dir::Etc::sourcelist") self.load(file) # read sources.list.d - partsdir = apt_pkg.Config.FindDir("Dir::Etc::sourceparts") + partsdir = apt_pkg.config.find_dir("Dir::Etc::sourceparts") for file in glob.glob("%s/*.list" % partsdir): self.load(file) # check if the source item fits a predefined template @@ -312,12 +312,12 @@ class SourcesList(object): def restore_backup(self, backup_ext): " restore sources.list files based on the backup extension " - file = apt_pkg.Config.FindFile("Dir::Etc::sourcelist") + file = apt_pkg.config.find_file("Dir::Etc::sourcelist") if os.path.exists(file+backup_ext) and \ os.path.exists(file): shutil.copy(file+backup_ext, file) # now sources.list.d - partsdir = apt_pkg.Config.FindDir("Dir::Etc::sourceparts") + partsdir = apt_pkg.config.find_dir("Dir::Etc::sourceparts") for file in glob.glob("%s/*.list" % partsdir): if os.path.exists(file+backup_ext): shutil.copy(file+backup_ext, file) @@ -355,7 +355,7 @@ class SourcesList(object): files = {} # write an empty default config file if there aren't any sources if len(self.list) == 0: - path = apt_pkg.Config.FindFile("Dir::Etc::sourcelist") + path = apt_pkg.config.find_file("Dir::Etc::sourcelist") header = ( "## See sources.list(5) for more information, especialy\n" "# Remember that you can only use http, ftp or file URIs\n" @@ -433,7 +433,7 @@ class SourceEntryMatcher: # some simple tests if __name__ == "__main__": - apt_pkg.InitConfig() + apt_pkg.init_config() sources = SourcesList() for entry in sources: diff --git a/doc/source/apt_pkg.rst b/doc/source/apt_pkg.rst index 8c602f37..39b48c35 100644 --- a/doc/source/apt_pkg.rst +++ b/doc/source/apt_pkg.rst @@ -13,17 +13,17 @@ 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 +.. function:: init_config Initialize the configuration of apt. This is needed for most operations. -.. function:: initSystem +.. function:: init_system Initialize the system. .. function:: init - Deprecated function. Use initConfig() and initSystem() instead. + Deprecated function. Use init_config() and init_system() instead. Working with the cache ---------------------- @@ -38,49 +38,49 @@ Working with the cache Return the :class:`Package()` object for the package name given by *pkgname*. - .. method:: Close() + .. method:: close() Close the package cache. - .. method:: Open([progress]) + .. method:: open([progress]) Open the package cache again. The parameter *progress* may be set to an :class:`apt.progress.OpProgress()` object or `None`. - .. method:: Update(progress, list) + .. method:: update(progress, list) Update the package cache. The parameter *progress* points to an :class:`apt.progress.FetchProgress()` object. The parameter *list* refers to a :class:`SourceList()` object. - .. attribute:: DependsCount + .. attribute:: depends_count The total number of dependencies. - .. attribute:: PackageCount + .. attribute:: package_count The total number of packages available in the cache. - .. attribute:: ProvidesCount + .. attribute:: provides_count The number of provided packages. - .. attribute:: VerFileCount + .. attribute:: ver_file_count .. todo:: Seems to be some mixture of versions and pkgFile. - .. attribute:: VersionCount + .. attribute:: version_count The total number of package versions available in the cache. - .. attribute:: PackageFileCount + .. attribute:: package_file_count The total number of Packages files available (the Packages files listing the packages). This is the same as the length of the list in - the attribute :attr:`FileList`. + the attribute :attr:`file_list`. - .. attribute:: FileList + .. attribute:: file_list A list of :class:`PackageFile` objects. @@ -92,7 +92,7 @@ Working with the cache The DepCache object contains various methods to manipulate the cache, to install packages, to remove them, and much more. - .. method:: Commit(fprogress, iprogress) + .. method:: commit(fprogress, iprogress) Apply all the changes made. @@ -102,11 +102,11 @@ Working with the cache The parameter *iprogress* has to be set to an instance of apt.progress.InstallProgress or one of its subclasses. - .. method:: FixBroken() + .. method:: fix_broken() Try to fix all broken packages in the cache. - .. method:: GetCandidateVer(pkg) + .. method:: get_candidate_ver(pkg) Return the candidate version of the package, ie. the version that would be installed normally. @@ -116,31 +116,31 @@ Working with the cache This method returns a :class:`Version` object. - .. method:: SetCandidateVer(pkg, version) + .. method:: set_candidate_ver(pkg, version) - The opposite of :meth:`pkgDepCache.GetCandidateVer`. Set the candidate + The opposite of :meth:`pkgDepCache.get_candidate_ver`. Set the candidate version of the :class:`Package` *pkg* to the :class:`Version` *version*. - .. method:: Upgrade([distUpgrade=False]) + .. method:: upgrade([dist_upgrade=False]) Perform an upgrade. More detailed, this marks all the upgradable packages for upgrade. You still need to call - :meth:`pkgDepCache.Commit` for the changes to apply. + :meth:`pkgDepCache.commit` for the changes to apply. - To perform a dist-upgrade, the optional parameter *distUpgrade* has + To perform a dist-upgrade, the optional parameter *dist_upgrade* has to be set to True. - .. method:: FixBroken() + .. method:: fix_broken() Fix broken packages. - .. method:: ReadPinFile() + .. method:: read_pin_file() Read the policy, eg. /etc/apt/preferences. - .. method:: MinimizeUpgrade() + .. method:: minimize_upgrade() Go over the entire set of packages and try to keep each package marked for upgrade. If a conflict is generated then the package is restored. @@ -148,101 +148,101 @@ Working with the cache .. todo:: Explain better.. - .. method:: MarkKeep(pkg) + .. method:: mark_keep(pkg) Mark the :class:`Package` *pkg* for keep. - .. method:: MarkDelete(pkg[, purge]) + .. method:: mark_delete(pkg[, purge]) Mark the :class:`Package` *pkg* for delete. If *purge* is True, the configuration files will be removed as well. - .. method:: MarkInstall(pkg[, autoInst=True[, fromUser=True]]) + .. method:: mark_install(pkg[, auto_inst=True[, from_user=True]]) Mark the :class:`Package` *pkg* for install. - If *autoInst* is ``True``, the dependencies of the package will be + If *auto_inst* is ``True``, the dependencies of the package will be installed as well. This is the default. - If *fromUser* is ``True``, the package will be marked as manually + If *from_user* is ``True``, the package will be marked as manually installed. This is the default. - .. method:: SetReinstall(pkg) + .. method:: set_re_install(pkg) Set if the :class:`Package` *pkg* should be reinstalled. - .. method:: IsUpgradable(pkg) + .. method:: is_upgradable(pkg) Return ``1`` if the package is upgradable. The package can be upgraded by calling :meth:`pkgDepCache.MarkInstall`. - .. method:: IsNowBroken(pkg) + .. method:: is_now_broken(pkg) Return `1` if the package is broken now (including changes made, but not committed). - .. method:: IsInstBroken(pkg) + .. method:: is_inst_broken(pkg) Return ``1`` if the package is broken on the current install. This takes changes which have not been committed not into effect. - .. method:: IsGarbage(pkg) + .. method:: is_garbage(pkg) Return ``1`` if the package is garbage, ie. if it is automatically installed and no longer referenced by other packages. - .. method:: IsAutoInstalled(pkg) + .. method:: is_auto_installed(pkg) Return ``1`` if the package is automatically installed (eg. as the dependency of another package). - .. method:: MarkedInstall(pkg) + .. method:: marked_install(pkg) Return ``1`` if the package is marked for install. - .. method:: MarkedUpgrade(pkg) + .. method:: marked_upgrade(pkg) Return ``1`` if the package is marked for upgrade. - .. method:: MarkedDelete(pkg) + .. method:: marked_delete(pkg) Return ``1`` if the package is marked for delete. - .. method:: MarkedKeep(pkg) + .. method:: marked_keep(pkg) Return ``1`` if the package is marked for keep. - .. method:: MarkedReinstall(pkg) + .. method:: marked_reinstall(pkg) Return ``1`` if the package should be installed. - .. method:: MarkedDowngrade(pkg) + .. method:: marked_downgrade(pkg) Return ``1`` if the package should be downgraded. - .. attribute:: KeepCount + .. attribute:: keep_count Integer, number of packages marked as keep - .. attribute:: InstCount + .. attribute:: inst_count Integer, number of packages marked for installation. - .. attribute:: DelCount + .. attribute:: del_count Number of packages which should be removed. - .. attribute:: BrokenCount + .. attribute:: broken_count Number of packages which are broken. - .. attribute:: UsrSize + .. attribute:: usr_size The size required for the changes on the filesystem. If you install packages, this is positive, if you remove them its negative. - .. attribute:: DebSize + .. attribute:: deb_size The size of the packages which are needed for the changes to be applied. @@ -256,7 +256,7 @@ Working with the cache :class:`PackageManager` objects provide several methods and attributes, which will be listed here: - .. method:: GetArchives(fetcher, list, records) + .. method:: get_archives(fetcher, list, records) Add all the selected packages to the :class:`Acquire()` object *fetcher*. @@ -265,34 +265,34 @@ Working with the cache The parameter *records* refers to a :class:`PackageRecords()` object. - .. method:: DoInstall() + .. method:: do_install() Install the packages. - .. method:: FixMissing + .. method:: fix_missing Fix the installation if a package could not be downloaded. - .. attribute:: ResultCompleted + .. attribute:: result_completed A constant for checking whether the the result is 'completed'. - Compare it against the return value of :meth:`PkgManager.GetArchives` - or :meth:`PkgManager.DoInstall`. + Compare it against the return value of :meth:`PackageManager.get_archives` + or :meth:`PackageManager.do_install`. - .. attribute:: ResultFailed + .. attribute:: result_failed A constant for checking whether the the result is 'failed'. - Compare it against the return value of :meth:`PkgManager.GetArchives` - or :meth:`PkgManager.DoInstall`. + Compare it against the return value of :meth:`PackageManager.get_archives` + or :meth:`PackageManager.do_install`. - .. attribute:: ResultIncomplete + .. attribute:: result_incomplete A constant for checking whether the the result is 'incomplete'. - Compare it against the return value of :meth:`PkgManager.GetArchives` - or :meth:`PkgManager.DoInstall`. + Compare it against the return value of :meth:`PackageManager.get_archives` + or :meth:`PackageManager.do_install`. Improve performance with :class:`ActionGroup` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -336,13 +336,13 @@ Resolving Dependencies .. class:: ProblemResolver(depcache) Return a new :class:`ProblemResolver` object. The parameter *depcache* - specifies a :class:`pkgDepCache` object as returned by :func:`GetDepCache`. + specifies a :class:`pDepCache` object. The problem resolver helps when there are problems in the package selection. An example is a package which conflicts with another, already installed package. - .. method:: Protect(pkg) + .. method:: protect(pkg) Protect the :class:`Package()` object given by the parameter *pkg*. @@ -350,11 +350,11 @@ Resolving Dependencies Really document it. - .. method:: InstallProtect() + .. method:: install_protect() Protect all installed packages from being removed. - .. method:: Remove(pkg) + .. method:: remove(pkg) Remove the :class:`Package()` object given by the parameter *pkg*. @@ -362,7 +362,7 @@ Resolving Dependencies Really document it. - .. method:: Clear(pkg) + .. method:: clear(pkg) Reset the :class:`Package()` *pkg* to the default state. @@ -370,11 +370,11 @@ Resolving Dependencies Really document it. - .. method:: Resolve() + .. method:: resolve() Try to resolve problems by installing and removing packages. - .. method:: ResolveByKeep() + .. method:: resolve_by_keep() Try to resolve problems only by using keep. @@ -386,65 +386,65 @@ Resolving Dependencies A :class:`PackageFile` represents a Packages file, eg. /var/lib/dpkg/status. - .. attribute:: Architecture + .. attribute:: architecture The architecture of the package file. - .. attribute:: Archive + .. attribute:: archive The archive (eg. unstable) - .. attribute:: Component + .. attribute:: component The component (eg. main) - .. attribute:: FileName + .. attribute:: file_name The name of the file. - .. attribute:: ID + .. attribute:: id The ID of the package. This is an integer which can be used to store further information about the file [eg. as dictionary key]. - .. attribute:: IndexType + .. attribute:: index_type The sort of the index file. In normal cases, this is 'Debian Package Index'. - .. attribute:: Label + .. attribute:: label The Label, as set in the Release file - .. attribute:: NotAutomatic + .. attribute:: not_automatic Whether packages from this list will be updated automatically. The default for eg. example is 0 (aka false). - .. attribute:: NotSource + .. attribute:: not_source Whether the file has no source from which it can be updated. In such a case, the value is 1; else 0. /var/lib/dpkg/status is 0 for example. Example:: - for pkgfile in cache.FileList: - if pkgfile.NotSource: - print 'The file %s has no source.' % pkgfile.FileName + for pkgfile in cache.file_list: + if pkgfile.not_source: + print 'The file %s has no source.' % pkgfile.file_name - .. attribute:: Origin + .. attribute:: origin The Origin, as set in the Release file - .. attribute:: Site + .. attribute:: site The hostname of the site. - .. attribute:: Size + .. attribute:: size The size of the file. - .. attribute:: Version + .. attribute:: version The version, as set in the release file (eg. "4.0" for "Etch") @@ -465,78 +465,78 @@ Example Attributes: - .. attribute:: CurrentVer + .. attribute:: current_ver The version currently installed, or None. This returns a :class:`Version` object. - .. attribute:: ID + .. attribute:: id The ID of the package. This can be used to store information about the package. The ID is an int value. - .. attribute:: Name + .. attribute:: name This is the name of the package. - .. attribute:: ProvidesList + .. attribute:: provides_list A list of packages providing this package. More detailed, this is a list of tuples (str:pkgname, ????, :class:`Version`). If you want to check for check for virtual packages, the expression - ``pkg.ProvidesList and not pkg.VersionList`` helps you. It detects if + ``pkg.provides_list and not pkg._version_list`` helps you. It detects if the package is provided by something else and is not available as a real package. - .. attribute:: RevDependsList + .. attribute:: rev_depends_list An iterator of :class:`Dependency` objects for dependencies on this package. - .. attribute:: Section + .. attribute:: section The section of the package, as specified in the record. The list of possible sections is defined in the Policy. - .. attribute:: VersionList + .. attribute:: version_list A list of :class:`Version` objects for all versions available in the cache. **States**: - .. attribute:: SelectedState + .. attribute:: selected_state The state we want it to be, ie. if you mark a package for installation, - this is :attr:`apt_pkg.SelStateInstall`. + this is :attr:`apt_pkg.SELSTATE_INSTALL`. See :ref:`SelStates` for a list of available states. - .. attribute:: InstState + .. attribute:: inst_state The state the currently installed version is in. This is normally - :attr:`apt_pkg.InstStateOK`, unless the installation failed. + :attr:`apt_pkg.INSTSTATE_OK`, unless the installation failed. See :ref:`InstStates` for a list of available states. - .. attribute:: CurState + .. attribute:: cur_state The current state of the package (not installed, unpacked, installed, etc). See :ref:`CurStates` for a list of available states. **Flags**: - .. attribute:: Auto + .. attribute:: auto Whether the package was installed automatically as a dependency of another package. (or marked otherwise as automatically installed) - .. attribute:: Essential + .. attribute:: essential Whether the package is essential. - .. attribute:: Important + .. attribute:: important Whether the package is important. @@ -553,25 +553,25 @@ Example: The version object contains all information related to a specific package version. - .. attribute:: VerStr + .. attribute:: ver_str The version, as a string. - .. attribute:: Section + .. attribute:: section The usual sections (eg. admin, net, etc.). Prefixed with the component name for packages not in main (eg. non-free/admin). - .. attribute:: Arch + .. attribute:: arch The architecture of the package, eg. amd64 or all. - .. attribute:: FileList + .. attribute:: file_list A list of (:class:`PackageFile`, int: index) tuples for all Package files containing this version of the package. - .. attribute:: DependsListStr + .. attribute:: depends_list_str A dictionary of dependencies. The key specifies the type of the dependency ('Depends', 'Recommends', etc.). @@ -601,58 +601,58 @@ Example: ] } - .. attribute:: DependsList + .. attribute:: depends_list This is basically the same as :attr:`Version.DependsListStr`, but instead of the ('pkgname', 'version', 'relation') tuples, it returns :class:`Dependency` objects, which can assist you with useful functions. - .. attribute:: ParentPkg + .. attribute:: parent_pkg The :class:`Package` object this version belongs to. - .. attribute:: ProvidesList + .. attribute:: provides_list This returns a list of all packages provided by this version. Like - :attr:`Package.ProvidesList`, it returns a list of tuples + :attr:`Package.provides_list`, it returns a list of tuples of the form ('virtualpkgname', ???, :class:`Version`), where as the last item is the same as the object itself. - .. attribute:: Size + .. attribute:: size The size of the .deb file, in bytes. - .. attribute:: InstalledSize + .. attribute:: installed_size The size of the package (in kilobytes), when unpacked on the disk. - .. attribute:: Hash + .. attribute:: hash An integer hash value. - .. attribute:: ID + .. attribute:: id An integer id. - .. attribute:: Priority + .. attribute:: priority The integer representation of the priority. This can be used to speed - up comparisons a lot, compared to :attr:`Version.PriorityStr`. + up comparisons a lot, compared to :attr:`Version.priority_str`. The values are defined in the :mod:`apt_pkg` extension, see :ref:`Priorities` for more information. - .. attribute:: PriorityStr + .. attribute:: priority_str Return the priority of the package version, as a string, eg. "optional". - .. attribute:: Downloadable + .. attribute:: downloadable Whether this package can be downloaded from a remote site. - .. attribute:: TranslatedDescription + .. attribute:: translated_description Return a :class:`Description` object. @@ -663,7 +663,7 @@ Example: Represent a dependency from one package to another one. - .. method:: AllTargets + .. method:: all_targets A list of :class:`Version` objects which satisfy the dependency, and do not conflict with already installed ones. @@ -673,40 +673,40 @@ Example: other candidates is already installed. This leads to results being very close to the normal package installation. - .. method:: SmartTargetPkg + .. method:: smart_target_pkg Return a :class:`Version` object of a package which satisfies the dependency and does not conflict with installed packages (the 'natural target'). - .. attribute:: TargetVer + .. attribute:: target_ver The target version of the dependency, as string. Empty string if the dependency is not versioned. - .. attribute:: TargetPkg + .. attribute:: target_pkg The :class:`Package` object of the target package. - .. attribute:: ParentVer + .. attribute:: parent_ver The :class:`Version` object of the parent version, ie. the package which declares the dependency. - .. attribute:: ParentPkg + .. attribute:: parent_pkg The :class:`Package` object of the package which declares the dependency. This is the same as using ParentVer.ParentPkg. - .. attribute:: CompType + .. attribute:: comp_type The type of comparison (>=, ==, >>, <=), as string. - .. attribute:: DepType + .. attribute:: dep_type The type of the dependency, as string, eg. "Depends". - .. attribute:: ID + .. attribute:: id The ID of the package, as integer. @@ -724,7 +724,7 @@ broken dependencies: Represent the description of the package. - .. attribute:: LanguageCode + .. attribute:: language_code The language code of the description @@ -732,7 +732,7 @@ broken dependencies: The md5 hashsum of the description - .. attribute:: FileList + .. attribute:: file_list A list of tuples (:class:`PackageFile`, int: index). @@ -747,10 +747,10 @@ broken dependencies: .. class:: MetaIndex - .. attribute:: URI - .. attribute:: Dist - .. attribute:: IsTrusted - .. attribute:: IndexFiles + .. attribute:: uri + .. attribute:: dist + .. attribute:: is_trusted + .. attribute:: index_files :class:`PackageIndexFile` @@ -758,27 +758,27 @@ broken dependencies: .. class:: PackageIndexFile - .. method:: ArchiveURI(path) + .. method:: archive_uri(path) Return the full url to path in the archive. - .. attribute:: Label + .. attribute:: label Return the Label. - .. attribute:: Exists + .. attribute:: exists Return whether the file exists. - .. attribute:: HasPackages + .. attribute:: has_packages Return whether the file has packages. - .. attribute:: Size + .. attribute:: size Size of the file - .. attribute:: IsTrusted + .. attribute:: is_trusted Whether we can trust the file. @@ -794,13 +794,13 @@ Records Provide access to the packages records. This provides very useful attributes for fast (convient) access to some fields of the record. - .. method:: Lookup(verfile_iter) + .. method:: lookup(verfile_iter) Change the actual package to the package given by the verfile_iter. The parameter *verfile_iter* refers to a tuple consisting of (:class:`PackageFile()`, int: index), as returned by various - attributes, including :attr:`Version.FileList`. + attributes, including :attr:`Version.file_list`. Example (shortened):: @@ -809,69 +809,69 @@ Records # Now you can access the record print records.SourcePkg # == python-apt - .. attribute:: FileName + .. attribute:: file_name Return the field 'Filename' of the record. This is the path to the package, relative to the base path of the archive. - .. attribute:: MD5Hash + .. attribute:: md5_hash Return the MD5 hashsum of the package This refers to the field 'MD5Sum' in the raw record. - .. attribute:: SHA1Hash + .. attribute:: sha1_hash Return the SHA1 hashsum of the package. This refers to the field 'SHA1' in the raw record. - .. attribute:: SHA256Hash + .. attribute:: sha256_hash Return the SHA256 hashsum of the package. This refers to the field 'SHA256' in the raw record. .. versionadded:: 0.7.9 - .. attribute:: SourcePkg + .. attribute:: source_pkg Return the source package. - .. attribute:: SourceVer + .. attribute:: source_ver Return the source version. - .. attribute:: Maintainer + .. attribute:: maintainer Return the maintainer of the package. - .. attribute:: ShortDesc + .. attribute:: short_desc Return the short description. This is the summary on the first line of the 'Description' field. - .. attribute:: LongDesc + .. attribute:: long_desc Return the long description. These are lines 2-END from the 'Description' field. - .. attribute:: Name + .. attribute:: name Return the name of the package. This is the 'Package' field. - .. attribute:: Homepage + .. attribute:: homepage Return the Homepage. This is the 'Homepage' field. - .. attribute:: Record + .. attribute:: record Return the whole record as a string. If you want to access fields of the record not available as an attribute, you can use - :func:`apt_pkg.ParseSection` to parse the record and access the field + :class:`apt_pkg.TagSection` to parse the record and access the field name. Example:: - section = apt_pkg.ParseSection(records.Record) - print section['SHA256'] + section = apt_pkg.TagSection(records.record) + print section['SHA256'] # Use records.sha256_hash instead .. class:: SourceRecords @@ -886,16 +886,16 @@ Records anymore (same applies when no Lookup has been made, or when it has been restarted). - .. method:: Lookup(pkgname) + .. method:: lookup(pkgname) Lookup the record for the package named *pkgname*. To access all available records, you need to call it multiple times. - Imagine a package P with two versions X, Y. The first ``Lookup(P)`` - would set the record to version X and the second ``Lookup(P)`` to + Imagine a package P with two versions X, Y. The first ``lookup(P)`` + would set the record to version X and the second ``lookup(P)`` to version Y. - .. method:: Restart() + .. method:: restart() Restart the lookup. @@ -903,26 +903,26 @@ Records would set the record to version X and the second ``Lookup(P)`` to version Y. - If you now call ``Restart()``, the internal position will be cleared. - Now you can call ``Lookup(P)`` again to move to X. + If you now call ``restart()``, the internal position will be cleared. + Now you can call ``lookup(P)`` again to move to X. - .. attribute:: Package + .. attribute:: package The name of the source package. - .. attribute:: Version + .. attribute:: version A string describing the version of the source package. - .. attribute:: Maintainer + .. attribute:: maintainer A string describing the name of the maintainer. - .. attribute:: Section + .. attribute:: section A string describing the section. - .. attribute:: Record + .. attribute:: record The whole record, as a string. You can use :func:`apt_pkg.ParseSection` if you need to parse it. @@ -930,22 +930,22 @@ Records You need to parse the record if you want to access fields not available via the attributes, eg. 'Standards-Version' - .. attribute:: Binaries + .. attribute:: binaries Return a list of strings describing the package names of the binaries created by the source package. This matches the 'Binary' field in the raw record. - .. attribute:: Index + .. attribute:: index The index in the Sources files. - .. attribute:: Files + .. attribute:: files The list of files. This returns a list of tuples with the contents ``(str: md5, int: size, str: path, str:type)``. - .. attribute:: BuildDepends + .. attribute:: build_depends Return the list of Build dependencies, as ``(str: package, str: version, int: op, int: type)``. @@ -1015,24 +1015,24 @@ installation. Acquire items have multiple methods: - .. method:: Acquire.Run() + .. method:: run() - Fetch all the items which have been added by :func:`GetPkgAcqFile`. + Fetch all the items which have been added by :class:`AcquireFile`. - .. method:: Acquire.Shutdown() + .. method:: shutdown() Shut the fetcher down. - .. attribute:: Acquire.TotalNeeded + .. attribute:: total_needed The total amount of bytes needed (including those of files which are already present) - .. attribute:: Acquire.FetchNeeded + .. attribute:: fetch_needed The total amount of bytes which need to be fetched. - .. attribute:: Acquire.PartialPresent + .. attribute:: partial_present Whether some files have been acquired already. (???) @@ -1040,70 +1040,70 @@ installation. The :class:`AcquireItem()` objects represent the items of a :class:`Acquire` object. :class:`AcquireItem()` objects can not be created - by the user, they are solely available through the :attr:`Acquire.Items` + by the user, they are solely available through the :attr:`Acquire.items` list of an :class:`Acquire` object. - .. attribute:: ID + .. attribute:: id The ID of the item. - .. attribute:: Complete + .. attribute:: complete Is the item completely acquired? - .. attribute:: Local + .. attribute:: local Is the item a local file? - .. attribute:: IsTrusted + .. attribute:: is_trusted Can the file be trusted? - .. attribute:: FileSize + .. attribute:: file_size The size of the file, in bytes. - .. attribute:: ErrorText + .. attribute:: error_text The error message. For example, when a file does not exist on a http server, this will contain a 404 error message. - .. attribute:: DestFile + .. attribute:: dest_file The location the file is saved as. - .. attribute:: DescURI + .. attribute:: desc_uri The source location. **Status**: - .. attribute:: Status + .. attribute:: status Integer, representing the status of the item. - .. attribute:: StatIdle + .. attribute:: stat_idle - Constant for comparing :attr:`AcquireItem.Status`. + Constant for comparing :attr:`AcquireItem.status`. - .. attribute:: StatFetching + .. attribute:: stat_fetching - Constant for comparing :attr:`AcquireItem.Status` + Constant for comparing :attr:`AcquireItem.status` - .. attribute:: StatDone + .. attribute:: stat_done - Constant for comparing :attr:`AcquireItem.Status` + Constant for comparing :attr:`AcquireItem.status` - .. attribute:: StatError + .. attribute:: stat_error - Constant for comparing :attr:`AcquireItem.Status` + Constant for comparing :attr:`AcquireItem.status` - .. attribute:: StatAuthError + .. attribute:: stat_auth_error - Constant for comparing :attr:`AcquireItem.Status` + Constant for comparing :attr:`AcquireItem.status` -.. class:: AcquireFile(owner, uri[, md5, size, descr, shortdescr, destdir, destfile]) +.. class:: AcquireFile(owner, uri[, md5, size, descr, short_descr, dest_dir, dest_file]) Create a new :class:`AcquireFile()` object and register it with *acquire*, so it will be fetched. AcquireFile objects provide no methods or attributes @@ -1123,12 +1123,12 @@ installation. which can then be used to calculate the progress and validate the download. The parameter *descr* is a descripition of the download. It may be - used to describe the item in the progress class. *shortDescr* is the + used to describe the item in the progress class. *short_descr* is the short form of it. - You can use *destdir* to manipulate the directory where the file will - be saved in. Instead of *destdir*, you can also specify the full path to - the file using the parameter *destfile*. You can not combine both. + You can use *dest_dir* to manipulate the directory where the file will + be saved in. Instead of *dest_dir*, you can also specify the full path to + the file using the parameter *dest_file*. You can not combine both. @@ -1192,24 +1192,24 @@ section as a string. An example for working with a TagFile could look like:: tagf = apt_pkg.TagFile(open('/var/lib/dpkg/status')) - tagf.Step() - print tagf.Section['Package'] + tagf.step() + print tagf.section['Package'] - .. method:: Step + .. method:: step Step forward to the next section. This simply returns ``1`` if OK, and ``0`` if there is no section - .. method:: Offset + .. method:: offset Return the current offset (in bytes) from the beginning of the file. - .. method:: Jump(offset) + .. method:: jump(offset) - Jump back/forward to *offset*. Use ``Jump(0)`` to jump to the + Jump back/forward to *offset*. Use ``jump(0)`` to jump to the beginning of the file again. - .. attribute:: Section + .. attribute:: section This is the current :class:`TagSection()` instance. @@ -1228,16 +1228,16 @@ section as a string. .. versionadded:: 0.8.0 - .. method:: Bytes + .. method:: bytes The number of bytes in the section. - .. method:: Find(key, default='') + .. method:: find(key, default='') Return the value of the field at the key *key* if available, else return *default*. - .. method:: FindFlag(key) + .. method:: find_flag(key) Find a yes/no value for the key *key*. An example for such a field is 'Essential'. @@ -1257,31 +1257,31 @@ section as a string. Return a list of keys in the section. -.. autofunction:: RewriteSection(section, order, rewrite_list) +.. autofunction:: rewrite_section(section, order, rewrite_list) -.. data:: RewritePackageOrder +.. data:: REWRITE_PACKAGE_ORDER The order in which the information for binary packages should be rewritten, i.e. the order in which the fields should appear. -.. data:: RewriteSourceOrder +.. data:: REWRITE_SOURCE_ORDER 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) +.. function:: check_dep(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")) + >>> bool(apt_pkg.check_dep("1.0", ">=", "1")) True -.. function:: ParseDepends(depends) +.. function:: parse_depends(depends) Parse the string *depends* which contains dependency information as specified in Debian Policy, Section 7.1. @@ -1290,10 +1290,10 @@ Dependencies one or more tuples in the format ``(package,version,operation)`` for every 'or'-option given, e.g.:: - >>> apt_pkg.ParseDepends("PkgA (>= VerA) | PkgB (>= VerB)") + >>> apt_pkg.parse_depends("PkgA (>= VerA) | PkgB (>= VerB)") [[('PkgA', 'VerA', '>='), ('PkgB', 'VerB', '>=')]] -.. function:: ParseSrcDepends(depends) +.. function:: parse_src_depends(depends) Parse the string *depends* which contains dependency information as specified in Debian Policy, Section 7.1. @@ -1302,14 +1302,14 @@ Dependencies one or more tuples in the format ``(package,version,operation)`` for every 'or'-option given, e.g.:: - >>> apt_pkg.ParseDepends("PkgA (>= VerA) | PkgB (>= VerB)") + >>> apt_pkg.parse_depends("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]") + >>> apt_pkg.parse_src_depends("a (>= 01) [i386 amd64]") [[('a', '01', '>=')]] @@ -1337,70 +1337,70 @@ Configuration Set the option at *key* to *value*. - .. method:: Find(key[, default='']) + .. method:: find(key[, default='']) Return the value for the given key *key*. This is the same as :meth:`Configuration.get`. If *key* does not exist, return *default*. - .. method:: FindFile(key[, default='']) + .. method:: find_file(key[, default='']) Return the filename hold by the configuration at *key*. This formats the filename correctly and supports the Dir:: stuff in the configuration. If *key* does not exist, return *default*. - .. method:: FindDir(key[, default='/']) + .. method:: find_dir(key[, default='/']) Return the absolute path to the directory specified in *key*. A trailing slash is appended. If *key* does not exist, return *default*. - .. method:: FindI(key[, default=0]) + .. method:: find_i(key[, default=0]) Return the integer value stored at *key*. If *key* does not exist, return *default*. - .. method:: FindB(key[, default=0]) + .. method:: find_b(key[, default=0]) Return the boolean value stored at *key*. This returns an integer, but it should be treated like True/False. If *key* does not exist, return *default*. - .. method:: Set(key, value) + .. method:: set(key, value) Set the value of *key* to *value*. - .. method:: Exists(key) + .. method:: exists(key) Check whether the key *key* exists in the configuration. - .. method:: SubTree(key) + .. method:: sub_tree(key) Return a sub tree starting at *key*. The resulting object can be used like this one. - .. method:: List([key]) + .. method:: list([key]) List all items at *key*. Normally, return the keys at the top level, eg. APT, Dir, etc. Use *key* to specify a key of which the childs will be returned. - .. method:: ValueList([key]) + .. method:: value_list([key]) - Same as :meth:`Configuration.List`, but this time for the values. + Same as :meth:`Configuration.list`, but this time for the values. - .. method:: MyTag() + .. method:: my_tag() Return the tag name of the current tree. Normally this is an empty string, but for subtrees it is the key of the subtree. - .. method:: Clear(key) + .. method:: clear(key) Clear the configuration. Remove all values and keys at *key*. @@ -1416,7 +1416,7 @@ Configuration .. method:: get(key[, default='']) - This behaves just like :meth:`dict.get` and :meth:`Configuration.Find`, + This behaves just like :meth:`dict.get` and :meth:`Configuration.find`, it returns the value of key or if it does not exist, *default*. .. class:: ConfigurationPtr @@ -1429,37 +1429,37 @@ Configuration Behaves like a :class:`Configuration()` objects, but provides access to a subsection of another Configuration-like object. This type of object is - returned by the :meth:`Configuration.SubTree()` method. + returned by the :meth:`Configuration.sub_tree()` method. -.. data:: Config +.. data:: config A :class:`ConfigurationPtr()` object with the default configuration. This - object is initialized by calling :func:`InitConfig`. + object is initialized by calling :func:`init_config`. Modifying ^^^^^^^^^ -.. function:: ReadConfigFile(configuration, filename) +.. function:: read_config_file(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) +.. function:: read_config_dir(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) +.. function:: read_config_file_isc(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) +.. function:: parse_command_line(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 @@ -1472,7 +1472,7 @@ Modifying Locking -------- -.. function:: GetLock(filename) +.. function:: get_lock(filename) Create an empty file at the path specified by the parameter *filename* and lock it. @@ -1483,11 +1483,11 @@ Locking When the lock is not required anymore, the file descriptor should be closed using :func:`os.close`. -.. function:: PkgSystemLock() +.. function:: pkg_system_lock() Lock the global pkgsystem. -.. function:: PkgSystemUnLock() +.. function:: pkg_system_un_lock() Unlock the global pkgsystem. @@ -1497,12 +1497,12 @@ Other classes Return a Cdrom object with the following methods: - .. method:: Ident(progress) + .. method:: ident(progress) Identify the cdrom. The parameter *progress* refers to an :class:`apt.progress.CdromProgress()` object. - .. method:: Add(progress) + .. method:: add(progress) Add the cdrom to the sources.list file. The parameter *progress* refers to an :class:`apt.progress.CdromProgress()` object. @@ -1511,52 +1511,52 @@ Other classes This is for :file:`/etc/apt/sources.list`. - .. method:: FindIndex(pkgfile) + .. method:: find_index(pkgfile) Return a :class:`PackageIndexFile` object for the :class:`PackageFile` *pkgfile*. - .. method:: ReadMainList + .. method:: read_main_list Read the main list. - .. method:: GetIndexes(acq[, all]) + .. method:: get_indexes(acq[, all]) Add the index files to the :class:`Acquire()` object *acq*. If *all* is given and ``True``, all files are fetched. String functions ---------------- -.. function:: Base64Encode(string) +.. function:: base64_encode(string) Encode the given string using base64, e.g:: - >>> apt_pkg.Base64Encode(u"A") + >>> apt_pkg.base64_encode(u"A") 'QQ==' -.. function:: CheckDomainList(host, list) +.. function:: check_domain_list(host, list) See if Host is in a ',' seperated list, e.g.:: - apt_pkg.CheckDomainList("alioth.debian.org","debian.net,debian.org") + apt_pkg.check_domain_list("alioth.debian.org","debian.net,debian.org") -.. function:: DeQuoteString(string) +.. function:: de_quote_string(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) +.. function:: quote_string(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") + >>> apt_pkg.quote_string("apt is cool","apt") '%61%70%74%20is%20cool' -.. function:: SizeToStr(size) +.. function:: size_to_str(size) Return a string presenting the human-readable version of the integer *size*. When calculating the units (k,M,G,etc.) the size is divided by the @@ -1564,10 +1564,10 @@ String functions Example:: - >>> apt_pkg.SizeToStr(10000) + >>> apt_pkg.size_to_str(10000) '10.0k' -.. function:: StringToBool(input) +.. function:: string_to_bool(input) Parse the string *input* and return one of **-1**, **0**, **1**. @@ -1583,35 +1583,35 @@ String functions Example:: - >>> apt_pkg.StringToBool("yes") + >>> apt_pkg.string_to_bool("yes") 1 - >>> apt_pkg.StringToBool("no") + >>> apt_pkg.string_to_bool("no") 0 - >>> apt_pkg.StringToBool("not-recognized") + >>> apt_pkg.string_to_bool("not-recognized") -1 -.. function:: StrToTime(rfc_time) +.. function:: str_to_time(rfc_time) Convert the :rfc:`1123` conforming string *rfc_time* to the unix time, and return the integer. This is the opposite of :func:`TimeRFC1123`. Example:: - >> apt_pkg.StrToTime('Thu, 01 Jan 1970 00:00:00 GMT') + >> apt_pkg.str_to_time('Thu, 01 Jan 1970 00:00:00 GMT') 0 -.. function:: TimeRFC1123(seconds) +.. function:: time_rfc1123(seconds) Format the unix time specified by the integer *seconds*, according to the requirements of :rfc:`1123`. Example:: - >>> apt_pkg.TimeRFC1123(0) + >>> apt_pkg.time_rfc1123(0) 'Thu, 01 Jan 1970 00:00:00 GMT' -.. function:: TimeToStr(seconds) +.. function:: time_to_str(seconds) Format a given duration in a human-readable manner. The parameter *seconds* refers to a number of seconds, given as an integer. The return value is a @@ -1619,26 +1619,26 @@ String functions Example:: - >>> apt_pkg.TimeToStr(3601) + >>> apt_pkg.time_to_str(3601) '1h0min1s' -.. function:: UpstreamVersion(version) +.. function:: upstream_version(version) Return the string *version*, eliminating everything following the last '-'. Thus, this should be equivalent to ``version.rsplit('-', 1)[0]``. -.. function:: URItoFileName(uri) +.. function:: uri_to_file_name(uri) Take a string *uri* as parameter and return a filename which can be used to store the file, based on the URI. Example:: - >>> apt_pkg.URItoFileName('http://debian.org/index.html') + >>> apt_pkg.uri_to_file_name('http://debian.org/index.html') 'debian.org_index.html' -.. function:: VersionCompare(a, b) +.. function:: version_compare(a, b) Compare two versions, *a* and *b*, and return an integer value which has the same characteristic as the built-in :func:`cmp` function. @@ -1662,73 +1662,73 @@ Module Constants Package States ^^^^^^^^^^^^^^^ -.. data:: CurStateConfigFiles -.. data:: CurStateHalfConfigured -.. data:: CurStateHalfInstalled -.. data:: CurStateInstalled -.. data:: CurStateNotInstalled -.. data:: CurStateUnPacked +.. data:: CURSTATE_CONFIG_FILES +.. data:: CURSTATE_HALF_CONFIGURED +.. data:: CURSTATE_HALF_INSTALLED +.. data:: CURSTATE_INSTALLED +.. data:: CURSTATE_NOT_INSTALLED +.. data:: CURSTATE_UN_PACKED Dependency types ^^^^^^^^^^^^^^^^ -.. data:: DepConflicts -.. data:: DepDepends -.. data:: DepObsoletes -.. data:: DepPreDepends -.. data:: DepRecommends -.. data:: DepReplaces -.. data:: DepSuggests +.. data:: DEP_CONFLICTS +.. data:: DEP_DEPENDS +.. data:: DEP_OBSOLETES +.. data:: DEP_PRE_DEPENDS +.. data:: DEP_RECOMMENDS +.. data:: DEP_REPLACES +.. data:: DEP_SUGGESTS .. _InstStates: Installed states ^^^^^^^^^^^^^^^^ -.. data:: InstStateHold -.. data:: InstStateHoldReInstReq -.. data:: InstStateOk -.. data:: InstStateReInstReq +.. data:: INSTSTATE_HOLD +.. data:: INSTSTATE_HOLD_RE_INST_REQ +.. data:: INSTSTATE_OK +.. data:: INSTSTATE_RE_INST_REQ .. _Priorities: Priorities ^^^^^^^^^^^ -.. data:: PriExtra -.. data:: PriImportant -.. data:: PriOptional -.. data:: PriRequired -.. data:: PriStandard +.. data:: PRI_EXTRA +.. data:: PRI_IMPORTANT +.. data:: PRI_OPTIONAL +.. data:: PRI_REQUIRED +.. data:: PRI_STANDARD .. _SelStates: Select states ^^^^^^^^^^^^^ -.. data:: SelStateDeInstall -.. data:: SelStateHold -.. data:: SelStateInstall -.. data:: SelStatePurge -.. data:: SelStateUnknown +.. data:: SELSTATE_DE_INSTALL +.. data:: SELSTATE_HOLD +.. data:: SELSTATE_INSTALL +.. data:: SELSTATE_PURGE +.. data:: SELSTATE_UNKNOWN Build information ^^^^^^^^^^^^^^^^^ -.. data:: Date +.. data:: DATE The date on which this extension has been compiled. -.. data:: LibVersion +.. data:: LIB_VERSION The version of the apt_pkg library. This is **not** the version of apt, nor the version of python-apt. -.. data:: Time +.. data:: TIME The time this extension has been built. -.. data:: Version +.. data:: VERSION The version of apt (not of python-apt). diff --git a/doc/source/examples/cache-packages.py b/doc/source/examples/cache-packages.py index 0af96f7d..72534303 100644 --- a/doc/source/examples/cache-packages.py +++ b/doc/source/examples/cache-packages.py @@ -6,17 +6,17 @@ import apt_pkg def main(): """Main.""" - apt_pkg.InitConfig() - apt_pkg.InitSystem() + apt_pkg.init_config() + apt_pkg.init_system() cache = apt_pkg.Cache() print "Essential packages:" - for pkg in cache.Packages: - if pkg.Essential: - print " ", pkg.Name + for pkg in cache.packages: + if pkg.essential: + print " ", pkg.name print "Important packages:" - for pkg in cache.Packages: - if pkg.Important: - print " ", pkg.Name + for pkg in cache.packages: + if pkg.important: + print " ", pkg.name if __name__ == "__main__": main() diff --git a/doc/source/examples/cache-pkgfile.py b/doc/source/examples/cache-pkgfile.py index a7c22c97..1300a55c 100644 --- a/doc/source/examples/cache-pkgfile.py +++ b/doc/source/examples/cache-pkgfile.py @@ -6,19 +6,19 @@ def main(): """Example for PackageFile()""" apt_pkg.init() cache = apt_pkg.Cache() - for pkgfile in cache.FileList: - print 'Package-File:', pkgfile.FileName - print 'Index-Type:', pkgfile.IndexType # 'Debian Package Index' - if pkgfile.NotSource: + for pkgfile in cache.file_list: + print 'Package-File:', pkgfile.file_name + print 'Index-Type:', pkgfile.index_type # 'Debian Package Index' + if pkgfile.not_source: print 'Source: None' else: - if pkgfile.Site: + if pkgfile.site: # There is a source, and a site, print the site - print 'Source:', pkgfile.Site + print 'Source:', pkgfile.site else: # It seems to be a local repository print 'Source: Local package file' - if pkgfile.NotAutomatic: + if pkgfile.not_automatic: # The system won't be updated automatically (eg. experimental) print 'Automatic: No' else: diff --git a/doc/source/examples/dpkg-contents.py b/doc/source/examples/dpkg-contents.py index 99d1596f..24d7ce98 100644 --- a/doc/source/examples/dpkg-contents.py +++ b/doc/source/examples/dpkg-contents.py @@ -28,7 +28,7 @@ def format_mode(what, mode): def callback(what, name, link, mode, uid, gid, size, mtime, major, minor): - """callback for debExtract""" + """callback for deb_extract""" s_mode = format_mode(what, mode) s_owner = "%s/%s" % (pwd.getpwuid(uid)[0], grp.getgrgid(gid)[0]) s_size = "%9d" % size @@ -47,7 +47,7 @@ def main(): fobj = open(sys.argv[1]) try: - apt_inst.debExtract(fobj, callback, "data.tar.gz") + apt_inst.deb_extract(fobj, callback, "data.tar.gz") finally: fobj.close() diff --git a/doc/source/examples/dpkg-extract.py b/doc/source/examples/dpkg-extract.py index ced8652f..8d144029 100644 --- a/doc/source/examples/dpkg-extract.py +++ b/doc/source/examples/dpkg-extract.py @@ -17,7 +17,7 @@ def main(): fobj = open(sys.argv[1]) try: - apt_inst.debExtractArchive(fobj, sys.argv[2]) + apt_inst.deb_extract_archive(fobj, sys.argv[2]) finally: fobj.close() diff --git a/doc/source/examples/dpkg-info.py b/doc/source/examples/dpkg-info.py index ff98d8b1..6be8595c 100644 --- a/doc/source/examples/dpkg-info.py +++ b/doc/source/examples/dpkg-info.py @@ -2,7 +2,7 @@ """Emulate dpkg --info package.deb control-file""" import sys -from apt_inst import debExtractControl +from apt_inst import deb_extract_control def main(): @@ -12,7 +12,7 @@ def main(): sys.exit(0) fobj = open(sys.argv[1]) try: - print debExtractControl(fobj, sys.argv[2]) + print deb_extract_control(fobj, sys.argv[2]) finally: fobj.close() diff --git a/doc/source/examples/missing-deps.py b/doc/source/examples/missing-deps.py index dd5eeb8a..7af18128 100644 --- a/doc/source/examples/missing-deps.py +++ b/doc/source/examples/missing-deps.py @@ -5,9 +5,9 @@ import apt_pkg def fmt_dep(dep): """Format a Dependency object [of apt_pkg] as a string.""" - ret = dep.TargetPkg.Name - if dep.TargetVer: - ret += " (%s %s)" % (dep.CompType, dep.TargetVer) + ret = dep.target_pkg.name + if dep.target_ver: + ret += " (%s %s)" % (dep.comp_type, dep.target_ver) return ret @@ -15,15 +15,15 @@ def check_version(pkgver): """Check the version of the package""" missing = [] - for or_group in pkgver.DependsList.get("Pre-Depends", []) + \ - pkgver.DependsList.get("Depends", []): - if not any(dep.AllTargets() for dep in or_group): + for or_group in pkgver.depends_list.get("Pre-Depends", []) + \ + pkgver.depends_list.get("Depends", []): + if not any(dep.all_targets() for dep in or_group): # If none of the or-choices can be satisfied, add it to missing missing.append(or_group) if missing: - print "Package:", pkgver.ParentPkg.Name - print "Version:", pkgver.VerStr + print "Package:", pkgver.parent_pkg.name + print "Version:", pkgver.ver_str print "Missing:", print ", ".join(" | ".join(fmt_dep(dep) for dep in or_group) for or_group in missing) @@ -32,18 +32,18 @@ def check_version(pkgver): def main(): """The main function.""" - apt_pkg.InitConfig() - apt_pkg.InitSystem() + apt_pkg.init_config() + apt_pkg.init_system() cache = apt_pkg.Cache() - for pkg in sorted(cache.Packages, key=lambda pkg: pkg.Name): + for pkg in sorted(cache.packages, key=lambda pkg: pkg.name): # pkg is from a list of packages, sorted by name. - for version in pkg.VersionList: + for version in pkg.version_list: # Check every version - for pfile, _ in version.FileList: - if (pfile.Origin == "Debian" and pfile.Component == "main" and - pfile.Archive == "unstable"): + for pfile, _ in version.file_list: + if (pfile.origin == "Debian" and pfile.component == "main" and + pfile.archive == "unstable"): # We only want packages from Debian unstable main. check_version(version) break -- cgit v1.2.3 From 14dfadc054e9bdafd2507dbca70dbec925471ae0 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 5 Jun 2009 15:00:15 +0200 Subject: Introduce the rename rules formally, and add some exceptions. --- apt/cache.py | 4 +- apt/package.py | 10 ++--- doc/source/apt_pkg.rst | 36 ++++++++-------- doc/source/examples/cache-pkgfile.py | 2 +- doc/source/whatsnew/0.8.0.rst | 82 +++++++++++++++++++++++++++++++++++- python/acquire.cc | 10 ++--- python/apt_pkgmodule.cc | 16 +++---- python/cache.cc | 2 +- python/configuration.cc | 2 +- python/depcache.cc | 4 +- python/pkgrecords.cc | 2 +- 11 files changed, 124 insertions(+), 46 deletions(-) (limited to 'apt') diff --git a/apt/cache.py b/apt/cache.py index 56b32d45..8590510c 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -170,8 +170,8 @@ class Cache(object): reqreinst = set() for pkg in self: if (not pkg.candidate.downloadable and - (pkg._pkg.inst_state == apt_pkg.INSTSTATE_RE_INST_REQ or - pkg._pkg.inst_state == apt_pkg.INSTSTATE_HOLD_RE_INST_REQ)): + (pkg._pkg.inst_state == apt_pkg.INSTSTATE_REINSTREQ or + pkg._pkg.inst_state == apt_pkg.INSTSTATE_HOLD_REINSTREQ)): reqreinst.add(pkg.name) return reqreinst diff --git a/apt/package.py b/apt/package.py index a24486e1..48d14595 100644 --- a/apt/package.py +++ b/apt/package.py @@ -379,7 +379,7 @@ class Version(object): .. versionadded:: 0.7.10 """ - return self._records.file_name + return self._records.filename @property def md5(self): @@ -413,7 +413,7 @@ class Version(object): for (packagefile, index) in self._cand.file_list: indexfile = self.package._pcache._list.find_index(packagefile) if indexfile: - yield indexfile.archive_uri(self._records.file_name) + yield indexfile.archive_uri(self._records.filename) @property def uris(self): @@ -443,19 +443,19 @@ class Version(object): .. versionadded:: 0.7.10 """ - base = os.path.basename(self._records.file_name) + base = os.path.basename(self._records.filename) destfile = os.path.join(destdir, base) if _file_is_same(destfile, self.size, self._records.md5_hash): print 'Ignoring already existing file:', destfile return acq = apt_pkg.Acquire(progress or apt.progress.TextFetchProgress()) apt_pkg.AcquireFile(acq, self.uri, self._records.md5_hash, self.size, - base, dest_file=destfile) + base, destfile=destfile) acq.run() for item in acq.items: if item.status != item.stat_done: raise FetchError("The item %r could not be fetched: %s" % - (item.dest_file, item.error_text)) + (item.destfile, item.error_text)) return os.path.abspath(destfile) def fetch_source(self, destdir="", progress=None, unpack=True): diff --git a/doc/source/apt_pkg.rst b/doc/source/apt_pkg.rst index 39b48c35..c814615c 100644 --- a/doc/source/apt_pkg.rst +++ b/doc/source/apt_pkg.rst @@ -167,7 +167,7 @@ Working with the cache If *from_user* is ``True``, the package will be marked as manually installed. This is the default. - .. method:: set_re_install(pkg) + .. method:: set_reinstall(pkg) Set if the :class:`Package` *pkg* should be reinstalled. @@ -398,7 +398,7 @@ Resolving Dependencies The component (eg. main) - .. attribute:: file_name + .. attribute:: filename The name of the file. @@ -430,7 +430,7 @@ Resolving Dependencies for pkgfile in cache.file_list: if pkgfile.not_source: - print 'The file %s has no source.' % pkgfile.file_name + print 'The file %s has no source.' % pkgfile.filename .. attribute:: origin @@ -809,7 +809,7 @@ Records # Now you can access the record print records.SourcePkg # == python-apt - .. attribute:: file_name + .. attribute:: filename Return the field 'Filename' of the record. This is the path to the package, relative to the base path of the archive. @@ -1103,7 +1103,7 @@ installation. Constant for comparing :attr:`AcquireItem.status` -.. class:: AcquireFile(owner, uri[, md5, size, descr, short_descr, dest_dir, dest_file]) +.. class:: AcquireFile(owner, uri[, md5, size, descr, short_descr, destdir, destfile]) Create a new :class:`AcquireFile()` object and register it with *acquire*, so it will be fetched. AcquireFile objects provide no methods or attributes @@ -1126,9 +1126,9 @@ installation. used to describe the item in the progress class. *short_descr* is the short form of it. - You can use *dest_dir* to manipulate the directory where the file will - be saved in. Instead of *dest_dir*, you can also specify the full path to - the file using the parameter *dest_file*. You can not combine both. + You can use *destdir* to manipulate the directory where the file will + be saved in. Instead of *destdir*, you can also specify the full path to + the file using the parameter *destfile*. You can not combine both. @@ -1379,7 +1379,7 @@ Configuration Check whether the key *key* exists in the configuration. - .. method:: sub_tree(key) + .. method:: subtree(key) Return a sub tree starting at *key*. The resulting object can be used like this one. @@ -1429,7 +1429,7 @@ Configuration Behaves like a :class:`Configuration()` objects, but provides access to a subsection of another Configuration-like object. This type of object is - returned by the :meth:`Configuration.sub_tree()` method. + returned by the :meth:`Configuration.subtree()` method. .. data:: config @@ -1459,7 +1459,7 @@ Modifying the settings therein to the :class:`Configuration()` object specified by the parameter *configuration* -.. function:: parse_command_line(configuration, options, argv) +.. function:: parse_commandline(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 @@ -1541,11 +1541,11 @@ String functions apt_pkg.check_domain_list("alioth.debian.org","debian.net,debian.org") -.. function:: de_quote_string(string) +.. function:: dequote_string(string) Dequote the string specified by the parameter *string*, e.g.:: - >>> apt_pkg.DeQuoteString("%61%70%74%20is%20cool") + >>> apt_pkg.dequote_string("%61%70%74%20is%20cool") 'apt is cool' .. function:: quote_string(string, repl) @@ -1627,14 +1627,14 @@ String functions Return the string *version*, eliminating everything following the last '-'. Thus, this should be equivalent to ``version.rsplit('-', 1)[0]``. -.. function:: uri_to_file_name(uri) +.. function:: uri_to_filename(uri) Take a string *uri* as parameter and return a filename which can be used to store the file, based on the URI. Example:: - >>> apt_pkg.uri_to_file_name('http://debian.org/index.html') + >>> apt_pkg.uri_to_filename('http://debian.org/index.html') 'debian.org_index.html' @@ -1667,7 +1667,7 @@ Package States .. data:: CURSTATE_HALF_INSTALLED .. data:: CURSTATE_INSTALLED .. data:: CURSTATE_NOT_INSTALLED -.. data:: CURSTATE_UN_PACKED +.. data:: CURSTATE_UNPACKED @@ -1687,9 +1687,9 @@ Dependency types Installed states ^^^^^^^^^^^^^^^^ .. data:: INSTSTATE_HOLD -.. data:: INSTSTATE_HOLD_RE_INST_REQ +.. data:: INSTSTATE_HOLD_REINSTREQ .. data:: INSTSTATE_OK -.. data:: INSTSTATE_RE_INST_REQ +.. data:: INSTSTATE_REINSTREQ .. _Priorities: diff --git a/doc/source/examples/cache-pkgfile.py b/doc/source/examples/cache-pkgfile.py index 1300a55c..f4cc2e66 100644 --- a/doc/source/examples/cache-pkgfile.py +++ b/doc/source/examples/cache-pkgfile.py @@ -7,7 +7,7 @@ def main(): apt_pkg.init() cache = apt_pkg.Cache() for pkgfile in cache.file_list: - print 'Package-File:', pkgfile.file_name + print 'Package-File:', pkgfile.filename print 'Index-Type:', pkgfile.index_type # 'Debian Package Index' if pkgfile.not_source: print 'Source: None' diff --git a/doc/source/whatsnew/0.8.0.rst b/doc/source/whatsnew/0.8.0.rst index d1ac3ac5..d507e82a 100644 --- a/doc/source/whatsnew/0.8.0.rst +++ b/doc/source/whatsnew/0.8.0.rst @@ -15,19 +15,97 @@ Python-apt is the first Debian package to support the third major release of Python. The port is straight forward and integrates as nicely in Python 3 as the Python 2 builds integrate in Python 2. +Please be aware that python-apt builds for Python 3 are built without the +compatibility options enabled for Python 2 builds. They also do not provide +methods like :meth:`has_key` on mapping objects, because it has been removed +in Python 3. + Real classes in :mod:`apt_pkg` ------------------------------ +The 0.8 release introduces real classes in the :mod:`apt_pkg` extension. This +is an important step forward and makes writing code much easier, because you +can see the classes without having to create an object first. It also makes +it easier to talk about those classes, because they have a real name now. + +The 0.7 series shipped many functions for creating new objects, because the +classes were not exported. In 0.8, the classes themselves replace those +functions, as you can see in the following table. + +.. table:: + + ===================================== ================================= + Function Replacing class + ===================================== ================================= + :func:`apt_pkg.GetAcquire` :class:`apt_pkg.Acquire` + :func:`apt_pkg.GetCache()` :class:`apt_pkg.Cache` + :func:`apt_pkg.GetCdrom()` :class:`apt_pkg.Cdrom` + :func:`apt_pkg.GetDepCache()` :class:`apt_pkg.DepCache` + :func:`apt_pkg.GetPackageManager` :class:`apt_pkg.PackageManager` + :func:`apt_pkg.GetPkgAcqFile` :class:`apt_pkg.AcquireFile` + :func:`apt_pkg.GetPkgActionGroup` :class:`apt_pkg.ActionGroup` + :func:`apt_pkg.GetPkgProblemResolver` :class:`apt_pkg.ProblemResolver` + :func:`apt_pkg.GetPkgRecords` :class:`apt_pkg.PackageRecords` + :func:`apt_pkg.GetPkgSourceList` :class:`apt_pkg.SourceList` + :func:`apt_pkg.GetPkgSrcRecords` :class:`apt_pkg.SourceRecords` + :func:`apt_pkg.ParseSection` :class:`apt_pkg.TagSection` + :func:`apt_pkg.ParseTagFile` :class:`apt_pkg.TagFile` + ===================================== ================================= Complete rename of functions, methods and attributes ----------------------------------------------------- +In May 2008, Ben Finney reported bug 481061 against the python-apt package, +asking for PEP8 conformant names. With the release of python-apt 0.8, this +is finally happening. Supporting new language features like the :keyword:`with` statement ------------------------------------------------------------------- +This is not a real big change, but it's good to have it: +:class:`apt_pkg.ActionGroup` can now be used as a context manager for the +:keyword:`with` statement. This makes it more obvious that you are using an +action group, and is just cooler:: + + with apt_pkg.ActionGroup(depcache): + for package in my_selected_packages: + depcache.mark_install(package) + +This also works for :class:`apt.Cache`:: + + with cache.action_group(): # cache is an Instance of apt.Cache + for package in my_selected_packages: + package.mark_install() # Instance of apt.Package + Other changes ------------- This release of python-apt also features several other, smaller changes: - * Reduced memory usage by creating Package() objects in apt.Cache() only - when needed. + * Reduced memory usage by making :class:`apt.Cache` create + :class:`apt.Package()` object dynamically, instead of creating all of + them during the cache initialization. * Support to set the candidate version in :class:`apt.package.Package` + +Porting your applications to python-apt 0.8 +------------------------------------------- +Porting your application to python-apt 0.8 may be trivial. You should download +the source tarball of python-apt and run the tool utils/migrate-0.8 using +Python 2.6 over your code:: + + python2.6 utils/migrate-0.8.py -c myapp.py mypackage/ + +This will search your code for places where possibly deprecated names are +used. Using the argument ``-c``, you can turn colorized output on. + +Now that you know which parts of your code have to be changed, you have to know +how to do this. For classes, please look at the table. For all attributes, +methods, functions, and their parameters the following rules apply: + + 1. Replace leading [A-Z] with [a-z] (e.g DescURI => descURI) + 2. Replace multiple [A-Z] with [A-Z][a-z] (e.g. descURI => descUri) + 3. Replace every [A-Z] with the corresponding [a-z] (descUri => desc_uri) + +As an exception, refixes such as 'de' (e.g. 'dequote') or 'un' (e.g. 'unlock') +are normally not seperated by underscores from the next word. There are also +some other exceptions which are listed here, and apply to any name containing +this word: **filename**, **filesize**, **destdir**, **destfile**, **dequote**, +**unlock**, **reinstall**, **pinfile**, **REINSTREQ**, **UNPACKED**, +**parse_commandline**. diff --git a/python/acquire.cc b/python/acquire.cc index 1b1c5dd8..5f38f7bd 100644 --- a/python/acquire.cc +++ b/python/acquire.cc @@ -40,9 +40,9 @@ MkGet(AcquireItemGetStatAuthError,Py_BuildValue("i", pkgAcquire::Item::StatAuthE static PyGetSetDef AcquireItemGetSet[] = { {"complete",AcquireItemGetComplete}, {"desc_uri",AcquireItemGetDescURI}, - {"dest_file",AcquireItemGetDestFile}, + {"destfile",AcquireItemGetDestFile}, {"error_text",AcquireItemGetErrorText}, - {"file_size",AcquireItemGetFileSize}, + {"filesize",AcquireItemGetFileSize}, {"is",AcquireItemGetID}, {"is_trusted",AcquireItemGetIsTrusted}, {"local",AcquireItemGetLocal}, @@ -310,7 +310,7 @@ static PyObject *PkgAcquireFileNew(PyTypeObject *type, PyObject *Args, PyObject int size = 0; uri = md5 = descr = shortDescr = destDir = destFile = ""; - char * kwlist[] = {"owner","uri", "md5", "size", "descr", "shortdescr", + char * kwlist[] = {"owner","uri", "md5", "size", "descr", "short_descr", "destdir", "destfile", NULL}; if (PyArg_ParseTupleAndKeywords(Args, kwds, "O!s|sissss", kwlist, @@ -335,8 +335,8 @@ static PyObject *PkgAcquireFileNew(PyTypeObject *type, PyObject *Args, PyObject static char *doc_PkgAcquireFile = - "AcquireFile(owner, uri[, md5, size, descr, short_descr, dest_dir," - "dest_file]) -> New AcquireFile() object\n\n" + "AcquireFile(owner, uri[, md5, size, descr, short_descr, destdir," + "destfile]) -> New AcquireFile() object\n\n" "The parameter *owner* refers to an apt_pkg.Acquire() object. You can use\n" "*destdir* OR *destfile* to specify the destination directory/file."; diff --git a/python/apt_pkgmodule.cc b/python/apt_pkgmodule.cc index bfabc652..403e0ebf 100644 --- a/python/apt_pkgmodule.cc +++ b/python/apt_pkgmodule.cc @@ -407,7 +407,7 @@ static PyMethodDef methods[] = // Locking {"get_lock",GetLock,METH_VARARGS,doc_GetLock}, {"pkgsystem_lock",PkgSystemLock,METH_VARARGS,doc_PkgSystemLock}, - {"pkgsystem_un_lock",PkgSystemUnLock,METH_VARARGS,doc_PkgSystemUnLock}, + {"pkgsystem_unlock",PkgSystemUnLock,METH_VARARGS,doc_PkgSystemUnLock}, #ifdef COMPAT_0_7 {"GetLock",GetLock,METH_VARARGS,doc_GetLock}, {"PkgSystemLock",PkgSystemLock,METH_VARARGS,doc_PkgSystemLock}, @@ -418,7 +418,7 @@ static PyMethodDef methods[] = {"read_config_file",LoadConfig,METH_VARARGS,doc_LoadConfig}, {"read_config_dir",LoadConfigDir,METH_VARARGS,doc_LoadConfigDir}, {"read_config_file_isc",LoadConfigISC,METH_VARARGS,doc_LoadConfig}, - {"parse_command_line",ParseCommandLine,METH_VARARGS,doc_ParseCommandLine}, + {"parse_commandline",ParseCommandLine,METH_VARARGS,doc_ParseCommandLine}, #ifdef COMPAT_0_7 {"ReadConfigFile",LoadConfig,METH_VARARGS,doc_LoadConfig}, {"ReadConfigDir",LoadConfigDir,METH_VARARGS,doc_LoadConfigDir}, @@ -452,10 +452,10 @@ static PyMethodDef methods[] = // Strings {"check_domain_list",StrCheckDomainList,METH_VARARGS,"CheckDomainList(String,String) -> Bool"}, {"quote_string",StrQuoteString,METH_VARARGS,"QuoteString(String,String) -> String"}, - {"de_quote_string",StrDeQuote,METH_VARARGS,"DeQuoteString(String) -> String"}, + {"dequote_string",StrDeQuote,METH_VARARGS,"DeQuoteString(String) -> String"}, {"size_to_str",StrSizeToStr,METH_VARARGS,"SizeToStr(int) -> String"}, {"time_to_str",StrTimeToStr,METH_VARARGS,"TimeToStr(int) -> String"}, - {"uri_to_file_name",StrURItoFileName,METH_VARARGS,"URItoFileName(String) -> String"}, + {"uri_to_filename",StrURItoFileName,METH_VARARGS,"URItoFileName(String) -> String"}, {"base64_encode",StrBase64Encode,METH_VARARGS,"Base64Encode(String) -> String"}, {"string_to_bool",StrStringToBool,METH_VARARGS,"StringToBool(String) -> int"}, {"time_rfc1123",StrTimeRFC1123,METH_VARARGS,"TimeRFC1123(int) -> String"}, @@ -657,7 +657,7 @@ extern "C" void initapt_pkg() #endif // CurState PyModule_AddIntConstant(Module,"CURSTATE_NOT_INSTALLED",pkgCache::State::NotInstalled); - PyModule_AddIntConstant(Module,"CURSTATE_UN_PACKED",pkgCache::State::UnPacked); + PyModule_AddIntConstant(Module,"CURSTATE_UNPACKED",pkgCache::State::UnPacked); PyModule_AddIntConstant(Module,"CURSTATE_HALF_CONFIGURED",pkgCache::State::HalfConfigured); PyModule_AddIntConstant(Module,"CURSTATE_HALF_INSTALLED",pkgCache::State::HalfInstalled); PyModule_AddIntConstant(Module,"CURSTATE_CONFIG_FILES",pkgCache::State::ConfigFiles); @@ -666,13 +666,13 @@ extern "C" void initapt_pkg() PyModule_AddIntConstant(Module,"SELSTATE_UNKNOWN",pkgCache::State::Unknown); PyModule_AddIntConstant(Module,"SELSTATE_INSTALL",pkgCache::State::Install); PyModule_AddIntConstant(Module,"SELSTATE_HOLD",pkgCache::State::Hold); - PyModule_AddIntConstant(Module,"SELSTATE_DE_INSTALL",pkgCache::State::DeInstall); + PyModule_AddIntConstant(Module,"SELSTATE_DEINSTALL",pkgCache::State::DeInstall); PyModule_AddIntConstant(Module,"SELSTATE_PURGE",pkgCache::State::Purge); // InstState PyModule_AddIntConstant(Module,"INSTSTATE_OK",pkgCache::State::Ok); - PyModule_AddIntConstant(Module,"INSTSTATE_RE_INST_REQ",pkgCache::State::ReInstReq); + PyModule_AddIntConstant(Module,"INSTSTATE_REINSTREQ",pkgCache::State::ReInstReq); PyModule_AddIntConstant(Module,"INSTSTATE_HOLD",pkgCache::State::Hold); - PyModule_AddIntConstant(Module,"INSTSTATE_HOLD_RE_INST_REQ",pkgCache::State::HoldReInstReq); + PyModule_AddIntConstant(Module,"INSTSTATE_HOLD_REINSTREQ",pkgCache::State::HoldReInstReq); #ifdef COMPAT_0_7 PyModule_AddIntConstant(Module,"CurStateNotInstalled",pkgCache::State::NotInstalled); diff --git a/python/cache.cc b/python/cache.cc index 21a6a872..d09e22f3 100644 --- a/python/cache.cc +++ b/python/cache.cc @@ -1030,7 +1030,7 @@ static PyGetSetDef PackageFileGetSet[] = { {(char*)"architecture",PackageFile_GetArchitecture}, {(char*)"archive",PackageFile_GetArchive}, {(char*)"component",PackageFile_GetComponent}, - {(char*)"file_name",PackageFile_GetFileName}, + {(char*)"filename",PackageFile_GetFileName}, {(char*)"id",PackageFile_GetID}, {(char*)"index_type",PackageFile_GetIndexType}, {(char*)"label",PackageFile_GetLabel}, diff --git a/python/configuration.cc b/python/configuration.cc index 7b08d90e..81dd78ac 100644 --- a/python/configuration.cc +++ b/python/configuration.cc @@ -462,7 +462,7 @@ static PyMethodDef CnfMethods[] = // Others {"set",CnfSet,METH_VARARGS,doc_Set}, {"exists",CnfExists,METH_VARARGS,doc_Exists}, - {"sub_tree",CnfSubTree,METH_VARARGS,doc_SubTree}, + {"subtree",CnfSubTree,METH_VARARGS,doc_SubTree}, {"list",CnfList,METH_VARARGS,doc_List}, {"value_list",CnfValueList,METH_VARARGS,doc_ValueList}, {"my_tag",CnfMyTag,METH_VARARGS,doc_MyTag}, diff --git a/python/depcache.cc b/python/depcache.cc index 650dcb23..f69802f8 100644 --- a/python/depcache.cc +++ b/python/depcache.cc @@ -535,13 +535,13 @@ static PyMethodDef PkgDepCacheMethods[] = // global cache operations {"upgrade",PkgDepCacheUpgrade,METH_VARARGS,"Perform Upgrade (optional boolean argument if dist-upgrade should be performed)"}, {"fix_broken",PkgDepCacheFixBroken,METH_VARARGS,"Fix broken packages"}, - {"read_pin_file",PkgDepCacheReadPinFile,METH_VARARGS,"Read the pin policy"}, + {"read_pinfile",PkgDepCacheReadPinFile,METH_VARARGS,"Read the pin policy"}, {"minimize_upgrade",PkgDepCacheMinimizeUpgrade, METH_VARARGS,"Go over the entire set of packages and try to keep each package marked for upgrade. If a conflict is generated then the package is restored."}, // Manipulators {"mark_keep",PkgDepCacheMarkKeep,METH_VARARGS,"Mark package for keep"}, {"mark_delete",PkgDepCacheMarkDelete,METH_VARARGS,"Mark package for delete (optional boolean argument if it should be purged)"}, {"mark_install",PkgDepCacheMarkInstall,METH_VARARGS,"Mark package for Install"}, - {"set_re_install",PkgDepCacheSetReInstall,METH_VARARGS,"Set if the package should be reinstalled"}, + {"set_reinstall",PkgDepCacheSetReInstall,METH_VARARGS,"Set if the package should be reinstalled"}, // state information {"is_upgradable",PkgDepCacheIsUpgradable,METH_VARARGS,"Is pkg upgradable"}, {"is_now_broken",PkgDepCacheIsNowBroken,METH_VARARGS,"Is pkg is now broken"}, diff --git a/python/pkgrecords.cc b/python/pkgrecords.cc index 48440387..212e4ab0 100644 --- a/python/pkgrecords.cc +++ b/python/pkgrecords.cc @@ -120,7 +120,7 @@ static PyObject *PkgRecordsGetRecord(PyObject *Self,void*) { return PyString_FromStringAndSize(start,stop-start); } static PyGetSetDef PkgRecordsGetSet[] = { - {"file_name",PkgRecordsGetFileName}, + {"filename",PkgRecordsGetFileName}, {"homepage",PkgRecordsGetHomepage}, {"long_desc",PkgRecordsGetLongDesc}, {"md5_hash",PkgRecordsGetMD5Hash}, -- cgit v1.2.3 From 994a13b252f97f6ae77872b5d5118ac1366b2a24 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 5 Jun 2009 19:13:20 +0200 Subject: python/progress.cc, apt/progress/*.py: Use PEP 8 naming conventions for progress This changes the progress classes to use PEP 8 names. Due to the concept of the deprecation system, this causes methods of subclasses not to be called at all. If a class implements a command with underscores, it is called. If the class also implements the version in mixedCase, this is ignored. This means that all subclasses will not work correctly, because only the method from the parent class is called. --- apt/deprecation.py | 2 +- apt/progress/__init__.py | 133 +++++++++++++++++++++++++++++++---------------- apt/progress/gtk2.py | 52 +++++++++++------- python/progress.cc | 81 +++++++++++++++++++++++------ 4 files changed, 184 insertions(+), 84 deletions(-) (limited to 'apt') diff --git a/apt/deprecation.py b/apt/deprecation.py index 6827a8b9..0f39ad63 100644 --- a/apt/deprecation.py +++ b/apt/deprecation.py @@ -67,7 +67,7 @@ def function_deprecated_by(func, convert_names=True): This function also converts all keyword argument names from mixedCase to lowercase_with_underscores, but only if 'convert_names' is True (default). """ - warning = 'Deprecated, please use \'%s\' instead' % func.__name__ + warning = 'Deprecated, please use \'%s()\' instead' % func.__name__ def deprecated_function(*args, **kwds): """Wrapper around a deprecated function.""" diff --git a/apt/progress/__init__.py b/apt/progress/__init__.py index d2a9d497..6e4c6eec 100644 --- a/apt/progress/__init__.py +++ b/apt/progress/__init__.py @@ -33,6 +33,7 @@ import select import sys import apt_pkg +from apt.deprecation import AttributeDeprecatedBy, function_deprecated_by __all__ = ('CdromProgress', 'DpkgInstallProgress', 'DumbInstallProgress', @@ -48,7 +49,7 @@ class OpProgress(object): def __init__(self): self.op = None - self.subOp = None + self.sub_op = None def update(self, percent): """Called periodically to update the user interface.""" @@ -56,6 +57,9 @@ class OpProgress(object): def done(self): """Called once an operation has been completed.""" + if apt_pkg._COMPAT_0_7: + subOp = AttributeDeprecatedBy('sub_op') + class OpTextProgress(OpProgress): """A simple text based cache open reporting class.""" @@ -65,7 +69,7 @@ class OpTextProgress(OpProgress): def update(self, percent): """Called periodically to update the user interface.""" - sys.stdout.write("\r%s: %.2i " % (self.subOp, percent)) + sys.stdout.write("\r%s: %.2i " % (self.sub_op, percent)) sys.stdout.flush() def done(self): @@ -80,26 +84,26 @@ class FetchProgress(object): """ # download status constants - dlDone = 0 - dlQueued = 1 - dlFailed = 2 - dlHit = 3 - dlIgnored = 4 - dlStatusStr = {dlDone: "Done", - dlQueued: "Queued", - dlFailed: "Failed", - dlHit: "Hit", - dlIgnored: "Ignored"} + dl_done = 0 + dl_queued = 1 + dl_failed = 2 + dl_hit = 3 + dl_ignored = 4 + dl_status_str = {dl_done: "Done", + dl_queued: "Queued", + dl_failed: "Failed", + dl_hit: "Hit", + dl_ignored: "Ignored"} def __init__(self): self.eta = 0.0 self.percent = 0.0 # Make checking easier - self.currentBytes = 0 - self.currentItems = 0 - self.totalBytes = 0 - self.totalItems = 0 - self.currentCPS = 0 + self.current_bytes = 0 + self.current_items = 0 + self.total_bytes = 0 + self.total_items = 0 + self.current_cps = 0 def start(self): """Called when the fetching starts.""" @@ -107,7 +111,7 @@ class FetchProgress(object): def stop(self): """Called when all files have been fetched.""" - def updateStatus(self, uri, descr, shortDescr, status): + def update_status(self, uri, descr, short_descr, status): """Called when the status of an item changes. This happens eg. when the downloads fails or is completed. @@ -118,16 +122,31 @@ class FetchProgress(object): Return True to continue or False to cancel. """ - self.percent = (((self.currentBytes + self.currentItems) * 100.0) / - float(self.totalBytes + self.totalItems)) - if self.currentCPS > 0: - self.eta = ((self.totalBytes - self.currentBytes) / - float(self.currentCPS)) + self.percent = (((self.current_bytes + self.current_items) * 100.0) / + float(self.total_bytes + self.total_items)) + if self.current_cps > 0: + self.eta = ((self.total_bytes - self.current_bytes) / + float(self.current_cps)) return True - def mediaChange(self, medium, drive): + def media_change(self, medium, drive): """react to media change events.""" + if apt_pkg._COMPAT_0_7: + dlDone = AttributeDeprecatedBy('dl_done') + dlQueued = AttributeDeprecatedBy('dl_queued') + dlFailed = AttributeDeprecatedBy('dl_failed') + dlHit = AttributeDeprecatedBy('dl_hit') + dlIgnored = AttributeDeprecatedBy('dl_ignored') + dlStatusStr = AttributeDeprecatedBy('dl_status_str') + currentBytes = AttributeDeprecatedBy('current_bytes') + currentItems = AttributeDeprecatedBy('current_items') + totalBytes = AttributeDeprecatedBy('total_bytes') + totalItems = AttributeDeprecatedBy('total_items') + currentCPS = AttributeDeprecatedBy('current_cps') + updateStatus = function_deprecated_by(update_status) + mediaChange = function_deprecated_by(media_change) + class TextFetchProgress(FetchProgress): """ Ready to use progress object for terminal windows """ @@ -136,13 +155,13 @@ class TextFetchProgress(FetchProgress): FetchProgress.__init__(self) self.items = {} - def updateStatus(self, uri, descr, shortDescr, status): + def update_status(self, uri, descr, short_descr, status): """Called when the status of an item changes. This happens eg. when the downloads fails or is completed. """ - if status != self.dlQueued: - print "\r%s %s" % (self.dlStatusStr[status], descr) + if status != self.dl_queued: + print "\r%s %s" % (self.dl_status_str[status], descr) self.items[uri] = status def pulse(self): @@ -151,10 +170,10 @@ class TextFetchProgress(FetchProgress): Return True to continue or False to cancel. """ FetchProgress.pulse(self) - if self.currentCPS > 0: + if self.current_cps > 0: s = "[%2.f%%] %sB/s %s" % (self.percent, - apt_pkg.size_to_str(int(self.currentCPS)), - apt_pkg.time_to_str(int(self.eta))) + apt_pkg.size_to_str(int(self.current_cps)), + apt_pkg.time_to_str(int(self.eta))) else: s = "%2.f%% [Working]" % (self.percent) print "\r%s" % (s), @@ -165,13 +184,17 @@ class TextFetchProgress(FetchProgress): """Called when all files have been fetched.""" print "\rDone downloading " - def mediaChange(self, medium, drive): + def media_change(self, medium, drive): """react to media change events.""" print ("Media change: please insert the disc labeled " "'%s' in the drive '%s' and press enter") % (medium, drive) return raw_input() not in ('c', 'C') + if apt_pkg._COMPAT_0_7: + updateStatus = function_deprecated_by(update_status) + mediaChange = function_deprecated_by(media_change) + class DumbInstallProgress(object): """Report the install progress. @@ -179,19 +202,24 @@ class DumbInstallProgress(object): Subclass this class to implement install progress reporting. """ - def startUpdate(self): + def start_update(self): """Start update.""" def run(self, pm): """Start installation.""" return pm.do_install() - def finishUpdate(self): + def finish_update(self): """Called when update has finished.""" - def updateInterface(self): + def update_interface(self): """Called periodically to update the user interface""" + if apt_pkg._COMPAT_0_7: + startUpdate = function_deprecated_by(start_update) + finishUpdate = function_deprecated_by(finish_update) + updateInterface = function_deprecated_by(update_interface) + class InstallProgress(DumbInstallProgress): """An InstallProgress that is pretty useful. @@ -202,7 +230,7 @@ class InstallProgress(DumbInstallProgress): def __init__(self): DumbInstallProgress.__init__(self) - self.selectTimeout = 0.1 + self.select_timeout = 0.1 (read, write) = os.pipe() self.writefd = write self.statusfd = os.fdopen(read, "r") @@ -217,10 +245,10 @@ class InstallProgress(DumbInstallProgress): def conffile(self, current, new): """Called when a conffile question from dpkg is detected.""" - def statusChange(self, pkg, percent, status): + def status_change(self, pkg, percent, status): """Called when the status changed.""" - def updateInterface(self): + def update_interface(self): """Called periodically to update the interface.""" if self.statusfd is None: return @@ -253,7 +281,7 @@ class InstallProgress(DumbInstallProgress): self.conffile(match.group(1), match.group(2)) elif status == "pmstatus": if float(percent) != self.percent or status_str != self.status: - self.statusChange(pkg, float(percent), + self.status_change(pkg, float(percent), status_str.strip()) self.percent = float(percent) self.status = status_str.strip() @@ -263,11 +291,11 @@ class InstallProgress(DumbInstallProgress): """Fork.""" return os.fork() - def waitChild(self): + def wait_child(self): """Wait for child progress to exit.""" while True: - select.select([self.statusfd], [], [], self.selectTimeout) - self.updateInterface() + select.select([self.statusfd], [], [], self.select_timeout) + self.update_interface() (pid, res) = os.waitpid(self.child_pid, os.WNOHANG) if pid == self.child_pid: break @@ -281,9 +309,15 @@ class InstallProgress(DumbInstallProgress): res = pm.do_install(self.writefd) os._exit(res) self.child_pid = pid - res = self.waitChild() + res = self.wait_child() return os.WEXITSTATUS(res) + if apt_pkg._COMPAT_0_7: + selectTimeout = AttributeDeprecatedBy('select_timeout') + statusChange = function_deprecated_by(status_change) + waitChild = function_deprecated_by(wait_child) + updateInterface = function_deprecated_by(update_interface) + class CdromProgress(object): """Report the cdrom add progress. @@ -297,12 +331,16 @@ class CdromProgress(object): def update(self, text, step): """Called periodically to update the user interface.""" - def askCdromName(self): + def ask_cdrom_name(self): """Called to ask for the name of the cdrom.""" - def changeCdrom(self): + def change_cdrom(self): """Called to ask for the cdrom to be changed.""" + if apt_pkg._COMPAT_0_7: + askCdromName = function_deprecated_by(ask_cdrom_name) + changeCdrom = function_deprecated_by(change_cdrom) + class DpkgInstallProgress(InstallProgress): """Progress handler for a local Debian package installation.""" @@ -318,10 +356,10 @@ class DpkgInstallProgress(InstallProgress): (self.writefd, self.debfile)) os._exit(os.WEXITSTATUS(res)) self.child_pid = pid - res = self.waitChild() + res = self.wait_child() return res - def updateInterface(self): + def update_interface(self): """Process status messages from dpkg.""" if self.statusfd is None: return @@ -354,3 +392,6 @@ class DpkgInstallProgress(InstallProgress): else: self.status = status self.read = "" + + if apt_pkg._COMPAT_0_7: + updateInterface = function_deprecated_by(update_interface) diff --git a/apt/progress/gtk2.py b/apt/progress/gtk2.py index 06ece2d5..c0c05426 100644 --- a/apt/progress/gtk2.py +++ b/apt/progress/gtk2.py @@ -39,6 +39,7 @@ import vte import apt import apt_pkg +from apt.deprecation import function_deprecated_by def mksig(params=(), run=gobject.SIGNAL_RUN_FIRST, rettype=gobject.TYPE_NONE): @@ -113,13 +114,13 @@ class GInstallProgress(gobject.GObject, apt.progress.InstallProgress): self.time_last_update = time.time() self.term = term reaper = vte.reaper_get() - reaper.connect("child-exited", self.childExited) + reaper.connect("child-exited", self.child_exited) self.env = ["VTE_PTY_KEEP_FD=%s" % self.writefd, "DEBIAN_FRONTEND=gnome", "APT_LISTCHANGES_FRONTEND=gtk"] self._context = glib.main_context_default() - def childExited(self, term, pid, status): + def child_exited(self, term, pid, status): """Called when a child process exits""" self.apt_status = os.WEXITSTATUS(status) self.finished = True @@ -138,21 +139,21 @@ class GInstallProgress(gobject.GObject, apt.progress.InstallProgress): """ self.emit("status-conffile") - def startUpdate(self): + def start_update(self): """Called when the update starts. Emits: status-started() """ self.emit("status-started") - def finishUpdate(self): + def finish_update(self): """Called when the update finished. Emits: status-finished() """ self.emit("status-finished") - def statusChange(self, pkg, percent, status): + def status_change(self, pkg, percent, status): """Called when the status changed. Emits: status-changed(status, percent) @@ -160,12 +161,12 @@ class GInstallProgress(gobject.GObject, apt.progress.InstallProgress): self.time_last_update = time.time() self.emit("status-changed", status, percent) - def updateInterface(self): + def update_interface(self): """Called periodically to update the interface. Emits: status-timeout() [When a timeout happens] """ - apt.progress.InstallProgress.updateInterface(self) + apt.progress.InstallProgress.update_interface(self) while self._context.pending(): self._context.iteration() if self.time_last_update + self.INSTALL_TIMEOUT < time.time(): @@ -175,12 +176,20 @@ class GInstallProgress(gobject.GObject, apt.progress.InstallProgress): """Fork the process.""" return self.term.forkpty(envv=self.env) - def waitChild(self): + def wait_child(self): """Wait for the child process to exit.""" while not self.finished: - self.updateInterface() + self.update_interface() return self.apt_status + if apt_pkg._COMPAT_0_7: + updateInterface = function_deprecated_by(update_interface) + startUpdate = function_deprecated_by(start_update) + finishUpdate = function_deprecated_by(finish_update) + statusChange = function_deprecated_by(status_change) + waitChild = function_deprecated_by(wait_child) + childExited = function_deprecated_by(child_exited) + class GDpkgInstallProgress(apt.progress.DpkgInstallProgress, GInstallProgress): """An InstallProgress for local installations. @@ -199,14 +208,17 @@ class GDpkgInstallProgress(apt.progress.DpkgInstallProgress, GInstallProgress): """Install the given package.""" apt.progress.DpkgInstallProgress.run(self, debfile) - def updateInterface(self): + def update_interface(self): """Called periodically to update the interface. Emits: status-timeout() [When a timeout happens]""" - apt.progress.DpkgInstallProgress.updateInterface(self) + apt.progress.DpkgInstallProgress.update_interface(self) if self.time_last_update + self.INSTALL_TIMEOUT < time.time(): self.emit("status-timeout") + if apt_pkg._COMPAT_0_7: + updateInterface = function_deprecated_by(update_interface) + class GFetchProgress(gobject.GObject, apt.progress.FetchProgress): """A Fetch Progress with GObject signals. @@ -239,19 +251,19 @@ class GFetchProgress(gobject.GObject, apt.progress.FetchProgress): def pulse(self): apt.progress.FetchProgress.pulse(self) - currentItem = self.currentItems + 1 - if currentItem > self.totalItems: - currentItem = self.totalItems - if self.currentCPS > 0: + current_item = self.current_items + 1 + if current_item > self.total_items: + current_item = self.total_items + if self.current_cps > 0: text = (_("Downloading file %(current)li of %(total)li with " "%(speed)s/s") % \ - {"current": currentItem, - "total": self.totalItems, - "speed": apt_pkg.size_to_str(self.currentCPS)}) + {"current": current_item, + "total": self.total_items, + "speed": apt_pkg.size_to_str(self.current_cps)}) else: text = (_("Downloading file %(current)li of %(total)li") % \ - {"current": currentItem, - "total": self.totalItems}) + {"current": current_item, + "total": self.total_items}) self.emit("status-changed", text, self.percent) while self._context.pending(): self._context.iteration() diff --git a/python/progress.cc b/python/progress.cc index bec40ce9..8214a789 100644 --- a/python/progress.cc +++ b/python/progress.cc @@ -12,7 +12,6 @@ #include #include "progress.h" - // generic bool PyCallbackObj::RunSimpleCallback(const char* method_name, PyObject *arglist, @@ -58,10 +57,16 @@ void PyOpProgress::Update() PyObject_SetAttrString(callbackInst, "op", o); Py_XDECREF(o); o = Py_BuildValue("s", SubOp.c_str()); - PyObject_SetAttrString(callbackInst, "subOp", o); + if(PyObject_HasAttrString(callbackInst, "sub_op")) + PyObject_SetAttrString(callbackInst, "sub_op", o); + else + PyObject_SetAttrString(callbackInst, "subOp", o); Py_XDECREF(o); o = Py_BuildValue("b", MajorChange); - PyObject_SetAttrString(callbackInst, "majorChange", o); + if(PyObject_HasAttrString(callbackInst, "major_change")) + PyObject_SetAttrString(callbackInst, "major_change", o); + else + PyObject_SetAttrString(callbackInst, "majorChange", o); Py_XDECREF(o); // Build up the argument list... @@ -89,7 +94,10 @@ bool PyFetchProgress::MediaChange(string Media, string Drive) //std::cout << "MediaChange" << std::endl; PyObject *arglist = Py_BuildValue("(ss)", Media.c_str(), Drive.c_str()); PyObject *result; - RunSimpleCallback("mediaChange", arglist, &result); + if(PyObject_HasAttrString(callbackInst, "media_change")) + RunSimpleCallback("media_change", arglist, &result); + else + RunSimpleCallback("mediaChange", arglist, &result); bool res = true; if(!PyArg_Parse(result, "b", &res)) @@ -105,7 +113,10 @@ void PyFetchProgress::UpdateStatus(pkgAcquire::ItemDesc &Itm, int status) { //std::cout << "UpdateStatus: " << Itm.URI << " " << status << std::endl; PyObject *arglist = Py_BuildValue("(sssi)", Itm.URI.c_str(), Itm.Description.c_str(), Itm.ShortDesc.c_str(), status); - RunSimpleCallback("updateStatus", arglist); + if(PyObject_HasAttrString(callbackInst, "update_status")) + RunSimpleCallback("update_status", arglist); + else + RunSimpleCallback("updateStatus", arglist); } void PyFetchProgress::IMSHit(pkgAcquire::ItemDesc &Itm) @@ -163,19 +174,34 @@ bool PyFetchProgress::Pulse(pkgAcquire * Owner) // set stats PyObject *o; o = Py_BuildValue("f", CurrentCPS); - PyObject_SetAttrString(callbackInst, "currentCPS", o); + if(PyObject_HasAttrString(callbackInst, "current_cps")) + PyObject_SetAttrString(callbackInst, "current_cps", o); + else + PyObject_SetAttrString(callbackInst, "currentCPS", o); Py_XDECREF(o); o = Py_BuildValue("f", CurrentBytes); - PyObject_SetAttrString(callbackInst, "currentBytes", o); + if(PyObject_HasAttrString(callbackInst, "current_bytes")) + PyObject_SetAttrString(callbackInst, "current_bytes", o); + else + PyObject_SetAttrString(callbackInst, "currentBytes", o); Py_XDECREF(o); o = Py_BuildValue("i", CurrentItems); - PyObject_SetAttrString(callbackInst, "currentItems", o); + if(PyObject_HasAttrString(callbackInst, "current_items")) + PyObject_SetAttrString(callbackInst, "current_items", o); + else + PyObject_SetAttrString(callbackInst, "currentItems", o); Py_XDECREF(o); o = Py_BuildValue("i", TotalItems); - PyObject_SetAttrString(callbackInst, "totalItems", o); + if(PyObject_HasAttrString(callbackInst, "total_items")) + PyObject_SetAttrString(callbackInst, "total_items", o); + else + PyObject_SetAttrString(callbackInst, "totalItems", o); Py_XDECREF(o); o = Py_BuildValue("f", TotalBytes); - PyObject_SetAttrString(callbackInst, "totalBytes", o); + if(PyObject_HasAttrString(callbackInst, "total_bytes")) + PyObject_SetAttrString(callbackInst, "total_bytes", o); + else + PyObject_SetAttrString(callbackInst, "totalBytes", o); Py_XDECREF(o); PyObject *arglist = Py_BuildValue("()"); @@ -201,17 +227,26 @@ bool PyFetchProgress::Pulse(pkgAcquire * Owner) void PyInstallProgress::StartUpdate() { - RunSimpleCallback("startUpdate"); + if(PyObject_HasAttrString(callbackInst, "start_update")) + RunSimpleCallback("start_update"); + else + RunSimpleCallback("startUpdate"); } void PyInstallProgress::UpdateInterface() { - RunSimpleCallback("updateInterface"); + if(PyObject_HasAttrString(callbackInst, "update_interface")) + RunSimpleCallback("update_interface"); + else + RunSimpleCallback("updateInterface"); } void PyInstallProgress::FinishUpdate() { - RunSimpleCallback("finishUpdate"); + if(PyObject_HasAttrString(callbackInst, "finish_update")) + RunSimpleCallback("finish_update"); + else + RunSimpleCallback("finishUpdate"); } pkgPackageManager::OrderResult PyInstallProgress::Run(pkgPackageManager *pm) @@ -272,8 +307,13 @@ pkgPackageManager::OrderResult PyInstallProgress::Run(pkgPackageManager *pm) StartUpdate(); - if(PyObject_HasAttrString(callbackInst, "waitChild")) { - PyObject *method = PyObject_GetAttrString(callbackInst, "waitChild"); + if(PyObject_HasAttrString(callbackInst, "waitChild") || + PyObject_HasAttrString(callbackInst, "wait_child")) { + PyObject *method; + if (PyObject_HasAttrString(callbackInst, "wait_child")) + method = PyObject_GetAttrString(callbackInst, "wait_child"); + else + method = PyObject_GetAttrString(callbackInst, "waitChild"); //std::cerr << "custom waitChild found" << std::endl; PyObject *arglist = Py_BuildValue("(i)",child_id); PyObject *result = PyEval_CallObject(method, arglist); @@ -323,7 +363,10 @@ bool PyCdromProgress::ChangeCdrom() { PyObject *arglist = Py_BuildValue("()"); PyObject *result; - RunSimpleCallback("changeCdrom", arglist, &result); + if(PyObject_HasAttrString(callbackInst, "change_cdrom")) + RunSimpleCallback("change_cdrom", arglist, &result); + else + RunSimpleCallback("changeCdrom", arglist, &result); bool res = true; if(!PyArg_Parse(result, "b", &res)) @@ -337,7 +380,11 @@ bool PyCdromProgress::AskCdromName(string &Name) { PyObject *arglist = Py_BuildValue("()"); PyObject *result; - RunSimpleCallback("askCdromName", arglist, &result); + + if(PyObject_HasAttrString(callbackInst, "ask_cdrom_name")) + RunSimpleCallback("ask_cdrom_name", arglist, &result); + else + RunSimpleCallback("askCdromName", arglist, &result); const char *new_name; bool res; -- cgit v1.2.3 From cef966b55a04ad09f38857aa1a3bff3e49b8f6a4 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 5 Jun 2009 19:29:17 +0200 Subject: apt/cache.py: Introduce Cache.actiongroup() This is a short function which creates an actiongroup on the current depcache. --- apt/cache.py | 21 +++++++++++++++++++++ doc/source/whatsnew/0.8.0.rst | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) (limited to 'apt') diff --git a/apt/cache.py b/apt/cache.py index 8590510c..16dfc011 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -347,6 +347,27 @@ class Cache(object): self._callbacks[name] = [] self._callbacks[name].append(callback) + def actiongroup(self): + """Return an ActionGroup() object for the current cache. + + Action groups can be used to speedup actions. The action group is + active as soon as it is created, and disabled when the object is + deleted or when release() is called. + + You can use the action group as a context manager, this is the + recommended way:: + + with cache.actiongroup(): + for package in my_selected_packages: + package.mark_install() + + This way, the ActionGroup is automatically released as soon as the + with statement block is left. It also has the benefit of making it + clear which parts of the code run with a action group and which + don't. + """ + return apt_pkg.ActionGroup(self._depcache) + if apt_pkg._COMPAT_0_7: _runCallbacks = function_deprecated_by(_run_callbacks) getChanges = function_deprecated_by(get_changes) diff --git a/doc/source/whatsnew/0.8.0.rst b/doc/source/whatsnew/0.8.0.rst index d507e82a..b2236e44 100644 --- a/doc/source/whatsnew/0.8.0.rst +++ b/doc/source/whatsnew/0.8.0.rst @@ -70,7 +70,7 @@ action group, and is just cooler:: This also works for :class:`apt.Cache`:: - with cache.action_group(): # cache is an Instance of apt.Cache + with cache.actiongroup(): # cache is an Instance of apt.Cache for package in my_selected_packages: package.mark_install() # Instance of apt.Package -- cgit v1.2.3 From b7f2997fc11283801260f54e9d84610265279aa0 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 9 Jun 2009 09:25:41 +0200 Subject: apt/package.py: Use destfile instead of dest_file. --- apt/package.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'apt') diff --git a/apt/package.py b/apt/package.py index 0dcc8b74..7c8d72fc 100644 --- a/apt/package.py +++ b/apt/package.py @@ -498,13 +498,13 @@ class Version(object): finally: fobj.close() apt_pkg.AcquireFile(acq, src.index.archive_uri(path), md5, size, - base, dest_file=destfile) + base, destfile=destfile) acq.run() for item in acq.items: if item.status != item.stat_done: raise FetchError("The item %r could not be fetched: %s" % - (item.dest_file, item.error_text)) + (item.destfile, item.error_text)) if unpack: outdir = src.package + '-' + apt_pkg.upstream_version(src.version) -- cgit v1.2.3 From 578de6dc29630db854eccec21ee895ad7c176227 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Sun, 14 Jun 2009 16:13:27 +0200 Subject: apt/package.py: Re-add Package.markedInstall --- apt/package.py | 1 + 1 file changed, 1 insertion(+) (limited to 'apt') diff --git a/apt/package.py b/apt/package.py index 7c8d72fc..a0727429 100644 --- a/apt/package.py +++ b/apt/package.py @@ -1101,6 +1101,7 @@ class Package(object): del candidateOrigin else: markedInstalled = AttributeDeprecatedBy('marked_installed') + markedInstall = AttributeDeprecatedBy('marked_install') markedUpgrade = AttributeDeprecatedBy('marked_upgrade') markedDelete = AttributeDeprecatedBy('marked_delete') markedKeep = AttributeDeprecatedBy('marked_keep') -- cgit v1.2.3 From 986993847b3d833f9ac0926c64f00fa03b895832 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Sun, 14 Jun 2009 16:47:05 +0200 Subject: apt/package.py: Return VersionList objects in Package.versions. VersionList objects provide the same features as sequences (they are even derived from collections.Sequence in Python 2.6 and newer), but also provide a mapping like interface. They are also more efficient than lists because Version objects are only created when they are accessed. --- apt/package.py | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++------ debian/changelog | 4 ++- 2 files changed, 87 insertions(+), 10 deletions(-) (limited to 'apt') diff --git a/apt/package.py b/apt/package.py index a0727429..0a80215e 100644 --- a/apt/package.py +++ b/apt/package.py @@ -29,10 +29,10 @@ import subprocess import urllib2 import warnings try: - from collections import Mapping + from collections import Mapping, Sequence except ImportError: # (for Python < 2.6) pylint: disable-msg=C0103 - Mapping = object + Sequence = Mapping = object import apt_pkg import apt.progress @@ -206,7 +206,10 @@ class Version(object): self._cand = cand def __eq__(self, other): - return self._cand.id == other._cand.id + try: + return self._cand.id == other._cand.id + except: + return apt_pkg.version_compare(self.version, other) == 0 def __gt__(self, other): return apt_pkg.version_compare(self.version, other.version) > 0 @@ -515,6 +518,81 @@ class Version(object): return os.path.abspath(dsc) +class VersionList(Sequence): + """Provide a mapping & sequence interface to all versions of a package. + + This class can be used like a dictionary, where version strings are the + keys. It can also be used as a sequence, where integers are the keys. + + You can also convert this to a dictionary or a list, using the usual way + of dict(version_list) or list(version_list). This is useful if you need + to access the version objects multiple times, because they do not have to + be recreated this way. + + Examples ('package.versions' being a version list): + '0.7.92' in package.versions # Check whether 0.7.92 is a valid version. + package.versions[0] # Return first version or raise IndexError + package.versions[0:2] # Return a new VersionList for objects 0-2 + package.versions['0.7.92'] # Return version 0.7.92 or raise KeyError + package.versions.keys() # All keys, as strings. + max(package.versions) + """ + + def __init__(self, package, slice=None): + self._package = package # apt.package.Package() + self._versions = package._pkg.version_list # [apt_pkg.Version(), ...] + if slice: + self._versions = self._versions[slice] + + def __getitem__(self, item): + if isinstance(item, slice): + return self.__class__(self._package, item) + try: + # Sequence interface, item is an integer + return Version(self._package, self._versions[item]) + except TypeError: + # Dictionary interface item is a string. + for ver in self._versions: + if ver.ver_str == item: + return Version(self._package, ver) + raise KeyError("Version: %r not found." % (item)) + + def __repr__(self): + return '' % self.keys() + + def __iter__(self): + """Return an iterator over all value objects.""" + return (Version(self._package, ver) for ver in self._versions) + + def __contains__(self, item): + if isinstance(item, Version): # Sequence interface + item = item.version + # Dictionary interface. + for ver in self._versions: + if ver.ver_str == item: + return True + return False + + def __eq__(self, other): + return list(self) == list(other) + + def __len__(self): + return len(self._versions) + + # Mapping interface + + def keys(self): + """Return a list of all versions, as strings.""" + return [ver.ver_str for ver in self._versions] + + def get(self, key, default=None): + """Return the key or the default.""" + try: + return self[key] + except LookupError: + return default + + class Package(object): """Representation of a package in a cache. @@ -988,18 +1066,15 @@ class Package(object): @property def versions(self): - """Return a list of versions. + """Return a VersionList() object for all available versions. .. versionadded:: 0.7.9 """ - return [Version(self, ver) for ver in self._pkg.version_list] + return VersionList(self) def get_version(self, version): """Get the Version instance matching the given version string.""" - for ver in self.versions: - if ver.version == version: - return ver - return None + return self.versions[version] # depcache actions diff --git a/debian/changelog b/debian/changelog index 7e79e89c..648b008d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -5,12 +5,14 @@ python-apt (0.7.92) UNRELEASED; urgency=low * Add apt_pkg.Policy class (Closes: #382725) * Allow types providing __new__() to be subclassed. * Bugfix: Delete pointers correctly, fixing memory leaks. (LP: #370149) + * apt/package.py: Return VersionList objects in Package.versions, which + are sequences and also provide features of mappings. (small API BREAK) [ Sebastian Heinlein ] * apt/progress.py: Extract the package name from the status message (Closes: #532660) - -- Julian Andres Klode Fri, 12 Jun 2009 18:42:02 +0200 + -- Julian Andres Klode Sun, 14 Jun 2009 16:23:39 +0200 python-apt (0.7.91) experimental; urgency=low -- cgit v1.2.3 From dc759b837ad5d7790fd54f081c1b95ffe76b926c Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 15 Jun 2009 14:47:15 +0200 Subject: apt/progress/__init__.py: Check for EINTR in select (Closes: #499296) --- apt/progress/__init__.py | 8 +++++++- debian/changelog | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'apt') diff --git a/apt/progress/__init__.py b/apt/progress/__init__.py index a6287dc4..3c5d4588 100644 --- a/apt/progress/__init__.py +++ b/apt/progress/__init__.py @@ -116,6 +116,7 @@ class FetchProgress(object): This happens eg. when the downloads fails or is completed. """ + def update_status_full(self, uri, descr, short_descr, status, file_size, partial_size): """Called when the status of an item changes. @@ -314,7 +315,12 @@ class InstallProgress(DumbInstallProgress): def wait_child(self): """Wait for child progress to exit.""" while True: - select.select([self.statusfd], [], [], self.select_timeout) + try: + select.select([self.statusfd], [], [], self.select_timeout) + except select.error, e: + if e[0] != errno.EINTR: + raise + self.update_interface() (pid, res) = os.waitpid(self.child_pid, os.WNOHANG) if pid == self.child_pid: diff --git a/debian/changelog b/debian/changelog index 6ad40154..55d3a834 100644 --- a/debian/changelog +++ b/debian/changelog @@ -7,6 +7,7 @@ python-apt (0.7.92) UNRELEASED; urgency=low * Bugfix: Delete pointers correctly, fixing memory leaks. (LP: #370149) * apt/package.py: Return VersionList objects in Package.versions, which are sequences and also provide features of mappings. (small API BREAK) + * apt/progress/__init__.py: Check for EINTR in select (Closes: #499296) [ Sebastian Heinlein ] * apt/progress.py: Extract the package name from the status message @@ -22,7 +23,7 @@ python-apt (0.7.92) UNRELEASED; urgency=low * python/progress.cc: - low level code for update_status_full and pulse_items() - -- Julian Andres Klode Sun, 14 Jun 2009 16:23:39 +0200 + -- Julian Andres Klode Mon, 15 Jun 2009 14:45:06 +0200 python-apt (0.7.91) experimental; urgency=low -- cgit v1.2.3 From 56ce90ed8cc9ce939dd7904c9b07478b0c3b2071 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 15 Jun 2009 15:14:30 +0200 Subject: apt/cache.py: Provide broken_count, delete_count, install_count, keep_count properties (Closes: #532338) --- apt/cache.py | 20 ++++++++++++++++++++ debian/changelog | 2 ++ 2 files changed, 22 insertions(+) (limited to 'apt') diff --git a/apt/cache.py b/apt/cache.py index 16dfc011..949de6cc 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -368,6 +368,26 @@ class Cache(object): """ return apt_pkg.ActionGroup(self._depcache) + @property + def broken_count(self): + """Return the number of packages with broken dependencies.""" + return self._depcache.broken_count + + @property + def delete_count(self): + """Return the number of packages marked for deletion.""" + return self._depcache.del_count + + @property + def install_count(self): + """Return the number of packages marked for installation.""" + return self._depcache.inst_count + + @property + def keep_count(self): + """Return the number of packages marked as keep.""" + return self._depcache.keep_count + if apt_pkg._COMPAT_0_7: _runCallbacks = function_deprecated_by(_run_callbacks) getChanges = function_deprecated_by(get_changes) diff --git a/debian/changelog b/debian/changelog index 9809d423..97b49021 100644 --- a/debian/changelog +++ b/debian/changelog @@ -9,6 +9,8 @@ python-apt (0.7.92) UNRELEASED; urgency=low are sequences and also provide features of mappings. (small API BREAK) * apt/progress/__init__.py: Check for EINTR in select (Closes: #499296) * Add support for Enhances as a dependency type (Closes: #416247) + * apt/cache.py: Provide broken_count, delete_count, install_count, keep_count + properties (Closes: #532338) [ Sebastian Heinlein ] * apt/progress.py: Extract the package name from the status message -- cgit v1.2.3 From 894a226f24150cc35f933b72bf14c9587e15b73e Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Sun, 21 Jun 2009 14:48:44 +0200 Subject: apt/package.py: Remove duplicated code in Version.fetch_source() --- apt/package.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'apt') diff --git a/apt/package.py b/apt/package.py index 0a80215e..cb99fe6a 100644 --- a/apt/package.py +++ b/apt/package.py @@ -492,14 +492,9 @@ class Version(object): destfile = os.path.join(destdir, base) if type == 'dsc': dsc = destfile - if os.path.exists(base) and os.path.getsize(base) == size: - fobj = open(base) - try: - if apt_pkg.md5sum(fobj) == md5: - print 'Ignoring already existing file:', destfile - continue - finally: - fobj.close() + if _file_is_same(destfile, size, md5): + print 'Ignoring already existing file:', destfile + continue apt_pkg.AcquireFile(acq, src.index.archive_uri(path), md5, size, base, destfile=destfile) acq.run() -- cgit v1.2.3 From 99f4e7d2ae98c2f5297d681f1ee89b845b577be0 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Sun, 21 Jun 2009 20:41:36 +0200 Subject: apt/cache.py: Only create _weakrefs, _set once per object. --- apt/cache.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'apt') diff --git a/apt/cache.py b/apt/cache.py index 949de6cc..737061ad 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -50,6 +50,8 @@ class Cache(object): def __init__(self, progress=None, rootdir=None, memonly=False): self._callbacks = {} + self._weakref = weakref.WeakValueDictionary() + self._set = set() if memonly: # force apt to build its caches in memory apt_pkg.config.set("Dir::Cache::pkgcache", "") @@ -71,7 +73,7 @@ class Cache(object): for callback in self._callbacks[name]: callback() - def open(self, progress): + def open(self, progress=None): """ Open the package cache, after that it can be used like a dictionary """ @@ -83,8 +85,8 @@ class Cache(object): self._records = apt_pkg.PackageRecords(self._cache) self._list = apt_pkg.SourceList() self._list.read_main_list() - self._set = set() - self._weakref = weakref.WeakValueDictionary() + self._set.clear() + self._weakref.clear() progress.Op = "Building data structures" i=last=0 -- cgit v1.2.3 From 6842933fb0b51aaa6fdc66e17b4645312876d0c9 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Sun, 21 Jun 2009 20:46:24 +0200 Subject: apt/cache.py: Correctly handle rootdir on second and later invocations of open() (LP: #320665). --- apt/cache.py | 4 ++++ debian/changelog | 2 ++ 2 files changed, 6 insertions(+) (limited to 'apt') diff --git a/apt/cache.py b/apt/cache.py index 737061ad..414bd982 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -80,6 +80,10 @@ class Cache(object): if progress is None: progress = apt.progress.OpProgress() self._run_callbacks("cache_pre_open") + + # Make changes to Dir::State::Status work again, by reinitialising + # the system. + apt_pkg.init_system() self._cache = apt_pkg.Cache(progress) self._depcache = apt_pkg.DepCache(self._cache) self._records = apt_pkg.PackageRecords(self._cache) diff --git a/debian/changelog b/debian/changelog index 97b49021..4fb6b0de 100644 --- a/debian/changelog +++ b/debian/changelog @@ -11,6 +11,8 @@ python-apt (0.7.92) UNRELEASED; urgency=low * Add support for Enhances as a dependency type (Closes: #416247) * apt/cache.py: Provide broken_count, delete_count, install_count, keep_count properties (Closes: #532338) + * apt/cache.py: Correctly handle rootdir on second and later invocations of + open() (LP: #320665). [ Sebastian Heinlein ] * apt/progress.py: Extract the package name from the status message -- cgit v1.2.3 From b426f959e7e515d5f267558b6ae51ed9ae03fb9d Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 22 Jun 2009 14:54:31 +0200 Subject: Add apt_pkg.DepCache.mark_auto() and apt.Package.mark_auto() methods to mark a package as automatically installed. --- apt/package.py | 13 +++++++++++++ debian/changelog | 4 +++- python/depcache.cc | 18 ++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) (limited to 'apt') diff --git a/apt/package.py b/apt/package.py index cb99fe6a..39a73c07 100644 --- a/apt/package.py +++ b/apt/package.py @@ -846,6 +846,10 @@ class Package(object): return self.is_installed and \ self._pcache._depcache.is_garbage(self._pkg) + @property + def is_auto_installed(self): + """Return whether the package is marked as automatically installed.""" + return self._pcache._depcache.is_auto_installed(self._pkg) # sizes @DeprecatedProperty @@ -1135,6 +1139,15 @@ class Package(object): sys.stderr.write(("MarkUpgrade() called on a non-upgrable pkg: " "'%s'\n") % self._pkg.name) + def mark_auto(self, auto=True): + """Mark a package as automatically installed. + + Call this function to mark a package as automatically installed. If the + optional parameter *auto* is set to ``False``, the package will not be + marked as automatically installed anymore. The default is ``True``. + """ + self._pcache._depcache.mark_auto(self._pkg, auto) + def commit(self, fprogress, iprogress): """Commit the changes. diff --git a/debian/changelog b/debian/changelog index 4fb6b0de..f0b3efbe 100644 --- a/debian/changelog +++ b/debian/changelog @@ -13,6 +13,8 @@ python-apt (0.7.92) UNRELEASED; urgency=low properties (Closes: #532338) * apt/cache.py: Correctly handle rootdir on second and later invocations of open() (LP: #320665). + * Add apt_pkg.DepCache.mark_auto() and apt.Package.mark_auto() methods to + mark a package as automatically installed. [ Sebastian Heinlein ] * apt/progress.py: Extract the package name from the status message @@ -28,7 +30,7 @@ python-apt (0.7.92) UNRELEASED; urgency=low * python/progress.cc: - low level code for update_status_full and pulse_items() - -- Julian Andres Klode Mon, 15 Jun 2009 14:45:06 +0200 + -- Julian Andres Klode Mon, 22 Jun 2009 14:38:19 +0200 python-apt (0.7.91) experimental; urgency=low diff --git a/python/depcache.cc b/python/depcache.cc index d0b233b8..e1514300 100644 --- a/python/depcache.cc +++ b/python/depcache.cc @@ -367,6 +367,23 @@ static PyObject *PkgDepCacheMarkInstall(PyObject *Self,PyObject *Args) return HandleErrors(Py_None); } +static PyObject *PkgDepCacheMarkAuto(PyObject *Self,PyObject *Args) +{ + pkgDepCache *depcache = GetCpp(Self); + + PyObject *PackageObj; + char value = 0; + if (PyArg_ParseTuple(Args,"O!b",&PackageType,&PackageObj, &value) == 0) + return 0; + + pkgCache::PkgIterator &Pkg = GetCpp(PackageObj); + depcache->MarkAuto(Pkg,value); + + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + + static PyObject *PkgDepCacheIsUpgradable(PyObject *Self,PyObject *Args) { pkgDepCache *depcache = GetCpp(Self); @@ -541,6 +558,7 @@ static PyMethodDef PkgDepCacheMethods[] = {"mark_keep",PkgDepCacheMarkKeep,METH_VARARGS,"Mark package for keep"}, {"mark_delete",PkgDepCacheMarkDelete,METH_VARARGS,"Mark package for delete (optional boolean argument if it should be purged)"}, {"mark_install",PkgDepCacheMarkInstall,METH_VARARGS,"Mark package for Install"}, + {"mark_auto",PkgDepCacheMarkAuto,METH_VARARGS,"mark_auto(pkg: apt_pkg.Package, auto: bool)\n\nMark package as automatically installed."}, {"set_reinstall",PkgDepCacheSetReInstall,METH_VARARGS,"Set if the package should be reinstalled"}, // state information {"is_upgradable",PkgDepCacheIsUpgradable,METH_VARARGS,"Is pkg upgradable"}, -- cgit v1.2.3 From bed3b54244340bd0fad1ea8c713c6e2ca2181467 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 22 Jun 2009 15:27:59 +0200 Subject: apt/package.py: Drop Package.get_version() again. --- apt/package.py | 4 ---- 1 file changed, 4 deletions(-) (limited to 'apt') diff --git a/apt/package.py b/apt/package.py index 39a73c07..0b2377c5 100644 --- a/apt/package.py +++ b/apt/package.py @@ -1071,10 +1071,6 @@ class Package(object): """ return VersionList(self) - def get_version(self, version): - """Get the Version instance matching the given version string.""" - return self.versions[version] - # depcache actions def mark_keep(self): -- cgit v1.2.3 From ed5de18da963f209badf32778ec7fd027f30311f Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 22 Jun 2009 15:28:16 +0200 Subject: apt/package.py: Do not re-define built-in names, fix small issue in Version.__eq__() --- apt/package.py | 46 +++++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 21 deletions(-) (limited to 'apt') diff --git a/apt/package.py b/apt/package.py index 0b2377c5..6d451eca 100644 --- a/apt/package.py +++ b/apt/package.py @@ -108,13 +108,13 @@ class DeprecatedProperty(property): property.__init__(self, fget, fset, fdel, doc) self.__doc__ = (doc or fget.__doc__ or '') - def __get__(self, obj, type=None): + def __get__(self, obj, type_=None): if obj is not None: warnings.warn("Accessed deprecated property %s.%s, please see the " "Version class for alternatives." % - ((obj.__class__.__name__ or type.__name__), + ((obj.__class__.__name__ or type_.__name__), self.fget.__name__), DeprecationWarning, 2) - return property.__get__(self, obj, type) + return property.__get__(self, obj, type_) class Origin(object): @@ -208,8 +208,10 @@ class Version(object): def __eq__(self, other): try: return self._cand.id == other._cand.id - except: + except AttributeError: return apt_pkg.version_compare(self.version, other) == 0 + except Exception: + return False def __gt__(self, other): return apt_pkg.version_compare(self.version, other.version) > 0 @@ -355,14 +357,14 @@ class Version(object): """Return the dependencies of the package version.""" depends_list = [] depends = self._cand.depends_list - for t in ["PreDepends", "Depends"]: + for type_ in ["PreDepends", "Depends"]: try: - for dep_ver_list in depends[t]: + for dep_ver_list in depends[type_]: base_deps = [] for dep_or in dep_ver_list: base_deps.append(BaseDependency(dep_or.target_pkg.name, dep_or.comp_type, dep_or.target_ver, - (t == "PreDepends"))) + (type_ == "PreDepends"))) depends_list.append(Dependency(base_deps)) except KeyError: pass @@ -372,7 +374,7 @@ class Version(object): def origins(self): """Return a list of origins for the package version.""" origins = [] - for (packagefile, index) in self._cand.file_list: + for (packagefile, _) in self._cand.file_list: origins.append(Origin(self.package, packagefile)) return origins @@ -413,7 +415,7 @@ class Version(object): .. versionadded:: 0.7.10 """ - for (packagefile, index) in self._cand.file_list: + for (packagefile, _) in self._cand.file_list: indexfile = self.package._pcache._list.find_index(packagefile) if indexfile: yield indexfile.archive_uri(self._records.filename) @@ -432,7 +434,7 @@ class Version(object): .. versionadded:: 0.7.10 """ - return self._uris().next() + return iter(self._uris()).next() def fetch_binary(self, destdir='', progress=None): """Fetch the binary version of the package. @@ -487,10 +489,10 @@ class Version(object): src.lookup(self.package.name) except AttributeError: raise ValueError("No source for %r" % self) - for md5, size, path, type in src.files: + for md5, size, path, type_ in src.files: base = os.path.basename(path) destfile = os.path.join(destdir, base) - if type == 'dsc': + if type_ == 'dsc': dsc = destfile if _file_is_same(destfile, size, md5): print 'Ignoring already existing file:', destfile @@ -533,11 +535,11 @@ class VersionList(Sequence): max(package.versions) """ - def __init__(self, package, slice=None): + def __init__(self, package, slice_=None): self._package = package # apt.package.Package() self._versions = package._pkg.version_list # [apt_pkg.Version(), ...] - if slice: - self._versions = self._versions[slice] + if slice_: + self._versions = self._versions[slice_] def __getitem__(self, item): if isinstance(item, slice): @@ -973,9 +975,10 @@ class Package(object): except SystemError: src_ver = bin_ver - l = section.split("/") - if len(l) > 1: - src_section = l[0] + section_split = section.split("/", 1) + if len(section_split) > 1: + src_section = section_split[0] + del section_split # lib is handled special prefix = src_pkg[0] @@ -983,9 +986,10 @@ class Package(object): prefix = "lib" + src_pkg[3] # stip epoch - l = src_ver.split(":") - if len(l) > 1: - src_ver = "".join(l[1:]) + src_ver_split = src_ver.split(":", 1) + if len(src_ver_split) > 1: + src_ver = "".join(src_ver_split[1:]) + del src_ver_split uri = uri % {"src_section": src_section, "prefix": prefix, -- cgit v1.2.3 From 7d12f1ce6bc839f27604782bc712a0ccb481f2b2 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Wed, 8 Jul 2009 20:59:15 +0200 Subject: doc/source/apt_pkg.rst: Update the documentation to reflect the latest changes. --- apt/package.py | 2 +- doc/source/apt_pkg.rst | 44 ++++++++++++++++++++++++++++++++++---------- 2 files changed, 35 insertions(+), 11 deletions(-) (limited to 'apt') diff --git a/apt/package.py b/apt/package.py index 6d451eca..072e86ca 100644 --- a/apt/package.py +++ b/apt/package.py @@ -64,7 +64,7 @@ class BaseDependency(object): Attributes defined here: name - The name of the dependency - relation - The relation (>>,>=,==,<<,<=,) + relation - The relation (>,>=,==,<,<=,) version - The version depended on pre_depend - Boolean value whether this is a pre-dependency. """ diff --git a/doc/source/apt_pkg.rst b/doc/source/apt_pkg.rst index c814615c..2af934a0 100644 --- a/doc/source/apt_pkg.rst +++ b/doc/source/apt_pkg.rst @@ -947,22 +947,30 @@ Records .. attribute:: build_depends + Return a dictionary representing the build-time dependencies of the + package. The format is the same as for :attr:`Version.depends_list_str` + and possible keys being ``"Build-Depends"``, ``"Build-Depends-Indep"``, + ``"Build-Conflicts"`` or ``"Build-Conflicts-Indep"``. + + .. attribute:: BuildDepends + Return the list of Build dependencies, as - ``(str: package, str: version, int: op, int: type)``. + ``(str: package, str: version, int: op, int: type)``. This is a + completely deprecated format .. table:: Values of *op* ===== ============================================= Value Meaning ===== ============================================= - 0x0 No Operation (no versioned build dependency) + 0x00 No Operation (no versioned build dependency) 0x10 | (or) - this will be added to the other values - 0x1 <= (less than or equal) - 0x2 >= (greater than or equal) - 0x3 << (less than) - 0x4 >> (greater than) - 0x5 == (equal) - 0x6 != (not equal) + 0x01 <= (less than or equal) + 0x02 >= (greater than or equal) + 0x03 << (less than) + 0x04 >> (greater than) + 0x05 = (equal) + 0x06 != (not equal) ===== ============================================= .. table:: Values of *type* @@ -983,7 +991,7 @@ Records This results in:: - [('A', '1', 18, 0), # 18 = 16 + 2 = 0x10 + 0x2 + [('A', '1', 18, 0), # 18 = (16 | 2) = (0x10 | 0x2) ('B', '1', 2, 0), ('C', '', 0, 0)] @@ -1293,10 +1301,19 @@ Dependencies >>> apt_pkg.parse_depends("PkgA (>= VerA) | PkgB (>= VerB)") [[('PkgA', 'VerA', '>='), ('PkgB', 'VerB', '>=')]] + + .. note:: + + The behavior of this function is different than the behavior of the + old function :func:`ParseDepends()`, because the third field + ``operation`` uses `>` instead of `>>` and `<` instead of `<<` which + is specified in control files. + + .. function:: parse_src_depends(depends) Parse the string *depends* which contains dependency information as - specified in Debian Policy, Section 7.1. + 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 @@ -1312,6 +1329,13 @@ Dependencies >>> apt_pkg.parse_src_depends("a (>= 01) [i386 amd64]") [[('a', '01', '>=')]] + .. note:: + + The behavior of this function is different than the behavior of the + old function :func:`ParseDepends()`, because the third field + ``operation`` uses `>` instead of `>>` and `<` instead of `<<` which + is specified in control files. + Configuration ------------- -- cgit v1.2.3 From 5505821c0d13ff66e5943b610705f1c9b202d7fa Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Sun, 12 Jul 2009 19:11:53 +0200 Subject: apt/package.py: Adjust AcquireFile() usage to future changes. The underlying C++ objects of the AcquireFile() objects are currently immortal. This should change at a later stage, to match the behavior of the C++ class. But AcquireItems needs to be fixed first to not segfault anymore. --- apt/package.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'apt') diff --git a/apt/package.py b/apt/package.py index 072e86ca..0ce2da3a 100644 --- a/apt/package.py +++ b/apt/package.py @@ -454,13 +454,13 @@ class Version(object): print 'Ignoring already existing file:', destfile return acq = apt_pkg.Acquire(progress or apt.progress.TextFetchProgress()) - apt_pkg.AcquireFile(acq, self.uri, self._records.md5_hash, self.size, - base, destfile=destfile) + acqfile = apt_pkg.AcquireFile(acq, self.uri, self._records.md5_hash, + self.size, base, destfile=destfile) acq.run() - for item in acq.items: - if item.status != item.stat_done: - raise FetchError("The item %r could not be fetched: %s" % - (item.destfile, item.error_text)) + + if acqfile.status != acqfile.stat_done: + raise FetchError("The item %r could not be fetched: %s" % + (acqfile.destfile, acqfile.error_text)) return os.path.abspath(destfile) def fetch_source(self, destdir="", progress=None, unpack=True): @@ -489,6 +489,7 @@ class Version(object): src.lookup(self.package.name) except AttributeError: raise ValueError("No source for %r" % self) + files = list() for md5, size, path, type_ in src.files: base = os.path.basename(path) destfile = os.path.join(destdir, base) @@ -497,8 +498,8 @@ class Version(object): if _file_is_same(destfile, size, md5): print 'Ignoring already existing file:', destfile continue - apt_pkg.AcquireFile(acq, src.index.archive_uri(path), md5, size, - base, destfile=destfile) + files.append(apt_pkg.AcquireFile(acq, src.index.archive_uri(path), + md5, size, base, destfile=destfile)) acq.run() for item in acq.items: -- cgit v1.2.3 From 22b5c5d28c31eed85d7fad3a7638e1067200029a Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Thu, 16 Jul 2009 15:25:30 +0200 Subject: apt/progress/text.py: Introduce new progress classes for text. These are based on the new classes in apt_pkg and work better, because they correctly clear the screen. --- apt/progress/text.py | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 apt/progress/text.py (limited to 'apt') diff --git a/apt/progress/text.py b/apt/progress/text.py new file mode 100644 index 00000000..6024f124 --- /dev/null +++ b/apt/progress/text.py @@ -0,0 +1,122 @@ +# Copyright (c) 2009 Julian Andres Klode +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA +"""Progress reporting for text interfaces.""" +import sys + +import apt_pkg + +__all__ = ['AcquireProgress', 'OpProgress'] + + +class TextProgress(object): + """Internal Base class for text progress classes.""" + + def __init__(self, outfile=None): + self._file = outfile or sys.stdout + self._width = 0 + + def _write(self, msg, newline=True): + """Write the message on the terminal, fill remaining space.""" + self._file.write("\r") + self._file.write(msg) + # Fill remaining stuff with whitespace + if self._width > len(msg): + self._file.write((self._width - len(msg)) * ' ') + else: + self._width = max(self._width, len(msg)) + if newline: + self._file.write("\n") + else: + self._file.write("\r") + self._file.flush() + + +class OpProgress(apt_pkg.OpProgress, TextProgress): + """Operation progress reporting. + + This closely resembles OpTextProgress in libapt-pkg. + """ + + def __init__(self, outfile=None): + TextProgress.__init__(self, outfile) + apt_pkg.OpProgress.__init__(self) + self.old_op = "" + + def update(self, percent=None): + """Called periodically to update the user interface.""" + if percent: + self.percent = percent + apt_pkg.OpProgress.update(self) + if self.major_change and self.old_op: + self._write(self.old_op) + self._write("%s... %i%%" % (self.op, self.percent), False) + self.old_op = self.op + + def done(self): + """Called once an operation has been completed.""" + apt_pkg.OpProgress.done(self) + if self.old_op: + self._write("%s... Done" % self.old_op) + self.old_op = "" + + +class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): + """AcquireProgress for the text interface.""" + + def ims_hit(self, item): + """Called when an item is update (e.g. not modified on the server).""" + self._write("Hit %s" % item.description) + + def done(self, item): + """Called when an item is completely fetched.""" + self._write("Done %s" % item.description) + + def fail(self, item): + """Called when an item is failed.""" + self._write("Fail %s" % item.description) + + def fetch(self, item): + """Called when some of the item's data is fetched.""" + self._write("Fetch %s" % item.description) + + def pulse(self, owner): + """Periodically invoked while the Acquire process is underway. + + Return False if the user asked to cancel the whole Acquire process.""" + + percent = (((self.current_bytes + self.current_items) * 100.0) / + float(self.total_bytes + self.total_items)) + if self.current_cps > 0: + eta = ((self.total_bytes - self.current_bytes) / + float(self.current_cps)) + self._write("[%2.f%%] %sB/s %s" % (percent, + apt_pkg.size_to_str(int(self.current_cps)), + apt_pkg.time_to_str(int(eta))), False) + else: + self._write("%2.f%% [Working]" % (percent), False) + return True + + def media_change(self, medium, drive): + """Prompt the user to change the inserted removable media.""" + print ("Media change: please insert the disc labeled " + "'%s' in the drive '%s' and press enter") % (medium, drive) + + return raw_input() not in ('c', 'C') + + def stop(self): + """Invoked when the Acquire process stops running.""" + self._write("Done downloading") -- cgit v1.2.3 From 5e3b11ad62c893fc3f46e748afdd4db5ce2d3672 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Thu, 16 Jul 2009 15:31:38 +0200 Subject: apt/cache.py: Support apt_pkg.OpProgress() and use apt.progress.text.OpProgress() --- apt/cache.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'apt') diff --git a/apt/cache.py b/apt/cache.py index 414bd982..a93d5575 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -26,7 +26,7 @@ import apt_pkg from apt import Package from apt.deprecation import (AttributeDeprecatedBy, function_deprecated_by, deprecated_args) -import apt.progress +import apt.progress.text class FetchCancelledException(IOError): @@ -78,7 +78,7 @@ class Cache(object): a dictionary """ if progress is None: - progress = apt.progress.OpProgress() + progress = apt.progress.text.OpProgress() self._run_callbacks("cache_pre_open") # Make changes to Dir::State::Status work again, by reinitialising @@ -92,12 +92,16 @@ class Cache(object): self._set.clear() self._weakref.clear() - progress.Op = "Building data structures" + progress.op = "Building data structures" i=last=0 size=len(self._cache.packages) for pkg in self._cache.packages: if progress is not None and last+100 < i: - progress.update(i/float(size)*100) + if isinstance(progress, apt_pkg.OpProgress): + progress.percent = i/float(size)*100 + progress.update() + else: + progress.update(i/float(size)*100) last=i # drop stuff with no versions (cruft) if len(pkg.version_list) > 0: -- cgit v1.2.3 From c8f2e068538dd54206669394507a52115ce9a621 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Thu, 16 Jul 2009 19:43:38 +0200 Subject: apt/progress/text.py: 'Sync' AcquireProgress with the one used for apt-get. --- apt/progress/text.py | 111 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 93 insertions(+), 18 deletions(-) (limited to 'apt') diff --git a/apt/progress/text.py b/apt/progress/text.py index 6024f124..eb196b55 100644 --- a/apt/progress/text.py +++ b/apt/progress/text.py @@ -36,12 +36,12 @@ class TextProgress(object): # Fill remaining stuff with whitespace if self._width > len(msg): self._file.write((self._width - len(msg)) * ' ') - else: - self._width = max(self._width, len(msg)) + #else: + # self._width = max(self._width, len(msg)) if newline: self._file.write("\n") else: - self._file.write("\r") + #self._file.write("\r") self._file.flush() @@ -63,7 +63,7 @@ class OpProgress(apt_pkg.OpProgress, TextProgress): apt_pkg.OpProgress.update(self) if self.major_change and self.old_op: self._write(self.old_op) - self._write("%s... %i%%" % (self.op, self.percent), False) + self._write("%s... %i%%\r" % (self.op, self.percent), False) self.old_op = self.op def done(self): @@ -77,21 +77,47 @@ class OpProgress(apt_pkg.OpProgress, TextProgress): class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): """AcquireProgress for the text interface.""" + def __init__(self, outfile=None): + TextProgress.__init__(self, outfile) + apt_pkg.AcquireProgress.__init__(self) + import signal + self._signal = signal.signal(signal.SIGWINCH, self._winch) + self._winch() + self._id = 1L + + def _winch(self, *a): + import fcntl + import termios + import struct + buf = fcntl.ioctl(self._file.fileno(),termios.TIOCGWINSZ, 8 * ' ') + row, col, rpx, cpx = struct.unpack('hhhh', buf) + self._width = col - 1 # 1 for the cursor + def ims_hit(self, item): """Called when an item is update (e.g. not modified on the server).""" - self._write("Hit %s" % item.description) - - def done(self, item): - """Called when an item is completely fetched.""" - self._write("Done %s" % item.description) + line = 'Hit %s' % item.description + if (item.owner.filesize != 0): + line+= ' [%sB]' % apt_pkg.size_to_str(item.owner.filesize) + self._write(line) def fail(self, item): """Called when an item is failed.""" self._write("Fail %s" % item.description) + if item.owner.status == item.owner.stat_done: + self._write("Ign %s" % item.description) + else: + self._write("Err %s" % item.description) + self._write(" %s" % item.owner.error_text) def fetch(self, item): """Called when some of the item's data is fetched.""" - self._write("Fetch %s" % item.description) + item.owner.id = self._id + self._id += 1 + line = "Get:%s %s" % (item.owner.id, item.description) + if item.owner.filesize != 0: + line += (" [%sB]" % apt_pkg.size_to_str(item.owner.filesize)) + + self._write(line) def pulse(self, owner): """Periodically invoked while the Acquire process is underway. @@ -100,14 +126,59 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): percent = (((self.current_bytes + self.current_items) * 100.0) / float(self.total_bytes + self.total_items)) - if self.current_cps > 0: - eta = ((self.total_bytes - self.current_bytes) / - float(self.current_cps)) - self._write("[%2.f%%] %sB/s %s" % (percent, - apt_pkg.size_to_str(int(self.current_cps)), - apt_pkg.time_to_str(int(eta))), False) + + shown = False + mode = 'long' + tval = '%i%%' % percent + + end = "" + if self.current_cps: + eta = int(float(self.total_bytes - self.current_bytes) / self.current_cps) + end = " %sB/s %s" % (apt_pkg.size_to_str(self.current_cps), + apt_pkg.time_to_str(eta)) + + for worker in owner.workers: + val = '' + if not worker.current_item: + if worker.status: + val += ' [%s]' % worker.status + shown = True + continue + shown = True + + if worker.current_item.owner.id != 0: + val += " [%i %s" % (worker.current_item.owner.id, worker.current_item.shortdesc) + else: + val += ' [%s' % worker.current_item.description + if worker.current_item.owner.mode: + val += ' %s' % worker.current_item.owner.mode + if mode == 'long' and False: + val += ' %i' % worker.current_size + elif mode == 'medium' or worker.total_size == 0 or True: + val += ' %sB' % apt_pkg.size_to_str(worker.current_size) + + # Add the total size and percent + if worker.total_size > 0 and worker.current_item.owner.complete == False: + if mode == 'short': + val += ' %i%%' % worker.current_size*100.0/worker.total_size + else: + val += "/%sB %i%%" % ( apt_pkg.size_to_str(worker.total_size), + worker.current_size*100.0/worker.total_size ) + + val += ']' + + tval += val + + if not shown: + tval += ' [Working]' + + if self.current_cps: + tval += (self._width - len(end) - len(tval)) * ' ' + end + + if len(tval) <= self._width: + self._write(tval, False) else: - self._write("%2.f%% [Working]" % (percent), False) + self._write(tval) return True def media_change(self, medium, drive): @@ -119,4 +190,8 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): def stop(self): """Invoked when the Acquire process stops running.""" - self._write("Done downloading") + if self.fetched_bytes != 0: + self._write("Fetched %sB in %s (%sB/s)" % ( + apt_pkg.size_to_str(self.fetched_bytes), + apt_pkg.time_to_str(self.elapsed_time), + apt_pkg.size_to_str(self.current_cps))) -- cgit v1.2.3 From 51f0b08149c39dc76664e1758aa0d71701920bd7 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Thu, 16 Jul 2009 19:50:18 +0200 Subject: apt/progress: Move apt.progress to apt.progress.old --- apt/__init__.py | 5 +- apt/cdrom.py | 2 +- apt/package.py | 27 +-- apt/progress/__init__.py | 439 +++-------------------------------------------- apt/progress/old.py | 426 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 464 insertions(+), 435 deletions(-) create mode 100644 apt/progress/old.py (limited to 'apt') diff --git a/apt/__init__.py b/apt/__init__.py index 41c0a30f..ec7103a1 100644 --- a/apt/__init__.py +++ b/apt/__init__.py @@ -26,9 +26,8 @@ from apt.cache import Cache from apt.cdrom import Cdrom if apt_pkg._COMPAT_0_7: - from apt.progress import (OpProgress, FetchProgress, InstallProgress, - CdromProgress) - + from apt.progress.old import (OpProgress, FetchProgress, InstallProgress, + CdromProgress) if apt_pkg._COMPAT_0_7: from apt_pkg import (size_to_str as SizeToStr, diff --git a/apt/cdrom.py b/apt/cdrom.py index a98b5d99..a3811ccb 100644 --- a/apt/cdrom.py +++ b/apt/cdrom.py @@ -23,7 +23,7 @@ import glob import apt_pkg -from apt.progress import CdromProgress +from apt.progress.old import CdromProgress from apt.deprecation import AttributeDeprecatedBy diff --git a/apt/package.py b/apt/package.py index 0ce2da3a..491571c2 100644 --- a/apt/package.py +++ b/apt/package.py @@ -35,7 +35,7 @@ except ImportError: Sequence = Mapping = object import apt_pkg -import apt.progress +import apt.progress.text from apt.deprecation import (function_deprecated_by, AttributeDeprecatedBy, deprecated_args) @@ -442,9 +442,9 @@ class Version(object): The parameter *destdir* specifies the directory where the package will be fetched to. - The parameter *progress* may refer to an apt.progress.FetchProgress() - object. If not specified or None, apt.progress.TextFetchProgress() is - used. + The parameter *progress* may refer to an apt_pkg.AcquireProgress() + object. If not specified or None, apt.progress.text.AcquireProgress() + is used. .. versionadded:: 0.7.10 """ @@ -453,7 +453,7 @@ class Version(object): if _file_is_same(destfile, self.size, self._records.md5_hash): print 'Ignoring already existing file:', destfile return - acq = apt_pkg.Acquire(progress or apt.progress.TextFetchProgress()) + acq = apt_pkg.Acquire(progress or apt.progress.text.AcquireProgress()) acqfile = apt_pkg.AcquireFile(acq, self.uri, self._records.md5_hash, self.size, base, destfile=destfile) acq.run() @@ -461,6 +461,7 @@ class Version(object): if acqfile.status != acqfile.stat_done: raise FetchError("The item %r could not be fetched: %s" % (acqfile.destfile, acqfile.error_text)) + print self._records.filename return os.path.abspath(destfile) def fetch_source(self, destdir="", progress=None, unpack=True): @@ -469,9 +470,9 @@ class Version(object): The parameter *destdir* specifies the directory where the source will be fetched to. - The parameter *progress* may refer to an apt.progress.FetchProgress() - object. If not specified or None, apt.progress.TextFetchProgress() is - used. + The parameter *progress* may refer to an apt_pkg.AcquireProgress() + object. If not specified or None, apt.progress.text.AcquireProgress() + is used. The parameter *unpack* describes whether the source should be unpacked (``True``) or not (``False``). By default, it is unpacked. @@ -480,7 +481,7 @@ class Version(object): returned. Otherwise, the path to the .dsc file is returned. """ src = apt_pkg.SourceRecords() - acq = apt_pkg.Acquire(progress or apt.progress.TextFetchProgress()) + acq = apt_pkg.Acquire(progress or apt.progress.text.AcquireProgress()) dsc = None src.lookup(self.package.name) @@ -1152,11 +1153,11 @@ class Package(object): def commit(self, fprogress, iprogress): """Commit the changes. - The parameter *fprogress* refers to a FetchProgress() object, as - found in apt.progress. + The parameter *fprogress* refers to a apt_pkg.AcquireProgress() object, + like apt.progress.text.AcquireProgress(). The parameter *iprogress* refers to an InstallProgress() object, as - found in apt.progress. + found in apt.progress.old. """ self._pcache._depcache.commit(fprogress, iprogress) @@ -1207,7 +1208,7 @@ def _test(): print "Self-test for the Package modul" import random apt_pkg.init() - progress = apt.progress.OpTextProgress() + progress = apt.progress.text.OpProgress() cache = apt.Cache(progress) pkg = cache["apt-utils"] print "Name: %s " % pkg.name diff --git a/apt/progress/__init__.py b/apt/progress/__init__.py index 3c5d4588..67880903 100644 --- a/apt/progress/__init__.py +++ b/apt/progress/__init__.py @@ -1,426 +1,29 @@ -# progress.py - progress reporting classes +# Copyright (c) 2009 Julian Andres Klode # -# Copyright (c) 2005-2009 Canonical +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. # -# Author: Michael Vogt +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. # -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -# USA -"""progress reporting classes. - -This module provides classes for progress reporting. They can be used with -e.g., for reporting progress on the cache opening process, the cache update -progress, or the package install progress. -""" - -import errno -import fcntl -import os -import re -import select -import sys - +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA +"""Progress reporting.""" import apt_pkg -from apt.deprecation import AttributeDeprecatedBy, function_deprecated_by - - -__all__ = ('CdromProgress', 'DpkgInstallProgress', 'DumbInstallProgress', - 'FetchProgress', 'InstallProgress', 'OpProgress', 'OpTextProgress', - 'TextFetchProgress') - - -class OpProgress(object): - """Abstract class to implement reporting on cache opening. - - Subclass this class to implement simple Operation progress reporting. - """ - - def __init__(self): - self.op = None - self.sub_op = None - - def update(self, percent): - """Called periodically to update the user interface.""" - - def done(self): - """Called once an operation has been completed.""" - - if apt_pkg._COMPAT_0_7: - subOp = AttributeDeprecatedBy('sub_op') - - -class OpTextProgress(OpProgress): - """A simple text based cache open reporting class.""" - - def __init__(self): - OpProgress.__init__(self) - - def update(self, percent): - """Called periodically to update the user interface.""" - sys.stdout.write("\r%s: %.2i " % (self.sub_op, percent)) - sys.stdout.flush() - - def done(self): - """Called once an operation has been completed.""" - sys.stdout.write("\r%s: Done\n" % self.op) - - -class FetchProgress(object): - """Report the download/fetching progress. - - Subclass this class to implement fetch progress reporting - """ - - # download status constants - dl_done = 0 - dl_queued = 1 - dl_failed = 2 - dl_hit = 3 - dl_ignored = 4 - dl_status_str = {dl_done: "Done", - dl_queued: "Queued", - dl_failed: "Failed", - dl_hit: "Hit", - dl_ignored: "Ignored"} - - def __init__(self): - self.eta = 0.0 - self.percent = 0.0 - # Make checking easier - self.current_bytes = 0 - self.current_items = 0 - self.total_bytes = 0 - self.total_items = 0 - self.current_cps = 0 - - def start(self): - """Called when the fetching starts.""" - - def stop(self): - """Called when all files have been fetched.""" - - def update_status(self, uri, descr, short_descr, status): - """Called when the status of an item changes. - - This happens eg. when the downloads fails or is completed. - """ - - def update_status_full(self, uri, descr, short_descr, status, file_size, - partial_size): - """Called when the status of an item changes. - - This happens eg. when the downloads fails or is completed. This - version include information on current filesize and partial size - """ - - def pulse(self): - """Called periodically to update the user interface. - - Return True to continue or False to cancel. - """ - self.percent = (((self.current_bytes + self.current_items) * 100.0) / - float(self.total_bytes + self.total_items)) - if self.current_cps > 0: - self.eta = ((self.total_bytes - self.current_bytes) / - float(self.current_cps)) - return True - - def pulse_items(self, items): - """Called periodically to update the user interface. - This function includes details about the items being fetched - Return True to continue or False to cancel. - - """ - self.percent = (((self.current_bytes + self.current_items) * 100.0) / - float(self.total_bytes + self.total_items)) - if self.current_cps > 0: - self.eta = ((self.total_bytes - self.current_bytes) / - float(self.current_cps)) - return True - - def media_change(self, medium, drive): - """react to media change events.""" - - if apt_pkg._COMPAT_0_7: - dlDone = AttributeDeprecatedBy('dl_done') - dlQueued = AttributeDeprecatedBy('dl_queued') - dlFailed = AttributeDeprecatedBy('dl_failed') - dlHit = AttributeDeprecatedBy('dl_hit') - dlIgnored = AttributeDeprecatedBy('dl_ignored') - dlStatusStr = AttributeDeprecatedBy('dl_status_str') - currentBytes = AttributeDeprecatedBy('current_bytes') - currentItems = AttributeDeprecatedBy('current_items') - totalBytes = AttributeDeprecatedBy('total_bytes') - totalItems = AttributeDeprecatedBy('total_items') - currentCPS = AttributeDeprecatedBy('current_cps') - updateStatus = function_deprecated_by(update_status) - mediaChange = function_deprecated_by(media_change) - - -class TextFetchProgress(FetchProgress): - """ Ready to use progress object for terminal windows """ - - def __init__(self): - FetchProgress.__init__(self) - self.items = {} - - def update_status(self, uri, descr, short_descr, status): - """Called when the status of an item changes. - - This happens eg. when the downloads fails or is completed. - """ - if status != self.dl_queued: - print "\r%s %s" % (self.dl_status_str[status], descr) - self.items[uri] = status - - def pulse(self): - """Called periodically to update the user interface. - - Return True to continue or False to cancel. - """ - FetchProgress.pulse(self) - if self.current_cps > 0: - s = "[%2.f%%] %sB/s %s" % (self.percent, - apt_pkg.size_to_str(int(self.current_cps)), - apt_pkg.time_to_str(int(self.eta))) - else: - s = "%2.f%% [Working]" % (self.percent) - print "\r%s" % (s), - sys.stdout.flush() - return True - - def stop(self): - """Called when all files have been fetched.""" - print "\rDone downloading " - - def media_change(self, medium, drive): - """react to media change events.""" - print ("Media change: please insert the disc labeled " - "'%s' in the drive '%s' and press enter") % (medium, drive) - - return raw_input() not in ('c', 'C') - - if apt_pkg._COMPAT_0_7: - updateStatus = function_deprecated_by(update_status) - mediaChange = function_deprecated_by(media_change) - - -class DumbInstallProgress(object): - """Report the install progress. - - Subclass this class to implement install progress reporting. - """ - - def start_update(self): - """Start update.""" - - def run(self, pm): - """Start installation.""" - return pm.do_install() - - def finish_update(self): - """Called when update has finished.""" - - def update_interface(self): - """Called periodically to update the user interface""" - - if apt_pkg._COMPAT_0_7: - startUpdate = function_deprecated_by(start_update) - finishUpdate = function_deprecated_by(finish_update) - updateInterface = function_deprecated_by(update_interface) - - -class InstallProgress(DumbInstallProgress): - """An InstallProgress that is pretty useful. - - It supports the attributes 'percent' 'status' and callbacks for the dpkg - errors and conffiles and status changes. - """ - - def __init__(self): - DumbInstallProgress.__init__(self) - self.select_timeout = 0.1 - (read, write) = os.pipe() - self.writefd = write - self.statusfd = os.fdopen(read, "r") - fcntl.fcntl(self.statusfd.fileno(), fcntl.F_SETFL, os.O_NONBLOCK) - self.read = "" - self.percent = 0.0 - self.status = "" - - def error(self, pkg, errormsg): - """Called when a error is detected during the install.""" - - def conffile(self, current, new): - """Called when a conffile question from dpkg is detected.""" - - def status_change(self, pkg, percent, status): - """Called when the status changed.""" - - def update_interface(self): - """Called periodically to update the interface.""" - if self.statusfd is None: - return - try: - while not self.read.endswith("\n"): - self.read += os.read(self.statusfd.fileno(), 1) - except OSError, (errno_, errstr): - # resource temporarly unavailable is ignored - if errno_ != errno.EAGAIN and errno_ != errno.EWOULDBLOCK: - print errstr - if not self.read.endswith("\n"): - return - - s = self.read - #print s - try: - (status, pkg, percent, status_str) = s.split(":", 3) - except ValueError: - # silently ignore lines that can't be parsed - self.read = "" - return - #print "percent: %s %s" % (pkg, float(percent)/100.0) - if status == "pmerror": - self.error(pkg, status_str) - elif status == "pmconffile": - # we get a string like this: - # 'current-conffile' 'new-conffile' useredited distedited - match = re.match("\s*\'(.*)\'\s*\'(.*)\'.*", status_str) - if match: - self.conffile(match.group(1), match.group(2)) - elif status == "pmstatus": - if float(percent) != self.percent or status_str != self.status: - self.status_change(pkg, float(percent), - status_str.strip()) - self.percent = float(percent) - self.status = status_str.strip() - self.read = "" - - def fork(self): - """Fork.""" - return os.fork() - - def wait_child(self): - """Wait for child progress to exit.""" - while True: - try: - select.select([self.statusfd], [], [], self.select_timeout) - except select.error, e: - if e[0] != errno.EINTR: - raise - - self.update_interface() - (pid, res) = os.waitpid(self.child_pid, os.WNOHANG) - if pid == self.child_pid: - break - return res - - def run(self, pm): - """Start installing.""" - pid = self.fork() - if pid == 0: - # child - res = pm.do_install(self.writefd) - os._exit(res) - self.child_pid = pid - res = self.wait_child() - return os.WEXITSTATUS(res) - - if apt_pkg._COMPAT_0_7: - selectTimeout = AttributeDeprecatedBy('select_timeout') - statusChange = function_deprecated_by(status_change) - waitChild = function_deprecated_by(wait_child) - updateInterface = function_deprecated_by(update_interface) - - -class CdromProgress(object): - """Report the cdrom add progress. - - Subclass this class to implement cdrom add progress reporting. - """ - - def __init__(self): - pass - - def update(self, text, step): - """Called periodically to update the user interface.""" - - def ask_cdrom_name(self): - """Called to ask for the name of the cdrom.""" - - def change_cdrom(self): - """Called to ask for the cdrom to be changed.""" - - if apt_pkg._COMPAT_0_7: - askCdromName = function_deprecated_by(ask_cdrom_name) - changeCdrom = function_deprecated_by(change_cdrom) - - -class DpkgInstallProgress(InstallProgress): - """Progress handler for a local Debian package installation.""" - - def run(self, debfile): - """Start installing the given Debian package.""" - if apt_pkg._COMPAT_0_7: # Deprecated stuff - self.debfile = debfile - self.debname = os.path.basename(debfile).split("_")[0] - pid = self.fork() - if pid == 0: - # child - res = os.system("/usr/bin/dpkg --status-fd %s -i %s" % \ - (self.writefd, debfile)) - os._exit(os.WEXITSTATUS(res)) - self.child_pid = pid - res = self.wait_child() - return res +#from apt.progress.text import AcquireProgress as TextAcquireProgress +#from apt.progress.text import OpProgress as TextOpProgress - def update_interface(self): - """Process status messages from dpkg.""" - if self.statusfd is None: - return - while True: - try: - self.read += os.read(self.statusfd.fileno(), 1) - except OSError, (errno_, errstr): - # resource temporarly unavailable is ignored - if errno_ != 11: - print errstr - break - if not self.read.endswith("\n"): - continue +__all__ = [] #'TextAcquireProgress', 'TextOpProgress'] - statusl = self.read.split(":") - if len(statusl) < 3: - print "got garbage from dpkg: '%s'" % self.read - self.read = "" - break - pkg_name = statusl[1].strip() - status = statusl[2].strip() - #print status - if status == "error": - self.error(pkg_name, status) - elif status == "conffile-prompt": - # we get a string like this: - # 'current-conffile' 'new-conffile' useredited distedited - match = re.match("\s*\'(.*)\'\s*\'(.*)\'.*", statusl[3]) - if match: - self.conffile(match.group(1), match.group(2)) - else: - self.status = status - self.read = "" +if apt_pkg._COMPAT_0_7: + import apt.progress.old + from apt.progress.old import * - if apt_pkg._COMPAT_0_7: - updateInterface = function_deprecated_by(update_interface) + __all__ += apt.progress.old.__all__ diff --git a/apt/progress/old.py b/apt/progress/old.py new file mode 100644 index 00000000..3c5d4588 --- /dev/null +++ b/apt/progress/old.py @@ -0,0 +1,426 @@ +# progress.py - progress reporting classes +# +# Copyright (c) 2005-2009 Canonical +# +# Author: Michael Vogt +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA +"""progress reporting classes. + +This module provides classes for progress reporting. They can be used with +e.g., for reporting progress on the cache opening process, the cache update +progress, or the package install progress. +""" + +import errno +import fcntl +import os +import re +import select +import sys + +import apt_pkg +from apt.deprecation import AttributeDeprecatedBy, function_deprecated_by + + +__all__ = ('CdromProgress', 'DpkgInstallProgress', 'DumbInstallProgress', + 'FetchProgress', 'InstallProgress', 'OpProgress', 'OpTextProgress', + 'TextFetchProgress') + + +class OpProgress(object): + """Abstract class to implement reporting on cache opening. + + Subclass this class to implement simple Operation progress reporting. + """ + + def __init__(self): + self.op = None + self.sub_op = None + + def update(self, percent): + """Called periodically to update the user interface.""" + + def done(self): + """Called once an operation has been completed.""" + + if apt_pkg._COMPAT_0_7: + subOp = AttributeDeprecatedBy('sub_op') + + +class OpTextProgress(OpProgress): + """A simple text based cache open reporting class.""" + + def __init__(self): + OpProgress.__init__(self) + + def update(self, percent): + """Called periodically to update the user interface.""" + sys.stdout.write("\r%s: %.2i " % (self.sub_op, percent)) + sys.stdout.flush() + + def done(self): + """Called once an operation has been completed.""" + sys.stdout.write("\r%s: Done\n" % self.op) + + +class FetchProgress(object): + """Report the download/fetching progress. + + Subclass this class to implement fetch progress reporting + """ + + # download status constants + dl_done = 0 + dl_queued = 1 + dl_failed = 2 + dl_hit = 3 + dl_ignored = 4 + dl_status_str = {dl_done: "Done", + dl_queued: "Queued", + dl_failed: "Failed", + dl_hit: "Hit", + dl_ignored: "Ignored"} + + def __init__(self): + self.eta = 0.0 + self.percent = 0.0 + # Make checking easier + self.current_bytes = 0 + self.current_items = 0 + self.total_bytes = 0 + self.total_items = 0 + self.current_cps = 0 + + def start(self): + """Called when the fetching starts.""" + + def stop(self): + """Called when all files have been fetched.""" + + def update_status(self, uri, descr, short_descr, status): + """Called when the status of an item changes. + + This happens eg. when the downloads fails or is completed. + """ + + def update_status_full(self, uri, descr, short_descr, status, file_size, + partial_size): + """Called when the status of an item changes. + + This happens eg. when the downloads fails or is completed. This + version include information on current filesize and partial size + """ + + def pulse(self): + """Called periodically to update the user interface. + + Return True to continue or False to cancel. + """ + self.percent = (((self.current_bytes + self.current_items) * 100.0) / + float(self.total_bytes + self.total_items)) + if self.current_cps > 0: + self.eta = ((self.total_bytes - self.current_bytes) / + float(self.current_cps)) + return True + + def pulse_items(self, items): + """Called periodically to update the user interface. + This function includes details about the items being fetched + Return True to continue or False to cancel. + + """ + self.percent = (((self.current_bytes + self.current_items) * 100.0) / + float(self.total_bytes + self.total_items)) + if self.current_cps > 0: + self.eta = ((self.total_bytes - self.current_bytes) / + float(self.current_cps)) + return True + + def media_change(self, medium, drive): + """react to media change events.""" + + if apt_pkg._COMPAT_0_7: + dlDone = AttributeDeprecatedBy('dl_done') + dlQueued = AttributeDeprecatedBy('dl_queued') + dlFailed = AttributeDeprecatedBy('dl_failed') + dlHit = AttributeDeprecatedBy('dl_hit') + dlIgnored = AttributeDeprecatedBy('dl_ignored') + dlStatusStr = AttributeDeprecatedBy('dl_status_str') + currentBytes = AttributeDeprecatedBy('current_bytes') + currentItems = AttributeDeprecatedBy('current_items') + totalBytes = AttributeDeprecatedBy('total_bytes') + totalItems = AttributeDeprecatedBy('total_items') + currentCPS = AttributeDeprecatedBy('current_cps') + updateStatus = function_deprecated_by(update_status) + mediaChange = function_deprecated_by(media_change) + + +class TextFetchProgress(FetchProgress): + """ Ready to use progress object for terminal windows """ + + def __init__(self): + FetchProgress.__init__(self) + self.items = {} + + def update_status(self, uri, descr, short_descr, status): + """Called when the status of an item changes. + + This happens eg. when the downloads fails or is completed. + """ + if status != self.dl_queued: + print "\r%s %s" % (self.dl_status_str[status], descr) + self.items[uri] = status + + def pulse(self): + """Called periodically to update the user interface. + + Return True to continue or False to cancel. + """ + FetchProgress.pulse(self) + if self.current_cps > 0: + s = "[%2.f%%] %sB/s %s" % (self.percent, + apt_pkg.size_to_str(int(self.current_cps)), + apt_pkg.time_to_str(int(self.eta))) + else: + s = "%2.f%% [Working]" % (self.percent) + print "\r%s" % (s), + sys.stdout.flush() + return True + + def stop(self): + """Called when all files have been fetched.""" + print "\rDone downloading " + + def media_change(self, medium, drive): + """react to media change events.""" + print ("Media change: please insert the disc labeled " + "'%s' in the drive '%s' and press enter") % (medium, drive) + + return raw_input() not in ('c', 'C') + + if apt_pkg._COMPAT_0_7: + updateStatus = function_deprecated_by(update_status) + mediaChange = function_deprecated_by(media_change) + + +class DumbInstallProgress(object): + """Report the install progress. + + Subclass this class to implement install progress reporting. + """ + + def start_update(self): + """Start update.""" + + def run(self, pm): + """Start installation.""" + return pm.do_install() + + def finish_update(self): + """Called when update has finished.""" + + def update_interface(self): + """Called periodically to update the user interface""" + + if apt_pkg._COMPAT_0_7: + startUpdate = function_deprecated_by(start_update) + finishUpdate = function_deprecated_by(finish_update) + updateInterface = function_deprecated_by(update_interface) + + +class InstallProgress(DumbInstallProgress): + """An InstallProgress that is pretty useful. + + It supports the attributes 'percent' 'status' and callbacks for the dpkg + errors and conffiles and status changes. + """ + + def __init__(self): + DumbInstallProgress.__init__(self) + self.select_timeout = 0.1 + (read, write) = os.pipe() + self.writefd = write + self.statusfd = os.fdopen(read, "r") + fcntl.fcntl(self.statusfd.fileno(), fcntl.F_SETFL, os.O_NONBLOCK) + self.read = "" + self.percent = 0.0 + self.status = "" + + def error(self, pkg, errormsg): + """Called when a error is detected during the install.""" + + def conffile(self, current, new): + """Called when a conffile question from dpkg is detected.""" + + def status_change(self, pkg, percent, status): + """Called when the status changed.""" + + def update_interface(self): + """Called periodically to update the interface.""" + if self.statusfd is None: + return + try: + while not self.read.endswith("\n"): + self.read += os.read(self.statusfd.fileno(), 1) + except OSError, (errno_, errstr): + # resource temporarly unavailable is ignored + if errno_ != errno.EAGAIN and errno_ != errno.EWOULDBLOCK: + print errstr + if not self.read.endswith("\n"): + return + + s = self.read + #print s + try: + (status, pkg, percent, status_str) = s.split(":", 3) + except ValueError: + # silently ignore lines that can't be parsed + self.read = "" + return + #print "percent: %s %s" % (pkg, float(percent)/100.0) + if status == "pmerror": + self.error(pkg, status_str) + elif status == "pmconffile": + # we get a string like this: + # 'current-conffile' 'new-conffile' useredited distedited + match = re.match("\s*\'(.*)\'\s*\'(.*)\'.*", status_str) + if match: + self.conffile(match.group(1), match.group(2)) + elif status == "pmstatus": + if float(percent) != self.percent or status_str != self.status: + self.status_change(pkg, float(percent), + status_str.strip()) + self.percent = float(percent) + self.status = status_str.strip() + self.read = "" + + def fork(self): + """Fork.""" + return os.fork() + + def wait_child(self): + """Wait for child progress to exit.""" + while True: + try: + select.select([self.statusfd], [], [], self.select_timeout) + except select.error, e: + if e[0] != errno.EINTR: + raise + + self.update_interface() + (pid, res) = os.waitpid(self.child_pid, os.WNOHANG) + if pid == self.child_pid: + break + return res + + def run(self, pm): + """Start installing.""" + pid = self.fork() + if pid == 0: + # child + res = pm.do_install(self.writefd) + os._exit(res) + self.child_pid = pid + res = self.wait_child() + return os.WEXITSTATUS(res) + + if apt_pkg._COMPAT_0_7: + selectTimeout = AttributeDeprecatedBy('select_timeout') + statusChange = function_deprecated_by(status_change) + waitChild = function_deprecated_by(wait_child) + updateInterface = function_deprecated_by(update_interface) + + +class CdromProgress(object): + """Report the cdrom add progress. + + Subclass this class to implement cdrom add progress reporting. + """ + + def __init__(self): + pass + + def update(self, text, step): + """Called periodically to update the user interface.""" + + def ask_cdrom_name(self): + """Called to ask for the name of the cdrom.""" + + def change_cdrom(self): + """Called to ask for the cdrom to be changed.""" + + if apt_pkg._COMPAT_0_7: + askCdromName = function_deprecated_by(ask_cdrom_name) + changeCdrom = function_deprecated_by(change_cdrom) + + +class DpkgInstallProgress(InstallProgress): + """Progress handler for a local Debian package installation.""" + + def run(self, debfile): + """Start installing the given Debian package.""" + if apt_pkg._COMPAT_0_7: # Deprecated stuff + self.debfile = debfile + self.debname = os.path.basename(debfile).split("_")[0] + + pid = self.fork() + if pid == 0: + # child + res = os.system("/usr/bin/dpkg --status-fd %s -i %s" % \ + (self.writefd, debfile)) + os._exit(os.WEXITSTATUS(res)) + self.child_pid = pid + res = self.wait_child() + return res + + def update_interface(self): + """Process status messages from dpkg.""" + if self.statusfd is None: + return + while True: + try: + self.read += os.read(self.statusfd.fileno(), 1) + except OSError, (errno_, errstr): + # resource temporarly unavailable is ignored + if errno_ != 11: + print errstr + break + if not self.read.endswith("\n"): + continue + + statusl = self.read.split(":") + if len(statusl) < 3: + print "got garbage from dpkg: '%s'" % self.read + self.read = "" + break + pkg_name = statusl[1].strip() + status = statusl[2].strip() + #print status + if status == "error": + self.error(pkg_name, status) + elif status == "conffile-prompt": + # we get a string like this: + # 'current-conffile' 'new-conffile' useredited distedited + match = re.match("\s*\'(.*)\'\s*\'(.*)\'.*", statusl[3]) + if match: + self.conffile(match.group(1), match.group(2)) + else: + self.status = status + self.read = "" + + if apt_pkg._COMPAT_0_7: + updateInterface = function_deprecated_by(update_interface) -- cgit v1.2.3 From 307a9f815c8d0344619c044d2d59eacdbebc25f3 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Thu, 16 Jul 2009 19:53:57 +0200 Subject: apt/progress/gtk2.py: Replace apt.progress with apt.progress.old. --- apt/progress/gtk2.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'apt') diff --git a/apt/progress/gtk2.py b/apt/progress/gtk2.py index c0c05426..c0f9ed82 100644 --- a/apt/progress/gtk2.py +++ b/apt/progress/gtk2.py @@ -37,7 +37,7 @@ import gobject import pango import vte -import apt +import apt.progress.old import apt_pkg from apt.deprecation import function_deprecated_by @@ -53,7 +53,7 @@ def mksig(params=(), run=gobject.SIGNAL_RUN_FIRST, rettype=gobject.TYPE_NONE): return (run, rettype, params) -class GOpProgress(gobject.GObject, apt.progress.OpProgress): +class GOpProgress(gobject.GObject, apt.progress.old.OpProgress): """Operation progress with GObject signals. Signals: @@ -69,7 +69,7 @@ class GOpProgress(gobject.GObject, apt.progress.OpProgress): "status-finished": mksig()} def __init__(self): - apt.progress.OpProgress.__init__(self) + apt.progress.old.OpProgress.__init__(self) gobject.GObject.__init__(self) self._context = glib.main_context_default() @@ -84,7 +84,7 @@ class GOpProgress(gobject.GObject, apt.progress.OpProgress): self.emit("status-finished") -class GInstallProgress(gobject.GObject, apt.progress.InstallProgress): +class GInstallProgress(gobject.GObject, apt.progress.old.InstallProgress): """Installation progress with GObject signals. Signals: @@ -108,7 +108,7 @@ class GInstallProgress(gobject.GObject, apt.progress.InstallProgress): "status-finished": mksig()} def __init__(self, term): - apt.progress.InstallProgress.__init__(self) + apt.progress.old.InstallProgress.__init__(self) gobject.GObject.__init__(self) self.finished = False self.time_last_update = time.time() @@ -166,7 +166,7 @@ class GInstallProgress(gobject.GObject, apt.progress.InstallProgress): Emits: status-timeout() [When a timeout happens] """ - apt.progress.InstallProgress.update_interface(self) + apt.progress.old.InstallProgress.update_interface(self) while self._context.pending(): self._context.iteration() if self.time_last_update + self.INSTALL_TIMEOUT < time.time(): @@ -191,7 +191,8 @@ class GInstallProgress(gobject.GObject, apt.progress.InstallProgress): childExited = function_deprecated_by(child_exited) -class GDpkgInstallProgress(apt.progress.DpkgInstallProgress, GInstallProgress): +class GDpkgInstallProgress(apt.progress.old.DpkgInstallProgress, + GInstallProgress): """An InstallProgress for local installations. Signals: @@ -206,13 +207,13 @@ class GDpkgInstallProgress(apt.progress.DpkgInstallProgress, GInstallProgress): def run(self, debfile): """Install the given package.""" - apt.progress.DpkgInstallProgress.run(self, debfile) + apt.progress.old.DpkgInstallProgress.run(self, debfile) def update_interface(self): """Called periodically to update the interface. Emits: status-timeout() [When a timeout happens]""" - apt.progress.DpkgInstallProgress.update_interface(self) + apt.progress.old.DpkgInstallProgress.update_interface(self) if self.time_last_update + self.INSTALL_TIMEOUT < time.time(): self.emit("status-timeout") @@ -220,7 +221,7 @@ class GDpkgInstallProgress(apt.progress.DpkgInstallProgress, GInstallProgress): updateInterface = function_deprecated_by(update_interface) -class GFetchProgress(gobject.GObject, apt.progress.FetchProgress): +class GFetchProgress(gobject.GObject, apt.progress.old.FetchProgress): """A Fetch Progress with GObject signals. Signals: @@ -235,7 +236,7 @@ class GFetchProgress(gobject.GObject, apt.progress.FetchProgress): "status-finished": mksig()} def __init__(self): - apt.progress.FetchProgress.__init__(self) + apt.progress.old.FetchProgress.__init__(self) gobject.GObject.__init__(self) self._continue = True self._context = glib.main_context_default() @@ -250,7 +251,7 @@ class GFetchProgress(gobject.GObject, apt.progress.FetchProgress): self._continue = False def pulse(self): - apt.progress.FetchProgress.pulse(self) + apt.progress.old.FetchProgress.pulse(self) current_item = self.current_items + 1 if current_item > self.total_items: current_item = self.total_items -- cgit v1.2.3 From 212ab0a6b95395bad245eb18d4aa710b01b24e9e Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Thu, 16 Jul 2009 20:08:00 +0200 Subject: apt/progress/text.py: Print status messages. --- apt/progress/text.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'apt') diff --git a/apt/progress/text.py b/apt/progress/text.py index eb196b55..2b2e5f27 100644 --- a/apt/progress/text.py +++ b/apt/progress/text.py @@ -29,15 +29,15 @@ class TextProgress(object): self._file = outfile or sys.stdout self._width = 0 - def _write(self, msg, newline=True): + def _write(self, msg, newline=True, maximize=False): """Write the message on the terminal, fill remaining space.""" self._file.write("\r") self._file.write(msg) # Fill remaining stuff with whitespace if self._width > len(msg): self._file.write((self._width - len(msg)) * ' ') - #else: - # self._width = max(self._width, len(msg)) + elif maximize: # Needed for OpProgress. + self._width = max(self._width, len(msg)) if newline: self._file.write("\n") else: @@ -63,14 +63,14 @@ class OpProgress(apt_pkg.OpProgress, TextProgress): apt_pkg.OpProgress.update(self) if self.major_change and self.old_op: self._write(self.old_op) - self._write("%s... %i%%\r" % (self.op, self.percent), False) + self._write("%s... %i%%\r" % (self.op, self.percent), False, True) self.old_op = self.op def done(self): """Called once an operation has been completed.""" apt_pkg.OpProgress.done(self) if self.old_op: - self._write("%s... Done" % self.old_op) + self._write("%s... Done" % self.old_op, True, True) self.old_op = "" @@ -102,7 +102,6 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): def fail(self, item): """Called when an item is failed.""" - self._write("Fail %s" % item.description) if item.owner.status == item.owner.stat_done: self._write("Ign %s" % item.description) else: @@ -141,7 +140,7 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): val = '' if not worker.current_item: if worker.status: - val += ' [%s]' % worker.status + tval += ' [%s]' % worker.status shown = True continue shown = True -- cgit v1.2.3 From 7f861d478db844037d14aeb423eaab88a0a47716 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Thu, 16 Jul 2009 20:16:27 +0200 Subject: apt/progress/text.py: Limit number of displayed items by display size. --- apt/progress/text.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'apt') diff --git a/apt/progress/text.py b/apt/progress/text.py index 2b2e5f27..4cdd266f 100644 --- a/apt/progress/text.py +++ b/apt/progress/text.py @@ -140,7 +140,10 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): val = '' if not worker.current_item: if worker.status: - tval += ' [%s]' % worker.status + val = ' [%s]' % worker.status + if len(tval) + len(val) + len(end) >= self._width: + break + tval += val shown = True continue shown = True @@ -166,7 +169,10 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): val += ']' - tval += val + if len(tval) + len(val) + len(end) >= self._width: + break + else: + tval += val if not shown: tval += ' [Working]' -- cgit v1.2.3 From 5dbe872723f375db9f5d371051f6a9756fdc4c60 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 17 Jul 2009 13:00:41 +0200 Subject: apt/progress/text.py: Don't display complete items in AcquireProgress.fetch --- apt/progress/text.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'apt') diff --git a/apt/progress/text.py b/apt/progress/text.py index 4cdd266f..2a6b188d 100644 --- a/apt/progress/text.py +++ b/apt/progress/text.py @@ -110,6 +110,9 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): def fetch(self, item): """Called when some of the item's data is fetched.""" + # It's complete already (e.g. Hit) + if item.owner.complete == True: + return item.owner.id = self._id self._id += 1 line = "Get:%s %s" % (item.owner.id, item.description) -- cgit v1.2.3 From 837e2fd927906c229801e41a5effbf95f9c6a106 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 17 Jul 2009 16:14:56 +0200 Subject: apt/progress: Fix apt.progress with COMPAT_0_7 --- apt/progress/__init__.py | 13 ++++--------- apt/progress/old.py | 6 ++---- 2 files changed, 6 insertions(+), 13 deletions(-) (limited to 'apt') diff --git a/apt/progress/__init__.py b/apt/progress/__init__.py index 67880903..c75c368b 100644 --- a/apt/progress/__init__.py +++ b/apt/progress/__init__.py @@ -17,13 +17,8 @@ """Progress reporting.""" import apt_pkg -#from apt.progress.text import AcquireProgress as TextAcquireProgress -#from apt.progress.text import OpProgress as TextOpProgress - -__all__ = [] #'TextAcquireProgress', 'TextOpProgress'] - if apt_pkg._COMPAT_0_7: - import apt.progress.old - from apt.progress.old import * - - __all__ += apt.progress.old.__all__ + from apt.progress.old import (CdromProgress, DpkgInstallProgress, + DumbInstallProgress, FetchProgress, + InstallProgress, OpProgress, + OpTextProgress, TextFetchProgress) diff --git a/apt/progress/old.py b/apt/progress/old.py index 3c5d4588..d4ff5815 100644 --- a/apt/progress/old.py +++ b/apt/progress/old.py @@ -18,7 +18,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # USA -"""progress reporting classes. +"""Deprecated progress reporting classes. This module provides classes for progress reporting. They can be used with e.g., for reporting progress on the cache opening process, the cache update @@ -36,9 +36,7 @@ import apt_pkg from apt.deprecation import AttributeDeprecatedBy, function_deprecated_by -__all__ = ('CdromProgress', 'DpkgInstallProgress', 'DumbInstallProgress', - 'FetchProgress', 'InstallProgress', 'OpProgress', 'OpTextProgress', - 'TextFetchProgress') +__all__ = [] class OpProgress(object): -- cgit v1.2.3 From 4e2bcf7853acd661bd9b56be7c774cc361fdebb4 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 17 Jul 2009 16:45:51 +0200 Subject: apt/progress/text.py: Cleanup, add i18n (and try apt translation if we have none). --- apt/progress/text.py | 92 +++++++++++++++++++++++++++++----------------------- 1 file changed, 52 insertions(+), 40 deletions(-) (limited to 'apt') diff --git a/apt/progress/text.py b/apt/progress/text.py index 2a6b188d..b50502e6 100644 --- a/apt/progress/text.py +++ b/apt/progress/text.py @@ -16,12 +16,22 @@ # USA """Progress reporting for text interfaces.""" import sys +from gettext import gettext, dgettext import apt_pkg __all__ = ['AcquireProgress', 'OpProgress'] +def _(msg): + """Translate the message, also try apt if translation is missing.""" + res = dgettext("python-apt", msg) + if res == msg: + return dgettext("apt", msg) + else: + return res + + class TextProgress(object): """Internal Base class for text progress classes.""" @@ -70,7 +80,7 @@ class OpProgress(apt_pkg.OpProgress, TextProgress): """Called once an operation has been completed.""" apt_pkg.OpProgress.done(self) if self.old_op: - self._write("%s... Done" % self.old_op, True, True) + self._write(_("%c%s... Done") % ('\r', self.old_op), True, True) self.old_op = "" @@ -85,42 +95,51 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): self._winch() self._id = 1L - def _winch(self, *a): + def __del__(self): + import signal + signal.signal(signal.SIGWINCH, self._signal) + + def _winch(self, *dummy): + """Signal handler for window resize signals.""" import fcntl import termios import struct - buf = fcntl.ioctl(self._file.fileno(),termios.TIOCGWINSZ, 8 * ' ') - row, col, rpx, cpx = struct.unpack('hhhh', buf) + buf = fcntl.ioctl(self._file, termios.TIOCGWINSZ, 8 * ' ') + dummy, col, dummy, dummy = struct.unpack('hhhh', buf) self._width = col - 1 # 1 for the cursor def ims_hit(self, item): """Called when an item is update (e.g. not modified on the server).""" - line = 'Hit %s' % item.description - if (item.owner.filesize != 0): - line+= ' [%sB]' % apt_pkg.size_to_str(item.owner.filesize) + line = _('Hit ') + item.description + if item.owner.filesize: + line += ' [%sB]' % apt_pkg.size_to_str(item.owner.filesize) self._write(line) def fail(self, item): """Called when an item is failed.""" if item.owner.status == item.owner.stat_done: - self._write("Ign %s" % item.description) + self._write(_("Ign ") + item.description) else: - self._write("Err %s" % item.description) + self._write(_("Err ") + item.description) self._write(" %s" % item.owner.error_text) def fetch(self, item): """Called when some of the item's data is fetched.""" # It's complete already (e.g. Hit) - if item.owner.complete == True: + if item.owner.complete: return item.owner.id = self._id self._id += 1 - line = "Get:%s %s" % (item.owner.id, item.description) - if item.owner.filesize != 0: + line = _("Get:") + "%s %s" % (item.owner.id, item.description) + if item.owner.filesize: line += (" [%sB]" % apt_pkg.size_to_str(item.owner.filesize)) self._write(line) + @staticmethod + def _fmt_worker(worker): + """Format a worker.""" + def pulse(self, owner): """Periodically invoked while the Acquire process is underway. @@ -130,14 +149,14 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): float(self.total_bytes + self.total_items)) shown = False - mode = 'long' tval = '%i%%' % percent end = "" if self.current_cps: - eta = int(float(self.total_bytes - self.current_bytes) / self.current_cps) + eta = int(float(self.total_bytes - self.current_bytes) / + self.current_cps) end = " %sB/s %s" % (apt_pkg.size_to_str(self.current_cps), - apt_pkg.time_to_str(eta)) + apt_pkg.time_to_str(eta)) for worker in owner.workers: val = '' @@ -151,55 +170,48 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): continue shown = True - if worker.current_item.owner.id != 0: - val += " [%i %s" % (worker.current_item.owner.id, worker.current_item.shortdesc) + if worker.current_item.owner.id: + val += " [%i %s" % (worker.current_item.owner.id, + worker.current_item.shortdesc) else: val += ' [%s' % worker.current_item.description if worker.current_item.owner.mode: val += ' %s' % worker.current_item.owner.mode - if mode == 'long' and False: - val += ' %i' % worker.current_size - elif mode == 'medium' or worker.total_size == 0 or True: - val += ' %sB' % apt_pkg.size_to_str(worker.current_size) + + val += ' %sB' % apt_pkg.size_to_str(worker.current_size) # Add the total size and percent - if worker.total_size > 0 and worker.current_item.owner.complete == False: - if mode == 'short': - val += ' %i%%' % worker.current_size*100.0/worker.total_size - else: - val += "/%sB %i%%" % ( apt_pkg.size_to_str(worker.total_size), - worker.current_size*100.0/worker.total_size ) + if worker.total_size and not worker.current_item.owner.complete: + val += "/%sB %i%%" % (apt_pkg.size_to_str(worker.total_size), + worker.current_size*100.0/worker.total_size) val += ']' - if len(tval) + len(val) + len(end) >= self._width: + if len(tval) + len(val) + len(end) >= self._width: break else: tval += val if not shown: - tval += ' [Working]' + tval += _(" [Working]") if self.current_cps: tval += (self._width - len(end) - len(tval)) * ' ' + end - if len(tval) <= self._width: - self._write(tval, False) - else: - self._write(tval) + self._write(tval, False) return True def media_change(self, medium, drive): """Prompt the user to change the inserted removable media.""" - print ("Media change: please insert the disc labeled " - "'%s' in the drive '%s' and press enter") % (medium, drive) - + self._write(_("Media change: please insert the disc labeled\n" + " '%s'\n" + "in the drive '%s' and press enter\n") % (medium, drive)) return raw_input() not in ('c', 'C') def stop(self): """Invoked when the Acquire process stops running.""" - if self.fetched_bytes != 0: - self._write("Fetched %sB in %s (%sB/s)" % ( - apt_pkg.size_to_str(self.fetched_bytes), + if self.fetched_bytes: + self._write(_("Fetched %sB in %s (%sB/s)\n") % ( + apt_pkg.size_to_str(self.fetched_bytes), apt_pkg.time_to_str(self.elapsed_time), - apt_pkg.size_to_str(self.current_cps))) + apt_pkg.size_to_str(self.current_cps)), False) -- cgit v1.2.3 From 16c00d2037cde6da07b4988dbd35ebce0af56791 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 17 Jul 2009 17:15:38 +0200 Subject: apt/__init__.py, apt/__cache__.py: Improve python-apt localization. --- apt/__init__.py | 6 +++--- apt/cache.py | 7 ++++++- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'apt') diff --git a/apt/__init__.py b/apt/__init__.py index ec7103a1..2ef8add3 100644 --- a/apt/__init__.py +++ b/apt/__init__.py @@ -18,6 +18,8 @@ # USA # import the core of apt_pkg """High-Level Interface for working with apt.""" +import locale + import apt_pkg # import some fancy classes @@ -28,15 +30,13 @@ from apt.cdrom import Cdrom if apt_pkg._COMPAT_0_7: from apt.progress.old import (OpProgress, FetchProgress, InstallProgress, CdromProgress) - -if apt_pkg._COMPAT_0_7: from apt_pkg import (size_to_str as SizeToStr, time_to_str as TimeToStr, version_compare as VersionCompare) # init the package system apt_pkg.init() - +locale.setlocale(locale.LC_ALL, '') #import warnings #warnings.warn("apt API not stable yet", FutureWarning) diff --git a/apt/cache.py b/apt/cache.py index a93d5575..6e11d215 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -21,6 +21,7 @@ import os import weakref +from gettext import dgettext import apt_pkg from apt import Package @@ -29,6 +30,10 @@ from apt.deprecation import (AttributeDeprecatedBy, function_deprecated_by, import apt.progress.text +def _(msg): + return dgettext('python-apt', msg) + + class FetchCancelledException(IOError): """Exception that is thrown when the user cancels a fetch operation.""" @@ -92,7 +97,7 @@ class Cache(object): self._set.clear() self._weakref.clear() - progress.op = "Building data structures" + progress.op = _("Building data structures") i=last=0 size=len(self._cache.packages) for pkg in self._cache.packages: -- cgit v1.2.3 From db6032394c794c6bbe59675bb38802d208d993cb Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 17 Jul 2009 17:24:58 +0200 Subject: apt/progress/text.py: Improve final summary. --- apt/progress/text.py | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) (limited to 'apt') diff --git a/apt/progress/text.py b/apt/progress/text.py index b50502e6..ba8e158d 100644 --- a/apt/progress/text.py +++ b/apt/progress/text.py @@ -16,7 +16,7 @@ # USA """Progress reporting for text interfaces.""" import sys -from gettext import gettext, dgettext +from gettext import dgettext import apt_pkg @@ -90,15 +90,22 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): def __init__(self, outfile=None): TextProgress.__init__(self, outfile) apt_pkg.AcquireProgress.__init__(self) + self._signal = None + self._width = 80 + self._id = 1 + + def start(self): + """Start an Acquire progress. + + In this case, the function sets up a signal handler for SIGWINCH, i.e. + window resize signals. And it also sets id to 1. + """ import signal self._signal = signal.signal(signal.SIGWINCH, self._winch) + # Get the window size. self._winch() self._id = 1L - def __del__(self): - import signal - signal.signal(signal.SIGWINCH, self._signal) - def _winch(self, *dummy): """Signal handler for window resize signals.""" import fcntl @@ -136,10 +143,6 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): self._write(line) - @staticmethod - def _fmt_worker(worker): - """Format a worker.""" - def pulse(self, owner): """Periodically invoked while the Acquire process is underway. @@ -188,6 +191,7 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): val += ']' if len(tval) + len(val) + len(end) >= self._width: + # Display as many items as screen width break else: tval += val @@ -210,8 +214,12 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): def stop(self): """Invoked when the Acquire process stops running.""" - if self.fetched_bytes: - self._write(_("Fetched %sB in %s (%sB/s)\n") % ( - apt_pkg.size_to_str(self.fetched_bytes), - apt_pkg.time_to_str(self.elapsed_time), - apt_pkg.size_to_str(self.current_cps)), False) + # Trick for getting a translation from apt + self._write((_("Fetched %sB in %s (%sB/s)\n") % ( + apt_pkg.size_to_str(self.fetched_bytes), + apt_pkg.time_to_str(self.elapsed_time), + apt_pkg.size_to_str(self.current_cps))).rstrip("\n")) + + # Delete the signal again. + import signal + signal.signal(signal.SIGWINCH, self._signal) -- cgit v1.2.3 From 9bd7c1dcf9942d6ce294aa5ac58d90d6c1aa9f51 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 17 Jul 2009 19:06:20 +0200 Subject: apt: Use apt_pkg.gettext instead of Python's gettext. --- apt/__init__.py | 9 +-------- apt/cache.py | 6 +----- apt/debfile.py | 2 +- apt/package.py | 7 +------ apt/progress/gtk2.py | 2 +- apt/progress/text.py | 6 ++---- 6 files changed, 7 insertions(+), 25 deletions(-) (limited to 'apt') diff --git a/apt/__init__.py b/apt/__init__.py index 2ef8add3..a75218a8 100644 --- a/apt/__init__.py +++ b/apt/__init__.py @@ -18,8 +18,6 @@ # USA # import the core of apt_pkg """High-Level Interface for working with apt.""" -import locale - import apt_pkg # import some fancy classes @@ -30,15 +28,10 @@ from apt.cdrom import Cdrom if apt_pkg._COMPAT_0_7: from apt.progress.old import (OpProgress, FetchProgress, InstallProgress, CdromProgress) - from apt_pkg import (size_to_str as SizeToStr, - time_to_str as TimeToStr, + from apt_pkg import (size_to_str as SizeToStr, time_to_str as TimeToStr, version_compare as VersionCompare) # init the package system apt_pkg.init() -locale.setlocale(locale.LC_ALL, '') -#import warnings -#warnings.warn("apt API not stable yet", FutureWarning) -#del warnings __all__ = ['Cache', 'Cdrom', 'Package'] diff --git a/apt/cache.py b/apt/cache.py index 6e11d215..9982559b 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -21,19 +21,15 @@ import os import weakref -from gettext import dgettext import apt_pkg from apt import Package +from apt_pkg import gettext as _ from apt.deprecation import (AttributeDeprecatedBy, function_deprecated_by, deprecated_args) import apt.progress.text -def _(msg): - return dgettext('python-apt', msg) - - class FetchCancelledException(IOError): """Exception that is thrown when the user cancels a fetch operation.""" diff --git a/apt/debfile.py b/apt/debfile.py index 84bbe3ab..e05233f4 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -17,12 +17,12 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # USA """Classes for working with locally available Debian packages.""" -from gettext import gettext as _ import os import sys import apt_inst import apt_pkg +from apt_pkg import gettext as _ # Constants for comparing the local package file with the version in the cache diff --git a/apt/package.py b/apt/package.py index 491571c2..1307ca3e 100644 --- a/apt/package.py +++ b/apt/package.py @@ -19,7 +19,6 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # USA """Functionality related to packages.""" -import gettext import httplib import os import sys @@ -36,6 +35,7 @@ except ImportError: import apt_pkg import apt.progress.text +from apt_pkg import gettext as _ from apt.deprecation import (function_deprecated_by, AttributeDeprecatedBy, deprecated_args) @@ -43,11 +43,6 @@ __all__ = ('BaseDependency', 'Dependency', 'Origin', 'Package', 'Record', 'Version') -def _(string): - """Return the translation of the string.""" - return gettext.dgettext("python-apt", string) - - def _file_is_same(path, size, md5): """Return ``True`` if the file is the same.""" if (os.path.exists(path) and os.path.getsize(path) == size and diff --git a/apt/progress/gtk2.py b/apt/progress/gtk2.py index c0f9ed82..066271c6 100644 --- a/apt/progress/gtk2.py +++ b/apt/progress/gtk2.py @@ -22,7 +22,6 @@ # USA """GObject-powered progress classes and a GTK+ status widget.""" -from gettext import gettext as _ import os import time @@ -39,6 +38,7 @@ import vte import apt.progress.old import apt_pkg +from apt_pkg import gettext as _ from apt.deprecation import function_deprecated_by diff --git a/apt/progress/text.py b/apt/progress/text.py index ba8e158d..b93a8e81 100644 --- a/apt/progress/text.py +++ b/apt/progress/text.py @@ -16,7 +16,6 @@ # USA """Progress reporting for text interfaces.""" import sys -from gettext import dgettext import apt_pkg @@ -25,13 +24,12 @@ __all__ = ['AcquireProgress', 'OpProgress'] def _(msg): """Translate the message, also try apt if translation is missing.""" - res = dgettext("python-apt", msg) + res = apt_pkg.gettext(msg) if res == msg: - return dgettext("apt", msg) + return apt_pkg.gettext(msg, "apt") else: return res - class TextProgress(object): """Internal Base class for text progress classes.""" -- cgit v1.2.3 From 5c219e07aea347f652cf7949dc74f37282a17144 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Sun, 19 Jul 2009 14:39:41 +0200 Subject: python/cdromprogress.cc: Add apt_pkg.CdromProgress. --- apt/progress/old.py | 22 ++-------- python/apt_pkgmodule.cc | 1 + python/apt_pkgmodule.h | 1 + python/cdrom.cc | 11 +++++ python/cdromprogress.cc | 106 ++++++++++++++++++++++++++++++++++++++++++++++++ python/progress.cc | 12 ++++-- python/progress.h | 6 +++ 7 files changed, 137 insertions(+), 22 deletions(-) create mode 100644 python/cdromprogress.cc (limited to 'apt') diff --git a/apt/progress/old.py b/apt/progress/old.py index d4ff5815..63fc5d2e 100644 --- a/apt/progress/old.py +++ b/apt/progress/old.py @@ -343,27 +343,13 @@ class InstallProgress(DumbInstallProgress): updateInterface = function_deprecated_by(update_interface) -class CdromProgress(object): +class CdromProgress(apt_pkg.CdromProgress): """Report the cdrom add progress. - Subclass this class to implement cdrom add progress reporting. + This class has been replaced by apt_pkg.CdromProgress. """ - - def __init__(self): - pass - - def update(self, text, step): - """Called periodically to update the user interface.""" - - def ask_cdrom_name(self): - """Called to ask for the name of the cdrom.""" - - def change_cdrom(self): - """Called to ask for the cdrom to be changed.""" - - if apt_pkg._COMPAT_0_7: - askCdromName = function_deprecated_by(ask_cdrom_name) - changeCdrom = function_deprecated_by(change_cdrom) + askCdromName = function_deprecated_by(apt_pkg.CdromProgress.ask_cdrom_name) + changeCdrom = function_deprecated_by(apt_pkg.CdromProgress.change_cdrom) class DpkgInstallProgress(InstallProgress): diff --git a/python/apt_pkgmodule.cc b/python/apt_pkgmodule.cc index d6b8e3d1..b6ae709e 100644 --- a/python/apt_pkgmodule.cc +++ b/python/apt_pkgmodule.cc @@ -651,6 +651,7 @@ extern "C" void initapt_pkg() ADDTYPE(Module,"OpProgress",&PyOpProgress_Type); ADDTYPE(Module,"AcquireProgress",&PyAcquireProgress_Type); ADDTYPE(Module,"AcquireItemDesc",&PyAcquireItemDesc_Type); + ADDTYPE(Module,"CdromProgress",&PyCdromProgress_Type); // Tag file constants PyModule_AddObject(Module,"REWRITE_PACKAGE_ORDER", CharCharToList(TFRewritePackageOrder)); diff --git a/python/apt_pkgmodule.h b/python/apt_pkgmodule.h index ad1fe9fe..1277ab60 100644 --- a/python/apt_pkgmodule.h +++ b/python/apt_pkgmodule.h @@ -114,6 +114,7 @@ extern PyTypeObject PyPolicy_Type; extern PyTypeObject PyHashes_Type; extern PyTypeObject PyOpProgress_Type; extern PyTypeObject PyAcquireProgress_Type; +extern PyTypeObject PyCdromProgress_Type; extern PyTypeObject PyAcquireItemDesc_Type; extern PyTypeObject PyAcquireWorker_Type; #include "python-apt.h" diff --git a/python/cdrom.cc b/python/cdrom.cc index 50d1b4b1..6ee3becd 100644 --- a/python/cdrom.cc +++ b/python/cdrom.cc @@ -34,9 +34,20 @@ static PyObject *PkgCdromIdent(PyObject *Self,PyObject *Args) pkgCdrom &Cdrom = GetCpp(Self); PyObject *pyCdromProgressInst = 0; +#ifdef COMPAT_0_7 if (PyArg_ParseTuple(Args, "O", &pyCdromProgressInst) == 0) { +#else + if (PyArg_ParseTuple(Args, "O!", &PyCdromProgress_Type, + &pyCdromProgressInst) == 0) { +#endif return 0; } +#ifdef COMPAT_0_7 + if (!PyObject_TypeCheck(pyCdromProgressInst, &PyCdromProgress_Type)) { + PyErr_WarnEx(PyExc_DeprecationWarning, "Argument should be a subclass of" + " apt_pkg.CdromProgress.", 1); + } +#endif PyCdromProgress progress; progress.setCallbackInst(pyCdromProgressInst); diff --git a/python/cdromprogress.cc b/python/cdromprogress.cc new file mode 100644 index 00000000..09c76a2a --- /dev/null +++ b/python/cdromprogress.cc @@ -0,0 +1,106 @@ +/* cdromprogress.cc - Base class for CdromProgress classes. + * + * Copyright 2009 Julian Andres Klode + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#include "apt_pkgmodule.h" +#include "progress.h" +#include +#include + +// Takes two arguments (string, int) +static PyObject *cdromprogress_update(PyObject *self, PyObject *args) +{ + Py_RETURN_NONE; +} + +// Takes no arguments +static PyObject *cdromprogress_change_cdrom(PyObject *self, PyObject *args) +{ + Py_RETURN_FALSE; +} + +// Takes a single PyObject argument as *arg +static PyObject *cdromprogress_ask_cdrom_name(PyObject *self, PyObject *arg) +{ + Py_RETURN_FALSE; +} + +static PyMethodDef cdromprogress_methods[] = { + {"update",cdromprogress_update,METH_VARARGS, + "update(text: str, current: int)\n\nCalled regularly."}, + {"change_cdrom",cdromprogress_change_cdrom,METH_NOARGS, + "change_cdrom() -> bool\n\nAsk for the CD-ROM to be changed.\n" + "Return False if the user requested to cancel the action (default)."}, + {"ask_cdrom_name",cdromprogress_ask_cdrom_name,METH_O, + "ask_cdrom_name(name: str) -> bool\n\nAsk for the name of the CD-ROM.\n" + "Return False if the user requested to cancel the action (default)."}, + {NULL} +}; + +static PyMemberDef cdromprogress_members[] = { + {"total_steps", T_INT, offsetof(PyCdromProgressObject,total_steps), 0, + "The number of total steps to be taken."}, + {NULL} +}; + +static char *cdromprogress_doc = "CdromProgress()\n\n" + "Base class for reporting the progress of adding a cdrom. Can be used\n" + "with apt_pkg.Cdrom to produce an utility like apt-cdrom."; + +PyTypeObject PyCdromProgress_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.CdromProgress", // tp_name + sizeof(PyCdromProgressObject), // tp_basicsize + 0, // tp_itemsize + // Methods + 0, // tp_dealloc + 0, // tp_print + 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_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_BASETYPE, + cdromprogress_doc, // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + cdromprogress_methods, // tp_methods + cdromprogress_members, // tp_members + 0, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + PyType_GenericNew, // tp_new +}; diff --git a/python/progress.cc b/python/progress.cc index 123a1805..b19ab0c7 100644 --- a/python/progress.cc +++ b/python/progress.cc @@ -518,10 +518,14 @@ pkgPackageManager::OrderResult PyInstallProgress::Run(pkgPackageManager *pm) void PyCdromProgress::Update(string text, int current) { PyObject *arglist = Py_BuildValue("(si)", text.c_str(), current); - - PyObject *o = Py_BuildValue("i", totalSteps); - PyObject_SetAttrString(callbackInst, "totalSteps", o); - Py_XDECREF(o); + if (PyObject_TypeCheck(callbackInst, &PyCdromProgress_Type)) { + ((PyCdromProgressObject *)callbackInst)->total_steps = totalSteps; + } + else { + PyObject *o = Py_BuildValue("i", totalSteps); + PyObject_SetAttrString(callbackInst, "totalSteps", o); + Py_XDECREF(o); + } RunSimpleCallback("update", arglist); } diff --git a/python/progress.h b/python/progress.h index e21a5c5a..88bd3552 100644 --- a/python/progress.h +++ b/python/progress.h @@ -28,6 +28,12 @@ typedef struct { float percent; } PyOpProgressObject; + +typedef struct { + PyObject_HEAD + int total_steps; +} PyCdromProgressObject; + typedef struct { PyObject_HEAD double last_bytes; -- cgit v1.2.3 From 7debfcbb984fe059ff08b7edba40f14bff2c28a6 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Sun, 19 Jul 2009 15:46:46 +0200 Subject: apt/progress/text.py: Introduce CdromProgress. --- apt/progress/text.py | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) (limited to 'apt') diff --git a/apt/progress/text.py b/apt/progress/text.py index b93a8e81..49707a23 100644 --- a/apt/progress/text.py +++ b/apt/progress/text.py @@ -26,9 +26,8 @@ def _(msg): """Translate the message, also try apt if translation is missing.""" res = apt_pkg.gettext(msg) if res == msg: - return apt_pkg.gettext(msg, "apt") - else: - return res + res = apt_pkg.gettext(msg, "apt") + return res class TextProgress(object): """Internal Base class for text progress classes.""" @@ -40,7 +39,8 @@ class TextProgress(object): def _write(self, msg, newline=True, maximize=False): """Write the message on the terminal, fill remaining space.""" self._file.write("\r") - self._file.write(msg) + print >> self._file, msg, + # Fill remaining stuff with whitespace if self._width > len(msg): self._file.write((self._width - len(msg)) * ' ') @@ -221,3 +221,26 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): # Delete the signal again. import signal signal.signal(signal.SIGWINCH, self._signal) + +class CdromProgress(apt_pkg.CdromProgress, TextProgress): + """Text CD-ROM progress.""" + + def ask_cdrom_name(self): + self._write(_("Please provide a name for this Disc, such as " + "'Debian 2.1r1 Disk 1'"), False) + try: + return raw_input(":") + except KeyboardInterrupt: + return + + def update(self, text, current): + if text: + self._write(text, False) + + def change_cdrom(self): + self._write(_("Please insert a Disc in the drive and press enter"), + False) + try: + return (raw_input() == '') + except KeyboardInterrupt: + return False -- cgit v1.2.3 From 50de9d386f4bfd9a699d52ae043ff0082cb1ee0c Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Sun, 19 Jul 2009 15:48:58 +0200 Subject: apt/cdrom.py: Make apt.cdrom.Cdrom a subclass of apt_pkg.Cdrom. --- apt/cdrom.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'apt') diff --git a/apt/cdrom.py b/apt/cdrom.py index a3811ccb..126c54dd 100644 --- a/apt/cdrom.py +++ b/apt/cdrom.py @@ -23,11 +23,10 @@ import glob import apt_pkg -from apt.progress.old import CdromProgress from apt.deprecation import AttributeDeprecatedBy -class Cdrom(object): +class Cdrom(apt_pkg.Cdrom): """Support for apt-cdrom like features. This class has several optional parameters for initialisation, which may @@ -45,9 +44,9 @@ class Cdrom(object): """ def __init__(self, progress=None, mountpoint=None, nomount=True): - self._cdrom = apt_pkg.Cdrom() + apt_pkg.Cdrom.__init__(self) if progress is None: - self._progress = CdromProgress() + self._progress = apt_pkg.CdromProgress() else: self._progress = progress # see if we have a alternative mountpoint @@ -59,15 +58,13 @@ class Cdrom(object): else: apt_pkg.config.set("APT::CDROM::NoMount", "false") - def add(self): + def add(self, progress=None): """Add cdrom to the sources.list.""" - return self._cdrom.add(self._progress) + return apt_pkg.Cdrom.add(self, progress or self._progress) - def ident(self): + def ident(self, progress=None): """Identify the cdrom.""" - (res, ident) = self._cdrom.ident(self._progress) - if res: - return ident + return apt_pkg.Cdrom.ident(self, progress or self._progress) @property def in_sources_list(self): -- cgit v1.2.3 From 2731686d7ef756062eeaf78d7809d18f71e9aaf5 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Sun, 19 Jul 2009 16:49:30 +0200 Subject: apt/progress/text.py: Add some docstrings. --- apt/progress/text.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'apt') diff --git a/apt/progress/text.py b/apt/progress/text.py index 49707a23..1316952c 100644 --- a/apt/progress/text.py +++ b/apt/progress/text.py @@ -29,6 +29,7 @@ def _(msg): res = apt_pkg.gettext(msg, "apt") return res + class TextProgress(object): """Internal Base class for text progress classes.""" @@ -222,10 +223,12 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): import signal signal.signal(signal.SIGWINCH, self._signal) + class CdromProgress(apt_pkg.CdromProgress, TextProgress): """Text CD-ROM progress.""" def ask_cdrom_name(self): + """Ask the user to provide a name for the disc.""" self._write(_("Please provide a name for this Disc, such as " "'Debian 2.1r1 Disk 1'"), False) try: @@ -234,10 +237,12 @@ class CdromProgress(apt_pkg.CdromProgress, TextProgress): return def update(self, text, current): + """Set the current progress.""" if text: self._write(text, False) def change_cdrom(self): + """Ask the user to change the CD-ROM.""" self._write(_("Please insert a Disc in the drive and press enter"), False) try: -- cgit v1.2.3 From 86007bcc5e1faa40d2d4e456121b839f96136fb6 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Sun, 19 Jul 2009 17:51:16 +0200 Subject: apt/progress/text.py: Always call methods of the parent class. --- apt/progress/text.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'apt') diff --git a/apt/progress/text.py b/apt/progress/text.py index 1316952c..a121eaaa 100644 --- a/apt/progress/text.py +++ b/apt/progress/text.py @@ -99,6 +99,7 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): In this case, the function sets up a signal handler for SIGWINCH, i.e. window resize signals. And it also sets id to 1. """ + apt_pkg.AcquireProgress.start(self) import signal self._signal = signal.signal(signal.SIGWINCH, self._winch) # Get the window size. @@ -116,6 +117,7 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): def ims_hit(self, item): """Called when an item is update (e.g. not modified on the server).""" + apt_pkg.AcquireProgress.ims_hit(self, item) line = _('Hit ') + item.description if item.owner.filesize: line += ' [%sB]' % apt_pkg.size_to_str(item.owner.filesize) @@ -123,6 +125,7 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): def fail(self, item): """Called when an item is failed.""" + apt_pkg.AcquireProgress.fail(self, item) if item.owner.status == item.owner.stat_done: self._write(_("Ign ") + item.description) else: @@ -131,6 +134,7 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): def fetch(self, item): """Called when some of the item's data is fetched.""" + apt_pkg.AcquireProgress.fetch(self, item) # It's complete already (e.g. Hit) if item.owner.complete: return @@ -146,7 +150,7 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): """Periodically invoked while the Acquire process is underway. Return False if the user asked to cancel the whole Acquire process.""" - + apt_pkg.AcquireProgress.pulse(self, owner) percent = (((self.current_bytes + self.current_items) * 100.0) / float(self.total_bytes + self.total_items)) @@ -206,6 +210,7 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): def media_change(self, medium, drive): """Prompt the user to change the inserted removable media.""" + apt_pkg.AcquireProgress.media_change(self, medium, drive) self._write(_("Media change: please insert the disc labeled\n" " '%s'\n" "in the drive '%s' and press enter\n") % (medium, drive)) @@ -213,6 +218,7 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): def stop(self): """Invoked when the Acquire process stops running.""" + apt_pkg.AcquireProgress.stop(self) # Trick for getting a translation from apt self._write((_("Fetched %sB in %s (%sB/s)\n") % ( apt_pkg.size_to_str(self.fetched_bytes), @@ -229,6 +235,7 @@ class CdromProgress(apt_pkg.CdromProgress, TextProgress): def ask_cdrom_name(self): """Ask the user to provide a name for the disc.""" + apt_pkg.CdromProgress.ask_cdrom_name(self) self._write(_("Please provide a name for this Disc, such as " "'Debian 2.1r1 Disk 1'"), False) try: @@ -238,11 +245,13 @@ class CdromProgress(apt_pkg.CdromProgress, TextProgress): def update(self, text, current): """Set the current progress.""" + apt_pkg.CdromProgress.change_cdrom(self, text, current) if text: self._write(text, False) def change_cdrom(self): """Ask the user to change the CD-ROM.""" + apt_pkg.CdromProgress.change_cdrom(self) self._write(_("Please insert a Disc in the drive and press enter"), False) try: -- cgit v1.2.3 From e784c6d89265337decb35cd587e4281228d625f0 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 21 Jul 2009 21:55:02 +0200 Subject: apt/progress/old.py: Replace OpProgress.sub_op with OpProgress.subop. --- apt/progress/old.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'apt') diff --git a/apt/progress/old.py b/apt/progress/old.py index 63fc5d2e..05597481 100644 --- a/apt/progress/old.py +++ b/apt/progress/old.py @@ -47,7 +47,7 @@ class OpProgress(object): def __init__(self): self.op = None - self.sub_op = None + self.subop = None def update(self, percent): """Called periodically to update the user interface.""" @@ -56,7 +56,7 @@ class OpProgress(object): """Called once an operation has been completed.""" if apt_pkg._COMPAT_0_7: - subOp = AttributeDeprecatedBy('sub_op') + subOp = AttributeDeprecatedBy('subop') class OpTextProgress(OpProgress): @@ -67,7 +67,7 @@ class OpTextProgress(OpProgress): def update(self, percent): """Called periodically to update the user interface.""" - sys.stdout.write("\r%s: %.2i " % (self.sub_op, percent)) + sys.stdout.write("\r%s: %.2i " % (self.subop, percent)) sys.stdout.flush() def done(self): -- cgit v1.2.3 From 1195d1d5b3b9c22d1756ba13780cb553c3d4d168 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Thu, 23 Jul 2009 16:47:13 +0200 Subject: python/cdrom.cc: Do not check arguments in PkgCdromNew. --- apt/progress/text.py | 2 +- python/cdrom.cc | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) (limited to 'apt') diff --git a/apt/progress/text.py b/apt/progress/text.py index a121eaaa..c9e2882b 100644 --- a/apt/progress/text.py +++ b/apt/progress/text.py @@ -245,7 +245,7 @@ class CdromProgress(apt_pkg.CdromProgress, TextProgress): def update(self, text, current): """Set the current progress.""" - apt_pkg.CdromProgress.change_cdrom(self, text, current) + apt_pkg.CdromProgress.update(self, text, current) if text: self._write(text, False) diff --git a/python/cdrom.cc b/python/cdrom.cc index bd181af7..5044f3fa 100644 --- a/python/cdrom.cc +++ b/python/cdrom.cc @@ -91,10 +91,6 @@ static PyObject *PkgCdromNew(PyTypeObject *type,PyObject *Args,PyObject *kwds) { pkgCdrom *cdrom = new pkgCdrom(); - char *kwlist[] = {NULL}; - if (PyArg_ParseTupleAndKeywords(Args,kwds,"",kwlist) == 0) - return 0; - CppOwnedPyObject *CdromObj = CppOwnedPyObject_NEW(0,type, *cdrom); -- cgit v1.2.3 From dd85685eb9c2a3ce4392b581818d4ac84410f296 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 31 Jul 2009 15:02:12 +0200 Subject: apt/progress/base.py: Introduce new base progress classes. Also adjust the class in apt/progress/text.py to derive from this instead of the classes in apt_pkg (which will be dropped). --- apt/progress/base.py | 164 +++++++++++++++++++++++++++++++++++++++++++++++++++ apt/progress/text.py | 39 ++++++------ 2 files changed, 183 insertions(+), 20 deletions(-) create mode 100644 apt/progress/base.py (limited to 'apt') diff --git a/apt/progress/base.py b/apt/progress/base.py new file mode 100644 index 00000000..fc5a8107 --- /dev/null +++ b/apt/progress/base.py @@ -0,0 +1,164 @@ +# apt/progress/base.py - Base classes for progress reporting. +# +# Copyright (C) 2009 Julian Andres Klode +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA +"""Base classes for progress reporting. + +Custom progress classes should inherit from these classes. They can also be +used as dummy progress classes which simply do nothing. +""" + + +class AcquireProgress(object): + """Monitor object for downloads controlled by the Acquire class. + + This is an mostly abstract class. You should subclass it and implement the + methods to get something useful. + """ + + current_bytes = current_cps = fetched_bytes = last_bytes = total_bytes \ + = 0.0 + current_items = elapsed_time = total_items = 0 + + def done(self, item): + """Invoked when an item is successfully and completely fetched.""" + + def fail(self, item): + """Invoked when an item could not be fetched.""" + + def fetch(self, item): + """Invoked when some of the item's data is fetched.""" + + def ims_hit(self, item): + """Invoked when an item is confirmed to be up-to-date. + + Invoked when an item is confirmed to be up-to-date. For instance, + when an HTTP download is informed that the file on the server was + not modified. + """ + + def media_change(self, media, drive): + """Prompt the user to change the inserted removable media. + + The parameter 'media' decribes the name of the the media type that + should be changed, whereas the parameter 'drive' should be the + identifying name of the drive whose media should be changed. + + This method should not return until the user has confirmed to the user + interface that the media change is complete. It must return True if + the user confirms the media change, or False to cancel it. + """ + return False + + def pulse(self, owner): + """Periodically invoked while the Acquire process is underway. + + This method gets invoked while the Acquire progress given by the + parameter 'owner' is underway. It should display information about + the current state. + + This function returns a boolean value indicating whether the + acquisition should be continued (True) or cancelled (False). + """ + return True + + def start(self): + """Invoked when the Acquire process starts running.""" + # Reset all our values. + self.current_bytes = 0.0 + self.current_cps = 0.0 + self.current_items = 0 + self.elapsed_time = 0 + self.fetched_bytes = 0.0 + self.last_bytes = 0.0 + self.total_bytes = 0.0 + self.total_items = 0 + + def stop(self): + """Invoked when the Acquire process stops running.""" + + +class CdromProgress(object): + """Base class for reporting the progress of adding a cdrom. + + Can be used with apt_pkg.Cdrom to produce an utility like apt-cdrom. The + attribute 'total_steps' defines the total number of steps and can be used + in update() to display the current progress. + """ + + total_steps = 0 + + def ask_cdrom_name(self): + """Ask for the name of the cdrom. + + If a name has been provided, return it. Otherwise, return None to + cancel the operation. + """ + + def change_cdrom(self): + """Ask for the CD-ROM to be changed. + + Return True once the cdrom has been changed or False to cancel the + operation. + """ + + def update(self, text, current): + """Periodically invoked to update the interface. + + The string 'text' defines the text which should be displayed. The + integer 'current' defines the number of completed steps. + """ + + +class InstallProgress(object): + """Report the install progress. + + Subclass this class to implement install progress reporting. + """ + + def start_update(self): + """Start update.""" + + def run(self, pm): + """Start installation.""" + return pm.do_install() + + def finish_update(self): + """Called when update has finished.""" + + def update_interface(self): + """Called periodically to update the user interface.""" + + +class OpProgress(object): + """Monitor objects for operations. + + Display the progress of operations such as opening the cache.""" + + major_change, op, percent, subop = False, "", 0.0, "" + + def update(self, percent=None): + """Called periodically to update the user interface. + + You may use the optional argument 'percent' to set the attribute + 'percent' in this call. + """ + if percent is not None: + self.percent = percent + + def done(self): + """Called once an operation has been completed.""" diff --git a/apt/progress/text.py b/apt/progress/text.py index c9e2882b..54a35704 100644 --- a/apt/progress/text.py +++ b/apt/progress/text.py @@ -18,8 +18,9 @@ import sys import apt_pkg +import apt.progress.base -__all__ = ['AcquireProgress', 'OpProgress'] +__all__ = ['AcquireProgress', 'CdromProgress', 'OpProgress'] def _(msg): @@ -54,7 +55,7 @@ class TextProgress(object): self._file.flush() -class OpProgress(apt_pkg.OpProgress, TextProgress): +class OpProgress(apt.progress.base.OpProgress, TextProgress): """Operation progress reporting. This closely resembles OpTextProgress in libapt-pkg. @@ -62,14 +63,12 @@ class OpProgress(apt_pkg.OpProgress, TextProgress): def __init__(self, outfile=None): TextProgress.__init__(self, outfile) - apt_pkg.OpProgress.__init__(self) + apt.progress.base.OpProgress.__init__(self) self.old_op = "" def update(self, percent=None): """Called periodically to update the user interface.""" - if percent: - self.percent = percent - apt_pkg.OpProgress.update(self) + apt.progress.base.OpProgress.update(self, percent) if self.major_change and self.old_op: self._write(self.old_op) self._write("%s... %i%%\r" % (self.op, self.percent), False, True) @@ -77,18 +76,18 @@ class OpProgress(apt_pkg.OpProgress, TextProgress): def done(self): """Called once an operation has been completed.""" - apt_pkg.OpProgress.done(self) + apt.progress.base.OpProgress.done(self) if self.old_op: self._write(_("%c%s... Done") % ('\r', self.old_op), True, True) self.old_op = "" -class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): +class AcquireProgress(apt.progress.base.AcquireProgress, TextProgress): """AcquireProgress for the text interface.""" def __init__(self, outfile=None): TextProgress.__init__(self, outfile) - apt_pkg.AcquireProgress.__init__(self) + apt.progress.base.AcquireProgress.__init__(self) self._signal = None self._width = 80 self._id = 1 @@ -99,7 +98,7 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): In this case, the function sets up a signal handler for SIGWINCH, i.e. window resize signals. And it also sets id to 1. """ - apt_pkg.AcquireProgress.start(self) + apt.progress.base.AcquireProgress.start(self) import signal self._signal = signal.signal(signal.SIGWINCH, self._winch) # Get the window size. @@ -117,7 +116,7 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): def ims_hit(self, item): """Called when an item is update (e.g. not modified on the server).""" - apt_pkg.AcquireProgress.ims_hit(self, item) + apt.progress.base.AcquireProgress.ims_hit(self, item) line = _('Hit ') + item.description if item.owner.filesize: line += ' [%sB]' % apt_pkg.size_to_str(item.owner.filesize) @@ -125,7 +124,7 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): def fail(self, item): """Called when an item is failed.""" - apt_pkg.AcquireProgress.fail(self, item) + apt.progress.base.AcquireProgress.fail(self, item) if item.owner.status == item.owner.stat_done: self._write(_("Ign ") + item.description) else: @@ -134,7 +133,7 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): def fetch(self, item): """Called when some of the item's data is fetched.""" - apt_pkg.AcquireProgress.fetch(self, item) + apt.progress.base.AcquireProgress.fetch(self, item) # It's complete already (e.g. Hit) if item.owner.complete: return @@ -150,7 +149,7 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): """Periodically invoked while the Acquire process is underway. Return False if the user asked to cancel the whole Acquire process.""" - apt_pkg.AcquireProgress.pulse(self, owner) + apt.progress.base.AcquireProgress.pulse(self, owner) percent = (((self.current_bytes + self.current_items) * 100.0) / float(self.total_bytes + self.total_items)) @@ -210,7 +209,7 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): def media_change(self, medium, drive): """Prompt the user to change the inserted removable media.""" - apt_pkg.AcquireProgress.media_change(self, medium, drive) + apt.progress.base.AcquireProgress.media_change(self, medium, drive) self._write(_("Media change: please insert the disc labeled\n" " '%s'\n" "in the drive '%s' and press enter\n") % (medium, drive)) @@ -218,7 +217,7 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): def stop(self): """Invoked when the Acquire process stops running.""" - apt_pkg.AcquireProgress.stop(self) + apt.progress.base.AcquireProgress.stop(self) # Trick for getting a translation from apt self._write((_("Fetched %sB in %s (%sB/s)\n") % ( apt_pkg.size_to_str(self.fetched_bytes), @@ -230,12 +229,12 @@ class AcquireProgress(apt_pkg.AcquireProgress, TextProgress): signal.signal(signal.SIGWINCH, self._signal) -class CdromProgress(apt_pkg.CdromProgress, TextProgress): +class CdromProgress(apt.progress.base.CdromProgress, TextProgress): """Text CD-ROM progress.""" def ask_cdrom_name(self): """Ask the user to provide a name for the disc.""" - apt_pkg.CdromProgress.ask_cdrom_name(self) + apt.progress.base.CdromProgress.ask_cdrom_name(self) self._write(_("Please provide a name for this Disc, such as " "'Debian 2.1r1 Disk 1'"), False) try: @@ -245,13 +244,13 @@ class CdromProgress(apt_pkg.CdromProgress, TextProgress): def update(self, text, current): """Set the current progress.""" - apt_pkg.CdromProgress.update(self, text, current) + apt.progress.base.CdromProgress.update(self, text, current) if text: self._write(text, False) def change_cdrom(self): """Ask the user to change the CD-ROM.""" - apt_pkg.CdromProgress.change_cdrom(self) + apt.progress.base.CdromProgress.change_cdrom(self) self._write(_("Please insert a Disc in the drive and press enter"), False) try: -- cgit v1.2.3 From fb8e639a7199a5707ae24c8424e5dc748fe0be37 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 31 Jul 2009 15:24:09 +0200 Subject: python: Remove the progress classes in apt_pkg. They have been replaced with apt.progress.base, so stuff like GTK+ or Qt progress classes can be written using subclassing. --- apt/cache.py | 6 +- apt/cdrom.py | 3 +- apt/progress/old.py | 28 +++---- apt/progress/text.py | 36 ++++---- python/acquireprogress.cc | 208 ---------------------------------------------- python/apt_pkgmodule.cc | 3 - python/apt_pkgmodule.h | 3 - python/cache.cc | 6 -- python/cdrom.cc | 3 +- python/cdromprogress.cc | 106 ----------------------- python/opprogress.cc | 175 -------------------------------------- python/progress.h | 32 ------- setup.py | 5 +- 13 files changed, 36 insertions(+), 578 deletions(-) delete mode 100644 python/acquireprogress.cc delete mode 100644 python/cdromprogress.cc delete mode 100644 python/opprogress.cc (limited to 'apt') diff --git a/apt/cache.py b/apt/cache.py index f507863c..ae4254e0 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -122,11 +122,7 @@ class Cache(object): size=len(self._cache.packages) for pkg in self._cache.packages: if progress is not None and last+100 < i: - if isinstance(progress, apt_pkg.OpProgress): - progress.percent = i/float(size)*100 - progress.update() - else: - progress.update(i/float(size)*100) + progress.update(i/float(size)*100) last=i # drop stuff with no versions (cruft) if len(pkg.version_list) > 0: diff --git a/apt/cdrom.py b/apt/cdrom.py index 126c54dd..01caa12f 100644 --- a/apt/cdrom.py +++ b/apt/cdrom.py @@ -24,6 +24,7 @@ import glob import apt_pkg from apt.deprecation import AttributeDeprecatedBy +from apt.progress.base import CdromProgress class Cdrom(apt_pkg.Cdrom): @@ -46,7 +47,7 @@ class Cdrom(apt_pkg.Cdrom): def __init__(self, progress=None, mountpoint=None, nomount=True): apt_pkg.Cdrom.__init__(self) if progress is None: - self._progress = apt_pkg.CdromProgress() + self._progress = CdromProgress() else: self._progress = progress # see if we have a alternative mountpoint diff --git a/apt/progress/old.py b/apt/progress/old.py index 88957272..adaf94b2 100644 --- a/apt/progress/old.py +++ b/apt/progress/old.py @@ -34,29 +34,21 @@ import sys import apt_pkg from apt.deprecation import AttributeDeprecatedBy, function_deprecated_by +from apt.progress import base __all__ = [] -class OpProgress(object): +class OpProgress(base.OpProgress): """Abstract class to implement reporting on cache opening. Subclass this class to implement simple Operation progress reporting. """ - def __init__(self): - self.op = None - self.subop = None - - def update(self, percent): - """Called periodically to update the user interface.""" - - def done(self): - """Called once an operation has been completed.""" - if apt_pkg._COMPAT_0_7: subOp = AttributeDeprecatedBy('subop') + Op = AttributeDeprecatedBy('op') class OpTextProgress(OpProgress): @@ -65,13 +57,15 @@ class OpTextProgress(OpProgress): def __init__(self): OpProgress.__init__(self) - def update(self, percent): + def update(self, percent=None): """Called periodically to update the user interface.""" - sys.stdout.write("\r%s: %.2i " % (self.subop, percent)) + OpProgress.update(self, percent) + sys.stdout.write("\r%s: %.2i " % (self.subop, self.percent)) sys.stdout.flush() def done(self): """Called once an operation has been completed.""" + OpProgress.done(self) sys.stdout.write("\r%s: Done\n" % self.op) @@ -349,13 +343,15 @@ class InstallProgress(DumbInstallProgress): updateInterface = function_deprecated_by(update_interface) -class CdromProgress(apt_pkg.CdromProgress): +class CdromProgress(base.CdromProgress): """Report the cdrom add progress. This class has been replaced by apt_pkg.CdromProgress. """ - askCdromName = function_deprecated_by(apt_pkg.CdromProgress.ask_cdrom_name) - changeCdrom = function_deprecated_by(apt_pkg.CdromProgress.change_cdrom) + _basetype = base.CdromProgress + askCdromName = function_deprecated_by(_basetype.ask_cdrom_name) + changeCdrom = function_deprecated_by(_basetype.change_cdrom) + del _basetype class DpkgInstallProgress(InstallProgress): diff --git a/apt/progress/text.py b/apt/progress/text.py index 54a35704..eb474d6d 100644 --- a/apt/progress/text.py +++ b/apt/progress/text.py @@ -18,7 +18,7 @@ import sys import apt_pkg -import apt.progress.base +from apt.progress import base __all__ = ['AcquireProgress', 'CdromProgress', 'OpProgress'] @@ -55,7 +55,7 @@ class TextProgress(object): self._file.flush() -class OpProgress(apt.progress.base.OpProgress, TextProgress): +class OpProgress(base.OpProgress, TextProgress): """Operation progress reporting. This closely resembles OpTextProgress in libapt-pkg. @@ -63,12 +63,12 @@ class OpProgress(apt.progress.base.OpProgress, TextProgress): def __init__(self, outfile=None): TextProgress.__init__(self, outfile) - apt.progress.base.OpProgress.__init__(self) + base.OpProgress.__init__(self) self.old_op = "" def update(self, percent=None): """Called periodically to update the user interface.""" - apt.progress.base.OpProgress.update(self, percent) + base.OpProgress.update(self, percent) if self.major_change and self.old_op: self._write(self.old_op) self._write("%s... %i%%\r" % (self.op, self.percent), False, True) @@ -76,18 +76,18 @@ class OpProgress(apt.progress.base.OpProgress, TextProgress): def done(self): """Called once an operation has been completed.""" - apt.progress.base.OpProgress.done(self) + base.OpProgress.done(self) if self.old_op: self._write(_("%c%s... Done") % ('\r', self.old_op), True, True) self.old_op = "" -class AcquireProgress(apt.progress.base.AcquireProgress, TextProgress): +class AcquireProgress(base.AcquireProgress, TextProgress): """AcquireProgress for the text interface.""" def __init__(self, outfile=None): TextProgress.__init__(self, outfile) - apt.progress.base.AcquireProgress.__init__(self) + base.AcquireProgress.__init__(self) self._signal = None self._width = 80 self._id = 1 @@ -98,7 +98,7 @@ class AcquireProgress(apt.progress.base.AcquireProgress, TextProgress): In this case, the function sets up a signal handler for SIGWINCH, i.e. window resize signals. And it also sets id to 1. """ - apt.progress.base.AcquireProgress.start(self) + base.AcquireProgress.start(self) import signal self._signal = signal.signal(signal.SIGWINCH, self._winch) # Get the window size. @@ -116,7 +116,7 @@ class AcquireProgress(apt.progress.base.AcquireProgress, TextProgress): def ims_hit(self, item): """Called when an item is update (e.g. not modified on the server).""" - apt.progress.base.AcquireProgress.ims_hit(self, item) + base.AcquireProgress.ims_hit(self, item) line = _('Hit ') + item.description if item.owner.filesize: line += ' [%sB]' % apt_pkg.size_to_str(item.owner.filesize) @@ -124,7 +124,7 @@ class AcquireProgress(apt.progress.base.AcquireProgress, TextProgress): def fail(self, item): """Called when an item is failed.""" - apt.progress.base.AcquireProgress.fail(self, item) + base.AcquireProgress.fail(self, item) if item.owner.status == item.owner.stat_done: self._write(_("Ign ") + item.description) else: @@ -133,7 +133,7 @@ class AcquireProgress(apt.progress.base.AcquireProgress, TextProgress): def fetch(self, item): """Called when some of the item's data is fetched.""" - apt.progress.base.AcquireProgress.fetch(self, item) + base.AcquireProgress.fetch(self, item) # It's complete already (e.g. Hit) if item.owner.complete: return @@ -149,7 +149,7 @@ class AcquireProgress(apt.progress.base.AcquireProgress, TextProgress): """Periodically invoked while the Acquire process is underway. Return False if the user asked to cancel the whole Acquire process.""" - apt.progress.base.AcquireProgress.pulse(self, owner) + base.AcquireProgress.pulse(self, owner) percent = (((self.current_bytes + self.current_items) * 100.0) / float(self.total_bytes + self.total_items)) @@ -209,7 +209,7 @@ class AcquireProgress(apt.progress.base.AcquireProgress, TextProgress): def media_change(self, medium, drive): """Prompt the user to change the inserted removable media.""" - apt.progress.base.AcquireProgress.media_change(self, medium, drive) + base.AcquireProgress.media_change(self, medium, drive) self._write(_("Media change: please insert the disc labeled\n" " '%s'\n" "in the drive '%s' and press enter\n") % (medium, drive)) @@ -217,7 +217,7 @@ class AcquireProgress(apt.progress.base.AcquireProgress, TextProgress): def stop(self): """Invoked when the Acquire process stops running.""" - apt.progress.base.AcquireProgress.stop(self) + base.AcquireProgress.stop(self) # Trick for getting a translation from apt self._write((_("Fetched %sB in %s (%sB/s)\n") % ( apt_pkg.size_to_str(self.fetched_bytes), @@ -229,12 +229,12 @@ class AcquireProgress(apt.progress.base.AcquireProgress, TextProgress): signal.signal(signal.SIGWINCH, self._signal) -class CdromProgress(apt.progress.base.CdromProgress, TextProgress): +class CdromProgress(base.CdromProgress, TextProgress): """Text CD-ROM progress.""" def ask_cdrom_name(self): """Ask the user to provide a name for the disc.""" - apt.progress.base.CdromProgress.ask_cdrom_name(self) + base.CdromProgress.ask_cdrom_name(self) self._write(_("Please provide a name for this Disc, such as " "'Debian 2.1r1 Disk 1'"), False) try: @@ -244,13 +244,13 @@ class CdromProgress(apt.progress.base.CdromProgress, TextProgress): def update(self, text, current): """Set the current progress.""" - apt.progress.base.CdromProgress.update(self, text, current) + base.CdromProgress.update(self, text, current) if text: self._write(text, False) def change_cdrom(self): """Ask the user to change the CD-ROM.""" - apt.progress.base.CdromProgress.change_cdrom(self) + base.CdromProgress.change_cdrom(self) self._write(_("Please insert a Disc in the drive and press enter"), False) try: diff --git a/python/acquireprogress.cc b/python/acquireprogress.cc deleted file mode 100644 index c7db8921..00000000 --- a/python/acquireprogress.cc +++ /dev/null @@ -1,208 +0,0 @@ -/* acquireprogress.cc - Base class for FetchProgress classes. - * - * Copyright 2009 Julian Andres Klode - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -#include "apt_pkgmodule.h" -#include "progress.h" -#include -#include - - - -// DUMMY IMPLEMENTATIONS. -static char *acquireprogress_media_change_doc = - "media_change(media: str, drive: str) -> bool\n\n" - "Invoked when the user should be prompted to change the inserted\n" - "removable media.\n\n" - "This method should not return until the user has confirmed to the user\n" - "interface that the media change is complete.\n\n" - ":param:media The name of the media type that should be changed.\n" - ":param:drive The identifying name of the drive whose media should be\n" - " changed.\n\n" - "Return True if the user confirms the media change, False if it is\n" - "cancelled."; -static PyObject *acquireprogress_media_change(PyObject *self, PyObject *args) -{ - Py_RETURN_FALSE; -} - -static char *acquireprogress_ims_hit_doc = "ims_hit(item: AcquireItemDesc)\n\n" - "Invoked when an item is confirmed to be up-to-date. For instance,\n" - "when an HTTP download is informed that the file on the server was\n" - "not modified."; -static PyObject *acquireprogress_ims_hit(PyObject *self, PyObject *arg) -{ - if (!PyAcquireItemDesc_Check(arg)) { - PyErr_SetString(PyExc_TypeError, "ims_hit() argument must be " - "apt_pkg.AcquireItemDesc"); - return 0; - } - Py_RETURN_NONE; -} - -static char *acquireprogress_fetch_doc = "fetch(item: AcquireItemDesc)\n\n" - "Invoked when some of an item's data is fetched."; -static PyObject *acquireprogress_fetch(PyObject *self, PyObject *arg) -{ - if (!PyAcquireItemDesc_Check(arg)) { - PyErr_SetString(PyExc_TypeError, "fetch() argument must be " - "apt_pkg.AcquireItemDesc"); - return 0; - } - Py_RETURN_NONE; -} - -static char *acquireprogress_done_doc = "done(item: AcquireItemDesc)\n\n" - "Invoked when an item is successfully and completely fetched."; -static PyObject *acquireprogress_done(PyObject *self, PyObject *arg) -{ - if (!PyAcquireItemDesc_Check(arg)) { - PyErr_SetString(PyExc_TypeError, "done() argument must be " - "apt_pkg.AcquireItemDesc"); - return 0; - } - Py_RETURN_NONE; -} - -static char *acquireprogress_fail_doc = "fail(item: AcquireItemDesc)\n\n" - "Invoked when the process of fetching an item encounters a fatal error."; -static PyObject *acquireprogress_fail(PyObject *self, PyObject *arg) -{ - if (!PyAcquireItemDesc_Check(arg)) { - PyErr_SetString(PyExc_TypeError, "fail() argument must be " - "apt_pkg.AcquireItemDesc"); - return 0; - } - Py_RETURN_NONE; -} - -static char *acquireprogress_pulse_doc = "pulse(owner: Acquire) -> bool\n\n" - "Periodically invoked while the Acquire process is underway.\n\n" - "Return False if the user asked to cancel the whole Acquire process."; -static PyObject *acquireprogress_pulse(PyObject *self, PyObject *arg) -{ - if (!PyAcquire_Check(arg)) { - PyErr_SetString(PyExc_TypeError, "pulse() argument must be " - "apt_pkg.Acquire"); - return 0; - } - Py_RETURN_TRUE; -} - -static char *acquireprogress_start_doc = "start()\n\n" - "Invoked when the Acquire process starts running."; -static PyObject *acquireprogress_start(PyObject *self, PyObject *args) -{ - Py_RETURN_NONE; -} - -static char *acquireprogress_stop_doc = "stop()\n\n" - "Invoked when the Acquire process stops running."; -static PyObject *acquireprogress_stop(PyObject *self, PyObject *args) -{ - Py_RETURN_NONE; -} - -static PyMethodDef acquireprogress_methods[] = { - {"media_change", acquireprogress_media_change, METH_VARARGS, - acquireprogress_media_change_doc}, - {"ims_hit",acquireprogress_ims_hit,METH_O, - acquireprogress_ims_hit_doc}, - {"fetch",acquireprogress_fetch,METH_O,acquireprogress_fetch_doc}, - {"done",acquireprogress_done,METH_O,acquireprogress_done_doc}, - {"fail",acquireprogress_fail,METH_O,acquireprogress_fail_doc}, - {"pulse",acquireprogress_pulse,METH_O,acquireprogress_pulse_doc}, - {"start",acquireprogress_start,METH_NOARGS,acquireprogress_start_doc}, - {"stop",acquireprogress_stop,METH_NOARGS,acquireprogress_stop_doc}, - {NULL} -}; - -static PyMemberDef acquireprogress_members[] = { - {"last_bytes", T_DOUBLE, offsetof(PyAcquireProgressObject, last_bytes), 0, - "The number of bytes fetched as of the previous call to pulse(),\n" - "including local items."}, - {"current_cps", T_DOUBLE, offsetof(PyAcquireProgressObject, current_cps), 0, - "The current rate of download, in bytes per second."}, - {"current_bytes", T_DOUBLE, offsetof(PyAcquireProgressObject, current_bytes), - 0, "The number of bytes fetched."}, - {"total_bytes", T_DOUBLE, offsetof(PyAcquireProgressObject, total_bytes), 0, - "The total number of bytes that need to be fetched. This member is\n" - "inaccurate, as new items might be enqueued while the download is\n" - "in progress!"}, - {"fetched_bytes", T_DOUBLE,offsetof(PyAcquireProgressObject, fetched_bytes), - 0, "The total number of bytes accounted for by items that were\n" - "successfully fetched."}, - {"elapsed_time", T_ULONG, offsetof(PyAcquireProgressObject, elapsed_time),0, - "The amount of time that has elapsed since the download started."}, - {"total_items", T_ULONG, offsetof(PyAcquireProgressObject, total_items),0, - "The total number of items that need to be fetched. This member is\n" - "inaccurate, as new items might be enqueued while the download is\n" - "in progress!"}, - {"current_items", T_ULONG, offsetof(PyAcquireProgressObject, current_items), - 0, "The number of items that have been successfully downloaded."}, - {NULL} -}; - -static char *acquireprogress_doc = "AcquireProgress()\n\n" - "A monitor object for downloads controlled by the Acquire class. This is\n" - "an mostly abstract class. You should subclass it and implement the\n" - "methods to get something useful."; - -PyTypeObject PyAcquireProgress_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "apt_pkg.AcquireProgress", // tp_name - sizeof(PyAcquireProgressObject), // tp_basicsize - 0, // tp_itemsize - // Methods - 0, // tp_dealloc - 0, // tp_print - 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_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT | // tp_flags - Py_TPFLAGS_BASETYPE, - acquireprogress_doc, // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - acquireprogress_methods, // tp_methods - acquireprogress_members, // tp_members - 0, // tp_getset - 0, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set - 0, // tp_dictoffset - 0, // tp_init - 0, // tp_alloc - PyType_GenericNew, // tp_new -}; diff --git a/python/apt_pkgmodule.cc b/python/apt_pkgmodule.cc index d53f64a6..faea423f 100644 --- a/python/apt_pkgmodule.cc +++ b/python/apt_pkgmodule.cc @@ -653,10 +653,7 @@ extern "C" void initapt_pkg() ADDTYPE(Module,"HashString",&PyHashString_Type); ADDTYPE(Module,"Policy",&PyPolicy_Type); ADDTYPE(Module,"Hashes",&PyHashes_Type); - ADDTYPE(Module,"OpProgress",&PyOpProgress_Type); - ADDTYPE(Module,"AcquireProgress",&PyAcquireProgress_Type); ADDTYPE(Module,"AcquireItemDesc",&PyAcquireItemDesc_Type); - ADDTYPE(Module,"CdromProgress",&PyCdromProgress_Type); ADDTYPE(Module,"SystemLock",&PySystemLock_Type); ADDTYPE(Module,"FileLock",&PyFileLock_Type); // Tag file constants diff --git a/python/apt_pkgmodule.h b/python/apt_pkgmodule.h index 3edba5d2..97ba05a7 100644 --- a/python/apt_pkgmodule.h +++ b/python/apt_pkgmodule.h @@ -117,9 +117,6 @@ extern PyTypeObject PyIndexRecords_Type; // Policy extern PyTypeObject PyPolicy_Type; extern PyTypeObject PyHashes_Type; -extern PyTypeObject PyOpProgress_Type; -extern PyTypeObject PyAcquireProgress_Type; -extern PyTypeObject PyCdromProgress_Type; extern PyTypeObject PyAcquireItemDesc_Type; extern PyTypeObject PyAcquireWorker_Type; extern PyTypeObject PySystemLock_Type; diff --git a/python/cache.cc b/python/cache.cc index 68ee7b9e..593bc1c2 100644 --- a/python/cache.cc +++ b/python/cache.cc @@ -246,15 +246,9 @@ static PyObject *PkgCacheNew(PyTypeObject *type,PyObject *Args,PyObject *kwds) PyObject *pyCallbackInst = 0; char *kwlist[] = {"progress", 0}; - #ifdef COMPAT_0_7 if (PyArg_ParseTupleAndKeywords(Args, kwds, "|O", kwlist, &pyCallbackInst) == 0) return 0; - #else - if (PyArg_ParseTupleAndKeywords(Args, kwds, "|O!", kwlist, - &PyOpProgress_Type, &pyCallbackInst) == 0) - return 0; - #endif if (_system == 0) { PyErr_SetString(PyExc_ValueError,"_system not initialized"); diff --git a/python/cdrom.cc b/python/cdrom.cc index 2270b01c..4195c9cb 100644 --- a/python/cdrom.cc +++ b/python/cdrom.cc @@ -57,8 +57,7 @@ static PyObject *cdrom_ident(PyObject *Self,PyObject *Args) { pkgCdrom &Cdrom = GetCpp(Self); PyObject *pyCdromProgressInst = 0; - if (PyArg_ParseTuple(Args, "O!", &PyCdromProgress_Type, - &pyCdromProgressInst) == 0) { + if (PyArg_ParseTuple(Args, "O", &pyCdromProgressInst) == 0) { return 0; } diff --git a/python/cdromprogress.cc b/python/cdromprogress.cc deleted file mode 100644 index 440b5ce6..00000000 --- a/python/cdromprogress.cc +++ /dev/null @@ -1,106 +0,0 @@ -/* cdromprogress.cc - Base class for CdromProgress classes. - * - * Copyright 2009 Julian Andres Klode - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ -#include "apt_pkgmodule.h" -#include "progress.h" -#include -#include - -// Takes two arguments (string, int) -static PyObject *cdromprogress_update(PyObject *self, PyObject *args) -{ - Py_RETURN_NONE; -} - -// Takes no arguments -static PyObject *cdromprogress_change_cdrom(PyObject *self, PyObject *args) -{ - Py_RETURN_FALSE; -} - -// Takes a single PyObject argument as *arg -static PyObject *cdromprogress_ask_cdrom_name(PyObject *self, PyObject *arg) -{ - Py_RETURN_NONE; -} - -static PyMethodDef cdromprogress_methods[] = { - {"update",cdromprogress_update,METH_VARARGS, - "update(text: str, current: int)\n\nCalled regularly."}, - {"change_cdrom",cdromprogress_change_cdrom,METH_NOARGS, - "change_cdrom() -> bool\n\nAsk for the CD-ROM to be changed.\n" - "Return False if the user requested to cancel the action (default)."}, - {"ask_cdrom_name",cdromprogress_ask_cdrom_name,METH_O, - "ask_cdrom_name() -> str\n\nAsk for the name of the CD-ROM.\n" - "Return None if the user requested to cancel the action (default)."}, - {NULL} -}; - -static PyMemberDef cdromprogress_members[] = { - {"total_steps", T_INT, offsetof(PyCdromProgressObject,total_steps), 0, - "The number of total steps to be taken."}, - {NULL} -}; - -static char *cdromprogress_doc = "CdromProgress()\n\n" - "Base class for reporting the progress of adding a cdrom. Can be used\n" - "with apt_pkg.Cdrom to produce an utility like apt-cdrom."; - -PyTypeObject PyCdromProgress_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "apt_pkg.CdromProgress", // tp_name - sizeof(PyCdromProgressObject), // tp_basicsize - 0, // tp_itemsize - // Methods - 0, // tp_dealloc - 0, // tp_print - 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_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT | // tp_flags - Py_TPFLAGS_BASETYPE, - cdromprogress_doc, // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - cdromprogress_methods, // tp_methods - cdromprogress_members, // tp_members - 0, // tp_getset - 0, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set - 0, // tp_dictoffset - 0, // tp_init - 0, // tp_alloc - PyType_GenericNew, // tp_new -}; diff --git a/python/opprogress.cc b/python/opprogress.cc deleted file mode 100644 index 2ee6a03e..00000000 --- a/python/opprogress.cc +++ /dev/null @@ -1,175 +0,0 @@ -/* op-progress.cc - Base class for OpProgress classes. - * - * Copyright 2009 Julian Andres Klode - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -#include "generic.h" -#include "progress.h" -#include -#include - - - -static PyObject *opprogress_update(PyObject *Self, PyObject *args) -{ - Py_RETURN_NONE; -} - -static PyObject *opprogress_done(PyObject *Self, PyObject *args) -{ - Py_RETURN_NONE; -} - -static PyObject *opprogress_get_op(PyOpProgressObject *self, void *closure) -{ - Py_INCREF(self->op); - return self->op; -} - -static int opprogress_set_op(PyOpProgressObject *self, PyObject *value, - void *closure) -{ - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, "Cannot delete 'op'"); - return -1; - } - if (!PyString_Check(value)) { - PyErr_SetString(PyExc_TypeError,"'op' must be a string."); - return -1; - } - Py_DECREF(self->op); - Py_INCREF(value); - - self->op = value; - return 0; -} - -static PyObject *opprogress_get_subop(PyOpProgressObject *self, void *closure) -{ - Py_INCREF(self->subop); - return self->subop; -} - -static int opprogress_set_subop(PyOpProgressObject *self, PyObject *value, - void *closure) -{ - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, "Cannot delete 'subop'."); - return -1; - } - if (!PyString_Check(value)) { - PyErr_SetString(PyExc_TypeError,"'subop' must be a string."); - return -1; - } - Py_DECREF(self->subop); - Py_INCREF(value); - self->subop = value; - return 0; -} - -static PyMethodDef opprogress_methods[] = { - {"update",opprogress_update,METH_NOARGS,"update()\n\nCalled periodically."}, - {"done",opprogress_done,METH_NOARGS,"update()\n\nCalled when done."}, - {NULL}, -}; - -#ifndef T_BOOL -# define _T_BOOL T_INT -#else -# define _T_BOOL T_BOOL -#endif -static PyMemberDef opprogress_members[] = { - {"major_change", _T_BOOL, offsetof(PyOpProgressObject, major_change), 0, - "Boolean value indicating whether the change is a major change."}, - {"percent", T_FLOAT, offsetof(PyOpProgressObject, percent), 0, - "Percentage of completion (float value)."}, - {NULL} -}; - -static PyGetSetDef opprogress_getset[] = { - {"op", (getter)opprogress_get_op, (setter)opprogress_set_op, - "Description of the current operation"}, - {"subop", (getter)opprogress_get_subop, (setter)opprogress_set_subop, - "Description of the current sub-operation"}, - {NULL}, -}; - -static void opprogress_dealloc(PyObject *self) -{ - Py_XDECREF(((PyOpProgressObject *)self)->op); - Py_XDECREF(((PyOpProgressObject *)self)->subop); - self->ob_type->tp_free(self); -} - -static PyObject *opprogress_new(PyTypeObject *type, PyObject *args, - PyObject *kwds) -{ - PyOpProgressObject *res = (PyOpProgressObject *)type->tp_alloc(type, 0); - res->op = PyString_FromString(""); - res->subop = PyString_FromString(""); - return (PyObject *)res; -} - -static char *opprogress_doc = "OpProgress()\n\n" - "A base class for writing custom operation progress classes. Subclasses\n" - "should override all the methods (and call the parent ones) but shall\n" - "not override any of the inherited descriptors because they may be\n" - "ignored."; - -PyTypeObject PyOpProgress_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "apt_pkg.OpProgress", // tp_name - sizeof(PyOpProgressObject), // tp_basicsize - 0, // tp_itemsize - // Methods - opprogress_dealloc, // tp_dealloc - 0, // tp_print - 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_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT | // tp_flags - Py_TPFLAGS_BASETYPE, - opprogress_doc, // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - opprogress_methods, // tp_methods - opprogress_members, // tp_members - opprogress_getset, // tp_getset - 0, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set - 0, // tp_dictoffset - 0, // tp_init - 0, // tp_alloc - opprogress_new, // tp_new -}; diff --git a/python/progress.h b/python/progress.h index bc1bd640..80cb2785 100644 --- a/python/progress.h +++ b/python/progress.h @@ -32,38 +32,6 @@ #define PyCbObj_BLOCK_THREADS Py_BLOCK_THREADS #define PyCbObj_UNBLOCK_THREADS Py_UNBLOCK_THREADS -typedef struct { - PyObject_HEAD - PyObject *op; - PyObject *subop; -#ifdef T_BOOL - char major_change; -#else - int major_change; -#endif - float percent; -} PyOpProgressObject; - - -typedef struct { - PyObject_HEAD - int total_steps; -} PyCdromProgressObject; - -typedef struct { - PyObject_HEAD - double last_bytes; - double current_cps; - double current_bytes; - double total_bytes; - double fetched_bytes; - unsigned long elapsed_time; - unsigned long total_items; - unsigned long current_items; -} PyAcquireProgressObject; - - - class PyCallbackObj { protected: PyObject *callbackInst; diff --git a/setup.py b/setup.py index 93fcb436..9b33ed5d 100644 --- a/setup.py +++ b/setup.py @@ -35,9 +35,8 @@ files = ['apt_pkgmodule.cc', 'acquire.cc', 'cache.cc', 'cdrom.cc', 'hashstring.cc', 'indexfile.cc', 'indexrecords.cc', 'metaindex.cc', 'pkgmanager.cc', 'pkgrecords.cc', 'pkgsrcrecords.cc', 'policy.cc', 'progress.cc', 'sourcelist.cc', 'string.cc', 'tag.cc', - 'opprogress.cc', 'acquireprogress.cc', 'cdromprogress.cc', 'lock.cc', - 'acquire-item.cc'] -files = sorted(['python/' + fname for fname in files]) + 'lock.cc', 'acquire-item.cc'] +files = sorted(['python/' + fname for fname in files], key=lambda s: s[:-3]) apt_pkg = Extension("apt_pkg", files, libraries=["apt-pkg"]) # The apt_inst module -- cgit v1.2.3 From bee2af041668dcd1e3d23197e275ffe3b3605a6f Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 31 Jul 2009 15:39:08 +0200 Subject: apt/progress/old.py: Derive some more old classes from new classes. OpTextProgress is now derived from text.OpProgress and DumbInstallProgress is derived from base.InstallProgress. --- apt/progress/old.py | 43 ++++++++++--------------------------------- 1 file changed, 10 insertions(+), 33 deletions(-) (limited to 'apt') diff --git a/apt/progress/old.py b/apt/progress/old.py index adaf94b2..6b6e21de 100644 --- a/apt/progress/old.py +++ b/apt/progress/old.py @@ -34,7 +34,7 @@ import sys import apt_pkg from apt.deprecation import AttributeDeprecatedBy, function_deprecated_by -from apt.progress import base +from apt.progress import base, text __all__ = [] @@ -51,22 +51,12 @@ class OpProgress(base.OpProgress): Op = AttributeDeprecatedBy('op') -class OpTextProgress(OpProgress): +class OpTextProgress(text.OpProgress): """A simple text based cache open reporting class.""" - def __init__(self): - OpProgress.__init__(self) - - def update(self, percent=None): - """Called periodically to update the user interface.""" - OpProgress.update(self, percent) - sys.stdout.write("\r%s: %.2i " % (self.subop, self.percent)) - sys.stdout.flush() - - def done(self): - """Called once an operation has been completed.""" - OpProgress.done(self) - sys.stdout.write("\r%s: Done\n" % self.op) + if apt_pkg._COMPAT_0_7: + subOp = AttributeDeprecatedBy('subop') + Op = AttributeDeprecatedBy('op') class FetchProgress(object): @@ -209,29 +199,16 @@ class TextFetchProgress(FetchProgress): mediaChange = function_deprecated_by(media_change) -class DumbInstallProgress(object): +class DumbInstallProgress(base.InstallProgress): """Report the install progress. Subclass this class to implement install progress reporting. """ - def start_update(self): - """Start update.""" - - def run(self, pm): - """Start installation.""" - return pm.do_install() - - def finish_update(self): - """Called when update has finished.""" - - def update_interface(self): - """Called periodically to update the user interface""" - - if apt_pkg._COMPAT_0_7: - startUpdate = function_deprecated_by(start_update) - finishUpdate = function_deprecated_by(finish_update) - updateInterface = function_deprecated_by(update_interface) + startUpdate = function_deprecated_by(base.InstallProgress.start_update) + finishUpdate = function_deprecated_by(base.InstallProgress.finish_update) + updateInterface = function_deprecated_by( + base.InstallProgress.update_interface) class InstallProgress(DumbInstallProgress): -- cgit v1.2.3 From d3832ab4faf69d8e8e0a0e14b159514505031231 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 31 Jul 2009 16:45:11 +0200 Subject: apt/progress/gtk2.py: Cleanup. --- apt/progress/gtk2.py | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) (limited to 'apt') diff --git a/apt/progress/gtk2.py b/apt/progress/gtk2.py index 066271c6..edba0a4d 100644 --- a/apt/progress/gtk2.py +++ b/apt/progress/gtk2.py @@ -36,10 +36,10 @@ import gobject import pango import vte -import apt.progress.old import apt_pkg from apt_pkg import gettext as _ -from apt.deprecation import function_deprecated_by +from apt.deprecation import function_deprecated_by, AttributeDeprecatedBy +from apt.progress import base, old def mksig(params=(), run=gobject.SIGNAL_RUN_FIRST, rettype=gobject.TYPE_NONE): @@ -53,7 +53,7 @@ def mksig(params=(), run=gobject.SIGNAL_RUN_FIRST, rettype=gobject.TYPE_NONE): return (run, rettype, params) -class GOpProgress(gobject.GObject, apt.progress.old.OpProgress): +class GOpProgress(gobject.GObject, base.OpProgress): """Operation progress with GObject signals. Signals: @@ -69,22 +69,28 @@ class GOpProgress(gobject.GObject, apt.progress.old.OpProgress): "status-finished": mksig()} def __init__(self): - apt.progress.old.OpProgress.__init__(self) + base.OpProgress.__init__(self) gobject.GObject.__init__(self) self._context = glib.main_context_default() - def update(self, percent): + def update(self, percent=None): """Called to update the percentage done""" - self.emit("status-changed", self.op, percent) + base.OpProgress.update(self, percent) + self.emit("status-changed", self.op, self.percent) while self._context.pending(): self._context.iteration() def done(self): """Called when all operation have finished.""" + base.OpProgress.done(self) self.emit("status-finished") + if apt_pkg._COMPAT_0_7: + subOp = AttributeDeprecatedBy('subop') + Op = AttributeDeprecatedBy('op') + -class GInstallProgress(gobject.GObject, apt.progress.old.InstallProgress): +class GInstallProgress(gobject.GObject, old.InstallProgress): """Installation progress with GObject signals. Signals: @@ -108,7 +114,7 @@ class GInstallProgress(gobject.GObject, apt.progress.old.InstallProgress): "status-finished": mksig()} def __init__(self, term): - apt.progress.old.InstallProgress.__init__(self) + old.InstallProgress.__init__(self) gobject.GObject.__init__(self) self.finished = False self.time_last_update = time.time() @@ -166,7 +172,7 @@ class GInstallProgress(gobject.GObject, apt.progress.old.InstallProgress): Emits: status-timeout() [When a timeout happens] """ - apt.progress.old.InstallProgress.update_interface(self) + old.InstallProgress.update_interface(self) while self._context.pending(): self._context.iteration() if self.time_last_update + self.INSTALL_TIMEOUT < time.time(): @@ -191,7 +197,7 @@ class GInstallProgress(gobject.GObject, apt.progress.old.InstallProgress): childExited = function_deprecated_by(child_exited) -class GDpkgInstallProgress(apt.progress.old.DpkgInstallProgress, +class GDpkgInstallProgress(old.DpkgInstallProgress, GInstallProgress): """An InstallProgress for local installations. @@ -207,13 +213,13 @@ class GDpkgInstallProgress(apt.progress.old.DpkgInstallProgress, def run(self, debfile): """Install the given package.""" - apt.progress.old.DpkgInstallProgress.run(self, debfile) + old.DpkgInstallProgress.run(self, debfile) def update_interface(self): """Called periodically to update the interface. Emits: status-timeout() [When a timeout happens]""" - apt.progress.old.DpkgInstallProgress.update_interface(self) + old.DpkgInstallProgress.update_interface(self) if self.time_last_update + self.INSTALL_TIMEOUT < time.time(): self.emit("status-timeout") @@ -221,7 +227,7 @@ class GDpkgInstallProgress(apt.progress.old.DpkgInstallProgress, updateInterface = function_deprecated_by(update_interface) -class GFetchProgress(gobject.GObject, apt.progress.old.FetchProgress): +class GFetchProgress(gobject.GObject, old.FetchProgress): """A Fetch Progress with GObject signals. Signals: @@ -236,7 +242,7 @@ class GFetchProgress(gobject.GObject, apt.progress.old.FetchProgress): "status-finished": mksig()} def __init__(self): - apt.progress.old.FetchProgress.__init__(self) + old.FetchProgress.__init__(self) gobject.GObject.__init__(self) self._continue = True self._context = glib.main_context_default() @@ -251,7 +257,7 @@ class GFetchProgress(gobject.GObject, apt.progress.old.FetchProgress): self._continue = False def pulse(self): - apt.progress.old.FetchProgress.pulse(self) + old.FetchProgress.pulse(self) current_item = self.current_items + 1 if current_item > self.total_items: current_item = self.total_items -- cgit v1.2.3 From e556b2cbbe5878c33d9e7302e637cc7f35dd14bf Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 31 Jul 2009 20:51:57 +0200 Subject: apt/progress: Large update, introducing apt.progress.base.InstallProgress. This contains many updates including the introduction of a new InstallProgress class which replaces the old InstallProgress and DpkgInstallProgress classes. --- apt/debfile.py | 2 +- apt/package.py | 2 +- apt/progress/__init__.py | 13 ++- apt/progress/base.py | 135 ++++++++++++++++++++-- apt/progress/gtk2.py | 82 +++++-------- apt/progress/old.py | 294 +++++++++-------------------------------------- apt/progress/text.py | 2 + 7 files changed, 225 insertions(+), 305 deletions(-) (limited to 'apt') diff --git a/apt/debfile.py b/apt/debfile.py index e05233f4..fd6c1532 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -417,7 +417,7 @@ class DebPackage(object): def install(self, install_progress=None): """Install the package.""" if install_progress is None: - return os.system("dpkg -i %s" % self.filename) + return os.spawnlp(os.P_WAIT, "dpkg", "dpkg", "-i", self.filename) else: try: install_progress.start_update() diff --git a/apt/package.py b/apt/package.py index f8e1354b..9a1b0d68 100644 --- a/apt/package.py +++ b/apt/package.py @@ -1180,7 +1180,7 @@ class Package(object): like apt.progress.text.AcquireProgress(). The parameter *iprogress* refers to an InstallProgress() object, as - found in apt.progress.old. + found in apt.progress.base. """ self._pcache._depcache.commit(fprogress, iprogress) diff --git a/apt/progress/__init__.py b/apt/progress/__init__.py index c75c368b..10c11021 100644 --- a/apt/progress/__init__.py +++ b/apt/progress/__init__.py @@ -1,3 +1,5 @@ +# apt/progress/__init__.py - Initialization file for apt.progress. +# # Copyright (c) 2009 Julian Andres Klode # # This program is free software; you can redistribute it and/or @@ -14,9 +16,18 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # USA -"""Progress reporting.""" +"""Progress reporting. + +This package provides progress reporting for the python-apt package. The module +'base' provides classes with no output, the module 'gtk2' provides classes for +GTK+ applications, and the module 'text' provides classes for terminals, etc. +""" import apt_pkg + +__all__ = [] + + if apt_pkg._COMPAT_0_7: from apt.progress.old import (CdromProgress, DpkgInstallProgress, DumbInstallProgress, FetchProgress, diff --git a/apt/progress/base.py b/apt/progress/base.py index fc5a8107..08d35533 100644 --- a/apt/progress/base.py +++ b/apt/progress/base.py @@ -21,6 +21,13 @@ Custom progress classes should inherit from these classes. They can also be used as dummy progress classes which simply do nothing. """ +import errno +import fcntl +import os +import re +import select + +__all__ = ['AcquireProgress', 'CdromProgress', 'InstallProgress', 'OpProgress'] class AcquireProgress(object): @@ -125,23 +132,131 @@ class CdromProgress(object): class InstallProgress(object): - """Report the install progress. + """Class to report the progress of installing packages.""" - Subclass this class to implement install progress reporting. - """ + percent, select_timeout, status = 0.0, 0.1, "" - def start_update(self): - """Start update.""" + def __init__(self): + (read, write) = os.pipe() + self.writefd = os.fdopen(write, "w") + self.statusfd = os.fdopen(read, "r") + fcntl.fcntl(self.statusfd, fcntl.F_SETFL, os.O_NONBLOCK) - def run(self, pm): - """Start installation.""" - return pm.do_install() + def start_update(self): + """(Abstract) Start update.""" def finish_update(self): - """Called when update has finished.""" + """(Abstract) Called when update has finished.""" + + def error(self, pkg, errormsg): + """(Abstract) Called when a error is detected during the install.""" + + def conffile(self, current, new): + """(Abstract) Called when a conffile question from dpkg is detected.""" + + def status_change(self, pkg, percent, status): + """(Abstract) Called when the status changed.""" + + def processing(self, pkg, stage): + """(Abstract) Sent just before a processing stage starts. + + The parameter 'stage' is one of "upgrade", "install" + (both sent before unpacking), "configure", "trigproc", "remove", + "purge". This method is used for dpkg only. + """ + + def run(self, obj): + """Install using the object 'obj'. + + This functions runs install actions. The parameter 'obj' may either + be a PackageManager object in which case its do_install() method is + called or the path to a deb file. + + If the object is a PackageManager, the functions returns the result + of calling its do_install() method. Otherwise, the function returns + the exit status of dpkg. In both cases, 0 means that there were no + problems. + """ + pid = self.fork() + if pid == 0: + try: + os._exit(obj.do_install(self.writefd.fileno())) + except AttributeError: + os._exit(os.spawnlp(os.P_WAIT, "dpkg", "dpkg", "--status-fd", + str(self.writefd.fileno()), "-i", obj)) + self.child_pid = pid + res = self.wait_child() + return os.WEXITSTATUS(res) + + def fork(self): + """Fork.""" + return os.fork() def update_interface(self): - """Called periodically to update the user interface.""" + """Update the interface.""" + try: + line = self.statusfd.readline() + except IOError, (errno_, errstr): + # resource temporarly unavailable is ignored + if errno_ != errno.EAGAIN and errno_ != errno.EWOULDBLOCK: + print errstr + return + + pkgname = status = status_str = percent = base = "" + + if line.startswith('pm'): + try: + (status, pkgname, percent, status_str) = line.split(":", 3) + except ValueError: + # silently ignore lines that can't be parsed + self.read = "" + return + elif line.startswith('status'): + try: + (base, pkgname, status, status_str) = line.split(": ", 3) + except ValueError: + (base, pkgname, status) = line.split(": ", 2) + elif line.startswith('processing'): + (status, status_str, pkgname) = line.split(": ", 2) + self.processing(pkgname.strip(), status_str.strip()) + + if status == 'pmerror' or status == 'error': + self.error(pkgname, status_str) + elif status == 'conffile-prompt' or status == 'pmconffile': + match = re.match("\s*\'(.*)\'\s*\'(.*)\'.*", status_str) + if match: + self.conffile(match.group(1), match.group(2)) + elif status == "pmstatus": + if float(percent) != self.percent or status_str != self.status: + self.status_change(pkgname, float(percent), status_str.strip()) + self.percent = float(percent) + self.status = status_str.strip() + + def wait_child(self): + """Wait for child progress to exit. + + This method is responsible for calling update_interface() from time to + time. It exits once the child has exited. + """ + (pid, res) = (0, 0) + while True: + try: + select.select([self.statusfd], [], [], self.select_timeout) + except select.error, err: + if err[0] != errno.EINTR: + raise + + self.update_interface() + try: + (pid, res) = os.waitpid(self.child_pid, os.WNOHANG) + if pid == self.child_pid: + break + except OSError, err: + if err[0] != errno.EINTR: + raise + if err[0] == errno.ECHILD: + break + return res class OpProgress(object): diff --git a/apt/progress/gtk2.py b/apt/progress/gtk2.py index edba0a4d..22788984 100644 --- a/apt/progress/gtk2.py +++ b/apt/progress/gtk2.py @@ -11,7 +11,7 @@ # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # -# his program is distributed in the hope that it will be useful, +# This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. @@ -42,6 +42,9 @@ from apt.deprecation import function_deprecated_by, AttributeDeprecatedBy from apt.progress import base, old +__all__ = ['GInstallProgress', 'GOpProgress', 'GtkAptProgress'] + + def mksig(params=(), run=gobject.SIGNAL_RUN_FIRST, rettype=gobject.TYPE_NONE): """Simplified Create a gobject signal. @@ -90,7 +93,7 @@ class GOpProgress(gobject.GObject, base.OpProgress): Op = AttributeDeprecatedBy('op') -class GInstallProgress(gobject.GObject, old.InstallProgress): +class GInstallProgress(gobject.GObject, base.InstallProgress): """Installation progress with GObject signals. Signals: @@ -114,7 +117,7 @@ class GInstallProgress(gobject.GObject, old.InstallProgress): "status-finished": mksig()} def __init__(self, term): - old.InstallProgress.__init__(self) + base.InstallProgress.__init__(self) gobject.GObject.__init__(self) self.finished = False self.time_last_update = time.time() @@ -152,6 +155,11 @@ class GInstallProgress(gobject.GObject, old.InstallProgress): """ self.emit("status-started") + def run(self, obj): + """Run.""" + self.finished = False + return base.InstallProgress.run(self, obj) + def finish_update(self): """Called when the update finished. @@ -159,6 +167,11 @@ class GInstallProgress(gobject.GObject, old.InstallProgress): """ self.emit("status-finished") + def processing(self, pkg, stage): + """Called when entering a new stage in dpkg.""" + # We have no percentage or alike, send -1 to let the bar pulse. + self.emit("status-changed", ("Installing %s...") % pkg, -1) + def status_change(self, pkg, percent, status): """Called when the status changed. @@ -172,7 +185,7 @@ class GInstallProgress(gobject.GObject, old.InstallProgress): Emits: status-timeout() [When a timeout happens] """ - old.InstallProgress.update_interface(self) + base.InstallProgress.update_interface(self) while self._context.pending(): self._context.iteration() if self.time_last_update + self.INSTALL_TIMEOUT < time.time(): @@ -197,34 +210,7 @@ class GInstallProgress(gobject.GObject, old.InstallProgress): childExited = function_deprecated_by(child_exited) -class GDpkgInstallProgress(old.DpkgInstallProgress, - GInstallProgress): - """An InstallProgress for local installations. - - Signals: - - * status-changed(str: status, int: percent) - * status-started() - Not Implemented yet - * status-finished() - * status-timeout() - When the maintainer script hangs - * status-error() - When an error happens - * status-conffile() - On Conffile - """ - - def run(self, debfile): - """Install the given package.""" - old.DpkgInstallProgress.run(self, debfile) - - def update_interface(self): - """Called periodically to update the interface. - - Emits: status-timeout() [When a timeout happens]""" - old.DpkgInstallProgress.update_interface(self) - if self.time_last_update + self.INSTALL_TIMEOUT < time.time(): - self.emit("status-timeout") - - if apt_pkg._COMPAT_0_7: - updateInterface = function_deprecated_by(update_interface) +GDpkgInstallProgress = GInstallProgress class GFetchProgress(gobject.GObject, old.FetchProgress): @@ -235,6 +221,8 @@ class GFetchProgress(gobject.GObject, old.FetchProgress): * status-changed(str: description, int: percent) * status-started() * status-finished() + + DEPRECATED. """ __gsignals__ = {"status-changed": mksig((str, int)), @@ -258,19 +246,19 @@ class GFetchProgress(gobject.GObject, old.FetchProgress): def pulse(self): old.FetchProgress.pulse(self) - current_item = self.current_items + 1 - if current_item > self.total_items: - current_item = self.total_items + current_item = self.currentItems + 1 + if current_item > self.totalItems: + current_item = self.totalItems if self.current_cps > 0: text = (_("Downloading file %(current)li of %(total)li with " "%(speed)s/s") % \ {"current": current_item, - "total": self.total_items, - "speed": apt_pkg.size_to_str(self.current_cps)}) + "total": self.totalItems, + "speed": apt_pkg.size_to_str(self.currentCPS)}) else: text = (_("Downloading file %(current)li of %(total)li") % \ {"current": current_item, - "total": self.total_items}) + "total": self.totalItems}) self.emit("status-changed", text, self.percent) while self._context.pending(): self._context.iteration() @@ -328,19 +316,6 @@ class GtkAptProgress(gtk.VBox): self._on_status_timeout) self._progress_install.connect("status-conffile", self._on_status_timeout) - self._progress_dpkg_install = GDpkgInstallProgress(self._terminal) - self._progress_dpkg_install.connect("status-changed", - self._on_status_changed) - self._progress_dpkg_install.connect("status-started", - self._on_status_started) - self._progress_dpkg_install.connect("status-finished", - self._on_status_finished) - self._progress_dpkg_install.connect("status-timeout", - self._on_status_timeout) - self._progress_dpkg_install.connect("status-error", - self._on_status_timeout) - self._progress_dpkg_install.connect("status-conffile", - self._on_status_timeout) def clear(self): """Reset all status information.""" @@ -361,7 +336,7 @@ class GtkAptProgress(gtk.VBox): @property def dpkg_install(self): """Return the install progress handler for dpkg.""" - return self._dpkg_progress_install + return self._progress_install @property def fetch(self): @@ -383,7 +358,7 @@ class GtkAptProgress(gtk.VBox): def _on_status_changed(self, progress, status, percent): """Called when the status changed.""" self._label.set_text(status) - if percent is None: + if percent is None or percent == -1: self._progressbar.pulse() else: self._progressbar.set_fraction(percent/100.0) @@ -431,6 +406,7 @@ def _test(): """Test function""" import sys + import apt from apt.debfile import DebPackage win = gtk.Window() diff --git a/apt/progress/old.py b/apt/progress/old.py index 6b6e21de..c2d95b85 100644 --- a/apt/progress/old.py +++ b/apt/progress/old.py @@ -20,72 +20,51 @@ # USA """Deprecated progress reporting classes. -This module provides classes for progress reporting. They can be used with -e.g., for reporting progress on the cache opening process, the cache update -progress, or the package install progress. +This module provides classes for compatibility with python-apt 0.7. They are +completely deprecated and should not be used anymore. """ -import errno -import fcntl + import os -import re -import select import sys import apt_pkg from apt.deprecation import AttributeDeprecatedBy, function_deprecated_by +import warnings from apt.progress import base, text - __all__ = [] class OpProgress(base.OpProgress): - """Abstract class to implement reporting on cache opening. - - Subclass this class to implement simple Operation progress reporting. - """ + """Abstract class to implement reporting on cache opening.""" - if apt_pkg._COMPAT_0_7: - subOp = AttributeDeprecatedBy('subop') - Op = AttributeDeprecatedBy('op') + subOp = AttributeDeprecatedBy('subop') + Op = AttributeDeprecatedBy('op') -class OpTextProgress(text.OpProgress): +class OpTextProgress(OpProgress, text.OpProgress): """A simple text based cache open reporting class.""" - if apt_pkg._COMPAT_0_7: - subOp = AttributeDeprecatedBy('subop') - Op = AttributeDeprecatedBy('op') - class FetchProgress(object): - """Report the download/fetching progress. - - Subclass this class to implement fetch progress reporting - """ + """Report the download/fetching progress.""" # download status constants - dl_done = 0 - dl_queued = 1 - dl_failed = 2 - dl_hit = 3 - dl_ignored = 4 - dl_status_str = {dl_done: "Done", - dl_queued: "Queued", - dl_failed: "Failed", - dl_hit: "Hit", - dl_ignored: "Ignored"} + (dlDone, dlQueued, dlFailed, dlHit, dlIgnored) = range(5) + dlStatusStr = {dlDone: "Done", dlQueued: "Queued", dlFailed: "Failed", + dlHit: "Hit", dlIgnored: "Ignored"} def __init__(self): self.eta = 0.0 self.percent = 0.0 # Make checking easier - self.current_bytes = 0 - self.current_items = 0 - self.total_bytes = 0 - self.total_items = 0 - self.current_cps = 0 + self.currentBytes = 0 + self.currentItems = 0 + self.totalBytes = 0 + self.totalItems = 0 + self.currentCPS = 0 + warnings.warn("FetchProgress() is deprecated.", DeprecationWarning) def start(self): """Called when the fetching starts.""" @@ -93,7 +72,7 @@ class FetchProgress(object): def stop(self): """Called when all files have been fetched.""" - def update_status(self, uri, descr, short_descr, status): + def updateStatus(self, uri, descr, short_descr, status): """Called when the status of an item changes. This happens eg. when the downloads fails or is completed. @@ -112,11 +91,11 @@ class FetchProgress(object): Return True to continue or False to cancel. """ - self.percent = (((self.current_bytes + self.current_items) * 100.0) / - float(self.total_bytes + self.total_items)) - if self.current_cps > 0: - self.eta = ((self.total_bytes - self.current_bytes) / - float(self.current_cps)) + self.percent = (((self.currentBytes + self.currentItems) * 100.0) / + float(self.totalBytes + self.totalItems)) + if self.currentCPS > 0: + self.eta = ((self.totalBytes - self.currentBytes) / + float(self.currentCPS)) return True def pulse_items(self, items): @@ -125,31 +104,16 @@ class FetchProgress(object): Return True to continue or False to cancel. """ - self.percent = (((self.current_bytes + self.current_items) * 100.0) / - float(self.total_bytes + self.total_items)) - if self.current_cps > 0: - self.eta = ((self.total_bytes - self.current_bytes) / - float(self.current_cps)) + self.percent = (((self.currentBytes + self.currentItems) * 100.0) / + float(self.totalBytes + self.totalItems)) + if self.currentCPS > 0: + self.eta = ((self.totalBytes - self.currentBytes) / + float(self.currentCPS)) return True - def media_change(self, medium, drive): + def mediaChange(self, medium, drive): """react to media change events.""" - if apt_pkg._COMPAT_0_7: - dlDone = AttributeDeprecatedBy('dl_done') - dlQueued = AttributeDeprecatedBy('dl_queued') - dlFailed = AttributeDeprecatedBy('dl_failed') - dlHit = AttributeDeprecatedBy('dl_hit') - dlIgnored = AttributeDeprecatedBy('dl_ignored') - dlStatusStr = AttributeDeprecatedBy('dl_status_str') - currentBytes = AttributeDeprecatedBy('current_bytes') - currentItems = AttributeDeprecatedBy('current_items') - totalBytes = AttributeDeprecatedBy('total_bytes') - totalItems = AttributeDeprecatedBy('total_items') - currentCPS = AttributeDeprecatedBy('current_cps') - updateStatus = function_deprecated_by(update_status) - mediaChange = function_deprecated_by(media_change) - class TextFetchProgress(FetchProgress): """ Ready to use progress object for terminal windows """ @@ -158,13 +122,13 @@ class TextFetchProgress(FetchProgress): FetchProgress.__init__(self) self.items = {} - def update_status(self, uri, descr, short_descr, status): + def updateStatus(self, uri, descr, short_descr, status): """Called when the status of an item changes. This happens eg. when the downloads fails or is completed. """ - if status != self.dl_queued: - print "\r%s %s" % (self.dl_status_str[status], descr) + if status != self.dlQueued: + print "\r%s %s" % (self.dlStatusStr[status], descr) self.items[uri] = status def pulse(self): @@ -173,9 +137,9 @@ class TextFetchProgress(FetchProgress): Return True to continue or False to cancel. """ FetchProgress.pulse(self) - if self.current_cps > 0: + if self.currentCPS > 0: s = "[%2.f%%] %sB/s %s" % (self.percent, - apt_pkg.size_to_str(int(self.current_cps)), + apt_pkg.size_to_str(int(self.currentCPS)), apt_pkg.time_to_str(int(self.eta))) else: s = "%2.f%% [Working]" % (self.percent) @@ -187,16 +151,23 @@ class TextFetchProgress(FetchProgress): """Called when all files have been fetched.""" print "\rDone downloading " - def media_change(self, medium, drive): + def mediaChange(self, medium, drive): """react to media change events.""" print ("Media change: please insert the disc labeled " "'%s' in the drive '%s' and press enter") % (medium, drive) return raw_input() not in ('c', 'C') - if apt_pkg._COMPAT_0_7: - updateStatus = function_deprecated_by(update_status) - mediaChange = function_deprecated_by(media_change) + +class CdromProgress(base.CdromProgress): + """Report the cdrom add progress. + + This class has been replaced by apt_pkg.CdromProgress. + """ + _basetype = base.CdromProgress + askCdromName = function_deprecated_by(_basetype.ask_cdrom_name) + changeCdrom = function_deprecated_by(_basetype.change_cdrom) + del _basetype class DumbInstallProgress(base.InstallProgress): @@ -208,127 +179,19 @@ class DumbInstallProgress(base.InstallProgress): startUpdate = function_deprecated_by(base.InstallProgress.start_update) finishUpdate = function_deprecated_by(base.InstallProgress.finish_update) updateInterface = function_deprecated_by( - base.InstallProgress.update_interface) + base.InstallProgress.update_interface) -class InstallProgress(DumbInstallProgress): +class InstallProgress(DumbInstallProgress, base.InstallProgress): """An InstallProgress that is pretty useful. It supports the attributes 'percent' 'status' and callbacks for the dpkg errors and conffiles and status changes. """ - def __init__(self): - DumbInstallProgress.__init__(self) - self.select_timeout = 0.1 - (read, write) = os.pipe() - self.writefd = write - self.statusfd = os.fdopen(read, "r") - fcntl.fcntl(self.statusfd.fileno(), fcntl.F_SETFL, os.O_NONBLOCK) - self.read = "" - self.percent = 0.0 - self.status = "" - - def error(self, pkg, errormsg): - """Called when a error is detected during the install.""" - - def conffile(self, current, new): - """Called when a conffile question from dpkg is detected.""" - - def status_change(self, pkg, percent, status): - """Called when the status changed.""" - - def update_interface(self): - """Called periodically to update the interface.""" - if self.statusfd is None: - return - try: - while not self.read.endswith("\n"): - self.read += os.read(self.statusfd.fileno(), 1) - except OSError, (errno_, errstr): - # resource temporarly unavailable is ignored - if errno_ != errno.EAGAIN and errno_ != errno.EWOULDBLOCK: - print errstr - if not self.read.endswith("\n"): - return - - s = self.read - #print s - try: - (status, pkg, percent, status_str) = s.split(":", 3) - except ValueError: - # silently ignore lines that can't be parsed - self.read = "" - return - #print "percent: %s %s" % (pkg, float(percent)/100.0) - if status == "pmerror": - self.error(pkg, status_str) - elif status == "pmconffile": - # we get a string like this: - # 'current-conffile' 'new-conffile' useredited distedited - match = re.match("\s*\'(.*)\'\s*\'(.*)\'.*", status_str) - if match: - self.conffile(match.group(1), match.group(2)) - elif status == "pmstatus": - if float(percent) != self.percent or status_str != self.status: - self.status_change(pkg, float(percent), - status_str.strip()) - self.percent = float(percent) - self.status = status_str.strip() - self.read = "" - - def fork(self): - """Fork.""" - return os.fork() - - def wait_child(self): - """Wait for child progress to exit.""" - while True: - try: - select.select([self.statusfd], [], [], self.select_timeout) - except select.error, (errno_, errstr): - if errno_ != errno.EINTR: - raise - - self.update_interface() - try: - (pid, res) = os.waitpid(self.child_pid, os.WNOHANG) - if pid == self.child_pid: - break - except OSError, (errno_, errstr): - if errno_ != errno.EINTR: - raise - if errno_ == errno.ECHILD: - break - return res - - def run(self, pm): - """Start installing.""" - pid = self.fork() - if pid == 0: - # child - res = pm.do_install(self.writefd) - os._exit(res) - self.child_pid = pid - res = self.wait_child() - return os.WEXITSTATUS(res) - - if apt_pkg._COMPAT_0_7: - selectTimeout = AttributeDeprecatedBy('select_timeout') - statusChange = function_deprecated_by(status_change) - waitChild = function_deprecated_by(wait_child) - updateInterface = function_deprecated_by(update_interface) - - -class CdromProgress(base.CdromProgress): - """Report the cdrom add progress. - - This class has been replaced by apt_pkg.CdromProgress. - """ - _basetype = base.CdromProgress - askCdromName = function_deprecated_by(_basetype.ask_cdrom_name) - changeCdrom = function_deprecated_by(_basetype.change_cdrom) - del _basetype + selectTimeout = AttributeDeprecatedBy('select_timeout') + statusChange = function_deprecated_by(base.InstallProgress.status_change) + waitChild = function_deprecated_by(base.InstallProgress.wait_child) class DpkgInstallProgress(InstallProgress): @@ -336,54 +199,7 @@ class DpkgInstallProgress(InstallProgress): def run(self, debfile): """Start installing the given Debian package.""" - if apt_pkg._COMPAT_0_7: # Deprecated stuff - self.debfile = debfile - self.debname = os.path.basename(debfile).split("_")[0] - - pid = self.fork() - if pid == 0: - # child - res = os.system("/usr/bin/dpkg --status-fd %s -i %s" % \ - (self.writefd, debfile)) - os._exit(os.WEXITSTATUS(res)) - self.child_pid = pid - res = self.wait_child() - return res - - def update_interface(self): - """Process status messages from dpkg.""" - if self.statusfd is None: - return - while True: - try: - self.read += os.read(self.statusfd.fileno(), 1) - except OSError, (errno_, errstr): - # resource temporarly unavailable is ignored - if errno_ != 11: - print errstr - break - if not self.read.endswith("\n"): - continue - - statusl = self.read.split(":") - if len(statusl) < 3: - print "got garbage from dpkg: '%s'" % self.read - self.read = "" - break - pkg_name = statusl[1].strip() - status = statusl[2].strip() - #print status - if status == "error": - self.error(pkg_name, status) - elif status == "conffile-prompt": - # we get a string like this: - # 'current-conffile' 'new-conffile' useredited distedited - match = re.match("\s*\'(.*)\'\s*\'(.*)\'.*", statusl[3]) - if match: - self.conffile(match.group(1), match.group(2)) - else: - self.status = status - self.read = "" - - if apt_pkg._COMPAT_0_7: - updateInterface = function_deprecated_by(update_interface) + # Deprecated stuff + self.debfile = debfile + self.debname = os.path.basename(debfile).split("_")[0] + return base.InstallProgress(self, debfile) diff --git a/apt/progress/text.py b/apt/progress/text.py index eb474d6d..3a6d3e65 100644 --- a/apt/progress/text.py +++ b/apt/progress/text.py @@ -257,3 +257,5 @@ class CdromProgress(base.CdromProgress, TextProgress): return (raw_input() == '') except KeyboardInterrupt: return False + +InstallProgress = base.InstallProgress -- cgit v1.2.3 From f93c026887322f38a60f979045d02e3df267d382 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 31 Jul 2009 20:53:54 +0200 Subject: apt/package.py: Fix apt_pkg.Version_compare => apt_pkg.version_compare. --- apt/package.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'apt') diff --git a/apt/package.py b/apt/package.py index 9a1b0d68..50b57760 100644 --- a/apt/package.py +++ b/apt/package.py @@ -207,9 +207,9 @@ class Version(object): def _cmp(self, other): try: - return apt_pkg.Version_compare(self._cand.ver_str, other.version) + return apt_pkg.version_compare(self._cand.ver_str, other.version) except AttributeError: - return apt_pkg.Version_compare(self._cand.ver_str, other) + return apt_pkg.version_compare(self._cand.ver_str, other) def __eq__(self, other): try: -- cgit v1.2.3 From 681990602c8569721dae83d887195548845d1656 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 18 Aug 2009 15:13:28 +0200 Subject: apt/debfile.py: Adapt to class-based API (WARNING: changes behavior on certain invalid packages). Use the class-based API now. This also means that if the archive is no valid Debian package (because it misses a 'data.tar.*', 'control.tar.gz' or a 'debian-binary' member) the method open() will now raise an Error; previously it only raised an error if there was no 'debian-binary' member or no 'control.tar.gz' member. --- apt/debfile.py | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) (limited to 'apt') diff --git a/apt/debfile.py b/apt/debfile.py index 421129c8..65f43f20 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -52,11 +52,8 @@ class DebPackage(object): def open(self, filename): " open given debfile " self.filename = filename - if not apt_inst.ar_check_member(open(self.filename), "debian-binary"): - raise NoDebArchiveException(_("This is not a valid DEB archive, " - "missing '%s' member" % - "debian-binary")) - control = apt_inst.deb_extract_control(open(self.filename)) + self._debfile = apt_inst.DebFile(self.filename) + control = self._debfile.control.extractdata("control") self._sections = apt_pkg.TagSection(control) self.pkgname = self._sections["Package"] @@ -67,19 +64,11 @@ class DebPackage(object): def filelist(self): """return the list of files in the deb.""" files = [] - - def extract_cb(what, name, *_): - files.append(name) - - for member in self._supported_data_members: - if apt_inst.ar_check_member(open(self.filename), member): - try: - apt_inst.deb_extract(open(self.filename), extract_cb, - member) - break - except SystemError: - return [_("List of files for '%s' could not be read" % - self.filename)] + try: + self._debfile.data.go(lambda item, data: files.append(item.name)) + except SystemError: + return [_("List of files for '%s' could not be read" % + self.filename)] return files def _is_or_group_satisfied(self, or_group): -- cgit v1.2.3