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: `site.abs__file__` fails for modules where `__file__` cannot be modified
Type: behavior Stage: test needed
Components: Library (Lib) Versions: Python 3.7, Python 3.6, Python 2.7
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Alexander McFarlane, eric.smith, terry.reedy
Priority: normal Keywords:

Created on 2017-10-16 10:55 by Alexander McFarlane, last changed 2022-04-11 14:58 by admin.

Messages (4)
msg304466 - (view) Author: Alexander McFarlane (Alexander McFarlane) Date: 2017-10-16 11:00
The pythonnet module clr causes a TypeError when `abs__file__` attempts to run the following line:

`m.__file__ = os.path.abspath(m.__file__)`

Reproduction:

```
import clr
cls.__file__ = 'example'
```
msg304550 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2017-10-18 01:43
I don't have clr installed in order to test this. It would be good if you could produce it without us having to install additional software.

Could you please copy the entire stack traceback you get when this error occurs?

Does this error happen on 3.6, too?
msg304669 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2017-10-20 18:34
2.7 site module has

def abs__file__():
    """Set all module' __file__ attribute to an absolute path"""
    for m in sys.modules.values():
        if hasattr(m, '__loader__'):
            continue   # don't mess with a PEP 302-supplied __file__
        try:
            m.__file__ = os.path.abspath(m.__file__)
        except (AttributeError, OSError):
            pass

This code assumes that if an object [not coded in python] has read-only attributes, so that the attempt to write would raise TypeError, then it do not have .__file__, so there will be an AttributeError, and there will not be a TypeError to catch.  This is true of CPython builtins.

>>> list.__file__
Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    list.__file__
AttributeError: type object 'list' has no attribute '__file__'

>>> list.__file__ = ''
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    list.__file__ = ''
TypeError: can't set attributes of built-in/extension type 'list'

On the other hand, C-coded _tkinter has a re-writable .__file__. 
>>> import _tkinter
>>> _tkinter.__file__
'C:\\Programs\\Python27\\DLLs\\_tkinter.pyd'
>>> _tkinter.__file__ = ''

From the minimal information given, it appears that clr defies this expectation by having an unwritable .__file__ attribute.  Hence the TypeError in abs_file.  Unless a read_only .__file__ is somewhere documented as prohibited, the bug seems to be not including TypeError in the exception tuple.

In 3.x, abs__file__ became abs_paths.  It has the same line with the same problem.
msg304670 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2017-10-20 18:41
2.7 site module has

def abs__file__():
    """Set all module' __file__ attribute to an absolute path"""
    for m in sys.modules.values():
        if hasattr(m, '__loader__'):
            continue   # don't mess with a PEP 302-supplied __file__
        try:
            m.__file__ = os.path.abspath(m.__file__)
        except (AttributeError, OSError):
            pass

This code assumes that if an object [not coded in python] has read-only attributes, so that the attempt to write would raise TypeError, then it do not have .__file__, so there will be an AttributeError, and there will not be a TypeError to catch.  This is true of CPython builtins.

>>> list.__file__
Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    list.__file__
AttributeError: type object 'list' has no attribute '__file__'

>>> list.__file__ = ''
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    list.__file__ = ''
TypeError: can't set attributes of built-in/extension type 'list'

On the other hand, C-coded _tkinter has a re-writable .__file__. 
>>> import _tkinter
>>> _tkinter.__file__
'C:\\Programs\\Python27\\DLLs\\_tkinter.pyd'
>>> _tkinter.__file__ = ''

From the minimal information given, it appears that clr defies this expectation by having an unwritable .__file__ attribute.  Hence the TypeError in abs_file.  Unless a read_only .__file__ is somewhere documented as prohibited, the bug seems to be not including TypeError in the exception tuple.

In 3.x, abs__file__ became abs_paths.  It has the same line with the same problem.

For testing, perhaps an instance of this in sys.modules would work.

class UnsettableFile:
    def __getattr__(self, name):
        return __file__
    def __setattr__(self, name, value):
        raise TypeError()
History
Date User Action Args
2022-04-11 14:58:53adminsetgithub: 75979
2017-10-20 18:41:48terry.reedysetstatus: open

messages: + msg304670
nosy: terry.reedy, eric.smith, Alexander McFarlane
stage: needs patch -> test needed
2017-10-20 18:34:56terry.reedysetstatus: open -> (no value)

type: crash -> behavior
versions: + Python 3.6, Python 3.7
nosy: + terry.reedy

messages: + msg304669
stage: needs patch
2017-10-18 01:43:52eric.smithsetnosy: + eric.smith
messages: + msg304550
2017-10-16 11:02:46Alexander McFarlanesettitle: "abs__file__" in "Lib/site.py" fails for modules where "__file__" cannot be assigned a new value -> `site.abs__file__` fails for modules where `__file__` cannot be modified
2017-10-16 11:00:34Alexander McFarlanesettype: crash
2017-10-16 11:00:16Alexander McFarlanesetversions: + Python 2.7
messages: + msg304466
components: + Library (Lib)
title: abs__file__ in "Lib/site.py" -> "abs__file__" in "Lib/site.py" fails for modules where "__file__" cannot be assigned a new value
2017-10-16 10:55:47Alexander McFarlanecreate