Skip to content

Commit 50331f5

Browse files
author
Christopher Doris
committed
test coverage
1 parent 1bdc2bf commit 50331f5

File tree

3 files changed

+259
-20
lines changed

3 files changed

+259
-20
lines changed

src/pywrap/PyDict.jl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ function Base.iterate(x::Base.KeySet{K,PyDict{K,V}}, it::Py=pyiter(x.dict)) wher
4747
end
4848

4949
function Base.getindex(x::PyDict{K,V}, k) where {K,V}
50-
return pyconvert(V, pygetitem(x, convert(K, k)))
50+
k2 = convert(K, k)
51+
pycontains(x, k2) || throw(KeyError(k))
52+
return pyconvert(V, pygetitem(x, k2))
5153
end
5254

5355
function Base.setindex!(x::PyDict{K,V}, v, k) where {K,V}
@@ -58,7 +60,8 @@ end
5860
function Base.delete!(x::PyDict{K,V}, k) where {K,V}
5961
r = pyconvert_tryconvert(K, k)
6062
if !pyconvert_isunconverted(r)
61-
pydelitem(x, pyconvert_result(K, r))
63+
k2 = pyconvert_result(K, r)
64+
pycontains(x, k2) && pydelitem(x, k2)
6265
end
6366
return x
6467
end

src/pywrap/PyList.jl

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,9 @@ Base.@propagate_inbounds function Base.pop!(x::PyList{T}) where {T}
7070
return pyconvert(T, @py x.pop())
7171
end
7272

73-
if isdefined(Base, :popat!)
74-
Base.@propagate_inbounds function Base.popat!(x::PyList{T}, i::Integer) where {T}
75-
@boundscheck checkbounds(x, i)
76-
return pyconvert(T, @py x.pop(@jl(i-1)))
77-
end
73+
Base.@propagate_inbounds function Base.popat!(x::PyList{T}, i::Integer) where {T}
74+
@boundscheck checkbounds(x, i)
75+
return pyconvert(T, @py x.pop(@jl(i-1)))
7876
end
7977

8078
Base.@propagate_inbounds function Base.popfirst!(x::PyList{T}) where {T}

test/pywrap.jl

Lines changed: 251 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,269 @@
22
end
33

44
@testset "PyDict" begin
5+
x = pydict(["foo"=>12])
6+
y = PyDict(x)
7+
z = PyDict{String,Int}(x)
8+
@testset "construct" begin
9+
@test y isa PyDict{Py,Py}
10+
@test PyDict{String}(x) isa PyDict{String,Py}
11+
@test z isa PyDict{String,Int}
12+
@test PythonCall.ispy(y)
13+
@test PythonCall.ispy(z)
14+
@test Py(y) === x
15+
@test Py(z) === x
16+
end
17+
@testset "length" begin
18+
@test length(y) == 1
19+
@test length(z) == 1
20+
end
521
@testset "copy" begin
6-
x = PyDict{String,Int}()
7-
x["foo"] = 12
8-
y = copy(x)
9-
@test y isa PyDict{String,Int}
10-
y["bar"] = 34
11-
@test x == Dict("foo"=>12)
12-
@test y == Dict("foo"=>12, "bar"=>34)
22+
t = copy(z)
23+
@test t isa PyDict{String,Int}
24+
@test !pyis(t, z)
25+
t["bar"] = 34
26+
@test z == Dict("foo"=>12)
27+
@test t == Dict("foo"=>12, "bar"=>34)
28+
end
29+
@testset "iterate" begin
30+
@test collect(z) == ["foo" => 12]
31+
end
32+
@testset "getindex" begin
33+
@test z["foo"] === 12
34+
@test_throws KeyError z["bar"]
35+
end
36+
@testset "setindex!" begin
37+
t = copy(z)
38+
@test setindex!(t, 34, "bar") === t
39+
@test t == Dict("foo"=>12, "bar"=>34)
40+
@test setindex!(t, 56, "foo") === t
41+
@test t == Dict("foo"=>56, "bar"=>34)
42+
@test_throws Exception setindex!(t, 0, nothing)
43+
@test_throws Exception setindex!(t, nothing, "foo")
44+
@test t == Dict("foo"=>56, "bar"=>34)
45+
end
46+
@testset "delete!" begin
47+
t = copy(z)
48+
@test delete!(t, "bar") === t
49+
@test t == Dict("foo"=>12)
50+
@test delete!(t, 0) === t
51+
@test t == Dict("foo"=>12)
52+
@test delete!(t, "foo") === t
53+
@test isempty(t)
54+
@test delete!(t, "foo") === t
55+
@test isempty(t)
56+
end
57+
@testset "empty!" begin
58+
t = copy(z)
59+
@test !isempty(t)
60+
@test empty!(t) === t
61+
@test isempty(t)
62+
end
63+
@testset "haskey" begin
64+
@test haskey(z, "foo")
65+
@test !haskey(z, "bar")
66+
@test !haskey(z, nothing)
67+
@test !haskey(z, 99)
68+
end
69+
@testset "get" begin
70+
t = copy(z)
71+
@test get(t, "foo", nothing) === 12
72+
@test get(t, "bar", nothing) === nothing
73+
@test get(t, nothing, missing) === missing
74+
@test get(t, 0, 1) === 1
75+
@test get(Vector, t, "foo") === 12
76+
@test get(Vector, t, "bar") == []
77+
@test t == Dict("foo"=>12)
78+
end
79+
@testset "get!" begin
80+
t = copy(z)
81+
@test get!(t, "foo", 0) === 12
82+
@test t == Dict("foo"=>12)
83+
@test get!(t, "bar", 0) === 0
84+
@test t == Dict("foo"=>12, "bar"=>0)
85+
@test get!(()->99, t, "foo") === 12
86+
@test t == Dict("foo"=>12, "bar"=>0)
87+
@test get!(()->99, t, "baz") === 99
88+
@test t == Dict("foo"=>12, "bar"=>0, "baz"=>99)
89+
@test_throws Exception get!(t, 0, 0)
90+
@test_throws Exception get!(t, "", "")
91+
@test_throws Exception get!(()->99, t, 0)
92+
@test_throws Exception get!(Vector, t, "")
93+
@test t == Dict("foo"=>12, "bar"=>0, "baz"=>99)
94+
end
95+
@testset "construct empty" begin
96+
@test PyDict() isa PyDict{Py,Py}
97+
@test PyDict{String}() isa PyDict{String,Py}
98+
@test PyDict{String,Int}() isa PyDict{String,Int}
99+
@test isempty(PyDict{String,Int}())
13100
end
14101
end
15102

16103
@testset "PyIO" begin
17104
end
18105

19106
@testset "PyIterable" begin
107+
x = pylist([1, 2, 3])
108+
y = PyIterable(x)
109+
z = PyIterable{Int}(x)
110+
@testset "construct" begin
111+
@test y isa PyIterable{Py}
112+
@test z isa PyIterable{Int}
113+
@test PythonCall.ispy(y)
114+
@test PythonCall.ispy(z)
115+
@test Py(y) === x
116+
@test Py(z) === x
117+
end
118+
@testset "iterate" begin
119+
@test Base.IteratorSize(typeof(y)) === Base.SizeUnknown()
120+
@test Base.IteratorSize(typeof(z)) === Base.SizeUnknown()
121+
@test eltype(y) == Py
122+
@test eltype(z) == Int
123+
@test collect(z) == [1, 2, 3]
124+
end
20125
end
21126

22127
@testset "PyList" begin
128+
x = pylist([1, 2, 3])
129+
y = PyList(x)
130+
z = PyList{Int}(x)
131+
@testset "construct" begin
132+
@test y isa PyList{Py}
133+
@test z isa PyList{Int}
134+
@test PythonCall.ispy(y)
135+
@test PythonCall.ispy(z)
136+
@test Py(y) === x
137+
@test Py(z) === x
138+
end
139+
@testset "length" begin
140+
@test length(y) == 3
141+
@test length(z) == 3
142+
end
143+
@testset "size" begin
144+
@test size(y) == (3,)
145+
@test size(z) == (3,)
146+
end
147+
@testset "getindex" begin
148+
@test y[1] isa Py
149+
@test pyeq(Bool, y[1], 1)
150+
@test pyeq(Bool, y[2], 2)
151+
@test pyeq(Bool, y[3], 3)
152+
@test_throws BoundsError y[-1]
153+
@test_throws BoundsError y[0]
154+
@test_throws BoundsError y[4]
155+
@test z[1] === 1
156+
@test z[2] === 2
157+
@test z[3] === 3
158+
@test_throws BoundsError z[-1]
159+
@test_throws BoundsError z[0]
160+
@test_throws BoundsError z[4]
161+
end
23162
@testset "copy" begin
24-
x = PyList{Int}([1, 2, 3])
25-
y = copy(x)
26-
@test y isa PyList{Int}
27-
push!(y, 99)
28-
@test x == [1, 2, 3]
29-
@test y == [1, 2, 3, 99]
163+
t = copy(z)
164+
@test t isa PyList{Int}
165+
push!(t, 99)
166+
@test z == [1, 2, 3]
167+
@test t == [1, 2, 3, 99]
168+
end
169+
@testset "setindex!" begin
170+
t = copy(z)
171+
@test setindex!(t, 11, 1) === t
172+
@test setindex!(t, 22.0, 2) === t
173+
@test setindex!(t, 66//2, 3) == t
174+
@test t == [11, 22, 33]
175+
@test_throws BoundsError t[-1] = 0
176+
@test_throws BoundsError t[0] = 0
177+
@test_throws BoundsError t[4] = 0
178+
@test t == [11, 22, 33]
179+
@test_throws Exception t[1] = nothing
180+
@test_throws Exception t[2] = missing
181+
@test_throws Exception t[3] = 4.5
182+
@test t == [11, 22, 33]
183+
end
184+
@testset "insert!" begin
185+
t = copy(z)
186+
@test insert!(t, 2, 11) === t
187+
@test t == [1, 11, 2, 3]
188+
@test insert!(t, 5, 33) === t
189+
@test t == [1, 11, 2, 3, 33]
190+
@test_throws BoundsError insert!(t, -1, 0)
191+
@test_throws BoundsError insert!(t, 0, 0)
192+
@test_throws BoundsError insert!(t, 7, 0)
193+
@test t == [1, 11, 2, 3, 33]
194+
@test_throws Exception insert!(t, nothing, 2)
195+
@test t == [1, 11, 2, 3, 33]
196+
end
197+
@testset "push!" begin
198+
t = copy(z)
199+
@test push!(t, 4) === t
200+
@test t == [1, 2, 3, 4]
201+
@test push!(t, 5, 6) === t
202+
@test t == [1, 2, 3, 4, 5, 6]
203+
@test_throws Exception push!(t, missing)
204+
@test t == [1, 2, 3, 4, 5, 6]
205+
end
206+
@testset "pushfirst!" begin
207+
t = copy(z)
208+
@test pushfirst!(t, -1) === t
209+
@test t == [-1, 1, 2, 3]
210+
@test pushfirst!(t, -3, -2) === t
211+
@test t == [-3, -2, -1, 1, 2, 3]
212+
@test_throws Exception pushfirst!(t, 4.5)
213+
@test t == [-3, -2, -1, 1, 2, 3]
214+
end
215+
@testset "append!" begin
216+
t = copy(z)
217+
@test append!(t, [4, 5, 6]) === t
218+
@test t == [1, 2, 3, 4, 5, 6]
219+
@test_throws Exception append!(t, [nothing, missing])
220+
@test t == [1, 2, 3, 4, 5, 6]
221+
end
222+
@testset "pop!" begin
223+
t = copy(z)
224+
@test pop!(t) == 3
225+
@test pop!(t) == 2
226+
@test pop!(t) == 1
227+
@test isempty(t)
228+
@test_throws BoundsError pop!(t)
229+
end
230+
@testset "popfirst!" begin
231+
t = copy(z)
232+
@test popfirst!(t) == 1
233+
@test popfirst!(t) == 2
234+
@test popfirst!(t) == 3
235+
@test isempty(t)
236+
@test_throws BoundsError popfirst!(t)
237+
end
238+
@testset "popat!" begin
239+
t = copy(z)
240+
@test_throws BoundsError popat!(t, 0)
241+
@test_throws BoundsError popat!(t, 4)
242+
@test t == [1, 2, 3]
243+
@test popat!(t, 2) == 2
244+
@test popat!(t, 2) == 3
245+
@test popat!(t, 1) == 1
246+
@test isempty(t)
247+
@test_throws BoundsError popat!(t, 1)
248+
@test_throws BoundsError popat!(t, 0)
249+
@test_throws BoundsError popat!(t, 1)
250+
@test_throws BoundsError popat!(t, 5)
251+
end
252+
@testset "reverse!" begin
253+
t = copy(z)
254+
@test reverse!(t) === t
255+
@test t == [3, 2, 1]
256+
end
257+
@testset "empty!" begin
258+
t = copy(z)
259+
@test !isempty(t)
260+
@test empty!(t) === t
261+
@test isempty(t)
262+
end
263+
@testset "construct empty" begin
264+
t = PyList{Int}()
265+
@test t isa PyList{Int}
266+
@test isempty(t)
267+
@test pyisinstance(t, pybuiltins.list)
30268
end
31269
end
32270

0 commit comments

Comments
 (0)