Skip to content

Commit 700ed74

Browse files
committed
fix __graalpython__ builtins for loading delegate module attributes lazily
1 parent 9448b19 commit 700ed74

File tree

2 files changed

+46
-27
lines changed

2 files changed

+46
-27
lines changed

graalpython/lib-graalpython/__graalpython__.py

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -37,46 +37,63 @@
3737
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3838
# SOFTWARE.
3939

40+
import sys
41+
4042

4143
@builtin
42-
def import_current_as_named_module(module_name, globals):
44+
def import_current_as_named_module(name, owner_globals=None):
4345
"""
4446
load a builtin anonymous module which does not have a Truffle land builtin module counter part
4547
46-
:param module_name: the module name to load as
47-
:param globals: the module globals (to update)
48-
:return: None
48+
:param name: the module name to load as
49+
:param owner_globals: the module globals (to update)
50+
:return: the loaded module
4951
"""
50-
import sys
51-
module = sys.modules.get(module_name, None)
52+
if owner_globals is None:
53+
owner_globals = {}
54+
55+
module = sys.modules.get(name, None)
5256
if not module:
53-
module = type(sys)(module_name)
54-
sys.modules[module_name] = module
55-
new_globals = dict(**globals)
57+
module = type(sys)(name)
58+
sys.modules[name] = module
59+
new_globals = dict(**owner_globals)
5660
new_globals.update(**module.__dict__)
5761
module.__dict__.update(**new_globals)
62+
return module
5863

5964

6065
@builtin
61-
def lazy_attribute_loading_from_module(attributes, module_name, globals):
66+
def lazy_attributes_from_delegate(delegate_name, attributes, owner_module):
6267
"""
6368
used to lazily load attributes defined in another module via the __getattr__ mechanism.
6469
This will only cache the attributes in the caller module.
6570
71+
:param delegate_name: the delegate module
6672
:param attributes: a list of attributes names to be loaded lazily from the delagate module
67-
:param module_name: the delegate module
68-
:param globals: the module globals (to update)
73+
:param owner_module: the owner module (where this is called from)
6974
:return:
7075
"""
71-
def __getattr__(name):
72-
if name in attributes:
73-
delegate_module = __import__(module_name)
74-
globals.update(delegate_module.__dict__)
75-
globals['__all__'] = attributes
76-
if '__getattr__' in globals:
77-
del globals['__getattr__']
78-
return getattr(delegate_module, name)
79-
raise AttributeError("module '{}' does not have '{}' attribute".format(module_name, name))
76+
attributes.append('__all__')
77+
78+
def __getattr__(attr):
79+
if attr in attributes:
80+
delegate_module = __import__(delegate_name)
81+
82+
new_globals = dict(**delegate_module.__dict__)
83+
new_globals.update(**owner_module.__dict__)
84+
owner_module.__dict__.update(**new_globals)
85+
86+
if '__getattr__' in owner_module.__dict__:
87+
del owner_module.__dict__['__getattr__']
8088

81-
globals['__getattr__'] = __getattr__
82-
globals['__all__'] = ['__getattr__']
89+
return getattr(delegate_module, attr)
90+
raise AttributeError("module '{}' does not have '{}' attribute".format(delegate_name, attr))
91+
92+
owner_module.__dict__['__getattr__'] = __getattr__
93+
94+
95+
@builtin
96+
def import_current_as_named_module_with_delegate(module_name, delegate_name, attributes=None, owner_globals=None):
97+
owner_module = import_current_as_named_module(module_name, owner_globals=owner_globals)
98+
if attributes:
99+
lazy_attributes_from_delegate(delegate_name, attributes, owner_module)

graalpython/lib-graalpython/_struct.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@
3838
# SOFTWARE.
3939

4040

41-
__graalpython__.lazy_attribute_loading_from_module(
42-
['Struct', '_clearcache', 'calcsize', 'error', 'iter_unpack', 'pack', 'pack_into', 'unpack', 'unpack_from'],
43-
'_cpython_struct', globals())
44-
__graalpython__.import_current_as_named_module("_struct", globals())
41+
__graalpython__.import_current_as_named_module_with_delegate(
42+
module_name="_struct",
43+
delegate_name="_cpython_struct",
44+
attributes=['Struct', '_clearcache', 'calcsize', 'error', 'iter_unpack', 'pack', 'pack_into', 'unpack',
45+
'unpack_from'],
46+
owner_globals=globals())

0 commit comments

Comments
 (0)