-
-
Notifications
You must be signed in to change notification settings - Fork 30.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
__module__
is not defined, seeming to contradict the Python Data Model.
#120857
Comments
Have you verified that the test works as expected with the suggested fix? The Data model section, seems to me to suggest that |
Hi @terryjreedy. Thanks for looking at this. I was able to reproduce the problem outside of Jupyter: import unittest
test_str = """
import unittest
class MyTest(unittest.TestCase):
def test_add(self):
self.assertEqual(1+2, 3)
derived = type("DerivedTest", (MyTest,), {})
"""
test_ns = {}
exec(test_str, test_ns)
suite = unittest.TestSuite()
suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(test_ns["derived"]))
runner = unittest.TextTestRunner()
runner.run(suite) I have not tested my fix. Sorry. I'll work on that but, in the meantime, I hope this example helps! |
Here's a simpler test case. You don't need test_str = """
class MyClass:
pass
Derived = type("Derived", (MyClass,), {})
"""
test_ns = {}
exec(test_str, test_ns)
print("__module__ exists:", hasattr(test_ns["Derived"], "__module__"))
print("Module for drived:", test_ns["Derived"].__module__) I agree with what you're saying about the Data Model section of the document. It seems like |
__module__
is not defined. __module__
is not defined, seeming to contradict the Python Data Model.
Maybe it could be useful but However, when you do something like:
then, |
Mmh.. the fix I'm trying to do is a bit tricky. Actually, we have >>> blts = builtins.__dict__.copy()
>>> del blts['__name__']
>>> exec("class A: pass\nB=type('B', (A,), {})", {'__builtins__': blts})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in <module>
File "<string>", line 1, in A
NameError: name '__name__' is not defined @JelleZijlstra What should we do? normally, you can specify your own builtins but if you do so, you'll need the >>> exec("class A: pass\nB=type('B', (A,), {})", ns := {}); ns['B'].__module__
...
AttributeError: __module__. Did you mean: '__reduce__'? and this indeed contradicts the data model. |
Here's a smaller reproducer:
Or similarly:
It is also possible to set
Not sure what to do about this; some options:
|
Yes... I had thought of those options and then I remembered that I needed to take into account the change in Sphinx, which I was not really happy about. In fact, we also have this behaviour: >>> del __name__
>>> class A: pass
...
>>> A.__module__
'builtins' So... does it make sense for |
The reason for that is that inside the class body we inject code that is essentially That behavior feels buggy too, though, and I'd rather not expand it further. Your class |
I think we also had quite a lot of if-branches in Sphinx for this kind of "fake builtins that are not builtins". I've tried a PR where I inject the Maybe having |
The behavior of the module name defaulting to |
Well... I would appreciated we first discuss more in details the directions to take before opening another PR since I've already started working on the issue. While setting (Also, in the future, I think it'd be better not to include the issue inside the commits because the issue noise becomes quite large) |
Sorry, I actually made my first commit 5 hours before yours but didn't push until quite a bit later due to other work, only to realize after submitting my PR that you had also submitted a PR. But then I thought that my solution may co-exist with yours since they fix different parts of the logics.
Good point. Your solution is indeed the safer and more practical route. A quick code search does reveal a lot of existing code that rely on the existing behavior of
Noted. Thanks for the tips. |
No worries! I don't mind when people suggest alternatives but it's better if we don't have two PRs that may do (in the end) the same work.
Actually, when I first implemented the patch on my side, I thought about just putting to |
Bug report
Bug description:
The
__module__
variable might not be defined.This is an update to the original bug post. After some investigation this doesn't seem like a bug in
unittest
. Here's a simple test case that shows a situation where__module__
is not defined:The original bug post is below:
cpython/Lib/unittest/loader.py
Line 220 in 03fa2df
The default test loader depends on
__module__
being present. In rare cases it may not be. I encountered a crash when running unit tests using a Jupyter cell magic. The line should probably be:This problem has cropped up in bug reports for other projects. For example:
ray-project/ray#4758
https://gitlab.orekit.org/orekit-labs/python-wrapper/-/issues/411
Thank you for the wonderful work!
CPython versions tested on:
3.12
Operating systems tested on:
Linux
Linked PRs
__name__
withinexec
#120957The text was updated successfully, but these errors were encountered: