This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: File object 'name' attribute inconsistent type and not obviously documented
Type: behavior Stage: resolved
Components: Documentation, Interpreter Core, IO Versions: Python 3.8, Python 3.7, Python 3.6
process
Status: closed Resolution: duplicate
Dependencies: Superseder: [doc] State clearly that open() 'file' param is "name" attr of the result
View: 18534
Assigned To: docs@python Nosy List: docs@python, matrixise, r.david.murray, serhiy.storchaka, skip.montanaro
Priority: normal Keywords:

Created on 2018-01-18 13:51 by skip.montanaro, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (10)
msg310237 - (view) Author: Skip Montanaro (skip.montanaro) * (Python triager) Date: 2018-01-18 13:51
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.
msg310238 - (view) Author: Stéphane Wirtel (matrixise) * (Python committer) Date: 2018-01-18 13:55
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.
msg310239 - (view) Author: Stéphane Wirtel (matrixise) * (Python committer) Date: 2018-01-18 13:58
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
>>>
msg310244 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2018-01-18 14:53
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.
msg310247 - (view) Author: Stéphane Wirtel (matrixise) * (Python committer) Date: 2018-01-18 15:32
Maybe we could add in the documentation.

"""
if we use a file descriptor as the parameter, the name of the returned file object will be the file descriptor itself.
"""
msg310248 - (view) Author: Skip Montanaro (skip.montanaro) * (Python triager) Date: 2018-01-18 15:51
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.
msg310249 - (view) Author: Skip Montanaro (skip.montanaro) * (Python triager) Date: 2018-01-18 16:01
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:

1. The type of the name attribute varies

2. The name attribute appears to be undocumented, at least not in the obvious place.

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.
msg310251 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2018-01-18 18:15
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 :)
msg310350 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2018-01-20 14:52
Isn't this a duplicate of issue18534?
msg310352 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2018-01-20 15:09
Ah, yes.  When I said "this has been discussed previously", that's the issue I was thinking of but couldn't find.
History
Date User Action Args
2022-04-11 14:58:56adminsetgithub: 76775
2018-01-20 15:09:21r.david.murraysetstatus: open -> closed
superseder: [doc] State clearly that open() 'file' param is "name" attr of the result
messages: + msg310352

resolution: duplicate
stage: resolved
2018-01-20 14:52:22serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg310350
2018-01-18 18:15:39r.david.murraysetmessages: + msg310251
2018-01-18 16:01:06skip.montanarosetmessages: + msg310249
2018-01-18 15:51:10skip.montanarosetmessages: + msg310248
2018-01-18 15:32:05matrixisesetmessages: + msg310247
2018-01-18 14:53:26r.david.murraysetnosy: + r.david.murray
messages: + msg310244
2018-01-18 13:58:33matrixisesetversions: - Python 2.7
2018-01-18 13:58:11matrixisesetmessages: + msg310239
2018-01-18 13:55:49matrixisesetnosy: + matrixise
messages: + msg310238
2018-01-18 13:51:34skip.montanarocreate