diff options
| author | Michael Vogt <michael.vogt@ubuntu.com> | 2010-06-01 17:08:24 +0200 |
|---|---|---|
| committer | Michael Vogt <michael.vogt@ubuntu.com> | 2010-06-01 17:08:24 +0200 |
| commit | e74ead9f918b38bfe8ae5cfe941df4057dcc509e (patch) | |
| tree | 9f678aa2510cb1df272cd5beca5cf551794e6307 | |
| parent | 5a062bb328348cd3a2ac693b579d35d0ce8e11f0 (diff) | |
| parent | 50f9df7e415deb9bb6156ef8f596b6d4d49b23a4 (diff) | |
| download | python-apt-e74ead9f918b38bfe8ae5cfe941df4057dcc509e.tar.gz | |
* merge from debian bzr, remaining changes:
- different mirror list
* data/templates/gNewSense.info.in,
data/templates/gNewSense.mirrors:
- add gNewSense template and mirrors, thanks to Karl Goetz
* apt/cache.py:
- Make Cache.get_changes() much (~35x) faster (Closes: #578074).
- Make Cache.req_reinstall_pkgs much faster as well.
- Make Cache.get_providing_packages() about 1000 times faster.
- Use has_versions and has_provides from apt_pkg.Package where possible.
* apt/package.py:
- Decode using utf-8 in installed_files (LP: #407953).
- Fix fetch_source() to work when source name = binary name (LP: #552400).
- Merge a patch from Sebastian Heinlein to make get_changelog() only
check sources where source version >= binary version (Closes: #581831).
- Add Version.source_version and enhance Sebastian's patch to make use
of it, in order to find the best changelog for the package.
* python:
- Return bool instead of int to Python where possible, looks better.
- Document every class, function, property.
* python/cache.cc:
- Check that 2nd argument to Cache.update() really is a SourceList object.
- Fix PackageFile.not_automatic to use NotAutomatic instead of NotSource.
- Add Package.has_versions to see which packages have at least one version,
and Package.has_provides for provides.
- Add rich compare methods to the Version object.
* python/generic.cc:
- Fix a memory leak when using old attribute names.
- Map ArchiveURI property to archive_uri
* python/progress.cc:
- Do not pass arguments to InstallProgress.wait_child().
* doc:
- Update the long documentation.
* debian/control:
- Change priority to standard, keep -doc and -dev on optional.
* utils/migrate-0.8.py:
- Open files in universal newline support and pass filename to ast.parse.
- Add has_key to the list of deprecated functions.
- Don't abort if parsing failed.
- do not require files to end in .py if they are passed on the command
line or if they contain python somewhere in the shebang line.
* apt/cache.py:
- make cache open silent by default (use apt.progress.base.OpProgress)
* tests/data/aptsources_ports/sources.list:
- fix ports test-data
* tests/test_apt_cache.py:
- add simple test for basic cache/dependency iteration
34 files changed, 2754 insertions, 1133 deletions
diff --git a/apt/cache.py b/apt/cache.py index cfe6bedc..8e07e4d0 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -136,7 +136,7 @@ class Cache(object): progress.update(i/float(size)*100) last = i # drop stuff with no versions (cruft) - if len(pkg.version_list) > 0: + if pkg.has_versions: self._set.add(pkg.name) i += 1 @@ -176,10 +176,14 @@ class Cache(object): def get_changes(self): """ Get the marked changes """ changes = [] - 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) + marked_keep = self._depcache.marked_keep + for pkg in self._cache.packages: + if not marked_keep(pkg): + try: + changes.append(self._weakref[pkg.name]) + except KeyError: + package = self._weakref[pkg.name] = Package(self, pkg) + changes.append(package) return changes @deprecated_args @@ -211,10 +215,12 @@ class Cache(object): def req_reinstall_pkgs(self): """Return the packages not downloadable packages in reqreinst state.""" reqreinst = set() - for pkg in self: - if (not pkg.candidate.downloadable and - (pkg._pkg.inst_state == apt_pkg.INSTSTATE_REINSTREQ or - pkg._pkg.inst_state == apt_pkg.INSTSTATE_HOLD_REINSTREQ)): + get_candidate_ver = self._depcache.get_candidate_ver + states = frozenset((apt_pkg.INSTSTATE_REINSTREQ, + apt_pkg.INSTSTATE_HOLD_REINSTREQ)) + for pkg in self._cache.packages: + cand = get_candidate_ver(pkg) + if cand and not cand.downloadable and pkg.inst_state in states: reqreinst.add(pkg.name) return reqreinst @@ -269,29 +275,36 @@ class Cache(object): except KeyError: return False else: - return bool(pkg.provides_list and not pkg.version_list) + return bool(pkg.has_provides and not pkg.has_versions) - def get_providing_packages(self, virtual): - """ + def get_providing_packages(self, virtual, candidate_only=True): + """Return a list of all packages providing a virtual package. + Return a list of packages which provide the virtual package of the - specified name + specified name. If 'candidate_only' is False, return all packages + with at least one version providing the virtual package. Otherwise, + return only those packages where the candidate version provides + the virtual package. """ - providers = [] + + providers = set() + get_candidate_ver = self._depcache.get_candidate_ver try: vp = self._cache[virtual] - if len(vp.version_list) != 0: - return providers + if vp.has_versions: + return list(providers) except KeyError: - return providers - for pkg in self: - v = self._depcache.get_candidate_ver(pkg._pkg) - if v is None: - continue - for p in v.provides_list: - if virtual == p[0]: - # we found a pkg that provides this virtual pkg - providers.append(pkg) - return providers + return list(providers) + + for provides, providesver, version in vp.provides_list: + pkg = version.parent_pkg + if not candidate_only or (version == get_candidate_ver(pkg)): + try: + providers.add(self._weakref[pkg.name]) + except KeyError: + package = self._weakref[pkg.name] = Package(self, pkg) + providers.add(package) + return list(providers) @deprecated_args def update(self, fetch_progress=None, pulse_interval=0, diff --git a/apt/package.py b/apt/package.py index 342fb5cf..7dcead02 100644 --- a/apt/package.py +++ b/apt/package.py @@ -379,6 +379,14 @@ class Version(object): return self.package.name @property + def source_version(self): + """Return the version of the source package.""" + try: + return self._records.source_ver or self._cand.ver_str + except IndexError: + return self._cand.ver_str + + @property def priority(self): """Return the priority of the package, as string.""" return self._cand.priority_str @@ -1006,34 +1014,31 @@ class Package(object): src_section = "main" # use the section of the candidate as a starting point section = self.candidate.section - - # get the source version, start with the binaries version - bin_ver = self.candidate.version - src_ver = self.candidate.version - #print "bin: %s" % binver + + # get the source version + src_ver = self.candidate.source_version + try: - # FIXME: This try-statement is too long ... # try to get the source version of the pkg, this differs # for some (e.g. libnspr4 on ubuntu) # this feature only works if the correct deb-src are in the - # sources.list - # otherwise we fall back to the binary version number + # sources.list otherwise we fall back to the binary version number src_records = apt_pkg.SourceRecords() - src_rec = src_records.lookup(src_pkg) - if src_rec: - 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 - #print "srcsect: %s" % section - else: - # fail into the error handler - raise SystemError except SystemError: - src_ver = bin_ver + pass + else: + while src_records.lookup(src_pkg): + if not src_records.version: + continue + if self.candidate.source_version == src_records.version: + # Direct match, use it and do not do more lookups. + src_ver = src_records.version + section = src_records.section + break + if apt_pkg.version_compare(src_records.version, src_ver) > 0: + # The version is higher, it seems to match. + src_ver = src_records.version + section = src_records.section section_split = section.split("/", 1) if len(section_split) > 1: diff --git a/data/templates/gNewSense.info.in b/data/templates/gNewSense.info.in new file mode 100644 index 00000000..c7636bc8 --- /dev/null +++ b/data/templates/gNewSense.info.in @@ -0,0 +1,55 @@ +_ChangelogURI: http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog + +# gNS 3, to be based on Squeeze. +Suite: parkes +RepositoryType: deb +BaseURI: http://archive.gnewsense.org/gnewsense/ +MatchURI: archive.gnewsense.org/gnewsense +MirrorsFile: gNewSense.mirrors +Description: gNewSense 3 - "parkes" +Component: main +_CompDescription: Main supported software +_CompDescriptionLong: Core software + +Suite: parkes/updates +RepositoryType: deb +BaseURI: http://security.gnewsense.org/gnewsense +MatchURI: security.gnewsense.org/security +ParentSuite: parkes +_Description: Security updates + +# gNS 2.x, based on hardy +Suite: deltah +RepositoryType: deb +BaseURI: http://archive.gnewsense.org/gnewsense/ +MatchURI: archive.gnewsense.org/gnewsense +MirrorsFile: gNewSense.mirrors +_Description: gNewSense "deltah" +Component: main +_CompDescription: Main supported software +_CompDescriptionLong: Core software +Component: universe +_CompDescription: Other useful software +_CompDescriptionLong: Non-core useful software + +Suite: deltah-security +ParentSuite: deltah +RepositoryType: deb +BaseURI: http://security.gnewsense.org/gnewsense/ +MatchURI: archive.gnewsense.org/gnewsense|security.gnewsense.org +_Description: Important security updates + +Suite: deltah-updates +ParentSuite: deltah +RepositoryType: deb +BaseURI: http://archive.gnewsense.org/gnewsense/ +MatchURI: archive.gnewsense.org/gnewsense +_Description: Unsupported updates + +Suite: deltah-backports +ParentSuite: deltah +RepositoryType: deb +BaseURI: http://archive.gnewsense.org/gnewsense/ +MatchURI: archive.gnewsense.org/gnewsense +_Description: Package Backports + diff --git a/data/templates/gNewSense.mirrors b/data/templates/gNewSense.mirrors new file mode 100644 index 00000000..7a8dbaa9 --- /dev/null +++ b/data/templates/gNewSense.mirrors @@ -0,0 +1,489 @@ + +#LOC:AD +http://ad.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AE +http://ae.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AF +http://af.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AG +http://ag.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AI +http://ai.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AL +http://al.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AM +http://am.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AN +http://an.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AO +http://ao.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AQ +http://aq.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AR +http://ar.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AS +http://as.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AT +http://at.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AU +http://au.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AW +http://aw.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AX +http://ax.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AZ +http://az.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BA +http://ba.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BB +http://bb.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BD +http://bd.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BE +http://be.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BF +http://bf.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BG +http://bg.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BH +http://bh.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BI +http://bi.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BJ +http://bj.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BM +http://bm.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BN +http://bn.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BO +http://bo.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BR +http://br.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BS +http://bs.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BT +http://bt.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BV +http://bv.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BW +http://bw.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BY +http://by.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BZ +http://bz.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CA +http://ca.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CC +http://cc.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CD +http://cd.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CF +http://cf.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CG +http://cg.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CH +http://ch.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CI +http://ci.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CK +http://ck.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CL +http://cl.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CM +http://cm.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CN +http://cn.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CO +http://co.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CR +http://cr.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CU +http://cu.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CV +http://cv.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CX +http://cx.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CY +http://cy.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CZ +http://cz.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:DE +http://de.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:DJ +http://dj.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:DK +http://dk.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:DM +http://dm.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:DO +http://do.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:DZ +http://dz.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:EC +http://ec.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:EE +http://ee.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:EG +http://eg.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:EH +http://eh.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:ER +http://er.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:ES +http://es.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:ET +http://et.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:FI +http://fi.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:FJ +http://fj.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:FK +http://fk.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:FM +http://fm.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:FO +http://fo.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:FR +http://fr.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GA +http://ga.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GB +http://gb.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GD +http://gd.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GE +http://ge.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GF +http://gf.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GG +http://gg.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GH +http://gh.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GI +http://gi.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GL +http://gl.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GM +http://gm.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GN +http://gn.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GP +http://gp.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GQ +http://gq.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GR +http://gr.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GS +http://gs.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GT +http://gt.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GU +http://gu.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GW +http://gw.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GY +http://gy.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:HK +http://hk.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:HM +http://hm.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:HN +http://hn.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:HR +http://hr.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:HT +http://ht.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:HU +http://hu.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:ID +http://id.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:IE +http://ie.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:IL +http://il.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:IM +http://im.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:IN +http://in.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:IO +http://io.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:IQ +http://iq.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:IR +http://ir.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:IS +http://is.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:IT +http://it.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:JE +http://je.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:JM +http://jm.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:JO +http://jo.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:JP +http://jp.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:KE +http://ke.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:KG +http://kg.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:KH +http://kh.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:KI +http://ki.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:KM +http://km.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:KN +http://kn.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:KP +http://kp.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:KR +http://kr.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:KW +http://kw.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:KY +http://ky.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:KZ +http://kz.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:LA +http://la.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:LB +http://lb.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:LC +http://lc.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:LI +http://li.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:LK +http://lk.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:LR +http://lr.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:LS +http://ls.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:LT +http://lt.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:LU +http://lu.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:LV +http://lv.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:LY +http://ly.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MA +http://ma.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MC +http://mc.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MD +http://md.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:ME +http://me.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MG +http://mg.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MH +http://mh.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MK +http://mk.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:ML +http://ml.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MM +http://mm.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MN +http://mn.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MO +http://mo.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MP +http://mp.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MQ +http://mq.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MR +http://mr.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MS +http://ms.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MT +http://mt.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MU +http://mu.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MV +http://mv.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MW +http://mw.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MX +http://mx.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MY +http://my.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MZ +http://mz.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:NA +http://na.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:NC +http://nc.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:NE +http://ne.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:NF +http://nf.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:NG +http://ng.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:NI +http://ni.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:NL +http://nl.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:NO +http://no.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:NP +http://np.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:NR +http://nr.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:NU +http://nu.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:NZ +http://nz.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:OM +http://om.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PA +http://pa.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PE +http://pe.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PF +http://pf.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PG +http://pg.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PH +http://ph.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PK +http://pk.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PL +http://pl.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PM +http://pm.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PN +http://pn.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PR +http://pr.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PS +http://ps.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PT +http://pt.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PW +http://pw.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PY +http://py.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:QA +http://qa.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:RE +http://re.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:RO +http://ro.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:RS +http://rs.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:RU +http://ru.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:RW +http://rw.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SA +http://sa.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SB +http://sb.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SC +http://sc.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SD +http://sd.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SE +http://se.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SG +http://sg.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SH +http://sh.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SI +http://si.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SJ +http://sj.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SK +http://sk.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SL +http://sl.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SM +http://sm.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SN +http://sn.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SO +http://so.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SR +http://sr.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:ST +http://st.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SV +http://sv.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SY +http://sy.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SZ +http://sz.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TC +http://tc.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TD +http://td.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TF +http://tf.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TG +http://tg.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TH +http://th.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TJ +http://tj.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TK +http://tk.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TL +http://tl.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TM +http://tm.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TN +http://tn.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TO +http://to.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TR +http://tr.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TT +http://tt.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TV +http://tv.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TW +http://tw.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TZ +http://tz.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:UA +http://ua.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:UG +http://ug.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:UM +http://um.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:US +http://us.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:UY +http://uy.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:UZ +http://uz.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:VA +http://va.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:VC +http://vc.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:VE +http://ve.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:VG +http://vg.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:VI +http://vi.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:VN +http://vn.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:VU +http://vu.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:WF +http://wf.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:WS +http://ws.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:YE +http://ye.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:YT +http://yt.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:ZA +http://za.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:ZM +http://zm.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:ZW +http://zw.archive.gnewsense.org/gnewsense-metad/gnewsense/ diff --git a/debian/changelog b/debian/changelog index 3a87ffeb..fd9632ce 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,64 @@ +python-apt (0.7.95ubuntu1) maverick; urgency=low + + * merge from debian bzr, remaining changes: + - different mirror list + + * data/templates/gNewSense.info.in, + data/templates/gNewSense.mirrors: + - add gNewSense template and mirrors, thanks to Karl Goetz + + -- Michael Vogt <michael.vogt@ubuntu.com> Tue, 01 Jun 2010 17:06:49 +0200 + +python-apt (0.7.95) unstable; urgency=low + + [ Julian Andres Klode ] + * apt/cache.py: + - Make Cache.get_changes() much (~35x) faster (Closes: #578074). + - Make Cache.req_reinstall_pkgs much faster as well. + - Make Cache.get_providing_packages() about 1000 times faster. + - Use has_versions and has_provides from apt_pkg.Package where possible. + * apt/package.py: + - Decode using utf-8 in installed_files (LP: #407953). + - Fix fetch_source() to work when source name = binary name (LP: #552400). + - Merge a patch from Sebastian Heinlein to make get_changelog() only + check sources where source version >= binary version (Closes: #581831). + - Add Version.source_version and enhance Sebastian's patch to make use + of it, in order to find the best changelog for the package. + * python: + - Return bool instead of int to Python where possible, looks better. + - Document every class, function, property. + * python/cache.cc: + - Check that 2nd argument to Cache.update() really is a SourceList object. + - Fix PackageFile.not_automatic to use NotAutomatic instead of NotSource. + - Add Package.has_versions to see which packages have at least one version, + and Package.has_provides for provides. + - Add rich compare methods to the Version object. + * python/generic.cc: + - Fix a memory leak when using old attribute names. + - Map ArchiveURI property to archive_uri + * python/progress.cc: + - Do not pass arguments to InstallProgress.wait_child(). + * doc: + - Update the long documentation. + * debian/control: + - Change priority to standard, keep -doc and -dev on optional. + * utils/migrate-0.8.py: + - Open files in universal newline support and pass filename to ast.parse. + - Add has_key to the list of deprecated functions. + - Don't abort if parsing failed. + - do not require files to end in .py if they are passed on the command + line or if they contain python somewhere in the shebang line. + + [ Michael Vogt ] + * apt/cache.py: + - make cache open silent by default (use apt.progress.base.OpProgress) + * tests/data/aptsources_ports/sources.list: + - fix ports test-data + * tests/test_apt_cache.py: + - add simple test for basic cache/dependency iteration + + -- Julian Andres Klode <jak@debian.org> Wed, 19 May 2010 15:43:09 +0200 + python-apt (0.7.94.2ubuntu7) maverick; urgency=low * data/templates/Ubuntu.info.in: diff --git a/doc/source/library/apt.progress.qt4.rst b/doc/source/library/apt.progress.qt4.rst deleted file mode 100644 index cd06a4e6..00000000 --- a/doc/source/library/apt.progress.qt4.rst +++ /dev/null @@ -1,3 +0,0 @@ -:mod:`apt.progress.qt4` --- Progress reporting for Qt4 interfaces -================================================================= -Not written yet. diff --git a/doc/source/library/apt_pkg.rst b/doc/source/library/apt_pkg.rst index bcdf2f7a..dd958959 100644 --- a/doc/source/library/apt_pkg.rst +++ b/doc/source/library/apt_pkg.rst @@ -30,11 +30,17 @@ be called without having run init*(), but will not return the expected value. Working with the cache ---------------------- -.. class:: Cache([progress]) +.. class:: Cache([progress: apt.progress.base.OpProgress]) - Return a :class:`Cache()` object. The optional parameter *progress* - specifies an instance of :class:`apt.progress.OpProgress()` which will - display the open progress. + A Cache object represents the cache used by APT which contains information + about packages. The object itself provides no means to modify the cache or + the installed packages, see the classes :class:`DepCache` and + :class:`PackageManager` for such functionality. + + The constructor takes an optional argument which must be a subclass of + :class:`apt.progress.base.OpProgress`. This object will then be used to + display information during the cache opening process (or possible creation + of the cache). .. describe:: cache[pkgname] @@ -46,189 +52,231 @@ Working with the cache Check whether a package with the name given by *pkgname* exists in the cache. - .. method:: update(progress, list[, pulse_interval]) - - Update the package cache. + .. method:: update(progress, sources [, pulse_interval]) -> bool - The parameter *progress* points to an :class:`apt.progress.FetchProgress()` - object. The parameter *list* refers to a :class:`SourceList()` object. + Update the index files used by the cache. A call to this method + does not affect the current Cache object, instead a new one + should be created in order to use the changed index files. - The optional parameter *pulse_interval* describes the interval between - the calls to the :meth:`FetchProgress.pulse` method. + The parameter *progress* takes an + :class:`apt.progress.base.AcquireProgress` object which will display + the progress of fetching the index files. The parameter *sources* takes + a :class:`SourceList` object which lists the sources. The parameter + *progress* takes an integer describing the interval (in microseconds) + in which the pulse() method of the *progress* object will be called. .. attribute:: depends_count - The total number of dependencies. + The total number of dependencies stored in the cache. + + .. attribute:: file_list + + A list of all :class:`PackageFile` objects stored in the cache. .. attribute:: package_count - The total number of packages available in the cache. + The total number of packages available in the cache. This value is + equal to the length of the list provided by the :attr:`packages` + attribute. - .. attribute:: packages + .. attribute:: package_file_count - A sequence of :class:`Package` objects. + 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:`file_list`. - .. attribute:: provides_count + .. attribute:: packages - The number of provided packages. + A sequence of :class:`Package` objects, implemented as a + :class:`PackageList` object. - .. attribute:: ver_file_count + .. class:: PackageList - .. todo:: Seems to be some mixture of versions and pkgFile. + A simple sequence-like object which only provides a length and + an implementation of ``__getitem__`` for accessing packages at + a certain index. Apart from being iterable, it can be used in + the following ways: - .. attribute:: version_count + .. describe:: list[index] - The total number of package versions available in the cache. + Get the :class:`Package` object for the package at the position + given by *index* in the PackageList *list*. - .. attribute:: package_file_count + .. describe:: len(list) - 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:`file_list`. + Return the length of the PackageList object *list*. - .. attribute:: file_list + .. attribute:: provides_count - A list of :class:`PackageFile` objects. + The number of provided packages. -.. class:: DepCache(cache) + .. attribute:: ver_file_count - Return a :class:`DepCache` object. The parameter *cache* specifies an - instance of :class:`Cache`. + The total number of ``(Version, PackageFile)`` relations stored in + the cache. - The DepCache object contains various methods to manipulate the cache, - to install packages, to remove them, and much more. + .. attribute:: version_count - .. method:: commit(fprogress, iprogress) + The total number of package versions available in the cache. - Apply all the changes made. +Managing the cache with :class:`DepCache` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. class:: DepCache(cache: apt_pkg.Cache) - The parameter *fprogress* has to be set to an instance of - apt.progress.FetchProgress or one of its subclasses. + A DepCache object provides access to more information about the + objects made available by the :class:`Cache` object as well as + means to mark packages for removal and installation, among other + actions. - The parameter *iprogress* has to be set to an instance of - apt.progress.InstallProgress or one of its subclasses. + The constructor takes a single argument which specifies the + :class:`Cache` object the new object shall be related to. While + it is theoretically possible to create multiple DepCache objects + for the same cache, they will not be independent from each other + since they all access the same underlying C++ object. - .. method:: fix_broken() + Objects of this type provide several methods. Most of those methods + are safe to use and should never raise any exception (all those + methods for requesting state information or marking changes). If a + method is expected to raise an exception, it will be stated in the + description. - Try to fix all broken packages in the cache. + .. method:: commit(acquire_progress, install_progress) - .. method:: get_candidate_ver(pkg) + Commit all marked changes, while reporting the progress of + fetching packages via the :class:`apt.progress.base.AcquireProgress` + object given by *acquire_progress* and reporting the installation + of the package using the :class:`apt.progress.base.InstallProgress` + object given by *install_progress*. - Return the candidate version of the package, ie. the version that - would be installed normally. + If this fails, an exception of the type :exc:`SystemError` will + be raised. - The parameter *pkg* refers to an :class:`Package` object, - available using the :class:`pkgCache`. + .. method:: fix_broken() -> bool - This method returns a :class:`Version` object. + Try to fix all broken packages in the cache and return ``True`` in + case of success. If an error occurred, a :exc:`SystemError` + exception is raised. - .. method:: set_candidate_ver(pkg, version) + .. method:: get_candidate_ver(pkg: Package) -> Version - The opposite of :meth:`pkgDepCache.get_candidate_ver`. Set the candidate - version of the :class:`Package` *pkg* to the :class:`Version` - *version*. + Return the candidate version for the package given by the parameter + *pkg* as a :class:`Version` object. The default candidate for a + package is the version with the highest pin, although a different + one may be set using :meth:`set_candidate_ver`. If no candidate + can be found, return ``None`` instead. - .. method:: upgrade([dist_upgrade=False]) + .. method:: init(progress: apt.progress.base.OpProgress) - 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. + Initialize the DepCache. This is done automatically when the + cache is opened, but sometimes it may be useful to reinitialize + the DepCache. Like the constructor of :class:`Cache`, this + function takes a single :class:`apt.progress.base.OpProgress` + object to display progress information. - To perform a dist-upgrade, the optional parameter *dist_upgrade* has - to be set to True. + .. method:: read_pinfile(file: str) - .. method:: fix_broken() + A proxy function which calls the method :meth:`Policy.read_pinfile` of + the :class:`Policy` object used by this object. This method raises + a :exc:`SystemError` exception if the file could not be parsed. - Fix broken packages. + .. method:: set_candidate_ver(pkg: Package, version: Version) -> bool - .. method:: read_pinfile() + Set the candidate version of the package given by the :class:`Package` + object *pkg* to the version given by the :class:`Version` object + *version* and return ``True``. If odd things happen, this function + may raise a :exc:`SystemError` exception, but this should not + happen in normal usage. See :meth:`get_candidate_ver` for a way + to retrieve the candidate version of a package. - Read the policy, eg. /etc/apt/preferences. + .. method:: upgrade([dist_upgrade=False]) -> bool - .. method:: minimize_upgrade() + Mark the packages for upgrade under the same conditions + :program:`apt-get` does. If *dist_upgrade* is ``True``, also + allow packages to be upgraded if they require installation/removal + of other packages; just like apt-get dist-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. + Despite returning a boolean value, this raises :exc:`SystemError` and + does not return ``False`` if an error occurred. - .. todo:: - Explain better.. + The following methods can mark a single package for installation, + removal, etc: - .. method:: mark_auto(pkg) + .. method:: mark_auto(pkg: Package) Mark the :class:`Package` *pkg* as automatically installed. - .. method:: mark_keep(pkg) + .. method:: mark_keep(pkg: Package) Mark the :class:`Package` *pkg* for keep. - .. method:: mark_delete(pkg[, purge]) + .. method:: mark_delete(pkg: Package[, purge]) Mark the :class:`Package` *pkg* for delete. If *purge* is True, the configuration files will be removed as well. - .. method:: mark_install(pkg[, auto_inst=True[, from_user=True]]) - - Mark the :class:`Package` *pkg* for install. + .. method:: mark_install(pkg: Package[, auto_inst=True[, from_user=True]]) - If *auto_inst* is ``True``, the dependencies of the package will be - installed as well. This is the default. + Mark the :class:`Package` *pkg* for install, and, if *auto_inst* + is ``True``, its dependencies as well. If *from_user* is ``True``, + the package will **not** be marked as automatically installed. - If *from_user* is ``True``, the package will be marked as manually - installed. This is the default. - - .. method:: set_reinstall(pkg) + .. method:: set_reinstall(pkg: Package) Set if the :class:`Package` *pkg* should be reinstalled. - .. method:: is_upgradable(pkg) + The following methods can be used to check the state of a package: - Return ``1`` if the package is upgradable. + .. method:: is_auto_installed(pkg: Package) -> bool - The package can be upgraded by calling :meth:`pkgDepCache.MarkInstall`. + Return ``True`` if the package is automatically installed, that + is, as a dependency of another package. - .. method:: is_now_broken(pkg) + .. method:: is_garbage(pkg: Package) -> bool - Return `1` if the package is broken now (including changes made, but - not committed). + Return ``True`` if the package is garbage, that is, if it was + automatically installed and no longer referenced by other packages. - .. method:: is_inst_broken(pkg) + .. method:: is_inst_broken(pkg: Package) -> bool - Return ``1`` if the package is broken on the current install. This - takes changes which have not been committed not into effect. + Return ``True`` if the package is broken on the current install. This + takes changes which have not been marked not into account. - .. method:: is_garbage(pkg) + .. method:: is_now_broken(pkg: Package) -> bool - Return ``1`` if the package is garbage, ie. if it is automatically - installed and no longer referenced by other packages. + Return ``True`` if the package is now broken, that is, if the package + is broken if the marked changes are applied. + + .. method:: is_upgradable(pkg: Package) -> bool - .. method:: is_auto_installed(pkg) + Return ``True`` if the package is upgradable, the package can then + be marked for upgrade by calling the method :meth:`mark_install`. - Return ``1`` if the package is automatically installed (eg. as the - dependency of another package). + .. method:: marked_delete(pkg: Package) -> bool - .. method:: marked_install(pkg) + Return ``True`` if the package is marked for delete. - Return ``1`` if the package is marked for install. + .. method:: marked_downgrade(pkg: Package) -> bool - .. method:: marked_upgrade(pkg) + Return ``True`` if the package should be downgraded. - Return ``1`` if the package is marked for upgrade. + .. method:: marked_install(pkg: Package) -> bool - .. method:: marked_delete(pkg) + Return ``True`` if the package is marked for install. - Return ``1`` if the package is marked for delete. + .. method:: marked_keep(pkg: Package) -> bool - .. method:: marked_keep(pkg) + Return ``True`` if the package is marked for keep. - Return ``1`` if the package is marked for keep. + .. method:: marked_reinstall(pkg: Package) -> bool - .. method:: marked_reinstall(pkg) + Return ``True`` if the package should be reinstalled. - Return ``1`` if the package should be installed. + .. method:: marked_upgrade(pkg: Package) -> bool - .. method:: marked_downgrade(pkg) + Return ``True`` if the package is marked for upgrade. - Return ``1`` if the package should be downgraded. + DepCache objects also provide several attributes containing information + on the marked changes: .. attribute:: keep_count @@ -261,52 +309,55 @@ Working with the cache The underlying :class:`Policy` object used by the :class:`DepCache` to select candidate versions. +Installing with :class:`PackageManager` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. class:: PackageManager(depcache) - Return a new :class:`PackageManager` object. The parameter *depcache* - specifies a :class:`DepCache` object. - - :class:`PackageManager` objects provide several methods and attributes, - which will be listed here: + Abstraction of a package manager. This object takes care of retrieving + packages, ordering the installation, and calling the package manager to + do the actual installation. + + .. method:: get_archives(fetcher, list, records) -> bool - .. method:: get_archives(fetcher, list, records) + Add all packages marked for installation (or upgrade, anything + which needs a download) to the :class:`Acquire` object referenced + by *fetcher*. - Add all the selected packages to the :class:`Acquire()` object - *fetcher*. + The parameter *list* specifies a :class:`SourceList` object which + is used to retrieve the information about the archive URI for the + packages which will be fetched. - The parameter *list* refers to a :class:`SourceList()` object. + The parameter *records* takes a :class:`PackageRecords` object which + will be used to look up the file name of the package. - The parameter *records* refers to a :class:`PackageRecords()` object. + .. method:: do_install(status_fd: int) -> int - .. method:: do_install() + Install the packages and return one of the class constants + :attr:`RESULT_COMPLETED`, :attr:`RESULT_FAILED`, + :attr:`RESULT_INCOMPLETE`. The argument *status_fd* can be used + to specify a file descriptor that APT will write status information + on (see README.progress-reporting in the apt source code for + information on what will be written there). - Install the packages. - - .. method:: fix_missing + .. method:: fix_missing() -> bool Fix the installation if a package could not be downloaded. .. attribute:: RESULT_COMPLETED - A constant for checking whether the the result is 'completed'. - - Compare it against the return value of :meth:`PackageManager.get_archives` - or :meth:`PackageManager.do_install`. + A constant for checking whether the the result of the call to + :meth:`do_install` is 'failed'. .. attribute:: RESULT_FAILED - A constant for checking whether the the result is 'failed'. - - Compare it against the return value of :meth:`PackageManager.get_archives` - or :meth:`PackageManager.do_install`. + A constant for checking whether the the result of the call to + :meth:`do_install` is 'failed'. .. attribute:: RESULT_INCOMPLETE - A constant for checking whether the the result is 'incomplete'. - - Compare it against the return value of :meth:`PackageManager.get_archives` - or :meth:`PackageManager.do_install`. + A constant for checking whether the the result of the call to + :meth:`do_install` is 'incomplete'. Improve performance with :class:`ActionGroup` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -318,14 +369,10 @@ Improve performance with :class:`ActionGroup` :class:`ActionGroup()` objects make operations on the cache faster by delaying certain cleanup operations until the action group is released. - ActionGroup is also a context manager and therefore supports the + An action group is also a context manager and therefore supports the :keyword:`with` statement. But because it becomes active as soon as it is created, you should not create an ActionGroup() object before entering - the with statement. - - If you want to use ActionGroup as a with statement (which is recommended - because it makes it easier to see when an actiongroup is active), always - use the following form:: + the with statement. Thus, you should always use the following form:: with apt_pkg.ActionGroup(depcache): ... @@ -337,76 +384,90 @@ Improve performance with :class:`ActionGroup` ... actiongroup.release() - :class:`ActionGroup` provides the following method: + In addition to the methods required to implement the context + manager interface, :class:`ActionGroup` objects provide the + following method: .. method:: release() Release the ActionGroup. This will reactive the collection of package garbage. -Resolving Dependencies -^^^^^^^^^^^^^^^^^^^^^^ - -.. class:: ProblemResolver(depcache) +Resolving Dependencies with :class:`ProblemResolver` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Return a new :class:`ProblemResolver` object. The parameter *depcache* - specifies a :class:`pDepCache` object. +.. class:: ProblemResolver(depcache: DepCache) - The problem resolver helps when there are problems in the package - selection. An example is a package which conflicts with another, already - installed package. + ProblemResolver objects take care of resolving problems with + dependencies. They mark packages for installation/removal and + try to satisfy all dependencies. The constructor takes a single + argument of the type :class:`apt_pkg.DepCache` to determine the + cache that shall be manipulated in order to resolve the problems. - .. method:: protect(pkg) + .. method:: clear(pkg: Package) - Protect the :class:`Package()` object given by the parameter *pkg*. - - .. todo:: - - Really document it. + Revert the action of calling :meth:`protect` or :meth:`remove` on + a package, resetting it to the default state. .. method:: install_protect() - Protect all installed packages from being removed. + Mark all protected packages for installation. - .. method:: remove(pkg) + .. method:: protect(pkg: Package) - Remove the :class:`Package()` object given by the parameter *pkg*. + Mark the package given by *pkg* as protected; that is, its state + will not be changed. - .. todo:: + .. method:: remove(pkg: Package) - Really document it. + Mark the package given by *pkg* for removal in the resolver. - .. method:: clear(pkg) + .. method:: resolve([fix_broken: bool = True]) -> bool - Reset the :class:`Package()` *pkg* to the default state. + Try to intelligently resolve problems by installing and removing + packages. If *fix_broken* is ``True``, apt will try to repair broken + dependencies of installed packages. - .. todo:: + .. method:: resolve_by_keep() -> bool - Really document it. + Try to resolve the problems without installing or removing packages. - .. method:: resolve() - Try to resolve problems by installing and removing packages. +:class:`Package` information +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. class:: Package - .. method:: resolve_by_keep() + Represent a package. A package is uniquely identified by its name + and each package can have zero or more versions which can be + accessed via the :attr:`version_list` property. Packages can be + installed and removed by a :class:`DepCache` object. - Try to resolve problems only by using keep. + Attributes: + .. attribute:: current_ver -:class:`Package` -^^^^^^^^^^^^^^^^^ -.. class:: Package + The version currently installed as a :class:`Version` object, or None + if the package is not installed. - The pkgCache::Package objects are an interface to package specific - features. + .. attribute:: has_provides + A boolean value determining whether the list available via the + attribute :attr:`provides_list` has at least one element. This + value may be used in combination with :attr:`has_versions` to + check whether a package is virtual; that is, it has no versions + and is provided at least once:: - Attributes: + pkg.has_provides and not pkg.has_versions - .. attribute:: current_ver + .. attribute:: has_versions - The version currently installed, or None. This returns a - :class:`Version` object. + A boolean value determining whether the list available via the + attribute :attr:`version_list` has at least one element. This + value may be used in combination with :attr:`has_provides` to + check whether a package is virtual; that is, it has no versions + and is provided at least once:: + + pkg.has_provides and not pkg.has_versions .. attribute:: id @@ -419,28 +480,43 @@ Resolving Dependencies .. 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.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. + A list of all package versions providing this package. Each element + of the list is a triplet, where the first element is the name of the + provided package, the second element the provided version (empty + string), and the third element the version providing this package + as a :class:`Version` object. .. attribute:: rev_depends_list An iterator of :class:`Dependency` objects for dependencies on this - package. + package. The returned iterator is implemented by the class + :class:`DependencyList`: + + .. class:: DependencyList + + A simple list-like type for representing multiple dependency + objects in an efficient manner; without having to generate + all Dependency objects in advance. + + .. describe:: list[index] + + Return the item at the position *index* in the list. + + .. method:: __len__() + + The length of the list. This method should not be used + irectly, instead Python's built-in function :func:`len` + should be used. .. attribute:: section The section of the package, as specified in the record. The list of - possible sections is defined in the Policy. + possible sections is defined in the Policy. This is a string. .. attribute:: version_list - A list of :class:`Version` objects for all versions available in the - cache. + A list of :class:`Version` objects for all versions of this package + available in the cache. **States**: @@ -467,16 +543,20 @@ Resolving Dependencies .. attribute:: auto - Whether the package was installed automatically as a dependency of - another package. (or marked otherwise as automatically installed) + This flag is here for compatibility purposes and does not appear to + be used anymore in APT. To find out whether a package is marked as + automatically installed, use :meth:`DepCache.is_auto_installed` + instead. .. attribute:: essential - Whether the package is essential. + Whether the package has the 'Essential' flag set; that is, + whether it has a field 'Essential: yes' in its record. .. attribute:: important - Whether the package is important. + Whether the package has the (obsolete) 'Important' flag set; that is, + whether it has a field 'Important: yes' in its record. Example: ~~~~~~~~~ @@ -491,23 +571,16 @@ Example: The version object contains all information related to a specific package version. - .. attribute:: ver_str - - The version, as a string. - - .. 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 The architecture of the package, eg. amd64 or all. - .. attribute:: file_list + .. attribute:: depends_list - A list of (:class:`PackageFile`, int: index) tuples for all Package - files containing this version of the package. + This is basically the same as :attr:`depends_list_str`, + but instead of the ('pkgname', 'version', 'relation') tuples, + it returns :class:`Dependency` objects, which can assist you with + useful functions. .. attribute:: depends_list_str @@ -538,44 +611,40 @@ Example: ] } - .. attribute:: depends_list + The comparison operators are not the Debian ones, but the standard + comparison operators as used in languages such as C and Python. This + means that '>' means "larger than" and '<' means "less than". - 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:: downloadable - .. attribute:: parent_pkg + Whether this package can be downloaded from a remote site. - The :class:`Package` object this version belongs to. + .. attribute:: file_list - .. attribute:: provides_list + A list of (:class:`PackageFile`, int: index) tuples for all Package + files containing this version of the package. - This returns a list of all packages provided by this version. Like - :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:: hash - .. attribute:: size + An integer hash value used for the internal storage. - The size of the .deb file, in bytes. + .. attribute:: id + + A numeric identifier which uniquely identifies this version in all + versions in the cache. .. attribute:: installed_size The size of the package (in kilobytes), when unpacked on the disk. - .. attribute:: hash - - An integer hash value. - - .. attribute:: id + .. attribute:: parent_pkg - An integer id. + The :class:`Package` object this version belongs to. .. attribute:: priority The integer representation of the priority. This can be used to speed - up comparisons a lot, compared to :attr:`Version.priority_str`. + up comparisons a lot, compared to :attr:`priority_str`. The values are defined in the :mod:`apt_pkg` extension, see :ref:`Priorities` for more information. @@ -585,13 +654,31 @@ Example: Return the priority of the package version, as a string, eg. "optional". - .. attribute:: downloadable + .. attribute:: provides_list - Whether this package can be downloaded from a remote site. + This returns a list of all packages provided by this version. Like + :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:: section + + The usual sections (eg. admin, net, etc.). Prefixed with the component + name for packages not in main (eg. non-free/admin). + + .. attribute:: size + + The size of the .deb file, in bytes. .. attribute:: translated_description - Return a :class:`Description` object. + Return a :class:`Description` object for the translated description + of this package version. + + .. attribute:: ver_str + + The version, as a string. + :class:`Dependency` @@ -616,25 +703,6 @@ Example: dependency and does not conflict with installed packages (the 'natural target'). - .. attribute:: target_ver - - The target version of the dependency, as string. Empty string if the - dependency is not versioned. - - .. attribute:: target_pkg - - The :class:`Package` object of the target package. - - .. attribute:: parent_ver - - The :class:`Version` object of the parent version, ie. the package - which declares the dependency. - - .. attribute:: parent_pkg - - The :class:`Package` object of the package which declares the - dependency. This is the same as using ParentVer.ParentPkg. - .. attribute:: comp_type The type of comparison (>=, ==, >>, <=), as string. @@ -656,6 +724,28 @@ Example: The ID of the package, as integer. + .. attribute:: parent_pkg + + The :class:`Package` object of the package which declares the + dependency. This is the same as using ParentVer.ParentPkg. + + .. attribute:: parent_ver + + The :class:`Version` object of the parent version, ie. the package + which declares the dependency. + + .. attribute:: target_pkg + + The :class:`Package` object of the target package. + + .. attribute:: target_ver + + The target version of the dependency, as string. Empty string if the + dependency is not versioned. + + The following constants describe all values the attribute *dep_type_enum* + can take: + .. attribute:: TYPE_CONFLICTS Constant for checking against dep_type_enum @@ -708,85 +798,146 @@ broken dependencies: .. attribute:: language_code - The language code of the description + The language code of the description; or, if the description + is untranslated, an empty string. .. attribute:: md5 - The md5 hashsum of the description + The MD5 checksum of the description. .. attribute:: file_list - A list of tuples (:class:`PackageFile`, int: index). + A list of tuples ``(packagefile: PackageFile, index: int)``. + +Package Pinning with :class:`Policy` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. class:: Policy(cache: apt_pkg.Cache) + + Representation of the policy of the :class:`Cache` object given by + *cache*. This provides a superset of policy-related functionality + compared to the *DepCache* class. The DepCache can be used for most + purposes, but there may be some cases where a special policy class + is needed. + + .. method:: create_pin(type: str, pkg: str, data: str, priority: int) + + Create a pin for the policy. The parameter *type* refers to one of the + strings 'Version', 'Release', or 'Origin'. The argument *pkg* is the + name of the package. The parameter *data* refers to the value (such + as 'unstable' for type='Release') and the other possible options. + The parameter 'priority' gives the priority of the pin. + + .. method:: get_candidate_ver(package: apt_pkg.Package) -> apt_pkg.Version + Get the best package for the job; that is, the package with the + highest pin priority. + .. method:: get_match(package: apt_pkg.Package) -> apt_pkg.Version -Index Files -------------- + Get a version for the package. + + .. method:: get_priority(package: apt_pkg.Package) -> int + + Get the pin priority of the package given by *package*. + + .. method:: read_pindir(dirname: str) -> bool + + Read the pin files in the given dir (e.g. '/etc/apt/preferences.d') + and add them to the policy. + + .. method:: read_pinfile(filename: str) -> bool + Read the pin file given by *filename* (e.g. '/etc/apt/preferences') + and add it to the policy. -.. todo:: - Complete them +Index Files +------------- .. class:: MetaIndex + Represent a Release file as stored in the cache. + .. attribute:: uri + + The URI the meta index file is located at, as a string. + .. attribute:: dist + + The distribution stored in the meta index, as a string. + .. attribute:: is_trusted + + A boolean value determining whether the meta index can be trusted. This + is ``True`` for signed Release files. + .. attribute:: index_files + A list of all :class:`IndexFile` objects associated with this meta + index. + .. class:: IndexFile - .. method:: archive_uri(path) + Represent an index file, that is, package indexes, translation indexes, + and source indexes. + + .. method:: archive_uri(path: str) -> str - Return the full url to path in the archive. + Return the URI to the given path in the archive. .. attribute:: label - Return the Label. + The label of the index file. .. attribute:: describe - A description of the :class:`IndexFile`. + A string describing this object. .. attribute:: exists - Return whether the file exists. + A boolean value determining whether the index file exists. .. attribute:: has_packages - Return whether the file has packages. + A boolean value determining whether the index file has packages. .. attribute:: size - Size of the file + The size of the file, measured in bytes. .. attribute:: is_trusted - Whether we can trust the file. + A boolean value determining whether the file can be trusted; that is, + because it is from a source with a GPG signed Release file. + .. class:: PackageFile - A :class:`PackageFile` represents a Packages file, eg. - /var/lib/dpkg/status. + Provide access to an index file stored in the cache, such as + :file:`/var/lib/dpkg/status`. .. attribute:: architecture - The architecture of the package file. + The architecture of the package file. This attribute normally + contains an empty string and is thus not very useful. .. attribute:: archive - The archive (eg. unstable) + The archive of the package file as set in the Release file via + the "Suite" field. If there is no Release file, this is an empty + string. .. attribute:: component - The component (eg. main) + The component of the package file, if it is provided by a repository + using the dists/ hierarchy. For other packages files, this property + is an empty string. .. attribute:: filename - The name of the file. + The path to the file on the local filesystem. .. attribute:: id @@ -795,22 +946,26 @@ Index Files .. attribute:: index_type - The sort of the index file. In normal cases, this is - 'Debian Package Index'. + A string describing the type of index. Known values are + "Debian Package Index", "Debian Translation Index", and + "Debian dpkg status file". .. attribute:: label - The Label, as set in the Release file + The label of the package file as set in the release file + via the 'Label' field. If there is no Release file, this + attribute is an empty string. .. attribute:: not_automatic Whether packages from this list will be updated automatically. The - default for eg. example is 0 (aka false). + default for example is False. .. 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. + case, the value is ``True``; else ``False``. For example, it is + ``False`` for :file:`/var/lib/dpkg/status`. Example:: @@ -835,30 +990,49 @@ Index Files The version, as set in the release file (eg. "4.0" for "Etch") - The following example shows how to use PackageFile: .. literalinclude:: ../examples/cache-pkgfile.py -Records --------- +Records (Release files, Packages, Sources) +------------------------------------------ + +.. class:: IndexRecords() + + Represent a Release file and provide means to read information from + the file. This class provides several methods: + + .. method:: get_dist() -> str + + Return the distribution set in the Release file. + + .. method:: load(filename: str) + + Load the file located at the path given by *filename*. + + .. method:: lookup(key: str) -> (HashString, int) -.. class:: PackageRecords(cache) + Look up the filename given by *key* and return a tuple (hash, size), + where the first element *hash* is a :class:`HashString` object + and the second element *size* is an int object. - Create a new :class:`PackageRecords` object, for the packages in the cache - specified by the parameter *cache*. - Provide access to the packages records. This provides very useful - attributes for fast (convient) access to some fields of the record. +.. class:: PackageRecords(cache: apt_pkg.Cache) - .. method:: lookup(verfile_iter) + Provide further information about the packages in the :class:`Cache` object + *cache*. This efficiently parses the package files to provide information + not available in the cache, such as maintainer, hash sums, description, + and the file name of the package. It also provides the complete record + of the package. + + .. method:: lookup(verfile_iter: (PackageFile, int)) -> bool 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.file_list`. + ``file_list`` attributes such as :attr:`Version.file_list`. Example (shortened):: @@ -891,11 +1065,14 @@ Records .. attribute:: source_pkg - Return the source package. + The name of the source package, if different from the name of the + binary package. This information is retrieved from the 'Source' field. .. attribute:: source_ver - Return the source version. + The version of the source package, if it differs from the version + of the binary package. Just like 'source_pkg', this information + is retrieved from the 'Source' field. .. attribute:: maintainer @@ -934,9 +1111,9 @@ Records .. class:: SourceRecords - This represents the entries in the Sources files, ie. the dsc files of - the source packages. - + Provide an easy way to look up the records of source packages and + provide easy attributes for some widely used fields of the record. + .. note:: If the Lookup failed, because no package could be found, no error is @@ -944,72 +1121,74 @@ Records anymore (same applies when no Lookup has been made, or when it has been restarted). - .. method:: lookup(pkgname) + .. method:: lookup(pkgname: str) -> bool - Lookup the record for the package named *pkgname*. To access all - available records, you need to call it multiple times. + Look up the source package with the given name. Each call moves + the position of the records parser forward. If there are no + more records, return None. If the lookup failed this way, + access to any of the attributes will result in an + :exc:`AttributeError`. 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. + version Y. A third call would return ``None`` and access to any + of the below attributes will result in an :exc:`AttributeError` .. method:: restart() - Restart the lookup. + Restart the lookup process. This moves the parser to the first + package and lookups can now be made just like on a new object. 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. + 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:: binaries - .. attribute:: package + 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. - The name of the source package. + .. attribute:: build_depends - .. attribute:: version + 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"``. - A string describing the version of the source package. + .. attribute:: files + + The list of files. This returns a list of tuples with the contents + ``(str: md5, int: size, str: path, str:type)``, where + 'type' can be 'diff' (includes .debian.tar.gz), 'dsc', 'tar'. + + .. attribute:: index + + A list of :class:`IndexFile` objects associated with this + source package record. .. attribute:: maintainer A string describing the name of the maintainer. - .. attribute:: section + .. attribute:: package - A string describing the section. + The name of the source package. .. attribute:: record The whole record, as a string. You can use :func:`apt_pkg.ParseSection` - if you need to parse it. - - You need to parse the record if you want to access fields not available - via the attributes, eg. 'Standards-Version' - - .. 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 - - The index in the Sources files. - - .. attribute:: files + if you need to parse it. You need to parse the record to access + fields not available via the attributes such as 'Standards-Version' - The list of files. This returns a list of tuples with the contents - ``(str: md5, int: size, str: path, str:type)``. + .. attribute:: section - .. attribute:: build_depends + A string describing the section. - 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:: version + A string describing the version of the source package. The Acquire interface ---------------------- @@ -1021,119 +1200,187 @@ you to implement file downloading in your applications. Together with the :class:`PackageManager` class you can also fetch all the packages marked for installation. +.. class:: Acquire([progress: apt.progress.base.AcquireProgress]) -.. class:: Acquire([progress]) - - Return an :class:`Acquire` object. The parameter *progress* refers to - an :class:`apt.progress.FetchProgress()` object. + Coordinate the retrieval of files via network or local file system + (using ``copy://path/to/file`` style URIs). Items can be added to + an Acquire object using various means such as creating instances + of :class:`AcquireFile` or the methods :meth:`SourceList.get_indexes` + and :meth:`PackageManager.get_archives`. - Acquire objects maintaing a list of items which will be fetched or have + Acquire objects maintain a list of items which will be fetched or have been fetched already during the lifetime of this object. To add new items to this list, you can create new :class:`AcquireFile` objects which allow you to add single files. - Acquire items have multiple methods and attributes: + The constructor takes an optional parameter *progress* which takes an + :class:`apt.progress.base.AcquireProgress` object. This object may then + report progress information (see :mod:`apt.progress.text` for reporting + progress to a I/O stream and :mod:`apt.progress.gtk2` for GTK+ progress + reporting). + + Acquire items have two methods to start and stop the fetching: - .. method:: run() + .. method:: run() -> int - Fetch all the items which have been added by :class:`AcquireFile`. + Fetch all the items which have been added by :class:`AcquireFile` and + return one of the constants :attr:`RESULT_CANCELLED`, + :attr:`RESULT_CONTINUE`, :attr:`RESULT_FAILED` to describe the + result of the run. .. method:: shutdown() - Shut the fetcher down. + Shut the fetcher down. This removes all items from the queue and + makes all :class:`AcquireItem`, :class:`AcquireWorker`, + :class:`AcquireItemDesc` objects useless. Accessing an object of one + of those types can cause a segfault then. - .. attribute:: total_needed + Removing an item does not mean that the already fetched data will + be removed from the destination. Instead, APT might use the partial + result and continue from thereon. - The total amount of bytes needed (including those of files which are - already present) + Furthermore, they provide three attributes which provide information + on how much data is already available and how much data still needs + to be fetched: .. attribute:: fetch_needed - The total amount of bytes which need to be fetched. + The amount of data that has to be fetched in order to fetch all + queued items. .. attribute:: partial_present - Whether some files have been acquired already. (???) + The amount of data which is already available. + + .. attribute:: total_needed + + The total amount of bytes needed (including those of files which are + already present). + + They also provide two attributes representing the items being processed + and the workers fetching them: .. attribute:: items A list of :class:`AcquireItem` objects which are attached to the - queue of this object. + to this Acquire object. This includes all items ever attached to + this object (except if they were removed using, for example, + :meth:`shutdown()` or by deleting an :class:`AcquireFile` object.) .. attribute:: workers A list of :class:`AcquireWorker` objects which are currently active on this instance. -.. class:: AcquireItem + The Acquire class comes with three constants which represents the results + of the :meth:`run` method: - 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` - list of an :class:`Acquire` object. + .. attribute:: RESULT_CANCELLED - .. attribute:: id + The fetching has been aborted, e.g. due to a progress class returning + ``False`` in its :meth:`pulse()` method. - The ID of the item. + .. attribute:: RESULT_CONTINUE - .. attribute:: complete + All items have been fetched successfully and the process has not been + canceled. - Is the item completely acquired? + .. attribute:: RESULT_FAILED - .. attribute:: local + An item failed to fetch due to some reasons. - Is the item a local file? - .. attribute:: mode +.. class:: AcquireItem - A string indicating the current mode e.g. ``"Fetching"``. + An AcquireItem object represents a single item of an :class:`Acquire` + object. It is an abstract class to represent various types of items + which are implemented as subclasses. The only exported subclass is + :class:`AcquireFile` which can be used to fetch files. - .. attribute:: is_trusted + .. attribute:: complete - Can the file be trusted? + A boolean value which is True only if the item has been + fetched successfully. - .. attribute:: filesize + .. attribute:: desc_uri - The size of the file, in bytes. + An URI describing where the item is located at. + + .. attribute:: destfile + + The path to the local location where the fetched data will be + stored at. .. attribute:: error_text - The error message. For example, when a file does not exist on a http + 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:: filesize - The location the file is saved as. + The size of the file, in bytes. If the size of the to be fetched file + is unknown, this attribute is set to ``0``. - .. attribute:: desc_uri + .. attribute:: id - The source location. + The ID of the item. This attribute is normally set to ``0``, users may + set a custom value here, for instance in an overridden + :meth:`apt.progress.base.AcquireProgress.fetch` method (the progress + class could keep a counter, increase it by one for every :meth:`fetch` + call and assign the current value to this attribute). - **Status**: + .. attribute:: is_trusted - .. attribute:: status + A boolean value determining whether the file is trusted. Only ``True`` + if the item represents a package coming from a repository which is + signed by one of the keys in APT's keyring. - Integer, representing the status of the item. + .. attribute:: local - .. attribute:: STAT_IDLE + A boolean value determining whether this file is locally available + (``True``) or whether it has to be fetched from a remote source + (``False``). - Constant for comparing :attr:`AcquireItem.status`. + .. attribute:: mode - .. attribute:: STAT_FETCHING + A localized string indicating the current mode e.g. ``"Fetching"``, + it may be used as part of printing progress information. + + **Status**: + + The following attribute represents the status of the item. This class + provides several constants for comparing against this value which are + listed here as well. + + .. attribute:: status + + Integer, representing the status of the item. This attribute can be + compared against the following constants to gain useful information + on the item's status. + + .. attribute:: STAT_AUTH_ERROR - Constant for comparing :attr:`AcquireItem.status` + An authentication error occurred while trying to fetch the item. .. attribute:: STAT_DONE - Constant for comparing :attr:`AcquireItem.status` + The item is completely fetched and there have been no problems + while fetching the item. .. attribute:: STAT_ERROR - Constant for comparing :attr:`AcquireItem.status` + An error occurred while trying to fetch the item. This error is + normally not related to authentication problems, as thus are + dealt with using :attr:`STAT_AUTH_ERROR`. - .. attribute:: STAT_AUTH_ERROR + .. attribute:: STAT_FETCHING + + The item is being fetched currently. + + .. attribute:: STAT_IDLE + + The item is yet to be fetched. - Constant for comparing :attr:`AcquireItem.status` .. class:: AcquireFile(owner, uri[, md5, size, descr, short_descr, destdir, destfile]) @@ -1154,22 +1401,34 @@ installation. The parameter *size* can be used to specify the size of the package, 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 + The parameter *descr* is a description of the download. It may be 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. + The parameters *descr* and *short_descr* can be used to specify + descriptions for the item. The string passed to *descr* should + describe the file and its origin (e.g. "http://localhost sid/main + python-apt 0.7.94.2") and the string passed to *short_descr* should + be one word such as the name of a package. + + Normally, the file will be stored in the current directory using the + file name given in the URI. This directory can be changed by passing + the name of a directory to the *destdir* parameter. It is also possible + to set a path to a file using the *destfile* parameter, but both can + not be specified together. In terms of attributes, this class is a subclass of :class:`AcquireItem` and thus inherits all its attributes. .. class:: AcquireWorker - An :class:`AcquireWorker` object represents a subprocess responsible for - fetching files from remote locations. This class is not instanciable from - Python. + An :class:`AcquireWorker` object represents a sub-process responsible for + fetching files from remote locations. There is no possibility to create + instances of this class from within Python, but a list of objects of + currently active workers is provided by :attr:`Acquire.workers`. + + Objects of this type provide several attributes which give information + about the worker's current activity. .. attribute:: current_item @@ -1183,22 +1442,25 @@ installation. .. attribute:: resumepoint - The amount of the file that was already downloaded prior to starting - this worker. + The amount of data which was already available when the download was + started. .. attribute:: status - The most recent status string received from the subprocess. + The most recent (localized) status string received from the + sub-process. .. attribute:: total_size - The total number of bytes to be downloaded. Zero if the total size is - unknown. + The total number of bytes to be downloaded for the item. Zero if the + total size is unknown. .. class:: AcquireItemDesc An :class:`AcquireItemDesc` object stores information about the item which - can be used to describe the item. + can be used to describe the item. Objects of this class are used in the + progress classes, see the :class:`apt.progress.base.AcquireProgress` + documentation for information how. .. attribute:: description @@ -1214,102 +1476,7 @@ installation. .. attribute:: uri - The URI from which to download this item. - -.. class:: AcquireProgress - - A 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. - - Methods defined here: - - .. method:: done(item: AcquireItemDesc) - - Invoked when an item is successfully and completely fetched. - - .. method:: fail(item: AcquireItemDesc) - - Invoked when the process of fetching an item encounters a fatal error. - - .. method:: fetch(item: AcquireItemDesc) - - Invoked when some of an item's data is fetched. - - .. method:: ims_hit(item: AcquireItemDesc) - - 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. - - .. method:: media_change(media: str, drive: str) -> bool - - Invoked when the user should be prompted to change the inserted - removable media. - - This method should not return until the user has confirmed to the user - interface that the media change is complete. - - The parameter *media* is the name of the media type that should be - changed, the parameter *drive* is the identifying name of the drive - whose media should be changed. - - Return True if the user confirms the media change, False if it is - cancelled. - - .. method:: pulse(owner: Acquire) -> bool - - Periodically invoked while the Acquire process is underway. - - Return False if the user asked to cancel the whole Acquire process. - - .. method:: start() - - Invoked when the Acquire process starts running. - - .. method:: stop() - - Invoked when the Acquire process stops running. - - There are also some data descriptors: - - .. attribute:: current_bytes - - The number of bytes fetched. - - .. attribute:: current_cps - - The current rate of download, in bytes per second. - - .. attribute:: current_items - - The number of items that have been successfully downloaded. - - .. attribute:: elapsed_time - - The amount of time that has elapsed since the download started. - - .. attribute:: fetched_bytes - - The total number of bytes accounted for by items that were - successfully fetched. - - .. attribute:: last_bytes - - The number of bytes fetched as of the previous call to pulse(), - including local items. - - .. attribute:: total_bytes - - The total number of bytes that need to be fetched. This member is - inaccurate, as new items might be enqueued while the download is - in progress! - - .. attribute:: total_items - - The total number of items that need to be fetched. This member is - inaccurate, as new items might be enqueued while the download is - in progress! + The URI from which this item would be downloaded. Hashes @@ -1324,7 +1491,7 @@ generic hash support: .. class:: Hashes(object) Calculate all supported hashes of the object. *object* may either be a - string, in which cases the hashes of the string are calculated, or a + string, in which cases the hashes of the string are calculated; or a :class:`file()` object or file descriptor, in which case the hashes of its contents is calculated. The calculated hashes are then available via attributes: @@ -1341,13 +1508,19 @@ generic hash support: The SHA256 hash of the data, as string. -.. class:: HashString(type: str, hash: str) +.. class:: HashString(type: str[, hash: str]) HashString objects store the type of a hash and the corresponding hash. They are used by e.g :meth:`IndexRecords.lookup`. The first parameter, - *type* refers to one of MD5Sum, SHA1 and SHA256. The second parameter + *type* refers to one of "MD5Sum", "SHA1" and "SHA256". The second parameter *hash* is the corresponding hash. + You can also use a combined form by passing a string with type and hash + separated by a colon as the only argument. For example:: + + HashString("MD5Sum:d41d8cd98f00b204e9800998ecf8427e") + + .. describe:: str(hashstring) Convert the HashString to a string by joining the hash type and the @@ -1355,12 +1528,13 @@ generic hash support: .. attribute:: hashtype - The type of the hash. This may be MD5Sum, SHA1 or SHA256. + The type of the hash, as a string. This may be "MD5Sum", "SHA1" + or "SHA256". .. method:: verify_file(filename: str) -> bool - Verify that the file given by the parameter *filename* matches the hash - stored in this object. + Verify that the file given by the parameter *filename* matches the + hash stored in this object. The :mod:`apt_pkg` module also provides the functions :func:`md5sum`, :func:`sha1sum` and :func:`sha256sum` for creating a single hash from a @@ -1373,7 +1547,7 @@ The :mod:`apt_pkg` module also provides the functions :func:`md5sum`, object (or a file descriptor), in which case the md5sum of its contents is returned. - .. versionchanged:: 0.8.0 + .. versionchanged:: 0.7.100 Added support for using file descriptors. .. function:: sha1sum(object) @@ -1383,7 +1557,7 @@ The :mod:`apt_pkg` module also provides the functions :func:`md5sum`, object (or a file descriptor), in which case the sha1sum of its contents is returned. - .. versionchanged:: 0.8.0 + .. versionchanged:: 0.7.100 Added support for using file descriptors. .. function:: sha256sum(object) @@ -1393,7 +1567,7 @@ The :mod:`apt_pkg` module also provides the functions :func:`md5sum`, object (or a file descriptor), in which case the sha256sum of its contents is returned. - .. versionchanged:: 0.8.0 + .. versionchanged:: 0.7.100 Added support for using file descriptors. Debian control files @@ -1443,19 +1617,20 @@ section as a string. tagf.step() print tagf.section['Package'] - .. method:: step + .. method:: step() -> bool - Step forward to the next section. This simply returns ``1`` if OK, and - ``0`` if there is no section. + Step forward to the next section. This simply returns ``True`` if OK, + and ``False`` if there is no section. - .. method:: offset + .. method:: offset() -> int Return the current offset (in bytes) from the beginning of the file. - .. method:: jump(offset) + .. method:: jump(offset) -> bool Jump back/forward to *offset*. Use ``jump(0)`` to jump to the - beginning of the file again. + beginning of the file again. Returns ``True`` if a section could + be parsed or ``False`` if not. .. attribute:: section @@ -1476,24 +1651,29 @@ section as a string. .. versionadded:: 0.8.0 - .. method:: bytes + .. method:: bytes() -> int The number of bytes in the section. - .. method:: find(key, default='') + .. method:: find(key: str, default: str = '') -> str Return the value of the field at the key *key* if available, else return *default*. - .. method:: find_flag(key) + .. method:: find_flag(key: str) -> bool Find a yes/no value for the key *key*. An example for such a field is 'Essential'. - .. method:: get(key, default='') + .. method:: find_raw(key: str, default: str = '') -> str + + Similar to :meth:`find`, but instead of returning just the value, + it returns the complete field consisting of 'key: value'. + + .. method:: get(key: str, default: str = '') Return the value of the field at the key *key* if available, else - return *default*. + return *default*. .. method:: keys() @@ -1511,7 +1691,7 @@ section as a string. package and source sections, respectively. The parameter *rewrite_list* is a list of tuples of the form - ``(tag, newvalue[, renamed_to])``, whereas *tag* describes the field which + ``(tag, newvalue[, renamed_to])``, where *tag* describes the field which should be changed, *newvalue* the value which should be inserted or ``None`` to delete the field, and the optional *renamed_to* can be used to rename the field. @@ -1528,14 +1708,16 @@ section as a string. Dependencies ------------ -.. function:: check_dep(pkgver, op, depver) - - Check that the dependency requirements consisting of op and depver can be - satisfied by the version pkgver. +.. function:: check_dep(pkgver: str, op: str, depver: str) -> bool - Example:: + Check that the given requirement is fulfilled; that is, that the version + string given by *pkg_ver* matches the version string *dep_ver* under + the condition specified by the operator 'dep_op' (<,<=,=,>=,>). + + Return True if *pkg_ver* matches *dep_ver* under the condition 'dep_op'; + for example:: - >>> bool(apt_pkg.check_dep("1.0", ">=", "1")) + >>> apt_pkg.check_dep("1.0", ">=", "1") True The following two functions provide the ability to parse dependencies. They @@ -1589,18 +1771,31 @@ use the same format as :attr:`Version.depends_list_str`. is specified in control files. -Configuration -------------- +Configuration and Command-line parsing +-------------------------------------- .. class:: Configuration() - Configuration() objects store the configuration of apt, mostly created - from the contents of :file:`/etc/apt.conf` and the files in - :file:`/etc/apt.conf.d`. + Provide access to and manipulation of APT's configuration which is + used by many classes and functions in this module to define their + behavior. There are options to install recommends, change the root + directory and much more. For an (incomplete) list of available options, + see the :manpage:`apt.conf(5)` manual page. + + The most important Configuration object is the one available by the + module's :attr:`apt_pkg.config` attribute. It stores the global + configuration which affects the behavior of most functions and is + initialized by a call to the function :func:`init_config`. While + possible, it is generally not needed to create other instances of + this class. + + For accessing and manipulating the configuration space, objects + of this type provide an interface which resembles Python mapping + types like :class:`dict`. .. describe:: key in conf - Return ``True`` if *conf* has a key *key*, else ``False``. + Return ``True`` if *conf* has a key *key*, else ``False``. .. describe:: conf[key] @@ -1611,115 +1806,184 @@ Configuration Set the option at *key* to *value*. - .. method:: find(key[, default='']) + .. describe del conf[key] - Return the value for the given key *key*. This is the same as - :meth:`Configuration.get`. + Delete the option with the name *key* in the configuration object + *conf*. - If *key* does not exist, return *default*. + .. method:: get(key[, default='']) -> str - .. method:: find_file(key[, default='']) + Find the value for the given key and return it. If the given key does + not exist, return *default* instead. - Return the filename hold by the configuration at *key*. This formats the - filename correctly and supports the Dir:: stuff in the configuration. + In addition, they provide methods to resemble the interface provided + by the C++ class and some more mapping methods which have been enhanced + to support some more advanced configuration features: - If *key* does not exist, return *default*. + .. method:: clear(key: str) - .. method:: find_dir(key[, default='/']) + Remove the option at *key* and all of its children. - Return the absolute path to the directory specified in *key*. A - trailing slash is appended. + .. method:: exists(key) - If *key* does not exist, return *default*. + Check whether an option named *key* exists in the configuration. - .. method:: find_i(key[, default=0]) + .. method:: find(key[, default='']) -> str - Return the integer value stored at *key*. + Return the value stored at the option named *key*, or the value + given by the string *default* if the option in question is not + set. - If *key* does not exist, return *default*. + .. method:: find_b(key[, default=False]) -> bool - .. method:: find_b(key[, default=0]) + Return the boolean value stored at *key*, or the value given by + the :class:`bool` object *default* if the requested option is + not set. - Return the boolean value stored at *key*. This returns an integer, but - it should be treated like True/False. + .. method:: find_file(key[, default='']) -> str + find_dir(key[, default='/']) -> str - If *key* does not exist, return *default*. + Locate the given key using :meth:`find` and return the path to the + file/directory. This uses a special algorithms which moves upwards + in the configuration space and prepends the values of the options + to the result. These methods are generally used for the options + stored in the 'Dir' section of the configuration. - .. method:: set(key, value) + As an example of how this works, take a look at the following options + and their values: - Set the value of *key* to *value*. + .. table:: - .. method:: exists(key) + ============== =========================== + Option Value + ============== =========================== + Dir / + Dir::Etc etc/apt/ + Dir::Etc::main apt.conf + ============== =========================== - Check whether the key *key* exists in the configuration. + A call to :meth:`find_file` would now return ``/etc/apt/apt.conf`` + because it prepends the values of "Dir::Etc" and "Dir" to the value + of "Dir::Etc::main":: - .. method:: subtree(key) + >>> apt_pkg.config.find_file("Dir::Etc::main") + '/etc/apt/apt.conf' - Return a sub tree starting at *key*. The resulting object can be used - like this one. + If the special configuration variable "RootDir" is set, this value + would be prepended to every return value, even if the path is already + absolute. If not, the function ends as soon as an absolute path is + created (once an option with a value starting with "/" is read). - .. method:: list([key]) + The method :meth:`find_dir` does exactly the same thing as + :meth:`find_file`, but adds a trailing forward slash before + returning the value. - List all items at *key*. Normally, return the keys at the top level, - eg. APT, Dir, etc. + .. method:: find_i(key[, default=0]) -> int - Use *key* to specify a key of which the childs will be returned. + Return the integer value stored at *key*, or the value given by + the integer *default* if the requested option is not set. - .. method:: value_list([key]) + .. method:: keys([key]) + + Return a recursive list of all configuration options or, if *key* + is given, a list of all its children. This method is comparable + to the **keys** method of a mapping object, but additionally + provides the parameter *key*. + + .. method:: list([key]) - Same as :meth:`Configuration.list`, but this time for the values. + Return a non-recursive list of all configuration options. If *key* + is not given, this returns a list of options like "Apt", "Dir", and + similar. If *key* is given, a list of the names of its child options + will be returned instead. .. 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. + Return the tag name of the current tree. Normally (for + :data:`apt_pkg.config`) this is an empty string, but for + sub-trees it is the key of the sub-tree. - .. method:: clear(key) + .. method:: set(key: str, value: str) - Clear the configuration. Remove all values and keys at *key*. + Set the option named *key* to the value given by the argument + *value*. It is possible to store objects of the types :class:`int` + and :class:`bool` by calling :func:`str` on them to convert them + to a string object. They can then be retrieved again by using the + methods :meth:`find_i` or :meth:`find_b`. - .. method:: keys([key]) + .. method:: subtree(key) - Return all the keys, recursive. If *key* is specified, ... (FIXME) + Return a new apt_pkg.Configuration object which starts at the + given option. Example:: - .. method:: get(key[, default='']) + apttree = config.subtree('APT') + apttree['Install-Suggests'] = config['APT::Install-Suggests'] - This behaves just like :meth:`dict.get` and :meth:`Configuration.find`, - it returns the value of key or if it does not exist, *default*. + The configuration space is shared with the main object which means + that all modifications in one object appear in the other one as + well. -.. data:: config + .. method:: value_list([key]) - A :class:`Configuration()` object with the default configuration. This - object is initialized by calling :func:`init_config`. + This is the opposite of the :meth:`list` method in that it returns the + values instead of the option names. +.. data:: config + + This variable contains the global configuration which is used by + all classes and functions in this module. After importing the + module, this object should be initialized by calling the module's + :func:`init_config` function. -.. function:: read_config_file(configuration, filename) +.. function:: read_config_file(configuration: Configuration, filename: str) - Read the configuration file specified by the parameter *filename* and add - the settings therein to the :class:`Configuration()` object specified by - the parameter *configuration* + Read the configuration file *filename* and set the appropriate + options in the configuration object *configuration*. .. 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*. + Read all configuration files in the dir given by 'dirname' in the + correct order. + .. 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* + Read the configuration file *filename* and set the appropriate + options in the configuration object *configuration*. This function + requires a slightly different format than APT configuration files, + if you are unsure, do not use it. .. 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 - list of tuples of the form ``('c',"long-opt or None", - "Configuration::Variable","optional type")``. + Parse the command line in *argv* into the configuration space. The + list *options* contains a list of 3-tuples or 4-tuples in the form:: + + (short_option: str, long_option: str, variable: str[, type: str]) + + The element *short_option* is one character, the *long_option* element + is the name of the long option, the element *variable* the name of the + configuration option the result will be stored in and *type* is one of + 'HasArg', 'IntLevel', 'Boolean', 'InvBoolean', 'ConfigFile', + 'ArbItem'. The default type is 'Boolean'. + + .. table:: Overview of all possible types + + =========== ===================================================== + Type What happens if the option is given + =========== ===================================================== + HasArg The argument given to the option is stored in + the target. + IntLevel The integer value in the target is increased by one + Boolean The target variable is set to True. + InvBoolean The target variable is set to False. + ConfigFile The file given as an argument to this option is read + in and all configuration options are added to the + configuration object (APT's '-c' option). + ArbItem The option takes an argument *key*=*value*, and the + configuration option at *key* is set to the value + *value* (APT's '-o' option). + =========== ===================================================== - Where ``type`` may be one of HasArg, IntLevel, Boolean, InvBoolean, - ConfigFile, or ArbItem. The default is Boolean. Locking -------- @@ -1734,7 +1998,7 @@ locking the package system or file-based locking. __exit__() is called. If the lock can not be acquired or can not be released an exception is raised. - This should be used via the 'with' statement, e.g.:: + This should be used via the 'with' statement. For example:: with apt_pkg.SystemLock(): ... # Do your stuff here. @@ -1756,7 +2020,7 @@ locking the package system or file-based locking. __exit__() is called. If the lock can not be acquired or can not be released, an exception is raised. - This should be used via the 'with' statement, e.g.:: + This should be used via the 'with' statement. For example:: with apt_pkg.FileLock(filename): ... @@ -1773,7 +2037,7 @@ locking the package system or file-based locking. For Python versions prior to 2.5, similar functionality is provided by the following three functions: -.. function:: get_lock(filename, errors=False) -> int +.. function:: get_lock(filename: str, errors=False) -> int Create an empty file at the path specified by the parameter *filename* and lock it. If this fails and *errors* is **True**, the function raises an @@ -1800,35 +2064,56 @@ Other classes -------------- .. class:: Cdrom() - Return a Cdrom object with the following methods: + A Cdrom object identifies Debian installation media and adds them to + :file:`/etc/apt/sources.list`. The C++ version of this class is used by + the apt-cdrom tool and using this class, you can re-implement apt-cdrom + in Python, see :doc:`../tutorials/apt-cdrom`. + + The class :class:`apt.cdrom.Cdrom` is a subclass of this class and + provides some additional functionality for higher level use and some + shortcuts for setting some related configuration options. - .. method:: ident(progress) + This class provides two functions which take an instance of + :class:`apt.progress.base.CdromProgress` as their argument. - Identify the cdrom. The parameter *progress* refers to an - :class:`apt.progress.CdromProgress()` object. + .. method:: add(progress: apt.progress.base.CdromProgress) -> bool - .. method:: add(progress) + Search for a Debian installation media and add it to the list of + sources stored in :file:`/etc/apt/sources.list`. On success, the + boolean value ``True`` is returned. If the process failed or was + canceled by the progress class, :exc:`SystemError` is raised or + ``False`` is returned. - Add the cdrom to the sources.list file. The parameter *progress* - refers to an :class:`apt.progress.CdromProgress()` object. + .. method:: ident(progress: apt.progress.base.CdromProgress) -> str + + Identify the installation media and return a string which describes + its identity. If no media could be identified, :exc:`SystemError` is + raised or ``None`` is returned. .. class:: SourceList - This is for :file:`/etc/apt/sources.list`. + Represent the list of sources stored in files such as + :file:`/etc/apt/sources.list`. - .. method:: find_index(pkgfile) + .. method:: find_index(pkgfile: PackageFile) -> IndexFile - Return a :class:`IndexFile` object for the :class:`PackageFile` - *pkgfile*. + Return the :class:`IndexFile` object for the :class:`PackageFile` + object given by the argument *pkgfile*. If no index could be found, + return ``None``. - .. method:: read_main_list + .. method:: get_indexes(acquire: Acquire[, all: bool = False]) -> bool - Read the main list. + Add all indexes to the :class:`Acquire` object given by the argument + *acquire*. If *all* is ``True``, all indexes will be added, otherwise + only the meta indexes (Release files) will be added and others are + fetched as needed. - .. method:: get_indexes(acq[, all]) + .. method:: read_main_list() -> bool - Add the index files to the :class:`Acquire()` object *acq*. If *all* is - given and ``True``, all files are fetched. + Read the files configured in Dir::Etc::SourceList and + Dir::Etc::sourceparts; that is (on normal system), + :file:`/etc/apt/sources.list` and the files in + :file:`/etc/apt/sources.list.d`. .. attribute:: list @@ -1836,20 +2121,26 @@ Other classes String functions ---------------- -.. function:: base64_encode(string) +.. function:: base64_encode(value: bytes) -> str - Encode the given string using base64, e.g:: + Encode the given bytes string (which may not contain a null byte) + using base64, for example, on Python 3 and newer:: - >>> apt_pkg.base64_encode(u"A") + >>> apt_pkg.base64_encode(b"A") 'QQ==' + on Python versions prior to 3, the 'b' before the string has to be + omitted. + .. function:: check_domain_list(host, list) - See if Host is in a ',' separated list, e.g.:: + See if the host name given by *host* is one of the domains given in the + comma-separated list *list* or a subdomain of one of them. - apt_pkg.check_domain_list("alioth.debian.org","debian.net,debian.org") + >>> apt_pkg.check_domain_list("alioth.debian.org","debian.net,debian.org") + True -.. function:: dequote_string(string) +.. function:: dequote_string(string: str) Dequote the string specified by the parameter *string*, e.g.:: @@ -1858,17 +2149,17 @@ String functions .. 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: + Escape the string *string*, replacing any character not allowed in a URL + or specified by *repl* with its ASCII value preceded by a percent sign + (so for example ' ' becomes '%20'). >>> apt_pkg.quote_string("apt is cool","apt") '%61%70%74%20is%20cool' -.. function:: size_to_str(size) +.. function:: size_to_str(size: int) - 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 - factor 1000. + Return a string describing the size in a human-readable manner using + SI prefix and base-10 units, e.g. '1k' for 1000, '1M' for 1000000, etc. Example:: @@ -1898,6 +2189,7 @@ String functions >>> apt_pkg.string_to_bool("not-recognized") -1 + .. function:: str_to_time(rfc_time) Convert the :rfc:`1123` conforming string *rfc_time* to the unix time, and @@ -1908,7 +2200,7 @@ String functions >> apt_pkg.str_to_time('Thu, 01 Jan 1970 00:00:00 GMT') 0 -.. function:: time_rfc1123(seconds) +.. function:: time_rfc1123(seconds: int) -> str Format the unix time specified by the integer *seconds*, according to the requirements of :rfc:`1123`. @@ -1919,7 +2211,7 @@ String functions 'Thu, 01 Jan 1970 00:00:00 GMT' -.. function:: time_to_str(seconds) +.. function:: time_to_str(seconds: int) -> str 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 @@ -1930,12 +2222,12 @@ String functions >>> apt_pkg.time_to_str(3601) '1h0min1s' -.. function:: upstream_version(version) +.. function:: upstream_version(version: str) -> str - Return the string *version*, eliminating everything following the last - '-'. Thus, this should be equivalent to ``version.rsplit('-', 1)[0]``. + Return the upstream version for the Debian package version given by + *version*. -.. function:: uri_to_filename(uri) +.. function:: uri_to_filename(uri: str) -> str Take a string *uri* as parameter and return a filename which can be used to store the file, based on the URI. @@ -1946,10 +2238,11 @@ String functions 'debian.org_index.html' -.. function:: version_compare(a, b) +.. function:: version_compare(a: str, b: str) -> int Compare two versions, *a* and *b*, and return an integer value which has - the same characteristic as the built-in :func:`cmp` function. + the same meaning as the built-in :func:`cmp` function's return value has, + see the following table for details. .. table:: Return values @@ -1962,8 +2255,6 @@ String functions ===== ============================================= - - Module Constants ---------------- .. _CurStates: @@ -1971,42 +2262,99 @@ Module Constants Package States ^^^^^^^^^^^^^^^ .. data:: CURSTATE_CONFIG_FILES + + Only the configuration files of the package exist on the system. + .. data:: CURSTATE_HALF_CONFIGURED + + The package is unpacked and configuration has been started, but not + yet completed. + .. data:: CURSTATE_HALF_INSTALLED + + The installation of the package has been started, but not completed. + .. data:: CURSTATE_INSTALLED + + The package is unpacked, configured and OK. + .. data:: CURSTATE_NOT_INSTALLED + + The package is not installed. + .. data:: CURSTATE_UNPACKED + The package is unpacked, but not configured. + .. _InstStates: Installed states ^^^^^^^^^^^^^^^^ .. data:: INSTSTATE_HOLD + + The package is put on hold. + .. data:: INSTSTATE_HOLD_REINSTREQ + + The package is put on hold, but broken and has to be reinstalled. + .. data:: INSTSTATE_OK + + The package is OK. + .. data:: INSTSTATE_REINSTREQ + The package is broken and has to be reinstalled. + .. _Priorities: Priorities ^^^^^^^^^^^ .. data:: PRI_EXTRA + + The integer representation of the priority 'extra'. + .. data:: PRI_IMPORTANT + + The integer representation of the priority 'important'. + .. data:: PRI_OPTIONAL + + The integer representation of the priority 'optional'. + .. data:: PRI_REQUIRED + + The integer representation of the priority 'required'. + .. data:: PRI_STANDARD + The integer representation of the priority 'standard'. + .. _SelStates: -Select states -^^^^^^^^^^^^^ +Package selection states +^^^^^^^^^^^^^^^^^^^^^^^^ .. data:: SELSTATE_DEINSTALL + + The package is selected for deinstallation. + .. data:: SELSTATE_HOLD + + The package is marked to be on hold and will not be modified. + .. data:: SELSTATE_INSTALL + + The package is selected for installation. + .. data:: SELSTATE_PURGE + + The package is selected to be purged. + .. data:: SELSTATE_UNKNOWN + The package is in an unknown state. + Build information ^^^^^^^^^^^^^^^^^ diff --git a/doc/source/library/index.rst b/doc/source/library/index.rst index f049efb8..70e91f84 100644 --- a/doc/source/library/index.rst +++ b/doc/source/library/index.rst @@ -29,7 +29,6 @@ read files like :file:`/etc/apt/sources.list` and to modify them. apt.progress.base apt.progress.text apt.progress.gtk2 - apt.progress.qt4 aptsources.distinfo aptsources.distro diff --git a/doc/source/tutorials/apt-get.rst b/doc/source/tutorials/apt-get.rst index 575f0c46..3bac473b 100644 --- a/doc/source/tutorials/apt-get.rst +++ b/doc/source/tutorials/apt-get.rst @@ -22,9 +22,10 @@ First of all, we have to create the objects:: Now we have to parse /etc/apt/sources.list and its friends, by using :meth:`apt_pkg.SourceList.read_main_list`:: + slist.read_main_list() -Now the **slist** object knows about the location of the indexes. We now have +The **slist** object now knows about the location of the indexes. We now have to load those indexes into the *acquire* object by calling :meth:`apt_pkg.SourceList.get_indexes`:: diff --git a/doc/source/tutorials/contributing.rst b/doc/source/tutorials/contributing.rst index f68d626e..0735982b 100644 --- a/doc/source/tutorials/contributing.rst +++ b/doc/source/tutorials/contributing.rst @@ -13,15 +13,8 @@ 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 +Distribution branches +^^^^^^^^^^^^^^^^^^^^^ **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 @@ -39,20 +32,35 @@ submit them. VCS-Browser: http://bzr.debian.org/loggerhead/apt/python-apt/debian-experimental/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. + for the debian-sid branch above. For the Ubuntu release branches, replace + ``ubuntu`` with the version you want; for example, for lucid: + ``lp:~ubuntu-core-dev/python-apt/lucid``. VCS-Browser: https://code.launchpad.net/~ubuntu-core-dev/python-apt/ubuntu +Important Personal branches +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +**mvo:** lp:~mvo/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: http://bazaar.launchpad.net/~mvo/python-apt/mvo/ + +**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. Most stuff happens in debian-sid now. + + VCS-Browser: http://bzr.debian.org/loggerhead/users/jak/python-apt/jak/ + + .. highlightlang:: c C++ Coding style @@ -80,10 +88,7 @@ C++ dialect - Use ISO standard C++ (the 1998 version of the standard). -- All function declarations and definitions must use full - prototypes (i.e. specify the types of all arguments). - -- Use C++ style // one-line comments where useful. +- Use C++ style // one-line comments for single-line comments. - No compiler warnings with ``gcc -std=c++98 -Wall -Wno-write-strings``. There should also be no errors with ``-pedantic`` added. diff --git a/doc/source/whatsnew/0.7.100.rst b/doc/source/whatsnew/0.7.100.rst index a3888b3a..b7768405 100644 --- a/doc/source/whatsnew/0.7.100.rst +++ b/doc/source/whatsnew/0.7.100.rst @@ -160,8 +160,7 @@ developers to provide Python support in the libapt-pkg-using application. .. warning:: - As of 0.7.93, those headers are still considered experimental and their - API may change without prior notice. + The ABI is not considered stable yet. Other changes ------------- diff --git a/python/acquire-item.cc b/python/acquire-item.cc index cb41f489..e94ea352 100644 --- a/python/acquire-item.cc +++ b/python/acquire-item.cc @@ -124,17 +124,34 @@ static int acquireitem_set_id(PyObject *self, PyObject *value, void *closure) static PyGetSetDef acquireitem_getset[] = { - {"complete",acquireitem_get_complete}, - {"desc_uri",acquireitem_get_desc_uri}, - {"destfile",acquireitem_get_destfile}, - {"error_text",acquireitem_get_error_text}, - {"filesize",acquireitem_get_filesize}, - {"id",acquireitem_get_id,acquireitem_set_id}, - {"mode",acquireitem_get_mode}, - {"is_trusted",acquireitem_get_is_trusted}, - {"local",acquireitem_get_local}, - {"partialsize",acquireitem_get_partialsize}, - {"status",acquireitem_get_status}, + {"complete",acquireitem_get_complete,0, + "A boolean value determining whether the item has been fetched\n" + "completely"}, + {"desc_uri",acquireitem_get_desc_uri,NULL, + "A string describing the URI from which the item is acquired."}, + {"destfile",acquireitem_get_destfile,NULL, + "The path to the file where the item will be stored."}, + {"error_text",acquireitem_get_error_text,NULL, + "If an error occured, a string describing the error; empty string\n" + "otherwise."}, + {"filesize",acquireitem_get_filesize,NULL, + "The size of the file (number of bytes). If unknown, it is set to 0."}, + {"id",acquireitem_get_id,acquireitem_set_id, + "The ID of the item. An integer which can be set by progress classes."}, + {"mode",acquireitem_get_mode,NULL, + "A localized string such as 'Fetching' which indicates the current\n" + "mode."}, + {"is_trusted",acquireitem_get_is_trusted,NULL, + "Whether the item is trusted or not. Only True for packages\n" + "which come from a repository signed with one of the keys in\n" + "APT's keyring."}, + {"local",acquireitem_get_local,NULL, + "Whether we are fetching a local item (copy:/) or not."}, + {"partialsize",acquireitem_get_partialsize,NULL, + "The amount of data which has already been fetched (number of bytes)."}, + {"status",acquireitem_get_status,NULL, + "An integer representing the item's status which can be compared\n" + "against one of the STAT_* constants defined in this class."}, {} }; @@ -158,6 +175,12 @@ static void acquireitem_dealloc(PyObject *self) CppDeallocPtr<pkgAcquire::Item*>(self); } +static const char *acquireitem_doc = + "Represent a single item to be fetched by an Acquire object.\n\n" + "It is not possible to construct instances of this class directly.\n" + "Prospective users should construct instances of a subclass such as\n" + "AcquireFile instead. It is not possible to create subclasses on the\n" + "Python level, only on the C++ level."; PyTypeObject PyAcquireItem_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "apt_pkg.AcquireItem", // tp_name @@ -181,7 +204,7 @@ PyTypeObject PyAcquireItem_Type = { 0, // tp_as_buffer Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags - "AcquireItem Object", // tp_doc + acquireitem_doc, // tp_doc CppTraverse<pkgAcquire::Item*>, // tp_traverse CppClear<pkgAcquire::Item*>, // tp_clear 0, // tp_richcompare @@ -226,9 +249,27 @@ static PyObject *acquirefile_new(PyTypeObject *type, PyObject *Args, PyObject * static char *acquirefile_doc = "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."; + "destfile])\n\n" + "Represent a file to be fetched. The parameter 'owner' points to\n" + "an apt_pkg.Acquire object and the parameter 'uri' to the source\n" + "location. Normally, the file will be stored in the current directory\n" + "using the file name given in the URI. This directory can be changed\n" + "by passing the name of a directory to the 'destdir' parameter. It is\n" + "also possible to set a path to a file using the 'destfile' parameter,\n" + "but both cannot be specified together.\n" + "\n" + "The parameters 'short_descr' and 'descr' can be used to specify\n" + "a short description and a longer description for the item. This\n" + "information is used by progress classes to refer to the item and\n" + "should be short, for example, package name as 'short_descr' and\n" + "and something like 'http://localhost sid/main python-apt 0.7.94.2'\n" + "as 'descr'." + "\n" + "The parameters 'md5' and 'size' are used to verify the resulting\n" + "file. The parameter 'size' is also to calculate the total amount\n" + "of data to be fetched and is useful for resuming a interrupted\n" + "download.\n\n" + "All parameters can be given by name (i.e. as keyword arguments)."; PyTypeObject PyAcquireFile_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) diff --git a/python/acquire.cc b/python/acquire.cc index 3f24a3e7..1d750f37 100644 --- a/python/acquire.cc +++ b/python/acquire.cc @@ -65,15 +65,25 @@ static PyObject *acquireworker_get_resumepoint(PyObject *self, void *closure) } static PyGetSetDef acquireworker_getset[] = { - {"current_item",acquireworker_get_current_item}, - {"status",acquireworker_get_status}, - {"current_size",acquireworker_get_current_size}, - {"total_size",acquireworker_get_total_size}, - {"resumepoint",acquireworker_get_resumepoint}, + {"current_item",acquireworker_get_current_item,0, + "The item currently being fetched, as an apt_pkg.AcquireItemDesc object."}, + {"status",acquireworker_get_status,0, + "The status of the worker, as a string."}, + {"current_size",acquireworker_get_current_size,0, + "The amount of data fetched so far for the current item."}, + {"total_size",acquireworker_get_total_size,0, + "The total size of the item."}, + {"resumepoint",acquireworker_get_resumepoint,0, + "The amount of data which was already available when the download was\n" + "started."}, {NULL} }; - +static const char *acquireworker_doc = + "Represent a sub-process responsible for fetching files from\n" + "remote locations. This sub-process uses 'methods' located in\n" + "the directory specified by the configuration option\n" + "Dir::Bin::Methods."; PyTypeObject PyAcquireWorker_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "apt_pkg.AcquireWorker", // tp_name @@ -97,7 +107,7 @@ PyTypeObject PyAcquireWorker_Type = { 0, // tp_as_buffer Py_TPFLAGS_DEFAULT| // tp_flags Py_TPFLAGS_HAVE_GC, - 0, // tp_doc + acquireworker_doc, // tp_doc CppTraverse<pkgAcquire::Worker*>, // tp_traverse CppClear<pkgAcquire::Worker*>, // tp_clear 0, // tp_richcompare @@ -147,16 +157,21 @@ static PyObject *acquireitemdesc_get_owner(CppPyObject<pkgAcquire::ItemDesc*> *s } static PyGetSetDef acquireitemdesc_getset[] = { - {"uri",acquireitemdesc_get_uri,0,"The URI from which to download this item."}, - {"description",acquireitemdesc_get_description}, - {"shortdesc",acquireitemdesc_get_shortdesc}, - {"owner",(getter)acquireitemdesc_get_owner}, + {"uri",acquireitemdesc_get_uri,0, + "The URI from which this item would be downloaded."}, + {"description",acquireitemdesc_get_description,0, + "A string describing the item."}, + {"shortdesc",acquireitemdesc_get_shortdesc,0, + "A short string describing the item (e.g. package name)."}, + {"owner",(getter)acquireitemdesc_get_owner,0, + "The owner of the item, an apt_pkg.AcquireItem object."}, {NULL} }; static char *acquireitemdesc_doc = - "Represent an AcquireItemDesc"; - + "Provide the description of an item and the URI the item is\n" + "fetched from. Progress classes make use of such objects to\n" + "retrieve description and other information about an item."; PyTypeObject PyAcquireItemDesc_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "apt_pkg.AcquireItemDesc", // tp_name @@ -227,8 +242,17 @@ static PyObject *PkgAcquireShutdown(PyObject *Self,PyObject *Args) static PyMethodDef PkgAcquireMethods[] = { - {"run",PkgAcquireRun,METH_VARARGS,"Run the fetcher"}, - {"shutdown",PkgAcquireShutdown, METH_VARARGS,"Shutdown the fetcher"}, + {"run",PkgAcquireRun,METH_VARARGS, + "run() -> int\n\nRun the fetcher and return one of RESULT_CANCELLED,\n" + "RESULT_CONTINUE, RESULT_FAILED. RESULT_CONTINUE means that all items\n" + "which where queued prior to calling run() have been fetched\n" + "successfully. RESULT_CANCELLED means that the process was canceled\n" + "by the progress class. And RESULT_FAILED means a generic failure."}, + {"shutdown",PkgAcquireShutdown, METH_VARARGS, + "shutdown()\n\n" + "Shut the fetcher down, removing all items from it. Future access to\n" + "queued AcquireItem objects will cause a segfault. The partial result\n" + "is kept on the disk and not removed and APT might reuse it."}, {} }; @@ -275,11 +299,18 @@ static PyObject *PkgAcquireGetItems(PyObject *Self,void*) } static PyGetSetDef PkgAcquireGetSet[] = { - {"fetch_needed",PkgAcquireGetFetchNeeded}, - {"items",PkgAcquireGetItems}, - {"workers",PkgAcquireGetWorkers}, - {"partial_present",PkgAcquireGetPartialPresent}, - {"total_needed",PkgAcquireGetTotalNeeded}, + {"fetch_needed",PkgAcquireGetFetchNeeded,0, + "The total amount of data to be fetched (number of bytes)."}, + {"items",PkgAcquireGetItems,0, + "A list of all items as apt_pkg.AcquireItem objects, including already\n" + "fetched ones and to be fetched ones."}, + {"workers",PkgAcquireGetWorkers,0, + "A list of all active workers as apt_pkg.AcquireWorker objects."}, + {"partial_present",PkgAcquireGetPartialPresent,0, + "The amount of data which is already available (number of bytes)."}, + {"total_needed",PkgAcquireGetTotalNeeded,0, + "The amount of data that needs to fetched plus the amount of data\n" + "which has already been fetched (number of bytes)."}, {} }; @@ -321,10 +352,11 @@ PyObject *PyAcquire_FromCpp(pkgAcquire *fetcher, bool Delete, PyObject *owner) { } static char *doc_PkgAcquire = - "Acquire(progress: apt_pkg.AcquireProgress) -> Acquire() object.\n\n" - "Create a new acquire object. The parameter *progress* can be used to\n" - "specify an apt_pkg.AcquireProgress() object, which will display the\n" - "progress of the fetching."; + "Acquire([progress: apt.progress.base.AcquireProgress])\n\n" + "Coordinate the retrieval of files via network or local file system\n" + "(using 'copy:/path/to/file' style URIs). The optional argument\n" + "'progress' takes an apt.progress.base.AcquireProgress object\n" + "which may report progress information."; PyTypeObject PyAcquire_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) diff --git a/python/apt_instmodule.cc b/python/apt_instmodule.cc index 2721509e..732f1bd0 100644 --- a/python/apt_instmodule.cc +++ b/python/apt_instmodule.cc @@ -102,7 +102,7 @@ static PyObject *debExtractArchive(PyObject *Self,PyObject *Args) if (_error->PendingError() == true) { if (Rootdir != NULL) chdir (cwd); - return HandleErrors(Py_BuildValue("b",false)); + return HandleErrors(); } // extracts relative to the current dir @@ -112,9 +112,9 @@ static PyObject *debExtractArchive(PyObject *Self,PyObject *Args) if (Rootdir != NULL) chdir (cwd); if (res == false) - return HandleErrors(Py_BuildValue("b",res)); + return HandleErrors(PyBool_FromLong(res)); } - return HandleErrors(Py_BuildValue("b",res)); + return HandleErrors(PyBool_FromLong(res)); } /*}}}*/ // arFindMember - Find member in AR archive /*{{{*/ @@ -136,12 +136,12 @@ static PyObject *arCheckMember(PyObject *Self,PyObject *Args) FileFd Fd(fileno,false); ARArchive AR(Fd); if (_error->PendingError() == true) - return HandleErrors(Py_BuildValue("b",res)); + return HandleErrors(); if(AR.FindMember(Member) != 0) res = true; - return HandleErrors(Py_BuildValue("b",res)); + return HandleErrors(PyBool_FromLong(res)); } /*}}}*/ @@ -168,7 +168,7 @@ static PyMethodDef *methods = 0; static const char *apt_inst_doc = - "Functions for working with AR,tar archives and .deb packages.\n\n" + "Functions for working with ar/tar archives and .deb packages.\n\n" "This module provides useful classes and functions to work with\n" "archives, modelled after the 'TarFile' class in the 'tarfile' module."; #define ADDTYPE(mod,name,type) { \ diff --git a/python/apt_pkgmodule.cc b/python/apt_pkgmodule.cc index 2a181619..c6353fcc 100644 --- a/python/apt_pkgmodule.cc +++ b/python/apt_pkgmodule.cc @@ -64,7 +64,10 @@ static PyObject *newConfiguration(PyObject *self,PyObject *args) // Version Wrappers /*{{{*/ // These are kind of legacy.. -static char *doc_VersionCompare = "VersionCompare(a,b) -> int"; +static char *doc_VersionCompare = + "version_compare(a: str, b: str) -> int\n\n" + "Compare the given versions; return -1 if 'a' is smaller than 'b',\n" + "0 if they are equal, and 2 if 'a' is larger than 'b'."; static PyObject *VersionCompare(PyObject *Self,PyObject *Args) { char *A; @@ -89,8 +92,8 @@ static char *doc_CheckDep = "Check that the given requirement is fulfilled; i.e. that the version\n" "string given by 'pkg_ver' matches the version string 'dep_ver' under\n" "the condition specified by the operator 'dep_op' (<,<=,=,>=,>).\n\n" - "This functions returns True if 'pkg_ver' matches 'dep_ver' under the\n" - "condition 'dep_op'; e.g. this returns True:\n\n" + "Return True if 'pkg_ver' matches 'dep_ver' under the\n" + "condition 'dep_op'; for example, this returns True:\n\n" " apt_pkg.check_dep('1', '<=', '2')"; static PyObject *CheckDep(PyObject *Self,PyObject *Args) { @@ -146,7 +149,9 @@ static PyObject *CheckDepOld(PyObject *Self,PyObject *Args) } #endif -static char *doc_UpstreamVersion = "UpstreamVersion(a) -> string"; +static char *doc_UpstreamVersion = + "upstream_version(ver: str) -> str\n\n" + "Return the upstream version for the package version given by 'ver'."; static PyObject *UpstreamVersion(PyObject *Self,PyObject *Args) { char *Ver; @@ -155,14 +160,29 @@ static PyObject *UpstreamVersion(PyObject *Self,PyObject *Args) return CppPyString(_system->VS->UpstreamVersion(Ver)); } -static char *doc_ParseDepends = -"ParseDepends(s) -> list of tuples\n" +static const char *doc_ParseDepends = +"parse_depends(s: str) -> list\n" "\n" -"The resulting tuples are (Pkg,Ver,Operation). Each anded dependency is a\n" -"list of or'd dependencies\n" -"Source depends are evaluated against the curernt arch and only those that\n" -"Match are returned.\n\n" -"apt_pkg.Parse{,Src}Depends() are old forms which return >>,<< instead of >,<"; +"Parse the dependencies given by 's' and return a list of lists. Each of\n" +"these lists represents one or more options for an 'or' dependency in\n" +"the form of '(pkg, ver, comptype)' tuples. The tuple element 'pkg'\n" +"is the name of the package; the element 'ver' is the version, or ''\n" +"if no version was requested. The element 'ver' is a comparison\n" +"operator ('<', '<=', '=', '>=', or '>')."; + +static const char *parse_src_depends_doc = +"parse_src_depends(s: str) -> list\n" +"\n" +"Parse the dependencies given by 's' and return a list of lists. Each of\n" +"these lists represents one or more options for an 'or' dependency in\n" +"the form of '(pkg, ver, comptype)' tuples. The tuple element 'pkg'\n" +"is the name of the package; the element 'ver' is the version, or ''\n" +"if no version was requested. The element 'ver' is a comparison\n" +"operator ('<', '<=', '=', '>=', or '>')." +"\n\n" +"Dependencies may be restricted to certain architectures and the result\n" +"only contains those dependencies for the architecture set in the\n" +"configuration variable APT::Architecture"; static PyObject *RealParseDepends(PyObject *Self,PyObject *Args, bool ParseArchFlags, string name, bool debStyle=false) @@ -238,7 +258,12 @@ static PyObject *ParseSrcDepends_old(PyObject *Self,PyObject *Args) /*}}}*/ // md5sum - Compute the md5sum of a file or string /*{{{*/ // --------------------------------------------------------------------- -static char *doc_md5sum = "md5sum(String) -> String or md5sum(File) -> String"; +static const char *doc_md5sum = + "md5sum(object) -> str\n\n" + "Return the md5sum of the object. 'object' may either be a string, in\n" + "which case the md5sum of the string is returned, or a file() object\n" + "(or file descriptor), in which case the md5sum of its contents is\n" + "returned."; static PyObject *md5sum(PyObject *Self,PyObject *Args) { PyObject *Obj; @@ -278,7 +303,12 @@ static PyObject *md5sum(PyObject *Self,PyObject *Args) /*}}}*/ // sha1sum - Compute the sha1sum of a file or string /*{{{*/ // --------------------------------------------------------------------- -static char *doc_sha1sum = "sha1sum(String) -> String or sha1sum(File) -> String"; +static const char *doc_sha1sum = + "sha1sum(object) -> str\n\n" + "Return the sha1sum of the object. 'object' may either be a string, in\n" + "which case the sha1sum of the string is returned, or a file() object\n" + "(or file descriptor), in which case the sha1sum of its contents is\n" + "returned."; static PyObject *sha1sum(PyObject *Self,PyObject *Args) { PyObject *Obj; @@ -318,7 +348,12 @@ static PyObject *sha1sum(PyObject *Self,PyObject *Args) /*}}}*/ // sha256sum - Compute the sha1sum of a file or string /*{{{*/ // --------------------------------------------------------------------- -static char *doc_sha256sum = "sha256sum(String) -> String or sha256sum(File) -> String"; +static const char *doc_sha256sum = + "sha256sum(object) -> str\n\n" + "Return the sha256sum of the object. 'object' may either be a string, in\n" + "which case the sha256sum of the string is returned, or a file() object\n" + "(or file descriptor), in which case the sha256sum of its contents is\n" + "returned.";; static PyObject *sha256sum(PyObject *Self,PyObject *Args) { PyObject *Obj; @@ -359,8 +394,10 @@ static PyObject *sha256sum(PyObject *Self,PyObject *Args) // init - 3 init functions /*{{{*/ // --------------------------------------------------------------------- static char *doc_Init = -"init() -> None\n" -"Legacy. Do InitConfig then parse the command line then do InitSystem\n"; +"init()\n\n" +"Shorthand for doing init_config() and init_system(). When working\n" +"with command line arguments, first call init_config() then parse\n" +"the command line and finally call init_system()."; static PyObject *Init(PyObject *Self,PyObject *Args) { if (PyArg_ParseTuple(Args,"") == 0) @@ -374,8 +411,8 @@ static PyObject *Init(PyObject *Self,PyObject *Args) } static char *doc_InitConfig = -"initconfig() -> None\n" -"Load the default configuration and the config file\n"; +"init_config()\n\n" +"Load the default configuration and the config file."; static PyObject *InitConfig(PyObject *Self,PyObject *Args) { if (PyArg_ParseTuple(Args,"") == 0) @@ -388,8 +425,8 @@ static PyObject *InitConfig(PyObject *Self,PyObject *Args) } static char *doc_InitSystem = -"initsystem() -> None\n" -"Construct the underlying system\n"; +"init_system()\n\n" +"Construct the apt_pkg system."; static PyObject *InitSystem(PyObject *Self,PyObject *Args) { if (PyArg_ParseTuple(Args,"") == 0) @@ -405,11 +442,13 @@ static PyObject *InitSystem(PyObject *Self,PyObject *Args) // fileutils.cc: GetLock /*{{{*/ // --------------------------------------------------------------------- static char *doc_GetLock = -"GetLock(string) -> int\n" -"This will create an empty file of the given name and lock it. Once this" -" is done all other calls to GetLock in any other process will fail with" -" -1. The return result is the fd of the file, the call should call" -" close at some time\n"; +"get_lock(file: str, errors: bool) -> int\n\n" +"Create an empty file of the given name and lock it. If the locking\n" +"succeeds, return the file descriptor of the lock file. Afterwards,\n" +"locking the file from another process will fail and thus cause\n" +"get_lock() to return -1 or raise an Error (if 'errors' is True).\n\n" +"From Python 2.6 on, it is recommended to use the context manager\n" +"provided by apt_pkg.FileLock instead using the with-statement."; static PyObject *GetLock(PyObject *Self,PyObject *Args) { const char *file; @@ -419,12 +458,14 @@ static PyObject *GetLock(PyObject *Self,PyObject *Args) int fd = GetLock(file, errors); - return HandleErrors(Py_BuildValue("i", fd)); + return HandleErrors(Py_BuildValue("i", fd)); } static char *doc_PkgSystemLock = -"PkgSystemLock() -> boolean\n" -"Get the global pkgsystem lock\n"; +"pkgsystem_lock() -> bool\n\n" +"Acquire the global lock for the package system by using /var/lib/dpkg/lock\n" +"to do the locking. From Python 2.6 on, the apt_pkg.SystemLock context\n" +"manager is available and should be used instead."; static PyObject *PkgSystemLock(PyObject *Self,PyObject *Args) { if (PyArg_ParseTuple(Args,"") == 0) @@ -433,12 +474,12 @@ static PyObject *PkgSystemLock(PyObject *Self,PyObject *Args) bool res = _system->Lock(); Py_INCREF(Py_None); - return HandleErrors(Py_BuildValue("b", res)); + return HandleErrors(PyBool_FromLong(res)); } static char *doc_PkgSystemUnLock = -"PkgSystemUnLock() -> boolean\n" -"Unset the global pkgsystem lock\n"; +"pkgsystem_unlock() -> bool\n\n" +"Release the global lock for the package system."; static PyObject *PkgSystemUnLock(PyObject *Self,PyObject *Args) { if (PyArg_ParseTuple(Args,"") == 0) @@ -447,7 +488,7 @@ static PyObject *PkgSystemUnLock(PyObject *Self,PyObject *Args) bool res = _system->UnLock(); Py_INCREF(Py_None); - return HandleErrors(Py_BuildValue("b", res)); + return HandleErrors(PyBool_FromLong(res)); } /*}}}*/ @@ -465,8 +506,8 @@ static PyMethodDef methods[] = // Internationalization. {"gettext",py_gettext,METH_VARARGS, "gettext(msg: str[, domain: str = 'python-apt']) -> str\n\n" - "Translate the given string. Much Faster than Python's version and only\n" - "does translations after setlocale() has been called."}, + "Translate the given string. This is much faster than Python's version\n" + "and only does translations after setlocale() has been called."}, // Tag File {"rewrite_section",RewriteSection,METH_VARARGS,doc_RewriteSection}, @@ -489,7 +530,7 @@ static PyMethodDef methods[] = // Depends {"parse_depends",ParseDepends,METH_VARARGS,doc_ParseDepends}, - {"parse_src_depends",ParseSrcDepends,METH_VARARGS,doc_ParseDepends}, + {"parse_src_depends",ParseSrcDepends,METH_VARARGS,parse_src_depends_doc}, // Stuff {"md5sum",md5sum,METH_VARARGS,doc_md5sum}, @@ -497,16 +538,50 @@ static PyMethodDef methods[] = {"sha256sum",sha256sum,METH_VARARGS,doc_sha256sum}, // Strings - {"check_domain_list",StrCheckDomainList,METH_VARARGS,"CheckDomainList(String,String) -> Bool"}, - {"quote_string",StrQuoteString,METH_VARARGS,"QuoteString(String,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_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"}, - {"str_to_time",StrStrToTime,METH_VARARGS,"StrToTime(String) -> Int"}, + {"check_domain_list",StrCheckDomainList,METH_VARARGS, + "check_domain_list(host: str, domains: str) -> bool\n\n" + "Check if the host given by 'host' belongs to one of the domains\n" + "specified in the comma separated string 'domains'. An example\n" + "would be:\n\n" + " check_domain_list('alioth.debian.org','debian.net,debian.org')\n\n" + "which would return True because alioth belongs to debian.org."}, + {"quote_string",StrQuoteString,METH_VARARGS, + "quote_string(string: str, repl: str) -> str\n\n" + "Escape the string 'string', replacing any character not allowed in a URL" + "or specified by 'repl' with its ASCII value preceded by a percent sign" + "(so for example ' ' becomes '%20')."}, + {"dequote_string",StrDeQuote,METH_VARARGS, + "dequote_string(string: str) -> str\n\n" + "Dequote the given string by replacing all HTTP encoded values such\n" + "as '%20' with their decoded value (in this case, ' ')."}, + {"size_to_str",StrSizeToStr,METH_VARARGS, + "size_to_str(bytes: int) -> str\n\n" + "Return a string describing the size in a human-readable manner using\n" + "SI prefix and base-10 units, e.g. '1k' for 1000, '1M' for 1000000, etc."}, + {"time_to_str",StrTimeToStr,METH_VARARGS, + "time_to_str(seconds: int) -> str\n\n" + "Return a string describing the number of seconds in a human\n" + "readable manner using days, hours, minutes and seconds."}, + {"uri_to_filename",StrURItoFileName,METH_VARARGS, + "uri_to_filename(uri: str) -> str\n\n" + "Return a filename based on the given URI after replacing some\n" + "parts not suited for filenames (e.g. '/')."}, + {"base64_encode",StrBase64Encode,METH_VARARGS, + "base64_encode(value: bytes) -> str\n\n" + "Encode the given bytestring into Base64. The input may not\n" + "contain a null byte character (use the base64 module for this)."}, + {"string_to_bool",StrStringToBool,METH_VARARGS, + "string_to_bool(string: str) -> int\n\n" + "Return 1 if the string is a value such as 'yes', 'true', '1';\n" + "0 if the string is a value such as 'no', 'false', '0'; -1 if\n" + "the string is not recognized."}, + {"time_rfc1123",StrTimeRFC1123,METH_VARARGS, + "time_rfc1123(unixtime: int) -> str\n\n" + "Format the given Unix time according to the requirements of\n" + "RFC 1123."}, + {"str_to_time",StrStrToTime,METH_VARARGS, + "str_to_time(rfc_time: str) -> int\n\n" + "Convert the given RFC 1123 formatted string to a Unix timestamp."}, // DEPRECATED #ifdef COMPAT_0_7 @@ -534,7 +609,8 @@ static PyMethodDef methods[] = {"ParseDepends",ParseDepends_old,METH_VARARGS,doc_ParseDepends}, {"ParseSrcDepends",ParseSrcDepends_old,METH_VARARGS,doc_ParseDepends}, - {"CheckDomainList",StrCheckDomainList,METH_VARARGS,"CheckDomainList(String,String) -> Bool"}, + {"CheckDomainList",StrCheckDomainList,METH_VARARGS, + "CheckDomainList(String,String) -> Bool"}, {"QuoteString",StrQuoteString,METH_VARARGS,"QuoteString(String,String) -> String"}, {"DeQuoteString",StrDeQuote,METH_VARARGS,"DeQuoteString(String) -> String"}, {"SizeToStr",StrSizeToStr,METH_VARARGS,"SizeToStr(int) -> String"}, @@ -664,12 +740,18 @@ static struct _PyAptPkgAPIStruct API = { PyModule_AddObject(mod,name,(PyObject *)type); } +static const char *apt_pkg_doc = + "Classes and functions wrapping the apt-pkg library.\n\n" + "The apt_pkg module provides several classes and functions for accessing\n" + "the functionality provided by the apt-pkg library. Typical uses might\n" + "include reading APT index files and configuration files and installing\n" + "or removing packages."; + #if PY_MAJOR_VERSION >= 3 static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, "apt_pkg", - "Classes and functions wrapping the apt-pkg library.\n\n" - "The apt_pkg module provides...", + apt_pkg_doc, -1, methods, 0, @@ -693,7 +775,7 @@ extern "C" void initapt_pkg() #if PY_MAJOR_VERSION >= 3 PyObject *Module = PyModule_Create(&moduledef); #else - PyObject *Module = Py_InitModule("apt_pkg",methods); + PyObject *Module = Py_InitModule3("apt_pkg",methods, apt_pkg_doc); #endif // Global variable linked to the global configuration class diff --git a/python/arfile.cc b/python/arfile.cc index 4f3b4ad7..a279807d 100644 --- a/python/arfile.cc +++ b/python/arfile.cc @@ -82,12 +82,12 @@ static PyGetSetDef armember_getset[] = { {"size",armember_get_size,0,"The size of the files."}, {"start",armember_get_start,0, "The offset in the archive where the file starts."}, - {"uid",armember_get_uid,0,"The user id of the owner."}, + {"uid",armember_get_uid,0,"The user ID of the owner."}, {NULL} }; static const char *armember_doc = - "An ArMember object represents a single file within an AR archive. For\n" + "Represent a single file within an AR archive. For\n" "Debian packages this can be e.g. control.tar.gz. This class provides\n" "information about this file, such as the mode and size."; PyTypeObject PyArMember_Type = { @@ -141,7 +141,7 @@ struct PyArArchiveObject : public CppPyObject<PyARArchiveHack*> { static const char *ararchive_getmember_doc = "getmember(name: str) -> ArMember\n\n" - "Return a ArMember object for the member given by name. Raise\n" + "Return an ArMember object for the member given by 'name'. Raise\n" "LookupError if there is no ArMember with the given name."; static PyObject *ararchive_getmember(PyArArchiveObject *self, PyObject *arg) { @@ -238,11 +238,11 @@ static PyObject *_extract(FileFd &Fd, const ARArchive::Member *member, static const char *ararchive_extract_doc = "extract(name: str[, target: str]) -> bool\n\n" - "Extract the member given by name into the directory given by target.\n" - "If the extraction failed, an error is raised. Otherwise, the method\n" - "returns True if the owner could be set or False if the owner could not\n" - "be changed. It may also raise LookupError if there is member with\n" - "the given name."; + "Extract the member given by 'name' into the directory given\n" + "by 'target'. If the extraction fails, raise OSError. In case\n" + "of success, return True if the file owner could be set or\n" + "False if this was not possible. If the requested member\n" + "does not exist, raise LookupError."; static PyObject *ararchive_extract(PyArArchiveObject *self, PyObject *args) { char *name = 0; @@ -260,11 +260,10 @@ static PyObject *ararchive_extract(PyArArchiveObject *self, PyObject *args) } static const char *ararchive_extractall_doc = - "extract([target: str]) -> bool\n\n" - "Extract all into the directory given by target.\n" - "If the extraction failed, an error is raised. Otherwise, the method\n" - "returns True if the owner could be set or False if the owner could not\n" - "be changed."; + "extractall([target: str]) -> bool\n\n" + "Extract all archive contents into the directory given by 'target'. If\n" + "the extraction fails, raise an error. Otherwise, return True if the\n" + "owner could be set or False if the owner could not be changed."; static PyObject *ararchive_extractall(PyArArchiveObject *self, PyObject *args) { @@ -311,7 +310,7 @@ static PyObject *ararchive_gettar(PyArArchiveObject *self, PyObject *args) static const char *ararchive_getmembers_doc = "getmembers() -> list\n\n" - "Return a list of all members in the AR archive."; + "Return a list of all members in the archive."; static PyObject *ararchive_getmembers(PyArArchiveObject *self) { PyObject *list = PyList_New(0); @@ -329,7 +328,7 @@ static PyObject *ararchive_getmembers(PyArArchiveObject *self) static const char *ararchive_getnames_doc = "getnames() -> list\n\n" - "Return a list of the names of all members in the AR archive."; + "Return a list of the names of all members in the archive."; static PyObject *ararchive_getnames(PyArArchiveObject *self) { PyObject *list = PyList_New(0); @@ -424,12 +423,12 @@ static PyMappingMethods ararchive_as_mapping = { static const char *ararchive_doc = "ArArchive(file: str/int/file)\n\n" - "An ArArchive object represents an archive in the 4.4 BSD AR format, \n" + "Represent an archive in the 4.4 BSD ar format,\n" "which is used for e.g. deb packages.\n\n" "The parameter 'file' may be a string specifying the path of a file, or\n" "a file-like object providing the fileno() method. It may also be an int\n" "specifying a file descriptor (returned by e.g. os.open()).\n" - "The recommended way is to pass in the path to the file."; + "The recommended way of using it is to pass in the path to the file."; PyTypeObject PyArArchive_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) @@ -599,10 +598,10 @@ static const char *debfile_doc = "The parameter 'file' may be a string specifying the path of a file, or\n" "a file-like object providing the fileno() method. It may also be an int\n" "specifying a file descriptor (returned by e.g. os.open()).\n" - "The recommended way is to pass in the path to the file.\n\n" + "The recommended way of using it is to pass in the path to the file.\n\n" "It differs from ArArchive by providing the members 'control', 'data'\n" - "and 'version' for accessing the control.tar.gz,data.tar.{gz,bz2,lzma}\n" - ",debian-binary members in the archive."; + "and 'version' for accessing the control.tar.gz, data.tar.{gz,bz2,lzma},\n" + "and debian-binary members in the archive."; PyTypeObject PyDebFile_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) diff --git a/python/cache.cc b/python/cache.cc index 515f0193..b0cfb469 100644 --- a/python/cache.cc +++ b/python/cache.cc @@ -85,6 +85,20 @@ static PyObject *CreateProvides(PyObject *Owner,pkgCache::PrvIterator I) // Cache Class /*{{{*/ // --------------------------------------------------------------------- + +static const char *cache_update_doc = + "update(progress, sources: SourceList, pulse_interval: int) -> bool\n\n" + "Update the index files used by the cache. A call to this method\n" + "does not affect the current Cache object; instead, a new one\n" + "should be created in order to use the changed index files.\n\n" + "The parameter 'progress' can be used to specify an\n" + "apt.progress.base.AcquireProgress() object , which will report\n" + "progress information while the index files are being fetched.\n" + "The parameter 'sources', if provided, is an apt_pkg.SourcesList\n" + "object listing the remote repositories to be used.\n" + "The 'pulse_interval' parameter indicates how long (in microseconds)\n" + "to wait between calls to the pulse() method of the 'progress' object.\n" + "The default is 500000 microseconds."; static PyObject *PkgCacheUpdate(PyObject *Self,PyObject *Args) { PyObject *pyFetchProgressInst = 0; @@ -99,7 +113,7 @@ static PyObject *PkgCacheUpdate(PyObject *Self,PyObject *Args) pkgSourceList *source = GetCpp<pkgSourceList*>(pySourcesList); bool res = ListUpdate(progress, *source, pulseInterval); - PyObject *PyRes = Py_BuildValue("b", res); + PyObject *PyRes = PyBool_FromLong(res); return HandleErrors(PyRes); } @@ -154,9 +168,10 @@ static PyObject *PkgCacheOpen(PyObject *Self,PyObject *Args) static PyMethodDef PkgCacheMethods[] = { - {"update",PkgCacheUpdate,METH_VARARGS,"Update the cache"}, + {"update",PkgCacheUpdate,METH_VARARGS,cache_update_doc}, #ifdef COMPAT_0_7 - {"Open", PkgCacheOpen, METH_VARARGS,"Open the cache"}, + {"Open", PkgCacheOpen, METH_VARARGS, + "Open the cache; deprecated and unsafe"}, {"Close", PkgCacheClose, METH_VARARGS,"Close the cache"}, #endif {} @@ -210,14 +225,22 @@ static PyObject *PkgCacheGetFileList(PyObject *Self, void*) { } static PyGetSetDef PkgCacheGetSet[] = { - {"depends_count",PkgCacheGetDependsCount}, - {"file_list",PkgCacheGetFileList}, - {"package_count",PkgCacheGetPackageCount}, - {"package_file_count",PkgCacheGetPackageFileCount}, - {"packages",PkgCacheGetPackages}, - {"provides_count",PkgCacheGetProvidesCount}, - {"ver_file_count",PkgCacheGetVerFileCount}, - {"version_count",PkgCacheGetVersionCount}, + {"depends_count",PkgCacheGetDependsCount,0, + "The number of apt_pkg.Dependency objects stored in the cache."}, + {"file_list",PkgCacheGetFileList,0, + "A list of apt_pkg.PackageFile objects stored in the cache."}, + {"package_count",PkgCacheGetPackageCount,0, + "The number of apt_pkg.Package objects stored in the cache."}, + {"package_file_count",PkgCacheGetPackageFileCount,0, + "The number of apt_pkg.PackageFile objects stored in the cache."}, + {"packages",PkgCacheGetPackages,0, + "A list of apt_pkg.Package objects stored in the cache."}, + {"provides_count",PkgCacheGetProvidesCount,0, + "Number of Provides relations described in the cache."}, + {"ver_file_count",PkgCacheGetVerFileCount,0, + "The number of (Version, PackageFile) relations."}, + {"version_count",PkgCacheGetVersionCount,0, + "The number of apt_pkg.Version objects stored in the cache."}, {} }; @@ -313,13 +336,17 @@ static Py_ssize_t CacheMapLen(PyObject *Self) } static char *doc_PkgCache = "Cache([progress]) -> Cache() object.\n\n" - "The cache provides access to the packages and other stuff.\n\n" + "The APT cache file contains a hash table mapping names of binary\n" + "packages to their metadata. A Cache object is the in-core\n" + "representation of the same. It provides access to APT’s idea of the\n" + "list of available packages.\n" "The optional parameter *progress* can be used to specify an \n" - "apt.progress.OpProgress() object (or similar) which displays\n" - "the opening progress. If not specified, the progress is\n" - "displayed in simple text form.\n\n" - "The cache can be used like a mapping of package names to Package\n" - "objects."; + "apt.progress.base.OpProgress() object (or similar) which reports\n" + "progress information while the cache is being opened. If this\n" + "parameter is not supplied, the progress will be reported in simple,\n" + "human-readable text to standard output.\n\n" + "The cache can be used like a mapping from package names to Package\n" + "objects (although only getting items is supported)."; static PySequenceMethods CacheSeq = {0,0,0,0,0,0,0,CacheContains,0,0}; static PyMappingMethods CacheMap = {CacheMapLen,CacheMapOp,0}; PyTypeObject PyCache_Type = @@ -442,6 +469,12 @@ static PySequenceMethods PkgListSeq = 0 // assign slice }; +static const char *packagelist_doc = + "A PackageList is an internally used structure to represent\n" + "the 'packages' attribute of apt_pkg.Cache objects in a more\n" + "efficient manner by creating Package objects only when they\n" + "are accessed."; + PyTypeObject PyPackageList_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) @@ -465,7 +498,7 @@ PyTypeObject PyPackageList_Type = 0, // tp_setattro 0, // tp_as_buffer Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags - 0, // tp_doc + packagelist_doc, // tp_doc CppTraverse<PkgListStruct>, // tp_traverse CppClear<PkgListStruct>, // tp_clear }; @@ -487,9 +520,9 @@ MkGet(PackageGetInstState,Py_BuildValue("i",Pkg->InstState)) MkGet(PackageGetCurrentState,Py_BuildValue("i",Pkg->CurrentState)) MkGet(PackageGetID,Py_BuildValue("i",Pkg->ID)) # -MkGet(PackageGetAuto,Py_BuildValue("i",(Pkg->Flags & pkgCache::Flag::Auto) != 0)) -MkGet(PackageGetEssential,Py_BuildValue("i",(Pkg->Flags & pkgCache::Flag::Essential) != 0)) -MkGet(PackageGetImportant,Py_BuildValue("i",(Pkg->Flags & pkgCache::Flag::Important) != 0)) +MkGet(PackageGetAuto,PyBool_FromLong((Pkg->Flags & pkgCache::Flag::Auto) != 0)) +MkGet(PackageGetEssential,PyBool_FromLong((Pkg->Flags & pkgCache::Flag::Essential) != 0)) +MkGet(PackageGetImportant,PyBool_FromLong((Pkg->Flags & pkgCache::Flag::Important) != 0)) #undef MkGet #undef Owner @@ -508,6 +541,19 @@ static PyObject *PackageGetVersionList(PyObject *Self,void*) } return List; } + +static PyObject *PackageGetHasVersions(PyObject *Self,void*) +{ + pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(Self); + return PyBool_FromLong(Pkg.VersionList().end() == false); +} + +static PyObject *PackageGetHasProvides(PyObject *Self,void*) +{ + pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(Self); + return PyBool_FromLong(Pkg.ProvidesList().end() == false); +} + static PyObject *PackageGetCurrentVer(PyObject *Self,void*) { pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(Self); @@ -522,19 +568,47 @@ static PyObject *PackageGetCurrentVer(PyObject *Self,void*) } static PyGetSetDef PackageGetSet[] = { - {"name",PackageGetName}, - {"section",PackageGetSection}, - {"rev_depends_list",PackageGetRevDependsList}, - {"provides_list",PackageGetProvidesList}, - {"selected_state",PackageGetSelectedState}, - {"inst_state",PackageGetInstState}, - {"current_state",PackageGetCurrentState}, - {"id",PackageGetID}, - {"auto",PackageGetAuto}, - {"essential",PackageGetEssential}, - {"important",PackageGetImportant}, - {"version_list",PackageGetVersionList}, - {"current_ver",PackageGetCurrentVer}, + {"name",PackageGetName,0, + "The name of the package."}, + {"section",PackageGetSection,0, + "The section of the package."}, + {"rev_depends_list",PackageGetRevDependsList,0, + "An apt_pkg.DependencyList object of all reverse dependencies."}, + {"provides_list",PackageGetProvidesList,0, + "A list of all packages providing this package. The list contains\n" + "tuples in the format (providesname, providesver, version)\n" + "where 'version' is an apt_pkg.Version object."}, + {"selected_state",PackageGetSelectedState,0, + "The state of the selection, which can be compared against the constants\n" + "SELSTATE_DEINSTALL, SELSTATE_HOLD, SELSTATE_INSTALL, SELSTATE_PURGE,\n" + "SELSTATE_UNKNOWN of the apt_pkg module."}, + {"inst_state",PackageGetInstState,0, + "The state of the install, which be compared against the constants\n" + "INSTSTATE_HOLD, INSTSTATE_HOLD_REINSTREQ, INSTSTATE_OK,\n" + "INSTSTATE_REINSTREQ of the apt_pkg module."}, + {"current_state",PackageGetCurrentState,0, + "The current state, which can be compared against the constants\n" + "CURSTATE_CONFIG_FILES, CURSTATE_HALF_CONFIGURED,\n" + "CURSTATE_HALF_INSTALLED, CURSTATE_INSTALLED, CURSTATE_NOT_INSTALLED,\n" + "CURSTATE_UNPACKED of the apt_pkg module."}, + {"id",PackageGetID,0, + "The numeric ID of the package"}, + {"auto",PackageGetAuto,0, + "Ignore it, it does nothing. You want to use\n" + "DepCache.is_auto_installed instead."}, + {"essential",PackageGetEssential,0, + "Boolean value determining whether the package is essential."}, + {"important",PackageGetImportant,0, + "Boolean value determining whether the package has the 'important'\n" + "flag set ('Important: yes' in the Packages file). No longer used."}, + {"version_list",PackageGetVersionList,0, + "A list of all apt_pkg.Version objects for this package."}, + {"current_ver",PackageGetCurrentVer,0, + "The version of the package currently installed or None."}, + {"has_versions",PackageGetHasVersions,0, + "Whether the package has at least one version in the cache."}, + {"has_provides",PackageGetHasProvides,0, + "Whether the package is provided by at least one other package."}, {} }; @@ -548,6 +622,12 @@ static PyObject *PackageRepr(PyObject *Self) Pkg->ID); } +static const char *package_doc = + "Represent a package. A package is uniquely identified by its name\n" + "and each package can have zero or more versions which can be\n" + "accessed via the version_list property. Packages can be installed\n" + "and removed by apt_pkg.DepCache."; + PyTypeObject PyPackage_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) @@ -571,7 +651,7 @@ PyTypeObject PyPackage_Type = 0, // tp_setattro 0, // tp_as_buffer Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags - "Package Object", // tp_doc + package_doc, // tp_doc CppTraverse<pkgCache::PkgIterator>, // tp_traverse CppClear<pkgCache::PkgIterator>,// tp_clear 0, // tp_richcompare @@ -615,9 +695,13 @@ static PyObject *DescriptionGetFileList(PyObject *Self,void*) } static PyGetSetDef DescriptionGetSet[] = { - {"language_code",DescriptionGetLanguageCode}, - {"md5",DescriptionGetMd5}, - {"file_list",DescriptionGetFileList}, + {"language_code",DescriptionGetLanguageCode,0, + "The language code of the description. Empty string for untranslated\n" + "descriptions."}, + {"md5",DescriptionGetMd5,0, + "The MD5 hash of the description."}, + {"file_list",DescriptionGetFileList,0, + "A list of all apt_pkg.PackageFile objects related to this description."}, {} }; @@ -629,6 +713,10 @@ static PyObject *DescriptionRepr(PyObject *Self) Desc.md5()); } +static const char *description_doc = + "Represent a package description and some attributes. Needed for\n" + "things like translated descriptions."; + PyTypeObject PyDescription_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) @@ -652,7 +740,7 @@ PyTypeObject PyDescription_Type = 0, // tp_setattro 0, // tp_as_buffer Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags - "apt_pkg.Description Object", // tp_doc + description_doc, // tp_doc CppTraverse<pkgCache::DescIterator>, // tp_traverse CppClear<pkgCache::DescIterator>,// tp_clear 0, // tp_richcompare @@ -799,7 +887,7 @@ static PyObject *VersionGetPriorityStr(PyObject *Self, void*) { return Safe_FromString(Version_GetVer(Self).PriorityType()); } static PyObject *VersionGetDownloadable(PyObject *Self, void*) { - return Py_BuildValue("b",Version_GetVer(Self).Downloadable()); + return PyBool_FromLong(Version_GetVer(Self).Downloadable()); } static PyObject *VersionGetTranslatedDescription(PyObject *Self, void*) { pkgCache::VerIterator &Ver = GetCpp<pkgCache::VerIterator>(Self); @@ -819,9 +907,9 @@ static PyObject *VersionGetIsTrusted(PyObject *Self, void*) { { pkgIndexFile *index; if(Sources.FindIndex(i.File(), index) && !index->IsTrusted()) - return Py_BuildValue("b", false); + Py_RETURN_FALSE; } - return Py_BuildValue("b", true); + Py_RETURN_TRUE; } } #endif @@ -842,23 +930,68 @@ static PyObject *VersionRepr(PyObject *Self) } #undef NOTNULL +static PyObject *version_richcompare(PyObject *obj1, PyObject *obj2, int op) +{ + if (!PyVersion_Check(obj2)) + return Py_INCREF(Py_NotImplemented), Py_NotImplemented; + + const pkgCache::VerIterator &a = GetCpp<pkgCache::VerIterator>(obj1); + const pkgCache::VerIterator &b = GetCpp<pkgCache::VerIterator>(obj2); + const int comparison = _system->VS->CmpVersion(a.VerStr(), b.VerStr()); + switch (op) { + case Py_LT: return PyBool_FromLong(comparison < 0); + case Py_LE: return PyBool_FromLong(comparison <= 0); + case Py_EQ: return PyBool_FromLong(comparison == 0); + case Py_NE: return PyBool_FromLong(comparison != 0); + case Py_GE: return PyBool_FromLong(comparison >= 0); + case Py_GT: return PyBool_FromLong(comparison > 0); + default: return NULL; // should not happen. + } +} + static PyGetSetDef VersionGetSet[] = { - {"arch",VersionGetArch}, - {"depends_list",VersionGetDependsList}, - {"depends_list_str",VersionGetDependsListStr}, - {"downloadable",VersionGetDownloadable}, - {"file_list",VersionGetFileList}, - {"hash",VersionGetHash}, - {"id",VersionGetID}, - {"installed_size",VersionGetInstalledSize}, - {"parent_pkg",VersionGetParentPkg}, - {"priority",VersionGetPriority}, - {"priority_str",VersionGetPriorityStr}, - {"provides_list",VersionGetProvidesList}, - {"section",VersionGetSection}, - {"size",VersionGetSize}, - {"translated_description",VersionGetTranslatedDescription}, - {"ver_str",VersionGetVerStr}, + {"arch",VersionGetArch,0, + "The architecture of this specific version of the package."}, + {"depends_list",VersionGetDependsList,0, + "A dictionary mapping dependency types to lists (A) of lists (B) of\n" + "apt_pkg.Dependency objects. The lists (B) represent or dependencies\n" + "like 'a || b'."}, + {"depends_list_str",VersionGetDependsListStr,0, + "Same as depends_list, except that the apt_pkg.Dependency objects\n" + "are 3-tuples of the form (name, version, operator); where operator\n" + "is one of '<', '<=', '=', '>=', '>'."}, + {"downloadable",VersionGetDownloadable,0, + "Whether the version can be downloaded."}, + {"file_list",VersionGetFileList,0, + "A list of tuples (packagefile: apt_pkg.PackageFile, index: int) for the\n" + "PackageFile objects related to this package. The index can be used\n" + "to retrieve the record of this package version."}, + {"hash",VersionGetHash,0, + "The numeric hash of the version used in the internal storage."}, + {"id",VersionGetID,0, + "The numeric ID of the package."}, + {"installed_size",VersionGetInstalledSize,0, + "The installed size of this package version."}, + {"parent_pkg",VersionGetParentPkg,0, + "The parent package of this version."}, + {"priority",VersionGetPriority,0, + "The priority of the package as an integer, which can be compared to\n" + "the constants PRI_EXTRA, PRI_IMPORTANT, PRI_OPTIONAL, PRI_REQUIRED,\n" + "PRI_STANDARD of the apt_pkg module."}, + {"priority_str",VersionGetPriorityStr,0, + "The priority of the package, as a string."}, + {"provides_list",VersionGetProvidesList,0, + "A list of all packages provided by this version. See\n" + "Package.provides_list for a description of the format."}, + {"section",VersionGetSection,0, + "The section of this package version."}, + {"size",VersionGetSize,0, + "The size of the package file."}, + {"translated_description",VersionGetTranslatedDescription,0, + "An apt_pkg.Description object for the translated description if\n" + "available or the untranslated fallback."}, + {"ver_str",VersionGetVerStr,0, + "The version string."}, {} }; @@ -888,7 +1021,7 @@ PyTypeObject PyVersion_Type = "Version Object", // tp_doc CppTraverse<pkgCache::VerIterator>, // tp_traverse CppClear<pkgCache::VerIterator>,// tp_clear - 0, // tp_richcompare + version_richcompare, // tp_richcompare 0, // tp_weaklistoffset 0, // tp_iter 0, // tp_iternext @@ -963,7 +1096,7 @@ static PyObject *PackageFile_GetSize(PyObject *Self,void*) static PyObject *PackageFile_GetNotSource(PyObject *Self,void*) { pkgCache::PkgFileIterator &File = GetCpp<pkgCache::PkgFileIterator>(Self); - return Py_BuildValue("i",(File->Flags & pkgCache::Flag::NotSource) != 0); + return PyBool_FromLong((File->Flags & pkgCache::Flag::NotSource) != 0); } static PyObject *PackageFile_GetNotAutomatic(PyObject *Self,void*) { @@ -995,22 +1128,43 @@ static PyObject *PackageFileRepr(PyObject *Self) #undef S static PyGetSetDef PackageFileGetSet[] = { - {(char*)"architecture",PackageFile_GetArchitecture}, - {(char*)"archive",PackageFile_GetArchive}, - {(char*)"component",PackageFile_GetComponent}, - {(char*)"filename",PackageFile_GetFileName}, - {(char*)"id",PackageFile_GetID}, - {(char*)"index_type",PackageFile_GetIndexType}, - {(char*)"label",PackageFile_GetLabel}, - {(char*)"not_automatic",PackageFile_GetNotAutomatic}, - {(char*)"not_source",PackageFile_GetNotSource}, - {(char*)"origin",PackageFile_GetOrigin}, - {(char*)"site",PackageFile_GetSite}, - {(char*)"size",PackageFile_GetSize}, - {(char*)"version",PackageFile_GetVersion}, + {"architecture",PackageFile_GetArchitecture,0, + "The architecture of the package file. Unused, empty string nowadays."}, + {"archive",PackageFile_GetArchive,0, + "The archive of the package file (i.e. 'Suite' in the Release file)."}, + {"component",PackageFile_GetComponent,0, + "The component of this package file (e.g. 'main')."}, + {"filename",PackageFile_GetFileName,0, + "The path to the file."}, + {"id",PackageFile_GetID,0, + "The numeric ID of this PackageFile object."}, + {"index_type",PackageFile_GetIndexType,0, + "A string describing the type of index. Known values are\n" + "'Debian Package Index', 'Debian Translation Index', and\n" + "'Debian dpkg status file'."}, + {"label",PackageFile_GetLabel,0, + "The label set in the release file (e.g. 'Debian')."}, + {"not_automatic",PackageFile_GetNotAutomatic,0, + "Whether the NotAutomatic flag is set in the Release file."}, + {"not_source",PackageFile_GetNotSource,0, + "Whether this package file lacks an active (sources.list) source;" + "packages listed in such a file cannot be downloaded."}, + {"origin",PackageFile_GetOrigin,0, + "The origin set in the release file."}, + {"site",PackageFile_GetSite,0, + "The hostname of the location this file comes from."}, + {"size",PackageFile_GetSize,0, + "The size of the file."}, + {"version",PackageFile_GetVersion,0, + "The version set in the release file (e.g. '5.0.X' for lenny, where X\n" + "is a point release)."}, {} }; +static const char *packagefile_doc = + "A package file is an index file stored in the cache with some\n" + "additional pieces of information."; + PyTypeObject PyPackageFile_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "apt_pkg.PackageFile", // tp_name @@ -1032,7 +1186,7 @@ PyTypeObject PyPackageFile_Type = { 0, // tp_setattro 0, // tp_as_buffer Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags - "apt_pkg.PackageFile Object", // tp_doc + packagefile_doc, // tp_doc CppTraverse<pkgCache::PkgFileIterator>, // tp_traverse CppClear<pkgCache::PkgFileIterator>, // tp_clear 0, // tp_richcompare @@ -1096,8 +1250,13 @@ static PyObject *DepAllTargets(PyObject *Self,PyObject *Args) static PyMethodDef DependencyMethods[] = { - {"smart_target_pkg",DepSmartTargetPkg,METH_VARARGS,"Returns the natural Target or None"}, - {"all_targets",DepAllTargets,METH_VARARGS,"Returns all possible Versions that match this dependency"}, + {"smart_target_pkg",DepSmartTargetPkg,METH_VARARGS, + "smart_target_pkg() -> apt_pkg.Package\n\n" + "Return the first package which provides a package with the name\n" + "of the target package."}, + {"all_targets",DepAllTargets,METH_VARARGS, + "all_targets() -> list\n\n" + "A list of all apt_pkg.Version objects satisfying the dependency."}, {} }; @@ -1167,18 +1326,34 @@ static PyObject *DependencyGetID(PyObject *Self,void*) } static PyGetSetDef DependencyGetSet[] = { - {"comp_type",DependencyGetCompType}, - {"dep_type",DependencyGetDepType}, - {"dep_type_untranslated",DependencyGetDepTypeUntranslated}, - {"dep_type_enum",DependencyGetDepTypeEnum}, - {"id",DependencyGetID}, - {"parent_pkg",DependencyGetParentPkg}, - {"parent_ver",DependencyGetParentVer}, - {"target_pkg",DependencyGetTargetPkg}, - {"target_ver",DependencyGetTargetVer}, + {"comp_type",DependencyGetCompType,0, + "The type of comparison, as a string (one of '<', '<=', '=', '>=', '>')."}, + {"dep_type",DependencyGetDepType,0, + "The type of the dependency; may be translated"}, + {"dep_type_untranslated",DependencyGetDepTypeUntranslated,0, + "Same as dep_type, but guaranteed to be untranslated."}, + {"dep_type_enum",DependencyGetDepTypeEnum,0, + "Same as dep_type, but with a numeric value instead of a string. Can\n" + "be compared against the TYPE_ constants defined in this class."}, + {"id",DependencyGetID,0, + "The numeric ID of this dependency object."}, + {"parent_pkg",DependencyGetParentPkg,0, + "The apt_pkg.Package object of the package which depends."}, + {"parent_ver",DependencyGetParentVer,0, + "The apt_pkg.Version object of the package which depends."}, + {"target_pkg",DependencyGetTargetPkg,0, + "The apt_pkg.Package object of the package depended upon"}, + {"target_ver",DependencyGetTargetVer,0, + "The version of the package depended upon as a string"}, {} }; +static const char *dependency_doc = + "Represent a dependency from one package version to a package,\n" + "and (optionally) a version relation (e.g. >= 1). Dependency\n" + "objects also provide useful functions like all_targets() or\n" + "smart_target_pkg() for selecting packages to satisfy the\n" + "dependency."; PyTypeObject PyDependency_Type = { @@ -1203,7 +1378,7 @@ PyTypeObject PyDependency_Type = 0, // tp_setattro 0, // tp_as_buffer Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags - "Dependency Object", // tp_doc + dependency_doc, // tp_doc CppTraverse<pkgCache::DepIterator>, // tp_traverse CppClear<pkgCache::DepIterator>, // tp_clear 0, // tp_richcompare @@ -1265,6 +1440,10 @@ static PySequenceMethods RDepListSeq = 0 // assign slice }; +static const char *dependencylist_doc = + "A simple list-like type for representing multiple dependency\n" + "objects in an efficient manner; without having to generate\n" + "all Dependency objects in advance."; PyTypeObject PyDependencyList_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) @@ -1288,7 +1467,7 @@ PyTypeObject PyDependencyList_Type = 0, // tp_setattro 0, // tp_as_buffer Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags - "DependencyList Object", // tp_doc + dependencylist_doc, // tp_doc CppTraverse<RDepListStruct>, // tp_traverse CppClear<RDepListStruct>, // tp_clear }; diff --git a/python/cdrom.cc b/python/cdrom.cc index d732a810..e6cc8e29 100644 --- a/python/cdrom.cc +++ b/python/cdrom.cc @@ -30,7 +30,7 @@ static char *cdrom_add_doc = "add(progress: apt_pkg.CdromProgress) -> bool\n\n" - "Add the given CD-ROM to the sources.list. Returns True on success, may\n" + "Add the given CD-ROM to the sources.list. Return True on success;\n" "raise an error on failure or return False."; static PyObject *cdrom_add(PyObject *Self,PyObject *Args) { @@ -51,8 +51,11 @@ static PyObject *cdrom_add(PyObject *Self,PyObject *Args) static char *cdrom_ident_doc = "ident(progress: apt_pkg.CdromProgress) -> str\n\n" - "Try to identify the CD-ROM and if successful return the identity as a\n" - "string. Otherwise, return None or raise an error."; + "Try to identify the CD-ROM and if successful return the hexadecimal\n" + "CDROM-ID (and a integer version suffix seperated by -) as a\n" + "string. Otherwise, return None or raise an error.\n\n" + "The ID is created by hashing all file and directory names on the\n" + "CD-ROM and appending the version."; static PyObject *cdrom_ident(PyObject *Self,PyObject *Args) { pkgCdrom &Cdrom = GetCpp<pkgCdrom>(Self); @@ -95,7 +98,8 @@ static PyObject *cdrom_ident_old(PyObject *Self,PyObject *Args) string ident; bool res = Cdrom.Ident(ident, &progress); - PyObject *result = Py_BuildValue("(bs)", res, ident.c_str()); + PyObject *boolres = PyBool_FromLong(res); + PyObject *result = Py_BuildValue("(Os)", boolres, ident.c_str()); return HandleErrors(result); } diff --git a/python/configuration.cc b/python/configuration.cc index 299e06ec..7c9ed7bc 100644 --- a/python/configuration.cc +++ b/python/configuration.cc @@ -33,7 +33,10 @@ static inline Configuration &GetSelf(PyObject *Obj) /*}}}*/ // Method Wrappers /*{{{*/ -static char *doc_Find = "Find(Name[,default]) -> String/None"; +static const char *doc_Find = + "find(key: str[, default: str = '']) -> str\n\n" + "Find the value for the given key and return it. If the\n" + "given key does not exist, return default instead."; static PyObject *CnfFind(PyObject *Self,PyObject *Args) { char *Name = 0; @@ -43,7 +46,21 @@ static PyObject *CnfFind(PyObject *Self,PyObject *Args) return CppPyString(GetSelf(Self).Find(Name,Default)); } -static char *doc_FindFile = "FindFile(Name[,default]) -> String/None"; +static const char *doc_FindFile = + "find_file(key: str[, default: str = '']) -> str\n\n" + "Same as find(), but for filenames. In the APT configuration, there\n" + "is a special section Dir:: for storing filenames. find_file() locates\n" + "the given key and then goes up and prepends the directory names to the\n" + "return value. For example, for:\n" + "\n" + " apt_pkg.config['Dir'] = 'a'\n" + " apt_pkg.config['Dir::D'] = 'b'\n" + " apt_pkg.config['Dir::D::F'] = 'c'\n" + "\n" + "find_file('Dir::D::F') returns 'a/b/c'. There is also a special\n" + "configuration setting RootDir which will always be prepended to the\n" + "result (the default being ''). Thus, if RootDir is 'x', the example\n" + "would return 'x/a/b/c'."; static PyObject *CnfFindFile(PyObject *Self,PyObject *Args) { char *Name = 0; @@ -53,7 +70,10 @@ static PyObject *CnfFindFile(PyObject *Self,PyObject *Args) return CppPyString(GetSelf(Self).FindFile(Name,Default)); } -static char *doc_FindDir = "FindDir(Name[,default]) -> String/None"; +static const char *doc_FindDir = + "find_dir(key: str[, default: str = '']) -> str\n\n" + "Same as find_file(), but for directories. The difference is\n" + "that this function adds a trailing slash to the result."; static PyObject *CnfFindDir(PyObject *Self,PyObject *Args) { char *Name = 0; @@ -63,7 +83,9 @@ static PyObject *CnfFindDir(PyObject *Self,PyObject *Args) return CppPyString(GetSelf(Self).FindDir(Name,Default)); } -static char *doc_FindI = "FindI(Name[,default]) -> Integer"; +static const char *doc_FindI = + "find_i(key: str[, default: int = 0]) -> int\n\n" + "Same as find, but for integer values."; static PyObject *CnfFindI(PyObject *Self,PyObject *Args) { char *Name = 0; @@ -73,17 +95,23 @@ static PyObject *CnfFindI(PyObject *Self,PyObject *Args) return Py_BuildValue("i",GetSelf(Self).FindI(Name,Default)); } -static char *doc_FindB = "FindB(Name[,default]) -> Integer"; +static const char *doc_FindB = + "find_i(key: str[, default: bool = False]) -> bool\n\n" + "Same as find, but for boolean values; returns False on unknown values."; static PyObject *CnfFindB(PyObject *Self,PyObject *Args) { char *Name = 0; int Default = 0; if (PyArg_ParseTuple(Args,"s|i",&Name,&Default) == 0) return 0; - return Py_BuildValue("i",(int)GetSelf(Self).FindB(Name,(Default == 0?false:true))); + return PyBool_FromLong(GetSelf(Self).FindB(Name,(Default == 0?false:true))); } -static char *doc_Set = "Set(Name,Value) -> None"; +static const char *doc_Set = + "set(key: str, value: str)\n\n" + "Set the given key to the given value. To set int or bool values,\n" + "encode them using str(value) and then use find_i()/find_b()\n" + "to retrieve their value again."; static PyObject *CnfSet(PyObject *Self,PyObject *Args) { char *Name = 0; @@ -96,13 +124,15 @@ static PyObject *CnfSet(PyObject *Self,PyObject *Args) return Py_None; } -static char *doc_Exists = "Exists(Name) -> Integer"; +static const char *doc_Exists = + "exists(key: str) -> bool\n\n" + "Check whether the given key exists."; static PyObject *CnfExists(PyObject *Self,PyObject *Args) { char *Name = 0; if (PyArg_ParseTuple(Args,"s",&Name) == 0) return 0; - return Py_BuildValue("i",(int)GetSelf(Self).Exists(Name)); + return PyBool_FromLong((int)GetSelf(Self).Exists(Name)); } static int CnfContains(PyObject *Self,PyObject *Arg) @@ -110,7 +140,9 @@ static int CnfContains(PyObject *Self,PyObject *Arg) return (int)GetSelf(Self).Exists(PyString_AsString(Arg)); } -static char *doc_Clear = "Clear(Name) -> None"; +static const char *doc_Clear = + "clear(key: str)\n\n" + "Remove the specified option and all sub-options."; static PyObject *CnfClear(PyObject *Self,PyObject *Args) { char *Name = 0; @@ -124,7 +156,13 @@ static PyObject *CnfClear(PyObject *Self,PyObject *Args) } // The amazing narrowing search ability! -static char *doc_SubTree = "SubTree(Name) -> Configuration"; +static const char *doc_SubTree = + "sub_tree(key: str) -> apt_pkg.Configuration\n\n" + + "Return a new apt_pkg.Configuration object with the given option\n" + "as its root. Example:\n\n" + " apttree = config.subtree('APT')\n" + " apttree['Install-Suggests'] = config['APT::Install-Suggests']"; static PyObject *CnfSubTree(PyObject *Self,PyObject *Args) { char *Name; @@ -142,7 +180,14 @@ static PyObject *CnfSubTree(PyObject *Self,PyObject *Args) } // Return a list of items at a specific level -static char *doc_List = "List([root]) -> List"; +static char *doc_List = + "list([root: str]) -> list\n\n" + "Return a list of all items at the given root, using their full\n" + "name. For example, in a configuration object where the options A,\n" + "B, and B::C are set, the following expressions evaluate to True:\n\n" + " conf.list() == ['A', 'B']\n" + " conf.list('A') == ['']\n" + " conf.list('B') == ['B::C']\n"; static PyObject *CnfList(PyObject *Self,PyObject *Args) { char *RootName = 0; @@ -169,7 +214,9 @@ static PyObject *CnfList(PyObject *Self,PyObject *Args) /* Return a list of values of items at a specific level.. This is used to get out value lists */ -static char *doc_ValueList = "ValueList([root]) -> List"; +static char *doc_ValueList = + "value_list([root: str]) -> list\n\n" + "Same as list(), but instead of returning the keys, return the values."; static PyObject *CnfValueList(PyObject *Self,PyObject *Args) { char *RootName = 0; @@ -191,7 +238,11 @@ static PyObject *CnfValueList(PyObject *Self,PyObject *Args) return List; } -static char *doc_MyTag = "MyTag() -> String"; +static char *doc_MyTag = + "my_tag() -> str\n\n" + "Return the tag of the root of this Configuration object. For the\n" + "default object, this is an empty string. For a subtree('APT') of\n" + "such an object, it would be 'APT' (given as an example)."; static PyObject *CnfMyTag(PyObject *Self,PyObject *Args) { if (PyArg_ParseTuple(Args,"") == 0) @@ -204,7 +255,10 @@ static PyObject *CnfMyTag(PyObject *Self,PyObject *Args) } // Look like a mapping -static char *doc_Keys = "keys([root]) -> List"; +static char *doc_Keys = + "keys([root: str]) -> list\n\n" + "Return a list of all keys in the configuration object. If 'root'\n" + "is given, limit the list to those below the root."; static PyObject *CnfKeys(PyObject *Self,PyObject *Args) { char *RootName = 0; @@ -274,7 +328,10 @@ static int CnfMapSet(PyObject *Self,PyObject *Arg,PyObject *Val) } /*}}}*/ // Config file loaders /*{{{*/ -char *doc_LoadConfig = "LoadConfig(Configuration,FileName) -> None"; +char *doc_LoadConfig = + "read_config_file(configuration: apt_pkg.Configuration, filename: str)\n\n" + "Read the configuration file 'filename' and set the appropriate\n" + "options in the configuration object."; PyObject *LoadConfig(PyObject *Self,PyObject *Args) { char *Name = 0; @@ -292,7 +349,11 @@ PyObject *LoadConfig(PyObject *Self,PyObject *Args) Py_INCREF(Py_None); return HandleErrors(Py_None); } -char *doc_LoadConfigISC = "LoadConfigISC(Configuration,FileName) -> None"; +char *doc_LoadConfigISC = + "read_config_file_isc(configuration: apt_pkg.Configuration, filename: str)\n\n" + "Like read_config_file(), but for configuration files like bind's\n" + "named.conf. They have a slightly different format than APT\n" + "configuration files."; PyObject *LoadConfigISC(PyObject *Self,PyObject *Args) { char *Name = 0; @@ -310,7 +371,10 @@ PyObject *LoadConfigISC(PyObject *Self,PyObject *Args) Py_INCREF(Py_None); return HandleErrors(Py_None); } -char *doc_LoadConfigDir = "LoadConfigDir(Configuration,DirName) -> None"; +char *doc_LoadConfigDir = + "read_config_dir(configuration: apt_pkg.Configuration, dirname: str)\n\n" + "Read all configuration files in the dir given by 'dirname' in the\n" + "correct order."; PyObject *LoadConfigDir(PyObject *Self,PyObject *Args) { char *Name = 0; @@ -333,14 +397,20 @@ PyObject *LoadConfigDir(PyObject *Self,PyObject *Args) // ParseCommandLine - Wrapper for the command line interface /*{{{*/ // --------------------------------------------------------------------- char *doc_ParseCommandLine = -"ParseCommandLine(Configuration,ListOfOptions,List-argv) -> List\n" +"parse_commandLine(config: Configuration, options: list, argv: list) -> list\n" "\n" -"This function is like getopt except it manipulates a configuration space.\n" -"output is a list of non-option arguments (filenames, etc).\n" -"ListOfOptions is a list of tuples of the form:\n" -" ('c',\"long-opt or None\",\"Configuration::Variable\",\"optional type\")\n" -"Where type may be one of HasArg, IntLevel, Boolean, InvBoolean,\n" -"ConfigFile, or ArbItem. The default is Boolean."; +"Parse the command line in 'argv' into the configuration space. The\n" +"list 'options' contains a list of 3-tuples or 4-tuples in the form:\n" +"\n" +" (short_option: str, long_option: str, variable: str[, type: str])\n" +"\n" +"The element 'short_option' is one character, the 'long_option' element\n" +"is the name of the long option, the element 'variable' the name of the\n" +"configuration option the result will be stored in and type is one of\n" +"'HasArg', 'IntLevel', 'Boolean', 'InvBoolean', 'ConfigFile',\n" +"'ArbItem'. The default type is 'Boolean'. Read the online documentation\n" +"in python-apt-doc and its tutorial on writing an apt-cdrom clone for more\n" +"details."; PyObject *ParseCommandLine(PyObject *Self,PyObject *Args) { PyObject *POList; @@ -465,6 +535,16 @@ static PyObject *CnfNew(PyTypeObject *type, PyObject *args, PyObject *kwds) { // Type for a Normal Configuration object static PySequenceMethods ConfigurationSeq = {0,0,0,0,0,0,0,CnfContains,0,0}; static PyMappingMethods ConfigurationMap = {0,CnfMap,CnfMapSet}; + +static const char *configuration_doc = + "Configuration()\n\n" + "Represent the configuration of APT by mapping option keys to\n" + "values and storing configuration parsed from files like\n" + "/etc/apt/apt.conf. The most important Configuration object\n" + "is apt_pkg.config which points to the global configuration\n" + "object. Other top-level Configuration objects can be created\n" + "by calling the constructor, but there is usually no reason to."; + PyTypeObject PyConfiguration_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) @@ -489,7 +569,7 @@ PyTypeObject PyConfiguration_Type = 0, // tp_as_buffer (Py_TPFLAGS_DEFAULT | // tp_flags Py_TPFLAGS_BASETYPE), - "Configuration Object", // tp_doc + configuration_doc, // tp_doc 0, // tp_traverse 0, // tp_clear 0, // tp_richcompare diff --git a/python/depcache.cc b/python/depcache.cc index 0d5d7882..e7d7d946 100644 --- a/python/depcache.cc +++ b/python/depcache.cc @@ -157,18 +157,18 @@ static PyObject *PkgDepCacheCommit(PyObject *Self,PyObject *Args) // fail if something else went wrong //FIXME: make this more flexible, e.g. with a failedDl handler if(Failed) - return Py_BuildValue("b", false); + Py_RETURN_FALSE; _system->UnLock(true); pkgPackageManager::OrderResult Res = iprogress.Run(PM); //std::cout << "iprogress.Run() returned: " << (int)Res << std::endl; if (Res == pkgPackageManager::Failed || _error->PendingError() == true) { - return HandleErrors(Py_BuildValue("b", false)); + return HandleErrors(PyBool_FromLong(false)); } if (Res == pkgPackageManager::Completed) { //std::cout << "iprogress.Run() returned Completed " << std::endl; - return Py_BuildValue("b", true); + Py_RETURN_TRUE; } //std::cout << "looping again, install unfinished" << std::endl; @@ -176,7 +176,7 @@ static PyObject *PkgDepCacheCommit(PyObject *Self,PyObject *Args) // Reload the fetcher object and loop again for media swapping Fetcher.Shutdown(); if (PM->GetArchives(&Fetcher,&List,&Recs) == false) { - return Py_BuildValue("b", false); + Py_RETURN_FALSE; } _system->Lock(); } @@ -196,11 +196,11 @@ static PyObject *PkgDepCacheSetCandidateVer(PyObject *Self,PyObject *Args) pkgCache::VerIterator &I = GetCpp<pkgCache::VerIterator>(VersionObj); if(I.end()) { - return HandleErrors(Py_BuildValue("b",false)); + return HandleErrors(PyBool_FromLong(false)); } depcache->SetCandidateVersion(I); - return HandleErrors(Py_BuildValue("b",true)); + return HandleErrors(PyBool_FromLong(true)); } static PyObject *PkgDepCacheGetCandidateVer(PyObject *Self,PyObject *Args) @@ -241,7 +241,7 @@ static PyObject *PkgDepCacheUpgrade(PyObject *Self,PyObject *Args) Py_END_ALLOW_THREADS Py_INCREF(Py_None); - return HandleErrors(Py_BuildValue("b",res)); + return HandleErrors(PyBool_FromLong(res)); } static PyObject *PkgDepCacheMinimizeUpgrade(PyObject *Self,PyObject *Args) @@ -257,7 +257,7 @@ static PyObject *PkgDepCacheMinimizeUpgrade(PyObject *Self,PyObject *Args) Py_END_ALLOW_THREADS Py_INCREF(Py_None); - return HandleErrors(Py_BuildValue("b",res)); + return HandleErrors(PyBool_FromLong(res)); } @@ -291,7 +291,7 @@ static PyObject *PkgDepCacheFixBroken(PyObject *Self,PyObject *Args) res &=pkgFixBroken(*depcache); res &=pkgMinimizeUpgrade(*depcache); - return HandleErrors(Py_BuildValue("b",res)); + return HandleErrors(PyBool_FromLong(res)); } @@ -380,7 +380,6 @@ static PyObject *PkgDepCacheMarkAuto(PyObject *Self,PyObject *Args) return HandleErrors(Py_None); } - static PyObject *PkgDepCacheIsUpgradable(PyObject *Self,PyObject *Args) { pkgDepCache *depcache = GetCpp<pkgDepCache *>(Self); @@ -392,7 +391,7 @@ static PyObject *PkgDepCacheIsUpgradable(PyObject *Self,PyObject *Args) pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj); pkgDepCache::StateCache &state = (*depcache)[Pkg]; - return HandleErrors(Py_BuildValue("b",state.Upgradable())); + return HandleErrors(PyBool_FromLong(state.Upgradable())); } static PyObject *PkgDepCacheIsGarbage(PyObject *Self,PyObject *Args) @@ -406,7 +405,7 @@ static PyObject *PkgDepCacheIsGarbage(PyObject *Self,PyObject *Args) pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj); pkgDepCache::StateCache &state = (*depcache)[Pkg]; - return HandleErrors(Py_BuildValue("b",state.Garbage)); + return HandleErrors(PyBool_FromLong(state.Garbage)); } static PyObject *PkgDepCacheIsAutoInstalled(PyObject *Self,PyObject *Args) @@ -420,7 +419,7 @@ static PyObject *PkgDepCacheIsAutoInstalled(PyObject *Self,PyObject *Args) pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj); pkgDepCache::StateCache &state = (*depcache)[Pkg]; - return HandleErrors(Py_BuildValue("b",state.Flags & pkgCache::Flag::Auto)); + return HandleErrors(PyBool_FromLong(state.Flags & pkgCache::Flag::Auto)); } static PyObject *PkgDepCacheIsNowBroken(PyObject *Self,PyObject *Args) @@ -434,7 +433,7 @@ static PyObject *PkgDepCacheIsNowBroken(PyObject *Self,PyObject *Args) pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj); pkgDepCache::StateCache &state = (*depcache)[Pkg]; - return HandleErrors(Py_BuildValue("b",state.NowBroken())); + return HandleErrors(PyBool_FromLong(state.NowBroken())); } static PyObject *PkgDepCacheIsInstBroken(PyObject *Self,PyObject *Args) @@ -448,7 +447,7 @@ static PyObject *PkgDepCacheIsInstBroken(PyObject *Self,PyObject *Args) pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj); pkgDepCache::StateCache &state = (*depcache)[Pkg]; - return HandleErrors(Py_BuildValue("b",state.InstBroken())); + return HandleErrors(PyBool_FromLong(state.InstBroken())); } @@ -463,7 +462,7 @@ static PyObject *PkgDepCacheMarkedInstall(PyObject *Self,PyObject *Args) pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj); pkgDepCache::StateCache &state = (*depcache)[Pkg]; - return HandleErrors(Py_BuildValue("b",state.NewInstall())); + return HandleErrors(PyBool_FromLong(state.NewInstall())); } @@ -478,7 +477,7 @@ static PyObject *PkgDepCacheMarkedUpgrade(PyObject *Self,PyObject *Args) pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj); pkgDepCache::StateCache &state = (*depcache)[Pkg]; - return HandleErrors(Py_BuildValue("b",state.Upgrade())); + return HandleErrors(PyBool_FromLong(state.Upgrade())); } static PyObject *PkgDepCacheMarkedDelete(PyObject *Self,PyObject *Args) @@ -492,7 +491,7 @@ static PyObject *PkgDepCacheMarkedDelete(PyObject *Self,PyObject *Args) pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj); pkgDepCache::StateCache &state = (*depcache)[Pkg]; - return HandleErrors(Py_BuildValue("b",state.Delete())); + return HandleErrors(PyBool_FromLong(state.Delete())); } static PyObject *PkgDepCacheMarkedKeep(PyObject *Self,PyObject *Args) @@ -506,7 +505,7 @@ static PyObject *PkgDepCacheMarkedKeep(PyObject *Self,PyObject *Args) pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj); pkgDepCache::StateCache &state = (*depcache)[Pkg]; - return HandleErrors(Py_BuildValue("b",state.Keep())); + return HandleErrors(PyBool_FromLong(state.Keep())); } static PyObject *PkgDepCacheMarkedDowngrade(PyObject *Self,PyObject *Args) @@ -520,7 +519,7 @@ static PyObject *PkgDepCacheMarkedDowngrade(PyObject *Self,PyObject *Args) pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj); pkgDepCache::StateCache &state = (*depcache)[Pkg]; - return HandleErrors(Py_BuildValue("b",state.Downgrade())); + return HandleErrors(PyBool_FromLong(state.Downgrade())); } static PyObject *PkgDepCacheMarkedReinstall(PyObject *Self,PyObject *Args) @@ -536,41 +535,104 @@ static PyObject *PkgDepCacheMarkedReinstall(PyObject *Self,PyObject *Args) bool res = state.Install() && (state.iFlags & pkgDepCache::ReInstall); - return HandleErrors(Py_BuildValue("b",res)); + return HandleErrors(PyBool_FromLong(res)); } static PyMethodDef PkgDepCacheMethods[] = { - {"init",PkgDepCacheInit,METH_VARARGS,"Init the depcache (done on construct automatically)"}, - {"get_candidate_ver",PkgDepCacheGetCandidateVer,METH_VARARGS,"Get candidate version"}, - {"set_candidate_ver",PkgDepCacheSetCandidateVer,METH_VARARGS,"Set candidate version"}, + {"init",PkgDepCacheInit,METH_VARARGS, + "init(progress: apt.progress.base.OpProgress)\n\n" + "Initialize the depcache (done automatically when constructing\n" + "the object)."}, + {"get_candidate_ver",PkgDepCacheGetCandidateVer,METH_VARARGS, + "get_candidate_ver(pkg: apt_pkg.Package) -> apt_pkg.Version\n\n" + "Return the candidate version for the package, normally the version\n" + "with the highest pin (changeable using set_candidate_ver)."}, + {"set_candidate_ver",PkgDepCacheSetCandidateVer,METH_VARARGS, + "set_candidate_ver(pkg: apt_pkg.Package, ver: apt_pkg.Version) -> bool\n\n" + "Set the candidate version of 'pkg' to 'ver'."}, // 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_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."}, + {"upgrade",PkgDepCacheUpgrade,METH_VARARGS, + "upgrade([dist_upgrade: bool = True]) -> bool\n\n" + "Mark the packages for upgrade under the same conditions apt-get\n" + "upgrade does. If 'dist_upgrade' is True, also allow packages to\n" + "be upgraded if they require installation/removal of other packages;\n" + "just like apt-get dist-upgrade."}, + {"fix_broken",PkgDepCacheFixBroken,METH_VARARGS, + "fix_broken() -> bool\n\n" + "Fix broken packages."}, + {"read_pinfile",PkgDepCacheReadPinFile,METH_VARARGS, + "read_pinfile([file: str])\n\n" + "Read the pin policy"}, + {"minimize_upgrade",PkgDepCacheMinimizeUpgrade, METH_VARARGS, + "minimize_upgrade() -> bool\n\n" + "Go over the entire set of packages and try to keep each package\n" + "marked for upgrade. If a conflict is generated then the package\n" + "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"}, - {"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"}, + {"mark_keep",PkgDepCacheMarkKeep,METH_VARARGS, + "mark_keep(pkg: apt_pkg.Package)\n\n" + "Mark package to be kept."}, + {"mark_delete",PkgDepCacheMarkDelete,METH_VARARGS, + "mark_delete(pkg: apt_pkg.Package[, purge: bool = False])\n\n" + "Mark package for deletion, and if 'purge' is True also for purging."}, + {"mark_install",PkgDepCacheMarkInstall,METH_VARARGS, + "mark_install(pkg: apt_pkg.Package[, auto_inst=True, from_user=True])\n\n" + "Mark the package for installation. The parameter 'auto_inst' controls\n" + "whether the dependencies of the package are marked for installation\n" + "as well. The parameter 'from_user' controls whether the package is\n" + "registered as NOT automatically installed."}, + {"mark_auto",PkgDepCacheMarkAuto,METH_VARARGS, + "mark_auto(pkg: apt_pkg.Package, auto: bool)\n\n" + "Mark package as automatically installed (if auto=True),\n" + "or as not automatically installed (if auto=False)."}, + {"set_reinstall",PkgDepCacheSetReInstall,METH_VARARGS, + "set_reinstall(pkg: apt_pkg.Package, reinstall: bool)\n\n" + "Set whether the package should be reinstalled (reinstall = True or False)."}, // state information - {"is_upgradable",PkgDepCacheIsUpgradable,METH_VARARGS,"Is pkg upgradable"}, - {"is_now_broken",PkgDepCacheIsNowBroken,METH_VARARGS,"Is pkg is now broken"}, - {"is_inst_broken",PkgDepCacheIsInstBroken,METH_VARARGS,"Is pkg broken on the current install"}, - {"is_garbage",PkgDepCacheIsGarbage,METH_VARARGS,"Is pkg garbage (mark-n-sweep)"}, - {"is_auto_installed",PkgDepCacheIsAutoInstalled,METH_VARARGS,"Is pkg marked as auto installed"}, - {"marked_install",PkgDepCacheMarkedInstall,METH_VARARGS,"Is pkg marked for install"}, - {"marked_upgrade",PkgDepCacheMarkedUpgrade,METH_VARARGS,"Is pkg marked for upgrade"}, - {"marked_delete",PkgDepCacheMarkedDelete,METH_VARARGS,"Is pkg marked for delete"}, - {"marked_keep",PkgDepCacheMarkedKeep,METH_VARARGS,"Is pkg marked for keep"}, - {"marked_reinstall",PkgDepCacheMarkedReinstall,METH_VARARGS,"Is pkg marked for reinstall"}, - {"marked_downgrade",PkgDepCacheMarkedDowngrade,METH_VARARGS,"Is pkg marked for downgrade"}, + {"is_upgradable",PkgDepCacheIsUpgradable,METH_VARARGS, + "is_upgradable(pkg: apt_pkg.Package) -> bool\n\n" + "Check whether the package is upgradable."}, + {"is_now_broken",PkgDepCacheIsNowBroken,METH_VARARGS, + "is_now_broken(pkg: apt_pkg.Package) -> bool\n\n" + "Check whether the package is broken, taking marked changes into account."}, + {"is_inst_broken",PkgDepCacheIsInstBroken,METH_VARARGS, + "is_inst_broken(pkg: apt_pkg.Package) -> bool\n\n" + "Check whether the package is broken, ignoring marked changes."}, + {"is_garbage",PkgDepCacheIsGarbage,METH_VARARGS, + "is_garbage(pkg: apt_pkg.Package) -> bool\n\n" + "Check whether the package is garbage, i.e. whether it is automatically\n" + "installed and the reverse dependencies are not installed anymore."}, + {"is_auto_installed",PkgDepCacheIsAutoInstalled,METH_VARARGS, + "is_auto_installed(pkg: apt_pkg.Package) -> bool\n\n" + "Check whether the package is marked as automatically installed."}, + {"marked_install",PkgDepCacheMarkedInstall,METH_VARARGS, + "marked_install(pkg: apt_pkg.Package) -> bool\n\n" + "Check whether the package is marked for installation."}, + {"marked_upgrade",PkgDepCacheMarkedUpgrade,METH_VARARGS, + "marked_upgrade(pkg: apt_pkg.Package) -> bool\n\n" + "Check whether the package is marked for upgrade."}, + {"marked_delete",PkgDepCacheMarkedDelete,METH_VARARGS, + "marked_delete(pkg: apt_pkg.Package) -> bool\n\n" + "Check whether the package is marked for removal."}, + {"marked_keep",PkgDepCacheMarkedKeep,METH_VARARGS, + "marked_keep(pkg: apt_pkg.Package) -> bool\n\n" + "Check whether the package should be kept."}, + {"marked_reinstall",PkgDepCacheMarkedReinstall,METH_VARARGS, + "marked_reinstall(pkg: apt_pkg.Package) -> bool\n\n" + "Check whether the package is marked for re-installation."}, + {"marked_downgrade",PkgDepCacheMarkedDowngrade,METH_VARARGS, + "marked_downgrade(pkg: apt_pkg.Package) -> bool\n\n" + "Check whether the package is marked for downgrade."}, // Action - {"commit", PkgDepCacheCommit, METH_VARARGS, "Commit pending changes"}, + {"commit", PkgDepCacheCommit, METH_VARARGS, + "commit(acquire_progress, install_progress)\n\n" + "Commit all the marked changes. This method takes two arguments,\n" + "'acquire_progress' takes an apt.progress.base.AcquireProgress\n" + "object and 'install_progress' an apt.progress.base.InstallProgress\n" + "object."}, {} }; @@ -608,13 +670,23 @@ static PyObject *PkgDepCacheGetPolicy(PyObject *Self,void*) { static PyGetSetDef PkgDepCacheGetSet[] = { - {"broken_count",PkgDepCacheGetBrokenCount}, - {"deb_size",PkgDepCacheGetDebSize}, - {"del_count",PkgDepCacheGetDelCount}, - {"inst_count",PkgDepCacheGetInstCount}, - {"keep_count",PkgDepCacheGetKeepCount}, - {"usr_size",PkgDepCacheGetUsrSize}, - {"policy",PkgDepCacheGetPolicy}, + {"broken_count",PkgDepCacheGetBrokenCount,0, + "The number of packages with broken dependencies in the cache."}, + {"deb_size",PkgDepCacheGetDebSize,0, + "The size of the packages which are needed for the changes to be\n" + "applied."}, + {"del_count",PkgDepCacheGetDelCount,0, + "The number of packages marked for removal."}, + {"inst_count",PkgDepCacheGetInstCount,0, + "The number of packages marked for installation."}, + {"keep_count",PkgDepCacheGetKeepCount,0, + "The number of packages marked for keep."}, + {"usr_size",PkgDepCacheGetUsrSize,0, + "The amount of space required for installing/removing the packages,\n" + "i.e. the Installed-Size of all packages marked for installation\n" + "minus the Installed-Size of all packages for removal."}, + {"policy",PkgDepCacheGetPolicy,0, + "The apt_pkg.Policy object used by this cache."}, {} }; @@ -643,9 +715,9 @@ static PyObject *PkgDepCacheNew(PyTypeObject *type,PyObject *Args,PyObject *kwds return HandleErrors(DepCachePyObj); } -static char *doc_PkgDepCache = "DepCache(cache) -> DepCache() object\n\n" +static char *doc_PkgDepCache = "DepCache(cache: apt_pkg.Cache)\n\n" "A DepCache() holds extra information on the state of the packages.\n\n" - "The parameter *cache* refers to an apt_pkg.Cache() object."; + "The parameter 'cache' refers to an apt_pkg.Cache() object."; PyTypeObject PyDepCache_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) @@ -750,7 +822,7 @@ static PyObject *PkgProblemResolverResolve(PyObject *Self,PyObject *Args) res = fixer->Resolve(brokenFix); Py_END_ALLOW_THREADS - return HandleErrors(Py_BuildValue("b", res)); + return HandleErrors(PyBool_FromLong(res)); } static PyObject *PkgProblemResolverResolveByKeep(PyObject *Self,PyObject *Args) @@ -764,7 +836,7 @@ static PyObject *PkgProblemResolverResolveByKeep(PyObject *Self,PyObject *Args) res = fixer->ResolveByKeep(); Py_END_ALLOW_THREADS - return HandleErrors(Py_BuildValue("b", res)); + return HandleErrors(PyBool_FromLong(res)); } static PyObject *PkgProblemResolverProtect(PyObject *Self,PyObject *Args) @@ -816,17 +888,37 @@ static PyObject *PkgProblemResolverInstallProtect(PyObject *Self,PyObject *Args) static PyMethodDef PkgProblemResolverMethods[] = { // config - {"protect", PkgProblemResolverProtect, METH_VARARGS, "protect(PkgIterator)"}, - {"remove", PkgProblemResolverRemove, METH_VARARGS, "remove(PkgIterator)"}, - {"clear", PkgProblemResolverClear, METH_VARARGS, "clear(PkgIterator)"}, - {"install_protect", PkgProblemResolverInstallProtect, METH_VARARGS, "install_protect()"}, + {"protect", PkgProblemResolverProtect, METH_VARARGS, + "protect(pkg: apt_pkg.Package)\n\n" + "Mark the package as protected in the resolver, meaning that its\n" + "state will not be changed."}, + {"remove", PkgProblemResolverRemove, METH_VARARGS, + "remove(pkg: apt_pkg.Package)\n\n" + "Mark the package for removal in the resolver."}, + {"clear", PkgProblemResolverClear, METH_VARARGS, + "clear(pkg: apt_pkg.Package)\n\n" + "Revert the actions done by protect()/remove() on the package."}, + {"install_protect", PkgProblemResolverInstallProtect, METH_VARARGS, + "install_protect()\n\n" + "Install all protected packages."}, // Actions - {"resolve", PkgProblemResolverResolve, METH_VARARGS, "Try to intelligently resolve problems by installing and removing packages"}, - {"resolve_by_keep", PkgProblemResolverResolveByKeep, METH_VARARGS, "Try to resolv problems only by using keep"}, + {"resolve", PkgProblemResolverResolve, METH_VARARGS, + "resolve([fix_broken: bool = True]) -> bool\n\n" + "Try to intelligently resolve problems by installing and removing\n" + "packages. If 'fix_broken' is True, apt will try to repair broken\n" + "dependencies of installed packages."}, + {"resolve_by_keep", PkgProblemResolverResolveByKeep, METH_VARARGS, + "resolve_by_keep() -> bool\n\n" + "Try to resolve problems only by using keep."}, {} }; +static const char *problemresolver_doc = + "ProblemResolver(depcache: apt_pkg.DepCache)\n\n" + "ProblemResolver objects take care of resolving problems\n" + "with dependencies. They mark packages for installation/\n" + "removal and try to satisfy all dependencies."; PyTypeObject PyProblemResolver_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) @@ -852,7 +944,7 @@ PyTypeObject PyProblemResolver_Type = (Py_TPFLAGS_DEFAULT | // tp_flags Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC), - "ProblemResolver Object", // tp_doc + problemresolver_doc, // tp_doc CppTraverse<pkgProblemResolver *>, // tp_traverse CppClear<pkgProblemResolver *>, // tp_clear 0, // tp_richcompare @@ -877,7 +969,11 @@ PyTypeObject PyProblemResolver_Type = // pkgActionGroup Class /*{{{*/ // --------------------------------------------------------------------- - +static const char *actiongroup_release_doc = + "release()\n\n" + "End the scope of this action group. If this is the only action\n" + "group bound to the cache, this will cause any deferred cleanup\n" + "actions to be performed."; static PyObject *PkgActionGroupRelease(PyObject *Self,PyObject *Args) { pkgDepCache::ActionGroup *ag = GetCpp<pkgDepCache::ActionGroup*>(Self); @@ -888,11 +984,19 @@ static PyObject *PkgActionGroupRelease(PyObject *Self,PyObject *Args) return HandleErrors(Py_None); } +static const char *actiongroup__enter__doc = + "__enter__() -> ActionGroup\n\n" + "A dummy action which just returns the object itself, so it can\n" + "be used as a context manager."; static PyObject *PkgActionGroupEnter(PyObject *Self,PyObject *Args) { if (PyArg_ParseTuple(Args,"") == 0) return 0; return Self; } + +static const char *actiongroup__exit__doc = + "__exit__(*excinfo) -> bool\n\n" + "Same as release(), but for use as a context manager."; static PyObject *PkgActionGroupExit(PyObject *Self,PyObject *Args) { pkgDepCache::ActionGroup *ag = GetCpp<pkgDepCache::ActionGroup*>(Self); ag->release(); @@ -901,11 +1005,9 @@ static PyObject *PkgActionGroupExit(PyObject *Self,PyObject *Args) { static PyMethodDef PkgActionGroupMethods[] = { - {"release", PkgActionGroupRelease, METH_VARARGS, "release()"}, - {"__exit__", PkgActionGroupExit, METH_VARARGS, "__exit__(...) -> " - "Release the action group, for 'with' statement."}, - {"__enter__", PkgActionGroupEnter, METH_VARARGS, "__enter__() -> " - "Enter, for the 'with' statement. Does nothing."}, + {"release", PkgActionGroupRelease, METH_VARARGS, actiongroup_release_doc}, + {"__enter__", PkgActionGroupEnter, METH_VARARGS, actiongroup__enter__doc}, + {"__exit__", PkgActionGroupExit, METH_VARARGS, actiongroup__exit__doc}, {} }; diff --git a/python/hashes.cc b/python/hashes.cc index d0b0fb0c..8cc86f4e 100644 --- a/python/hashes.cc +++ b/python/hashes.cc @@ -88,9 +88,8 @@ static char *hashes_doc = "Hashes([object: (bytes, file)])\n\n" "Calculate hashes for the given object. It can be used to create all\n" "supported hashes for a file.\n\n" - "The parameter *object* can be a bytes (3.X) / str (2.X) object, or an\n" - "object providing the fileno() method or an integer describing a file\n" - "descriptor."; + "The parameter 'object' can be a bytestring, an object providing the\n" + "fileno() method, or an integer describing a file descriptor."; PyTypeObject PyHashes_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) diff --git a/python/indexfile.cc b/python/indexfile.cc index c6d0b1cc..037be210 100644 --- a/python/indexfile.cc +++ b/python/indexfile.cc @@ -27,7 +27,9 @@ static PyObject *IndexFileArchiveURI(PyObject *Self,PyObject *Args) static PyMethodDef IndexFileMethods[] = { - {"archive_uri",IndexFileArchiveURI,METH_VARARGS,"Returns the ArchiveURI"}, + {"archive_uri",IndexFileArchiveURI,METH_VARARGS, + "archive_uri(path: str) -> str\n\n" + "Return the URI to the given path in the archive."}, {} }; @@ -39,16 +41,16 @@ static PyObject *IndexFileGetDescribe(PyObject *Self,void*) { return Safe_FromString(File->Describe().c_str()); } static PyObject *IndexFileGetExists(PyObject *Self,void*) { - return Py_BuildValue("i",(File->Exists())); + return PyBool_FromLong((File->Exists())); } static PyObject *IndexFileGetHasPackages(PyObject *Self,void*) { - return Py_BuildValue("i",(File->HasPackages())); + return PyBool_FromLong((File->HasPackages())); } static PyObject *IndexFileGetSize(PyObject *Self,void*) { return Py_BuildValue("i",(File->Size())); } static PyObject *IndexFileGetIsTrusted(PyObject *Self,void*) { - return Py_BuildValue("i",(File->IsTrusted())); + return PyBool_FromLong((File->IsTrusted())); } #undef File @@ -67,15 +69,26 @@ static PyObject *IndexFileRepr(PyObject *Self) #undef S static PyGetSetDef IndexFileGetSet[] = { - {"describe",IndexFileGetDescribe}, - {"exists",IndexFileGetExists}, - {"has_packages",IndexFileGetHasPackages}, - {"is_trusted",IndexFileGetIsTrusted}, - {"label",IndexFileGetLabel}, - {"size",IndexFileGetSize}, + {"describe",IndexFileGetDescribe,0, + "A string describing the index file."}, + {"exists",IndexFileGetExists,0, + "A boolean value determining whether the index file exists."}, + {"has_packages",IndexFileGetHasPackages,0, + "A boolean value determining whether the index file has packages."}, + {"is_trusted",IndexFileGetIsTrusted,0, + "A boolean value determining whether the file can be trusted; e.g.\n" + "because it is from a source with a GPG signed Release file."}, + {"label",IndexFileGetLabel,0, + "The label of the index file."}, + {"size",IndexFileGetSize,0, + "The size of the files, measured in bytes."}, {} }; +static const char *indexfile_doc = + "Represent an index file, i.e. package indexes, translation indexes,\n" + "and source indexes."; + PyTypeObject PyIndexFile_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) @@ -100,7 +113,7 @@ PyTypeObject PyIndexFile_Type = 0, // tp_setattro 0, // tp_as_buffer Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags - "IndexFile Object", // tp_doc + indexfile_doc, // tp_doc CppTraverse<pkgIndexFile*>, // tp_traverse CppClear<pkgIndexFile*>, // tp_clear 0, // tp_richcompare diff --git a/python/indexrecords.cc b/python/indexrecords.cc index 80960160..d6a3263c 100644 --- a/python/indexrecords.cc +++ b/python/indexrecords.cc @@ -41,12 +41,14 @@ static PyObject *indexrecords_load(PyObject *self,PyObject *args) if (PyArg_ParseTuple(args, "s", &filename) == 0) return 0; indexRecords *records = GetCpp<indexRecords*>(self); - return HandleErrors(Py_BuildValue("i", records->Load(filename))); + return HandleErrors(PyBool_FromLong(records->Load(filename))); } -static char *indexrecords_lookup_doc = "lookup(metakey)\n\n" - "Lookup the filename given by metakey, return a tuple (hash, size).\n" - "The hash part is a HashString() object."; +static char *indexrecords_lookup_doc = + "lookup(key: str) -> (HashString, int)\n\n" + "Look up the filename given by 'key' and return a tuple (hash, size),\n" + "where the first element 'hash' is an apt_pkg.HashString object\n" + "and the second element 'size' is an int object."; static PyObject *indexrecords_lookup(PyObject *self,PyObject *args) { const char *keyname; @@ -74,15 +76,17 @@ static PyObject *indexrecords_get_dist(PyObject *self) static PyMethodDef indexrecords_methods[] = { {"load",indexrecords_load,METH_VARARGS, - "load(filename: str)\n\nLoad the file given by filename."}, + "load(filename: str)\n\n" + "Load the file given by filename."}, {"get_dist",(PyCFunction)indexrecords_get_dist,METH_NOARGS, - "get_dist() -> str\n\nReturn a distribution set in the release file."}, + "get_dist() -> str\n\n" + "Return a distribution set in the release file."}, {"lookup",indexrecords_lookup,METH_VARARGS,indexrecords_lookup_doc}, {} }; static char *indexrecords_doc = "IndexRecords()\n\n" - "Representation of a release file."; + "Representation of a Release file."; PyTypeObject PyIndexRecords_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "apt_pkg.IndexRecords", // tp_name diff --git a/python/lock.cc b/python/lock.cc index fc78c0cb..2c957df1 100644 --- a/python/lock.cc +++ b/python/lock.cc @@ -78,11 +78,11 @@ static char *systemlock_doc = "SystemLock()\n\n" "Context manager for locking the package system. The lock is established\n" "as soon as the method __enter__() is called. It is released when\n" "__exit__() is called.\n\n" - "This should be used via the 'with' statement, e.g.::\n\n" + "This should be used via the 'with' statement, for example:\n\n" " with apt_pkg.SystemLock():\n" " ...\n\n" "Once the block is left, the lock is released automatically. The object\n" - "can be used multiple times::\n\n" + "can be used multiple times:\n\n" " lock = apt_pkg.SystemLock()\n" " with lock:\n" " ...\n" @@ -210,11 +210,11 @@ static char *filelock_doc = "SystemLock(filename: str)\n\n" "Context manager for locking using a file. The lock is established\n" "as soon as the method __enter__() is called. It is released when\n" "__exit__() is called.\n\n" - "This should be used via the 'with' statement, e.g.::\n\n" + "This should be used via the 'with' statement, for example:\n\n" " with apt_pkg.FileLock(filename):\n" " ...\n\n" "Once the block is left, the lock is released automatically. The object\n" - "can be used multiple times::\n\n" + "can be used multiple times:\n\n" " lock = apt_pkg.FileLock(filename)\n" " with lock:\n" " ...\n" diff --git a/python/metaindex.cc b/python/metaindex.cc index 2dcade7d..a00cf04e 100644 --- a/python/metaindex.cc +++ b/python/metaindex.cc @@ -27,7 +27,7 @@ static PyObject *MetaIndexGetDist(PyObject *Self,void*) { static PyObject *MetaIndexGetIsTrusted(PyObject *Self,void*) { metaIndex *meta = GetCpp<metaIndex*>(Self); - return Py_BuildValue("i",(meta->IsTrusted())); + return PyBool_FromLong((meta->IsTrusted())); } static PyObject *MetaIndexGetIndexFiles(PyObject *Self,void*) { @@ -48,10 +48,13 @@ static PyObject *MetaIndexGetIndexFiles(PyObject *Self,void*) { } static PyGetSetDef MetaIndexGetSet[] = { - {"dist",MetaIndexGetDist}, - {"index_files",MetaIndexGetIndexFiles}, - {"is_trusted",MetaIndexGetIsTrusted}, - {"uri",MetaIndexGetURI}, + {"dist",MetaIndexGetDist,0,"The distribution, as a string."}, + {"index_files",MetaIndexGetIndexFiles,0, + "A list of all IndexFile objects associated with this meta index."}, + {"is_trusted",MetaIndexGetIsTrusted,0, + "A boolean value determining whether the file can be trusted."}, + {"uri",MetaIndexGetURI,0, + "The uri the meta index is located at."}, {} }; @@ -66,6 +69,11 @@ static PyObject *MetaIndexRepr(PyObject *Self) } #undef S + +static const char *metaindex_doc = + "Provide information on meta-indexes (i.e. Release files), such as\n" + "whether they are trusted or their URI."; + PyTypeObject PyMetaIndex_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) @@ -89,7 +97,7 @@ PyTypeObject PyMetaIndex_Type = 0, // tp_setattro 0, // tp_as_buffer Py_TPFLAGS_DEFAULT, // tp_flags - "apt_pkg.MetaIndex Object", // tp_doc + metaindex_doc, // tp_doc 0, // tp_traverse 0, // tp_clear 0, // tp_richcompare diff --git a/python/pkgmanager.cc b/python/pkgmanager.cc index e8346b3d..df66c8c7 100644 --- a/python/pkgmanager.cc +++ b/python/pkgmanager.cc @@ -66,7 +66,7 @@ static PyObject *PkgManagerGetArchives(PyObject *Self,PyObject *Args) bool res = pm->GetArchives(s_fetcher, s_list, &s_records.Records); - return HandleErrors(Py_BuildValue("b",res)); + return HandleErrors(PyBool_FromLong(res)); } static PyObject *PkgManagerDoInstall(PyObject *Self,PyObject *Args) @@ -93,18 +93,35 @@ static PyObject *PkgManagerFixMissing(PyObject *Self,PyObject *Args) bool res = pm->FixMissing(); - return HandleErrors(Py_BuildValue("b",res)); + return HandleErrors(PyBool_FromLong(res)); } static PyMethodDef PkgManagerMethods[] = { - {"get_archives",PkgManagerGetArchives,METH_VARARGS,"Load the selected archives into the fetcher"}, - {"do_install",PkgManagerDoInstall,METH_VARARGS,"Do the actual install"}, - {"fix_missing",PkgManagerFixMissing,METH_VARARGS,"Fix the install if a pkg couldn't be downloaded"}, + {"get_archives",PkgManagerGetArchives,METH_VARARGS, + "get_archives(fetcher: Acquire, list: SourceList, recs: PackageRecords) -> bool\n\n" + "Download the packages marked for installation via the Acquire object\n" + "'fetcher', using the information found in 'list' and 'recs'."}, + {"do_install",PkgManagerDoInstall,METH_VARARGS, + "do_install(status_fd: int) -> int\n\n" + "Install the packages and return one of the class constants\n" + "RESULT_COMPLETED, RESULT_FAILED, RESULT_INCOMPLETE. The argument\n" + "status_fd can be used to specify a file descriptor that APT will\n" + "write status information on (see README.progress-reporting in the\n" + "apt source code for information on what will be written there)."}, + {"fix_missing",PkgManagerFixMissing,METH_VARARGS, + "fix_missing() -> bool\n\n" + "Fix the installation if a package could not be downloaded."}, {} }; +static const char *packagemanager_doc = + "PackageManager(depcache: apt_pkg.DepCache)\n\n" + "PackageManager objects allow the fetching of packages marked for\n" + "installation and the installation of those packages. The parameter\n" + "'depcache' specifies an apt_pkg.DepCache object where information\n" + "about the package selections is retrieved from."; PyTypeObject PyPackageManager_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) @@ -129,7 +146,7 @@ PyTypeObject PyPackageManager_Type = 0, // tp_as_buffer (Py_TPFLAGS_DEFAULT | // tp_flags Py_TPFLAGS_BASETYPE), - "PackageManager Object", // tp_doc + packagemanager_doc, // tp_doc 0, // tp_traverse 0, // tp_clear 0, // tp_richcompare diff --git a/python/pkgrecords.cc b/python/pkgrecords.cc index 916a2e0f..efa99b62 100644 --- a/python/pkgrecords.cc +++ b/python/pkgrecords.cc @@ -44,12 +44,14 @@ static PyObject *PkgRecordsLookup(PyObject *Self,PyObject *Args) Struct.Last = &Struct.Records.Lookup(pkgCache::VerFileIterator(*Cache,Cache->VerFileP+Index)); // always return true (to make it consistent with the pkgsrcrecords object - return Py_BuildValue("i", 1); + return PyBool_FromLong(1); } static PyMethodDef PkgRecordsMethods[] = { - {"lookup",PkgRecordsLookup,METH_VARARGS,"Changes to a new package"}, + {"lookup",PkgRecordsLookup,METH_VARARGS, + "lookup((packagefile: apt_pkg.PackageFile, index: int)) -> bool\n\n" + "Changes to a new package"}, {} }; @@ -117,18 +119,35 @@ static PyObject *PkgRecordsGetRecord(PyObject *Self,void*) { return PyString_FromStringAndSize(start,stop-start); } static PyGetSetDef PkgRecordsGetSet[] = { - {"filename",PkgRecordsGetFileName}, - {"homepage",PkgRecordsGetHomepage}, - {"long_desc",PkgRecordsGetLongDesc}, - {"md5_hash",PkgRecordsGetMD5Hash}, - {"maintainer",PkgRecordsGetMaintainer}, - {"name",PkgRecordsGetName}, - {"record",PkgRecordsGetRecord}, - {"sha1_hash",PkgRecordsGetSHA1Hash}, - {"sha256_hash",PkgRecordsGetSHA256Hash}, - {"short_desc",PkgRecordsGetShortDesc}, - {"source_pkg",PkgRecordsGetSourcePkg}, - {"source_ver",PkgRecordsGetSourceVer}, + {"filename",PkgRecordsGetFileName,0, + "The filename of the package, as stored in the 'Filename' field."}, + {"homepage",PkgRecordsGetHomepage,0, + "The homepage of the package, as stored in the 'Homepage' field."}, + {"long_desc",PkgRecordsGetLongDesc,0, + "The long description of the packages; i.e. all lines in the\n" + "'Description' field except for the first one."}, + {"md5_hash",PkgRecordsGetMD5Hash,0, + "The MD5 hash value of the package, as stored in the 'MD5Sum' field."}, + {"maintainer",PkgRecordsGetMaintainer,0, + "The maintainer of the package, as stored in the 'Maintainer' field."}, + {"name",PkgRecordsGetName,0, + "The name of the package, as stored in the 'Package' field."}, + {"record",PkgRecordsGetRecord,0, + "The raw record, suitable for parsing by apt_pkg.TagSection."}, + {"sha1_hash",PkgRecordsGetSHA1Hash,0, + "The SHA1 hash value, as stored in the 'SHA1' field."}, + {"sha256_hash",PkgRecordsGetSHA256Hash,0, + "The SHA256 hash value, as stored in the 'SHA256' field."}, + {"short_desc",PkgRecordsGetShortDesc,0, + "The short description of the package, i.e. the first line of the\n" + "'Description' field."}, + {"source_pkg",PkgRecordsGetSourcePkg,0, + "The name of the source package, if different from the name of the\n" + "binary package. This information is retrieved from the 'Source' field."}, + {"source_ver",PkgRecordsGetSourceVer,0, + "The version of the source package, if it differs from the version\n" + "of the binary package. Just like 'source_pkg', this information\n" + "is retrieved from the 'Source' field."}, {} }; @@ -144,6 +163,13 @@ static PyObject *PkgRecordsNew(PyTypeObject *type,PyObject *Args,PyObject *kwds) GetCpp<pkgCache *>(Owner))); } +static const char *packagerecords_doc = + "PackageRecords(cache: apt_pkg.Cache)\n\n" + "Package Records contain information about packages. Those objects\n" + "can be used to retrieve information such as maintainer or filename\n" + "of a package. They can also be used to retrieve the raw records\n" + "of the packages (i.e. those stanzas stored in Packages files)."; + PyTypeObject PyPackageRecords_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) @@ -169,9 +195,9 @@ PyTypeObject PyPackageRecords_Type = (Py_TPFLAGS_DEFAULT | // tp_flags Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC), - "Records Object", // tp_doc - CppTraverse<PkgRecordsStruct>, // tp_traverse - CppClear<PkgRecordsStruct>, // tp_clear + packagerecords_doc, // tp_doc + CppTraverse<PkgRecordsStruct>, // tp_traverse + CppClear<PkgRecordsStruct>, // tp_clear 0, // tp_richcompare 0, // tp_weaklistoffset 0, // tp_iter diff --git a/python/pkgsrcrecords.cc b/python/pkgsrcrecords.cc index 729a74b5..da3d0e04 100644 --- a/python/pkgsrcrecords.cc +++ b/python/pkgsrcrecords.cc @@ -34,7 +34,12 @@ struct PkgSrcRecordsStruct // PkgSrcRecords Class /*{{{*/ // --------------------------------------------------------------------- -static char *doc_PkgSrcRecordsLookup = "xxx"; +static char *doc_PkgSrcRecordsLookup = + "lookup(name: str) -> bool\n\n" + "Look up the source package with the given name. Each call moves\n" + "the position of the records parser forward. If there are no\n" + "more records, return None. If the lookup failed this way,\n" + "access to any of the attributes will result in an AttributeError."; static PyObject *PkgSrcRecordsLookup(PyObject *Self,PyObject *Args) { PkgSrcRecordsStruct &Struct = GetCpp<PkgSrcRecordsStruct>(Self); @@ -50,10 +55,13 @@ static PyObject *PkgSrcRecordsLookup(PyObject *Self,PyObject *Args) return HandleErrors(Py_None); } - return Py_BuildValue("i", 1); + return PyBool_FromLong(1); } -static char *doc_PkgSrcRecordsRestart = "Start Lookup from the beginning"; +static char *doc_PkgSrcRecordsRestart = + "restart()\n\n" + "Restart the lookup process. This moves the parser to the first\n" + "package and lookups can now be made just like on a new object."; static PyObject *PkgSrcRecordsRestart(PyObject *Self,PyObject *Args) { PkgSrcRecordsStruct &Struct = GetCpp<PkgSrcRecordsStruct>(Self); @@ -220,15 +228,27 @@ static PyObject *PkgSrcRecordsGetBuildDepends_old(PyObject *Self,void*) { #endif static PyGetSetDef PkgSrcRecordsGetSet[] = { - {"binaries",PkgSrcRecordsGetBinaries}, - {"build_depends",PkgSrcRecordsGetBuildDepends}, - {"files",PkgSrcRecordsGetFiles}, - {"index",PkgSrcRecordsGetIndex}, - {"maintainer",PkgSrcRecordsGetMaintainer}, - {"package",PkgSrcRecordsGetPackage}, - {"record",PkgSrcRecordsGetRecord}, - {"section",PkgSrcRecordsGetSection}, - {"version",PkgSrcRecordsGetVersion}, + {"binaries",PkgSrcRecordsGetBinaries,0, + "A list of the names of the binaries produced by this source package."}, + {"build_depends",PkgSrcRecordsGetBuildDepends,0, + "A dictionary describing the build-time dependencies of the package;\n" + "the format is the same as used for apt_pkg.Version.depends_list_str."}, + {"files",PkgSrcRecordsGetFiles,0, + "A list of tuples (md5: str, size: int, path: str, type: str), whereas\n" + "'type' can be 'diff' (includes .debian.tar.gz), 'dsc', 'tar'."}, + {"index",PkgSrcRecordsGetIndex,0, + "The index file associated with this record as a list of\n" + "apt_pkg.IndexFile objects."}, + {"maintainer",PkgSrcRecordsGetMaintainer,0, + "The maintainer of the package."}, + {"package",PkgSrcRecordsGetPackage,0, + "The name of the source package."}, + {"record",PkgSrcRecordsGetRecord,0, + "The raw record, suitable for parsing using apt_pkg.TagSection."}, + {"section",PkgSrcRecordsGetSection,0, + "The section of the source package."}, + {"version",PkgSrcRecordsGetVersion,0, + "The version of the source package."}, #ifdef COMPAT_0_7 {"BuildDepends",PkgSrcRecordsGetBuildDepends_old,0,"Deprecated function and deprecated output format."}, #endif @@ -243,6 +263,11 @@ static PyObject *PkgSrcRecordsNew(PyTypeObject *type,PyObject *args,PyObject *kw return HandleErrors(CppPyObject_NEW<PkgSrcRecordsStruct>(NULL, type)); } +static const char *sourcerecords_doc = + "SourceRecords()\n\n" + "Provide an easy way to look up the records of source packages and\n" + "provide easy attributes for some widely used fields of the record."; + PyTypeObject PySourceRecords_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) @@ -267,7 +292,7 @@ PyTypeObject PySourceRecords_Type = 0, // tp_as_buffer (Py_TPFLAGS_DEFAULT | // tp_flags Py_TPFLAGS_BASETYPE), - "SourceRecords Object", // tp_doc + sourcerecords_doc, // tp_doc 0, // tp_traverse 0, // tp_clear 0, // tp_richcompare diff --git a/python/policy.cc b/python/policy.cc index 3e1ec589..7eccb30c 100644 --- a/python/policy.cc +++ b/python/policy.cc @@ -37,8 +37,8 @@ static PyObject *policy_new(PyTypeObject *type,PyObject *Args, return CppPyObject_NEW<pkgPolicy*>(cache,&PyPolicy_Type,policy); } -static char *policy_get_priority_doc = "get_priority(package: apt_pkg.Package)" - " -> int\n\n" +static char *policy_get_priority_doc = + "get_priority(package: apt_pkg.Package) -> int\n\n" "Return the priority of the package."; PyObject *policy_get_priority(PyObject *self, PyObject *arg) { @@ -52,8 +52,8 @@ PyObject *policy_get_priority(PyObject *self, PyObject *arg) { } } -static char *policy_get_candidate_ver_doc = "get_match(package: apt_pkg.Package)" - " -> apt_pkg.Version\n\n" +static char *policy_get_candidate_ver_doc = + "get_match(package: apt_pkg.Package) -> apt_pkg.Version\n\n" "Get the best package for the job."; PyObject *policy_get_candidate_ver(PyObject *self, PyObject *arg) { @@ -69,8 +69,8 @@ PyObject *policy_get_candidate_ver(PyObject *self, PyObject *arg) { } } -static char *policy_get_match_doc = "get_match(package: apt_pkg.Package) -> " - "apt_pkg.Version\n\n" +static char *policy_get_match_doc = + "get_match(package: apt_pkg.Package) -> apt_pkg.Version\n\n" "Return a matching version for the given package."; static PyObject *policy_get_match(PyObject *self, PyObject *arg) { @@ -84,9 +84,10 @@ static PyObject *policy_get_match(PyObject *self, PyObject *arg) { return CppPyObject_NEW<pkgCache::VerIterator>(arg,&PyVersion_Type,ver); } -static char *policy_read_pinfile_doc = "read_pinfile(filename: str) -> bool\n\n" - "Read the pin file given by filename (e.g. '/etc/apt/preferences') and\n" - "add it to the policy."; +static char *policy_read_pinfile_doc = + "read_pinfile(filename: str) -> bool\n\n" + "Read the pin file given by filename (e.g. '/etc/apt/preferences')\n" + "and add it to the policy."; static PyObject *policy_read_pinfile(PyObject *self, PyObject *arg) { if (!PyString_Check(arg)) @@ -97,9 +98,10 @@ static PyObject *policy_read_pinfile(PyObject *self, PyObject *arg) { } #if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 8) -static char *policy_read_pindir_doc = "read_pindir(dirname: str) -> bool\n\n" - "Read the pin files in the given dir (e.g. '/etc/apt/preferences.d') and\n" - "add them to the policy."; +static char *policy_read_pindir_doc = + "read_pindir(dirname: str) -> bool\n\n" + "Read the pin files in the given dir (e.g. '/etc/apt/preferences.d')\n" + "and add them to the policy."; static PyObject *policy_read_pindir(PyObject *self, PyObject *arg) { if (!PyString_Check(arg)) @@ -110,12 +112,12 @@ static PyObject *policy_read_pindir(PyObject *self, PyObject *arg) { } #endif -static char *policy_create_pin_doc = "create_pin(type: str, pkg: str, " - "data: str, priority: int)\n\n" +static char *policy_create_pin_doc = + "create_pin(type: str, pkg: str, data: str, priority: int)\n\n" "Create a pin for the policy. The parameter 'type' refers to one of the\n" - "following strings: 'Version', 'Release', 'Origin'. The argument 'pkg'\n" - "is the name of the package, the parameter 'data' refers to the value\n" - "e.g. unstable for type='Release' and the other possible options. \n" + "strings 'Version', 'Release', or 'Origin'. The argument 'pkg' is the\n" + "name of the package. The parameter 'data' refers to the value\n" + "(e.g. 'unstable' for type='Release') and the other possible options.\n" "The parameter 'priority' gives the priority of the pin."; static PyObject *policy_create_pin(PyObject *self, PyObject *args) { @@ -154,7 +156,8 @@ static PyMethodDef policy_methods[] = { {} }; -static char *policy_doc = "Policy(cache)\n\n" +static char *policy_doc = + "Policy(cache)\n\n" "Representation of the policy of the Cache object given by cache. This\n" "provides a superset of policy-related functionality compared to the\n" "DepCache class. The DepCache can be used for most purposes, but there\n" diff --git a/python/progress.cc b/python/progress.cc index 18081690..9002b3eb 100644 --- a/python/progress.cc +++ b/python/progress.cc @@ -501,9 +501,7 @@ pkgPackageManager::OrderResult PyInstallProgress::Run(pkgPackageManager *pm) else method = PyObject_GetAttrString(callbackInst, "wait_child"); //std::cerr << "custom waitChild found" << std::endl; - PyObject *arglist = Py_BuildValue("(i)",child_id); - PyObject *result = PyObject_CallObject(method, arglist); - Py_DECREF(arglist); + PyObject *result = PyObject_CallObject(method, NULL); if (result == NULL) { std::cerr << "waitChild method invalid" << std::endl; PyErr_Print(); diff --git a/python/sourcelist.cc b/python/sourcelist.cc index 5a950b2c..b04bf5cb 100644 --- a/python/sourcelist.cc +++ b/python/sourcelist.cc @@ -21,7 +21,10 @@ // PkgsourceList Class /*{{{*/ // --------------------------------------------------------------------- -static char *doc_PkgSourceListFindIndex = "xxx"; +static char *doc_PkgSourceListFindIndex = + "find_index(pkgfile: apt_pkg.PackageFile) -> apt_pkg.IndexFile\n\n" + "Return the index file for the given package file, or None if none\n" + "could be found."; static PyObject *PkgSourceListFindIndex(PyObject *Self,PyObject *Args) { pkgSourceList *list = GetCpp<pkgSourceList*>(Self); @@ -47,16 +50,23 @@ static PyObject *PkgSourceListFindIndex(PyObject *Self,PyObject *Args) return Py_None; } -static char *doc_PkgSourceListReadMainList = "xxx"; +static char *doc_PkgSourceListReadMainList = + "read_main_list() -> bool\n\n" + "Read /etc/apt/sources.list and similar files to populate the list\n" + "of indexes."; static PyObject *PkgSourceListReadMainList(PyObject *Self,PyObject *Args) { pkgSourceList *list = GetCpp<pkgSourceList*>(Self); bool res = list->ReadMainList(); - return HandleErrors(Py_BuildValue("b",res)); + return HandleErrors(PyBool_FromLong(res)); } -static char *doc_PkgSourceListGetIndexes = "Load the indexes into the fetcher"; +static char *doc_PkgSourceListGetIndexes = + "get_indexes(acquire: apt_pkg.Acquire[, all: bool=False]) -> bool\n\n" + "Add all indexes (i.e. stuff like Release files, Packages files)\n" + "to the Acquire object 'acquire'. If 'all' is True, all indexes\n" + "will be added, otherwise only changed indexes will be added."; static PyObject *PkgSourceListGetIndexes(PyObject *Self,PyObject *Args) { pkgSourceList *list = GetCpp<pkgSourceList*>(Self); @@ -69,7 +79,7 @@ static PyObject *PkgSourceListGetIndexes(PyObject *Self,PyObject *Args) pkgAcquire *fetcher = GetCpp<pkgAcquire*>(pyFetcher); bool res = list->GetIndexes(fetcher, all); - return HandleErrors(Py_BuildValue("b",res)); + return HandleErrors(PyBool_FromLong(res)); } static PyMethodDef PkgSourceListMethods[] = @@ -110,6 +120,10 @@ static PyObject *PkgSourceListNew(PyTypeObject *type,PyObject *args,PyObject *kw return CppPyObject_NEW<pkgSourceList*>(NULL, type,new pkgSourceList()); } +static const char *sourcelist_doc = + "SourceList()\n\n" + "Represent the list of sources stored in /etc/apt/sources.list and\n" + "similar files."; PyTypeObject PySourceList_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) @@ -134,7 +148,7 @@ PyTypeObject PySourceList_Type = 0, // tp_as_buffer (Py_TPFLAGS_DEFAULT | // tp_flags Py_TPFLAGS_BASETYPE), - "pkgSourceList Object", // tp_doc + sourcelist_doc, // tp_doc 0, // tp_traverse 0, // tp_clear 0, // tp_richcompare diff --git a/python/string.cc b/python/string.cc index b95ee3eb..6a1ce4e2 100644 --- a/python/string.cc +++ b/python/string.cc @@ -116,7 +116,7 @@ PyObject *StrCheckDomainList(PyObject *Self,PyObject *Args) char *List = 0; if (PyArg_ParseTuple(Args,"ss",&Host,&List) == 0) return 0; - return Py_BuildValue("i",CheckDomainList(Host,List)); + return PyBool_FromLong(CheckDomainList(Host,List)); } /*}}}*/ diff --git a/python/tag.cc b/python/tag.cc index bc470620..5db34c1d 100644 --- a/python/tag.cc +++ b/python/tag.cc @@ -89,7 +89,10 @@ void TagFileFree(PyObject *Obj) /*}}}*/ // Tag Section Wrappers /*{{{*/ -static char *doc_Find = "Find(Name) -> String/None"; +static char *doc_Find = + "find(name: str[, default = None]) -> str\n\n" + "Find the key given by 'name' and return the value. If the key can\n" + "not be found, return 'default'."; static PyObject *TagSecFind(PyObject *Self,PyObject *Args) { char *Name = 0; @@ -108,7 +111,10 @@ static PyObject *TagSecFind(PyObject *Self,PyObject *Args) return PyString_FromStringAndSize(Start,Stop-Start); } -static char *doc_FindRaw = "FindRaw(Name) -> String/None"; +static char *doc_FindRaw = + "find_raw(name: str[, default = None] -> str\n\n" + "Same as find(), but returns the complete 'key: value' field; instead of\n" + "just the value."; static PyObject *TagSecFindRaw(PyObject *Self,PyObject *Args) { char *Name = 0; @@ -131,7 +137,11 @@ static PyObject *TagSecFindRaw(PyObject *Self,PyObject *Args) return PyString_FromStringAndSize(Start,Stop-Start); } -static char *doc_FindFlag = "FindFlag(Name) -> integer/none"; +static char *doc_FindFlag = + "find_flag(name: str) -> int\n\n" + "Return 1 if the key's value is 'yes' or a similar value describing\n" + "a boolean true. If the field does not exist, or does not have such a\n" + "value, return 0."; static PyObject *TagSecFindFlag(PyObject *Self,PyObject *Args) { char *Name = 0; @@ -144,7 +154,7 @@ static PyObject *TagSecFindFlag(PyObject *Self,PyObject *Args) Py_INCREF(Py_None); return Py_None; } - return Py_BuildValue("i",Flag); + return PyBool_FromLong(Flag); } // Map access, operator [] @@ -175,7 +185,9 @@ static Py_ssize_t TagSecLength(PyObject *Self) } // Look like a mapping -static char *doc_Keys = "keys() -> List"; +static char *doc_Keys = + "keys() -> list\n\n" + "Return a list of all keys."; static PyObject *TagSecKeys(PyObject *Self,PyObject *Args) { pkgTagSection &Tags = GetCpp<pkgTagSection>(Self); @@ -200,7 +212,9 @@ static PyObject *TagSecKeys(PyObject *Self,PyObject *Args) } #if PY_MAJOR_VERSION < 3 -static char *doc_Exists = "Exists(Name) -> integer"; +static char *doc_Exists = + "has_key(name: str) -> bool\n\n" + "Return True if the key given by 'name' exists, False otherwise."; static PyObject *TagSecExists(PyObject *Self,PyObject *Args) { char *Name = 0; @@ -209,9 +223,7 @@ static PyObject *TagSecExists(PyObject *Self,PyObject *Args) const char *Start; const char *Stop; - if (GetCpp<pkgTagSection>(Self).Find(Name,Start,Stop) == false) - return Py_BuildValue("i",0); - return Py_BuildValue("i",1); + return PyBool_FromLong(GetCpp<pkgTagSection>(Self).Find(Name,Start,Stop)); } #endif @@ -227,7 +239,9 @@ static int TagSecContains(PyObject *Self,PyObject *Arg) return 1; } -static char *doc_Bytes = "Bytes() -> integer"; +static char *doc_Bytes = + "bytes() -> int\n\n" + "Return the number of bytes this section is large."; static PyObject *TagSecBytes(PyObject *Self,PyObject *Args) { if (PyArg_ParseTuple(Args,"") == 0) @@ -245,7 +259,9 @@ static PyObject *TagSecStr(PyObject *Self) } /*}}}*/ // TagFile Wrappers /*{{{*/ -static char *doc_Step = "Step() -> Integer\n0 means EOF."; +static char *doc_Step = + "step() -> bool\n\n" + "Step forward in the file"; static PyObject *TagFileStep(PyObject *Self,PyObject *Args) { if (PyArg_ParseTuple(Args,"") == 0) @@ -253,9 +269,9 @@ static PyObject *TagFileStep(PyObject *Self,PyObject *Args) TagFileData &Obj = *(TagFileData *)Self; if (Obj.Object.Step(Obj.Section->Object) == false) - return HandleErrors(Py_BuildValue("i",0)); + return HandleErrors(PyBool_FromLong(0)); - return HandleErrors(Py_BuildValue("i",1)); + return HandleErrors(PyBool_FromLong(1)); } // TagFile Wrappers /*{{{*/ @@ -296,7 +312,9 @@ static PyObject *TagFileIter(PyObject *Self) { return Self; } -static char *doc_Offset = "Offset() -> Integer"; +static char *doc_Offset = + "offset() -> int\n\n" + "Return the current offset."; static PyObject *TagFileOffset(PyObject *Self,PyObject *Args) { if (PyArg_ParseTuple(Args,"") == 0) @@ -304,7 +322,11 @@ static PyObject *TagFileOffset(PyObject *Self,PyObject *Args) return Py_BuildValue("i",((TagFileData *)Self)->Object.Offset()); } -static char *doc_Jump = "Jump(Offset) -> Integer"; +static char *doc_Jump = + "jump(offset: int) -> bool\n\n" + "Jump to the given offset; return True on success. Note that jumping to\n" + "an offset is not very reliable, and the 'section' attribute may point\n" + "to an unexpected section."; static PyObject *TagFileJump(PyObject *Self,PyObject *Args) { int Offset; @@ -313,9 +335,9 @@ static PyObject *TagFileJump(PyObject *Self,PyObject *Args) TagFileData &Obj = *(TagFileData *)Self; if (Obj.Object.Jump(Obj.Section->Object,Offset) == false) - return HandleErrors(Py_BuildValue("i",0)); + return HandleErrors(PyBool_FromLong(0)); - return HandleErrors(Py_BuildValue("i",1)); + return HandleErrors(PyBool_FromLong(1)); } /*}}}*/ // ParseSection - Parse a single section from a tag file /*{{{*/ @@ -346,7 +368,7 @@ static PyObject *TagSecNew(PyTypeObject *type,PyObject *Args,PyObject *kwds) { } #ifdef COMPAT_0_7 -char *doc_ParseSection ="ParseSection(Text) -> TagSection() object. Deprecated."; +char *doc_ParseSection = "ParseSection(Text) -> TagSection()\n\nDeprecated."; PyObject *ParseSection(PyObject *self,PyObject *Args) { if (getenv("PYTHON_APT_DEPRECATION_WARNINGS") != NULL) @@ -387,7 +409,7 @@ static PyObject *TagFileNew(PyTypeObject *type,PyObject *Args,PyObject *kwds) return HandleErrors(New); } #ifdef COMPAT_0_7 -char *doc_ParseTagFile = "ParseTagFile(File) -> TagFile() object. Deprecated."; +char *doc_ParseTagFile = "ParseTagFile(file) -> TagFile()\n\nDeprecated."; PyObject *ParseTagFile(PyObject *self,PyObject *Args) { if (getenv("PYTHON_APT_DEPRECATION_WARNINGS") != NULL) PyErr_WarnEx(PyExc_DeprecationWarning, "apt_pkg.ParseTagFile() is " @@ -402,20 +424,19 @@ PyObject *ParseTagFile(PyObject *self,PyObject *Args) { /* An interesting future extension would be to add a user settable order list */ char *doc_RewriteSection = -"RewriteSection(Section,Order,RewriteList) -> String\n" +"rewrite_section(section: TagSection, order: list, rewrite_list: list) -> str\n" "\n" -"The section rewriter allows a section to be taken in, have fields added,\n" -"removed or changed and then put back out. During this process the fields\n" -"within the section are sorted to corrispond to a proper order. Order is a\n" -"list of field names with their proper capitialization.\n" -"apt_pkg.RewritePackageOrder and apt_pkg.RewriteSourceOrder are two predefined\n" -"orders.\n" -"RewriteList is a list of tuples. Each tuple is of the form:\n" -" (Tag,NewValue[,RenamedTo])\n" -"Tag specifies the tag in the source section. NewValue is the new value of\n" -"that tag and the optional RenamedTo field can cause the tag to be changed.\n" -"If NewValue is None then the tag is removed\n" -"Ex. ('Source','apt','Package') is used for .dsc files."; +"Rewrite the section given by 'section' using 'rewrite_list', and order the\n" +"fields according to 'order'.\n\n" +"The parameter 'order' is a list object containing the names of the fields\n" +"in the order they should appear in the rewritten section.\n" +"apt_pkg.REWRITE_PACKAGE_ORDER and apt_pkg.REWRITE_SOURCE_ORDER are two\n" +"predefined lists for rewriting package and source sections, respectively\n\n" +"The parameter 'rewrite_list' is a list of tuples of the form\n" +"'(tag, newvalue[, renamed_to])', where 'tag' describes the field which\n" +"should be changed, 'newvalue' the value which should be inserted or None\n" +"to delete the field, and the optional renamed_to can be used to rename the\n" +"field."; PyObject *RewriteSection(PyObject *self,PyObject *Args) { PyObject *Section; @@ -491,11 +512,11 @@ PySequenceMethods TagSecSeqMeth = {0,0,0,0,0,0,0,TagSecContains,0,0}; PyMappingMethods TagSecMapMeth = {TagSecLength,TagSecMap,0}; -static char *doc_TagSec = "TagSection(text) -> Create a new object.\n\n" - "TagSection() objects provide methods to access rfc822-style formatted\n" - "header sections, like those in debian/control or Packages files.\n\n" +static char *doc_TagSec = "TagSection(text: str)\n\n" + "Provide methods to access RFC822-style header sections, like those\n" + "found in debian/control or Packages files.\n\n" "TagSection() behave like read-only dictionaries and also provide access\n" - "to the functions provided by the C++ class (e.g. Find)"; + "to the functions provided by the C++ class (e.g. find)"; PyTypeObject PyTagSection_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) @@ -560,22 +581,24 @@ static PyObject *TagFileGetSection(PyObject *Self,void*) { } static PyGetSetDef TagFileGetSet[] = { - {"section",TagFileGetSection,0,"Return a TagSection.",0}, + {"section",TagFileGetSection,0, + "The current section, as a TagSection object.",0}, {} }; -static char *doc_TagFile = "TagFile(file) -> TagFile() object. \n\n" - "TagFile() objects provide access to debian control files, which consists\n" - "of multiple RFC822-like formatted sections.\n\n" +static char *doc_TagFile = "TagFile(file)\n\n" + "TagFile() objects provide access to debian control files, which consist\n" + "of multiple RFC822-style sections.\n\n" "To provide access to those sections, TagFile objects provide an iterator\n" "which yields TagSection objects for each section.\n\n" "TagFile objects also provide another API which uses a shared TagSection\n" "object in the 'section' member. The functions step() and jump() can be\n" - "used to navigate in the file; and offset() tells the current position.\n\n" + "used to navigate within the file; offset() returns the current\n" + "position.\n\n" "It is important to not mix the use of both APIs, because this can have\n" "unwanted effects.\n\n" - "The parameter *file* refers to an object providing a fileno() method or\n" + "The parameter 'file' refers to an object providing a fileno() method or\n" "a file descriptor (an integer)"; // Type for a Tag File diff --git a/python/tarfile.cc b/python/tarfile.cc index 6363af0f..215d3a8c 100644 --- a/python/tarfile.cc +++ b/python/tarfile.cc @@ -235,7 +235,7 @@ static PyMethodDef tarmember_methods[] = { {"ischr",tarmember_ischr,METH_NOARGS, "Determine whether the member is a character device."}, {"isdev",tarmember_isdev,METH_NOARGS, - "Determine whether the member is a device (block,character or FIFO)."}, + "Determine whether the member is a device (block, character or FIFO)."}, {"isdir",tarmember_isdir,METH_NOARGS, "Determine whether the member is a directory."}, {"isfifo",tarmember_isfifo,METH_NOARGS, @@ -252,7 +252,7 @@ static PyMethodDef tarmember_methods[] = { }; static PyGetSetDef tarmember_getset[] = { - {"gid",tarmember_get_gid,0,"The owner's group id"}, + {"gid",tarmember_get_gid,0,"The owner's group ID."}, {"linkname",tarmember_get_linkname,0,"The target of the link."}, {"major",tarmember_get_major,0,"The major ID of the device."}, {"minor",tarmember_get_minor,0,"The minor ID of the device."}, @@ -260,7 +260,7 @@ static PyGetSetDef tarmember_getset[] = { {"mtime",tarmember_get_mtime,0,"Last time of modification."}, {"name",tarmember_get_name,0,"The name of the file."}, {"size",tarmember_get_size,0,"The size of the file."}, - {"uid",tarmember_get_uid,0,"The owner's user id."}, + {"uid",tarmember_get_uid,0,"The owner's user ID."}, {NULL} }; @@ -375,11 +375,11 @@ static PyObject *tarfile_extractall(PyObject *self, PyObject *args) static const char *tarfile_go_doc = "go(callback: callable[, member: str]) -> True\n\n" - "Go through the archive and call the callable callback for each\n" + "Go through the archive and call the callable 'callback' for each\n" "member with 2 arguments. The first argument is the TarMember and\n" "the second one is the data, as bytes.\n\n" "The optional parameter 'member' can be used to specify the member for\n" - "which call the callback. If not specified, it will be called for all\n" + "which to call the callback. If not specified, it will be called for all\n" "members. If specified and not found, LookupError will be raised."; static PyObject *tarfile_go(PyObject *self, PyObject *args) { |
