New submission from Christian Heimes:
I always missed a getsize() method on file objects. The patch adds a
method getsize() to all io instances. The method returns a SizeInfo
object which can print a human readable name or the bare size in bytes.
The method is using os.fstat and falls back to the seek(0,2), tell()
pattern.
>>> f = open("/etc/passwd")
>>> f.getsize()
<SizeInfo 1.7 KiB>
>>> int(f.getsize())
1721
>>> str(f.getsize())
'1.7 KiB'
>>> (f.getsize().sizeinfo())
(1.681, 1)
I'm going to provide unit tests and documentation if you like the feature.
----------
components: Library (Lib)
files: py3k_sizeinfo.patch
messages: 56877
nosy: tiran
severity: normal
status: open
title: Add getsize() to io instances
type: rfe
versions: Python 3.0
Added file: http://bugs.python.org/file8642/py3k_sizeinfo.patch
__________________________________
Tracker <[EMAIL PROTECTED]>
<http://bugs.python.org/issue1351>
__________________________________
Index: Lib/io.py
===================================================================
--- Lib/io.py (Revision 58695)
+++ Lib/io.py (Arbeitskopie)
@@ -190,6 +190,42 @@
return open(*args, **kwargs)
+class SizeInfo:
+ """Wrapper for size information
+ """
+ size_names = ('B', 'KiB', 'MiB', 'GiB')
+
+ def __init__(self, size:int):
+ if not isinstance(size, int) and not size >=0:
+ raise ValueError("Invalid size %r" % size)
+ self._size = size
+
+ def __int__(self) -> int:
+ """int(sizeinfo) -> int
+ """
+ return self._size
+
+ def sizeinfo(self) -> tuple:
+ """sizeinfo() -> (rounded size:float, size name:int)
+ """
+ if self._size == 0:
+ return 0, 0
+ if self._size < 1024:
+ return self._size, 0
+ if self._size < 1048576:
+ return round(self._size / 1024, 3), 1
+ if self._size < 1073741824:
+ return round(self._size / 1048576, 3), 2
+ return round(self._size / 1073741824, 3), 3
+
+ def __str__(self) -> str:
+ size, name = self.sizeinfo()
+ return "%1.1f %s" % (size, self.size_names[name])
+
+ def __repr__(self) -> str:
+ return "<%s %s>" % (self.__class__.__name__, self)
+
+
class UnsupportedOperation(ValueError, IOError):
pass
@@ -339,6 +375,27 @@
raise ValueError("I/O operation on closed file."
if msg is None else msg)
+ def getsize(self) -> SizeInfo:
+ """getsize() -> SizeInfo object
+ """
+ size = None
+ self.flush()
+
+ try:
+ size = os.fstat(self.fileno()).st_size
+ except (IOError, OSError):
+ pass
+
+ if size is None:
+ oldpos = self.tell()
+ try:
+ self.seek(0, 2)
+ size = self.tell()
+ finally:
+ self.seek(oldpos)
+
+ return SizeInfo(size)
+
### Context manager ###
def __enter__(self) -> "IOBase": # That's a forward reference
@@ -621,6 +678,10 @@
### Inquiries ###
+ def getsize(self):
+ self.flush()
+ return self.raw.getsize()
+
def seekable(self):
return self.raw.seekable()
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com