From 273385870cce1628fca0e7885c71819fd472e94a Mon Sep 17 00:00:00 2001 From: Christopher Rowley Date: Sat, 24 Oct 2026 21:27:57 +0100 Subject: [PATCH] Move Julia wrapper Python code into juliacall._jlwrap modules --- pysrc/juliacall/__init__.py | 29 ++++ pysrc/juliacall/_jlwrap/__init__.py | 35 +++++ pysrc/juliacall/_jlwrap/any.py | 152 ++++++++++++++++++++ pysrc/juliacall/_jlwrap/array.py | 52 +++++++ pysrc/juliacall/_jlwrap/callback.py | 27 ++++ pysrc/juliacall/_jlwrap/dict.py | 77 ++++++++++ pysrc/juliacall/_jlwrap/io.py | 99 +++++++++++++ pysrc/juliacall/_jlwrap/iter.py | 15 ++ pysrc/juliacall/_jlwrap/module.py | 16 +++ pysrc/juliacall/_jlwrap/number.py | 144 +++++++++++++++++++ pysrc/juliacall/_jlwrap/raw.py | 59 ++++++++ pysrc/juliacall/_jlwrap/set.py | 50 +++++++ pysrc/juliacall/_jlwrap/type.py | 20 +++ pysrc/juliacall/_jlwrap/vector.py | 38 +++++ src/JlWrap/any.jl | 211 ++++++++-------------------- src/JlWrap/array.jl | 64 ++------- src/JlWrap/base.jl | 1 + src/JlWrap/callback.jl | 34 +---- src/JlWrap/dict.jl | 92 ++---------- src/JlWrap/io.jl | 117 +++------------ src/JlWrap/iter.jl | 19 +-- src/JlWrap/module.jl | 20 +-- src/JlWrap/number.jl | 188 +++++++------------------ src/JlWrap/raw.jl | 75 ++-------- src/JlWrap/set.jl | 63 ++------- src/JlWrap/type.jl | 25 +--- src/JlWrap/vector.jl | 53 ++----- 27 files changed, 1023 insertions(+), 752 deletions(-) create mode 100644 pysrc/juliacall/_jlwrap/__init__.py create mode 100644 pysrc/juliacall/_jlwrap/any.py create mode 100644 pysrc/juliacall/_jlwrap/array.py create mode 100644 pysrc/juliacall/_jlwrap/callback.py create mode 100644 pysrc/juliacall/_jlwrap/dict.py create mode 100644 pysrc/juliacall/_jlwrap/io.py create mode 100644 pysrc/juliacall/_jlwrap/iter.py create mode 100644 pysrc/juliacall/_jlwrap/module.py create mode 100644 pysrc/juliacall/_jlwrap/number.py create mode 100644 pysrc/juliacall/_jlwrap/raw.py create mode 100644 pysrc/juliacall/_jlwrap/set.py create mode 100644 pysrc/juliacall/_jlwrap/type.py create mode 100644 pysrc/juliacall/_jlwrap/vector.py diff --git a/pysrc/juliacall/__init__.py b/pysrc/juliacall/__init__.py index 30d2b2dd..9370b60d 100644 --- a/pysrc/juliacall/__init__.py +++ b/pysrc/juliacall/__init__.py @@ -46,6 +46,35 @@ def exception(self): def backtrace(self): return self.args[1] +def _init_jlwrap(): + # Called by PythonCall once the native ValueBase type is available. + global RawValue, AnyValue, IteratorValue, TypeValue + global ModuleValue, IOValueBase, BinaryIOValue, TextIOValue + global NumberValue, ComplexValue, RealValue, RationalValue + global IntegerValue, ArrayValue, VectorValue, DictValue + global SetValue, CallbackValue + from ._jlwrap import ( + RawValue, + AnyValue, + IteratorValue, + TypeValue, + ModuleValue, + IOValueBase, + BinaryIOValue, + TextIOValue, + NumberValue, + ComplexValue, + RealValue, + RationalValue, + IntegerValue, + ArrayValue, + VectorValue, + DictValue, + SetValue, + CallbackValue, + ) + + CONFIG = {'inited': False} def init(): diff --git a/pysrc/juliacall/_jlwrap/__init__.py b/pysrc/juliacall/_jlwrap/__init__.py new file mode 100644 index 00000000..a0f257d2 --- /dev/null +++ b/pysrc/juliacall/_jlwrap/__init__.py @@ -0,0 +1,35 @@ +"""Python implementations of Julia value wrappers, initialized by PythonCall.""" + +from .raw import RawValue +from .any import AnyValue +from .iter import IteratorValue +from .type import TypeValue +from .module import ModuleValue +from .io import IOValueBase, BinaryIOValue, TextIOValue +from .number import NumberValue, ComplexValue, RealValue, RationalValue, IntegerValue +from .array import ArrayValue +from .vector import VectorValue +from .dict import DictValue +from .set import SetValue +from .callback import CallbackValue + +__all__ = [ + "RawValue", + "AnyValue", + "IteratorValue", + "TypeValue", + "ModuleValue", + "IOValueBase", + "BinaryIOValue", + "TextIOValue", + "NumberValue", + "ComplexValue", + "RealValue", + "RationalValue", + "IntegerValue", + "ArrayValue", + "VectorValue", + "DictValue", + "SetValue", + "CallbackValue", +] diff --git a/pysrc/juliacall/_jlwrap/any.py b/pysrc/juliacall/_jlwrap/any.py new file mode 100644 index 00000000..e444f53c --- /dev/null +++ b/pysrc/juliacall/_jlwrap/any.py @@ -0,0 +1,152 @@ +"""Julia value wrappers from src/JlWrap/any.jl.""" + +from juliacall import ValueBase + +# Populated by Julia during PythonCall initialization. +_jl_methods = {} + + +class AnyValue(ValueBase): + __module__ = "juliacall" + __slots__ = () + def __repr__(self): + if self._jl_isnull(): + return "" + else: + return self._jl_callmethod(_jl_methods["__repr__"]) + def __str__(self): + if self._jl_isnull(): + return "NULL" + else: + return self._jl_callmethod(_jl_methods["__str__"]) + def __getattr__(self, k): + if k.startswith("__") and k.endswith("__"): + raise AttributeError(k) + else: + return self._jl_callmethod(_jl_methods["__getattr__"], k) + def __setattr__(self, k, v): + try: + ValueBase.__setattr__(self, k, v) + except AttributeError: + if k.startswith("__") and k.endswith("__"): + raise + else: + return + self._jl_callmethod(_jl_methods["__setattr__"], k, v) + def __dir__(self): + return ValueBase.__dir__(self) + self._jl_callmethod(_jl_methods["__dir__"]) + def __call__(self, *args, **kwargs): + return self._jl_callmethod(_jl_methods["__call__"], args, kwargs) + def __bool__(self): + return True + def __len__(self): + return self._jl_callmethod(_jl_methods["__len__"]) + def __getitem__(self, k): + return self._jl_callmethod(_jl_methods["__getitem__"], k) + def __setitem__(self, k, v): + self._jl_callmethod(_jl_methods["__setitem__"], k, v) + def __delitem__(self, k): + self._jl_callmethod(_jl_methods["__delitem__"], k) + def __iter__(self): + return self._jl_callmethod(_jl_methods["__iter__"]) + def __reversed__(self): + return self._jl_callmethod(_jl_methods["__reversed__"]) + def __contains__(self, v): + return self._jl_callmethod(_jl_methods["__contains__"], v) + def __pos__(self): + return self._jl_callmethod(_jl_methods["__pos__"]) + def __neg__(self): + return self._jl_callmethod(_jl_methods["__neg__"]) + def __abs__(self): + return self._jl_callmethod(_jl_methods["__abs__"]) + def __invert__(self): + return self._jl_callmethod(_jl_methods["__invert__"]) + def __add__(self, other): + return self._jl_callmethod(_jl_methods["__add__"], other) + def __sub__(self, other): + return self._jl_callmethod(_jl_methods["__sub__"], other) + def __mul__(self, other): + return self._jl_callmethod(_jl_methods["__mul__"], other) + def __truediv__(self, other): + return self._jl_callmethod(_jl_methods["__truediv__"], other) + def __floordiv__(self, other): + return self._jl_callmethod(_jl_methods["__floordiv__"], other) + def __mod__(self, other): + return self._jl_callmethod(_jl_methods["__mod__"], other) + def __pow__(self, other, modulo=None): + if modulo is None: + return self._jl_callmethod(_jl_methods["__pow__"], other) + else: + return self._jl_callmethod(_jl_methods["__pow_modulo__"], other, modulo) + def __lshift__(self, other): + return self._jl_callmethod(_jl_methods["__lshift__"], other) + def __rshift__(self, other): + return self._jl_callmethod(_jl_methods["__rshift__"], other) + def __and__(self, other): + return self._jl_callmethod(_jl_methods["__and__"], other) + def __xor__(self, other): + return self._jl_callmethod(_jl_methods["__xor__"], other) + def __or__(self, other): + return self._jl_callmethod(_jl_methods["__or__"], other) + def __radd__(self, other): + return self._jl_callmethod(_jl_methods["__radd__"], other) + def __rsub__(self, other): + return self._jl_callmethod(_jl_methods["__rsub__"], other) + def __rmul__(self, other): + return self._jl_callmethod(_jl_methods["__rmul__"], other) + def __rtruediv__(self, other): + return self._jl_callmethod(_jl_methods["__rtruediv__"], other) + def __rfloordiv__(self, other): + return self._jl_callmethod(_jl_methods["__rfloordiv__"], other) + def __rmod__(self, other): + return self._jl_callmethod(_jl_methods["__rmod__"], other) + def __rpow__(self, other, modulo=None): + if modulo is None: + return self._jl_callmethod(_jl_methods["__rpow__"], other) + else: + return self._jl_callmethod(_jl_methods["__rpow_modulo__"], other, modulo) + def __rlshift__(self, other): + return self._jl_callmethod(_jl_methods["__rlshift__"], other) + def __rrshift__(self, other): + return self._jl_callmethod(_jl_methods["__rrshift__"], other) + def __rand__(self, other): + return self._jl_callmethod(_jl_methods["__rand__"], other) + def __rxor__(self, other): + return self._jl_callmethod(_jl_methods["__rxor__"], other) + def __ror__(self, other): + return self._jl_callmethod(_jl_methods["__ror__"], other) + def __eq__(self, other): + return self._jl_callmethod(_jl_methods["__eq__"], other) + def __ne__(self, other): + return self._jl_callmethod(_jl_methods["__ne__"], other) + def __le__(self, other): + return self._jl_callmethod(_jl_methods["__le__"], other) + def __lt__(self, other): + return self._jl_callmethod(_jl_methods["__lt__"], other) + def __ge__(self, other): + return self._jl_callmethod(_jl_methods["__ge__"], other) + def __gt__(self, other): + return self._jl_callmethod(_jl_methods["__gt__"], other) + def __hash__(self): + return self._jl_callmethod(_jl_methods["__hash__"]) + @property + def __name__(self): + return self._jl_callmethod(_jl_methods["__name__"]) + def _jl_raw(self): + '''Convert this to a juliacall.RawValue.''' + return self._jl_callmethod(_jl_methods["_jl_raw"]) + def _jl_display(self, mime=None): + '''Display this, optionally specifying the MIME type.''' + return self._jl_callmethod(_jl_methods["_jl_display"], mime) + def _jl_help(self, mime=None): + '''Show help for this Julia object.''' + return self._jl_callmethod(_jl_methods["_jl_help"], mime) + def _jl_call_nogil(self, *args, **kwargs): + '''Call this with the given arguments but with the GIL disabled. + + WARNING: This function must not interact with Python at all without re-acquiring + the GIL. + ''' + return self._jl_callmethod(_jl_methods["_jl_call_nogil"], args, kwargs) + def _repr_mimebundle_(self, include=None, exclude=None): + return self._jl_callmethod(_jl_methods["_repr_mimebundle_"], include, exclude) diff --git a/pysrc/juliacall/_jlwrap/array.py b/pysrc/juliacall/_jlwrap/array.py new file mode 100644 index 00000000..223ae289 --- /dev/null +++ b/pysrc/juliacall/_jlwrap/array.py @@ -0,0 +1,52 @@ +"""Julia value wrappers from src/JlWrap/array.jl.""" + +from .any import AnyValue + +# Populated by Julia during PythonCall initialization. +_jl_methods = {} + + +class ArrayValue(AnyValue): + __module__ = "juliacall" + __slots__ = () + @property + def _jl_buffer_info(self): + return _jl_methods["_jl_buffer_info"] + @property + def ndim(self): + return self._jl_callmethod(_jl_methods["ndim"]) + @property + def shape(self): + return self._jl_callmethod(_jl_methods["shape"]) + def copy(self): + return self._jl_callmethod(_jl_methods["copy"]) + def reshape(self, shape): + return self._jl_callmethod(_jl_methods["reshape"], shape) + def __bool__(self): + return bool(len(self)) + def __getitem__(self, k): + return self._jl_callmethod(_jl_methods["__getitem__"], k) + def __setitem__(self, k, v): + self._jl_callmethod(_jl_methods["__setitem__"], k, v) + def __delitem__(self, k): + self._jl_callmethod(_jl_methods["__delitem__"], k) + @property + def __array_interface__(self): + return self._jl_callmethod(_jl_methods["__array_interface__"]) + def __array__(self, dtype=None, copy=None): + import numpy + # convert to an array-like object + arr = self + if not (hasattr(arr, "__array_interface__") or hasattr(arr, "__array_struct__")): + if copy is False: + raise ValueError("copy=False is not supported when collecting ArrayValue data") + # the first attempt collects into an Array + arr = self._jl_callmethod(_jl_methods["__array__"]) + if not (hasattr(arr, "__array_interface__") or hasattr(arr, "__array_struct__")): + # the second attempt collects into a PyObjectArray + arr = self._jl_callmethod(_jl_methods["__array_pyobjectarray__"]) + # convert to a numpy array if numpy is available + return numpy.array(arr, dtype=dtype, copy=copy) + def to_numpy(self, dtype=None, copy=True, order="K"): + import numpy + return numpy.array(self, dtype=dtype, copy=copy, order=order) diff --git a/pysrc/juliacall/_jlwrap/callback.py b/pysrc/juliacall/_jlwrap/callback.py new file mode 100644 index 00000000..35cd2f75 --- /dev/null +++ b/pysrc/juliacall/_jlwrap/callback.py @@ -0,0 +1,27 @@ +"""Julia value wrappers from src/JlWrap/callback.jl.""" + +from juliacall import ValueBase + +# Populated by Julia during PythonCall initialization. +_jl_methods = {} + + +class CallbackValue(ValueBase): + __module__ = "juliacall" + __slots__ = () + def __repr__(self): + if self._jl_isnull(): + return "" + else: + return self._jl_callmethod(_jl_methods["__repr__"]) + def __str__(self): + if self._jl_isnull(): + return "NULL" + else: + return self._jl_callmethod(_jl_methods["__str__"]) + def __call__(self, *args, **kwargs): + return self._jl_callmethod(_jl_methods["__call__"], args, kwargs) + + +def wrap_callback(f): + return lambda *args, **kwargs: f(*args, **kwargs) diff --git a/pysrc/juliacall/_jlwrap/dict.py b/pysrc/juliacall/_jlwrap/dict.py new file mode 100644 index 00000000..82368022 --- /dev/null +++ b/pysrc/juliacall/_jlwrap/dict.py @@ -0,0 +1,77 @@ +"""Julia value wrappers from src/JlWrap/dict.jl.""" + +from .any import AnyValue + +# Populated by Julia during PythonCall initialization. +_jl_methods = {} + + +class DictValue(AnyValue): + __module__ = "juliacall" + __slots__ = () + _jl_undefined_ = object() + def __bool__(self): + return bool(len(self)) + def __iter__(self): + return self._jl_callmethod(_jl_methods["__iter__"]) + def __contains__(self, key): + return self._jl_callmethod(_jl_methods["__contains__"], key) + def __getitem__(self, key): + if key in self: + return self._jl_callmethod(_jl_methods["__getitem__"], key) + else: + raise KeyError(key) + def __setitem__(self, key, value): + return self._jl_callmethod(_jl_methods["__setitem__"], key, value) + def __delitem__(self, key): + if key in self: + return self._jl_callmethod(_jl_methods["__delitem__"], key) + else: + raise KeyError(key) + def keys(self): + return self._jl_callmethod(_jl_methods["keys"]) + def values(self): + return self._jl_callmethod(_jl_methods["values"]) + def items(self): + return self._jl_callmethod(_jl_methods["items"]) + def get(self, key, default=None): + if key in self: + return self[key] + else: + return default + def setdefault(self, key, default=None): + if key not in self: + self[key] = default + return self[key] + def clear(self): + return self._jl_callmethod(_jl_methods["clear"]) + def pop(self, key, default=_jl_undefined_): + if key in self: + ans = self[key] + del self[key] + return ans + elif default is self._jl_undefined_: + raise KeyError(key) + else: + return default + def popitem(self): + if len(self): + return self._jl_callmethod(_jl_methods["popitem"]) + else: + raise KeyError() + def update(self, other=_jl_undefined_, **kwargs): + if other is self._jl_undefined_: + pass + else: + if hasattr(other, "keys"): + items = ((k, other[k]) for k in other.keys()) + else: + items = other + self._jl_callmethod(_jl_methods["update"], items) + if kwargs: + self.update(kwargs) + def copy(self): + return self._jl_callmethod(_jl_methods["copy"]) +import collections.abc +collections.abc.MutableMapping.register(DictValue) +del collections diff --git a/pysrc/juliacall/_jlwrap/io.py b/pysrc/juliacall/_jlwrap/io.py new file mode 100644 index 00000000..a7aef9d5 --- /dev/null +++ b/pysrc/juliacall/_jlwrap/io.py @@ -0,0 +1,99 @@ +"""Julia value wrappers from src/JlWrap/io.jl.""" + +from .any import AnyValue + +# Populated by Julia during PythonCall initialization. +_jl_methods = {} + + +class IOValueBase(AnyValue): + __module__ = "juliacall" + __slots__ = () + def close(self): + return self._jl_callmethod(_jl_methods["close"]) + @property + def closed(self): + return self._jl_callmethod(_jl_methods["closed"]) + def fileno(self): + return self._jl_callmethod(_jl_methods["fileno"]) + def flush(self): + return self._jl_callmethod(_jl_methods["flush"]) + def isatty(self): + return self._jl_callmethod(_jl_methods["isatty"]) + def readable(self): + return self._jl_callmethod(_jl_methods["readable"]) + def readlines(self, hint=-1): + lines = [] + total = 0 + while hint < 0 or total < hint: + line = self.readline() + if line: + lines.append(line) + total += len(line) + else: + break + return lines + def seek(self, offset, whence=0): + return self._jl_callmethod(_jl_methods["seek"], offset, whence) + def seekable(self): + return True + def tell(self): + return self._jl_callmethod(_jl_methods["tell"]) + def truncate(self, size=None): + return self._jl_callmethod(_jl_methods["truncate"], size) + def writable(self): + return self._jl_callmethod(_jl_methods["writable"]) + def writelines(self, lines): + for line in lines: + self.write(line) + def __enter__(self): + return self + def __exit__(self, t, v, b): + self.close() + def __iter__(self): + return self + def __next__(self): + line = self.readline() + if line: + return line + else: + raise StopIteration +class BinaryIOValue(IOValueBase): + __module__ = "juliacall" + __slots__ = () + def detach(self): + raise ValueError("Cannot detach '{}'.".format(type(self))) + def read(self, size=-1): + return self._jl_callmethod(_jl_methods["binary_read"], size) + def read1(self, size=-1): + return self.read(size) + def readline(self, size=-1): + return self._jl_callmethod(_jl_methods["binary_readline"], size) + def readinto(self, b): + return self._jl_callmethod(_jl_methods["readinto"], b) + def readinto1(self, b): + return self.readinto(b) + def write(self, b): + return self._jl_callmethod(_jl_methods["binary_write"], b) +class TextIOValue(IOValueBase): + __module__ = "juliacall" + __slots__ = () + @property + def encoding(self): + return "UTF-8" + @property + def errors(self): + return "strict" + def detach(self): + raise ValueError("Cannot detach '{}'.".format(type(self))) + def read(self, size=-1): + return self._jl_callmethod(_jl_methods["text_read"], size) + def readline(self, size=-1): + return self._jl_callmethod(_jl_methods["text_readline"], size) + def write(self, s): + return self._jl_callmethod(_jl_methods["text_write"], s) +import io +io.IOBase.register(IOValueBase) +io.BufferedIOBase.register(BinaryIOValue) +io.TextIOBase.register(TextIOValue) +del io diff --git a/pysrc/juliacall/_jlwrap/iter.py b/pysrc/juliacall/_jlwrap/iter.py new file mode 100644 index 00000000..ea33c3ca --- /dev/null +++ b/pysrc/juliacall/_jlwrap/iter.py @@ -0,0 +1,15 @@ +"""Julia value wrappers from src/JlWrap/iter.jl.""" + +from .any import AnyValue + +# Populated by Julia during PythonCall initialization. +_jl_methods = {} + + +class IteratorValue(AnyValue): + __module__ = "juliacall" + __slots__ = () + def __iter__(self): + return self + def __next__(self): + return self._jl_callmethod(_jl_methods["__next__"]) diff --git a/pysrc/juliacall/_jlwrap/module.py b/pysrc/juliacall/_jlwrap/module.py new file mode 100644 index 00000000..72904247 --- /dev/null +++ b/pysrc/juliacall/_jlwrap/module.py @@ -0,0 +1,16 @@ +"""Julia value wrappers from src/JlWrap/module.jl.""" + +from .any import AnyValue +from juliacall import ValueBase + +# Populated by Julia during PythonCall initialization. +_jl_methods = {} + + +class ModuleValue(AnyValue): + __module__ = "juliacall" + __slots__ = () + def __dir__(self): + return ValueBase.__dir__(self) + self._jl_callmethod(_jl_methods["__dir__"]) + def seval(self, expr): + return self._jl_callmethod(_jl_methods["seval"], expr) diff --git a/pysrc/juliacall/_jlwrap/number.py b/pysrc/juliacall/_jlwrap/number.py new file mode 100644 index 00000000..b84f3484 --- /dev/null +++ b/pysrc/juliacall/_jlwrap/number.py @@ -0,0 +1,144 @@ +"""Julia value wrappers from src/JlWrap/number.jl.""" + +from .any import AnyValue + +# Populated by Julia during PythonCall initialization. +_jl_methods = {} + + +class NumberValue(AnyValue): + __module__ = "juliacall" + __slots__ = () + def __bool__(self): + return not self._jl_callmethod(_jl_methods["__bool__"]) + def __add__(self, other): + return self._jl_callmethod(_jl_methods["__add__"], other) + def __sub__(self, other): + return self._jl_callmethod(_jl_methods["__sub__"], other) + def __mul__(self, other): + return self._jl_callmethod(_jl_methods["__mul__"], other) + def __truediv__(self, other): + return self._jl_callmethod(_jl_methods["__truediv__"], other) + def __floordiv__(self, other): + return self._jl_callmethod(_jl_methods["__floordiv__"], other) + def __mod__(self, other): + return self._jl_callmethod(_jl_methods["__mod__"], other) + def __pow__(self, other, modulo=None): + if modulo is None: + return self._jl_callmethod(_jl_methods["__pow__"], other) + else: + return self._jl_callmethod(_jl_methods["__pow_modulo__"], other, modulo) + def __lshift__(self, other): + return self._jl_callmethod(_jl_methods["__lshift__"], other) + def __rshift__(self, other): + return self._jl_callmethod(_jl_methods["__rshift__"], other) + def __and__(self, other): + return self._jl_callmethod(_jl_methods["__and__"], other) + def __xor__(self, other): + return self._jl_callmethod(_jl_methods["__xor__"], other) + def __or__(self, other): + return self._jl_callmethod(_jl_methods["__or__"], other) + def __radd__(self, other): + return self._jl_callmethod(_jl_methods["__radd__"], other) + def __rsub__(self, other): + return self._jl_callmethod(_jl_methods["__rsub__"], other) + def __rmul__(self, other): + return self._jl_callmethod(_jl_methods["__rmul__"], other) + def __rtruediv__(self, other): + return self._jl_callmethod(_jl_methods["__rtruediv__"], other) + def __rfloordiv__(self, other): + return self._jl_callmethod(_jl_methods["__rfloordiv__"], other) + def __rmod__(self, other): + return self._jl_callmethod(_jl_methods["__rmod__"], other) + def __rpow__(self, other, modulo=None): + if modulo is None: + return self._jl_callmethod(_jl_methods["__rpow__"], other) + else: + return self._jl_callmethod(_jl_methods["__rpow_modulo__"], other, modulo) + def __rlshift__(self, other): + return self._jl_callmethod(_jl_methods["__rlshift__"], other) + def __rrshift__(self, other): + return self._jl_callmethod(_jl_methods["__rrshift__"], other) + def __rand__(self, other): + return self._jl_callmethod(_jl_methods["__rand__"], other) + def __rxor__(self, other): + return self._jl_callmethod(_jl_methods["__rxor__"], other) + def __ror__(self, other): + return self._jl_callmethod(_jl_methods["__ror__"], other) + def __eq__(self, other): + return self._jl_callmethod(_jl_methods["__eq__"], other) + def __ne__(self, other): + return self._jl_callmethod(_jl_methods["__ne__"], other) + def __le__(self, other): + return self._jl_callmethod(_jl_methods["__le__"], other) + def __lt__(self, other): + return self._jl_callmethod(_jl_methods["__lt__"], other) + def __ge__(self, other): + return self._jl_callmethod(_jl_methods["__ge__"], other) + def __gt__(self, other): + return self._jl_callmethod(_jl_methods["__gt__"], other) +class ComplexValue(NumberValue): + __module__ = "juliacall" + __slots__ = () + def __complex__(self): + return self._jl_callmethod(_jl_methods["__complex__"]) + @property + def real(self): + return self._jl_callmethod(_jl_methods["real"]) + @property + def imag(self): + return self._jl_callmethod(_jl_methods["imag"]) + def conjugate(self): + return self._jl_callmethod(_jl_methods["conjugate"]) +class RealValue(ComplexValue): + __module__ = "juliacall" + __slots__ = () + def __float__(self): + return self._jl_callmethod(_jl_methods["__float__"]) + @property + def real(self): + return self + @property + def imag(self): + return 0 + def conjugate(self): + return self + def __complex__(self): + return complex(float(self)) + def __trunc__(self): + return self._jl_callmethod(_jl_methods["__trunc__"]) + def __floor__(self): + return self._jl_callmethod(_jl_methods["__floor__"]) + def __ceil__(self): + return self._jl_callmethod(_jl_methods["__ceil__"]) + def __round__(self, ndigits=None): + return self._jl_callmethod(_jl_methods["__round__"], ndigits) +class RationalValue(RealValue): + __module__ = "juliacall" + __slots__ = () + @property + def numerator(self): + return self._jl_callmethod(_jl_methods["numerator"]) + @property + def denominator(self): + return self._jl_callmethod(_jl_methods["denominator"]) +class IntegerValue(RationalValue): + __module__ = "juliacall" + __slots__ = () + def __int__(self): + return self._jl_callmethod(_jl_methods["__int__"]) + def __index__(self): + return self.__int__() + @property + def numerator(self): + return self + @property + def denominator(self): + return 1 +import numbers +numbers.Number.register(NumberValue) +numbers.Complex.register(ComplexValue) +numbers.Real.register(RealValue) +numbers.Rational.register(RationalValue) +numbers.Integral.register(IntegerValue) +del numbers diff --git a/pysrc/juliacall/_jlwrap/raw.py b/pysrc/juliacall/_jlwrap/raw.py new file mode 100644 index 00000000..d12e75b8 --- /dev/null +++ b/pysrc/juliacall/_jlwrap/raw.py @@ -0,0 +1,59 @@ +"""Julia value wrappers from src/JlWrap/raw.jl.""" + +from juliacall import ValueBase + +# Populated by Julia during PythonCall initialization. +_jl_methods = {} + + +class RawValue(ValueBase): + __module__ = "juliacall" + __slots__ = () + def __repr__(self): + if self._jl_isnull(): + return "" + else: + return self._jl_callmethod(_jl_methods["__repr__"]) + def __str__(self): + if self._jl_isnull(): + return "NULL" + else: + return self._jl_callmethod(_jl_methods["__str__"]) + def __getattr__(self, k): + if k.startswith("__") and k.endswith("__"): + raise AttributeError(k) + else: + return self._jl_callmethod(_jl_methods["__getattr__"], k) + def __setattr__(self, k, v): + try: + ValueBase.__setattr__(self, k, v) + except AttributeError: + if k.startswith("__") and k.endswith("__"): + raise + else: + return + self._jl_callmethod(_jl_methods["__setattr__"], k, v) + def __dir__(self): + return ValueBase.__dir__(self) + self._jl_callmethod(_jl_methods["__dir__"]) + def __call__(self, *args, **kwargs): + return self._jl_callmethod(_jl_methods["__call__"], args, kwargs) + def __len__(self): + return self._jl_callmethod(_jl_methods["__len__"]) + def __getitem__(self, k): + return self._jl_callmethod(_jl_methods["__getitem__"], k) + def __setitem__(self, k, v): + self._jl_callmethod(_jl_methods["__setitem__"], k, v) + def __delitem__(self, k): + self._jl_callmethod(_jl_methods["__delitem__"], k) + def __bool__(self): + return self._jl_callmethod(_jl_methods["__bool__"]) + def _jl_any(self): + '''Convert this to a juliacall.AnyValue.''' + return self._jl_callmethod(_jl_methods["_jl_any"]) + def _jl_call_nogil(self, *args, **kwargs): + '''Call this with the given arguments but with the GIL disabled. + + WARNING: This function must not interact with Python at all without re-acquiring + the GIL. + ''' + return self._jl_callmethod(_jl_methods["_jl_call_nogil"], args, kwargs) diff --git a/pysrc/juliacall/_jlwrap/set.py b/pysrc/juliacall/_jlwrap/set.py new file mode 100644 index 00000000..e7ae2564 --- /dev/null +++ b/pysrc/juliacall/_jlwrap/set.py @@ -0,0 +1,50 @@ +"""Julia value wrappers from src/JlWrap/set.jl.""" + +from .any import AnyValue + +# Populated by Julia during PythonCall initialization. +_jl_methods = {} + + +class SetValue(AnyValue): + __module__ = "juliacall" + __slots__ = () + def __bool__(self): + return bool(len(self)) + def add(self, value): + return self._jl_callmethod(_jl_methods["add"], value) + def discard(self, value): + return self._jl_callmethod(_jl_methods["discard"], value) + def clear(self): + return self._jl_callmethod(_jl_methods["clear"]) + def copy(self): + return self._jl_callmethod(_jl_methods["copy"]) + def pop(self): + return self._jl_callmethod(_jl_methods["pop"]) + def remove(self, value): + return self._jl_callmethod(_jl_methods["remove"], value) + def difference(self, other): + return set(self).difference(other) + def intersection(self, other): + return set(self).intersection(other) + def symmetric_difference(self, other): + return set(self).symmetric_difference(other) + def union(self, other): + return set(self).union(other) + def isdisjoint(self, other): + return set(self).isdisjoint(other) + def issubset(self, other): + return set(self).issubset(other) + def issuperset(self, other): + return set(self).issuperset(other) + def difference_update(self, other): + return self._jl_callmethod(_jl_methods["difference_update"], other) + def intersection_update(self, other): + return self._jl_callmethod(_jl_methods["intersection_update"], other) + def symmetric_difference_update(self, other): + return self._jl_callmethod(_jl_methods["symmetric_difference_update"], other) + def update(self, other): + return self._jl_callmethod(_jl_methods["update"], other) +import collections.abc +collections.abc.MutableSet.register(SetValue) +del collections diff --git a/pysrc/juliacall/_jlwrap/type.py b/pysrc/juliacall/_jlwrap/type.py new file mode 100644 index 00000000..b618debe --- /dev/null +++ b/pysrc/juliacall/_jlwrap/type.py @@ -0,0 +1,20 @@ +"""Julia value wrappers from src/JlWrap/type.jl.""" + +from .any import AnyValue + +# Populated by Julia during PythonCall initialization. +_jl_methods = {} + + +class TypeValue(AnyValue): + __module__ = "juliacall" + __slots__ = () + def __getitem__(self, k): + return self._jl_callmethod(_jl_methods["__getitem__"], k) + def __setitem__(self, k, v): + raise TypeError("not supported") + def __delitem__(self, k): + raise TypeError("not supported") + @property + def __numpy_dtype__(self): + return self._jl_callmethod(_jl_methods["__numpy_dtype__"]) diff --git a/pysrc/juliacall/_jlwrap/vector.py b/pysrc/juliacall/_jlwrap/vector.py new file mode 100644 index 00000000..c246b7fa --- /dev/null +++ b/pysrc/juliacall/_jlwrap/vector.py @@ -0,0 +1,38 @@ +"""Julia value wrappers from src/JlWrap/vector.jl.""" + +from .array import ArrayValue + +# Populated by Julia during PythonCall initialization. +_jl_methods = {} + + +class VectorValue(ArrayValue): + __module__ = "juliacall" + __slots__ = () + def resize(self, size): + return self._jl_callmethod(_jl_methods["resize"], size) + def sort(self, reverse=False, key=None): + return self._jl_callmethod(_jl_methods["sort"], reverse, key) + def reverse(self): + return self._jl_callmethod(_jl_methods["reverse"]) + def clear(self): + return self._jl_callmethod(_jl_methods["clear"]) + def __reversed__(self): + return self._jl_callmethod(_jl_methods["__reversed__"]) + def insert(self, index, value): + return self._jl_callmethod(_jl_methods["insert"], index, value) + def append(self, value): + return self._jl_callmethod(_jl_methods["append"], value) + def extend(self, values): + return self._jl_callmethod(_jl_methods["extend"], values) + def pop(self, index=-1): + return self._jl_callmethod(_jl_methods["pop"], index) + def remove(self, value): + return self._jl_callmethod(_jl_methods["remove"], value) + def index(self, value): + return self._jl_callmethod(_jl_methods["index"], value) + def count(self, value): + return self._jl_callmethod(_jl_methods["count"], value) +import collections.abc +collections.abc.MutableSequence.register(VectorValue) +del collections diff --git a/src/JlWrap/any.jl b/src/JlWrap/any.jl index c0a4244c..551f6ccf 100644 --- a/src/JlWrap/any.jl +++ b/src/JlWrap/any.jl @@ -229,159 +229,64 @@ end function init_any() jl = pyjuliacallmodule - pybuiltins.exec( - pybuiltins.compile( - """ -$("\n"^(@__LINE__()-1)) -class AnyValue(ValueBase): - __slots__ = () - def __repr__(self): - if self._jl_isnull(): - return "" - else: - return self._jl_callmethod($(pyjl_methodnum(pyjlany_repr))) - def __str__(self): - if self._jl_isnull(): - return "NULL" - else: - return self._jl_callmethod($(pyjl_methodnum(pyjlany_str))) - def __getattr__(self, k): - if k.startswith("__") and k.endswith("__"): - raise AttributeError(k) - else: - return self._jl_callmethod($(pyjl_methodnum(pyjlany_getattr)), k) - def __setattr__(self, k, v): - try: - ValueBase.__setattr__(self, k, v) - except AttributeError: - if k.startswith("__") and k.endswith("__"): - raise - else: - return - self._jl_callmethod($(pyjl_methodnum(pyjlany_setattr)), k, v) - def __dir__(self): - return ValueBase.__dir__(self) + self._jl_callmethod($(pyjl_methodnum(pyjlany_dir))) - def __call__(self, *args, **kwargs): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_call)), args, kwargs) - def __bool__(self): - return True - def __len__(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_op(length)))) - def __getitem__(self, k): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_getitem)), k) - def __setitem__(self, k, v): - self._jl_callmethod($(pyjl_methodnum(pyjlany_setitem)), k, v) - def __delitem__(self, k): - self._jl_callmethod($(pyjl_methodnum(pyjlany_delitem)), k) - def __iter__(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_op(Iterator)))) - def __reversed__(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_op(reverse)))) - def __contains__(self, v): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_contains)), v) - def __pos__(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_op(+)))) - def __neg__(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_op(-)))) - def __abs__(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_op(abs)))) - def __invert__(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_op(~)))) - def __add__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_op(+))), other) - def __sub__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_op(-))), other) - def __mul__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_op(*))), other) - def __truediv__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_op(/))), other) - def __floordiv__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_op(÷))), other) - def __mod__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_op(%))), other) - def __pow__(self, other, modulo=None): - if modulo is None: - return self._jl_callmethod($(pyjl_methodnum(pyjlany_op(^))), other) - else: - return self._jl_callmethod($(pyjl_methodnum(pyjlany_op(powermod))), other, modulo) - def __lshift__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_op(<<))), other) - def __rshift__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_op(>>))), other) - def __and__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_op(&))), other) - def __xor__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_op(⊻))), other) - def __or__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_op(|))), other) - def __radd__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_rev_op(+))), other) - def __rsub__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_rev_op(-))), other) - def __rmul__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_rev_op(*))), other) - def __rtruediv__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_rev_op(/))), other) - def __rfloordiv__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_rev_op(÷))), other) - def __rmod__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_rev_op(%))), other) - def __rpow__(self, other, modulo=None): - if modulo is None: - return self._jl_callmethod($(pyjl_methodnum(pyjlany_rev_op(^))), other) - else: - return self._jl_callmethod($(pyjl_methodnum(pyjlany_rev_op(powermod))), other, modulo) - def __rlshift__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_rev_op(<<))), other) - def __rrshift__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_rev_op(>>))), other) - def __rand__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_rev_op(&))), other) - def __rxor__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_rev_op(⊻))), other) - def __ror__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_rev_op(|))), other) - def __eq__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_op(==))), other) - def __ne__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_op(!=))), other) - def __le__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_op(≤))), other) - def __lt__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_op(<))), other) - def __ge__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_op(≥))), other) - def __gt__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_op(>))), other) - def __hash__(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_op(hash)))) - @property - def __name__(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_name))) - def _jl_raw(self): - '''Convert this to a juliacall.RawValue.''' - return self._jl_callmethod($(pyjl_methodnum(pyjlraw))) - def _jl_display(self, mime=None): - '''Display this, optionally specifying the MIME type.''' - return self._jl_callmethod($(pyjl_methodnum(pyjlany_display)), mime) - def _jl_help(self, mime=None): - '''Show help for this Julia object.''' - return self._jl_callmethod($(pyjl_methodnum(pyjlany_help)), mime) - def _jl_call_nogil(self, *args, **kwargs): - '''Call this with the given arguments but with the GIL disabled. - - WARNING: This function must not interact with Python at all without re-acquiring - the GIL. - ''' - return self._jl_callmethod($(pyjl_methodnum(pyjlany_call_nogil)), args, kwargs) - def _repr_mimebundle_(self, include=None, exclude=None): - return self._jl_callmethod($(pyjl_methodnum(pyjlany_mimebundle)), include, exclude) -""", - @__FILE__(), - "exec", - ), - jl.__dict__, - ) + m = pyimport("juliacall._jlwrap.any") + methods = m._jl_methods + methods["__repr__"] = pyjl_methodnum(pyjlany_repr) + methods["__str__"] = pyjl_methodnum(pyjlany_str) + methods["__getattr__"] = pyjl_methodnum(pyjlany_getattr) + methods["__setattr__"] = pyjl_methodnum(pyjlany_setattr) + methods["__dir__"] = pyjl_methodnum(pyjlany_dir) + methods["__call__"] = pyjl_methodnum(pyjlany_call) + methods["__len__"] = pyjl_methodnum(pyjlany_op(length)) + methods["__getitem__"] = pyjl_methodnum(pyjlany_getitem) + methods["__setitem__"] = pyjl_methodnum(pyjlany_setitem) + methods["__delitem__"] = pyjl_methodnum(pyjlany_delitem) + methods["__iter__"] = pyjl_methodnum(pyjlany_op(Iterator)) + methods["__reversed__"] = pyjl_methodnum(pyjlany_op(reverse)) + methods["__contains__"] = pyjl_methodnum(pyjlany_contains) + methods["__pos__"] = pyjl_methodnum(pyjlany_op(+)) + methods["__neg__"] = pyjl_methodnum(pyjlany_op(-)) + methods["__abs__"] = pyjl_methodnum(pyjlany_op(abs)) + methods["__invert__"] = pyjl_methodnum(pyjlany_op(~)) + methods["__add__"] = pyjl_methodnum(pyjlany_op(+)) + methods["__sub__"] = pyjl_methodnum(pyjlany_op(-)) + methods["__mul__"] = pyjl_methodnum(pyjlany_op(*)) + methods["__truediv__"] = pyjl_methodnum(pyjlany_op(/)) + methods["__floordiv__"] = pyjl_methodnum(pyjlany_op(÷)) + methods["__mod__"] = pyjl_methodnum(pyjlany_op(%)) + methods["__pow__"] = pyjl_methodnum(pyjlany_op(^)) + methods["__pow_modulo__"] = pyjl_methodnum(pyjlany_op(powermod)) + methods["__lshift__"] = pyjl_methodnum(pyjlany_op(<<)) + methods["__rshift__"] = pyjl_methodnum(pyjlany_op(>>)) + methods["__and__"] = pyjl_methodnum(pyjlany_op(&)) + methods["__xor__"] = pyjl_methodnum(pyjlany_op(⊻)) + methods["__or__"] = pyjl_methodnum(pyjlany_op(|)) + methods["__radd__"] = pyjl_methodnum(pyjlany_rev_op(+)) + methods["__rsub__"] = pyjl_methodnum(pyjlany_rev_op(-)) + methods["__rmul__"] = pyjl_methodnum(pyjlany_rev_op(*)) + methods["__rtruediv__"] = pyjl_methodnum(pyjlany_rev_op(/)) + methods["__rfloordiv__"] = pyjl_methodnum(pyjlany_rev_op(÷)) + methods["__rmod__"] = pyjl_methodnum(pyjlany_rev_op(%)) + methods["__rpow__"] = pyjl_methodnum(pyjlany_rev_op(^)) + methods["__rpow_modulo__"] = pyjl_methodnum(pyjlany_rev_op(powermod)) + methods["__rlshift__"] = pyjl_methodnum(pyjlany_rev_op(<<)) + methods["__rrshift__"] = pyjl_methodnum(pyjlany_rev_op(>>)) + methods["__rand__"] = pyjl_methodnum(pyjlany_rev_op(&)) + methods["__rxor__"] = pyjl_methodnum(pyjlany_rev_op(⊻)) + methods["__ror__"] = pyjl_methodnum(pyjlany_rev_op(|)) + methods["__eq__"] = pyjl_methodnum(pyjlany_op(==)) + methods["__ne__"] = pyjl_methodnum(pyjlany_op(!=)) + methods["__le__"] = pyjl_methodnum(pyjlany_op(≤)) + methods["__lt__"] = pyjl_methodnum(pyjlany_op(<)) + methods["__ge__"] = pyjl_methodnum(pyjlany_op(≥)) + methods["__gt__"] = pyjl_methodnum(pyjlany_op(>)) + methods["__hash__"] = pyjl_methodnum(pyjlany_op(hash)) + methods["__name__"] = pyjl_methodnum(pyjlany_name) + methods["_jl_raw"] = pyjl_methodnum(pyjlraw) + methods["_jl_display"] = pyjl_methodnum(pyjlany_display) + methods["_jl_help"] = pyjl_methodnum(pyjlany_help) + methods["_jl_call_nogil"] = pyjl_methodnum(pyjlany_call_nogil) + methods["_repr_mimebundle_"] = pyjl_methodnum(pyjlany_mimebundle) pycopy!(pyjlanytype, jl.AnyValue) end diff --git a/src/JlWrap/array.jl b/src/JlWrap/array.jl index 6ed25176..f1dd3d7b 100644 --- a/src/JlWrap/array.jl +++ b/src/JlWrap/array.jl @@ -328,57 +328,19 @@ pyjl_handle_error_type(::typeof(pyjlarray_array_interface), x, exc) = function init_array() jl = pyjuliacallmodule - pybuiltins.exec( - pybuiltins.compile( - """ -$("\n"^(@__LINE__()-1)) -class ArrayValue(AnyValue): - __slots__ = () - _jl_buffer_info = $(pyjl_methodnum(pyjlarray_buffer_info)) - @property - def ndim(self): - return self._jl_callmethod($(pyjl_methodnum(Py ∘ ndims))) - @property - def shape(self): - return self._jl_callmethod($(pyjl_methodnum(Py ∘ size))) - def copy(self): - return self._jl_callmethod($(pyjl_methodnum(Py ∘ copy))) - def reshape(self, shape): - return self._jl_callmethod($(pyjl_methodnum(pyjlarray_reshape)), shape) - def __bool__(self): - return bool(len(self)) - def __getitem__(self, k): - return self._jl_callmethod($(pyjl_methodnum(pyjlarray_getitem)), k) - def __setitem__(self, k, v): - self._jl_callmethod($(pyjl_methodnum(pyjlarray_setitem)), k, v) - def __delitem__(self, k): - self._jl_callmethod($(pyjl_methodnum(pyjlarray_delitem)), k) - @property - def __array_interface__(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlarray_array_interface))) - def __array__(self, dtype=None, copy=None): - import numpy - # convert to an array-like object - arr = self - if not (hasattr(arr, "__array_interface__") or hasattr(arr, "__array_struct__")): - if copy is False: - raise ValueError("copy=False is not supported when collecting ArrayValue data") - # the first attempt collects into an Array - arr = self._jl_callmethod($(pyjl_methodnum(pyjlarray_array__array))) - if not (hasattr(arr, "__array_interface__") or hasattr(arr, "__array_struct__")): - # the second attempt collects into a PyObjectArray - arr = self._jl_callmethod($(pyjl_methodnum(pyjlarray_array__pyobjectarray))) - # convert to a numpy array if numpy is available - return numpy.array(arr, dtype=dtype, copy=copy) - def to_numpy(self, dtype=None, copy=True, order="K"): - import numpy - return numpy.array(self, dtype=dtype, copy=copy, order=order) -""", - @__FILE__(), - "exec", - ), - jl.__dict__, - ) + m = pyimport("juliacall._jlwrap.array") + methods = m._jl_methods + methods["_jl_buffer_info"] = pyjl_methodnum(pyjlarray_buffer_info) + methods["ndim"] = pyjl_methodnum(Py ∘ ndims) + methods["shape"] = pyjl_methodnum(Py ∘ size) + methods["copy"] = pyjl_methodnum(Py ∘ copy) + methods["reshape"] = pyjl_methodnum(pyjlarray_reshape) + methods["__getitem__"] = pyjl_methodnum(pyjlarray_getitem) + methods["__setitem__"] = pyjl_methodnum(pyjlarray_setitem) + methods["__delitem__"] = pyjl_methodnum(pyjlarray_delitem) + methods["__array_interface__"] = pyjl_methodnum(pyjlarray_array_interface) + methods["__array__"] = pyjl_methodnum(pyjlarray_array__array) + methods["__array_pyobjectarray__"] = pyjl_methodnum(pyjlarray_array__pyobjectarray) pycopy!(pyjlarraytype, jl.ArrayValue) end diff --git a/src/JlWrap/base.jl b/src/JlWrap/base.jl index 3a8b6c6b..f11e28ac 100644 --- a/src/JlWrap/base.jl +++ b/src/JlWrap/base.jl @@ -37,6 +37,7 @@ end function init_base() setptr!(pyjlbasetype, incref(Cjl.PyJuliaBase_Type[])) pyjuliacallmodule.ValueBase = pyjlbasetype + pyjuliacallmodule._init_jlwrap() # conversion rule priority = PYCONVERT_PRIORITY_WRAP diff --git a/src/JlWrap/callback.jl b/src/JlWrap/callback.jl index 8fdd48d1..e5e92991 100644 --- a/src/JlWrap/callback.jl +++ b/src/JlWrap/callback.jl @@ -38,35 +38,13 @@ pyjl_handle_error_type(::typeof(pyjlcallback_call), self, exc::MethodError) = function init_callback() jl = pyjuliacallmodule - pybuiltins.exec( - pybuiltins.compile( - """ -$("\n"^(@__LINE__()-1)) -class CallbackValue(ValueBase): - __slots__ = () - def __repr__(self): - if self._jl_isnull(): - return "" - else: - return self._jl_callmethod($(pyjl_methodnum(pyjlcallback_repr))) - def __str__(self): - if self._jl_isnull(): - return "NULL" - else: - return self._jl_callmethod($(pyjl_methodnum(pyjlcallback_str))) - def __call__(self, *args, **kwargs): - return self._jl_callmethod($(pyjl_methodnum(pyjlcallback_call)), args, kwargs) -""", - @__FILE__(), - "exec", - ), - jl.__dict__, - ) + m = pyimport("juliacall._jlwrap.callback") + methods = m._jl_methods + methods["__repr__"] = pyjl_methodnum(pyjlcallback_repr) + methods["__str__"] = pyjl_methodnum(pyjlcallback_str) + methods["__call__"] = pyjl_methodnum(pyjlcallback_call) pycopy!(pyjlcallbacktype, jl.CallbackValue) - pycopy!( - pywrapcallback, - pybuiltins.eval("lambda f: lambda *args, **kwargs: f(*args, **kwargs)", pydict()), - ) + pycopy!(pywrapcallback, m.wrap_callback) end pyjlcallback(f) = pyjl(pyjlcallbacktype, f) diff --git a/src/JlWrap/dict.jl b/src/JlWrap/dict.jl index 52a61fe3..933a9eb0 100644 --- a/src/JlWrap/dict.jl +++ b/src/JlWrap/dict.jl @@ -37,84 +37,20 @@ const pyjldicttype = pynew() function init_dict() jl = pyjuliacallmodule - pybuiltins.exec( - pybuiltins.compile( - """ -$("\n"^(@__LINE__()-1)) -class DictValue(AnyValue): - __slots__ = () - _jl_undefined_ = object() - def __bool__(self): - return bool(len(self)) - def __iter__(self): - return self._jl_callmethod($(pyjl_methodnum(pyjldict_iter))) - def __contains__(self, key): - return self._jl_callmethod($(pyjl_methodnum(pyjldict_contains)), key) - def __getitem__(self, key): - if key in self: - return self._jl_callmethod($(pyjl_methodnum(pyjldict_getitem)), key) - else: - raise KeyError(key) - def __setitem__(self, key, value): - return self._jl_callmethod($(pyjl_methodnum(pyjldict_setitem)), key, value) - def __delitem__(self, key): - if key in self: - return self._jl_callmethod($(pyjl_methodnum(pyjldict_delitem)), key) - else: - raise KeyError(key) - def keys(self): - return self._jl_callmethod($(pyjl_methodnum(Py ∘ keys))) - def values(self): - return self._jl_callmethod($(pyjl_methodnum(Py ∘ values))) - def items(self): - return self._jl_callmethod($(pyjl_methodnum(Py ∘ DictPairSet))) - def get(self, key, default=None): - if key in self: - return self[key] - else: - return default - def setdefault(self, key, default=None): - if key not in self: - self[key] = default - return self[key] - def clear(self): - return self._jl_callmethod($(pyjl_methodnum(pyjldict_clear))) - def pop(self, key, default=_jl_undefined_): - if key in self: - ans = self[key] - del self[key] - return ans - elif default is self._jl_undefined_: - raise KeyError(key) - else: - return default - def popitem(self): - if len(self): - return self._jl_callmethod($(pyjl_methodnum(Py ∘ pop!))) - else: - raise KeyError() - def update(self, other=_jl_undefined_, **kwargs): - if other is self._jl_undefined_: - pass - else: - if hasattr(other, "keys"): - items = ((k, other[k]) for k in other.keys()) - else: - items = other - self._jl_callmethod($(pyjl_methodnum(pyjldict_update)), items) - if kwargs: - self.update(kwargs) - def copy(self): - return self._jl_callmethod($(pyjl_methodnum(Py ∘ copy))) -import collections.abc -collections.abc.MutableMapping.register(DictValue) -del collections -""", - @__FILE__(), - "exec", - ), - jl.__dict__, - ) + m = pyimport("juliacall._jlwrap.dict") + methods = m._jl_methods + methods["__iter__"] = pyjl_methodnum(pyjldict_iter) + methods["__contains__"] = pyjl_methodnum(pyjldict_contains) + methods["__getitem__"] = pyjl_methodnum(pyjldict_getitem) + methods["__setitem__"] = pyjl_methodnum(pyjldict_setitem) + methods["__delitem__"] = pyjl_methodnum(pyjldict_delitem) + methods["keys"] = pyjl_methodnum(Py ∘ keys) + methods["values"] = pyjl_methodnum(Py ∘ values) + methods["items"] = pyjl_methodnum(Py ∘ DictPairSet) + methods["clear"] = pyjl_methodnum(pyjldict_clear) + methods["popitem"] = pyjl_methodnum(Py ∘ pop!) + methods["update"] = pyjl_methodnum(pyjldict_update) + methods["copy"] = pyjl_methodnum(Py ∘ copy) pycopy!(pyjldicttype, jl.DictValue) end diff --git a/src/JlWrap/io.jl b/src/JlWrap/io.jl index 5fa54a57..f79691ee 100644 --- a/src/JlWrap/io.jl +++ b/src/JlWrap/io.jl @@ -224,104 +224,25 @@ pyjl_handle_error_type(::typeof(pyjltextio_write), io, exc) = function init_io() jl = pyjuliacallmodule - pybuiltins.exec( - pybuiltins.compile( - """ -$("\n"^(@__LINE__()-1)) -class IOValueBase(AnyValue): - __slots__ = () - def close(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlio_close))) - @property - def closed(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlio_closed))) - def fileno(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlio_fileno))) - def flush(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlio_flush))) - def isatty(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlio_isatty))) - def readable(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlio_readable))) - def readlines(self, hint=-1): - lines = [] - total = 0 - while hint < 0 or total < hint: - line = self.readline() - if line: - lines.append(line) - total += len(line) - else: - break - return lines - def seek(self, offset, whence=0): - return self._jl_callmethod($(pyjl_methodnum(pyjlio_seek)), offset, whence) - def seekable(self): - return True - def tell(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlio_tell))) - def truncate(self, size=None): - return self._jl_callmethod($(pyjl_methodnum(pyjlio_truncate)), size) - def writable(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlio_writable))) - def writelines(self, lines): - for line in lines: - self.write(line) - def __enter__(self): - return self - def __exit__(self, t, v, b): - self.close() - def __iter__(self): - return self - def __next__(self): - line = self.readline() - if line: - return line - else: - raise StopIteration -class BinaryIOValue(IOValueBase): - __slots__ = () - def detach(self): - raise ValueError("Cannot detach '{}'.".format(type(self))) - def read(self, size=-1): - return self._jl_callmethod($(pyjl_methodnum(pyjlbinaryio_read)), size) - def read1(self, size=-1): - return self.read(size) - def readline(self, size=-1): - return self._jl_callmethod($(pyjl_methodnum(pyjlbinaryio_readline)), size) - def readinto(self, b): - return self._jl_callmethod($(pyjl_methodnum(pyjlbinaryio_readinto)), b) - def readinto1(self, b): - return self.readinto(b) - def write(self, b): - return self._jl_callmethod($(pyjl_methodnum(pyjlbinaryio_write)), b) -class TextIOValue(IOValueBase): - __slots__ = () - @property - def encoding(self): - return "UTF-8" - @property - def errors(self): - return "strict" - def detach(self): - raise ValueError("Cannot detach '{}'.".format(type(self))) - def read(self, size=-1): - return self._jl_callmethod($(pyjl_methodnum(pyjltextio_read)), size) - def readline(self, size=-1): - return self._jl_callmethod($(pyjl_methodnum(pyjltextio_readline)), size) - def write(self, s): - return self._jl_callmethod($(pyjl_methodnum(pyjltextio_write)), s) -import io -io.IOBase.register(IOValueBase) -io.BufferedIOBase.register(BinaryIOValue) -io.TextIOBase.register(TextIOValue) -del io -""", - @__FILE__(), - "exec", - ), - jl.__dict__, - ) + m = pyimport("juliacall._jlwrap.io") + methods = m._jl_methods + methods["close"] = pyjl_methodnum(pyjlio_close) + methods["closed"] = pyjl_methodnum(pyjlio_closed) + methods["fileno"] = pyjl_methodnum(pyjlio_fileno) + methods["flush"] = pyjl_methodnum(pyjlio_flush) + methods["isatty"] = pyjl_methodnum(pyjlio_isatty) + methods["readable"] = pyjl_methodnum(pyjlio_readable) + methods["seek"] = pyjl_methodnum(pyjlio_seek) + methods["tell"] = pyjl_methodnum(pyjlio_tell) + methods["truncate"] = pyjl_methodnum(pyjlio_truncate) + methods["writable"] = pyjl_methodnum(pyjlio_writable) + methods["binary_read"] = pyjl_methodnum(pyjlbinaryio_read) + methods["binary_readline"] = pyjl_methodnum(pyjlbinaryio_readline) + methods["readinto"] = pyjl_methodnum(pyjlbinaryio_readinto) + methods["binary_write"] = pyjl_methodnum(pyjlbinaryio_write) + methods["text_read"] = pyjl_methodnum(pyjltextio_read) + methods["text_readline"] = pyjl_methodnum(pyjltextio_readline) + methods["text_write"] = pyjl_methodnum(pyjltextio_write) pycopy!(pyjliobasetype, jl.IOValueBase) pycopy!(pyjlbinaryiotype, jl.BinaryIOValue) pycopy!(pyjltextiotype, jl.TextIOValue) diff --git a/src/JlWrap/iter.jl b/src/JlWrap/iter.jl index 787bd46f..bf1f1288 100644 --- a/src/JlWrap/iter.jl +++ b/src/JlWrap/iter.jl @@ -27,22 +27,9 @@ end function init_iter() jl = pyjuliacallmodule - pybuiltins.exec( - pybuiltins.compile( - """ -$("\n"^(@__LINE__()-1)) -class IteratorValue(AnyValue): - __slots__ = () - def __iter__(self): - return self - def __next__(self): - return self._jl_callmethod($(pyjl_methodnum(pyjliter_next))) -""", - @__FILE__(), - "exec", - ), - jl.__dict__, - ) + m = pyimport("juliacall._jlwrap.iter") + methods = m._jl_methods + methods["__next__"] = pyjl_methodnum(pyjliter_next) pycopy!(pyjlitertype, jl.IteratorValue) end diff --git a/src/JlWrap/module.jl b/src/JlWrap/module.jl index 5fb1aa8f..9b6ac0f6 100644 --- a/src/JlWrap/module.jl +++ b/src/JlWrap/module.jl @@ -17,22 +17,10 @@ precompile(pyjlmodule_seval, (Module, Py)) function init_module() jl = pyjuliacallmodule - pybuiltins.exec( - pybuiltins.compile( - """ -$("\n"^(@__LINE__()-1)) -class ModuleValue(AnyValue): - __slots__ = () - def __dir__(self): - return ValueBase.__dir__(self) + self._jl_callmethod($(pyjl_methodnum(pyjlmodule_dir))) - def seval(self, expr): - return self._jl_callmethod($(pyjl_methodnum(pyjlmodule_seval)), expr) -""", - @__FILE__(), - "exec", - ), - jl.__dict__, - ) + m = pyimport("juliacall._jlwrap.module") + methods = m._jl_methods + methods["__dir__"] = pyjl_methodnum(pyjlmodule_dir) + methods["seval"] = pyjl_methodnum(pyjlmodule_seval) pycopy!(pyjlmoduletype, jl.ModuleValue) end diff --git a/src/JlWrap/number.jl b/src/JlWrap/number.jl index ebc5b2a6..1914b3af 100644 --- a/src/JlWrap/number.jl +++ b/src/JlWrap/number.jl @@ -91,147 +91,53 @@ pyjl_handle_error_type(::typeof(pyjlreal_round), self, exc::MethodError) = function init_number() jl = pyjuliacallmodule - pybuiltins.exec( - pybuiltins.compile( - """ -$("\n"^(@__LINE__()-1)) -class NumberValue(AnyValue): - __slots__ = () - def __bool__(self): - return not self._jl_callmethod($(pyjl_methodnum(pyjlnumber_op(iszero)))) - def __add__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_op(+))), other) - def __sub__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_op(-))), other) - def __mul__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_op(*))), other) - def __truediv__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_op(/))), other) - def __floordiv__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_op(÷))), other) - def __mod__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_op(%))), other) - def __pow__(self, other, modulo=None): - if modulo is None: - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_op(^))), other) - else: - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_op(powermod))), other, modulo) - def __lshift__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_op(<<))), other) - def __rshift__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_op(>>))), other) - def __and__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_op(&))), other) - def __xor__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_op(⊻))), other) - def __or__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_op(|))), other) - def __radd__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_rev_op(+))), other) - def __rsub__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_rev_op(-))), other) - def __rmul__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_rev_op(*))), other) - def __rtruediv__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_rev_op(/))), other) - def __rfloordiv__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_rev_op(÷))), other) - def __rmod__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_rev_op(%))), other) - def __rpow__(self, other, modulo=None): - if modulo is None: - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_rev_op(^))), other) - else: - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_rev_op(powermod))), other, modulo) - def __rlshift__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_rev_op(<<))), other) - def __rrshift__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_rev_op(>>))), other) - def __rand__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_rev_op(&))), other) - def __rxor__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_rev_op(⊻))), other) - def __ror__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_rev_op(|))), other) - def __eq__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_op(==))), other) - def __ne__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_op(!=))), other) - def __le__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_op(≤))), other) - def __lt__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_op(<))), other) - def __ge__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_op(≥))), other) - def __gt__(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_op(>))), other) -class ComplexValue(NumberValue): - __slots__ = () - def __complex__(self): - return self._jl_callmethod($(pyjl_methodnum(pycomplex))) - @property - def real(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_op(real)))) - @property - def imag(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_op(imag)))) - def conjugate(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_op(conj)))) -class RealValue(ComplexValue): - __slots__ = () - def __float__(self): - return self._jl_callmethod($(pyjl_methodnum(pyfloat))) - @property - def real(self): - return self - @property - def imag(self): - return 0 - def conjugate(self): - return self - def __complex__(self): - return complex(float(self)) - def __trunc__(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlreal_trunc))) - def __floor__(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlreal_floor))) - def __ceil__(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlreal_ceil))) - def __round__(self, ndigits=None): - return self._jl_callmethod($(pyjl_methodnum(pyjlreal_round)), ndigits) -class RationalValue(RealValue): - __slots__ = () - @property - def numerator(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_op(numerator)))) - @property - def denominator(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlnumber_op(denominator)))) -class IntegerValue(RationalValue): - __slots__ = () - def __int__(self): - return self._jl_callmethod($(pyjl_methodnum(pyint))) - def __index__(self): - return self.__int__() - @property - def numerator(self): - return self - @property - def denominator(self): - return 1 -import numbers -numbers.Number.register(NumberValue) -numbers.Complex.register(ComplexValue) -numbers.Real.register(RealValue) -numbers.Rational.register(RationalValue) -numbers.Integral.register(IntegerValue) -del numbers -""", - @__FILE__(), - "exec", - ), - jl.__dict__, - ) + m = pyimport("juliacall._jlwrap.number") + methods = m._jl_methods + methods["__bool__"] = pyjl_methodnum(pyjlnumber_op(iszero)) + methods["__add__"] = pyjl_methodnum(pyjlnumber_op(+)) + methods["__sub__"] = pyjl_methodnum(pyjlnumber_op(-)) + methods["__mul__"] = pyjl_methodnum(pyjlnumber_op(*)) + methods["__truediv__"] = pyjl_methodnum(pyjlnumber_op(/)) + methods["__floordiv__"] = pyjl_methodnum(pyjlnumber_op(÷)) + methods["__mod__"] = pyjl_methodnum(pyjlnumber_op(%)) + methods["__pow__"] = pyjl_methodnum(pyjlnumber_op(^)) + methods["__pow_modulo__"] = pyjl_methodnum(pyjlnumber_op(powermod)) + methods["__lshift__"] = pyjl_methodnum(pyjlnumber_op(<<)) + methods["__rshift__"] = pyjl_methodnum(pyjlnumber_op(>>)) + methods["__and__"] = pyjl_methodnum(pyjlnumber_op(&)) + methods["__xor__"] = pyjl_methodnum(pyjlnumber_op(⊻)) + methods["__or__"] = pyjl_methodnum(pyjlnumber_op(|)) + methods["__radd__"] = pyjl_methodnum(pyjlnumber_rev_op(+)) + methods["__rsub__"] = pyjl_methodnum(pyjlnumber_rev_op(-)) + methods["__rmul__"] = pyjl_methodnum(pyjlnumber_rev_op(*)) + methods["__rtruediv__"] = pyjl_methodnum(pyjlnumber_rev_op(/)) + methods["__rfloordiv__"] = pyjl_methodnum(pyjlnumber_rev_op(÷)) + methods["__rmod__"] = pyjl_methodnum(pyjlnumber_rev_op(%)) + methods["__rpow__"] = pyjl_methodnum(pyjlnumber_rev_op(^)) + methods["__rpow_modulo__"] = pyjl_methodnum(pyjlnumber_rev_op(powermod)) + methods["__rlshift__"] = pyjl_methodnum(pyjlnumber_rev_op(<<)) + methods["__rrshift__"] = pyjl_methodnum(pyjlnumber_rev_op(>>)) + methods["__rand__"] = pyjl_methodnum(pyjlnumber_rev_op(&)) + methods["__rxor__"] = pyjl_methodnum(pyjlnumber_rev_op(⊻)) + methods["__ror__"] = pyjl_methodnum(pyjlnumber_rev_op(|)) + methods["__eq__"] = pyjl_methodnum(pyjlnumber_op(==)) + methods["__ne__"] = pyjl_methodnum(pyjlnumber_op(!=)) + methods["__le__"] = pyjl_methodnum(pyjlnumber_op(≤)) + methods["__lt__"] = pyjl_methodnum(pyjlnumber_op(<)) + methods["__ge__"] = pyjl_methodnum(pyjlnumber_op(≥)) + methods["__gt__"] = pyjl_methodnum(pyjlnumber_op(>)) + methods["__complex__"] = pyjl_methodnum(pycomplex) + methods["real"] = pyjl_methodnum(pyjlnumber_op(real)) + methods["imag"] = pyjl_methodnum(pyjlnumber_op(imag)) + methods["conjugate"] = pyjl_methodnum(pyjlnumber_op(conj)) + methods["__float__"] = pyjl_methodnum(pyfloat) + methods["__trunc__"] = pyjl_methodnum(pyjlreal_trunc) + methods["__floor__"] = pyjl_methodnum(pyjlreal_floor) + methods["__ceil__"] = pyjl_methodnum(pyjlreal_ceil) + methods["__round__"] = pyjl_methodnum(pyjlreal_round) + methods["numerator"] = pyjl_methodnum(pyjlnumber_op(numerator)) + methods["denominator"] = pyjl_methodnum(pyjlnumber_op(denominator)) + methods["__int__"] = pyjl_methodnum(pyint) pycopy!(pyjlnumbertype, jl.NumberValue) pycopy!(pyjlcomplextype, jl.ComplexValue) pycopy!(pyjlrealtype, jl.RealValue) diff --git a/src/JlWrap/raw.jl b/src/JlWrap/raw.jl index 663b0087..f64c0918 100644 --- a/src/JlWrap/raw.jl +++ b/src/JlWrap/raw.jl @@ -100,66 +100,21 @@ pyjlraw_bool(self) = function init_raw() jl = pyjuliacallmodule - pybuiltins.exec( - pybuiltins.compile( - """ -$("\n"^(@__LINE__()-1)) -class RawValue(ValueBase): - __slots__ = () - def __repr__(self): - if self._jl_isnull(): - return "" - else: - return self._jl_callmethod($(pyjl_methodnum(pyjlraw_repr))) - def __str__(self): - if self._jl_isnull(): - return "NULL" - else: - return self._jl_callmethod($(pyjl_methodnum(pyjlraw_str))) - def __getattr__(self, k): - if k.startswith("__") and k.endswith("__"): - raise AttributeError(k) - else: - return self._jl_callmethod($(pyjl_methodnum(pyjlraw_getattr)), k) - def __setattr__(self, k, v): - try: - ValueBase.__setattr__(self, k, v) - except AttributeError: - if k.startswith("__") and k.endswith("__"): - raise - else: - return - self._jl_callmethod($(pyjl_methodnum(pyjlraw_setattr)), k, v) - def __dir__(self): - return ValueBase.__dir__(self) + self._jl_callmethod($(pyjl_methodnum(pyjlraw_dir))) - def __call__(self, *args, **kwargs): - return self._jl_callmethod($(pyjl_methodnum(pyjlraw_call)), args, kwargs) - def __len__(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlraw_len))) - def __getitem__(self, k): - return self._jl_callmethod($(pyjl_methodnum(pyjlraw_getitem)), k) - def __setitem__(self, k, v): - self._jl_callmethod($(pyjl_methodnum(pyjlraw_setitem)), k, v) - def __delitem__(self, k): - self._jl_callmethod($(pyjl_methodnum(pyjlraw_delitem)), k) - def __bool__(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlraw_bool))) - def _jl_any(self): - '''Convert this to a juliacall.AnyValue.''' - return self._jl_callmethod($(pyjl_methodnum(pyjl))) - def _jl_call_nogil(self, *args, **kwargs): - '''Call this with the given arguments but with the GIL disabled. - - WARNING: This function must not interact with Python at all without re-acquiring - the GIL. - ''' - return self._jl_callmethod($(pyjl_methodnum(pyjlraw_call_nogil)), args, kwargs) -""", - @__FILE__(), - "exec", - ), - jl.__dict__, - ) + m = pyimport("juliacall._jlwrap.raw") + methods = m._jl_methods + methods["__repr__"] = pyjl_methodnum(pyjlraw_repr) + methods["__str__"] = pyjl_methodnum(pyjlraw_str) + methods["__getattr__"] = pyjl_methodnum(pyjlraw_getattr) + methods["__setattr__"] = pyjl_methodnum(pyjlraw_setattr) + methods["__dir__"] = pyjl_methodnum(pyjlraw_dir) + methods["__call__"] = pyjl_methodnum(pyjlraw_call) + methods["__len__"] = pyjl_methodnum(pyjlraw_len) + methods["__getitem__"] = pyjl_methodnum(pyjlraw_getitem) + methods["__setitem__"] = pyjl_methodnum(pyjlraw_setitem) + methods["__delitem__"] = pyjl_methodnum(pyjlraw_delitem) + methods["__bool__"] = pyjl_methodnum(pyjlraw_bool) + methods["_jl_any"] = pyjl_methodnum(pyjl) + methods["_jl_call_nogil"] = pyjl_methodnum(pyjlraw_call_nogil) pycopy!(pyjlrawtype, jl.RawValue) end diff --git a/src/JlWrap/set.jl b/src/JlWrap/set.jl index 7b7b08e0..c555bafd 100644 --- a/src/JlWrap/set.jl +++ b/src/JlWrap/set.jl @@ -76,57 +76,18 @@ end function init_set() jl = pyjuliacallmodule - pybuiltins.exec( - pybuiltins.compile( - """ -$("\n"^(@__LINE__()-1)) -class SetValue(AnyValue): - __slots__ = () - def __bool__(self): - return bool(len(self)) - def add(self, value): - return self._jl_callmethod($(pyjl_methodnum(pyjlset_add)), value) - def discard(self, value): - return self._jl_callmethod($(pyjl_methodnum(pyjlset_discard)), value) - def clear(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlset_clear))) - def copy(self): - return self._jl_callmethod($(pyjl_methodnum(Py ∘ copy))) - def pop(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlset_pop))) - def remove(self, value): - return self._jl_callmethod($(pyjl_methodnum(pyjlset_remove)), value) - def difference(self, other): - return set(self).difference(other) - def intersection(self, other): - return set(self).intersection(other) - def symmetric_difference(self, other): - return set(self).symmetric_difference(other) - def union(self, other): - return set(self).union(other) - def isdisjoint(self, other): - return set(self).isdisjoint(other) - def issubset(self, other): - return set(self).issubset(other) - def issuperset(self, other): - return set(self).issuperset(other) - def difference_update(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlset_difference_update)), other) - def intersection_update(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlset_intersection_update)), other) - def symmetric_difference_update(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlset_symmetric_difference_update)), other) - def update(self, other): - return self._jl_callmethod($(pyjl_methodnum(pyjlset_update)), other) -import collections.abc -collections.abc.MutableSet.register(SetValue) -del collections -""", - @__FILE__(), - "exec", - ), - jl.__dict__, - ) + m = pyimport("juliacall._jlwrap.set") + methods = m._jl_methods + methods["add"] = pyjl_methodnum(pyjlset_add) + methods["discard"] = pyjl_methodnum(pyjlset_discard) + methods["clear"] = pyjl_methodnum(pyjlset_clear) + methods["copy"] = pyjl_methodnum(Py ∘ copy) + methods["pop"] = pyjl_methodnum(pyjlset_pop) + methods["remove"] = pyjl_methodnum(pyjlset_remove) + methods["difference_update"] = pyjl_methodnum(pyjlset_difference_update) + methods["intersection_update"] = pyjl_methodnum(pyjlset_intersection_update) + methods["symmetric_difference_update"] = pyjl_methodnum(pyjlset_symmetric_difference_update) + methods["update"] = pyjl_methodnum(pyjlset_update) pycopy!(pyjlsettype, jl.SetValue) end diff --git a/src/JlWrap/type.jl b/src/JlWrap/type.jl index 669111ac..116b8d4b 100644 --- a/src/JlWrap/type.jl +++ b/src/JlWrap/type.jl @@ -56,27 +56,10 @@ end function init_type() jl = pyjuliacallmodule - pybuiltins.exec( - pybuiltins.compile( - """ -$("\n"^(@__LINE__()-1)) -class TypeValue(AnyValue): - __slots__ = () - def __getitem__(self, k): - return self._jl_callmethod($(pyjl_methodnum(pyjltype_getitem)), k) - def __setitem__(self, k, v): - raise TypeError("not supported") - def __delitem__(self, k): - raise TypeError("not supported") - @property - def __numpy_dtype__(self): - return self._jl_callmethod($(pyjl_methodnum(pyjltype_numpy_dtype))) -""", - @__FILE__(), - "exec", - ), - jl.__dict__, - ) + m = pyimport("juliacall._jlwrap.type") + methods = m._jl_methods + methods["__getitem__"] = pyjl_methodnum(pyjltype_getitem) + methods["__numpy_dtype__"] = pyjl_methodnum(pyjltype_numpy_dtype) pycopy!(pyjltypetype, jl.TypeValue) end diff --git a/src/JlWrap/vector.jl b/src/JlWrap/vector.jl index 3c71e5b9..8b665f4c 100644 --- a/src/JlWrap/vector.jl +++ b/src/JlWrap/vector.jl @@ -119,45 +119,20 @@ end function init_vector() jl = pyjuliacallmodule - pybuiltins.exec( - pybuiltins.compile( - """ -$("\n"^(@__LINE__()-1)) -class VectorValue(ArrayValue): - __slots__ = () - def resize(self, size): - return self._jl_callmethod($(pyjl_methodnum(pyjlvector_resize)), size) - def sort(self, reverse=False, key=None): - return self._jl_callmethod($(pyjl_methodnum(pyjlvector_sort)), reverse, key) - def reverse(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlvector_reverse))) - def clear(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlvector_clear))) - def __reversed__(self): - return self._jl_callmethod($(pyjl_methodnum(pyjlvector_reversed))) - def insert(self, index, value): - return self._jl_callmethod($(pyjl_methodnum(pyjlvector_insert)), index, value) - def append(self, value): - return self._jl_callmethod($(pyjl_methodnum(pyjlvector_append)), value) - def extend(self, values): - return self._jl_callmethod($(pyjl_methodnum(pyjlvector_extend)), values) - def pop(self, index=-1): - return self._jl_callmethod($(pyjl_methodnum(pyjlvector_pop)), index) - def remove(self, value): - return self._jl_callmethod($(pyjl_methodnum(pyjlvector_remove)), value) - def index(self, value): - return self._jl_callmethod($(pyjl_methodnum(pyjlvector_index)), value) - def count(self, value): - return self._jl_callmethod($(pyjl_methodnum(pyjlvector_count)), value) -import collections.abc -collections.abc.MutableSequence.register(VectorValue) -del collections -""", - @__FILE__(), - "exec", - ), - jl.__dict__, - ) + m = pyimport("juliacall._jlwrap.vector") + methods = m._jl_methods + methods["resize"] = pyjl_methodnum(pyjlvector_resize) + methods["sort"] = pyjl_methodnum(pyjlvector_sort) + methods["reverse"] = pyjl_methodnum(pyjlvector_reverse) + methods["clear"] = pyjl_methodnum(pyjlvector_clear) + methods["__reversed__"] = pyjl_methodnum(pyjlvector_reversed) + methods["insert"] = pyjl_methodnum(pyjlvector_insert) + methods["append"] = pyjl_methodnum(pyjlvector_append) + methods["extend"] = pyjl_methodnum(pyjlvector_extend) + methods["pop"] = pyjl_methodnum(pyjlvector_pop) + methods["remove"] = pyjl_methodnum(pyjlvector_remove) + methods["index"] = pyjl_methodnum(pyjlvector_index) + methods["count"] = pyjl_methodnum(pyjlvector_count) pycopy!(pyjlvectortype, jl.VectorValue) end