It occurred to me this afternoon (after answering aquestion about creating file objects from file descriptors) that perhaps os.fdopen would be more logically placed someplace else - of course it could also remain as os.fdopen() for whatever deprecation period is warrented.
Perhaps as a class method of the file type, file.fromfd()?
Should I file a feature request for this on sf, or would it be considered too much of a mindless twiddle to bother with?
The latter. If I had to do it over again, your suggestion would make sense; class methods are a good way to provide alternative constructors, and we're doing this e.g. for the new datetime class/module. But having this in the os module, which deals with such low-level file descriptors, still strikes me as a pretty decent place to put it as well, and I don't think it's worth the bother of updating documentation and so on. The social cost of deprecating a feature is pretty high. In general, I'm open to fixing design bugs if keeping the buggy design means forever having to explain a wart to new users, or forever having to debug bad code written because of a misunderstanding perpetuated by the buggy design (like int division). But in this case, I see no compelling reason; explaining how to do this isn't particularly easier or harder one way or the other. Responses to other messages in this thread: [Greg Ewing]
Not all OSes have the notion of a file descriptor, which is probably why it's in the os module.
Perhaps, but note that file objects have a method fileno(), which returns a file descriptor. Its implementation is not #ifdefed in any way -- the C stdio library requires fileno() to exist! Even if fdopen() really did need an #ifdef, it would be just as simple only to have the file.fdopen() class method when the C library defines fdopen() as it is to only have os.fdopen() under those conditions. [Oren Tirosh]
I don't see much point in moving it around just because the place doesn't seem right but the fact that it's a function rather than a method means that some things cannot be done in pure Python.
I can create an uninitialized instance of a subclass of 'file' using file.__new__(filesubclass) but the only way to open it is by name using file.__init__(filesubclassinstance, 'filename'). A file subclass cannot be opened from a file descriptor because fdopen always returns a new instance of 'file'.
If there was some way to open an uninitialized file object from a file descriptor it would be possible, for example, to write a version of popen that returns a subclass of file. It could add a method for retrieving the exit code of the process, do something interesting on __del__, etc.
You have a point, but it's mostly theoretical: anything involving popen() should be done in C anyway, and this is no problem in C.
Here are some alternatives of where this could be implemented, followed by what a Python implementation of os.fdopen would look like:
1. New form of file.__new__ with more arguments:
def fdopen(fd, mode='r', buffering=-1): return file.__new__('(fdopen)', mode, buffering, fd)
This violates the current invariant that __new__ doesn't initialize the file with a C-level FILE *.
2. Optional argument to file.__init__:
def fdopen(fd, mode='r', buffering=-1): return file('(fdopen)', mode, buffering, fd)
3. Instance method (NOT a class method):
def fdopen(fd, mode='r', buffering=-1): f = file.__new__() f.fdopen(fd, mode, buffering, '(fdopen)') return f
Hm, you seem to be implying that it should not be a class method because it should be possible to first create an uninitialized instance with __new__ (possibly of a subclass) and then initialize it separately. Perhaps. But since class methods also work for subclasses, I'm not sure I see the use case for this distinction. In any case I think this should wait until a future redesign of the stdio library, which will probably do some other refactoring (while staying compatible with the existing API). I've checked in some rough ideas in nondist/sandbox/sio/. --Guido van Rossum (home page: http://www.python.org/~guido/)