classification
Title: Inspect.getsource raises wrong error on classes in interactive session
Type: behavior Stage: resolved
Components: Versions: Python 3.11, Python 3.10
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: FFY00, andrei.avk, aroberge, jaraco, lukasz.langa, miss-islington, othmaneelbouri1, pablogsal
Priority: normal Keywords: patch

Created on 2021-07-15 18:31 by andrei.avk, last changed 2021-08-02 09:59 by pablogsal. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 27171 merged andrei.avk, 2021-07-15 20:43
PR 27495 merged miss-islington, 2021-07-30 17:17
PR 27484 FFY00, 2021-07-30 20:05
PR 27436 jaraco, 2021-07-30 20:26
Messages (11)
msg397573 - (view) Author: Andrei Kulakov (andrei.avk) * (Python triager) Date: 2021-07-15 18:31
[ins] In [63]: class A:pass

[ins] In [64]: import inspect

[ins] In [65]: inspect.getsource(A)

[snip]

/usr/local/Cellar/python@3.9/3.9.1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/inspect.py in getfile(object)
    664             if getattr(module, '__file__', None):
    665                 return module.__file__
--> 666         raise TypeError('{!r} is a built-in class'.format(object))

The error is 'X is a built-in class', instead it should be OSError, source code is not available.
msg397629 - (view) Author: Łukasz Langa (lukasz.langa) * (Python committer) Date: 2021-07-16 13:54
Why do you think OSError fits here? Since objects provided on the command line by definition cannot have source code files, the problem isn't that the file is missing or inaccessible. Rather, the value provided to getsource() is wrong. So, in my view, this should rather be ValueError.

Moreover, checking for __main__ is insufficient as there are __main__.py modules after all in many packages.
msg397631 - (view) Author: Andrei Kulakov (andrei.avk) * (Python triager) Date: 2021-07-16 14:55
Łukasz:

Thanks for looking at this!

 - I agree OSError is not ideal, but I chose it because it's consistent with how inspect reports similar errors. For example, see all instances of OSError, except for first, in this function:

https://github.com/python/cpython/blob/7915c96ffd7ddc5cb6d54015ee4c31255a416892/Lib/inspect.py#L930

I think it's an implementation detail that class source is not available on interactive prompt, for example function source is available via `inspect.getsource()`.

If a user can do getsource(func) and getsource(cls) in a file, and getsource(func) on interactive prompt, it seems wrong to return a ValueError when the user is trying to getsource(cls) in interactive.

I'm open to change it to ValueError though because I think the err message here is more important to avoid user confusion.

 - good point about __main__.py files, I didn't remember about them. However they will have the __file__ attribute set, so they will return that right above the check for '__main__' in my patch.

I tested it to make sure:
import inspect
class A: 0
print(inspect.getsource(A))


./python.exe ~/temp/__main__.py                                                 
class A: 0
msg397634 - (view) Author: Andrei Kulakov (andrei.avk) * (Python triager) Date: 2021-07-16 15:16
I'm not sure though how is the unit test succeeding since the test module should have __file__ set. Looking into it..
msg397636 - (view) Author: Andrei Kulakov (andrei.avk) * (Python triager) Date: 2021-07-16 15:38
This is kind of interesting:

 - The unit test was wrong, it was catching the wrong OSError. (I was catching regex first but after some tweaking and changes I lost it and forgot to readd)

 - The reason it was passing is exactly what you pointed out -- the __main__.py in `unittest` package. After I change the class' module to __main__ in the test, it starts looking at sys.modules['__main__'] which is the one in unittest, which doesn't have this class, which causes the inspect to throw another OSError.

 - I fixed the unit test by both checking for error regex and patching sys.modules['__main__'] (and of course restoring it later).

Thanks for helping to catch this :-)
msg398579 - (view) Author: Łukasz Langa (lukasz.langa) * (Python committer) Date: 2021-07-30 17:17
New changeset 48a62559dfaf775e4f1cc56b19379c799e8e2587 by andrei kulakov in branch 'main':
bpo-44648: Fix error type in inspect.getsource() in interactive session (GH-27171)
https://github.com/python/cpython/commit/48a62559dfaf775e4f1cc56b19379c799e8e2587
msg398580 - (view) Author: Łukasz Langa (lukasz.langa) * (Python committer) Date: 2021-07-30 17:19
Since this is an exception type change, I'd feel more comfortable leaving 3.9 out of the backports here. That way it will be easier for application authors to differentiate between when the change was introduced or not.
msg398588 - (view) Author: Othmane EL BOURI (othmaneelbouri1) Date: 2021-07-30 17:40
ince this is an exception type change, I'd feel more comfortable leaving 3.9 out of the backports here. That way it will be easier for application authors to differentiate between when the change was introduced or not.
msg398589 - (view) Author: Łukasz Langa (lukasz.langa) * (Python committer) Date: 2021-07-30 17:46
New changeset f468ede4a2b7ab5c72ae85ab04cb56904300cd23 by Miss Islington (bot) in branch '3.10':
bpo-44648: Fix error type in inspect.getsource() in interactive session (GH-27171) (GH-27495)
https://github.com/python/cpython/commit/f468ede4a2b7ab5c72ae85ab04cb56904300cd23
msg398590 - (view) Author: Łukasz Langa (lukasz.langa) * (Python committer) Date: 2021-07-30 17:47
Thanks, Andrei! ✨ 🍰 ✨
msg398748 - (view) Author: Pablo Galindo Salgado (pablogsal) * (Python committer) Date: 2021-08-02 09:59
Unfortunately, this PR has broken test_inspect when executed with -R, see:

https://bugs.python.org/issue44808
History
Date User Action Args
2021-08-02 09:59:39pablogsalsetnosy: + pablogsal
messages: + msg398748
2021-07-30 20:26:24jaracosetnosy: + jaraco

pull_requests: + pull_request26014
2021-07-30 20:05:34FFY00setnosy: + FFY00

pull_requests: + pull_request26013
2021-07-30 17:47:14lukasz.langasetstatus: open -> closed
resolution: fixed
messages: + msg398590

stage: patch review -> resolved
2021-07-30 17:46:51lukasz.langasetmessages: + msg398589
2021-07-30 17:40:56othmaneelbouri1setnosy: + othmaneelbouri1
messages: + msg398588
2021-07-30 17:20:54lukasz.langasetversions: - Python 3.9
2021-07-30 17:19:30lukasz.langasetmessages: + msg398580
2021-07-30 17:17:55miss-islingtonsetnosy: + miss-islington
pull_requests: + pull_request26011
2021-07-30 17:17:50lukasz.langasetmessages: + msg398579
2021-07-16 15:38:40andrei.avksetmessages: + msg397636
2021-07-16 15:16:39andrei.avksetmessages: + msg397634
2021-07-16 14:55:37andrei.avksetmessages: + msg397631
2021-07-16 13:54:29lukasz.langasetnosy: + lukasz.langa
messages: + msg397629
2021-07-16 08:47:11arobergesetnosy: + aroberge
2021-07-15 20:43:41andrei.avksetkeywords: + patch
stage: patch review
pull_requests: + pull_request25708
2021-07-15 18:31:57andrei.avksetversions: + Python 3.9, Python 3.10
2021-07-15 18:31:38andrei.avkcreate