From ef987ddbc38828de2ba202791d3043c1f6f8a32a Mon Sep 17 00:00:00 2001 From: jverzani Date: Wed, 15 Nov 2023 14:53:22 -0500 Subject: [PATCH 1/5] rework to avoid extra allocations --- Project.toml | 2 +- src/SymPyPythonCall.jl | 1 + src/python_connection.jl | 55 +++++++++++++++++++--------------------- 3 files changed, 28 insertions(+), 30 deletions(-) diff --git a/Project.toml b/Project.toml index de6d61d..396df60 100644 --- a/Project.toml +++ b/Project.toml @@ -27,7 +27,7 @@ PythonCall = "0.9" SpecialFunctions = "0.8, 0.9, 0.10, 1.0, 2" Symbolics = "5" SymbolicUtils = "1" -SymPyCore = "0.1.3, 1" +SymPyCore = "0.1.6, 1" julia = "1.6.1" diff --git a/src/SymPyPythonCall.jl b/src/SymPyPythonCall.jl index b7878ad..92b3df1 100644 --- a/src/SymPyPythonCall.jl +++ b/src/SymPyPythonCall.jl @@ -15,6 +15,7 @@ _pyimport(a) = PythonCall.pyimport(a) _pyimport_conda(a,b) = PythonCall.pyimport(a) # XXX lose things _pyobject(x) = PythonCall.pyconvert(Py, x) _pytype_mapping(typ,a) = nothing +_pybuiltin = PythonCall.pybuiltins core_src_path = joinpath(pathof(SymPyCore), "../../src/SymPy") include(joinpath(core_src_path, "sympy.jl")) diff --git a/src/python_connection.jl b/src/python_connection.jl index b6b475b..290515d 100644 --- a/src/python_connection.jl +++ b/src/python_connection.jl @@ -15,23 +15,24 @@ end ## Modifications for ↓, ↑ Sym(x::Nothing) = Sym(pybuiltins.None) + SymPyCore.:↓(x::PythonCall.Py) = x SymPyCore.:↓(d::Dict) = pydict((↓(k) => ↓(v) for (k,v) ∈ pairs(d))) SymPyCore.:↓(x::Set) = _sympy_.sympify(pyset(↓(sᵢ) for sᵢ ∈ x)) -SymPyCore.:↑(::Type{<:AbstractString}, x) = Py(x) +SymPyCore.:↑(::Type{<:AbstractString}, x) = Sym(Py(x)) function SymPyCore.:↑(::Type{PythonCall.Py}, x) - class_nm = SymPyCore.classname(x) - class_nm == "set" && return Set(Sym.(collect(x))) - class_nm == "tuple" && return Tuple(↑(xᵢ) for xᵢ ∈ x) - class_nm == "list" && return [↑(xᵢ) for xᵢ ∈ x] - class_nm == "dict" && return Dict(↑(k) => ↑(x[k]) for k ∈ x) - - class_nm == "FiniteSet" && return Set(Sym.(collect(x))) - class_nm == "MutableDenseMatrix" && return _up_matrix(x) #map(↑, x.tolist()) + # this lower level approach shouldn't allocate + pyisinstance(x, pybuiltins.set) && return Set(Sym.(x)) #Set(↑(xᵢ) for xᵢ ∈ x) + pyisinstance(x, pybuiltins.tuple) && return Tuple(↑(xᵢ) for xᵢ ∈ x) + pyisinstance(x, pybuiltins.list) && return [↑(xᵢ) for xᵢ ∈ x] + pyisinstance(x, pybuiltins.dict) && return Dict(↑(k) => ↑(x[k]) for k ∈ x) - # others ... more hands on than pytype_mapping + # add more sympy containers in sympy.jl and here + pyisinstance(x, _FiniteSet_) && return Set(Sym.(x)) + pyisinstance(x, _MutableDenseMatrix_) && return _up_matrix(x) #map(↑, x.tolist()) + # fallback Sym(x) end @@ -52,42 +53,38 @@ end # should we also have different code path for a::String like PyCall? function Base.getproperty(x::SymbolicObject{T}, a::Symbol) where {T <: PythonCall.Py} + a == :o && return getfield(x, a) + if a == :py Base.depwarn("The field `.py` has been renamed `.o`", :getproperty) return getfield(x,:o) end val = ↓(x) - !hasproperty(val, a) && return nothing # not a property + 𝑎 = string(a) - meth = getproperty(val, a) + hasproperty(val, 𝑎) || return nothing # not a property + meth = getproperty(val, 𝑎) - pyconvert(Bool, meth == pybuiltins.None) && return nothing + pyis(meth, pybuiltins.None) && return nothing - if hasproperty(meth, "is_Boolean") - if pyconvert(Bool, meth.is_Boolean == true) - return meth == _sympy_.logic.boolalg.BooleanFalse - end + ## __call__ + if pycallable(meth) # "__call__") #hasproperty(meth, "__call__") + return SymPyCore.SymbolicCallable(meth) end # __class__ dispatch - if hasproperty(meth, :__class__) - cnm = string(meth.__class__.__name__) - if cnm == "bool" - return pyconvert(Bool, meth) - end - if cnm == "module" - # treat modules, callsm others differently - return Sym(meth) - end + if pyisinstance(meth, _bool_) + return pyconvert(Bool, meth) end - ## __call__ - if hasproperty(meth, "__call__") - return SymPyCore.SymbolicCallable(meth) + if pyisinstance(meth, _ModuleType_) + return Sym(meth) end + + # just convert return ↑(convert(PythonCall.Py, meth)) end From a4dd4a2aae89b7e074a2517ab93e30cf2795cab8 Mon Sep 17 00:00:00 2001 From: jverzani Date: Wed, 15 Nov 2023 15:07:34 -0500 Subject: [PATCH 2/5] add const annotation --- src/SymPyPythonCall.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SymPyPythonCall.jl b/src/SymPyPythonCall.jl index 92b3df1..7fff663 100644 --- a/src/SymPyPythonCall.jl +++ b/src/SymPyPythonCall.jl @@ -15,7 +15,7 @@ _pyimport(a) = PythonCall.pyimport(a) _pyimport_conda(a,b) = PythonCall.pyimport(a) # XXX lose things _pyobject(x) = PythonCall.pyconvert(Py, x) _pytype_mapping(typ,a) = nothing -_pybuiltin = PythonCall.pybuiltins +const _pybuiltin = PythonCall.pybuiltins core_src_path = joinpath(pathof(SymPyCore), "../../src/SymPy") include(joinpath(core_src_path, "sympy.jl")) From c570af593192841a120170145dffa232f7cc02a8 Mon Sep 17 00:00:00 2001 From: jverzani Date: Wed, 15 Nov 2023 15:12:10 -0500 Subject: [PATCH 3/5] version bump --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 396df60..57971a1 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "SymPyPythonCall" uuid = "bc8888f7-b21e-4b7c-a06a-5d9c9496438c" authors = ["jverzani and contributors"] -version = "0.2.3" +version = "0.2.5" [deps] CommonEq = "3709ef60-1bee-4518-9f2f-acd86f176c50" From ef8096bb651271f1347a2aa403139bb882ffb434 Mon Sep 17 00:00:00 2001 From: jverzani Date: Wed, 15 Nov 2023 15:52:25 -0500 Subject: [PATCH 4/5] version bump --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 57971a1..8d2c099 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "SymPyPythonCall" uuid = "bc8888f7-b21e-4b7c-a06a-5d9c9496438c" authors = ["jverzani and contributors"] -version = "0.2.5" +version = "0.2.4" [deps] CommonEq = "3709ef60-1bee-4518-9f2f-acd86f176c50" From 9bd6e7ebf2f9685ae956ec45beed291655bcd949 Mon Sep 17 00:00:00 2001 From: jverzani Date: Wed, 15 Nov 2023 15:52:50 -0500 Subject: [PATCH 5/5] compat bump --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 8d2c099..77ab26b 100644 --- a/Project.toml +++ b/Project.toml @@ -19,7 +19,7 @@ Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" SymPyPythonCallSymbolicsExt = "Symbolics" [compat] -CommonEq = "0.2" +CommonEq = "0.2.1" CommonSolve = "0.2" CondaPkg = "0.2" LinearAlgebra = "1.6.1"