bpo-43951: Two minor fixes for accessing a module's name. #25658
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
While working on another issue, I noticed two minor nits in the C implementation of the module object. Both are related to getting a module's name.
First, the C function
module_dir()
(akamodule.__dir__
) starts by ensuring the module dict is valid. If the module dict is invalid, it wants to format an exception using the name of the module, which it gets fromPyModule_GetName()
. However,PyModule_GetName()
gets the name of the module from the dict. So getting the name in this circumstance will never succeed.When
module_dir()
wants to format the error but can't get the name, it knows thatPyModule_GetName()
must have already raised an exception. So it leaves that exception alone and returns an error. The end result is that the exception raised here is kind of useless and misleading:dir(module)
on a module with no__dict__
raisesSystemError("nameless module")
. I changed the code to actually raise the exception it wanted to raise, just without a real module name:TypeError("<module>.__dict__ is not a dictionary")
. This seems more useful, and would do a better job putting the programmer who encountered this on the right track of figuring out what was going on.Second, the C API function
PyModule_GetNameObject()
checks to see if the module has a dict. Ifm->md_dict
is notNULL
, it calls_PyDict_GetItemIdWithError()
. However, it's possible form->md_dict
to beNone
. And if you call_PyDict_GetItemIdWithError(Py_None, ...)
it will crash.Unfortunately, this crash was due to my own bug in the other branch. Fixing my code made the crash go away. I assert that this is still possible at the API level.
The fix is easy: add a
PyDict_Check()
toPyModule_GetNameObject()
.Unfortunately, I don't know how to add a unit test for this. Having changed
module_dir()
above, I can't find any other interfaces callable from Python that eventually callPyModule_GetNameObject()
. So I don't know how to trick the runtime into reproducing this error.https://bugs.python.org/issue43951