Skip to content

Commit

Permalink
disable deepcopy on PyObject #757 (#1039)
Browse files Browse the repository at this point in the history
* disable deepcopy on PyObject #757

* Update src/PyCall.jl

Co-authored-by: Steven G. Johnson <stevenj@mit.edu>

* fix deepcopy and add tests

* add another deepcopy test

* v1.95.2

* Update Project.toml

* Update test/runtests.jl

---------

Co-authored-by: Steven G. Johnson <stevenj@mit.edu>
  • Loading branch information
jw3126 and stevengj committed Jun 21, 2023
1 parent b5da159 commit c12d6d7
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Project.toml
@@ -1,7 +1,7 @@
name = "PyCall"
uuid = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0"
authors = ["Steven G. Johnson <stevenj@mit.edu>", "Yichao Yu <yyc1992@gmail.com>", "Takafumi Arakaki <aka.tkf@gmail.com>", "Simon Kornblith <simon@simonster.com>", "Páll Haraldsson <Pall.Haraldsson@gmail.com>", "Jon Malmaud <malmaud@gmail.com>", "Jake Bolewski <jakebolewski@gmail.com>", "Keno Fischer <keno@alumni.harvard.edu>", "Joel Mason <jobba1@hotmail.com>", "Jameson Nash <vtjnash@gmail.com>", "The JuliaPy development team"]
version = "1.95.2"
version = "1.96.0"

[deps]
Conda = "8f4d0f93-b110-5947-807f-2305c1781a2d"
Expand Down
10 changes: 10 additions & 0 deletions src/PyCall.jl
Expand Up @@ -979,6 +979,16 @@ include("serialize.jl")

include("pyinit.jl")

const _deepcopy = PyNULL()

function Base.deepcopy_internal(obj::PyObject, stackdict::Base.IdDict)
haskey(stackdict, obj) && return stackdict[obj]
ispynull(_deepcopy) && copy!(_deepcopy, pyimport("copy")["deepcopy"])
ret = pycall(_deepcopy, PyObject, obj)
stackdict[obj] = ret
ret
end

#########################################################################

include("precompile.jl")
Expand Down
40 changes: 40 additions & 0 deletions test/runtests.jl
Expand Up @@ -620,6 +620,45 @@ const PyInt = pyversion < v"3" ? Int : Clonglong
@test_throws ArgumentError float(pybuiltin("type"))
end

@testset "deepcopy #757" begin
l = py"[1,2,3]"o
l2 = deepcopy(l)
@test l == l2
l2.append(4)
@test l != l2
@test collect(l2) == [1,2,3,4]
@test collect(l) == [1,2,3]

obj = py"""
class C757:
def __init__(self, a, b):
self.a = a
self.b = b
"""
obj = py"C757(C757(1,2), C757(3,4))"o
obj2 = deepcopy(obj)
@test PyPtr(obj) != PyPtr(obj2) # make sure a new Python object is created
@test obj.a.a == obj2.a.a
@test obj.a.b == obj2.a.b
@test obj.b.a == obj2.b.a
@test obj.b.b == obj2.b.b
obj.a = 3
@test obj.a == 3
@test obj2.a.a == 1
@test obj2.a.b == 2

struct S;a;b;end

c = py"C757(1,2)"
obj = S(c, c)
obj2 = deepcopy(obj)
@test obj.a === obj.b
@test obj2.a === obj2.b
obj.a.a = 4
@test obj.a.a == 4
@test obj2.a.a == 1
end

######################################################################
#@pydef tests: type declarations need to happen at top level

Expand Down Expand Up @@ -855,3 +894,4 @@ end
@test_throws PyCall.PyError a.a = 0
@test_throws KeyError a.a = 1
end

2 comments on commit c12d6d7

@stevengj
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/86027

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v1.96.0 -m "<description of version>" c12d6d7da4116d8231c57e349a469567f14f362c
git push origin v1.96.0

Please sign in to comment.