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

2008-11-01 Thread Tomas Matousek
I think nobody answered this question yet:

 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...)

There is no default scope associated with an engine (other than Global scope on 
ScriptRuntime).
All methods that operate on a scope yet don't take one create a new empty scope 
each time called.

Tomas
___
Users mailing list
Users@lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com


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

2008-11-01 Thread Michael Foord

Tomas Matousek wrote:

I think nobody answered this question yet:

  

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...)



There is no default scope associated with an engine (other than Global scope on 
ScriptRuntime).
All methods that operate on a scope yet don't take one create a new empty scope 
each time called.
  


Thanks. It turns out I was talking about the default scope on a compiled 
code object. We need to execute a lot of code in the same scope. Looks 
like we lose *some* of the advantage of compiling by not executing in 
the default scope of the compiled code.


All the best,

Michael


Tomas
___
Users mailing list
Users@lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
  



--
http://www.ironpythoninaction.com/
http://www.voidspace.org.uk/blog


___
Users mailing list
Users@lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com


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

2008-10-31 Thread Michael Foord

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.
[EMAIL PROTECTED]
+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@lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com


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

2008-10-31 Thread Curt Hagenlocher
I don't know the answer to your question (and don't have the source code
with me on the bus) but by calling Python.CreateEngine(), you're now
creating a second copy of the runtime.  Notionally, the runtimes are
independent of each other and I would expect there to be a second import
when the same module is used in both.

On Fri, Oct 31, 2008 at 6:53 AM, Michael Foord 
[EMAIL PROTECTED] wrote:

 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.
 [EMAIL PROTECTED]
 +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@lists.ironpython.com
 http://lists.ironpython.com/listinfo.cgi/users-ironpython.com

___
Users mailing list
Users@lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com


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

2008-10-31 Thread Michael Foord

Curt Hagenlocher wrote:
I don't know the answer to your question (and don't have the source 
code with me on the bus) but by calling Python.CreateEngine(), you're 
now creating a second copy of the runtime.  Notionally, the runtimes 
are independent of each other and I would expect there to be a second 
import when the same module is used in both.


Yes - which is why the code explicitly adds the module to the runtime 
associated with the engine we have just created. At least the theory was 
that this would publish the already imported module to the new engine, 
and make it available for import without having to re-execute the module.


Michael



On Fri, Oct 31, 2008 at 6:53 AM, Michael Foord 
[EMAIL PROTECTED] 
mailto:[EMAIL PROTECTED] wrote:


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.
[EMAIL PROTECTED]
mailto:[EMAIL PROTECTED]
+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@lists.ironpython.com mailto:Users@lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com




___
Users mailing list
Users@lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
  



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

___
Users mailing list
Users@lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com


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

2008-10-31 Thread Dino Viehland
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 :) ).

-Original Message-
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] 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.
[EMAIL PROTECTED]
+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@lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
___
Users mailing list
Users@lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com


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

2008-10-31 Thread Michael Foord

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: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] 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.
[EMAIL PROTECTED]
+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@lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
___
Users mailing list
Users@lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
  



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

___
Users mailing list
Users@lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com


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

2008-10-31 Thread Michael Foord

Dino Viehland wrote:

If you also have those modules living on disk in sys.path - yes.  But honestly 
it is a little scary that you're using modules across ScriptRuntime's and I 
can't say that I'd advise that as a best practice.  Of course I don't know that 
anything will go wrong either but it might get really confusing...
  


The basic scenario is that our spreadsheets use a host of our 
spreadsheet model libraries.


If every new document has to import these from scratch then it 
drastically increases the time (and memory use) associated with creating 
a new document and doing the first calculation.


Of course if importing large amounts of Python code was quicker and used 
less memory it wouldn't be such an issue. ;-)


If a single runtime could have multiple Python engines associated then 
we could do that, but as far as I can tell creating a new engine from a 
runtime with an existing engine will always return the existing engine?


Though as they are all using the same libraries it seems sensible for 
them to be shared rather than each document holding an identical copy. 
If at some point we move to isolate documents using AppDomains then this 
will obviously change - but the time cost of a new document having to 
import everything from scratch is a factor in being able to do that.


Michael

-Original Message-
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Michael Foord
Sent: Friday, October 31, 2008 9:40 AM
To: Discussion of IronPython
Subject: Re: [IronPython] IronPython 2: Oddity with Hosting API from within 
IronPython

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: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] 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.
[EMAIL PROTECTED]
+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@lists.ironpython.com
http://lists.ironpython.com

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

2008-10-31 Thread Dino Viehland
Makes sense - and having the same libraries loaded will certainly reduce any 
confusion...  can you just have sys.path be empty or different for the 2ndary 
hosted engines?  Also if you're using the pre-compiled modules you could 
actually just remove the compiled loader from sys.meta_path.

-Original Message-
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Michael Foord
Sent: Friday, October 31, 2008 9:53 AM
To: Discussion of IronPython
Subject: Re: [IronPython] IronPython 2: Oddity with Hosting API from within 
IronPython

Dino Viehland wrote:
 If you also have those modules living on disk in sys.path - yes.  But 
 honestly it is a little scary that you're using modules across 
 ScriptRuntime's and I can't say that I'd advise that as a best practice.  Of 
 course I don't know that anything will go wrong either but it might get 
 really confusing...


The basic scenario is that our spreadsheets use a host of our
spreadsheet model libraries.

If every new document has to import these from scratch then it
drastically increases the time (and memory use) associated with creating
a new document and doing the first calculation.

Of course if importing large amounts of Python code was quicker and used
less memory it wouldn't be such an issue. ;-)

If a single runtime could have multiple Python engines associated then
we could do that, but as far as I can tell creating a new engine from a
runtime with an existing engine will always return the existing engine?

Though as they are all using the same libraries it seems sensible for
them to be shared rather than each document holding an identical copy.
If at some point we move to isolate documents using AppDomains then this
will obviously change - but the time cost of a new document having to
import everything from scratch is a factor in being able to do that.

Michael
 -Original Message-
 From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Michael Foord
 Sent: Friday, October 31, 2008 9:40 AM
 To: Discussion of IronPython
 Subject: Re: [IronPython] IronPython 2: Oddity with Hosting API from within 
 IronPython

 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: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] 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

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

2008-10-31 Thread Dino Viehland
If you also have those modules living on disk in sys.path - yes.  But honestly 
it is a little scary that you're using modules across ScriptRuntime's and I 
can't say that I'd advise that as a best practice.  Of course I don't know that 
anything will go wrong either but it might get really confusing...

-Original Message-
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Michael Foord
Sent: Friday, October 31, 2008 9:40 AM
To: Discussion of IronPython
Subject: Re: [IronPython] IronPython 2: Oddity with Hosting API from within 
IronPython

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: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] 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.
 [EMAIL PROTECTED]
 +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@lists.ironpython.com
 http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
 ___
 Users mailing list
 Users@lists.ironpython.com
 http://lists.ironpython.com/listinfo.cgi/users-ironpython.com



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

___
Users mailing list
Users@lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
___
Users mailing list
Users@lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com