Author: Carl Friedrich Bolz-Tereick <cfb...@gmx.de> Branch: py3.6 Changeset: r96076:b7b3ef736a84 Date: 2019-02-18 21:45 +0100 http://bitbucket.org/pypy/pypy/changeset/b7b3ef736a84/
Log: make sure __import__ is not stored in a celldict cell, otherwise local imports are really slow diff --git a/pypy/interpreter/mixedmodule.py b/pypy/interpreter/mixedmodule.py --- a/pypy/interpreter/mixedmodule.py +++ b/pypy/interpreter/mixedmodule.py @@ -197,6 +197,17 @@ def get__doc__(cls, space): return space.newtext_or_none(cls.__doc__) + def setdictvalue_dont_introduce_cell(self, name, w_value): + """ inofficial interface on MixedModules to override an existing value + in the module but without introducing a cell (in the sense of + celldict.py) for it. Should be used sparingly, since it will trigger a + JIT recompile of all code that uses this module.""" + from pypy.objspace.std.celldict import setdictvalue_dont_introduce_cell + # first do a regular setdictvalue to force the lazy loading + self.setdictvalue(self.space, name, w_value) + # then ask cell dict to remove the cell, and store the value directly + setdictvalue_dont_introduce_cell(self, self.space, name, w_value) + @not_rpython def getinterpevalloader(pkgroot, spec): diff --git a/pypy/module/_frozen_importlib/__init__.py b/pypy/module/_frozen_importlib/__init__.py --- a/pypy/module/_frozen_importlib/__init__.py +++ b/pypy/module/_frozen_importlib/__init__.py @@ -80,7 +80,9 @@ """Copy our __import__ to builtins.""" if not we_are_translated(): self.startup_at_translation_time_only(space) - self.space.builtin.setdictvalue(space, '__import__', self.w_import) + # use special module api to prevent a cell from being introduced + self.space.builtin.setdictvalue_dont_introduce_cell( + '__import__', self.w_import) def startup_at_translation_time_only(self, space): # Issue #2834 diff --git a/pypy/objspace/std/celldict.py b/pypy/objspace/std/celldict.py --- a/pypy/objspace/std/celldict.py +++ b/pypy/objspace/std/celldict.py @@ -186,5 +186,17 @@ def wrapvalue(space, value): return unwrap_cell(space, value) +def setdictvalue_dont_introduce_cell(w_obj, space, name, w_value): + from pypy.objspace.std.dictmultiobject import W_DictMultiObject + w_dict = w_obj.getdict(space) + if isinstance(w_dict, W_DictMultiObject): + strategy = w_dict.get_strategy() + if isinstance(strategy, ModuleDictStrategy): + dict_w = strategy.unerase(w_dict.dstorage) + strategy.mutated() + dict_w[name] = w_value + return + w_obj.setdictvalue(space, name, w_value) + create_iterator_classes(ModuleDictStrategy) diff --git a/pypy/objspace/std/test/test_celldict.py b/pypy/objspace/std/test/test_celldict.py --- a/pypy/objspace/std/test/test_celldict.py +++ b/pypy/objspace/std/test/test_celldict.py @@ -58,6 +58,31 @@ v3 = strategy.version assert v2 is v3 + def test_module_no_cell_interface(self): + from pypy.interpreter.module import Module + w_mod = Module(space, None) + assert isinstance(w_mod.w_dict, W_ModuleDictObject) + + key = "a" + value1 = object() + w_mod.setdictvalue(space, key, value1) + + strategy = w_mod.w_dict.get_strategy() + storage = strategy.unerase(w_mod.w_dict.dstorage) + assert storage["a"] is value1 + + value2 = object() + w_mod.setdictvalue_dont_introduce_cell(key, value2) + assert storage["a"] is value2 + + def test___import__not_a_cell(self): + # _frozen_importlib overrides __import__, which used to introduce a + # cell + w_dict = self.space.builtin.w_dict + storage = w_dict.get_strategy().unerase(w_dict.dstorage) + assert "Cell" not in repr(storage['__import__']) + + class AppTestModuleDict(object): def setup_class(cls): @@ -173,3 +198,4 @@ d[o] = 'baz' assert set(d) == set(['foo', 'λ', o]) assert "ObjectDictStrategy" in __pypy__.internal_repr(d) + _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit