From c81153de466d317338fb2061d6513b5398e9f793 Mon Sep 17 00:00:00 2001 From: MilesCranmerBot Date: Tue, 29 Sep 2026 00:40:03 +0000 Subject: [PATCH] Remove `>` and `>=` overloads to cut invalidations by ~63% Deleting the six `Base.:(>)` and `Base.:(>=)` methods (`Py`/`Py`, `Py`/`Number`, `Number`/`Py`) removes most invalidation trees caused by loading PythonCall, because Base only defines `>` and `>=` through the generic fallbacks `>(x, y) = y < x` and `>=(x, y) = y <= x`, which route to PythonCall's own `<` and `<=` methods with identical results. Measured with SnoopCompile (`@snoop_invalidations`) on Julia 1.12.7, loading `using PythonCall; using SymbolicRegression`: | PythonCall | unique invalidated method instances | |---|---| | 0.9.36 (current release) | 6830 | | 0.9.36 with `>` and `>=` removed | 2532 (rerun: 2413) | One intentional behavior change: `x > y` now evaluates as Python `y < x`, so Python tries `y.__lt__` before `x.__gt__` (reflected operator ordering). This only matters for types whose `__gt__` and `__lt__` disagree. `!=` is intentionally not removed on 0.9, since the Base fallback `!=(x, y) = !(x == y)` would require a `!(::Py)` method (#702/#709 handle this properly on the `v1` branch). Refs #828 (non-breaking portion; the v1 branch fixes the rest). Co-authored-by: Miles Cranmer --- src/Core/Py.jl | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/Core/Py.jl b/src/Core/Py.jl index 0705bded..fd95e577 100644 --- a/src/Core/Py.jl +++ b/src/Core/Py.jl @@ -361,8 +361,6 @@ Base.:(==)(x::Py, y::Py) = pyeq(x, y) Base.:(!=)(x::Py, y::Py) = pyne(x, y) Base.:(<=)(x::Py, y::Py) = pyle(x, y) Base.:(<)(x::Py, y::Py) = pylt(x, y) -Base.:(>=)(x::Py, y::Py) = pyge(x, y) -Base.:(>)(x::Py, y::Py) = pygt(x, y) Base.isless(x::Py, y::Py) = pylt(Bool, x, y) Base.isequal(x::Py, y::Py) = pyeq(Bool, x, y) @@ -371,8 +369,6 @@ Base.:(==)(x::Py, y::Number) = pyeq(x, y) Base.:(!=)(x::Py, y::Number) = pyne(x, y) Base.:(<=)(x::Py, y::Number) = pyle(x, y) Base.:(<)(x::Py, y::Number) = pylt(x, y) -Base.:(>=)(x::Py, y::Number) = pyge(x, y) -Base.:(>)(x::Py, y::Number) = pygt(x, y) Base.isless(x::Py, y::Number) = pylt(Bool, x, y) Base.isequal(x::Py, y::Number) = pyeq(Bool, x, y) @@ -380,8 +376,6 @@ Base.:(==)(x::Number, y::Py) = pyeq(x, y) Base.:(!=)(x::Number, y::Py) = pyne(x, y) Base.:(<=)(x::Number, y::Py) = pyle(x, y) Base.:(<)(x::Number, y::Py) = pylt(x, y) -Base.:(>=)(x::Number, y::Py) = pyge(x, y) -Base.:(>)(x::Number, y::Py) = pygt(x, y) Base.isless(x::Number, y::Py) = pylt(Bool, x, y) Base.isequal(x::Number, y::Py) = pyeq(Bool, x, y)