[Pkg-python-debian-commits] r74 trunk: docstrings and other cosmetic stuff
zack at bononia.it
zack at bononia.it
Sat Jul 14 16:11:36 UTC 2007
------------------------------------------------------------
revno: 74
committer: zack at bononia.it
branch nick: pkg-python-debian.debfile
timestamp: Sat 2007-07-14 18:11:36 +0200
message:
docstrings and other cosmetic stuff
modified:
debian_bundle/arfile.py
debian_bundle/test_debfile.py
-------------- next part --------------
=== modified file 'debian_bundle/arfile.py'
--- a/debian_bundle/arfile.py 2007-07-14 13:30:55 +0000
+++ b/debian_bundle/arfile.py 2007-07-14 16:11:36 +0000
@@ -1,7 +1,7 @@
#!/usr/bin/python
GLOBAL_HEADER = "!<arch>\n"
-GLOBAL_HEADER_LENGTH = 8
+GLOBAL_HEADER_LENGTH = len(GLOBAL_HEADER)
FILE_HEADER_LENGTH = 60
FILE_MAGIC = "`\n"
@@ -10,21 +10,25 @@
pass
class ArFile(object):
-# XXX trying to mimick the interface of TarFile in the standard library
+ """ Representation of an ar archive, see man 1 ar.
+
+ The interface of this class tries to mimick that of the TarFile module in
+ the standard library. """
def __init__(self, filename=None, mode='r', fileobj=None):
- self.__members_list = []
+ """ Build an ar file representation starting from either a filename or
+ an existing file object. The only supported mode is 'r' """
+
+ self.__members = []
+ self.__members_dict = {}
self.__fname = filename
self.__fileobj = fileobj
-
+
if mode == "r":
- self.__index_archive()
+ self.__indexArchive()
pass # TODO write support
- def __iter__(self):
- return iter(self.getmembers())
-
- def __index_archive(self):
+ def __indexArchive(self):
if self.__fname:
fp = open(self.__fname, "rb")
elif self.__fileobj:
@@ -39,7 +43,8 @@
newmember = ArMember.from_file(fp, self.__fname)
if not newmember:
break
- self.__members_list.append(newmember)
+ self.__members.append(newmember)
+ self.__members_dict[newmember.name] = newmember
#print newmember.name + " added tell " + str(fp.tell()) + " size: " + repr(newmember.size)
if newmember.getsize() % 2 == 0: # even, no pad
fp.seek(newmember.getsize(), 1) # skip to next header
@@ -50,65 +55,92 @@
fp.close()
def getmember(self, name):
- for m in self.__members_list:
- if name == m.name:
- return m
-
- return None
-
- def getmembers(self): return self.__members_list
+ """ Return the (last occurrence of a) member in the archive whose name
+ is 'name'. Raise KeyError if no member matches the given name.
+
+ Note that in case of name collisions the only way to retrieve all
+ members matching a given name is to use getmembers. """
+
+ return self.__members_dict[name]
+
+ def getmembers(self):
+ """ Return a list of all members contained in the archive.
+
+ The list has the same order of members in the archive and can contain
+ duplicate members (i.e. members with the same name) if they are
+ duplicate in the archive itself. """
+
+ return self.__members
+
members = property(getmembers)
def getnames(self):
- return map(lambda f: f.name, self.__members_list)
+ """ Return a list of all member names in the archive. """
- def __iter__(self):
- return self.__members_list.__iter__()
+ return map(lambda f: f.name, self.__members)
def extractall():
- pass # TODO
+ """ Not (yet) implemented. """
+
+ raise NotImpelementedError # TODO
def extract(self, member, path):
- pass # TODO
+ """ Not (yet) implemented. """
+
+ raise NotImpelementedError # TODO
def extractfile(self, member):
- for m in self__members_list:
- if isinstance(member, ArMember) and m.name == member.name:
- return m
- if member == m.name:
- return m
-
- return None
+ """ Return a file object corresponding to the requested member. A member
+ can be specified either as a string (its name) or as a ArMember
+ instance. """
+
+ for m in self.__members:
+ if isinstance(member, ArMember) and m.name == member.name:
+ return m
+ elif member == m.name:
+ return m
+ else:
+ return None
+
+ # container emulation
+
+ def __iter__(self):
+ """ Iterate over the members of the present ar archive. """
+
+ return iter(self.__members)
+
+ def __getitem__(self, name):
+ """ Same as .getmember(name). """
+
+ return self.getmember(name)
+
class ArMember(object):
- # XXX trying to mimick the interface of TarInfo in the standard library
+ """ Member of an ar archive.
+
+ Implements most of a file object interface: read, readline, next,
+ readlines, seek, tell, close. """
def __init__(self):
self.__name = None # member name (i.e. filename) in the archive
- self.__mtime = None
- self.__owner = None
- self.__group = None
- self.__fmode = None
- self.__size = None # member size in bytes
+ self.__mtime = None # last modification time
+ self.__owner = None # owner user
+ self.__group = None # owner group
+ self.__fmode = None # permissions
+ self.__size = None # member size in bytes
self.__fname = None # file name associated with this member
- self.__fp = None # file pointer
+ self.__fp = None # file pointer
self.__offset = None # start-of-data offset
- self.__end = None # end-of-data offset
- pass # TODO
+ self.__end = None # end-of-data offset
- def _from_file(fp, fname):
- """fp is an open File object positioned to a valid file header or global header.
- Returns a new ArMember on success"""
+ def from_file(fp, fname):
+ """fp is an open File object positioned on a valid file header inside
+ an ar archive. Return a new ArMember on success, None otherwise. """
buf = fp.read(FILE_HEADER_LENGTH)
if not buf:
- return False
-
-# XXX testare
- # fp is an ar archive start
-# if buf[0:GLOBAL_HEADER_LENGTH] == GLOBAL_HEADER:
-# buf = buf[GLOBAL_HEADER_LENGTH:] + fp.read(GLOBAL_HEADER_LENGTH)
+ return None
# sanity checks
if len(buf) < FILE_HEADER_LENGTH:
@@ -117,23 +149,23 @@
if buf[58:60] != FILE_MAGIC:
raise IOError, "Incorrect file magic"
-# http://en.wikipedia.org/wiki/Ar_(Unix)
-#from to Name Format
-#0 15 File name ASCII
-#16 27 File modification date Decimal
-#28 33 Owner ID Decimal
-#34 39 Group ID Decimal
-#40 47 File mode Octal
-#48 57 File size in bytes Decimal
-#58 59 File magic \140\012
+ # http://en.wikipedia.org/wiki/Ar_(Unix)
+ #from to Name Format
+ #0 15 File name ASCII
+ #16 27 File modification date Decimal
+ #28 33 Owner ID Decimal
+ #34 39 Group ID Decimal
+ #40 47 File mode Octal
+ #48 57 File size in bytes Decimal
+ #58 59 File magic \140\012
-# XXX struct.unpack can be used as well here
+ # XXX struct.unpack can be used as well here
f = ArMember()
f.__name = buf[0:16].split("/")[0].strip()
f.__mtime = int(buf[16:28])
f.__owner = int(buf[28:34])
f.__group = int(buf[34:40])
- f.__fmode = buf[40:48] # XXX e' un ottale
+ f.__fmode = buf[40:48] # XXX octal value
f.__size = int(buf[48:58])
f.__fname = fname
@@ -142,11 +174,12 @@
return f
- from_file = staticmethod(_from_file)
+ from_file = staticmethod(from_file)
-# file interface
-# XXX this is not a sequence like file objects
-# XXX test padding
+ # file interface
+
+ # XXX this is not a sequence like file objects
+ # XXX test padding
def read(self, size=0):
if self.__fp is None:
self.__fp = open(self.__fname, "r")
@@ -162,7 +195,7 @@
return self.__fp.read(self.__end - cur)
-# XXX check corner cases for readline(s)
+ # XXX check corner cases for readline(s)
def readline(self, size=None):
if self.__fp is None:
self.__fp = open(self.__fname, "r")
@@ -217,19 +250,6 @@
elif whence == 2:
self.__fp.seek(self.__end + offset, 0)
- #if whence == 0: # absolute
- #if self.__offset + offset > end: # out-of-bounds
- #self.__fp.seek(end)
- #else:
- #self.__fp.seek(self.__offset + offset, 0)
- #elif whence == 1: # relative
- #if cur + offset > end: # out-of-bounds
- #self.__fp.seek(end)
- #else:
- #self.__fp.seek(offset, 1)
- #elif whence == 2: # relative to EOF
- #self.__fp.seek(end)
-
def tell(self):
if self.__fp is None:
self.__fp = open(self.__fname, "r")
@@ -254,9 +274,6 @@
return iter(nextline())
- def getoffset(self): return self.__offset
- offset = property(getoffset)
-
def getname(self): return self.__name
name = property(getname)
@@ -275,24 +292,16 @@
def getsize(self): return self.__size
size = property(getsize)
-
- # ALTRE PROP da aggiungere: mtime, mode, ...
-
- def tobuf():
- pass # TODO
-
- def tofile(self):
- return self
-
-# FINQUI
+ def getfname(self): return self.__fname
+ fname = property(getsize)
if __name__ == '__main__':
-# test
-# ar r test.ar <file1> <file2> .. <fileN>
+ # test
+ # ar r test.ar <file1> <file2> .. <fileN>
t = ArFile("test.deb")
print t.getmembers()
print t.getnames()
a = t.getmember("debian-binary")
for l in a:
print repr(l)
-# vim:et:ts=4
+
=== modified file 'debian_bundle/test_debfile.py'
--- a/debian_bundle/test_debfile.py 2007-07-14 13:30:55 +0000
+++ b/debian_bundle/test_debfile.py 2007-07-14 16:11:36 +0000
@@ -4,12 +4,15 @@
import unittest
import os
+from stat import *
+
class TestArFile(unittest.TestCase):
-# def setUp(self):
+
def setUp(self):
os.system("ar r test.ar test_debfile.py arfile.py debfile.py")
assert os.path.exists("test.ar")
- self.testmembers = [x.strip() for x in os.popen("ar t test.ar").readlines()]
+ self.testmembers = [ x.strip()
+ for x in os.popen("ar t test.ar").readlines() ]
a = arfile.ArFile("test.ar")
def test_getnames(self):
@@ -18,7 +21,6 @@
def test_getmember(self):
a = arfile.ArFile("test.ar")
- from stat import *
for member in self.testmembers:
m = a.getmember(member)
@@ -62,4 +64,3 @@
if __name__ == '__main__':
unittest.main()
-# vim:set ts=4 sw=4 expandtab:
More information about the pkg-python-debian-commits
mailing list