Why is Python not supporting full derivation of built-in file class?

P

Pierre Rouleau

Greetings,

I'm wondering why the >> operator does not use the write() method of a
class derived from the built-in file class as in DerivedFile below.

In the following example:

- StringFile is just a file-like string accumulation class that can be
used in place of a real file to accumulate strings that would otherwise
be printed. Works fine, can accumulate strings with the >> operator,
but is not a true file.

- DelegatedFile is a new-style class, a true file class, which provides
all the features of a real file through delegation. It also works fine
and can accumulate string with the >> operator.

- DerivedFile is a new-style class that is derived from file. It
behaves like a true file, but the >> operator does not call its write()
method. Why is that?

Is this related to the fact that on object from that class is seen as a
file (as shown at the end of the code session below)?

Is this intended or is it a flaw in the language that is waiting to be
fixed?

... if stream is None:
... stream = sys.stdout
... print >> stream, "Bonjour!"
...
... # that behaves like a file for writing only.
... class StringFile:
... "A file-like object to accumulate strings"
... # print >> aStringFile works
... def __init__(self):
... self.strings = []
... def write(self, text):
... self.strings.append(text)
... def writelines(self, lines):
... self.strings.extend(lines)
...
... # extends the built-in file object.
... class DelegatedFile(object):
... "A file-like object to accumulate strings"
... # print >> aStringFile works
... def __init__(self, *args):
... self.strings = []
... self._file = file(*args)
... def __getattr__(self, name) :
... return getattr(self._file, name)
... def write(self, text):
... self.strings.append(text)
... self._file.write(text)
... def writelines(self, lines):
... self.strings.extend(lines)
... self._file.writelines(lines)
...
... # that extends file. But has a flaw in the use of the >> operator!
... class DerivedFile(file):
... "A file object that accumulated written strings"
... # print >> a DerivedFile doe NOT work!
... def __init__(self, *args):
... self.strings = []
... file.__init__(self, *args)
... def write(self, text):
... self.strings.append(text)
... file.write(self, text)
... # super(DerivedFile, self).write(text)
... def writelines(self, lines):
... self.strings.extend(lines)
... file.writelines(self, lines)
... # super(DerivedFile, self).writelines(lines)
...
>>> hello() Bonjour!
>>>
>>> sf = StringFile()
>>> hello(sf)
>>> sf.strings ['Bonjour!', '\n']
>>>
>>> dg = DelegatedFile("temp.txt","w")
>>> hello(dg)
>>> dg.close()
>>> dg.strings ['Bonjour!', '\n']
>>> for line in file("temp.txt"): print line
...

Bonjour!
>>> df = DerivedFile("temp2.txt","w")
>>> hello(df)
>>> df.close()
>>> df.strings []
>>> for line in file("temp2.txt"): print line
...

Bonjour!
 
J

Jeff Epler

This issue was discussed in another recent python-list thread, called
"Writing to stdout and a log file".

My second post includes a patch to Python's "fileobject.c" that made the
code that started that thread work, but for reasons I mentioned in that
post I didn't want to push for inclusion of my patch. I didn't check,
but it will probably allow your code to work too.

If you feel differently, then the thing to do is probably to submit the
patch plus a test case to the sf.net patch tracker for python
(sf.net/projects/python, click on "patches". you'll need a sourceforge
account to submit the patch)

Jeff
PS I did allow the Python test suite to run to completion after I wrote
that message. It didn't produce any failures or unexpected skips on my
platform.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)

iD8DBQFCa89CJd01MZaTXX0RAlm7AJ43s/kOwPqRfcug/I3I1wzqL/QOggCeLzkr
tTXfi52B7wY4Id55oeOuGhk=
=9oYm
-----END PGP SIGNATURE-----
 
P

Pierre Rouleau

Jeff said:
This issue was discussed in another recent python-list thread, called
"Writing to stdout and a log file".

My second post includes a patch to Python's "fileobject.c" that made the
code that started that thread work, but for reasons I mentioned in that
post I didn't want to push for inclusion of my patch. I didn't check,
but it will probably allow your code to work too.

If you feel differently, then the thing to do is probably to submit the
patch plus a test case to the sf.net patch tracker for python
(sf.net/projects/python, click on "patches". you'll need a sourceforge
account to submit the patch)

Jeff
PS I did allow the Python test suite to run to completion after I wrote
that message. It didn't produce any failures or unexpected skips on my
platform.

Thanks. I never got involved in Python development before, so I will
take a look at the development process. I took a quick look at the
affected C files and must confess that I need more time looking at them
to learn everything around it. However, I think that the behaviour of
file handling should change so that any class derived from file should
support the >> operator 'properly' (ie the derived class write() method
should be called).

Pierre
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,236
Messages
2,571,184
Members
47,820
Latest member
HortenseKo

Latest Threads

Top