From d8ff4f37ee648a890759c5dc1ed02381e4e0ab5d Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Thu, 22 Oct 2026 12:44:00 -0400 Subject: [PATCH] chore: drop Python 3.10 Use typing.Self now that 3.11 is the minimum. Assisted-by: ClaudeCode:claude-opus-5-5 --- .github/workflows/ci.yml | 2 - .github/workflows/notebooks.yml | 2 +- .pre-commit-config.yaml | 2 +- docs/conf.py | 4 +- pyproject.toml | 11 +- src/vector/_methods.py | 181 +++++++++++++++----------------- src/vector/backends/numpy.py | 26 ++--- src/vector/backends/object.py | 17 ++- src/vector/backends/sympy.py | 17 ++- 9 files changed, 120 insertions(+), 142 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3296e237..498a547d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,7 +44,6 @@ jobs: fail-fast: false matrix: python-version: - - "3.10" - "3.11" - "3.12" - "3.13" @@ -78,7 +77,6 @@ jobs: fail-fast: false matrix: python-version: - - "3.10" - "3.11" - "3.12" - "3.13" diff --git a/.github/workflows/notebooks.yml b/.github/workflows/notebooks.yml index 1929a331..6a09f153 100644 --- a/.github/workflows/notebooks.yml +++ b/.github/workflows/notebooks.yml @@ -32,7 +32,7 @@ jobs: - name: Set up Python uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: - python-version: "3.10" + python-version: "3.11" - uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a689f364..a882a548 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -33,7 +33,7 @@ repos: args: [] additional_dependencies: # numpy>=2.5 requires Python>=3.12 and its stubs use PEP 695 syntax, - # which mypy cannot parse while python_version is pinned to 3.10 + # which mypy cannot parse while python_version is pinned to 3.11 - numpy<2.5 - packaging - sympy diff --git a/docs/conf.py b/docs/conf.py index 0093f45a..f522a609 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -7,7 +7,7 @@ from __future__ import annotations import importlib.metadata -from datetime import datetime, timezone +from datetime import UTC, datetime # -- Path setup -------------------------------------------------------------- # If extensions (or modules to document with autodoc) are in another directory, @@ -22,7 +22,7 @@ # -- Project information ----------------------------------------------------- project = "Vector" -copyright = f"2019\u2012{datetime.now(tz=timezone.utc).year}" +copyright = f"2019\u2012{datetime.now(tz=UTC).year}" author = ( "Saransh Chopra, Henry Schreiner, Jim Pivarski, Eduardo Rodrigues, and Jonas Eschle" ) diff --git a/pyproject.toml b/pyproject.toml index d3a4c14f..3e06dde9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,7 +19,7 @@ maintainers = [ authors = [ { name = "Saransh Chopra, Jim Pivarski, Henry Schreiner, Eduardo Rodrigues, Jonas Eschle", email = "eduardo.rodrigues@cern.ch" }, ] -requires-python = ">=3.10" +requires-python = ">=3.11" classifiers = [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", @@ -27,7 +27,6 @@ classifiers = [ "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", @@ -136,8 +135,6 @@ ignore = [ "PLR09", # Too many X "PLR2004", # Magic values "N999", # Module names follow ROOT's spelling (Et, deltaR, rotateZ, ...) - "PYI019", # returning Self needs typing_extensions on Python 3.10 - "PYI034", # __new__ returning Self needs typing_extensions on Python 3.10 "TRY004", # AssertionError marks unreachable branches, not bad user types ] typing-modules = [ @@ -185,7 +182,7 @@ isort.required-imports = [ ] [tool.pylint] -master.py-version = "3.10" +master.py-version = "3.11" reports.output-format = "colorized" similarities.ignore-imports = "yes" master.jobs = "0" @@ -274,7 +271,7 @@ filterwarnings = [ files = [ "src/vector", ] -python_version = "3.10" +python_version = "3.11" strict = true warn_return_any = false enable_error_code = [ @@ -311,7 +308,7 @@ platforms = ["linux-64", "osx-arm64", "osx-64"] exclude-newer = "7d" [tool.pixi.feature.root.dependencies] -python = ">=3.10" +python = ">=3.11" root = ">=6.18.04" numba = ">=0.57" numpy = ">=1.19.3" diff --git a/src/vector/_methods.py b/src/vector/_methods.py index d164e084..d6744103 100644 --- a/src/vector/_methods.py +++ b/src/vector/_methods.py @@ -129,9 +129,6 @@ class TemporalTau(Temporal): tau: ScalarCollection -SameVectorType = typing.TypeVar("SameVectorType", bound="VectorProtocol") - - class VectorProtocol: """ Attributes: @@ -600,7 +597,7 @@ def to_ptphietamass(self) -> VectorProtocolLorentz: """ raise AssertionError - def unit(self: SameVectorType) -> SameVectorType: + def unit(self) -> typing.Self: """ Returns vector(s) normalized to unit length, which is `rho == 1` for 2D vectors, `mag == 1` for 3D vectors, and `tau == 1` for 4D vectors. @@ -631,7 +628,7 @@ def subtract(self, other: VectorProtocol) -> VectorProtocol: """ raise AssertionError - def scale(self: SameVectorType, factor: ScalarCollection) -> SameVectorType: + def scale(self, factor: ScalarCollection) -> typing.Self: """ Returns vector(s) scaled by a ``factor``, changing the length(s) but not the direction(s). @@ -752,7 +749,7 @@ def phi(self) -> ScalarCollection: """ raise AssertionError - def scale2D(self: SameVectorType, factor: ScalarCollection) -> SameVectorType: + def scale2D(self, factor: ScalarCollection) -> typing.Self: """ Returns vector(s) with the 2D part scaled by a ``factor``, not affecting any longitudinal or temporal parts. @@ -760,7 +757,7 @@ def scale2D(self: SameVectorType, factor: ScalarCollection) -> SameVectorType: raise AssertionError @property - def neg2D(self: SameVectorType) -> SameVectorType: + def neg2D(self) -> typing.Self: """ Returns vector(s) with the 2D part negated, not affecting any longitudinal or temporal parts. @@ -771,7 +768,7 @@ def deltaphi(self, other: VectorProtocol) -> ScalarCollection: r"""Signed difference in $\phi$ of ``self`` minus ``other`` (in radians).""" raise AssertionError - def rotateZ(self: SameVectorType, angle: ScalarCollection) -> SameVectorType: + def rotateZ(self, angle: ScalarCollection) -> typing.Self: """ Rotates the vector(s) by a given ``angle`` (in radians) around the longitudinal axis. @@ -781,7 +778,7 @@ def rotateZ(self: SameVectorType, angle: ScalarCollection) -> SameVectorType: """ raise AssertionError - def transform2D(self: SameVectorType, obj: TransformProtocol2D) -> SameVectorType: + def transform2D(self, obj: TransformProtocol2D) -> typing.Self: """ Arbitrarily transforms the vector(s) by @@ -890,7 +887,7 @@ def mag2(self) -> ScalarCollection: """The magnitude-squared of the vector(s) in 3D (not including any temporal parts).""" raise AssertionError - def scale3D(self: SameVectorType, factor: ScalarCollection) -> SameVectorType: + def scale3D(self, factor: ScalarCollection) -> typing.Self: """ Returns vector(s) with the 3D part scaled by a ``factor``, not affecting any longitudinal or temporal parts. @@ -898,7 +895,7 @@ def scale3D(self: SameVectorType, factor: ScalarCollection) -> SameVectorType: raise AssertionError @property - def neg3D(self: SameVectorType) -> SameVectorType: + def neg3D(self) -> typing.Self: """ Returns vector(s) with the 3D part negated, not affecting any longitudinal or temporal parts. @@ -951,7 +948,7 @@ def deltaR2( """ raise AssertionError - def rotateX(self: SameVectorType, angle: ScalarCollection) -> SameVectorType: + def rotateX(self, angle: ScalarCollection) -> typing.Self: """ Rotates the vector(s) by a given ``angle`` (in radians) around the $x$ axis. @@ -961,7 +958,7 @@ def rotateX(self: SameVectorType, angle: ScalarCollection) -> SameVectorType: """ raise AssertionError - def rotateY(self: SameVectorType, angle: ScalarCollection) -> SameVectorType: + def rotateY(self, angle: ScalarCollection) -> typing.Self: """ Rotates the vector(s) by a given ``angle`` (in radians) around the $y$ axis. @@ -972,8 +969,8 @@ def rotateY(self: SameVectorType, angle: ScalarCollection) -> SameVectorType: raise AssertionError def rotate_axis( - self: SameVectorType, axis: VectorProtocolSpatial, angle: ScalarCollection - ) -> SameVectorType: + self, axis: VectorProtocolSpatial, angle: ScalarCollection + ) -> typing.Self: """ Rotates the vector(s) by a given ``angle`` (in radians) around the axis indicated by another vector, ``axis``. The magnitude of ``axis`` is @@ -985,12 +982,12 @@ def rotate_axis( raise AssertionError def rotate_euler( - self: SameVectorType, + self, phi: ScalarCollection, theta: ScalarCollection, psi: ScalarCollection, order: str = "zxz", - ) -> SameVectorType: + ) -> typing.Self: """ Rotates the vector(s) by three given angles: ``phi``, ``theta``, and ``psi`` (in radians). The ``order`` string determines which axis each rotation is @@ -1014,11 +1011,11 @@ def rotate_euler( raise AssertionError def rotate_nautical( - self: SameVectorType, + self, yaw: ScalarCollection, pitch: ScalarCollection, roll: ScalarCollection, - ) -> SameVectorType: + ) -> typing.Self: """ Rotates the vector(s) by three given angles: ``yaw``, ``pitch``, and ``roll`` (in radians). These are Tait-Bryan angles often used for boats and planes @@ -1037,12 +1034,12 @@ def rotate_nautical( raise AssertionError def rotate_quaternion( - self: SameVectorType, + self, u: ScalarCollection, i: ScalarCollection, j: ScalarCollection, k: ScalarCollection, - ) -> SameVectorType: + ) -> typing.Self: """ Rotates the vector(s) by four angles as quaternion coefficients (in radians). Four angles are sometimes preferred over three because the latter has a @@ -1056,7 +1053,7 @@ def rotate_quaternion( """ raise AssertionError - def transform3D(self: SameVectorType, obj: TransformProtocol3D) -> SameVectorType: + def transform3D(self, obj: TransformProtocol3D) -> typing.Self: """ Arbitrarily transforms the vector(s) by @@ -1199,16 +1196,16 @@ def deltaRapidityPhi2(self, other: VectorProtocolLorentz) -> ScalarCollection: """ raise AssertionError - def scale4D(self: SameVectorType, factor: ScalarCollection) -> SameVectorType: + def scale4D(self, factor: ScalarCollection) -> typing.Self: """Same as ``scale``.""" raise AssertionError @property - def neg4D(self: SameVectorType) -> SameVectorType: + def neg4D(self) -> typing.Self: """Same as multiplying by -1.""" raise AssertionError - def boost_p4(self: SameVectorType, p4: VectorProtocolLorentz) -> SameVectorType: + def boost_p4(self, p4: VectorProtocolLorentz) -> typing.Self: """ Boosts the vector or array of vectors in a direction and magnitude given by the 4D vector or array of vectors ``p4``. @@ -1234,9 +1231,7 @@ def boost_p4(self: SameVectorType, p4: VectorProtocolLorentz) -> SameVectorType: """ raise AssertionError - def boost_beta3( - self: SameVectorType, beta3: VectorProtocolSpatial - ) -> SameVectorType: + def boost_beta3(self, beta3: VectorProtocolSpatial) -> typing.Self: """ Boosts the vector or array of vectors in a direction and magnitude given by the 3D velocity or array of velocity vectors ``beta3``. @@ -1254,8 +1249,8 @@ def boost_beta3( raise AssertionError def boost( - self: SameVectorType, booster: VectorProtocolSpatial | VectorProtocolLorentz - ) -> SameVectorType: + self, booster: VectorProtocolSpatial | VectorProtocolLorentz + ) -> typing.Self: """ Boosts the vector or array of vectors using the 3D or 4D ``booster``. @@ -1277,9 +1272,7 @@ def boost( """ raise AssertionError - def boostCM_of_p4( - self: SameVectorType, p4: VectorProtocolLorentz - ) -> SameVectorType: + def boostCM_of_p4(self, p4: VectorProtocolLorentz) -> typing.Self: """ Boosts the vector or array of vectors to the center-of-mass (CM) frame of the 4D vector or array of vectors ``p4``. @@ -1295,9 +1288,7 @@ def boostCM_of_p4( """ raise AssertionError - def boostCM_of_beta3( - self: SameVectorType, beta3: VectorProtocolSpatial - ) -> SameVectorType: + def boostCM_of_beta3(self, beta3: VectorProtocolSpatial) -> typing.Self: """ Boosts the vector or array of vectors to the center-of-mass (CM) frame of the 3D velocity or array of velocity vectors ``beta3``. @@ -1308,8 +1299,8 @@ def boostCM_of_beta3( raise AssertionError def boostCM_of( - self: SameVectorType, booster: VectorProtocolSpatial | VectorProtocolLorentz - ) -> SameVectorType: + self, booster: VectorProtocolSpatial | VectorProtocolLorentz + ) -> typing.Self: """ Boosts the vector or array of vectors to the center-of-mass (CM) frame of the 3D or 4D ``booster``. @@ -1327,10 +1318,10 @@ def boostCM_of( raise AssertionError def boostX( - self: SameVectorType, + self, beta: ScalarCollection | None = None, gamma: ScalarCollection | None = None, - ) -> SameVectorType: + ) -> typing.Self: """ Boosts the vector or array of vectors in the $x$ direction by a speed ``beta`` (in which lightlike boosts have ``beta == 1``) or time dilation/length @@ -1344,10 +1335,10 @@ def boostX( raise AssertionError def boostY( - self: SameVectorType, + self, beta: ScalarCollection | None = None, gamma: ScalarCollection | None = None, - ) -> SameVectorType: + ) -> typing.Self: """ Boosts the vector or array of vectors in the $y$ direction by a speed ``beta`` (in which lightlike boosts have ``beta == 1``) or time dilation/length @@ -1361,10 +1352,10 @@ def boostY( raise AssertionError def boostZ( - self: SameVectorType, + self, beta: ScalarCollection | None = None, gamma: ScalarCollection | None = None, - ) -> SameVectorType: + ) -> typing.Self: """ Boosts the vector or array of vectors in the $z$ direction by a speed ``beta`` (in which lightlike boosts have ``beta == 1``) or time dilation/length @@ -1377,7 +1368,7 @@ def boostZ( """ raise AssertionError - def transform4D(self: SameVectorType, obj: TransformProtocol4D) -> SameVectorType: + def transform4D(self, obj: TransformProtocol4D) -> typing.Self: """ Arbitrarily transforms the vector(s) by @@ -2736,7 +2727,7 @@ def __new__( __temporal: Temporal, ) -> Vector: ... - def __new__(cls, *args: typing.Any, **kwargs: float) -> Vector: + def __new__(cls, *args: typing.Any, **kwargs: float) -> Vector: # noqa: PYI034 if cls is not Vector: return super().__new__(cls) @@ -3462,12 +3453,12 @@ def deltaphi(self, other: VectorProtocol) -> ScalarCollection: return deltaphi.dispatch(self, other) - def rotateZ(self: SameVectorType, angle: ScalarCollection) -> SameVectorType: + def rotateZ(self, angle: ScalarCollection) -> typing.Self: from vector._compute.planar import rotateZ return rotateZ.dispatch(angle, self) - def transform2D(self: SameVectorType, obj: TransformProtocol2D) -> SameVectorType: + def transform2D(self, obj: TransformProtocol2D) -> typing.Self: from vector._compute.planar import transform2D return transform2D.dispatch(obj, self) @@ -3496,7 +3487,7 @@ def is_perpendicular( _maybe_same_dimension_error(self, other, self.is_perpendicular.__name__) return is_perpendicular.dispatch(tolerance, self, other) - def unit(self: SameVectorType) -> SameVectorType: + def unit(self) -> typing.Self: from vector._compute.planar import unit return unit.dispatch(self) @@ -3517,17 +3508,17 @@ def subtract(self, other: VectorProtocol) -> VectorProtocol: return module.subtract.dispatch(self, other) @property - def neg2D(self: SameVectorType) -> SameVectorType: + def neg2D(self) -> typing.Self: from vector._compute.planar import scale return scale.dispatch(-1, self) - def scale2D(self: SameVectorType, factor: ScalarCollection) -> SameVectorType: + def scale2D(self, factor: ScalarCollection) -> typing.Self: from vector._compute.planar import scale return scale.dispatch(factor, self) - def scale(self: SameVectorType, factor: ScalarCollection) -> SameVectorType: + def scale(self, factor: ScalarCollection) -> typing.Self: from vector._compute.planar import scale return scale.dispatch(factor, self) @@ -3643,19 +3634,19 @@ def deltaR2( raise TypeError(f"{other!r} is not a 3D or a 4D vector") return deltaR2.dispatch(self, other) - def rotateX(self: SameVectorType, angle: ScalarCollection) -> SameVectorType: + def rotateX(self, angle: ScalarCollection) -> typing.Self: from vector._compute.spatial import rotateX return rotateX.dispatch(angle, self) - def rotateY(self: SameVectorType, angle: ScalarCollection) -> SameVectorType: + def rotateY(self, angle: ScalarCollection) -> typing.Self: from vector._compute.spatial import rotateY return rotateY.dispatch(angle, self) def rotate_axis( - self: SameVectorType, axis: VectorProtocolSpatial, angle: ScalarCollection - ) -> SameVectorType: + self, axis: VectorProtocolSpatial, angle: ScalarCollection + ) -> typing.Self: from vector._compute.spatial import rotate_axis if dim(axis) != 3: @@ -3663,22 +3654,22 @@ def rotate_axis( return rotate_axis.dispatch(angle, axis, self) def rotate_euler( - self: SameVectorType, + self, phi: ScalarCollection, theta: ScalarCollection, psi: ScalarCollection, order: str = "zxz", - ) -> SameVectorType: + ) -> typing.Self: from vector._compute.spatial import rotate_euler return rotate_euler.dispatch(phi, theta, psi, order.lower(), self) def rotate_nautical( - self: SameVectorType, + self, yaw: ScalarCollection, pitch: ScalarCollection, roll: ScalarCollection, - ) -> SameVectorType: + ) -> typing.Self: # The order of arguments is reversed because rotate_euler # follows ROOT's argument order: phi, theta, psi. from vector._compute.spatial import rotate_euler @@ -3686,17 +3677,17 @@ def rotate_nautical( return rotate_euler.dispatch(roll, pitch, yaw, "zyx", self) def rotate_quaternion( - self: SameVectorType, + self, u: ScalarCollection, i: ScalarCollection, j: ScalarCollection, k: ScalarCollection, - ) -> SameVectorType: + ) -> typing.Self: from vector._compute.spatial import rotate_quaternion return rotate_quaternion.dispatch(u, i, j, k, self) - def transform3D(self: SameVectorType, obj: TransformProtocol3D) -> SameVectorType: + def transform3D(self, obj: TransformProtocol3D) -> typing.Self: from vector._compute.spatial import transform3D return transform3D.dispatch(obj, self) @@ -3725,7 +3716,7 @@ def is_perpendicular( _maybe_same_dimension_error(self, other, self.is_perpendicular.__name__) return is_perpendicular.dispatch(tolerance, self, other) - def unit(self: SameVectorType) -> SameVectorType: + def unit(self) -> typing.Self: from vector._compute.spatial import unit return unit.dispatch(self) @@ -3746,28 +3737,28 @@ def subtract(self, other: VectorProtocol) -> VectorProtocol: return module.subtract.dispatch(self, other) @property - def neg2D(self: SameVectorType) -> SameVectorType: + def neg2D(self) -> typing.Self: from vector._compute.planar import scale return scale.dispatch(-1, self) @property - def neg3D(self: SameVectorType) -> SameVectorType: + def neg3D(self) -> typing.Self: from vector._compute.spatial import scale return scale.dispatch(-1, self) - def scale2D(self: SameVectorType, factor: ScalarCollection) -> SameVectorType: + def scale2D(self, factor: ScalarCollection) -> typing.Self: from vector._compute.planar import scale return scale.dispatch(factor, self) - def scale3D(self: SameVectorType, factor: ScalarCollection) -> SameVectorType: + def scale3D(self, factor: ScalarCollection) -> typing.Self: from vector._compute.spatial import scale return scale.dispatch(factor, self) - def scale(self: SameVectorType, factor: ScalarCollection) -> SameVectorType: + def scale(self, factor: ScalarCollection) -> typing.Self: from vector._compute.spatial import scale return scale.dispatch(factor, self) @@ -3854,16 +3845,14 @@ def deltaRapidityPhi2(self, other: VectorProtocolLorentz) -> ScalarCollection: raise TypeError(f"{other!r} is not a 4D vector") return deltaRapidityPhi2.dispatch(self, other) - def boost_p4(self: SameVectorType, p4: VectorProtocolLorentz) -> SameVectorType: + def boost_p4(self, p4: VectorProtocolLorentz) -> typing.Self: from vector._compute.lorentz import boost_p4 if dim(p4) != 4: raise TypeError(f"{p4!r} is not a 4D vector") return boost_p4.dispatch(self, p4) - def boost_beta3( - self: SameVectorType, beta3: VectorProtocolSpatial - ) -> SameVectorType: + def boost_beta3(self, beta3: VectorProtocolSpatial) -> typing.Self: from vector._compute.lorentz import boost_beta3 if dim(beta3) != 3: @@ -3871,8 +3860,8 @@ def boost_beta3( return boost_beta3.dispatch(self, beta3) def boost( - self: SameVectorType, booster: VectorProtocolSpatial | VectorProtocolLorentz - ) -> SameVectorType: + self, booster: VectorProtocolSpatial | VectorProtocolLorentz + ) -> typing.Self: from vector._compute.lorentz import boost_beta3, boost_p4 if isinstance(booster, Vector3D): @@ -3885,18 +3874,14 @@ def boost( "a Vector4D to boost by a momentum 4-vector" ) - def boostCM_of_p4( - self: SameVectorType, p4: VectorProtocolLorentz - ) -> SameVectorType: + def boostCM_of_p4(self, p4: VectorProtocolLorentz) -> typing.Self: from vector._compute.lorentz import boost_p4 if dim(p4) != 4: raise TypeError(f"{p4!r} is not a 4D momentum vector") return boost_p4.dispatch(self, p4.neg3D) - def boostCM_of_beta3( - self: SameVectorType, beta3: VectorProtocolSpatial - ) -> SameVectorType: + def boostCM_of_beta3(self, beta3: VectorProtocolSpatial) -> typing.Self: from vector._compute.lorentz import boost_beta3 if dim(beta3) != 3: @@ -3904,8 +3889,8 @@ def boostCM_of_beta3( return boost_beta3.dispatch(self, beta3.neg3D) def boostCM_of( - self: SameVectorType, booster: VectorProtocolSpatial | VectorProtocolLorentz - ) -> SameVectorType: + self, booster: VectorProtocolSpatial | VectorProtocolLorentz + ) -> typing.Self: from vector._compute.lorentz import boost_beta3, boost_p4 if isinstance(booster, Vector3D): @@ -3919,10 +3904,10 @@ def boostCM_of( ) def boostX( - self: SameVectorType, + self, beta: ScalarCollection | None = None, gamma: ScalarCollection | None = None, - ) -> SameVectorType: + ) -> typing.Self: from vector._compute.lorentz import boostX_beta, boostX_gamma if beta is not None and gamma is None: @@ -3933,10 +3918,10 @@ def boostX( raise TypeError("specify 'beta' xor 'gamma', not both or neither") def boostY( - self: SameVectorType, + self, beta: ScalarCollection | None = None, gamma: ScalarCollection | None = None, - ) -> SameVectorType: + ) -> typing.Self: from vector._compute.lorentz import boostY_beta, boostY_gamma if beta is not None and gamma is None: @@ -3947,10 +3932,10 @@ def boostY( raise TypeError("specify 'beta' xor 'gamma', not both or neither") def boostZ( - self: SameVectorType, + self, beta: ScalarCollection | None = None, gamma: ScalarCollection | None = None, - ) -> SameVectorType: + ) -> typing.Self: from vector._compute.lorentz import boostZ_beta, boostZ_gamma if beta is not None and gamma is None: @@ -3960,7 +3945,7 @@ def boostZ( else: raise TypeError("specify 'beta' xor 'gamma', not both or neither") - def transform4D(self: SameVectorType, obj: TransformProtocol4D) -> SameVectorType: + def transform4D(self, obj: TransformProtocol4D) -> typing.Self: from vector._compute.lorentz import transform4D return transform4D.dispatch(obj, self) @@ -3985,7 +3970,7 @@ def is_lightlike(self, tolerance: ScalarCollection = 1e-5) -> BoolCollection: return is_lightlike.dispatch(tolerance, self) - def unit(self: SameVectorType) -> SameVectorType: + def unit(self) -> typing.Self: from vector._compute.lorentz import unit return unit.dispatch(self) @@ -4006,39 +3991,39 @@ def subtract(self, other: VectorProtocol) -> VectorProtocol: return module.subtract.dispatch(self, other) @property - def neg2D(self: SameVectorType) -> SameVectorType: + def neg2D(self) -> typing.Self: from vector._compute.planar import scale return scale.dispatch(-1, self) @property - def neg3D(self: SameVectorType) -> SameVectorType: + def neg3D(self) -> typing.Self: from vector._compute.spatial import scale return scale.dispatch(-1, self) @property - def neg4D(self: SameVectorType) -> SameVectorType: + def neg4D(self) -> typing.Self: from vector._compute.lorentz import scale return scale.dispatch(-1, self) - def scale2D(self: SameVectorType, factor: ScalarCollection) -> SameVectorType: + def scale2D(self, factor: ScalarCollection) -> typing.Self: from vector._compute.planar import scale return scale.dispatch(factor, self) - def scale3D(self: SameVectorType, factor: ScalarCollection) -> SameVectorType: + def scale3D(self, factor: ScalarCollection) -> typing.Self: from vector._compute.spatial import scale return scale.dispatch(factor, self) - def scale4D(self: SameVectorType, factor: ScalarCollection) -> SameVectorType: + def scale4D(self, factor: ScalarCollection) -> typing.Self: from vector._compute.lorentz import scale return scale.dispatch(factor, self) - def scale(self: SameVectorType, factor: ScalarCollection) -> SameVectorType: + def scale(self, factor: ScalarCollection) -> typing.Self: from vector._compute.lorentz import scale return scale.dispatch(factor, self) diff --git a/src/vector/backends/numpy.py b/src/vector/backends/numpy.py index 0a0bad98..312d09aa 100644 --- a/src/vector/backends/numpy.py +++ b/src/vector/backends/numpy.py @@ -521,7 +521,7 @@ class AzimuthalNumpyXY(AzimuthalNumpy, AzimuthalXY, GetItem, FloatArray): # typ ObjectClass = vector.backends.object.AzimuthalObjectXY _IS_MOMENTUM = False - def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> AzimuthalNumpyXY: + def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> typing.Self: return numpy.array(*args, **kwargs).view(cls) def __array_finalize__(self, obj: typing.Any) -> None: @@ -578,7 +578,7 @@ class AzimuthalNumpyRhoPhi(AzimuthalNumpy, AzimuthalRhoPhi, GetItem, FloatArray) ObjectClass = vector.backends.object.AzimuthalObjectRhoPhi _IS_MOMENTUM = False - def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> AzimuthalNumpyRhoPhi: + def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> typing.Self: return numpy.array(*args, **kwargs).view(cls) def __array_finalize__(self, obj: typing.Any) -> None: @@ -634,7 +634,7 @@ class LongitudinalNumpyZ(LongitudinalNumpy, LongitudinalZ, GetItem, FloatArray): ObjectClass = vector.backends.object.LongitudinalObjectZ _IS_MOMENTUM = False - def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> LongitudinalNumpyZ: + def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> typing.Self: return numpy.array(*args, **kwargs).view(cls) def __array_finalize__(self, obj: typing.Any) -> None: @@ -685,7 +685,7 @@ class LongitudinalNumpyTheta(LongitudinalNumpy, LongitudinalTheta, GetItem, Floa ObjectClass = vector.backends.object.LongitudinalObjectTheta _IS_MOMENTUM = False - def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> LongitudinalNumpyTheta: + def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> typing.Self: return numpy.array(*args, **kwargs).view(cls) def __array_finalize__(self, obj: typing.Any) -> None: @@ -736,7 +736,7 @@ class LongitudinalNumpyEta(LongitudinalNumpy, LongitudinalEta, GetItem, FloatArr ObjectClass = vector.backends.object.LongitudinalObjectEta _IS_MOMENTUM = False - def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> LongitudinalNumpyEta: + def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> typing.Self: return numpy.array(*args, **kwargs).view(cls) def __array_finalize__(self, obj: typing.Any) -> None: @@ -787,7 +787,7 @@ class TemporalNumpyT(TemporalNumpy, TemporalT, GetItem, FloatArray): # type: ig ObjectClass = vector.backends.object.TemporalObjectT _IS_MOMENTUM = False - def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> TemporalNumpyT: + def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> typing.Self: return numpy.array(*args, **kwargs).view(cls) def __array_finalize__(self, obj: typing.Any) -> None: @@ -830,7 +830,7 @@ class TemporalNumpyTau(TemporalNumpy, TemporalTau, GetItem, FloatArray): # type ObjectClass = vector.backends.object.TemporalObjectTau _IS_MOMENTUM = False - def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> TemporalNumpyTau: + def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> typing.Self: return numpy.array(*args, **kwargs).view(cls) def __array_finalize__(self, obj: typing.Any) -> None: @@ -937,16 +937,16 @@ def allclose( return self.isclose(other, rtol=rtol, atol=atol, equal_nan=equal_nan).all() def sum( - self: SameVectorNumpyType, + self, axis: int | None = None, dtype: numpy.dtype[typing.Any] | str | None = None, out: ArrayLike | None = None, keepdims: bool = False, initial: typing.Any = None, where: typing.Any = None, - ) -> SameVectorNumpyType: + ) -> typing.Self: return typing.cast( - SameVectorNumpyType, + typing.Self, numpy.sum( self, axis=axis, @@ -1236,7 +1236,7 @@ class VectorNumpy2D(VectorNumpy, Planar, Vector2D, FloatArray): # type: ignore[ _IS_MOMENTUM = False _azimuthal_type: type[AzimuthalNumpyXY | AzimuthalNumpyRhoPhi] - def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> VectorNumpy2D: + def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> typing.Self: """Returns the object of ``VectorNumpy2D``. Behaves as ``__init__`` in this case.""" if len(args) == 1 and len(kwargs) == 0 and isinstance(args[0], dict): array = _array_from_columns(args[0]) @@ -1439,7 +1439,7 @@ class VectorNumpy3D(VectorNumpy, Spatial, Vector3D, FloatArray): # type: ignore LongitudinalNumpyZ | LongitudinalNumpyTheta | LongitudinalNumpyEta ] - def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> VectorNumpy3D: + def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> typing.Self: """Returns the object of ``VectorNumpy3D``. Behaves as ``__init__`` in this case.""" if len(args) == 1 and len(kwargs) == 0 and isinstance(args[0], dict): array = _array_from_columns(args[0]) @@ -1698,7 +1698,7 @@ class VectorNumpy4D(VectorNumpy, Lorentz, Vector4D, FloatArray): # type: ignore ] _temporal_type: type[TemporalNumpyT | TemporalNumpyTau] - def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> VectorNumpy4D: + def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> typing.Self: """Returns the object of ``VectorNumpy4D``. Behaves as ``__init__`` in this case.""" if len(args) == 1 and len(kwargs) == 0 and isinstance(args[0], dict): array = _array_from_columns(args[0]) diff --git a/src/vector/backends/object.py b/src/vector/backends/object.py index 6b8a2516..80cd7d1f 100644 --- a/src/vector/backends/object.py +++ b/src/vector/backends/object.py @@ -46,7 +46,6 @@ LorentzMomentum, Planar, PlanarMomentum, - SameVectorType, Spatial, SpatialMomentum, Temporal, @@ -375,7 +374,7 @@ def __add__(self, other: VectorProtocol) -> VectorProtocol: def __radd__(self, other: VectorProtocol) -> VectorProtocol: return numpy.add(other, self) # type: ignore[call-overload] - def __iadd__(self: SameVectorType, other: VectorProtocol) -> SameVectorType: + def __iadd__(self, other: VectorProtocol) -> typing.Self: return _replace_data( self, numpy.add(self, other), # type: ignore[call-overload] @@ -387,7 +386,7 @@ def __sub__(self, other: VectorProtocol) -> VectorProtocol: def __rsub__(self, other: VectorProtocol) -> VectorProtocol: return numpy.subtract(other, self) # type: ignore[call-overload] - def __isub__(self: SameVectorType, other: VectorProtocol) -> SameVectorType: + def __isub__(self, other: VectorProtocol) -> typing.Self: return _replace_data( self, numpy.subtract(self, other), # type: ignore[call-overload] @@ -399,17 +398,17 @@ def __mul__(self, other: float) -> VectorProtocol: def __rmul__(self, other: float) -> VectorProtocol: return numpy.multiply(other, self) # type: ignore[call-overload] - def __imul__(self: SameVectorType, other: float) -> SameVectorType: + def __imul__(self, other: float) -> typing.Self: return _replace_data( self, numpy.multiply(self, other), # type: ignore[call-overload] ) - def __neg__(self: SameVectorType) -> SameVectorType: - return numpy.negative(self) # type: ignore[call-overload] + def __neg__(self) -> typing.Self: + return numpy.negative(self) - def __pos__(self: SameVectorType) -> SameVectorType: - return numpy.positive(self) # type: ignore[call-overload] + def __pos__(self) -> typing.Self: + return numpy.positive(self) def __truediv__(self, other: float) -> VectorProtocol: return numpy.true_divide(self, other) # type: ignore[call-overload] @@ -417,7 +416,7 @@ def __truediv__(self, other: float) -> VectorProtocol: def __rtruediv__(self, other: float) -> VectorProtocol: return numpy.true_divide(other, self) # type: ignore[call-overload] - def __itruediv__(self: SameVectorType, other: float) -> VectorProtocol: + def __itruediv__(self, other: float) -> VectorProtocol: return _replace_data( self, numpy.true_divide(self, other), # type: ignore[call-overload] diff --git a/src/vector/backends/sympy.py b/src/vector/backends/sympy.py index 14f4d7cd..43f86018 100644 --- a/src/vector/backends/sympy.py +++ b/src/vector/backends/sympy.py @@ -34,7 +34,6 @@ LorentzMomentum, Planar, PlanarMomentum, - SameVectorType, Spatial, SpatialMomentum, Temporal, @@ -505,7 +504,7 @@ def __add__(self, other: VectorProtocol) -> VectorProtocol: def __radd__(self, other: VectorProtocol) -> VectorProtocol: return numpy.add(other, self) # type: ignore[call-overload] - def __iadd__(self: SameVectorType, other: VectorProtocol) -> SameVectorType: + def __iadd__(self, other: VectorProtocol) -> typing.Self: return _replace_data( self, numpy.add(self, other), # type: ignore[call-overload] @@ -517,7 +516,7 @@ def __sub__(self, other: VectorProtocol) -> VectorProtocol: def __rsub__(self, other: VectorProtocol) -> VectorProtocol: return numpy.subtract(other, self) # type: ignore[call-overload] - def __isub__(self: SameVectorType, other: VectorProtocol) -> SameVectorType: + def __isub__(self, other: VectorProtocol) -> typing.Self: return _replace_data( self, numpy.subtract(self, other), # type: ignore[call-overload] @@ -529,17 +528,17 @@ def __mul__(self, other: float) -> VectorProtocol: def __rmul__(self, other: float) -> VectorProtocol: return numpy.multiply(other, self) # type: ignore[call-overload] - def __imul__(self: SameVectorType, other: float) -> SameVectorType: + def __imul__(self, other: float) -> typing.Self: return _replace_data( self, numpy.multiply(self, other), # type: ignore[call-overload] ) - def __neg__(self: SameVectorType) -> SameVectorType: - return numpy.negative(self) # type: ignore[call-overload] + def __neg__(self) -> typing.Self: + return numpy.negative(self) - def __pos__(self: SameVectorType) -> SameVectorType: - return numpy.positive(self) # type: ignore[call-overload] + def __pos__(self) -> typing.Self: + return numpy.positive(self) def __truediv__(self, other: float) -> VectorProtocol: return numpy.true_divide(self, other) # type: ignore[call-overload] @@ -547,7 +546,7 @@ def __truediv__(self, other: float) -> VectorProtocol: def __rtruediv__(self, other: float) -> VectorProtocol: return numpy.true_divide(other, self) # type: ignore[call-overload] - def __itruediv__(self: SameVectorType, other: float) -> VectorProtocol: + def __itruediv__(self, other: float) -> VectorProtocol: return _replace_data( self, numpy.true_divide(self, other), # type: ignore[call-overload]