IronLanguages / ironpython2

Implementation of the Python programming language for .NET Framework; built on top of the Dynamic Language Runtime (DLR).

Home Page:http://ironpython.net

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Wrapping __import__ affects accessibility of some properties

janrehberg opened this issue · comments

Version

IronPython 2.7.11 (2.7.11.1000) NETFramework,Version=v4.5 on .NET Framework 4.8.4300.0 (64-bit)]

Description

Wrapping __builtin__.__import__ appears to affect visibility/accessibility of certain properties of builtin classes,
but only when it is done outside of __main__.

Specifically, when trying to check the type of a generic list by reading the PropertyType of its Item property
and using the unmodified import, this will succeed:

from System.Collections.Generic import List
obj = List[int]()
assert hasattr(obj.Item, 'PropertyType')  # success

Adding a simple wrapper around __import__ will also work:

import __builtin__

def wrapper(*args, **kwargs):
        return __builtin__.__org_import__(*args, **kwargs)
    
__builtin__.__org_import__ = __builtin__.__import__
__builtin__.__import__ = wrapper

from System.Collections.Generic import List
obj = List[int]()
assert hasattr(obj.Item, 'PropertyType')  # success

But once the wrapper is moved to its own module, the assertion fails and the PropertyType is no longer accessible:

# import_wrap.py
import __builtin__

def wrapper(*args, **kwargs):
        return __builtin__.__org_import__(*args, **kwargs)
    
__builtin__.__org_import__ = __builtin__.__import__
__builtin__.__import__ = wrapper
# check.py
import import_wrap
from System.Collections.Generic import List

obj = List[int]()
assert hasattr(obj.Item, 'PropertyType')  # fail

However, access to the property can be restored by importing List again using the unmodified __import__ function.

Thanks for the report.

It looks like when __builtin__.__import__ is called it sets a flag on the caller's CodeContext (basically the calling module) to make the .NET methods visible. In this case the import_wrap module is the one that gets flagged instead of the main module.

Here's a slightly simplified check.py:

# check.py
import import_wrap
import System

int.Parse("1")

Unfortunately I can't think of a workaround, but please let me know if you find a solution.