msg143645 - (view) |
Author: PCManticore (Claudiu.Popa) * |
Date: 2011-09-06 18:37 |
inspect.getsource called with a class defined in the same file fails with
TypeError: <module '__main__' (built-in)> is a built-in class, although the documentation says that:
"The argument may be a module, class, method, function, traceback, frame,
or code object. The source code is returned as a single string." I think that should be specified in documentation that this function works only for objects living in a module.
|
msg143773 - (view) |
Author: Éric Araujo (eric.araujo) * |
Date: 2011-09-09 17:16 |
> inspect.getsource called with a class defined in the same file fails
> with TypeError: <module '__main__' (built-in)> is a built-in class
The error message makes me think that getsource(__main__) was used, not getsource(SomeClass). Can you check again?
|
msg143790 - (view) |
Author: PCManticore (Claudiu.Popa) * |
Date: 2011-09-09 18:59 |
Yes. On Python 3.2 (r32:88445, Feb 20 2011, 21:29:02) [MSC v.1500 32 bit (Intel)] on win32, the result for the following lines:
import inspect
class A:
pass
inspect.getsource(A)
is:
Traceback (most recent call last):
File "E:/Scripts/Snippets/test_inspect_bug.py", line 4, in <module>
inspect.getsource(A)
File "C:\Python32\lib\inspect.py", line 694, in getsource
lines, lnum = getsourcelines(object)
File "C:\Python32\lib\inspect.py", line 683, in getsourcelines
lines, lnum = findsource(object)
File "C:\Python32\lib\inspect.py", line 522, in findsource
file = getsourcefile(object)
File "C:\Python32\lib\inspect.py", line 441, in getsourcefile
filename = getfile(object)
File "C:\Python32\lib\inspect.py", line 406, in getfile
raise TypeError('{!r} is a built-in class'.format(object))
TypeError: <module '__main__' (built-in)> is a built-in class
>>>
|
msg143831 - (view) |
Author: PCManticore (Claudiu.Popa) * |
Date: 2011-09-10 06:45 |
I forgot to mention that I executed this code directly in IDLE. It seems to work perfectly on command line though.
|
msg185179 - (view) |
Author: Éric Araujo (eric.araujo) * |
Date: 2013-03-25 02:54 |
> It seems to work perfectly on command line though.
If the code is saved in a file, yes, but not in an interactive interpreter. This is not actually related to IDLE, but to the fact that inspect.getsource merely finds the __file__ attribute of the module object for its argument. If a module object has no file, the error message indicates that it’s a built-in module (like sys), but this fails to take into account the special __main__ module in an interactive interpreter.
It might be worth it to improve the error message, and in any case the documentation can be improved.
|
msg245714 - (view) |
Author: Ned Deily (ned.deily) * |
Date: 2015-06-24 04:04 |
In duplicate Issue24491, zorceta notes: "Both python.exe and IDLE can't. IPython is able to, as it inserts REPL input into linecache."
|
msg245721 - (view) |
Author: Zorceta (zorceta) |
Date: 2015-06-24 05:45 |
When provided object is not from a file, like input in interactive shell, `inspect` internals will check for it in `linecache`, which official Python shell and IDLE won't put interactive shell input into, yet. This can be simply solved.
Whether interactive shell input can be put into `linecache` may be a problem, but it'll make life easier, as interactive shell saves time from edit-save-run 'loop'.
btw, I changed the title, since I don't think, what original author thought need to be documented, is absolutely right.
|
msg245723 - (view) |
Author: Zorceta (zorceta) |
Date: 2015-06-24 06:05 |
> When provided object is not from a file
should be
'When `inspect` can't find the source file of provided object'.
My mistake.
|
msg252846 - (view) |
Author: (nikitakit) |
Date: 2015-10-12 06:33 |
I just ran into this issue trying to introspect an IPython session, in which case the __main__ module doesn't have a file associated with it.
But it turns out that methods defined in a class do have source code associated with them, so it's possible to add a workaround for the common case where a class actually has methods.
Code: https://gist.github.com/nikitakit/642cb96febdf2f812d0b
|
msg265815 - (view) |
Author: Steven Barker (Steven.Barker) * |
Date: 2016-05-18 06:45 |
The problem being discussed here just came up on Stack Overflow today: http://stackoverflow.com/questions/37288135/inspect-module-for-python/
The cause of the incorrect error message is pretty clear. The relevant code from `inspect.getfile` should do something better when the object has a `__module__` attribute, but the module named (when looked up in `sys.modules`) does not have a `__file__` attribute. Currently it says the module is a builtin class, which is total nonsense.
A very basic fix would be to have an extra error case:
if isclass(object):
if hasattr(object, '__module__'):
object = sys.modules.get(object.__module__)
if hasattr(object, '__file__'):
return object.__file__
raise TypeError() # need a relevant message here!!!
raise TypeError('{!r} is a built-in class'.format(object))
It might be easier to make a meaningful message if the code after the first `if` didn't overwrite `object` with the module.
But, really, it would be nice to figure out a better fix, which would make the relevant inspect functions actually work for classes defined interactively in the `__main__` module.
|
msg297768 - (view) |
Author: Vitor Pereira (vmsp) * |
Date: 2017-07-05 15:25 |
So, what would be the right approach here? Store the interactive session's input text in memory?
|
msg297797 - (view) |
Author: R. David Murray (r.david.murray) * |
Date: 2017-07-06 04:04 |
Probably. Figure out a protocol to inject them into linecache, perhaps. But I'm not sure such a thing would be accepted. If you can figure out a way to make it work at least theoretically, it would probably be best to talk about it on python-ideas first.
In the meantime it would be nice to improve the error message, which is what we should use this issue for.
|
msg328836 - (view) |
Author: Ivan Pozdeev (Ivan.Pozdeev) * |
Date: 2018-10-29 15:02 |
See https://bugs.python.org/issue33826?@ok_message=msg%20328824%20created%0Aissue%2033826%20message_count%2C%20messages%20edited%20ok&@template=item#msg319692 how IPython stores source from interactive input and why it's not appropriate for vanilla REPL IMO.
|
msg331659 - (view) |
Author: Terry J. Reedy (terry.reedy) * |
Date: 2018-12-11 22:23 |
Do we really need to say that getsource(object) can only get the object's source if it is accessible from the object? Getsource also fails if a module is loaded from a .pyc with not corresponding .py available.
The problem is not the call being in __main__. When I put the three lines (with the 3rd wrapped with print()) in an IDLE editor and run, and re-inspect, I get
======================== RESTART: F:\Python\a\tem3.py ========================
class A:
pass
>>> inspect.getsource(A)
'class A:\n pass\n'
Ditto if I run > py -i -m a.tem3
If I continue in IDLE's Shell
>>> class B: pass
>>> inspect.getsource(B)
Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module>
inspect.getsource(B)
File "F:\dev\37\lib\inspect.py", line 973, in getsource
lines, lnum = getsourcelines(object)
File "F:\dev\37\lib\inspect.py", line 955, in getsourcelines
lines, lnum = findsource(object)
File "F:\dev\37\lib\inspect.py", line 812, in findsource
raise OSError('could not find class definition')
OSError: could not find class definition
If I enter the three lines above in a fress python or IDLEs shell, I get the TypeError above.
IDLE does store interactive inputs into linecache, so that tracebacks contain the offending line (unlike interactive python). But it does so on a statement by statement basis, so that each entry is treated as a separate file. In a traceback for an exception in a multiline statement, the line number is relative to the statement.
>>> def f():
# line2 of f
1/0
>>> f()
Traceback (most recent call last):
File "<pyshell#13>", line 1, in <module>
f()
File "<pyshell#12>", line 3, in f
1/0
ZeroDivisionError: division by zero
Interactive python displays '<stdin>' as the file for all entries. IDLE numbers them, so previous statements remained cached. I consider enhanced interactive tracebacks to be an important feature.
But I don't see how to attach individual pseudofile names to classes and functions so that getsource could find their source lines.
|
msg382107 - (view) |
Author: Alexey Volkov (Ark-kun) |
Date: 2020-11-30 02:13 |
This is also an issue even for non-interactive scenarios:
When doing `python -c '<some code>'` inspect.getsource does not work and there are no stack traces.
Perhaps this case will be easier to fix?
|
|
Date |
User |
Action |
Args |
2022-04-11 14:57:21 | admin | set | github: 57129 |
2020-11-30 02:13:01 | Ark-kun | set | nosy:
+ Ark-kun messages:
+ msg382107
|
2018-12-11 22:23:06 | terry.reedy | set | nosy:
+ terry.reedy
messages:
+ msg331659 versions:
+ Python 3.7, Python 3.8, - Python 2.7, Python 3.4, Python 3.5, Python 3.6 |
2018-10-29 15:02:29 | Ivan.Pozdeev | set | nosy:
+ Ivan.Pozdeev messages:
+ msg328836
|
2017-07-06 04:04:18 | r.david.murray | set | nosy:
+ r.david.murray messages:
+ msg297797
|
2017-07-05 15:25:22 | vmsp | set | nosy:
+ vmsp messages:
+ msg297768
|
2016-05-18 06:45:42 | Steven.Barker | set | nosy:
+ Steven.Barker messages:
+ msg265815
|
2015-10-12 06:33:34 | nikitakit | set | nosy:
+ nikitakit messages:
+ msg252846
|
2015-06-24 06:05:03 | zorceta | set | messages:
+ msg245723 |
2015-06-24 05:46:58 | zorceta | set | nosy:
- docs@python
|
2015-06-24 05:46:38 | zorceta | set | components:
+ IDLE, Interpreter Core, - Documentation |
2015-06-24 05:45:05 | zorceta | set | messages:
+ msg245721 title: Document that inspect.getsource only works for objects loaded from files, not interactive session -> inspect.getsource only works for objects loaded from files, not interactive session |
2015-06-24 04:04:41 | ned.deily | link | issue24491 superseder |
2015-06-24 04:04:29 | ned.deily | set | nosy:
+ ned.deily, zorceta
messages:
+ msg245714 versions:
+ Python 3.5, Python 3.6, - Python 3.2, Python 3.3 |
2013-03-25 02:54:47 | eric.araujo | set | title: inspect.getsource fails to get source of local classes -> Document that inspect.getsource only works for objects loaded from files, not interactive session stage: needs patch messages:
+ msg185179 versions:
+ Python 3.4 |
2013-03-24 00:40:58 | Naddiseo | set | nosy:
+ Naddiseo
|
2011-09-10 06:45:37 | Claudiu.Popa | set | messages:
+ msg143831 |
2011-09-09 18:59:58 | Claudiu.Popa | set | messages:
+ msg143790 |
2011-09-09 17:16:18 | eric.araujo | set | nosy:
+ eric.araujo title: Inspect.getsource fails to get source of local classes -> inspect.getsource fails to get source of local classes messages:
+ msg143773
versions:
- Python 3.1 |
2011-09-06 18:37:57 | Claudiu.Popa | create | |