8383
8484function 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))
108108end
109109
110- # N-Tuple for N up to 16
111- # TODO : Vararg
112-
113110for 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
124142end
125143
126144# Pair
0 commit comments