Issue25493
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.
Created on 2015-10-27 16:46 by bevan, last changed 2022-04-11 14:58 by admin. This issue is now closed.
Messages (7) | |||
---|---|---|---|
msg253551 - (view) | Author: Michael Laß (bevan) | Date: 2015-10-27 16:46 | |
When there is a file called "sys" in the local directory of a python script and warning.warn is called with an invalid stacklevel, python tries to import that file and throws an error like the following: >>> import warnings >>> warnings.warn("foo", Warning, stacklevel=2) Traceback (most recent call last): File "/usr/lib/python3.5/tokenize.py", line 392, in find_cookie line_string = line.decode('utf-8') UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 24: invalid start byte During handling of the above exception, another exception occurred: Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python3.5/warnings.py", line 18, in showwarning file.write(formatwarning(message, category, filename, lineno, line)) File "/usr/lib/python3.5/warnings.py", line 26, in formatwarning line = linecache.getline(filename, lineno) if line is None else line File "/usr/lib/python3.5/linecache.py", line 16, in getline lines = getlines(filename, module_globals) File "/usr/lib/python3.5/linecache.py", line 47, in getlines return updatecache(filename, module_globals) File "/usr/lib/python3.5/linecache.py", line 136, in updatecache with tokenize.open(fullname) as fp: File "/usr/lib/python3.5/tokenize.py", line 456, in open encoding, lines = detect_encoding(buffer.readline) File "/usr/lib/python3.5/tokenize.py", line 433, in detect_encoding encoding = find_cookie(first) File "/usr/lib/python3.5/tokenize.py", line 397, in find_cookie raise SyntaxError(msg) SyntaxError: invalid or missing encoding declaration for 'sys' In this case "sys" is a binary that belongs to openafs (/usr/bin/sys) and of course it is no valid python. "import sys" produces no error though, so typically python is able to distinguish between its sys module and this file. A workaround is to run python with the "-I" parameter. Expected output: >>> import warnings >>> warnings.warn("foo", Warning, stacklevel=2) sys:1: Warning: foo This bug was spotted in Gnome's pygobject bindings. Here is the corresponding bug report: https://bugzilla.gnome.org/show_bug.cgi?id=757184 |
|||
msg253553 - (view) | Author: Brett Cannon (brett.cannon) * | Date: 2015-10-27 17:05 | |
I'll have to dig into this to figure out what's going on, but since the sys module is built into Python it makes it so import won't accidentally import some file named sys. the real question is who thinks the 'sys' file should be considered. |
|||
msg253563 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * | Date: 2015-10-27 21:07 | |
The "sys" file is not imported. It is read by linecache. warnings.warn() tries to determine the file name by looking at __file__ in module's globals. If it fails, it falls back to the module name. Definitely it fails also for builtin modules, binary extensions and zipimported modules. |
|||
msg253566 - (view) | Author: R. David Murray (r.david.murray) * | Date: 2015-10-27 21:42 | |
Hmm. I remember fixing problems with linecache and inspect. I wonder if this is a variation on that? I don't remember the issue number. |
|||
msg253764 - (view) | Author: Brett Cannon (brett.cannon) * | Date: 2015-10-30 21:57 | |
So I'm going to close this as "won't fix" because linecache is horribly over-engineered and I'm afraid trying to fix this will break code that actually worked previously. This is obviously an odd edge case that I think we can live with. |
|||
msg254532 - (view) | Author: Christoph Reiter (lazka) * | Date: 2015-11-12 15:00 | |
To add some info why we hit that bug: https://bugs.python.org/issue24305 changed the warning stacklevel needed for import warnings from 8 to 2. As a result any code doing import warnings will likely hit that edge case when run with 3.5 and openafs installed. But I'm not sure if there is much code out there doing import warnings.. so ymmv. For anyone with the same problem looking for a workaround: I went through all Python versions and searched for the needed stacklevel. def get_import_stacklevel(import_hook): """Returns the stacklevel value for warnings.warn() for when the warning gets emitted by an imported module, but the warning should point at the code doing the import. Pass import_hook=True if the warning gets generated by an import hook (warn() gets called in load_module(), see PEP302) """ py_version = sys.version_info[:2] if py_version <= (3, 2): # 2.7 included return 4 if import_hook else 2 elif py_version == (3, 3): return 8 if import_hook else 10 elif py_version == (3, 4): return 10 if import_hook else 8 else: # fixed again in 3.5+, see https://bugs.python.org/issue24305 return 4 if import_hook else 2 |
|||
msg256165 - (view) | Author: John Mark Vandenberg (jayvdb) * | Date: 2015-12-10 06:00 | |
It seems like there is already sufficient detection of invalid stack levels in warnings.warn, and one of the code paths does `module = "<string>"` and later another does `filename = module`, so `filename` can be intentionally junk data, which will be passed to `linecache`. I expect this could be satisfactorily resolved by warn() setting filename = '<invalid stacklevel>', and `formatwarning` not invoking linecache when the filename is '<string>', '<invalid stacklevel>', etc., or at least ignoring the exception from linecache when the filename is <foo>. Looking forward, why not let Python 3.6 warn() behave 'better' when the stacklevel is invalid. e.g. it could raise ValueError (ouch, but 'correct'), or it could reset the stacklevel to 1 (a sensible fallback) and issue an auxillary SyntaxWarning to inform everyone that the stacklevel requested was incorrect. |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-11 14:58:23 | admin | set | github: 69679 |
2015-12-10 06:00:22 | jayvdb | set | nosy:
+ jayvdb messages: + msg256165 |
2015-11-12 15:00:32 | lazka | set | nosy:
+ lazka messages: + msg254532 |
2015-10-30 21:57:18 | brett.cannon | set | status: open -> closed resolution: wont fix messages: + msg253764 |
2015-10-27 21:42:57 | r.david.murray | set | nosy:
+ r.david.murray messages: + msg253566 |
2015-10-27 21:07:41 | serhiy.storchaka | set | nosy:
+ serhiy.storchaka messages: + msg253563 |
2015-10-27 17:34:26 | Arfrever | set | nosy:
+ Arfrever |
2015-10-27 17:05:48 | brett.cannon | set | assignee: brett.cannon messages: + msg253553 |
2015-10-27 16:58:06 | r.david.murray | set | nosy:
+ brett.cannon |
2015-10-27 16:46:01 | bevan | create |