diff options
| author | Julian Andres Klode <jak@debian.org> | 2010-02-13 15:34:24 +0100 |
|---|---|---|
| committer | Julian Andres Klode <jak@debian.org> | 2010-02-13 15:34:24 +0100 |
| commit | c8fa835540d60393f2a1168625bf5d5ae01c4538 (patch) | |
| tree | b99415fbe2d2bfe2249c3beb5083c2b0587734c9 | |
| parent | 0401747854d7fc26eb097663822e26a988cf4aa4 (diff) | |
| download | python-apt-c8fa835540d60393f2a1168625bf5d5ae01c4538.tar.gz | |
python/tagfile.cc: Implement the iterator protocol in TagFile.
| -rw-r--r-- | apt/debfile.py | 3 | ||||
| -rw-r--r-- | apt/utils.py | 6 | ||||
| -rw-r--r-- | debian/changelog | 2 | ||||
| -rw-r--r-- | doc/source/library/apt_pkg.rst | 29 | ||||
| -rw-r--r-- | python/tag.cc | 36 |
5 files changed, 63 insertions, 13 deletions
diff --git a/apt/debfile.py b/apt/debfile.py index 65f43f20..e27917d5 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -448,9 +448,8 @@ class DscSrcPackage(DebPackage): fobj = open(file) tagfile = apt_pkg.TagFile(fobj) - sec = tagfile.section try: - while tagfile.step() == 1: + for sec in tagfile: for tag in depends_tags: if not tag in sec: continue diff --git a/apt/utils.py b/apt/utils.py index 8949c2ab..61d5d54f 100644 --- a/apt/utils.py +++ b/apt/utils.py @@ -39,10 +39,10 @@ def get_release_date_from_release_file(path): if not path or not os.path.exists(path): return None tag = apt_pkg.TagFile(open(path)) - tag.step() - if not "Date" in tag.section: + section = tag.next() + if not "Date" in section: return None - date = tag.section["Date"] + date = section["Date"] return apt_pkg.str_to_time(date) def get_release_filename_for_pkg(cache, pkgname, label, release): diff --git a/debian/changelog b/debian/changelog index b09fb684..fe0d3b9a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -7,6 +7,8 @@ python-apt (0.7.93.2) UNRELEASED; urgency=low * utils/migrate-0.8.py: - Improve C++ parsing and add apt.progress.old to the modules, reduces false positives. + * python/tagfile.cc: + - Implement the iterator protocol in TagFile. -- Julian Andres Klode <jak@debian.org> Sun, 07 Feb 2010 19:58:40 +0100 diff --git a/doc/source/library/apt_pkg.rst b/doc/source/library/apt_pkg.rst index 7989a68a..05b3e1fc 100644 --- a/doc/source/library/apt_pkg.rst +++ b/doc/source/library/apt_pkg.rst @@ -1407,9 +1407,32 @@ section as a string. .. class:: TagFile(file) An object which represents a typical debian control file. Can be used for - Packages, Sources, control, Release, etc. + Packages, Sources, control, Release, etc. Such an object provides two + kinds of API which should not be used together: - An example for working with a TagFile could look like:: + The first API implements the iterator protocol and should be used whenever + possible because it has less side effects than the other one. It may be + used e.g. with a for loop:: + + tagf = apt_pkg.TagFile(open('/var/lib/dpkg/status')) + for section in tagfile: + print section['Package'] + + .. method:: next() + + A TagFile is its own iterator. This method is part of the iterator + protocol and returns a :class:`TagSection` object for the next + section in the file. If there is no further section, this method + raises the :exc:`StopIteration` exception. + + From Python 3 on, this method is not available anymore, and the + global function ``next()`` replaces it. + + The second API uses a shared :class:`TagSection` object which is exposed + through the :attr:`section` attribute. This object is modified by calls + to :meth:`step` and :meth:`jump`. This API provides more control and may + use less memory, but is not recommended because it works by modifying + one object. It can be used like this:: tagf = apt_pkg.TagFile(open('/var/lib/dpkg/status')) tagf.step() @@ -1418,7 +1441,7 @@ section as a string. .. method:: step Step forward to the next section. This simply returns ``1`` if OK, and - ``0`` if there is no section + ``0`` if there is no section. .. method:: offset diff --git a/python/tag.cc b/python/tag.cc index 2aaf3beb..4971a03d 100644 --- a/python/tag.cc +++ b/python/tag.cc @@ -258,6 +258,28 @@ static PyObject *TagFileStep(PyObject *Self,PyObject *Args) return HandleErrors(Py_BuildValue("i",1)); } +// TagFile Wrappers /*{{{*/ +static PyObject *TagFileNext(PyObject *Self) +{ + TagFileData &Obj = *(TagFileData *)Self; + // Replace the section. + Py_CLEAR(Obj.Section); + Obj.Section = (TagSecData*)(&PyTagSection_Type)->tp_alloc(&PyTagSection_Type, 0); + new (&Obj.Section->Object) pkgTagSection(); + Obj.Section->Owner = Self; + Py_INCREF(Obj.Section->Owner); + Obj.Section->Data = 0; + if (Obj.Object.Step(Obj.Section->Object) == false) + return HandleErrors(NULL); + Py_INCREF(Obj.Section); + return HandleErrors(Obj.Section); +} + +static PyObject *TagFileIter(PyObject *Self) { + Py_INCREF(Self); + return Self; +} + static char *doc_Offset = "Offset() -> Integer"; static PyObject *TagFileOffset(PyObject *Self,PyObject *Args) { @@ -541,9 +563,13 @@ static PyGetSetDef TagFileGetSet[] = { 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" - "A file may consists of multiple sections, and you can use Step() to move\n" - "forward. The current TagSection() is available via the attribute section" - ".\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" + "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" "a file descriptor (an integer)"; @@ -578,8 +604,8 @@ PyTypeObject PyTagFile_Type = TagFileClear, // tp_clear 0, // tp_richcompare 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext + TagFileIter, // tp_iter + TagFileNext, // tp_iternext TagFileMethods, // tp_methods 0, // tp_members TagFileGetSet, // tp_getset |
