Skip to content
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

Conversation

ericsnowcurrently
Copy link
Member

@ericsnowcurrently ericsnowcurrently commented May 17, 2017

@mention-bot
Copy link

@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.

@ericsnowcurrently
Copy link
Member Author

@ncoghlan

Copy link
Member

@vstinner vstinner left a 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.

@@ -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*,
Copy link
Member

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().

Copy link
Member Author

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)
Copy link
Member

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.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point.

Copy link
Member Author

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) {
Copy link
Member

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 :-)

@ericsnowcurrently ericsnowcurrently force-pushed the remove-modules-from-interpreter-state branch from b073e48 to 1c472f7 Compare May 20, 2017 06:42
@@ -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.
Copy link
Member

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?

Copy link
Member

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.

Copy link
Member Author

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.

Copy link
Member

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.

Copy link
Member Author

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.

Copy link
Member

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.

@@ -28,7 +28,6 @@ typedef struct _is {
struct _is *next;
struct _ts *tstate_head;

PyObject *modules;
Copy link
Member

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.

Copy link
Member

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.

@serhiy-storchaka serhiy-storchaka self-requested a review May 22, 2017 11:19
Python/import.c Outdated
return NULL;
}
if (PyDict_Check(modules))
return PyDict_GetItemWithError(modules, name);
Copy link
Member

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.

Copy link
Member Author

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.

Copy link
Member

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.

Copy link
Member Author

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;
Copy link
Member

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?

Copy link
Member Author

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);
Copy link
Member

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()?

Copy link
Member Author

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().

@ericsnowcurrently ericsnowcurrently force-pushed the remove-modules-from-interpreter-state branch 3 times, most recently from b7d3895 to 19388d4 Compare May 25, 2017 18:31
@ericsnowcurrently
Copy link
Member Author

I didn't expect the Spanish Inquisition!

@bedevere-bot
Copy link

Nobody expects the Spanish Inquisition!

@Haypo, @serhiy-storchaka: please review the changes made to this pull request.

@pitrou
Copy link
Member

pitrou commented Sep 4, 2017

Actually, I did.

Copy link
Member

@vstinner vstinner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ericsnowcurrently ericsnowcurrently merged commit 86b7afd into python:master Sep 4, 2017
@ericsnowcurrently ericsnowcurrently deleted the remove-modules-from-interpreter-state branch September 4, 2017 23:54
jimmylai pushed a commit to jimmylai/cpython that referenced this pull request Sep 5, 2017
* '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)
  ...
GadgetSteve pushed a commit to GadgetSteve/cpython that referenced this pull request Sep 10, 2017
@ericsnowcurrently ericsnowcurrently restored the remove-modules-from-interpreter-state branch September 14, 2017 06:04
ericsnowcurrently added a commit to ericsnowcurrently/cpython that referenced this pull request Sep 14, 2017
ericsnowcurrently added a commit that referenced this pull request Sep 14, 2017
…3565)

PR #1638, for bpo-28411, causes problems in some (very) edge cases. Until that gets sorted out, we're reverting the merge. PR #3506, a fix on top of #1638, is also getting reverted.
ericsnowcurrently added a commit to ericsnowcurrently/cpython that referenced this pull request Sep 14, 2017
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.
@hroncok
Copy link
Contributor

hroncok commented May 11, 2018

Maybe just mention the change in https://docs.python.org/dev/whatsnew/3.7.html#porting-to-python-3-7

What this ever put there? I've juts been bit by the changed API of _PyImport_FixupBuiltin (in gdb).

https://bugzilla.redhat.com/show_bug.cgi?id=1577396

@vstinner
Copy link
Member

@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 :-(

@hroncok
Copy link
Contributor

hroncok commented May 12, 2018

Sure, i was just checking. Here it is: https://bugs.python.org/issue33470

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants