Python subclassing file types
I was hoping to write a simple tee class by subclassing file, but there must be further type magic getting in the way when print >> is used.
import sys
class tee(file):
def write(self, text):
sys.stdout.write(text)
file.write(self, text)
fd = tee("output.txt", "w")
print >> fd, "Test 1"
fd.write("Test 2n")
$ python test.py Test 2 $ cat output.txt Test 1 Test 2
Using the dis module, we can tell that print >> is compiled into PRINT_ITEM_TO.
>>> def t(): print >> fd, "foo"
...
>>> import dis; dis.dis(t)
1 0 LOAD_GLOBAL 0 (fd)
3 DUP_TOP
4 LOAD_CONST 1 ('foo')
7 ROT_TWO
8 PRINT_ITEM_TO
9 PRINT_NEWLINE_TO
10 LOAD_CONST 0 (None)
13 RETURN_VALUE
and looking through ceval.c, searching for PRINT_ITEM_TO yields
case PRINT_ITEM_TO:
w = stream = POP();
/* fall through to PRINT_ITEM */
case PRINT_ITEM:
v = POP();
if (stream == NULL || stream == Py_None) {
w = PySys_GetObject("stdout");
if (w == NULL) {
PyErr_SetString(PyExc_RuntimeError,
"lost sys.stdout");
err = -1;
}
}
/* PyFile_SoftSpace() can exececute arbitrary code
if sys.stdout is an instance with a __getattr__.
If __getattr__ raises an exception, w will
be freed, so we need to prevent that temporarily. */
Py_XINCREF(w);
if (w != NULL && PyFile_SoftSpace(w, 0))
err = PyFile_WriteString(" ", w);
if (err == 0)
err = PyFile_WriteObject(v, w, Py_PRINT_RAW);
Any ideas why?
About this entry
You’re currently reading “ Python subclassing file types ,” an entry on Chui's Counterpoint
- Published:
- 6.3.08 / 10am
- Category:
- Python
2 Comments
Jump to comment form | comments rss [?] | trackback uri [?]