summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorJulian Andres Klode <jak@debian.org>2009-07-21 21:53:36 +0200
committerJulian Andres Klode <jak@debian.org>2009-07-21 21:53:36 +0200
commit1358664af2c27db4d7d62292680013e811f11750 (patch)
treed599ab1e2b82124ee2c9aa05f85cd92babb81c80 /python
parent59ca8fafbe93d5aff7ac4baf54877dd1aa5fa036 (diff)
downloadpython-apt-1358664af2c27db4d7d62292680013e811f11750.tar.gz
python/progress.cc: Introduce setattr to reduce code duplication.
This way, we can replace stuff like PyObject *o = PyBuildValue("i", 0); PyObject_SetAttrString(callbackInst, "attribute", o); Py_DECREF(o) with setattr(callbackInst,"attribute","i",0);
Diffstat (limited to 'python')
-rw-r--r--python/progress.cc135
-rw-r--r--python/progress.h3
2 files changed, 55 insertions, 83 deletions
diff --git a/python/progress.cc b/python/progress.cc
index cc0c9ffc..305246b7 100644
--- a/python/progress.cc
+++ b/python/progress.cc
@@ -17,6 +17,24 @@
#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;
+}
+
#define TUPLEIZE(op) Py_BuildValue("(O)", op)
// generic
bool PyCallbackObj::RunSimpleCallback(const char* method_name,
@@ -81,22 +99,11 @@ void PyOpProgress::Update()
RunSimpleCallback("update");
}
else {
- PyObject *o;
- o = Py_BuildValue("s", Op.c_str());
- PyObject_SetAttrString(callbackInst, "op", o);
- Py_XDECREF(o);
- o = Py_BuildValue("s", SubOp.c_str());
- if(PyObject_HasAttrString(callbackInst, "sub_op"))
- PyObject_SetAttrString(callbackInst, "sub_op", o);
- else
- PyObject_SetAttrString(callbackInst, "subOp", o);
- Py_XDECREF(o);
- o = Py_BuildValue("b", MajorChange);
- if(PyObject_HasAttrString(callbackInst, "major_change"))
- PyObject_SetAttrString(callbackInst, "major_change", o);
- else
- PyObject_SetAttrString(callbackInst, "majorChange", o);
- Py_XDECREF(o);
+ setattr(callbackInst, "op", "s", Op.c_str());
+ setattr(callbackInst, "subop", "s", SubOp.c_str());
+ setattr(callbackInst, "subOp", "s", SubOp.c_str());
+ setattr(callbackInst, "major_change", "b", MajorChange);
+ setattr(callbackInst, "majorChange", "b", MajorChange);
PyObject *arglist = Py_BuildValue("(f)", Percent);
RunSimpleCallback("update", arglist);
}
@@ -219,35 +226,16 @@ void PyFetchProgress::Start()
//std::cout << "Start" << std::endl;
pkgAcquireStatus::Start();
+#ifdef COMPAT_0_7
+ if (!PyObject_TypeCheck(callbackInst,&PyAcquireProgress_Type)) {
+ 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
- if (PyObject_TypeCheck(callbackInst,&PyAcquireProgress_Type))
- goto end;
-
- // These attributes should be initialized before the first callback (start)
- // is invoked.
- // -- Stephan
- PyObject *o;
-
- o = Py_BuildValue("d", 0);
- PyObject_SetAttrString(callbackInst, "currentCPS", o);
- Py_XDECREF(o);
-
- o = Py_BuildValue("d", 0);
- PyObject_SetAttrString(callbackInst, "currentBytes", o);
- Py_XDECREF(o);
-
- o = Py_BuildValue("k", 0);
- PyObject_SetAttrString(callbackInst, "currentItems", o);
- Py_XDECREF(o);
- o = Py_BuildValue("k", 0);
- PyObject_SetAttrString(callbackInst, "totalItems", o);
- Py_XDECREF(o);
-
- o = Py_BuildValue("d", 0);
- PyObject_SetAttrString(callbackInst, "totalBytes", o);
- Py_XDECREF(o);
-
-end:
RunSimpleCallback("start");
/* After calling the start method we can safely allow
* other Python threads to do their work for now.
@@ -291,41 +279,22 @@ bool PyFetchProgress::Pulse(pkgAcquire * Owner)
obj->current_items = CurrentItems;
}
else {
- // set stats
- PyObject *o;
- o = Py_BuildValue("d", FetchedBytes);
- PyObject_SetAttrString(callbackInst, "fetched_bytes", o);
- Py_DECREF(o);
- o = Py_BuildValue("d", CurrentCPS);
- if(PyObject_HasAttrString(callbackInst, "current_cps"))
- PyObject_SetAttrString(callbackInst, "current_cps", o);
- else
- PyObject_SetAttrString(callbackInst, "currentCPS", o);
- Py_XDECREF(o);
- o = Py_BuildValue("d", CurrentBytes);
- if(PyObject_HasAttrString(callbackInst, "current_bytes"))
- PyObject_SetAttrString(callbackInst, "current_bytes", o);
- else
- PyObject_SetAttrString(callbackInst, "currentBytes", o);
- Py_XDECREF(o);
- o = Py_BuildValue("k", CurrentItems);
- if(PyObject_HasAttrString(callbackInst, "current_items"))
- PyObject_SetAttrString(callbackInst, "current_items", o);
- else
- PyObject_SetAttrString(callbackInst, "currentItems", o);
- Py_XDECREF(o);
- o = Py_BuildValue("k", TotalItems);
- if(PyObject_HasAttrString(callbackInst, "total_items"))
- PyObject_SetAttrString(callbackInst, "total_items", o);
- else
- PyObject_SetAttrString(callbackInst, "totalItems", o);
- Py_XDECREF(o);
- o = Py_BuildValue("d", TotalBytes);
- if(PyObject_HasAttrString(callbackInst, "total_bytes"))
- PyObject_SetAttrString(callbackInst, "total_bytes", o);
- else
- 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);
+#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);
+#endif
}
if (PyObject_TypeCheck(callbackInst, &PyAcquireProgress_Type)) {
@@ -568,9 +537,11 @@ void PyCdromProgress::Update(string text, int current)
((PyCdromProgressObject *)callbackInst)->total_steps = totalSteps;
}
else {
- 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);
diff --git a/python/progress.h b/python/progress.h
index 88c0a21b..e92933a7 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
@@ -63,6 +63,7 @@ typedef struct {
} PyAcquireProgressObject;
+
class PyCallbackObj {
protected:
PyObject *callbackInst;