-
-
Notifications
You must be signed in to change notification settings - Fork 31.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
File object 'name' attribute inconsistent type and not obviously documented #76775
Comments
I stumbled on what I think is an inconsistency in the "name" attribute of file objects. When a file is opened with an existing file descriptor, the "name" attribute is of type int (this from a 3.6.4 session, but it also exists in 2.7): >>> import sys
>>> sys.stderr.name
'<stderr>'
>>> f = open(sys.stderr.fileno())
>>> f.name
2
>>> type(f.name)
<class 'int'> I thought it odd that the standard I/O objects would be blessed with string filenames (despite not representing real filesystem paths), but that files opened by file descriptor would have that file descriptor as their name. I looked in the documentation for open(): https://docs.python.org/3/library/functions.html#open but saw no mention of the "name" attribute at all. In fact, the first argument to open() is called "file", so it's not obvious that the "name" attribute needs to be a copy of that parameter. It seems to me that "name" attributes of open file objects should be of a consistent type, even if they might not represent an actual path in the filesystem. Even if this dual-type behavior is retained, it should be documented. |
Hi Skip, I only tested with the last revision of 2.7 Python 2.7.14+ (heads/2.7:b1a52b1167, Jan 18 2018, 14:53:29)
[GCC 7.2.1 20170915 (Red Hat 7.2.1-2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.stderr.name
'<stderr>'
>>> f = open(sys.stderr.fileno())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: coercing to Unicode: need string or buffer, int found I can't create a file with an int. |
but I can confirm your issue with 3.6.4+ Python 3.6.4+ (heads/3.6:f31c70b0d6, Jan 18 2018, 14:57:01)
[GCC 7.2.1 20170915 (Red Hat 7.2.1-2)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.stderr.name
'<stderr>'
>>> f = open(sys.stderr.fileno())
>>> f.name
2
>>> |
This has been discussed previously. The nature of the 'name' attribute for file objects is not really specified, so I'm not even sure what we would document. Maybe just that it is unspecified. |
Maybe we could add in the documentation. """ |
Apologies for the incomplete report. In 2.7 this anomaly exists in the io.open() function. You are correct, builtin open() in 2.x doesn't support opening by file descriptor. |
I'm not terribly concerned with the end result, only that we wind up with a more consistent system. As I see it, there are two main problems:
Of lesser importance, but still unintuitive, is that the "name" attribute doesn't refer to an actual name in the filesystem. (I realize that the "name" of sys.std{in,out,err} is also meaningless when interpreted as an actual filename, but that ship sailed long ago.) I realize that it might well be infeasible to modify behavior at this point. I do think it important to document the "name" attribute (item #2). After all, it doesn't appear to be obviously private. I live in a Linux-only world, so this workaround in my own code is likely not useful everywhere, but, when I try to convert a builtin file object to an io.TextIOWrapper object using io.open(f.fileno()), I actually do this: io.open("/dev/fd/{}".format(f.fileno()), ...) This gives me a meaningful "name" attribute in that it is a string, and that it names an actual filename. How this might work on systems without "/dev/fd", I don't know, but might be worth thinking about for a couple minutes before dismissing it out-of-hand. |
I believe you are correct that it is too late to modify the existing behavior. Too many programs depend on it. As far as documenting, my point is that it is *not specified* what the name attribute contains. It can contain literally anything, depending on the particular file object involved. Could we document what the open function actually does? That perhaps we could do, since it is likely that other python implementations will want to copy what CPython does in this case. But as you observe, this can also be *system dependent*, so it is not completely clear to me exactly how we should do that. That is, the description of what actually happens could be so complex that it might be better to just say something like "The exact type and value of the name attribute is not specified, but when the file is opened via a file system path it will almost always be that path as a string.". I'd be happy for a better answer, though :) |
Isn't this a duplicate of bpo-18534? |
Ah, yes. When I said "this has been discussed previously", that's the issue I was thinking of but couldn't find. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: