Package: python-debian
Version: 0.1.14ubuntu2
Severity: normal
Tags: patch
Currently (tested using trunk), ArFile assumes that it will always receive a
filename, and that filename relates to the local filesystem.
This means that, when instantiating a DebFile using only a fileobj parameter,
you get something like:
from debian import debfile
package = debfile.DebFile(fileobj=open('some-package.deb', 'r'))
Traceback (most recent call last):
File stdin, line 1, in module
File
/usr/local/lib/python2.6/dist-packages/python_debian-_CHANGELOG_VERSION_-py2.6.egg/debian/debfile.py,
line 236, in __init__
self.__version = f.read().strip()
File
/usr/local/lib/python2.6/dist-packages/python_debian-_CHANGELOG_VERSION_-py2.6.egg/debian/arfile.py,
line 211, in read
self.__fp = open(self.__fname, r)
TypeError: coercing to Unicode: need string or buffer, NoneType found
The solution I've come up with will involve DebFile sharing the fileobj among
several ArFile instances (is there a way to clone file-like objects?), which
means ArFiles keep an internal seek-location, and don't actually close() the
file pointer (leaky?).
A patch should be attached, or there is my fork on GitHub:
https://github.com/Raumkraut/python-debian
-- System Information:
Debian Release: squeeze/sid
APT prefers lucid-updates
APT policy: (500, 'lucid-updates'), (500, 'lucid-security'), (500, 'lucid')
Architecture: i386 (i686)
Kernel: Linux 2.6.32-33-generic-pae (SMP w/2 CPU cores)
Locale: LANG=en_GB.utf8, LC_CTYPE=en_GB.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Versions of packages python-debian depends on:
ii python 2.6.5-0ubuntu1An interactive high-level object-o
ii python-apt 0.7.94.2ubuntu6.4 Python interface to libapt-pkg
ii python-support 1.0.4ubuntu1 automated rebuilding support for P
python-debian recommends no packages.
Versions of packages python-debian suggests:
ii gpgv 1.4.10-2ubuntu1 GNU privacy guard - signature veri
diff --git a/lib/debian/arfile.py b/lib/debian/arfile.py
index 9ad757e..d881e5f 100644
--- a/lib/debian/arfile.py
+++ b/lib/debian/arfile.py
@@ -159,6 +159,7 @@ class ArMember(object):
self.__fp = None# file pointer
self.__offset = None# start-of-data offset
self.__end = None # end-of-data offset
+self.__cur = None # current seek-location (for shared fp)
def from_file(fp, fname):
fp is an open File object positioned on a valid file header inside
@@ -198,51 +199,68 @@ class ArMember(object):
f.__fname = fname
f.__offset = fp.tell() # start-of-data
f.__end = f.__offset + f.__size
-
+
+if fname is None:
+f.__fp = fp
+f.__cur = f.__offset
+
return f
from_file = staticmethod(from_file)
-# file interface
-
-# XXX this is not a sequence like file objects
-def read(self, size=0):
+def _init_fp(self):
+Readies the file pointer.
if self.__fp is None:
+# We have just a filename, so open it (one time)
self.__fp = open(self.__fname, r)
self.__fp.seek(self.__offset)
+
+elif self.__fname is None:
+# Nameless (possibly shared) file-like object
+self.__fp.seek(self.__cur)
+
+def _update_cur(self):
+Update our current position.
+self.__cur = self.__fp.tell()
+
+# file interface
-cur = self.__fp.tell()
-
-if size 0 and size = self.__end - cur: # there's room
-return self.__fp.read(size)
+# XXX this is not a sequence like file objects
+def read(self, size=0):
+self._init_fp()
-if cur = self.__end or cur self.__offset:
-return ''
+if size 0 and size = self.__end - self.__cur: # there's room
+ret = self.__fp.read(size)
-return self.__fp.read(self.__end - cur)
+elif self.__cur = self.__end or self.__cur self.__offset:
+ret = ''
+
+else:
+ret = self.__fp.read(self.__end - self.__cur)
+
+self._update_cur()
+return ret
def readline(self, size=None):
-if self.__fp is None:
-self.__fp = open(self.__fname, r)
-self.__fp.seek(self.__offset)
-
+self._init_fp()
+
if size is not None:
buf = self.__fp.readline(size)
-if self.__fp.tell() self.__end:
+self._update_cur()
+if self.__cur self.__end:
return ''
return buf
buf = self.__fp.readline()
-if self.__fp.tell() self.__end:
+self._update_cur()
+if self.__cur self.__end:
return ''
else:
return buf
def readlines(self, sizehint=0):
-if self.__fp is None:
-