summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/acquire-item.cc314
-rw-r--r--python/acquire.cc548
-rw-r--r--python/apt_instmodule.cc79
-rw-r--r--python/apt_instmodule.h15
-rw-r--r--python/apt_pkgmodule.cc600
-rw-r--r--python/apt_pkgmodule.h153
-rw-r--r--python/arfile.cc648
-rw-r--r--python/cache.cc1133
-rw-r--r--python/cdrom.cc217
-rw-r--r--python/configuration.cc177
-rw-r--r--python/depcache.cc444
-rw-r--r--python/generic.cc78
-rw-r--r--python/generic.h167
-rw-r--r--python/hashes.cc136
-rw-r--r--python/hashstring.cc134
-rw-r--r--python/indexfile.cc103
-rw-r--r--python/indexrecords.cc127
-rw-r--r--python/lock.cc265
-rw-r--r--python/makefile26
-rw-r--r--python/metaindex.cc133
-rw-r--r--python/pkgmanager.cc114
-rw-r--r--python/pkgrecords.cc178
-rw-r--r--python/pkgsrcrecords.cc275
-rw-r--r--python/policy.cc205
-rw-r--r--python/progress.cc329
-rw-r--r--python/progress.h15
-rw-r--r--python/python-apt-helpers.cc68
-rw-r--r--python/python-apt.h347
-rw-r--r--python/sourcelist.cc100
-rw-r--r--python/string.cc16
-rw-r--r--python/tag.cc283
-rw-r--r--python/tar.cc25
-rw-r--r--python/tarfile.cc490
33 files changed, 6274 insertions, 1668 deletions
diff --git a/python/acquire-item.cc b/python/acquire-item.cc
new file mode 100644
index 00000000..cdb4a4bc
--- /dev/null
+++ b/python/acquire-item.cc
@@ -0,0 +1,314 @@
+/*
+ * acquire-item.cc - Wrapper around pkgAcquire::Item and pkgAcqFile.
+ *
+ * Copyright 2004-2009 Canonical Ltd.
+ * Copyright 2009 Julian Andres Klode <jak@debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include "generic.h"
+#include "apt_pkgmodule.h"
+
+#include <apt-pkg/acquire-item.h>
+#include <map>
+
+using namespace std;
+
+inline pkgAcquire::Item *acquireitem_tocpp(PyObject *self)
+{
+ pkgAcquire::Item *itm = GetCpp<pkgAcquire::Item*>(self);
+ if (itm == 0)
+ PyErr_SetString(PyExc_ValueError, "Acquire() has been shut down or "
+ "the AcquireFile() object has been deallocated.");
+ return itm;
+}
+
+static PyObject *acquireitem_get_complete(PyObject *self, void *closure)
+{
+ pkgAcquire::Item *item = acquireitem_tocpp(self);
+ return item ? PyBool_FromLong(item->Complete) : 0;
+}
+
+static PyObject *acquireitem_get_desc_uri(PyObject *self, void *closure)
+{
+ pkgAcquire::Item *item = acquireitem_tocpp(self);
+ return item ? CppPyString(item->DescURI()) : 0;
+}
+
+static PyObject *acquireitem_get_destfile(PyObject *self, void *closure)
+{
+ pkgAcquire::Item *item = acquireitem_tocpp(self);
+ return item ? CppPyString(item->DestFile) : 0;
+}
+
+
+static PyObject *acquireitem_get_error_text(PyObject *self, void *closure)
+{
+ pkgAcquire::Item *item = acquireitem_tocpp(self);
+ return item ? CppPyString(item->ErrorText) : 0;
+}
+
+static PyObject *acquireitem_get_filesize(PyObject *self, void *closure)
+{
+ pkgAcquire::Item *item = acquireitem_tocpp(self);
+ return item ? Py_BuildValue("i", item->FileSize) : 0;
+}
+
+static PyObject *acquireitem_get_id(PyObject *self, void *closure)
+{
+ pkgAcquire::Item *item = acquireitem_tocpp(self);
+ return item ? Py_BuildValue("k", item->ID) : 0;
+}
+
+static PyObject *acquireitem_get_mode(PyObject *self, void *closure)
+{
+ pkgAcquire::Item *item = acquireitem_tocpp(self);
+ return item ? Py_BuildValue("s", item->Mode) : 0;
+}
+
+static PyObject *acquireitem_get_is_trusted(PyObject *self, void *closure)
+{
+ pkgAcquire::Item *item = acquireitem_tocpp(self);
+ return item ? PyBool_FromLong(item->IsTrusted()) : 0;
+}
+
+static PyObject *acquireitem_get_local(PyObject *self, void *closure)
+{
+ pkgAcquire::Item *item = acquireitem_tocpp(self);
+ return item ? PyBool_FromLong(item->Local) : 0;
+}
+
+static PyObject *acquireitem_get_partialsize(PyObject *self, void *closure)
+{
+ pkgAcquire::Item *item = acquireitem_tocpp(self);
+ return item ? Py_BuildValue("i", item->PartialSize) : 0;
+}
+
+static PyObject *acquireitem_get_status(PyObject *self, void *closure)
+{
+ pkgAcquire::Item *item = acquireitem_tocpp(self);
+ return item ? Py_BuildValue("i", item->Status) : 0;
+}
+
+static int acquireitem_set_id(PyObject *self, PyObject *value, void *closure)
+{
+ pkgAcquire::Item *Itm = acquireitem_tocpp(self);
+ if (Itm == 0)
+ return -1;
+ if (PyLong_Check(value)) {
+ Itm->ID = PyLong_AsLong(value);
+ }
+ else if (PyInt_Check(value)) {
+ Itm->ID = PyInt_AsLong(value);
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError, "value must be integer.");
+ return -1;
+ }
+ return 0;
+}
+
+
+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},
+ {}
+};
+
+static PyObject *acquireitem_repr(PyObject *Self)
+{
+ pkgAcquire::Item *Itm = acquireitem_tocpp(Self);
+ if (Itm == 0)
+ return 0;
+ return PyString_FromFormat("<%s object: "
+ "Status: %i Complete: %i Local: %i IsTrusted: %i "
+ "FileSize: %lu DestFile:'%s' "
+ "DescURI: '%s' ID:%lu ErrorText: '%s'>",
+ Self->ob_type->tp_name,
+ Itm->Status, Itm->Complete, Itm->Local, Itm->IsTrusted(),
+ Itm->FileSize, Itm->DestFile.c_str(), Itm->DescURI().c_str(),
+ Itm->ID,Itm->ErrorText.c_str());
+}
+
+static void acquireitem_dealloc(PyObject *self)
+{
+ CppDeallocPtr<pkgAcquire::Item*>(self);
+}
+
+PyTypeObject PyAcquireItem_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.AcquireItem", // tp_name
+ sizeof(CppPyObject<pkgAcquire::Item*>), // tp_basicsize
+ 0, // tp_itemsize
+ // Methods
+ acquireitem_dealloc, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ acquireitem_repr, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ _PyAptObject_getattro, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT |
+ Py_TPFLAGS_HAVE_GC, // tp_flags
+ "AcquireItem Object", // tp_doc
+ CppTraverse<pkgAcquire::Item*>, // tp_traverse
+ CppClear<pkgAcquire::Item*>, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ 0, // tp_methods
+ 0, // tp_members
+ acquireitem_getset, // tp_getset
+};
+
+static PyObject *acquirefile_new(PyTypeObject *type, PyObject *Args, PyObject * kwds)
+{
+ PyObject *pyfetcher;
+ char *uri, *md5, *descr, *shortDescr, *destDir, *destFile;
+ int size = 0;
+ uri = md5 = descr = shortDescr = destDir = destFile = "";
+
+ char *kwlist[] = {"owner","uri", "md5", "size", "descr", "short_descr",
+ "destdir", "destfile", NULL
+ };
+
+ if (PyArg_ParseTupleAndKeywords(Args, kwds, "O!s|sissss", kwlist,
+ &PyAcquire_Type, &pyfetcher, &uri, &md5,
+ &size, &descr, &shortDescr, &destDir, &destFile) == 0)
+ return 0;
+
+ pkgAcquire *fetcher = GetCpp<pkgAcquire*>(pyfetcher);
+ pkgAcqFile *af = new pkgAcqFile(fetcher, // owner
+ uri, // uri
+ md5, // md5
+ size, // size
+ descr, // descr
+ shortDescr,
+ destDir,
+ destFile); // short-desc
+ CppPyObject<pkgAcqFile*> *AcqFileObj = CppPyObject_NEW<pkgAcqFile*>(pyfetcher, type);
+ AcqFileObj->Object = af;
+ return AcqFileObj;
+}
+
+
+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.";
+
+PyTypeObject PyAcquireFile_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.AcquireFile", // tp_name
+ sizeof(CppPyObject<pkgAcqFile*>),// tp_basicsize
+ 0, // tp_itemsize
+ // Methods
+ acquireitem_dealloc, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_HAVE_GC,
+ acquirefile_doc, // tp_doc
+ CppTraverse<pkgAcqFile*>, // tp_traverse
+ CppClear<pkgAcqFile*>, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ 0, // tp_methods
+ 0, // tp_members
+ 0, // tp_getset
+ &PyAcquireItem_Type, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ 0, // tp_alloc
+ acquirefile_new, // tp_new
+};
+
+#ifdef COMPAT_0_7
+char *doc_GetPkgAcqFile =
+ "GetPkgAcqFile(pkgAquire, uri[, md5, size, descr, shortDescr, destDir, destFile]) -> PkgAcqFile\n";
+PyObject *GetPkgAcqFile(PyObject *Self, PyObject *Args, PyObject * kwds)
+{
+ PyErr_WarnEx(PyExc_DeprecationWarning, "apt_pkg.GetPkgAcqFile() is "
+ "deprecated. Please see apt_pkg.AcquireFile() for the "
+ "replacement", 1);
+ PyObject *pyfetcher;
+ char *uri, *md5, *descr, *shortDescr, *destDir, *destFile;
+ int size = 0;
+ uri = md5 = descr = shortDescr = destDir = destFile = "";
+
+ char * kwlist[] = {"owner","uri", "md5", "size", "descr", "shortDescr",
+ "destDir", "destFile", NULL
+ };
+
+ if (PyArg_ParseTupleAndKeywords(Args, kwds, "O!s|sissss", kwlist,
+ &PyAcquire_Type, &pyfetcher, &uri, &md5,
+ &size, &descr, &shortDescr, &destDir, &destFile) == 0)
+ return 0;
+
+ pkgAcquire *fetcher = GetCpp<pkgAcquire*>(pyfetcher);
+ pkgAcqFile *af = new pkgAcqFile(fetcher, // owner
+ uri, // uri
+ md5, // md5
+ size, // size
+ descr, // descr
+ shortDescr,
+ destDir,
+ destFile); // short-desc
+ CppPyObject<pkgAcqFile*> *AcqFileObj = CppPyObject_NEW<pkgAcqFile*>(NULL, &PyAcquireFile_Type);
+ AcqFileObj->Object = af;
+ AcqFileObj->NoDelete = true;
+
+ return AcqFileObj;
+}
+#endif
diff --git a/python/acquire.cc b/python/acquire.cc
index 1ecf55a5..cc9ee310 100644
--- a/python/acquire.cc
+++ b/python/acquire.cc
@@ -1,278 +1,380 @@
-// Description /*{{{*/
-// $Id: acquire.cc,v 1.1 2003/06/03 03:03:23 mvo Exp $
-/* ######################################################################
-
- Acquire - Wrapper for the acquire code
-
- ##################################################################### */
+/* acquire.cc - Wrapper for pkgAcquire.
+ *
+ * Copyright 2004-2009 Canonical Ltd
+ * Copyright 2009 Julian Andres Klode <jak@debian.org>
+ *
+ * Authors: Michael Vogt
+ * Julian Andres Klode
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
#include "generic.h"
#include "apt_pkgmodule.h"
#include "progress.h"
#include <apt-pkg/acquire-item.h>
+#include <apt-pkg/acquire-worker.h>
-// pkgAcquire::Item
-static PyObject *AcquireItemAttr(PyObject *Self,char *Name)
+
+static PyObject *acquireworker_get_current_item(PyObject *self, void *closure)
{
- pkgAcquire::ItemIterator &I = GetCpp<pkgAcquire::ItemIterator>(Self);
-
- if (strcmp("ID",Name) == 0)
- return Py_BuildValue("i",(*I)->ID);
- else if (strcmp("Status",Name) == 0)
- return Py_BuildValue("i",(*I)->Status);
- else if (strcmp("Complete",Name) == 0)
- return Py_BuildValue("i",(*I)->Complete);
- else if (strcmp("Local",Name) == 0)
- return Py_BuildValue("i",(*I)->Local);
- else if (strcmp("IsTrusted",Name) == 0)
- return Py_BuildValue("i",(*I)->IsTrusted());
- else if (strcmp("FileSize",Name) == 0)
- return Py_BuildValue("i",(*I)->FileSize);
- else if (strcmp("ErrorText",Name) == 0)
- return Safe_FromString((*I)->ErrorText.c_str());
- else if (strcmp("DestFile",Name) == 0)
- return Safe_FromString((*I)->DestFile.c_str());
- else if (strcmp("DescURI",Name) == 0)
- return Safe_FromString((*I)->DescURI().c_str());
- // constants
- else if (strcmp("StatIdle",Name) == 0)
- return Py_BuildValue("i", pkgAcquire::Item::StatIdle);
- else if (strcmp("StatFetching",Name) == 0)
- return Py_BuildValue("i", pkgAcquire::Item::StatFetching);
- else if (strcmp("StatDone",Name) == 0)
- return Py_BuildValue("i", pkgAcquire::Item::StatDone);
- else if (strcmp("StatError",Name) == 0)
- return Py_BuildValue("i", pkgAcquire::Item::StatError);
- else if (strcmp("StatAuthError",Name) == 0)
- return Py_BuildValue("i", pkgAcquire::Item::StatAuthError);
-
-
- PyErr_SetString(PyExc_AttributeError,Name);
- return 0;
+ pkgAcquire::Worker *worker = GetCpp<pkgAcquire::Worker*>(self);
+ pkgAcquire::ItemDesc *desc = worker->CurrentItem;
+ if (desc == NULL) {
+ Py_RETURN_NONE;
+ }
+ PyObject *PyAcq = GetOwner<pkgAcquire::Worker*>(self);
+ PyObject *PyItem = PyAcquireItem_FromCpp(desc->Owner, false, PyAcq);
+ PyObject *PyDesc = PyAcquireItemDesc_FromCpp(desc, false, PyItem);
+ Py_XDECREF(PyItem);
+ return PyDesc;
}
+static PyObject *acquireworker_get_status(PyObject *self, void *closure)
+{
+ return CppPyString(GetCpp<pkgAcquire::Worker*>(self)->Status);
+}
-static PyObject *AcquireItemRepr(PyObject *Self)
+static PyObject *acquireworker_get_current_size(PyObject *self, void *closure)
{
- pkgAcquire::ItemIterator &I = GetCpp<pkgAcquire::ItemIterator>(Self);
-
- char S[300];
- snprintf(S,sizeof(S),"<pkgAcquire::ItemIterator object: "
- "Status: %i Complete: %i Local: %i IsTrusted: %i "
- "FileSize: %i DestFile:'%s' "
- "DescURI: '%s' ID:%i ErrorText: '%s'>",
- (*I)->Status, (*I)->Complete, (*I)->Local, (*I)->IsTrusted(),
- (*I)->FileSize, (*I)->DestFile.c_str(), (*I)->DescURI().c_str(),
- (*I)->ID,(*I)->ErrorText.c_str());
- return PyString_FromString(S);
+ return Py_BuildValue("k",GetCpp<pkgAcquire::Worker*>(self)->CurrentSize);
}
+static PyObject *acquireworker_get_total_size(PyObject *self, void *closure)
+{
+ return Py_BuildValue("k",GetCpp<pkgAcquire::Worker*>(self)->TotalSize);
+}
-PyTypeObject AcquireItemType =
+static PyObject *acquireworker_get_resumepoint(PyObject *self, void *closure)
{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "pkgAcquire::ItemIterator", // tp_name
- sizeof(CppOwnedPyObject<pkgAcquire::ItemIterator>), // tp_basicsize
- 0, // tp_itemsize
- // Methods
- CppOwnedDealloc<pkgAcquire::ItemIterator>, // tp_dealloc
- 0, // tp_print
- AcquireItemAttr, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- AcquireItemRepr, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
- 0, // tp_hash
-};
+ return Py_BuildValue("k",GetCpp<pkgAcquire::Worker*>(self)->ResumePoint);
+}
+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},
+ {NULL}
+};
-static PyObject *PkgAcquireRun(PyObject *Self,PyObject *Args)
-{
- pkgAcquire *fetcher = GetCpp<pkgAcquire*>(Self);
- int pulseInterval = 500000;
- if (PyArg_ParseTuple(Args, "|i", &pulseInterval) == 0)
- return 0;
+PyTypeObject PyAcquireWorker_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.AcquireWorker", // tp_name
+ sizeof(CppPyObject<pkgAcquire::Worker*>),// tp_basicsize
+ 0, // tp_itemsize
+ // Methods
+ CppDealloc<pkgAcquire::Worker*>, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT| // tp_flags
+ Py_TPFLAGS_HAVE_GC,
+ 0, // tp_doc
+ CppTraverse<pkgAcquire::Worker*>, // tp_traverse
+ CppClear<pkgAcquire::Worker*>, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ 0, // tp_methods
+ 0, // tp_members
+ acquireworker_getset, // tp_getset
+};
- pkgAcquire::RunResult run = fetcher->Run(pulseInterval);
- return HandleErrors(Py_BuildValue("i",run));
+static pkgAcquire::ItemDesc* acquireitemdesc_tocpp(PyObject *self) {
+ pkgAcquire::ItemDesc *item = GetCpp<pkgAcquire::ItemDesc*>(self);
+ if (item == NULL)
+ PyErr_SetString(PyExc_ValueError, "Acquire has been shutdown");
+ return item;
}
-static PyObject *PkgAcquireShutdown(PyObject *Self,PyObject *Args)
+static PyObject *acquireitemdesc_get_uri(PyObject *self, void *closure)
{
- pkgAcquire *fetcher = GetCpp<pkgAcquire*>(Self);
-
- if (PyArg_ParseTuple(Args, "") == 0)
- return 0;
-
- fetcher->Shutdown();
-
- Py_INCREF(Py_None);
- return HandleErrors(Py_None);
+ pkgAcquire::ItemDesc *item = acquireitemdesc_tocpp(self);
+ return item ? CppPyString(item->URI) : NULL;
}
-
-static PyMethodDef PkgAcquireMethods[] =
+static PyObject *acquireitemdesc_get_description(PyObject *self, void *closure)
{
- {"Run",PkgAcquireRun,METH_VARARGS,"Run the fetcher"},
- {"Shutdown",PkgAcquireShutdown, METH_VARARGS,"Shutdown the fetcher"},
- {}
-};
-
-
-static PyObject *AcquireAttr(PyObject *Self,char *Name)
+ pkgAcquire::ItemDesc *item = acquireitemdesc_tocpp(self);
+ return item ? CppPyString(item->Description) : NULL;
+}
+static PyObject *acquireitemdesc_get_shortdesc(PyObject *self, void *closure)
{
- pkgAcquire *fetcher = GetCpp<pkgAcquire*>(Self);
-
- if(strcmp("TotalNeeded",Name) == 0)
- return Py_BuildValue("d", fetcher->TotalNeeded());
- if(strcmp("FetchNeeded",Name) == 0)
- return Py_BuildValue("d", fetcher->FetchNeeded());
- if(strcmp("PartialPresent",Name) == 0)
- return Py_BuildValue("d", fetcher->PartialPresent());
- if(strcmp("Items",Name) == 0)
- {
- PyObject *List = PyList_New(0);
- for (pkgAcquire::ItemIterator I = fetcher->ItemsBegin();
- I != fetcher->ItemsEnd(); I++)
- {
- PyObject *Obj;
- Obj = CppOwnedPyObject_NEW<pkgAcquire::ItemIterator>(Self,&AcquireItemType,I);
- PyList_Append(List,Obj);
- Py_DECREF(Obj);
-
- }
- return List;
- }
- // some constants
- if(strcmp("ResultContinue",Name) == 0)
- return Py_BuildValue("i", pkgAcquire::Continue);
- if(strcmp("ResultFailed",Name) == 0)
- return Py_BuildValue("i", pkgAcquire::Failed);
- if(strcmp("ResultCancelled",Name) == 0)
- return Py_BuildValue("i", pkgAcquire::Cancelled);
-
- return Py_FindMethod(PkgAcquireMethods,Self,Name);
+ pkgAcquire::ItemDesc *item = acquireitemdesc_tocpp(self);
+ return item ? CppPyString(item->ShortDesc) : NULL;
+}
+static PyObject *acquireitemdesc_get_owner(CppPyObject<pkgAcquire::ItemDesc*> *self, void *closure)
+{
+ if (self->Owner != NULL) {
+ Py_INCREF(self->Owner);
+ return self->Owner;
+ }
+ else if (self->Object) {
+ self->Owner = PyAcquireItem_FromCpp(self->Object->Owner, false, NULL);
+ Py_INCREF(self->Owner);
+ return self->Owner;
+ }
+ Py_RETURN_NONE;
}
+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},
+ {NULL}
+};
-
-
-PyTypeObject PkgAcquireType =
-{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "Acquire", // tp_name
- sizeof(CppPyObject<pkgAcquire*>), // tp_basicsize
- 0, // tp_itemsize
- // Methods
- CppDealloc<pkgAcquire*>, // tp_dealloc
- 0, // tp_print
- AcquireAttr, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
- 0, // tp_hash
+static char *acquireitemdesc_doc =
+ "Represent an AcquireItemDesc";
+
+PyTypeObject PyAcquireItemDesc_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.AcquireItemDesc", // tp_name
+ sizeof(CppPyObject<pkgAcquire::ItemDesc*>),// tp_basicsize
+ 0, // tp_itemsize
+ // Methods
+ CppDealloc<pkgAcquire::ItemDesc*>, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ (Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_HAVE_GC),
+ acquireitemdesc_doc, // tp_doc
+ CppTraverse<pkgAcquire::ItemDesc*>,// tp_traverse
+ CppClear<pkgAcquire::ItemDesc*>, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ 0, // tp_methods
+ 0, // tp_members
+ acquireitemdesc_getset, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ 0, // tp_alloc
+ 0, // tp_new
};
-PyObject *GetAcquire(PyObject *Self,PyObject *Args)
+static PyObject *PkgAcquireRun(PyObject *Self,PyObject *Args)
{
- pkgAcquire *fetcher;
-
- PyObject *pyFetchProgressInst = NULL;
- if (PyArg_ParseTuple(Args,"|O",&pyFetchProgressInst) == 0)
- return 0;
+ pkgAcquire *fetcher = GetCpp<pkgAcquire*>(Self);
- if (pyFetchProgressInst != NULL) {
- // FIXME: memleak?
- PyFetchProgress *progress = new PyFetchProgress();
- progress->setCallbackInst(pyFetchProgressInst);
- fetcher = new pkgAcquire(progress);
- } else {
- fetcher = new pkgAcquire();
- }
+ int pulseInterval = 500000;
+ if (PyArg_ParseTuple(Args, "|i", &pulseInterval) == 0)
+ return 0;
- CppPyObject<pkgAcquire*> *FetcherObj =
- CppPyObject_NEW<pkgAcquire*>(&PkgAcquireType, fetcher);
+ pkgAcquire::RunResult run = fetcher->Run(pulseInterval);
- return FetcherObj;
+ return HandleErrors(Py_BuildValue("i",run));
}
+static PyObject *PkgAcquireShutdown(PyObject *Self,PyObject *Args)
+{
+ pkgAcquire *fetcher = GetCpp<pkgAcquire*>(Self);
+ if (PyArg_ParseTuple(Args, "") == 0)
+ return 0;
+ fetcher->Shutdown();
+ Py_INCREF(Py_None);
+ return HandleErrors(Py_None);
+}
-// pkgAcquireFile
+static PyMethodDef PkgAcquireMethods[] = {
+ {"run",PkgAcquireRun,METH_VARARGS,"Run the fetcher"},
+ {"shutdown",PkgAcquireShutdown, METH_VARARGS,"Shutdown the fetcher"},
+ {}
+};
-static PyObject *AcquireFileAttr(PyObject *Self,char *Name)
+#define fetcher (GetCpp<pkgAcquire*>(Self))
+static PyObject *PkgAcquireGetTotalNeeded(PyObject *Self,void*)
{
- pkgAcqFile *acqFile = GetCpp<pkgAcqFile*>(Self);
+ return Py_BuildValue("d", fetcher->TotalNeeded());
+}
+static PyObject *PkgAcquireGetFetchNeeded(PyObject *Self,void*)
+{
+ return Py_BuildValue("d", fetcher->FetchNeeded());
+}
+static PyObject *PkgAcquireGetPartialPresent(PyObject *Self,void*)
+{
+ return Py_BuildValue("d", fetcher->PartialPresent());
+}
+#undef fetcher
- PyErr_SetString(PyExc_AttributeError,Name);
- return 0;
+static PyObject *PkgAcquireGetWorkers(PyObject *self, void *closure)
+{
+ PyObject *List = PyList_New(0);
+ pkgAcquire *Owner = GetCpp<pkgAcquire*>(self);
+ PyObject *PyWorker = NULL;
+ for (pkgAcquire::Worker *Worker = Owner->WorkersBegin();
+ Worker != 0; Worker = Owner->WorkerStep(Worker)) {
+ PyWorker = PyAcquireWorker_FromCpp(Worker, false, self);
+ PyList_Append(List, PyWorker);
+ Py_DECREF(PyWorker);
+ }
+ return List;
+}
+static PyObject *PkgAcquireGetItems(PyObject *Self,void*)
+{
+ pkgAcquire *fetcher = GetCpp<pkgAcquire*>(Self);
+ PyObject *List = PyList_New(0);
+ PyObject *Obj;
+ for (pkgAcquire::ItemIterator I = fetcher->ItemsBegin();
+ I != fetcher->ItemsEnd(); I++) {
+ Obj = PyAcquireItem_FromCpp(*I, false, Self);
+ PyList_Append(List,Obj);
+ Py_DECREF(Obj);
+ }
+ return List;
}
+static PyGetSetDef PkgAcquireGetSet[] = {
+ {"fetch_needed",PkgAcquireGetFetchNeeded},
+ {"items",PkgAcquireGetItems},
+ {"workers",PkgAcquireGetWorkers},
+ {"partial_present",PkgAcquireGetPartialPresent},
+ {"total_needed",PkgAcquireGetTotalNeeded},
+ {}
+};
+static PyObject *PkgAcquireNew(PyTypeObject *type,PyObject *Args,PyObject *kwds)
+{
+ pkgAcquire *fetcher;
+
+ PyObject *pyFetchProgressInst = NULL;
+ char *kwlist[] = {"progress", 0};
+ if (PyArg_ParseTupleAndKeywords(Args,kwds,"|O",kwlist,&pyFetchProgressInst) == 0)
+ return 0;
+
+ PyFetchProgress *progress = 0;
+ if (pyFetchProgressInst != NULL) {
+ // FIXME: memleak?
+ progress = new PyFetchProgress();
+ progress->setCallbackInst(pyFetchProgressInst);
+ fetcher = new pkgAcquire(progress);
+ }
+ else {
+ fetcher = new pkgAcquire();
+ }
+
+ PyObject *FetcherObj = CppPyObject_NEW<pkgAcquire*>(NULL, type, fetcher);
+
+ if (progress != 0)
+ progress->setPyAcquire(FetcherObj);
+ // prepare our map of items.
+ return FetcherObj;
+}
+/**
+ * Create a new apt_pkg.Acquire Python object from the pkgAcquire object.
+ */
+PyObject *PyAcquire_FromCpp(pkgAcquire *fetcher, bool Delete, PyObject *owner) {
+ CppPyObject<pkgAcquire*> *obj = CppPyObject_NEW<pkgAcquire*>(owner, &PyAcquire_Type, fetcher);
+ obj->NoDelete = (!Delete);
+ return obj;
+}
-PyTypeObject PkgAcquireFileType =
-{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "pkgAcquireFile", // tp_name
- sizeof(CppPyObject<pkgAcqFile*>),// tp_basicsize
- 0, // tp_itemsize
- // Methods
- CppDealloc<pkgAcqFile*>, // tp_dealloc
- 0, // tp_print
- AcquireFileAttr, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
- 0, // tp_hash
+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.";
+
+PyTypeObject PyAcquire_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.Acquire", // tp_name
+ sizeof(CppPyObject<pkgAcquire*>), // tp_basicsize
+ 0, // tp_itemsize
+ // Methods
+ CppDeallocPtr<pkgAcquire*>, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ _PyAptObject_getattro, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ (Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_BASETYPE),
+ doc_PkgAcquire, // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ PkgAcquireMethods, // tp_methods
+ 0, // tp_members
+ PkgAcquireGetSet, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ 0, // tp_alloc
+ PkgAcquireNew, // tp_new
};
-char *doc_GetPkgAcqFile =
-"GetPkgAcqFile(pkgAquire, uri[, md5, size, descr, shortDescr, destDir, destFile]) -> PkgAcqFile\n";
-PyObject *GetPkgAcqFile(PyObject *Self, PyObject *Args, PyObject * kwds)
+#ifdef COMPAT_0_7
+PyObject *GetAcquire(PyObject *Self,PyObject *Args)
{
- PyObject *pyfetcher;
- char *uri, *md5, *descr, *shortDescr, *destDir, *destFile;
- int size = 0;
- uri = md5 = descr = shortDescr = destDir = destFile = "";
-
- char * kwlist[] = {"owner","uri", "md5", "size", "descr", "shortDescr",
- "destDir", "destFile", NULL};
-
- if (PyArg_ParseTupleAndKeywords(Args, kwds, "O!s|sissss", kwlist,
- &PkgAcquireType, &pyfetcher, &uri, &md5,
- &size, &descr, &shortDescr, &destDir, &destFile) == 0)
- return 0;
-
- pkgAcquire *fetcher = GetCpp<pkgAcquire*>(pyfetcher);
- pkgAcqFile *af = new pkgAcqFile(fetcher, // owner
- uri, // uri
- md5, // md5
- size, // size
- descr, // descr
- shortDescr,
- destDir,
- destFile); // short-desc
- CppPyObject<pkgAcqFile*> *AcqFileObj = CppPyObject_NEW<pkgAcqFile*>(&PkgAcquireFileType);
- AcqFileObj->Object = af;
-
- return AcqFileObj;
+ PyErr_WarnEx(PyExc_DeprecationWarning,"apt_pkg.GetAcquire() is deprecated."
+ " Please see apt_pkg.Acquire() for the replacement.", 1);
+ return PkgAcquireNew(&PyAcquire_Type,Args,0);
}
+#endif
-
- /*}}}*/
diff --git a/python/apt_instmodule.cc b/python/apt_instmodule.cc
index 48868d86..2721509e 100644
--- a/python/apt_instmodule.cc
+++ b/python/apt_instmodule.cc
@@ -23,26 +23,31 @@
#include <Python.h>
/*}}}*/
+#ifdef COMPAT_0_7
+
// debExtractControl - Exctract an arbitary control member /*{{{*/
// ---------------------------------------------------------------------
/* This is a common operation so this function will stay, but others that
expose the full range of the apt-inst .deb processing will join it some
day. */
static char *doc_debExtractControl =
-"debExtractControl(File[,Member]) -> String\n"
+"deb_extract_control(file[,member]) -> String\n"
"Returns the indicated file from the control tar. The default is 'control'\n";
static PyObject *debExtractControl(PyObject *Self,PyObject *Args)
{
char *Member = "control";
PyObject *File;
- if (PyArg_ParseTuple(Args,"O!|s",&PyFile_Type,&File,&Member) == 0)
+ if (PyArg_ParseTuple(Args,"O|s",&File,&Member) == 0)
return 0;
// Subscope makes sure any clean up errors are properly handled.
PyObject *Res = 0;
{
// Open the file and associate the .deb
- FileFd Fd(fileno(PyFile_AsFile(File)),false);
+ int fileno = PyObject_AsFileDescriptor(File);
+ if (fileno == -1)
+ return 0;
+ FileFd Fd(fileno,false);
debDebFile Deb(Fd);
if (_error->PendingError() == true)
return HandleErrors();
@@ -69,14 +74,14 @@ static PyObject *debExtractControl(PyObject *Self,PyObject *Args)
// debExtractArchive - Exctract the archive /*{{{*/
// ---------------------------------------------------------------------
static char *doc_debExtractArchive =
-"debExtractArchve(File,rootdir) -> Bool\n"
+"deb_extract_archive(File,rootdir) -> Bool\n"
"Extracts the Archive into the given root dir";
static PyObject *debExtractArchive(PyObject *Self,PyObject *Args)
{
char *Rootdir = NULL;
char cwd[512];
PyObject *File;
- if (PyArg_ParseTuple(Args,"O!|s",&PyFile_Type,&File,&Rootdir) == 0)
+ if (PyArg_ParseTuple(Args,"O|s",&File,&Rootdir) == 0)
return 0;
// Subscope makes sure any clean up errors are properly handled.
@@ -89,7 +94,10 @@ static PyObject *debExtractArchive(PyObject *Self,PyObject *Args)
}
// Open the file and associate the .deb
- FileFd Fd(fileno(PyFile_AsFile(File)),false);
+ int fileno = PyObject_AsFileDescriptor(File);
+ if (fileno == -1)
+ return 0;
+ FileFd Fd(fileno,false);
debDebFile Deb(Fd);
if (_error->PendingError() == true) {
if (Rootdir != NULL)
@@ -112,17 +120,20 @@ static PyObject *debExtractArchive(PyObject *Self,PyObject *Args)
// arFindMember - Find member in AR archive /*{{{*/
// ---------------------------------------------------------------------
static char *doc_arCheckMember =
-"arCheckMember(File, membername) -> Bool\n";
+"ar_check_member(file, membername) -> Bool\n";
static PyObject *arCheckMember(PyObject *Self,PyObject *Args)
{
char *Member = NULL;
bool res = false;
PyObject *File;
- if (PyArg_ParseTuple(Args,"O!s",&PyFile_Type,&File,&Member) == 0)
+ if (PyArg_ParseTuple(Args,"Os",&File,&Member) == 0)
return 0;
// Open the file and associate the .deb
- FileFd Fd(fileno(PyFile_AsFile(File)),false);
+ int fileno = PyObject_AsFileDescriptor(File);
+ if (fileno == -1)
+ return 0;
+ FileFd Fd(fileno,false);
ARArchive AR(Fd);
if (_error->PendingError() == true)
return HandleErrors(Py_BuildValue("b",res));
@@ -145,16 +156,56 @@ static PyMethodDef methods[] =
// access to deb files
{"debExtractControl",debExtractControl,METH_VARARGS,doc_debExtractControl},
{"debExtractArchive",debExtractArchive,METH_VARARGS,doc_debExtractArchive},
-
+
// access to tar streams
{"tarExtract",tarExtract,METH_VARARGS,doc_tarExtract},
{"debExtract",debExtract,METH_VARARGS,doc_debExtract},
-
{}
};
-
+#else
+static PyMethodDef *methods = 0;
+#endif // defined(COMPAT_0_7)
+
+
+static const char *apt_inst_doc =
+ "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) { \
+ if (PyType_Ready(type) == -1) RETURN(0); \
+ Py_INCREF(type); \
+ PyModule_AddObject(mod,name,(PyObject *)type); }
+
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef moduledef = {
+ PyModuleDef_HEAD_INIT,
+ "apt_inst",
+ apt_inst_doc,
+ -1,
+ methods,
+ 0,
+ 0,
+ 0,
+ 0
+};
+#define RETURN(x) return x
+extern "C" PyObject * PyInit_apt_inst()
+#else
extern "C" void initapt_inst()
+#define RETURN(x)
+#endif
{
- Py_InitModule("apt_inst",methods);
+#if PY_MAJOR_VERSION >= 3
+ PyObject *module = PyModule_Create(&moduledef);
+#else
+ PyObject *module = Py_InitModule3("apt_inst",methods, apt_inst_doc);
+#endif
+
+ ADDTYPE(module,"ArMember",&PyArMember_Type);
+ ADDTYPE(module,"ArArchive",&PyArArchive_Type);
+ ADDTYPE(module,"DebFile",&PyDebFile_Type);
+ ADDTYPE(module,"TarFile",&PyTarFile_Type);
+ ADDTYPE(module,"TarMember",&PyTarMember_Type);
+ RETURN(module);
}
- /*}}}*/
diff --git a/python/apt_instmodule.h b/python/apt_instmodule.h
index 45ba5f85..f6b337f4 100644
--- a/python/apt_instmodule.h
+++ b/python/apt_instmodule.h
@@ -11,10 +11,25 @@
#define APT_INSTMODULE_H
#include <Python.h>
+#include "generic.h"
+#include <apt-pkg/extracttar.h>
+#ifdef COMPAT_0_7
PyObject *debExtract(PyObject *Self,PyObject *Args);
extern char *doc_debExtract;
PyObject *tarExtract(PyObject *Self,PyObject *Args);
extern char *doc_tarExtract;
+#endif
+
+extern PyTypeObject PyArMember_Type;
+extern PyTypeObject PyArArchive_Type;
+extern PyTypeObject PyDebFile_Type;
+extern PyTypeObject PyTarFile_Type;
+extern PyTypeObject PyTarMember_Type;
+
+struct PyTarFileObject : public CppPyObject<ExtractTar*> {
+ int min;
+ FileFd Fd;
+};
#endif
diff --git a/python/apt_pkgmodule.cc b/python/apt_pkgmodule.cc
index bfa1227e..3d40832b 100644
--- a/python/apt_pkgmodule.cc
+++ b/python/apt_pkgmodule.cc
@@ -13,6 +13,8 @@
#include "generic.h"
#include <apt-pkg/configuration.h>
+#include <apt-pkg/acquire-item.h>
+#include <apt-pkg/packagemanager.h>
#include <apt-pkg/version.h>
#include <apt-pkg/deblistparser.h>
#include <apt-pkg/pkgcache.h>
@@ -24,17 +26,39 @@
#include <apt-pkg/pkgsystem.h>
#include <sys/stat.h>
+#include <libintl.h>
#include <unistd.h>
#include <Python.h>
/*}}}*/
+/**
+ * A Python->C->Python gettext() function.
+ *
+ * Python's gettext() ignores setlocale() which causes a strange behavior
+ * because the values received from apt-pkg respect setlocale(). We circumvent
+ * this problem by calling the C version of gettext(). This is also much
+ * faster.
+ */
+static PyObject *py_gettext(PyObject *self, PyObject *Args) {
+ const char *msg;
+ char *domain = "python-apt";
+ if (PyArg_ParseTuple(Args,"s|s:gettext",&msg, &domain) == 0)
+ return 0;
+
+ return PyString_FromString(dgettext(domain, msg));
+}
+
// newConfiguration - Build a new configuration class /*{{{*/
// ---------------------------------------------------------------------
+#ifdef COMPAT_0_7
static char *doc_newConfiguration = "Construct a configuration instance";
static PyObject *newConfiguration(PyObject *self,PyObject *args)
{
- return CppPyObject_NEW<Configuration>(&ConfigurationType);
+ PyErr_WarnEx(PyExc_DeprecationWarning, "apt_pkg.newConfiguration() is "
+ "deprecated. Use apt_pkg.Configuration() instead.", 1);
+ return CppPyObject_NEW<Configuration*>(NULL, &PyConfiguration_Type, new Configuration());
}
+#endif
/*}}}*/
// Version Wrappers /*{{{*/
@@ -59,7 +83,14 @@ static PyObject *VersionCompare(PyObject *Self,PyObject *Args)
return Py_BuildValue("i",_system->VS->DoCmpVersion(A,A+LenA,B,B+LenB));
}
-static char *doc_CheckDep = "CheckDep(PkgVer,DepOp,DepVer) -> int";
+static char *doc_CheckDep =
+ "check_dep(pkg_ver: str, dep_op: str, dep_ver: str) -> bool\n\n"
+ "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"
+ " apt_pkg.check_dep('1', '<=', '2')";
static PyObject *CheckDep(PyObject *Self,PyObject *Args)
{
char *A;
@@ -69,6 +100,9 @@ static PyObject *CheckDep(PyObject *Self,PyObject *Args)
if (PyArg_ParseTuple(Args,"sss",&A,&OpStr,&B) == 0)
return 0;
+
+ if (strcmp(OpStr, ">") == 0) OpStr = ">>";
+ if (strcmp(OpStr, "<") == 0) OpStr = "<<";
if (*debListParser::ConvertRelation(OpStr,Op) != 0)
{
PyErr_SetString(PyExc_ValueError,"Bad comparision operation");
@@ -81,10 +115,36 @@ static PyObject *CheckDep(PyObject *Self,PyObject *Args)
return 0;
}
- return Py_BuildValue("i",_system->VS->CheckDep(A,Op,B));
-// return Py_BuildValue("i",pkgCheckDep(B,A,Op));
+ return PyBool_FromLong(_system->VS->CheckDep(A,Op,B));
}
+#ifdef COMPAT_0_7
+static char *doc_CheckDepOld = "CheckDep(PkgVer,DepOp,DepVer) -> bool";
+static PyObject *CheckDepOld(PyObject *Self,PyObject *Args)
+{
+ char *A;
+ char *B;
+ char *OpStr;
+ unsigned int Op = 0;
+
+ if (PyArg_ParseTuple(Args,"sss",&A,&OpStr,&B) == 0)
+ return 0;
+ if (*debListParser::ConvertRelation(OpStr,Op) != 0)
+ {
+ PyErr_SetString(PyExc_ValueError,"Bad comparision operation");
+ return 0;
+ }
+
+ if (_system == 0)
+ {
+ PyErr_SetString(PyExc_ValueError,"_system not initialized");
+ return 0;
+ }
+
+ return PyBool_FromLong(_system->VS->CheckDep(A,Op,B));
+}
+#endif
+
static char *doc_UpstreamVersion = "UpstreamVersion(a) -> string";
static PyObject *UpstreamVersion(PyObject *Self,PyObject *Args)
{
@@ -100,9 +160,11 @@ static char *doc_ParseDepends =
"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.";
+"Match are returned.\n\n"
+"apt_pkg.Parse{,Src}Depends() are old forms which return >>,<< instead of >,<";
static PyObject *RealParseDepends(PyObject *Self,PyObject *Args,
- bool ParseArchFlags)
+ bool ParseArchFlags, string name,
+ bool debStyle=false)
{
string Package;
string Version;
@@ -112,7 +174,7 @@ static PyObject *RealParseDepends(PyObject *Self,PyObject *Args,
const char *Stop;
int Len;
- if (PyArg_ParseTuple(Args,"s#",&Start,&Len) == 0)
+ if (PyArg_ParseTuple(Args,(char *)("s#:" + name).c_str(),&Start,&Len) == 0)
return 0;
Stop = Start + Len;
PyObject *List = PyList_New(0);
@@ -139,7 +201,7 @@ static PyObject *RealParseDepends(PyObject *Self,PyObject *Args,
PyObject *Obj;
PyList_Append(LastRow,Obj = Py_BuildValue("sss",Package.c_str(),
Version.c_str(),
- pkgCache::CompTypeDeb(Op)));
+ debStyle ? pkgCache::CompTypeDeb(Op) : pkgCache::CompType(Op)));
Py_DECREF(Obj);
}
@@ -156,12 +218,22 @@ static PyObject *RealParseDepends(PyObject *Self,PyObject *Args,
}
static PyObject *ParseDepends(PyObject *Self,PyObject *Args)
{
- return RealParseDepends(Self,Args,false);
+ return RealParseDepends(Self, Args, false, "parse_depends");
}
static PyObject *ParseSrcDepends(PyObject *Self,PyObject *Args)
{
- return RealParseDepends(Self,Args,true);
+ return RealParseDepends(Self, Args, true, "parse_src_depends");
+}
+#ifdef COMPAT_0_7
+static PyObject *ParseDepends_old(PyObject *Self,PyObject *Args)
+{
+ return RealParseDepends(Self, Args, false, "ParseDepends", true);
+}
+static PyObject *ParseSrcDepends_old(PyObject *Self,PyObject *Args)
+{
+ return RealParseDepends(Self, Args, true, "ParseSrcDepends", true);
}
+#endif
/*}}}*/
// md5sum - Compute the md5sum of a file or string /*{{{*/
// ---------------------------------------------------------------------
@@ -173,21 +245,21 @@ static PyObject *md5sum(PyObject *Self,PyObject *Args)
return 0;
// Digest of a string.
- if (PyString_Check(Obj) != 0)
+ if (PyBytes_Check(Obj) != 0)
{
char *s;
Py_ssize_t len;
MD5Summation Sum;
- PyString_AsStringAndSize(Obj, &s, &len);
+ PyBytes_AsStringAndSize(Obj, &s, &len);
Sum.Add((const unsigned char*)s, len);
return CppPyString(Sum.Result().Value());
}
// Digest of a file
- if (PyFile_Check(Obj) != 0)
+ int Fd = PyObject_AsFileDescriptor(Obj);
+ if (Fd != -1)
{
MD5Summation Sum;
- int Fd = fileno(PyFile_AsFile(Obj));
struct stat St;
if (fstat(Fd,&St) != 0 ||
Sum.AddFD(Fd,St.st_size) == false)
@@ -213,21 +285,21 @@ static PyObject *sha1sum(PyObject *Self,PyObject *Args)
return 0;
// Digest of a string.
- if (PyString_Check(Obj) != 0)
+ if (PyBytes_Check(Obj) != 0)
{
char *s;
Py_ssize_t len;
SHA1Summation Sum;
- PyString_AsStringAndSize(Obj, &s, &len);
+ PyBytes_AsStringAndSize(Obj, &s, &len);
Sum.Add((const unsigned char*)s, len);
return CppPyString(Sum.Result().Value());
}
// Digest of a file
- if (PyFile_Check(Obj) != 0)
+ int Fd = PyObject_AsFileDescriptor(Obj);
+ if (Fd != -1)
{
SHA1Summation Sum;
- int Fd = fileno(PyFile_AsFile(Obj));
struct stat St;
if (fstat(Fd,&St) != 0 ||
Sum.AddFD(Fd,St.st_size) == false)
@@ -253,21 +325,21 @@ static PyObject *sha256sum(PyObject *Self,PyObject *Args)
return 0;
// Digest of a string.
- if (PyString_Check(Obj) != 0)
+ if (PyBytes_Check(Obj) != 0)
{
char *s;
Py_ssize_t len;
SHA256Summation Sum;
- PyString_AsStringAndSize(Obj, &s, &len);
+ PyBytes_AsStringAndSize(Obj, &s, &len);
Sum.Add((const unsigned char*)s, len);
return CppPyString(Sum.Result().Value());
}
// Digest of a file
- if (PyFile_Check(Obj) != 0)
+ int Fd = PyObject_AsFileDescriptor(Obj);
+ if (Fd != -1)
{
SHA256Summation Sum;
- int Fd = fileno(PyFile_AsFile(Obj));
struct stat St;
if (fstat(Fd,&St) != 0 ||
Sum.AddFD(Fd,St.st_size) == false)
@@ -385,42 +457,82 @@ static PyObject *PkgSystemUnLock(PyObject *Self,PyObject *Args)
static PyMethodDef methods[] =
{
// Constructors
- {"newConfiguration",newConfiguration,METH_VARARGS,doc_newConfiguration},
{"init",Init,METH_VARARGS,doc_Init},
+ {"init_config",InitConfig,METH_VARARGS,doc_InitConfig},
+ {"init_system",InitSystem,METH_VARARGS,doc_InitSystem},
+
+ // 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."},
+
+ // Tag File
+ {"rewrite_section",RewriteSection,METH_VARARGS,doc_RewriteSection},
+
+ // Locking
+ {"get_lock",GetLock,METH_VARARGS,doc_GetLock},
+ {"pkgsystem_lock",PkgSystemLock,METH_VARARGS,doc_PkgSystemLock},
+ {"pkgsystem_unlock",PkgSystemUnLock,METH_VARARGS,doc_PkgSystemUnLock},
+
+ // Command line
+ {"read_config_file",LoadConfig,METH_VARARGS,doc_LoadConfig},
+ {"read_config_dir",LoadConfigDir,METH_VARARGS,doc_LoadConfigDir},
+ {"read_config_file_isc",LoadConfigISC,METH_VARARGS,doc_LoadConfig},
+ {"parse_commandline",ParseCommandLine,METH_VARARGS,doc_ParseCommandLine},
+
+ // Versioning
+ {"version_compare",VersionCompare,METH_VARARGS,doc_VersionCompare},
+ {"check_dep",CheckDep,METH_VARARGS,doc_CheckDep},
+ {"upstream_version",UpstreamVersion,METH_VARARGS,doc_UpstreamVersion},
+
+ // Depends
+ {"parse_depends",ParseDepends,METH_VARARGS,doc_ParseDepends},
+ {"parse_src_depends",ParseSrcDepends,METH_VARARGS,doc_ParseDepends},
+
+ // Stuff
+ {"md5sum",md5sum,METH_VARARGS,doc_md5sum},
+ {"sha1sum",sha1sum,METH_VARARGS,doc_sha1sum},
+ {"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"},
+
+ // DEPRECATED
+ #ifdef COMPAT_0_7
+ {"CheckDep",CheckDepOld,METH_VARARGS,doc_CheckDepOld},
+ {"newConfiguration",newConfiguration,METH_VARARGS,doc_newConfiguration},
{"InitConfig",InitConfig,METH_VARARGS,doc_InitConfig},
{"InitSystem",InitSystem,METH_VARARGS,doc_InitSystem},
- // Tag File
{"ParseSection",ParseSection,METH_VARARGS,doc_ParseSection},
{"ParseTagFile",ParseTagFile,METH_VARARGS,doc_ParseTagFile},
{"RewriteSection",RewriteSection,METH_VARARGS,doc_RewriteSection},
- // Locking
{"GetLock",GetLock,METH_VARARGS,doc_GetLock},
{"PkgSystemLock",PkgSystemLock,METH_VARARGS,doc_PkgSystemLock},
{"PkgSystemUnLock",PkgSystemUnLock,METH_VARARGS,doc_PkgSystemUnLock},
- // Command line
{"ReadConfigFile",LoadConfig,METH_VARARGS,doc_LoadConfig},
{"ReadConfigDir",LoadConfigDir,METH_VARARGS,doc_LoadConfigDir},
{"ReadConfigFileISC",LoadConfigISC,METH_VARARGS,doc_LoadConfig},
{"ParseCommandLine",ParseCommandLine,METH_VARARGS,doc_ParseCommandLine},
- // Versioning
{"VersionCompare",VersionCompare,METH_VARARGS,doc_VersionCompare},
- {"CheckDep",CheckDep,METH_VARARGS,doc_CheckDep},
{"UpstreamVersion",UpstreamVersion,METH_VARARGS,doc_UpstreamVersion},
- // Depends
- {"ParseDepends",ParseDepends,METH_VARARGS,doc_ParseDepends},
- {"ParseSrcDepends",ParseSrcDepends,METH_VARARGS,doc_ParseDepends},
+ {"ParseDepends",ParseDepends_old,METH_VARARGS,doc_ParseDepends},
+ {"ParseSrcDepends",ParseSrcDepends_old,METH_VARARGS,doc_ParseDepends},
- // Stuff
- {"md5sum",md5sum,METH_VARARGS,doc_md5sum},
- {"sha1sum",sha1sum,METH_VARARGS,doc_sha1sum},
- {"sha256sum",sha256sum,METH_VARARGS,doc_sha256sum},
-
- // Strings
{"CheckDomainList",StrCheckDomainList,METH_VARARGS,"CheckDomainList(String,String) -> Bool"},
{"QuoteString",StrQuoteString,METH_VARARGS,"QuoteString(String,String) -> String"},
{"DeQuoteString",StrDeQuote,METH_VARARGS,"DeQuoteString(String) -> String"},
@@ -432,104 +544,376 @@ static PyMethodDef methods[] =
{"TimeRFC1123",StrTimeRFC1123,METH_VARARGS,"TimeRFC1123(int) -> String"},
{"StrToTime",StrStrToTime,METH_VARARGS,"StrToTime(String) -> Int"},
- // Cache
{"GetCache",TmpGetCache,METH_VARARGS,"GetCache() -> PkgCache"},
{"GetDepCache",GetDepCache,METH_VARARGS,"GetDepCache(Cache) -> DepCache"},
{"GetPkgRecords",GetPkgRecords,METH_VARARGS,"GetPkgRecords(Cache) -> PkgRecords"},
{"GetPkgSrcRecords",GetPkgSrcRecords,METH_VARARGS,"GetPkgSrcRecords() -> PkgSrcRecords"},
{"GetPkgSourceList",GetPkgSourceList,METH_VARARGS,"GetPkgSourceList() -> PkgSourceList"},
-
- // misc
{"GetPkgProblemResolver",GetPkgProblemResolver,METH_VARARGS,"GetDepProblemResolver(DepCache) -> PkgProblemResolver"},
{"GetPkgActionGroup",GetPkgActionGroup,METH_VARARGS,"GetPkgActionGroup(DepCache) -> PkgActionGroup"},
-
- // Cdrom
{"GetCdrom",GetCdrom,METH_VARARGS,"GetCdrom() -> Cdrom"},
-
- // Acquire
{"GetAcquire",GetAcquire,METH_VARARGS,"GetAcquire() -> Acquire"},
{"GetPkgAcqFile",(PyCFunction)GetPkgAcqFile,METH_KEYWORDS|METH_VARARGS, doc_GetPkgAcqFile},
-
- // PkgManager
{"GetPackageManager",GetPkgManager,METH_VARARGS,"GetPackageManager(DepCache) -> PackageManager"},
+ #endif
{}
};
-static void AddStr(PyObject *Dict,const char *Itm,const char *Str)
-{
- PyObject *Obj = PyString_FromString(Str);
- PyDict_SetItemString(Dict,(char *)Itm,Obj);
- Py_DECREF(Obj);
-}
+static struct _PyAptPkgAPIStruct API = {
+ &PyAcquire_Type, // acquire_type
+ &PyAcquire_FromCpp, // acquire_fromcpp
+ &PyAcquire_ToCpp, // acquire_tocpp
+ &PyAcquireFile_Type, // acquirefile_type
+ &PyAcquireFile_FromCpp, // acquirefile_fromcpp
+ &PyAcquireFile_ToCpp, // acquirefile_tocpp
+ &PyAcquireItem_Type, // acquireitem_type
+ &PyAcquireItem_FromCpp, // acquireitem_fromcpp
+ &PyAcquireItem_ToCpp, // acquireitem_type
+ &PyAcquireItemDesc_Type, // acquireitemdesc_type
+ &PyAcquireItemDesc_FromCpp,// acquireitemdesc_fromcpp
+ &PyAcquireItemDesc_ToCpp, // acquireitemdesc_tocpp
+ &PyAcquireWorker_Type, // acquireworker_type
+ &PyAcquireWorker_FromCpp, // acquireworker_fromcpp
+ &PyAcquireWorker_ToCpp, // acquireworker_tocpp
+ &PyActionGroup_Type, // actiongroup_type
+ &PyActionGroup_FromCpp, // actiongroup_fromcpp
+ &PyActionGroup_ToCpp, // actiongroup_tocpp
+ &PyCache_Type, // cache_type
+ &PyCache_FromCpp, // cache_fromcpp
+ &PyCache_ToCpp, // cache_tocpp
+ &PyCacheFile_Type, // cachefile_type
+ &PyCacheFile_FromCpp, // cachefile_fromcpp
+ &PyCacheFile_ToCpp, // cachefile_tocpp
+ &PyCdrom_Type, // cdrom_type
+ &PyCdrom_FromCpp, // cdrom_fromcpp
+ &PyCdrom_ToCpp, // cdrom_tocpp
+ &PyConfiguration_Type, // configuration_type
+ &PyConfiguration_FromCpp, // configuration_fromcpp
+ &PyConfiguration_ToCpp, // configuration_tocpp
+ &PyDepCache_Type, // depcache_type
+ &PyDepCache_FromCpp, // depcache_fromcpp
+ &PyDepCache_ToCpp, // depcache_tocpp
+ &PyDependency_Type, // dependency_type
+ &PyDependency_FromCpp, // dependency_fromcpp
+ &PyDependency_ToCpp, // dependency_tocpp
+ &PyDependencyList_Type, // dependencylist_type
+ 0, // FIXME: dependencylist_fromcpp
+ 0, // FIXME: dependencylist_tocpp
+ &PyDescription_Type, // description_type
+ &PyDescription_FromCpp, // description_fromcpp
+ &PyDescription_ToCpp, // description_tocpp
+ &PyHashes_Type, // hashes_type
+ &PyHashes_FromCpp, // hashes_fromcpp
+ &PyHashes_ToCpp, // hashes_tocpp
+ &PyHashString_Type, // hashstring_type
+ &PyHashString_FromCpp, // hashstring_fromcpp
+ &PyHashString_ToCpp, // hashstring_tocpp
+ &PyIndexRecords_Type, // indexrecords_type
+ &PyIndexRecords_FromCpp, // indexrecords_tocpp
+ &PyIndexRecords_ToCpp, // indexrecords_tocpp
+ &PyMetaIndex_Type, // metaindex_type
+ &PyMetaIndex_FromCpp, // metaindex_tocpp
+ &PyMetaIndex_ToCpp, // metaindex_tocpp
+ &PyPackage_Type, // package_type
+ &PyPackage_FromCpp, // package_tocpp
+ &PyPackage_ToCpp, // package_tocpp
+ &PyPackageFile_Type, // packagefile_type
+ &PyPackageFile_FromCpp, // packagefile_tocpp
+ &PyPackageFile_ToCpp, // packagefile_tocpp
+ &PyIndexFile_Type, // packageindexfile_type
+ &PyIndexFile_FromCpp, // packageindexfile_tocpp
+ &PyIndexFile_ToCpp, // packageindexfile_tocpp
+ &PyPackageList_Type, // packagelist_type
+ 0, // FIXME: packagelist_fromcpp
+ 0, // FIXME: packagelist_tocpp
+ &PyPackageManager_Type, // packagemanager_type
+ &PyPackageManager_FromCpp, // packagemanager_type
+ &PyPackageManager_ToCpp, // packagemanager_type
+ &PyPackageRecords_Type, // packagerecords_type
+ 0, // FIXME: packagerecords_fromcpp
+ 0, // FIXME: packagerecords_tocpp
+ &PyPolicy_Type, // policy_type
+ &PyPolicy_FromCpp, // policy_tocpp
+ &PyPolicy_ToCpp, // policy_tocpp
+ &PyProblemResolver_Type, // problemresolver_type
+ &PyProblemResolver_FromCpp, // problemresolver_tocpp
+ &PyProblemResolver_ToCpp, // problemresolver_tocpp
+ &PySourceList_Type, // sourcelist_type
+ &PySourceList_FromCpp, // sourcelist_tocpp
+ &PySourceList_ToCpp, // sourcelist_tocpp
+ &PySourceRecords_Type, // sourcerecords_type
+ 0, // FIXME: sourcerecords_fromcpp
+ 0, // FIXME: sourcerecords_tocpp
+ &PyTagFile_Type, // tagfile_type
+ &PyTagFile_FromCpp, // tagfile_tocpp
+ &PyTagFile_ToCpp, // tagfile_tocpp
+ &PyTagSection_Type, // tagsection_type
+ &PyTagSection_FromCpp, // tagsection_tocpp
+ &PyTagSection_ToCpp, // tagsection_tocpp
+ &PyVersion_Type, // version_type
+ &PyVersion_FromCpp, // version_tocpp
+ &PyVersion_ToCpp, // version_tocpp
+};
-static void AddInt(PyObject *Dict,const char *Itm,unsigned long I)
-{
- PyObject *Obj = Py_BuildValue("i",I);
- PyDict_SetItemString(Dict,(char *)Itm,Obj);
- Py_DECREF(Obj);
-}
+#define ADDTYPE(mod,name,type) { \
+ if (PyType_Ready(type) == -1) INIT_ERROR; \
+ Py_INCREF(type); \
+ PyModule_AddObject(mod,name,(PyObject *)type); }
+
+
+#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...",
+ -1,
+ methods,
+ 0,
+ 0,
+ 0,
+ 0,
+};
+
+#define INIT_ERROR return 0
+extern "C" PyObject * PyInit_apt_pkg()
+#else
+#define INIT_ERROR return
extern "C" void initapt_pkg()
+#endif
{
+ // Finalize our types to add slots, etc.
+ if (PyType_Ready(&PyConfiguration_Type) == -1) INIT_ERROR;
+ if (PyType_Ready(&PyCacheFile_Type) == -1) INIT_ERROR;
+
+ // Initialize the module
+ #if PY_MAJOR_VERSION >= 3
+ PyObject *Module = PyModule_Create(&moduledef);
+ #else
PyObject *Module = Py_InitModule("apt_pkg",methods);
- PyObject *Dict = PyModule_GetDict(Module);
+ #endif
// Global variable linked to the global configuration class
- CppPyObject<Configuration *> *Config = CppPyObject_NEW<Configuration *>(&ConfigurationPtrType);
+ CppPyObject<Configuration*> *Config = CppPyObject_NEW<Configuration*>(NULL, &PyConfiguration_Type);
Config->Object = _config;
- PyDict_SetItemString(Dict,"Config",Config);
- Py_DECREF(Config);
-
+ // Global configuration, should never be deleted.
+ Config->NoDelete = true;
+ PyModule_AddObject(Module,"config",Config);
+ #ifdef COMPAT_0_7
+ Py_INCREF(Config);
+ PyModule_AddObject(Module,"Config",Config);
+ #endif
+
+
+
+
+ // Add our classes.
+ /* ============================ tag.cc ============================ */
+ ADDTYPE(Module,"TagSection",&PyTagSection_Type);
+ ADDTYPE(Module,"TagFile",&PyTagFile_Type);
+ /* ============================ acquire.cc ============================ */
+ ADDTYPE(Module,"Acquire",&PyAcquire_Type);
+ ADDTYPE(Module,"AcquireFile",&PyAcquireFile_Type);
+ ADDTYPE(Module,"AcquireItem",&PyAcquireItem_Type); // NO __new__()
+ ADDTYPE(Module,"AcquireWorker",&PyAcquireWorker_Type); // NO __new__()
+ /* ============================ cache.cc ============================ */
+ ADDTYPE(Module,"Cache",&PyCache_Type);
+ ADDTYPE(Module,"Dependency",&PyDependency_Type); // NO __new__()
+ ADDTYPE(Module,"Description",&PyDescription_Type); // NO __new__()
+ ADDTYPE(Module,"PackageFile",&PyPackageFile_Type); // NO __new__()
+ ADDTYPE(Module,"PackageList",&PyPackageList_Type); // NO __new__(), internal
+ ADDTYPE(Module,"DependencyList",&PyDependencyList_Type); // NO __new__(), internal
+ ADDTYPE(Module,"Package",&PyPackage_Type); // NO __new__()
+ ADDTYPE(Module,"Version",&PyVersion_Type); // NO __new__()
+ /* ============================ cdrom.cc ============================ */
+ ADDTYPE(Module,"Cdrom",&PyCdrom_Type);
+ /* ========================= configuration.cc ========================= */
+ ADDTYPE(Module,"Configuration",&PyConfiguration_Type);
+ /* ========================= depcache.cc ========================= */
+ ADDTYPE(Module,"ActionGroup",&PyActionGroup_Type);
+ ADDTYPE(Module,"DepCache",&PyDepCache_Type);
+ ADDTYPE(Module,"ProblemResolver",&PyProblemResolver_Type);
+ /* ========================= indexfile.cc ========================= */
+ ADDTYPE(Module,"IndexFile",&PyIndexFile_Type); // NO __new__()
+ /* ========================= metaindex.cc ========================= */
+ ADDTYPE(Module,"MetaIndex",&PyMetaIndex_Type); // NO __new__()
+ /* ========================= pkgmanager.cc ========================= */
+ ADDTYPE(Module,"PackageManager",&PyPackageManager_Type);
+ /* ========================= pkgrecords.cc ========================= */
+ ADDTYPE(Module,"PackageRecords",&PyPackageRecords_Type);
+ /* ========================= pkgsrcrecords.cc ========================= */
+ ADDTYPE(Module,"SourceRecords",&PySourceRecords_Type);
+ /* ========================= sourcelist.cc ========================= */
+ ADDTYPE(Module,"SourceList",&PySourceList_Type);
+ ADDTYPE(Module,"IndexRecords",&PyIndexRecords_Type);
+ ADDTYPE(Module,"HashString",&PyHashString_Type);
+ ADDTYPE(Module,"Policy",&PyPolicy_Type);
+ ADDTYPE(Module,"Hashes",&PyHashes_Type);
+ ADDTYPE(Module,"AcquireItemDesc",&PyAcquireItemDesc_Type);
+ ADDTYPE(Module,"SystemLock",&PySystemLock_Type);
+ ADDTYPE(Module,"FileLock",&PyFileLock_Type);
// Tag file constants
- PyObject *Obj;
- PyDict_SetItemString(Dict,"RewritePackageOrder",
- Obj = CharCharToList(TFRewritePackageOrder));
- Py_DECREF(Obj);
- PyDict_SetItemString(Dict,"RewriteSourceOrder",
- Obj = CharCharToList(TFRewriteSourceOrder));
- Py_DECREF(Obj);
-
+ PyModule_AddObject(Module,"REWRITE_PACKAGE_ORDER",
+ CharCharToList(TFRewritePackageOrder));
+
+ PyModule_AddObject(Module,"REWRITE_SOURCE_ORDER",
+ CharCharToList(TFRewriteSourceOrder));
+
+
+ // Acquire constants.
+ // some constants
+ PyDict_SetItemString(PyAcquire_Type.tp_dict, "RESULT_CANCELLED",
+ Py_BuildValue("i", pkgAcquire::Cancelled));
+ PyDict_SetItemString(PyAcquire_Type.tp_dict, "RESULT_CONTINUE",
+ Py_BuildValue("i", pkgAcquire::Continue));
+ PyDict_SetItemString(PyAcquire_Type.tp_dict, "RESULT_FAILED",
+ Py_BuildValue("i", pkgAcquire::Failed));
+#ifdef COMPAT_0_7
+ PyDict_SetItemString(PyAcquire_Type.tp_dict, "ResultCancelled",
+ Py_BuildValue("i", pkgAcquire::Cancelled));
+ PyDict_SetItemString(PyAcquire_Type.tp_dict, "ResultContinue",
+ Py_BuildValue("i", pkgAcquire::Continue));
+ PyDict_SetItemString(PyAcquire_Type.tp_dict, "ResultFailed",
+ Py_BuildValue("i", pkgAcquire::Failed));
+#endif
+ // Dependency constants
+ PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_DEPENDS",
+ Py_BuildValue("i", pkgCache::Dep::Depends));
+ PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_PREDEPENDS",
+ Py_BuildValue("i", pkgCache::Dep::PreDepends));
+ PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_SUGGESTS",
+ Py_BuildValue("i", pkgCache::Dep::Suggests));
+ PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_RECOMMENDS",
+ Py_BuildValue("i", pkgCache::Dep::Suggests));
+ PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_CONFLICTS",
+ Py_BuildValue("i", pkgCache::Dep::Conflicts));
+ PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_REPLACES",
+ Py_BuildValue("i", pkgCache::Dep::Replaces));
+ PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_OBSOLETES",
+ Py_BuildValue("i", pkgCache::Dep::Obsoletes));
+ PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_DPKG_BREAKS",
+ Py_BuildValue("i", pkgCache::Dep::DpkgBreaks));
+ PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_ENHANCES",
+ Py_BuildValue("i", pkgCache::Dep::Enhances));
+
+
+ // PackageManager constants
+ PyDict_SetItemString(PyPackageManager_Type.tp_dict, "RESULT_COMPLETED",
+ Py_BuildValue("i", pkgPackageManager::Completed));
+ PyDict_SetItemString(PyPackageManager_Type.tp_dict, "RESULT_FAILED",
+ Py_BuildValue("i", pkgPackageManager::Failed));
+ PyDict_SetItemString(PyPackageManager_Type.tp_dict, "RESULT_INCOMPLETE",
+ Py_BuildValue("i", pkgPackageManager::Incomplete));
+
+#ifdef COMPAT_0_7
+ PyDict_SetItemString(PyPackageManager_Type.tp_dict, "ResultCompleted",
+ Py_BuildValue("i", pkgPackageManager::Completed));
+ PyDict_SetItemString(PyPackageManager_Type.tp_dict, "ResultFailed",
+ Py_BuildValue("i", pkgPackageManager::Failed));
+ PyDict_SetItemString(PyPackageManager_Type.tp_dict, "ResultIncomplete",
+ Py_BuildValue("i", pkgPackageManager::Incomplete));
+#endif
+
+ // AcquireItem Constants.
+ PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "STAT_IDLE",
+ Py_BuildValue("i", pkgAcquire::Item::StatIdle));
+ PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "STAT_FETCHING",
+ Py_BuildValue("i", pkgAcquire::Item::StatFetching));
+ PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "STAT_DONE",
+ Py_BuildValue("i", pkgAcquire::Item::StatDone));
+ PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "STAT_ERROR",
+ Py_BuildValue("i", pkgAcquire::Item::StatError));
+ PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "STAT_AUTH_ERROR",
+ Py_BuildValue("i", pkgAcquire::Item::StatAuthError));
+
+#ifdef COMPAT_0_7
+ PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "StatIdle",
+ Py_BuildValue("i", pkgAcquire::Item::StatIdle));
+ PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "StatFetching",
+ Py_BuildValue("i", pkgAcquire::Item::StatFetching));
+ PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "StatDone",
+ Py_BuildValue("i", pkgAcquire::Item::StatDone));
+ PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "StatError",
+ Py_BuildValue("i", pkgAcquire::Item::StatError));
+ PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "StatAuthError",
+ Py_BuildValue("i", pkgAcquire::Item::StatAuthError));
+#endif
+
+#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 1
+ PyObject *PyCapsule = PyCapsule_New(&API, "apt_pkg._C_API", NULL);
+#else
+ PyObject *PyCapsule = PyCObject_FromVoidPtr(&API, NULL);
+#endif
+ PyModule_AddObject(Module, "_C_API", PyCapsule);
// Version..
- AddStr(Dict,"Version",pkgVersion);
- AddStr(Dict,"LibVersion",pkgLibVersion);
- AddStr(Dict,"Date",__DATE__);
- AddStr(Dict,"Time",__TIME__);
+ PyModule_AddStringConstant(Module,"VERSION",(char *)pkgVersion);
+ PyModule_AddStringConstant(Module,"LIB_VERSION",(char *)pkgLibVersion);
+ PyModule_AddStringConstant(Module,"DATE",__DATE__);
+ PyModule_AddStringConstant(Module,"TIME",__TIME__);
// My constants
- AddInt(Dict,"DepDepends",pkgCache::Dep::Depends);
- AddInt(Dict,"DepPreDepends",pkgCache::Dep::PreDepends);
- AddInt(Dict,"DepSuggests",pkgCache::Dep::Suggests);
- AddInt(Dict,"DepRecommends",pkgCache::Dep::Recommends);
- AddInt(Dict,"DepConflicts",pkgCache::Dep::Conflicts);
- AddInt(Dict,"DepReplaces",pkgCache::Dep::Replaces);
- AddInt(Dict,"DepObsoletes",pkgCache::Dep::Obsoletes);
- AddInt(Dict,"DepDpkgBreaks",pkgCache::Dep::DpkgBreaks);
- AddInt(Dict,"DepEnhances",pkgCache::Dep::Enhances);
-
- AddInt(Dict,"PriImportant",pkgCache::State::Important);
- AddInt(Dict,"PriRequired",pkgCache::State::Required);
- AddInt(Dict,"PriStandard",pkgCache::State::Standard);
- AddInt(Dict,"PriOptional",pkgCache::State::Optional);
- AddInt(Dict,"PriExtra",pkgCache::State::Extra);
-
- AddInt(Dict,"CurStateNotInstalled",pkgCache::State::NotInstalled);
- AddInt(Dict,"CurStateUnPacked",pkgCache::State::UnPacked);
- AddInt(Dict,"CurStateHalfConfigured",pkgCache::State::HalfConfigured);
- AddInt(Dict,"CurStateHalfInstalled",pkgCache::State::HalfInstalled);
- AddInt(Dict,"CurStateConfigFiles",pkgCache::State::ConfigFiles);
- AddInt(Dict,"CurStateInstalled",pkgCache::State::Installed);
-
- AddInt(Dict,"SelStateUnknown",pkgCache::State::Unknown);
- AddInt(Dict,"SelStateInstall",pkgCache::State::Install);
- AddInt(Dict,"SelStateHold",pkgCache::State::Hold);
- AddInt(Dict,"SelStateDeInstall",pkgCache::State::DeInstall);
- AddInt(Dict,"SelStatePurge",pkgCache::State::Purge);
-
- AddInt(Dict,"InstStateOk",pkgCache::State::Ok);
- AddInt(Dict,"InstStateReInstReq",pkgCache::State::ReInstReq);
- AddInt(Dict,"InstStateHold",pkgCache::State::Hold);
- AddInt(Dict,"InstStateHoldReInstReq",pkgCache::State::HoldReInstReq);
+ PyModule_AddIntConstant(Module,"PRI_IMPORTANT",pkgCache::State::Important);
+ PyModule_AddIntConstant(Module,"PRI_REQUIRED",pkgCache::State::Required);
+ PyModule_AddIntConstant(Module,"PRI_STANDARD",pkgCache::State::Standard);
+ PyModule_AddIntConstant(Module,"PRI_OPTIONAL",pkgCache::State::Optional);
+ PyModule_AddIntConstant(Module,"PRI_EXTRA",pkgCache::State::Extra);
+ // CurState
+ PyModule_AddIntConstant(Module,"CURSTATE_NOT_INSTALLED",pkgCache::State::NotInstalled);
+ PyModule_AddIntConstant(Module,"CURSTATE_UNPACKED",pkgCache::State::UnPacked);
+ PyModule_AddIntConstant(Module,"CURSTATE_HALF_CONFIGURED",pkgCache::State::HalfConfigured);
+ PyModule_AddIntConstant(Module,"CURSTATE_HALF_INSTALLED",pkgCache::State::HalfInstalled);
+ PyModule_AddIntConstant(Module,"CURSTATE_CONFIG_FILES",pkgCache::State::ConfigFiles);
+ PyModule_AddIntConstant(Module,"CURSTATE_INSTALLED",pkgCache::State::Installed);
+ // SelState
+ PyModule_AddIntConstant(Module,"SELSTATE_UNKNOWN",pkgCache::State::Unknown);
+ PyModule_AddIntConstant(Module,"SELSTATE_INSTALL",pkgCache::State::Install);
+ PyModule_AddIntConstant(Module,"SELSTATE_HOLD",pkgCache::State::Hold);
+ PyModule_AddIntConstant(Module,"SELSTATE_DEINSTALL",pkgCache::State::DeInstall);
+ PyModule_AddIntConstant(Module,"SELSTATE_PURGE",pkgCache::State::Purge);
+ // InstState
+ PyModule_AddIntConstant(Module,"INSTSTATE_OK",pkgCache::State::Ok);
+ PyModule_AddIntConstant(Module,"INSTSTATE_REINSTREQ",pkgCache::State::ReInstReq);
+ PyModule_AddIntConstant(Module,"INSTSTATE_HOLD",pkgCache::State::Hold);
+ PyModule_AddIntConstant(Module,"INSTSTATE_HOLD_REINSTREQ",pkgCache::State::HoldReInstReq);
+
+ // DEPRECATED API
+ #ifdef COMPAT_0_7
+ PyModule_AddObject(Module,"RewritePackageOrder",
+ CharCharToList(TFRewritePackageOrder));
+ PyModule_AddObject(Module,"RewriteSourceOrder",
+ CharCharToList(TFRewriteSourceOrder));
+ PyModule_AddStringConstant(Module,"LibVersion",(char *)pkgLibVersion);
+ PyModule_AddStringConstant(Module,"Date",__DATE__);
+ PyModule_AddStringConstant(Module,"Time",__TIME__);
+ PyModule_AddIntConstant(Module,"PriImportant",pkgCache::State::Important);
+ PyModule_AddIntConstant(Module,"PriRequired",pkgCache::State::Required);
+ PyModule_AddIntConstant(Module,"PriStandard",pkgCache::State::Standard);
+ PyModule_AddIntConstant(Module,"PriOptional",pkgCache::State::Optional);
+ PyModule_AddIntConstant(Module,"PriExtra",pkgCache::State::Extra);
+ PyModule_AddIntConstant(Module,"CurStateNotInstalled",pkgCache::State::NotInstalled);
+ PyModule_AddIntConstant(Module,"CurStateUnPacked",pkgCache::State::UnPacked);
+ PyModule_AddIntConstant(Module,"CurStateHalfConfigured",pkgCache::State::HalfConfigured);
+ PyModule_AddIntConstant(Module,"CurStateHalfInstalled",pkgCache::State::HalfInstalled);
+ PyModule_AddIntConstant(Module,"CurStateConfigFiles",pkgCache::State::ConfigFiles);
+ PyModule_AddIntConstant(Module,"CurStateInstalled",pkgCache::State::Installed);
+ PyModule_AddIntConstant(Module,"SelStateUnknown",pkgCache::State::Unknown);
+ PyModule_AddIntConstant(Module,"SelStateInstall",pkgCache::State::Install);
+ PyModule_AddIntConstant(Module,"SelStateHold",pkgCache::State::Hold);
+ PyModule_AddIntConstant(Module,"SelStateDeInstall",pkgCache::State::DeInstall);
+ PyModule_AddIntConstant(Module,"SelStatePurge",pkgCache::State::Purge);
+ PyModule_AddIntConstant(Module,"InstStateOk",pkgCache::State::Ok);
+ PyModule_AddIntConstant(Module,"InstStateReInstReq",pkgCache::State::ReInstReq);
+ PyModule_AddIntConstant(Module,"InstStateHold",pkgCache::State::Hold);
+ PyModule_AddIntConstant(Module,"InstStateHoldReInstReq",pkgCache::State::HoldReInstReq);
+ PyModule_AddIntConstant(Module,"_COMPAT_0_7",1);
+ #else
+ PyModule_AddIntConstant(Module,"_COMPAT_0_7",0);
+ #endif
+ #if PY_MAJOR_VERSION >= 3
+ return Module;
+ #endif
}
/*}}}*/
diff --git a/python/apt_pkgmodule.h b/python/apt_pkgmodule.h
index e047bcd8..da647c3f 100644
--- a/python/apt_pkgmodule.h
+++ b/python/apt_pkgmodule.h
@@ -11,15 +11,24 @@
#define APT_PKGMODULE_H
#include <Python.h>
+#include <apt-pkg/hashes.h>
+#include <apt-pkg/acquire-item.h>
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/packagemanager.h>
+#include <apt-pkg/version.h>
+#include <apt-pkg/deblistparser.h>
+#include <apt-pkg/pkgcache.h>
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/tagfile.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/pkgsystem.h>
+#include <apt-pkg/cdrom.h>
+#include <apt-pkg/algorithms.h>
+#include "generic.h"
// Configuration Stuff
-#define Configuration_Check(op) ((op)->ob_type == &ConfigurationType || \
- (op)->ob_type == &ConfigurationPtrType || \
- (op)->ob_type == &ConfigurationSubType)
-extern PyTypeObject ConfigurationType;
-extern PyTypeObject ConfigurationPtrType;
-extern PyTypeObject ConfigurationSubType;
-extern PyTypeObject VersionType;
+extern PyTypeObject PyConfiguration_Type;
+extern PyTypeObject PyVersion_Type;
extern char *doc_LoadConfig;
extern char *doc_LoadConfigISC;
@@ -31,8 +40,8 @@ PyObject *LoadConfigDir(PyObject *Self,PyObject *Args);
PyObject *ParseCommandLine(PyObject *Self,PyObject *Args);
// Tag File Stuff
-extern PyTypeObject TagSecType;
-extern PyTypeObject TagFileType;
+extern PyTypeObject PyTagSection_Type;
+extern PyTypeObject PyTagFile_Type;
extern char *doc_ParseSection;
extern char *doc_ParseTagFile;
extern char *doc_RewriteSection;
@@ -52,54 +61,144 @@ PyObject *StrTimeRFC1123(PyObject *self,PyObject *Args);
PyObject *StrStrToTime(PyObject *self,PyObject *Args);
PyObject *StrCheckDomainList(PyObject *Self,PyObject *Args);
+PyObject *PyAcquire_GetItem(PyObject *self, pkgAcquire::Item *item);
+PyObject *PyAcquire_GetItemDesc(PyObject *self, pkgAcquire::ItemDesc *item);
+bool PyAcquire_DropItem(PyObject *self, pkgAcquire::Item *item);
+
// Cache Stuff
-extern PyTypeObject PkgCacheType;
-extern PyTypeObject PkgCacheFileType;
-extern PyTypeObject PkgListType;
-extern PyTypeObject PackageType;
-extern PyTypeObject PackageFileType;
-extern PyTypeObject DependencyType;
-extern PyTypeObject RDepListType;
+extern PyTypeObject PyCache_Type;
+extern PyTypeObject PyCacheFile_Type;
+extern PyTypeObject PyPackageList_Type;
+extern PyTypeObject PyDescription_Type;
+extern PyTypeObject PyPackage_Type;
+extern PyTypeObject PyPackageFile_Type;
+extern PyTypeObject PyDependency_Type;
+extern PyTypeObject PyDependencyList_Type;
PyObject *TmpGetCache(PyObject *Self,PyObject *Args);
// DepCache
-extern PyTypeObject PkgDepCacheType;
+extern PyTypeObject PyDepCache_Type;
PyObject *GetDepCache(PyObject *Self,PyObject *Args);
// pkgProblemResolver
-extern PyTypeObject PkgProblemResolverType;
+extern PyTypeObject PyProblemResolver_Type;
PyObject *GetPkgProblemResolver(PyObject *Self, PyObject *Args);
PyObject *GetPkgActionGroup(PyObject *Self, PyObject *Args);
+extern PyTypeObject PyActionGroup_Type;
// cdrom
-extern PyTypeObject PkgCdromType;
+extern PyTypeObject PyCdrom_Type;
PyObject *GetCdrom(PyObject *Self,PyObject *Args);
// acquire
-extern PyTypeObject PkgAcquireType;
+extern PyTypeObject PyAcquireItem_Type;
+extern PyTypeObject PyAcquire_Type;
+extern PyTypeObject PyAcquireFile_Type;
extern char *doc_GetPkgAcqFile;
PyObject *GetAcquire(PyObject *Self,PyObject *Args);
PyObject *GetPkgAcqFile(PyObject *Self, PyObject *Args, PyObject *kwds);
// packagemanager
-extern PyTypeObject PkgManagerType;
+extern PyTypeObject PyPackageManager_Type;
PyObject *GetPkgManager(PyObject *Self,PyObject *Args);
// PkgRecords Stuff
-extern PyTypeObject PkgRecordsType;
+extern PyTypeObject PyPackageRecords_Type;
+extern PyTypeObject PySourceRecords_Type;
PyObject *GetPkgRecords(PyObject *Self,PyObject *Args);
PyObject *GetPkgSrcRecords(PyObject *Self,PyObject *Args);
// pkgSourceList
-extern PyTypeObject PkgSourceListType;
+extern PyTypeObject PySourceList_Type;
PyObject *GetPkgSourceList(PyObject *Self,PyObject *Args);
// pkgSourceList
-extern PyTypeObject PackageIndexFileType;
+extern PyTypeObject PyIndexFile_Type;
// metaIndex
-extern PyTypeObject MetaIndexType;
-
-
+extern PyTypeObject PyMetaIndex_Type;
+
+// HashString
+extern PyTypeObject PyHashString_Type;
+
+// IndexRecord
+extern PyTypeObject PyIndexRecords_Type;
+
+// Policy
+extern PyTypeObject PyPolicy_Type;
+extern PyTypeObject PyHashes_Type;
+extern PyTypeObject PyAcquireItemDesc_Type;
+extern PyTypeObject PyAcquireWorker_Type;
+extern PyTypeObject PySystemLock_Type;
+extern PyTypeObject PyFileLock_Type;
+
+// Functions to be exported in the public API.
+
+# define PyAcquire_ToCpp GetCpp<pkgAcquire*>
+# define PyAcquireFile_ToCpp GetCpp<pkgAcqFile*>
+# define PyAcquireItem_ToCpp GetCpp<pkgAcquire::Item*>
+# define PyAcquireItemDesc_ToCpp GetCpp<pkgAcquire::ItemDesc*>
+# define PyAcquireWorker_ToCpp GetCpp<pkgAcquire::Worker*>
+# define PyActionGroup_ToCpp GetCpp<pkgDepCache::ActionGroup*>
+# define PyCache_ToCpp GetCpp<pkgCache*>
+# define PyCacheFile_ToCpp GetCpp<pkgCacheFile*>
+# define PyCdrom_ToCpp GetCpp<pkgCdrom>
+# define PyConfiguration_ToCpp GetCpp<Configuration*>
+# define PyDepCache_ToCpp GetCpp<pkgDepCache*>
+# define PyDependency_ToCpp GetCpp<pkgCache::DepIterator>
+# define PyDependencyList_ToCpp GetCpp<RDepListStruct> // TODO
+# define PyDescription_ToCpp GetCpp<pkgCache::DescIterator>
+# define PyHashes_ToCpp GetCpp<Hashes>
+# define PyHashString_ToCpp GetCpp<HashString*>
+# define PyIndexRecords_ToCpp GetCpp<indexRecords*>
+# define PyMetaIndex_ToCpp GetCpp<metaIndex*>
+# define PyPackage_ToCpp GetCpp<pkgCache::PkgIterator>
+# define PyPackageFile_ToCpp GetCpp<pkgCache::PkgFileIterator>
+# define PyIndexFile_ToCpp GetCpp<pkgIndexFile*>
+# define PyPackageList_ToCpp GetCpp<PkgListStruct> // TODO
+# define PyPackageManager_ToCpp GetCpp<pkgPackageManager*>
+# define PyPackageRecords_ToCpp GetCpp<PkgRecordsStruct> // TODO
+# define PyPolicy_ToCpp GetCpp<pkgPolicy*>
+# define PyProblemResolver_ToCpp GetCpp<pkgProblemResolver*>
+# define PySourceList_ToCpp GetCpp<pkgSourceList*>
+# define PySourceRecords_ToCpp GetCpp<PkgSrcRecordsStruct> // TODO
+# define PyTagFile_ToCpp GetCpp<pkgTagFile>
+# define PyTagSection_ToCpp GetCpp<pkgTagSection>
+# define PyVersion_ToCpp GetCpp<pkgCache::VerIterator>
+
+PyObject* PyAcquire_FromCpp(pkgAcquire *fetcher, bool Delete, PyObject *Owner);
+PyObject* PyAcquireFile_FromCpp(pkgAcqFile* const &obj, bool Delete, PyObject *Owner);
+PyObject* PyAcquireItem_FromCpp(pkgAcquire::Item* const &obj, bool Delete, PyObject *Owner);
+PyObject* PyAcquireItemDesc_FromCpp(pkgAcquire::ItemDesc* const &obj, bool Delete, PyObject *Owner);
+PyObject* PyAcquireWorker_FromCpp(pkgAcquire::Worker* const &obj, bool Delete, PyObject *Owner);
+PyObject* PyActionGroup_FromCpp(pkgDepCache::ActionGroup* const &obj, bool Delete, PyObject *Owner);
+PyObject* PyCache_FromCpp(pkgCache* const &obj, bool Delete, PyObject *Owner);
+PyObject* PyCacheFile_FromCpp(pkgCacheFile* const &obj, bool Delete, PyObject *Owner);
+PyObject* PyCdrom_FromCpp(pkgCdrom const &obj, bool Delete, PyObject *Owner);
+PyObject* PyConfiguration_FromCpp(Configuration* const &obj, bool Delete, PyObject *Owner);
+PyObject* PyDepCache_FromCpp(pkgDepCache* const &obj, bool Delete, PyObject *Owner);
+PyObject* PyDependency_FromCpp(pkgCache::DepIterator const &obj, bool Delete, PyObject *Owner);
+//PyObject* PyDependencyList_FromCpp(RDepListStruct const &obj, bool Delete, PyObject *Owner);
+PyObject* PyDescription_FromCpp(pkgCache::DescIterator const &obj, bool Delete, PyObject *Owner);
+PyObject* PyHashes_FromCpp(Hashes const &obj, bool Delete, PyObject *Owner);
+PyObject* PyHashString_FromCpp(HashString* const &obj, bool Delete, PyObject *Owner);
+PyObject* PyIndexRecords_FromCpp(indexRecords* const &obj, bool Delete, PyObject *Owner);
+PyObject* PyMetaIndex_FromCpp(metaIndex* const &obj, bool Delete, PyObject *Owner);
+PyObject* PyPackage_FromCpp(pkgCache::PkgIterator const &obj, bool Delete, PyObject *Owner);
+PyObject* PyIndexFile_FromCpp(pkgIndexFile* const &obj, bool Delete, PyObject *Owner);
+PyObject* PyPackageFile_FromCpp(pkgCache::PkgFileIterator const &obj, bool Delete, PyObject *Owner);
+//PyObject* PyPackageList_FromCpp(PkgListStruct const &obj, bool Delete, PyObject *Owner);
+PyObject* PyPackageManager_FromCpp(pkgPackageManager* const &obj, bool Delete, PyObject *Owner);
+//PyObject* PyPackageRecords_FromCpp(PkgRecordsStruct const &obj, bool Delete, PyObject *Owner);
+PyObject* PyPolicy_FromCpp(pkgPolicy* const &obj, bool Delete, PyObject *Owner);
+PyObject* PyProblemResolver_FromCpp(pkgProblemResolver* const &obj, bool Delete, PyObject *Owner);
+PyObject* PySourceList_FromCpp(pkgSourceList* const &obj, bool Delete, PyObject *Owner);
+//PyObject* PySourceRecords_FromCpp(PkgSrcRecordsStruct const &obj, bool Delete, PyObject *Owner);
+PyObject* PyTagFile_FromCpp(pkgTagFile const &obj, bool Delete, PyObject *Owner);
+PyObject* PyTagSection_FromCpp(pkgTagSection const &obj, bool Delete, PyObject *Owner);
+PyObject* PyVersion_FromCpp(pkgCache::VerIterator const &obj, bool Delete, PyObject *Owner);
+
+#include "python-apt.h"
#endif
+
diff --git a/python/arfile.cc b/python/arfile.cc
new file mode 100644
index 00000000..4f3b4ad7
--- /dev/null
+++ b/python/arfile.cc
@@ -0,0 +1,648 @@
+/*
+ * arfile.cc - Wrapper around ARArchive and ARArchive::Member.
+ *
+ * Copyright 2009 Julian Andres Klode <jak@debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <Python.h>
+#include "generic.h"
+#include "apt_instmodule.h"
+#include <apt-pkg/arfile.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/sptr.h>
+#include <utime.h>
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+static PyObject *armember_get_name(PyObject *self, void *closure)
+{
+ return CppPyString(GetCpp<ARArchive::Member*>(self)->Name);
+}
+
+static PyObject *armember_get_mtime(PyObject *self, void *closure)
+{
+ return Py_BuildValue("k", GetCpp<ARArchive::Member*>(self)->MTime);
+}
+
+static PyObject *armember_get_uid(PyObject *self, void *closure)
+{
+ return Py_BuildValue("k", GetCpp<ARArchive::Member*>(self)->UID);
+}
+
+static PyObject *armember_get_gid(PyObject *self, void *closure)
+{
+ return Py_BuildValue("k", GetCpp<ARArchive::Member*>(self)->GID);
+}
+
+static PyObject *armember_get_mode(PyObject *self, void *closure)
+{
+ return Py_BuildValue("k", GetCpp<ARArchive::Member*>(self)->Mode);
+}
+
+static PyObject *armember_get_size(PyObject *self, void *closure)
+{
+ return Py_BuildValue("k", GetCpp<ARArchive::Member*>(self)->Size);
+}
+
+static PyObject *armember_get_start(PyObject *self, void *closure)
+{
+ return Py_BuildValue("k", GetCpp<ARArchive::Member*>(self)->Start);
+}
+
+static PyObject *armember_repr(PyObject *self)
+{
+ return PyString_FromFormat("<%s object: name:'%s'>",
+ self->ob_type->tp_name,
+ GetCpp<ARArchive::Member*>(self)->Name.c_str());
+}
+
+static PyGetSetDef armember_getset[] = {
+ {"gid",armember_get_gid,0,"The group id of the owner."},
+ {"mode",armember_get_mode,0,"The mode of the file."},
+ {"mtime",armember_get_mtime,0,"Last time of modification."},
+ {"name",armember_get_name,0,"The name of the file."},
+ {"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."},
+ {NULL}
+};
+
+static const char *armember_doc =
+ "An ArMember object represents 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 = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_inst.ArMember", // tp_name
+ sizeof(CppPyObject<ARArchive::Member*>), // tp_basicsize
+ 0, // tp_itemsize
+ // Methods
+ CppDeallocPtr<ARArchive::Member*>, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ armember_repr, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_HAVE_GC,
+ armember_doc, // tp_doc
+ CppTraverse<ARArchive::Member*>,// tp_traverse
+ CppClear<ARArchive::Member*>, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ 0, // tp_methods
+ 0, // tp_members
+ armember_getset, // tp_getset
+};
+
+// We just add an inline method and should thus be ABI compatible in a way that
+// we can simply cast ARArchive instances to PyARArchiveHack.
+class PyARArchiveHack : public ARArchive
+{
+public:
+ inline Member *Members() {
+ return List;
+ }
+};
+
+struct PyArArchiveObject : public CppPyObject<PyARArchiveHack*> {
+ FileFd Fd;
+};
+
+static const char *ararchive_getmember_doc =
+ "getmember(name: str) -> ArMember\n\n"
+ "Return a 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)
+{
+ const char *name;
+ CppPyObject<ARArchive::Member*> *ret;
+ if (! (name = PyObject_AsString(arg)))
+ return 0;
+
+ const ARArchive::Member *member = self->Object->FindMember(name);
+ if (!member) {
+ PyErr_Format(PyExc_LookupError,"No member named '%s'",name);
+ return 0;
+ }
+
+ // Create our object.
+ ret = CppPyObject_NEW<ARArchive::Member*>(self,&PyArMember_Type);
+ ret->Object = const_cast<ARArchive::Member*>(member);
+ ret->NoDelete = true;
+ return ret;
+}
+
+static const char *ararchive_extractdata_doc =
+ "extractdata(name: str) -> bytes\n\n"
+ "Return the contents of the member, as a bytes object. Raise\n"
+ "LookupError if there is no ArMember with the given name.";
+static PyObject *ararchive_extractdata(PyArArchiveObject *self, PyObject *args)
+{
+ char *name = 0;
+ if (PyArg_ParseTuple(args, "s:extractdata", &name) == 0)
+ return 0;
+ const ARArchive::Member *member = self->Object->FindMember(name);
+ if (!member) {
+ PyErr_Format(PyExc_LookupError,"No member named '%s'",name);
+ return 0;
+ }
+ if (!self->Fd.Seek(member->Start))
+ return HandleErrors();
+
+ char* value = new char[member->Size];
+ self->Fd.Read(value, member->Size, true);
+ PyObject *result = PyBytes_FromStringAndSize(value, member->Size);
+ delete[] value;
+ return result;
+}
+
+// Helper class to close the FD automatically.
+class IntFD {
+ public:
+ int fd;
+ inline operator int() { return fd; };
+ inline IntFD(int fd): fd(fd) { };
+ inline ~IntFD() { close(fd); };
+};
+
+static PyObject *_extract(FileFd &Fd, const ARArchive::Member *member,
+ const char *dir)
+{
+ if (!Fd.Seek(member->Start))
+ return HandleErrors();
+
+ string outfile_str = flCombine(dir,member->Name);
+ char *outfile = (char*)outfile_str.c_str();
+
+ // We are not using FileFd here, because we want to raise OSErrror with
+ // the correct errno and filename. IntFD's are closed automatically.
+ IntFD outfd(open(outfile, O_NDELAY|O_WRONLY|O_CREAT|O_TRUNC|O_APPEND,
+ member->Mode));
+ if (outfd == -1)
+ return PyErr_SetFromErrnoWithFilename(PyExc_OSError, outfile);
+ if (fchmod(outfd, member->Mode) == -1)
+ return PyErr_SetFromErrnoWithFilename(PyExc_OSError, outfile);
+ if (fchown(outfd, member->UID, member->GID) != 0 && errno != EPERM)
+ return PyErr_SetFromErrnoWithFilename(PyExc_OSError, outfile);
+
+ // Read 4 KiB from the file, until all of the file is read. Deallocated
+ // automatically when the function returns.
+ SPtrArray<char> value = new char[4096];
+ unsigned long size = member->Size;
+ unsigned long read = 4096;
+ while (size > 0) {
+ if (size < read)
+ read = size;
+ if (!Fd.Read(value, read, true))
+ return HandleErrors();
+ if (write(outfd, value, read) != (signed)read)
+ return PyErr_SetFromErrnoWithFilename(PyExc_OSError, outfile);
+ size -= read;
+ }
+ utimbuf time = {member->MTime, member->MTime};
+ if (utime(outfile,&time) == -1)
+ return PyErr_SetFromErrnoWithFilename(PyExc_OSError, outfile);
+ Py_RETURN_TRUE;
+}
+
+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.";
+static PyObject *ararchive_extract(PyArArchiveObject *self, PyObject *args)
+{
+ char *name = 0;
+ char *target = "";
+ if (PyArg_ParseTuple(args, "s|s:extract", &name, &target) == 0)
+ return 0;
+
+ const ARArchive::Member *member = self->Object->FindMember(name);
+
+ if (!member) {
+ PyErr_Format(PyExc_LookupError,"No member named '%s'",name);
+ return 0;
+ }
+ return _extract(self->Fd, member, target);
+}
+
+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.";
+
+static PyObject *ararchive_extractall(PyArArchiveObject *self, PyObject *args)
+{
+ char *target = "";
+ if (PyArg_ParseTuple(args, "|s:extractall", &target) == 0)
+ return 0;
+
+ const ARArchive::Member *member = self->Object->Members();
+
+ do {
+ if (_extract(self->Fd, member, target) == 0)
+ return 0;
+ } while ((member = member->Next));
+ Py_RETURN_TRUE;
+}
+
+static const char *ararchive_gettar_doc =
+ "gettar(name: str, comp: str) -> TarFile\n\n"
+ "Return a TarFile object for the member given by 'name' which will be\n"
+ "decompressed using the compression algorithm given by 'comp'.\n"
+ "This is almost equal to:\n\n"
+ " member = arfile.getmember(name)\n"
+ " tarfile = TarFile(file, member.start, member.size, 'gzip')'\n\n"
+ "It just opens a new TarFile on the given position in the stream.";
+static PyObject *ararchive_gettar(PyArArchiveObject *self, PyObject *args)
+{
+ const char *name;
+ const char *comp;
+ if (PyArg_ParseTuple(args, "ss:gettar", &name, &comp) == 0)
+ return 0;
+
+ const ARArchive::Member *member = self->Object->FindMember(name);
+ if (!member) {
+ PyErr_Format(PyExc_LookupError,"No member named '%s'",name);
+ return 0;
+ }
+
+ PyTarFileObject *tarfile = (PyTarFileObject*)CppPyObject_NEW<ExtractTar*>(self,&PyTarFile_Type);
+ new (&tarfile->Fd) FileFd(self->Fd);
+ tarfile->min = member->Start;
+ tarfile->Object = new ExtractTar(self->Fd, member->Size, comp);
+ return HandleErrors(tarfile);
+}
+
+static const char *ararchive_getmembers_doc =
+ "getmembers() -> list\n\n"
+ "Return a list of all members in the AR archive.";
+static PyObject *ararchive_getmembers(PyArArchiveObject *self)
+{
+ PyObject *list = PyList_New(0);
+ ARArchive::Member *member = self->Object->Members();
+ do {
+ CppPyObject<ARArchive::Member*> *ret;
+ ret = CppPyObject_NEW<ARArchive::Member*>(self,&PyArMember_Type);
+ ret->Object = member;
+ ret->NoDelete = true;
+ PyList_Append(list, ret);
+ Py_DECREF(ret);
+ } while ((member = member->Next));
+ return list;
+}
+
+static const char *ararchive_getnames_doc =
+ "getnames() -> list\n\n"
+ "Return a list of the names of all members in the AR archive.";
+static PyObject *ararchive_getnames(PyArArchiveObject *self)
+{
+ PyObject *list = PyList_New(0);
+ ARArchive::Member *member = self->Object->Members();
+ do {
+ PyObject *item = CppPyString(member->Name);
+ PyList_Append(list, item);
+ Py_DECREF(item);
+ } while ((member = member->Next));
+ return list;
+}
+
+// Just run getmembers() and return an iterator over the list.
+static PyObject *ararchive_iter(PyArArchiveObject *self) {
+ PyObject *members = ararchive_getmembers(self);
+ PyObject *iter = PyObject_GetIter(members);
+ Py_DECREF(members);
+ return iter;
+}
+
+static PyMethodDef ararchive_methods[] = {
+ {"getmember",(PyCFunction)ararchive_getmember,METH_O,
+ ararchive_getmember_doc},
+ {"gettar",(PyCFunction)ararchive_gettar,METH_VARARGS,
+ ararchive_gettar_doc},
+ {"extractdata",(PyCFunction)ararchive_extractdata,METH_VARARGS,
+ ararchive_extractdata_doc},
+ {"extract",(PyCFunction)ararchive_extract,METH_VARARGS,
+ ararchive_extract_doc},
+ {"extractall",(PyCFunction)ararchive_extractall,METH_VARARGS,
+ ararchive_extractall_doc},
+ {"getmembers",(PyCFunction)ararchive_getmembers,METH_NOARGS,
+ ararchive_getmembers_doc},
+ {"getnames",(PyCFunction)ararchive_getnames,METH_NOARGS,
+ ararchive_getnames_doc},
+ {NULL}
+};
+
+static PyObject *ararchive_new(PyTypeObject *type, PyObject *args,
+ PyObject *kwds)
+{
+ PyObject *file;
+ PyArArchiveObject *self;
+ char *filename = 0;
+ int fileno;
+ if (PyArg_ParseTuple(args,"O:__new__",&file) == 0)
+ return 0;
+
+ // We receive a filename.
+ if ((filename = (char*)PyObject_AsString(file))) {
+ self = (PyArArchiveObject *)CppPyObject_NEW<ARArchive*>(0,type);
+ new (&self->Fd) FileFd(filename,FileFd::ReadOnly);
+ }
+ // We receive a file object.
+ else if ((fileno = PyObject_AsFileDescriptor(file)) != -1) {
+ // Clear the error set by PyObject_AsString().
+ PyErr_Clear();
+ self = (PyArArchiveObject *)CppPyObject_NEW<ARArchive*>(file,type);
+ new (&self->Fd) FileFd(fileno,false);
+ }
+ else {
+ return 0;
+ }
+ self->Object = (PyARArchiveHack*)new ARArchive(self->Fd);
+ if (_error->PendingError() == true)
+ return HandleErrors();
+ return self;
+}
+
+static void ararchive_dealloc(PyObject *self)
+{
+ ((PyArArchiveObject *)(self))->Fd.~FileFd();
+ CppDeallocPtr<ARArchive*>(self);
+}
+
+// Return bool or -1 (exception).
+static int ararchive_contains(PyObject *self, PyObject *arg)
+{
+ const char *name = PyObject_AsString(arg);
+ if (!name)
+ return -1;
+ return (GetCpp<ARArchive*>(self)->FindMember(name) != 0);
+}
+
+static PySequenceMethods ararchive_as_sequence = {
+ 0,0,0,0,0,0,0,ararchive_contains,0,0
+};
+
+static PyMappingMethods ararchive_as_mapping = {
+ 0,(PyCFunction)ararchive_getmember,0
+};
+
+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"
+ "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.";
+
+PyTypeObject PyArArchive_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_inst.ArArchive", // tp_name
+ sizeof(PyArArchiveObject), // tp_basicsize
+ 0, // tp_itemsize
+ // Methods
+ ararchive_dealloc, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ &ararchive_as_sequence, // tp_as_sequence
+ &ararchive_as_mapping, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_HAVE_GC,
+ ararchive_doc, // tp_doc
+ CppTraverse<ARArchive*>, // tp_traverse
+ CppClear<ARArchive*>, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ (getiterfunc)ararchive_iter, // tp_iter
+ 0, // tp_iternext
+ ararchive_methods, // tp_methods
+ 0, // tp_members
+ 0, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ 0, // tp_alloc
+ ararchive_new // tp_new
+};
+
+/**
+ * Representation of a Debian package.
+ *
+ * This does not resemble debDebFile in apt-inst, but instead is a subclass
+ * of ArFile which adds properties for the control.tar.{lzma,bz2,gz} and
+ * data.tar.{lzma,bz2,gz} members which return TarFile objects. It also adds
+ * a descriptor 'version' which returns the content of 'debian-binary'.
+ *
+ * We are using it this way as it seems more natural to represent this special
+ * kind of AR archive as an AR archive with some extras.
+ */
+struct PyDebFileObject : PyArArchiveObject {
+ PyObject *data;
+ PyObject *control;
+ PyObject *debian_binary;
+};
+
+static PyObject *debfile_get_data(PyDebFileObject *self)
+{
+ return Py_INCREF(self->data), self->data;
+}
+
+static PyObject *debfile_get_control(PyDebFileObject *self)
+{
+ return Py_INCREF(self->control), self->control;
+}
+
+static PyObject *debfile_get_debian_binary(PyDebFileObject *self)
+{
+ return Py_INCREF(self->debian_binary), self->debian_binary;
+}
+
+static PyObject *_gettar(PyDebFileObject *self, const ARArchive::Member *m,
+ const char *comp)
+{
+ if (!m)
+ return 0;
+ PyTarFileObject *tarfile = (PyTarFileObject*)CppPyObject_NEW<ExtractTar*>(self,&PyTarFile_Type);
+ new (&tarfile->Fd) FileFd(self->Fd);
+ tarfile->min = m->Start;
+ tarfile->Object = new ExtractTar(self->Fd, m->Size, comp);
+ return tarfile;
+}
+
+
+
+static PyObject *debfile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyDebFileObject *self = (PyDebFileObject*)ararchive_new(type, args, kwds);
+ if (self == NULL)
+ return NULL;
+
+ // DebFile
+ self->control = _gettar(self, self->Object->FindMember("control.tar.gz"),
+ "gzip");
+ if (!self->control)
+ return PyErr_Format(PyExc_SystemError, "No debian archive, missing %s",
+ "control.tar.gz");
+
+ self->data = _gettar(self, self->Object->FindMember("data.tar.gz"),
+ "gzip");
+ if (!self->data)
+ self->data = _gettar(self, self->Object->FindMember("data.tar.bz2"),
+ "bzip2");
+ if (!self->data)
+ self->data = _gettar(self, self->Object->FindMember("data.tar.lzma"),
+ "lzma");
+ if (!self->data)
+ return PyErr_Format(PyExc_SystemError, "No debian archive, missing %s",
+ "data.tar.gz or data.tar.bz2 or data.tar.lzma");
+
+
+ const ARArchive::Member *member = self->Object->FindMember("debian-binary");
+ if (!member)
+ return PyErr_Format(PyExc_SystemError, "No debian archive, missing %s",
+ "debian-binary");
+
+ if (!self->Fd.Seek(member->Start))
+ return HandleErrors();
+
+ char* value = new char[member->Size];
+ self->Fd.Read(value, member->Size, true);
+ self->debian_binary = PyBytes_FromStringAndSize(value, member->Size);
+ delete[] value;
+ return self;
+}
+
+static int debfile_traverse(PyObject *_self, visitproc visit, void* arg)
+{
+ PyDebFileObject *self = (PyDebFileObject*)_self;
+ Py_VISIT(self->data);
+ Py_VISIT(self->control);
+ Py_VISIT(self->debian_binary);
+ return PyArArchive_Type.tp_traverse(self, visit, arg);
+}
+
+static int debfile_clear(PyObject *_self) {
+ PyDebFileObject *self = (PyDebFileObject*)_self;
+ Py_CLEAR(self->data);
+ Py_CLEAR(self->control);
+ Py_CLEAR(self->debian_binary);
+ return PyArArchive_Type.tp_clear(self);
+}
+
+static void debfile_dealloc(PyObject *self) {
+ debfile_clear((PyDebFileObject *)self);
+ PyArArchive_Type.tp_dealloc(self);
+}
+
+static PyGetSetDef debfile_getset[] = {
+ {"control",(getter)debfile_get_control,0,
+ "The TarFile object associated with the control.tar.gz member."},
+ {"data",(getter)debfile_get_data,0,
+ "The TarFile object associated with the data.tar.{gz,bz2,lzma} member."},
+ {"debian_binary",(getter)debfile_get_debian_binary,0,
+ "The package version, as contained in debian-binary."},
+ {NULL}
+};
+
+static const char *debfile_doc =
+ "DebFile(file: str/int/file)\n\n"
+ "A DebFile object represents a file in the .deb package format.\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.\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.";
+
+PyTypeObject PyDebFile_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_inst.DebFile", // tp_name
+ sizeof(PyDebFileObject), // tp_basicsize
+ 0, // tp_itemsize
+ // Methods
+ debfile_dealloc, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_HAVE_GC,
+ debfile_doc, // tp_doc
+ debfile_traverse, // tp_traverse
+ debfile_clear, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ 0, // tp_methods
+ 0, // tp_members
+ debfile_getset, // tp_getset
+ &PyArArchive_Type, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ 0, // tp_alloc
+ debfile_new // tp_new
+};
diff --git a/python/cache.cc b/python/cache.cc
index 023cf041..3c9bc785 100644
--- a/python/cache.cc
+++ b/python/cache.cc
@@ -73,7 +73,7 @@ static PyObject *CreateProvides(PyObject *Owner,pkgCache::PrvIterator I)
{
PyObject *Obj;
PyObject *Ver;
- Ver = CppOwnedPyObject_NEW<pkgCache::VerIterator>(Owner,&VersionType,
+ Ver = CppPyObject_NEW<pkgCache::VerIterator>(Owner,&PyVersion_Type,
I.OwnerVer());
Obj = Py_BuildValue("ssN",I.ParentPkg().Name(),I.ProvideVersion(),
Ver);
@@ -87,9 +87,6 @@ static PyObject *CreateProvides(PyObject *Owner,pkgCache::PrvIterator I)
// ---------------------------------------------------------------------
static PyObject *PkgCacheUpdate(PyObject *Self,PyObject *Args)
{
- PyObject *CacheFilePy = GetOwner<pkgCache*>(Self);
- pkgCacheFile *Cache = GetCpp<pkgCacheFile*>(CacheFilePy);
-
PyObject *pyFetchProgressInst = 0;
PyObject *pySourcesList = 0;
int pulseInterval = 0;
@@ -105,8 +102,11 @@ static PyObject *PkgCacheUpdate(PyObject *Self,PyObject *Args)
return HandleErrors(PyRes);
}
+#ifdef COMPAT_0_7
static PyObject *PkgCacheClose(PyObject *Self,PyObject *Args)
{
+ PyErr_WarnEx(PyExc_DeprecationWarning, "Cache.Close() is deprecated, "
+ "because it causes segfaults. Delete the Cache instead.", 1);
PyObject *CacheFilePy = GetOwner<pkgCache*>(Self);
pkgCacheFile *Cache = GetCpp<pkgCacheFile*>(CacheFilePy);
Cache->Close();
@@ -117,6 +117,9 @@ static PyObject *PkgCacheClose(PyObject *Self,PyObject *Args)
static PyObject *PkgCacheOpen(PyObject *Self,PyObject *Args)
{
+ PyErr_WarnEx(PyExc_DeprecationWarning, "Cache.Open() is deprecated, "
+ "because it causes memory leaks. Create a new Cache instead.",
+ 1);
PyObject *CacheFilePy = GetOwner<pkgCache*>(Self);
pkgCacheFile *Cache = GetCpp<pkgCacheFile*>(CacheFilePy);
@@ -144,63 +147,91 @@ static PyObject *PkgCacheOpen(PyObject *Self,PyObject *Args)
Py_INCREF(Py_None);
return HandleErrors(Py_None);
}
-
+#endif
static PyMethodDef PkgCacheMethods[] =
{
- {"Update",PkgCacheUpdate,METH_VARARGS,"Update the cache"},
+ {"update",PkgCacheUpdate,METH_VARARGS,"Update the cache"},
+#ifdef COMPAT_0_7
{"Open", PkgCacheOpen, METH_VARARGS,"Open the cache"},
{"Close", PkgCacheClose, METH_VARARGS,"Close the cache"},
+#endif
{}
};
-static PyObject *CacheAttr(PyObject *Self,char *Name)
-{
+static PyObject *PkgCacheGetPackages(PyObject *Self, void*) {
+ pkgCache *Cache = GetCpp<pkgCache *>(Self);
+ return CppPyObject_NEW<PkgListStruct>(Self,&PyPackageList_Type,Cache->PkgBegin());
+}
+
+static PyObject *PkgCacheGetPackageCount(PyObject *Self, void*) {
pkgCache *Cache = GetCpp<pkgCache *>(Self);
+ return Py_BuildValue("i",Cache->HeaderP->PackageCount);
+}
+
+static PyObject *PkgCacheGetVersionCount(PyObject *Self, void*) {
+ pkgCache *Cache = GetCpp<pkgCache *>(Self);
+ return Py_BuildValue("i",Cache->HeaderP->VersionCount);
+}
+static PyObject *PkgCacheGetDependsCount(PyObject *Self, void*) {
+ pkgCache *Cache = GetCpp<pkgCache *>(Self);
+ return Py_BuildValue("i",Cache->HeaderP->DependsCount);
+}
- if (strcmp("Packages",Name) == 0)
- return CppOwnedPyObject_NEW<PkgListStruct>(Self,&PkgListType,Cache->PkgBegin());
- else if (strcmp("PackageCount",Name) == 0)
- return Py_BuildValue("i",Cache->HeaderP->PackageCount);
- else if (strcmp("VersionCount",Name) == 0)
- return Py_BuildValue("i",Cache->HeaderP->VersionCount);
- else if (strcmp("DependsCount",Name) == 0)
- return Py_BuildValue("i",Cache->HeaderP->DependsCount);
- else if (strcmp("PackageFileCount",Name) == 0)
- return Py_BuildValue("i",Cache->HeaderP->PackageFileCount);
- else if (strcmp("VerFileCount",Name) == 0)
- return Py_BuildValue("i",Cache->HeaderP->VerFileCount);
- else if (strcmp("ProvidesCount",Name) == 0)
- return Py_BuildValue("i",Cache->HeaderP->ProvidesCount);
- else if (strcmp("FileList",Name) == 0)
+static PyObject *PkgCacheGetPackageFileCount(PyObject *Self, void*) {
+ pkgCache *Cache = GetCpp<pkgCache *>(Self);
+ return Py_BuildValue("i",Cache->HeaderP->PackageFileCount);
+}
+
+static PyObject *PkgCacheGetVerFileCount(PyObject *Self, void*) {
+ pkgCache *Cache = GetCpp<pkgCache *>(Self);
+ return Py_BuildValue("i",Cache->HeaderP->VerFileCount);
+}
+
+static PyObject *PkgCacheGetProvidesCount(PyObject *Self, void*) {
+ pkgCache *Cache = GetCpp<pkgCache *>(Self);
+ return Py_BuildValue("i",Cache->HeaderP->ProvidesCount);
+}
+
+static PyObject *PkgCacheGetFileList(PyObject *Self, void*) {
+ pkgCache *Cache = GetCpp<pkgCache *>(Self);
+ PyObject *List = PyList_New(0);
+ for (pkgCache::PkgFileIterator I = Cache->FileBegin(); I.end() == false; I++)
{
- PyObject *List = PyList_New(0);
- for (pkgCache::PkgFileIterator I = Cache->FileBegin(); I.end() == false; I++)
- {
- PyObject *Obj;
- Obj = CppOwnedPyObject_NEW<pkgCache::PkgFileIterator>(Self,&PackageFileType,I);
- PyList_Append(List,Obj);
- Py_DECREF(Obj);
- }
- return List;
+ PyObject *Obj;
+ Obj = CppPyObject_NEW<pkgCache::PkgFileIterator>(Self,&PyPackageFile_Type,I);
+ PyList_Append(List,Obj);
+ Py_DECREF(Obj);
}
-
- return Py_FindMethod(PkgCacheMethods,Self,Name);
+ return List;
}
+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},
+ {}
+};
+
+
+
// Map access, operator []
static PyObject *CacheMapOp(PyObject *Self,PyObject *Arg)
{
pkgCache *Cache = GetCpp<pkgCache *>(Self);
- if (PyString_Check(Arg) == 0)
- {
- PyErr_SetNone(PyExc_TypeError);
+ // Get the name of the package, unicode and normal strings.
+ const char *Name = PyObject_AsString(Arg);
+ if (Name == NULL)
return 0;
- }
+
// Search for the package
- const char *Name = PyString_AsString(Arg);
pkgCache::PkgIterator Pkg = Cache->FindPkg(Name);
if (Pkg.end() == true)
{
@@ -208,52 +239,141 @@ static PyObject *CacheMapOp(PyObject *Self,PyObject *Arg)
return 0;
}
- return CppOwnedPyObject_NEW<pkgCache::PkgIterator>(Self,&PackageType,Pkg);
+ return CppPyObject_NEW<pkgCache::PkgIterator>(Self,&PyPackage_Type,Pkg);
}
-// we need a special dealloc here to make sure that the CacheFile
-// is closed before deallocation the cache (otherwise we have a bad)
-// memory leak
-void PkgCacheFileDealloc(PyObject *Self)
+// Check whether the cache contains a package with a given name.
+static int CacheContains(PyObject *Self,PyObject *Arg)
{
- PyObject *CacheFilePy = GetOwner<pkgCache*>(Self);
- pkgCacheFile *CacheF = GetCpp<pkgCacheFile*>(CacheFilePy);
- CacheF->Close();
- CppOwnedDealloc<pkgCache *>(Self);
+ // Get the name of the package, unicode and normal strings.
+ const char *Name = PyObject_AsString(Arg);
+ if (Name == NULL)
+ return 0;
+ return (GetCpp<pkgCache *>(Self)->FindPkg(Name).end() == false);
}
-static PyMappingMethods CacheMap = {0,CacheMapOp,0};
-PyTypeObject PkgCacheType =
+static PyObject *PkgCacheNew(PyTypeObject *type,PyObject *Args,PyObject *kwds)
{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "pkgCache", // tp_name
- sizeof(CppOwnedPyObject<pkgCache *>), // tp_basicsize
+ PyObject *pyCallbackInst = 0;
+ char *kwlist[] = {"progress", 0};
+
+ if (PyArg_ParseTupleAndKeywords(Args, kwds, "|O", kwlist,
+ &pyCallbackInst) == 0)
+ return 0;
+
+ if (_system == 0) {
+ PyErr_SetString(PyExc_ValueError,"_system not initialized");
+ return 0;
+ }
+
+ pkgCacheFile *Cache = new pkgCacheFile();
+
+ if(pyCallbackInst != 0) {
+ // sanity check for the progress object, see #497049
+ if (PyObject_HasAttrString(pyCallbackInst, "done") != true) {
+ PyErr_SetString(PyExc_ValueError,
+ "OpProgress object must implement done()");
+ return 0;
+ }
+ if (PyObject_HasAttrString(pyCallbackInst, "update") != true) {
+ PyErr_SetString(PyExc_ValueError,
+ "OpProgress object must implement update()");
+ return 0;
+ }
+ PyOpProgress progress;
+ progress.setCallbackInst(pyCallbackInst);
+ if (Cache->Open(progress,false) == false)
+ return HandleErrors();
+ }
+ else {
+ OpTextProgress Prog;
+ if (Cache->Open(Prog,false) == false)
+ return HandleErrors();
+ }
+
+ CppPyObject<pkgCacheFile*> *CacheFileObj =
+ CppPyObject_NEW<pkgCacheFile*>(0,&PyCacheFile_Type, Cache);
+
+ CppPyObject<pkgCache *> *CacheObj =
+ CppPyObject_NEW<pkgCache *>(CacheFileObj,type,
+ (pkgCache *)(*Cache));
+
+ // Do not delete the pointer to the pkgCache, it is managed by pkgCacheFile.
+ CacheObj->NoDelete = true;
+ Py_DECREF(CacheFileObj);
+ return CacheObj;
+}
+
+static Py_ssize_t CacheMapLen(PyObject *Self)
+{
+ return GetCpp<pkgCache*>(Self)->HeaderP->PackageCount;
+}
+
+static char *doc_PkgCache = "Cache([progress]) -> Cache() object.\n\n"
+ "The cache provides access to the packages and other stuff.\n\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.";
+static PySequenceMethods CacheSeq = {0,0,0,0,0,0,0,CacheContains,0,0};
+static PyMappingMethods CacheMap = {CacheMapLen,CacheMapOp,0};
+PyTypeObject PyCache_Type =
+{
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.Cache", // tp_name
+ sizeof(CppPyObject<pkgCache *>), // tp_basicsize
0, // tp_itemsize
// Methods
- PkgCacheFileDealloc, // tp_dealloc
+ CppDeallocPtr<pkgCache *>, // tp_dealloc
0, // tp_print
- CacheAttr, // tp_getattr
+ 0, // tp_getattr
0, // tp_setattr
0, // tp_compare
0, // tp_repr
0, // tp_as_number
- 0, // tp_as_sequence
+ &CacheSeq, // tp_as_sequence
&CacheMap, // tp_as_mapping
0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ _PyAptObject_getattro, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ (Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_HAVE_GC),
+ doc_PkgCache, // tp_doc
+ CppTraverse<pkgCache *>, // tp_traverse
+ CppClear<pkgCache *>, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ PkgCacheMethods, // tp_methods
+ 0, // tp_members
+ PkgCacheGetSet, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ 0, // tp_alloc
+ PkgCacheNew, // tp_new
};
/*}}}*/
// PkgCacheFile Class /*{{{*/
// ---------------------------------------------------------------------
-PyTypeObject PkgCacheFileType =
+PyTypeObject PyCacheFile_Type =
{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
"pkgCacheFile", // tp_name
- sizeof(CppOwnedPyObject<pkgCacheFile*>), // tp_basicsize
+ sizeof(CppPyObject<pkgCacheFile*>), // tp_basicsize
0, // tp_itemsize
// Methods
- CppOwnedDealloc<pkgCacheFile*>, // tp_dealloc
+ CppDeallocPtr<pkgCacheFile*>, // tp_dealloc
0, // tp_print
0, // tp_getattr
0, // tp_setattr
@@ -263,6 +383,12 @@ PyTypeObject PkgCacheFileType =
0, // tp_as_sequence
0, // tp_as_mapping
0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT, // tp_flags
};
/*}}}*/
// Package List Class /*{{{*/
@@ -298,7 +424,7 @@ static PyObject *PkgListItem(PyObject *iSelf,Py_ssize_t Index)
}
}
- return CppOwnedPyObject_NEW<pkgCache::PkgIterator>(GetOwner<PkgListStruct>(iSelf),&PackageType,
+ return CppPyObject_NEW<pkgCache::PkgIterator>(GetOwner<PkgListStruct>(iSelf),&PyPackage_Type,
Self.Iter);
}
@@ -313,15 +439,14 @@ static PySequenceMethods PkgListSeq =
0 // assign slice
};
-PyTypeObject PkgListType =
+PyTypeObject PyPackageList_Type =
{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "pkgCache::PkgIterator", // tp_name
- sizeof(CppOwnedPyObject<PkgListStruct>), // tp_basicsize
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.PackageList", // tp_name
+ sizeof(CppPyObject<PkgListStruct>), // tp_basicsize
0, // tp_itemsize
// Methods
- CppOwnedDealloc<PkgListStruct>, // tp_dealloc
+ CppDealloc<PkgListStruct>, // tp_dealloc
0, // tp_print
0, // tp_getattr
0, // tp_setattr
@@ -331,89 +456,105 @@ PyTypeObject PkgListType =
&PkgListSeq, // tp_as_sequence
0, // tp_as_mapping
0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags
+ 0, // tp_doc
+ CppTraverse<PkgListStruct>, // tp_traverse
+ CppClear<PkgListStruct>, // tp_clear
};
- /*}}}*/
-// Package Class /*{{{*/
-// ---------------------------------------------------------------------
-static PyObject *PackageAttr(PyObject *Self,char *Name)
+#define Owner (GetOwner<pkgCache::PkgIterator>(Self))
+#define MkGet(PyFunc,Ret) static PyObject *PyFunc(PyObject *Self,void*) \
+{ \
+ pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(Self); \
+ return Ret; \
+}
+
+MkGet(PackageGetName,PyString_FromString(Pkg.Name()))
+MkGet(PackageGetSection,Safe_FromString(Pkg.Section()))
+MkGet(PackageGetRevDependsList,CppPyObject_NEW<RDepListStruct>(Owner,
+ &PyDependencyList_Type, Pkg.RevDependsList()))
+MkGet(PackageGetProvidesList,CreateProvides(Owner,Pkg.ProvidesList()))
+MkGet(PackageGetSelectedState,Py_BuildValue("i",Pkg->SelectedState))
+MkGet(PackageGetInstState,Py_BuildValue("i",Pkg->InstState))
+MkGet(PackageGetCurrentState,Py_BuildValue("i",Pkg->CurrentState))
+MkGet(PackageGetID,Py_BuildValue("i",Pkg->ID))
+#
+MkGet(PackageGetAuto,Py_BuildValue("i",(Pkg->Flags & pkgCache::Flag::Auto) != 0))
+MkGet(PackageGetEssential,Py_BuildValue("i",(Pkg->Flags & pkgCache::Flag::Essential) != 0))
+MkGet(PackageGetImportant,Py_BuildValue("i",(Pkg->Flags & pkgCache::Flag::Important) != 0))
+#undef MkGet
+#undef Owner
+
+static PyObject *PackageGetVersionList(PyObject *Self,void*)
{
pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(Self);
PyObject *Owner = GetOwner<pkgCache::PkgIterator>(Self);
- if (strcmp("Name",Name) == 0)
- return PyString_FromString(Pkg.Name());
- else if (strcmp("VersionList",Name) == 0)
+ PyObject *List = PyList_New(0);
+ for (pkgCache::VerIterator I = Pkg.VersionList(); I.end() == false; I++)
{
- PyObject *List = PyList_New(0);
- for (pkgCache::VerIterator I = Pkg.VersionList(); I.end() == false; I++)
- {
- PyObject *Obj;
- Obj = CppOwnedPyObject_NEW<pkgCache::VerIterator>(Owner,&VersionType,I);
- PyList_Append(List,Obj);
- Py_DECREF(Obj);
- }
- return List;
+ PyObject *Obj;
+ Obj = CppPyObject_NEW<pkgCache::VerIterator>(Owner,&PyVersion_Type,I);
+ PyList_Append(List,Obj);
+ Py_DECREF(Obj);
}
- else if (strcmp("CurrentVer",Name) == 0)
+ return List;
+}
+static PyObject *PackageGetCurrentVer(PyObject *Self,void*)
+{
+ pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(Self);
+ PyObject *Owner = GetOwner<pkgCache::PkgIterator>(Self);
+ if (Pkg->CurrentVer == 0)
{
- if (Pkg->CurrentVer == 0)
- {
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- return CppOwnedPyObject_NEW<pkgCache::VerIterator>(Owner,&VersionType,
- Pkg.CurrentVer());
+ Py_INCREF(Py_None);
+ return Py_None;
}
- else if (strcmp("Section",Name) == 0)
- return Safe_FromString(Pkg.Section());
- else if (strcmp("RevDependsList",Name) == 0)
- return CppOwnedPyObject_NEW<RDepListStruct>(Owner,&RDepListType,
- Pkg.RevDependsList());
- else if (strcmp("ProvidesList",Name) == 0)
- return CreateProvides(Owner,Pkg.ProvidesList());
- else if (strcmp("SelectedState",Name) == 0)
- return Py_BuildValue("i",Pkg->SelectedState);
- else if (strcmp("InstState",Name) == 0)
- return Py_BuildValue("i",Pkg->InstState);
- else if (strcmp("CurrentState",Name) == 0)
- return Py_BuildValue("i",Pkg->CurrentState);
- else if (strcmp("ID",Name) == 0)
- return Py_BuildValue("i",Pkg->ID);
- else if (strcmp("Auto",Name) == 0)
- return Py_BuildValue("i",(Pkg->Flags & pkgCache::Flag::Auto) != 0);
- else if (strcmp("Essential",Name) == 0)
- return Py_BuildValue("i",(Pkg->Flags & pkgCache::Flag::Essential) != 0);
- else if (strcmp("Important",Name) == 0)
- return Py_BuildValue("i",(Pkg->Flags & pkgCache::Flag::Important) != 0);
-
- PyErr_SetString(PyExc_AttributeError,Name);
- return 0;
+ return CppPyObject_NEW<pkgCache::VerIterator>(Owner,&PyVersion_Type,
+ Pkg.CurrentVer());
}
+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},
+ {}
+};
+
static PyObject *PackageRepr(PyObject *Self)
{
pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(Self);
- char S[300];
- snprintf(S,sizeof(S),"<pkgCache::Package object: Name:'%s' Section: '%s'"
- " ID:%u Flags:0x%lX>",
- Pkg.Name(),Pkg.Section(),Pkg->ID,Pkg->Flags);
- return PyString_FromString(S);
+ return PyString_FromFormat("<%s object: name:'%s' section: "
+ "'%s' id:%u>", Self->ob_type->tp_name,
+ Pkg.Name(), (Pkg.Section() ? Pkg.Section() : ""),
+ Pkg->ID);
}
-PyTypeObject PackageType =
+PyTypeObject PyPackage_Type =
{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "pkgCache::Package", // tp_name
- sizeof(CppOwnedPyObject<pkgCache::PkgIterator>), // tp_basicsize
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.Package", // tp_name
+ sizeof(CppPyObject<pkgCache::PkgIterator>), // tp_basicsize
0, // tp_itemsize
// Methods
- CppOwnedDealloc<pkgCache::PkgIterator>, // tp_dealloc
+ CppDealloc<pkgCache::PkgIterator>, // tp_dealloc
0, // tp_print
- PackageAttr, // tp_getattr
+ 0, // tp_getattr
0, // tp_setattr
0, // tp_compare
PackageRepr, // tp_repr
@@ -421,62 +562,80 @@ PyTypeObject PackageType =
0, // tp_as_sequence
0, // tp_as_mapping
0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ _PyAptObject_getattro, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags
+ "Package Object", // tp_doc
+ CppTraverse<pkgCache::PkgIterator>, // tp_traverse
+ CppClear<pkgCache::PkgIterator>,// tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ 0, // tp_methods
+ 0, // tp_members
+ PackageGetSet, // tp_getset
};
- /*}}}*/
-// Description Class /*{{{*/
-// ---------------------------------------------------------------------
-static PyObject *DescriptionAttr(PyObject *Self,char *Name)
+
+#define Description_MkGet(PyFunc,Ret) static PyObject \
+ *PyFunc(PyObject *Self,void*) { \
+ pkgCache::DescIterator &Desc = GetCpp<pkgCache::DescIterator>(Self); \
+ return Ret; }
+
+Description_MkGet(DescriptionGetLanguageCode,
+ PyString_FromString(Desc.LanguageCode()))
+Description_MkGet(DescriptionGetMd5,Safe_FromString(Desc.md5()))
+#undef Description_MkGet
+
+static PyObject *DescriptionGetFileList(PyObject *Self,void*)
{
pkgCache::DescIterator &Desc = GetCpp<pkgCache::DescIterator>(Self);
PyObject *Owner = GetOwner<pkgCache::DescIterator>(Self);
- if (strcmp("LanguageCode",Name) == 0)
- return PyString_FromString(Desc.LanguageCode());
- else if (strcmp("md5",Name) == 0)
- return Safe_FromString(Desc.md5());
- else if (strcmp("FileList",Name) == 0)
+ /* The second value in the tuple is the index of the VF item. If the
+ user wants to request a lookup then that number will be used.
+ Maybe later it can become an object. */
+ PyObject *List = PyList_New(0);
+ for (pkgCache::DescFileIterator I = Desc.FileList(); I.end() == false; I++)
{
- /* The second value in the tuple is the index of the VF item. If the
- user wants to request a lookup then that number will be used.
- Maybe later it can become an object. */
- PyObject *List = PyList_New(0);
- for (pkgCache::DescFileIterator I = Desc.FileList(); I.end() == false; I++)
- {
- PyObject *DescFile;
- PyObject *Obj;
- DescFile = CppOwnedPyObject_NEW<pkgCache::PkgFileIterator>(Owner,&PackageFileType,I.File());
- Obj = Py_BuildValue("Nl",DescFile,I.Index());
- PyList_Append(List,Obj);
- Py_DECREF(Obj);
- }
- return List;
+ PyObject *DescFile;
+ PyObject *Obj;
+ DescFile = CppPyObject_NEW<pkgCache::PkgFileIterator>(Owner,&PyPackageFile_Type,I.File());
+ Obj = Py_BuildValue("Nl",DescFile,I.Index());
+ PyList_Append(List,Obj);
+ Py_DECREF(Obj);
}
- PyErr_SetString(PyExc_AttributeError,Name);
- return 0;
+ return List;
}
+static PyGetSetDef DescriptionGetSet[] = {
+ {"language_code",DescriptionGetLanguageCode},
+ {"md5",DescriptionGetMd5},
+ {"file_list",DescriptionGetFileList},
+ {}
+};
+
static PyObject *DescriptionRepr(PyObject *Self)
{
pkgCache::DescIterator &Desc = GetCpp<pkgCache::DescIterator>(Self);
-
- char S[300];
- snprintf(S,sizeof(S),
- "<pkgCache::Description object: language_code:'%s' md5:'%s' ",
- Desc.LanguageCode(), Desc.md5());
- return PyString_FromString(S);
+ return PyString_FromFormat("<%s object: language_code:'%s' md5:'%s' ",
+ Self->ob_type->tp_name, Desc.LanguageCode(),
+ Desc.md5());
}
-PyTypeObject DescriptionType =
+PyTypeObject PyDescription_Type =
{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "pkgCache::DescIterator", // tp_name
- sizeof(CppOwnedPyObject<pkgCache::DescIterator>), // tp_basicsize
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.Description", // tp_name
+ sizeof(CppPyObject<pkgCache::DescIterator>), // tp_basicsize
0, // tp_itemsize
// Methods
- CppOwnedDealloc<pkgCache::DescIterator>, // tp_dealloc
+ CppDealloc<pkgCache::DescIterator>, // tp_dealloc
0, // tp_print
- DescriptionAttr, // tp_getattr
+ 0, // tp_getattr
0, // tp_setattr
0, // tp_compare
DescriptionRepr, // tp_repr
@@ -484,6 +643,22 @@ PyTypeObject DescriptionType =
0, // tp_as_sequence
0, // tp_as_mapping
0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ _PyAptObject_getattro, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags
+ "apt_pkg.Description Object", // tp_doc
+ CppTraverse<pkgCache::DescIterator>, // tp_traverse
+ CppClear<pkgCache::DescIterator>,// tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ 0, // tp_methods
+ 0, // tp_members
+ DescriptionGetSet, // tp_getset
};
/*}}}*/
// Version Class /*{{{*/
@@ -523,7 +698,7 @@ static PyObject *MakeDepends(PyObject *Owner,pkgCache::VerIterator &Ver,
{
PyObject *Obj;
if (AsObj == true)
- Obj = CppOwnedPyObject_NEW<pkgCache::DepIterator>(Owner,&DependencyType,
+ Obj = CppPyObject_NEW<pkgCache::DepIterator>(Owner,&PyDependency_Type,
Start);
else
{
@@ -553,63 +728,86 @@ static PyObject *MakeDepends(PyObject *Owner,pkgCache::VerIterator &Ver,
return Dict;
}
-static PyObject *VersionAttr(PyObject *Self,char *Name)
-{
+static inline pkgCache::VerIterator Version_GetVer(PyObject *Self) {
+ return GetCpp<pkgCache::VerIterator>(Self);
+}
+
+// Version attributes.
+static PyObject *VersionGetVerStr(PyObject *Self, void*) {
+ return PyString_FromString(Version_GetVer(Self).VerStr());
+}
+static PyObject *VersionGetSection(PyObject *Self, void*) {
+ return Safe_FromString(Version_GetVer(Self).Section());
+}
+static PyObject *VersionGetArch(PyObject *Self, void*) {
+ return Safe_FromString(Version_GetVer(Self).Arch());
+}
+static PyObject *VersionGetFileList(PyObject *Self, void*) {
pkgCache::VerIterator &Ver = GetCpp<pkgCache::VerIterator>(Self);
PyObject *Owner = GetOwner<pkgCache::VerIterator>(Self);
-
- if (strcmp("VerStr",Name) == 0)
- return PyString_FromString(Ver.VerStr());
- else if (strcmp("Section",Name) == 0)
- return Safe_FromString(Ver.Section());
- else if (strcmp("Arch",Name) == 0)
- return Safe_FromString(Ver.Arch());
- else if (strcmp("FileList",Name) == 0)
+ PyObject *List = PyList_New(0);
+ for (pkgCache::VerFileIterator I = Ver.FileList(); I.end() == false; I++)
{
- /* The second value in the tuple is the index of the VF item. If the
- user wants to request a lookup then that number will be used.
- Maybe later it can become an object. */
- PyObject *List = PyList_New(0);
- for (pkgCache::VerFileIterator I = Ver.FileList(); I.end() == false; I++)
- {
- PyObject *PkgFile;
- PyObject *Obj;
- PkgFile = CppOwnedPyObject_NEW<pkgCache::PkgFileIterator>(Owner,&PackageFileType,I.File());
- Obj = Py_BuildValue("Nl",PkgFile,I.Index());
- PyList_Append(List,Obj);
- Py_DECREF(Obj);
- }
- return List;
- }
- else if (strcmp("DependsListStr",Name) == 0)
- return MakeDepends(Owner,Ver,false);
- else if (strcmp("DependsList",Name) == 0)
- return MakeDepends(Owner,Ver,true);
- else if (strcmp("ParentPkg",Name) == 0)
- return CppOwnedPyObject_NEW<pkgCache::PkgIterator>(Owner,&PackageType,
- Ver.ParentPkg());
- else if (strcmp("ProvidesList",Name) == 0)
- return CreateProvides(Owner,Ver.ProvidesList());
- else if (strcmp("Size",Name) == 0)
- return Py_BuildValue("i",Ver->Size);
- else if (strcmp("InstalledSize",Name) == 0)
- return Py_BuildValue("i",Ver->InstalledSize);
- else if (strcmp("Hash",Name) == 0)
- return Py_BuildValue("i",Ver->Hash);
- else if (strcmp("ID",Name) == 0)
- return Py_BuildValue("i",Ver->ID);
- else if (strcmp("Priority",Name) == 0)
- return Py_BuildValue("i",Ver->Priority);
- else if (strcmp("PriorityStr",Name) == 0)
- return Safe_FromString(Ver.PriorityType());
- else if (strcmp("Downloadable", Name) == 0)
- return Py_BuildValue("b", Ver.Downloadable());
- else if (strcmp("TranslatedDescription", Name) == 0) {
- return CppOwnedPyObject_NEW<pkgCache::DescIterator>(Owner,
- &DescriptionType,
- Ver.TranslatedDescription());
+ PyObject *PkgFile;
+ PyObject *Obj;
+ PkgFile = CppPyObject_NEW<pkgCache::PkgFileIterator>(Owner,&PyPackageFile_Type,I.File());
+ Obj = Py_BuildValue("Nl",PkgFile,I.Index());
+ PyList_Append(List,Obj);
+ Py_DECREF(Obj);
}
+ return List;
+}
+
+static PyObject *VersionGetDependsListStr(PyObject *Self, void*) {
+ pkgCache::VerIterator &Ver = GetCpp<pkgCache::VerIterator>(Self);
+ PyObject *Owner = GetOwner<pkgCache::VerIterator>(Self);
+ return MakeDepends(Owner,Ver,false);
+}
+static PyObject *VersionGetDependsList(PyObject *Self, void*) {
+ pkgCache::VerIterator &Ver = GetCpp<pkgCache::VerIterator>(Self);
+ PyObject *Owner = GetOwner<pkgCache::VerIterator>(Self);
+ return MakeDepends(Owner,Ver,true);
+}
+static PyObject *VersionGetParentPkg(PyObject *Self, void*) {
+ PyObject *Owner = GetOwner<pkgCache::VerIterator>(Self);
+ return CppPyObject_NEW<pkgCache::PkgIterator>(Owner,&PyPackage_Type,
+ Version_GetVer(Self).ParentPkg());
+}
+static PyObject *VersionGetProvidesList(PyObject *Self, void*) {
+ PyObject *Owner = GetOwner<pkgCache::VerIterator>(Self);
+ return CreateProvides(Owner,Version_GetVer(Self).ProvidesList());
+}
+static PyObject *VersionGetSize(PyObject *Self, void*) {
+ return Py_BuildValue("i", Version_GetVer(Self)->Size);
+}
+static PyObject *VersionGetInstalledSize(PyObject *Self, void*) {
+ return Py_BuildValue("i", Version_GetVer(Self)->InstalledSize);
+}
+static PyObject *VersionGetHash(PyObject *Self, void*) {
+ return Py_BuildValue("i", Version_GetVer(Self)->Hash);
+}
+static PyObject *VersionGetID(PyObject *Self, void*) {
+ return Py_BuildValue("i", Version_GetVer(Self)->ID);
+}
+static PyObject *VersionGetPriority(PyObject *Self, void*) {
+ return Py_BuildValue("i",Version_GetVer(Self)->Priority);
+}
+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());
+}
+static PyObject *VersionGetTranslatedDescription(PyObject *Self, void*) {
+ pkgCache::VerIterator &Ver = GetCpp<pkgCache::VerIterator>(Self);
+ PyObject *Owner = GetOwner<pkgCache::VerIterator>(Self);
+ return CppPyObject_NEW<pkgCache::DescIterator>(Owner,
+ &PyDescription_Type,
+ Ver.TranslatedDescription());
+}
+
#if 0 // FIXME: enable once pkgSourceList is stored somewhere
+static PyObject *VersionGetIsTrusted(PyObject *Self, void*) {
else if (strcmp("IsTrusted", Name) == 0)
{
pkgSourceList Sources;
@@ -622,37 +820,55 @@ static PyObject *VersionAttr(PyObject *Self,char *Name)
}
return Py_BuildValue("b", true);
}
+}
#endif
- PyErr_SetString(PyExc_AttributeError,Name);
- return 0;
-}
+#define NOTNULL(x) (x ? x : "")
static PyObject *VersionRepr(PyObject *Self)
{
pkgCache::VerIterator &Ver = GetCpp<pkgCache::VerIterator>(Self);
-
- char S[300];
- snprintf(S,sizeof(S),"<pkgCache::Version object: Pkg:'%s' Ver:'%s' "
- "Section:'%s' Arch:'%s' Size:%lu ISize:%lu Hash:%u "
- "ID:%u Priority:%u>",
- Ver.ParentPkg().Name(),Ver.VerStr(),Ver.Section(),Ver.Arch(),
- (unsigned long)Ver->Size,(unsigned long)Ver->InstalledSize,
- Ver->Hash,Ver->ID,Ver->Priority);
- return PyString_FromString(S);
+ return PyString_FromFormat("<%s object: Pkg:'%s' Ver:'%s' Section:'%s' "
+ " Arch:'%s' Size:%lu ISize:%lu Hash:%u ID:%u "
+ "Priority:%u>", Self->ob_type->tp_name,
+ Ver.ParentPkg().Name(), Ver.VerStr(),
+ NOTNULL(Ver.Section()), NOTNULL(Ver.Arch()),
+ (unsigned long)Ver->Size,
+ (unsigned long)Ver->InstalledSize,
+ Ver->Hash, Ver->ID, Ver->Priority);
}
+#undef NOTNULL
+
+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},
+ {}
+};
-PyTypeObject VersionType =
+PyTypeObject PyVersion_Type =
{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "pkgCache::VerIterator", // tp_name
- sizeof(CppOwnedPyObject<pkgCache::VerIterator>), // tp_basicsize
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.Version", // tp_name
+ sizeof(CppPyObject<pkgCache::VerIterator>), // tp_basicsize
0, // tp_itemsize
// Methods
- CppOwnedDealloc<pkgCache::VerIterator>, // tp_dealloc
+ CppDealloc<pkgCache::VerIterator>, // tp_dealloc
0, // tp_print
- VersionAttr, // tp_getattr
+ 0, // tp_getattr
0, // tp_setattr
0, // tp_compare
VersionRepr, // tp_repr
@@ -660,96 +876,180 @@ PyTypeObject VersionType =
0, // tp_as_sequence
0, // tp_as_mapping
0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ _PyAptObject_getattro, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags
+ "Version Object", // tp_doc
+ CppTraverse<pkgCache::VerIterator>, // tp_traverse
+ CppClear<pkgCache::VerIterator>,// tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ 0, // tp_methods
+ 0, // tp_members
+ VersionGetSet, // tp_getset
};
/*}}}*/
// PackageFile Class /*{{{*/
// ---------------------------------------------------------------------
-static PyObject *PackageFileAttr(PyObject *Self,char *Name)
-{
- pkgCache::PkgFileIterator &File = GetCpp<pkgCache::PkgFileIterator>(Self);
-// PyObject *Owner = GetOwner<pkgCache::PkgFileIterator>(Self);
-
- if (strcmp("FileName",Name) == 0)
- return Safe_FromString(File.FileName());
- else if (strcmp("Archive",Name) == 0)
- return Safe_FromString(File.Archive());
- else if (strcmp("Component",Name) == 0)
- return Safe_FromString(File.Component());
- else if (strcmp("Version",Name) == 0)
- return Safe_FromString(File.Version());
- else if (strcmp("Origin",Name) == 0)
- return Safe_FromString(File.Origin());
- else if (strcmp("Label",Name) == 0)
- return Safe_FromString(File.Label());
- else if (strcmp("Architecture",Name) == 0)
- return Safe_FromString(File.Architecture());
- else if (strcmp("Site",Name) == 0)
- return Safe_FromString(File.Site());
- else if (strcmp("IndexType",Name) == 0)
- return Safe_FromString(File.IndexType());
- else if (strcmp("Size",Name) == 0)
- return Py_BuildValue("i",File->Size);
- else if (strcmp("NotSource",Name) == 0)
- return Py_BuildValue("i",(File->Flags & pkgCache::Flag::NotSource) != 0);
- else if (strcmp("NotAutomatic",Name) == 0)
- return Py_BuildValue("i",(File->Flags & pkgCache::Flag::NotAutomatic) != 0);
- else if (strcmp("ID",Name) == 0)
- return Py_BuildValue("i",File->ID);
-
- PyErr_SetString(PyExc_AttributeError,Name);
- return 0;
+static PyObject *PackageFile_GetFileName(PyObject *Self,void*)
+{
+ pkgCache::PkgFileIterator &File = GetCpp<pkgCache::PkgFileIterator>(Self);
+ return Safe_FromString(File.FileName());
}
-static PyObject *PackageFileRepr(PyObject *Self)
+static PyObject *PackageFile_GetArchive(PyObject *Self,void*)
{
- pkgCache::PkgFileIterator &File = GetCpp<pkgCache::PkgFileIterator>(Self);
+ pkgCache::PkgFileIterator &File = GetCpp<pkgCache::PkgFileIterator>(Self);
+ return Safe_FromString(File.Archive());
+}
- char S[300];
- snprintf(S,sizeof(S),"<pkgCache::PackageFile object: "
- "File:'%s' a=%s,c=%s,v=%s,o=%s,l=%s "
- "Arch='%s' Site='%s' IndexType='%s' Size=%lu "
- "Flags=0x%lX ID:%u>",
- File.FileName(),File.Archive(),File.Component(),File.Version(),
- File.Origin(),File.Label(),File.Architecture(),File.Site(),
- File.IndexType(),File->Size,File->Flags,File->ID);
- return PyString_FromString(S);
+static PyObject *PackageFile_GetComponent(PyObject *Self,void*)
+{
+ pkgCache::PkgFileIterator &File = GetCpp<pkgCache::PkgFileIterator>(Self);
+ return Safe_FromString(File.Component());
}
-PyTypeObject PackageFileType =
+static PyObject *PackageFile_GetVersion(PyObject *Self,void*)
{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "pkgCache::PkgFileIterator", // tp_name
- sizeof(CppOwnedPyObject<pkgCache::PkgFileIterator>), // tp_basicsize
- 0, // tp_itemsize
- // Methods
- CppOwnedDealloc<pkgCache::PkgFileIterator>, // tp_dealloc
- 0, // tp_print
- PackageFileAttr, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- PackageFileRepr, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
- 0, // tp_hash
+ pkgCache::PkgFileIterator &File = GetCpp<pkgCache::PkgFileIterator>(Self);
+ return Safe_FromString(File.Version());
+}
+
+static PyObject *PackageFile_GetOrigin(PyObject *Self,void*)
+{
+ pkgCache::PkgFileIterator &File = GetCpp<pkgCache::PkgFileIterator>(Self);
+ return Safe_FromString(File.Origin());
+}
+
+static PyObject *PackageFile_GetLabel(PyObject *Self,void*)
+{
+ pkgCache::PkgFileIterator &File = GetCpp<pkgCache::PkgFileIterator>(Self);
+ return Safe_FromString(File.Label());
+}
+
+static PyObject *PackageFile_GetArchitecture(PyObject *Self,void*)
+{
+ pkgCache::PkgFileIterator &File = GetCpp<pkgCache::PkgFileIterator>(Self);
+ return Safe_FromString(File.Architecture());
+}
+
+static PyObject *PackageFile_GetSite(PyObject *Self,void*)
+{
+ pkgCache::PkgFileIterator &File = GetCpp<pkgCache::PkgFileIterator>(Self);
+ return Safe_FromString(File.Site());
+}
+
+static PyObject *PackageFile_GetIndexType(PyObject *Self,void*)
+{
+ pkgCache::PkgFileIterator &File = GetCpp<pkgCache::PkgFileIterator>(Self);
+ return Safe_FromString(File.IndexType());
+}
+static PyObject *PackageFile_GetSize(PyObject *Self,void*)
+{
+ pkgCache::PkgFileIterator &File = GetCpp<pkgCache::PkgFileIterator>(Self);
+ return Py_BuildValue("i",File->Size);
+}
+
+static PyObject *PackageFile_GetNotSource(PyObject *Self,void*)
+{
+ pkgCache::PkgFileIterator &File = GetCpp<pkgCache::PkgFileIterator>(Self);
+ return Py_BuildValue("i",(File->Flags & pkgCache::Flag::NotSource) != 0);
+}
+static PyObject *PackageFile_GetNotAutomatic(PyObject *Self,void*)
+{
+ pkgCache::PkgFileIterator &File = GetCpp<pkgCache::PkgFileIterator>(Self);
+ return Py_BuildValue("i",(File->Flags & pkgCache::Flag::NotSource) != 0);
+}
+
+static PyObject *PackageFile_GetID(PyObject *Self,void*)
+{
+ pkgCache::PkgFileIterator &File = GetCpp<pkgCache::PkgFileIterator>(Self);
+ return Py_BuildValue("i",File->ID);
+}
+
+#define S(s) (s == NULL ? "" : s)
+static PyObject *PackageFileRepr(PyObject *Self)
+{
+ pkgCache::PkgFileIterator &File = GetCpp<pkgCache::PkgFileIterator>(Self);
+
+ return PyString_FromFormat("<%s object: filename:'%s'"
+ " a=%s,c=%s,v=%s,o=%s,l=%s arch='%s' site='%s'"
+ " IndexType='%s' Size=%lu ID:%u>",
+ Self->ob_type->tp_name, File.FileName(),
+ S(File.Archive()),
+ S(File.Component()),S(File.Version()),
+ S(File.Origin()),S(File.Label()),
+ S(File.Architecture()),S(File.Site()),
+ S(File.IndexType()),File->Size,File->ID);
+}
+#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},
+ {}
};
+PyTypeObject PyPackageFile_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.PackageFile", // tp_name
+ sizeof(CppPyObject<pkgCache::PkgFileIterator>), // tp_basicsize
+ 0, // tp_itemsize
+ CppDealloc<pkgCache::PkgFileIterator>, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ PackageFileRepr, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ _PyAptObject_getattro, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags
+ "apt_pkg.PackageFile Object", // tp_doc
+ CppTraverse<pkgCache::PkgFileIterator>, // tp_traverse
+ CppClear<pkgCache::PkgFileIterator>, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ 0, // tp_methods
+ 0, // tp_members
+ PackageFileGetSet, // tp_getset
+};
// depends class
static PyObject *DependencyRepr(PyObject *Self)
{
pkgCache::DepIterator &Dep = GetCpp<pkgCache::DepIterator>(Self);
- char S[300];
- snprintf(S,sizeof(S),"<pkgCache::Dependency object: "
- "Pkg:'%s' Ver:'%s' Comp:'%s'>",
- Dep.TargetPkg().Name(),
- (Dep.TargetVer() == 0?"":Dep.TargetVer()),
- Dep.CompType());
- return PyString_FromString(S);
+ return PyString_FromFormat("<%s object: pkg:'%s' ver:'%s' comp:'%s'>",
+ Self->ob_type->tp_name, Dep.TargetPkg().Name(),
+ (Dep.TargetVer() == 0 ? "" : Dep.TargetVer()),
+ Dep.CompType());
}
static PyObject *DepSmartTargetPkg(PyObject *Self,PyObject *Args)
@@ -767,7 +1067,7 @@ static PyObject *DepSmartTargetPkg(PyObject *Self,PyObject *Args)
return Py_None;
}
- return CppOwnedPyObject_NEW<pkgCache::PkgIterator>(Owner,&PackageType,P);
+ return CppPyObject_NEW<pkgCache::PkgIterator>(Owner,&PyPackage_Type,P);
}
static PyObject *DepAllTargets(PyObject *Self,PyObject *Args)
@@ -783,7 +1083,7 @@ static PyObject *DepAllTargets(PyObject *Self,PyObject *Args)
for (pkgCache::Version **I = Vers; *I != 0; I++)
{
PyObject *Obj;
- Obj = CppOwnedPyObject_NEW<pkgCache::VerIterator>(Owner,&VersionType,
+ Obj = CppPyObject_NEW<pkgCache::VerIterator>(Owner,&PyVersion_Type,
pkgCache::VerIterator(*Dep.Cache(),*I));
PyList_Append(List,Obj);
Py_DECREF(Obj);
@@ -793,65 +1093,123 @@ static PyObject *DepAllTargets(PyObject *Self,PyObject *Args)
static PyMethodDef DependencyMethods[] =
{
- {"SmartTargetPkg",DepSmartTargetPkg,METH_VARARGS,"Returns the natural Target or None"},
- {"AllTargets",DepAllTargets,METH_VARARGS,"Returns all possible Versions that match this dependency"},
+ {"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"},
{}
};
// Dependency Class /*{{{*/
// ---------------------------------------------------------------------
-static PyObject *DependencyAttr(PyObject *Self,char *Name)
+static PyObject *DependencyGetTargetVer(PyObject *Self,void*)
+{
+ pkgCache::DepIterator &Dep = GetCpp<pkgCache::DepIterator>(Self);
+ if (Dep->Version == 0)
+ return PyString_FromString("");
+ return PyString_FromString(Dep.TargetVer());
+}
+
+static PyObject *DependencyGetTargetPkg(PyObject *Self,void*)
+{
+ pkgCache::DepIterator &Dep = GetCpp<pkgCache::DepIterator>(Self);
+ PyObject *Owner = GetOwner<pkgCache::DepIterator>(Self);
+ return CppPyObject_NEW<pkgCache::PkgIterator>(Owner,&PyPackage_Type,
+ Dep.TargetPkg());
+}
+
+static PyObject *DependencyGetParentVer(PyObject *Self,void*)
{
pkgCache::DepIterator &Dep = GetCpp<pkgCache::DepIterator>(Self);
PyObject *Owner = GetOwner<pkgCache::DepIterator>(Self);
+ return CppPyObject_NEW<pkgCache::VerIterator>(Owner,&PyVersion_Type,
+ Dep.ParentVer());
+}
- if (strcmp("TargetVer",Name) == 0)
- {
- if (Dep->Version == 0)
- return PyString_FromString("");
- return PyString_FromString(Dep.TargetVer());
- }
- else if (strcmp("TargetPkg",Name) == 0)
- return CppOwnedPyObject_NEW<pkgCache::PkgIterator>(Owner,&PackageType,
- Dep.TargetPkg());
- else if (strcmp("ParentVer",Name) == 0)
- return CppOwnedPyObject_NEW<pkgCache::VerIterator>(Owner,&VersionType,
- Dep.ParentVer());
- else if (strcmp("ParentPkg",Name) == 0)
- return CppOwnedPyObject_NEW<pkgCache::PkgIterator>(Owner,&PackageType, Dep.ParentPkg());
- else if (strcmp("CompType",Name) == 0)
- return PyString_FromString(Dep.CompType());
- else if (strcmp("DepType",Name) == 0)
- return PyString_FromString(Dep.DepType());
- else if (strcmp("UntranslatedDepType",Name) == 0)
- return PyString_FromString(UntranslatedDepTypes[Dep->Type]);
- else if (strcmp("DepTypeEnum",Name) == 0)
- return Py_BuildValue("i", Dep->Type);
- else if (strcmp("ID",Name) == 0)
- return Py_BuildValue("i",Dep->ID);
-
- return Py_FindMethod(DependencyMethods,Self,Name);
-}
-
-PyTypeObject DependencyType =
-{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "pkgCache::DepIterator", // tp_name
- sizeof(CppOwnedPyObject<pkgCache::DepIterator>), // tp_basicsize
+static PyObject *DependencyGetParentPkg(PyObject *Self,void*)
+{
+ pkgCache::DepIterator &Dep = GetCpp<pkgCache::DepIterator>(Self);
+ PyObject *Owner = GetOwner<pkgCache::DepIterator>(Self);
+ return CppPyObject_NEW<pkgCache::PkgIterator>(Owner,&PyPackage_Type,
+ Dep.ParentPkg());
+}
+
+static PyObject *DependencyGetCompType(PyObject *Self,void*)
+{
+ pkgCache::DepIterator &Dep = GetCpp<pkgCache::DepIterator>(Self);
+ return PyString_FromString(Dep.CompType());
+}
+
+static PyObject *DependencyGetDepType(PyObject *Self,void*)
+{
+ pkgCache::DepIterator &Dep = GetCpp<pkgCache::DepIterator>(Self);
+ return PyString_FromString(Dep.DepType());
+}
+
+static PyObject *DependencyGetDepTypeUntranslated(PyObject *Self,void*)
+{
+ pkgCache::DepIterator &Dep = GetCpp<pkgCache::DepIterator>(Self);
+ return PyString_FromString(UntranslatedDepTypes[Dep->Type]);
+}
+
+static PyObject *DependencyGetDepTypeEnum(PyObject *Self,void*)
+{
+ pkgCache::DepIterator &Dep = GetCpp<pkgCache::DepIterator>(Self);
+ return Py_BuildValue("i", Dep->Type);
+}
+
+static PyObject *DependencyGetID(PyObject *Self,void*)
+{
+ pkgCache::DepIterator &Dep = GetCpp<pkgCache::DepIterator>(Self);
+ return Py_BuildValue("i",Dep->ID);
+}
+
+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},
+ {}
+};
+
+
+PyTypeObject PyDependency_Type =
+{
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.Dependency", // tp_name
+ sizeof(CppPyObject<pkgCache::DepIterator>), // tp_basicsize
0, // tp_itemsize
// Methods
- CppOwnedDealloc<pkgCache::DepIterator>, // tp_dealloc
+ CppDealloc<pkgCache::DepIterator>, // tp_dealloc
0, // tp_print
- DependencyAttr, // tp_getattr
+ 0, // tp_getattr
0, // tp_setattr
0, // tp_compare
- DependencyRepr, // tp_repr
+ DependencyRepr, // tp_repr
0, // tp_as_number
0, // tp_as_sequence
0, // tp_as_mapping
0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ _PyAptObject_getattro, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags
+ "Dependency Object", // tp_doc
+ CppTraverse<pkgCache::DepIterator>, // tp_traverse
+ CppClear<pkgCache::DepIterator>, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ DependencyMethods, // tp_methods
+ 0, // tp_members
+ DependencyGetSet, // tp_getset
};
/*}}}*/
@@ -889,8 +1247,8 @@ static PyObject *RDepListItem(PyObject *iSelf,Py_ssize_t Index)
}
}
- return CppOwnedPyObject_NEW<pkgCache::DepIterator>(GetOwner<RDepListStruct>(iSelf),
- &DependencyType,Self.Iter);
+ return CppPyObject_NEW<pkgCache::DepIterator>(GetOwner<RDepListStruct>(iSelf),
+ &PyDependency_Type,Self.Iter);
}
static PySequenceMethods RDepListSeq =
@@ -904,15 +1262,14 @@ static PySequenceMethods RDepListSeq =
0 // assign slice
};
-PyTypeObject RDepListType =
+PyTypeObject PyDependencyList_Type =
{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "pkgCache::DepIterator", // tp_name
- sizeof(CppOwnedPyObject<RDepListStruct>), // tp_basicsize
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.DependencyList", // tp_name
+ sizeof(CppPyObject<RDepListStruct>), // tp_basicsize
0, // tp_itemsize
// Methods
- CppOwnedDealloc<RDepListStruct>, // tp_dealloc
+ CppDealloc<RDepListStruct>, // tp_dealloc
0, // tp_print
0, // tp_getattr
0, // tp_setattr
@@ -922,55 +1279,25 @@ PyTypeObject RDepListType =
&RDepListSeq, // tp_as_sequence
0, // tp_as_mapping
0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags
+ "DependencyList Object", // tp_doc
+ CppTraverse<RDepListStruct>, // tp_traverse
+ CppClear<RDepListStruct>, // tp_clear
};
/*}}}*/
-
+#ifdef COMPAT_0_7
PyObject *TmpGetCache(PyObject *Self,PyObject *Args)
{
- PyObject *pyCallbackInst = 0;
- if (PyArg_ParseTuple(Args, "|O", &pyCallbackInst) == 0)
- return 0;
-
- if (_system == 0) {
- PyErr_SetString(PyExc_ValueError,"_system not initialized");
- return 0;
- }
-
- pkgCacheFile *Cache = new pkgCacheFile();
-
- if(pyCallbackInst != 0) {
- // sanity check for the progress object, see #497049
- if (PyObject_HasAttrString(pyCallbackInst, "done") != true) {
- PyErr_SetString(PyExc_ValueError,
- "OpProgress object must implement done()");
- return 0;
- }
- if (PyObject_HasAttrString(pyCallbackInst, "update") != true) {
- PyErr_SetString(PyExc_ValueError,
- "OpProgress object must implement update()");
- return 0;
- }
- PyOpProgress progress;
- progress.setCallbackInst(pyCallbackInst);
- if (Cache->Open(progress,false) == false)
- return HandleErrors();
- }
- else {
- OpTextProgress Prog;
- if (Cache->Open(Prog,false) == false)
- return HandleErrors();
- }
-
- CppOwnedPyObject<pkgCacheFile*> *CacheFileObj =
- CppOwnedPyObject_NEW<pkgCacheFile*>(0,&PkgCacheFileType, Cache);
-
- CppOwnedPyObject<pkgCache *> *CacheObj =
- CppOwnedPyObject_NEW<pkgCache *>(CacheFileObj,&PkgCacheType,
- (pkgCache *)(*Cache));
-
- //Py_DECREF(CacheFileObj);
- return CacheObj;
+ PyErr_WarnEx(PyExc_DeprecationWarning, "apt_pkg.GetCache() is deprecated. "
+ "Please see apt_pkg.Cache() for the replacement.", 1);
+ return PkgCacheNew(&PyCache_Type,Args,0);
}
+#endif
diff --git a/python/cdrom.cc b/python/cdrom.cc
index 0831548e..9eae49dc 100644
--- a/python/cdrom.cc
+++ b/python/cdrom.cc
@@ -1,10 +1,26 @@
-// Description /*{{{*/
-// $Id: cdrom.cc,v 1.1 2003/06/03 03:03:23 mvo Exp $
-/* ######################################################################
-
- Cdrom - Wrapper for the apt-cdrom support
-
- ##################################################################### */
+/* cdrom.cc - Wrapper for pkgCdrom.
+ *
+ * Copyright 2004-2009 Canonical Ltd.
+ * Copyright 2009 Julian Andres Klode <jak@debian.org>
+ *
+ * Authors: Michael Vogt
+ * Julian Andres Klode
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
#include "generic.h"
#include "apt_pkgmodule.h"
@@ -12,99 +28,144 @@
#include <apt-pkg/cdrom.h>
-
-struct PkgCdromStruct
+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"
+ "raise an error on failure or return False.";
+static PyObject *cdrom_add(PyObject *Self,PyObject *Args)
{
- pkgCdrom cdrom;
-};
+ pkgCdrom &Cdrom = GetCpp<pkgCdrom>(Self);
-static PyObject *PkgCdromAdd(PyObject *Self,PyObject *Args)
-{
- PkgCdromStruct &Struct = GetCpp<PkgCdromStruct>(Self);
+ PyObject *pyCdromProgressInst = 0;
+ if (PyArg_ParseTuple(Args, "O", &pyCdromProgressInst) == 0) {
+ return 0;
+ }
- PyObject *pyCdromProgressInst = 0;
- if (PyArg_ParseTuple(Args, "O", &pyCdromProgressInst) == 0) {
- return 0;
- }
+ PyCdromProgress progress;
+ progress.setCallbackInst(pyCdromProgressInst);
- PyCdromProgress progress;
- progress.setCallbackInst(pyCdromProgressInst);
+ bool res = Cdrom.Add(&progress);
- bool res = Struct.cdrom.Add(&progress);
+ return HandleErrors(PyBool_FromLong(res));
+}
- return HandleErrors(Py_BuildValue("b", res));
+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.";
+static PyObject *cdrom_ident(PyObject *Self,PyObject *Args)
+{
+ pkgCdrom &Cdrom = GetCpp<pkgCdrom>(Self);
+ PyObject *pyCdromProgressInst = 0;
+ if (PyArg_ParseTuple(Args, "O", &pyCdromProgressInst) == 0) {
+ return 0;
+ }
+
+ PyCdromProgress progress;
+ progress.setCallbackInst(pyCdromProgressInst);
+
+ string ident;
+ bool res = Cdrom.Ident(ident, &progress);
+
+ if (res)
+ return CppPyString(ident);
+ else {
+ Py_INCREF(Py_None);
+ return HandleErrors(Py_None);
+ }
}
-static PyObject *PkgCdromIdent(PyObject *Self,PyObject *Args)
+#ifdef COMPAT_0_7
+static PyObject *cdrom_ident_old(PyObject *Self,PyObject *Args)
{
- PkgCdromStruct &Struct = GetCpp<PkgCdromStruct>(Self);
+ PyErr_WarnEx(PyExc_DeprecationWarning, "Method 'Ident' of the "
+ "'apt_pkg.Cdrom' object is deprecated, use 'ident' instead.",
+ 1);
+ pkgCdrom &Cdrom = GetCpp<pkgCdrom>(Self);
- PyObject *pyCdromProgressInst = 0;
- if (PyArg_ParseTuple(Args, "O", &pyCdromProgressInst) == 0) {
- return 0;
- }
+ PyObject *pyCdromProgressInst = 0;
+ if (PyArg_ParseTuple(Args, "O", &pyCdromProgressInst) == 0) {
+ return 0;
+ }
- PyCdromProgress progress;
- progress.setCallbackInst(pyCdromProgressInst);
+ PyCdromProgress progress;
+ progress.setCallbackInst(pyCdromProgressInst);
- string ident;
- bool res = Struct.cdrom.Ident(ident, &progress);
+ string ident;
+ bool res = Cdrom.Ident(ident, &progress);
- PyObject *result = Py_BuildValue("(bs)", res, ident.c_str());
+ PyObject *result = Py_BuildValue("(bs)", res, ident.c_str());
- return HandleErrors(result);
+ return HandleErrors(result);
}
-
-
-static PyMethodDef PkgCdromMethods[] =
-{
- {"Add",PkgCdromAdd,METH_VARARGS,"Add a cdrom"},
- {"Ident",PkgCdromIdent,METH_VARARGS,"Ident a cdrom"},
- {}
+#endif
+
+static PyMethodDef cdrom_methods[] = {
+ {"add",cdrom_add,METH_VARARGS,cdrom_add_doc},
+ {"ident",cdrom_ident,METH_VARARGS,cdrom_ident_doc},
+#ifdef COMPAT_0_7
+ {"Ident",cdrom_ident_old,METH_VARARGS,"DEPRECATED. DO NOT USE"},
+#endif
+ {}
};
-
-static PyObject *CdromAttr(PyObject *Self,char *Name)
+static PyObject *cdrom_new(PyTypeObject *type,PyObject *Args,PyObject *kwds)
{
- PkgCdromStruct &Struct = GetCpp<PkgCdromStruct>(Self);
-
- return Py_FindMethod(PkgCdromMethods,Self,Name);
+ return CppPyObject_NEW<pkgCdrom>(NULL, type);
}
-
-
-
-PyTypeObject PkgCdromType =
-{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "Cdrom", // tp_name
- sizeof(CppOwnedPyObject<PkgCdromStruct>), // tp_basicsize
- 0, // tp_itemsize
- // Methods
- CppOwnedDealloc<PkgCdromStruct>, // tp_dealloc
- 0, // tp_print
- CdromAttr, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
- 0, // tp_hash
+static char *cdrom_doc =
+ "Cdrom()\n\n"
+ "Cdrom objects can be used to identify Debian installation media and to\n"
+ "add them to /etc/apt/sources.list.";
+PyTypeObject PyCdrom_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.Cdrom", // tp_name
+ sizeof(CppPyObject<pkgCdrom>), // tp_basicsize
+ 0, // tp_itemsize
+ // Methods
+ CppDealloc<pkgCdrom>, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ _PyAptObject_getattro, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_BASETYPE,
+ cdrom_doc, // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ cdrom_methods, // tp_methods
+ 0, // tp_members
+ 0, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ 0, // tp_alloc
+ cdrom_new, // tp_new
};
+#ifdef COMPAT_0_7
PyObject *GetCdrom(PyObject *Self,PyObject *Args)
{
- pkgCdrom *cdrom = new pkgCdrom();
-
- CppOwnedPyObject<pkgCdrom> *CdromObj =
- CppOwnedPyObject_NEW<pkgCdrom>(0,&PkgCdromType, *cdrom);
-
- return CdromObj;
+ PyErr_WarnEx(PyExc_DeprecationWarning, "apt_pkg.GetCdrom() is deprecated. "
+ "Please see apt_pkg.Cdrom() for the replacement.", 1);
+ return cdrom_new(&PyCdrom_Type,Args,0);
}
-
-
-
-
- /*}}}*/
+#endif
diff --git a/python/configuration.cc b/python/configuration.cc
index 21f70bc1..299e06ec 100644
--- a/python/configuration.cc
+++ b/python/configuration.cc
@@ -5,11 +5,8 @@
Configuration - Binding for the configuration object.
- There are three seperate classes..
- Configuration - A stand alone configuration instance
- ConfigurationPtr - A pointer to a configuration instance, used only
- for the global instance (_config)
- ConfigurationSub - A subtree - has a reference to its owner.
+ The Configuration object can have an owner (a parent Configuration object),
+ and it always uses a pointer.
The wrapping is mostly 1:1 with the C++ code, but there are additions to
wrap the linked tree walking into nice flat sequence walking.
@@ -25,33 +22,13 @@
#include <Python.h>
/*}}}*/
-/* If we create a sub tree then it is of this type, the Owner is used
- to manage reference counting. */
-struct SubConfiguration : public CppPyObject<Configuration>
-{
- PyObject *Owner;
-};
-
- /*}}}*/
-// CnfSubFree - Free a sub configuration /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-void CnfSubFree(PyObject *Obj)
-{
- SubConfiguration *Self = (SubConfiguration *)Obj;
- Py_DECREF(Self->Owner);
- CppDealloc<Configuration>(Obj);
-}
- /*}}}*/
// GetSelf - Convert PyObject to Configuration /*{{{*/
// ---------------------------------------------------------------------
/* */
static inline Configuration &GetSelf(PyObject *Obj)
{
- if (Obj->ob_type == &ConfigurationPtrType)
- return *GetCpp<Configuration *>(Obj);
- return GetCpp<Configuration>(Obj);
+ return *GetCpp<Configuration*>(Obj);
}
/*}}}*/
@@ -128,6 +105,11 @@ static PyObject *CnfExists(PyObject *Self,PyObject *Args)
return Py_BuildValue("i",(int)GetSelf(Self).Exists(Name));
}
+static int CnfContains(PyObject *Self,PyObject *Arg)
+{
+ return (int)GetSelf(Self).Exists(PyString_AsString(Arg));
+}
+
static char *doc_Clear = "Clear(Name) -> None";
static PyObject *CnfClear(PyObject *Self,PyObject *Args)
{
@@ -155,12 +137,8 @@ static PyObject *CnfSubTree(PyObject *Self,PyObject *Args)
return 0;
}
- // Create a new sub configuration.
- SubConfiguration *New = PyObject_NEW(SubConfiguration,&ConfigurationSubType);
- new (&New->Object) Configuration(Itm);
- New->Owner = Self;
- Py_INCREF(Self);
- return New;
+ return CppPyObject_NEW<Configuration*>(Self,&PyConfiguration_Type,
+ new Configuration(Itm));
}
// Return a list of items at a specific level
@@ -174,6 +152,8 @@ static PyObject *CnfList(PyObject *Self,PyObject *Args)
// Convert the whole configuration space into a list
PyObject *List = PyList_New(0);
const Configuration::Item *Top = GetSelf(Self).Tree(RootName);
+ if (!GetSelf(Self).Tree(0))
+ return List;
const Configuration::Item *Root = GetSelf(Self).Tree(0)->Parent;
if (Top != 0 && RootName != 0)
Top = Top->Child;
@@ -238,7 +218,7 @@ static PyObject *CnfKeys(PyObject *Self,PyObject *Args)
const Configuration::Item *Root = 0;
if (RootName == 0)
Stop = 0;
- if (Top != 0)
+ if (Top != 0 && GetSelf(Self).Tree(0))
Root = GetSelf(Self).Tree(0)->Parent;
for (; Top != 0;)
{
@@ -300,7 +280,7 @@ PyObject *LoadConfig(PyObject *Self,PyObject *Args)
char *Name = 0;
if (PyArg_ParseTuple(Args,"Os",&Self,&Name) == 0)
return 0;
- if (Configuration_Check(Self)== 0)
+ if (PyConfiguration_Check(Self)== 0)
{
PyErr_SetString(PyExc_TypeError,"argument 1: expected Configuration.");
return 0;
@@ -318,7 +298,7 @@ PyObject *LoadConfigISC(PyObject *Self,PyObject *Args)
char *Name = 0;
if (PyArg_ParseTuple(Args,"Os",&Self,&Name) == 0)
return 0;
- if (Configuration_Check(Self)== 0)
+ if (PyConfiguration_Check(Self)== 0)
{
PyErr_SetString(PyExc_TypeError,"argument 1: expected Configuration.");
return 0;
@@ -336,7 +316,7 @@ PyObject *LoadConfigDir(PyObject *Self,PyObject *Args)
char *Name = 0;
if (PyArg_ParseTuple(Args,"Os",&Self,&Name) == 0)
return 0;
- if (Configuration_Check(Self)== 0)
+ if (PyConfiguration_Check(Self)== 0)
{
PyErr_SetString(PyExc_TypeError,"argument 1: expected Configuration.");
return 0;
@@ -368,7 +348,7 @@ PyObject *ParseCommandLine(PyObject *Self,PyObject *Args)
if (PyArg_ParseTuple(Args,"OO!O!",&Self,
&PyList_Type,&POList,&PyList_Type,&Pargv) == 0)
return 0;
- if (Configuration_Check(Self)== 0)
+ if (PyConfiguration_Check(Self)== 0)
{
PyErr_SetString(PyExc_TypeError,"argument 1: expected Configuration.");
return 0;
@@ -383,7 +363,11 @@ PyObject *ParseCommandLine(PyObject *Self,PyObject *Args)
for (int I = 0; I != Length; I++)
{
char *Type = 0;
+ #if PY_MAJOR_VERSION >= 3
+ if (PyArg_ParseTuple(PySequence_GetItem(POList,I),"Czs|s",
+ #else
if (PyArg_ParseTuple(PySequence_GetItem(POList,I),"czs|s",
+ #endif
&OList[I].ShortOpt,&OList[I].LongOpt,
&OList[I].ConfName,&Type) == 0)
{
@@ -448,95 +432,80 @@ PyObject *ParseCommandLine(PyObject *Self,PyObject *Args)
static PyMethodDef CnfMethods[] =
{
// Query
- {"Find",CnfFind,METH_VARARGS,doc_Find},
- {"FindFile",CnfFindFile,METH_VARARGS,doc_FindFile},
- {"FindDir",CnfFindDir,METH_VARARGS,doc_FindDir},
- {"FindI",CnfFindI,METH_VARARGS,doc_FindI},
- {"FindB",CnfFindB,METH_VARARGS,doc_FindB},
+ {"find",CnfFind,METH_VARARGS,doc_Find},
+ {"find_file",CnfFindFile,METH_VARARGS,doc_FindFile},
+ {"find_dir",CnfFindDir,METH_VARARGS,doc_FindDir},
+ {"find_i",CnfFindI,METH_VARARGS,doc_FindI},
+ {"find_b",CnfFindB,METH_VARARGS,doc_FindB},
// Others
- {"Set",CnfSet,METH_VARARGS,doc_Set},
- {"Exists",CnfExists,METH_VARARGS,doc_Exists},
- {"SubTree",CnfSubTree,METH_VARARGS,doc_SubTree},
- {"List",CnfList,METH_VARARGS,doc_List},
- {"ValueList",CnfValueList,METH_VARARGS,doc_ValueList},
- {"MyTag",CnfMyTag,METH_VARARGS,doc_MyTag},
- {"Clear",CnfClear,METH_VARARGS,doc_Clear},
-
+ {"set",CnfSet,METH_VARARGS,doc_Set},
+ {"exists",CnfExists,METH_VARARGS,doc_Exists},
+ {"subtree",CnfSubTree,METH_VARARGS,doc_SubTree},
+ {"list",CnfList,METH_VARARGS,doc_List},
+ {"value_list",CnfValueList,METH_VARARGS,doc_ValueList},
+ {"my_tag",CnfMyTag,METH_VARARGS,doc_MyTag},
+ {"clear",CnfClear,METH_VARARGS,doc_Clear},
// Python Special
{"keys",CnfKeys,METH_VARARGS,doc_Keys},
+ #if PY_MAJOR_VERSION < 3
{"has_key",CnfExists,METH_VARARGS,doc_Exists},
+ #endif
{"get",CnfFind,METH_VARARGS,doc_Find},
{}
};
-// CnfGetAttr - Get an attribute - variable/method /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-static PyObject *CnfGetAttr(PyObject *Self,char *Name)
-{
- return Py_FindMethod(CnfMethods,Self,Name);
+static PyObject *CnfNew(PyTypeObject *type, PyObject *args, PyObject *kwds) {
+ char *kwlist[] = {NULL};
+ if (PyArg_ParseTupleAndKeywords(args,kwds,"",kwlist) == 0)
+ return 0;
+ return CppPyObject_NEW<Configuration*>(NULL, type, new Configuration());
}
// Type for a Normal Configuration object
+static PySequenceMethods ConfigurationSeq = {0,0,0,0,0,0,0,CnfContains,0,0};
static PyMappingMethods ConfigurationMap = {0,CnfMap,CnfMapSet};
-PyTypeObject ConfigurationType =
-{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "Configuration", // tp_name
- sizeof(CppPyObject<Configuration>), // tp_basicsize
- 0, // tp_itemsize
- // Methods
- CppDealloc<Configuration>, // tp_dealloc
- 0, // tp_print
- CnfGetAttr, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- &ConfigurationMap, // tp_as_mapping
- 0, // tp_hash
-};
-
-PyTypeObject ConfigurationPtrType =
-{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "ConfigurationPtr", // tp_name
- sizeof(CppPyObject<Configuration *>), // tp_basicsize
- 0, // tp_itemsize
- // Methods
- (destructor)PyObject_Free, // tp_dealloc
- 0, // tp_print
- CnfGetAttr, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- &ConfigurationMap, // tp_as_mapping
- 0, // tp_hash
-};
-
-PyTypeObject ConfigurationSubType =
+PyTypeObject PyConfiguration_Type =
{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "ConfigurationSub", // tp_name
- sizeof(SubConfiguration), // tp_basicsize
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.Configuration", // tp_name
+ sizeof(CppPyObject<Configuration*>), // tp_basicsize
0, // tp_itemsize
// Methods
- CnfSubFree, // tp_dealloc
+ CppDeallocPtr<Configuration*>, // tp_dealloc
0, // tp_print
- CnfGetAttr, // tp_getattr
+ 0, // tp_getattr
0, // tp_setattr
0, // tp_compare
0, // tp_repr
0, // tp_as_number
- 0, // tp_as_sequence
+ &ConfigurationSeq, // tp_as_sequence
&ConfigurationMap, // tp_as_mapping
0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ _PyAptObject_getattro, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ (Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_BASETYPE),
+ "Configuration Object", // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ CnfMethods, // tp_methods
+ 0, // tp_members
+ 0, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ 0, // tp_alloc
+ CnfNew, // tp_new
};
diff --git a/python/depcache.cc b/python/depcache.cc
index 7edb7b59..8b4e02b5 100644
--- a/python/depcache.cc
+++ b/python/depcache.cc
@@ -62,8 +62,6 @@ static PyObject *PkgDepCacheInit(PyObject *Self,PyObject *Args)
static PyObject *PkgDepCacheCommit(PyObject *Self,PyObject *Args)
{
- PyObject *result;
-
pkgDepCache *depcache = GetCpp<pkgDepCache *>(Self);
PyObject *pyInstallProgressInst = 0;
@@ -192,11 +190,10 @@ static PyObject *PkgDepCacheSetCandidateVer(PyObject *Self,PyObject *Args)
PyObject *PackageObj;
PyObject *VersionObj;
if (PyArg_ParseTuple(Args,"O!O!",
- &PackageType, &PackageObj,
- &VersionType, &VersionObj) == 0)
+ &PyPackage_Type, &PackageObj,
+ &PyVersion_Type, &VersionObj) == 0)
return 0;
- pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj);
pkgCache::VerIterator &I = GetCpp<pkgCache::VerIterator>(VersionObj);
if(I.end()) {
return HandleErrors(Py_BuildValue("b",false));
@@ -211,7 +208,7 @@ static PyObject *PkgDepCacheGetCandidateVer(PyObject *Self,PyObject *Args)
pkgDepCache *depcache = GetCpp<pkgDepCache *>(Self);
PyObject *PackageObj;
PyObject *CandidateObj;
- if (PyArg_ParseTuple(Args,"O!",&PackageType,&PackageObj) == 0)
+ if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0)
return 0;
pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj);
@@ -222,7 +219,7 @@ static PyObject *PkgDepCacheGetCandidateVer(PyObject *Self,PyObject *Args)
Py_INCREF(Py_None);
return Py_None;
}
- CandidateObj = CppOwnedPyObject_NEW<pkgCache::VerIterator>(PackageObj,&VersionType,I);
+ CandidateObj = CppPyObject_NEW<pkgCache::VerIterator>(PackageObj,&PyVersion_Type,I);
return CandidateObj;
}
@@ -303,7 +300,7 @@ static PyObject *PkgDepCacheMarkKeep(PyObject *Self,PyObject *Args)
pkgDepCache *depcache = GetCpp<pkgDepCache*>(Self);
PyObject *PackageObj;
- if (PyArg_ParseTuple(Args,"O!",&PackageType,&PackageObj) == 0)
+ if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0)
return 0;
pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj);
@@ -319,7 +316,7 @@ static PyObject *PkgDepCacheSetReInstall(PyObject *Self,PyObject *Args)
PyObject *PackageObj;
char value = 0;
- if (PyArg_ParseTuple(Args,"O!b",&PackageType,&PackageObj, &value) == 0)
+ if (PyArg_ParseTuple(Args,"O!b",&PyPackage_Type,&PackageObj, &value) == 0)
return 0;
pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj);
@@ -336,7 +333,7 @@ static PyObject *PkgDepCacheMarkDelete(PyObject *Self,PyObject *Args)
PyObject *PackageObj;
char purge = 0;
- if (PyArg_ParseTuple(Args,"O!|b",&PackageType,&PackageObj, &purge) == 0)
+ if (PyArg_ParseTuple(Args,"O!|b",&PyPackage_Type,&PackageObj, &purge) == 0)
return 0;
pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj);
@@ -354,7 +351,7 @@ static PyObject *PkgDepCacheMarkInstall(PyObject *Self,PyObject *Args)
PyObject *PackageObj;
char autoInst=1;
char fromUser=1;
- if (PyArg_ParseTuple(Args,"O!|bb",&PackageType,&PackageObj,
+ if (PyArg_ParseTuple(Args,"O!|bb",&PyPackage_Type,&PackageObj,
&autoInst, &fromUser) == 0)
return 0;
@@ -367,12 +364,29 @@ static PyObject *PkgDepCacheMarkInstall(PyObject *Self,PyObject *Args)
return HandleErrors(Py_None);
}
+static PyObject *PkgDepCacheMarkAuto(PyObject *Self,PyObject *Args)
+{
+ pkgDepCache *depcache = GetCpp<pkgDepCache*>(Self);
+
+ PyObject *PackageObj;
+ char value = 0;
+ if (PyArg_ParseTuple(Args,"O!b",&PyPackage_Type,&PackageObj, &value) == 0)
+ return 0;
+
+ pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj);
+ depcache->MarkAuto(Pkg,value);
+
+ Py_INCREF(Py_None);
+ return HandleErrors(Py_None);
+}
+
+
static PyObject *PkgDepCacheIsUpgradable(PyObject *Self,PyObject *Args)
{
pkgDepCache *depcache = GetCpp<pkgDepCache *>(Self);
PyObject *PackageObj;
- if (PyArg_ParseTuple(Args,"O!",&PackageType,&PackageObj) == 0)
+ if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0)
return 0;
pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj);
@@ -386,7 +400,7 @@ static PyObject *PkgDepCacheIsGarbage(PyObject *Self,PyObject *Args)
pkgDepCache *depcache = GetCpp<pkgDepCache *>(Self);
PyObject *PackageObj;
- if (PyArg_ParseTuple(Args,"O!",&PackageType,&PackageObj) == 0)
+ if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0)
return 0;
pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj);
@@ -400,7 +414,7 @@ static PyObject *PkgDepCacheIsAutoInstalled(PyObject *Self,PyObject *Args)
pkgDepCache *depcache = GetCpp<pkgDepCache *>(Self);
PyObject *PackageObj;
- if (PyArg_ParseTuple(Args,"O!",&PackageType,&PackageObj) == 0)
+ if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0)
return 0;
pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj);
@@ -414,7 +428,7 @@ static PyObject *PkgDepCacheIsNowBroken(PyObject *Self,PyObject *Args)
pkgDepCache *depcache = GetCpp<pkgDepCache *>(Self);
PyObject *PackageObj;
- if (PyArg_ParseTuple(Args,"O!",&PackageType,&PackageObj) == 0)
+ if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0)
return 0;
pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj);
@@ -428,7 +442,7 @@ static PyObject *PkgDepCacheIsInstBroken(PyObject *Self,PyObject *Args)
pkgDepCache *depcache = GetCpp<pkgDepCache *>(Self);
PyObject *PackageObj;
- if (PyArg_ParseTuple(Args,"O!",&PackageType,&PackageObj) == 0)
+ if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0)
return 0;
pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj);
@@ -443,7 +457,7 @@ static PyObject *PkgDepCacheMarkedInstall(PyObject *Self,PyObject *Args)
pkgDepCache *depcache = GetCpp<pkgDepCache *>(Self);
PyObject *PackageObj;
- if (PyArg_ParseTuple(Args,"O!",&PackageType,&PackageObj) == 0)
+ if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0)
return 0;
pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj);
@@ -458,7 +472,7 @@ static PyObject *PkgDepCacheMarkedUpgrade(PyObject *Self,PyObject *Args)
pkgDepCache *depcache = GetCpp<pkgDepCache *>(Self);
PyObject *PackageObj;
- if (PyArg_ParseTuple(Args,"O!",&PackageType,&PackageObj) == 0)
+ if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0)
return 0;
pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj);
@@ -472,7 +486,7 @@ static PyObject *PkgDepCacheMarkedDelete(PyObject *Self,PyObject *Args)
pkgDepCache *depcache = GetCpp<pkgDepCache *>(Self);
PyObject *PackageObj;
- if (PyArg_ParseTuple(Args,"O!",&PackageType,&PackageObj) == 0)
+ if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0)
return 0;
pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj);
@@ -486,7 +500,7 @@ static PyObject *PkgDepCacheMarkedKeep(PyObject *Self,PyObject *Args)
pkgDepCache *depcache = GetCpp<pkgDepCache *>(Self);
PyObject *PackageObj;
- if (PyArg_ParseTuple(Args,"O!",&PackageType,&PackageObj) == 0)
+ if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0)
return 0;
pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj);
@@ -500,7 +514,7 @@ static PyObject *PkgDepCacheMarkedDowngrade(PyObject *Self,PyObject *Args)
pkgDepCache *depcache = GetCpp<pkgDepCache *>(Self);
PyObject *PackageObj;
- if (PyArg_ParseTuple(Args,"O!",&PackageType,&PackageObj) == 0)
+ if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0)
return 0;
pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj);
@@ -514,7 +528,7 @@ static PyObject *PkgDepCacheMarkedReinstall(PyObject *Self,PyObject *Args)
pkgDepCache *depcache = GetCpp<pkgDepCache *>(Self);
PyObject *PackageObj;
- if (PyArg_ParseTuple(Args,"O!",&PackageType,&PackageObj) == 0)
+ if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0)
return 0;
pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj);
@@ -528,108 +542,163 @@ static PyObject *PkgDepCacheMarkedReinstall(PyObject *Self,PyObject *Args)
static PyMethodDef PkgDepCacheMethods[] =
{
- {"Init",PkgDepCacheInit,METH_VARARGS,"Init the depcache (done on construct automatically)"},
- {"GetCandidateVer",PkgDepCacheGetCandidateVer,METH_VARARGS,"Get candidate version"},
- {"SetCandidateVer",PkgDepCacheSetCandidateVer,METH_VARARGS,"Set candidate version"},
+ {"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"},
// global cache operations
- {"Upgrade",PkgDepCacheUpgrade,METH_VARARGS,"Perform Upgrade (optional boolean argument if dist-upgrade should be performed)"},
- {"FixBroken",PkgDepCacheFixBroken,METH_VARARGS,"Fix broken packages"},
- {"ReadPinFile",PkgDepCacheReadPinFile,METH_VARARGS,"Read the pin policy"},
- {"MinimizeUpgrade",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,"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."},
// Manipulators
- {"MarkKeep",PkgDepCacheMarkKeep,METH_VARARGS,"Mark package for keep"},
- {"MarkDelete",PkgDepCacheMarkDelete,METH_VARARGS,"Mark package for delete (optional boolean argument if it should be purged)"},
- {"MarkInstall",PkgDepCacheMarkInstall,METH_VARARGS,"Mark package for Install"},
- {"SetReInstall",PkgDepCacheSetReInstall,METH_VARARGS,"Set if the package should be reinstalled"},
+ {"mark_keep",PkgDepCacheMarkKeep,METH_VARARGS,"Mark package for keep"},
+ {"mark_delete",PkgDepCacheMarkDelete,METH_VARARGS,"Mark package for delete (optional boolean argument if it should be purged)"},
+ {"mark_install",PkgDepCacheMarkInstall,METH_VARARGS,"Mark package for Install"},
+ {"mark_auto",PkgDepCacheMarkAuto,METH_VARARGS,"mark_auto(pkg: apt_pkg.Package, auto: bool)\n\nMark package as automatically installed."},
+ {"set_reinstall",PkgDepCacheSetReInstall,METH_VARARGS,"Set if the package should be reinstalled"},
// state information
- {"IsUpgradable",PkgDepCacheIsUpgradable,METH_VARARGS,"Is pkg upgradable"},
- {"IsNowBroken",PkgDepCacheIsNowBroken,METH_VARARGS,"Is pkg is now broken"},
- {"IsInstBroken",PkgDepCacheIsInstBroken,METH_VARARGS,"Is pkg broken on the current install"},
- {"IsGarbage",PkgDepCacheIsGarbage,METH_VARARGS,"Is pkg garbage (mark-n-sweep)"},
- {"IsAutoInstalled",PkgDepCacheIsAutoInstalled,METH_VARARGS,"Is pkg marked as auto installed"},
- {"MarkedInstall",PkgDepCacheMarkedInstall,METH_VARARGS,"Is pkg marked for install"},
- {"MarkedUpgrade",PkgDepCacheMarkedUpgrade,METH_VARARGS,"Is pkg marked for upgrade"},
- {"MarkedDelete",PkgDepCacheMarkedDelete,METH_VARARGS,"Is pkg marked for delete"},
- {"MarkedKeep",PkgDepCacheMarkedKeep,METH_VARARGS,"Is pkg marked for keep"},
- {"MarkedReinstall",PkgDepCacheMarkedReinstall,METH_VARARGS,"Is pkg marked for reinstall"},
- {"MarkedDowngrade",PkgDepCacheMarkedDowngrade,METH_VARARGS,"Is pkg marked for downgrade"},
-
+ {"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"},
// Action
- {"Commit", PkgDepCacheCommit, METH_VARARGS, "Commit pending changes"},
+ {"commit", PkgDepCacheCommit, METH_VARARGS, "Commit pending changes"},
{}
};
+#define depcache (GetCpp<pkgDepCache *>(Self))
+static PyObject *PkgDepCacheGetKeepCount(PyObject *Self,void*) {
+ return Py_BuildValue("l", depcache->KeepCount());
+}
+static PyObject *PkgDepCacheGetInstCount(PyObject *Self,void*) {
+ return Py_BuildValue("l", depcache->InstCount());
+}
+static PyObject *PkgDepCacheGetDelCount(PyObject *Self,void*) {
+ return Py_BuildValue("l", depcache->DelCount());
+}
+static PyObject *PkgDepCacheGetBrokenCount(PyObject *Self,void*) {
+ return Py_BuildValue("l", depcache->BrokenCount());
+}
+static PyObject *PkgDepCacheGetUsrSize(PyObject *Self,void*) {
+ return Py_BuildValue("d", depcache->UsrSize());
+}
+static PyObject *PkgDepCacheGetDebSize(PyObject *Self,void*) {
+ return Py_BuildValue("d", depcache->DebSize());
+}
+#undef depcache
+
+static PyObject *PkgDepCacheGetPolicy(PyObject *Self,void*) {
+ PyObject *Owner = GetOwner<pkgDepCache*>(Self);
+ pkgDepCache *DepCache = GetCpp<pkgDepCache*>(Self);
+ pkgPolicy *Policy = (pkgPolicy *)&DepCache->GetPolicy();
+ CppPyObject<pkgPolicy*> *PyPolicy =
+ CppPyObject_NEW<pkgPolicy*>(Owner,&PyPolicy_Type,Policy);
+ // Policy should not be deleted, it is managed by CacheFile.
+ PyPolicy->NoDelete = true;
+ return PyPolicy;
+}
-static PyObject *DepCacheAttr(PyObject *Self,char *Name)
-{
- pkgDepCache *depcache = GetCpp<pkgDepCache *>(Self);
- // size querries
- if(strcmp("KeepCount",Name) == 0)
- return Py_BuildValue("l", depcache->KeepCount());
- else if(strcmp("InstCount",Name) == 0)
- return Py_BuildValue("l", depcache->InstCount());
- else if(strcmp("DelCount",Name) == 0)
- return Py_BuildValue("l", depcache->DelCount());
- else if(strcmp("BrokenCount",Name) == 0)
- return Py_BuildValue("l", depcache->BrokenCount());
- else if(strcmp("UsrSize",Name) == 0)
- return Py_BuildValue("d", depcache->UsrSize());
- else if(strcmp("DebSize",Name) == 0)
- return Py_BuildValue("d", depcache->DebSize());
+static PyGetSetDef PkgDepCacheGetSet[] = {
+ {"broken_count",PkgDepCacheGetBrokenCount},
+ {"deb_size",PkgDepCacheGetDebSize},
+ {"del_count",PkgDepCacheGetDelCount},
+ {"inst_count",PkgDepCacheGetInstCount},
+ {"keep_count",PkgDepCacheGetKeepCount},
+ {"usr_size",PkgDepCacheGetUsrSize},
+ {"policy",PkgDepCacheGetPolicy},
+ {}
+};
+static PyObject *PkgDepCacheNew(PyTypeObject *type,PyObject *Args,PyObject *kwds)
+{
+ PyObject *Owner;
+ char *kwlist[] = {"cache", 0};
+ if (PyArg_ParseTupleAndKeywords(Args,kwds,"O!",kwlist,&PyCache_Type,
+ &Owner) == 0)
+ return 0;
- return Py_FindMethod(PkgDepCacheMethods,Self,Name);
-}
+ // the owner of the Python cache object is a cachefile object, get it
+ PyObject *CacheFilePy = GetOwner<pkgCache*>(Owner);
+ // get the pkgCacheFile from the cachefile
+ pkgCacheFile *CacheF = GetCpp<pkgCacheFile*>(CacheFilePy);
+ // and now the depcache
+ pkgDepCache *depcache = (pkgDepCache *)(*CacheF);
+ CppPyObject<pkgDepCache*> *DepCachePyObj;
+ DepCachePyObj = CppPyObject_NEW<pkgDepCache*>(Owner,type,depcache);
+ // Do not delete the underlying pointer, it is managed by the cachefile.
+ DepCachePyObj->NoDelete = true;
-PyTypeObject PkgDepCacheType =
+ return HandleErrors(DepCachePyObj);
+}
+
+static char *doc_PkgDepCache = "DepCache(cache) -> DepCache() object\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.";
+PyTypeObject PyDepCache_Type =
{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "pkgDepCache", // tp_name
- sizeof(CppOwnedPyObject<pkgDepCache *>), // tp_basicsize
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.DepCache", // tp_name
+ sizeof(CppPyObject<pkgDepCache *>), // tp_basicsize
0, // tp_itemsize
// Methods
- CppOwnedDealloc<pkgDepCache *>, // tp_dealloc
+ CppDeallocPtr<pkgDepCache *>, // tp_dealloc
0, // tp_print
- DepCacheAttr, // tp_getattr
+ 0, // tp_getattr
0, // tp_setattr
0, // tp_compare
0, // tp_repr
0, // tp_as_number
0, // tp_as_sequence
- 0, // tp_as_mapping
+ 0, // tp_as_mapping
0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ _PyAptObject_getattro, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ (Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_HAVE_GC),
+ doc_PkgDepCache, // tp_doc
+ CppTraverse<pkgDepCache *>, // tp_traverse
+ CppClear<pkgDepCache *>, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ PkgDepCacheMethods, // tp_methods
+ 0, // tp_members
+ PkgDepCacheGetSet, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ 0, // tp_alloc
+ PkgDepCacheNew, // tp_new
};
-
+#ifdef COMPAT_0_7
PyObject *GetDepCache(PyObject *Self,PyObject *Args)
{
- PyObject *Owner;
- if (PyArg_ParseTuple(Args,"O!",&PkgCacheType,&Owner) == 0)
- return 0;
-
-
- // the owner of the Python cache object is a cachefile object, get it
- PyObject *CacheFilePy = GetOwner<pkgCache*>(Owner);
- // get the pkgCacheFile from the cachefile
- pkgCacheFile *CacheF = GetCpp<pkgCacheFile*>(CacheFilePy);
- // and now the depcache
- pkgDepCache *depcache = (pkgDepCache *)(*CacheF);
-
- CppOwnedPyObject<pkgDepCache*> *DepCachePyObj;
- DepCachePyObj = CppOwnedPyObject_NEW<pkgDepCache*>(Owner,
- &PkgDepCacheType,
- depcache);
- HandleErrors(DepCachePyObj);
-
- return DepCachePyObj;
+ PyErr_WarnEx(PyExc_DeprecationWarning,"apt_pkg.GetDepCache() is deprecated"
+ ". Please see apt_pkg.DepCache() for the replacement.",1);
+ return PkgDepCacheNew(&PyDepCache_Type,Args,0);
}
-
+#endif
@@ -638,26 +707,33 @@ PyObject *GetDepCache(PyObject *Self,PyObject *Args)
// pkgProblemResolver Class /*{{{*/
// ---------------------------------------------------------------------
-
-
-PyObject *GetPkgProblemResolver(PyObject *Self,PyObject *Args)
+static PyObject *PkgProblemResolverNew(PyTypeObject *type,PyObject *Args,PyObject *kwds)
{
PyObject *Owner;
- if (PyArg_ParseTuple(Args,"O!",&PkgDepCacheType,&Owner) == 0)
+ char *kwlist[] = {"depcache",0};
+ if (PyArg_ParseTupleAndKeywords(Args,kwds,"O!",kwlist,&PyDepCache_Type,
+ &Owner) == 0)
return 0;
pkgDepCache *depcache = GetCpp<pkgDepCache*>(Owner);
pkgProblemResolver *fixer = new pkgProblemResolver(depcache);
- CppOwnedPyObject<pkgProblemResolver*> *PkgProblemResolverPyObj;
- PkgProblemResolverPyObj = CppOwnedPyObject_NEW<pkgProblemResolver*>(Owner,
- &PkgProblemResolverType,
+ CppPyObject<pkgProblemResolver*> *PkgProblemResolverPyObj;
+ PkgProblemResolverPyObj = CppPyObject_NEW<pkgProblemResolver*>(Owner,
+ type,
fixer);
HandleErrors(PkgProblemResolverPyObj);
return PkgProblemResolverPyObj;
-
}
+#ifdef COMPAT_0_7
+PyObject *GetPkgProblemResolver(PyObject *Self,PyObject *Args) {
+ PyErr_WarnEx(PyExc_DeprecationWarning, "apt_pkg.GetPkgProblemResolver() is"
+ " deprecated. Please see apt_pkg.ProblemResolver() for the "
+ "replacement.", 1);
+ return PkgProblemResolverNew(&PyProblemResolver_Type,Args,0);
+}
+#endif
static PyObject *PkgProblemResolverResolve(PyObject *Self,PyObject *Args)
{
@@ -693,7 +769,7 @@ static PyObject *PkgProblemResolverProtect(PyObject *Self,PyObject *Args)
{
pkgProblemResolver *fixer = GetCpp<pkgProblemResolver *>(Self);
PyObject *PackageObj;
- if (PyArg_ParseTuple(Args,"O!",&PackageType,&PackageObj) == 0)
+ if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0)
return 0;
pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj);
fixer->Protect(Pkg);
@@ -705,7 +781,7 @@ static PyObject *PkgProblemResolverRemove(PyObject *Self,PyObject *Args)
{
pkgProblemResolver *fixer = GetCpp<pkgProblemResolver *>(Self);
PyObject *PackageObj;
- if (PyArg_ParseTuple(Args,"O!",&PackageType,&PackageObj) == 0)
+ if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0)
return 0;
pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj);
fixer->Remove(Pkg);
@@ -717,7 +793,7 @@ static PyObject *PkgProblemResolverClear(PyObject *Self,PyObject *Args)
{
pkgProblemResolver *fixer = GetCpp<pkgProblemResolver *>(Self);
PyObject *PackageObj;
- if (PyArg_ParseTuple(Args,"O!",&PackageType,&PackageObj) == 0)
+ if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0)
return 0;
pkgCache::PkgIterator &Pkg = GetCpp<pkgCache::PkgIterator>(PackageObj);
fixer->Clear(Pkg);
@@ -738,37 +814,27 @@ 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)"},
- {"InstallProtect", PkgProblemResolverInstallProtect, METH_VARARGS, "ProtectInstalled()"},
+ {"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()"},
// Actions
- {"Resolve", PkgProblemResolverResolve, METH_VARARGS, "Try to intelligently resolve problems by installing and removing packages"},
- {"ResolveByKeep", PkgProblemResolverResolveByKeep, METH_VARARGS, "Try to resolv problems only by using keep"},
+ {"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"},
{}
};
-
-static PyObject *ProblemResolverAttr(PyObject *Self,char *Name)
+PyTypeObject PyProblemResolver_Type =
{
- pkgProblemResolver *fixer = GetCpp<pkgProblemResolver *>(Self);
-
- return Py_FindMethod(PkgProblemResolverMethods,Self,Name);
-}
-
-
-PyTypeObject PkgProblemResolverType =
-{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "pkgProblemResolver", // tp_name
- sizeof(CppOwnedPyObject<pkgProblemResolver *>), // tp_basicsize
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.ProblemResolver", // tp_name
+ sizeof(CppPyObject<pkgProblemResolver *>), // tp_basicsize
0, // tp_itemsize
// Methods
- CppOwnedDealloc<pkgProblemResolver *>, // tp_dealloc
+ CppDeallocPtr<pkgProblemResolver *>,// tp_dealloc
0, // tp_print
- ProblemResolverAttr, // tp_getattr
+ 0, // tp_getattr
0, // tp_setattr
0, // tp_compare
0, // tp_repr
@@ -776,6 +842,32 @@ PyTypeObject PkgProblemResolverType =
0, // tp_as_sequence
0, // tp_as_mapping
0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ _PyAptObject_getattro, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ (Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_HAVE_GC),
+ "ProblemResolver Object", // tp_doc
+ CppTraverse<pkgProblemResolver *>, // tp_traverse
+ CppClear<pkgProblemResolver *>, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ PkgProblemResolverMethods, // tp_methods
+ 0, // tp_members
+ 0, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ 0, // tp_alloc
+ PkgProblemResolverNew, // tp_new
};
/*}}}*/
@@ -797,7 +889,6 @@ static PyObject *PkgActionGroupRelease(PyObject *Self,PyObject *Args)
static PyObject *PkgActionGroupEnter(PyObject *Self,PyObject *Args) {
if (PyArg_ParseTuple(Args,"") == 0)
return 0;
- Py_INCREF(Self);
return Self;
}
static PyObject *PkgActionGroupExit(PyObject *Self,PyObject *Args) {
@@ -806,35 +897,60 @@ static PyObject *PkgActionGroupExit(PyObject *Self,PyObject *Args) {
Py_RETURN_FALSE;
}
-
static PyMethodDef PkgActionGroupMethods[] =
{
{"release", PkgActionGroupRelease, METH_VARARGS, "release()"},
- {"__enter__", PkgActionGroupEnter, METH_VARARGS, "__enter__() -> self"},
- {"__exit__", PkgActionGroupExit, METH_VARARGS, "__exit__()"},
+ {"__exit__", PkgActionGroupExit, METH_VARARGS, "__exit__(...) -> "
+ "Release the action group, for 'with' statement."},
+ {"__enter__", PkgActionGroupEnter, METH_VARARGS, "__enter__() -> "
+ "Enter, for the 'with' statement. Does nothing."},
{}
};
-
-static PyObject *ActionGroupAttr(PyObject *Self,char *Name)
+static PyObject *PkgActionGroupNew(PyTypeObject *type,PyObject *Args,PyObject *kwds)
{
- pkgDepCache::ActionGroup *ag = GetCpp<pkgDepCache::ActionGroup*>(Self);
+ PyObject *Owner;
+ char *kwlist[] = {"depcache", 0};
+ if (PyArg_ParseTupleAndKeywords(Args,kwds,"O!",kwlist,&PyDepCache_Type,
+ &Owner) == 0)
+ return 0;
+
+ pkgDepCache *depcache = GetCpp<pkgDepCache*>(Owner);
+ pkgDepCache::ActionGroup *group = new pkgDepCache::ActionGroup(*depcache);
+ CppPyObject<pkgDepCache::ActionGroup*> *PkgActionGroupPyObj;
+ PkgActionGroupPyObj = CppPyObject_NEW<pkgDepCache::ActionGroup*>(Owner,
+ type,
+ group);
+ HandleErrors(PkgActionGroupPyObj);
+
+ return PkgActionGroupPyObj;
- return Py_FindMethod(PkgActionGroupMethods,Self,Name);
}
+static char *doc_PkgActionGroup = "ActionGroup(depcache)\n\n"
+ "Create a new ActionGroup() object. The parameter *depcache* refers to an\n"
+ "apt_pkg.DepCache() object.\n\n"
+ "ActionGroups disable certain cleanup actions, so modifying many packages\n"
+ "is much faster.\n\n"
+ "ActionGroup() can also be used with the 'with' statement, but be aware\n"
+ "that the ActionGroup() is active as soon as it is created, and not just\n"
+ "when entering the context. This means you can write::\n\n"
+ " with apt_pkg.ActionGroup(depcache):\n"
+ " depcache.markInstall(pkg)\n\n"
+ "Once the block of the with statement is left, the action group is \n"
+ "automatically released from the cache.";
+
-PyTypeObject PkgActionGroupType =
+PyTypeObject PyActionGroup_Type =
{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "pkgActionGroup", // tp_name
- sizeof(CppOwnedPyObject<pkgDepCache::ActionGroup*>), // tp_basicsize
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.ActionGroup", // tp_name
+ sizeof(CppPyObject<pkgDepCache::ActionGroup*>), // tp_basicsize
0, // tp_itemsize
// Methods
- CppOwnedDealloc<pkgDepCache::ActionGroup*>, // tp_dealloc
+ CppDeallocPtr<pkgDepCache::ActionGroup*>, // tp_dealloc
0, // tp_print
- ActionGroupAttr, // tp_getattr
+ 0, // tp_getattr
0, // tp_setattr
0, // tp_compare
0, // tp_repr
@@ -842,25 +958,43 @@ PyTypeObject PkgActionGroupType =
0, // tp_as_sequence
0, // tp_as_mapping
0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ (Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_HAVE_GC),
+ doc_PkgActionGroup, // tp_doc
+ CppTraverse<pkgDepCache::ActionGroup*>, // tp_traverse
+ CppClear<pkgDepCache::ActionGroup*>, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ PkgActionGroupMethods, // tp_methods
+ 0, // tp_members
+ 0, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ 0, // tp_alloc
+ PkgActionGroupNew, // tp_new
};
+#ifdef COMPAT_0_7
PyObject *GetPkgActionGroup(PyObject *Self,PyObject *Args)
{
- PyObject *Owner;
- if (PyArg_ParseTuple(Args,"O!",&PkgDepCacheType,&Owner) == 0)
- return 0;
-
- pkgDepCache *depcache = GetCpp<pkgDepCache*>(Owner);
- pkgDepCache::ActionGroup *group = new pkgDepCache::ActionGroup(*depcache);
- CppOwnedPyObject<pkgDepCache::ActionGroup*> *PkgActionGroupPyObj;
- PkgActionGroupPyObj = CppOwnedPyObject_NEW<pkgDepCache::ActionGroup*>(Owner,
- &PkgActionGroupType,
- group);
- HandleErrors(PkgActionGroupPyObj);
-
- return PkgActionGroupPyObj;
-
+ PyErr_WarnEx(PyExc_DeprecationWarning, "apt_pkg.GetPkgActionGroup() is "
+ "deprecated. Please see apt_pkg.ActionGroup() for the "
+ "replacement.", 1);
+ return PkgActionGroupNew(&PyActionGroup_Type,Args,0);
}
+#endif
/*}}}*/
diff --git a/python/generic.cc b/python/generic.cc
index 7309d978..f0980f2b 100644
--- a/python/generic.cc
+++ b/python/generic.cc
@@ -9,6 +9,8 @@
/*}}}*/
// Include Files /*{{{*/
#include "generic.h"
+using namespace std;
+
#include <apt-pkg/error.h>
/*}}}*/
@@ -25,14 +27,15 @@ PyObject *HandleErrors(PyObject *Res)
return Res;
}
- if (Res != 0)
+ if (Res != 0) {
Py_DECREF(Res);
+ }
- string Err;
+ std::string Err;
int errcnt = 0;
while (_error->empty() == false)
{
- string Msg;
+ std::string Msg;
bool Type = _error->PopMessage(Msg);
if (errcnt > 0)
Err.append(", ");
@@ -45,6 +48,75 @@ PyObject *HandleErrors(PyObject *Res)
PyErr_SetString(PyExc_SystemError,Err.c_str());
return 0;
}
+
+# ifdef COMPAT_0_7
+// Helpers for deprecation.
+
+// Given the name of the old attribute, return the name of the new attribute
+// in a PyObject.
+static PyObject *_PyApt_NewNameForAttribute(const char *attr) {
+ // Some exceptions from the standard algorithm.
+ if (strcasecmp(attr, "FileName") == 0) return PyString_FromString("filename");
+ if (strcasecmp(attr, "DestFile") == 0) return PyString_FromString("destfile");
+ if (strcasecmp(attr, "FileSize") == 0) return PyString_FromString("filesize");
+ if (strcasecmp(attr, "SubTree") == 0) return PyString_FromString("subtree");
+ if (strcasecmp(attr, "ReadPinFile") == 0) return PyString_FromString("read_pinfile");
+ if (strcasecmp(attr, "SetReInstall") == 0) return PyString_FromString("set_reinstall");
+ if (strcasecmp(attr, "URI") == 0) return PyString_FromString("uri");
+ if (strcasecmp(attr, "MD5Hash") == 0) return PyString_FromString("md5_hash");
+ if (strcasecmp(attr, "SHA1Hash") == 0) return PyString_FromString("sha1_hash");
+ if (strcasecmp(attr, "SHA256Hash") == 0) return PyString_FromString("sha256_hash");
+ if (strcasecmp(attr, "UntranslatedDepType") == 0) return PyString_FromString("dep_type_untranslated");
+ size_t attrlen = strlen(attr);
+ // Reserve the old name + 5, this should reduce resize to a minimum.
+ string new_name;
+ new_name.reserve(attrlen + 5);
+ for(unsigned int i=0; i < attrlen; i++) {
+ // Replace all uppercase ASCII characters with their lower-case ones.
+ if (attr[i] > 64 && attr[i] < 91) {
+ if (i > 0)
+ new_name += "_";
+ new_name += attr[i] + 32;
+ } else {
+ new_name += attr[i];
+ }
+ }
+ return CppPyString(new_name);
+}
+
+// Handle deprecated attributes by setting a warning and returning the new
+// attribute.
+PyObject *_PyAptObject_getattro(PyObject *self, PyObject *attr) {
+ PyObject *value = PyObject_GenericGetAttr(self, attr);
+ if (value == NULL) {
+ PyObject *ptype, *pvalue, *ptraceback;
+ PyErr_Fetch(&ptype, &pvalue, &ptraceback);
+ const char *attrname = PyObject_AsString(attr);
+ PyObject *newattr = _PyApt_NewNameForAttribute(attrname);
+ value = PyObject_GenericGetAttr(self, newattr);
+ if (value != NULL) {
+ const char *newattrname = PyString_AsString(newattr);
+ const char *cls = self->ob_type->tp_name;
+ char *warning_string = new char[strlen(newattrname) + strlen(cls) +
+ strlen(attrname) + 66];
+ sprintf(warning_string, "Attribute '%s' of the '%s' object is "
+ "deprecated, use '%s' instead.", attrname, cls, newattrname);
+ PyErr_WarnEx(PyExc_DeprecationWarning, warning_string, 1);
+ delete[] warning_string;
+ } else {
+ Py_XINCREF(ptype);
+ Py_XINCREF(pvalue);
+ Py_XINCREF(ptraceback);
+ PyErr_Restore(ptype, pvalue, ptraceback);
+ }
+ Py_DECREF(newattr);
+ Py_XDECREF(ptype);
+ Py_XDECREF(pvalue);
+ Py_XDECREF(ptraceback);
+ }
+ return value;
+}
+# endif //COMPAT_0_7
/*}}}*/
// ListToCharChar - Convert a list to an array of char char /*{{{*/
// ---------------------------------------------------------------------
diff --git a/python/generic.h b/python/generic.h
index d2fcf42a..31c1bc2d 100644
--- a/python/generic.h
+++ b/python/generic.h
@@ -29,12 +29,81 @@
#include <Python.h>
#include <string>
+#include <iostream>
#include <new>
#if PYTHON_API_VERSION < 1013
typedef int Py_ssize_t;
#endif
+/* Define compatibility for Python 3.
+ *
+ * We will use the names PyString_* to refer to the default string type
+ * of the current Python version (PyString on 2.X, PyUnicode on 3.X).
+ *
+ * When we really need unicode strings, we will use PyUnicode_* directly, as
+ * long as it exists in Python 2 and Python 3.
+ *
+ * When we want bytes in Python 3, we use PyBytes*_ instead of PyString_* and
+ * define aliases from PyBytes_* to PyString_* for Python 2.
+ */
+
+#if PY_MAJOR_VERSION >= 3
+#define PyString_Check PyUnicode_Check
+#define PyString_FromString PyUnicode_FromString
+#define PyString_FromStringAndSize PyUnicode_FromStringAndSize
+#define PyString_AsString PyUnicode_AsString
+#define PyString_FromFormat PyUnicode_FromFormat
+#define PyString_Type PyUnicode_Type
+#define PyInt_Check PyLong_Check
+#define PyInt_AsLong PyLong_AsLong
+// Force 0.7 compatibility to be off in Python 3 builds
+#undef COMPAT_0_7
+#else
+// Compatibility for Python 2.5 and previous.
+#if (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 5)
+#define PyBytes_Check PyString_Check
+#define PyBytes_AS_STRING PyString_AS_STRING
+#define PyBytes_AsString PyString_AsString
+#define PyBytes_AsStringAndSize PyString_AsStringAndSize
+#define PyBytes_FromStringAndSize PyString_FromStringAndSize
+#define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
+#endif
+#endif
+
+// Hacks to make Python 2.4 build.
+#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 4
+#define PyErr_WarnEx(cat,msg,stacklevel) PyErr_Warn(cat,msg)
+#endif
+
+
+static inline const char *PyUnicode_AsString(PyObject *op) {
+ // Convert to bytes object, using the default encoding.
+ PyObject *bytes = PyUnicode_AsEncodedString(op,0,0);
+ return bytes ? PyBytes_AS_STRING(bytes) : 0;
+}
+
+// Convert any type of string based object to a const char.
+#if PY_MAJOR_VERSION < 3
+static inline const char *PyObject_AsString(PyObject *object) {
+ if (PyBytes_Check(object))
+ return PyBytes_AsString(object);
+ else if (PyUnicode_Check(object))
+ return PyUnicode_AsString(object);
+ else
+ PyErr_SetString(PyExc_TypeError, "Argument must be str.");
+ return 0;
+}
+#else
+static inline const char *PyObject_AsString(PyObject *object) {
+ if (PyUnicode_Check(object) == 0) {
+ PyErr_SetString(PyExc_TypeError, "Argument must be str.");
+ return 0;
+ }
+ return PyUnicode_AsString(object);
+}
+#endif
+
template <class T> struct CppPyObject : public PyObject
{
// We are only using CppPyObject and friends as dumb structs only, ie the
@@ -42,18 +111,22 @@ template <class T> struct CppPyObject : public PyObject
// However if T doesn't have a default c'tor C++ doesn't generate one for
// CppPyObject (since it can't know how it should initialize Object).
//
- // This causes problems then in CppOwnedPyObject, for which C++ can't create
+ // This causes problems then in CppPyObject, for which C++ can't create
// a c'tor that calls the base class c'tor (which causes a compilation
// error).
// So basically having the c'tor here removes the need for T to have a
// default c'tor, which is not always desireable.
CppPyObject() { };
- T Object;
-};
-template <class T> struct CppOwnedPyObject : public CppPyObject<T>
-{
+ // The owner of the object. The object keeps a reference to it during its
+ // lifetime.
PyObject *Owner;
+
+ // Flag which causes the underlying object to not be deleted.
+ bool NoDelete;
+
+ // The underlying C++ object.
+ T Object;
};
template <class T>
@@ -65,66 +138,74 @@ inline T &GetCpp(PyObject *Obj)
template <class T>
inline PyObject *GetOwner(PyObject *Obj)
{
- return ((CppOwnedPyObject<T> *)Obj)->Owner;
+ return ((CppPyObject<T> *)Obj)->Owner;
}
-// Generic 'new' functions
+
template <class T>
-inline CppPyObject<T> *CppPyObject_NEW(PyTypeObject *Type)
+inline CppPyObject<T> *CppPyObject_NEW(PyObject *Owner,PyTypeObject *Type)
{
- CppPyObject<T> *New = PyObject_NEW(CppPyObject<T>,Type);
+ #ifdef ALLOC_DEBUG
+ std::cerr << "=== ALLOCATING " << Type->tp_name << "+ ===\n";
+ #endif
+ CppPyObject<T> *New = (CppPyObject<T>*)Type->tp_alloc(Type, 0);
new (&New->Object) T;
+ New->Owner = Owner;
+ Py_XINCREF(Owner);
return New;
}
template <class T,class A>
-inline CppPyObject<T> *CppPyObject_NEW(PyTypeObject *Type,A const &Arg)
+inline CppPyObject<T> *CppPyObject_NEW(PyObject *Owner, PyTypeObject *Type,A const &Arg)
{
- CppPyObject<T> *New = PyObject_NEW(CppPyObject<T>,Type);
+ #ifdef ALLOC_DEBUG
+ std::cerr << "=== ALLOCATING " << Type->tp_name << "+ ===\n";
+ #endif
+ CppPyObject<T> *New = (CppPyObject<T>*)Type->tp_alloc(Type, 0);
new (&New->Object) T(Arg);
+ New->Owner = Owner;
+ Py_XINCREF(Owner);
return New;
}
+// Traversal and Clean for objects
template <class T>
-inline CppOwnedPyObject<T> *CppOwnedPyObject_NEW(PyObject *Owner,
- PyTypeObject *Type)
-{
- CppOwnedPyObject<T> *New = PyObject_NEW(CppOwnedPyObject<T>,Type);
- new (&New->Object) T;
- New->Owner = Owner;
- Py_INCREF(Owner);
- return New;
+int CppTraverse(PyObject *self, visitproc visit, void* arg) {
+ Py_VISIT(((CppPyObject<T> *)self)->Owner);
+ return 0;
}
-template <class T,class A>
-inline CppOwnedPyObject<T> *CppOwnedPyObject_NEW(PyObject *Owner,
- PyTypeObject *Type,A const &Arg)
-{
- CppOwnedPyObject<T> *New = PyObject_NEW(CppOwnedPyObject<T>,Type);
- new (&New->Object) T(Arg);
- New->Owner = Owner;
- if (Owner != 0)
- Py_INCREF(Owner);
- return New;
+template <class T>
+int CppClear(PyObject *self) {
+ Py_CLEAR(((CppPyObject<T> *)self)->Owner);
+ return 0;
}
-// Generic Dealloc type functions
template <class T>
-void CppDealloc(PyObject *Obj)
+void CppDealloc(PyObject *iObj)
{
- GetCpp<T>(Obj).~T();
- PyObject_DEL(Obj);
+ #ifdef ALLOC_DEBUG
+ std::cerr << "=== DEALLOCATING " << iObj->ob_type->tp_name << "+ ===\n";
+ #endif
+ CppPyObject<T> *Obj = (CppPyObject<T> *)iObj;
+ if (!((CppPyObject<T>*)Obj)->NoDelete)
+ Obj->Object.~T();
+ CppClear<T>(iObj);
+ iObj->ob_type->tp_free(iObj);
}
+
template <class T>
-void CppOwnedDealloc(PyObject *iObj)
+void CppDeallocPtr(PyObject *iObj)
{
- CppOwnedPyObject<T> *Obj = (CppOwnedPyObject<T> *)iObj;
- Obj->Object.~T();
- if (Obj->Owner != 0) {
- Py_DECREF(Obj->Owner);
- }
- PyObject_DEL(Obj);
+ #ifdef ALLOC_DEBUG
+ std::cerr << "=== DEALLOCATING " << iObj->ob_type->tp_name << "*+ ===\n";
+ #endif
+ CppPyObject<T> *Obj = (CppPyObject<T> *)iObj;
+ if (!((CppPyObject<T>*)Obj)->NoDelete)
+ delete Obj->Object;
+ CppClear<T>(iObj);
+ iObj->ob_type->tp_free(iObj);
}
inline PyObject *CppPyString(std::string Str)
@@ -146,4 +227,10 @@ PyObject *HandleErrors(PyObject *Res = 0);
const char **ListToCharChar(PyObject *List,bool NullTerm = false);
PyObject *CharCharToList(const char **List,unsigned long Size = 0);
+# ifdef COMPAT_0_7
+PyObject *_PyAptObject_getattro(PyObject *self, PyObject *attr);
+# else
+# define _PyAptObject_getattro 0
+# endif
+
#endif
diff --git a/python/hashes.cc b/python/hashes.cc
new file mode 100644
index 00000000..d0b0fb0c
--- /dev/null
+++ b/python/hashes.cc
@@ -0,0 +1,136 @@
+/* hashes.cc - Wrapper around apt-pkg's Hashes.
+ *
+ * Copyright 2009 Julian Andres Klode <jak@debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+#include <Python.h>
+#include "generic.h"
+#include "apt_pkgmodule.h"
+#include <apt-pkg/hashes.h>
+
+static PyObject *hashes_new(PyTypeObject *type,PyObject *args,
+ PyObject *kwds)
+{
+ return CppPyObject_NEW<Hashes>(NULL, type);
+}
+
+static int hashes_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ PyObject *object = 0;
+ int Fd;
+ char *kwlist[] = {"object", NULL};
+
+ if (PyArg_ParseTupleAndKeywords(args, kwds, "|O:__init__", kwlist,
+ &object) == 0)
+ return -1;
+ if (object == 0)
+ return 0;
+ Hashes &hashes = GetCpp<Hashes>(self);
+
+ if (PyBytes_Check(object) != 0) {
+ char *s;
+ Py_ssize_t len;
+ PyBytes_AsStringAndSize(object, &s, &len);
+ hashes.Add((const unsigned char*)s, len);
+ }
+ else if ((Fd = PyObject_AsFileDescriptor(object)) != -1) {
+ struct stat St;
+ if (fstat(Fd, &St) != 0 || hashes.AddFD(Fd, St.st_size) == false) {
+ PyErr_SetFromErrno(PyExc_SystemError);
+ return -1;
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "__init__() only understand strings and files");
+ return -1;
+ }
+ return 0;
+}
+
+static PyObject *hashes_get_md5(PyObject *self, void*)
+{
+ return CppPyString(GetCpp<Hashes>(self).MD5.Result().Value());
+}
+
+static PyObject *hashes_get_sha1(PyObject *self, void*)
+{
+ return CppPyString(GetCpp<Hashes>(self).SHA1.Result().Value());
+}
+
+static PyObject *hashes_get_sha256(PyObject *self, void*)
+{
+ return CppPyString(GetCpp<Hashes>(self).SHA256.Result().Value());
+}
+
+static PyGetSetDef hashes_getset[] = {
+ {"md5",hashes_get_md5,0,"The MD5Sum of the file as a string."},
+ {"sha1",hashes_get_sha1,0,"The SHA1Sum of the file as a string."},
+ {"sha256",hashes_get_sha256,0,"The SHA256Sum of the file as a string."},
+ {}
+};
+
+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.";
+
+PyTypeObject PyHashes_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.Hashes", // tp_name
+ sizeof(CppPyObject<Hashes>), // tp_basicsize
+ 0, // tp_itemsize
+ // Methods
+ CppDealloc<Hashes>, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_BASETYPE,
+ hashes_doc, // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ 0, // tp_methods
+ 0, // tp_members
+ hashes_getset, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ hashes_init, // tp_init
+ 0, // tp_alloc
+ hashes_new, // tp_new
+};
diff --git a/python/hashstring.cc b/python/hashstring.cc
new file mode 100644
index 00000000..59d533f8
--- /dev/null
+++ b/python/hashstring.cc
@@ -0,0 +1,134 @@
+/* hashstring.cc - Wrapper around HashString
+ *
+ * Copyright 2009 Julian Andres Klode <jak@debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+#include <Python.h>
+#include "generic.h"
+#include "apt_pkgmodule.h"
+#include <apt-pkg/hashes.h>
+
+static PyObject *hashstring_new(PyTypeObject *type,PyObject *Args,
+ PyObject *kwds)
+{
+ char *Type = NULL;
+ char *Hash = NULL;
+ char *kwlist[] = {"type", "hash", NULL};
+ if (PyArg_ParseTupleAndKeywords(Args, kwds, "s|s:__new__", kwlist, &Type,
+ &Hash) == 0)
+ return 0;
+ CppPyObject<HashString*> *PyObj = CppPyObject_NEW<HashString*>(NULL, type);
+ if (Hash)
+ PyObj->Object = new HashString(Type,Hash);
+ else // Type is the combined form now (i.e. type:hash)
+ PyObj->Object = new HashString(Type);
+ return PyObj;
+}
+
+static PyObject *hashstring_repr(PyObject *self)
+{
+ HashString *hash = GetCpp<HashString*>(self);
+ return PyString_FromFormat("<%s object: \"%s\">", self->ob_type->tp_name,
+ hash->toStr().c_str());
+}
+
+static PyObject *hashstring_str(PyObject *self)
+{
+ HashString *hash = GetCpp<HashString*>(self);
+ return CppPyString(hash->toStr());
+}
+
+static PyObject *hashstring_get_hashtype(PyObject *self)
+{
+ HashString *hash = GetCpp<HashString*>(self);
+ return CppPyString(hash->HashType());
+}
+
+static char *hashstring_verify_file_doc =
+ "verify_file(filename: str) -> bool\n\n"
+ "Verify that the file indicated by filename matches the hash.";
+
+static PyObject *hashstring_verify_file(PyObject *self,PyObject *args)
+{
+ HashString *hash = GetCpp<HashString*>(self);
+ char *filename;
+ if (PyArg_ParseTuple(args, "s:verify_file", &filename) == 0)
+ return 0;
+ return PyBool_FromLong(hash->VerifyFile(filename));
+}
+
+static PyMethodDef hashstring_methods[] = {
+ {"verify_file",hashstring_verify_file,METH_VARARGS,
+ hashstring_verify_file_doc},
+ {NULL}
+};
+
+static PyGetSetDef hashstring_getset[] = {
+ {"hashtype",(getter)hashstring_get_hashtype,0,
+ "The type of the hash, as a string (possible: MD5Sum,SHA1,SHA256)."},
+ {NULL}
+};
+
+static char *hashstring_doc =
+ "HashString(type, hash) OR HashString('type:hash')\n\n"
+ "Create a new HashString object. The first form allows you to specify\n"
+ "a type and a hash, and the second form a single string where type and\n"
+ "hash are separated by a colon, e.g.::\n\n"
+ " HashString('MD5Sum', '6cc1b6e6655e3555ac47e5b5fe26d04e')\n\n"
+ "Valid options for 'type' are: MD5Sum, SHA1, SHA256.";
+PyTypeObject PyHashString_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.HashString", // tp_name
+ sizeof(CppPyObject<HashString*>), // tp_basicsize
+ 0, // tp_itemsize
+ // Methods
+ CppDeallocPtr<HashString*>, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ hashstring_repr, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ hashstring_str, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_BASETYPE,
+ hashstring_doc, // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ hashstring_methods, // tp_methods
+ 0, // tp_members
+ hashstring_getset, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ 0, // tp_alloc
+ hashstring_new, // tp_new
+};
diff --git a/python/indexfile.cc b/python/indexfile.cc
index 107eae27..c6d0b1cc 100644
--- a/python/indexfile.cc
+++ b/python/indexfile.cc
@@ -15,76 +15,101 @@
#include <Python.h>
-static PyObject *PackageIndexFileArchiveURI(PyObject *Self,PyObject *Args)
+static PyObject *IndexFileArchiveURI(PyObject *Self,PyObject *Args)
{
pkgIndexFile *File = GetCpp<pkgIndexFile*>(Self);
char *path;
if (PyArg_ParseTuple(Args, "s",&path) == 0)
return 0;
-
return HandleErrors(Safe_FromString(File->ArchiveURI(path).c_str()));
}
-static PyMethodDef PackageIndexFileMethods[] =
+static PyMethodDef IndexFileMethods[] =
{
- {"ArchiveURI",PackageIndexFileArchiveURI,METH_VARARGS,"Returns the ArchiveURI"},
+ {"archive_uri",IndexFileArchiveURI,METH_VARARGS,"Returns the ArchiveURI"},
{}
};
-
-static PyObject *PackageIndexFileAttr(PyObject *Self,char *Name)
-{
- pkgIndexFile *File = GetCpp<pkgIndexFile*>(Self);
- if (strcmp("Label",Name) == 0)
- return Safe_FromString(File->GetType()->Label);
- else if (strcmp("Describe",Name) == 0)
- return Safe_FromString(File->Describe().c_str());
- else if (strcmp("Exists",Name) == 0)
- return Py_BuildValue("i",(File->Exists()));
- else if (strcmp("HasPackages",Name) == 0)
- return Py_BuildValue("i",(File->HasPackages()));
- else if (strcmp("Size",Name) == 0)
- return Py_BuildValue("i",(File->Size()));
- else if (strcmp("IsTrusted",Name) == 0)
- return Py_BuildValue("i",(File->IsTrusted()));
-
- return Py_FindMethod(PackageIndexFileMethods,Self,Name);
+#define File (GetCpp<pkgIndexFile*>(Self))
+static PyObject *IndexFileGetLabel(PyObject *Self,void*) {
+ return Safe_FromString(File->GetType()->Label);
+}
+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()));
+}
+static PyObject *IndexFileGetHasPackages(PyObject *Self,void*) {
+ return Py_BuildValue("i",(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()));
+}
+#undef File
-static PyObject *PackageIndexFileRepr(PyObject *Self)
+#define S(x) (x ? x : "")
+static PyObject *IndexFileRepr(PyObject *Self)
{
pkgIndexFile *File = GetCpp<pkgIndexFile*>(Self);
-
- char S[1024];
- snprintf(S,sizeof(S),"<pkIndexFile object: "
+ return PyString_FromFormat("<pkIndexFile object: "
"Label:'%s' Describe='%s' Exists='%i' "
- "HasPackages='%i' Size='%i' "
+ "HasPackages='%i' Size='%lu' "
"IsTrusted='%i' ArchiveURI='%s'>",
- File->GetType()->Label, File->Describe().c_str(), File->Exists(),
+ S(File->GetType()->Label), File->Describe().c_str(), File->Exists(),
File->HasPackages(), File->Size(),
File->IsTrusted(), File->ArchiveURI("").c_str());
- return PyString_FromString(S);
}
+#undef S
+
+static PyGetSetDef IndexFileGetSet[] = {
+ {"describe",IndexFileGetDescribe},
+ {"exists",IndexFileGetExists},
+ {"has_packages",IndexFileGetHasPackages},
+ {"is_trusted",IndexFileGetIsTrusted},
+ {"label",IndexFileGetLabel},
+ {"size",IndexFileGetSize},
+ {}
+};
-PyTypeObject PackageIndexFileType =
+PyTypeObject PyIndexFile_Type =
{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "pkgIndexFile", // tp_name
- sizeof(CppOwnedPyObject<pkgIndexFile*>), // tp_basicsize
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.IndexFile", // tp_name
+ sizeof(CppPyObject<pkgIndexFile*>), // tp_basicsize
0, // tp_itemsize
// Methods
- CppOwnedDealloc<pkgIndexFile*>, // tp_dealloc
+ // Not ..Ptr, because the pointer is managed somewhere else.
+ CppDeallocPtr<pkgIndexFile*>, // tp_dealloc
0, // tp_print
- PackageIndexFileAttr, // tp_getattr
+ 0, // tp_getattr
0, // tp_setattr
0, // tp_compare
- PackageIndexFileRepr, // tp_repr
+ IndexFileRepr, // tp_repr
0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ _PyAptObject_getattro, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags
+ "IndexFile Object", // tp_doc
+ CppTraverse<pkgIndexFile*>, // tp_traverse
+ CppClear<pkgIndexFile*>, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ IndexFileMethods, // tp_methods
+ 0, // tp_members
+ IndexFileGetSet, // tp_getset
};
diff --git a/python/indexrecords.cc b/python/indexrecords.cc
new file mode 100644
index 00000000..80960160
--- /dev/null
+++ b/python/indexrecords.cc
@@ -0,0 +1,127 @@
+/*
+ * indexrecords.cc - Wrapper around indexRecords
+ *
+ * Copyright 2009 Julian Andres Klode <jak@debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+#include <Python.h>
+#include "apt_pkgmodule.h"
+#include "generic.h"
+#include <apt-pkg/indexrecords.h>
+
+static PyObject *indexrecords_new(PyTypeObject *type,PyObject *Args,
+ PyObject *kwds)
+{
+ char * kwlist[] = {NULL};
+ if (PyArg_ParseTupleAndKeywords(Args, kwds, "", kwlist) == 0)
+ return 0;
+ indexRecords *records = new indexRecords();
+ CppPyObject<indexRecords*> *New = CppPyObject_NEW<indexRecords*>(NULL, type,
+ records);
+ return New;
+}
+
+static PyObject *indexrecords_load(PyObject *self,PyObject *args)
+{
+ const char *filename;
+ if (PyArg_ParseTuple(args, "s", &filename) == 0)
+ return 0;
+ indexRecords *records = GetCpp<indexRecords*>(self);
+ return HandleErrors(Py_BuildValue("i", 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 PyObject *indexrecords_lookup(PyObject *self,PyObject *args)
+{
+ const char *keyname;
+ if (PyArg_ParseTuple(args, "s", &keyname) == 0)
+ return 0;
+ indexRecords *records = GetCpp<indexRecords*>(self);
+ const indexRecords::checkSum *result = records->Lookup(keyname);
+ if (result == 0) {
+ PyErr_SetString(PyExc_KeyError,keyname);
+ return 0;
+ }
+ // Copy the HashString(), to prevent crashes and to not require the
+ // indexRecords object to exist.
+ PyObject *py_hash = PyHashString_FromCpp(new HashString(result->Hash), true, NULL);
+ PyObject *value = Py_BuildValue("(Oi)",py_hash,result->Size);
+ Py_DECREF(py_hash);
+ return value;
+}
+
+static PyObject *indexrecords_get_dist(PyObject *self)
+{
+ indexRecords *records = GetCpp<indexRecords*>(self);
+ return HandleErrors(PyString_FromString(records->GetDist().c_str()));
+}
+
+static PyMethodDef indexrecords_methods[] = {
+ {"load",indexrecords_load,METH_VARARGS,
+ "load(filename: str)\n\nLoad 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."},
+ {"lookup",indexrecords_lookup,METH_VARARGS,indexrecords_lookup_doc},
+ {}
+};
+
+static char *indexrecords_doc = "IndexRecords()\n\n"
+ "Representation of a release file.";
+PyTypeObject PyIndexRecords_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.IndexRecords", // tp_name
+ sizeof(CppPyObject<indexRecords*>), // tp_basicsize
+ 0, // tp_itemsize
+ // Methods
+ CppDeallocPtr<indexRecords*>, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ (Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_BASETYPE),
+ indexrecords_doc, // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ indexrecords_methods, // tp_methods
+ 0, // tp_members
+ 0, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ 0, // tp_alloc
+ indexrecords_new, // tp_new
+};
diff --git a/python/lock.cc b/python/lock.cc
new file mode 100644
index 00000000..fc78c0cb
--- /dev/null
+++ b/python/lock.cc
@@ -0,0 +1,265 @@
+/*
+ * lock.cc - Context managers for implementing locking.
+ *
+ * Copyright 2009 Julian Andres Klode <jak@debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+#include <Python.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/error.h>
+#include "generic.h"
+
+static PyObject *systemlock_exit(PyObject *self, PyObject *args)
+{
+
+ PyObject *exc_type = 0;
+ PyObject *exc_value = 0;
+ PyObject *traceback = 0;
+ if (!PyArg_UnpackTuple(args, "__exit__", 3, 3, &exc_type, &exc_value,
+ &traceback)) {
+ return 0;
+ }
+
+ if (_system->UnLock() == 0) {
+ // The unlock failed. If no exception happened within the suite, we
+ // will raise an error here. Otherwise, we just display the error, so
+ // Python can handle the original exception instead.
+ HandleErrors();
+ if (exc_type == Py_None)
+ return NULL;
+ else
+ PyErr_WriteUnraisable(self);
+ }
+ // Return False, as required by the context manager protocol.
+ Py_RETURN_FALSE;
+}
+
+static PyObject *systemlock_enter(PyObject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+ if (!_system->Lock())
+ return HandleErrors();
+ Py_INCREF(self);
+ return self;
+}
+
+static PyObject *systemlock_new(PyTypeObject *type, PyObject *args,
+ PyObject *kwds)
+{
+ if (_system == 0) {
+ PyErr_SetString(PyExc_ValueError,"_system not initialized");
+ return 0;
+ }
+ return PyType_GenericNew(type,args,kwds);
+}
+
+static PyMethodDef systemlock_methods[] = {
+ {"__enter__",systemlock_enter,METH_VARARGS,"Lock the system."},
+ {"__exit__",systemlock_exit,METH_VARARGS,"Unlock the system."},
+ {NULL}
+};
+
+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"
+ " 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"
+ " lock = apt_pkg.SystemLock()\n"
+ " with lock:\n"
+ " ...\n"
+ " with lock:\n"
+ " ...\n\n";
+
+PyTypeObject PySystemLock_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.SystemLock", // tp_name
+ 0, // tp_basicsize
+ 0, // tp_itemsize
+ // Methods
+ 0, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ (Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_BASETYPE),
+ systemlock_doc, // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ systemlock_methods, // tp_methods
+ 0, // tp_members
+ 0, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ 0, // tp_alloc
+ systemlock_new, // tp_new
+};
+
+
+/**
+ * File Based locking.
+ *
+ * The counter is increased by every call to filelock_enter() and decreased by
+ * every call to filelock_exit(). When the counter reaches 0, the underlying
+ * file descriptor is closed.
+ *
+ * Members:
+ * @member char* filename The name of the file
+ * @member int lock_count How many times we have locked it.
+ * @member int fd The filedescriptor returned by GetLock() or 0.
+ */
+struct filelock_object {
+ PyObject_HEAD
+ char *filename;
+ int lock_count;
+ int fd;
+};
+
+static PyObject *filelock_enter(filelock_object *self, PyObject *args)
+{
+ self->lock_count++;
+ // If we have no lock yet, get a lock.
+ if (self->lock_count == 1) {
+ self->fd = GetLock(self->filename, true);
+ if (self->fd == -1) {
+ self->lock_count--;
+ return HandleErrors();
+ }
+ }
+ Py_INCREF(self);
+ return (PyObject *)self;
+}
+
+static PyObject *filelock_exit(filelock_object *self, PyObject *args)
+{
+ // Count down the lock_count, if it is less than 0, reset it to 0.
+ self->lock_count--;
+ if (self->lock_count < 0)
+ self->lock_count = 0;
+ if (self->lock_count == 0 && self->fd != 0 && close(self->fd) == -1) {
+ return PyErr_SetFromErrno(PyExc_OSError);
+ }
+ Py_RETURN_FALSE;
+}
+
+static PyObject *filelock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ char *filename = 0;
+ char *kwlist[] = {"filename", NULL};
+ if (PyArg_ParseTupleAndKeywords(args, kwds, "s:__init__", kwlist,
+ &filename) == 0) {
+ return NULL;
+ }
+ filelock_object *self = (filelock_object *)type->tp_alloc(type, 0);
+ // Copy the string into the object.
+ self->filename = new char[strlen(filename) + 1];
+ strcpy(self->filename, filename);
+ return (PyObject *)self;
+}
+
+static void filelock_dealloc(filelock_object *self)
+{
+ delete[] self->filename;
+ ((PyObject*)self)->ob_type->tp_free(self);
+}
+
+static PyMethodDef filelock_methods[] = {
+ {"__enter__",(PyCFunction)filelock_enter,METH_VARARGS,"Lock the system."},
+ {"__exit__",(PyCFunction)filelock_exit,METH_VARARGS,"Unlock the system."},
+ {NULL}
+};
+
+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"
+ " 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"
+ " lock = apt_pkg.FileLock(filename)\n"
+ " with lock:\n"
+ " ...\n"
+ " with lock:\n"
+ " ...\n\n";
+
+PyTypeObject PyFileLock_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.FileLock", // tp_name
+ sizeof(filelock_object), // tp_basicsize
+ 0, // tp_itemsize
+ // Methods
+ destructor(filelock_dealloc), // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ (Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_BASETYPE),
+ filelock_doc, // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ filelock_methods, // tp_methods
+ 0, // tp_members
+ 0, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ 0, // tp_alloc
+ filelock_new, // tp_new
+};
diff --git a/python/makefile b/python/makefile
deleted file mode 100644
index 3e6458f4..00000000
--- a/python/makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-# -*- make -*-
-BASE=..
-SUBDIR=python
-
-# Bring in the default rules
-include ../buildlib/defaults.mak
-
-# The apt_pkg module
-MODULE=apt_pkg
-SLIBS = -lapt-pkg
-LIB_MAKES = apt-pkg/makefile
-APT_PKG_SRC = apt_pkgmodule.cc configuration.cc generic.cc tag.cc string.cc \
- cache.cc pkgrecords.cc pkgsrcrecords.cc sourcelist.cc \
- depcache.cc progress.cc cdrom.cc acquire.cc pkgmanager.cc \
- indexfile.cc metaindex.cc
-SOURCE := $(APT_PKG_SRC)
-include $(PYTHON_H) progress.h
-
-# The apt_int module..
-MODULE=apt_inst
-SLIBS = -lapt-inst -lapt-pkg
-LIB_MAKES = apt-inst/makefile
-APT_INST_SRC = apt_instmodule.cc tar.cc generic.cc
-SOURCE := $(APT_INST_SRC)
-include $(PYTHON_H)
-
diff --git a/python/metaindex.cc b/python/metaindex.cc
index efbc38af..2dcade7d 100644
--- a/python/metaindex.cc
+++ b/python/metaindex.cc
@@ -1,13 +1,13 @@
// -*- mode: cpp; mode: fold -*-
-// Description /*{{{*/
+// Description /*{{{*/
// $Id: metaindex.cc,v 1.2 2003/12/26 17:04:22 mdz Exp $
/* ######################################################################
metaindex - Wrapper for the metaIndex functions
##################################################################### */
- /*}}}*/
-// Include Files /*{{{*/
+ /*}}}*/
+// Include Files /*{{{*/
#include "generic.h"
#include "apt_pkgmodule.h"
@@ -15,67 +15,88 @@
#include <Python.h>
+static PyObject *MetaIndexGetURI(PyObject *Self,void*) {
+ metaIndex *meta = GetCpp<metaIndex*>(Self);
+ return Safe_FromString(meta->GetURI().c_str());
+}
-static PyObject *MetaIndexAttr(PyObject *Self,char *Name)
-{
- metaIndex *meta = GetCpp<metaIndex*>(Self);
- if (strcmp("URI",Name) == 0)
- return Safe_FromString(meta->GetURI().c_str());
- else if (strcmp("Dist",Name) == 0)
- return Safe_FromString(meta->GetDist().c_str());
- else if (strcmp("IsTrusted",Name) == 0)
- return Py_BuildValue("i",(meta->IsTrusted()));
- else if (strcmp("IndexFiles",Name) == 0)
- {
- PyObject *List = PyList_New(0);
- vector<pkgIndexFile *> *indexFiles = meta->GetIndexFiles();
- for (vector<pkgIndexFile *>::const_iterator I = indexFiles->begin();
- I != indexFiles->end(); I++)
- {
- PyObject *Obj;
- Obj = CppPyObject_NEW<pkgIndexFile*>(&PackageIndexFileType,*I);
- PyList_Append(List,Obj);
- }
- return List;
- }
+static PyObject *MetaIndexGetDist(PyObject *Self,void*) {
+ metaIndex *meta = GetCpp<metaIndex*>(Self);
+ return Safe_FromString(meta->GetDist().c_str());
+}
- PyErr_SetString(PyExc_AttributeError,Name);
- return 0;
+static PyObject *MetaIndexGetIsTrusted(PyObject *Self,void*) {
+ metaIndex *meta = GetCpp<metaIndex*>(Self);
+ return Py_BuildValue("i",(meta->IsTrusted()));
}
-static PyObject *MetaIndexRepr(PyObject *Self)
-{
- metaIndex *meta = GetCpp<metaIndex*>(Self);
+static PyObject *MetaIndexGetIndexFiles(PyObject *Self,void*) {
+ metaIndex *meta = GetCpp<metaIndex*>(Self);
+ PyObject *List = PyList_New(0);
+ vector<pkgIndexFile *> *indexFiles = meta->GetIndexFiles();
+ for (vector<pkgIndexFile *>::const_iterator I = indexFiles->begin();
+ I != indexFiles->end(); I++)
+ {
+ CppPyObject<pkgIndexFile*> *Obj;
+ Obj = CppPyObject_NEW<pkgIndexFile*>(Self, &PyIndexFile_Type,*I);
+ // Do not delete pkgIndexFile*, they are managed by metaIndex.
+ Obj->NoDelete = true;
+ PyList_Append(List,Obj);
+ Py_DECREF(Obj);
+ }
+ return List;
+}
- char S[1024];
- snprintf(S,sizeof(S),"<metaIndex object: "
- "Type='%s', URI:'%s' Dist='%s' IsTrusted='%i'>",
- meta->GetType(), meta->GetURI().c_str(), meta->GetDist().c_str(),
- meta->IsTrusted());
+static PyGetSetDef MetaIndexGetSet[] = {
+ {"dist",MetaIndexGetDist},
+ {"index_files",MetaIndexGetIndexFiles},
+ {"is_trusted",MetaIndexGetIsTrusted},
+ {"uri",MetaIndexGetURI},
+ {}
+};
- return PyString_FromString(S);
+#define S(x) (x ? x : "")
+static PyObject *MetaIndexRepr(PyObject *Self)
+{
+ metaIndex *meta = GetCpp<metaIndex*>(Self);
+ return PyString_FromFormat("<%s object: type='%s', uri:'%s' dist='%s' "
+ "is_trusted='%i'>", Self->ob_type->tp_name,
+ S(meta->GetType()), meta->GetURI().c_str(),
+ meta->GetDist().c_str(), meta->IsTrusted());
}
+#undef S
-PyTypeObject MetaIndexType =
+PyTypeObject PyMetaIndex_Type =
{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "metaIndex", // tp_name
- sizeof(CppOwnedPyObject<metaIndex*>), // tp_basicsize
- 0, // tp_itemsize
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.MetaIndex", // tp_name
+ sizeof(CppPyObject<metaIndex*>), // tp_basicsize
+ 0, // tp_itemsize
// Methods
- CppOwnedDealloc<metaIndex*>, // tp_dealloc
- 0, // tp_print
- MetaIndexAttr, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- MetaIndexRepr, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
- 0, // tp_hash
+ CppDeallocPtr<metaIndex*>, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ MetaIndexRepr, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ _PyAptObject_getattro, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT, // tp_flags
+ "apt_pkg.MetaIndex Object", // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ 0, // tp_methods
+ 0, // tp_members
+ MetaIndexGetSet, // tp_getset
};
-
-
-
-
diff --git a/python/pkgmanager.cc b/python/pkgmanager.cc
index 0eaa28cd..2fda14ee 100644
--- a/python/pkgmanager.cc
+++ b/python/pkgmanager.cc
@@ -15,8 +15,37 @@
#include <apt-pkg/sourcelist.h>
#include <apt-pkg/error.h>
#include <apt-pkg/acquire.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/configuration.h>
+
#include <iostream>
+static PyObject *PkgManagerNew(PyTypeObject *type,PyObject *Args,PyObject *kwds)
+{
+ PyObject *Owner;
+ char *kwlist[] = {"depcache",0};
+ if (PyArg_ParseTupleAndKeywords(Args,kwds,"O!",kwlist,&PyDepCache_Type,
+ &Owner) == 0)
+ return 0;
+
+ pkgPackageManager *pm = _system->CreatePM(GetCpp<pkgDepCache*>(Owner));
+
+ CppPyObject<pkgPackageManager*> *PkgManagerObj =
+ CppPyObject_NEW<pkgPackageManager*>(NULL, type,pm);
+
+ return PkgManagerObj;
+}
+
+#ifdef COMPAT_0_7
+PyObject *GetPkgManager(PyObject *Self,PyObject *Args)
+{
+ PyErr_WarnEx(PyExc_DeprecationWarning, "apt_pkg.GetPackageManager() is "
+ "deprecated. Please see apt_pkg.PackageManager() for the "
+ "replacement.", 1);
+ return PkgManagerNew(&PyPackageManager_Type,Args,0);
+}
+#endif
+
static PyObject *PkgManagerGetArchives(PyObject *Self,PyObject *Args)
{
@@ -24,9 +53,9 @@ static PyObject *PkgManagerGetArchives(PyObject *Self,PyObject *Args)
PyObject *fetcher, *list, *recs;
if (PyArg_ParseTuple(Args, "O!O!O!",
- &PkgAcquireType,&fetcher,
- &PkgSourceListType, &list,
- &PkgRecordsType, &recs) == 0)
+ &PyAcquire_Type,&fetcher,
+ &PySourceList_Type, &list,
+ &PyPackageRecords_Type, &recs) == 0)
return 0;
pkgAcquire *s_fetcher = GetCpp<pkgAcquire*>(fetcher);
@@ -68,68 +97,57 @@ static PyObject *PkgManagerFixMissing(PyObject *Self,PyObject *Args)
static PyMethodDef PkgManagerMethods[] =
{
- {"GetArchives",PkgManagerGetArchives,METH_VARARGS,"Load the selected archives into the fetcher"},
- {"DoInstall",PkgManagerDoInstall,METH_VARARGS,"Do the actual install"},
- {"FixMissing",PkgManagerFixMissing,METH_VARARGS,"Fix the install if a pkg couldn't be downloaded"},
+ {"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"},
{}
};
-static PyObject *PkgManagerAttr(PyObject *Self,char *Name)
-{
- //PkgManagerStruct &Struct = GetCpp<PkgManagerStruct>(Self);
- pkgPackageManager *pm = GetCpp<pkgPackageManager*>(Self);
-
- // some constants
- if(strcmp("ResultCompleted",Name) == 0)
- return Py_BuildValue("i", pkgPackageManager::Completed);
- if(strcmp("ResultFailed",Name) == 0)
- return Py_BuildValue("i", pkgPackageManager::Failed);
- if(strcmp("ResultIncomplete",Name) == 0)
- return Py_BuildValue("i", pkgPackageManager::Incomplete);
-
- return Py_FindMethod(PkgManagerMethods,Self,Name);
-}
-
-
-PyTypeObject PkgManagerType =
+PyTypeObject PyPackageManager_Type =
{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "PackageManager", // tp_name
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.PackageManager", // tp_name
sizeof(CppPyObject<pkgPackageManager*>), // tp_basicsize
0, // tp_itemsize
// Methods
- CppDealloc<pkgPackageManager*>, // tp_dealloc
+ CppDeallocPtr<pkgPackageManager*>, // tp_dealloc
0, // tp_print
- PkgManagerAttr, // tp_getattr
+ 0, // tp_getattr
0, // tp_setattr
0, // tp_compare
0, // tp_repr
0, // tp_as_number
0, // tp_as_sequence
- 0, // tp_as_mapping
+ 0, // tp_as_mapping
0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ _PyAptObject_getattro, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ (Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_BASETYPE),
+ "PackageManager Object", // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ PkgManagerMethods, // tp_methods
+ 0, // tp_members
+ 0, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ 0, // tp_alloc
+ PkgManagerNew, // tp_new
};
-#include <apt-pkg/init.h>
-#include <apt-pkg/configuration.h>
-
-PyObject *GetPkgManager(PyObject *Self,PyObject *Args)
-{
- PyObject *Owner;
- if (PyArg_ParseTuple(Args,"O!",&PkgDepCacheType,&Owner) == 0)
- return 0;
-
- pkgPackageManager *pm = _system->CreatePM(GetCpp<pkgDepCache*>(Owner));
-
- CppPyObject<pkgPackageManager*> *PkgManagerObj =
- CppPyObject_NEW<pkgPackageManager*>(&PkgManagerType,pm);
-
- return PkgManagerObj;
-}
-
-
/*}}}*/
diff --git a/python/pkgrecords.cc b/python/pkgrecords.cc
index 5359ee6f..0e00edcd 100644
--- a/python/pkgrecords.cc
+++ b/python/pkgrecords.cc
@@ -27,7 +27,7 @@ static PyObject *PkgRecordsLookup(PyObject *Self,PyObject *Args)
PyObject *PkgFObj;
long int Index;
- if (PyArg_ParseTuple(Args,"(O!l)",&PackageFileType,&PkgFObj,&Index) == 0)
+ if (PyArg_ParseTuple(Args,"(O!l)",&PyPackageFile_Type,&PkgFObj,&Index) == 0)
return 0;
// Get the index and check to make sure it is reasonable
@@ -49,59 +49,111 @@ static PyObject *PkgRecordsLookup(PyObject *Self,PyObject *Args)
static PyMethodDef PkgRecordsMethods[] =
{
- {"Lookup",PkgRecordsLookup,METH_VARARGS,"Changes to a new package"},
+ {"lookup",PkgRecordsLookup,METH_VARARGS,"Changes to a new package"},
{}
};
-static PyObject *PkgRecordsAttr(PyObject *Self,char *Name)
-{
+/**
+ * Get the PkgSrcRecordsStruct from a PyObject. If no package has been looked
+ * up, set an AttributeError using the given name.
+ */
+static inline PkgRecordsStruct &GetStruct(PyObject *Self,char *name) {
PkgRecordsStruct &Struct = GetCpp<PkgRecordsStruct>(Self);
+ if (Struct.Last == 0)
+ PyErr_SetString(PyExc_AttributeError,name);
+ return Struct;
+}
- if (Struct.Last != 0)
- {
- if (strcmp("FileName",Name) == 0)
- return CppPyString(Struct.Last->FileName());
- else if (strcmp("MD5Hash",Name) == 0)
- return CppPyString(Struct.Last->MD5Hash());
- else if (strcmp("SHA1Hash",Name) == 0)
- return CppPyString(Struct.Last->SHA1Hash());
- else if (strcmp("SHA256Hash",Name) == 0)
- return CppPyString(Struct.Last->SHA256Hash());
- else if (strcmp("SourcePkg",Name) == 0)
- return CppPyString(Struct.Last->SourcePkg());
- else if (strcmp("SourceVer",Name) == 0)
- return CppPyString(Struct.Last->SourceVer());
- else if (strcmp("Maintainer",Name) == 0)
- return CppPyString(Struct.Last->Maintainer());
- else if (strcmp("ShortDesc",Name) == 0)
- return CppPyString(Struct.Last->ShortDesc());
- else if (strcmp("LongDesc",Name) == 0)
- return CppPyString(Struct.Last->LongDesc());
- else if (strcmp("Name",Name) == 0)
- return CppPyString(Struct.Last->Name());
- else if (strcmp("Homepage",Name) == 0)
- return CppPyString(Struct.Last->Homepage());
- else if (strcmp("Record", Name) == 0)
- {
- const char *start, *stop;
- Struct.Last->GetRec(start, stop);
- return PyString_FromStringAndSize(start,stop-start);
- }
- }
+static PyObject *PkgRecordsGetFileName(PyObject *Self,void*) {
+ PkgRecordsStruct &Struct = GetStruct(Self,"FileName");
+ return (Struct.Last != 0) ? CppPyString(Struct.Last->FileName()) : 0;
+}
+static PyObject *PkgRecordsGetMD5Hash(PyObject *Self,void*) {
+ PkgRecordsStruct &Struct = GetStruct(Self,"MD5Hash");
+ return (Struct.Last != 0) ? CppPyString(Struct.Last->MD5Hash()) : 0;
+}
+static PyObject *PkgRecordsGetSHA1Hash(PyObject *Self,void*) {
+ PkgRecordsStruct &Struct = GetStruct(Self,"SHA1Hash");
+ return (Struct.Last != 0) ? CppPyString(Struct.Last->SHA1Hash()) : 0;
+}
+static PyObject *PkgRecordsGetSHA256Hash(PyObject *Self,void*) {
+ PkgRecordsStruct &Struct = GetStruct(Self,"SHA256Hash");
+ return (Struct.Last != 0) ? CppPyString(Struct.Last->SHA256Hash()) : 0;
+}
+static PyObject *PkgRecordsGetSourcePkg(PyObject *Self,void*) {
+ PkgRecordsStruct &Struct = GetStruct(Self,"SourcePkg");
+ return (Struct.Last != 0) ? CppPyString(Struct.Last->SourcePkg()) : 0;
+}
+static PyObject *PkgRecordsGetSourceVer(PyObject *Self,void*) {
+ PkgRecordsStruct &Struct = GetStruct(Self,"SourceVer");
+ return (Struct.Last != 0) ? CppPyString(Struct.Last->SourceVer()) : 0;
+}
+static PyObject *PkgRecordsGetMaintainer(PyObject *Self,void*) {
+ PkgRecordsStruct &Struct = GetStruct(Self,"Maintainer");
+ return (Struct.Last != 0) ? CppPyString(Struct.Last->Maintainer()) : 0;
+}
+static PyObject *PkgRecordsGetShortDesc(PyObject *Self,void*) {
+ PkgRecordsStruct &Struct = GetStruct(Self,"ShortDesc");
+ return (Struct.Last != 0) ? CppPyString(Struct.Last->ShortDesc()) : 0;
+}
+static PyObject *PkgRecordsGetLongDesc(PyObject *Self,void*) {
+ PkgRecordsStruct &Struct = GetStruct(Self,"LongDesc");
+ return (Struct.Last != 0) ? CppPyString(Struct.Last->LongDesc()) : 0;
+}
+static PyObject *PkgRecordsGetName(PyObject *Self,void*) {
+ PkgRecordsStruct &Struct = GetStruct(Self,"Name");
+ return (Struct.Last != 0) ? CppPyString(Struct.Last->Name()) : 0;
+}
+static PyObject *PkgRecordsGetHomepage(PyObject *Self,void*) {
+ PkgRecordsStruct &Struct = GetStruct(Self,"Homepage");
+ return (Struct.Last != 0) ? CppPyString(Struct.Last->Homepage()) : 0;
+}
+static PyObject *PkgRecordsGetRecord(PyObject *Self,void*) {
+ const char *start, *stop;
+ PkgRecordsStruct &Struct = GetStruct(Self,"Record");
+ if (Struct.Last == 0)
+ return 0;
+ Struct.Last->GetRec(start, stop);
+ return PyString_FromStringAndSize(start,stop-start);
+}
+static PyGetSetDef PkgRecordsGetSet[] = {
+ {"filename",PkgRecordsGetFileName},
+ {"homepage",PkgRecordsGetHomepage},
+ {"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},
+ {}
+};
+
+static PyObject *PkgRecordsNew(PyTypeObject *type,PyObject *Args,PyObject *kwds)
+{
+ PyObject *Owner;
+ char *kwlist[] = {"cache",0};
+ if (PyArg_ParseTupleAndKeywords(Args,kwds,"O!",kwlist,&PyCache_Type,
+ &Owner) == 0)
+ return 0;
- return Py_FindMethod(PkgRecordsMethods,Self,Name);
+ return HandleErrors(CppPyObject_NEW<PkgRecordsStruct>(Owner,type,
+ GetCpp<pkgCache *>(Owner)));
}
-PyTypeObject PkgRecordsType =
+
+PyTypeObject PyPackageRecords_Type =
{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "pkgRecords", // tp_name
- sizeof(CppOwnedPyObject<PkgRecordsStruct>), // tp_basicsize
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.PackageRecords", // tp_name
+ sizeof(CppPyObject<PkgRecordsStruct>), // tp_basicsize
0, // tp_itemsize
// Methods
- CppOwnedDealloc<PkgRecordsStruct>, // tp_dealloc
+ CppDealloc<PkgRecordsStruct>, // tp_dealloc
0, // tp_print
- PkgRecordsAttr, // tp_getattr
+ 0, // tp_getattr
0, // tp_setattr
0, // tp_compare
0, // tp_repr
@@ -109,17 +161,43 @@ PyTypeObject PkgRecordsType =
0, // tp_as_sequence
0, // tp_as_mapping
0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ _PyAptObject_getattro, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ (Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_HAVE_GC),
+ "Records Object", // tp_doc
+ CppTraverse<PkgRecordsStruct>, // tp_traverse
+ CppClear<PkgRecordsStruct>, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ PkgRecordsMethods, // tp_methods
+ 0, // tp_members
+ PkgRecordsGetSet, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ 0, // tp_alloc
+ PkgRecordsNew, // tp_new
};
/*}}}*/
+
+#ifdef COMPAT_0_7
PyObject *GetPkgRecords(PyObject *Self,PyObject *Args)
{
- PyObject *Owner;
- if (PyArg_ParseTuple(Args,"O!",&PkgCacheType,&Owner) == 0)
- return 0;
-
- return HandleErrors(CppOwnedPyObject_NEW<PkgRecordsStruct>(Owner,&PkgRecordsType,
- GetCpp<pkgCache *>(Owner)));
+ PyErr_WarnEx(PyExc_DeprecationWarning, "apt_pkg.GetPkgRecords() is "
+ "deprecated. Please see apt_pkg.Records() for the "
+ "replacement.", 1);
+ return PkgRecordsNew(&PyPackageRecords_Type,Args,0);
}
-
+#endif
diff --git a/python/pkgsrcrecords.cc b/python/pkgsrcrecords.cc
index 36493e7b..95f35f23 100644
--- a/python/pkgsrcrecords.cc
+++ b/python/pkgsrcrecords.cc
@@ -58,7 +58,6 @@ static PyObject *PkgSrcRecordsRestart(PyObject *Self,PyObject *Args)
{
PkgSrcRecordsStruct &Struct = GetCpp<PkgSrcRecordsStruct>(Self);
- char *Name = 0;
if (PyArg_ParseTuple(Args,"") == 0)
return 0;
@@ -70,87 +69,190 @@ static PyObject *PkgSrcRecordsRestart(PyObject *Self,PyObject *Args)
static PyMethodDef PkgSrcRecordsMethods[] =
{
- {"Lookup",PkgSrcRecordsLookup,METH_VARARGS,doc_PkgSrcRecordsLookup},
- {"Restart",PkgSrcRecordsRestart,METH_VARARGS,doc_PkgSrcRecordsRestart},
+ {"lookup",PkgSrcRecordsLookup,METH_VARARGS,doc_PkgSrcRecordsLookup},
+ {"restart",PkgSrcRecordsRestart,METH_VARARGS,doc_PkgSrcRecordsRestart},
{}
};
-static PyObject *PkgSrcRecordsAttr(PyObject *Self,char *Name)
-{
+/**
+ * Get the PkgSrcRecordsStruct from a PyObject. If no package has been looked
+ * up, set an AttributeError using the given name.
+ */
+static inline PkgSrcRecordsStruct &GetStruct(PyObject *Self,char *name) {
PkgSrcRecordsStruct &Struct = GetCpp<PkgSrcRecordsStruct>(Self);
+ if (Struct.Last == 0)
+ PyErr_SetString(PyExc_AttributeError,name);
+ return Struct;
+}
- if (Struct.Last != 0)
- {
- if (strcmp("Package",Name) == 0)
- return CppPyString(Struct.Last->Package());
- else if (strcmp("Version",Name) == 0)
- return CppPyString(Struct.Last->Version());
- else if (strcmp("Maintainer",Name) == 0)
- return CppPyString(Struct.Last->Maintainer());
- else if (strcmp("Section",Name) == 0)
- return CppPyString(Struct.Last->Section());
- else if (strcmp("Record",Name) == 0)
- return CppPyString(Struct.Last->AsStr());
- else if (strcmp("Binaries",Name) == 0) {
- PyObject *List = PyList_New(0);
-
- for(const char **b = Struct.Last->Binaries();
- *b != 0;
- ++b)
- PyList_Append(List, CppPyString(*b));
- return List; // todo
- } else if (strcmp("Index",Name) == 0) {
- const pkgIndexFile &tmp = Struct.Last->Index();
- return CppOwnedPyObject_NEW<pkgIndexFile*>(Self,&PackageIndexFileType, (pkgIndexFile*)&tmp);
- } else if (strcmp("Files",Name) == 0) {
- PyObject *List = PyList_New(0);
-
- vector<pkgSrcRecords::File> f;
- if(!Struct.Last->Files(f))
- return NULL; // error
-
- PyObject *v;
- for(unsigned int i=0;i<f.size();i++) {
- v = Py_BuildValue("(siss)",
- f[i].MD5Hash.c_str(),
- f[i].Size,
- f[i].Path.c_str(),
- f[i].Type.c_str());
- PyList_Append(List, v);
- Py_DECREF(v);
+static PyObject *PkgSrcRecordsGetPackage(PyObject *Self,void*) {
+ PkgSrcRecordsStruct &Struct = GetStruct(Self,"Package");
+ return (Struct.Last != 0) ? CppPyString(Struct.Last->Package()) : 0;
+}
+static PyObject *PkgSrcRecordsGetVersion(PyObject *Self,void*) {
+ PkgSrcRecordsStruct &Struct = GetStruct(Self,"Version");
+ return (Struct.Last != 0) ? CppPyString(Struct.Last->Version()) : 0;
+}
+static PyObject *PkgSrcRecordsGetMaintainer(PyObject *Self,void*) {
+ PkgSrcRecordsStruct &Struct = GetStruct(Self,"Maintainer");
+ return (Struct.Last != 0) ? CppPyString(Struct.Last->Maintainer()) : 0;
+}
+static PyObject *PkgSrcRecordsGetSection(PyObject *Self,void*) {
+ PkgSrcRecordsStruct &Struct = GetStruct(Self,"Section");
+ return (Struct.Last != 0) ? CppPyString(Struct.Last->Section()) : 0;
+}
+static PyObject *PkgSrcRecordsGetRecord(PyObject *Self,void*) {
+ PkgSrcRecordsStruct &Struct = GetStruct(Self,"Record");
+ return (Struct.Last != 0) ? CppPyString(Struct.Last->AsStr()) : 0;
+}
+static PyObject *PkgSrcRecordsGetBinaries(PyObject *Self,void*) {
+ PkgSrcRecordsStruct &Struct = GetStruct(Self,"Binaries");
+ if (Struct.Last == 0)
+ return 0;
+ PyObject *List = PyList_New(0);
+ for(const char **b = Struct.Last->Binaries(); *b != 0; ++b)
+ PyList_Append(List, CppPyString(*b));
+ return List; // todo
+}
+static PyObject *PkgSrcRecordsGetIndex(PyObject *Self,void*) {
+ PkgSrcRecordsStruct &Struct = GetStruct(Self,"Index");
+ if (Struct.Last == 0)
+ return 0;
+ const pkgIndexFile &tmp = Struct.Last->Index();
+ CppPyObject<pkgIndexFile*> *PyObj;
+ PyObj = CppPyObject_NEW<pkgIndexFile*>(Self,&PyIndexFile_Type,
+ (pkgIndexFile*)&tmp);
+ // Do not delete the pkgIndexFile*, it is managed by PkgSrcRecords::Parser.
+ PyObj->NoDelete=true;
+ return PyObj;
+}
+
+static PyObject *PkgSrcRecordsGetFiles(PyObject *Self,void*) {
+ PkgSrcRecordsStruct &Struct = GetStruct(Self,"Files");
+ if (Struct.Last == 0)
+ return 0;
+ PyObject *List = PyList_New(0);
+
+ vector<pkgSrcRecords::File> f;
+ if(!Struct.Last->Files(f))
+ return NULL; // error
+
+ PyObject *v;
+ for(unsigned int i=0;i<f.size();i++) {
+ v = Py_BuildValue("(siss)",
+ f[i].MD5Hash.c_str(),
+ f[i].Size,
+ f[i].Path.c_str(),
+ f[i].Type.c_str());
+ PyList_Append(List, v);
+ Py_DECREF(v);
+ }
+ return List;
+}
+
+static PyObject *PkgSrcRecordsGetBuildDepends(PyObject *Self,void*) {
+ PkgSrcRecordsStruct &Struct = GetStruct(Self,"BuildDepends");
+ if (Struct.Last == 0)
+ return 0;
+
+ PyObject *Dict = PyDict_New();
+ PyObject *Dep = 0;
+ PyObject *LastDep = 0;
+ PyObject *OrGroup = 0;
+
+ vector<pkgSrcRecords::Parser::BuildDepRec> bd;
+ if(!Struct.Last->BuildDepends(bd, false /* arch-only*/))
+ return NULL; // error
+
+ PyObject *v;
+ for(unsigned int i=0;i<bd.size();i++) {
+
+ Dep = PyString_FromString(pkgSrcRecords::Parser::BuildDepType(bd[i].Type));
+
+ LastDep = PyDict_GetItem(Dict,Dep);
+ if (LastDep == 0)
+ {
+ LastDep = PyList_New(0);
+ PyDict_SetItem(Dict,Dep,LastDep);
+ Py_DECREF(LastDep);
}
- return List;
- } else if (strcmp("BuildDepends",Name) == 0) {
- PyObject *List = PyList_New(0);
-
- vector<pkgSrcRecords::Parser::BuildDepRec> bd;
- if(!Struct.Last->BuildDepends(bd, false /* arch-only*/))
- return NULL; // error
-
- PyObject *v;
- for(unsigned int i=0;i<bd.size();i++) {
- v = Py_BuildValue("(ssii)", bd[i].Package.c_str(),
- bd[i].Version.c_str(), bd[i].Op, bd[i].Type);
- PyList_Append(List, v);
+ Py_DECREF(Dep);
+ OrGroup = PyList_New(0);
+ PyList_Append(LastDep, OrGroup);
+ Py_DECREF(OrGroup);
+
+ // Add at least one package to the group, add more if Or is set.
+ while (1)
+ {
+ v = Py_BuildValue("(sss)", bd[i].Package.c_str(),
+ bd[i].Version.c_str(), pkgCache::CompType(bd[i].Op));
+ PyList_Append(OrGroup, v);
Py_DECREF(v);
- }
- return List;
- }
+ if (pkgCache::Dep::Or != (bd[i].Op & pkgCache::Dep::Or) || i == bd.size())
+ break;
+ i++;
+ }
+
}
+ return Dict;
+}
+
+#ifdef COMPAT_0_7
+static PyObject *PkgSrcRecordsGetBuildDepends_old(PyObject *Self,void*) {
+ PkgSrcRecordsStruct &Struct = GetStruct(Self,"BuildDepends");
+ if (Struct.Last == 0)
+ return 0;
+ PyObject *List = PyList_New(0);
+
+ vector<pkgSrcRecords::Parser::BuildDepRec> bd;
+ if(!Struct.Last->BuildDepends(bd, false /* arch-only*/))
+ return NULL; // error
+
+ PyObject *v;
+ for(unsigned int i=0;i<bd.size();i++) {
+ v = Py_BuildValue("(ssii)", bd[i].Package.c_str(),
+ bd[i].Version.c_str(), bd[i].Op, bd[i].Type);
+ PyList_Append(List, v);
+ Py_DECREF(v);
+ }
+ return List;
+}
+#endif
+
+static PyGetSetDef PkgSrcRecordsGetSet[] = {
+ {"binaries",PkgSrcRecordsGetBinaries},
+ {"build_depends",PkgSrcRecordsGetBuildDepends},
+ {"files",PkgSrcRecordsGetFiles},
+ {"index",PkgSrcRecordsGetIndex},
+ {"maintainer",PkgSrcRecordsGetMaintainer},
+ {"package",PkgSrcRecordsGetPackage},
+ {"record",PkgSrcRecordsGetRecord},
+ {"section",PkgSrcRecordsGetSection},
+ {"version",PkgSrcRecordsGetVersion},
+#ifdef COMPAT_0_7
+ {"BuildDepends",PkgSrcRecordsGetBuildDepends_old,0,"Deprecated function and deprecated output format."},
+#endif
+ {}
+};
- return Py_FindMethod(PkgSrcRecordsMethods,Self,Name);
+static PyObject *PkgSrcRecordsNew(PyTypeObject *type,PyObject *args,PyObject *kwds) {
+ char *kwlist[] = {0};
+ if (PyArg_ParseTupleAndKeywords(args,kwds,"",kwlist) == 0)
+ return 0;
+
+ return HandleErrors(CppPyObject_NEW<PkgSrcRecordsStruct>(NULL, type));
}
-PyTypeObject PkgSrcRecordsType =
+
+PyTypeObject PySourceRecords_Type =
{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "pkgSrcRecords", // tp_name
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.SourceRecords", // tp_name
sizeof(CppPyObject<PkgSrcRecordsStruct>), // tp_basicsize
0, // tp_itemsize
// Methods
CppDealloc<PkgSrcRecordsStruct>, // tp_dealloc
0, // tp_print
- PkgSrcRecordsAttr, // tp_getattr
+ 0, // tp_getattr
0, // tp_setattr
0, // tp_compare
0, // tp_repr
@@ -158,23 +260,44 @@ PyTypeObject PkgSrcRecordsType =
0, // tp_as_sequence
0, // tp_as_mapping
0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ _PyAptObject_getattro, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ (Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_BASETYPE),
+ "SourceRecords Object", // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ PkgSrcRecordsMethods, // tp_methods
+ 0, // tp_members
+ PkgSrcRecordsGetSet, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ 0, // tp_alloc
+ PkgSrcRecordsNew, // tp_new
};
/*}}}*/
+#ifdef COMPAT_0_7
PyObject *GetPkgSrcRecords(PyObject *Self,PyObject *Args)
{
-#if 0
- PyObject *Owner;
- if (PyArg_ParseTuple(Args,"O!",&PkgCacheType,&Owner) == 0)
- return 0;
-
- return HandleErrors(CppOwnedPyObject_NEW<PkgSrcRecordsStruct>(Owner,
- &PkgSrcRecordsType));
-#endif
+ PyErr_WarnEx(PyExc_DeprecationWarning, "apt_pkg.GetPkgSrcRecords() is "
+ "deprecated. Please see apt_pkg.SourceRecords() for the "
+ "replacement.", 1);
if (PyArg_ParseTuple(Args,"") == 0)
return 0;
- return HandleErrors(CppPyObject_NEW<PkgSrcRecordsStruct>(&PkgSrcRecordsType));
+ return HandleErrors(CppPyObject_NEW<PkgSrcRecordsStruct>(NULL, &PySourceRecords_Type));
}
-
+#endif
diff --git a/python/policy.cc b/python/policy.cc
new file mode 100644
index 00000000..3e1ec589
--- /dev/null
+++ b/python/policy.cc
@@ -0,0 +1,205 @@
+/*
+ * policy.cc - Wrapper around pkgPolicy
+ *
+ * Copyright 2009 Julian Andres Klode <jak@debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+#include <Python.h>
+#include "apt_pkgmodule.h"
+#include "generic.h"
+#include <apt-pkg/policy.h>
+
+static PyObject *policy_new(PyTypeObject *type,PyObject *Args,
+ PyObject *kwds) {
+ PyObject *cache;
+ char *kwlist[] = {"cache", NULL};
+ if (PyArg_ParseTupleAndKeywords(Args, kwds, "O", kwlist, &cache) == 0)
+ return 0;
+ if (!PyObject_TypeCheck(cache, &PyCache_Type)) {
+ PyErr_SetString(PyExc_TypeError,"`cache` must be a apt_pkg.Cache().");
+ return 0;
+ }
+ pkgPolicy *policy = new pkgPolicy(GetCpp<pkgCache *>(cache));
+ return CppPyObject_NEW<pkgPolicy*>(cache,&PyPolicy_Type,policy);
+}
+
+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) {
+ pkgPolicy *policy = GetCpp<pkgPolicy *>(self);
+ if (PyObject_TypeCheck(arg, &PyPackage_Type)) {
+ pkgCache::PkgIterator pkg = GetCpp<pkgCache::PkgIterator>(arg);
+ return Py_BuildValue("i", policy->GetPriority(pkg));
+ } else {
+ PyErr_SetString(PyExc_TypeError,"Argument must be of Package().");
+ return 0;
+ }
+}
+
+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) {
+ if (PyObject_TypeCheck(arg, &PyPackage_Type)) {
+ pkgPolicy *policy = GetCpp<pkgPolicy *>(self);
+ pkgCache::PkgIterator pkg = GetCpp<pkgCache::PkgIterator>(arg);
+ pkgCache::VerIterator ver = policy->GetCandidateVer(pkg);
+ return CppPyObject_NEW<pkgCache::VerIterator>(arg,&PyVersion_Type,
+ ver);
+ } else {
+ PyErr_SetString(PyExc_TypeError,"Argument must be of Package().");
+ return 0;
+ }
+}
+
+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) {
+ if (PyObject_TypeCheck(arg, &PyPackage_Type) == 0) {
+ PyErr_SetString(PyExc_TypeError,"Argument must be of Package().");
+ return 0;
+ }
+ pkgPolicy *policy = GetCpp<pkgPolicy *>(self);
+ pkgCache::PkgIterator pkg = GetCpp<pkgCache::PkgIterator>(arg);
+ pkgCache::VerIterator ver = policy->GetMatch(pkg);
+ 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 PyObject *policy_read_pinfile(PyObject *self, PyObject *arg) {
+ if (!PyString_Check(arg))
+ return 0;
+ pkgPolicy *policy = GetCpp<pkgPolicy *>(self);
+
+ return PyBool_FromLong(ReadPinFile(*policy, PyString_AsString(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 PyObject *policy_read_pindir(PyObject *self, PyObject *arg) {
+ if (!PyString_Check(arg))
+ return 0;
+ pkgPolicy *policy = GetCpp<pkgPolicy *>(self);
+
+ return PyBool_FromLong(ReadPinDir(*policy, PyString_AsString(arg)));
+}
+#endif
+
+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"
+ "The parameter 'priority' gives the priority of the pin.";
+
+static PyObject *policy_create_pin(PyObject *self, PyObject *args) {
+ pkgVersionMatch::MatchType match_type;
+ const char *type, *pkg, *data;
+ signed short priority;
+ if (PyArg_ParseTuple(args, "sssh", &type, &pkg, &data, &priority) == 0)
+ return 0;
+ pkgPolicy *policy = GetCpp<pkgPolicy *>(self);
+ if (strcmp(type,"Version") == 0 || strcmp(type, "version") == 0)
+ match_type = pkgVersionMatch::Version;
+ if (strcmp(type,"Release") == 0 || strcmp(type, "release") == 0)
+ match_type = pkgVersionMatch::Release;
+ if (strcmp(type,"Origin") == 0 || strcmp(type, "origin") == 0)
+ match_type = pkgVersionMatch::Origin;
+ else
+ match_type = pkgVersionMatch::None;
+ policy->CreatePin(match_type,pkg,data,priority);
+ HandleErrors();
+ Py_RETURN_NONE;
+}
+
+static PyMethodDef policy_methods[] = {
+ {"get_priority",(PyCFunction)policy_get_priority,METH_O,
+ policy_get_priority_doc},
+ {"get_candidate_ver",(PyCFunction)policy_get_candidate_ver,METH_O,
+ policy_get_candidate_ver_doc},
+ {"read_pinfile",(PyCFunction)policy_read_pinfile,METH_O,
+ policy_read_pinfile_doc},
+#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 8)
+ {"read_pindir",(PyCFunction)policy_read_pindir,METH_O,
+ policy_read_pindir_doc},
+#endif
+ {"create_pin",policy_create_pin,METH_VARARGS,policy_create_pin_doc},
+ {"get_match",(PyCFunction)policy_get_match,METH_O, policy_get_match_doc},
+ {}
+};
+
+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"
+ "may be some cases where a special policy class is needed.";
+
+PyTypeObject PyPolicy_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.Policy", // tp_name
+ sizeof(CppPyObject<pkgPolicy*>),// tp_basicsize
+ 0, // tp_itemsize
+ // Methods
+ CppDeallocPtr<pkgPolicy*>, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ (Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_HAVE_GC),
+ policy_doc, // tp_doc
+ CppTraverse<pkgPolicy*>, // tp_traverse
+ CppClear<pkgPolicy*>, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ policy_methods, // tp_methods
+ 0, // tp_members
+ 0, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ 0, // tp_alloc
+ policy_new, // tp_new
+};
diff --git a/python/progress.cc b/python/progress.cc
index 82967687..097f06cf 100644
--- a/python/progress.cc
+++ b/python/progress.cc
@@ -5,7 +5,7 @@
Progress - Wrapper for the progress related functions
##################################################################### */
-
+#include <Python.h>
#include <iostream>
#include <sys/types.h>
#include <sys/wait.h>
@@ -13,8 +13,32 @@
#include <utility>
#include <apt-pkg/acquire-item.h>
#include <apt-pkg/acquire-worker.h>
-#include "generic.h"
#include "progress.h"
+#include "generic.h"
+#include "apt_pkgmodule.h"
+
+/**
+ * Set an attribute on an object, after creating the value with
+ * Py_BuildValue(fmt, arg). Afterwards, decrease its refcount and return
+ * whether setting the attribute was successful.
+ */
+template<class T>
+inline bool setattr(PyObject *object, const char *attr, const char *fmt, T arg)
+{
+ if (!object)
+ return false;
+ PyObject *value = Py_BuildValue(fmt, arg);
+
+ int result = PyObject_SetAttrString(object, attr, value);
+ Py_DECREF(value);
+ return result != -1;
+}
+
+inline PyObject *TUPLEIZE(PyObject *op) {
+ PyObject *ret = Py_BuildValue("(O)", op);
+ Py_DECREF(op);
+ return ret;
+}
// generic
bool PyCallbackObj::RunSimpleCallback(const char* method_name,
@@ -36,8 +60,8 @@ bool PyCallbackObj::RunSimpleCallback(const char* method_name,
}
return false;
}
- PyObject *result = PyEval_CallObject(method, arglist);
-
+
+ PyObject *result = PyObject_CallObject(method, arglist);
Py_XDECREF(arglist);
if(result == NULL) {
@@ -61,26 +85,24 @@ bool PyCallbackObj::RunSimpleCallback(const char* method_name,
// OpProgress interface
void PyOpProgress::Update()
{
- PyObject *o;
- o = Py_BuildValue("s", Op.c_str());
- PyObject_SetAttrString(callbackInst, "op", o);
- Py_XDECREF(o);
- o = Py_BuildValue("s", SubOp.c_str());
- PyObject_SetAttrString(callbackInst, "subOp", o);
- Py_XDECREF(o);
- o = Py_BuildValue("b", MajorChange);
- PyObject_SetAttrString(callbackInst, "majorChange", o);
- Py_XDECREF(o);
-
- // CheckChange takes a time delta argument how often we
- // should run update - for interactive UIs it makes sense
- // to run ~25/sec
- if(CheckChange(0.04))
- {
- PyObject *arglist = Py_BuildValue("(f)", Percent);
- RunSimpleCallback("update", arglist);
- }
-};
+ // Build up the argument list...
+ if(!CheckChange(0.7))
+ return;
+
+ setattr(callbackInst, "op", "s", Op.c_str());
+ setattr(callbackInst, "subop", "s", SubOp.c_str());
+ setattr(callbackInst, "major_change", "b", MajorChange);
+ setattr(callbackInst, "percent", "f", Percent);
+#ifdef COMPAT_0_7
+ setattr(callbackInst, "Op", "s", Op.c_str());
+ setattr(callbackInst, "subOp", "s", SubOp.c_str());
+ setattr(callbackInst, "majorChange", "b", MajorChange);
+ PyObject *arglist = Py_BuildValue("(f)", Percent);
+ RunSimpleCallback("update", arglist);
+#else
+ RunSimpleCallback("update");
+#endif
+}
void PyOpProgress::Done()
{
@@ -95,17 +117,32 @@ void PyOpProgress::Done()
// apt interface
+PyObject *PyFetchProgress::GetDesc(pkgAcquire::ItemDesc *item) {
+ if (!pyAcquire && item->Owner && item->Owner->GetOwner()) {
+ pyAcquire = PyAcquire_FromCpp(item->Owner->GetOwner(), false, NULL);
+ }
+ PyObject *pyItem = PyAcquireItem_FromCpp(item->Owner, false, pyAcquire);
+ PyObject *pyDesc = PyAcquireItemDesc_FromCpp(item, false, pyItem);
+ Py_DECREF(pyItem);
+ return pyDesc;
+}
+
bool PyFetchProgress::MediaChange(string Media, string Drive)
{
PyCbObj_END_ALLOW_THREADS
//std::cout << "MediaChange" << std::endl;
PyObject *arglist = Py_BuildValue("(ss)", Media.c_str(), Drive.c_str());
PyObject *result;
- RunSimpleCallback("mediaChange", arglist, &result);
+
+ if(PyObject_HasAttrString(callbackInst, "mediaChange"))
+ RunSimpleCallback("mediaChange", arglist, &result);
+ else
+ RunSimpleCallback("media_change", arglist, &result);
bool res = true;
if(!PyArg_Parse(result, "b", &res)) {
// no return value or None, assume false
+ PyCbObj_BEGIN_ALLOW_THREADS
return false;
}
@@ -116,14 +153,12 @@ bool PyFetchProgress::MediaChange(string Media, string Drive)
void PyFetchProgress::UpdateStatus(pkgAcquire::ItemDesc &Itm, int status)
{
//std::cout << "UpdateStatus: " << Itm.URI << " " << status << std::endl;
-
// Added object file size and object partial size to
// parameters that are passed to updateStatus.
// -- Stephan
- PyCbObj_END_ALLOW_THREADS
- PyObject *arglist = Py_BuildValue("(sssikk)", Itm.URI.c_str(),
- Itm.Description.c_str(),
- Itm.ShortDesc.c_str(),
+ PyObject *arglist = Py_BuildValue("(sssikk)", Itm.URI.c_str(),
+ Itm.Description.c_str(),
+ Itm.ShortDesc.c_str(),
status,
Itm.Owner->FileSize,
Itm.Owner->PartialSize);
@@ -131,42 +166,72 @@ void PyFetchProgress::UpdateStatus(pkgAcquire::ItemDesc &Itm, int status)
RunSimpleCallback("update_status_full", arglist);
// legacy version of the interface
- arglist = Py_BuildValue("(sssi)", Itm.URI.c_str(),
- Itm.Description.c_str(),
- Itm.ShortDesc.c_str(),
- status);
- RunSimpleCallback("updateStatus", arglist);
- PyCbObj_BEGIN_ALLOW_THREADS
+ arglist = Py_BuildValue("(sssi)", Itm.URI.c_str(), Itm.Description.c_str(),
+ Itm.ShortDesc.c_str(), status);
+
+ if(PyObject_HasAttrString(callbackInst, "updateStatus"))
+ RunSimpleCallback("updateStatus", arglist);
+ else
+ RunSimpleCallback("update_status", arglist);
}
void PyFetchProgress::IMSHit(pkgAcquire::ItemDesc &Itm)
{
- UpdateStatus(Itm, DLHit);
+ PyCbObj_END_ALLOW_THREADS
+ if (PyObject_HasAttrString(callbackInst, "ims_hit"))
+ RunSimpleCallback("ims_hit", TUPLEIZE(GetDesc(&Itm)));
+ else
+ UpdateStatus(Itm, DLHit);
+ PyCbObj_BEGIN_ALLOW_THREADS
}
void PyFetchProgress::Fetch(pkgAcquire::ItemDesc &Itm)
{
- UpdateStatus(Itm, DLQueued);
+ PyCbObj_END_ALLOW_THREADS
+ if (PyObject_HasAttrString(callbackInst, "fetch"))
+ RunSimpleCallback("fetch", TUPLEIZE(GetDesc(&Itm)));
+ else
+ UpdateStatus(Itm, DLQueued);
+ PyCbObj_BEGIN_ALLOW_THREADS
}
void PyFetchProgress::Done(pkgAcquire::ItemDesc &Itm)
{
- UpdateStatus(Itm, DLDone);
+ PyCbObj_END_ALLOW_THREADS
+ if (PyObject_HasAttrString(callbackInst, "done"))
+ RunSimpleCallback("done", TUPLEIZE(GetDesc(&Itm)));
+ else
+ UpdateStatus(Itm, DLDone);
+ PyCbObj_BEGIN_ALLOW_THREADS
}
void PyFetchProgress::Fail(pkgAcquire::ItemDesc &Itm)
{
+ PyCbObj_END_ALLOW_THREADS
+ if (PyObject_HasAttrString(callbackInst, "fail")) {
+ RunSimpleCallback("fail", TUPLEIZE(GetDesc(&Itm)));
+ PyCbObj_BEGIN_ALLOW_THREADS
+ return;
+ }
+
// Ignore certain kinds of transient failures (bad code)
- if (Itm.Owner->Status == pkgAcquire::Item::StatIdle)
+ if (Itm.Owner->Status == pkgAcquire::Item::StatIdle) {
+ PyCbObj_BEGIN_ALLOW_THREADS
return;
+ }
if (Itm.Owner->Status == pkgAcquire::Item::StatDone)
{
UpdateStatus(Itm, DLIgnored);
}
- UpdateStatus(Itm, DLFailed);
+
+ if (PyObject_HasAttrString(callbackInst, "fail"))
+ RunSimpleCallback("fail", TUPLEIZE(GetDesc(&Itm)));
+ else
+ UpdateStatus(Itm, DLFailed);
+ PyCbObj_BEGIN_ALLOW_THREADS
}
void PyFetchProgress::Start()
@@ -174,26 +239,13 @@ void PyFetchProgress::Start()
//std::cout << "Start" << std::endl;
pkgAcquireStatus::Start();
- // These attributes should be initialized before the first callback (start)
- // is invoked.
- // -- Stephan
- PyObject *o;
-
- o = Py_BuildValue("f", 0.0f);
- PyObject_SetAttrString(callbackInst, "currentCPS", o);
- Py_XDECREF(o);
- o = Py_BuildValue("f", 0.0f);
- PyObject_SetAttrString(callbackInst, "currentBytes", o);
- Py_XDECREF(o);
- o = Py_BuildValue("i", 0);
- PyObject_SetAttrString(callbackInst, "currentItems", o);
- Py_XDECREF(o);
- o = Py_BuildValue("i", 0);
- PyObject_SetAttrString(callbackInst, "totalItems", o);
- Py_XDECREF(o);
- o = Py_BuildValue("f", 0.0f);
- PyObject_SetAttrString(callbackInst, "totalBytes", o);
- Py_XDECREF(o);
+#ifdef COMPAT_0_7
+ setattr(callbackInst, "currentCPS", "d", 0);
+ setattr(callbackInst, "currentBytes", "d", 0);
+ setattr(callbackInst, "currentItems", "k", 0);
+ setattr(callbackInst, "totalItems", "k", 0);
+ setattr(callbackInst, "totalBytes", "d", 0);
+#endif
RunSimpleCallback("start");
/* After calling the start method we can safely allow
@@ -206,10 +258,11 @@ void PyFetchProgress::Start()
void PyFetchProgress::Stop()
{
/* After the stop operation occured no other threads
- * are allowed. This is done so we have a matching
+ * are allowed. This is done so we have a matching
* PyCbObj_END_ALLOW_THREADS to our previous
* PyCbObj_BEGIN_ALLOW_THREADS (Python requires this!).
*/
+
PyCbObj_END_ALLOW_THREADS
//std::cout << "Stop" << std::endl;
pkgAcquireStatus::Stop();
@@ -222,31 +275,51 @@ bool PyFetchProgress::Pulse(pkgAcquire * Owner)
pkgAcquireStatus::Pulse(Owner);
//std::cout << "Pulse" << std::endl;
- if(callbackInst == 0)
+ if(callbackInst == 0) {
+ PyCbObj_BEGIN_ALLOW_THREADS
return false;
+ }
- // set stats
- PyObject *o;
- o = Py_BuildValue("f", CurrentCPS);
- PyObject_SetAttrString(callbackInst, "currentCPS", o);
- Py_XDECREF(o);
- o = Py_BuildValue("f", CurrentBytes);
- PyObject_SetAttrString(callbackInst, "currentBytes", o);
- Py_XDECREF(o);
- o = Py_BuildValue("i", CurrentItems);
- PyObject_SetAttrString(callbackInst, "currentItems", o);
- Py_XDECREF(o);
- o = Py_BuildValue("i", TotalItems);
- PyObject_SetAttrString(callbackInst, "totalItems", o);
- Py_XDECREF(o);
- o = Py_BuildValue("f", TotalBytes);
- PyObject_SetAttrString(callbackInst, "totalBytes", o);
- Py_XDECREF(o);
+ setattr(callbackInst, "last_bytes", "d", LastBytes);
+ setattr(callbackInst, "current_cps", "d", CurrentCPS);
+ setattr(callbackInst, "current_bytes", "d", CurrentBytes);
+ setattr(callbackInst, "total_bytes", "d", TotalBytes);
+ setattr(callbackInst, "fetched_bytes", "d", FetchedBytes);
+ setattr(callbackInst, "elapsed_time", "k", ElapsedTime);
+ setattr(callbackInst, "current_items", "k", CurrentItems);
+ setattr(callbackInst, "total_items", "k", TotalItems);
+
+ // New style
+ if (!PyObject_HasAttrString(callbackInst, "updateStatus")) {
+ PyObject *result1;
+ bool res1 = true;
+
+ if (pyAcquire == NULL) {
+ pyAcquire = PyAcquire_FromCpp(Owner, false, NULL);
+ }
+ Py_INCREF(pyAcquire);
+ if (RunSimpleCallback("pulse", TUPLEIZE(pyAcquire) , &result1)) {
+ if (result1 != NULL && PyArg_Parse(result1, "b", &res1) && res1 == false) {
+ // the user returned a explicit false here, stop
+ PyCbObj_BEGIN_ALLOW_THREADS
+ return false;
+ }
+ }
+ PyCbObj_BEGIN_ALLOW_THREADS
+ return true;
+ }
+#ifdef COMPAT_0_7
+ setattr(callbackInst, "currentCPS", "d", CurrentCPS);
+ setattr(callbackInst, "currentBytes", "d", CurrentBytes);
+ setattr(callbackInst, "totalBytes", "d", TotalBytes);
+ setattr(callbackInst, "fetchedBytes", "d", FetchedBytes);
+ setattr(callbackInst, "currentItems", "k", CurrentItems);
+ setattr(callbackInst, "totalItems", "k", TotalItems);
// Go through the list of items and add active items to the
// activeItems vector.
map<pkgAcquire::Worker *, pkgAcquire::ItemDesc *> activeItemMap;
-
+
for(pkgAcquire::Worker *Worker = Owner->WorkersBegin();
Worker != 0; Worker = Owner->WorkerStep(Worker)) {
@@ -256,7 +329,7 @@ bool PyFetchProgress::Pulse(pkgAcquire * Owner)
}
activeItemMap.insert(std::make_pair(Worker, Worker->CurrentItem));
}
-
+
// Create the tuple that is passed as argument to pulse().
// This tuple contains activeItemMap.size() item tuples.
PyObject *arglist;
@@ -270,8 +343,8 @@ bool PyFetchProgress::Pulse(pkgAcquire * Owner)
map<pkgAcquire::Worker *, pkgAcquire::ItemDesc *>::iterator iter;
int tuplePos;
- for(tuplePos = 0, iter = activeItemMap.begin();
- iter != activeItemMap.end(); ++iter, tuplePos++) {
+ for(tuplePos = 0, iter = activeItemMap.begin();
+ iter != activeItemMap.end(); ++iter, tuplePos++) {
pkgAcquire::Worker *worker = iter->first;
pkgAcquire::ItemDesc *itm = iter->second;
@@ -304,13 +377,15 @@ bool PyFetchProgress::Pulse(pkgAcquire * Owner)
PyObject *result;
bool res = true;
- RunSimpleCallback("pulse_items", arglist, &result);
- if (result != NULL && PyArg_Parse(result, "b", &res) && res == false) {
- // the user returned a explicit false here, stop
- PyCbObj_BEGIN_ALLOW_THREADS
- return false;
+ if (RunSimpleCallback("pulse_items", arglist, &result)) {
+ if (result != NULL && PyArg_Parse(result, "b", &res) && res == false) {
+ // the user returned a explicit false here, stop
+ PyCbObj_BEGIN_ALLOW_THREADS
+ return false;
+ }
}
+
arglist = Py_BuildValue("()");
if (!RunSimpleCallback("pulse", arglist, &result)) {
PyCbObj_BEGIN_ALLOW_THREADS
@@ -319,7 +394,7 @@ bool PyFetchProgress::Pulse(pkgAcquire * Owner)
if((result == NULL) || (!PyArg_Parse(result, "b", &res)))
{
- // most of the time the user who subclasses the pulse()
+ // most of the time the user who subclasses the pulse()
// method forgot to add a return {True,False} so we just
// assume he wants a True
PyCbObj_BEGIN_ALLOW_THREADS
@@ -329,6 +404,9 @@ bool PyFetchProgress::Pulse(pkgAcquire * Owner)
PyCbObj_BEGIN_ALLOW_THREADS
// fetching can be canceld by returning false
return res;
+#else
+ return false;
+#endif
}
@@ -337,26 +415,28 @@ bool PyFetchProgress::Pulse(pkgAcquire * Owner)
void PyInstallProgress::StartUpdate()
{
- RunSimpleCallback("startUpdate");
+ if (!RunSimpleCallback("startUpdate"))
+ RunSimpleCallback("start_update");
PyCbObj_BEGIN_ALLOW_THREADS
}
void PyInstallProgress::UpdateInterface()
{
PyCbObj_END_ALLOW_THREADS
- RunSimpleCallback("updateInterface");
+ if (!RunSimpleCallback("updateInterface"))
+ RunSimpleCallback("update_interface");
PyCbObj_BEGIN_ALLOW_THREADS
}
void PyInstallProgress::FinishUpdate()
{
PyCbObj_END_ALLOW_THREADS
- RunSimpleCallback("finishUpdate");
+ if (!RunSimpleCallback("finishUpdate"))
+ RunSimpleCallback("finish_update");
}
pkgPackageManager::OrderResult PyInstallProgress::Run(pkgPackageManager *pm)
{
- void *dummy;
pkgPackageManager::OrderResult res;
int ret;
pid_t child_id;
@@ -372,7 +452,7 @@ pkgPackageManager::OrderResult PyInstallProgress::Run(pkgPackageManager *pm)
PyObject *method = PyObject_GetAttrString(callbackInst, "fork");
std::cerr << "custom fork found" << std::endl;
PyObject *arglist = Py_BuildValue("()");
- PyObject *result = PyEval_CallObject(method, arglist);
+ PyObject *result = PyObject_CallObject(method, arglist);
Py_DECREF(arglist);
if (result == NULL) {
std::cerr << "fork method invalid" << std::endl;
@@ -412,18 +492,23 @@ pkgPackageManager::OrderResult PyInstallProgress::Run(pkgPackageManager *pm)
StartUpdate();
PyCbObj_END_ALLOW_THREADS
- if(PyObject_HasAttrString(callbackInst, "waitChild")) {
- PyObject *method = PyObject_GetAttrString(callbackInst, "waitChild");
+ if(PyObject_HasAttrString(callbackInst, "waitChild") ||
+ PyObject_HasAttrString(callbackInst, "wait_child")) {
+ PyObject *method;
+ if (PyObject_HasAttrString(callbackInst, "waitChild"))
+ method = PyObject_GetAttrString(callbackInst, "waitChild");
+ else
+ method = PyObject_GetAttrString(callbackInst, "wait_child");
//std::cerr << "custom waitChild found" << std::endl;
PyObject *arglist = Py_BuildValue("(i)",child_id);
- PyObject *result = PyEval_CallObject(method, arglist);
+ PyObject *result = PyObject_CallObject(method, arglist);
Py_DECREF(arglist);
if (result == NULL) {
std::cerr << "waitChild method invalid" << std::endl;
PyErr_Print();
+ PyCbObj_BEGIN_ALLOW_THREADS
return pkgPackageManager::Failed;
}
- int child_res;
if(!PyArg_Parse(result, "i", &res) ) {
std::cerr << "custom waitChild() result could not be parsed?"<< std::endl;
PyCbObj_BEGIN_ALLOW_THREADS
@@ -456,11 +541,10 @@ pkgPackageManager::OrderResult PyInstallProgress::Run(pkgPackageManager *pm)
void PyCdromProgress::Update(string text, int current)
{
PyObject *arglist = Py_BuildValue("(si)", text.c_str(), current);
-
- PyObject *o = Py_BuildValue("i", totalSteps);
- PyObject_SetAttrString(callbackInst, "totalSteps", o);
- Py_XDECREF(o);
-
+ setattr(callbackInst, "total_steps", "i", totalSteps);
+ #ifdef COMPAT_0_7
+ setattr(callbackInst, "totalSteps", "i", totalSteps);
+ #endif
RunSimpleCallback("update", arglist);
}
@@ -468,7 +552,10 @@ bool PyCdromProgress::ChangeCdrom()
{
PyObject *arglist = Py_BuildValue("()");
PyObject *result;
- RunSimpleCallback("changeCdrom", arglist, &result);
+ if (PyObject_HasAttrString(callbackInst, "changeCdrom"))
+ RunSimpleCallback("changeCdrom", arglist, &result);
+ else
+ RunSimpleCallback("change_cdrom", arglist, &result);
bool res = true;
if(!PyArg_Parse(result, "b", &res))
@@ -481,18 +568,28 @@ bool PyCdromProgress::ChangeCdrom()
bool PyCdromProgress::AskCdromName(string &Name)
{
PyObject *arglist = Py_BuildValue("()");
- PyObject *result;
- RunSimpleCallback("askCdromName", arglist, &result);
-
const char *new_name;
bool res;
- if(!PyArg_Parse(result, "(bs)", &res, &new_name))
- std::cerr << "AskCdromName: result could not be parsed" << std::endl;
-
- //std::cerr << "got: " << res << " " << "name: " << new_name << std::endl;
-
- // set the new name
- Name = string(new_name);
+ PyObject *result;
- return res;
+ // Old style: (True, name) on success, (False, name) on failure.
+ if (PyObject_HasAttrString(callbackInst, "askAdromName")) {
+ RunSimpleCallback("askAdromName", arglist, &result);
+ if(!PyArg_Parse(result, "(bs)", &res, &new_name))
+ std::cerr << "AskCdromName: result could not be parsed" << std::endl;
+ // set the new name
+ Name = string(new_name);
+ return res;
+ }
+ // New style: String on success, None on failure.
+ else {
+ RunSimpleCallback("ask_cdrom_name", arglist, &result);
+ if(result == Py_None)
+ return false;
+ if(!PyArg_Parse(result, "s", &new_name))
+ std::cerr << "ask_cdrom_name: result could not be parsed" << std::endl;
+ else
+ Name = string(new_name);
+ return true;
+ }
}
diff --git a/python/progress.h b/python/progress.h
index 29243bfc..4e66c771 100644
--- a/python/progress.h
+++ b/python/progress.h
@@ -18,7 +18,7 @@
/* PyCbObj_BEGIN_ALLOW_THREADS and PyCbObj_END_ALLOW_THREADS are sligthly
* modified versions of Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS.
* Instead of storing the thread state in a function-local variable these
- * use a class attribute (with the same) name, allowing blocking and
+ * use a class attribute (with the same) name, allowing blocking and
* unblocking from different class methods.
* Py_BLOCK_THREADS and Py_UNBLOCK_THREADS do not define their own
* local variable but use the one provided by PyCbObj_BEGIN_ALLOW_THREADS
@@ -62,6 +62,10 @@ struct PyOpProgress : public OpProgress, public PyCallbackObj
struct PyFetchProgress : public pkgAcquireStatus, public PyCallbackObj
{
+ protected:
+ PyObject *pyAcquire;
+ PyObject *GetDesc(pkgAcquire::ItemDesc *item);
+ public:
enum {
DLDone, DLQueued, DLFailed, DLHit, DLIgnored
};
@@ -70,6 +74,12 @@ struct PyFetchProgress : public pkgAcquireStatus, public PyCallbackObj
virtual bool MediaChange(string Media, string Drive);
+ void setPyAcquire(PyObject *o) {
+ Py_CLEAR(pyAcquire);
+ Py_INCREF(o);
+ pyAcquire = o;
+ }
+
/* apt stuff */
virtual void IMSHit(pkgAcquire::ItemDesc &Itm);
virtual void Fetch(pkgAcquire::ItemDesc &Itm);
@@ -79,7 +89,8 @@ struct PyFetchProgress : public pkgAcquireStatus, public PyCallbackObj
virtual void Stop();
bool Pulse(pkgAcquire * Owner);
- PyFetchProgress() : PyCallbackObj() {};
+ PyFetchProgress() : PyCallbackObj(), pyAcquire(0) {};
+ ~PyFetchProgress() { Py_XDECREF(pyAcquire); };
};
struct PyInstallProgress : public PyCallbackObj
diff --git a/python/python-apt-helpers.cc b/python/python-apt-helpers.cc
new file mode 100644
index 00000000..7a0f20c4
--- /dev/null
+++ b/python/python-apt-helpers.cc
@@ -0,0 +1,68 @@
+/*
+ * python-apt.h - Common object creation functions for the public API
+ *
+ * Copyright 2010 Julian Andres Klode <jak@debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include "apt_pkgmodule.h"
+
+/**
+ * Short macro to be used for the generic FromCpp functions.
+ *
+ */
+#define NEW_FROM(NAME,TYPE,Cpp) \
+PyObject* NAME(Cpp const &obj, bool Delete, PyObject *Owner) \
+{ \
+ CppPyObject<Cpp> *Obj = CppPyObject_NEW<Cpp>(Owner, TYPE, obj); \
+ Obj->NoDelete = (!Delete); \
+ return Obj; \
+}
+
+// Create all those functions
+NEW_FROM(PyAcquireFile_FromCpp,&PyAcquireFile_Type,pkgAcqFile*)
+NEW_FROM(PyAcquireItem_FromCpp,&PyAcquireItem_Type,pkgAcquire::Item*)
+NEW_FROM(PyAcquireItemDesc_FromCpp,&PyAcquireItemDesc_Type,pkgAcquire::ItemDesc*)
+NEW_FROM(PyAcquireWorker_FromCpp,&PyAcquireWorker_Type,pkgAcquire::Worker*)
+NEW_FROM(PyActionGroup_FromCpp,&PyActionGroup_Type,pkgDepCache::ActionGroup*)
+NEW_FROM(PyCache_FromCpp,&PyCache_Type,pkgCache*)
+NEW_FROM(PyCacheFile_FromCpp,&PyCacheFile_Type,pkgCacheFile*)
+NEW_FROM(PyCdrom_FromCpp,&PyCdrom_Type,pkgCdrom)
+NEW_FROM(PyConfiguration_FromCpp,&PyConfiguration_Type,Configuration*)
+NEW_FROM(PyDepCache_FromCpp,&PyDepCache_Type,pkgDepCache*)
+NEW_FROM(PyDependency_FromCpp,&PyDependency_Type,pkgCache::DepIterator)
+//NEW_FROM(PyDependencyList_FromCpp,&PyDependencyList_Type,RDepListStruct)
+NEW_FROM(PyDescription_FromCpp,&PyDescription_Type,pkgCache::DescIterator)
+NEW_FROM(PyHashes_FromCpp,&PyHashes_Type,Hashes)
+NEW_FROM(PyHashString_FromCpp,&PyHashString_Type,HashString*)
+NEW_FROM(PyIndexRecords_FromCpp,&PyIndexRecords_Type,indexRecords*)
+NEW_FROM(PyMetaIndex_FromCpp,&PyMetaIndex_Type,metaIndex*)
+NEW_FROM(PyPackage_FromCpp,&PyPackage_Type,pkgCache::PkgIterator)
+NEW_FROM(PyIndexFile_FromCpp,&PyIndexFile_Type,pkgIndexFile*)
+NEW_FROM(PyPackageFile_FromCpp,&PyPackageFile_Type,pkgCache::PkgFileIterator)
+//NEW_FROM(PyPackageList_FromCpp,&PyPackageList_Type,PkgListStruct)
+NEW_FROM(PyPackageManager_FromCpp,&PyPackageManager_Type,pkgPackageManager*)
+//NEW_FROM(PyPackageRecords_FromCpp,&PyPackageRecords_Type,PkgRecordsStruct)
+NEW_FROM(PyPolicy_FromCpp,&PyPolicy_Type,pkgPolicy*)
+NEW_FROM(PyProblemResolver_FromCpp,&PyProblemResolver_Type,pkgProblemResolver*)
+NEW_FROM(PySourceList_FromCpp,&PySourceList_Type,pkgSourceList*)
+//NEW_FROM(PySourceRecords_FromCpp,&PySourceRecords_Type,PkgSrcRecordsStruct)
+NEW_FROM(PyTagFile_FromCpp,&PyTagFile_Type,pkgTagFile)
+NEW_FROM(PyTagSection_FromCpp,&PyTagSection_Type,pkgTagSection)
+NEW_FROM(PyVersion_FromCpp,&PyVersion_Type,pkgCache::VerIterator)
+
+#undef NEW_FROM
diff --git a/python/python-apt.h b/python/python-apt.h
new file mode 100644
index 00000000..b9fc9212
--- /dev/null
+++ b/python/python-apt.h
@@ -0,0 +1,347 @@
+/*
+ * python-apt.h - Header file for the public interface.
+ *
+ * Copyright 2009-2010 Julian Andres Klode <jak@debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef PYTHON_APT_H
+#define PYTHON_APT_H
+#include <Python.h>
+#include "generic.h"
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/acquire-item.h>
+#include <apt-pkg/packagemanager.h>
+#include <apt-pkg/version.h>
+#include <apt-pkg/deblistparser.h>
+#include <apt-pkg/pkgcache.h>
+#include <apt-pkg/cachefile.h>
+#include <apt-pkg/tagfile.h>
+#include <apt-pkg/init.h>
+#include <apt-pkg/pkgsystem.h>
+#include <apt-pkg/cdrom.h>
+#include <apt-pkg/algorithms.h>
+#include <apt-pkg/hashes.h>
+
+typedef PyObject *ActionGroupF(pkgDepCache::ActionGroup *);
+typedef pkgDepCache::ActionGroup*& ActionGroupT(PyObject *self);
+
+struct _PyAptPkgAPIStruct {
+ // apt_pkg.Acquire (pkgAcquire*)
+ PyTypeObject *acquire_type;
+ PyObject* (*acquire_fromcpp)(pkgAcquire *acquire, bool Delete, PyObject*);
+ pkgAcquire*& (*acquire_tocpp)(PyObject *self);
+ // apt_pkg.AcquireFile
+ PyTypeObject *acquirefile_type;
+ PyObject* (*acquirefile_fromcpp)(pkgAcqFile* const &obj, bool Delete, PyObject *Owner);
+ pkgAcqFile*& (*acquirefile_tocpp)(PyObject *self);
+
+ // apt_pkg.AcquireItem
+ PyTypeObject *acquireitem_type;
+ PyObject* (*acquireitem_fromcpp)(pkgAcquire::Item* const &obj, bool Delete, PyObject *Owner);
+ pkgAcquire::Item*& (*acquireitem_tocpp)(PyObject *self);
+ // apt_pkg.AcquireItemDesc
+ PyTypeObject *acquireitemdesc_type;
+ PyObject* (*acquireitemdesc_fromcpp)(pkgAcquire::ItemDesc* const &obj, bool Delete, PyObject *Owner);
+ pkgAcquire::ItemDesc*& (*acquireitemdesc_tocpp)(PyObject *self);
+
+ PyTypeObject *acquireworker_type;
+ PyObject* (*acquireworker_fromcpp)(pkgAcquire::Worker* const &obj, bool Delete, PyObject *Owner);
+ pkgAcquire::Worker*& (*acquireworker_tocpp)(PyObject *self);
+
+ PyTypeObject *actiongroup_type;
+ PyObject* (*actiongroup_fromcpp)(pkgDepCache::ActionGroup* const &obj, bool Delete, PyObject *Owner);
+ pkgDepCache::ActionGroup*& (*actiongroup_tocpp)(PyObject *self);
+
+ PyTypeObject *cache_type;
+ PyObject* (*cache_fromcpp)(pkgCache* const &obj, bool Delete, PyObject *Owner);
+ pkgCache*& (*cache_tocpp)(PyObject *self);
+
+ PyTypeObject *cachefile_type;
+ PyObject* (*cachefile_fromcpp)(pkgCacheFile* const &obj, bool Delete, PyObject *Owner);
+ pkgCacheFile*& (*cachefile_tocpp)(PyObject *self);
+
+ PyTypeObject *cdrom_type;
+ PyObject* (*cdrom_fromcpp)(pkgCdrom const &obj, bool Delete, PyObject *Owner);
+ pkgCdrom& (*cdrom_tocpp)(PyObject *self);
+
+ PyTypeObject *configuration_type;
+ PyObject* (*configuration_fromcpp)(Configuration* const &obj, bool Delete, PyObject *Owner);
+ Configuration*& (*configuration_tocpp)(PyObject *self);
+
+ PyTypeObject *depcache_type;
+ PyObject* (*depcache_fromcpp)(pkgDepCache* const &obj, bool Delete, PyObject *Owner);
+ pkgDepCache*& (*depcache_tocpp)(PyObject *self);
+
+ PyTypeObject *dependency_type;
+ PyObject* (*dependency_fromcpp)(pkgCache::DepIterator const &obj, bool Delete, PyObject *Owner);
+ pkgCache::DepIterator& (*dependency_tocpp)(PyObject *self);
+
+ PyTypeObject *dependencylist_type;
+ void *dependencylist_fromcpp; // FIXME: need dependencylist_fromcpp
+ void *dependencylist_tocpp; // FIXME: need dependencylist_tocpp
+
+ PyTypeObject *description_type;
+ PyObject* (*description_fromcpp)(pkgCache::DescIterator const &obj, bool Delete, PyObject *Owner);
+ pkgCache::DescIterator& (*description_tocpp)(PyObject *self);
+
+ PyTypeObject *hashes_type;
+ PyObject* (*hashes_fromcpp)(Hashes const &obj, bool Delete, PyObject *Owner);
+ Hashes& (*hashes_tocpp)(PyObject *self);
+
+ PyTypeObject *hashstring_type;
+ PyObject* (*hashstring_fromcpp)(HashString* const &obj, bool Delete, PyObject *Owner);
+ HashString*& (*hashstring_tocpp)(PyObject *self);
+
+ PyTypeObject *indexrecords_type;
+ PyObject* (*indexrecords_fromcpp)(indexRecords* const &obj, bool Delete, PyObject *Owner);
+ indexRecords*& (*indexrecords_tocpp)(PyObject *self);
+
+ PyTypeObject *metaindex_type;
+ PyObject* (*metaindex_fromcpp)(metaIndex* const &obj, bool Delete, PyObject *Owner);
+ metaIndex*& (*metaindex_tocpp)(PyObject *self);
+
+ PyTypeObject *package_type;
+ PyObject* (*package_fromcpp)(pkgCache::PkgIterator const &obj, bool Delete, PyObject *Owner);
+ pkgCache::PkgIterator& (*package_tocpp)(PyObject *self);
+
+ PyTypeObject *packagefile_type;
+ PyObject* (*packagefile_fromcpp)(pkgCache::PkgFileIterator const &obj, bool Delete, PyObject *Owner);
+ pkgCache::PkgFileIterator& (*packagefile_tocpp)(PyObject *self);
+
+ PyTypeObject *packageindexfile_type;
+ PyObject* (*indexfile_fromcpp)(pkgIndexFile* const &obj, bool Delete, PyObject *Owner);
+ pkgIndexFile*& (*packageindexfile_tocpp)(PyObject *self);
+
+ PyTypeObject *packagelist_type;
+ void *packagelist_fromcpp; // FIXME: need packagelist_fromcpp
+ void *packagelist_tocpp; // FIXME: need packagelist_tocpp
+
+ PyTypeObject *packagemanager_type;
+ PyObject* (*packagemanager_fromcpp)(pkgPackageManager* const &obj, bool Delete, PyObject *Owner);
+ pkgPackageManager*& (*packagemanager_tocpp)(PyObject *self);
+
+ PyTypeObject *packagerecords_type;
+ void *packagerecords_fromcpp; // FIXME: need packagerecords_fromcpp
+ void *packagerecords_tocpp; // FIXME: need packagerecords_tocpp
+
+ PyTypeObject *policy_type;
+ PyObject* (*policy_fromcpp)(pkgPolicy* const &obj, bool Delete, PyObject *Owner);
+ pkgPolicy*& (*policy_tocpp)(PyObject *self);
+
+ PyTypeObject *problemresolver_type;
+ PyObject* (*problemresolver_fromcpp)(pkgProblemResolver* const &obj, bool Delete, PyObject *Owner);
+ pkgProblemResolver*& (*problemresolver_tocpp)(PyObject *self);
+
+ PyTypeObject *sourcelist_type;
+ PyObject* (*sourcelist_fromcpp)(pkgSourceList* const &obj, bool Delete, PyObject *Owner);
+ pkgSourceList*& (*sourcelist_tocpp)(PyObject *self);
+
+ PyTypeObject *sourcerecords_type;
+ void *sourcerecords_fromcpp; // FIXME: need sourcerecords_fromcpp
+ void *sourcerecords_tocpp; // FIXME: need sourcerecords_tocpp
+
+ PyTypeObject *tagfile_type;
+ PyObject* (*tagfile_fromcpp)(pkgTagFile const &obj, bool Delete, PyObject *Owner);
+ pkgTagFile& (*tagfile_tocpp)(PyObject *self);
+
+ PyTypeObject *tagsection_type;
+ PyObject* (*tagsection_fromcpp)(pkgTagSection const &obj, bool Delete, PyObject *Owner);
+ pkgTagSection& (*tagsection_tocpp)(PyObject *self);
+
+ PyTypeObject *version_type;
+ PyObject* (*version_fromcpp)(pkgCache::VerIterator const &obj, bool Delete, PyObject *Owner);
+ pkgCache::VerIterator& (*version_tocpp)(PyObject *self);
+
+};
+
+// Checking macros.
+# define PyAcquire_Check(op) PyObject_TypeCheck(op, &PyAcquire_Type)
+# define PyAcquireFile_Check(op) PyObject_TypeCheck(op, &PyAcquireFile_Type)
+# define PyAcquireItem_Check(op) PyObject_TypeCheck(op, &PyAcquireItem_Type)
+# define PyAcquireItemDesc_Check(op) PyObject_TypeCheck(op, &PyAcquireItemDesc_Type)
+# define PyAcquireWorker_Check(op) PyObject_TypeCheck(op, &PyAcquireWorker_Type)
+# define PyActionGroup_Check(op) PyObject_TypeCheck(op, &PyActionGroup_Type)
+# define PyCache_Check(op) PyObject_TypeCheck(op, &PyCache_Type)
+# define PyCacheFile_Check(op) PyObject_TypeCheck(op, &PyCacheFile_Type)
+# define PyCdrom_Check(op) PyObject_TypeCheck(op, &PyCdrom_Type)
+# define PyConfiguration_Check(op) PyObject_TypeCheck(op, &PyConfiguration_Type)
+# define PyDepCache_Check(op) PyObject_TypeCheck(op, &PyDepCache_Type)
+# define PyDependency_Check(op) PyObject_TypeCheck(op, &PyDependency_Type)
+# define PyDependencyList_Check(op) PyObject_TypeCheck(op, &PyDependencyList_Type)
+# define PyDescription_Check(op) PyObject_TypeCheck(op, &PyDescription_Type)
+# define PyHashes_Check(op) PyObject_TypeCheck(op, &PyHashes_Type)
+# define PyHashString_Check(op) PyObject_TypeCheck(op, &PyHashString_Type)
+# define PyIndexRecords_Check(op) PyObject_TypeCheck(op, &PyIndexRecords_Type)
+# define PyMetaIndex_Check(op) PyObject_TypeCheck(op, &PyMetaIndex_Type)
+# define PyPackage_Check(op) PyObject_TypeCheck(op, &PyPackage_Type)
+# define PyPackageFile_Check(op) PyObject_TypeCheck(op, &PyPackageFile_Type)
+# define PyIndexFile_Check(op) PyObject_TypeCheck(op, &PyIndexFile_Type)
+# define PyPackageList_Check(op) PyObject_TypeCheck(op, &PyPackageList_Type)
+# define PyPackageManager_Check(op) PyObject_TypeCheck(op, &PyPackageManager_Type)
+# define PyPackageRecords_Check(op) PyObject_TypeCheck(op, &PyPackageRecords_Type)
+# define PyPolicy_Check(op) PyObject_TypeCheck(op, &PyPolicy_Type)
+# define PyProblemResolver_Check(op) PyObject_TypeCheck(op, &PyProblemResolver_Type)
+# define PySourceList_Check(op) PyObject_TypeCheck(op, &PySourceList_Type)
+# define PySourceRecords_Check(op) PyObject_TypeCheck(op, &PySourceRecords_Type)
+# define PyTagFile_Check(op) PyObject_TypeCheck(op, &PyTagFile_Type)
+# define PyTagSection_Check(op) PyObject_TypeCheck(op, &PyTagSection_Type)
+# define PyVersion_Check(op) PyObject_TypeCheck(op, &PyVersion_Type)
+// Exact check macros.
+# define PyAcquire_CheckExact(op) (op->op_type == &PyAcquire_Type)
+# define PyAcquireFile_CheckExact(op) (op->op_type == &PyAcquireFile_Type)
+# define PyAcquireItem_CheckExact(op) (op->op_type == &PyAcquireItem_Type)
+# define PyAcquireItemDesc_CheckExact(op) (op->op_type == &PyAcquireItemDesc_Type)
+# define PyAcquireWorker_CheckExact(op) (op->op_type == &PyAcquireWorker_Type)
+# define PyActionGroup_CheckExact(op) (op->op_type == &PyActionGroup_Type)
+# define PyCache_CheckExact(op) (op->op_type == &PyCache_Type)
+# define PyCacheFile_CheckExact(op) (op->op_type == &PyCacheFile_Type)
+# define PyCdrom_CheckExact(op) (op->op_type == &PyCdrom_Type)
+# define PyConfiguration_CheckExact(op) (op->op_type == &PyConfiguration_Type)
+# define PyDepCache_CheckExact(op) (op->op_type == &PyDepCache_Type)
+# define PyDependency_CheckExact(op) (op->op_type == &PyDependency_Type)
+# define PyDependencyList_CheckExact(op) (op->op_type == &PyDependencyList_Type)
+# define PyDescription_CheckExact(op) (op->op_type == &PyDescription_Type)
+# define PyHashes_CheckExact(op) (op->op_type == &PyHashes_Type)
+# define PyHashString_CheckExact(op) (op->op_type == &PyHashString_Type)
+# define PyIndexRecords_CheckExact(op) (op->op_type == &PyIndexRecords_Type)
+# define PyMetaIndex_CheckExact(op) (op->op_type == &PyMetaIndex_Type)
+# define PyPackage_CheckExact(op) (op->op_type == &PyPackage_Type)
+# define PyPackageFile_CheckExact(op) (op->op_type == &PyPackageFile_Type)
+# define PyIndexFile_CheckExact(op) (op->op_type == &PyIndexFile_Type)
+# define PyPackageList_CheckExact(op) (op->op_type == &PyPackageList_Type)
+# define PyPackageManager_CheckExact(op) (op->op_type == &PyPackageManager_Type)
+# define PyPackageRecords_CheckExact(op) (op->op_type == &PyPackageRecords_Type)
+# define PyPolicy_CheckExact(op) (op->op_type == &PyPolicy_Type)
+# define PyProblemResolver_CheckExact(op) (op->op_type == &PyProblemResolver_Type)
+# define PySourceList_CheckExact(op) (op->op_type == &PySourceList_Type)
+# define PySourceRecords_CheckExact(op) (op->op_type == &PySourceRecords_Type)
+# define PyTagFile_CheckExact(op) (op->op_type == &PyTagFile_Type)
+# define PyTagSection_CheckExact(op) (op->op_type == &PyTagSection_Type)
+# define PyVersion_CheckExact(op) (op->op_type == &PyVersion_Type)
+
+# ifndef APT_PKGMODULE_H
+static struct _PyAptPkgAPIStruct *_PyAptPkg_API;
+
+static int import_apt_pkg(void) {
+# if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 1
+ _PyAptPkg_API = (_PyAptPkgAPIStruct *)PyCapsule_Import("apt_pkg._C_API", 0);
+# else
+ _PyAptPkg_API = (_PyAptPkgAPIStruct *)PyCObject_Import("apt_pkg", "_C_API");
+# endif // PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 1
+ return (_PyAptPkg_API != NULL) ? 0 : -1;
+}
+
+# define PyAcquire_Type *(_PyAptPkg_API->acquire_type)
+# define PyAcquireFile_Type *(_PyAptPkg_API->acquirefile_type)
+# define PyAcquireItem_Type *(_PyAptPkg_API->acquireitem_type)
+# define PyAcquireItemDesc_Type *(_PyAptPkg_API->acquireitemdesc_type)
+# define PyAcquireWorker_Type *(_PyAptPkg_API->acquireworker_type)
+# define PyActionGroup_Type *(_PyAptPkg_API->actiongroup_type)
+# define PyCache_Type *(_PyAptPkg_API->cache_type)
+# define PyCacheFile_Type *(_PyAptPkg_API->cachefile_type)
+# define PyCdrom_Type *(_PyAptPkg_API->cdrom_type)
+# define PyConfiguration_Type *(_PyAptPkg_API->configuration_type)
+# define PyDepCache_Type *(_PyAptPkg_API->depcache_type)
+# define PyDependency_Type *(_PyAptPkg_API->dependency_type)
+# define PyDependencyList_Type *(_PyAptPkg_API->dependencylist_type)
+# define PyDescription_Type *(_PyAptPkg_API->description_type)
+# define PyHashes_Type *(_PyAptPkg_API->hashes_type)
+# define PyHashString_Type *(_PyAptPkg_API->hashstring_type)
+# define PyIndexRecords_Type *(_PyAptPkg_API->indexrecords_type)
+# define PyMetaIndex_Type *(_PyAptPkg_API->metaindex_type)
+# define PyPackage_Type *(_PyAptPkg_API->package_type)
+# define PyPackageFile_Type *(_PyAptPkg_API->packagefile_type)
+# define PyIndexFile_Type *(_PyAptPkg_API->packageindexfile_type)
+# define PyPackageList_Type *(_PyAptPkg_API->packagelist_type)
+# define PyPackageManager_Type *(_PyAptPkg_API->packagemanager_type)
+# define PyPackageRecords_Type *(_PyAptPkg_API->packagerecords_type)
+# define PyPolicy_Type *(_PyAptPkg_API->policy_type)
+# define PyProblemResolver_Type *(_PyAptPkg_API->problemresolver_type)
+# define PySourceList_Type *(_PyAptPkg_API->sourcelist_type)
+# define PySourceRecords_Type *(_PyAptPkg_API->sourcerecords_type)
+# define PyTagFile_Type *(_PyAptPkg_API->tagfile_type)
+# define PyTagSection_Type *(_PyAptPkg_API->tagsection_type)
+# define PyVersion_Type *(_PyAptPkg_API->version_type)
+// Code
+# define PyAcquire_ToCpp _PyAptPkg_API->acquire_tocpp
+# define PyAcquireFile_ToCpp _PyAptPkg_API->acquirefile_tocpp
+# define PyAcquireItem_ToCpp _PyAptPkg_API->acquireitem_tocpp
+# define PyAcquireItemDesc_ToCpp _PyAptPkg_API->acquireitemdesc_tocpp
+# define PyAcquireWorker_ToCpp _PyAptPkg_API->acquireworker_tocpp
+# define PyActionGroup_ToCpp _PyAptPkg_API->actiongroup_tocpp
+# define PyCache_ToCpp _PyAptPkg_API->cache_tocpp
+# define PyCacheFile_ToCpp _PyAptPkg_API->cachefile_tocpp
+# define PyCdrom_ToCpp _PyAptPkg_API->cdrom_tocpp
+# define PyConfiguration_ToCpp _PyAptPkg_API->configuration_tocpp
+# define PyDepCache_ToCpp _PyAptPkg_API->depcache_tocpp
+# define PyDependency_ToCpp _PyAptPkg_API->dependency_tocpp
+# define PyDependencyList_ToCpp _PyAptPkg_API->dependencylist_tocpp // NULL
+# define PyDescription_ToCpp _PyAptPkg_API->description_tocpp
+# define PyHashes_ToCpp _PyAptPkg_API->hashes_tocpp
+# define PyHashString_ToCpp _PyAptPkg_API->hashstring_tocpp
+# define PyIndexRecords_ToCpp _PyAptPkg_API->indexrecords_tocpp
+# define PyMetaIndex_ToCpp _PyAptPkg_API->metaindex_tocpp
+# define PyPackage_ToCpp _PyAptPkg_API->package_tocpp
+# define PyPackageFile_ToCpp _PyAptPkg_API->packagefile_tocpp
+# define PyIndexFile_ToCpp _PyAptPkg_API->packageindexfile_tocpp
+# define PyPackageList_ToCpp _PyAptPkg_API->packagelist_tocpp // NULL
+# define PyPackageManager_ToCpp _PyAptPkg_API->packagemanager_tocpp
+# define PyPackageRecords_ToCpp _PyAptPkg_API->packagerecords_tocpp
+# define PyPolicy_ToCpp _PyAptPkg_API->policy_tocpp
+# define PyProblemResolver_ToCpp _PyAptPkg_API->problemresolver_tocpp
+# define PySourceList_ToCpp _PyAptPkg_API->sourcelist_tocpp
+# define PySourceRecords_ToCpp _PyAptPkg_API->sourcerecords_tocpp // NULL
+# define PyTagFile_ToCpp _PyAptPkg_API->tagfile_tocpp
+# define PyTagSection_ToCpp _PyAptPkg_API->tagsection_tocpp
+# define PyVersion_ToCpp _PyAptPkg_API->version_tocpp
+// Get the C++ object
+# define PyAcquire_FromCpp _PyAptPkg_API->acquire_fromcpp
+# define PyAcquireFile_FromCpp _PyAptPkg_API->acquirefile_fromcpp
+# define PyAcquireItem_FromCpp _PyAptPkg_API->acquireitem_fromcpp
+# define PyAcquireItemDesc_FromCpp _PyAptPkg_API->acquireitemdesc_fromcpp
+# define PyAcquireWorker_FromCpp _PyAptPkg_API->acquireworker_fromcpp
+# define PyActionGroup_FromCpp _PyAptPkg_API->actiongroup_fromcpp
+# define PyCache_FromCpp _PyAptPkg_API->cache_fromcpp
+# define PyCacheFile_FromCpp _PyAptPkg_API->cachefile_fromcpp
+# define PyCdrom_FromCpp _PyAptPkg_API->cdrom_fromcpp
+# define PyConfiguration_FromCpp _PyAptPkg_API->configuration_fromcpp
+# define PyDepCache_FromCpp _PyAptPkg_API->depcache_fromcpp
+# define PyDependency_FromCpp _PyAptPkg_API->dependency_fromcpp
+# define PyDependencyList_FromCpp _PyAptPkg_API->dependencylist_fromcpp // NULL
+# define PyDescription_FromCpp _PyAptPkg_API->description_fromcpp
+# define PyHashes_FromCpp _PyAptPkg_API->hashes_fromcpp
+# define PyHashString_FromCpp _PyAptPkg_API->hashstring_fromcpp
+# define PyIndexRecords_FromCpp _PyAptPkg_API->indexrecords_fromcpp
+# define PyMetaIndex_FromCpp _PyAptPkg_API->metaindex_fromcpp
+# define PyPackage_FromCpp _PyAptPkg_API->package_fromcpp
+# define PyPackageFile_FromCpp _PyAptPkg_API->packagefile_fromcpp
+# define PyIndexFile_FromCpp _PyAptPkg_API->packageindexfile_fromcpp
+# define PyPackageList_FromCpp _PyAptPkg_API->packagelist_fromcpp // NULL
+# define PyPackageManager_FromCpp _PyAptPkg_API->packagemanager_fromcpp
+# define PyPackageRecords_FromCpp _PyAptPkg_API->packagerecords_fromcpp
+# define PyPolicy_FromCpp _PyAptPkg_API->policy_fromcpp
+# define PyProblemResolver_FromCpp _PyAptPkg_API->problemresolver_fromcpp
+# define PySourceList_FromCpp _PyAptPkg_API->sourcelist_fromcpp
+# define PySourceRecords_FromCpp _PyAptPkg_API->sourcerecords_fromcpp // NULL
+# define PyTagFile_FromCpp _PyAptPkg_API->tagfile_fromcpp
+# define PyTagSection_FromCpp _PyAptPkg_API->tagsection_fromcpp
+# define PyVersion_FromCpp _PyAptPkg_API->version_fromcpp
+# endif // APT_PKGMODULE_H
+
+#endif
+
diff --git a/python/sourcelist.cc b/python/sourcelist.cc
index 5dcaf86b..6184fee3 100644
--- a/python/sourcelist.cc
+++ b/python/sourcelist.cc
@@ -26,20 +26,22 @@ static PyObject *PkgSourceListFindIndex(PyObject *Self,PyObject *Args)
{
pkgSourceList *list = GetCpp<pkgSourceList*>(Self);
PyObject *pyPkgFileIter;
- PyObject *pyPkgIndexFile;
+ CppPyObject<pkgIndexFile*> *pyPkgIndexFile;
- if (PyArg_ParseTuple(Args, "O!", &PackageFileType,&pyPkgFileIter) == 0)
+ if (PyArg_ParseTuple(Args, "O!", &PyPackageFile_Type,&pyPkgFileIter) == 0)
return 0;
pkgCache::PkgFileIterator &i = GetCpp<pkgCache::PkgFileIterator>(pyPkgFileIter);
pkgIndexFile *index;
if(list->FindIndex(i, index))
{
- pyPkgIndexFile = CppOwnedPyObject_NEW<pkgIndexFile*>(pyPkgFileIter,&PackageIndexFileType,index);
+ pyPkgIndexFile = CppPyObject_NEW<pkgIndexFile*>(pyPkgFileIter,&PyIndexFile_Type,index);
+ // Do not delete the pkgIndexFile*, it is managed by pkgSourceList.
+ pyPkgIndexFile->NoDelete = true;
return pyPkgIndexFile;
}
- //&PackageIndexFileType,&pyPkgIndexFile)
+ //&PyIndexFile_Type,&pyPkgIndexFile)
Py_INCREF(Py_None);
return Py_None;
@@ -61,7 +63,7 @@ static PyObject *PkgSourceListGetIndexes(PyObject *Self,PyObject *Args)
PyObject *pyFetcher;
char all = 0;
- if (PyArg_ParseTuple(Args, "O!|b",&PkgAcquireType,&pyFetcher, &all) == 0)
+ if (PyArg_ParseTuple(Args, "O!|b",&PyAcquire_Type,&pyFetcher, &all) == 0)
return 0;
pkgAcquire *fetcher = GetCpp<pkgAcquire*>(pyFetcher);
@@ -72,41 +74,52 @@ static PyObject *PkgSourceListGetIndexes(PyObject *Self,PyObject *Args)
static PyMethodDef PkgSourceListMethods[] =
{
- {"FindIndex",PkgSourceListFindIndex,METH_VARARGS,doc_PkgSourceListFindIndex},
- {"ReadMainList",PkgSourceListReadMainList,METH_VARARGS,doc_PkgSourceListReadMainList},
- {"GetIndexes",PkgSourceListGetIndexes,METH_VARARGS,doc_PkgSourceListReadMainList},
+ {"find_index",PkgSourceListFindIndex,METH_VARARGS,doc_PkgSourceListFindIndex},
+ {"read_main_list",PkgSourceListReadMainList,METH_VARARGS,doc_PkgSourceListReadMainList},
+ {"get_indexes",PkgSourceListGetIndexes,METH_VARARGS,doc_PkgSourceListGetIndexes},
{}
};
-static PyObject *PkgSourceListAttr(PyObject *Self,char *Name)
+static PyObject *PkgSourceListGetList(PyObject *Self,void*)
{
pkgSourceList *list = GetCpp<pkgSourceList*>(Self);
-
- if (strcmp("List",Name) == 0)
+ PyObject *List = PyList_New(0);
+ for (vector<metaIndex *>::const_iterator I = list->begin();
+ I != list->end(); I++)
{
- PyObject *List = PyList_New(0);
- for (vector<metaIndex *>::const_iterator I = list->begin();
- I != list->end(); I++)
- {
- PyObject *Obj;
- Obj = CppPyObject_NEW<metaIndex*>(&MetaIndexType,*I);
- PyList_Append(List,Obj);
- }
- return List;
+ CppPyObject<metaIndex*> *Obj;
+ Obj = CppPyObject_NEW<metaIndex*>(Self, &PyMetaIndex_Type,*I);
+ // Never delete metaIndex*, they are managed by the pkgSourceList.
+ Obj->NoDelete = true;
+ PyList_Append(List,Obj);
+ Py_DECREF(Obj);
}
- return Py_FindMethod(PkgSourceListMethods,Self,Name);
+ return List;
}
-PyTypeObject PkgSourceListType =
+
+static PyGetSetDef PkgSourceListGetSet[] = {
+ {"list",PkgSourceListGetList,0,"A list of MetaIndex() objects.",0},
+ {}
+};
+
+static PyObject *PkgSourceListNew(PyTypeObject *type,PyObject *args,PyObject *kwds)
{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "pkgSourceList", // tp_name
+ char *kwlist[] = {0};
+ if (PyArg_ParseTupleAndKeywords(args,kwds,"",kwlist) == 0)
+ return 0;
+ return CppPyObject_NEW<pkgSourceList*>(NULL, type,new pkgSourceList());
+}
+
+PyTypeObject PySourceList_Type =
+{
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.SourceList", // tp_name
sizeof(CppPyObject<pkgSourceList*>), // tp_basicsize
0, // tp_itemsize
// Methods
- CppDealloc<pkgSourceList*>, // tp_dealloc
+ CppDeallocPtr<pkgSourceList*>, // tp_dealloc
0, // tp_print
- PkgSourceListAttr, // tp_getattr
+ 0, // tp_getattr
0, // tp_setattr
0, // tp_compare
0, // tp_repr
@@ -114,10 +127,39 @@ PyTypeObject PkgSourceListType =
0, // tp_as_sequence
0, // tp_as_mapping
0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ _PyAptObject_getattro, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ (Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_BASETYPE),
+ "pkgSourceList Object", // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ PkgSourceListMethods, // tp_methods
+ 0, // tp_members
+ PkgSourceListGetSet, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ 0, // tp_alloc
+ PkgSourceListNew, // tp_new
};
+#ifdef COMPAT_0_7
PyObject *GetPkgSourceList(PyObject *Self,PyObject *Args)
{
- return CppPyObject_NEW<pkgSourceList*>(&PkgSourceListType,new pkgSourceList());
+ PyErr_WarnEx(PyExc_DeprecationWarning, "apt_pkg.GetPkgSourceList() is "
+ "deprecated. Please see apt_pkg.SourceList() for the "
+ "replacement.", 1);
+ return PkgSourceListNew(&PySourceList_Type,Args,0);
}
-
+#endif
diff --git a/python/string.cc b/python/string.cc
index 8168ea5b..b95ee3eb 100644
--- a/python/string.cc
+++ b/python/string.cc
@@ -38,7 +38,21 @@ PyObject *Python(PyObject *Self,PyObject *Args) \
}
MkStr(StrDeQuote,DeQuoteString);
-MkStr(StrBase64Encode,Base64Encode);
+
+/*
+ * Input bytes(Py3k)/str(Py2), output str.
+ */
+PyObject *StrBase64Encode(PyObject *Self,PyObject *Args) {
+ char *Str = 0;
+ #if PY_MAJOR_VERSION >= 3
+ if (PyArg_ParseTuple(Args,"y",&Str) == 0)
+ #else
+ if (PyArg_ParseTuple(Args,"s",&Str) == 0)
+ #endif
+ return 0;
+ return CppPyString(Base64Encode(Str));
+}
+
MkStr(StrURItoFileName,URItoFileName);
//MkFloat(StrSizeToStr,SizeToStr);
diff --git a/python/tag.cc b/python/tag.cc
index 6fe97ed5..c7edcb31 100644
--- a/python/tag.cc
+++ b/python/tag.cc
@@ -39,14 +39,27 @@ struct TagSecData : public CppPyObject<pkgTagSection>
char *Data;
};
-struct TagFileData : public PyObject
+// The owner of the TagFile is a Python file object.
+struct TagFileData : public CppPyObject<pkgTagFile>
{
- pkgTagFile Object;
- PyObject *File;
TagSecData *Section;
FileFd Fd;
};
+// Traversal and Clean for owned objects
+int TagFileTraverse(PyObject *self, visitproc visit, void* arg) {
+ Py_VISIT(((TagFileData *)self)->Section);
+ Py_VISIT(((TagFileData *)self)->Owner);
+ return 0;
+}
+
+int TagFileClear(PyObject *self) {
+ Py_CLEAR(((TagFileData *)self)->Section);
+ Py_CLEAR(((TagFileData *)self)->Owner);
+ return 0;
+}
+
+
/*}}}*/
// TagSecFree - Free a Tag Section /*{{{*/
// ---------------------------------------------------------------------
@@ -63,12 +76,15 @@ void TagSecFree(PyObject *Obj)
/* */
void TagFileFree(PyObject *Obj)
{
+ #ifdef ALLOC_DEBUG
+ std::cerr << "=== DEALLOCATING " << Obj->ob_type->tp_name << "^ ===\n";
+ #endif
TagFileData *Self = (TagFileData *)Obj;
- Py_DECREF((PyObject *)Self->Section);
+ Py_CLEAR(Self->Section);
Self->Object.~pkgTagFile();
Self->Fd.~FileFd();
- Py_DECREF(Self->File);
- PyObject_DEL(Obj);
+ Py_CLEAR(Self->Owner);
+ Obj->ob_type->tp_free(Obj);
}
/*}}}*/
@@ -183,6 +199,7 @@ static PyObject *TagSecKeys(PyObject *Self,PyObject *Args)
return List;
}
+#if PY_MAJOR_VERSION < 3
static char *doc_Exists = "Exists(Name) -> integer";
static PyObject *TagSecExists(PyObject *Self,PyObject *Args)
{
@@ -196,6 +213,19 @@ static PyObject *TagSecExists(PyObject *Self,PyObject *Args)
return Py_BuildValue("i",0);
return Py_BuildValue("i",1);
}
+#endif
+
+static int TagSecContains(PyObject *Self,PyObject *Arg)
+{
+ if (PyString_Check(Arg) == 0)
+ return 0;
+ const char *Name = PyString_AsString(Arg);
+ const char *Start;
+ const char *Stop;
+ if (GetCpp<pkgTagSection>(Self).Find(Name,Start,Stop) == false)
+ return 0;
+ return 1;
+}
static char *doc_Bytes = "Bytes() -> integer";
static PyObject *TagSecBytes(PyObject *Self,PyObject *Args)
@@ -228,6 +258,44 @@ 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);
+
+ // Bug-Debian: http://bugs.debian.org/572596
+ // Duplicate the data here and scan the duplicated section data; in order
+ // to not use any shared storage.
+ // TODO: Provide an API in apt-pkg to do this; this is really ugly.
+
+ // Fetch old section data
+ const char *Start;
+ const char *Stop;
+ Obj.Section->Object.GetSection(Start,Stop);
+ // Duplicate the data
+ Obj.Section->Data = new char[Stop-Start];
+ strncpy(Obj.Section->Data, Start, Stop-Start);
+ // Rescan it
+ Obj.Section->Object.Scan(Obj.Section->Data, Stop-Start);
+
+ 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)
{
@@ -252,15 +320,14 @@ static PyObject *TagFileJump(PyObject *Self,PyObject *Args)
/*}}}*/
// ParseSection - Parse a single section from a tag file /*{{{*/
// ---------------------------------------------------------------------
-char *doc_ParseSection ="ParseSection(Text) -> SectionObject";
-PyObject *ParseSection(PyObject *self,PyObject *Args)
-{
+static PyObject *TagSecNew(PyTypeObject *type,PyObject *Args,PyObject *kwds) {
char *Data;
- if (PyArg_ParseTuple(Args,"s",&Data) == 0)
+ char *kwlist[] = {"text", 0};
+ if (PyArg_ParseTupleAndKeywords(Args,kwds,"s",kwlist,&Data) == 0)
return 0;
// Create the object..
- TagSecData *New = PyObject_NEW(TagSecData,&TagSecType);
+ TagSecData *New = (TagSecData*)type->tp_alloc(type, 0);
new (&New->Object) pkgTagSection();
New->Data = new char[strlen(Data)+2];
snprintf(New->Data,strlen(Data)+2,"%s\n",Data);
@@ -277,30 +344,56 @@ PyObject *ParseSection(PyObject *self,PyObject *Args)
return New;
}
+
+#ifdef COMPAT_0_7
+char *doc_ParseSection ="ParseSection(Text) -> TagSection() object. Deprecated.";
+PyObject *ParseSection(PyObject *self,PyObject *Args)
+{
+ PyErr_WarnEx(PyExc_DeprecationWarning, "apt_pkg.ParseSection() is "
+ "deprecated. Please see apt_pkg.TagSection() for the "
+ "replacement.", 1);
+ return TagSecNew(&PyTagSection_Type,Args,0);
+}
+#endif
/*}}}*/
// ParseTagFile - Parse a tagd file /*{{{*/
// ---------------------------------------------------------------------
/* This constructs the parser state. */
-char *doc_ParseTagFile = "ParseTagFile(File) -> TagFile";
-PyObject *ParseTagFile(PyObject *self,PyObject *Args)
+
+static PyObject *TagFileNew(PyTypeObject *type,PyObject *Args,PyObject *kwds)
{
PyObject *File;
- if (PyArg_ParseTuple(Args,"O!",&PyFile_Type,&File) == 0)
+ char *kwlist[] = {"file", 0};
+ if (PyArg_ParseTupleAndKeywords(Args,kwds,"O",kwlist,&File) == 0)
+ return 0;
+ int fileno = PyObject_AsFileDescriptor(File);
+ if (fileno == -1)
return 0;
- TagFileData *New = PyObject_NEW(TagFileData,&TagFileType);
- new (&New->Fd) FileFd(fileno(PyFile_AsFile(File)),false);
- New->File = File;
- Py_INCREF(New->File);
+ TagFileData *New = (TagFileData*)type->tp_alloc(type, 0);
+ new (&New->Fd) FileFd(fileno,false);
+ New->Owner = File;
+ Py_INCREF(New->Owner);
new (&New->Object) pkgTagFile(&New->Fd);
// Create the section
- New->Section = PyObject_NEW(TagSecData,&TagSecType);
+ New->Section = (TagSecData*)(&PyTagSection_Type)->tp_alloc(&PyTagSection_Type, 0);
new (&New->Section->Object) pkgTagSection();
+ New->Section->Owner = New;
+ Py_INCREF(New->Section->Owner);
New->Section->Data = 0;
return HandleErrors(New);
}
+#ifdef COMPAT_0_7
+char *doc_ParseTagFile = "ParseTagFile(File) -> TagFile() object. Deprecated.";
+PyObject *ParseTagFile(PyObject *self,PyObject *Args) {
+ PyErr_WarnEx(PyExc_DeprecationWarning, "apt_pkg.ParseTagFile() is "
+ "deprecated. Please see apt_pkg.TagFile() for the "
+ "replacement.", 1);
+ return TagFileNew(&PyTagFile_Type,Args,0);
+}
+#endif
/*}}}*/
// RewriteSection - Rewrite a section.. /*{{{*/
// ---------------------------------------------------------------------
@@ -326,7 +419,7 @@ PyObject *RewriteSection(PyObject *self,PyObject *Args)
PyObject *Section;
PyObject *Order;
PyObject *Rewrite;
- if (PyArg_ParseTuple(Args,"O!O!O!",&TagSecType,&Section,
+ if (PyArg_ParseTuple(Args,"O!O!O!",&PyTagSection_Type,&Section,
&PyList_Type,&Order,&PyList_Type,&Rewrite) == 0)
return 0;
@@ -377,93 +470,155 @@ PyObject *RewriteSection(PyObject *self,PyObject *Args)
static PyMethodDef TagSecMethods[] =
{
// Query
- {"Find",TagSecFind,METH_VARARGS,doc_Find},
- {"FindRaw",TagSecFindRaw,METH_VARARGS,doc_FindRaw},
- {"FindFlag",TagSecFindFlag,METH_VARARGS,doc_FindFlag},
- {"Bytes",TagSecBytes,METH_VARARGS,doc_Bytes},
+ {"find",TagSecFind,METH_VARARGS,doc_Find},
+ {"find_raw",TagSecFindRaw,METH_VARARGS,doc_FindRaw},
+ {"find_flag",TagSecFindFlag,METH_VARARGS,doc_FindFlag},
+ {"bytes",TagSecBytes,METH_VARARGS,doc_Bytes},
// Python Special
{"keys",TagSecKeys,METH_VARARGS,doc_Keys},
+#if PY_MAJOR_VERSION < 3
{"has_key",TagSecExists,METH_VARARGS,doc_Exists},
+#endif
{"get",TagSecFind,METH_VARARGS,doc_Find},
{}
};
-// TagSecGetAttr - Get an attribute - variable/method /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-static PyObject *TagSecGetAttr(PyObject *Self,char *Name)
-{
- return Py_FindMethod(TagSecMethods,Self,Name);
-}
- /*}}}*/
-// Type for a Tag Section
+
+PySequenceMethods TagSecSeqMeth = {0,0,0,0,0,0,0,TagSecContains,0,0};
PyMappingMethods TagSecMapMeth = {TagSecLength,TagSecMap,0};
-PyTypeObject TagSecType =
+
+
+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"
+ "TagSection() behave like read-only dictionaries and also provide access\n"
+ "to the functions provided by the C++ class (e.g. Find)";
+PyTypeObject PyTagSection_Type =
{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "TagSection", // tp_name
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.TagSection", // tp_name
sizeof(TagSecData), // tp_basicsize
0, // tp_itemsize
// Methods
TagSecFree, // tp_dealloc
- 0, // tp_print
- TagSecGetAttr, // tp_getattr
+ 0, // tp_print
+ 0, // tp_getattr
0, // tp_setattr
0, // tp_compare
0, // tp_repr
0, // tp_as_number
- 0, // tp_as_sequence
+ &TagSecSeqMeth, // tp_as_sequence
&TagSecMapMeth, // tp_as_mapping
0, // tp_hash
- 0, // tp_call
- TagSecStr, // tp_str
+ 0, // tp_call
+ TagSecStr, // tp_str
+ _PyAptObject_getattro, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ (Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_HAVE_GC),
+ doc_TagSec, // tp_doc
+ CppTraverse<pkgTagSection>, // tp_traverse
+ CppClear<pkgTagSection>, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ TagSecMethods, // tp_methods
+ 0, // tp_members
+ 0, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ 0, // tp_alloc
+ TagSecNew, // tp_new
};
// Method table for the Tag File object
static PyMethodDef TagFileMethods[] =
{
// Query
- {"Step",TagFileStep,METH_VARARGS,doc_Step},
- {"Offset",TagFileOffset,METH_VARARGS,doc_Offset},
- {"Jump",TagFileJump,METH_VARARGS,doc_Jump},
+ {"step",TagFileStep,METH_VARARGS,doc_Step},
+ {"offset",TagFileOffset,METH_VARARGS,doc_Offset},
+ {"jump",TagFileJump,METH_VARARGS,doc_Jump},
{}
};
-// TagFileGetAttr - Get an attribute - variable/method /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-static PyObject *TagFileGetAttr(PyObject *Self,char *Name)
-{
- if (strcmp("Section",Name) == 0)
- {
- PyObject *Obj = ((TagFileData *)Self)->Section;
- Py_INCREF(Obj);
- return Obj;
- }
-
- return Py_FindMethod(TagFileMethods,Self,Name);
+// Return the current section.
+static PyObject *TagFileGetSection(PyObject *Self,void*) {
+ PyObject *Obj = ((TagFileData *)Self)->Section;
+ Py_INCREF(Obj);
+ return Obj;
}
+static PyGetSetDef TagFileGetSet[] = {
+ {"section",TagFileGetSection,0,"Return a TagSection.",0},
+ {}
+};
+
+
+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"
+ "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)";
+
// Type for a Tag File
-PyTypeObject TagFileType =
+PyTypeObject PyTagFile_Type =
{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, // ob_size
- "TagFile", // tp_name
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.TagFile", // tp_name
sizeof(TagFileData), // tp_basicsize
0, // tp_itemsize
// Methods
TagFileFree, // tp_dealloc
0, // tp_print
- TagFileGetAttr, // tp_getattr
+ 0, // tp_getattr
0, // tp_setattr
0, // tp_compare
0, // tp_repr
0, // tp_as_number
0, // tp_as_sequence
- 0, // tp_as_mapping
+ 0, // tp_as_mapping
0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ _PyAptObject_getattro, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ (Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_HAVE_GC),
+ doc_TagFile, // tp_doc
+ TagFileTraverse, // tp_traverse
+ TagFileClear, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ TagFileIter, // tp_iter
+ TagFileNext, // tp_iternext
+ TagFileMethods, // tp_methods
+ 0, // tp_members
+ TagFileGetSet, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ 0, // tp_alloc
+ TagFileNew, // tp_new
+
};
diff --git a/python/tar.cc b/python/tar.cc
index e5aaee6f..b994d4e7 100644
--- a/python/tar.cc
+++ b/python/tar.cc
@@ -4,10 +4,13 @@
/* ######################################################################
Tar Inteface
+ * THIS FILE IS COMPLETELY DEPRECATED, AND NOT USED ANYMORE IF BUILT *
+ * WITHOUT COMPATIBILITY. *
##################################################################### */
/*}}}*/
// Include Files /*{{{*/
+#ifdef COMPAT_0_7
#include "generic.h"
#include <apt-pkg/extracttar.h>
@@ -72,8 +75,12 @@ bool ProcessTar::DoItem(Item &Itm,int &Fd)
case Item::FIFO:
Type = "FIFO";
break;
+
+ default:
+ return false;
}
+
if (PyObject_CallFunction(Function,"sssiiiiiii",Type,Itm.Name,
Itm.LinkTarget,Itm.Mode,Itm.UID,Itm.GID,Itm.Size,
Itm.MTime,Itm.Major,Itm.Minor) == 0)
@@ -97,8 +104,7 @@ PyObject *tarExtract(PyObject *Self,PyObject *Args)
PyObject *Function;
char *Comp;
- if (PyArg_ParseTuple(Args,"O!Os",&PyFile_Type,&File,
- &Function,&Comp) == 0)
+ if (PyArg_ParseTuple(Args,"OOs",&File, &Function,&Comp) == 0)
return 0;
if (PyCallable_Check(Function) == 0)
@@ -109,7 +115,11 @@ PyObject *tarExtract(PyObject *Self,PyObject *Args)
{
// Open the file and associate the tar
- FileFd Fd(fileno(PyFile_AsFile(File)),false);
+ int fileno = PyObject_AsFileDescriptor(File);
+ if (fileno == -1)
+ return 0;
+
+ FileFd Fd(fileno,false);
ExtractTar Tar(Fd,0xFFFFFFFF,Comp);
if (_error->PendingError() == true)
return HandleErrors();
@@ -139,8 +149,7 @@ PyObject *debExtract(PyObject *Self,PyObject *Args)
char *Chunk;
const char *Comp = "gzip";
- if (PyArg_ParseTuple(Args,"O!Os",&PyFile_Type,&File,
- &Function,&Chunk) == 0)
+ if (PyArg_ParseTuple(Args,"OOs",&File,&Function,&Chunk) == 0)
return 0;
if (PyCallable_Check(Function) == 0)
@@ -149,10 +158,13 @@ PyObject *debExtract(PyObject *Self,PyObject *Args)
return 0;
}
+ int fileno = PyObject_AsFileDescriptor(File);
+ if (fileno == -1)
+ return 0;
{
// Open the file and associate the tar
// Open the file and associate the .deb
- FileFd Fd(fileno(PyFile_AsFile(File)),false);
+ FileFd Fd(fileno,false);
debDebFile Deb(Fd);
if (_error->PendingError() == true)
return HandleErrors();
@@ -180,3 +192,4 @@ PyObject *debExtract(PyObject *Self,PyObject *Args)
return HandleErrors(Py_None);
}
/*}}}*/
+#endif // defined(COMPAT_0_7)
diff --git a/python/tarfile.cc b/python/tarfile.cc
new file mode 100644
index 00000000..6363af0f
--- /dev/null
+++ b/python/tarfile.cc
@@ -0,0 +1,490 @@
+/*
+ * arfile.cc - Wrapper around ExtractTar which behaves like Python's tarfile.
+ *
+ * Copyright 2009 Julian Andres Klode <jak@debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include "generic.h"
+#include "apt_instmodule.h"
+#include <apt-pkg/extracttar.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/dirstream.h>
+
+/**
+ * A subclass of pkgDirStream which calls a Python callback.
+ *
+ * This calls a Python callback in FinishedFile() with the Item as the first
+ * argument and the data as the second argument.
+ *
+ * It can also work without a callback, in which case it just sets the
+ * 'py_member' and 'py_data' members. This can be combined with setting
+ * 'member' to extract a single member into the memory.
+ */
+class PyDirStream : public pkgDirStream
+{
+
+public:
+ PyObject *callback;
+ PyObject *py_data;
+ // The requested member or NULL.
+ const char *member;
+ // Set to true if an error occured in the Python callback.
+ bool error;
+ // Place where the copy of the data is stored.
+ char *copy;
+ // The size of the copy
+ size_t copy_size;
+
+ virtual bool DoItem(Item &Itm,int &Fd);
+ virtual bool FinishedFile(Item &Itm,int Fd);
+ virtual bool Process(Item &Itm,const unsigned char *Data,
+ unsigned long Size,unsigned long Pos);
+
+ PyDirStream(PyObject *callback, const char *member=0) : callback(callback),
+ py_data(0), member(member), error(false), copy(0)
+ {
+ Py_XINCREF(callback);
+ }
+
+ virtual ~PyDirStream() {
+ Py_XDECREF(callback);
+ Py_XDECREF(py_data);
+ delete[] copy;
+ }
+};
+
+bool PyDirStream::DoItem(Item &Itm, int &Fd)
+{
+ if (!member || strcmp(Itm.Name, member) == 0) {
+ // Allocate a new buffer if the old one is too small.
+ if (copy == NULL || copy_size < Itm.Size) {
+ delete[] copy;
+ copy = new char[Itm.Size];
+ copy_size = Itm.Size;
+ }
+ Fd = -2;
+ } else {
+ Fd = -1;
+ }
+ return true;
+}
+
+bool PyDirStream::Process(Item &Itm,const unsigned char *Data,
+ unsigned long Size,unsigned long Pos)
+{
+ memcpy(copy + Pos, Data,Size);
+ return true;
+}
+
+bool PyDirStream::FinishedFile(Item &Itm,int Fd)
+{
+ if (member && strcmp(Itm.Name, member) != 0)
+ // Skip non-matching Items, if a specific one is requested.
+ return true;
+
+ Py_XDECREF(py_data);
+ py_data = PyBytes_FromStringAndSize(copy, Itm.Size);
+
+ if (!callback)
+ return true;
+
+ // The current member and data.
+ CppPyObject<Item> *py_member;
+ py_member = CppPyObject_NEW<Item>(0, &PyTarMember_Type);
+ // Clone our object, including the strings in it.
+ py_member->Object = Itm;
+ py_member->Object.Name = new char[strlen(Itm.Name)+1];
+ py_member->Object.LinkTarget = new char[strlen(Itm.LinkTarget)+1];
+ strcpy(py_member->Object.Name, Itm.Name);
+ strcpy(py_member->Object.LinkTarget,Itm.LinkTarget);
+ py_member->NoDelete = true;
+ error = PyObject_CallFunctionObjArgs(callback, py_member, py_data, 0) == 0;
+ // Clear the old objects and create new ones.
+ Py_XDECREF(py_member);
+ return (!error);
+}
+
+void tarmember_dealloc(PyObject *self) {
+ // We cloned those strings, delete them again.
+ delete[] GetCpp<pkgDirStream::Item>(self).Name;
+ delete[] GetCpp<pkgDirStream::Item>(self).LinkTarget;
+ CppDealloc<pkgDirStream::Item>(self);
+}
+
+// The tarfile.TarInfo interface for our TarMember class.
+static PyObject *tarmember_isblk(PyObject *self, PyObject *args)
+{
+ return PyBool_FromLong(GetCpp<pkgDirStream::Item>(self).Type ==
+ pkgDirStream::Item::BlockDevice);
+}
+static PyObject *tarmember_ischr(PyObject *self, PyObject *args)
+{
+ return PyBool_FromLong(GetCpp<pkgDirStream::Item>(self).Type ==
+ pkgDirStream::Item::CharDevice);
+}
+static PyObject *tarmember_isdev(PyObject *self, PyObject *args)
+{
+ pkgDirStream::Item::Type_t type = GetCpp<pkgDirStream::Item>(self).Type;
+ return PyBool_FromLong(type == pkgDirStream::Item::CharDevice ||
+ type == pkgDirStream::Item::BlockDevice ||
+ type == pkgDirStream::Item::FIFO);
+}
+
+static PyObject *tarmember_isdir(PyObject *self, PyObject *args)
+{
+ return PyBool_FromLong(GetCpp<pkgDirStream::Item>(self).Type ==
+ pkgDirStream::Item::Directory);
+}
+
+static PyObject *tarmember_isfifo(PyObject *self, PyObject *args)
+{
+ return PyBool_FromLong(GetCpp<pkgDirStream::Item>(self).Type ==
+ pkgDirStream::Item::FIFO);
+}
+
+static PyObject *tarmember_isfile(PyObject *self, PyObject *args)
+{
+ return PyBool_FromLong(GetCpp<pkgDirStream::Item>(self).Type ==
+ pkgDirStream::Item::File);
+}
+static PyObject *tarmember_islnk(PyObject *self, PyObject *args)
+{
+ return PyBool_FromLong(GetCpp<pkgDirStream::Item>(self).Type ==
+ pkgDirStream::Item::HardLink);
+}
+static PyObject *tarmember_isreg(PyObject *self, PyObject *args)
+{
+ return tarmember_isfile(self, NULL);
+}
+static PyObject *tarmember_issym(PyObject *self, PyObject *args)
+{
+ return PyBool_FromLong(GetCpp<pkgDirStream::Item>(self).Type ==
+ pkgDirStream::Item::SymbolicLink);
+}
+
+static PyObject *tarmember_get_name(PyObject *self, void *closure)
+{
+ return PyString_FromString(GetCpp<pkgDirStream::Item>(self).Name);
+}
+
+static PyObject *tarmember_get_linkname(PyObject *self, void *closure)
+{
+ return Safe_FromString(GetCpp<pkgDirStream::Item>(self).LinkTarget);
+}
+
+static PyObject *tarmember_get_mode(PyObject *self, void *closure)
+{
+ return Py_BuildValue("k", GetCpp<pkgDirStream::Item>(self).Mode);
+}
+
+static PyObject *tarmember_get_uid(PyObject *self, void *closure)
+{
+ return Py_BuildValue("k", GetCpp<pkgDirStream::Item>(self).UID);
+}
+static PyObject *tarmember_get_gid(PyObject *self, void *closure)
+{
+ return Py_BuildValue("k", GetCpp<pkgDirStream::Item>(self).GID);
+}
+static PyObject *tarmember_get_size(PyObject *self, void *closure)
+{
+ return Py_BuildValue("k", GetCpp<pkgDirStream::Item>(self).Size);
+}
+
+static PyObject *tarmember_get_mtime(PyObject *self, void *closure)
+{
+ return Py_BuildValue("k", GetCpp<pkgDirStream::Item>(self).MTime);
+}
+
+static PyObject *tarmember_get_major(PyObject *self, void *closure)
+{
+ return Py_BuildValue("k", GetCpp<pkgDirStream::Item>(self).Major);
+}
+
+static PyObject *tarmember_get_minor(PyObject *self, void *closure)
+{
+ return Py_BuildValue("k", GetCpp<pkgDirStream::Item>(self).Minor);
+}
+
+static PyObject *tarmember_repr(PyObject *self)
+{
+ return PyString_FromFormat("<%s object: name:'%s'>",
+ self->ob_type->tp_name,
+ GetCpp<pkgDirStream::Item>(self).Name);
+
+}
+
+
+static PyMethodDef tarmember_methods[] = {
+ {"isblk",tarmember_isblk,METH_NOARGS,
+ "Determine whether the member is a block device."},
+ {"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)."},
+ {"isdir",tarmember_isdir,METH_NOARGS,
+ "Determine whether the member is a directory."},
+ {"isfifo",tarmember_isfifo,METH_NOARGS,
+ "Determine whether the member is a FIFO."},
+ {"isfile",tarmember_isfile,METH_NOARGS,
+ "Determine whether the member is a regular file."},
+ {"islnk",tarmember_islnk,METH_NOARGS,
+ "Determine whether the member is a hardlink."},
+ {"isreg",tarmember_isreg,METH_NOARGS,
+ "Determine whether the member is a regular file, same as isfile()."},
+ {"issym",tarmember_issym,METH_NOARGS,
+ "Determine whether the member is a symbolic link."},
+ {NULL}
+};
+
+static PyGetSetDef tarmember_getset[] = {
+ {"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."},
+ {"mode",tarmember_get_mode,0,"The mode (permissions)."},
+ {"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."},
+ {NULL}
+};
+
+static const char *tarmember_doc =
+ "Represent a single member of a 'tar' archive.\n\n"
+ "This class, which has been modelled after 'tarfile.TarInfo', represents\n"
+ "information about a given member in an archive.";
+PyTypeObject PyTarMember_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_inst.TarMember", // tp_name
+ sizeof(CppPyObject<pkgDirStream::Item>), // tp_basicsize
+ 0, // tp_itemsize
+ // Methods
+ tarmember_dealloc, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ tarmember_repr, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_HAVE_GC,
+ tarmember_doc, // tp_doc
+ CppTraverse<pkgDirStream::Item>, // tp_traverse
+ CppClear<pkgDirStream::Item>, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ tarmember_methods, // tp_methods
+ 0, // tp_members
+ tarmember_getset // tp_getset
+};
+
+
+
+static PyObject *tarfile_new(PyTypeObject *type,PyObject *args,PyObject *kwds)
+{
+ PyObject *file;
+ PyTarFileObject *self;
+ char *filename;
+ int fileno;
+ int min = 0;
+ int max = 0xFFFFFFFF;
+ char *comp = "gzip";
+
+ static char *kwlist[] = {"file","min","max","comp",NULL};
+ if (PyArg_ParseTupleAndKeywords(args, kwds, "O|iis", kwlist, &file, &min,
+ &max,&comp) == 0)
+ return 0;
+
+ self = (PyTarFileObject*)CppPyObject_NEW<ExtractTar*>(file,type);
+
+ // We receive a filename.
+ if ((filename = (char*)PyObject_AsString(file)))
+ new (&self->Fd) FileFd(filename,FileFd::ReadOnly);
+ else if ((fileno = PyObject_AsFileDescriptor(file)) != -1) {
+ // clear the error set by PyObject_AsString().
+ PyErr_Clear();
+ new (&self->Fd) FileFd(fileno,false);
+ }
+ else {
+ Py_DECREF(self);
+ return 0;
+ }
+
+ self->min = min;
+ self->Object = new ExtractTar(self->Fd,max,comp);
+ if (_error->PendingError() == true)
+ return HandleErrors(self);
+ return self;
+}
+
+static const char *tarfile_extractall_doc =
+ "extractall([rootdir: str]) -> True\n\n"
+ "Extract the archive in the current directory. The argument 'rootdir'\n"
+ "can be used to change the target directory.";
+static PyObject *tarfile_extractall(PyObject *self, PyObject *args)
+{
+ string cwd = SafeGetCWD();
+ char *rootdir = 0;
+ if (PyArg_ParseTuple(args,"|s:extractall",&rootdir) == 0)
+ return 0;
+
+ if (rootdir) {
+ if (chdir(rootdir) == -1)
+ return PyErr_SetFromErrnoWithFilename(PyExc_OSError, rootdir);
+ }
+
+ pkgDirStream Extract;
+
+ ((PyTarFileObject*)self)->Fd.Seek(((PyTarFileObject*)self)->min);
+ bool res = GetCpp<ExtractTar*>(self)->Go(Extract);
+
+
+
+ if (rootdir) {
+ if (chdir(cwd.c_str()) == -1)
+ return PyErr_SetFromErrnoWithFilename(PyExc_OSError,
+ (char*)cwd.c_str());
+ }
+ return HandleErrors(PyBool_FromLong(res));
+}
+
+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"
+ "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"
+ "members. If specified and not found, LookupError will be raised.";
+static PyObject *tarfile_go(PyObject *self, PyObject *args)
+{
+ PyObject *callback;
+ char *member = 0;
+ if (PyArg_ParseTuple(args,"O|s",&callback,&member) == 0)
+ return 0;
+ if (member && strcmp(member, "") == 0)
+ member = 0;
+ pkgDirStream Extract;
+ PyDirStream stream(callback, member);
+ ((PyTarFileObject*)self)->Fd.Seek(((PyTarFileObject*)self)->min);
+ bool res = GetCpp<ExtractTar*>(self)->Go(stream);
+ if (stream.error)
+ return 0;
+ if (member && !stream.py_data)
+ return PyErr_Format(PyExc_LookupError, "There is no member named '%s'",
+ member);
+ return HandleErrors(PyBool_FromLong(res));
+}
+
+static const char *tarfile_extractdata_doc =
+ "extractdata(member: str) -> bytes\n\n"
+ "Return the contents of the member, as a bytes object. Raise\n"
+ "LookupError if there is no member with the given name.";
+static PyObject *tarfile_extractdata(PyObject *self, PyObject *args)
+{
+ const char *member;
+ if (PyArg_ParseTuple(args,"s",&member) == 0)
+ return 0;
+ PyDirStream stream(NULL, member);
+ ((PyTarFileObject*)self)->Fd.Seek(((PyTarFileObject*)self)->min);
+ // Go through the stream.
+ GetCpp<ExtractTar*>(self)->Go(stream);
+
+ if (!stream.py_data)
+ return PyErr_Format(PyExc_LookupError, "There is no member named '%s'",
+ member);
+ if (stream.error) {
+ return 0;
+ }
+ return Py_INCREF(stream.py_data), stream.py_data;
+}
+
+static PyMethodDef tarfile_methods[] = {
+ {"extractdata",tarfile_extractdata,METH_VARARGS,tarfile_extractdata_doc},
+ {"extractall",tarfile_extractall,METH_VARARGS,tarfile_extractall_doc},
+ {"go",tarfile_go,METH_VARARGS,tarfile_go_doc},
+ {NULL}
+};
+
+static PyObject *tarfile_repr(PyObject *self)
+{
+ return PyString_FromFormat("<%s object: %s>", self->ob_type->tp_name,
+ PyString_AsString(PyObject_Repr(GetOwner<ExtractTar*>(self))));
+}
+
+static const char *tarfile_doc =
+ "TarFile(file: str/int/file[, min: int, max: int, comp: str])\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\n"
+ "The parameter 'min' describes the offset in the file where the archive\n"
+ "begins and the parameter 'max' is the size of the archive.\n\n"
+ "The compression of the archive is set by the parameter 'comp'. It can\n"
+ "be set to any program supporting the -d switch, the default being gzip.";
+PyTypeObject PyTarFile_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_inst.TarFile", // tp_name
+ sizeof(PyTarFileObject), // tp_basicsize
+ 0, // tp_itemsize
+ // Methods
+ CppDealloc<ExtractTar*>, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ tarfile_repr, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT | // tp_flags
+ Py_TPFLAGS_HAVE_GC,
+ tarfile_doc, // tp_doc
+ CppTraverse<ExtractTar*>, // tp_traverse
+ CppClear<ExtractTar*>, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ tarfile_methods, // tp_methods
+ 0, // tp_members
+ 0, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ 0, // tp_alloc
+ tarfile_new // tp_new
+};