Skip to content

Commit 2eb6abf

Browse files
author
Christopher Doris
committed
fix tuple conversion bug
1 parent 0148fd2 commit 2eb6abf

File tree

3 files changed

+37
-8
lines changed

3 files changed

+37
-8
lines changed

src/abstract/collection.jl

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,14 @@ end
8383

8484
function pyconvert_rule_iterable(::Type{T}, xs::Py) where {T<:Tuple}
8585
T isa DataType || return pyconvert_unconverted()
86-
ts = collect(T.parameters)
87-
if !isempty(ts) && Base.isvarargtype(ts[end])
86+
if T != Tuple{} && Tuple{T.parameters[end]} == Base.tuple_type_tail(Tuple{T.parameters[end]})
8887
isvararg = true
89-
vartype = ts[end].body.parameters[1]::Type
90-
pop!(ts)
88+
vartype = Base.tuple_type_head(Tuple{T.parameters[end]})
89+
ts = T.parameters[1:end-1]
9190
else
9291
isvararg = false
9392
vartype = Union{}
93+
ts = T.parameters
9494
end
9595
zs = Any[]
9696
for x in xs
@@ -107,20 +107,38 @@ function pyconvert_rule_iterable(::Type{T}, xs::Py) where {T<:Tuple}
107107
return length(zs) < length(ts) ? pyconvert_unconverted() : pyconvert_return(T(zs))
108108
end
109109

110-
# N-Tuple for N up to 16
111-
# TODO: Vararg
112-
113110
for N in 0:16
114111
Ts = [Symbol("T", n) for n in 1:N]
115112
zs = [Symbol("z", n) for n in 1:N]
113+
# Tuple with N elements
116114
@eval function pyconvert_rule_iterable(::Type{Tuple{$(Ts...)}}, xs::Py) where {$(Ts...)}
117-
pylen(xs) == $N || return pyconvert_unconverted()
115+
xs = pytuple(xs)
116+
n = pylen(xs)
117+
n == $N || return pyconvert_unconverted()
118118
$((
119119
:($z = @pyconvert_and_del($T, pytuple_getitem(xs, $(i-1))))
120120
for (i, T, z) in zip(1:N, Ts, zs)
121121
)...)
122+
pydel!(xs)
122123
return pyconvert_return(($(zs...),))
123124
end
125+
# Tuple with N elements plus Vararg
126+
@eval function pyconvert_rule_iterable(::Type{Tuple{$(Ts...),Vararg{V}}}, xs::Py) where {$(Ts...),V}
127+
xs = pytuple(xs)
128+
n = pylen(xs)
129+
n $N || return pyconvert_unconverted()
130+
$((
131+
:($z = @pyconvert_and_del($T, pytuple_getitem(xs, $(i-1))))
132+
for (i, T, z) in zip(1:N, Ts, zs)
133+
)...)
134+
vs = V[]
135+
for i in $(N+1):n
136+
v = @pyconvert_and_del(V, pytuple_getitem(xs, i-1))
137+
push!(vs, v)
138+
end
139+
pydel!(xs)
140+
return pyconvert_return(($(zs...), vs...))
141+
end
124142
end
125143

126144
# Pair

test/convert.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
@testset "iterable -> Tuple" begin
2+
t1 = pyconvert(Tuple, (1, 2))
3+
@test t1 === (1, 2)
4+
t2 = pyconvert(Tuple{Vararg{Int}}, (3, 4, 5))
5+
@test t2 === (3, 4, 5)
6+
t3 = pyconvert(Tuple{Int,Int}, (6, 7))
7+
@test t3 === (6, 7)
8+
end

test/runtests.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ Aqua.test_all(PythonCall)
99
@testset "concrete" begin
1010
include("concrete.jl")
1111
end
12+
@testset "convert" begin
13+
include("convert.jl")
14+
end
1215
@testset "jlwrap" begin
1316
include("jlwrap.jl")
1417
end

0 commit comments

Comments
 (0)