Skip to content

Commit 609075b

Browse files
author
Christopher Doris
committed
another second off init
1 parent 7a8db65 commit 609075b

18 files changed

+1123
-1102
lines changed

src/PyRef.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ mutable struct PyRef
1818
ptr = x.ptr
1919
if !isnull(ptr)
2020
with_gil(false) do
21+
@assert C.Py_RefCnt(ptr) > 0
2122
C.Py_DecRef(ptr)
2223
end
2324
x.ptr = C_NULL

src/cpython/CPython.jl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ include("juliaio.jl")
100100
include("as.jl")
101101
include("arg.jl")
102102

103-
@init begin
103+
init() = begin
104104
PyObject_TryConvert_AddRule("builtins.NoneType", Nothing, PyNone_TryConvertRule_nothing, 100)
105105
PyObject_TryConvert_AddRule("builtins.NoneType", Missing, PyNone_TryConvertRule_missing)
106106
PyObject_TryConvert_AddRule("builtins.bool", Bool, PyBool_TryConvertRule_bool, 100)
@@ -150,6 +150,7 @@ include("arg.jl")
150150
PyObject_TryConvert_AddRule("datetime.timedelta", Dates.Period, PyTimeDelta_TryConvertRule_period, 100)
151151
PyObject_TryConvert_AddRule("datetime.timedelta", Dates.CompoundPeriod, PyTimeDelta_TryConvertRule_compoundperiod)
152152
PyObject_TryConvert_AddRule("juliacall.ValueBase", Any, PyJuliaValue_TryConvert_any, 1000)
153+
PyObject_TryConvert_AddRule("juliacall.As", Any, PyAs_ConvertRule_tryconvert, 1000)
153154
PyObject_TryConvert_AddExtraType(PyIterableABC_Type)
154155
PyObject_TryConvert_AddExtraType(PyCallableABC_Type)
155156
PyObject_TryConvert_AddExtraType(PySequenceABC_Type)
@@ -247,5 +248,10 @@ include("arg.jl")
247248
PyObject_TryConvert_AddRule("numpy.$p", Any, PyNumpySimpleData_TryConvert_value{T,true}())
248249
end
249250
end
251+
precompile(init, ())
252+
@init init()
253+
254+
precompile(PyJuliaValue_New, (PyPtr, Function))
255+
precompile(PyMappingABC_Type, ())
250256

251257
end

src/cpython/as.jl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
@init PyObject_TryConvert_AddRule("juliacall.As", Any, PyAs_ConvertRule_tryconvert)
2-
31
PyAs_ConvertRule_tryconvert(o, ::Type{S}) where {S} = begin
42
# get the type
53
to = PyObject_GetAttrString(o, "type")

src/cpython/juliaany.jl

Lines changed: 85 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,3 @@
1-
const PyJuliaAnyValue_Type__ref = Ref(PyNULL)
2-
PyJuliaAnyValue_Type() = begin
3-
ptr = PyJuliaAnyValue_Type__ref[]
4-
if isnull(ptr)
5-
c = []
6-
base = PyJuliaBaseValue_Type()
7-
isnull(base) && return PyNULL
8-
t = fill(
9-
PyType_Create(
10-
c,
11-
name = "juliacall.AnyValue",
12-
base = base,
13-
repr = pyjlany_repr,
14-
str = pyjlany_str,
15-
getattro = pyjlany_getattro,
16-
setattro = pyjlany_setattro,
17-
call = pyjlany_call,
18-
iter = pyjlany_iter,
19-
richcompare = pyjlany_richcompare,
20-
as_mapping = (
21-
length = pyjlany_length,
22-
subscript = pyjlany_getitem,
23-
ass_subscript = pyjlany_setitem,
24-
),
25-
as_sequence = (contains = pyjlany_contains,),
26-
as_number = (
27-
positive = pyjlany_positive,
28-
negative = pyjlany_negative,
29-
absolute = pyjlany_absolute,
30-
power = pyjlany_power,
31-
add = pyjlany_binop(+),
32-
subtract = pyjlany_binop(-),
33-
multiply = pyjlany_binop(*),
34-
truedivide = pyjlany_binop(/),
35-
divmod = pyjlany_binop((x, y) -> (fld(x, y), mod(x, y))),
36-
floordivide = pyjlany_binop(fld),
37-
remainder = pyjlany_binop(mod),
38-
lshift = pyjlany_binop(<<),
39-
rshift = pyjlany_binop(>>),
40-
and = pyjlany_binop(&),
41-
xor = pyjlany_binop(xor),
42-
or = pyjlany_binop(|),
43-
),
44-
methods = [
45-
(name = "__dir__", flags = Py_METH_NOARGS, meth = pyjlany_dir),
46-
(name = "_repr_mimebundle_", flags = Py_METH_VARARGS | Py_METH_KEYWORDS, meth = pyjlany_repr_mimebundle),
47-
(name = "_jl_raw", flags = Py_METH_NOARGS, meth = pyjlany_toraw),
48-
(name = "_jl_display", flags = Py_METH_NOARGS, meth = pyjlany_display),
49-
(name = "_jl_help", flags = Py_METH_NOARGS, meth = pyjlany_help),
50-
],
51-
getset = [(name = "__name__", get = pyjlany_name)],
52-
),
53-
)
54-
ptr = PyPtr(pointer(t))
55-
err = PyType_Ready(ptr)
56-
ism1(err) && return PyNULL
57-
PYJLGCCACHE[ptr] = push!(c, t)
58-
PyJuliaAnyValue_Type__ref[] = ptr
59-
end
60-
ptr
61-
end
62-
63-
PyJuliaAnyValue_New(x) = PyJuliaValue_New(PyJuliaAnyValue_Type(), x)
64-
PyJuliaValue_From(x) = PyJuliaAnyValue_New(x)
65-
661
pyjlany_repr(xo::PyPtr) =
672
try
683
x = PyJuliaValue_GetValue(xo)
@@ -553,3 +488,88 @@ pyjlany_power(xo::PyPtr, yo::PyPtr, zo::PyPtr) = begin
553488
end
554489
end
555490
end
491+
492+
PyJuliaAnyValue_New(x) = PyJuliaValue_New(PyJuliaAnyValue_Type(), x)
493+
PyJuliaValue_From(x) = PyJuliaAnyValue_New(x)
494+
495+
const PyJuliaAnyValue_Type = LazyPyObject() do
496+
c = []
497+
base = PyJuliaBaseValue_Type()
498+
isnull(base) && return PyNULL
499+
ptr = PyPtr(cacheptr!(c, fill(PyTypeObject(
500+
name = cacheptr!(c, "juliacall.AnyValue"),
501+
base = base,
502+
repr = @cfunctionOO(pyjlany_repr),
503+
str = @cfunctionOO(pyjlany_str),
504+
getattro = @cfunctionOOO(pyjlany_getattro),
505+
setattro = @cfunctionIOOO(pyjlany_setattro),
506+
call = @cfunctionOOOO(pyjlany_call),
507+
iter = @cfunctionOO(pyjlany_iter),
508+
richcompare = @cfunctionOOOI(pyjlany_richcompare),
509+
as_mapping = cacheptr!(c, fill(PyMappingMethods(
510+
length = @cfunctionZO(pyjlany_length),
511+
subscript = @cfunctionOOO(pyjlany_getitem),
512+
ass_subscript = @cfunctionIOOO(pyjlany_setitem),
513+
))),
514+
as_sequence = cacheptr!(c, fill(PySequenceMethods(
515+
contains = @cfunctionIOO(pyjlany_contains),
516+
))),
517+
as_number = cacheptr!(c, fill(PyNumberMethods(
518+
positive = @cfunctionOO(pyjlany_positive),
519+
negative = @cfunctionOO(pyjlany_negative),
520+
absolute = @cfunctionOO(pyjlany_absolute),
521+
power = @cfunctionOOOO(pyjlany_power),
522+
add = @cfunctionOOO(pyjlany_binop(+)),
523+
subtract = @cfunctionOOO(pyjlany_binop(-)),
524+
multiply = @cfunctionOOO(pyjlany_binop(*)),
525+
truedivide = @cfunctionOOO(pyjlany_binop(/)),
526+
divmod = @cfunctionOOO(pyjlany_binop((x,y) -> (fld(x,y), mod(x,y)))),
527+
floordivide = @cfunctionOOO(pyjlany_binop(fld)),
528+
remainder = @cfunctionOOO(pyjlany_binop(mod)),
529+
lshift = @cfunctionOOO(pyjlany_binop(<<)),
530+
rshift = @cfunctionOOO(pyjlany_binop(>>)),
531+
and = @cfunctionOOO(pyjlany_binop(&)),
532+
xor = @cfunctionOOO(pyjlany_binop()),
533+
or = @cfunctionOOO(pyjlany_binop(|)),
534+
))),
535+
methods = cacheptr!(c, [
536+
PyMethodDef(
537+
name = cacheptr!(c, "__dir__"),
538+
flags = Py_METH_NOARGS,
539+
meth = @cfunctionOOO(pyjlany_dir),
540+
),
541+
PyMethodDef(
542+
name = cacheptr!(c, "_repr_mimebundle_"),
543+
flags = Py_METH_VARARGS | Py_METH_KEYWORDS,
544+
meth = @cfunctionOOOO(pyjlany_repr_mimebundle),
545+
),
546+
PyMethodDef(
547+
name = cacheptr!(c, "_jl_raw"),
548+
flags = Py_METH_NOARGS,
549+
meth = @cfunctionOOO(pyjlany_toraw),
550+
),
551+
PyMethodDef(
552+
name = cacheptr!(c, "_jl_display"),
553+
flags = Py_METH_NOARGS,
554+
meth = @cfunctionOOO(pyjlany_display),
555+
),
556+
PyMethodDef(
557+
name = cacheptr!(c, "_jl_help"),
558+
flags = Py_METH_NOARGS,
559+
meth = @cfunctionOOO(pyjlany_help),
560+
),
561+
PyMethodDef(),
562+
]),
563+
getset = cacheptr!(c, [
564+
PyGetSetDef(
565+
name = cacheptr!(c, "__name__"),
566+
get = @cfunctionOOP(pyjlany_name),
567+
),
568+
PyGetSetDef(),
569+
])
570+
))))
571+
err = PyType_Ready(ptr)
572+
ism1(err) && return PyNULL
573+
PYJLGCCACHE[ptr] = c
574+
return ptr
575+
end

src/cpython/juliaarray.jl

Lines changed: 63 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,3 @@
1-
const PyJuliaArrayValue_Type__ref = Ref(PyNULL)
2-
PyJuliaArrayValue_Type() = begin
3-
ptr = PyJuliaArrayValue_Type__ref[]
4-
if isnull(ptr)
5-
c = []
6-
base = PyJuliaAnyValue_Type()
7-
isnull(base) && return PyNULL
8-
t = fill(
9-
PyType_Create(
10-
c,
11-
name = "juliacall.ArrayValue",
12-
base = base,
13-
as_mapping = (
14-
subscript = pyjlarray_getitem,
15-
ass_subscript = pyjlarray_setitem,
16-
),
17-
as_buffer = (
18-
get = pyjlarray_get_buffer,
19-
release = pyjlarray_release_buffer,
20-
),
21-
getset = [
22-
(name = "ndim", get = pyjlarray_ndim),
23-
(name = "shape", get = pyjlarray_shape),
24-
(name = "__array_interface__", get = pyjlarray_array_interface),
25-
],
26-
methods = [
27-
(name = "copy", flags = Py_METH_NOARGS, meth = pyjlarray_copy),
28-
(name = "reshape", flags = Py_METH_O, meth = pyjlarray_reshape),
29-
(name = "__array__", flags = Py_METH_NOARGS, meth = pyjlarray_array),
30-
],
31-
),
32-
)
33-
ptr = PyPtr(pointer(t))
34-
err = PyType_Ready(ptr)
35-
ism1(err) && return PyNULL
36-
for abcf in (CONFIG.version < v"3.6" ? (PyContainerABC_Type, PyIterableABC_Type, PySizedABC_Type) : (PyCollectionABC_Type,))
37-
abc = abcf()
38-
isnull(abc) && return PyNULL
39-
ism1(PyABC_Register(ptr, abc)) && return PyNULL
40-
end
41-
PYJLGCCACHE[ptr] = push!(c, t)
42-
PyJuliaArrayValue_Type__ref[] = ptr
43-
end
44-
ptr
45-
end
46-
47-
PyJuliaArrayValue_New(x::AbstractArray) = PyJuliaValue_New(PyJuliaArrayValue_Type(), x)
48-
PyJuliaValue_From(x::AbstractArray) = PyJuliaArrayValue_New(x)
49-
501
pyjl_getaxisindex(x::AbstractUnitRange{<:Integer}, ko::PyPtr) = begin
512
if PySlice_Check(ko)
523
ao, co, bo = PySimpleObject_GetValue(ko, Tuple{PyPtr,PyPtr,PyPtr})
@@ -504,3 +455,66 @@ pyjlarray_array(xo::PyPtr, ::PyPtr) = begin
504455
ao
505456
end
506457
end
458+
459+
const PyJuliaArrayValue_Type = LazyPyObject() do
460+
c = []
461+
base = PyJuliaAnyValue_Type()
462+
isnull(base) && return PyNULL
463+
ptr = PyPtr(cacheptr!(c, fill(PyTypeObject(
464+
name = cacheptr!(c, "juliacall.ArrayValue"),
465+
base = base,
466+
as_mapping = cacheptr!(c, fill(PyMappingMethods(
467+
subscript = @cfunctionOOO(pyjlarray_getitem),
468+
ass_subscript = @cfunctionIOOO(pyjlarray_setitem),
469+
))),
470+
as_buffer = cacheptr!(c, fill(PyBufferProcs(
471+
get = @cfunction(pyjlarray_get_buffer, Cint, (PyPtr, Ptr{Py_buffer}, Cint)),
472+
release = @cfunction(pyjlarray_release_buffer, Cvoid, (PyPtr, Ptr{Py_buffer})),
473+
))),
474+
getset = cacheptr!(c, [
475+
PyGetSetDef(
476+
name = cacheptr!(c, "ndim"),
477+
get = @cfunctionOOP(pyjlarray_ndim),
478+
),
479+
PyGetSetDef(
480+
name = cacheptr!(c, "shape"),
481+
get = @cfunctionOOP(pyjlarray_shape),
482+
),
483+
PyGetSetDef(
484+
name = cacheptr!(c, "__array_interface__"),
485+
get = @cfunctionOOP(pyjlarray_array_interface),
486+
),
487+
PyGetSetDef(),
488+
]),
489+
methods = cacheptr!(c, [
490+
PyMethodDef(
491+
name = cacheptr!(c, "copy"),
492+
flags = Py_METH_NOARGS,
493+
meth = @cfunctionOOO(pyjlarray_copy),
494+
),
495+
PyMethodDef(
496+
name = cacheptr!(c, "reshape"),
497+
flags = Py_METH_O,
498+
meth = @cfunctionOOO(pyjlarray_reshape),
499+
),
500+
PyMethodDef(
501+
name = cacheptr!(c, "__array__"),
502+
flags = Py_METH_NOARGS,
503+
meth = @cfunctionOOO(pyjlarray_array),
504+
),
505+
PyMethodDef(),
506+
])
507+
))))
508+
err = PyType_Ready(ptr)
509+
ism1(err) && return PyNULL
510+
for abcf in (CONFIG.version < v"3.6" ? (PyContainerABC_Type, PyIterableABC_Type, PySizedABC_Type) : (PyCollectionABC_Type,))
511+
abc = abcf()
512+
isnull(abc) && return PyNULL
513+
ism1(PyABC_Register(ptr, abc)) && return PyNULL
514+
end
515+
PYJLGCCACHE[ptr] = c
516+
return ptr
517+
end
518+
519+
PyJuliaArrayValue_New(x::AbstractArray) = PyJuliaValue_New(PyJuliaArrayValue_Type(), x)
520+
PyJuliaValue_From(x::AbstractArray) = PyJuliaArrayValue_New(x)

src/cpython/juliabase.jl

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -30,34 +30,25 @@ pyjlbase_dealloc(o::PyPtr) = begin
3030
nothing
3131
end
3232

33-
const PyJuliaBaseValue_Type__ref = Ref(PyNULL)
34-
PyJuliaBaseValue_Type() = begin
35-
ptr = PyJuliaBaseValue_Type__ref[]
36-
if isnull(ptr)
37-
c = []
38-
t = fill(
39-
PyType_Create(
40-
c,
41-
name = "juliacall.ValueBase",
42-
basicsize = sizeof(PyJuliaValueObject),
43-
new = pyglobal(:PyType_GenericNew),
44-
init = @cfunction(pyjlbase_init, Cint, (PyPtr, PyPtr, PyPtr)),
45-
dealloc = @cfunction(pyjlbase_dealloc, Cvoid, (PyPtr,)),
46-
flags = Py_TPFLAGS_BASETYPE |
47-
Py_TPFLAGS_HAVE_VERSION_TAG |
48-
(CONFIG.isstackless ? Py_TPFLAGS_HAVE_STACKLESS_EXTENSION : 0x00),
49-
weaklistoffset = fieldoffset(PyJuliaValueObject, 3),
50-
getattro = pyglobal(:PyObject_GenericGetAttr),
51-
setattro = pyglobal(:PyObject_GenericSetAttr),
52-
),
53-
)
54-
ptr = PyPtr(pointer(t))
55-
err = PyType_Ready(ptr)
56-
ism1(err) && return PyNULL
57-
PYJLGCCACHE[ptr] = push!(c, t)
58-
PyJuliaBaseValue_Type__ref[] = ptr
59-
end
60-
ptr
33+
const PyJuliaBaseValue_Type = LazyPyObject() do
34+
c = []
35+
ptr = PyPtr(cacheptr!(c, fill(PyTypeObject(
36+
name = cacheptr!(c, "juliacall.ValueBase"),
37+
basicsize = sizeof(PyJuliaValueObject),
38+
new = pyglobal(:PyType_GenericNew),
39+
init = @cfunctionIOOO(pyjlbase_init),
40+
dealloc = @cfunctionVO(pyjlbase_dealloc),
41+
flags = Py_TPFLAGS_BASETYPE |
42+
Py_TPFLAGS_HAVE_VERSION_TAG |
43+
(CONFIG.isstackless ? Py_TPFLAGS_HAVE_STACKLESS_EXTENSION : 0x00),
44+
weaklistoffset = fieldoffset(PyJuliaValueObject, 3),
45+
getattro = pyglobal(:PyObject_GenericGetAttr),
46+
setattro = pyglobal(:PyObject_GenericSetAttr),
47+
))))
48+
err = PyType_Ready(ptr)
49+
ism1(err) && return PyNULL
50+
PYJLGCCACHE[ptr] = c
51+
return ptr
6152
end
6253

6354
PyJuliaValue_Check(o) = Py_TypeCheck(o, PyJuliaBaseValue_Type())

0 commit comments

Comments
 (0)