Skip to content

Commit f832d77

Browse files
committed
Replace almost all ccall with @CCall
1 parent 7bdfe5f commit f832d77

15 files changed

+162
-177
lines changed

src/PyCall.jl

Lines changed: 42 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,6 @@ import Base: size, ndims, similar, copy, getindex, setindex!, stride,
2020
append!, insert!, prepend!, unsafe_convert
2121
import Compat: pushfirst!, popfirst!, firstindex, lastindex
2222

23-
# Python C API is not interrupt-safe. In principle, we should
24-
# use sigatomic for every ccall to the Python library, but this
25-
# should really be fixed in Julia (#2622). However, we will
26-
# use the sigatomic_begin/end functions to protect pycall and
27-
# similar long-running (or potentially long-running) code.
2823
import Base: sigatomic_begin, sigatomic_end
2924

3025
import Conda
@@ -36,6 +31,21 @@ import Base.Iterators: filter
3631
include(joinpath(dirname(@__FILE__), "..", "deps","depsutils.jl"))
3732
include("startup.jl")
3833

34+
# Python C API is not interrupt-safe. In principle, we should
35+
# use sigatomic for every ccall to the Python library, but this
36+
# should really be fixed in Julia (#2622). However, we will
37+
# use the `disable_sigint` function to protect *all* invocations
38+
# of Python API. This is required since `pyjlwrap_call` uses
39+
# `reenable_sigint` which has to be called within `disable_sigint`
40+
# context.
41+
macro ccall(args...)
42+
quote
43+
disable_sigint() do
44+
ccall($(esc.(args)...))
45+
end
46+
end
47+
end
48+
3949
#########################################################################
4050

4151
# Mirror of C PyObject struct (for non-debugging Python builds).
@@ -99,7 +109,7 @@ it is equivalent to a `PyNULL()` object.
99109
ispynull(o::PyObject) = o.o == PyPtr_NULL
100110

101111
function pydecref_(o::Union{PyPtr,PyObject})
102-
ccall(@pysym(:Py_DecRef), Cvoid, (PyPtr,), o)
112+
@ccall(@pysym(:Py_DecRef), Cvoid, (PyPtr,), o)
103113
return o
104114
end
105115

@@ -110,7 +120,7 @@ function pydecref(o::PyObject)
110120
end
111121

112122
function pyincref_(o::Union{PyPtr,PyObject})
113-
ccall((@pysym :Py_IncRef), Cvoid, (PyPtr,), o)
123+
@ccall((@pysym :Py_IncRef), Cvoid, (PyPtr,), o)
114124
return o
115125
end
116126

@@ -150,13 +160,13 @@ function Base.copy!(dest::PyObject, src::PyObject)
150160
end
151161

152162
pyisinstance(o::PyObject, t::PyObject) =
153-
!ispynull(t) && ccall((@pysym :PyObject_IsInstance), Cint, (PyPtr,PyPtr), o, t.o) == 1
163+
!ispynull(t) && @ccall((@pysym :PyObject_IsInstance), Cint, (PyPtr,PyPtr), o, t.o) == 1
154164

155165
pyisinstance(o::PyObject, t::Union{Ptr{Cvoid},PyPtr}) =
156-
t != C_NULL && ccall((@pysym :PyObject_IsInstance), Cint, (PyPtr,PyPtr), o, t) == 1
166+
t != C_NULL && @ccall((@pysym :PyObject_IsInstance), Cint, (PyPtr,PyPtr), o, t) == 1
157167

158168
pyquery(q::Ptr{Cvoid}, o::PyObject) =
159-
ccall(q, Cint, (PyPtr,), o) == 1
169+
@ccall(q, Cint, (PyPtr,), o) == 1
160170

161171
# conversion to pass PyObject as ccall arguments:
162172
unsafe_convert(::Type{PyPtr}, po::PyObject) = po.o
@@ -171,7 +181,7 @@ PyObject(o::PyObject) = o
171181
include("exception.jl")
172182
include("gui.jl")
173183

174-
pytypeof(o::PyObject) = ispynull(o) ? throw(ArgumentError("NULL PyObjects have no Python type")) : PyObject(@pycheckn ccall(@pysym(:PyObject_Type), PyPtr, (PyPtr,), o))
184+
pytypeof(o::PyObject) = ispynull(o) ? throw(ArgumentError("NULL PyObjects have no Python type")) : PyObject(@pycheckn @ccall(@pysym(:PyObject_Type), PyPtr, (PyPtr,), o))
175185

176186
#########################################################################
177187

@@ -201,7 +211,7 @@ PyObject(o::PyPtr, keep::Any) = pyembed(PyObject(o), keep)
201211
Return a string representation of `o` corresponding to `str(o)` in Python.
202212
"""
203213
pystr(o::PyObject) = convert(AbstractString,
204-
PyObject(@pycheckn ccall((@pysym :PyObject_Str), PyPtr,
214+
PyObject(@pycheckn @ccall((@pysym :PyObject_Str), PyPtr,
205215
(PyPtr,), o)))
206216

207217
"""
@@ -210,7 +220,7 @@ pystr(o::PyObject) = convert(AbstractString,
210220
Return a string representation of `o` corresponding to `repr(o)` in Python.
211221
"""
212222
pyrepr(o::PyObject) = convert(AbstractString,
213-
PyObject(@pycheckn ccall((@pysym :PyObject_Repr), PyPtr,
223+
PyObject(@pycheckn @ccall((@pysym :PyObject_Repr), PyPtr,
214224
(PyPtr,), o)))
215225

216226
"""
@@ -224,10 +234,10 @@ function pystring(o::PyObject)
224234
if ispynull(o)
225235
return "NULL"
226236
else
227-
s = ccall((@pysym :PyObject_Repr), PyPtr, (PyPtr,), o)
237+
s = @ccall((@pysym :PyObject_Repr), PyPtr, (PyPtr,), o)
228238
if (s == C_NULL)
229239
pyerr_clear()
230-
s = ccall((@pysym :PyObject_Str), PyPtr, (PyPtr,), o)
240+
s = @ccall((@pysym :PyObject_Str), PyPtr, (PyPtr,), o)
231241
if (s == C_NULL)
232242
pyerr_clear()
233243
return string(o.o)
@@ -265,7 +275,7 @@ function hash(o::PyObject)
265275
# since on 64-bit Windows the Python 2.x hash is only 32 bits
266276
hashsalt(unsafe_pyjlwrap_to_objref(o.o))
267277
else
268-
h = ccall((@pysym :PyObject_Hash), Py_hash_t, (PyPtr,), o)
278+
h = @ccall((@pysym :PyObject_Hash), Py_hash_t, (PyPtr,), o)
269279
if h == -1 # error
270280
pyerr_clear()
271281
return hashsalt(o.o)
@@ -283,7 +293,7 @@ function getindex(o::PyObject, s::AbstractString)
283293
if ispynull(o)
284294
throw(ArgumentError("ref of NULL PyObject"))
285295
end
286-
p = ccall((@pysym :PyObject_GetAttrString), PyPtr, (PyPtr, Cstring), o, s)
296+
p = @ccall((@pysym :PyObject_GetAttrString), PyPtr, (PyPtr, Cstring), o, s)
287297
if p == C_NULL
288298
pyerr_clear()
289299
throw(KeyError(s))
@@ -297,7 +307,7 @@ function setindex!(o::PyObject, v, s::Union{Symbol,AbstractString})
297307
if ispynull(o)
298308
throw(ArgumentError("assign of NULL PyObject"))
299309
end
300-
if -1 == ccall((@pysym :PyObject_SetAttrString), Cint,
310+
if -1 == @ccall((@pysym :PyObject_SetAttrString), Cint,
301311
(PyPtr, Cstring, PyPtr), o, s, PyObject(v))
302312
pyerr_clear()
303313
throw(KeyError(s))
@@ -309,7 +319,7 @@ function haskey(o::PyObject, s::Union{Symbol,AbstractString})
309319
if ispynull(o)
310320
throw(ArgumentError("haskey of NULL PyObject"))
311321
end
312-
return 1 == ccall((@pysym :PyObject_HasAttrString), Cint,
322+
return 1 == @ccall((@pysym :PyObject_HasAttrString), Cint,
313323
(PyPtr, Cstring), o, s)
314324
end
315325

@@ -408,7 +418,7 @@ end
408418
function _pyimport(name::AbstractString)
409419
cookie = ActivatePyActCtx()
410420
try
411-
return PyObject(ccall((@pysym :PyImport_ImportModule), PyPtr, (Cstring,), name))
421+
return PyObject(@ccall((@pysym :PyImport_ImportModule), PyPtr, (Cstring,), name))
412422
finally
413423
DeactivatePyActCtx(cookie)
414424
end
@@ -709,7 +719,7 @@ include("pyfncall.jl")
709719
# for now we can define "get".
710720

711721
function get(o::PyObject, returntype::TypeTuple, k, default)
712-
r = ccall((@pysym :PyObject_GetItem), PyPtr, (PyPtr,PyPtr), o,PyObject(k))
722+
r = @ccall((@pysym :PyObject_GetItem), PyPtr, (PyPtr,PyPtr), o,PyObject(k))
713723
if r == C_NULL
714724
pyerr_clear()
715725
default
@@ -719,22 +729,22 @@ function get(o::PyObject, returntype::TypeTuple, k, default)
719729
end
720730

721731
get(o::PyObject, returntype::TypeTuple, k) =
722-
convert(returntype, PyObject(@pycheckn ccall((@pysym :PyObject_GetItem),
732+
convert(returntype, PyObject(@pycheckn @ccall((@pysym :PyObject_GetItem),
723733
PyPtr, (PyPtr,PyPtr), o, PyObject(k))))
724734

725735
get(o::PyObject, k, default) = get(o, PyAny, k, default)
726736
get(o::PyObject, k) = get(o, PyAny, k)
727737

728738
function delete!(o::PyObject, k)
729-
e = ccall((@pysym :PyObject_DelItem), Cint, (PyPtr, PyPtr), o, PyObject(k))
739+
e = @ccall((@pysym :PyObject_DelItem), Cint, (PyPtr, PyPtr), o, PyObject(k))
730740
if e == -1
731741
pyerr_clear() # delete! ignores errors in Julia
732742
end
733743
return o
734744
end
735745

736746
function set!(o::PyObject, k, v)
737-
@pycheckz ccall((@pysym :PyObject_SetItem), Cint, (PyPtr, PyPtr, PyPtr),
747+
@pycheckz @ccall((@pysym :PyObject_SetItem), Cint, (PyPtr, PyPtr, PyPtr),
738748
o, PyObject(k), PyObject(v))
739749
v
740750
end
@@ -751,24 +761,24 @@ function ind2py(i::Integer)
751761
return i-1
752762
end
753763

754-
_getindex(o::PyObject, i::Integer, T) = convert(T, PyObject(@pycheckn ccall((@pysym :PySequence_GetItem), PyPtr, (PyPtr, Int), o, ind2py(i))))
764+
_getindex(o::PyObject, i::Integer, T) = convert(T, PyObject(@pycheckn @ccall((@pysym :PySequence_GetItem), PyPtr, (PyPtr, Int), o, ind2py(i))))
755765
getindex(o::PyObject, i::Integer) = _getindex(o, i, PyAny)
756766
function setindex!(o::PyObject, v, i::Integer)
757-
@pycheckz ccall((@pysym :PySequence_SetItem), Cint, (PyPtr, Int, PyPtr), o, ind2py(i), PyObject(v))
767+
@pycheckz @ccall((@pysym :PySequence_SetItem), Cint, (PyPtr, Int, PyPtr), o, ind2py(i), PyObject(v))
758768
v
759769
end
760770
getindex(o::PyObject, i1::Integer, i2::Integer) = get(o, (ind2py(i1),ind2py(i2)))
761771
setindex!(o::PyObject, v, i1::Integer, i2::Integer) = set!(o, (ind2py(i1),ind2py(i2)), v)
762772
getindex(o::PyObject, I::Integer...) = get(o, map(ind2py, I))
763773
setindex!(o::PyObject, v, I::Integer...) = set!(o, map(ind2py, I), v)
764-
length(o::PyObject) = @pycheckz ccall((@pysym :PySequence_Size), Int, (PyPtr,), o)
774+
length(o::PyObject) = @pycheckz @ccall((@pysym :PySequence_Size), Int, (PyPtr,), o)
765775
size(o::PyObject) = (length(o),)
766776
firstindex(o::PyObject) = 1
767777
lastindex(o::PyObject) = length(o)
768778

769779
function splice!(a::PyObject, i::Integer)
770780
v = a[i]
771-
@pycheckz ccall((@pysym :PySequence_DelItem), Cint, (PyPtr, Int), a, i-1)
781+
@pycheckz @ccall((@pysym :PySequence_DelItem), Cint, (PyPtr, Int), a, i-1)
772782
v
773783
end
774784

@@ -777,20 +787,20 @@ popfirst!(a::PyObject) = splice!(a, 1)
777787

778788
function empty!(a::PyObject)
779789
for i in length(a):-1:1
780-
@pycheckz ccall((@pysym :PySequence_DelItem), Cint, (PyPtr, Int), a, i-1)
790+
@pycheckz @ccall((@pysym :PySequence_DelItem), Cint, (PyPtr, Int), a, i-1)
781791
end
782792
a
783793
end
784794

785795
# The following operations only work for the list type and subtypes thereof:
786796
function push!(a::PyObject, item)
787-
@pycheckz ccall((@pysym :PyList_Append), Cint, (PyPtr, PyPtr),
797+
@pycheckz @ccall((@pysym :PyList_Append), Cint, (PyPtr, PyPtr),
788798
a, PyObject(item))
789799
a
790800
end
791801

792802
function insert!(a::PyObject, i::Integer, item)
793-
@pycheckz ccall((@pysym :PyList_Insert), Cint, (PyPtr, Int, PyPtr),
803+
@pycheckz @ccall((@pysym :PyList_Insert), Cint, (PyPtr, Int, PyPtr),
794804
a, ind2py(i), PyObject(item))
795805
a
796806
end
@@ -816,7 +826,7 @@ function append!(a::PyObject, items)
816826
end
817827

818828
append!(a::PyObject, items::PyObject) =
819-
PyObject(@pycheckn ccall((@pysym :PySequence_InPlaceConcat),
829+
PyObject(@pycheckn @ccall((@pysym :PySequence_InPlaceConcat),
820830
PyPtr, (PyPtr, PyPtr), a, items))
821831

822832
#########################################################################

0 commit comments

Comments
 (0)