ironpython2 icon indicating copy to clipboard operation
ironpython2 copied to clipboard

importlib.import_module not working as expected with namespaces

Open vsajip opened this issue 4 years ago • 0 comments

Given these sources, which build without errors:

::::::::::::::
Main.cs
::::::::::::::
using System;

namespace App.Package
{
    public class Main
    {
        public void Hello() {
            System.Console.WriteLine("Hello, world!");
        }
    }
}
::::::::::::::
lib.csproj
::::::::::::::
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>net5.0;netstandard2.1</TargetFrameworks>
  </PropertyGroup>
</Project>

$ dotnet build
Microsoft (R) Build Engine version 16.11.0+0538acc04 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.

  Determining projects to restore...
  All projects are up-to-date for restore.
  lib -> /disk2/projects/scratch/dotnet/foo/bin/Debug/net5.0/lib.dll
  lib -> /disk2/projects/scratch/dotnet/foo/bin/Debug/netstandard2.1/lib.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:02.24

The following script demonstrates that importlib.import_module() doesn't handle namespaces as expected:

from __future__ import print_function
import sys, os, clr
import importlib

print(sys.version)
p = os.path.abspath('bin/Debug/netstandard2.1')
sys.path.append(p)
clr.AddReference('lib.dll')
import App.Package
App.Package.Main().Hello()
print('OK, so importing in the source worked. Trying importlib ...')
try:
    mod = importlib.import_module('App.Package')
except Exception as e:
    print('Failed to import_module(\'App.Package\'): %s: %s' % (type(e).__name__, e))
print('That failed. Try a piece at a time')
parts = ['App', 'Package']
mod = importlib.import_module(parts.pop(0))
print('  intermediate step: %s' % mod)
for p in parts:
	mod = getattr(mod, p)
	print('  intermediate step: %s' % mod)
getattr(mod, 'Main')().Hello()
print('So piece-by-piece fetching worked, but surely importlib.import_module() is supposed to do all this internally?!')

When run, this prints

2.7.11 (2.7.11.1000)
[.NETFramework,Version=v4.5 on Mono 6.12.0.122 (tarball Mon Feb 22 17:33:28 UTC 2021) (64-bit)]
Hello, world!
OK, so importing in the source worked. Trying importlib ...
Failed to import_module('App.Package'): KeyError: App.Package
That failed. Try a piece at a time
  intermediate step: Microsoft.Scripting.Actions.NamespaceTracker:App
  intermediate step: Microsoft.Scripting.Actions.NamespaceTracker:App.Package
Hello, world!
So piece-by-piece fetching worked, but surely importlib.import_module() is supposed to do all this internally?!

The expected behaviour would be: given a namepace App.Package, import_module() does what I have done in this script, sets sys.modules['App.Package'] to the App.Package NamespaceTracker and returns it from the import_module() call. Then code to getattr(mod, 'Main)would return theMain` type, as expected.

vsajip avatar Aug 20 '21 15:08 vsajip