Skip to content

Cython v3 support #426

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[build-system]
requires = ["setuptools>=42.0", "wheel", "oldest-supported-numpy", "cython>=0.28"]
requires = ["setuptools>=42.0", "wheel", "oldest-supported-numpy", "cython~=3.0"]
build-backend = "setuptools.build_meta"
6 changes: 3 additions & 3 deletions raysect/core/math/affinematrix.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ cdef class AffineMatrix3D(_Mat4):
s += ", "
return s + "])"

def __mul__(object x, object y):
def __mul__(self, object y):
"""Multiplication operator.

>>> from raysect.core import translate, rotate_x
Expand All @@ -146,9 +146,9 @@ cdef class AffineMatrix3D(_Mat4):

cdef AffineMatrix3D mx, my

if isinstance(x, AffineMatrix3D) and isinstance(y, AffineMatrix3D):
if isinstance(y, AffineMatrix3D):

mx = <AffineMatrix3D>x
mx = self
my = <AffineMatrix3D>y
return new_affinematrix3d(mx.m[0][0] * my.m[0][0] + mx.m[0][1] * my.m[1][0] + mx.m[0][2] * my.m[2][0] + mx.m[0][3] * my.m[3][0],
mx.m[0][0] * my.m[0][1] + mx.m[0][1] * my.m[1][1] + mx.m[0][2] * my.m[2][1] + mx.m[0][3] * my.m[3][1],
Expand Down
163 changes: 91 additions & 72 deletions raysect/core/math/function/float/function1d/base.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -65,104 +65,123 @@ cdef class Function1D(FloatFunction):
def __repr__(self):
return 'Function1D(x)'

def __add__(object a, object b):
if is_callable(a):
if is_callable(b):
# a() + b()
return AddFunction1D(a, b)
elif isinstance(b, numbers.Real):
# a() + B -> B + a()
return AddScalar1D(<double> b, a)
elif isinstance(a, numbers.Real):
if is_callable(b):
# A + b()
return AddScalar1D(<double> a, b)
def __add__(self, object b):
if is_callable(b):
# a() + b()
return AddFunction1D(self, b)
elif isinstance(b, numbers.Real):
# a() + B -> B + a()
return AddScalar1D(<double> b, self)
return NotImplemented

def __sub__(object a, object b):

def __radd__(self, object a):
return self.__add__(a)

def __sub__(self, object b):
if is_callable(b):
# a() - b()
return SubtractFunction1D(self, b)
elif isinstance(b, numbers.Real):
# a() - B -> -B + a()
return AddScalar1D(-(<double> b), self)
return NotImplemented

def __rsub__(self, object a):
if is_callable(a):
if is_callable(b):
# a() - b()
return SubtractFunction1D(a, b)
elif isinstance(b, numbers.Real):
# a() - B -> -B + a()
return AddScalar1D(-(<double> b), a)
# a() - b()
return SubtractFunction1D(a, self)
elif isinstance(a, numbers.Real):
if is_callable(b):
# A - b()
return SubtractScalar1D(<double> a, b)
# A - b()
return SubtractScalar1D(<double> a, self)
return NotImplemented

def __mul__(object a, object b):
if is_callable(a):
if is_callable(b):
# a() * b()
return MultiplyFunction1D(a, b)
elif isinstance(b, numbers.Real):
# a() * B -> B * a()
return MultiplyScalar1D(<double> b, a)
elif isinstance(a, numbers.Real):
if is_callable(b):
# A * b()
return MultiplyScalar1D(<double> a, b)
def __mul__(self, object b):
if is_callable(b):
# a() * b()
return MultiplyFunction1D(self, b)
elif isinstance(b, numbers.Real):
# a() * B -> B * a()
return MultiplyScalar1D(<double> b, self)
return NotImplemented

def __rmul__(self, object a):
return self.__mul__(a)

@cython.cdivision(True)
def __truediv__(object a, object b):
def __truediv__(self, object b):
cdef double v
if is_callable(b):
# a() / b()
return DivideFunction1D(self, b)
elif isinstance(b, numbers.Real):
# a() / B -> 1/B * a()
v = <double> b
if v == 0.0:
raise ZeroDivisionError("Scalar used as the denominator of the division is zero valued.")
return MultiplyScalar1D(1/v, self)
return NotImplemented

@cython.cdivision(True)
def __rtruediv__(self, object a):
if is_callable(a):
if is_callable(b):
# a() / b()
return DivideFunction1D(a, b)
elif isinstance(b, numbers.Real):
# a() / B -> 1/B * a()
v = <double> b
if v == 0.0:
raise ZeroDivisionError("Scalar used as the denominator of the division is zero valued.")
return MultiplyScalar1D(1/v, a)
# a() / b()
return DivideFunction1D(a, self)
elif isinstance(a, numbers.Real):
if is_callable(b):
# A * b()
return DivideScalar1D(<double> a, b)
# A / b()
return DivideScalar1D(<double> a, self)
return NotImplemented

def __mod__(object a, object b):
def __mod__(self, object b):
cdef double v
if is_callable(b):
# a() % b()
return ModuloFunction1D(self, b)
elif isinstance(b, numbers.Real):
# a() % B
v = <double> b
if v == 0.0:
raise ZeroDivisionError("Scalar used as the divisor of the division is zero valued.")
return ModuloFunctionScalar1D(self, v)
return NotImplemented

def __rmod__(self, object a):
if is_callable(a):
if is_callable(b):
# a() % b()
return ModuloFunction1D(a, b)
elif isinstance(b, numbers.Real):
# a() % B
v = <double> b
if v == 0.0:
raise ZeroDivisionError("Scalar used as the divisor of the division is zero valued.")
return ModuloFunctionScalar1D(a, v)
# a() % b()
return ModuloFunction1D(a, self)
elif isinstance(a, numbers.Real):
if is_callable(b):
# A % b()
return ModuloScalarFunction1D(<double> a, b)
# A % b()
return ModuloScalarFunction1D(<double> a, self)
return NotImplemented

def __neg__(self):
return MultiplyScalar1D(-1, self)

def __pow__(object a, object b, object c):
def __pow__(self, object b, object c):
if c is not None:
# Optimised implementation of pow(a, b, c) not available: fall back
# to general implementation
return PowFunction1D(self, b) % c

if is_callable(b):
# a() ** b()
return PowFunction1D(self, b)
elif isinstance(b, numbers.Real):
# a() ** b
return PowFunctionScalar1D(self, <double> b)
return NotImplemented

def __rpow__(self, object a, object c):
if c is not None:
# Optimised implementation of pow(a, b, c) not available: fall back
# to general implementation
return (a ** b) % c
return PowFunction1D(a, self) % c

if is_callable(a):
if is_callable(b):
# a() ** b()
return PowFunction1D(a, b)
elif isinstance(b, numbers.Real):
# a() ** b
return PowFunctionScalar1D(a, <double> b)
# a() ** b()
return PowFunction1D(a, self)
elif isinstance(a, numbers.Real):
if is_callable(b):
# a ** b()
return PowScalarFunction1D(<double> a, b)
# A ** b()
return PowScalarFunction1D(<double> a, self)
return NotImplemented

def __abs__(self):
Expand Down
Loading