-
-
Notifications
You must be signed in to change notification settings - Fork 31.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
bpo-28411: Remove "modules" field from Py_InterpreterState. #1638
bpo-28411: Remove "modules" field from Py_InterpreterState. #1638
Conversation
@ericsnowcurrently, thanks for your PR! By analyzing the history of the files in this pull request, we identified @brettcannon, @serhiy-storchaka and @tim-one to be potential reviewers. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the overall change. I don't expect any major performance slowdown.
I just have a few suggestions on the implementation.
Include/modsupport.h
Outdated
@@ -194,6 +194,10 @@ PyAPI_FUNC(int) PyModule_ExecDef(PyObject *module, PyModuleDef *def); | |||
|
|||
PyAPI_FUNC(PyObject *) PyModule_Create2(struct PyModuleDef*, | |||
int apiver); | |||
#ifndef Py_LIMITED_API | |||
PyAPI_FUNC(PyObject *) _PyModule_Create2(struct PyModuleDef*, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest to name _PyModule_CreateInitialized().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point.
Python/import.c
Outdated
example, see issue #4236 and PyModule_Create2(). */ | ||
|
||
void | ||
_PyImport_EnsureInitialized(PyInterpreterState *interp) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a big fan of functions calling Py_FatalError(). I suggest to return an integer and call Py_FatalError() in the caller. Rename the function to _PyImport_IsInitialized().
Or... maybe use PyDict_GetItemWithError()? :-) I'm lost in all these "Get" functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consolidating direct usage of sys.modules ended up being more work than expected. However, I think it's worth it.
Python/import.c
Outdated
goto error; | ||
else { | ||
PyObject *modules = PyImport_GetModuleDict(); | ||
if (PyDict_GetItem(modules, package) == NULL) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add a private helper function to PyDict_GetItem(PyImport_GetModuleDict)? I ask because in another function PyMapping_GetItemString() is used. I don't know which one is correct :-)
b073e48
to
1c472f7
Compare
Doc/c-api/import.rst
Outdated
@@ -204,6 +204,11 @@ Importing Modules | |||
Return the dictionary used for the module administration (a.k.a. | |||
``sys.modules``). Note that this is a per-interpreter variable. | |||
|
|||
.. c:function:: PyObject* PyImport_GetModule(PyObject *name) | |||
|
|||
Return the already imported module with the given name. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if the module is not found?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems this function returns a borrowed reference. This should be specially emphasized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It shouldn't be returning a borrowed reference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only code that uses it (_pickle_Unpickler_find_class_impl
) is written as PyImport_GetModule
returning a borrowed reference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That was an omission on my part. I should have moved the Py_DECREF(module) line down.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should document that the function returns NULL if the module is not already imported, but raise an exception and return NULL on exception. I don't think that it's obvious from the current doc.
Include/pystate.h
Outdated
@@ -28,7 +28,6 @@ typedef struct _is { | |||
struct _is *next; | |||
struct _ts *tstate_head; | |||
|
|||
PyObject *modules; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we can remove a field in the middle of the struct, as that would break the stable ABI (perhaps @zooba can confirm). Instead probably replace it with void *_unused
or something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This structure is not a part of the stable ABI.
Python/import.c
Outdated
return NULL; | ||
} | ||
if (PyDict_Check(modules)) | ||
return PyDict_GetItemWithError(modules, name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This returns a borrowed reference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unlike PyDict_GetItem() and PyDict_GetItemString(), PyDict_GetItemWithError() does not return a borrowed reference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, the documentation does not indicate it returns a borrowed reference. However, looking at the implementation indicates it is a borrowed reference. Thanks for catching that. I'll make a separate PR to fix the docs.
Python/import.c
Outdated
PyObject *m = PyObject_GetItem(modules, name); | ||
if (PyErr_Occurred() && !PyMapping_HasKey(modules, name)) | ||
PyErr_Clear(); | ||
return m; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But this returns an owned reference.
Is there a need to support non-dicts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, part of the point here is to support arbitrary mappings (anything you might assign to sys.modules).
Python/import.c
Outdated
PyImport_GetModule(PyObject *name) | ||
{ | ||
_Py_IDENTIFIER(modules); | ||
PyObject *modules = _PySys_GetObjectId(&PyId_modules); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use just PyImport_GetModuleDict()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was following some precedent. However, there isn't a strong argument either way. I'm fine with changing it to PyImport_GetModuleDict().
b7d3895
to
19388d4
Compare
I didn't expect the Spanish Inquisition! |
Nobody expects the Spanish Inquisition! @Haypo, @serhiy-storchaka: please review the changes made to this pull request. |
Actually, I did. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Maybe just mention the change in https://docs.python.org/dev/whatsnew/3.7.html#porting-to-python-3-7
* 'master' of https://github.com/python/cpython: (32 commits) Conceptually, roots is a set. Also searching it as a set is a tiny bit faster (python#3338) bpo-31343: Include sys/sysmacros.h (python#3318) bpo-30102: Call OPENSSL_add_all_algorithms_noconf (python#3112) Prevent a few make suspicious warnings. (python#3341) Include additional changes to support blurbified NEWS (python#3340) Simplify NEWS entry to prevent suspicious warnings. (python#3339) bpo-31347: _PyObject_FastCall_Prepend: do not call memcpy if args might not be null (python#3329) Revert "bpo-17852: Maintain a list of BufferedWriter objects. Flush them on exit. (python#1908)" (python#3337) bpo-17852: Maintain a list of BufferedWriter objects. Flush them on exit. (python#1908) Fix terminology in comment and add more design rationale. (python#3335) Add comment to explain the implications of not sorting keywords (python#3331) bpo-31170: Update libexpat from 2.2.3 to 2.2.4 (python#3315) bpo-28411: Remove "modules" field from Py_InterpreterState. (python#1638) random_triangular: sqrt() is more accurate than **0.5 (python#3317) Travis: use ccache (python#3307) remove IRIX support (closes bpo-31341) (python#3310) Code clean-up. Remove unnecessary pre-increment before the loop starts. (python#3312) Regen Moduls/clinic/_ssl.c.h (pythonGH-3320) bpo-30502: Fix handling of long oids in ssl. (python#2909) Cache externals, depending on changes to PCbuild (python#3308) ...
…ython#1638)" This reverts commit 86b7afd.
A bunch of code currently uses PyInterpreterState.modules directly instead of PyImport_GetModuleDict(). This complicates efforts to make changes relative to sys.modules. This patch switches to using PyImport_GetModuleDict() uniformly. Also, a number of related uses of sys.modules are updated for uniformity for the same reason. Note that this code was already reviewed and merged as part of python#1638. I reverted that and am now splitting it up into more focused parts.
What this ever put there? I've juts been bit by the changed API of _PyImport_FixupBuiltin (in gdb). |
@hroncok: Would you mind to open a new issue at bugs.python.org? This PR has been closed since last September, so people will unlikely notice your comment :-( |
Sure, i was just checking. Here it is: https://bugs.python.org/issue33470 |
(see http://bugs.python.org/issue28411)
https://bugs.python.org/issue28411