summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/acquire.cc9
-rw-r--r--python/apt_pkgmodule.cc37
-rw-r--r--python/apt_pkgmodule.h1
-rw-r--r--python/arfile.cc54
-rw-r--r--python/cache.cc14
-rw-r--r--python/cdrom.cc4
-rw-r--r--python/configuration.cc9
-rw-r--r--python/depcache.cc1
-rw-r--r--python/lock.cc2
-rw-r--r--python/metaindex.cc4
-rw-r--r--python/policy.cc5
-rw-r--r--python/progress.cc14
-rw-r--r--python/progress.h6
-rw-r--r--python/tag.cc162
-rw-r--r--python/tar.cc2
-rw-r--r--python/tarfile.cc2
16 files changed, 244 insertions, 82 deletions
diff --git a/python/acquire.cc b/python/acquire.cc
index 6169ff40..45b4493c 100644
--- a/python/acquire.cc
+++ b/python/acquire.cc
@@ -328,18 +328,17 @@ static PyObject *PkgAcquireNew(PyTypeObject *type,PyObject *Args,PyObject *kwds)
// FIXME: memleak?
progress = new PyFetchProgress();
progress->setCallbackInst(pyFetchProgressInst);
- fetcher = new pkgAcquire(progress);
- }
- else {
- fetcher = new pkgAcquire();
}
+ fetcher = new pkgAcquire();
+ fetcher->Setup(progress);
+
PyObject *FetcherObj = CppPyObject_NEW<pkgAcquire*>(NULL, type, fetcher);
if (progress != 0)
progress->setPyAcquire(FetcherObj);
// prepare our map of items.
- return FetcherObj;
+ return HandleErrors(FetcherObj);
}
/**
diff --git a/python/apt_pkgmodule.cc b/python/apt_pkgmodule.cc
index e8490b4e..7704aa01 100644
--- a/python/apt_pkgmodule.cc
+++ b/python/apt_pkgmodule.cc
@@ -25,6 +25,8 @@
#include <apt-pkg/init.h>
#include <apt-pkg/pkgsystem.h>
#include <apt-pkg/orderlist.h>
+#include <apt-pkg/aptconfiguration.h>
+#include <apt-pkg/fileutl.h>
#include <sys/stat.h>
#include <libintl.h>
@@ -184,11 +186,11 @@ static const char *parse_src_depends_doc =
"only contains those dependencies for the architecture set in the\n"
"configuration variable APT::Architecture";
static PyObject *RealParseDepends(PyObject *Self,PyObject *Args,
- bool ParseArchFlags, string name,
+ bool ParseArchFlags, std::string name,
bool debStyle=false)
{
- string Package;
- string Version;
+ std::string Package;
+ std::string Version;
unsigned int Op;
bool StripMultiArch=true;
@@ -393,6 +395,30 @@ static PyObject *sha256sum(PyObject *Self,PyObject *Args)
return 0;
}
/*}}}*/
+// get_architectures - return the list of architectures /*{{{*/
+// ---------------------------------------------------------------------
+static const char *doc_GetArchitectures =
+ "get_architectures() -> list\n\n"
+ "Return the list of supported architectures on this system. On a \n"
+ "multiarch system this can be more than one. The main architectures\n"
+ "is the first item in the list.";;
+static PyObject *GetArchitectures(PyObject *Self,PyObject *Args)
+{
+ PyObject *Obj;
+ if (PyArg_ParseTuple(Args,"",&Obj) == 0)
+ return 0;
+
+ PyObject *List = PyList_New(0);
+ std::vector<std::string> arches = APT::Configuration::getArchitectures();
+ std::vector<std::string>::const_iterator I;
+ for (I = arches.begin(); I != arches.end(); I++)
+ {
+ PyList_Append(List, CppPyString(*I));
+ }
+
+ return List;
+}
+ /*}}}*/
// init - 3 init functions /*{{{*/
// ---------------------------------------------------------------------
static char *doc_Init =
@@ -539,6 +565,9 @@ static PyMethodDef methods[] =
{"sha1sum",sha1sum,METH_VARARGS,doc_sha1sum},
{"sha256sum",sha256sum,METH_VARARGS,doc_sha256sum},
+ // multiarch
+ {"get_architectures", GetArchitectures, METH_VARARGS, doc_GetArchitectures},
+
// Strings
{"check_domain_list",StrCheckDomainList,METH_VARARGS,
"check_domain_list(host: str, domains: str) -> bool\n\n"
@@ -891,7 +920,7 @@ extern "C" void initapt_pkg()
PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_SUGGESTS",
MkPyNumber(pkgCache::Dep::Suggests));
PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_RECOMMENDS",
- MkPyNumber(pkgCache::Dep::Suggests));
+ MkPyNumber(pkgCache::Dep::Recommends));
PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_CONFLICTS",
MkPyNumber(pkgCache::Dep::Conflicts));
PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_REPLACES",
diff --git a/python/apt_pkgmodule.h b/python/apt_pkgmodule.h
index b3534a30..85c34130 100644
--- a/python/apt_pkgmodule.h
+++ b/python/apt_pkgmodule.h
@@ -24,6 +24,7 @@
#include <apt-pkg/pkgsystem.h>
#include <apt-pkg/cdrom.h>
#include <apt-pkg/algorithms.h>
+#include <apt-pkg/metaindex.h>
#include "generic.h"
// Configuration Stuff
diff --git a/python/arfile.cc b/python/arfile.cc
index c3aa74d1..44cd3c82 100644
--- a/python/arfile.cc
+++ b/python/arfile.cc
@@ -25,6 +25,8 @@
#include <apt-pkg/arfile.h>
#include <apt-pkg/error.h>
#include <apt-pkg/sptr.h>
+#include <apt-pkg/aptconfiguration.h>
+#include <apt-pkg/configuration.h>
#include <utime.h>
#include <unistd.h>
@@ -202,7 +204,7 @@ static PyObject *_extract(FileFd &Fd, const ARArchive::Member *member,
if (!Fd.Seek(member->Start))
return HandleErrors();
- string outfile_str = flCombine(dir,member->Name);
+ std::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
@@ -477,8 +479,8 @@ PyTypeObject PyArArchive_Type = {
* 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.{xz,lzma,bz2,gz} and
- * data.tar.{xz,lzma,bz2,gz} members which return TarFile objects. It also adds
+ * of ArFile which adds properties for the control.tar.$compression and
+ * data.tar.$compression 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
@@ -532,21 +534,28 @@ static PyObject *debfile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
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)
- self->data = _gettar(self, self->Object->FindMember("data.tar.xz"),
- "xz");
- if (!self->data)
- return PyErr_Format(PyExc_SystemError, "No debian archive, missing %s",
- "data.tar.gz or data.tar.bz2 or data.tar.lzma "
- "or data.tar.xz");
+ // try all compression types
+ std::vector<std::string> types = APT::Configuration::getCompressionTypes();
+ for (std::vector<std::string>::const_iterator t = types.begin();
+ t != types.end(); ++t)
+ {
+ std::string member = std::string("data.tar.").append(*t);
+ std::string comp = _config->Find(std::string("Acquire::CompressionTypes::").append(*t));
+ self->data = _gettar(self, self->Object->FindMember(member.c_str()),
+ comp.c_str());
+ if (self->data)
+ break;
+ }
+ // no data found, we need to
+ if (!self->data) {
+ std::string error;
+ for (std::vector<std::string>::const_iterator t = types.begin();
+ t != types.end(); ++t)
+ error.append(*t + ",");
+ return PyErr_Format(PyExc_SystemError,
+ "No debian archive, missing data.tar.{%s}",
+ error.c_str());
+ }
const ARArchive::Member *member = self->Object->FindMember("debian-binary");
@@ -590,7 +599,9 @@ 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,xz}) member."},
+ "The TarFile object associated with the data.tar.$compression member. "
+ "All apt compression methods are supported. "
+ },
{"debian_binary",(getter)debfile_get_debian_binary,0,
"The package version, as contained in debian-binary."},
{NULL}
@@ -604,8 +615,9 @@ static const char *debfile_doc =
"specifying a file descriptor (returned by e.g. os.open()).\n"
"The recommended way of using it 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,xz},\n"
- "and debian-binary members in the archive.";
+ "and 'version' for accessing the control.tar.gz, data.tar.$compression \n"
+ "(all apt compression methods are supported), and debian-binary members \n"
+ "in the archive.";
PyTypeObject PyDebFile_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
diff --git a/python/cache.cc b/python/cache.cc
index b263d320..c51bd4af 100644
--- a/python/cache.cc
+++ b/python/cache.cc
@@ -198,11 +198,13 @@ static PyObject *PkgCacheOpen(PyObject *Self,PyObject *Args)
}
//std::cout << "new cache is " << (pkgCache*)(*Cache) << std::endl;
+
+ // ensure that the states are correct (LP: #659438)
+ pkgApplyStatus(*Cache);
// update the cache pointer after the cache was rebuild
((CppPyObject<pkgCache*> *)Self)->Object = (pkgCache*)(*Cache);
-
Py_INCREF(Py_None);
return HandleErrors(Py_None);
}
@@ -229,6 +231,12 @@ static PyObject *PkgCacheGetGroups(PyObject *Self, void*) {
return CppPyObject_NEW<GrpListStruct>(Self,&PyGroupList_Type,Cache->GrpBegin());
}
+static PyObject *PkgCacheGetPolicy(PyObject *Self, void*) {
+ pkgCacheFile *CacheFile = GetCpp<pkgCacheFile *>(Self);
+ std::cerr << "policy: " << CacheFile->Policy << std::endl;
+ return CppPyObject_NEW<pkgPolicy*>(Self,&PyPolicy_Type,CacheFile->Policy);
+}
+
static PyObject *PkgCacheGetPackages(PyObject *Self, void*) {
pkgCache *Cache = GetCpp<pkgCache *>(Self);
return CppPyObject_NEW<PkgListStruct>(Self,&PyPackageList_Type,Cache->PkgBegin());
@@ -289,6 +297,7 @@ static PyGetSetDef PkgCacheGetSet[] = {
{"group_count",PkgCacheGetGroupCount,0,
"The number of apt_pkg.Group objects stored in the cache."},
{"groups", PkgCacheGetGroups, 0, "A list of Group objects in the cache"},
+ {"policy", PkgCacheGetPolicy, 0, "The PkgPolicy for the cache"},
{"is_multi_arch", PkgCacheGetIsMultiArch, 0,
"Whether the cache supports multi-arch."},
{"package_count",PkgCacheGetPackageCount,0,
@@ -394,6 +403,9 @@ static PyObject *PkgCacheNew(PyTypeObject *type,PyObject *Args,PyObject *kwds)
return HandleErrors();
}
+ // ensure that the states are correct (LP: #659438)
+ pkgApplyStatus(*Cache);
+
CppPyObject<pkgCacheFile*> *CacheFileObj =
CppPyObject_NEW<pkgCacheFile*>(0,&PyCacheFile_Type, Cache);
diff --git a/python/cdrom.cc b/python/cdrom.cc
index 6ac16d59..46bb769c 100644
--- a/python/cdrom.cc
+++ b/python/cdrom.cc
@@ -67,7 +67,7 @@ static PyObject *cdrom_ident(PyObject *Self,PyObject *Args)
PyCdromProgress progress;
progress.setCallbackInst(pyCdromProgressInst);
- string ident;
+ std::string ident;
bool res = Cdrom.Ident(ident, &progress);
if (res)
@@ -94,7 +94,7 @@ static PyObject *cdrom_ident_old(PyObject *Self,PyObject *Args)
PyCdromProgress progress;
progress.setCallbackInst(pyCdromProgressInst);
- string ident;
+ std::string ident;
bool res = Cdrom.Ident(ident, &progress);
PyObject *boolres = PyBool_FromLong(res);
diff --git a/python/configuration.cc b/python/configuration.cc
index 9000f71f..37374625 100644
--- a/python/configuration.cc
+++ b/python/configuration.cc
@@ -262,7 +262,7 @@ static PyObject *CnfDump(PyObject *Self,PyObject *Args)
if (PyArg_ParseTuple(Args,"") == 0)
return 0;
- stringstream ss;
+ std::stringstream ss;
GetSelf(Self).Dump(ss);
return CppPyString(ss.str());
}
@@ -331,13 +331,16 @@ static PyObject *CnfMap(PyObject *Self,PyObject *Arg)
// Assignment with operator []
static int CnfMapSet(PyObject *Self,PyObject *Arg,PyObject *Val)
{
- if (PyString_Check(Arg) == 0 || PyString_Check(Val) == 0)
+ if (PyString_Check(Arg) == 0 || (Val != NULL && PyString_Check(Val) == 0))
{
PyErr_SetNone(PyExc_TypeError);
return -1;
}
- GetSelf(Self).Set(PyString_AsString(Arg),PyString_AsString(Val));
+ if (Val == NULL)
+ GetSelf(Self).Clear(PyString_AsString(Arg));
+ else
+ GetSelf(Self).Set(PyString_AsString(Arg),PyString_AsString(Val));
return 0;
}
/*}}}*/
diff --git a/python/depcache.cc b/python/depcache.cc
index e6113429..73993c82 100644
--- a/python/depcache.cc
+++ b/python/depcache.cc
@@ -22,6 +22,7 @@
#include <apt-pkg/sourcelist.h>
#include <apt-pkg/pkgrecords.h>
#include <apt-pkg/acquire-item.h>
+#include <apt-pkg/fileutl.h>
#include <Python.h>
#include <iostream>
diff --git a/python/lock.cc b/python/lock.cc
index 2c957df1..38a2bc74 100644
--- a/python/lock.cc
+++ b/python/lock.cc
@@ -21,6 +21,8 @@
#include <Python.h>
#include <apt-pkg/init.h>
#include <apt-pkg/error.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/pkgsystem.h>
#include "generic.h"
static PyObject *systemlock_exit(PyObject *self, PyObject *args)
diff --git a/python/metaindex.cc b/python/metaindex.cc
index a00cf04e..9e330d3d 100644
--- a/python/metaindex.cc
+++ b/python/metaindex.cc
@@ -33,8 +33,8 @@ static PyObject *MetaIndexGetIsTrusted(PyObject *Self,void*) {
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();
+ std::vector<pkgIndexFile *> *indexFiles = meta->GetIndexFiles();
+ for (std::vector<pkgIndexFile *>::const_iterator I = indexFiles->begin();
I != indexFiles->end(); I++)
{
CppPyObject<pkgIndexFile*> *Obj;
diff --git a/python/policy.cc b/python/policy.cc
index b11e4dde..96b83abd 100644
--- a/python/policy.cc
+++ b/python/policy.cc
@@ -46,8 +46,11 @@ PyObject *policy_get_priority(PyObject *self, PyObject *arg) {
if (PyObject_TypeCheck(arg, &PyPackage_Type)) {
pkgCache::PkgIterator pkg = GetCpp<pkgCache::PkgIterator>(arg);
return MkPyNumber(policy->GetPriority(pkg));
+ } else if (PyObject_TypeCheck(arg, &PyPackageFile_Type)) {
+ pkgCache::PkgFileIterator pkgfile = GetCpp<pkgCache::PkgFileIterator>(arg);
+ return MkPyNumber(policy->GetPriority(pkgfile));
} else {
- PyErr_SetString(PyExc_TypeError,"Argument must be of Package().");
+ PyErr_SetString(PyExc_TypeError,"Argument must be of Package() or PackageFile().");
return 0;
}
}
diff --git a/python/progress.cc b/python/progress.cc
index bd3c2ad6..a7fd7ae1 100644
--- a/python/progress.cc
+++ b/python/progress.cc
@@ -127,7 +127,7 @@ PyObject *PyFetchProgress::GetDesc(pkgAcquire::ItemDesc *item) {
return pyDesc;
}
-bool PyFetchProgress::MediaChange(string Media, string Drive)
+bool PyFetchProgress::MediaChange(std::string Media, std::string Drive)
{
PyCbObj_END_ALLOW_THREADS
//std::cout << "MediaChange" << std::endl;
@@ -485,7 +485,7 @@ pkgPackageManager::OrderResult PyInstallProgress::Run(pkgPackageManager *pm)
PyObject *v = PyObject_GetAttrString(callbackInst, "writefd");
if(v) {
int fd = PyObject_AsFileDescriptor(v);
- cout << "got fd: " << fd << endl;
+ std::cout << "got fd: " << fd << std::endl;
res = pm->DoInstall(fd);
} else {
res = pm->DoInstall();
@@ -542,7 +542,7 @@ pkgPackageManager::OrderResult PyInstallProgress::Run(pkgPackageManager *pm)
//-----------------------------------------------------------------------------
// apt-cdrom interface
-void PyCdromProgress::Update(string text, int current)
+void PyCdromProgress::Update(std::string text, int current)
{
PyObject *arglist = Py_BuildValue("(si)", text.c_str(), current);
setattr(callbackInst, "total_steps", "i", totalSteps);
@@ -569,7 +569,7 @@ bool PyCdromProgress::ChangeCdrom()
}
-bool PyCdromProgress::AskCdromName(string &Name)
+bool PyCdromProgress::AskCdromName(std::string &Name)
{
PyObject *arglist = Py_BuildValue("()");
const char *new_name;
@@ -582,7 +582,7 @@ bool PyCdromProgress::AskCdromName(string &Name)
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);
+ Name =std:: string(new_name);
return res;
}
// New style: String on success, None on failure.
@@ -593,7 +593,7 @@ bool PyCdromProgress::AskCdromName(string &Name)
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;
+ Name = std::string(new_name);
+ return true;
}
}
diff --git a/python/progress.h b/python/progress.h
index 4e66c771..af8e3acc 100644
--- a/python/progress.h
+++ b/python/progress.h
@@ -72,7 +72,7 @@ struct PyFetchProgress : public pkgAcquireStatus, public PyCallbackObj
void UpdateStatus(pkgAcquire::ItemDesc & Itm, int status);
- virtual bool MediaChange(string Media, string Drive);
+ virtual bool MediaChange(std::string Media, std::string Drive);
void setPyAcquire(PyObject *o) {
Py_CLEAR(pyAcquire);
@@ -107,11 +107,11 @@ struct PyInstallProgress : public PyCallbackObj
struct PyCdromProgress : public pkgCdromStatus, public PyCallbackObj
{
// update steps, will be called regularly as a "pulse"
- virtual void Update(string text="", int current=0);
+ virtual void Update(std::string text="", int current=0);
// ask for cdrom insert
virtual bool ChangeCdrom();
// ask for cdrom name
- virtual bool AskCdromName(string &Name);
+ virtual bool AskCdromName(std::string &Name);
PyCdromProgress() : PyCallbackObj() {};
};
diff --git a/python/tag.cc b/python/tag.cc
index 94554400..248d818d 100644
--- a/python/tag.cc
+++ b/python/tag.cc
@@ -26,6 +26,7 @@
#include "apt_pkgmodule.h"
#include <apt-pkg/tagfile.h>
+#include <apt-pkg/fileutl.h>
#include <stdio.h>
#include <iostream>
@@ -37,6 +38,10 @@ using namespace std;
struct TagSecData : public CppPyObject<pkgTagSection>
{
char *Data;
+ bool Bytes;
+#if PY_MAJOR_VERSION >= 3
+ PyObject *Encoding;
+#endif
};
// The owner of the TagFile is a Python file object.
@@ -44,6 +49,10 @@ struct TagFileData : public CppPyObject<pkgTagFile>
{
TagSecData *Section;
FileFd Fd;
+ bool Bytes;
+#if PY_MAJOR_VERSION >= 3
+ PyObject *Encoding;
+#endif
};
// Traversal and Clean for owned objects
@@ -59,6 +68,35 @@ int TagFileClear(PyObject *self) {
return 0;
}
+// Helpers to return Unicode or bytes as appropriate.
+#if PY_MAJOR_VERSION < 3
+#define TagSecString_FromStringAndSize(self, v, len) \
+ PyString_FromStringAndSize((v), (len))
+#define TagSecString_FromString(self, v) PyString_FromString(v)
+#else
+PyObject *TagSecString_FromStringAndSize(PyObject *self, const char *v,
+ Py_ssize_t len) {
+ TagSecData *Self = (TagSecData *)self;
+ if (Self->Bytes)
+ return PyBytes_FromStringAndSize(v, len);
+ else if (Self->Encoding)
+ return PyUnicode_Decode(v, len, PyUnicode_AsString(Self->Encoding), 0);
+ else
+ return PyUnicode_FromStringAndSize(v, len);
+}
+
+PyObject *TagSecString_FromString(PyObject *self, const char *v) {
+ TagSecData *Self = (TagSecData *)self;
+ if (Self->Bytes)
+ return PyBytes_FromString(v);
+ else if (Self->Encoding)
+ return PyUnicode_Decode(v, strlen(v),
+ PyUnicode_AsString(Self->Encoding), 0);
+ else
+ return PyUnicode_FromString(v);
+}
+#endif
+
/*}}}*/
// TagSecFree - Free a Tag Section /*{{{*/
@@ -106,9 +144,9 @@ static PyObject *TagSecFind(PyObject *Self,PyObject *Args)
{
if (Default == 0)
Py_RETURN_NONE;
- return PyString_FromString(Default);
+ return TagSecString_FromString(Self,Default);
}
- return PyString_FromStringAndSize(Start,Stop-Start);
+ return TagSecString_FromStringAndSize(Self,Start,Stop-Start);
}
static char *doc_FindRaw =
@@ -127,14 +165,14 @@ static PyObject *TagSecFindRaw(PyObject *Self,PyObject *Args)
{
if (Default == 0)
Py_RETURN_NONE;
- return PyString_FromString(Default);
+ return TagSecString_FromString(Self,Default);
}
const char *Start;
const char *Stop;
GetCpp<pkgTagSection>(Self).Get(Start,Stop,Pos);
- return PyString_FromStringAndSize(Start,Stop-Start);
+ return TagSecString_FromStringAndSize(Self,Start,Stop-Start);
}
static char *doc_FindFlag =
@@ -160,21 +198,18 @@ static PyObject *TagSecFindFlag(PyObject *Self,PyObject *Args)
// Map access, operator []
static PyObject *TagSecMap(PyObject *Self,PyObject *Arg)
{
- if (PyString_Check(Arg) == 0)
- {
- PyErr_SetNone(PyExc_TypeError);
+ const char *Name = PyObject_AsString(Arg);
+ if (Name == 0)
return 0;
- }
-
const char *Start;
const char *Stop;
- if (GetCpp<pkgTagSection>(Self).Find(PyString_AsString(Arg),Start,Stop) == false)
+ if (GetCpp<pkgTagSection>(Self).Find(Name,Start,Stop) == false)
{
- PyErr_SetString(PyExc_KeyError,PyString_AsString(Arg));
+ PyErr_SetString(PyExc_KeyError,Name);
return 0;
}
- return PyString_FromStringAndSize(Start,Stop-Start);
+ return TagSecString_FromStringAndSize(Self,Start,Stop-Start);
}
// len() operation
@@ -229,9 +264,9 @@ static PyObject *TagSecExists(PyObject *Self,PyObject *Args)
static int TagSecContains(PyObject *Self,PyObject *Arg)
{
- if (PyString_Check(Arg) == 0)
- return 0;
- const char *Name = PyString_AsString(Arg);
+ const char *Name = PyObject_AsString(Arg);
+ if (Name == 0)
+ return 0;
const char *Start;
const char *Stop;
if (GetCpp<pkgTagSection>(Self).Find(Name,Start,Stop) == false)
@@ -255,7 +290,7 @@ static PyObject *TagSecStr(PyObject *Self)
const char *Start;
const char *Stop;
GetCpp<pkgTagSection>(Self).GetSection(Start,Stop);
- return PyString_FromStringAndSize(Start,Stop-Start);
+ return TagSecString_FromStringAndSize(Self,Start,Stop-Start);
}
/*}}}*/
// TagFile Wrappers /*{{{*/
@@ -285,6 +320,12 @@ static PyObject *TagFileNext(PyObject *Self)
Obj.Section->Owner = Self;
Py_INCREF(Obj.Section->Owner);
Obj.Section->Data = 0;
+ Obj.Section->Bytes = Obj.Bytes;
+#if PY_MAJOR_VERSION >= 3
+ // We don't need to incref Encoding as the previous Section object already
+ // held a reference to it.
+ Obj.Section->Encoding = Obj.Encoding;
+#endif
if (Obj.Object.Step(Obj.Section->Object) == false)
return HandleErrors(NULL);
@@ -346,11 +387,12 @@ static PyObject *TagFileJump(PyObject *Self,PyObject *Args)
static PyObject *TagSecNew(PyTypeObject *type,PyObject *Args,PyObject *kwds) {
char *Data;
int Len;
- char *kwlist[] = {"text", 0};
+ char Bytes = 0;
+ char *kwlist[] = {"text", "bytes", 0};
// this allows reading "byte" types from python3 - but we don't
// make (much) use of it yet
- if (PyArg_ParseTupleAndKeywords(Args,kwds,"s#",kwlist,&Data,&Len) == 0)
+ if (PyArg_ParseTupleAndKeywords(Args,kwds,"s#|b",kwlist,&Data,&Len,&Bytes) == 0)
return 0;
// Create the object..
@@ -358,6 +400,10 @@ static PyObject *TagSecNew(PyTypeObject *type,PyObject *Args,PyObject *kwds) {
new (&New->Object) pkgTagSection();
New->Data = new char[strlen(Data)+2];
snprintf(New->Data,strlen(Data)+2,"%s\n",Data);
+ New->Bytes = Bytes;
+#if PY_MAJOR_VERSION >= 3
+ New->Encoding = 0;
+#endif
if (New->Object.Scan(New->Data,strlen(New->Data)) == false)
{
@@ -389,23 +435,62 @@ PyObject *ParseSection(PyObject *self,PyObject *Args)
static PyObject *TagFileNew(PyTypeObject *type,PyObject *Args,PyObject *kwds)
{
- PyObject *File;
- char *kwlist[] = {"file", 0};
- if (PyArg_ParseTupleAndKeywords(Args,kwds,"O",kwlist,&File) == 0)
+ TagFileData *New;
+ PyObject *File = 0;
+ char Bytes = 0;
+
+ char *kwlist[] = {"file", "bytes", 0};
+ if (PyArg_ParseTupleAndKeywords(Args,kwds,"O|b",kwlist,&File,&Bytes) == 0)
return 0;
- int fileno = PyObject_AsFileDescriptor(File);
- if (fileno == -1)
+
+ // check if we got a filename or a file object
+ int fileno = -1;
+ const char *filename = NULL;
+ filename = PyObject_AsString(File);
+ if (filename == NULL) {
+ PyErr_Clear();
+ fileno = PyObject_AsFileDescriptor(File);
+ }
+
+ // handle invalid arguments
+ if (fileno == -1 && filename == NULL)
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "Argument must be string, fd or have a fileno() method");
return 0;
+ }
- TagFileData *New = (TagFileData*)type->tp_alloc(type, 0);
+ New = (TagFileData*)type->tp_alloc(type, 0);
+ if (fileno != -1)
+ {
#ifdef APT_HAS_GZIP
- new (&New->Fd) FileFd();
- New->Fd.OpenDescriptor(fileno, FileFd::ReadOnlyGzip, false);
+ new (&New->Fd) FileFd();
+ New->Fd.OpenDescriptor(fileno, FileFd::ReadOnlyGzip, false);
#else
- new (&New->Fd) FileFd(fileno,false);
+ new (&New->Fd) FileFd(fileno,false);
#endif
+ }
+ else
+ {
+ // FileFd::Extension got added in this revision
+#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 12)
+ new (&New->Fd) FileFd(filename, FileFd::ReadOnly, FileFd::Extension, false);
+#else
+ new (&New->Fd) FileFd(filename, FileFd::ReadOnly, false);
+#endif
+ }
+ New->Bytes = Bytes;
New->Owner = File;
Py_INCREF(New->Owner);
+#if PY_MAJOR_VERSION >= 3
+ if (fileno != -1) {
+ New->Encoding = PyObject_GetAttr(File, PyUnicode_FromString("encoding"));
+ if (New->Encoding && !PyUnicode_Check(New->Encoding))
+ New->Encoding = 0;
+ } else
+ New->Encoding = 0;
+ Py_XINCREF(New->Encoding);
+#endif
new (&New->Object) pkgTagFile(&New->Fd);
// Create the section
@@ -414,6 +499,11 @@ static PyObject *TagFileNew(PyTypeObject *type,PyObject *Args,PyObject *kwds)
New->Section->Owner = New;
Py_INCREF(New->Section->Owner);
New->Section->Data = 0;
+ New->Section->Bytes = Bytes;
+#if PY_MAJOR_VERSION >= 3
+ New->Section->Encoding = New->Encoding;
+ Py_XINCREF(New->Section->Encoding);
+#endif
return HandleErrors(New);
}
@@ -491,7 +581,7 @@ PyObject *RewriteSection(PyObject *self,PyObject *Args)
}
// Return the string
- PyObject *ResObj = PyString_FromStringAndSize(bp,size);
+ PyObject *ResObj = TagSecString_FromStringAndSize(Section,bp,size);
free(bp);
return HandleErrors(ResObj);
}
@@ -520,11 +610,15 @@ PySequenceMethods TagSecSeqMeth = {0,0,0,0,0,0,0,TagSecContains,0,0};
PyMappingMethods TagSecMapMeth = {TagSecLength,TagSecMap,0};
-static char *doc_TagSec = "TagSection(text: str)\n\n"
+static char *doc_TagSec = "TagSection(text: str, [bytes: bool = False])\n\n"
"Provide methods to access RFC822-style header sections, like those\n"
"found 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)";
+ "to the functions provided by the C++ class (e.g. find).\n\n"
+ "By default, text read from files is treated as strings (binary data in\n"
+ "Python 2, Unicode strings in Python 3). Use bytes=True to cause all\n"
+ "header values read from this TagSection to be bytes even in Python 3.\n"
+ "Header names are always treated as Unicode.";
PyTypeObject PyTagSection_Type =
{
PyVarObject_HEAD_INIT(&PyType_Type, 0)
@@ -595,7 +689,7 @@ static PyGetSetDef TagFileGetSet[] = {
};
-static char *doc_TagFile = "TagFile(file)\n\n"
+static char *doc_TagFile = "TagFile(file, [bytes: bool = False])\n\n"
"TagFile() objects provide access to debian control files, which consist\n"
"of multiple RFC822-style sections.\n\n"
"To provide access to those sections, TagFile objects provide an iterator\n"
@@ -607,7 +701,11 @@ static char *doc_TagFile = "TagFile(file)\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)";
+ "a file descriptor (an integer).\n\n"
+ "By default, text read from files is treated as strings (binary data in\n"
+ "Python 2, Unicode strings in Python 3). Use bytes=True to cause all\n"
+ "header values read from this TagFile to be bytes even in Python 3.\n"
+ "Header names are always treated as Unicode.";
// Type for a Tag File
PyTypeObject PyTagFile_Type =
diff --git a/python/tar.cc b/python/tar.cc
index b994d4e7..e42a9c50 100644
--- a/python/tar.cc
+++ b/python/tar.cc
@@ -182,6 +182,8 @@ PyObject *debExtract(PyObject *Self,PyObject *Args)
Comp = "bzip2";
else if(strcmp(".lzma", &Chunk[strlen(Chunk)-5]) == 0)
Comp = "lzma";
+ else if(strcmp(".xz", &Chunk[strlen(Chunk)-3]) == 0)
+ Comp = "xz";
ExtractTar Tar(Deb.GetFile(),Member->Size,Comp);
ProcessTar Proc(Function);
if (Tar.Go(Proc) == false)
diff --git a/python/tarfile.cc b/python/tarfile.cc
index cdfe0a7c..bd903b57 100644
--- a/python/tarfile.cc
+++ b/python/tarfile.cc
@@ -348,7 +348,7 @@ static const char *tarfile_extractall_doc =
"can be used to change the target directory.";
static PyObject *tarfile_extractall(PyObject *self, PyObject *args)
{
- string cwd = SafeGetCWD();
+ std::string cwd = SafeGetCWD();
char *rootdir = 0;
if (PyArg_ParseTuple(args,"|s:extractall",&rootdir) == 0)
return 0;