forked from JuliaPy/PythonCall.jl
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPyList.jl
More file actions
103 lines (82 loc) · 2.38 KB
/
PyList.jl
File metadata and controls
103 lines (82 loc) · 2.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
"""
PyList{T=Py}([x])
Wraps the Python list `x` (or anything satisfying the sequence interface) as an `AbstractVector{T}`.
If `x` is not a Python object, it is converted to one using `pylist`.
"""
struct PyList{T} <: AbstractVector{T}
py::Py
PyList{T}(x = pylist()) where {T} = new{T}(ispy(x) ? Py(x) : pylist(x))
end
export PyList
PyList(x = pylist()) = PyList{Py}(x)
ispy(::PyList) = true
Py(x::PyList) = x.py
function pyconvert_rule_sequence(
::Type{T},
x::Py,
::Type{T1} = Utils._type_ub(T),
) where {T<:PyList,T1}
pyconvert_return(T1(x))
end
Base.length(x::PyList) = Int(pylen(x))
Base.size(x::PyList) = (length(x),)
Base.@propagate_inbounds function Base.getindex(x::PyList{T}, i::Int) where {T}
@boundscheck checkbounds(x, i)
return pyconvert(T, @py x[@jl(i - 1)])
end
Base.@propagate_inbounds function Base.setindex!(x::PyList{T}, v, i::Int) where {T}
@boundscheck checkbounds(x, i)
pysetitem(x, i - 1, convert(T, v))
return x
end
Base.@propagate_inbounds function Base.insert!(x::PyList{T}, i::Integer, v) where {T}
@boundscheck (i == length(x) + 1 || checkbounds(x, i))
pydel!(@py x.insert(@jl(i - 1), @jl(convert(T, v))))
return x
end
function Base.push!(x::PyList{T}, v) where {T}
pydel!(@py x.append(@jl(convert(T, v))))
return x
end
function Base.pushfirst!(x::PyList, v)
return @inbounds Base.insert!(x, 1, v)
end
function Base.append!(x::PyList, vs)
for v in vs
push!(x, v)
end
return x
end
function Base.prepend!(x::PyList, vs)
for v in reverse(vs)
pushfirst!(x, v)
end
return x
end
function Base.push!(x::PyList, v1, v2, vs...)
push!(x, v1)
push!(x, v2, vs...)
end
Base.@propagate_inbounds function Base.pop!(x::PyList{T}) where {T}
@boundscheck (isempty(x) && throw(BoundsError(x)))
return pyconvert(T, @py x.pop())
end
Base.@propagate_inbounds function Base.popat!(x::PyList{T}, i::Integer) where {T}
@boundscheck checkbounds(x, i)
return pyconvert(T, @py x.pop(@jl(i - 1)))
end
Base.@propagate_inbounds function Base.popfirst!(x::PyList{T}) where {T}
@boundscheck checkbounds(x, 1)
return pyconvert(T, @py x.pop(0))
end
function Base.reverse!(x::PyList)
pydel!(@py x.reverse())
return x
end
function Base.empty!(x::PyList)
pydel!(@py x.clear())
return x
end
function Base.copy(x::PyList{T}) where {T}
return PyList{T}(@py x.copy())
end