On Mon, Jun 15, 2020 at 7:22 AM Thomas Viehmann < tv.python-dev.python.org@beamnet.de> wrote:
Hello,
thank you for making Python and the neat inspect module.
I would love to hear your opinion on the following aspect of inspect that I believe might be worth improving:
Consider the following program saved in a file (say hello.py):
import inspect
def hello(): print("Hello World") print(inspect.getsource(hello))
class Hello: def __init__(self): print("Hello World") print(inspect.getsource(Hello))
Running hello.py will, unsurprisingly, print the source of hello and Hello.
Now, some of us use an Jupyter (with the capabilities provided by IPython) notebooks, which are a great tool and awesome match with Python. These notebooks can be large and complex enough to want to use introspection on methods defined in itself (also, I'm prototyping things I might want to use as a library in Notebooks a lot, and I think I'm not alone).
IPython enhances the interactive console to enable introspection (by providing "files" for the cells). As a result, the following will work as expected:
def hello(): print("Hello World") print(inspect.getsource(hello))
However, it does not work for classes: class Hello: def __init__(self): print("Hello World") print(inspect.getsource(Hello))
will run into an error in a Jupyter notebook, more precisely
TypeError: <class '__main__.Hello'> is a built-in class
The reason why the latter does not work is because inspect cannot find a source file.
The technical background is that for a function hello, inspect.getfile finds the file through hello.__code__.co_filename which IPython can arrange for, while for the class Hello, it tries `Hello.__module__`, which is `__main__` and then would see if sys.modules[Hello.__module__] has a __file__ attribute, which it does not (and which could not be disambiguated into cell-level).
I once made a PR in github #13894 and earlier https://bugs.python.org/issue33826 but got, let's say, reactions that were not entirely encouraging. I still think that it is a useful feature and I don't think that there are readily available solutions and after another year has passed, I humbly submit this for your considerations.
Best regards and thank you.
Thomas
It would probably help if you didn't bury the lede: You have a languishing bug+PR that would benefit users of Jupyter Notebooks, and you would like some help getting your proposal accepted. The proposal is to add a `__filename__` attribute to classes, and the problem it solves is that currently inspect.getsource() uses the class's `__module__` attribute, which in Jupyter's case points to `__main__` for all classes defined in cells. There can be only one file per module object so Jupyter cannot trick inspect.getsource() into showing the source of the cell containing the class definition (which it manages to do for functions, because of the `__code__.co_filename` attribute). I could think of a trick that inspect.getsource() might use if the class contains at least one method: it could look at a method and try its `__code__.co_filename` attribute (maybe only if the `__file__` attribute for the module found via the class's `__module__` doesn't exist -- I'm sure Jupyter can arrange for that to be the case). But I see how that would be a problem (I can think of plenty of reasons why a class might not have any methods). I do think that your proposal is reasonable, although I wonder what the Jupyter developers think of it. (How closely are you connected to that project?) Hopefully some other core dev will now take pity on you. -- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>