~ubuntu-branches/debian/experimental/python-apt/experimental

« back to all changes in this revision

Viewing changes to python/cachegroup.cc

  • Committer: Bazaar Package Importer
  • Author(s): Julian Andres Klode
  • Date: 2011-04-05 16:21:45 UTC
  • mfrom: (6.2.21 sid)
  • Revision ID: james.westby@ubuntu.com-20110405162145-aiy6hoplxqviai14
Tags: 0.8.0~exp1
* Disable the old-style API, and break all packages using it
* Add an 'is_multi_arch' attribute to apt_pkg.Cache
* Add apt_pkg.Group class, wrapping pkgCache::GrpIterator
* Change apt_pkg.Cache() so that passing None for 'progress' results in
  no progress output
* Support (name, arch) tuples in apt_pkg.Cache mappings, wrapping
  FindPkg() with two string parameters.
* Introduce apt_pkg.Cache.groups and apt_pkg.Cache.group_count
* Fix debian/rules to work correctly with tilde in version number

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * cachegroup.cc - Wrapper around pkgCache::GrpIterator
 
3
 *
 
4
 * Copyright 2011 Julian Andres Klode <jak@debian.org>
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2 of the License, or
 
9
 * (at your option) any later version.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software
 
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
19
 * MA 02110-1301, USA.
 
20
 */
 
21
#include <Python.h>
 
22
#include "apt_pkgmodule.h"
 
23
#include "generic.h"
 
24
#include <apt-pkg/pkgcache.h>
 
25
 
 
26
struct PyGroup : CppPyObject<pkgCache::GrpIterator> {
 
27
    pkgCache::PkgIterator current;
 
28
    int nextIndex;
 
29
};
 
30
 
 
31
static PyObject *group_new(PyTypeObject *type,PyObject *args,
 
32
                                  PyObject *kwds)
 
33
{
 
34
    PyObject *pyCache;
 
35
    char *name;
 
36
    char *kwlist[] = {"cache", "name", NULL};
 
37
    if (PyArg_ParseTupleAndKeywords(args, kwds, "O!s", kwlist,
 
38
                                    &PyCache_Type, &pyCache,
 
39
                                    &name) == 0)
 
40
        return 0;
 
41
 
 
42
    pkgCache *cache = GetCpp<pkgCache *>(pyCache);
 
43
 
 
44
    pkgCache::GrpIterator grp = cache->FindGrp(name);
 
45
 
 
46
    if (!grp.end()) {
 
47
        return PyGroup_FromCpp(grp, true, pyCache);
 
48
    } else {
 
49
        PyErr_SetString(PyExc_KeyError, name);
 
50
        return NULL;
 
51
    }
 
52
}
 
53
 
 
54
static const char group_find_package_doc[] =
 
55
    "find_package(architecture: str) -> Package\n\n"
 
56
    "Return a package for the given architecture, or None if none exists";
 
57
static PyObject *group_find_package(PyObject *self,PyObject *args)
 
58
{
 
59
    pkgCache::GrpIterator grp = GetCpp<pkgCache::GrpIterator>(self);
 
60
    PyObject *owner = GetOwner<pkgCache::GrpIterator>(self);
 
61
    
 
62
    char *architecture;
 
63
    if (PyArg_ParseTuple(args, "s", &architecture) == 0)
 
64
        return 0;
 
65
 
 
66
    pkgCache::PkgIterator pkg = grp.FindPkg(architecture);
 
67
 
 
68
    if (pkg.end()) {
 
69
        Py_RETURN_NONE;
 
70
    } else {
 
71
        return PyPackage_FromCpp(pkg, true, owner ? owner : self);
 
72
    }
 
73
}
 
74
 
 
75
static const char group_find_preferred_package_doc[] =
 
76
    "find_preferred_package(prefer_non_virtual: bool = True) -> Package\n\n"
 
77
    "Return a package for the best architecture, either the native one\n"
 
78
    "or the first found one. If none exists, return None. If non_virtual\n"
 
79
    "is True, prefer non-virtual packages over virtual ones.";
 
80
static PyObject *group_find_preferred_package(PyObject *self,PyObject *args,
 
81
                                              PyObject *kwds)
 
82
{
 
83
    pkgCache::GrpIterator grp = GetCpp<pkgCache::GrpIterator>(self);
 
84
    PyObject *owner = GetOwner<pkgCache::GrpIterator>(self);
 
85
    char nonvirtual = 1;
 
86
    char *kwlist[] = {"prefer_non_virtual", NULL};
 
87
    if (PyArg_ParseTupleAndKeywords(args, kwds, "|b", kwlist, &nonvirtual) == 0)
 
88
        return 0;
 
89
    pkgCache::PkgIterator pkg = grp.FindPreferredPkg(nonvirtual);
 
90
 
 
91
    if (pkg.end()) {
 
92
        Py_RETURN_NONE;
 
93
    } else {
 
94
        return PyPackage_FromCpp(pkg, true, owner);
 
95
    }
 
96
}
 
97
 
 
98
static PyMethodDef group_methods[] = {
 
99
    {"find_package",group_find_package,METH_VARARGS,group_find_package_doc},
 
100
    {"find_preferred_package",(PyCFunction) group_find_preferred_package,
 
101
     METH_VARARGS|METH_KEYWORDS,group_find_preferred_package_doc},
 
102
    {}
 
103
};
 
104
 
 
105
static PyObject *group_seq_item(PyObject *pySelf,Py_ssize_t index)
 
106
{
 
107
    PyGroup *self = static_cast<PyGroup *>(pySelf);
 
108
    pkgCache::GrpIterator grp = GetCpp<pkgCache::GrpIterator>(self);
 
109
    PyObject *owner = GetOwner<pkgCache::GrpIterator>(self);
 
110
 
 
111
    if (self->nextIndex > index || self->nextIndex == 0)  {
 
112
        self->nextIndex = 1;
 
113
        new (&self->current) pkgCache::PkgIterator(grp.PackageList());
 
114
    }
 
115
        
 
116
    if (self->nextIndex != index + 1) {
 
117
        while (self->nextIndex <= index && !self->current.end()) {
 
118
            self->current = grp.NextPkg(self->current);
 
119
            self->nextIndex++;
 
120
        }
 
121
    }
 
122
 
 
123
    if (self->current.end())
 
124
        return PyErr_Format(PyExc_IndexError, "Out of range: %zd", index);
 
125
 
 
126
    return PyPackage_FromCpp(self->current, true, owner);
 
127
}
 
128
 
 
129
 
 
130
static PySequenceMethods group_as_sequence =
 
131
{
 
132
   0,
 
133
   0,                // concat
 
134
   0,                // repeat
 
135
   group_seq_item,
 
136
   0,                // slice
 
137
   0,                // assign item
 
138
   0                 // assign slice
 
139
};
 
140
 
 
141
 
 
142
static const char group_doc[] = "Group(cache, name)\n\n"
 
143
    "Group of packages with the same name.\n\n"
 
144
    "Provides access to all packages sharing a name. Can be used this\n"
 
145
    "like a list, or by using the special find_*() methods. If you use\n"
 
146
    "it as a sequence, make sure to access it linearly, as this uses a\n"
 
147
    "linked list internally.";
 
148
PyTypeObject PyGroup_Type = {
 
149
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
 
150
    "apt_pkg.Group",                     // tp_name
 
151
    sizeof(PyGroup),                     // tp_basicsize
 
152
    0,                                   // tp_itemsize
 
153
    // Methods
 
154
    CppDealloc<pkgCache::GrpIterator>,   // tp_dealloc
 
155
    0,                                   // tp_print
 
156
    0,                                   // tp_getattr
 
157
    0,                                   // tp_setattr
 
158
    0,                                   // tp_compare
 
159
    0,                                   // tp_repr
 
160
    0,                                   // tp_as_number
 
161
    &group_as_sequence,                  // tp_as_sequence
 
162
    0,                                   // tp_as_mapping
 
163
    0,                                   // tp_hash
 
164
    0,                                   // tp_call
 
165
    0,                                   // tp_str
 
166
    0,                                   // tp_getattro
 
167
    0,                                   // tp_setattro
 
168
    0,                                   // tp_as_buffer
 
169
    Py_TPFLAGS_DEFAULT,                  // tp_flags
 
170
    group_doc,                           // tp_doc
 
171
    0,                                   // tp_traverse
 
172
    0,                                   // tp_clear
 
173
    0,                                   // tp_richcompare
 
174
    0,                                   // tp_weaklistoffset
 
175
    0,                                   // tp_iter
 
176
    0,                                   // tp_iternext
 
177
    group_methods,                       // tp_methods
 
178
    0,                                   // tp_members
 
179
    0,                                   // tp_getset
 
180
    0,                                   // tp_base
 
181
    0,                                   // tp_dict
 
182
    0,                                   // tp_descr_get
 
183
    0,                                   // tp_descr_set
 
184
    0,                                   // tp_dictoffset
 
185
    0,                                   // tp_init
 
186
    0,                                   // tp_alloc
 
187
    group_new,                           // tp_new
 
188
};