Quantcast

clr.ImportExtensions are not available outside module ?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

clr.ImportExtensions are not available outside module ?

daniel kottow
Hi,

Just as Dave Wald, I have also trying out the ImportExtensions methods which I
personally find very useful, thank you for implementing. Everything is working
fine on using 2.7 (and .net 4), but extension methods loaded by one module seem
not available on another...


I will stick to Dave's code exmaple:

import clr
clr.AddReference("System.Core")
import System
from System import Linq

clr.ImportExtensions(Linq)

class Product(object):
     def __init__(self, cat, id, qtyOnHand ):
         self.Cat = cat
         self.ID = id
         self.QtyOnHand = qtyOnHand
         self.Q = self.QtyOnHand

If I put this into a file, lets say test.py and now use the module on the
command line:

>>> import test
>>> products = [test.Product('food', i, 10) for i in range(3)]
>>>
>>>
>>> products.Where
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute 'Where'

The linq extensions are not available. I have to re-import them:

>>> test.clr.ImportExtensions(test.Linq)
>>> products.Where
<built-in method Where of list object at 0x000000000000002B>
>>>

Is this a current limitation, or should I be doing things differently ?
Any help appreciated.

Greetings,
Daniel
_______________________________________________
Users mailing list
[hidden email]
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: clr.ImportExtensions are not available outside module ?

Dino Viehland


Daniel wrote:
> Just as Dave Wald, I have also trying out the ImportExtensions methods
> which I personally find very useful, thank you for implementing. Everything is
> working fine on using 2.7 (and .net 4), but extension methods loaded by one
> module seem not available on another...

This is by design.  It works similar to how "import clr" only effects the current module
and how extension methods work in C# where they are scoped by file.  So if you
want extension methods available in a file you'll need to import them in that file.
If they were globally scoped it would be easy for one module to break another by
bringing in the 'wrong' extension methods.

>
>
> I will stick to Dave's code exmaple:
>
> import clr
> clr.AddReference("System.Core")
> import System
> from System import Linq
>
> clr.ImportExtensions(Linq)
>
> class Product(object):
>      def __init__(self, cat, id, qtyOnHand ):
>          self.Cat = cat
>          self.ID = id
>          self.QtyOnHand = qtyOnHand
>          self.Q = self.QtyOnHand
>
> If I put this into a file, lets say test.py and now use the module on the
> command line:
>
> >>> import test
> >>> products = [test.Product('food', i, 10) for i in range(3)]
> >>>
> >>>
> >>> products.Where
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> AttributeError: 'list' object has no attribute 'Where'
>
> The linq extensions are not available. I have to re-import them:
>
> >>> test.clr.ImportExtensions(test.Linq)
> >>> products.Where
> <built-in method Where of list object at 0x000000000000002B>
> >>>
>
> Is this a current limitation, or should I be doing things differently ?
> Any help appreciated.
>
> Greetings,
> Daniel
> _______________________________________________
> Users mailing list
> [hidden email]
> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
_______________________________________________
Users mailing list
[hidden email]
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: clr.ImportExtensions are not available outside module ?

daniel kottow
Ok.
I am not sure what you mean by similar to import clr, though.

Because in my example, clr is available from outside test; its just named
test.clr...
Let me give you another example which is closer on how I ran into this...

Lets say you have in C#:

--- iron.Example.cs

namespace iron
{
    public class Example
    {
        public Example()
        {
        }

        public int foo()
        {
            return 1;
        }
    }

    public static class ExampleExtension
    {
        public static int bar(this Example example)
        {
            return example.foo() + 1;
        }
   
    }
}

--- EOF

Then I define an example.py to wrap this up:

--- test.py

import clr
clr.AddReference("iron")
import iron
clr.ImportExtensions(iron.ExampleExtension)

# lets use this just to test it out

e = iron.Example()
print e.foo()
print e.bar()

--- EOF

now on my command line I get

>>> import example
1
2
>>> ex = example.iron.Example()
>>> ex.foo()
1
>>> ex.bar()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Example' object has no attribute 'bar'

And so I don't find a nice way to wrap my C# functionality in just one python
module,

where I whish I could offer the extension methods just like any other method...
or is my import strategy somehow flawed ?

Greetings,
Daniel





namespace native
{
    public class Example
    {
    }

    public static class ExampleExtension
    {
         public static void
    }

add some extension methods to it, and then want to import everything in one
python stub module. E.g.





----- Original Message ----
From: Dino Viehland <[hidden email]>
To: Discussion of IronPython <[hidden email]>
Sent: Thu, May 12, 2011 1:01:33 PM
Subject: Re: [IronPython] clr.ImportExtensions are not available outside module
?



Daniel wrote:
> Just as Dave Wald, I have also trying out the ImportExtensions methods
> which I personally find very useful, thank you for implementing. Everything is
> working fine on using 2.7 (and .net 4), but extension methods loaded by one
> module seem not available on another...

This is by design.  It works similar to how "import clr" only effects the
current module
and how extension methods work in C# where they are scoped by file.  So if you
want extension methods available in a file you'll need to import them in that
file.

If they were globally scoped it would be easy for one module to break another by
bringing in the 'wrong' extension methods.

>
>
> I will stick to Dave's code exmaple:
>
> import clr
> clr.AddReference("System.Core")
> import System
> from System import Linq
>
> clr.ImportExtensions(Linq)
>
> class Product(object):
>      def __init__(self, cat, id, qtyOnHand ):
>          self.Cat = cat
>          self.ID = id
>          self.QtyOnHand = qtyOnHand
>          self.Q = self.QtyOnHand
>
> If I put this into a file, lets say test.py and now use the module on the
> command line:
>
> >>> import test
> >>> products = [test.Product('food', i, 10) for i in range(3)]
> >>>
> >>>
> >>> products.Where
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> AttributeError: 'list' object has no attribute 'Where'
>
> The linq extensions are not available. I have to re-import them:
>
> >>> test.clr.ImportExtensions(test.Linq)
> >>> products.Where
> <built-in method Where of list object at 0x000000000000002B>
> >>>
>
> Is this a current limitation, or should I be doing things differently ?
> Any help appreciated.
>
> Greetings,
> Daniel
> _______________________________________________
> Users mailing list
> [hidden email]
> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
_______________________________________________
Users mailing list
[hidden email]
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com

_______________________________________________
Users mailing list
[hidden email]
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: clr.ImportExtensions are not available outside module ?

Dino Viehland
Daniel wrote:
> Ok.
> I am not sure what you mean by similar to import clr, though.

It's similar to import clr in that importing clr not only gives you the clr module
but also makes .NET members available to the module which imported clr.
For example before doing "import clr" calling .ToString() on an object will
raise an AttributeError but afterwards it will call the .NET ToString method.

If you'd like to provide a set of globally available extension methods specifically
for IronPython users you could use ExtensionTypeAttribute (which is defined
in the DLR outer layer).  IronPython will look for that attribute declared on an
assembly.  The attribute will give a type to extend and a type to pull the extension
methods from.  All you need to do is load the assembly into the script runtime
either via the hosting APIs or clr.AddReference.  This was the mechanism we
originally used to add the Python methods to the .NET types like string (we now
hard code the types for Python rather reflecting over the types at startup, but
the mechanism remains for backwards compat).  

>
> Because in my example, clr is available from outside test; its just named
> test.clr...
> Let me give you another example which is closer on how I ran into this...
>
> Lets say you have in C#:
>
> --- iron.Example.cs
>
> namespace iron
> {
>     public class Example
>     {
>         public Example()
>         {
>         }
>
>         public int foo()
>         {
>             return 1;
>         }
>     }
>
>     public static class ExampleExtension
>     {
>         public static int bar(this Example example)
>         {
>             return example.foo() + 1;
>         }
>
>     }
> }
>
> --- EOF
>
> Then I define an example.py to wrap this up:
>
> --- test.py
>
> import clr
> clr.AddReference("iron")
> import iron
> clr.ImportExtensions(iron.ExampleExtension)
>
> # lets use this just to test it out
>
> e = iron.Example()
> print e.foo()
> print e.bar()
>
> --- EOF
>
> now on my command line I get
>
> >>> import example
> 1
> 2
> >>> ex = example.iron.Example()
> >>> ex.foo()
> 1
> >>> ex.bar()
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> AttributeError: 'Example' object has no attribute 'bar'
>
> And so I don't find a nice way to wrap my C# functionality in just one python
> module,
>
> where I whish I could offer the extension methods just like any other
> method...
> or is my import strategy somehow flawed ?
>
> Greetings,
> Daniel
>
>
>
>
>
> namespace native
> {
>     public class Example
>     {
>     }
>
>     public static class ExampleExtension
>     {
>          public static void
>     }
>
> add some extension methods to it, and then want to import everything in
> one
> python stub module. E.g.
>
>
>
>
>
> ----- Original Message ----
> From: Dino Viehland <[hidden email]>
> To: Discussion of IronPython <[hidden email]>
> Sent: Thu, May 12, 2011 1:01:33 PM
> Subject: Re: [IronPython] clr.ImportExtensions are not available outside
> module
> ?
>
>
>
> Daniel wrote:
> > Just as Dave Wald, I have also trying out the ImportExtensions methods
> > which I personally find very useful, thank you for implementing. Everything
> is
> > working fine on using 2.7 (and .net 4), but extension methods loaded by
> one
> > module seem not available on another...
>
> This is by design.  It works similar to how "import clr" only effects the
> current module
> and how extension methods work in C# where they are scoped by file.  So if
> you
> want extension methods available in a file you'll need to import them in that
> file.
>
> If they were globally scoped it would be easy for one module to break
> another by
> bringing in the 'wrong' extension methods.
>
> >
> >
> > I will stick to Dave's code exmaple:
> >
> > import clr
> > clr.AddReference("System.Core")
> > import System
> > from System import Linq
> >
> > clr.ImportExtensions(Linq)
> >
> > class Product(object):
> >      def __init__(self, cat, id, qtyOnHand ):
> >          self.Cat = cat
> >          self.ID = id
> >          self.QtyOnHand = qtyOnHand
> >          self.Q = self.QtyOnHand
> >
> > If I put this into a file, lets say test.py and now use the module on the
> > command line:
> >
> > >>> import test
> > >>> products = [test.Product('food', i, 10) for i in range(3)]
> > >>>
> > >>>
> > >>> products.Where
> > Traceback (most recent call last):
> >   File "<stdin>", line 1, in <module>
> > AttributeError: 'list' object has no attribute 'Where'
> >
> > The linq extensions are not available. I have to re-import them:
> >
> > >>> test.clr.ImportExtensions(test.Linq)
> > >>> products.Where
> > <built-in method Where of list object at 0x000000000000002B>
> > >>>
> >
> > Is this a current limitation, or should I be doing things differently ?
> > Any help appreciated.
> >
> > Greetings,
> > Daniel
> > _______________________________________________
> > Users mailing list
> > [hidden email]
> > http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
> _______________________________________________
> Users mailing list
> [hidden email]
> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
>
> _______________________________________________
> Users mailing list
> [hidden email]
> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
_______________________________________________
Users mailing list
[hidden email]
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: clr.ImportExtensions are not available outside module ?

daniel kottow
Hello Dino,
I don't think I want to delve into more complexity, thank you :-)

What I was trying to say that, unfortunately, I do not see a way to encapsulate
my extension methods written in C# so that a person doing only python does not
have to worry about it -
on the other hand, i reckon it is also not such a big deal to write some
clr.ImportExtensions on the beginning of a module and then the developer *can*
forget on how the methods got there.

Btw, in order to use the methods interactively, I now start my session with "-i
ironstuff" and everything is fine, i get my classes with their extension methods
on the cmd line... very nice.

Thank you for time.
Daniel.





----- Original Message ----
From: Dino Viehland <[hidden email]>
To: Discussion of IronPython <[hidden email]>
Sent: Thu, May 12, 2011 3:50:01 PM
Subject: Re: [IronPython] clr.ImportExtensions are not available outside module
?

Daniel wrote:
> Ok.
> I am not sure what you mean by similar to import clr, though.

It's similar to import clr in that importing clr not only gives you the clr
module
but also makes .NET members available to the module which imported clr.
For example before doing "import clr" calling .ToString() on an object will
raise an AttributeError but afterwards it will call the .NET ToString method.

If you'd like to provide a set of globally available extension methods
specifically
for IronPython users you could use ExtensionTypeAttribute (which is defined
in the DLR outer layer).  IronPython will look for that attribute declared on an
assembly.  The attribute will give a type to extend and a type to pull the
extension
methods from.  All you need to do is load the assembly into the script runtime
either via the hosting APIs or clr.AddReference.  This was the mechanism we
originally used to add the Python methods to the .NET types like string (we now
hard code the types for Python rather reflecting over the types at startup, but
the mechanism remains for backwards compat).  

>
> Because in my example, clr is available from outside test; its just named
> test.clr...
> Let me give you another example which is closer on how I ran into this...
>
> Lets say you have in C#:
>
> --- iron.Example.cs
>
> namespace iron
> {
>     public class Example
>     {
>         public Example()
>         {
>         }
>
>         public int foo()
>         {
>             return 1;
>         }
>     }
>
>     public static class ExampleExtension
>     {
>         public static int bar(this Example example)
>         {
>             return example.foo() + 1;
>         }
>
>     }
> }
>
> --- EOF
>
> Then I define an example.py to wrap this up:
>
> --- test.py
>
> import clr
> clr.AddReference("iron")
> import iron
> clr.ImportExtensions(iron.ExampleExtension)
>
> # lets use this just to test it out
>
> e = iron.Example()
> print e.foo()
> print e.bar()
>
> --- EOF
>
> now on my command line I get
>
> >>> import example
> 1
> 2
> >>> ex = example.iron.Example()
> >>> ex.foo()
> 1
> >>> ex.bar()
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> AttributeError: 'Example' object has no attribute 'bar'
>
> And so I don't find a nice way to wrap my C# functionality in just one python
> module,
>
> where I whish I could offer the extension methods just like any other
> method...
> or is my import strategy somehow flawed ?
>
> Greetings,
> Daniel
>
>
>
>
>
> namespace native
> {
>     public class Example
>     {
>     }
>
>     public static class ExampleExtension
>     {
>          public static void
>     }
>
> add some extension methods to it, and then want to import everything in
> one
> python stub module. E.g.
>
>
>
>
>
> ----- Original Message ----
> From: Dino Viehland <[hidden email]>
> To: Discussion of IronPython <[hidden email]>
> Sent: Thu, May 12, 2011 1:01:33 PM
> Subject: Re: [IronPython] clr.ImportExtensions are not available outside
> module
> ?
>
>
>
> Daniel wrote:
> > Just as Dave Wald, I have also trying out the ImportExtensions methods
> > which I personally find very useful, thank you for implementing. Everything
> is
> > working fine on using 2.7 (and .net 4), but extension methods loaded by
> one
> > module seem not available on another...
>
> This is by design.  It works similar to how "import clr" only effects the
> current module
> and how extension methods work in C# where they are scoped by file.  So if
> you
> want extension methods available in a file you'll need to import them in that
> file.
>
> If they were globally scoped it would be easy for one module to break
> another by
> bringing in the 'wrong' extension methods.
>
> >
> >
> > I will stick to Dave's code exmaple:
> >
> > import clr
> > clr.AddReference("System.Core")
> > import System
> > from System import Linq
> >
> > clr.ImportExtensions(Linq)
> >
> > class Product(object):
> >      def __init__(self, cat, id, qtyOnHand ):
> >          self.Cat = cat
> >          self.ID = id
> >          self.QtyOnHand = qtyOnHand
> >          self.Q = self.QtyOnHand
> >
> > If I put this into a file, lets say test.py and now use the module on the
> > command line:
> >
> > >>> import test
> > >>> products = [test.Product('food', i, 10) for i in range(3)]
> > >>>
> > >>>
> > >>> products.Where
> > Traceback (most recent call last):
> >   File "<stdin>", line 1, in <module>
> > AttributeError: 'list' object has no attribute 'Where'
> >
> > The linq extensions are not available. I have to re-import them:
> >
> > >>> test.clr.ImportExtensions(test.Linq)
> > >>> products.Where
> > <built-in method Where of list object at 0x000000000000002B>
> > >>>
> >
> > Is this a current limitation, or should I be doing things differently ?
> > Any help appreciated.
> >
> > Greetings,
> > Daniel
> > _______________________________________________
> > Users mailing list
> > [hidden email]
> > http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
> _______________________________________________
> Users mailing list
> [hidden email]
> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
>
> _______________________________________________
> Users mailing list
> [hidden email]
> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
_______________________________________________
Users mailing list
[hidden email]
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com

_______________________________________________
Users mailing list
[hidden email]
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: clr.ImportExtensions are not available outside module ?

Jeff Hardy-4
On Fri, May 13, 2011 at 5:41 AM, daniel kottow <[hidden email]> wrote:
> What I was trying to say that, unfortunately, I do not see a way to encapsulate
> my extension methods written in C# so that a person doing only python does not
> have to worry about it -
> on the other hand, i reckon it is also not such a big deal to write some
> clr.ImportExtensions on the beginning of a module and then the developer *can*
> forget on how the methods got there.

Don't forget that Python is a dynamic language - you can add methods
to the class after it's defined. You might have to inherit from the
.NET class in Python, but then you can loop over the extension methods
and add them to the Python class.

It might be nice to have a clr.ImbueTypeWithExtensions(cls, extcls)
method that did this, and made the extensions available everywhere,
but it would have to be used with care.

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