[IronPython] IronPython 2: Oddity with Hosting API from within IronPython

Michael Foord fuzzyman at voidspace.org.uk
Fri Oct 31 17:39:40 CET 2008


Dino Viehland wrote:
> We try to import from the file system before we attempt to import from the DLR (which includes both globals & .NET namespaces).  So in this case we'll pick up foobar from disk because presumably these 2 engines both share the entry in sys.path where foobar lives.
>
> I think long term this logic is going to move into an importer hook because by CPython 3.1 the import logic may be written entirely in Python.  In that case you'd have the ability to re-order the import hooks so you could control the precedence.  But for now I think it's by design - we don't want to block potentially valid imports that would work in CPython (e.g. import System :) ).
>   

So if we want to pre-populate an engine with modules we *ought* to be 
hooking directly into 'sys.modules' of the hosted engines rather than 
using runtime.Globals ?

Michael

> -----Original Message-----
> From: users-bounces at lists.ironpython.com [mailto:users-bounces at lists.ironpython.com] On Behalf Of Michael Foord
> Sent: Friday, October 31, 2008 6:54 AM
> To: Discussion of IronPython
> Subject: [IronPython] IronPython 2: Oddity with Hosting API from within IronPython
>
> Hello guys,
>
> In Resolver One we use the IronPython hosting API from inside IronPython
> code. I've noticed an oddity that is not how I would expect the hosting
> API to behave if I was using it from C#.
>
> My understanding is that the correct way to publish a module (make it
> available for a ScriptEngine to import) is to set it in
> 'engine.Runtime.Globals'.
>
> If I do this from within IronPython code with a module I have already
> imported and then execute an import statement in the engine, the module
> is re-imported (code executed) rather than using the one I have
> published to the runtime globals.
>
> If I have a 'foobar' module that prints when importing, the following
> code prints twice instead of the once I would expect:
>
> import sys
> import clr
> clr.AddReference('IronPython')
> clr.AddReference('Microsoft.Scripting')
>
> from IronPython.Hosting import Python
> from Microsoft.Scripting import SourceCodeKind
>
> import foobar
>
> engine = Python.CreateEngine()
> engine.Runtime.Globals.SetVariable('foobar', sys.modules['foobar'])
>
> source = engine.CreateScriptSourceFromString('import foobar\r\n',
> SourceCodeKind.Statements)
> scope = engine.CreateScope()
> source.Compile().Execute(scope)
>
>
> *However*, if I change the code to not use Runtime.Globals, but instead
> do the following, then the module is only imported once and I get one
> print as expected:
>
> hostedSys = Python.GetSysModule(engine)
> hostedSys.modules['foobar'] = sys.modules['foobar']
>
> Is there something I have overlooked here?
>
> As a minor supplementary question, how do I get a reference to the
> default ScriptScope on an engine? Is there any performance advantage in
> using the default one, can I replace it, and does replacing it remove
> any performance benefits we might have got? (OK, so strictly speaking
> that wasn't just one question...)
>
> All the best,
>
> Michael Foord
>
> --
> Michael Foord
> Senior Software Engineer, Resolver Systems Ltd.
> michael.foord at resolversystems.com
> +44 (0) 20 7253 6372
>
> Try out Resolver One! <http://www.resolversystems.com/get-it/>
>
> 17a Clerkenwell Road, London EC1M 5RD, UK
> VAT No.: GB 893 5643 79 Registered in England and Wales as company number 5467329.
> Registered address: 843 Finchley Road, London NW11 8NA, UK
>
> _______________________________________________
> Users mailing list
> Users at lists.ironpython.com
> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
> _______________________________________________
> Users mailing list
> Users at lists.ironpython.com
> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
>   


-- 
http://www.ironpythoninaction.com/




More information about the Ironpython-users mailing list