[IronPython] infinite import loop for nested packages (and fix)
Martin Maly
Martin.Maly at microsoft.com
Thu Mar 2 17:49:06 CET 2006
I believe we already have fix for this one. It will go out in the Beta 4 release next week.
Martin
-----Original Message-----
From: users-bounces at lists.ironpython.com [mailto:users-bounces at lists.ironpython.com] On Behalf Of Andrew Sutherland
Sent: Wednesday, March 01, 2006 11:14 PM
To: users at lists.ironpython.com
Subject: [IronPython] infinite import loop for nested packages (and fix)
If you have a directory on your python path like so:
foo/
__init__.py: import foo.bar as bar
bar/
__init__.py: import foo.bar.baz as baz
baz.py: print 'Baz imported'
testit.py: import foo.bar
And you run testit.py, the import process will go into an infinite
loop while importing 'foo.bar' because an effort is only made to see
if the top-level package already exists. Although it will find 'foo'
alright in that fashion, it will repeatedly look up 'foo.bar' because
the name traversal logic in Importer::ImportModule finds 'foo' already
exists, then goes to import foo.bar again.
A solution that works follows.
internal static object ImportModule(PythonModule mod, string
fullName, bool bottom) {
string[] names = fullName.Split('.');
object newmod = null;
// Find the most specific already-existing module if we may.
// Since the module import mechanism in CPython is not backtracking,
// this is a safe behaviour.
string nameRemaining = fullName;
// (At the conclusion of this loop,) the index of the name
thus looked up. In the
// event our loop fails, iNameSatisfied will be zero.
int iNameSatisfied = names.Length - 1;
while(nameRemaining.LastIndexOf('.') >= 0) {
if(TryGetExistingModule(nameRemaining, out newmod)) {
break;
}
else {
nameRemaining = nameRemaining.Substring(0,
nameRemaining.LastIndexOf('.'));
iNameSatisfied--;
}
}
if(iNameSatisfied == 0)
{
newmod = ImportTopFrom(mod, names[0]);
}
else if (names.Length == 1)
{
// if we imported before having the assembly
// loaded and then loaded the assembly we want
// to make the assembly available now.
PythonModule pm = newmod as PythonModule;
if (pm.InnerModule != null) pm.PackageImported = true;
}
if (newmod == null) {
newmod = ImportTop(mod, names[0]);
if (newmod == null) return null;
}
object next = newmod;
for (int i = iNameSatisfied + 1; i < names.Length; i++) {
next = ImportFrom(next, names[i]);
}
return bottom ? next : newmod;
}
Andrew
_______________________________________________
users mailing list
users at lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
More information about the Ironpython-users
mailing list