add_trait and copying

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

add_trait and copying

Satrajit Ghosh
is there a way to make a copy of 'a'?

thanks,

satra

In [33]: class A(HasTraits):
   ....:         foo = Int
In [34]: a = A()
In [36]: a.add_trait('bar', Float)
In [37]: a.bar = 1.0
In [39]: b = deepcopy(a)
In [42]: b.bar
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)

/software/temp/nipype-tutorial/<ipython console> in <module>()

AttributeError: 'A' object has no attribute 'bar'



_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: add_trait and copying

Robert Kern
On Sat, Apr 10, 2010 at 1:20 AM, Satrajit Ghosh <[hidden email]> wrote:

> is there a way to make a copy of 'a'?
>
> thanks,
>
> satra
>
> In [33]: class A(HasTraits):
>    ....:         foo = Int
> In [34]: a = A()
> In [36]: a.add_trait('bar', Float)
> In [37]: a.bar = 1.0
> In [39]: b = deepcopy(a)
> In [42]: b.bar
> ---------------------------------------------------------------------------
> AttributeError                            Traceback (most recent call last)
>
> /software/temp/nipype-tutorial/<ipython console> in <module>()
>
> AttributeError: 'A' object has no attribute 'bar'

Hmmm. That's a bug. We don't currently propagate the dynamically added
traits through the __getstate__ scheme that deepcopy() uses.

However, for this case, you can use the .clone_traits() method, which
will do this correctly.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless
enigma that is made terrible by our own mad attempt to interpret it as
though it had an underlying truth."
  -- Umberto Eco
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: add_trait and copying

Satrajit Ghosh
thanks robert.

since i'm using a traited class within one of my classes, would i have to overwrite my class' __deepcopy__ and do the cloning within it?

class A(HasTraits):
    foo = Int

class B(object):
    spec = A
    def __init__(self, addfields=[], rmfields=[]):
        inputs = spec()
        for f in addfields:
             inputs.add_trait(f, SomeTrait)
        for f in rmfields:
             inputs.remove_trait(f)

so typically, i would do something like:

a = B(addfields='bar')
b = deepcopy(a)

cheers,

satra


On Sat, Apr 10, 2010 at 10:11 AM, Robert Kern <[hidden email]> wrote:
On Sat, Apr 10, 2010 at 1:20 AM, Satrajit Ghosh <[hidden email]> wrote:
> is there a way to make a copy of 'a'?
>
> thanks,
>
> satra
>
> In [33]: class A(HasTraits):
>    ....:         foo = Int
> In [34]: a = A()
> In [36]: a.add_trait('bar', Float)
> In [37]: a.bar = 1.0
> In [39]: b = deepcopy(a)
> In [42]: b.bar
> ---------------------------------------------------------------------------
> AttributeError                            Traceback (most recent call last)
>
> /software/temp/nipype-tutorial/<ipython console> in <module>()
>
> AttributeError: 'A' object has no attribute 'bar'

Hmmm. That's a bug. We don't currently propagate the dynamically added
traits through the __getstate__ scheme that deepcopy() uses.

However, for this case, you can use the .clone_traits() method, which
will do this correctly.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless
enigma that is made terrible by our own mad attempt to interpret it as
though it had an underlying truth."
 -- Umberto Eco
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev


_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: add_trait and copying

Robert Kern
On Sat, Apr 10, 2010 at 8:05 PM, Satrajit Ghosh <[hidden email]> wrote:
> thanks robert.
>
> since i'm using a traited class within one of my classes, would i have to
> overwrite my class' __deepcopy__ and do the cloning within it?

No, sorry. This is just a weird bug in clone_traits().
HasTraits.__deepcopy__() already uses clone_traits(). You can
replicate the problem with clone_traits(). However, the second time
you try it, it will succeed.

In [1]: from enthought.traits.api import *

In [2]: class A(HasTraits):
   ...:     pass
   ...:

In [3]: a = A()

In [5]: a.add_trait('x', Float())

In [6]: a.clone_traits().x
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)

/Users/rkern/<ipython console> in <module>()

AttributeError: 'A' object has no attribute 'x'

In [7]: a.clone_traits().x
Out[7]: 0.0

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless
enigma that is made terrible by our own mad attempt to interpret it as
though it had an underlying truth."
  -- Umberto Eco
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: add_trait and copying

Satrajit Ghosh
dear robert,

No, sorry. This is just a weird bug in clone_traits().
HasTraits.__deepcopy__() already uses clone_traits(). You can
replicate the problem with clone_traits(). However, the second time
you try it, it will succeed.

yes this works. however, if i replace HasTraits with HasStrictTraits, it fails always. i thought this might provide some additional info.

cheers,

satra
 

In [1]: from enthought.traits.api import *

In [2]: class A(HasTraits):
  ...:     pass
  ...:

In [3]: a = A()

In [5]: a.add_trait('x', Float())

In [6]: a.clone_traits().x
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)

/Users/rkern/<ipython console> in <module>()

AttributeError: 'A' object has no attribute 'x'

In [7]: a.clone_traits().x
Out[7]: 0.0

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless
enigma that is made terrible by our own mad attempt to interpret it as
though it had an underlying truth."
 -- Umberto Eco
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev


_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: add_trait and copying

Satrajit Ghosh
hi robert,

i think several of the issues i'm currently running into are related to dynamic trait operations (add_trait, remove_trait) that i'm doing and then wanting to copy/clone the dynamically changed object. for example, i don't quite understand why the trait 'foo' behaves the way it does (see below)? i would expect line 58 to raise AttributeError.

also, from a developer's standpoint would it be better if posted these as tickets instead of posting to the list? i do appreciate the responses. i've at least got things moving again (albeit with a few band-aids).

cheers,

satra

-------
In [52]: class A(HasTraits):
    foo = Int
In [54]: a = A()
In [55]: a.foo = 1
In [56]: a.foo
Out[56]: 1

In [57]: a.remove_trait('foo')
Out[57]: False

In [58]: a.foo
Out[58]: 0   # note foo is 0

In [59]: a.bar = 2

In [60]: a.bar
Out[60]: 2

In [61]: a.remove_trait('bar')
Out[61]: False

In [62]: a.bar
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)

/software/temp/nipype-tutorial/<ipython console> in <module>()

AttributeError: 'A' object has no attribute 'bar'

----------


On Sat, Apr 10, 2010 at 11:06 PM, Satrajit Ghosh <[hidden email]> wrote:
dear robert,

No, sorry. This is just a weird bug in clone_traits().
HasTraits.__deepcopy__() already uses clone_traits(). You can
replicate the problem with clone_traits(). However, the second time
you try it, it will succeed.

yes this works. however, if i replace HasTraits with HasStrictTraits, it fails always. i thought this might provide some additional info.

cheers,

satra
 

In [1]: from enthought.traits.api import *

In [2]: class A(HasTraits):
  ...:     pass
  ...:

In [3]: a = A()

In [5]: a.add_trait('x', Float())

In [6]: a.clone_traits().x
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)

/Users/rkern/<ipython console> in <module>()

AttributeError: 'A' object has no attribute 'x'

In [7]: a.clone_traits().x
Out[7]: 0.0

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless
enigma that is made terrible by our own mad attempt to interpret it as
though it had an underlying truth."
 -- Umberto Eco
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev



_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev