From 6ba42d2e31f161fc0ebe5405cf63b616c3e822b4 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Wed, 22 Jul 2009 17:21:08 +0200 Subject: python: First step of fixing acquire stuff. Basically, we only want to have on PyAcquireItem per pkgAcquire::Item, and one PyAcquireItemDesc per pkgAcquire::ItemDesc. Therefore, we store them so we can return them at a later time. --- python/acquire-item.cc | 357 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 357 insertions(+) create mode 100644 python/acquire-item.cc (limited to 'python/acquire-item.cc') diff --git a/python/acquire-item.cc b/python/acquire-item.cc new file mode 100644 index 00000000..cf0a628e --- /dev/null +++ b/python/acquire-item.cc @@ -0,0 +1,357 @@ +/* + * acquire-item.cc - Wrapper around pkgAcquire::Item and pkgAcqFile. + * + * Copyright 2004-2009 Canonical Ltd. + * Copyright 2009 Julian Andres Klode + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include "generic.h" +#include "apt_pkgmodule.h" + +#include +#include + +using namespace std; + + + +struct PyAcquireItems { + CppOwnedPyObject *file; + CppOwnedPyObject *item; + CppOwnedPyObject *desc; +}; + +typedef map item_map; + +// Keep a vector to PyAcquireItemObject pointers, so we can set the Object +// pointers to NULL when deallocating the main object (mostly AcquireFile). +struct PyAcquireObject : public CppPyObject { + item_map items; +}; + +inline pkgAcquire::Item *acquireitem_tocpp(PyObject *self) +{ + pkgAcquire::Item *itm = GetCpp(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_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}, + {"status",acquireitem_get_status}, +#ifdef COMPAT_0_7 + {"Complete",acquireitem_get_complete}, + {"DescURI",acquireitem_get_desc_uri}, + {"DestFile",acquireitem_get_destfile}, + {"ErrorText",acquireitem_get_error_text}, + {"FileSize",acquireitem_get_filesize}, + {"ID",acquireitem_get_id}, + {"IsTrusted",acquireitem_get_is_trusted}, + {"Local",acquireitem_get_local}, + {"Status",acquireitem_get_status}, +#endif + {} +}; + +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) +{ + // TODO: Unregister the object in the owner. + if (!((CppOwnedPyObject*)self)->NoDelete) { + pkgAcquire::Item *item = PyAcquireItem_ToCpp(self); + PyAcquireObject *Owner = (PyAcquireObject *)GetOwner(self); + + PyAcquireItems item_struct = Owner->items[item]; + + if (item_struct.file != 0 && item_struct.file != self) + item_struct.file->Object = 0; + if (item_struct.item != 0 && item_struct.item != self) { + item_struct.item->Object = 0; + Py_DECREF(item_struct.item); + } + if (item_struct.desc != 0) { + item_struct.desc->Object = 0; + Py_DECREF(item_struct.desc); + } + Owner->items.erase(item); + } + + CppOwnedDeallocPtr(self); +} + +PyTypeObject PyAcquireItem_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.AcquireItem", // tp_name + sizeof(CppOwnedPyObject), // 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 + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "AcquireItem 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 + 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(pyfetcher); + pkgAcqFile *af = new pkgAcqFile(fetcher, // owner + uri, // uri + md5, // md5 + size, // size + descr, // descr + shortDescr, + destDir, + destFile); // short-desc + CppOwnedPyObject *AcqFileObj = CppOwnedPyObject_NEW(pyfetcher, type); + AcqFileObj->Object = af; + + + ((PyAcquireObject *)pyfetcher)->items[af].file = AcqFileObj; + 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(CppOwnedPyObject),// 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 + CppOwnedTraverse, // tp_traverse + CppOwnedClear, // 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(pyfetcher); + pkgAcqFile *af = new pkgAcqFile(fetcher, // owner + uri, // uri + md5, // md5 + size, // size + descr, // descr + shortDescr, + destDir, + destFile); // short-desc + CppPyObject *AcqFileObj = CppPyObject_NEW(&PyAcquireFile_Type); + AcqFileObj->Object = af; + AcqFileObj->NoDelete = true; + + return AcqFileObj; +} +#endif -- cgit v1.2.3 From 544f14e0f2fb70b5a1f30786a93023a42d88290d Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Wed, 22 Jul 2009 18:16:28 +0200 Subject: python: 2nd part of the acquire fixes (one PyObject per C++ object). --- python/acquire-item.cc | 14 +++++++---- python/acquire.cc | 63 +++++++++++++++++++++++++------------------------- python/apt_pkgmodule.h | 5 ++++ python/progress.cc | 10 ++++---- python/python-apt.h | 5 ++-- 5 files changed, 54 insertions(+), 43 deletions(-) (limited to 'python/acquire-item.cc') diff --git a/python/acquire-item.cc b/python/acquire-item.cc index cf0a628e..1fb66080 100644 --- a/python/acquire-item.cc +++ b/python/acquire-item.cc @@ -176,13 +176,11 @@ static PyObject *acquireitem_repr(PyObject *Self) static void acquireitem_dealloc(PyObject *self) { + pkgAcquire::Item *item = PyAcquireItem_ToCpp(self); + PyAcquireObject *Owner = (PyAcquireObject *)GetOwner(self); + PyAcquireItems item_struct = Owner->items[item]; // TODO: Unregister the object in the owner. if (!((CppOwnedPyObject*)self)->NoDelete) { - pkgAcquire::Item *item = PyAcquireItem_ToCpp(self); - PyAcquireObject *Owner = (PyAcquireObject *)GetOwner(self); - - PyAcquireItems item_struct = Owner->items[item]; - if (item_struct.file != 0 && item_struct.file != self) item_struct.file->Object = 0; if (item_struct.item != 0 && item_struct.item != self) { @@ -195,6 +193,12 @@ static void acquireitem_dealloc(PyObject *self) } Owner->items.erase(item); } + else { + if (item_struct.file == self) + item_struct.file = 0; + if (item_struct.item == self) + item_struct.item = 0; + } CppOwnedDeallocPtr(self); } diff --git a/python/acquire.cc b/python/acquire.cc index 5e03586e..1085d0a2 100644 --- a/python/acquire.cc +++ b/python/acquire.cc @@ -40,26 +40,17 @@ static PyObject *acquireworker_get_current_item(PyObject *self, void *closure) Py_RETURN_NONE; } - PyAcquireObject *PyAcquire = (PyAcquireObject *)GetOwner(self); + PyObject *PyAcquire = GetOwner(self); - pkgAcquire::Item *Item = worker->CurrentItem->Owner; - - PyObject *PyItem; - // FIXME: PyAcquire_FromCpp needs to initialize item_map. - if (PyAcquire && false && PyAcquire->items[Item].item) { - Py_INCREF(PyItem); - PyItem = PyAcquire->items[Item].item; - } + if (PyAcquire) + return PyAcquire_GetItemDesc(PyAcquire, worker->CurrentItem); else { - PyItem = PyAcquireItem_FromCpp(Item,false,PyAcquire); - // FIXME: PyAcquire_FromCpp needs to initialize item_map. - if (PyAcquire && false) - PyAcquire->items[Item].item = (CppOwnedPyObject*)PyItem; + PyObject *PyItem = PyAcquireItem_FromCpp(worker->CurrentItem->Owner); + PyObject *ret = PyAcquireItemDesc_FromCpp(worker->CurrentItem,false, + PyItem); + Py_DECREF(PyItem); + return ret; } - - PyObject *ret = PyAcquireItemDesc_FromCpp(worker->CurrentItem,false,PyItem); - Py_DECREF(PyItem); - return ret; } static PyObject *acquireworker_get_status(PyObject *self, void *closure) @@ -146,7 +137,7 @@ static PyObject *acquireitemdesc_get_owner(CppOwnedPyObjectOwner); return self->Owner; } - else if (self->Object && self->Object->Owner != NULL) { + else if (self->Object) { self->Owner = PyAcquireItem_FromCpp(self->Object->Owner); Py_INCREF(self->Owner); return self->Owner; @@ -210,7 +201,27 @@ PyTypeObject PyAcquireItemDesc_Type = }; +// Acquire + +PyObject *PyAcquire_GetItem(PyObject *self, pkgAcquire::Item *item) { + PyAcquireItems &item_struct = ((PyAcquireObject *)self)->items[item]; + if (! item_struct.item) { + item_struct.item = PyAcquireItem_FromCpp(item,false,self); + } + Py_INCREF(item_struct.item); + return item_struct.item; +} +PyObject *PyAcquire_GetItemDesc(PyObject *self, pkgAcquire::ItemDesc *item) { + PyAcquireItems &item_struct = ((PyAcquireObject *)self)->items[item->Owner]; + if (! item_struct.item) + item_struct.item = PyAcquireItem_FromCpp(item->Owner,false,self); + if (! item_struct.desc) + item_struct.desc = PyAcquireItemDesc_FromCpp(item,false, + item_struct.item); + Py_INCREF(item_struct.desc); + return item_struct.desc; +} static PyObject *PkgAcquireRun(PyObject *Self,PyObject *Args) { @@ -294,23 +305,13 @@ static PyObject *PkgAcquireGetItems(PyObject *Self,void*) { pkgAcquire *fetcher = GetCpp(Self); PyObject *List = PyList_New(0); - CppOwnedPyObject *Obj; + PyObject *Obj; for (pkgAcquire::ItemIterator I = fetcher->ItemsBegin(); I != fetcher->ItemsEnd(); I++) { - - if (((PyAcquireObject *)Self)->items[*I].item) - PyList_Append(List, ((PyAcquireObject *)Self)->items[*I].item); - else { - Obj = CppOwnedPyObject_NEW(Self,&PyAcquireItem_Type,*I); - Obj->NoDelete = true; - + Obj = PyAcquire_GetItem(Self, *I); PyList_Append(List,Obj); - ((PyAcquireObject *)Self)->items[*I].item = Obj; - - - // Not DECREFING it, we want to manage it somewhere else. - } + Py_DECREF(Obj); } return List; } diff --git a/python/apt_pkgmodule.h b/python/apt_pkgmodule.h index 04bce2cc..3edba5d2 100644 --- a/python/apt_pkgmodule.h +++ b/python/apt_pkgmodule.h @@ -12,6 +12,7 @@ #include #include +#include // Configuration Stuff #define Configuration_Check(op) ((op)->ob_type == &PyConfiguration_Type) @@ -49,6 +50,10 @@ 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 PyCache_Type; extern PyTypeObject PyCacheFile_Type; diff --git a/python/progress.cc b/python/progress.cc index 1b135a75..7873d894 100644 --- a/python/progress.cc +++ b/python/progress.cc @@ -175,7 +175,7 @@ void PyFetchProgress::IMSHit(pkgAcquire::ItemDesc &Itm) { PyCbObj_END_ALLOW_THREADS if (PyObject_TypeCheck(callbackInst,&PyAcquireProgress_Type)) - RunSimpleCallback("ims_hit", TUPLEIZE(PyAcquireItemDesc_FromCpp(&Itm))); + RunSimpleCallback("ims_hit", TUPLEIZE(PyAcquire_GetItemDesc(pyAcquire, &Itm))); else UpdateStatus(Itm, DLHit); PyCbObj_BEGIN_ALLOW_THREADS @@ -185,7 +185,7 @@ void PyFetchProgress::Fetch(pkgAcquire::ItemDesc &Itm) { PyCbObj_END_ALLOW_THREADS if (PyObject_TypeCheck(callbackInst,&PyAcquireProgress_Type)) - RunSimpleCallback("fetch", TUPLEIZE(PyAcquireItemDesc_FromCpp(&Itm))); + RunSimpleCallback("fetch", TUPLEIZE(PyAcquire_GetItemDesc(pyAcquire, &Itm))); else UpdateStatus(Itm, DLQueued); PyCbObj_BEGIN_ALLOW_THREADS @@ -195,7 +195,7 @@ void PyFetchProgress::Done(pkgAcquire::ItemDesc &Itm) { PyCbObj_END_ALLOW_THREADS if (PyObject_TypeCheck(callbackInst,&PyAcquireProgress_Type)) - RunSimpleCallback("done", TUPLEIZE(PyAcquireItemDesc_FromCpp(&Itm))); + RunSimpleCallback("done", TUPLEIZE(PyAcquire_GetItemDesc(pyAcquire, &Itm))); else UpdateStatus(Itm, DLDone); PyCbObj_BEGIN_ALLOW_THREADS @@ -205,7 +205,7 @@ void PyFetchProgress::Fail(pkgAcquire::ItemDesc &Itm) { PyCbObj_END_ALLOW_THREADS if (PyObject_TypeCheck(callbackInst,&PyAcquireProgress_Type)) { - RunSimpleCallback("fail", TUPLEIZE(PyAcquireItemDesc_FromCpp(&Itm))); + RunSimpleCallback("fail", TUPLEIZE(PyAcquire_GetItemDesc(pyAcquire, &Itm))); return; } @@ -220,7 +220,7 @@ void PyFetchProgress::Fail(pkgAcquire::ItemDesc &Itm) if (PyObject_TypeCheck(callbackInst,&PyAcquireProgress_Type)) - RunSimpleCallback("fail", TUPLEIZE(PyAcquireItemDesc_FromCpp(&Itm))); + RunSimpleCallback("fail", TUPLEIZE(PyAcquire_GetItemDesc(pyAcquire, &Itm))); else UpdateStatus(Itm, DLFailed); PyCbObj_BEGIN_ALLOW_THREADS diff --git a/python/python-apt.h b/python/python-apt.h index 80ad03bd..fb84b394 100644 --- a/python/python-apt.h +++ b/python/python-apt.h @@ -220,7 +220,8 @@ static int import_apt_pkg(void) { // Python object creation, using two inline template functions and one variadic // macro per type. template -inline PyObject *FromCpp(PyTypeObject *pytype, Cpp obj, bool Delete=false) +inline CppPyObject *FromCpp(PyTypeObject *pytype, Cpp obj, + bool Delete=false) { CppPyObject *Obj = CppPyObject_NEW(pytype, obj); Obj->NoDelete = (!Delete); @@ -228,7 +229,7 @@ inline PyObject *FromCpp(PyTypeObject *pytype, Cpp obj, bool Delete=false) } template -inline PyObject *FromCppOwned(PyTypeObject *pytype, Cpp const &obj, +inline CppOwnedPyObject *FromCppOwned(PyTypeObject *pytype, Cpp const &obj, bool Delete=false, PyObject *Owner=NULL) { CppOwnedPyObject *Obj = CppOwnedPyObject_NEW(Owner, pytype, obj); -- cgit v1.2.3