Tuesday, February 8, 2011

jython copy versus clone

We're a Java shop at work.  We do a lot of passing of Java objects back and forth through the jython API to our application.

The other day I had the need to copy a Java object.  It was a flat structure and my instinct was to use the object's clone method, which I did.  This got me thinking about the use of clone versus the copy module in jython and I gave it a look:

Jython 2.5.1 (Release_2_5_1:6813, Sep 26 2009, 13:47:54)
[Java HotSpot(TM) 64-Bit Server VM (Sun Microsystems Inc.)] on java1.6.0_22
Type "help", "copyright", "credits" or "license" for more information.
>>> from java.util import ArrayList
>>> a = ArrayList()
>>> a
[]
>>> a.add(1)
True
>>> a.add([2, 3])
True
>>> import copy
>>> b = a.clone()
>>> b
[1, [2, 3]]
>>> b[1]
[2, 3]
>>> b[1][1]
3
>>> b[1][1] = 22
>>> b
[1, [2, 22]]
>>> a
[1, [2, 22]]
>>> b = copy.deepcopy(a)
>>> b
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
SystemError: Automatic proxy initialization should only occur on proxy classes


OK, clone works similar to copy.copy (shallow copy).  Not sure what's going on with deepcopy, but it doesn't appear to be available in the case of an ArrayList object.

Update:  as noted in the comments, the copy behavior on Java objects is a known bug and is scheduled to be fixed in jython version 2.5.2.  In the meantime, clone() would appear to be a decent option.

Let's test the shallow copy capability of clone():

>>> a = ArrayList()
>>> a.add(1)
True
>>> a.add(2)
True
>>> a.add(3)
True
>>> a
[1, 2, 3]
>>> b = a.clone()
>>> b
[1, 2, 3]
>>> b[2] = 22
>>> b
[1, 2, 22]
>>> a
[1, 2, 3]


Perfect - it works just like copy.copy() would.

2 comments:

  1. FYI the copy problems should be fixed in the upcoming 2.5.2 release, see http://bugs.jython.org/issue1551

    ReplyDelete
  2. @Philip, thanks for pointing that out. I wasn't sure if it was a bug or intended behavior.

    ReplyDelete