I think you can depend upon this behavior.  Compiled loader support is 
implemented as a meta path hook and therefore the pure Python version of this 
looks like:

import sys

class my_loader(object):
                def find_module(self, fullname, path):
                                print 'find', fullname
                                if fullname == 'foo': return module_loader()

class module_loader(object):
                def load_module(self, fullname):
                                print 'load', fullname
                                if fullname == 'foo':
                                                res = __import__('x')
                                                sys.modules['foo'] = res
                                                res.__name__ = 'foo'
                                                res.__path__ = ['foo']
                                                return res


sys.meta_path.append(my_loader())

from foo import foo
from foo.bar import bar

On disk x is a package which has your 1st package structure, foo is a package 
which has your 2nd package structure.  The loader hook in this case is 
importing x, renaming it to foo, and then it doesn't resolve foo.bar.  That 
turns into a full lookup and the importer rules dictate that we'll happily look 
on disk because foo appears to be a parent package.  This outputs the same on 
CPython and IronPython so I'm pretty sure we're correct here :)

As to the identity of the modules - the compiled modules always win because the 
meta path hooks get to execute first.  So you'll only ever successfully import 
compiled modules if they exist.  So while you can augment an existing package 
you cannot replace files from it.


From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Glenn Jones
Sent: Monday, December 08, 2008 3:40 AM
To: Discussion of IronPython
Subject: [IronPython] Compiled IronPython mixed with source files

Hi all,

In our work to get Resolver One working on IronPython 2, we've noticed this 
interesting behaviour and would like to know whether it's defined behaviour 
that we can rely on or just happenstance.

Create a package with the following structure:
+ foo
|----__init__.py
|----foo.py

where foo.py contains
print "foo (compiled)"

and compile it to foo.dll.

Now change foo.py to
print "foo (not compiled)"

and add a bar package:
+ foo
|----__init__.py
|----foo.py
|---+ bar
    |--- __init__.py
    |--- bar.py

where bar contains:
print "bar (not compiled)"

then, the following code:
import clr
clr.AddReference('foo')
from foo import foo
from foo.bar import bar

outputs:
foo(compiled)
bar (not compiled)

and removing the AddReference line outputs:
foo (not compiled)
bar (not compiled)


This makes it clear that we can have a package that is split between compiled 
dll and source and that they work together.

Can we rely on this behaviour? Is there a specified order in which imports from 
different sources are resolved? How is the multiple identity of the foo module 
(compiled and not compiled) handled?

Thanks

Glenn & Michael

_______________________________________________
Users mailing list
[email protected]
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com

Reply via email to