From 63b80c7b4018eb35feae73d200c013598e7d88c8 Mon Sep 17 00:00:00 2001 From: Christopher Rowley Date: Sun, 8 Nov 2026 20:01:53 +0000 Subject: [PATCH 1/7] Redesign v1 pyconvert dispatch and native conversions --- AGENTS.md | 33 + benchmark/convert-array-allocations-after.txt | 1533 +++++++++++++++++ .../convert-array-allocations-before.txt | 1389 +++++++++++++++ .../convert-array-allocations-unwrapped.txt | 1389 +++++++++++++++ benchmark/convert-array-allocations.jl | 35 + benchmark/convert-baseline.tsv | 16 + benchmark/convert-dispatch-final.tsv | 10 + benchmark/convert-dispatch.jl | 25 + benchmark/convert-dispatch.tsv | 12 + .../convert-expanded-after-environment.txt | 7 + benchmark/convert-expanded-after.tsv | 37 + .../convert-expanded-before-environment.txt | 7 + benchmark/convert-expanded-before.tsv | 37 + ...rt-expanded-final-after-r1-environment.txt | 10 + benchmark/convert-expanded-final-after-r1.tsv | 37 + ...rt-expanded-final-after-r2-environment.txt | 10 + benchmark/convert-expanded-final-after-r2.tsv | 37 + ...rt-expanded-final-after-r3-environment.txt | 10 + benchmark/convert-expanded-final-after-r3.tsv | 37 + ...t-expanded-final-before-r1-environment.txt | 10 + .../convert-expanded-final-before-r1.tsv | 37 + ...t-expanded-final-before-r2-environment.txt | 10 + .../convert-expanded-final-before-r2.tsv | 37 + ...t-expanded-final-before-r3-environment.txt | 10 + .../convert-expanded-final-before-r3.tsv | 37 + benchmark/convert-expanded-report.md | 147 ++ ...xpanded-unwrapped-after-r1-environment.txt | 10 + .../convert-expanded-unwrapped-after-r1.tsv | 15 + ...xpanded-unwrapped-after-r2-environment.txt | 10 + .../convert-expanded-unwrapped-after-r2.tsv | 15 + ...xpanded-unwrapped-after-r3-environment.txt | 10 + .../convert-expanded-unwrapped-after-r3.tsv | 15 + ...panded-unwrapped-before-r1-environment.txt | 10 + .../convert-expanded-unwrapped-before-r1.tsv | 15 + ...panded-unwrapped-before-r2-environment.txt | 10 + .../convert-expanded-unwrapped-before-r2.tsv | 15 + ...panded-unwrapped-before-r3-environment.txt | 10 + .../convert-expanded-unwrapped-before-r3.tsv | 15 + benchmark/convert-expanded.jl | 184 ++ .../convert-final-after-r1-environment.txt | 30 + benchmark/convert-final-after-r1.tsv | 30 + .../convert-final-after-r2-environment.txt | 30 + benchmark/convert-final-after-r2.tsv | 30 + .../convert-final-after-r3-environment.txt | 30 + benchmark/convert-final-after-r3.tsv | 30 + .../convert-final-before-r1-environment.txt | 30 + benchmark/convert-final-before-r1.tsv | 30 + .../convert-final-before-r2-environment.txt | 30 + benchmark/convert-final-before-r2.tsv | 30 + .../convert-final-before-r3-environment.txt | 30 + benchmark/convert-final-before-r3.tsv | 30 + benchmark/convert-final-summary.tsv | 66 + ...t-final-unwrapped-after-r1-environment.txt | 30 + .../convert-final-unwrapped-after-r1.tsv | 30 + ...t-final-unwrapped-after-r2-environment.txt | 30 + .../convert-final-unwrapped-after-r2.tsv | 30 + ...t-final-unwrapped-after-r3-environment.txt | 30 + .../convert-final-unwrapped-after-r3.tsv | 30 + ...-final-unwrapped-before-r1-environment.txt | 30 + .../convert-final-unwrapped-before-r1.tsv | 30 + ...-final-unwrapped-before-r2-environment.txt | 30 + .../convert-final-unwrapped-before-r2.tsv | 30 + ...-final-unwrapped-before-r3-environment.txt | 30 + .../convert-final-unwrapped-before-r3.tsv | 30 + benchmark/convert-final.jl | 63 + benchmark/convert-inference-final.txt | 63 + benchmark/convert-inference.txt | 63 + benchmark/convert-redesign.jl | 24 + benchmark/convert-redesign.tsv | 16 + benchmark/convert-report.md | 197 +++ benchmark/convert-results-final.tsv | 67 + benchmark/convert-results.jl | 44 + benchmark/convert-results.tsv | 67 + benchmark/convert-scalaropt.tsv | 16 + .../convert-scalars-before-allocations.txt | 139 ++ .../convert-scalars-before-inference.txt | 663 +++++++ benchmark/convert-scalars-before.tsv | 25 + .../convert-scalars-final-allocations.txt | 113 ++ benchmark/convert-scalars-final-inference.txt | 663 +++++++ benchmark/convert-scalars-final-repeat.tsv | 16 + benchmark/convert-scalars-final.tsv | 25 + .../convert-scalars-optimized-allocations.txt | 113 ++ .../convert-scalars-optimized-inference.txt | 663 +++++++ .../convert-scalars-optimized-repeat.tsv | 16 + benchmark/convert-scalars-optimized.tsv | 25 + benchmark/convert-scalars-report.md | 124 ++ ...vert-scalars-source-policy-allocations.txt | 113 ++ ...onvert-scalars-source-policy-inference.txt | 663 +++++++ .../convert-scalars-source-policy-repeat.tsv | 16 + benchmark/convert-scalars-source-policy.tsv | 25 + benchmark/convert-scalars.jl | 80 + benchmark/convert-unwrapped-report.md | 119 ++ benchmark/convert-unwrapped-summary.tsv | 44 + benchmark/convert-unwrapped.patch | 29 + benchmark/run-convert-final.sh | 33 + benchmark/summarize-convert-final.py | 56 + docs/make.jl | 2 +- docs/src/conversion-to-julia.md | 217 ++- docs/src/v1-migration-guide.md | 28 + pytest/test_convert_v1.py | 17 + src/API/exports.jl | 11 +- src/API/functions.jl | 6 +- src/API/types.jl | 10 - src/Convert/Convert.jl | 15 +- src/Convert/numpy.jl | 6 +- src/Convert/pandas.jl | 2 +- src/Convert/pyconvert.jl | 824 ++++----- src/Convert/rules.jl | 55 +- src/Core/Py.jl | 1 + src/JlWrap/JlWrap.jl | 1 + src/JlWrap/base.jl | 3 +- src/PythonCall.jl | 2 + src/Wrap/PyArray.jl | 100 +- src/Wrap/Wrap.jl | 71 +- test/Convert.jl | 1 + test/ConvertRedesign.jl | 503 ++++++ 116 files changed, 11725 insertions(+), 612 deletions(-) create mode 100644 benchmark/convert-array-allocations-after.txt create mode 100644 benchmark/convert-array-allocations-before.txt create mode 100644 benchmark/convert-array-allocations-unwrapped.txt create mode 100644 benchmark/convert-array-allocations.jl create mode 100644 benchmark/convert-baseline.tsv create mode 100644 benchmark/convert-dispatch-final.tsv create mode 100644 benchmark/convert-dispatch.jl create mode 100644 benchmark/convert-dispatch.tsv create mode 100644 benchmark/convert-expanded-after-environment.txt create mode 100644 benchmark/convert-expanded-after.tsv create mode 100644 benchmark/convert-expanded-before-environment.txt create mode 100644 benchmark/convert-expanded-before.tsv create mode 100644 benchmark/convert-expanded-final-after-r1-environment.txt create mode 100644 benchmark/convert-expanded-final-after-r1.tsv create mode 100644 benchmark/convert-expanded-final-after-r2-environment.txt create mode 100644 benchmark/convert-expanded-final-after-r2.tsv create mode 100644 benchmark/convert-expanded-final-after-r3-environment.txt create mode 100644 benchmark/convert-expanded-final-after-r3.tsv create mode 100644 benchmark/convert-expanded-final-before-r1-environment.txt create mode 100644 benchmark/convert-expanded-final-before-r1.tsv create mode 100644 benchmark/convert-expanded-final-before-r2-environment.txt create mode 100644 benchmark/convert-expanded-final-before-r2.tsv create mode 100644 benchmark/convert-expanded-final-before-r3-environment.txt create mode 100644 benchmark/convert-expanded-final-before-r3.tsv create mode 100644 benchmark/convert-expanded-report.md create mode 100644 benchmark/convert-expanded-unwrapped-after-r1-environment.txt create mode 100644 benchmark/convert-expanded-unwrapped-after-r1.tsv create mode 100644 benchmark/convert-expanded-unwrapped-after-r2-environment.txt create mode 100644 benchmark/convert-expanded-unwrapped-after-r2.tsv create mode 100644 benchmark/convert-expanded-unwrapped-after-r3-environment.txt create mode 100644 benchmark/convert-expanded-unwrapped-after-r3.tsv create mode 100644 benchmark/convert-expanded-unwrapped-before-r1-environment.txt create mode 100644 benchmark/convert-expanded-unwrapped-before-r1.tsv create mode 100644 benchmark/convert-expanded-unwrapped-before-r2-environment.txt create mode 100644 benchmark/convert-expanded-unwrapped-before-r2.tsv create mode 100644 benchmark/convert-expanded-unwrapped-before-r3-environment.txt create mode 100644 benchmark/convert-expanded-unwrapped-before-r3.tsv create mode 100644 benchmark/convert-expanded.jl create mode 100644 benchmark/convert-final-after-r1-environment.txt create mode 100644 benchmark/convert-final-after-r1.tsv create mode 100644 benchmark/convert-final-after-r2-environment.txt create mode 100644 benchmark/convert-final-after-r2.tsv create mode 100644 benchmark/convert-final-after-r3-environment.txt create mode 100644 benchmark/convert-final-after-r3.tsv create mode 100644 benchmark/convert-final-before-r1-environment.txt create mode 100644 benchmark/convert-final-before-r1.tsv create mode 100644 benchmark/convert-final-before-r2-environment.txt create mode 100644 benchmark/convert-final-before-r2.tsv create mode 100644 benchmark/convert-final-before-r3-environment.txt create mode 100644 benchmark/convert-final-before-r3.tsv create mode 100644 benchmark/convert-final-summary.tsv create mode 100644 benchmark/convert-final-unwrapped-after-r1-environment.txt create mode 100644 benchmark/convert-final-unwrapped-after-r1.tsv create mode 100644 benchmark/convert-final-unwrapped-after-r2-environment.txt create mode 100644 benchmark/convert-final-unwrapped-after-r2.tsv create mode 100644 benchmark/convert-final-unwrapped-after-r3-environment.txt create mode 100644 benchmark/convert-final-unwrapped-after-r3.tsv create mode 100644 benchmark/convert-final-unwrapped-before-r1-environment.txt create mode 100644 benchmark/convert-final-unwrapped-before-r1.tsv create mode 100644 benchmark/convert-final-unwrapped-before-r2-environment.txt create mode 100644 benchmark/convert-final-unwrapped-before-r2.tsv create mode 100644 benchmark/convert-final-unwrapped-before-r3-environment.txt create mode 100644 benchmark/convert-final-unwrapped-before-r3.tsv create mode 100644 benchmark/convert-final.jl create mode 100644 benchmark/convert-inference-final.txt create mode 100644 benchmark/convert-inference.txt create mode 100644 benchmark/convert-redesign.jl create mode 100644 benchmark/convert-redesign.tsv create mode 100644 benchmark/convert-report.md create mode 100644 benchmark/convert-results-final.tsv create mode 100644 benchmark/convert-results.jl create mode 100644 benchmark/convert-results.tsv create mode 100644 benchmark/convert-scalaropt.tsv create mode 100644 benchmark/convert-scalars-before-allocations.txt create mode 100644 benchmark/convert-scalars-before-inference.txt create mode 100644 benchmark/convert-scalars-before.tsv create mode 100644 benchmark/convert-scalars-final-allocations.txt create mode 100644 benchmark/convert-scalars-final-inference.txt create mode 100644 benchmark/convert-scalars-final-repeat.tsv create mode 100644 benchmark/convert-scalars-final.tsv create mode 100644 benchmark/convert-scalars-optimized-allocations.txt create mode 100644 benchmark/convert-scalars-optimized-inference.txt create mode 100644 benchmark/convert-scalars-optimized-repeat.tsv create mode 100644 benchmark/convert-scalars-optimized.tsv create mode 100644 benchmark/convert-scalars-report.md create mode 100644 benchmark/convert-scalars-source-policy-allocations.txt create mode 100644 benchmark/convert-scalars-source-policy-inference.txt create mode 100644 benchmark/convert-scalars-source-policy-repeat.tsv create mode 100644 benchmark/convert-scalars-source-policy.tsv create mode 100644 benchmark/convert-scalars.jl create mode 100644 benchmark/convert-unwrapped-report.md create mode 100644 benchmark/convert-unwrapped-summary.tsv create mode 100644 benchmark/convert-unwrapped.patch create mode 100644 benchmark/run-convert-final.sh create mode 100644 benchmark/summarize-convert-final.py create mode 100644 pytest/test_convert_v1.py create mode 100644 test/ConvertRedesign.jl diff --git a/AGENTS.md b/AGENTS.md index b194a6eb6..be3cce5cd 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -16,6 +16,10 @@ the process uses its newer `libstdc++`. - `julia --project=docs docs/make.jl` requires a valid Git `origin` so Documenter can infer source links; it fails during `makedocs` in checkouts without one. +- `Documenter.HTML` discovers its default edit-link branch with `git remote show + origin`, which contacts the remote. Set `edit_link` explicitly for a local build + without that network lookup; v1's docs use `edit_link="v1"`. Disabling source + remotes alone does not prevent the HTML constructor's branch lookup. The majority of tests live in the Julia package; Python tests cover functionality that cannot be exercised from Julia (e.g., JuliaCall-specific behavior). Run both suites—typically Julia first—in whichever order makes sense. @@ -25,10 +29,39 @@ The majority of tests live in the Julia package; Python tests cover functionalit `main`'s `ValueBase`/`AnyValue` hierarchy. Keep the collection wrapper when porting `_jlwrap` changes. Wrapper modules load before `juliacall.Base` is assigned, so constructors must look it up through `juliacall` when called. +- For numeric Python fixtures, use `pycomplex(real, imag)` when a Python complex + value is needed. Passing a Julia `Complex` directly to a Python constructor can + produce a Julia wrapper, which NumPy may treat as a sequence rather than a scalar. - The benchmark suite is shared across the compared revisions: `main` uses `pydel!`, while `v1` uses `unsafe_pydel`. - `main` does not have `@pyregion`. Benchmark region wrappers must select a plain-body fallback before macro expansion; a runtime conditional around an unavailable macro still fails when loading the suite. - Julia CI caches can preserve Conda's build metadata without its root environment. Rebuild `Conda` before building `PyCall` or running tests to recreate that directory. - In restricted sandboxes, both suites need approval to write to the shared caches (`~/.julia` and `~/.cache/uv`). +- Julia also writes `~/.julia/logs/manifest_usage.toml` during dependency discovery, + including PythonCall startup through CondaPkg. Cache permissions must include + `~/.julia/logs`, in addition to compiled packages, artifacts and registries. +- Notebook tests start a Jupyter kernel using local sockets. A sandbox that blocks + sockets can run the ordinary Python tests but cannot run `--nbval` successfully. +- Loopback TCP permission alone may be insufficient for notebook tests: ZeroMQ + queries network interfaces via `getifaddrs`, which on Linux needs + `AF_NETLINK`/`NETLINK_ROUTE` sockets. In the tested sandbox, loopback binding + succeeded but creating a route Netlink socket failed with `EPERM`. +- Use the absolute installed Julia executable in a restricted sandbox to avoid + Juliaup's configuration lock. Installed channels may differ from those listed above. +- `JULIA_PKG_OFFLINE=true` lets JuliaPkg resolve the development Python test + environment using installed packages without refreshing registries or cloning + uncached package versions. +- `JULIA_CONDAPKG_ENV` must not point at an existing `.CondaPkg` directory. + To run Aqua against an installed interpreter without creating a fresh Conda + environment, use `JULIA_CONDAPKG_BACKEND=Null` and set `JULIA_PYTHONCALL_EXE` + to that interpreter's absolute path. +- `test/runtests.jl` infers optional development dependencies from the CondaPkg + backend. With the Null backend and an explicit Conda interpreter, PySide6 may + be installed even though `Setup.devdeps` is false, causing the GUI test to + incorrectly expect an import failure. Focused conversion tests are unaffected. +- Interrupted sandbox runs can leave a CondaPkg lock containing a PID from a + different PID namespace. A reused small PID can make later runs wait for that + lock indefinitely. Prefer an explicit installed Python/Null backend for + focused conversion tests; do not remove a lock without checking its owner. - `pysrc/juliacall/juliapkg.json` is tracked; restore its original contents after using the development copy for Python tests. ## Meta instructions diff --git a/benchmark/convert-array-allocations-after.txt b/benchmark/convert-array-allocations-after.txt new file mode 100644 index 000000000..0baedfc78 --- /dev/null +++ b/benchmark/convert-array-allocations-after.txt @@ -0,0 +1,1533 @@ +Julia: 1.13.2; PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl + +ndarray_native +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at regions.jl:296 [inlined] + pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 + pystr_fromUTF8 at builtins.jl:585 [inlined] + pystr at builtins.jl:593 [inlined] + Py at Py.jl:117 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at Py.jl:103 [inlined] + macro expansion at builtins.jl:63 [inlined] + macro expansion at regions.jl:302 [inlined] + pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at builtins.jl:72 [inlined] + macro expansion at regions.jl:302 [inlined] + pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +PythonCall.Wrap.PyArraySource_ArrayStruct: 80 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Tuple{Int64}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Core.SimpleVector: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +DataType: 56 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +UnionAll: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +PythonCall.Wrap.PyArraySource_ArrayStruct: 80 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Tuple{Int64}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Core.SimpleVector: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +DataType: 56 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +UnionAll: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Vector{Symbol}: 32 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:134 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Memory{Symbol}: 40 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:143 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Tuple{Symbol, Symbol, Symbol}: 24 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:146 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Ptr{Nothing}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +PyArray{Int64, 1, (:mutable, :linear, :contiguous)}: 64 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Some{PyArray{Int64, 1, (:mutable, :linear, :contiguous)}}: 64 bytes + pyconvert_return at pyconvert.jl:97 [inlined] + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:152 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +PyArray{Int64, 1, (:mutable, :linear, :contiguous)}: 48 bytes + pyconvert_result at pyconvert.jl:100 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Profile.Allocs.BufferType: 8000 bytes + pyconvert_tryconvert(::Type{Array}, x::PyArray{Int64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:138 + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Memory{Int64}: 24 bytes + pyconvert_tryconvert(::Type{Array}, x::PyArray{Int64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:138 + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Vector{Int64}: 32 bytes + pyconvert_tryconvert(::Type{Array}, x::PyArray{Int64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:138 + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Some{Vector{Int64}}: 16 bytes + pyconvert_tryconvert(::Type{Array}, x::PyArray{Int64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:138 + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] + +ndarray_wrapper +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at regions.jl:296 [inlined] + pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 + pystr_fromUTF8 at builtins.jl:585 [inlined] + pystr at builtins.jl:593 [inlined] + Py at Py.jl:117 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at Py.jl:103 [inlined] + macro expansion at builtins.jl:63 [inlined] + macro expansion at regions.jl:302 [inlined] + pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at builtins.jl:72 [inlined] + macro expansion at regions.jl:302 [inlined] + pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +PythonCall.Wrap.PyArraySource_ArrayStruct: 80 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Tuple{Int64}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Core.SimpleVector: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +DataType: 56 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +UnionAll: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +PythonCall.Wrap.PyArraySource_ArrayStruct: 80 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Tuple{Int64}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Core.SimpleVector: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +DataType: 56 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +UnionAll: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Vector{Symbol}: 32 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:134 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Memory{Symbol}: 40 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:143 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Tuple{Symbol, Symbol, Symbol}: 24 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:146 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Ptr{Nothing}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +PyArray{Int64, 1, (:mutable, :linear, :contiguous)}: 64 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Some{PyArray{Int64, 1, (:mutable, :linear, :contiguous)}}: 64 bytes + pyconvert_return at pyconvert.jl:97 [inlined] + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:152 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +PyArray{Int64, 1, (:mutable, :linear, :contiguous)}: 48 bytes + pyconvert_raw at pyconvert.jl:131 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] + +buffer_native +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at regions.jl:296 [inlined] + pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 + pystr_fromUTF8 at builtins.jl:585 [inlined] + pystr at builtins.jl:593 [inlined] + Py at Py.jl:117 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at Py.jl:103 [inlined] + macro expansion at builtins.jl:63 [inlined] + macro expansion at regions.jl:302 [inlined] + pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at regions.jl:296 [inlined] + pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 + pystr_fromUTF8 at builtins.jl:585 [inlined] + pystr at builtins.jl:593 [inlined] + Py at Py.jl:117 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at Py.jl:103 [inlined] + macro expansion at builtins.jl:63 [inlined] + macro expansion at regions.jl:302 [inlined] + pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:56 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at regions.jl:302 [inlined] + pynulltuple(len::Int64) at builtins.jl:848 + macro expansion at builtins.jl:? [inlined] + pytuple_fromiter at builtins.jl:877 [inlined] + #pycall#21 at builtins.jl:220 [inlined] + pycall at builtins.jl:211 [inlined] + #_#9 at Py.jl:350 [inlined] + Py at Py.jl:350 [inlined] + PyArraySource_Buffer at PyArray.jl:504 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at regions.jl:302 [inlined] + pycallargs(f::Py, args::Py) at builtins.jl:202 + #pycall#21 at builtins.jl:221 [inlined] + pycall at builtins.jl:211 [inlined] + #_#9 at Py.jl:350 [inlined] + Py at Py.jl:350 [inlined] + PyArraySource_Buffer at PyArray.jl:504 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +String: 10 bytes + pyarray_get_R at PyArray.jl:556 [inlined] + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:104 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +PythonCall.Wrap.PyArraySource_Buffer: 32 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Tuple{Int64}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Core.SimpleVector: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +DataType: 56 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +UnionAll: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +PythonCall.Wrap.PyArraySource_Buffer: 32 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Tuple{Int64}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Core.SimpleVector: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +DataType: 56 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +UnionAll: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Vector{Symbol}: 32 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:134 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Memory{Symbol}: 40 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:143 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Tuple{Symbol, Symbol, Symbol}: 24 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:146 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Ptr{Nothing}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +PyArray{Float64, 1, (:mutable, :linear, :contiguous)}: 64 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Some{PyArray{Float64, 1, (:mutable, :linear, :contiguous)}}: 64 bytes + pyconvert_return at pyconvert.jl:97 [inlined] + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:152 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +PyArray{Float64, 1, (:mutable, :linear, :contiguous)}: 48 bytes + pyconvert_result at pyconvert.jl:100 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Profile.Allocs.BufferType: 8000 bytes + pyconvert_tryconvert(::Type{Array}, x::PyArray{Float64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:138 + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Memory{Float64}: 24 bytes + pyconvert_tryconvert(::Type{Array}, x::PyArray{Float64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:138 + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Vector{Float64}: 32 bytes + pyconvert_tryconvert(::Type{Array}, x::PyArray{Float64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:138 + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Some{Vector{Float64}}: 16 bytes + pyconvert_tryconvert(::Type{Array}, x::PyArray{Float64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:138 + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] + +buffer_wrapper +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at regions.jl:296 [inlined] + pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 + pystr_fromUTF8 at builtins.jl:585 [inlined] + pystr at builtins.jl:593 [inlined] + Py at Py.jl:117 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at Py.jl:103 [inlined] + macro expansion at builtins.jl:63 [inlined] + macro expansion at regions.jl:302 [inlined] + pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at regions.jl:296 [inlined] + pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 + pystr_fromUTF8 at builtins.jl:585 [inlined] + pystr at builtins.jl:593 [inlined] + Py at Py.jl:117 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at Py.jl:103 [inlined] + macro expansion at builtins.jl:63 [inlined] + macro expansion at regions.jl:302 [inlined] + pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:56 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at regions.jl:302 [inlined] + pynulltuple(len::Int64) at builtins.jl:848 + macro expansion at builtins.jl:? [inlined] + pytuple_fromiter at builtins.jl:877 [inlined] + #pycall#21 at builtins.jl:220 [inlined] + pycall at builtins.jl:211 [inlined] + #_#9 at Py.jl:350 [inlined] + Py at Py.jl:350 [inlined] + PyArraySource_Buffer at PyArray.jl:504 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at regions.jl:302 [inlined] + pycallargs(f::Py, args::Py) at builtins.jl:202 + #pycall#21 at builtins.jl:221 [inlined] + pycall at builtins.jl:211 [inlined] + #_#9 at Py.jl:350 [inlined] + Py at Py.jl:350 [inlined] + PyArraySource_Buffer at PyArray.jl:504 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +String: 10 bytes + pyarray_get_R at PyArray.jl:556 [inlined] + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:104 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +PythonCall.Wrap.PyArraySource_Buffer: 32 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Tuple{Int64}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Core.SimpleVector: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +DataType: 56 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +UnionAll: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +PythonCall.Wrap.PyArraySource_Buffer: 32 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Tuple{Int64}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Core.SimpleVector: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +DataType: 56 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +UnionAll: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Vector{Symbol}: 32 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:134 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Memory{Symbol}: 40 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:143 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Tuple{Symbol, Symbol, Symbol}: 24 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:146 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Ptr{Nothing}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +PyArray{Float64, 1, (:mutable, :linear, :contiguous)}: 64 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +Some{PyArray{Float64, 1, (:mutable, :linear, :contiguous)}}: 64 bytes + pyconvert_return at pyconvert.jl:97 [inlined] + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:152 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] +PyArray{Float64, 1, (:mutable, :linear, :contiguous)}: 48 bytes + pyconvert_raw at pyconvert.jl:131 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:316 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] diff --git a/benchmark/convert-array-allocations-before.txt b/benchmark/convert-array-allocations-before.txt new file mode 100644 index 000000000..0972c3f2b --- /dev/null +++ b/benchmark/convert-array-allocations-before.txt @@ -0,0 +1,1389 @@ +Julia: 1.13.2; PythonCall source: /tmp/pythoncall-convert-baseline.HAfFfi/src/PythonCall.jl + +ndarray_native +Py: 16 bytes + Py at types.jl:27 [inlined] + pynew at Py.jl:51 [inlined] + pynew at Py.jl:55 [inlined] + macro expansion at regions.jl:296 [inlined] + pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 + pystr_fromUTF8 at builtins.jl:585 [inlined] + pystr at builtins.jl:593 [inlined] + Py at Py.jl:116 [inlined] + macro expansion at Py.jl:107 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at Py.jl:102 [inlined] + macro expansion at builtins.jl:63 [inlined] + macro expansion at regions.jl:302 [inlined] + pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:41 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +Py: 16 bytes + Py at types.jl:27 [inlined] + pynew at Py.jl:51 [inlined] + pynew at Py.jl:55 [inlined] + macro expansion at builtins.jl:72 [inlined] + macro expansion at regions.jl:302 [inlined] + pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:41 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +PythonCall.Wrap.PyArraySource_ArrayStruct: 80 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +Tuple{Int64}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +Core.SimpleVector: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +DataType: 56 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +UnionAll: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +PythonCall.Wrap.PyArraySource_ArrayStruct: 80 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +Tuple{Int64}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +Core.SimpleVector: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +DataType: 56 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +UnionAll: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +Vector{Symbol}: 32 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:122 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +Memory{Symbol}: 40 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:131 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +Tuple{Symbol, Symbol, Symbol}: 24 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:134 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +Ptr{Nothing}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:139 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +PyArray{Int64, 1, (:mutable, :linear, :contiguous)}: 64 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:139 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +Profile.Allocs.BufferType: 8000 bytes + pyconvert_tryconvert(::Type{Array}, x::PyArray{Int64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:140 + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +Memory{Int64}: 24 bytes + pyconvert_tryconvert(::Type{Array}, x::PyArray{Int64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:140 + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +Vector{Int64}: 32 bytes + pyconvert_tryconvert(::Type{Array}, x::PyArray{Int64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:140 + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 + +ndarray_wrapper +Py: 16 bytes + Py at types.jl:27 [inlined] + pynew at Py.jl:51 [inlined] + pynew at Py.jl:55 [inlined] + macro expansion at regions.jl:296 [inlined] + pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 + pystr_fromUTF8 at builtins.jl:585 [inlined] + pystr at builtins.jl:593 [inlined] + Py at Py.jl:116 [inlined] + macro expansion at Py.jl:107 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at Py.jl:102 [inlined] + macro expansion at builtins.jl:63 [inlined] + macro expansion at regions.jl:302 [inlined] + pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:41 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +Py: 16 bytes + Py at types.jl:27 [inlined] + pynew at Py.jl:51 [inlined] + pynew at Py.jl:55 [inlined] + macro expansion at builtins.jl:72 [inlined] + macro expansion at regions.jl:302 [inlined] + pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:41 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +PythonCall.Wrap.PyArraySource_ArrayStruct: 80 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +Tuple{Int64}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +Core.SimpleVector: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +DataType: 56 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +UnionAll: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +PythonCall.Wrap.PyArraySource_ArrayStruct: 80 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +Tuple{Int64}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +Core.SimpleVector: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +DataType: 56 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +UnionAll: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +Vector{Symbol}: 32 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:122 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +Memory{Symbol}: 40 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:131 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +Tuple{Symbol, Symbol, Symbol}: 24 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:134 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +Ptr{Nothing}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:139 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +PyArray{Int64, 1, (:mutable, :linear, :contiguous)}: 64 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:139 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 + +buffer_native +Py: 16 bytes + Py at types.jl:27 [inlined] + pynew at Py.jl:51 [inlined] + pynew at Py.jl:55 [inlined] + macro expansion at regions.jl:296 [inlined] + pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 + pystr_fromUTF8 at builtins.jl:585 [inlined] + pystr at builtins.jl:593 [inlined] + Py at Py.jl:116 [inlined] + macro expansion at Py.jl:107 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at Py.jl:102 [inlined] + macro expansion at builtins.jl:63 [inlined] + macro expansion at regions.jl:302 [inlined] + pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:41 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +Py: 16 bytes + Py at types.jl:27 [inlined] + pynew at Py.jl:51 [inlined] + pynew at Py.jl:55 [inlined] + macro expansion at regions.jl:296 [inlined] + pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 + pystr_fromUTF8 at builtins.jl:585 [inlined] + pystr at builtins.jl:593 [inlined] + Py at Py.jl:116 [inlined] + macro expansion at Py.jl:107 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at Py.jl:102 [inlined] + macro expansion at builtins.jl:63 [inlined] + macro expansion at regions.jl:302 [inlined] + pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +Py: 16 bytes + Py at types.jl:27 [inlined] + pynew at Py.jl:51 [inlined] + pynew at Py.jl:55 [inlined] + macro expansion at regions.jl:302 [inlined] + pynulltuple(len::Int64) at builtins.jl:848 + macro expansion at builtins.jl:? [inlined] + pytuple_fromiter at builtins.jl:877 [inlined] + #pycall#21 at builtins.jl:220 [inlined] + pycall at builtins.jl:211 [inlined] + #_#9 at Py.jl:349 [inlined] + Py at Py.jl:349 [inlined] + PyArraySource_Buffer at PyArray.jl:492 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +Py: 16 bytes + Py at types.jl:27 [inlined] + pynew at Py.jl:51 [inlined] + pynew at Py.jl:55 [inlined] + macro expansion at regions.jl:302 [inlined] + pycallargs(f::Py, args::Py) at builtins.jl:202 + #pycall#21 at builtins.jl:221 [inlined] + pycall at builtins.jl:211 [inlined] + #_#9 at Py.jl:349 [inlined] + Py at Py.jl:349 [inlined] + PyArraySource_Buffer at PyArray.jl:492 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +String: 10 bytes + pyarray_get_R at PyArray.jl:544 [inlined] + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:92 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +PythonCall.Wrap.PyArraySource_Buffer: 32 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +Tuple{Int64}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +Core.SimpleVector: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +DataType: 56 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +UnionAll: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +PythonCall.Wrap.PyArraySource_Buffer: 32 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +Tuple{Int64}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +Core.SimpleVector: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +DataType: 56 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +UnionAll: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +Vector{Symbol}: 32 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:122 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +Memory{Symbol}: 40 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:131 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +Tuple{Symbol, Symbol, Symbol}: 24 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:134 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +Ptr{Nothing}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:139 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +PyArray{Float64, 1, (:mutable, :linear, :contiguous)}: 64 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:139 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +Profile.Allocs.BufferType: 8000 bytes + pyconvert_tryconvert(::Type{Array}, x::PyArray{Float64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:140 + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +Memory{Float64}: 24 bytes + pyconvert_tryconvert(::Type{Array}, x::PyArray{Float64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:140 + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 +Vector{Float64}: 32 bytes + pyconvert_tryconvert(::Type{Array}, x::PyArray{Float64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:140 + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 + +buffer_wrapper +Py: 16 bytes + Py at types.jl:27 [inlined] + pynew at Py.jl:51 [inlined] + pynew at Py.jl:55 [inlined] + macro expansion at regions.jl:296 [inlined] + pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 + pystr_fromUTF8 at builtins.jl:585 [inlined] + pystr at builtins.jl:593 [inlined] + Py at Py.jl:116 [inlined] + macro expansion at Py.jl:107 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at Py.jl:102 [inlined] + macro expansion at builtins.jl:63 [inlined] + macro expansion at regions.jl:302 [inlined] + pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:41 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +Py: 16 bytes + Py at types.jl:27 [inlined] + pynew at Py.jl:51 [inlined] + pynew at Py.jl:55 [inlined] + macro expansion at regions.jl:296 [inlined] + pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 + pystr_fromUTF8 at builtins.jl:585 [inlined] + pystr at builtins.jl:593 [inlined] + Py at Py.jl:116 [inlined] + macro expansion at Py.jl:107 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at Py.jl:102 [inlined] + macro expansion at builtins.jl:63 [inlined] + macro expansion at regions.jl:302 [inlined] + pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +Py: 16 bytes + Py at types.jl:27 [inlined] + pynew at Py.jl:51 [inlined] + pynew at Py.jl:55 [inlined] + macro expansion at regions.jl:302 [inlined] + pynulltuple(len::Int64) at builtins.jl:848 + macro expansion at builtins.jl:? [inlined] + pytuple_fromiter at builtins.jl:877 [inlined] + #pycall#21 at builtins.jl:220 [inlined] + pycall at builtins.jl:211 [inlined] + #_#9 at Py.jl:349 [inlined] + Py at Py.jl:349 [inlined] + PyArraySource_Buffer at PyArray.jl:492 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +Py: 16 bytes + Py at types.jl:27 [inlined] + pynew at Py.jl:51 [inlined] + pynew at Py.jl:55 [inlined] + macro expansion at regions.jl:302 [inlined] + pycallargs(f::Py, args::Py) at builtins.jl:202 + #pycall#21 at builtins.jl:221 [inlined] + pycall at builtins.jl:211 [inlined] + #_#9 at Py.jl:349 [inlined] + Py at Py.jl:349 [inlined] + PyArraySource_Buffer at PyArray.jl:492 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +String: 10 bytes + pyarray_get_R at PyArray.jl:544 [inlined] + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:92 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +PythonCall.Wrap.PyArraySource_Buffer: 32 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +Tuple{Int64}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +Core.SimpleVector: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +DataType: 56 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +UnionAll: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +PythonCall.Wrap.PyArraySource_Buffer: 32 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +Tuple{Int64}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +Core.SimpleVector: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +DataType: 56 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +UnionAll: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +Vector{Symbol}: 32 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:122 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +Memory{Symbol}: 40 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:131 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +Tuple{Symbol, Symbol, Symbol}: 24 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:134 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +Ptr{Nothing}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:139 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 +PyArray{Float64, 1, (:mutable, :linear, :contiguous)}: 64 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:139 + pyarray_make at PyArray.jl:92 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 + pyarray_make at PyArray.jl:32 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 + macro expansion at regions.jl:323 [inlined] + pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 + macro expansion at pyconvert.jl:376 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at pyconvert.jl:373 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:302 [inlined] + macro expansion at Py.jl:102 [inlined] + pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 diff --git a/benchmark/convert-array-allocations-unwrapped.txt b/benchmark/convert-array-allocations-unwrapped.txt new file mode 100644 index 000000000..23732a8f7 --- /dev/null +++ b/benchmark/convert-array-allocations-unwrapped.txt @@ -0,0 +1,1389 @@ +Julia: 1.13.2; PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl + +ndarray_native +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at regions.jl:296 [inlined] + pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 + pystr_fromUTF8 at builtins.jl:585 [inlined] + pystr at builtins.jl:593 [inlined] + Py at Py.jl:117 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at Py.jl:103 [inlined] + macro expansion at builtins.jl:63 [inlined] + macro expansion at regions.jl:302 [inlined] + pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at builtins.jl:72 [inlined] + macro expansion at regions.jl:302 [inlined] + pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +PythonCall.Wrap.PyArraySource_ArrayStruct: 80 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Tuple{Int64}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Core.SimpleVector: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +DataType: 56 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +UnionAll: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +PythonCall.Wrap.PyArraySource_ArrayStruct: 80 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Tuple{Int64}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Core.SimpleVector: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +DataType: 56 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +UnionAll: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Vector{Symbol}: 32 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:134 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Memory{Symbol}: 40 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:143 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Tuple{Symbol, Symbol, Symbol}: 24 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:146 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Ptr{Nothing}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +PyArray{Int64, 1, (:mutable, :linear, :contiguous)}: 64 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Profile.Allocs.BufferType: 8000 bytes + pyconvert_tryconvert(::Type{Array}, x::PyArray{Int64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:142 + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Memory{Int64}: 24 bytes + pyconvert_tryconvert(::Type{Array}, x::PyArray{Int64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:142 + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Vector{Int64}: 32 bytes + pyconvert_tryconvert(::Type{Array}, x::PyArray{Int64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:142 + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] + +ndarray_wrapper +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at regions.jl:296 [inlined] + pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 + pystr_fromUTF8 at builtins.jl:585 [inlined] + pystr at builtins.jl:593 [inlined] + Py at Py.jl:117 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at Py.jl:103 [inlined] + macro expansion at builtins.jl:63 [inlined] + macro expansion at regions.jl:302 [inlined] + pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at builtins.jl:72 [inlined] + macro expansion at regions.jl:302 [inlined] + pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +PythonCall.Wrap.PyArraySource_ArrayStruct: 80 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Tuple{Int64}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Core.SimpleVector: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +DataType: 56 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +UnionAll: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +PythonCall.Wrap.PyArraySource_ArrayStruct: 80 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Tuple{Int64}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Core.SimpleVector: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +DataType: 56 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +UnionAll: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Vector{Symbol}: 32 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:134 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Memory{Symbol}: 40 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:143 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Tuple{Symbol, Symbol, Symbol}: 24 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:146 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Ptr{Nothing}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +PyArray{Int64, 1, (:mutable, :linear, :contiguous)}: 64 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] + +buffer_native +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at regions.jl:296 [inlined] + pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 + pystr_fromUTF8 at builtins.jl:585 [inlined] + pystr at builtins.jl:593 [inlined] + Py at Py.jl:117 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at Py.jl:103 [inlined] + macro expansion at builtins.jl:63 [inlined] + macro expansion at regions.jl:302 [inlined] + pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at regions.jl:296 [inlined] + pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 + pystr_fromUTF8 at builtins.jl:585 [inlined] + pystr at builtins.jl:593 [inlined] + Py at Py.jl:117 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at Py.jl:103 [inlined] + macro expansion at builtins.jl:63 [inlined] + macro expansion at regions.jl:302 [inlined] + pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:56 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at regions.jl:302 [inlined] + pynulltuple(len::Int64) at builtins.jl:848 + macro expansion at builtins.jl:? [inlined] + pytuple_fromiter at builtins.jl:877 [inlined] + #pycall#21 at builtins.jl:220 [inlined] + pycall at builtins.jl:211 [inlined] + #_#9 at Py.jl:350 [inlined] + Py at Py.jl:350 [inlined] + PyArraySource_Buffer at PyArray.jl:504 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at regions.jl:302 [inlined] + pycallargs(f::Py, args::Py) at builtins.jl:202 + #pycall#21 at builtins.jl:221 [inlined] + pycall at builtins.jl:211 [inlined] + #_#9 at Py.jl:350 [inlined] + Py at Py.jl:350 [inlined] + PyArraySource_Buffer at PyArray.jl:504 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +String: 10 bytes + pyarray_get_R at PyArray.jl:556 [inlined] + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:104 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +PythonCall.Wrap.PyArraySource_Buffer: 32 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Tuple{Int64}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Core.SimpleVector: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +DataType: 56 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +UnionAll: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +PythonCall.Wrap.PyArraySource_Buffer: 32 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Tuple{Int64}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Core.SimpleVector: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +DataType: 56 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +UnionAll: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Vector{Symbol}: 32 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:134 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Memory{Symbol}: 40 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:143 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Tuple{Symbol, Symbol, Symbol}: 24 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:146 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Ptr{Nothing}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +PyArray{Float64, 1, (:mutable, :linear, :contiguous)}: 64 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Profile.Allocs.BufferType: 8000 bytes + pyconvert_tryconvert(::Type{Array}, x::PyArray{Float64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:142 + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Memory{Float64}: 24 bytes + pyconvert_tryconvert(::Type{Array}, x::PyArray{Float64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:142 + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Vector{Float64}: 32 bytes + pyconvert_tryconvert(::Type{Array}, x::PyArray{Float64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:142 + pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] + +buffer_wrapper +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at regions.jl:296 [inlined] + pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 + pystr_fromUTF8 at builtins.jl:585 [inlined] + pystr at builtins.jl:593 [inlined] + Py at Py.jl:117 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at Py.jl:103 [inlined] + macro expansion at builtins.jl:63 [inlined] + macro expansion at regions.jl:302 [inlined] + pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at regions.jl:296 [inlined] + pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 + pystr_fromUTF8 at builtins.jl:585 [inlined] + pystr at builtins.jl:593 [inlined] + Py at Py.jl:117 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at Py.jl:103 [inlined] + macro expansion at builtins.jl:63 [inlined] + macro expansion at regions.jl:302 [inlined] + pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:56 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at regions.jl:302 [inlined] + pynulltuple(len::Int64) at builtins.jl:848 + macro expansion at builtins.jl:? [inlined] + pytuple_fromiter at builtins.jl:877 [inlined] + #pycall#21 at builtins.jl:220 [inlined] + pycall at builtins.jl:211 [inlined] + #_#9 at Py.jl:350 [inlined] + Py at Py.jl:350 [inlined] + PyArraySource_Buffer at PyArray.jl:504 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at regions.jl:302 [inlined] + pycallargs(f::Py, args::Py) at builtins.jl:202 + #pycall#21 at builtins.jl:221 [inlined] + pycall at builtins.jl:211 [inlined] + #_#9 at Py.jl:350 [inlined] + Py at Py.jl:350 [inlined] + PyArraySource_Buffer at PyArray.jl:504 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +String: 10 bytes + pyarray_get_R at PyArray.jl:556 [inlined] + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:104 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +PythonCall.Wrap.PyArraySource_Buffer: 32 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Tuple{Int64}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Core.SimpleVector: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +DataType: 56 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +UnionAll: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +PythonCall.Wrap.PyArraySource_Buffer: 32 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Tuple{Int64}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Core.SimpleVector: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +DataType: 56 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +UnionAll: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Vector{Symbol}: 32 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:134 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Memory{Symbol}: 40 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:143 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Tuple{Symbol, Symbol, Symbol}: 24 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:146 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +Ptr{Nothing}: 16 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] +PyArray{Float64, 1, (:mutable, :linear, :contiguous)}: 64 bytes + pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 + pyarray_make at PyArray.jl:104 [inlined] + pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 + pyarray_make at PyArray.jl:39 [inlined] + pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] + (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 + macro expansion at regions.jl:323 [inlined] + pyconvert_first at pyconvert.jl:320 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 + pytryconvert_raw at pyconvert.jl:345 [inlined] + macro expansion at pyconvert.jl:421 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 + #pyconvert#36 at pyconvert.jl:426 [inlined] + pyconvert at pyconvert.jl:426 [inlined] diff --git a/benchmark/convert-array-allocations.jl b/benchmark/convert-array-allocations.jl new file mode 100644 index 000000000..0e9489d9f --- /dev/null +++ b/benchmark/convert-array-allocations.jl @@ -0,0 +1,35 @@ +# Attribution only: run after timing trials, with the same environment/Python. +using PythonCall, Profile +array_value(::Val{T},x) where T = pyconvert(T,x,nothing) +label=isempty(ARGS) ? "after" : only(ARGS) +source_root=dirname(pathof(PythonCall)) +np=pyimport("numpy") +array=pyimport("array") +cases=[("ndarray_native",Array,np.arange(1000)), + ("ndarray_wrapper",PyArray,np.arange(1000)), + ("buffer_native",Array,array.array("d",pylist(1:1000))), + ("buffer_wrapper",PyArray,array.array("d",pylist(1:1000)))] +open(joinpath(@__DIR__,"convert-array-allocations-$label.txt"),"w") do io + println(io,"Julia: ",VERSION,"; PythonCall source: ",pathof(PythonCall)) + for (name,T,x) in cases + f=let tag=Val(T), x=x + ()->array_value(tag,x) + end + for _=1:3 + f() + end + GC.gc() + Profile.Allocs.clear() + Profile.Allocs.@profile sample_rate=1.0 f() + println(io,"\n",name) + for a in Profile.Allocs.fetch().allocs + println(io,a.type,": ",a.size," bytes") + for frame in a.stacktrace + file=string(frame.file) + if occursin(source_root,file) + println(io," ",frame) + end + end + end + end +end diff --git a/benchmark/convert-baseline.tsv b/benchmark/convert-baseline.tsv new file mode 100644 index 000000000..588a89e1c --- /dev/null +++ b/benchmark/convert-baseline.tsv @@ -0,0 +1,16 @@ +case ns bytes allocs +int 379.32211538461536 0 0 +integer 716.6590909090909 0 0 +bigint 1140.0 216 7 +float 380.9707317073171 16 1 +bool 420.3744075829384 0 0 +string 529.0765306122449 48 2 +none 349.76056338028167 0 0 +failure 366.33658536585364 0 0 +list10 9299.0 704 17 +list10000 7.432131e6 513864 19507 +mixed 7449.75 608 20 +nested 575.6850828729282 16 1 +dict 8699.75 1248 22 +wrapper 558.0591397849462 16 1 +iterator 579.5524861878453 16 1 diff --git a/benchmark/convert-dispatch-final.tsv b/benchmark/convert-dispatch-final.tsv new file mode 100644 index 000000000..e1bef004a --- /dev/null +++ b/benchmark/convert-dispatch-final.tsv @@ -0,0 +1,10 @@ +case ns bytes allocs +no_preference 9700.0 864 32 +one_preference 1899.9 256 11 +multiple_preferences 3475.0 576 21 +unmatched_preferences 22099.0 2304 93 +nested_context 5283.333333333333 608 26 +ndarray_native 5014.285714285715 8888 23 +ndarray_wrapper 3225.0 800 19 +bytes_explicit 584.0604395604396 128 4 +scope_filtered 5216.5 688 17 diff --git a/benchmark/convert-dispatch.jl b/benchmark/convert-dispatch.jl new file mode 100644 index 000000000..06721bf87 --- /dev/null +++ b/benchmark/convert-dispatch.jl @@ -0,0 +1,25 @@ +using PythonCall, BenchmarkTools +const CV=PythonCall.Convert +label = isempty(ARGS) ? "" : "-" * only(ARGS) +x=pylist([pylist(1:5),pylist(6:10)]) +scoped=pylist(1:10) +np=pyimport("numpy") +cases = [ + ("no_preference", ()->pyconvert(Any,x)), + ("one_preference", ()->pyconvert(Any,x;prefer=("builtins:list"=>PyList,))), + ("multiple_preferences", ()->pyconvert(Any,x;prefer=("builtins:dict"=>PyDict,"builtins:list"=>PyList))), + ("unmatched_preferences", ()->pyconvert(Any,x;prefer=("builtins:dict"=>PyDict,))), + ("nested_context", ()->pyconvert(PyConvertContext(;prefer=("builtins:list"=>PyList,)),Vector,x)), + ("ndarray_native", let a=np.arange(1000); ()->pyconvert(Any,a) end), + ("ndarray_wrapper", let a=np.arange(1000); ()->pyconvert(PyArray,a) end), + ("bytes_explicit", let a=pybytes(pylist([1,2,3])); ()->pyconvert(Vector{UInt8},a) end), + ("scope_filtered", ()->pyconvert(Vector{Int},scoped)), +] +open(joinpath(@__DIR__,"convert-dispatch$label.tsv"),"w") do io + println(io,"case\tns\tbytes\tallocs") + for (name,f) in cases + m=minimum(@benchmark $f() seconds=1.0 samples=5000) + println(io,"$name\t$(m.time)\t$(m.memory)\t$(m.allocs)") + end +end +# Cache misses/invalidation are measured with untimed setup in convert-expanded.jl. diff --git a/benchmark/convert-dispatch.tsv b/benchmark/convert-dispatch.tsv new file mode 100644 index 000000000..78a9c13fe --- /dev/null +++ b/benchmark/convert-dispatch.tsv @@ -0,0 +1,12 @@ +case ns bytes allocs +no_preference 11100.0 864 32 +one_preference 1740.0 192 9 +multiple_preferences 3437.375 448 17 +unmatched_preferences 26399.0 2240 91 +nested_context 5300.0 544 24 +ndarray_native 4614.142857142857 8888 23 +ndarray_wrapper 3662.5 800 19 +buffer 710.608938547486 128 4 +scope_filtered 8400.0 864 28 +selection_miss 37799.0 2160 76 +registry_rebuild 2.484981e6 1310488 19575 diff --git a/benchmark/convert-expanded-after-environment.txt b/benchmark/convert-expanded-after-environment.txt new file mode 100644 index 000000000..355c75eca --- /dev/null +++ b/benchmark/convert-expanded-after-environment.txt @@ -0,0 +1,7 @@ +Julia: 1.13.2 +Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] +Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python +NumPy: 2.5.4 +BenchmarkTools: 1.8.0 +PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl +New API: true diff --git a/benchmark/convert-expanded-after.tsv b/benchmark/convert-expanded-after.tsv new file mode 100644 index 000000000..b08ebc35e --- /dev/null +++ b/benchmark/convert-expanded-after.tsv @@ -0,0 +1,37 @@ +case mode status min_ns median_ns bytes allocs +single_rule warm measured 380.3872549019608 424.5049019607843 0 0 +single_rule selection_miss measured 66399.0 67099.0 8304 261 +single_rule invalidated measured 2.59848e6 2.999976e6 1535216 22416 +decline_then_success warm measured 535.7842105263157 537.3684210526316 0 0 +decline_then_success selection_miss measured 72299.0 81800.0 8400 264 +decline_then_success invalidated measured 2.670179e6 3.0039265e6 1535312 22419 +three_declines_then_success warm measured 861.4142857142857 869.9857142857143 0 0 +three_declines_then_success selection_miss measured 76100.0 83699.0 8688 271 +three_declines_then_success invalidated measured 2.662079e6 2.8253285e6 1535600 22426 +sixteen_scoped_decliners warm measured 401.9850746268657 414.4228855721393 0 0 +sixteen_scoped_decliners selection_miss measured 69900.0 78999.0 8304 261 +sixteen_scoped_decliners invalidated measured 2.65408e6 2.7655285e6 1535216 22416 +virtual_mapping_abc warm measured 401.9655172413793 413.7881773399015 0 0 +virtual_mapping_abc selection_miss measured 66700.0 76700.0 8304 261 +virtual_mapping_abc invalidated measured 2.672779e6 2.843228e6 1535216 22416 +buffer_only_native warm measured 7199.75 7650.0 8856 26 +buffer_only_native selection_miss measured 40199.0 45049.5 9880 62 +buffer_only_native invalidated measured 2.640482e6 2.723231e6 1535928 22205 +buffer_only_wrapper warm measured 5599.833333333333 6250.0 768 22 +buffer_only_wrapper selection_miss measured 36800.0 39899.0 1920 58 +buffer_only_wrapper invalidated measured 2.646981e6 3.003029e6 1527968 22201 +interface_only_native warm measured 22600.0 23500.0 9368 55 +interface_only_native selection_miss measured 59700.0 68399.0 10408 91 +interface_only_native invalidated measured 2.978079e6 3.2996265e6 1567848 23253 +array_method_only_native warm measured 7774.75 8450.0 9016 30 +array_method_only_native selection_miss measured 41200.0 45399.0 10056 66 +array_method_only_native invalidated measured 2.663281e6 2.7410805e6 1536968 22221 +ndarray_native warm measured 4966.666666666667 5550.0 8888 23 +ndarray_native selection_miss measured 36400.0 39199.0 10872 84 +ndarray_native invalidated measured 2.740381e6 2.8986295e6 1536920 22227 +ndarray_wrapper warm measured 3362.5 3537.375 800 19 +ndarray_wrapper selection_miss measured 34600.0 37399.0 3488 86 +ndarray_wrapper invalidated measured 2.688781e6 3.030328e6 1529536 22229 +two_matching_first_success warm measured 3275.0 3487.5 432 14 +two_matching_first_declines warm measured 3812.5 3962.5 592 20 +two_matching_decline_then_ordinary warm measured 4171.428571428572 4257.142857142857 624 21 diff --git a/benchmark/convert-expanded-before-environment.txt b/benchmark/convert-expanded-before-environment.txt new file mode 100644 index 000000000..aee3d1309 --- /dev/null +++ b/benchmark/convert-expanded-before-environment.txt @@ -0,0 +1,7 @@ +Julia: 1.13.2 +Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] +Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python +NumPy: 2.5.4 +BenchmarkTools: 1.8.0 +PythonCall source: /tmp/pythoncall-convert-baseline.HAfFfi/src/PythonCall.jl +New API: false diff --git a/benchmark/convert-expanded-before.tsv b/benchmark/convert-expanded-before.tsv new file mode 100644 index 000000000..3adcb9207 --- /dev/null +++ b/benchmark/convert-expanded-before.tsv @@ -0,0 +1,37 @@ +case mode status min_ns median_ns bytes allocs +single_rule warm measured 393.5323383084577 404.4726368159204 0 0 +single_rule selection_miss measured 26500.0 29000.0 4976 149 +single_rule invalidated measured 21400.0 23150.0 4976 149 +decline_then_success warm measured 547.3351063829788 548.3989361702128 0 0 +decline_then_success selection_miss measured 27700.0 29749.5 5840 174 +decline_then_success invalidated measured 29400.0 30499.5 5840 174 +three_declines_then_success warm measured 871.1346153846154 875.0 0 0 +three_declines_then_success selection_miss measured 30299.0 33450.0 8752 234 +three_declines_then_success invalidated measured 34000.0 35750.0 8752 234 +sixteen_scoped_decliners warm measured 4114.142857142857 4157.0 0 0 +sixteen_scoped_decliners selection_miss measured 65999.0 74499.5 31344 797 +sixteen_scoped_decliners invalidated measured 72500.0 78150.0 31344 797 +virtual_mapping_abc warm measured 397.029702970297 398.509900990099 0 0 +virtual_mapping_abc selection_miss measured 49999.0 54400.0 18752 539 +virtual_mapping_abc invalidated measured 65799.0 70549.5 18752 539 +buffer_only_native warm measured 7050.0 7612.375 8712 23 +buffer_only_native selection_miss measured 79599.0 99699.5 35784 778 +buffer_only_native invalidated measured 105799.0 116549.0 35784 778 +buffer_only_wrapper warm measured 5266.5 5983.333333333333 640 20 +buffer_only_wrapper selection_miss measured 82000.0 95449.5 26816 757 +buffer_only_wrapper invalidated measured 87900.0 98599.0 26816 757 +interface_only_native warm measured 21400.0 22600.0 9224 52 +interface_only_native selection_miss measured 66200.0 77599.5 15896 244 +interface_only_native invalidated measured 240499.0 272048.0 64232 1579 +array_method_only_native warm measured 7733.333333333333 8233.0 8872 27 +array_method_only_native selection_miss measured 44700.0 51500.0 15544 219 +array_method_only_native invalidated measured 50500.0 55050.0 15544 219 +ndarray_native warm measured 4485.714285714285 4864.214285714286 8744 20 +ndarray_native selection_miss measured 73899.0 84599.0 35208 788 +ndarray_native invalidated measured 83000.0 88999.5 35208 788 +ndarray_wrapper warm measured 3112.5 3312.5 672 17 +ndarray_wrapper selection_miss measured 67099.0 79599.5 28208 803 +ndarray_wrapper invalidated measured 82400.0 87399.5 28208 803 +two_matching_first_success warm unsupported NA NA NA NA +two_matching_first_declines warm unsupported NA NA NA NA +two_matching_decline_then_ordinary warm unsupported NA NA NA NA diff --git a/benchmark/convert-expanded-final-after-r1-environment.txt b/benchmark/convert-expanded-final-after-r1-environment.txt new file mode 100644 index 000000000..fce316d62 --- /dev/null +++ b/benchmark/convert-expanded-final-after-r1-environment.txt @@ -0,0 +1,10 @@ +Julia: 1.13.2 +Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] +Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python +NumPy: 2.5.4 +BenchmarkTools: 1.8.0 +PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl +New API: true +Convert/pyconvert.jl SHA256: 7d8337b08370a90127dcc5a9d7b9b79f743ee2998c5ac6154a671725682aad6e +Convert/rules.jl SHA256: d42b0af459b0243412a5f9befa62caccc5039a8e0561be414cf9f941a6c328e4 +Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a diff --git a/benchmark/convert-expanded-final-after-r1.tsv b/benchmark/convert-expanded-final-after-r1.tsv new file mode 100644 index 000000000..256344ff8 --- /dev/null +++ b/benchmark/convert-expanded-final-after-r1.tsv @@ -0,0 +1,37 @@ +case mode status min_ns median_ns bytes allocs +single_rule warm measured 377.9362745098039 388.2352941176471 0 0 +single_rule selection_miss measured 63999.0 72299.0 8304 261 +single_rule invalidated measured 2.562281e6 3.059677e6 1474960 21262 +decline_then_success warm measured 528.7905759162304 586.9057591623036 0 0 +decline_then_success selection_miss measured 62999.0 63600.0 8400 264 +decline_then_success invalidated measured 2.542581e6 2.897078e6 1475056 21265 +three_declines_then_success warm measured 842.8214285714286 989.2857142857143 0 0 +three_declines_then_success selection_miss measured 62499.0 66550.0 8688 271 +three_declines_then_success invalidated measured 2.508581e6 2.6649795e6 1475344 21272 +sixteen_scoped_decliners warm measured 380.87745098039215 401.4656862745098 0 0 +sixteen_scoped_decliners selection_miss measured 71500.0 78699.5 8304 261 +sixteen_scoped_decliners invalidated measured 2.500481e6 2.6097305e6 1474960 21262 +virtual_mapping_abc warm measured 379.40686274509807 433.3333333333333 0 0 +virtual_mapping_abc selection_miss measured 71599.0 81300.0 8304 261 +virtual_mapping_abc invalidated measured 2.533781e6 2.7204295e6 1474960 21262 +buffer_only_native warm measured 7399.75 8300.0 8856 26 +buffer_only_native selection_miss measured 43600.0 48399.5 9880 62 +buffer_only_native invalidated measured 2.75358e6 3.167676e6 1475672 21051 +buffer_only_wrapper warm measured 5549.833333333333 6608.25 768 22 +buffer_only_wrapper selection_miss measured 31700.0 33300.0 1920 58 +buffer_only_wrapper invalidated measured 2.525881e6 2.667029e6 1467712 21047 +interface_only_native warm measured 22999.0 24100.0 9368 55 +interface_only_native selection_miss measured 57999.0 65000.0 10408 91 +interface_only_native invalidated measured 2.864778e6 3.1550755e6 1507208 22091 +array_method_only_native warm measured 8000.0 9533.0 9016 30 +array_method_only_native selection_miss measured 36100.0 38799.0 10056 66 +array_method_only_native invalidated measured 2.679379e6 2.944427e6 1476712 21067 +ndarray_native warm measured 4750.0 5150.0 8888 23 +ndarray_native selection_miss measured 38400.0 41149.5 10872 84 +ndarray_native invalidated measured 2.58148e6 2.6334295e6 1476664 21073 +ndarray_wrapper warm measured 3287.5 3637.5 800 19 +ndarray_wrapper selection_miss measured 34300.0 37100.0 3488 86 +ndarray_wrapper invalidated measured 2.870077e6 3.0517765e6 1469280 21075 +two_matching_first_success warm measured 3375.0 3975.0 560 18 +two_matching_first_declines warm measured 4128.428571428572 4871.428571428572 720 24 +two_matching_decline_then_ordinary warm measured 4685.714285714285 5014.142857142857 752 25 diff --git a/benchmark/convert-expanded-final-after-r2-environment.txt b/benchmark/convert-expanded-final-after-r2-environment.txt new file mode 100644 index 000000000..fce316d62 --- /dev/null +++ b/benchmark/convert-expanded-final-after-r2-environment.txt @@ -0,0 +1,10 @@ +Julia: 1.13.2 +Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] +Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python +NumPy: 2.5.4 +BenchmarkTools: 1.8.0 +PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl +New API: true +Convert/pyconvert.jl SHA256: 7d8337b08370a90127dcc5a9d7b9b79f743ee2998c5ac6154a671725682aad6e +Convert/rules.jl SHA256: d42b0af459b0243412a5f9befa62caccc5039a8e0561be414cf9f941a6c328e4 +Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a diff --git a/benchmark/convert-expanded-final-after-r2.tsv b/benchmark/convert-expanded-final-after-r2.tsv new file mode 100644 index 000000000..4617dd310 --- /dev/null +++ b/benchmark/convert-expanded-final-after-r2.tsv @@ -0,0 +1,37 @@ +case mode status min_ns median_ns bytes allocs +single_rule warm measured 402.44607843137254 403.4313725490196 0 0 +single_rule selection_miss measured 71199.0 79449.5 8304 261 +single_rule invalidated measured 2.58888e6 2.990877e6 1474960 21262 +decline_then_success warm measured 573.3989361702128 638.2925531914893 0 0 +decline_then_success selection_miss measured 67899.0 77000.0 8400 264 +decline_then_success invalidated measured 2.66258e6 3.0398265e6 1475056 21265 +three_declines_then_success warm measured 936.0 954.0 0 0 +three_declines_then_success selection_miss measured 62399.0 65800.0 8688 271 +three_declines_then_success invalidated measured 2.62558e6 2.725679e6 1475344 21272 +sixteen_scoped_decliners warm measured 402.00502512562815 473.86934673366835 0 0 +sixteen_scoped_decliners selection_miss measured 60900.0 79249.5 8304 261 +sixteen_scoped_decliners invalidated measured 2.872478e6 4.6828645e6 1474960 21262 +virtual_mapping_abc warm measured 391.6617647058824 434.79901960784315 0 0 +virtual_mapping_abc selection_miss measured 71499.0 76850.0 8304 261 +virtual_mapping_abc invalidated measured 2.60008e6 2.741429e6 1474960 21262 +buffer_only_native warm measured 7675.0 8550.0 8856 26 +buffer_only_native selection_miss measured 41900.0 46700.0 9880 62 +buffer_only_native invalidated measured 2.608181e6 2.942877e6 1475672 21051 +buffer_only_wrapper warm measured 5619.8 6020.0 768 22 +buffer_only_wrapper selection_miss measured 35099.0 36900.0 1920 58 +buffer_only_wrapper invalidated measured 2.528881e6 2.8052785e6 1467712 21047 +interface_only_native warm measured 22600.0 24000.0 9368 55 +interface_only_native selection_miss measured 58600.0 66699.0 10408 91 +interface_only_native invalidated measured 2.890477e6 2.9367265e6 1507208 22091 +array_method_only_native warm measured 7933.333333333333 9033.0 9016 30 +array_method_only_native selection_miss measured 38999.0 42200.0 10056 66 +array_method_only_native invalidated measured 2.648979e6 2.903577e6 1476712 21067 +ndarray_native warm measured 4950.0 5666.666666666667 8888 23 +ndarray_native selection_miss measured 41300.0 46949.5 10872 84 +ndarray_native invalidated measured 2.949576e6 3.063675e6 1476664 21073 +ndarray_wrapper warm measured 3612.5 3925.0 800 19 +ndarray_wrapper selection_miss measured 33899.0 36899.5 3488 86 +ndarray_wrapper invalidated measured 2.649578e6 3.021126e6 1469280 21075 +two_matching_first_success warm measured 3499.875 3750.0 560 18 +two_matching_first_declines warm measured 4228.428571428572 4642.857142857143 720 24 +two_matching_decline_then_ordinary warm measured 5285.714285714285 5671.428571428572 752 25 diff --git a/benchmark/convert-expanded-final-after-r3-environment.txt b/benchmark/convert-expanded-final-after-r3-environment.txt new file mode 100644 index 000000000..fce316d62 --- /dev/null +++ b/benchmark/convert-expanded-final-after-r3-environment.txt @@ -0,0 +1,10 @@ +Julia: 1.13.2 +Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] +Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python +NumPy: 2.5.4 +BenchmarkTools: 1.8.0 +PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl +New API: true +Convert/pyconvert.jl SHA256: 7d8337b08370a90127dcc5a9d7b9b79f743ee2998c5ac6154a671725682aad6e +Convert/rules.jl SHA256: d42b0af459b0243412a5f9befa62caccc5039a8e0561be414cf9f941a6c328e4 +Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a diff --git a/benchmark/convert-expanded-final-after-r3.tsv b/benchmark/convert-expanded-final-after-r3.tsv new file mode 100644 index 000000000..b59ee3ce7 --- /dev/null +++ b/benchmark/convert-expanded-final-after-r3.tsv @@ -0,0 +1,37 @@ +case mode status min_ns median_ns bytes allocs +single_rule warm measured 376.3497536945813 393.5960591133005 0 0 +single_rule selection_miss measured 71800.0 81699.5 8304 261 +single_rule invalidated measured 2.59368e6 2.987577e6 1474960 21262 +decline_then_success warm measured 540.2063492063492 541.7936507936508 0 0 +decline_then_success selection_miss measured 72899.0 80699.5 8400 264 +decline_then_success invalidated measured 2.60238e6 2.9269775e6 1475056 21265 +three_declines_then_success warm measured 994.719298245614 1031.578947368421 0 0 +three_declines_then_success selection_miss measured 71799.0 81649.5 8688 271 +three_declines_then_success invalidated measured 2.588081e6 2.753979e6 1475344 21272 +sixteen_scoped_decliners warm measured 384.7241379310345 440.38916256157637 0 0 +sixteen_scoped_decliners selection_miss measured 70199.0 77199.5 8304 261 +sixteen_scoped_decliners invalidated measured 2.58768e6 2.6627795e6 1474960 21262 +virtual_mapping_abc warm measured 375.6048780487805 417.0682926829268 0 0 +virtual_mapping_abc selection_miss measured 61300.0 62000.0 8304 261 +virtual_mapping_abc invalidated measured 2.61728e6 2.9357275e6 1474960 21262 +buffer_only_native warm measured 7474.75 8300.0 8856 26 +buffer_only_native selection_miss measured 44899.0 48900.0 9880 62 +buffer_only_native invalidated measured 2.60498e6 2.937977e6 1475672 21051 +buffer_only_wrapper warm measured 5633.166666666667 6433.166666666667 768 22 +buffer_only_wrapper selection_miss measured 35000.0 36949.5 1920 58 +buffer_only_wrapper invalidated measured 2.58308e6 2.6519795e6 1467712 21047 +interface_only_native warm measured 21800.0 24500.0 9368 55 +interface_only_native selection_miss measured 58100.0 67999.5 10408 91 +interface_only_native invalidated measured 3.192776e6 3.325924e6 1507208 22091 +array_method_only_native warm measured 8233.333333333334 9100.0 9016 30 +array_method_only_native selection_miss measured 39300.0 42400.0 10056 66 +array_method_only_native invalidated measured 2.55408e6 2.731279e6 1476712 21067 +ndarray_native warm measured 4816.5 5166.666666666667 8888 23 +ndarray_native selection_miss measured 39000.0 41199.5 10872 84 +ndarray_native invalidated measured 2.58278e6 2.6616295e6 1476664 21073 +ndarray_wrapper warm measured 3725.0 4112.5 800 19 +ndarray_wrapper selection_miss measured 35399.0 37300.0 3488 86 +ndarray_wrapper invalidated measured 2.875978e6 3.184225e6 1469280 21075 +two_matching_first_success warm measured 3325.0 3937.5 560 18 +two_matching_first_declines warm measured 4114.285714285715 4571.428571428572 720 24 +two_matching_decline_then_ordinary warm measured 5142.857142857143 5442.714285714285 752 25 diff --git a/benchmark/convert-expanded-final-before-r1-environment.txt b/benchmark/convert-expanded-final-before-r1-environment.txt new file mode 100644 index 000000000..f248d0560 --- /dev/null +++ b/benchmark/convert-expanded-final-before-r1-environment.txt @@ -0,0 +1,10 @@ +Julia: 1.13.2 +Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] +Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python +NumPy: 2.5.4 +BenchmarkTools: 1.8.0 +PythonCall source: /tmp/pythoncall-convert-baseline.HAfFfi/src/PythonCall.jl +New API: false +Convert/pyconvert.jl SHA256: 5509bf4deca224297091884d72a684ead91a2f1b42444c46047f228ff75d4619 +Convert/rules.jl SHA256: 3c1c30262bcc1f2e940d8d64593b4b3c869d2523d0789f7d13da76638db9032c +Wrap/PyArray.jl SHA256: 10e270400fab16e3941fc127021fc4f25a4c3c0a0847b5abd547be125f825d3c diff --git a/benchmark/convert-expanded-final-before-r1.tsv b/benchmark/convert-expanded-final-before-r1.tsv new file mode 100644 index 000000000..30358aebe --- /dev/null +++ b/benchmark/convert-expanded-final-before-r1.tsv @@ -0,0 +1,37 @@ +case mode status min_ns median_ns bytes allocs +single_rule warm measured 393.5273631840796 450.7412935323383 0 0 +single_rule selection_miss measured 26899.0 28200.0 4976 149 +single_rule invalidated measured 27599.0 29199.5 4976 149 +decline_then_success warm measured 547.0534759358288 612.8288770053476 0 0 +decline_then_success selection_miss measured 28100.0 30299.5 5840 174 +decline_then_success invalidated measured 29500.0 30499.0 5840 174 +three_declines_then_success warm measured 883.5901639344262 909.8360655737705 0 0 +three_declines_then_success selection_miss measured 32599.0 34900.0 8752 234 +three_declines_then_success invalidated measured 34200.0 36150.0 8752 234 +sixteen_scoped_decliners warm measured 4000.0 4128.571428571428 0 0 +sixteen_scoped_decliners selection_miss measured 65500.0 76599.0 31344 797 +sixteen_scoped_decliners invalidated measured 75699.0 79249.0 31344 797 +virtual_mapping_abc warm measured 393.995 426.495 0 0 +virtual_mapping_abc selection_miss measured 57399.0 66750.0 18752 539 +virtual_mapping_abc invalidated measured 66000.0 71649.5 18752 539 +buffer_only_native warm measured 6925.0 7500.0 8712 23 +buffer_only_native selection_miss measured 84900.0 106049.5 35784 778 +buffer_only_native invalidated measured 104499.0 112649.5 35784 778 +buffer_only_wrapper warm measured 5433.166666666667 6658.25 640 20 +buffer_only_wrapper selection_miss measured 80600.0 97749.0 26816 757 +buffer_only_wrapper invalidated measured 97500.0 107199.0 26816 757 +interface_only_native warm measured 20800.0 23100.0 9224 52 +interface_only_native selection_miss measured 55699.0 61649.5 15896 244 +interface_only_native invalidated measured 238999.0 272998.0 64232 1579 +array_method_only_native warm measured 7633.333333333333 8400.0 8872 27 +array_method_only_native selection_miss measured 45099.0 49100.0 15544 219 +array_method_only_native invalidated measured 50200.0 51850.0 15544 219 +ndarray_native warm measured 4257.142857142857 4671.428571428572 8744 20 +ndarray_native selection_miss measured 72600.0 85349.0 35208 788 +ndarray_native invalidated measured 85699.0 90299.0 35208 788 +ndarray_wrapper warm measured 3312.5 3537.5 672 17 +ndarray_wrapper selection_miss measured 63399.0 75949.5 28208 803 +ndarray_wrapper invalidated measured 71599.0 78949.5 28208 803 +two_matching_first_success warm unsupported NA NA NA NA +two_matching_first_declines warm unsupported NA NA NA NA +two_matching_decline_then_ordinary warm unsupported NA NA NA NA diff --git a/benchmark/convert-expanded-final-before-r2-environment.txt b/benchmark/convert-expanded-final-before-r2-environment.txt new file mode 100644 index 000000000..f248d0560 --- /dev/null +++ b/benchmark/convert-expanded-final-before-r2-environment.txt @@ -0,0 +1,10 @@ +Julia: 1.13.2 +Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] +Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python +NumPy: 2.5.4 +BenchmarkTools: 1.8.0 +PythonCall source: /tmp/pythoncall-convert-baseline.HAfFfi/src/PythonCall.jl +New API: false +Convert/pyconvert.jl SHA256: 5509bf4deca224297091884d72a684ead91a2f1b42444c46047f228ff75d4619 +Convert/rules.jl SHA256: 3c1c30262bcc1f2e940d8d64593b4b3c869d2523d0789f7d13da76638db9032c +Wrap/PyArray.jl SHA256: 10e270400fab16e3941fc127021fc4f25a4c3c0a0847b5abd547be125f825d3c diff --git a/benchmark/convert-expanded-final-before-r2.tsv b/benchmark/convert-expanded-final-before-r2.tsv new file mode 100644 index 000000000..e383f99b7 --- /dev/null +++ b/benchmark/convert-expanded-final-before-r2.tsv @@ -0,0 +1,37 @@ +case mode status min_ns median_ns bytes allocs +single_rule warm measured 393.495 463.495 0 0 +single_rule selection_miss measured 27100.0 28600.0 4976 149 +single_rule invalidated measured 27799.0 29600.0 4976 149 +decline_then_success warm measured 535.1010638297872 628.1914893617021 0 0 +decline_then_success selection_miss measured 28100.0 30800.0 5840 174 +decline_then_success invalidated measured 30199.0 31150.0 5840 174 +three_declines_then_success warm measured 979.2264150943396 1016.9811320754717 0 0 +three_declines_then_success selection_miss measured 33200.0 35699.0 8752 234 +three_declines_then_success invalidated measured 34799.0 36650.0 8752 234 +sixteen_scoped_decliners warm measured 4100.0 4471.428571428572 0 0 +sixteen_scoped_decliners selection_miss measured 65999.0 75849.5 31344 797 +sixteen_scoped_decliners invalidated measured 76200.0 79150.0 31344 797 +virtual_mapping_abc warm measured 389.5990099009901 400.490099009901 0 0 +virtual_mapping_abc selection_miss measured 58200.0 66999.5 18752 539 +virtual_mapping_abc invalidated measured 65300.0 72249.0 18752 539 +buffer_only_native warm measured 7000.0 7625.0 8712 23 +buffer_only_native selection_miss measured 80999.0 101399.0 35784 778 +buffer_only_native invalidated measured 105599.0 116649.0 35784 778 +buffer_only_wrapper warm measured 5483.333333333333 6500.0 640 20 +buffer_only_wrapper selection_miss measured 75499.0 84949.0 26816 757 +buffer_only_wrapper invalidated measured 78099.0 86049.5 26816 757 +interface_only_native warm measured 21500.0 22400.0 9224 52 +interface_only_native selection_miss measured 68099.0 80549.0 15896 244 +interface_only_native invalidated measured 246598.0 280597.5 64232 1579 +array_method_only_native warm measured 7899.666666666667 8800.0 8872 27 +array_method_only_native selection_miss measured 48100.0 55549.5 15544 219 +array_method_only_native invalidated measured 53500.0 57000.0 15544 219 +ndarray_native warm measured 4799.857142857143 5314.285714285715 8744 20 +ndarray_native selection_miss measured 71399.0 76099.5 35208 788 +ndarray_native invalidated measured 96299.0 103049.5 35208 788 +ndarray_wrapper warm measured 3199.875 3837.375 672 17 +ndarray_wrapper selection_miss measured 70900.0 83499.0 28208 803 +ndarray_wrapper invalidated measured 84099.0 90650.0 28208 803 +two_matching_first_success warm unsupported NA NA NA NA +two_matching_first_declines warm unsupported NA NA NA NA +two_matching_decline_then_ordinary warm unsupported NA NA NA NA diff --git a/benchmark/convert-expanded-final-before-r3-environment.txt b/benchmark/convert-expanded-final-before-r3-environment.txt new file mode 100644 index 000000000..f248d0560 --- /dev/null +++ b/benchmark/convert-expanded-final-before-r3-environment.txt @@ -0,0 +1,10 @@ +Julia: 1.13.2 +Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] +Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python +NumPy: 2.5.4 +BenchmarkTools: 1.8.0 +PythonCall source: /tmp/pythoncall-convert-baseline.HAfFfi/src/PythonCall.jl +New API: false +Convert/pyconvert.jl SHA256: 5509bf4deca224297091884d72a684ead91a2f1b42444c46047f228ff75d4619 +Convert/rules.jl SHA256: 3c1c30262bcc1f2e940d8d64593b4b3c869d2523d0789f7d13da76638db9032c +Wrap/PyArray.jl SHA256: 10e270400fab16e3941fc127021fc4f25a4c3c0a0847b5abd547be125f825d3c diff --git a/benchmark/convert-expanded-final-before-r3.tsv b/benchmark/convert-expanded-final-before-r3.tsv new file mode 100644 index 000000000..583455f22 --- /dev/null +++ b/benchmark/convert-expanded-final-before-r3.tsv @@ -0,0 +1,37 @@ +case mode status min_ns median_ns bytes allocs +single_rule warm measured 384.995 439.995 0 0 +single_rule selection_miss measured 26100.0 28450.0 4976 149 +single_rule invalidated measured 27300.0 28700.0 4976 149 +decline_then_success warm measured 533.6844919786096 644.9144385026738 0 0 +decline_then_success selection_miss measured 27900.0 29949.5 5840 174 +decline_then_success invalidated measured 29600.0 30550.0 5840 174 +three_declines_then_success warm measured 982.0 1027.98 0 0 +three_declines_then_success selection_miss measured 25899.0 27349.5 8752 234 +three_declines_then_success invalidated measured 34599.0 35749.5 8752 234 +sixteen_scoped_decliners warm measured 4071.285714285714 4700.0 0 0 +sixteen_scoped_decliners selection_miss measured 64800.0 74899.5 31344 797 +sixteen_scoped_decliners invalidated measured 74700.0 79050.0 31344 797 +virtual_mapping_abc warm measured 396.5124378109453 443.2786069651741 0 0 +virtual_mapping_abc selection_miss measured 48300.0 55900.0 18752 539 +virtual_mapping_abc invalidated measured 64499.0 69699.5 18752 539 +buffer_only_native warm measured 7225.0 8000.0 8712 23 +buffer_only_native selection_miss measured 87899.0 105749.0 35784 778 +buffer_only_native invalidated measured 100799.0 114299.0 35784 778 +buffer_only_wrapper warm measured 5133.333333333333 5966.666666666667 640 20 +buffer_only_wrapper selection_miss measured 71699.0 83649.0 26816 757 +buffer_only_wrapper invalidated measured 96500.0 106599.0 26816 757 +interface_only_native warm measured 21199.0 22700.0 9224 52 +interface_only_native selection_miss measured 66700.0 77249.5 15896 244 +interface_only_native invalidated measured 248098.0 275248.0 64232 1579 +array_method_only_native warm measured 7266.333333333333 8199.833333333332 8872 27 +array_method_only_native selection_miss measured 44699.0 51799.0 15544 219 +array_method_only_native invalidated measured 51099.0 57050.0 15544 219 +ndarray_native warm measured 4471.428571428572 5157.142857142857 8744 20 +ndarray_native selection_miss measured 71099.0 82699.0 35208 788 +ndarray_native invalidated measured 80199.0 88549.0 35208 788 +ndarray_wrapper warm measured 3125.0 3474.9375 672 17 +ndarray_wrapper selection_miss measured 70500.0 81749.5 28208 803 +ndarray_wrapper invalidated measured 80999.0 87749.5 28208 803 +two_matching_first_success warm unsupported NA NA NA NA +two_matching_first_declines warm unsupported NA NA NA NA +two_matching_decline_then_ordinary warm unsupported NA NA NA NA diff --git a/benchmark/convert-expanded-report.md b/benchmark/convert-expanded-report.md new file mode 100644 index 000000000..cab3f4736 --- /dev/null +++ b/benchmark/convert-expanded-report.md @@ -0,0 +1,147 @@ +# Final rule dispatch, protocols and preferences + +**Current update:** [convert-unwrapped-report.md](convert-unwrapped-report.md) +records the subsequent optimization: all extra Some/reboxing allocations below +are removed, with approximately 2–6% faster array conversions in its direct +before/after experiment. The tables below retain the earlier full original-v1 +comparison, including cold-path measurements. + +These results cover the final working tree, including public source aliases, +built-in shorthand and the numeric-source policy. They supersede the earlier +single-run table. See [convert-report.md](convert-report.md) for environment, +implementation, final validation status and reproduction. + +## Fixtures and method + +The same harness ran on original v1 commit +25f82cc8effbd6c487ddceaffc34aa7cbe86505b and current v1. Three before/after rounds +ran sequentially with the middle round reversed. No tests ran concurrently. +Each process records loaded source paths/hashes and environment versions. + +The buffer-only fixture is array.array('d', ...): it has the C buffer protocol +and none of the array attributes. Assertions verify the first selected converter +is the protocol array converter on both revisions. Interface-only and +__array__-only fixtures lack buffers. Each array has 1,000 elements, and shape, +element type and endpoint values are checked outside timing. + +Synthetic classes exercise one rule, decline/success, three declines/success, +destination scope filtering and virtual collections.abc.Mapping membership. +Eligible counts are checked: 1/2/4 on both revisions; scoped filtering changes +17 callbacks to one eligible callback. There are 27 synthetic/scoped registrations. +Every input is created before timing; requested types remain visible through Val. + +All times are microseconds: median of three trial minima. Warm trials use up to +5,000 samples / one second. Julia allocations exclude Python allocations. Raw +minimum/median data and round ranges are in convert-final-summary.tsv and +convert-expanded-final-{before,after}-r{1,2,3}.tsv. No confidence intervals are claimed. + +## Warm conversion + +| Case | Before us | After us | Change | Before B / allocs | After B / allocs | +| --- | ---: | ---: | ---: | ---: | ---: | +| Single rule | 0.393 | 0.378 | -4.0% | 0 / 0 | 0 / 0 | +| Decline then success | 0.535 | 0.540 | +1.0% | 0 / 0 | 0 / 0 | +| Three declines then success | 0.979 | 0.936 | -4.4% | 0 / 0 | 0 / 0 | +| Sixteen scoped decliners | 4.071 | 0.385 | -90.6% | 0 / 0 | 0 / 0 | +| Virtual Mapping ABC | 0.394 | 0.379 | -3.7% | 0 / 0 | 0 / 0 | +| Buffer-only native | 7.000 | 7.475 | +6.8% | 8712 / 23 | 8856 / 26 | +| Buffer-only wrapper | 5.433 | 5.620 | +3.4% | 640 / 20 | 768 / 22 | +| Interface-only native | 21.199 | 22.600 | +6.6% | 9224 / 52 | 9368 / 55 | +| Array-method-only native | 7.633 | 8.000 | +4.8% | 8872 / 27 | 9016 / 30 | +| ndarray native | 4.471 | 4.816 | +7.7% | 8744 / 20 | 8888 / 23 | +| ndarray wrapper | 3.200 | 3.612 | +12.9% | 672 / 17 | 800 / 19 | + +Scope filtering measures the intended exclusion of sixteen callbacks, rather +than faster execution of the same callback work. + +### Do extra array allocations translate to slower conversion? + +The final end-to-end measurements show modest regressions, with important +variation between rounds/statistics. The following ranges are the lowest/highest +trial minima, while the last columns are medians of the three trial medians: + +| Case | Before minimum range us | After minimum range us | Before p50 us | After p50 us | +| --- | ---: | ---: | ---: | ---: | +| Buffer-only native | 6.925–7.225 | 7.400–7.675 | 7.625 | 8.300 | +| Buffer-only wrapper | 5.133–5.483 | 5.550–5.633 | 6.500 | 6.433 | +| Interface-only native | 20.800–21.500 | 21.800–22.999 | 22.700 | 24.100 | +| Array-method-only native | 7.266–7.900 | 7.933–8.233 | 8.400 | 9.100 | +| ndarray native | 4.257–4.800 | 4.750–4.950 | 5.157 | 5.167 | +| ndarray wrapper | 3.125–3.312 | 3.288–3.725 | 3.538 | 3.925 | + +ndarray wrapping's median latency also rises about 11%; native ndarray median +latency is essentially unchanged despite the worse minimum. Buffer wrapping's +median also does not regress. Therefore the extra allocations do not imply a +fixed slowdown across every workload or statistic. These experiments compare +the whole old/new conversion paths; they cannot assign all timing changes to +allocation alone. + +### Allocation attribution + +Separate warmed Profile.Allocs runs on both revisions identify two extra objects +for wrappers: Some{PyArray{...}} created in pyarray_make/pyconvert_return, and a +boxed PyArray when the result is unwrapped in pyconvert_raw. Native conversion +also creates Some{Vector{...}} in pyconvert_tryconvert, and unwraps the temporary +PyArray through pyconvert_result. These account for the additional object counts. + +The profiles report requested object sizes; BenchmarkTools reports allocator +byte totals. Use the stable measured differences of 128 bytes / two allocations +for wrappers and 144 bytes / three allocations for native arrays. Raw stacks +are in convert-array-allocations-before.txt and -after.txt. No array runtime +optimization was made in this refresh. + +## Selection misses and invalidation + +Cache clearing is BenchmarkTools setup, outside timing, with evals=1. +A selection miss clears only target/context selections and preserves the global +order. Full invalidation also dirties the global order. Old v1 has no equivalent +global DAG rebuild. Timings include converting the fixture. + +Selection-miss trials use up to 200 samples / 0.4 seconds; invalidation trials +use up to 40. Aggregate values again use the median of three trial minima. + +| Case | Selection before us | Selection after us | Invalidated before us | Invalidated after us | +| --- | ---: | ---: | ---: | ---: | +| Single rule | 26.899 | 71.199 | 27.599 | 2588.880 | +| Decline then success | 28.100 | 67.899 | 29.600 | 2602.380 | +| Three declines then success | 32.599 | 62.499 | 34.599 | 2588.081 | +| Sixteen scoped decliners | 65.500 | 70.199 | 75.699 | 2587.680 | +| Virtual Mapping ABC | 57.399 | 71.499 | 65.300 | 2600.080 | +| Buffer-only native | 84.900 | 43.600 | 104.499 | 2608.181 | +| Buffer-only wrapper | 75.499 | 35.000 | 96.500 | 2528.881 | +| Interface-only native | 66.700 | 58.100 | 246.598 | 2890.477 | +| Array-method-only native | 45.099 | 38.999 | 51.099 | 2648.979 | +| ndarray native | 71.399 | 39.000 | 85.699 | 2582.780 | +| ndarray wrapper | 70.500 | 34.300 | 80.999 | 2870.077 | + +Full rebuilding is a real rare-path cost: approximately 1.47 MB / 21,262 +allocations for the single-rule fixture, compared with 4,976 B / 149 before. +Ordinary protocol selection misses generally improve, while simple synthetic +classes regress. No registry-size scaling study was performed. + +## Multiple matching preferences + +Both supplied source names match one controlled class. Its String rule declines +and its Int rule succeeds with 42. The two preference attempts always have +nonempty intersections with Any. Context construction is included in timing. + +| Ordered attempts | After us | B / allocs | +| --- | ---: | ---: | +| Int succeeds before String | 3.375 | 560 / 18 | +| String declines, then Int succeeds | 4.128 | 720 / 24 | +| String/Float64 decline, then ordinary conversion succeeds | 5.143 | 752 / 25 | + +Old v1 is explicitly recorded as unsupported. These scalar fixtures make +fallthrough controllable; they do not recommend narrow scalar preferences. +Additional unmatched/wrapper/nested cases are in convert-dispatch-final.tsv. +Those include deliberate representation/work differences: matching wrapper +preferences avoid copying, whereas an unmatched preference is checked again +by context-propagating child conversions. + +## Reproduction + +Run benchmark/run-convert-final.sh as documented in the main report, then +python3 benchmark/summarize-convert-final.py. For allocation profiles, run +convert-array-allocations.jl with labels before/after in their respective +Julia environments, using the same installed Python. Profiling runs occur +after timing and do not overlap it. diff --git a/benchmark/convert-expanded-unwrapped-after-r1-environment.txt b/benchmark/convert-expanded-unwrapped-after-r1-environment.txt new file mode 100644 index 000000000..224e533e6 --- /dev/null +++ b/benchmark/convert-expanded-unwrapped-after-r1-environment.txt @@ -0,0 +1,10 @@ +Julia: 1.13.2 +Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] +Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python +NumPy: 2.5.4 +BenchmarkTools: 1.8.0 +PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl +New API: true +Convert/pyconvert.jl SHA256: b9ff0cdfadc7561bd9725c0862cdcd0b08ba38958faab6e24053a42241b244ea +Convert/rules.jl SHA256: 2a064304ea9cd4edc2143621ffd0309d5b2a660326e38a6033b7b0ca2a8afc43 +Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a diff --git a/benchmark/convert-expanded-unwrapped-after-r1.tsv b/benchmark/convert-expanded-unwrapped-after-r1.tsv new file mode 100644 index 000000000..638236e41 --- /dev/null +++ b/benchmark/convert-expanded-unwrapped-after-r1.tsv @@ -0,0 +1,15 @@ +case mode status min_ns median_ns bytes allocs +single_rule warm measured 392.5422885572139 465.1741293532338 0 0 +decline_then_success warm measured 547.5989304812834 613.9090909090909 0 0 +three_declines_then_success warm measured 880.7692307692307 1015.4038461538462 0 0 +sixteen_scoped_decliners warm measured 401.5151515151515 438.3888888888889 0 0 +virtual_mapping_abc warm measured 393.0693069306931 450.5 0 0 +buffer_only_native warm measured 6925.0 7875.0 8712 23 +buffer_only_wrapper warm measured 5366.666666666667 6533.333333333333 640 20 +interface_only_native warm measured 22000.0 25500.0 9224 52 +array_method_only_native warm measured 7600.0 8200.0 8872 27 +ndarray_native warm measured 4700.0 5257.142857142857 8744 20 +ndarray_wrapper warm measured 3337.5 3962.5 672 17 +two_matching_first_success warm measured 3562.5 3925.0 560 18 +two_matching_first_declines warm measured 4671.428571428572 5014.285714285715 720 24 +two_matching_decline_then_ordinary warm measured 4657.142857142857 5314.428571428572 752 25 diff --git a/benchmark/convert-expanded-unwrapped-after-r2-environment.txt b/benchmark/convert-expanded-unwrapped-after-r2-environment.txt new file mode 100644 index 000000000..224e533e6 --- /dev/null +++ b/benchmark/convert-expanded-unwrapped-after-r2-environment.txt @@ -0,0 +1,10 @@ +Julia: 1.13.2 +Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] +Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python +NumPy: 2.5.4 +BenchmarkTools: 1.8.0 +PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl +New API: true +Convert/pyconvert.jl SHA256: b9ff0cdfadc7561bd9725c0862cdcd0b08ba38958faab6e24053a42241b244ea +Convert/rules.jl SHA256: 2a064304ea9cd4edc2143621ffd0309d5b2a660326e38a6033b7b0ca2a8afc43 +Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a diff --git a/benchmark/convert-expanded-unwrapped-after-r2.tsv b/benchmark/convert-expanded-unwrapped-after-r2.tsv new file mode 100644 index 000000000..b91d4652f --- /dev/null +++ b/benchmark/convert-expanded-unwrapped-after-r2.tsv @@ -0,0 +1,15 @@ +case mode status min_ns median_ns bytes allocs +single_rule warm measured 382.3529411764706 383.828431372549 0 0 +decline_then_success warm measured 525.7894736842105 567.9 0 0 +three_declines_then_success warm measured 989.1090909090909 1029.1090909090908 0 0 +sixteen_scoped_decliners warm measured 375.3694581280788 395.57142857142856 0 0 +virtual_mapping_abc warm measured 382.9145728643216 438.19095477386935 0 0 +buffer_only_native warm measured 7375.0 8150.0 8712 23 +buffer_only_wrapper warm measured 5250.0 5900.166666666667 640 20 +interface_only_native warm measured 21600.0 22600.0 9224 52 +array_method_only_native warm measured 7867.0 9100.0 8872 27 +ndarray_native warm measured 4585.714285714285 4985.857142857143 8744 20 +ndarray_wrapper warm measured 3287.5 3650.0 672 17 +two_matching_first_success warm measured 3475.0 3662.5 560 18 +two_matching_first_declines warm measured 4400.0 5314.285714285715 720 24 +two_matching_decline_then_ordinary warm measured 4628.571428571428 5443.0 752 25 diff --git a/benchmark/convert-expanded-unwrapped-after-r3-environment.txt b/benchmark/convert-expanded-unwrapped-after-r3-environment.txt new file mode 100644 index 000000000..224e533e6 --- /dev/null +++ b/benchmark/convert-expanded-unwrapped-after-r3-environment.txt @@ -0,0 +1,10 @@ +Julia: 1.13.2 +Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] +Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python +NumPy: 2.5.4 +BenchmarkTools: 1.8.0 +PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl +New API: true +Convert/pyconvert.jl SHA256: b9ff0cdfadc7561bd9725c0862cdcd0b08ba38958faab6e24053a42241b244ea +Convert/rules.jl SHA256: 2a064304ea9cd4edc2143621ffd0309d5b2a660326e38a6033b7b0ca2a8afc43 +Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a diff --git a/benchmark/convert-expanded-unwrapped-after-r3.tsv b/benchmark/convert-expanded-unwrapped-after-r3.tsv new file mode 100644 index 000000000..ae1d39a2e --- /dev/null +++ b/benchmark/convert-expanded-unwrapped-after-r3.tsv @@ -0,0 +1,15 @@ +case mode status min_ns median_ns bytes allocs +single_rule warm measured 386.69950738916253 444.3349753694581 0 0 +decline_then_success warm measured 543.0904255319149 573.4095744680851 0 0 +three_declines_then_success warm measured 964.1509433962265 1028.3207547169811 0 0 +sixteen_scoped_decliners warm measured 377.27272727272725 379.2979797979798 0 0 +virtual_mapping_abc warm measured 379.3103448275862 410.8374384236453 0 0 +buffer_only_native warm measured 7150.0 7600.25 8712 23 +buffer_only_wrapper warm measured 5283.333333333333 5850.0 640 20 +interface_only_native warm measured 21700.0 24600.0 9224 52 +array_method_only_native warm measured 7633.333333333333 8300.0 8872 27 +ndarray_native warm measured 4685.714285714285 5214.285714285715 8744 20 +ndarray_wrapper warm measured 3200.125 3800.0 672 17 +two_matching_first_success warm measured 3500.0 4175.0 560 18 +two_matching_first_declines warm measured 4428.714285714285 5157.285714285715 720 24 +two_matching_decline_then_ordinary warm measured 5214.285714285715 5471.571428571428 752 25 diff --git a/benchmark/convert-expanded-unwrapped-before-r1-environment.txt b/benchmark/convert-expanded-unwrapped-before-r1-environment.txt new file mode 100644 index 000000000..215c3d52a --- /dev/null +++ b/benchmark/convert-expanded-unwrapped-before-r1-environment.txt @@ -0,0 +1,10 @@ +Julia: 1.13.2 +Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] +Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python +NumPy: 2.5.4 +BenchmarkTools: 1.8.0 +PythonCall source: /tmp/pythoncall-some-before.LlDQq5/src/PythonCall.jl +New API: true +Convert/pyconvert.jl SHA256: 7d8337b08370a90127dcc5a9d7b9b79f743ee2998c5ac6154a671725682aad6e +Convert/rules.jl SHA256: d42b0af459b0243412a5f9befa62caccc5039a8e0561be414cf9f941a6c328e4 +Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a diff --git a/benchmark/convert-expanded-unwrapped-before-r1.tsv b/benchmark/convert-expanded-unwrapped-before-r1.tsv new file mode 100644 index 000000000..7d83b4ce7 --- /dev/null +++ b/benchmark/convert-expanded-unwrapped-before-r1.tsv @@ -0,0 +1,15 @@ +case mode status min_ns median_ns bytes allocs +single_rule warm measured 413.0 473.005 0 0 +decline_then_success warm measured 557.6086956521739 604.8967391304348 0 0 +three_declines_then_success warm measured 930.5555555555555 1072.2222222222222 0 0 +sixteen_scoped_decliners warm measured 460.30150753768845 475.3819095477387 0 0 +virtual_mapping_abc warm measured 411.6751269035533 414.21319796954316 0 0 +buffer_only_native warm measured 6950.0 7500.25 8856 26 +buffer_only_wrapper warm measured 5416.666666666667 6166.833333333333 768 22 +interface_only_native warm measured 23300.0 25000.0 9368 55 +array_method_only_native warm measured 8366.666666666666 9133.666666666666 9016 30 +ndarray_native warm measured 4866.666666666667 5333.333333333333 8888 23 +ndarray_wrapper warm measured 3550.0 3862.625 800 19 +two_matching_first_success warm measured 3362.5 3775.0 560 18 +two_matching_first_declines warm measured 4200.0 5057.142857142857 720 24 +two_matching_decline_then_ordinary warm measured 4528.571428571428 4928.571428571428 752 25 diff --git a/benchmark/convert-expanded-unwrapped-before-r2-environment.txt b/benchmark/convert-expanded-unwrapped-before-r2-environment.txt new file mode 100644 index 000000000..215c3d52a --- /dev/null +++ b/benchmark/convert-expanded-unwrapped-before-r2-environment.txt @@ -0,0 +1,10 @@ +Julia: 1.13.2 +Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] +Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python +NumPy: 2.5.4 +BenchmarkTools: 1.8.0 +PythonCall source: /tmp/pythoncall-some-before.LlDQq5/src/PythonCall.jl +New API: true +Convert/pyconvert.jl SHA256: 7d8337b08370a90127dcc5a9d7b9b79f743ee2998c5ac6154a671725682aad6e +Convert/rules.jl SHA256: d42b0af459b0243412a5f9befa62caccc5039a8e0561be414cf9f941a6c328e4 +Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a diff --git a/benchmark/convert-expanded-unwrapped-before-r2.tsv b/benchmark/convert-expanded-unwrapped-before-r2.tsv new file mode 100644 index 000000000..01c1c47e1 --- /dev/null +++ b/benchmark/convert-expanded-unwrapped-before-r2.tsv @@ -0,0 +1,15 @@ +case mode status min_ns median_ns bytes allocs +single_rule warm measured 393.10837438423647 477.8374384236453 0 0 +decline_then_success warm measured 550.8108108108108 649.7351351351351 0 0 +three_declines_then_success warm measured 875.4716981132076 905.6792452830189 0 0 +sixteen_scoped_decliners warm measured 402.5 463.505 0 0 +virtual_mapping_abc warm measured 448.9949494949495 464.14141414141415 0 0 +buffer_only_native warm measured 7550.0 8450.0 8856 26 +buffer_only_wrapper warm measured 5583.5 6166.833333333333 768 22 +interface_only_native warm measured 22100.0 27700.0 9368 55 +array_method_only_native warm measured 8133.333333333333 9033.333333333334 9016 30 +ndarray_native warm measured 4666.666666666667 5416.666666666667 8888 23 +ndarray_wrapper warm measured 3325.0 3575.125 800 19 +two_matching_first_success warm measured 3725.0 4025.0 560 18 +two_matching_first_declines warm measured 4528.571428571428 4900.142857142857 720 24 +two_matching_decline_then_ordinary warm measured 4528.571428571428 4728.714285714285 752 25 diff --git a/benchmark/convert-expanded-unwrapped-before-r3-environment.txt b/benchmark/convert-expanded-unwrapped-before-r3-environment.txt new file mode 100644 index 000000000..215c3d52a --- /dev/null +++ b/benchmark/convert-expanded-unwrapped-before-r3-environment.txt @@ -0,0 +1,10 @@ +Julia: 1.13.2 +Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] +Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python +NumPy: 2.5.4 +BenchmarkTools: 1.8.0 +PythonCall source: /tmp/pythoncall-some-before.LlDQq5/src/PythonCall.jl +New API: true +Convert/pyconvert.jl SHA256: 7d8337b08370a90127dcc5a9d7b9b79f743ee2998c5ac6154a671725682aad6e +Convert/rules.jl SHA256: d42b0af459b0243412a5f9befa62caccc5039a8e0561be414cf9f941a6c328e4 +Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a diff --git a/benchmark/convert-expanded-unwrapped-before-r3.tsv b/benchmark/convert-expanded-unwrapped-before-r3.tsv new file mode 100644 index 000000000..a1997a548 --- /dev/null +++ b/benchmark/convert-expanded-unwrapped-before-r3.tsv @@ -0,0 +1,15 @@ +case mode status min_ns median_ns bytes allocs +single_rule warm measured 405.5 465.005 0 0 +decline_then_success warm measured 560.9679144385027 642.2513368983957 0 0 +three_declines_then_success warm measured 865.4545454545455 1016.3636363636364 0 0 +sixteen_scoped_decliners warm measured 405.97512437810946 452.7412935323383 0 0 +virtual_mapping_abc warm measured 405.55555555555554 465.66161616161617 0 0 +buffer_only_native warm measured 7325.0 8325.0 8856 26 +buffer_only_wrapper warm measured 5680.0 6620.0 768 22 +interface_only_native warm measured 22200.0 23101.0 9368 55 +array_method_only_native warm measured 8033.333333333333 9167.0 9016 30 +ndarray_native warm measured 4983.333333333333 5683.333333333333 8888 23 +ndarray_wrapper warm measured 3387.5 3950.125 800 19 +two_matching_first_success warm measured 3437.5 3850.0 560 18 +two_matching_first_declines warm measured 4228.571428571428 5242.857142857143 720 24 +two_matching_decline_then_ordinary warm measured 4528.571428571428 4671.428571428572 752 25 diff --git a/benchmark/convert-expanded.jl b/benchmark/convert-expanded.jl new file mode 100644 index 000000000..d7a30e8b7 --- /dev/null +++ b/benchmark/convert-expanded.jl @@ -0,0 +1,184 @@ +# Shared harness for the pre-redesign revision and current v1. +# julia --project=benchmark benchmark/convert-expanded.jl after +# Optional second argument "warm" skips unchanged cold-path experiments. +using PythonCall, BenchmarkTools, SHA +const ExpandedConvert = PythonCall.Convert +const EXPANDED_NEW_API = isdefined(PythonCall, :PyConvertContext) + +expanded_decline1(T,x) = ExpandedConvert.pyconvert_unconverted() +expanded_decline2(T,x) = ExpandedConvert.pyconvert_unconverted() +expanded_decline3(T,x) = ExpandedConvert.pyconvert_unconverted() +expanded_success(T,x) = ExpandedConvert.pyconvert_return(42) +struct ExpandedDestination{I} end +struct ExpandedScopedDecliner{I} <: Function end +(::ExpandedScopedDecliner)(T,x) = ExpandedConvert.pyconvert_unconverted() + +function expanded_register(source,T,f;scope=T) + if EXPANDED_NEW_API + pyconvert_add_rule(source,T,f;scope) + else + pyconvert_add_rule(source,T,f) + end +end +expanded_value(::Val{T},x) where T = pyconvert(T,x,nothing) +function expanded_case(name,::Type{T},x,valid) where T + tag=Val(T) + (;name, target=T, run=()->expanded_value(tag,x), valid) +end +function expanded_cache(T) + if EXPANDED_NEW_API + ExpandedConvert.pyconvert_rules_cache(typeof(PyConvertContext()),T) + else + ExpandedConvert.pyconvert_rules_cache(T) + end +end +function expanded_invalidate!() + if EXPANDED_NEW_API + ExpandedConvert.pyconvert_invalidate!() + else + foreach(empty!,values(ExpandedConvert.PYCONVERT_RULES_CACHE)) + end +end + +label=isempty(ARGS) ? "after" : first(ARGS) +warm_only=length(ARGS)>=2 && ARGS[2]=="warm" +ns=pyimport("types").ModuleType("convert_expanded_benchmark") +pyimport("sys").modules["convert_expanded_benchmark"]=ns +pyexec(""" +import collections.abc +import array +import numpy +class Success: pass +class Declines: pass +class ThreeDeclines: pass +class Scoped: pass +class Preference: pass +class VirtualMapping: pass +collections.abc.Mapping.register(VirtualMapping) +class InterfaceOnly: + def __init__(self, owner): self.owner = owner + @property + def __array_interface__(self): return self.owner.__array_interface__ +class ArrayOnly: + def __init__(self, owner): self.owner = owner + def __array__(self): return self.owner +""",ns.__dict__) +prefix="convert_expanded_benchmark:" +expanded_register(prefix*"Success",Int,expanded_success;scope=Any) +expanded_register(prefix*"Declines",Int,expanded_decline1;scope=Any) +expanded_register(prefix*"Declines",Int,expanded_success;scope=Any) +for f in (expanded_decline1,expanded_decline2,expanded_decline3,expanded_success) + expanded_register(prefix*"ThreeDeclines",Int,f;scope=Any) +end +for i=1:16 + # These rules legitimately decline for this value. Old v1 has no scope + # filtering and must try them; the redesign excludes their owned scopes. + expanded_register(prefix*"Scoped",Any,ExpandedScopedDecliner{i}();scope=ExpandedDestination{i}) +end +expanded_register(prefix*"Scoped",Int,expanded_success;scope=Any) +expanded_register(prefix*"Preference",String,expanded_decline1;scope=Any) +expanded_register(prefix*"Preference",Int,expanded_success;scope=Any) +expanded_register("collections.abc:Mapping",Int,expanded_success) + +buffer=ns.array.array("d",pylist(1:1000)) +owner=ns.numpy.arange(1000) +interface=ns.InterfaceOnly(owner) +arrayonly=ns.ArrayOnly(owner) +@assert PythonCall.C.PyType_CheckBuffer(pytype(buffer)) +@assert !any(pyhasattr(pytype(buffer),a) for a in ("__array_struct__","__array_interface__","__array__")) +@assert !PythonCall.C.PyType_CheckBuffer(pytype(interface)) +@assert !PythonCall.C.PyType_CheckBuffer(pytype(arrayonly)) +if EXPANDED_NEW_API + eligible=filter(r->r.eligible,pyconvert_rules(Array,buffer)) + @assert first(eligible).source=="" +else + eligible=filter(r->typeintersect(r.type,Array)!==Union{}, + ExpandedConvert._pyconvert_get_rules(pytype(buffer))) + @assert first(eligible).func===PythonCall.Wrap.pyconvert_rule_array +end +validint=x->x===42 +validarray=x->x isa Array && size(x)==(1000,) && eltype(x)===Int64 && first(x)==0 && last(x)==999 +validbuffer=x->x isa Array && size(x)==(1000,) && eltype(x)===Float64 && first(x)==1.0 && last(x)==1000.0 +validwrapper=x->x isa PyArray && size(x)==(1000,) && first(x)==0 && last(x)==999 +validbufferwrapper=x->x isa PyArray && size(x)==(1000,) && first(x)==1.0 && last(x)==1000.0 +cases=[ + expanded_case("single_rule",Int,ns.Success(),validint), + expanded_case("decline_then_success",Int,ns.Declines(),validint), + expanded_case("three_declines_then_success",Int,ns.ThreeDeclines(),validint), + expanded_case("sixteen_scoped_decliners",Int,ns.Scoped(),validint), + expanded_case("virtual_mapping_abc",Int,ns.VirtualMapping(),validint), + expanded_case("buffer_only_native",Array,buffer,validbuffer), + expanded_case("buffer_only_wrapper",PyArray,buffer,validbufferwrapper), + expanded_case("interface_only_native",Array,interface,validarray), + expanded_case("array_method_only_native",Array,arrayonly,validarray), + expanded_case("ndarray_native",Array,owner,validarray), + expanded_case("ndarray_wrapper",PyArray,owner,validwrapper), +] +# Verify the dispatch fixtures themselves, outside the measured regions. +for (i,expected) in enumerate(EXPANDED_NEW_API ? (1,2,4,1) : (1,2,4,17)) + case=cases[i] + # The first fixtures are distinct Python classes, each with the indicated + # number of eligible rules. This also detects accidental rule deduplication. + t=(ns.Success,ns.Declines,ns.ThreeDeclines,ns.Scoped)[i] + if EXPANDED_NEW_API + @assert count(r->r.eligible,pyconvert_rules(Int,t()))==expected case.name + else + @assert length(ExpandedConvert.pyconvert_get_rules(Int,t))==expected case.name + end +end +preference_names=("two_matching_first_success","two_matching_first_declines", + "two_matching_decline_then_ordinary") +preference_cases=if EXPANDED_NEW_API + x=ns.Preference() + source=prefix*"Preference" + [(;name=preference_names[1],run=()->pyconvert(Any,x;prefer=(source=>Int,source=>String))), + (;name=preference_names[2],run=()->pyconvert(Any,x;prefer=(source=>String,source=>Int))), + (;name=preference_names[3],run=()->pyconvert(Any,x;prefer=(source=>String,source=>Float64)))] +else + [] +end + +open(joinpath(@__DIR__,"convert-expanded-$label.tsv"),"w") do io + println(io,"case\tmode\tstatus\tmin_ns\tmedian_ns\tbytes\tallocs") + for case in cases + f=case.run + @assert case.valid(f()) case.name + cache=expanded_cache(case.target) + for mode in (warm_only ? ("warm",) : ("warm","selection_miss","invalidated")) + trial=if mode=="warm" + @benchmark $f() seconds=1.0 samples=5000 + elseif mode=="selection_miss" + @benchmark $f() setup=(empty!($cache)) seconds=0.4 samples=200 evals=1 + else + @benchmark $f() setup=(expanded_invalidate!()) seconds=0.4 samples=40 evals=1 + end + m,d=minimum(trial),median(trial) + println(io,"$(case.name)\t$mode\tmeasured\t$(m.time)\t$(d.time)\t$(m.memory)\t$(m.allocs)") + end + flush(io) + end + for case in preference_cases + f=case.run + @assert f()===42 case.name + trial=@benchmark $f() seconds=1.0 samples=5000 + m,d=minimum(trial),median(trial) + println(io,"$(case.name)\twarm\tmeasured\t$(m.time)\t$(d.time)\t$(m.memory)\t$(m.allocs)") + end + if !EXPANDED_NEW_API + for name in preference_names + println(io,"$name\twarm\tunsupported\tNA\tNA\tNA\tNA") + end + end +end +open(joinpath(@__DIR__,"convert-expanded-$label-environment.txt"),"w") do io + println(io,"Julia: ",VERSION) + println(io,"Python: ",pyconvert(String,pyimport("sys").version)) + println(io,"Python executable: ",pyconvert(String,pyimport("sys").executable)) + println(io,"NumPy: ",pyconvert(String,ns.numpy.__version__)) + println(io,"BenchmarkTools: ",pkgversion(BenchmarkTools)) + println(io,"PythonCall source: ",pathof(PythonCall)) + println(io,"New API: ",EXPANDED_NEW_API) + for file in ("Convert/pyconvert.jl","Convert/rules.jl","Wrap/PyArray.jl") + println(io,file," SHA256: ",bytes2hex(sha256(read(joinpath(dirname(pathof(PythonCall)),file))))) + end +end diff --git a/benchmark/convert-final-after-r1-environment.txt b/benchmark/convert-final-after-r1-environment.txt new file mode 100644 index 000000000..0f1136c17 --- /dev/null +++ b/benchmark/convert-final-after-r1-environment.txt @@ -0,0 +1,30 @@ +Julia: 1.13.2 +Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] +Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python +BenchmarkTools: 1.8.0 +PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl +New API: true +Convert/pyconvert.jl SHA256: 7d8337b08370a90127dcc5a9d7b9b79f743ee2998c5ac6154a671725682aad6e +Convert/rules.jl SHA256: d42b0af459b0243412a5f9befa62caccc5039a8e0561be414cf9f941a6c328e4 +Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a +int result type: Int64 +integer result type: Int64 +bigint result type: BigInt +float result type: Float64 +bool result type: Bool +string result type: String +none result type: Nothing +failure result type: Nothing +list10 result type: Vector{Int64} +list10000 result type: Vector{Int64} +list10000_concrete result type: Vector{Int64} +mixed_numeric result type: Vector{Real} +heterogeneous result type: Vector{Any} +nested_concrete result type: Vector{Vector{Int64}} +nested_any result type: Vector{Vector{Int64}} +dict result type: Dict{String, Real} +dict_concrete result type: Dict{String, Float64} +empty_list result type: Vector{Any} +empty_dict result type: Dict{Any, Any} +wrapper result type: PyList{Any} +iterator result type: PyIterable{Any} diff --git a/benchmark/convert-final-after-r1.tsv b/benchmark/convert-final-after-r1.tsv new file mode 100644 index 000000000..438123c80 --- /dev/null +++ b/benchmark/convert-final-after-r1.tsv @@ -0,0 +1,30 @@ +case mode min_ns median_ns bytes allocs +int typed 240.43341404358353 275.180387409201 0 0 +int runtime_target 386.1857142857143 412.37619047619046 16 1 +integer typed 241.56532066508314 242.51543942992873 0 0 +integer runtime_target 359.70388349514565 382.0388349514563 0 0 +bigint typed 943.4347826086956 969.5652173913044 216 7 +bigint runtime_target 1130.0 1189.9 216 7 +float typed 239.75061728395062 240.49135802469135 0 0 +float runtime_target 361.7177033492823 403.3492822966507 16 1 +bool typed 247.27507163323781 260.45558739255017 0 0 +bool runtime_target 366.82211538461536 378.3605769230769 0 0 +string typed 345.8287037037037 397.2175925925926 48 2 +string runtime_target 452.79187817258884 525.8832487309645 48 2 +none typed 230.02421307506054 263.43825665859566 0 0 +none runtime_target 370.04347826086956 422.7004830917874 0 0 +failure typed 230.9630681818182 264.20170454545456 0 0 +failure runtime_target 329.64159292035396 334.9513274336283 0 0 +list10 typed 7439.8 7800.0 720 18 +list10000 typed 4.852463e6 5.23921e6 513880 19508 +list10000_concrete typed 4.122169e6 4.4618665e6 362024 10018 +mixed_numeric typed 3799.875 3912.375 352 13 +heterogeneous typed 4785.571428571428 5114.285714285715 384 14 +nested_concrete typed 7060.0 7820.0 768 29 +nested_any typed 9399.0 9900.0 864 32 +dict typed 7079.8 7560.0 1280 24 +dict_concrete typed 3750.0 3837.5 672 16 +empty_list typed 1139.9 1190.0 112 5 +empty_dict typed 1129.9 1180.0 208 5 +wrapper typed 389.1039603960396 433.16831683168317 16 1 +iterator typed 385.56716417910445 397.5124378109453 16 1 diff --git a/benchmark/convert-final-after-r2-environment.txt b/benchmark/convert-final-after-r2-environment.txt new file mode 100644 index 000000000..0f1136c17 --- /dev/null +++ b/benchmark/convert-final-after-r2-environment.txt @@ -0,0 +1,30 @@ +Julia: 1.13.2 +Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] +Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python +BenchmarkTools: 1.8.0 +PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl +New API: true +Convert/pyconvert.jl SHA256: 7d8337b08370a90127dcc5a9d7b9b79f743ee2998c5ac6154a671725682aad6e +Convert/rules.jl SHA256: d42b0af459b0243412a5f9befa62caccc5039a8e0561be414cf9f941a6c328e4 +Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a +int result type: Int64 +integer result type: Int64 +bigint result type: BigInt +float result type: Float64 +bool result type: Bool +string result type: String +none result type: Nothing +failure result type: Nothing +list10 result type: Vector{Int64} +list10000 result type: Vector{Int64} +list10000_concrete result type: Vector{Int64} +mixed_numeric result type: Vector{Real} +heterogeneous result type: Vector{Any} +nested_concrete result type: Vector{Vector{Int64}} +nested_any result type: Vector{Vector{Int64}} +dict result type: Dict{String, Real} +dict_concrete result type: Dict{String, Float64} +empty_list result type: Vector{Any} +empty_dict result type: Dict{Any, Any} +wrapper result type: PyList{Any} +iterator result type: PyIterable{Any} diff --git a/benchmark/convert-final-after-r2.tsv b/benchmark/convert-final-after-r2.tsv new file mode 100644 index 000000000..55486ff0b --- /dev/null +++ b/benchmark/convert-final-after-r2.tsv @@ -0,0 +1,30 @@ +case mode min_ns median_ns bytes allocs +int typed 249.74102564102563 286.66410256410256 0 0 +int runtime_target 360.4714285714286 391.9047619047619 16 1 +integer typed 246.1164383561644 268.0342465753425 0 0 +integer runtime_target 370.04347826086956 401.44444444444446 0 0 +bigint typed 970.0 1060.0 216 7 +bigint runtime_target 1220.0 1340.0 216 7 +float typed 269.0048426150121 285.22760290556903 0 0 +float runtime_target 371.14903846153845 403.84134615384613 16 1 +bool typed 253.98670212765958 291.88563829787233 0 0 +bool runtime_target 385.2167487684729 387.192118226601 0 0 +string typed 309.0085836909871 363.9442060085837 48 2 +string runtime_target 425.6281407035176 431.15577889447235 48 2 +none typed 230.1076923076923 264.3934065934066 0 0 +none runtime_target 354.24528301886795 383.48820754716985 0 0 +failure typed 232.16333333333333 257.99833333333333 0 0 +failure runtime_target 371.6849315068493 384.013698630137 0 0 +list10 typed 6759.8 7340.0 720 18 +list10000 typed 4.821463e6 5.093261e6 513880 19508 +list10000_concrete typed 4.122068e6 4.728164e6 362024 10018 +mixed_numeric typed 3774.875 3875.0 352 13 +heterogeneous typed 4899.857142857143 5214.285714285715 384 14 +nested_concrete typed 7324.75 7900.0 768 29 +nested_any typed 10700.0 11300.0 864 32 +dict typed 6700.0 6900.0 1280 24 +dict_concrete typed 3662.375 4237.5 672 16 +empty_list typed 1290.0 1350.0 112 5 +empty_dict typed 1009.0 1172.7272727272727 208 5 +wrapper typed 387.495 398.995 16 1 +iterator typed 394.5273631840796 428.3532338308458 16 1 diff --git a/benchmark/convert-final-after-r3-environment.txt b/benchmark/convert-final-after-r3-environment.txt new file mode 100644 index 000000000..0f1136c17 --- /dev/null +++ b/benchmark/convert-final-after-r3-environment.txt @@ -0,0 +1,30 @@ +Julia: 1.13.2 +Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] +Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python +BenchmarkTools: 1.8.0 +PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl +New API: true +Convert/pyconvert.jl SHA256: 7d8337b08370a90127dcc5a9d7b9b79f743ee2998c5ac6154a671725682aad6e +Convert/rules.jl SHA256: d42b0af459b0243412a5f9befa62caccc5039a8e0561be414cf9f941a6c328e4 +Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a +int result type: Int64 +integer result type: Int64 +bigint result type: BigInt +float result type: Float64 +bool result type: Bool +string result type: String +none result type: Nothing +failure result type: Nothing +list10 result type: Vector{Int64} +list10000 result type: Vector{Int64} +list10000_concrete result type: Vector{Int64} +mixed_numeric result type: Vector{Real} +heterogeneous result type: Vector{Any} +nested_concrete result type: Vector{Vector{Int64}} +nested_any result type: Vector{Vector{Int64}} +dict result type: Dict{String, Real} +dict_concrete result type: Dict{String, Float64} +empty_list result type: Vector{Any} +empty_dict result type: Dict{Any, Any} +wrapper result type: PyList{Any} +iterator result type: PyIterable{Any} diff --git a/benchmark/convert-final-after-r3.tsv b/benchmark/convert-final-after-r3.tsv new file mode 100644 index 000000000..b5c80a00e --- /dev/null +++ b/benchmark/convert-final-after-r3.tsv @@ -0,0 +1,30 @@ +case mode min_ns median_ns bytes allocs +int typed 234.70319634703196 254.10730593607306 0 0 +int runtime_target 351.41037735849056 414.14622641509436 16 1 +integer typed 239.5 266.2955801104972 0 0 +integer runtime_target 360.7607655502392 373.20095693779905 0 0 +bigint typed 1100.0 1190.0 216 7 +bigint runtime_target 1169.9 1310.0 216 7 +float typed 235.8646080760095 242.27790973871734 0 0 +float runtime_target 354.32211538461536 419.22596153846155 16 1 +bool typed 253.98936170212767 291.48670212765956 0 0 +bool runtime_target 368.9271844660194 371.84466019417476 0 0 +string typed 311.42448979591836 377.1387755102041 48 2 +string runtime_target 428.63819095477385 491.45226130653265 48 2 +none typed 226.48173515981736 266.43607305936075 0 0 +none runtime_target 355.9194312796209 418.0047393364929 0 0 +failure typed 254.54261363636363 270.45170454545456 0 0 +failure runtime_target 329.2237442922374 341.0913242009132 0 0 +list10 typed 6440.0 7660.0 720 18 +list10000 typed 4.650965e6 5.387959e6 513880 19508 +list10000_concrete typed 4.058069e6 4.295168e6 362024 10018 +mixed_numeric typed 3837.375 4400.0 352 13 +heterogeneous typed 4771.428571428572 5057.142857142857 384 14 +nested_concrete typed 6880.0 7400.0 768 29 +nested_any typed 9500.0 10600.0 864 32 +dict typed 6660.0 6820.0 1280 24 +dict_concrete typed 3900.0 4312.5 672 16 +empty_list typed 1130.0 1180.0 112 5 +empty_dict typed 1099.9 1210.0 208 5 +wrapper typed 386.63366336633663 407.4207920792079 16 1 +iterator typed 388.6089108910891 431.6831683168317 16 1 diff --git a/benchmark/convert-final-before-r1-environment.txt b/benchmark/convert-final-before-r1-environment.txt new file mode 100644 index 000000000..781de5898 --- /dev/null +++ b/benchmark/convert-final-before-r1-environment.txt @@ -0,0 +1,30 @@ +Julia: 1.13.2 +Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] +Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python +BenchmarkTools: 1.8.0 +PythonCall source: /tmp/pythoncall-convert-baseline.HAfFfi/src/PythonCall.jl +New API: false +Convert/pyconvert.jl SHA256: 5509bf4deca224297091884d72a684ead91a2f1b42444c46047f228ff75d4619 +Convert/rules.jl SHA256: 3c1c30262bcc1f2e940d8d64593b4b3c869d2523d0789f7d13da76638db9032c +Wrap/PyArray.jl SHA256: 10e270400fab16e3941fc127021fc4f25a4c3c0a0847b5abd547be125f825d3c +int result type: Int64 +integer result type: Int64 +bigint result type: BigInt +float result type: Float64 +bool result type: Bool +string result type: String +none result type: Nothing +failure result type: Nothing +list10 result type: Vector{Int64} +list10000 result type: Vector{Int64} +list10000_concrete result type: Vector{Int64} +mixed_numeric result type: Vector{Float64} +heterogeneous result type: Vector{Any} +nested_concrete result type: Vector{Vector{Int64}} +nested_any result type: PyList{Any} +dict result type: Dict{String, Float64} +dict_concrete result type: Dict{String, Float64} +empty_list result type: Vector{Union{}} +empty_dict result type: Dict{Union{}, Union{}} +wrapper result type: PyList{Any} +iterator result type: PyIterable{Any} diff --git a/benchmark/convert-final-before-r1.tsv b/benchmark/convert-final-before-r1.tsv new file mode 100644 index 000000000..22e3d8e2e --- /dev/null +++ b/benchmark/convert-final-before-r1.tsv @@ -0,0 +1,30 @@ +case mode min_ns median_ns bytes allocs +int typed 228.7648401826484 241.32191780821918 0 0 +int runtime_target 339.4319248826291 359.61971830985914 16 1 +integer typed 590.2119565217391 610.320652173913 0 0 +integer runtime_target 716.6597222222222 774.9930555555555 0 0 +bigint typed 977.2727272727273 1027.2727272727273 216 7 +bigint runtime_target 1120.0 1190.0 216 7 +float typed 239.99764705882353 253.88 0 0 +float runtime_target 350.719806763285 361.8357487922705 16 1 +bool typed 232.47058823529412 258.11764705882354 0 0 +bool runtime_target 349.0607476635514 369.1542056074766 0 0 +string typed 302.6988416988417 336.6756756756757 48 2 +string runtime_target 409.5427135678392 427.1356783919598 48 2 +none typed 212.14107142857142 217.85535714285714 0 0 +none runtime_target 317.69135802469134 326.7489711934156 0 0 +failure typed 243.0109589041096 263.56164383561645 0 0 +failure runtime_target 371.8398058252427 393.20388349514565 0 0 +list10 typed 9100.0 9300.0 704 17 +list10000 typed 7.292249e6 8.0350435e6 513864 19507 +list10000_concrete typed 3.848273e6 4.20647e6 362008 10017 +mixed_numeric typed 4471.428571428572 4800.0 320 11 +heterogeneous typed 5766.666666666667 6150.0 368 13 +nested_concrete typed 7424.75 7725.0 720 26 +nested_any typed 400.4925373134328 435.32338308457713 16 1 +dict typed 7025.0 7250.0 1248 22 +dict_concrete typed 3237.5 3550.0 656 15 +empty_list typed 1199.9 1220.0 64 3 +empty_dict typed 1053.8461538461538 1100.0 112 3 +wrapper typed 383.5771144278607 395.0199004975124 16 1 +iterator typed 390.5422885572139 401.4875621890547 16 1 diff --git a/benchmark/convert-final-before-r2-environment.txt b/benchmark/convert-final-before-r2-environment.txt new file mode 100644 index 000000000..781de5898 --- /dev/null +++ b/benchmark/convert-final-before-r2-environment.txt @@ -0,0 +1,30 @@ +Julia: 1.13.2 +Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] +Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python +BenchmarkTools: 1.8.0 +PythonCall source: /tmp/pythoncall-convert-baseline.HAfFfi/src/PythonCall.jl +New API: false +Convert/pyconvert.jl SHA256: 5509bf4deca224297091884d72a684ead91a2f1b42444c46047f228ff75d4619 +Convert/rules.jl SHA256: 3c1c30262bcc1f2e940d8d64593b4b3c869d2523d0789f7d13da76638db9032c +Wrap/PyArray.jl SHA256: 10e270400fab16e3941fc127021fc4f25a4c3c0a0847b5abd547be125f825d3c +int result type: Int64 +integer result type: Int64 +bigint result type: BigInt +float result type: Float64 +bool result type: Bool +string result type: String +none result type: Nothing +failure result type: Nothing +list10 result type: Vector{Int64} +list10000 result type: Vector{Int64} +list10000_concrete result type: Vector{Int64} +mixed_numeric result type: Vector{Float64} +heterogeneous result type: Vector{Any} +nested_concrete result type: Vector{Vector{Int64}} +nested_any result type: PyList{Any} +dict result type: Dict{String, Float64} +dict_concrete result type: Dict{String, Float64} +empty_list result type: Vector{Union{}} +empty_dict result type: Dict{Union{}, Union{}} +wrapper result type: PyList{Any} +iterator result type: PyIterable{Any} diff --git a/benchmark/convert-final-before-r2.tsv b/benchmark/convert-final-before-r2.tsv new file mode 100644 index 000000000..01e8bdb7b --- /dev/null +++ b/benchmark/convert-final-before-r2.tsv @@ -0,0 +1,30 @@ +case mode min_ns median_ns bytes allocs +int typed 219.510162601626 244.71341463414635 0 0 +int runtime_target 341.0913242009132 398.63013698630135 16 1 +integer typed 625.5380434782609 662.4945652173913 0 0 +integer runtime_target 692.8967741935484 777.4129032258064 0 0 +bigint typed 956.25 1006.1875 216 7 +bigint runtime_target 1139.9 1300.0 216 7 +float typed 255.24885844748857 270.7739726027397 0 0 +float runtime_target 353.91244239631334 407.8294930875576 16 1 +bool typed 229.53892215568862 255.4870259481038 0 0 +bool runtime_target 329.27477477477476 356.7522522522523 0 0 +string typed 293.1123188405797 344.92753623188406 48 2 +string runtime_target 404.495 417.0 48 2 +none typed 209.165 219.99833333333333 0 0 +none runtime_target 321.69787234042553 368.51063829787233 0 0 +failure typed 229.28496042216358 241.68601583113457 0 0 +failure runtime_target 336.40552995391704 346.5437788018433 0 0 +list10 typed 9899.0 10600.0 704 17 +list10000 typed 7.243345e6 7.9604895e6 513864 19507 +list10000_concrete typed 3.91897e6 4.278517e6 362008 10017 +mixed_numeric typed 4371.285714285715 4685.714285714285 320 11 +heterogeneous typed 5466.5 6150.0 368 13 +nested_concrete typed 7974.75 8550.0 720 26 +nested_any typed 389.6502463054187 446.30049261083747 16 1 +dict typed 7424.75 8024.75 1248 22 +dict_concrete typed 3212.5 3387.5 656 15 +empty_list typed 1289.9 1310.0 64 3 +empty_dict typed 970.5294117647059 988.2352941176471 112 3 +wrapper typed 377.0682926829268 421.45853658536583 16 1 +iterator typed 389.6502463054187 402.95073891625617 16 1 diff --git a/benchmark/convert-final-before-r3-environment.txt b/benchmark/convert-final-before-r3-environment.txt new file mode 100644 index 000000000..781de5898 --- /dev/null +++ b/benchmark/convert-final-before-r3-environment.txt @@ -0,0 +1,30 @@ +Julia: 1.13.2 +Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] +Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python +BenchmarkTools: 1.8.0 +PythonCall source: /tmp/pythoncall-convert-baseline.HAfFfi/src/PythonCall.jl +New API: false +Convert/pyconvert.jl SHA256: 5509bf4deca224297091884d72a684ead91a2f1b42444c46047f228ff75d4619 +Convert/rules.jl SHA256: 3c1c30262bcc1f2e940d8d64593b4b3c869d2523d0789f7d13da76638db9032c +Wrap/PyArray.jl SHA256: 10e270400fab16e3941fc127021fc4f25a4c3c0a0847b5abd547be125f825d3c +int result type: Int64 +integer result type: Int64 +bigint result type: BigInt +float result type: Float64 +bool result type: Bool +string result type: String +none result type: Nothing +failure result type: Nothing +list10 result type: Vector{Int64} +list10000 result type: Vector{Int64} +list10000_concrete result type: Vector{Int64} +mixed_numeric result type: Vector{Float64} +heterogeneous result type: Vector{Any} +nested_concrete result type: Vector{Vector{Int64}} +nested_any result type: PyList{Any} +dict result type: Dict{String, Float64} +dict_concrete result type: Dict{String, Float64} +empty_list result type: Vector{Union{}} +empty_dict result type: Dict{Union{}, Union{}} +wrapper result type: PyList{Any} +iterator result type: PyIterable{Any} diff --git a/benchmark/convert-final-before-r3.tsv b/benchmark/convert-final-before-r3.tsv new file mode 100644 index 000000000..27b66180a --- /dev/null +++ b/benchmark/convert-final-before-r3.tsv @@ -0,0 +1,30 @@ +case mode min_ns median_ns bytes allocs +int typed 222.79260780287476 262.42094455852157 0 0 +int runtime_target 365.561320754717 377.82547169811323 16 1 +integer typed 575.4098360655738 642.0710382513661 0 0 +integer runtime_target 704.7876712328767 708.2191780821918 0 0 +bigint typed 1072.2222222222222 1144.4444444444443 216 7 +bigint runtime_target 1159.9 1320.0 216 7 +float typed 231.46620046620046 265.4988344988345 0 0 +float runtime_target 352.3317757009346 425.2289719626168 16 1 +bool typed 233.82452431289641 246.08668076109936 0 0 +bool runtime_target 355.1839622641509 408.0141509433962 0 0 +string typed 296.6804979253112 313.27385892116183 48 2 +string runtime_target 405.995 419.5 48 2 +none typed 210.52456140350878 221.75263157894736 0 0 +none runtime_target 317.42323651452284 362.23651452282155 0 0 +failure typed 238.73849878934624 241.40193704600483 0 0 +failure runtime_target 351.7363184079602 415.4179104477612 0 0 +list10 typed 10499.0 11400.0 704 17 +list10000 typed 7.226144e6 7.739141e6 513864 19507 +list10000_concrete typed 3.92657e6 4.363367e6 362008 10017 +mixed_numeric typed 4657.0 4985.714285714285 320 11 +heterogeneous typed 5416.5 5749.833333333333 368 13 +nested_concrete typed 8050.0 8525.0 720 26 +nested_any typed 374.871921182266 395.5665024630542 16 1 +dict typed 7599.75 8499.75 1248 22 +dict_concrete typed 3550.0 3950.0 656 15 +empty_list typed 1359.9 1420.0 64 3 +empty_dict typed 1099.95 1180.0 112 3 +wrapper typed 378.320197044335 443.3497536945813 16 1 +iterator typed 376.47058823529414 388.23039215686276 16 1 diff --git a/benchmark/convert-final-summary.tsv b/benchmark/convert-final-summary.tsv new file mode 100644 index 000000000..7d4f1700b --- /dev/null +++ b/benchmark/convert-final-summary.tsv @@ -0,0 +1,66 @@ +group case mode before_ns after_ns change_percent before_p50_ns after_p50_ns before_low_ns before_high_ns after_low_ns after_high_ns before_bytes before_allocs after_bytes after_allocs +common int typed 222.79260780287476 240.43341404358353 7.918039298825041 244.71341463414635 275.180387409201 219.510162601626 228.7648401826484 234.70319634703196 249.74102564102563 0 0 0 0 +common int runtime_target 341.0913242009132 360.4714285714286 5.681793407064162 377.82547169811323 412.37619047619046 339.4319248826291 365.561320754717 351.41037735849056 386.1857142857143 16 1 16 1 +common integer typed 590.2119565217391 241.56532066508314 -59.07142883233243 642.0710382513661 266.2955801104972 575.4098360655738 625.5380434782609 239.5 246.1164383561644 0 0 0 0 +common integer runtime_target 704.7876712328767 360.7607655502392 -48.81284388542656 774.9930555555555 382.0388349514563 692.8967741935484 716.6597222222222 359.70388349514565 370.04347826086956 0 0 0 0 +common bigint typed 977.2727272727273 970.0 -0.7441860465116301 1027.2727272727273 1060.0 956.25 1072.2222222222222 943.4347826086956 1100.0 216 7 216 7 +common bigint runtime_target 1139.9 1169.9 2.631809807877894 1300.0 1310.0 1120.0 1159.9 1130.0 1220.0 216 7 216 7 +common float typed 239.99764705882353 239.75061728395062 -0.10293008198216658 265.4988344988345 242.27790973871734 231.46620046620046 255.24885844748857 235.8646080760095 269.0048426150121 0 0 0 0 +common float runtime_target 352.3317757009346 361.7177033492823 2.6639458305102393 407.8294930875576 403.84134615384613 350.719806763285 353.91244239631334 354.32211538461536 371.14903846153845 16 1 16 1 +common bool typed 232.47058823529412 253.98670212765958 9.255413364630893 255.4870259481038 291.48670212765956 229.53892215568862 233.82452431289641 247.27507163323781 253.98936170212767 0 0 0 0 +common bool runtime_target 349.0607476635514 368.9271844660194 5.691398112060608 369.1542056074766 378.3605769230769 329.27477477477476 355.1839622641509 366.82211538461536 385.2167487684729 0 0 0 0 +common string typed 296.6804979253112 311.42448979591836 4.969653203938917 336.6756756756757 377.1387755102041 293.1123188405797 302.6988416988417 309.0085836909871 345.8287037037037 48 2 48 2 +common string runtime_target 405.995 428.63819095477385 5.577209314098419 419.5 491.45226130653265 404.495 409.5427135678392 425.6281407035176 452.79187817258884 48 2 48 2 +common none typed 210.52456140350878 230.02421307506054 9.262411730751507 219.99833333333333 264.3934065934066 209.165 212.14107142857142 226.48173515981736 230.1076923076923 0 0 0 0 +common none runtime_target 317.69135802469134 355.9194312796209 12.033085662959198 362.23651452282155 418.0047393364929 317.42323651452284 321.69787234042553 354.24528301886795 370.04347826086956 0 0 0 0 +common failure typed 238.73849878934624 232.16333333333333 -2.754128676085288 241.68601583113457 264.20170454545456 229.28496042216358 243.0109589041096 230.9630681818182 254.54261363636363 0 0 0 0 +common failure runtime_target 351.7363184079602 329.64159292035396 -6.2816161798736285 393.20388349514565 341.0913242009132 336.40552995391704 371.8398058252427 329.2237442922374 371.6849315068493 0 0 0 0 +common list10 typed 9899.0 6759.8 -31.7122941711284 10600.0 7660.0 9100.0 10499.0 6440.0 7439.8 704 17 720 18 +common list10000 typed 7243345.0 4821463.0 -33.4359608716691 7960489.5 5239210.0 7226144.0 7292249.0 4650965.0 4852463.0 513864 19507 513880 19508 +common list10000_concrete typed 3918970.0 4122068.0 5.182433139319764 4278517.0 4461866.5 3848273.0 3926570.0 4058069.0 4122169.0 362008 10017 362024 10018 +common mixed_numeric typed 4471.428571428572 3799.875 -15.018769968051116 4800.0 3912.375 4371.285714285715 4657.0 3774.875 3837.375 320 11 352 13 +common heterogeneous typed 5466.5 4785.571428571428 -12.456390220956216 6150.0 5114.285714285715 5416.5 5766.666666666667 4771.428571428572 4899.857142857143 368 13 384 14 +common nested_concrete typed 7974.75 7060.0 -11.470579015016147 8525.0 7820.0 7424.75 8050.0 6880.0 7324.75 720 26 768 29 +common nested_any typed 389.6502463054187 9500.0 2338.0839201506974 435.32338308457713 10600.0 374.871921182266 400.4925373134328 9399.0 10700.0 16 1 864 32 +common dict typed 7424.75 6700.0 -9.761271423280249 8024.75 6900.0 7025.0 7599.75 6660.0 7079.8 1248 22 1280 24 +common dict_concrete typed 3237.5 3750.0 15.83011583011582 3550.0 4237.5 3212.5 3550.0 3662.375 3900.0 656 15 672 16 +common empty_list typed 1289.9 1139.9 -11.628808434762384 1310.0 1190.0 1199.9 1359.9 1130.0 1290.0 64 3 112 5 +common empty_dict typed 1053.8461538461538 1099.9 4.370072992700735 1100.0 1180.0 970.5294117647059 1099.95 1009.0 1129.9 112 3 208 5 +common wrapper typed 378.320197044335 387.495 2.425142254456447 421.45853658536583 407.4207920792079 377.0682926829268 383.5771144278607 386.63366336633663 389.1039603960396 16 1 16 1 +common iterator typed 389.6502463054187 388.6089108910891 -0.26724875043794283 401.4875621890547 428.3532338308458 376.47058823529414 390.5422885572139 385.56716417910445 394.5273631840796 16 1 16 1 +expanded single_rule warm 393.495 377.9362745098039 -3.9539830214351035 450.7412935323383 393.5960591133005 384.995 393.5273631840796 376.3497536945813 402.44607843137254 0 0 0 0 +expanded single_rule selection_miss 26899.0 71199.0 164.6901371798208 28450.0 79449.5 26100.0 27100.0 63999.0 71800.0 4976 149 8304 261 +expanded single_rule invalidated 27599.0 2588880.0 9280.3398673865 29199.5 2990877.0 27300.0 27799.0 2562281.0 2593680.0 4976 149 1474960 21262 +expanded decline_then_success warm 535.1010638297872 540.2063492063492 0.95407871926525 628.1914893617021 586.9057591623036 533.6844919786096 547.0534759358288 528.7905759162304 573.3989361702128 0 0 0 0 +expanded decline_then_success selection_miss 28100.0 67899.0 141.63345195729536 30299.5 77000.0 27900.0 28100.0 62999.0 72899.0 5840 174 8400 264 +expanded decline_then_success invalidated 29600.0 2602380.0 8691.824324324323 30550.0 2926977.5 29500.0 30199.0 2542581.0 2662580.0 5840 174 1475056 21265 +expanded three_declines_then_success warm 979.2264150943396 936.0 -4.414343243607776 1016.9811320754717 989.2857142857143 883.5901639344262 982.0 842.8214285714286 994.719298245614 0 0 0 0 +expanded three_declines_then_success selection_miss 32599.0 62499.0 91.7206049265315 34900.0 66550.0 25899.0 33200.0 62399.0 71799.0 8752 234 8688 271 +expanded three_declines_then_success invalidated 34599.0 2588081.0 7380.2190814763435 36150.0 2725679.0 34200.0 34799.0 2508581.0 2625580.0 8752 234 1475344 21272 +expanded sixteen_scoped_decliners warm 4071.285714285714 384.7241379310345 -90.55030364041812 4471.428571428572 440.38916256157637 4000.0 4100.0 380.87745098039215 402.00502512562815 0 0 0 0 +expanded sixteen_scoped_decliners selection_miss 65500.0 70199.0 7.174045801526718 75849.5 78699.5 64800.0 65999.0 60900.0 71500.0 31344 797 8304 261 +expanded sixteen_scoped_decliners invalidated 75699.0 2587680.0 3318.3806919510166 79150.0 2662779.5 74700.0 76200.0 2500481.0 2872478.0 31344 797 1474960 21262 +expanded virtual_mapping_abc warm 393.995 379.40686274509807 -3.7026198948976297 426.495 433.3333333333333 389.5990099009901 396.5124378109453 375.6048780487805 391.6617647058824 0 0 0 0 +expanded virtual_mapping_abc selection_miss 57399.0 71499.0 24.564887890032928 66750.0 76850.0 48300.0 58200.0 61300.0 71599.0 18752 539 8304 261 +expanded virtual_mapping_abc invalidated 65300.0 2600080.0 3881.7457886676875 71649.5 2741429.0 64499.0 66000.0 2533781.0 2617280.0 18752 539 1474960 21262 +expanded buffer_only_native warm 7000.0 7474.75 6.782142857142848 7625.0 8300.0 6925.0 7225.0 7399.75 7675.0 8712 23 8856 26 +expanded buffer_only_native selection_miss 84900.0 43600.0 -48.64546525323911 105749.0 48399.5 80999.0 87899.0 41900.0 44899.0 35784 778 9880 62 +expanded buffer_only_native invalidated 104499.0 2608181.0 2395.8908697690886 114299.0 2942877.0 100799.0 105599.0 2604980.0 2753580.0 35784 778 1475672 21051 +expanded buffer_only_wrapper warm 5433.166666666667 5619.8 3.4350746955428058 6500.0 6433.166666666667 5133.333333333333 5483.333333333333 5549.833333333333 5633.166666666667 640 20 768 22 +expanded buffer_only_wrapper selection_miss 75499.0 35000.0 -53.64177008967006 84949.0 36900.0 71699.0 80600.0 31700.0 35099.0 26816 757 1920 58 +expanded buffer_only_wrapper invalidated 96500.0 2528881.0 2520.6020725388603 106599.0 2667029.0 78099.0 97500.0 2525881.0 2583080.0 26816 757 1467712 21047 +expanded interface_only_native warm 21199.0 22600.0 6.608802301995387 22700.0 24100.0 20800.0 21500.0 21800.0 22999.0 9224 52 9368 55 +expanded interface_only_native selection_miss 66700.0 58100.0 -12.89355322338831 77249.5 66699.0 55699.0 68099.0 57999.0 58600.0 15896 244 10408 91 +expanded interface_only_native invalidated 246598.0 2890477.0 1072.1412987939884 275248.0 3155075.5 238999.0 248098.0 2864778.0 3192776.0 64232 1579 1507208 22091 +expanded array_method_only_native warm 7633.333333333333 8000.0 4.8034934497816595 8400.0 9100.0 7266.333333333333 7899.666666666667 7933.333333333333 8233.333333333334 8872 27 9016 30 +expanded array_method_only_native selection_miss 45099.0 38999.0 -13.525798798199517 51799.0 42200.0 44699.0 48100.0 36100.0 39300.0 15544 219 10056 66 +expanded array_method_only_native invalidated 51099.0 2648979.0 5084.013385780543 57000.0 2903577.0 50200.0 53500.0 2554080.0 2679379.0 15544 219 1476712 21067 +expanded ndarray_native warm 4471.428571428572 4816.5 7.717252396166141 5157.142857142857 5166.666666666667 4257.142857142857 4799.857142857143 4750.0 4950.0 8744 20 8888 23 +expanded ndarray_native selection_miss 71399.0 39000.0 -45.37738623790249 82699.0 41199.5 71099.0 72600.0 38400.0 41300.0 35208 788 10872 84 +expanded ndarray_native invalidated 85699.0 2582780.0 2913.780790907712 90299.0 2661629.5 80199.0 96299.0 2581480.0 2949576.0 35208 788 1476664 21073 +expanded ndarray_wrapper warm 3199.875 3612.5 12.895034962303221 3537.5 3925.0 3125.0 3312.5 3287.5 3725.0 672 17 800 19 +expanded ndarray_wrapper selection_miss 70500.0 34300.0 -51.34751773049646 81749.5 37100.0 63399.0 70900.0 33899.0 35399.0 28208 803 3488 86 +expanded ndarray_wrapper invalidated 80999.0 2870077.0 3443.348683317078 87749.5 3051776.5 71599.0 84099.0 2649578.0 2875978.0 28208 803 1469280 21075 +expanded two_matching_first_success warm 3375.0 3937.5 3325.0 3499.875 560 18 +expanded two_matching_first_declines warm 4128.428571428572 4642.857142857143 4114.285714285715 4228.428571428572 720 24 +expanded two_matching_decline_then_ordinary warm 5142.857142857143 5442.714285714285 4685.714285714285 5285.714285714285 752 25 diff --git a/benchmark/convert-final-unwrapped-after-r1-environment.txt b/benchmark/convert-final-unwrapped-after-r1-environment.txt new file mode 100644 index 000000000..2e84f861a --- /dev/null +++ b/benchmark/convert-final-unwrapped-after-r1-environment.txt @@ -0,0 +1,30 @@ +Julia: 1.13.2 +Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] +Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python +BenchmarkTools: 1.8.0 +PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl +New API: true +Convert/pyconvert.jl SHA256: b9ff0cdfadc7561bd9725c0862cdcd0b08ba38958faab6e24053a42241b244ea +Convert/rules.jl SHA256: 2a064304ea9cd4edc2143621ffd0309d5b2a660326e38a6033b7b0ca2a8afc43 +Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a +int result type: Int64 +integer result type: Int64 +bigint result type: BigInt +float result type: Float64 +bool result type: Bool +string result type: String +none result type: Nothing +failure result type: Nothing +list10 result type: Vector{Int64} +list10000 result type: Vector{Int64} +list10000_concrete result type: Vector{Int64} +mixed_numeric result type: Vector{Real} +heterogeneous result type: Vector{Any} +nested_concrete result type: Vector{Vector{Int64}} +nested_any result type: Vector{Vector{Int64}} +dict result type: Dict{String, Real} +dict_concrete result type: Dict{String, Float64} +empty_list result type: Vector{Any} +empty_dict result type: Dict{Any, Any} +wrapper result type: PyList{Any} +iterator result type: PyIterable{Any} diff --git a/benchmark/convert-final-unwrapped-after-r1.tsv b/benchmark/convert-final-unwrapped-after-r1.tsv new file mode 100644 index 000000000..312c5fbe2 --- /dev/null +++ b/benchmark/convert-final-unwrapped-after-r1.tsv @@ -0,0 +1,30 @@ +case mode min_ns median_ns bytes allocs +int typed 247.71689497716895 284.02054794520546 0 0 +int runtime_target 380.19323671497585 444.20531400966183 16 1 +integer typed 236.17021276595744 285.1090425531915 0 0 +integer runtime_target 356.1320754716981 366.0377358490566 0 0 +bigint typed 980.0 1060.1 216 7 +bigint runtime_target 1110.0 1300.0 216 7 +float typed 236.5641646489104 249.63922518159805 0 0 +float runtime_target 391.04477611940297 449.2587064676617 16 1 +bool typed 273.93882978723406 306.65159574468083 0 0 +bool runtime_target 421.28712871287127 447.03465346534654 0 0 +string typed 309.880658436214 355.14814814814815 48 2 +string runtime_target 425.6281407035176 487.94472361809045 48 2 +none typed 225.9356846473029 232.1597510373444 0 0 +none runtime_target 340.0 349.54545454545456 0 0 +failure typed 263.56164383561645 279.4547945205479 0 0 +failure runtime_target 335.02764976958525 373.2718894009217 0 0 +list10 typed 7080.0 7560.0 704 17 +list10000 typed 4.624435e6 5.458141e6 513864 19507 +list10000_concrete typed 4.018131e6 4.755336e6 362008 10017 +mixed_numeric typed 3800.125 3912.5 336 12 +heterogeneous typed 4728.571428571428 5214.428571428572 368 13 +nested_concrete typed 6920.0 7080.0 720 26 +nested_any typed 9500.0 9701.0 816 29 +dict typed 7580.0 8040.0 1264 23 +dict_concrete typed 3950.0 4325.0 656 15 +empty_list typed 1130.0 1180.0 96 4 +empty_dict typed 1080.0 1200.0 192 4 +wrapper typed 395.02487562189054 453.23880597014926 16 1 +iterator typed 397.505 469.5 16 1 diff --git a/benchmark/convert-final-unwrapped-after-r2-environment.txt b/benchmark/convert-final-unwrapped-after-r2-environment.txt new file mode 100644 index 000000000..2e84f861a --- /dev/null +++ b/benchmark/convert-final-unwrapped-after-r2-environment.txt @@ -0,0 +1,30 @@ +Julia: 1.13.2 +Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] +Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python +BenchmarkTools: 1.8.0 +PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl +New API: true +Convert/pyconvert.jl SHA256: b9ff0cdfadc7561bd9725c0862cdcd0b08ba38958faab6e24053a42241b244ea +Convert/rules.jl SHA256: 2a064304ea9cd4edc2143621ffd0309d5b2a660326e38a6033b7b0ca2a8afc43 +Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a +int result type: Int64 +integer result type: Int64 +bigint result type: BigInt +float result type: Float64 +bool result type: Bool +string result type: String +none result type: Nothing +failure result type: Nothing +list10 result type: Vector{Int64} +list10000 result type: Vector{Int64} +list10000_concrete result type: Vector{Int64} +mixed_numeric result type: Vector{Real} +heterogeneous result type: Vector{Any} +nested_concrete result type: Vector{Vector{Int64}} +nested_any result type: Vector{Vector{Int64}} +dict result type: Dict{String, Real} +dict_concrete result type: Dict{String, Float64} +empty_list result type: Vector{Any} +empty_dict result type: Dict{Any, Any} +wrapper result type: PyList{Any} +iterator result type: PyIterable{Any} diff --git a/benchmark/convert-final-unwrapped-after-r2.tsv b/benchmark/convert-final-unwrapped-after-r2.tsv new file mode 100644 index 000000000..6ebecadab --- /dev/null +++ b/benchmark/convert-final-unwrapped-after-r2.tsv @@ -0,0 +1,30 @@ +case mode min_ns median_ns bytes allocs +int typed 234.9246231155779 243.09170854271355 0 0 +int runtime_target 360.2870813397129 410.5311004784689 16 1 +integer typed 243.46793349168647 278.8622327790974 0 0 +integer runtime_target 361.9095238095238 414.76190476190476 0 0 +bigint typed 953.8461538461538 1007.6923076923077 216 7 +bigint runtime_target 1190.0 1300.0 216 7 +float typed 239.63031914893617 266.7579787234043 0 0 +float runtime_target 383.66336633663366 443.0693069306931 16 1 +bool typed 255.58823529411765 292.06176470588235 0 0 +bool runtime_target 395.0980392156863 418.1421568627451 0 0 +string typed 313.8655462184874 371.43277310924367 48 2 +string runtime_target 426.2676767676768 474.75252525252523 48 2 +none typed 231.80125523012552 258.1610878661088 0 0 +none runtime_target 345.23809523809524 395.23809523809524 0 0 +failure typed 229.68036529680364 262.5570776255708 0 0 +failure runtime_target 333.1838565022422 351.1255605381166 0 0 +list10 typed 6440.2 7500.0 704 17 +list10000 typed 4.805737e6 5.634343e6 513864 19507 +list10000_concrete typed 4.036031e6 4.764337e6 362008 10017 +mixed_numeric typed 4225.0 4512.5 336 12 +heterogeneous typed 5057.142857142857 5443.0 368 13 +nested_concrete typed 6920.0 7820.0 720 26 +nested_any typed 10701.0 11300.0 816 29 +dict typed 6540.0 7620.0 1264 23 +dict_concrete typed 3612.625 4200.0 656 15 +empty_list typed 1120.0 1200.0 96 4 +empty_dict typed 1036.3636363636363 1163.6363636363637 192 4 +wrapper typed 404.97512437810946 466.1741293532338 16 1 +iterator typed 400.5 405.5 16 1 diff --git a/benchmark/convert-final-unwrapped-after-r3-environment.txt b/benchmark/convert-final-unwrapped-after-r3-environment.txt new file mode 100644 index 000000000..2e84f861a --- /dev/null +++ b/benchmark/convert-final-unwrapped-after-r3-environment.txt @@ -0,0 +1,30 @@ +Julia: 1.13.2 +Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] +Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python +BenchmarkTools: 1.8.0 +PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl +New API: true +Convert/pyconvert.jl SHA256: b9ff0cdfadc7561bd9725c0862cdcd0b08ba38958faab6e24053a42241b244ea +Convert/rules.jl SHA256: 2a064304ea9cd4edc2143621ffd0309d5b2a660326e38a6033b7b0ca2a8afc43 +Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a +int result type: Int64 +integer result type: Int64 +bigint result type: BigInt +float result type: Float64 +bool result type: Bool +string result type: String +none result type: Nothing +failure result type: Nothing +list10 result type: Vector{Int64} +list10000 result type: Vector{Int64} +list10000_concrete result type: Vector{Int64} +mixed_numeric result type: Vector{Real} +heterogeneous result type: Vector{Any} +nested_concrete result type: Vector{Vector{Int64}} +nested_any result type: Vector{Vector{Int64}} +dict result type: Dict{String, Real} +dict_concrete result type: Dict{String, Float64} +empty_list result type: Vector{Any} +empty_dict result type: Dict{Any, Any} +wrapper result type: PyList{Any} +iterator result type: PyIterable{Any} diff --git a/benchmark/convert-final-unwrapped-after-r3.tsv b/benchmark/convert-final-unwrapped-after-r3.tsv new file mode 100644 index 000000000..f624f61dc --- /dev/null +++ b/benchmark/convert-final-unwrapped-after-r3.tsv @@ -0,0 +1,30 @@ +case mode min_ns median_ns bytes allocs +int typed 239.5964467005076 280.96700507614213 0 0 +int runtime_target 410.4265402843602 440.28909952606637 16 1 +integer typed 237.46223564954684 278.8549848942598 0 0 +integer runtime_target 356.3380281690141 420.1924882629108 0 0 +bigint typed 1042.1052631578948 1121.0526315789473 216 7 +bigint runtime_target 1110.0 1170.0 216 7 +float typed 237.28813559322035 271.18886198547216 0 0 +float runtime_target 373.30582524271847 428.6456310679612 16 1 +bool typed 251.11111111111111 303.1777777777778 0 0 +bool runtime_target 385.02415458937196 418.3623188405797 0 0 +string typed 311.4035087719298 367.5438596491228 48 2 +string runtime_target 427.1356783919598 452.76884422110555 48 2 +none typed 236.30365296803652 270.32191780821915 0 0 +none runtime_target 375.23364485981307 387.1518691588785 0 0 +failure typed 238.68778280542986 251.58597285067873 0 0 +failure runtime_target 338.7142857142857 376.0414746543779 0 0 +list10 typed 6560.0 6940.0 704 17 +list10000 typed 4.545035e6 5.467642e6 513864 19507 +list10000_concrete typed 4.094831e6 4.7470365e6 362008 10017 +mixed_numeric typed 3800.0 3962.5 336 12 +heterogeneous typed 4842.857142857143 5300.0 368 13 +nested_concrete typed 8075.0 8425.0 720 26 +nested_any typed 9800.0 10300.0 816 29 +dict typed 6540.0 7220.0 1264 23 +dict_concrete typed 3612.5 3687.625 656 15 +empty_list typed 1180.0 1370.0 96 4 +empty_dict typed 1030.0 1060.0 192 4 +wrapper typed 399.505 422.005 16 1 +iterator typed 398.99497487437185 402.5175879396985 16 1 diff --git a/benchmark/convert-final-unwrapped-before-r1-environment.txt b/benchmark/convert-final-unwrapped-before-r1-environment.txt new file mode 100644 index 000000000..d0e4169d0 --- /dev/null +++ b/benchmark/convert-final-unwrapped-before-r1-environment.txt @@ -0,0 +1,30 @@ +Julia: 1.13.2 +Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] +Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python +BenchmarkTools: 1.8.0 +PythonCall source: /tmp/pythoncall-some-before.LlDQq5/src/PythonCall.jl +New API: true +Convert/pyconvert.jl SHA256: 7d8337b08370a90127dcc5a9d7b9b79f743ee2998c5ac6154a671725682aad6e +Convert/rules.jl SHA256: d42b0af459b0243412a5f9befa62caccc5039a8e0561be414cf9f941a6c328e4 +Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a +int result type: Int64 +integer result type: Int64 +bigint result type: BigInt +float result type: Float64 +bool result type: Bool +string result type: String +none result type: Nothing +failure result type: Nothing +list10 result type: Vector{Int64} +list10000 result type: Vector{Int64} +list10000_concrete result type: Vector{Int64} +mixed_numeric result type: Vector{Real} +heterogeneous result type: Vector{Any} +nested_concrete result type: Vector{Vector{Int64}} +nested_any result type: Vector{Vector{Int64}} +dict result type: Dict{String, Real} +dict_concrete result type: Dict{String, Float64} +empty_list result type: Vector{Any} +empty_dict result type: Dict{Any, Any} +wrapper result type: PyList{Any} +iterator result type: PyIterable{Any} diff --git a/benchmark/convert-final-unwrapped-before-r1.tsv b/benchmark/convert-final-unwrapped-before-r1.tsv new file mode 100644 index 000000000..70877c21b --- /dev/null +++ b/benchmark/convert-final-unwrapped-before-r1.tsv @@ -0,0 +1,30 @@ +case mode min_ns median_ns bytes allocs +int typed 240.14251781472683 270.4299287410926 0 0 +int runtime_target 363.9423076923077 395.67788461538464 16 1 +integer typed 242.13317191283292 270.22033898305085 0 0 +integer runtime_target 362.20095693779905 414.35885167464113 0 0 +bigint typed 1070.0 1160.0 216 7 +bigint runtime_target 1280.0 1390.0 216 7 +float typed 240.38004750593825 275.061757719715 0 0 +float runtime_target 370.5314009661836 427.05797101449275 16 1 +bool typed 257.2755417956656 294.73993808049534 0 0 +bool runtime_target 431.15577889447235 434.678391959799 0 0 +string typed 319.91525423728814 348.7330508474576 48 2 +string runtime_target 431.8181818181818 481.3131313131313 48 2 +none typed 231.83856502242153 251.347533632287 0 0 +none runtime_target 337.8995433789954 376.25570776255705 0 0 +failure typed 229.93569844789357 242.35254988913525 0 0 +failure runtime_target 341.2844036697248 389.45412844036696 0 0 +list10 typed 7120.0 7620.0 720 18 +list10000 typed 4.687736e6 5.057489e6 513880 19508 +list10000_concrete typed 4.084732e6 4.4526345e6 362024 10018 +mixed_numeric typed 3837.625 4475.125 352 13 +heterogeneous typed 4828.571428571428 5614.428571428572 384 14 +nested_concrete typed 6940.0 7340.0 768 29 +nested_any typed 9900.0 10900.0 864 32 +dict typed 6500.0 7580.0 1280 24 +dict_concrete typed 3675.0 4062.625 672 16 +empty_list typed 1260.0 1340.0 112 5 +empty_dict typed 1120.0 1230.1 208 5 +wrapper typed 394.02985074626866 428.363184079602 16 1 +iterator typed 402.0 462.505 16 1 diff --git a/benchmark/convert-final-unwrapped-before-r2-environment.txt b/benchmark/convert-final-unwrapped-before-r2-environment.txt new file mode 100644 index 000000000..d0e4169d0 --- /dev/null +++ b/benchmark/convert-final-unwrapped-before-r2-environment.txt @@ -0,0 +1,30 @@ +Julia: 1.13.2 +Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] +Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python +BenchmarkTools: 1.8.0 +PythonCall source: /tmp/pythoncall-some-before.LlDQq5/src/PythonCall.jl +New API: true +Convert/pyconvert.jl SHA256: 7d8337b08370a90127dcc5a9d7b9b79f743ee2998c5ac6154a671725682aad6e +Convert/rules.jl SHA256: d42b0af459b0243412a5f9befa62caccc5039a8e0561be414cf9f941a6c328e4 +Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a +int result type: Int64 +integer result type: Int64 +bigint result type: BigInt +float result type: Float64 +bool result type: Bool +string result type: String +none result type: Nothing +failure result type: Nothing +list10 result type: Vector{Int64} +list10000 result type: Vector{Int64} +list10000_concrete result type: Vector{Int64} +mixed_numeric result type: Vector{Real} +heterogeneous result type: Vector{Any} +nested_concrete result type: Vector{Vector{Int64}} +nested_any result type: Vector{Vector{Int64}} +dict result type: Dict{String, Real} +dict_concrete result type: Dict{String, Float64} +empty_list result type: Vector{Any} +empty_dict result type: Dict{Any, Any} +wrapper result type: PyList{Any} +iterator result type: PyIterable{Any} diff --git a/benchmark/convert-final-unwrapped-before-r2.tsv b/benchmark/convert-final-unwrapped-before-r2.tsv new file mode 100644 index 000000000..aadb29a92 --- /dev/null +++ b/benchmark/convert-final-unwrapped-before-r2.tsv @@ -0,0 +1,30 @@ +case mode min_ns median_ns bytes allocs +int typed 242.8595641646489 286.2009685230024 0 0 +int runtime_target 392.5422885572139 413.43283582089555 16 1 +integer typed 242.22222222222223 285.68148148148146 0 0 +integer runtime_target 386.2068965517241 397.04926108374383 0 0 +bigint typed 932.0 1004.0 216 7 +bigint runtime_target 1190.0 1250.0 216 7 +float typed 249.72375690607734 296.6878453038674 0 0 +float runtime_target 393.0348258706468 397.5124378109453 16 1 +bool typed 259.025787965616 296.2750716332378 0 0 +bool runtime_target 445.9646464646465 526.2676767676768 0 0 +string typed 318.0257510729614 375.9699570815451 48 2 +string runtime_target 445.95959595959596 516.1666666666666 48 2 +none typed 240.55944055944056 276.9230769230769 0 0 +none runtime_target 354.50236966824644 395.2654028436019 0 0 +failure typed 231.52391304347827 258.045652173913 0 0 +failure runtime_target 371.5 426.005 0 0 +list10 typed 7760.0 8120.0 720 18 +list10000 typed 4.854337e6 5.624843e6 513880 19508 +list10000_concrete typed 4.225432e6 4.674036e6 362024 10018 +mixed_numeric typed 4000.0 4175.0 352 13 +heterogeneous typed 5400.0 6000.0 384 14 +nested_concrete typed 7050.0 8600.0 768 29 +nested_any typed 10800.0 11600.0 864 32 +dict typed 6360.0 7380.2 1280 24 +dict_concrete typed 3675.0 3950.125 672 16 +empty_list typed 1210.0 1400.0 112 5 +empty_dict typed 1040.0 1090.0 208 5 +wrapper typed 400.49751243781094 412.93532338308455 16 1 +iterator typed 401.0 485.505 16 1 diff --git a/benchmark/convert-final-unwrapped-before-r3-environment.txt b/benchmark/convert-final-unwrapped-before-r3-environment.txt new file mode 100644 index 000000000..d0e4169d0 --- /dev/null +++ b/benchmark/convert-final-unwrapped-before-r3-environment.txt @@ -0,0 +1,30 @@ +Julia: 1.13.2 +Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] +Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python +BenchmarkTools: 1.8.0 +PythonCall source: /tmp/pythoncall-some-before.LlDQq5/src/PythonCall.jl +New API: true +Convert/pyconvert.jl SHA256: 7d8337b08370a90127dcc5a9d7b9b79f743ee2998c5ac6154a671725682aad6e +Convert/rules.jl SHA256: d42b0af459b0243412a5f9befa62caccc5039a8e0561be414cf9f941a6c328e4 +Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a +int result type: Int64 +integer result type: Int64 +bigint result type: BigInt +float result type: Float64 +bool result type: Bool +string result type: String +none result type: Nothing +failure result type: Nothing +list10 result type: Vector{Int64} +list10000 result type: Vector{Int64} +list10000_concrete result type: Vector{Int64} +mixed_numeric result type: Vector{Real} +heterogeneous result type: Vector{Any} +nested_concrete result type: Vector{Vector{Int64}} +nested_any result type: Vector{Vector{Int64}} +dict result type: Dict{String, Real} +dict_concrete result type: Dict{String, Float64} +empty_list result type: Vector{Any} +empty_dict result type: Dict{Any, Any} +wrapper result type: PyList{Any} +iterator result type: PyIterable{Any} diff --git a/benchmark/convert-final-unwrapped-before-r3.tsv b/benchmark/convert-final-unwrapped-before-r3.tsv new file mode 100644 index 000000000..2e19c285a --- /dev/null +++ b/benchmark/convert-final-unwrapped-before-r3.tsv @@ -0,0 +1,30 @@ +case mode min_ns median_ns bytes allocs +int typed 240.86294416243655 275.89086294416245 0 0 +int runtime_target 393.0 406.505 16 1 +integer typed 243.8280871670702 288.38014527845036 0 0 +integer runtime_target 389.6039603960396 447.529702970297 0 0 +bigint typed 934.7826086956521 1004.3913043478261 216 7 +bigint runtime_target 1200.0 1250.0 216 7 +float typed 234.5679012345679 240.99012345679012 0 0 +float runtime_target 429.1457286432161 499.50251256281405 16 1 +bool typed 254.00890207715133 299.7032640949555 0 0 +bool runtime_target 441.9191919191919 445.9646464646465 0 0 +string typed 313.79741379310343 369.82758620689657 48 2 +string runtime_target 454.04545454545456 521.7222222222222 48 2 +none typed 225.57077625570776 250.2283105022831 0 0 +none runtime_target 364.5980861244019 420.0956937799043 0 0 +failure typed 230.824200913242 231.73744292237444 0 0 +failure runtime_target 378.2608695652174 438.6497584541063 0 0 +list10 typed 6680.0 6960.2 720 18 +list10000 typed 4.714836e6 5.668843e6 513880 19508 +list10000_concrete typed 3.97843e6 4.284532e6 362024 10018 +mixed_numeric typed 3971.4285714285716 4614.285714285715 352 13 +heterogeneous typed 4871.428571428572 5471.428571428572 384 14 +nested_concrete typed 6950.0 7250.25 768 29 +nested_any typed 10800.0 11600.0 864 32 +dict typed 6480.0 6740.2 1280 24 +dict_concrete typed 3925.0 4525.0 672 16 +empty_list typed 1240.0 1530.0 112 5 +empty_dict typed 1040.0 1220.0 208 5 +wrapper typed 416.005 466.505 16 1 +iterator typed 406.5 467.5 16 1 diff --git a/benchmark/convert-final.jl b/benchmark/convert-final.jl new file mode 100644 index 000000000..47b83dfca --- /dev/null +++ b/benchmark/convert-final.jl @@ -0,0 +1,63 @@ +# Same harness on original v1 and the final working tree. No new-API dependency. +# julia --project=benchmark benchmark/convert-final.jl after-r1 +using PythonCall, BenchmarkTools, SHA + +final_value(::Val{T}, x) where T = pyconvert(T,x,nothing) +label = isempty(ARGS) ? "after-r1" : only(ARGS) +newapi = isdefined(PythonCall,:PyConvertContext) +fixtures = [ + ("int",Int,pyint(10000),x->x===10000), + ("integer",Integer,pyint(42),x->x===42), + ("bigint",BigInt,pyint(big(2)^200),x->x==big(2)^200), + ("float",Float64,pyfloat(1.5),x->x===1.5), + ("bool",Bool,pybool(true),x->x===true), + ("string",String,pystr("hello"),x->x=="hello"), + ("none",Nothing,pybuiltins.None,isnothing), + ("failure",Int,pystr("oops"),isnothing), + ("list10",Vector,pylist(1:10),x->x==collect(1:10)), + ("list10000",Vector,pylist(1:10000),x->x==collect(1:10000)), + ("list10000_concrete",Vector{Int},pylist(1:10000),x->x==collect(1:10000)), + ("mixed_numeric",Vector,pylist([pyint(1),pyfloat(2.5)]),x->x==[1,2.5]), + ("heterogeneous",Vector,pylist([pyint(1),pystr("two"),pybuiltins.None]),x->isequal(x,Any[1,"two",nothing])), + ("nested_concrete",Vector{Vector{Int}},pylist([pylist(1:5),pylist(6:10)]),x->x==[collect(1:5),collect(6:10)]), + # Any intentionally changes from wrapping to native recursive conversion. + ("nested_any",Any,pylist([pylist(1:5),pylist(6:10)]),x->newapi ? x isa Vector{Vector{Int}} : x isa PyList), + ("dict",Dict,pydict("a"=>1,"b"=>2.5),x->x==Dict("a"=>1,"b"=>2.5)), + ("dict_concrete",Dict{String,Float64},pydict("a"=>1,"b"=>2.5),x->x==Dict("a"=>1.0,"b"=>2.5)), + ("empty_list",Vector,pylist(),x->x isa Vector && isempty(x)), + ("empty_dict",Dict,pydict(),x->x isa Dict && isempty(x)), + ("wrapper",PyList,pylist(1:10),x->x isa PyList && length(x)==10), + ("iterator",Any,pyiter(pylist(1:10)),x->x isa PyIterable), +] +open(joinpath(@__DIR__,"convert-final-$label.tsv"),"w") do io + println(io,"case\tmode\tmin_ns\tmedian_ns\tbytes\tallocs") + for (i,(name,T,x,valid)) in enumerate(fixtures) + tag=Val(T) + @assert valid(final_value(tag,x)) name + modes=i<=8 ? ("typed","runtime_target") : ("typed",) + for mode in modes + trial = if mode=="typed" + @benchmark final_value($tag,$x) seconds=1.0 samples=5000 + else + @benchmark pyconvert($T,$x,nothing) seconds=1.0 samples=5000 + end + m,d=minimum(trial),median(trial) + println(io,"$name\t$mode\t$(m.time)\t$(d.time)\t$(m.memory)\t$(m.allocs)") + end + flush(io) + end +end +open(joinpath(@__DIR__,"convert-final-$label-environment.txt"),"w") do io + println(io,"Julia: ",VERSION) + println(io,"Python: ",pyconvert(String,pyimport("sys").version)) + println(io,"Python executable: ",pyconvert(String,pyimport("sys").executable)) + println(io,"BenchmarkTools: ",pkgversion(BenchmarkTools)) + println(io,"PythonCall source: ",pathof(PythonCall)) + println(io,"New API: ",newapi) + for file in ("Convert/pyconvert.jl","Convert/rules.jl","Wrap/PyArray.jl") + println(io,file," SHA256: ",bytes2hex(sha256(read(joinpath(dirname(pathof(PythonCall)),file))))) + end + for (name,T,x,_) in fixtures + println(io,name," result type: ",typeof(final_value(Val(T),x))) + end +end diff --git a/benchmark/convert-inference-final.txt b/benchmark/convert-inference-final.txt new file mode 100644 index 000000000..45c0f1119 --- /dev/null +++ b/benchmark/convert-inference-final.txt @@ -0,0 +1,63 @@ + +pytryconvert(Int64, ::Py) +MethodInstance for pytryconvert(::Type{Int64}, ::Py) + from pytryconvert(::Type{T}, x; prefer) where T @ PythonCall.Convert ~/.julia/dev/PythonCall/src/Convert/pyconvert.jl:357 +Static Parameters + T = Int64 +Arguments + #self#::Core.Const(PythonCall.pytryconvert) + @_2::Core.Const(Int64) + x::Py +Body::UNION{NOTHING, SOME{INT64}} +1 ─ %1 = PythonCall.Convert.:(var"#pytryconvert#30")::Core.Const(PythonCall.Convert.var"#pytryconvert#30") +│ %2 = ()::Core.Const(()) +│ %3 = (%1)(%2, #self#, @_2, x)::UNION{NOTHING, SOME{INT64}} +└── return %3 + + +pytryconvert(Integer, ::Py) +MethodInstance for pytryconvert(::Type{Integer}, ::Py) + from pytryconvert(::Type{T}, x; prefer) where T @ PythonCall.Convert ~/.julia/dev/PythonCall/src/Convert/pyconvert.jl:357 +Static Parameters + T = Integer +Arguments + #self#::Core.Const(PythonCall.pytryconvert) + @_2::Core.Const(Integer) + x::Py +Body::UNION{NOTHING, SOME{T} WHERE T<:INTEGER} +1 ─ %1 = PythonCall.Convert.:(var"#pytryconvert#30")::Core.Const(PythonCall.Convert.var"#pytryconvert#30") +│ %2 = ()::Core.Const(()) +│ %3 = (%1)(%2, #self#, @_2, x)::UNION{NOTHING, SOME{T} WHERE T<:INTEGER} +└── return %3 + + +pytryconvert(Union{Nothing, Int64}, ::Py) +MethodInstance for pytryconvert(::Type{Union{Nothing, Int64}}, ::Py) + from pytryconvert(::Type{T}, x; prefer) where T @ PythonCall.Convert ~/.julia/dev/PythonCall/src/Convert/pyconvert.jl:357 +Static Parameters + T = Union{Nothing, Int64} +Arguments + #self#::Core.Const(PythonCall.pytryconvert) + @_2::Type{Union{Nothing, Int64}} + x::Py +Body::UNION{SOME{NOTHING}, NOTHING, SOME{INT64}} +1 ─ %1 = PythonCall.Convert.:(var"#pytryconvert#30")::Core.Const(PythonCall.Convert.var"#pytryconvert#30") +│ %2 = ()::Core.Const(()) +│ %3 = (%1)(%2, #self#, @_2, x)::UNION{SOME{NOTHING}, NOTHING, SOME{INT64}} +└── return %3 + + +pytryconvert(Any, ::Py) +MethodInstance for pytryconvert(::Type{Any}, ::Py) + from pytryconvert(::Type{T}, x; prefer) where T @ PythonCall.Convert ~/.julia/dev/PythonCall/src/Convert/pyconvert.jl:357 +Static Parameters + T = Any +Arguments + #self#::Core.Const(PythonCall.pytryconvert) + @_2::Core.Const(Any) + x::Py +Body::UNION{NOTHING, SOME} +1 ─ %1 = PythonCall.Convert.:(var"#pytryconvert#30")::Core.Const(PythonCall.Convert.var"#pytryconvert#30") +│ %2 = ()::Core.Const(()) +│ %3 = (%1)(%2, #self#, @_2, x)::UNION{NOTHING, SOME} +└── return %3 diff --git a/benchmark/convert-inference.txt b/benchmark/convert-inference.txt new file mode 100644 index 000000000..842b44d42 --- /dev/null +++ b/benchmark/convert-inference.txt @@ -0,0 +1,63 @@ + +pytryconvert(Int64, ::Py) +MethodInstance for pytryconvert(::Type{Int64}, ::Py) + from pytryconvert(::Type{T}, x; prefer) where T @ PythonCall.Convert ~/.julia/dev/PythonCall/src/Convert/pyconvert.jl:327 +Static Parameters + T = Int64 +Arguments + #self#::Core.Const(PythonCall.pytryconvert) + @_2::Core.Const(Int64) + x::Py +Body::UNION{NOTHING, SOME{INT64}} +1 ─ %1 = PythonCall.Convert.:(var"#pytryconvert#30")::Core.Const(PythonCall.Convert.var"#pytryconvert#30") +│ %2 = ()::Core.Const(()) +│ %3 = (%1)(%2, #self#, @_2, x)::UNION{NOTHING, SOME{INT64}} +└── return %3 + + +pytryconvert(Integer, ::Py) +MethodInstance for pytryconvert(::Type{Integer}, ::Py) + from pytryconvert(::Type{T}, x; prefer) where T @ PythonCall.Convert ~/.julia/dev/PythonCall/src/Convert/pyconvert.jl:327 +Static Parameters + T = Integer +Arguments + #self#::Core.Const(PythonCall.pytryconvert) + @_2::Core.Const(Integer) + x::Py +Body::UNION{NOTHING, SOME{T} WHERE T<:INTEGER} +1 ─ %1 = PythonCall.Convert.:(var"#pytryconvert#30")::Core.Const(PythonCall.Convert.var"#pytryconvert#30") +│ %2 = ()::Core.Const(()) +│ %3 = (%1)(%2, #self#, @_2, x)::UNION{NOTHING, SOME{T} WHERE T<:INTEGER} +└── return %3 + + +pytryconvert(Union{Nothing, Int64}, ::Py) +MethodInstance for pytryconvert(::Type{Union{Nothing, Int64}}, ::Py) + from pytryconvert(::Type{T}, x; prefer) where T @ PythonCall.Convert ~/.julia/dev/PythonCall/src/Convert/pyconvert.jl:327 +Static Parameters + T = Union{Nothing, Int64} +Arguments + #self#::Core.Const(PythonCall.pytryconvert) + @_2::Type{Union{Nothing, Int64}} + x::Py +Body::UNION{SOME{NOTHING}, NOTHING, SOME{INT64}} +1 ─ %1 = PythonCall.Convert.:(var"#pytryconvert#30")::Core.Const(PythonCall.Convert.var"#pytryconvert#30") +│ %2 = ()::Core.Const(()) +│ %3 = (%1)(%2, #self#, @_2, x)::UNION{SOME{NOTHING}, NOTHING, SOME{INT64}} +└── return %3 + + +pytryconvert(Any, ::Py) +MethodInstance for pytryconvert(::Type{Any}, ::Py) + from pytryconvert(::Type{T}, x; prefer) where T @ PythonCall.Convert ~/.julia/dev/PythonCall/src/Convert/pyconvert.jl:327 +Static Parameters + T = Any +Arguments + #self#::Core.Const(PythonCall.pytryconvert) + @_2::Core.Const(Any) + x::Py +Body::UNION{NOTHING, SOME} +1 ─ %1 = PythonCall.Convert.:(var"#pytryconvert#30")::Core.Const(PythonCall.Convert.var"#pytryconvert#30") +│ %2 = ()::Core.Const(()) +│ %3 = (%1)(%2, #self#, @_2, x)::UNION{NOTHING, SOME} +└── return %3 diff --git a/benchmark/convert-redesign.jl b/benchmark/convert-redesign.jl new file mode 100644 index 000000000..83494f015 --- /dev/null +++ b/benchmark/convert-redesign.jl @@ -0,0 +1,24 @@ +# Run with julia --project=benchmark benchmark/convert-redesign.jl baseline|redesign +using PythonCall, BenchmarkTools +label = isempty(ARGS) ? "redesign" : ARGS[1] +const CV = PythonCall.Convert +cases = [ + ("int", Int, pyint(42)), ("integer", Integer, pyint(42)), + ("bigint", BigInt, pyint(big(2)^200)), ("float", Float64, pyfloat(1.5)), + ("bool", Bool, pybool(true)), ("string", String, pystr("hello")), + ("none", Nothing, pybuiltins.None), ("failure", Int, pystr("oops")), + ("list10", Vector, pylist(1:10)), ("list10000", Vector, pylist(1:10000)), + ("mixed", Vector, pylist([1, 2.5, "three", nothing])), + ("nested", Any, pylist([pylist(1:5), pylist(6:10)])), + ("dict", Dict, pydict("a"=>1, "b"=>2.5)), + ("wrapper", PyList, pylist(1:10)), + ("iterator", Any, pyiter(pylist(1:10))), +] +open(joinpath(@__DIR__, "convert-$label.tsv"), "w") do io + println(io, "case\tns\tbytes\tallocs") + for (name, T, x) in cases + trial = @benchmark pyconvert($T, $x, nothing) seconds=0.3 samples=1000 + m = minimum(trial) + println(io, "$name\t$(m.time)\t$(m.memory)\t$(m.allocs)") + end +end diff --git a/benchmark/convert-redesign.tsv b/benchmark/convert-redesign.tsv new file mode 100644 index 000000000..ac05470e9 --- /dev/null +++ b/benchmark/convert-redesign.tsv @@ -0,0 +1,16 @@ +case ns bytes allocs +int 375.2378640776699 0 0 +integer 393.495 0 0 +bigint 1319.9 232 8 +float 424.0 32 2 +bool 408.3743842364532 0 0 +string 451.015306122449 48 2 +none 451.7363184079602 0 0 +failure 402.803738317757 0 0 +list10 7760.0 720 18 +list10000 5.007263e6 513880 19508 +mixed 6900.0 608 20 +nested 11000.0 864 32 +dict 6739.8 1280 24 +wrapper 558.5967741935484 16 1 +iterator 547.5882352941177 16 1 diff --git a/benchmark/convert-report.md b/benchmark/convert-report.md new file mode 100644 index 000000000..69c1249bc --- /dev/null +++ b/benchmark/convert-report.md @@ -0,0 +1,197 @@ +# v1 pyconvert final implementation report + +The redesign is implemented on v1. The latest minimal-wrapping optimization and +current performance totals are in [convert-unwrapped-report.md](convert-unwrapped-report.md). +Latest local checks: **1,765 conversion/wrapper/Julia-wrapper checks passed**, with +one existing optional-dependency skip. The most recent 15-test ordinary Python +run predates that optimization. The +maintainer assigned final full-suite/notebook/docs and version-matrix validation +to CI; those checks were not rerun for this benchmark refresh. Work is uncommitted. + +## Design implemented + +- Rules store source, advertised output, scope, function and increasing ID. Adds + always create entries; replacement preserves identity/order. Mutations invalidate + all selections. Pending sources resolve without importing optional modules. +- A global strict-subclass DAG includes ABC relationships and independent array/ + buffer matchers. Inherited priorities are monotonic; stable topological sorting + uses source registration order, then rule creation order. Aliases share ordering + and priority. Per-call selection filters without reordering. +- Output intersection and destination scope determine eligibility, including + normalized union arms. Each rule receives non-union intersections, rule-first; + union-arm order is unspecified. The final Py fallback is outside the registry. +- Source names resolve loaded-module attributes, including public re-exports and + dotted paths. Bare names abbreviate builtins. Legacy exec-defined ancestors + can also resolve from an encountered class hierarchy. Cached Python type + references prevent pointer reuse. +- Cached invocations select context-aware/legacy signatures once per target and + context type. Scalar shortcuts require a matching cached first rule/target. + Explicit contexts carry ordered source-specific preferences and propagate + recursively when requested, with no task-local state. +- Canonical materialized containers become native Julia containers. Vector/dict + types widen with Base.promote_typejoin within requested bounds; unconstrained + empties use Any. Generic iterables remain lazy PyIterable values. +- Rules accept values, nothing for decline, and Some for explicit success. + Public pytryconvert always returns Some/nothing. Internal raw values, a private + failure sentinel and an escape avoid per-element Some allocations. Exceptions + propagate; preferred-type introspection returns a candidate, not a guarantee. + Built-in success helpers wrap only actual nothing/Some values; array and + native-container results cross dispatch boundaries directly. + +Public additions: PyConvertContext, pytryconvert, pyconvert_remove_rule, +pyconvert_replace_rule, pyconvert_rules, scope and prefer. Public rule priorities +and result helpers were removed. Main changes are in src/Convert/pyconvert.jl, +rules.jl, NumPy/pandas registrations, Wrap/PyArray, JlWrap, API declarations, +conversion documentation, migration guide and tests. + +## Agreed decisions and limitations + +The maintainer accepted pyconvert(Py, x::Py) as an identity shortcut. Generic +numbers.Real/Complex coercions were replaced by float/complex source rules: +integral/rational sources retain exact intermediates, supported NumPy scalars +retain dedicated rules, and other numeric types require explicit rules. Python +float-to-Int remains available when exact and in range. This fixes integer +overflow being hidden by an intermediate rounded Float64. + +The optimized internal result representation is explicitly allowed by the +specification; the public contract is unchanged. v1 calls its iterator wrapper +PyIterable rather than PyIterator. Ownership remains an API contract. +Cycles/identity preservation, dynamic ABC mutations, arbitrary module/type +replacement and method changes without invalidation remain unsupported. +Copy-policy frameworks and public priority controls were deliberately omitted. + +## Final benchmark method + +The full original-v1 comparison below measures the implementation immediately +before minimal result wrapping. The linked follow-up supersedes affected +allocation/timing totals and compares directly against that pre-change snapshot. + +Baseline: original v1 commit 25f82cc8effbd6c487ddceaffc34aa7cbe86505b, extracted +into an isolated checkout/environment. After: the final working tree, including +the alias/shorthand and numeric-source changes. Environment records include +source paths and SHA256 fingerprints. + +Linux x86_64, Intel Core i7-8750H, Julia 1.13.2, Python 3.15.0, NumPy 2.5.4, +BenchmarkTools 1.8.0. Both revisions use the same Python executable and Null +CondaPkg backend. All processes ran sequentially without concurrent tests. +Round order: before/after, after/before, before/after. + +Tables use microseconds and the **median of three trial minima**. Warm trials +use up to 5,000 samples / one second. Julia bytes/allocation counts exclude +Python allocations. Trial medians and round ranges remain in +convert-final-summary.tsv. These are short local trials, not confidence intervals. + +## Cached scalars + +The requested type is visible to inference through Val. Runtime-target variants +are separately recorded; those can box values in the benchmark caller. + +| Target/source | Before us | After us | Change | Before B / allocs | After B / allocs | +| --- | ---: | ---: | ---: | ---: | ---: | +| Int / int | 0.223 | 0.240 | +7.9% | 0 / 0 | 0 / 0 | +| Integer / int | 0.590 | 0.242 | -59.1% | 0 / 0 | 0 / 0 | +| BigInt / large int | 0.977 | 0.970 | -0.7% | 216 / 7 | 216 / 7 | +| Float64 / float | 0.240 | 0.240 | -0.1% | 0 / 0 | 0 / 0 | +| Bool / bool | 0.232 | 0.254 | +9.3% | 0 / 0 | 0 / 0 | +| String / str | 0.297 | 0.311 | +5.0% | 48 / 2 | 48 / 2 | +| Nothing / None | 0.211 | 0.230 | +9.3% | 0 / 0 | 0 / 0 | +| Int / incompatible str | 0.239 | 0.232 | -2.8% | 0 / 0 | 0 / 0 | + +Positive scalar differences are tens of nanoseconds and remain visible in the +report. None is not slower than Int in the final implementation. +Float64/BigInt no longer retain the initial redesign's extra allocation. + +## Containers + +| Case | Before us | After us | Change | Before B / allocs | After B / allocs | +| --- | ---: | ---: | ---: | ---: | ---: | +| Vector, 10 integers | 9.899 | 6.760 | -31.7% | 704 / 17 | 720 / 18 | +| Vector, 10,000 integers | 7243.345 | 4821.463 | -33.4% | 513864 / 19507 | 513880 / 19508 | +| Vector{Int}, 10,000 integers | 3918.970 | 4122.068 | +5.2% | 362008 / 10017 | 362024 / 10018 | +| Vector, mixed numeric | 4.471 | 3.800 | -15.0% | 320 / 11 | 352 / 13 | +| Vector, heterogeneous | 5.466 | 4.786 | -12.5% | 368 / 13 | 384 / 14 | +| Vector{Vector{Int}}, nested | 7.975 | 7.060 | -11.5% | 720 / 26 | 768 / 29 | +| Dict, heterogeneous values | 7.425 | 6.700 | -9.8% | 1248 / 22 | 1280 / 24 | +| Dict{String,Float64} | 3.237 | 3.750 | +15.8% | 656 / 15 | 672 / 16 | +| Empty Vector | 1.290 | 1.140 | -11.6% | 64 / 3 | 112 / 5 | +| Empty Dict | 1.054 | 1.100 | +4.4% | 112 / 3 | 208 / 5 | + +Mixed numeric outputs intentionally change from promoted Float64 to Real while +preserving individual values; dictionary value types change similarly. Empty +types change from bottom to Any. Nested Any changes from wrapping (0.390 us, +16 B / 1 allocation) to recursive copying (9.500 us, 864 B / 32 allocations); +those perform different work. Explicit PyList and iterator wrapping remain +about 0.39 us / 16 B / 1 allocation. + +## Arrays, dispatch and preferences + +In this pre-optimization snapshot, array wrappers retain 128 extra bytes / two allocations, native arrays 144 bytes / +three allocations. Median trial minima rise 3.4% for buffer wrapping, 12.9% for +ndarray wrapping, and 4.8–7.7% for native arrays. Native ndarray trial medians +are essentially unchanged, while ndarray wrapper trial medians rise about 11%. +These end-to-end timings do not isolate allocation cost from other dispatch +changes. See [convert-expanded-report.md](convert-expanded-report.md) for ranges, +complete protocol/cold-path tables and allocation attribution. + +Cached single-rule/decline-chain dispatch stays allocation-free at roughly +0.38/0.54/0.94 us. Scope filtering excludes sixteen callbacks (4.07 to 0.38 us), +an intentional work difference. Selection misses are mixed: the simple fixture +rises from 26.9 to 71.2 us, while most protocol cases improve. + +Full invalidation/global rebuilding costs about 2.5–2.9 ms and 1.47–1.51 MB +with builtins plus 27 synthetic registrations, versus tens/hundreds of +microseconds in the old per-type scheme. Warm calls never rebuild the DAG. +This remains a measured cold-path regression, not a registry scaling study. + +New-API matching-preference cases cost 3.38/4.13/5.14 us for first success, +first decline then success, and all preferences declining before ordinary +conversion. Context-construction/source checks are included. Old v1 is marked +unsupported. Broader nested preferences are in convert-dispatch-final.tsv. + +## Result representation and inference + +Final raw-Unconverted versus Some/nothing models cover successful/failed Int64, +Float64, String, Vector{Int}, Integer, AbstractArray, Union{Int64,Nothing}, Any, +escaping results and typed 100-element loops. Both loops allocate zero; +escaping Some values can allocate, including an extra 16 bytes in the Int case. +This supports optimized internal dispatch behind the ergonomic public API. + +Inference preserves Some{Int} for Int, existential Some subtypes for Integer, +separate Some alternatives for Union{Int,Nothing}, and Some for Any. Scalar +profiles confirm no internal Float64 box or Some{BigInt} allocation. See +convert-results-final.tsv, convert-inference-final.txt, convert-scalars-final-* +and [convert-scalars-report.md](convert-scalars-report.md). + +## Reproduction and artifacts + +Use the same Julia executable and installed Python/backend in all runs. Prepare +an isolated baseline environment without changing the working tree: + +~~~sh +convert_baseline_src=$(mktemp -d) +convert_baseline_env=$(mktemp -d) +git archive 25f82cc8effbd6c487ddceaffc34aa7cbe86505b | tar -x -C "$convert_baseline_src" +/absolute/path/to/julia --project="$convert_baseline_env" -e \ + 'using Pkg; Pkg.develop(path=ARGS[1]); Pkg.add(PackageSpec(name="BenchmarkTools",version="1.8.0"))' \ + "$convert_baseline_src" +~~~ + +With the checkout's benchmark dependencies installed, run: + +~~~sh +JULIA_CONDAPKG_BACKEND=Null JULIA_PYTHONCALL_EXE=/absolute/path/to/python \ + bash benchmark/run-convert-final.sh /absolute/path/to/julia "$convert_baseline_env" +python3 benchmark/summarize-convert-final.py +~~~ + +The runner serializes three paired common/expanded rounds, then final scalar, +result/inference and preference suites. Fixture assertions passed on both +revisions. Allocation attribution can be reproduced with +convert-array-allocations.jl before/after in the respective environments. + +Authoritative paired data use convert-final-{before,after}-r{1,2,3} and +convert-expanded-final-{before,after}-r{1,2,3}; each includes an environment record. +The summarizer validates constant source snapshots and allocation counts across +rounds. Older TSV/profile files are historical snapshots, superseded by these +final measurements. No runtime policy or conversion optimization changed during +this refresh. diff --git a/benchmark/convert-results-final.tsv b/benchmark/convert-results-final.tsv new file mode 100644 index 000000000..258c73248 --- /dev/null +++ b/benchmark/convert-results-final.tsv @@ -0,0 +1,67 @@ +type representation success escaping ns bytes allocs +Int64 raw true true 133.56128293241696 16 1 +Int64 raw true false 140.57028571428572 0 0 +Int64 raw false true 131.88952164009112 16 1 +Int64 raw false false 136.09421112372303 0 0 +Int64 some true true 141.46225319396052 32 2 +Int64 some true false 129.4501679731243 16 1 +Int64 some false true 128.3783783783784 16 1 +Int64 some false false 121.34103410341034 0 0 +Float64 raw true true 154.18021201413427 48 3 +Float64 raw true false 150.46503496503496 32 2 +Float64 raw false true 140.2582159624413 32 2 +Float64 raw false false 141.6945412311266 16 1 +Float64 some true true 140.34970760233918 48 3 +Float64 some true false 147.3672514619883 32 2 +Float64 some false true 134.84562996594778 32 2 +Float64 some false false 133.56401384083046 16 1 +String raw true true 132.6867881548975 16 1 +String raw true false 121.21546961325967 0 0 +String raw false true 139.52050113895217 16 1 +String raw false false 132.4313063063063 0 0 +String some true true 144.3417142857143 48 3 +String some true false 129.49772209567197 16 1 +String some false true 134.55444444444444 16 1 +String some false false 134.27922814982975 0 0 +Vector{Int64} raw true true 147.74971164936562 16 1 +Vector{Int64} raw true false 115.62046204620462 0 0 +Vector{Int64} raw false true 137.38310185185185 16 1 +Vector{Int64} raw false false 124.88973799126637 0 0 +Vector{Int64} some true true 164.4159509202454 48 3 +Vector{Int64} some true false 142.7884160756501 16 1 +Vector{Int64} some false true 141.43075117370893 16 1 +Vector{Int64} some false false 146.85198135198135 0 0 +Integer raw true true 150.1153846153846 16 1 +Integer raw true false 146.5311004784689 0 0 +Integer raw false true 152.11150234741785 16 1 +Integer raw false false 158.29020100502512 0 0 +Integer some true true 143.2612293144208 32 2 +Integer some true false 146.2163120567376 16 1 +Integer some false true 145.27068557919623 16 1 +Integer some false false 142.7884160756501 0 0 +AbstractArray raw true true 204.7527733755943 16 1 +AbstractArray raw true false 182.4802919708029 0 0 +AbstractArray raw false true 189.55299539170508 16 1 +AbstractArray raw false false 192.02753623188406 0 0 +AbstractArray some true true 215.9274336283186 48 3 +AbstractArray some true false 196.75162337662337 16 1 +AbstractArray some false true 200.30804953560371 16 1 +AbstractArray some false false 194.56709265175718 0 0 +Union{Nothing, Int64} raw true true 67.51685393258427 16 1 +Union{Nothing, Int64} raw true false 60.957186544342505 0 0 +Union{Nothing, Int64} raw false true 61.671763506625894 16 1 +Union{Nothing, Int64} raw false false 60.38594704684318 0 0 +Union{Nothing, Int64} some true true 70.79815573770492 32 2 +Union{Nothing, Int64} some true false 72.08486707566462 16 1 +Union{Nothing, Int64} some false true 65.91734693877551 16 1 +Union{Nothing, Int64} some false false 69.8661899897855 0 0 +Any raw true true 184.297256097561 16 1 +Any raw true false 199.17326732673268 0 0 +Any raw false true 188.1981845688351 16 1 +Any raw false false 202.78068739770868 0 0 +Any some true true 204.17217391304348 32 2 +Any some true false 223.92678571428573 16 1 +Any some false true 197.70703764320785 16 1 +Any some false false 223.06007751937983 0 0 +loop100 raw true false 288.4364161849711 0 0 +loop100 some true false 268.33 0 0 diff --git a/benchmark/convert-results.jl b/benchmark/convert-results.jl new file mode 100644 index 000000000..b59a529c3 --- /dev/null +++ b/benchmark/convert-results.jl @@ -0,0 +1,44 @@ +# Isolate result representation from Python dispatch and iteration. +# julia --project=benchmark benchmark/convert-results.jl +using BenchmarkTools, PythonCall, InteractiveUtils +label = isempty(ARGS) ? "" : "-" * only(ARGS) +struct UnconvertedBaseline end +@noinline function old_result(::Type{T}, x, success) where T + (success ? (x::T) : UnconvertedBaseline())::Union{T,UnconvertedBaseline} +end +@noinline function new_result(::Type{T}, x, success) where T + (success ? Some(x::T) : nothing)::PythonCall.Convert.pyconvert_returntype(T) +end +@noinline escaping(x) = Ref{Any}(x) +function consume(f,::Type{T},values) where T + result = 0 + for x in values + r = f(T,x,true) + result += r isa Some ? something(r) : r + end + result +end +cases = [(Int64,1), (Float64,1.5), (String,"hello"), (Vector{Int},[1,2]), + (Integer,1), (AbstractArray,[1,2]), (Union{Int64,Nothing},1), (Any,1)] +open(joinpath(@__DIR__,"convert-results$label.tsv"),"w") do io + println(io,"type\trepresentation\tsuccess\tescaping\tns\tbytes\tallocs") + for (T,x) in cases, (name,f) in (("raw",old_result),("some",new_result)), success in (true,false), escape in (true,false) + b = escape ? (@benchmark escaping($f($T,$x,$success)) seconds=0.1 samples=500) : + (@benchmark $f($T,$x,$success) seconds=0.1 samples=500) + m=minimum(b) + println(io,"$T\t$name\t$success\t$escape\t$(m.time)\t$(m.memory)\t$(m.allocs)") + end + for (name,f) in (("raw",old_result),("some",new_result)) + values=collect(1:100) + m=minimum(@benchmark consume($f,Int,$values) seconds=0.1 samples=500) + println(io,"loop100\t$name\ttrue\tfalse\t$(m.time)\t$(m.memory)\t$(m.allocs)") + end +end +open(joinpath(@__DIR__,"convert-inference$label.txt"),"w") do io + for T in (Int,Integer,Union{Int,Nothing},Any) + println(io,"\npytryconvert($T, ::Py)") + inferred=IOBuffer() + code_warntype(inferred,pytryconvert,Tuple{Type{T},Py};debuginfo=:none) + println(io,rstrip(String(take!(inferred)))) + end +end diff --git a/benchmark/convert-results.tsv b/benchmark/convert-results.tsv new file mode 100644 index 000000000..4a81e5ddc --- /dev/null +++ b/benchmark/convert-results.tsv @@ -0,0 +1,67 @@ +type representation success escaping ns bytes allocs +Int64 raw true true 143.5885780885781 16 1 +Int64 raw true false 123.2547065337763 0 0 +Int64 raw false true 138.77199074074073 16 1 +Int64 raw false false 136.21262458471762 0 0 +Int64 some true true 134.82130584192439 32 2 +Int64 some true false 139.79123414071512 16 1 +Int64 some false true 131.4189189189189 16 1 +Int64 some false false 133.48405466970388 0 0 +Float64 raw true true 159.75337423312882 48 3 +Float64 raw true false 160.53125 32 2 +Float64 raw false true 171.75757575757575 32 2 +Float64 raw false false 136.2156862745098 16 1 +Float64 some true true 138.22727272727272 48 3 +Float64 some true false 136.68865740740742 32 2 +Float64 some false true 135.42742857142858 32 2 +Float64 some false false 139.18806306306305 16 1 +String raw true true 201.98439716312058 16 1 +String raw true false 172.75950920245398 0 0 +String raw false true 180.2822695035461 16 1 +String raw false false 163.56658291457288 0 0 +String some true true 165.17843866171003 48 3 +String some true false 131.87317620650953 16 1 +String some false true 167.3064903846154 16 1 +String some false false 140.67482517482517 0 0 +Vector{Int64} raw true true 129.61599099099098 16 1 +Vector{Int64} raw true false 142.24122310305776 0 0 +Vector{Int64} raw false true 128.94144144144144 16 1 +Vector{Int64} raw false false 131.35273159144893 0 0 +Vector{Int64} some true true 160.5524798154556 48 3 +Vector{Int64} some true false 128.7150900900901 16 1 +Vector{Int64} some false true 130.45912653975364 16 1 +Vector{Int64} some false false 125.85148514851485 0 0 +Integer raw true true 169.8123543123543 16 1 +Integer raw true false 135.0504009163803 0 0 +Integer raw false true 149.58164481525625 16 1 +Integer raw false false 134.7356725146199 0 0 +Integer some true true 147.2476076555024 32 2 +Integer some true false 139.3927738927739 16 1 +Integer some false true 143.66079812206573 16 1 +Integer some false false 135.27436440677965 0 0 +AbstractArray raw true true 202.2711038961039 16 1 +AbstractArray raw true false 219.1542207792208 0 0 +AbstractArray raw false true 231.69322033898305 16 1 +AbstractArray raw false false 232.12443438914028 0 0 +AbstractArray some true true 213.45607476635513 48 3 +AbstractArray some true false 196.5663026521061 16 1 +AbstractArray some false true 213.09557522123893 16 1 +AbstractArray some false false 199.36450079239302 0 0 +Union{Nothing, Int64} raw true true 76.3023493360572 16 1 +Union{Nothing, Int64} raw true false 63.68158697863682 0 0 +Union{Nothing, Int64} raw false true 63.738508682328906 16 1 +Union{Nothing, Int64} raw false false 57.63747454175153 0 0 +Union{Nothing, Int64} some true true 71.23848515864893 32 2 +Union{Nothing, Int64} some true false 71.0204081632653 16 1 +Union{Nothing, Int64} some false true 71.3265306122449 16 1 +Union{Nothing, Int64} some false false 65.30925737538149 0 0 +Any raw true true 196.61674718196457 16 1 +Any raw true false 192.86687797147385 0 0 +Any raw false true 204.8685064935065 16 1 +Any raw false false 199.83166666666668 0 0 +Any some true true 273.9698630136986 32 2 +Any some true false 226.34860883797054 16 1 +Any some false true 278.32637075718014 16 1 +Any some false false 190.18333333333334 0 0 +loop100 raw true false 306.11436170212767 0 0 +loop100 some true false 253.29041916167665 0 0 diff --git a/benchmark/convert-scalaropt.tsv b/benchmark/convert-scalaropt.tsv new file mode 100644 index 000000000..2d9c6b16e --- /dev/null +++ b/benchmark/convert-scalaropt.tsv @@ -0,0 +1,16 @@ +case ns bytes allocs +int 379.121359223301 0 0 +integer 362.85238095238094 0 0 +bigint 1189.9 216 7 +float 367.3076923076923 16 1 +bool 381.45853658536583 0 0 +string 489.3888888888889 48 2 +none 355.70319634703196 0 0 +failure 352.37619047619046 0 0 +list10 7160.0 720 18 +list10000 5.30626e6 513880 19508 +mixed 6459.8 608 20 +nested 9499.0 864 32 +dict 6719.8 1280 24 +wrapper 574.9945652173913 16 1 +iterator 574.2105263157895 16 1 diff --git a/benchmark/convert-scalars-before-allocations.txt b/benchmark/convert-scalars-before-allocations.txt new file mode 100644 index 000000000..4838eec36 --- /dev/null +++ b/benchmark/convert-scalars-before-allocations.txt @@ -0,0 +1,139 @@ + +int + +float +Float64: 16 bytes + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Float64}, x::Py) at pyconvert.jl:296 + pytryconvert_raw at pyconvert.jl:318 [inlined] + macro expansion at pyconvert.jl:394 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Float64}, x::Py, default::Nothing) at pyconvert.jl:393 + #pyconvert#36 at pyconvert.jl:399 [inlined] + pyconvert at pyconvert.jl:399 [inlined] + scalar_convert(::Val{Float64}, x::Py) at convert-scalars.jl:5 + (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 + eval(m::Module, e::Any) at boot.jl:489 +Float64: 16 bytes + (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 + eval(m::Module, e::Any) at boot.jl:489 + +bigint +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:51 [inlined] + pynew at Py.jl:55 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at Py.jl:102 [inlined] + macro expansion at regions.jl:296 [inlined] + pyint(x::Py) at builtins.jl:689 + macro expansion at rules.jl:90 [inlined] + macro expansion at regions.jl:296 [inlined] + pyconvert_rule_int(::Type{BigInt}, x::Py) at rules.jl:61 + pyconvert_first at pyconvert.jl:282 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:299 + pytryconvert_raw at pyconvert.jl:318 [inlined] + macro expansion at pyconvert.jl:394 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:393 + #pyconvert#36 at pyconvert.jl:399 [inlined] + pyconvert at pyconvert.jl:399 [inlined] + scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 + (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 + eval(m::Module, e::Any) at boot.jl:489 +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:51 [inlined] + pynew at Py.jl:55 [inlined] + macro expansion at regions.jl:296 [inlined] + pystr(x::Py) at builtins.jl:592 + pystr at builtins.jl:598 [inlined] + macro expansion at rules.jl:91 [inlined] + macro expansion at regions.jl:296 [inlined] + pyconvert_rule_int(::Type{BigInt}, x::Py) at rules.jl:61 + pyconvert_first at pyconvert.jl:282 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:299 + pytryconvert_raw at pyconvert.jl:318 [inlined] + macro expansion at pyconvert.jl:394 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:393 + #pyconvert#36 at pyconvert.jl:399 [inlined] + pyconvert at pyconvert.jl:399 [inlined] + scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 + (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 + eval(m::Module, e::Any) at boot.jl:489 +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:51 [inlined] + pynew at Py.jl:55 [inlined] + macro expansion at regions.jl:296 [inlined] + pystr_asUTF8bytes(x::Py) at builtins.jl:600 + pystr_asstring(x::Py) at builtins.jl:603 + pystr at builtins.jl:598 [inlined] + macro expansion at rules.jl:91 [inlined] + macro expansion at regions.jl:296 [inlined] + pyconvert_rule_int(::Type{BigInt}, x::Py) at rules.jl:61 + pyconvert_first at pyconvert.jl:282 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:299 + pytryconvert_raw at pyconvert.jl:318 [inlined] + macro expansion at pyconvert.jl:394 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:393 + #pyconvert#36 at pyconvert.jl:399 [inlined] + pyconvert at pyconvert.jl:399 [inlined] + scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 + (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 + eval(m::Module, e::Any) at boot.jl:489 +String: 70 bytes + pybytes_asUTF8string at builtins.jl:654 [inlined] + pystr_asstring(x::Py) at builtins.jl:604 + pystr at builtins.jl:598 [inlined] + macro expansion at rules.jl:91 [inlined] + macro expansion at regions.jl:296 [inlined] + pyconvert_rule_int(::Type{BigInt}, x::Py) at rules.jl:61 + pyconvert_first at pyconvert.jl:282 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:299 + pytryconvert_raw at pyconvert.jl:318 [inlined] + macro expansion at pyconvert.jl:394 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:393 + #pyconvert#36 at pyconvert.jl:399 [inlined] + pyconvert at pyconvert.jl:399 [inlined] + scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 + (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 + eval(m::Module, e::Any) at boot.jl:489 +BigInt: 32 bytes + _ at gmp.jl:70 [inlined] + BigInt at gmp.jl:69 [inlined] + tryparse_internal(::Type{BigInt}, s::String, startpos::Int64, endpos::Int64, base_::Int64, raise::Bool) at gmp.jl:302 + macro expansion at rules.jl:93 [inlined] + macro expansion at regions.jl:296 [inlined] + pyconvert_rule_int(::Type{BigInt}, x::Py) at rules.jl:61 + pyconvert_first at pyconvert.jl:282 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:299 + pytryconvert_raw at pyconvert.jl:318 [inlined] + macro expansion at pyconvert.jl:394 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:393 + #pyconvert#36 at pyconvert.jl:399 [inlined] + pyconvert at pyconvert.jl:399 [inlined] + scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 + (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 + eval(m::Module, e::Any) at boot.jl:489 +Some{BigInt}: 16 bytes + macro expansion at rules.jl:94 [inlined] + macro expansion at regions.jl:296 [inlined] + pyconvert_rule_int(::Type{BigInt}, x::Py) at rules.jl:61 + pyconvert_first at pyconvert.jl:282 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:299 + pytryconvert_raw at pyconvert.jl:318 [inlined] + macro expansion at pyconvert.jl:394 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:393 + #pyconvert#36 at pyconvert.jl:399 [inlined] + pyconvert at pyconvert.jl:399 [inlined] + scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 + (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 + eval(m::Module, e::Any) at boot.jl:489 + +none diff --git a/benchmark/convert-scalars-before-inference.txt b/benchmark/convert-scalars-before-inference.txt new file mode 100644 index 000000000..38aa8b8d0 --- /dev/null +++ b/benchmark/convert-scalars-before-inference.txt @@ -0,0 +1,663 @@ + +int: scalar_convert +MethodInstance for scalar_convert(::Val{Int64}, ::Py) + from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 +Static Parameters + T = Int64 +Arguments + #self#::Core.Const(Main.scalar_convert) + _::Core.Const(Val{Int64}()) + x::Py +Body::UNION{NOTHING, INT64} +1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) +│ %2 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ %3 = Main.nothing::Core.Const(nothing) +│ %4 = (%1)(%2, x, %3)::UNION{NOTHING, INT64} +└── return %4 + + +int: scalar_plain +MethodInstance for scalar_plain(::Val{Int64}, ::Py) + from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 +Static Parameters + T = Int64 +Arguments + #self#::Core.Const(Main.scalar_plain) + _::Core.Const(Val{Int64}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + @_7::Int64 + @_8::ANY +Body::ANY +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ %4 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %4 +2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %10 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ %11 = (%7)(%9, %10, x)::ANY +└── return %11 +3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%13)()) +│ %15 = task::Task +│ (state = (PythonCall.C.current_task_state)(%15)) +│ %17 = task::Task +│ %18 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%17, %18)) +4 ─ %20 = enter #7 +5 ─ (@_7 = -1) +│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %26 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ (@_8 = (%23)(%25, %26, x)) +│ (@_7 = 1) +└── $(Expr(:leave, :(%20))) +6 ─ goto #8 +7 ┄ %31 = task::Task +│ %32 = state::PythonCall.C.TaskState +│ %33 = token::Symbol +│ (PythonCall.C.exit_region)(%31, %32, %33) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%20))))) +└── Core.Const(:(return nothing)) +8 ┄ %38 = task::Task +│ %39 = state::PythonCall.C.TaskState +│ %40 = token::Symbol +│ (PythonCall.C.exit_region)(%38, %39, %40) +│ %42 = @_8::ANY +└── return %42 + + +int: scalar_first +MethodInstance for scalar_first(::Val{Int64}, ::Py) + from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 +Static Parameters + T = Int64 +Arguments + #self#::Core.Const(Main.scalar_first) + _::Core.Const(Val{Int64}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + selection::PythonCall.Convert.PyConvertSelection + ctx::PyConvertContext{Tuple{}} + @_9::Int64 + @_10::ANY +Body::ANY +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ Core.NewvarNode(:(selection)) +│ Core.NewvarNode(:(ctx)) +│ %6 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %6 +2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%8)()) +│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %13 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ %14 = Main.PythonCall::Core.Const(PythonCall) +│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) +│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%11)(%12, %13, %17)) +│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %22 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ %23 = selection::PythonCall.Convert.PyConvertSelection +│ %24 = (%20)(%21, %22, x, %23)::ANY +└── return %24 +3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%26)()) +│ %28 = task::Task +│ (state = (PythonCall.C.current_task_state)(%28)) +│ %30 = task::Task +│ %31 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%30, %31)) +4 ─ %33 = enter #7 +5 ─ (@_9 = -1) +│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%35)()) +│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %40 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ %41 = Main.PythonCall::Core.Const(PythonCall) +│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) +│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%38)(%39, %40, %44)) +│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %49 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ %50 = selection::PythonCall.Convert.PyConvertSelection +│ %51 = (%47)(%48, %49, x, %50)::ANY +│ (@_10 = %51) +│ (@_9 = 1) +└── $(Expr(:leave, :(%33))) +6 ─ goto #8 +7 ┄ %56 = task::Task +│ %57 = state::PythonCall.C.TaskState +│ %58 = token::Symbol +│ (PythonCall.C.exit_region)(%56, %57, %58) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%33))))) +└── Core.Const(:(return nothing)) +8 ┄ %63 = task::Task +│ %64 = state::PythonCall.C.TaskState +│ %65 = token::Symbol +│ (PythonCall.C.exit_region)(%63, %64, %65) +│ %67 = @_10::ANY +└── return %67 + + +float: scalar_convert +MethodInstance for scalar_convert(::Val{Float64}, ::Py) + from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 +Static Parameters + T = Float64 +Arguments + #self#::Core.Const(Main.scalar_convert) + _::Core.Const(Val{Float64}()) + x::Py +Body::UNION{NOTHING, FLOAT64} +1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) +│ %2 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ %3 = Main.nothing::Core.Const(nothing) +│ %4 = (%1)(%2, x, %3)::UNION{NOTHING, FLOAT64} +└── return %4 + + +float: scalar_plain +MethodInstance for scalar_plain(::Val{Float64}, ::Py) + from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 +Static Parameters + T = Float64 +Arguments + #self#::Core.Const(Main.scalar_plain) + _::Core.Const(Val{Float64}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + @_7::Int64 + @_8::ANY +Body::ANY +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ %4 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %4 +2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %10 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ %11 = (%7)(%9, %10, x)::ANY +└── return %11 +3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%13)()) +│ %15 = task::Task +│ (state = (PythonCall.C.current_task_state)(%15)) +│ %17 = task::Task +│ %18 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%17, %18)) +4 ─ %20 = enter #7 +5 ─ (@_7 = -1) +│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %26 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ (@_8 = (%23)(%25, %26, x)) +│ (@_7 = 1) +└── $(Expr(:leave, :(%20))) +6 ─ goto #8 +7 ┄ %31 = task::Task +│ %32 = state::PythonCall.C.TaskState +│ %33 = token::Symbol +│ (PythonCall.C.exit_region)(%31, %32, %33) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%20))))) +└── Core.Const(:(return nothing)) +8 ┄ %38 = task::Task +│ %39 = state::PythonCall.C.TaskState +│ %40 = token::Symbol +│ (PythonCall.C.exit_region)(%38, %39, %40) +│ %42 = @_8::ANY +└── return %42 + + +float: scalar_first +MethodInstance for scalar_first(::Val{Float64}, ::Py) + from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 +Static Parameters + T = Float64 +Arguments + #self#::Core.Const(Main.scalar_first) + _::Core.Const(Val{Float64}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + selection::PythonCall.Convert.PyConvertSelection + ctx::PyConvertContext{Tuple{}} + @_9::Int64 + @_10::ANY +Body::ANY +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ Core.NewvarNode(:(selection)) +│ Core.NewvarNode(:(ctx)) +│ %6 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %6 +2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%8)()) +│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %13 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ %14 = Main.PythonCall::Core.Const(PythonCall) +│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) +│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%11)(%12, %13, %17)) +│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %22 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ %23 = selection::PythonCall.Convert.PyConvertSelection +│ %24 = (%20)(%21, %22, x, %23)::ANY +└── return %24 +3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%26)()) +│ %28 = task::Task +│ (state = (PythonCall.C.current_task_state)(%28)) +│ %30 = task::Task +│ %31 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%30, %31)) +4 ─ %33 = enter #7 +5 ─ (@_9 = -1) +│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%35)()) +│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %40 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ %41 = Main.PythonCall::Core.Const(PythonCall) +│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) +│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%38)(%39, %40, %44)) +│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %49 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ %50 = selection::PythonCall.Convert.PyConvertSelection +│ %51 = (%47)(%48, %49, x, %50)::ANY +│ (@_10 = %51) +│ (@_9 = 1) +└── $(Expr(:leave, :(%33))) +6 ─ goto #8 +7 ┄ %56 = task::Task +│ %57 = state::PythonCall.C.TaskState +│ %58 = token::Symbol +│ (PythonCall.C.exit_region)(%56, %57, %58) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%33))))) +└── Core.Const(:(return nothing)) +8 ┄ %63 = task::Task +│ %64 = state::PythonCall.C.TaskState +│ %65 = token::Symbol +│ (PythonCall.C.exit_region)(%63, %64, %65) +│ %67 = @_10::ANY +└── return %67 + + +bigint: scalar_convert +MethodInstance for scalar_convert(::Val{BigInt}, ::Py) + from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 +Static Parameters + T = BigInt +Arguments + #self#::Core.Const(Main.scalar_convert) + _::Core.Const(Val{BigInt}()) + x::Py +Body::UNION{NOTHING, BIGINT} +1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) +│ %2 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ %3 = Main.nothing::Core.Const(nothing) +│ %4 = (%1)(%2, x, %3)::UNION{NOTHING, BIGINT} +└── return %4 + + +bigint: scalar_plain +MethodInstance for scalar_plain(::Val{BigInt}, ::Py) + from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 +Static Parameters + T = BigInt +Arguments + #self#::Core.Const(Main.scalar_plain) + _::Core.Const(Val{BigInt}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + @_7::Int64 + @_8::ANY +Body::ANY +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ %4 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %4 +2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %10 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ %11 = (%7)(%9, %10, x)::ANY +└── return %11 +3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%13)()) +│ %15 = task::Task +│ (state = (PythonCall.C.current_task_state)(%15)) +│ %17 = task::Task +│ %18 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%17, %18)) +4 ─ %20 = enter #7 +5 ─ (@_7 = -1) +│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %26 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ (@_8 = (%23)(%25, %26, x)) +│ (@_7 = 1) +└── $(Expr(:leave, :(%20))) +6 ─ goto #8 +7 ┄ %31 = task::Task +│ %32 = state::PythonCall.C.TaskState +│ %33 = token::Symbol +│ (PythonCall.C.exit_region)(%31, %32, %33) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%20))))) +└── Core.Const(:(return nothing)) +8 ┄ %38 = task::Task +│ %39 = state::PythonCall.C.TaskState +│ %40 = token::Symbol +│ (PythonCall.C.exit_region)(%38, %39, %40) +│ %42 = @_8::ANY +└── return %42 + + +bigint: scalar_first +MethodInstance for scalar_first(::Val{BigInt}, ::Py) + from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 +Static Parameters + T = BigInt +Arguments + #self#::Core.Const(Main.scalar_first) + _::Core.Const(Val{BigInt}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + selection::PythonCall.Convert.PyConvertSelection + ctx::PyConvertContext{Tuple{}} + @_9::Int64 + @_10::ANY +Body::ANY +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ Core.NewvarNode(:(selection)) +│ Core.NewvarNode(:(ctx)) +│ %6 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %6 +2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%8)()) +│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %13 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ %14 = Main.PythonCall::Core.Const(PythonCall) +│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) +│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%11)(%12, %13, %17)) +│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %22 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ %23 = selection::PythonCall.Convert.PyConvertSelection +│ %24 = (%20)(%21, %22, x, %23)::ANY +└── return %24 +3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%26)()) +│ %28 = task::Task +│ (state = (PythonCall.C.current_task_state)(%28)) +│ %30 = task::Task +│ %31 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%30, %31)) +4 ─ %33 = enter #7 +5 ─ (@_9 = -1) +│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%35)()) +│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %40 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ %41 = Main.PythonCall::Core.Const(PythonCall) +│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) +│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%38)(%39, %40, %44)) +│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %49 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ %50 = selection::PythonCall.Convert.PyConvertSelection +│ %51 = (%47)(%48, %49, x, %50)::ANY +│ (@_10 = %51) +│ (@_9 = 1) +└── $(Expr(:leave, :(%33))) +6 ─ goto #8 +7 ┄ %56 = task::Task +│ %57 = state::PythonCall.C.TaskState +│ %58 = token::Symbol +│ (PythonCall.C.exit_region)(%56, %57, %58) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%33))))) +└── Core.Const(:(return nothing)) +8 ┄ %63 = task::Task +│ %64 = state::PythonCall.C.TaskState +│ %65 = token::Symbol +│ (PythonCall.C.exit_region)(%63, %64, %65) +│ %67 = @_10::ANY +└── return %67 + + +none: scalar_convert +MethodInstance for scalar_convert(::Val{Nothing}, ::Py) + from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 +Static Parameters + T = Nothing +Arguments + #self#::Core.Const(Main.scalar_convert) + _::Core.Const(Val{Nothing}()) + x::Py +Body::Nothing +1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) +│ %2 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ %3 = Main.nothing::Core.Const(nothing) +│ %4 = (%1)(%2, x, %3)::Core.Const(nothing) +└── return %4 + + +none: scalar_plain +MethodInstance for scalar_plain(::Val{Nothing}, ::Py) + from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 +Static Parameters + T = Nothing +Arguments + #self#::Core.Const(Main.scalar_plain) + _::Core.Const(Val{Nothing}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + @_7::Int64 + @_8::ANY +Body::ANY +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ %4 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %4 +2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %10 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ %11 = (%7)(%9, %10, x)::ANY +└── return %11 +3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%13)()) +│ %15 = task::Task +│ (state = (PythonCall.C.current_task_state)(%15)) +│ %17 = task::Task +│ %18 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%17, %18)) +4 ─ %20 = enter #7 +5 ─ (@_7 = -1) +│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %26 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ (@_8 = (%23)(%25, %26, x)) +│ (@_7 = 1) +└── $(Expr(:leave, :(%20))) +6 ─ goto #8 +7 ┄ %31 = task::Task +│ %32 = state::PythonCall.C.TaskState +│ %33 = token::Symbol +│ (PythonCall.C.exit_region)(%31, %32, %33) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%20))))) +└── Core.Const(:(return nothing)) +8 ┄ %38 = task::Task +│ %39 = state::PythonCall.C.TaskState +│ %40 = token::Symbol +│ (PythonCall.C.exit_region)(%38, %39, %40) +│ %42 = @_8::ANY +└── return %42 + + +none: scalar_first +MethodInstance for scalar_first(::Val{Nothing}, ::Py) + from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 +Static Parameters + T = Nothing +Arguments + #self#::Core.Const(Main.scalar_first) + _::Core.Const(Val{Nothing}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + selection::PythonCall.Convert.PyConvertSelection + ctx::PyConvertContext{Tuple{}} + @_9::Int64 + @_10::ANY +Body::ANY +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ Core.NewvarNode(:(selection)) +│ Core.NewvarNode(:(ctx)) +│ %6 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %6 +2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%8)()) +│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %13 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ %14 = Main.PythonCall::Core.Const(PythonCall) +│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) +│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%11)(%12, %13, %17)) +│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %22 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ %23 = selection::PythonCall.Convert.PyConvertSelection +│ %24 = (%20)(%21, %22, x, %23)::ANY +└── return %24 +3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%26)()) +│ %28 = task::Task +│ (state = (PythonCall.C.current_task_state)(%28)) +│ %30 = task::Task +│ %31 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%30, %31)) +4 ─ %33 = enter #7 +5 ─ (@_9 = -1) +│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%35)()) +│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %40 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ %41 = Main.PythonCall::Core.Const(PythonCall) +│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) +│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%38)(%39, %40, %44)) +│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %49 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ %50 = selection::PythonCall.Convert.PyConvertSelection +│ %51 = (%47)(%48, %49, x, %50)::ANY +│ (@_10 = %51) +│ (@_9 = 1) +└── $(Expr(:leave, :(%33))) +6 ─ goto #8 +7 ┄ %56 = task::Task +│ %57 = state::PythonCall.C.TaskState +│ %58 = token::Symbol +│ (PythonCall.C.exit_region)(%56, %57, %58) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%33))))) +└── Core.Const(:(return nothing)) +8 ┄ %63 = task::Task +│ %64 = state::PythonCall.C.TaskState +│ %65 = token::Symbol +│ (PythonCall.C.exit_region)(%63, %64, %65) +│ %67 = @_10::ANY +└── return %67 diff --git a/benchmark/convert-scalars-before.tsv b/benchmark/convert-scalars-before.tsv new file mode 100644 index 000000000..8f502c50f --- /dev/null +++ b/benchmark/convert-scalars-before.tsv @@ -0,0 +1,25 @@ +case path min_ns median_ns bytes allocs +int dynamic 364.7294685990338 367.6328502415459 0 0 +int typed 238.51604938271606 245.18271604938272 0 0 +int discard 247.4227642276423 254.739837398374 0 0 +int try 238.69095477386935 245.4748743718593 0 0 +int plain 235.38584474885846 242.9200913242009 0 0 +int first 235.8951048951049 255.7086247086247 0 0 +float dynamic 372.33009708737865 380.09708737864077 32 2 +float typed 251.4878048780488 272.8970189701897 16 1 +float discard 254.54261363636363 255.9659090909091 16 1 +float try 243.81451612903226 250.80376344086022 16 1 +float plain 248.66755319148936 249.99734042553192 16 1 +float first 242.89027431421445 249.37655860349128 16 1 +bigint dynamic 1220.0 1300.0 232 8 +bigint typed 1060.0 1130.0 232 8 +bigint discard 1049.9 1100.0 232 8 +bigint try 1040.0 1110.0 248 9 +bigint plain 1009.9 1069.9 232 8 +bigint first 1021.4285714285714 1135.7142857142858 232 8 +none dynamic 341.73853211009174 370.63761467889907 0 0 +none typed 235.84246575342465 255.7054794520548 0 0 +none discard 236.07077625570776 242.9200913242009 0 0 +none try 235.3846153846154 236.26153846153846 0 0 +none plain 230.54725274725274 237.14065934065934 0 0 +none first 219.44820295983087 226.00211416490487 0 0 diff --git a/benchmark/convert-scalars-final-allocations.txt b/benchmark/convert-scalars-final-allocations.txt new file mode 100644 index 000000000..33cf76cd7 --- /dev/null +++ b/benchmark/convert-scalars-final-allocations.txt @@ -0,0 +1,113 @@ + +int + +float +Float64: 16 bytes + (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 + eval(m::Module, e::Any) at boot.jl:489 + +bigint +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at Py.jl:109 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at Py.jl:103 [inlined] + macro expansion at regions.jl:296 [inlined] + pyint(x::Py) at builtins.jl:689 + macro expansion at rules.jl:97 [inlined] + macro expansion at regions.jl:296 [inlined] + pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 + pyconvert_first at pyconvert.jl:305 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] + scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 + (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 + eval(m::Module, e::Any) at boot.jl:489 +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at regions.jl:296 [inlined] + pystr(x::Py) at builtins.jl:592 + pystr at builtins.jl:598 [inlined] + macro expansion at rules.jl:98 [inlined] + macro expansion at regions.jl:296 [inlined] + pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 + pyconvert_first at pyconvert.jl:305 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] + scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 + (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 + eval(m::Module, e::Any) at boot.jl:489 +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at regions.jl:296 [inlined] + pystr_asUTF8bytes(x::Py) at builtins.jl:600 + pystr_asstring(x::Py) at builtins.jl:603 + pystr at builtins.jl:598 [inlined] + macro expansion at rules.jl:98 [inlined] + macro expansion at regions.jl:296 [inlined] + pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 + pyconvert_first at pyconvert.jl:305 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] + scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 + (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 + eval(m::Module, e::Any) at boot.jl:489 +String: 70 bytes + pybytes_asUTF8string at builtins.jl:654 [inlined] + pystr_asstring(x::Py) at builtins.jl:604 + pystr at builtins.jl:598 [inlined] + macro expansion at rules.jl:98 [inlined] + macro expansion at regions.jl:296 [inlined] + pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 + pyconvert_first at pyconvert.jl:305 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] + scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 + (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 + eval(m::Module, e::Any) at boot.jl:489 +BigInt: 32 bytes + _ at gmp.jl:70 [inlined] + BigInt at gmp.jl:69 [inlined] + tryparse_internal(::Type{BigInt}, s::String, startpos::Int64, endpos::Int64, base_::Int64, raise::Bool) at gmp.jl:302 + macro expansion at rules.jl:100 [inlined] + macro expansion at regions.jl:296 [inlined] + pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 + pyconvert_first at pyconvert.jl:305 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] + scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 + (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 + eval(m::Module, e::Any) at boot.jl:489 + +none diff --git a/benchmark/convert-scalars-final-inference.txt b/benchmark/convert-scalars-final-inference.txt new file mode 100644 index 000000000..ec78abe6f --- /dev/null +++ b/benchmark/convert-scalars-final-inference.txt @@ -0,0 +1,663 @@ + +int: scalar_convert +MethodInstance for scalar_convert(::Val{Int64}, ::Py) + from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 +Static Parameters + T = Int64 +Arguments + #self#::Core.Const(Main.scalar_convert) + _::Core.Const(Val{Int64}()) + x::Py +Body::UNION{NOTHING, INT64} +1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) +│ %2 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ %3 = Main.nothing::Core.Const(nothing) +│ %4 = (%1)(%2, x, %3)::UNION{NOTHING, INT64} +└── return %4 + + +int: scalar_plain +MethodInstance for scalar_plain(::Val{Int64}, ::Py) + from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 +Static Parameters + T = Int64 +Arguments + #self#::Core.Const(Main.scalar_plain) + _::Core.Const(Val{Int64}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + @_7::Int64 + @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} +Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ %4 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %4 +2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %10 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ %11 = (%7)(%9, %10, x)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} +└── return %11 +3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%13)()) +│ %15 = task::Task +│ (state = (PythonCall.C.current_task_state)(%15)) +│ %17 = task::Task +│ %18 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%17, %18)) +4 ─ %20 = enter #7 +5 ─ (@_7 = -1) +│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %26 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ (@_8 = (%23)(%25, %26, x)) +│ (@_7 = 1) +└── $(Expr(:leave, :(%20))) +6 ─ goto #8 +7 ┄ %31 = task::Task +│ %32 = state::PythonCall.C.TaskState +│ %33 = token::Symbol +│ (PythonCall.C.exit_region)(%31, %32, %33) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%20))))) +└── Core.Const(:(return nothing)) +8 ┄ %38 = task::Task +│ %39 = state::PythonCall.C.TaskState +│ %40 = token::Symbol +│ (PythonCall.C.exit_region)(%38, %39, %40) +│ %42 = @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} +└── return %42 + + +int: scalar_first +MethodInstance for scalar_first(::Val{Int64}, ::Py) + from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 +Static Parameters + T = Int64 +Arguments + #self#::Core.Const(Main.scalar_first) + _::Core.Const(Val{Int64}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + selection::PythonCall.Convert.PyConvertSelection + ctx::PyConvertContext{Tuple{}} + @_9::Int64 + @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} +Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ Core.NewvarNode(:(selection)) +│ Core.NewvarNode(:(ctx)) +│ %6 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %6 +2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%8)()) +│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %13 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ %14 = Main.PythonCall::Core.Const(PythonCall) +│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) +│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%11)(%12, %13, %17)) +│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %22 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ %23 = selection::PythonCall.Convert.PyConvertSelection +│ %24 = (%20)(%21, %22, x, %23)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} +└── return %24 +3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%26)()) +│ %28 = task::Task +│ (state = (PythonCall.C.current_task_state)(%28)) +│ %30 = task::Task +│ %31 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%30, %31)) +4 ─ %33 = enter #7 +5 ─ (@_9 = -1) +│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%35)()) +│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %40 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ %41 = Main.PythonCall::Core.Const(PythonCall) +│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) +│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%38)(%39, %40, %44)) +│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %49 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ %50 = selection::PythonCall.Convert.PyConvertSelection +│ %51 = (%47)(%48, %49, x, %50)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} +│ (@_10 = %51) +│ (@_9 = 1) +└── $(Expr(:leave, :(%33))) +6 ─ goto #8 +7 ┄ %56 = task::Task +│ %57 = state::PythonCall.C.TaskState +│ %58 = token::Symbol +│ (PythonCall.C.exit_region)(%56, %57, %58) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%33))))) +└── Core.Const(:(return nothing)) +8 ┄ %63 = task::Task +│ %64 = state::PythonCall.C.TaskState +│ %65 = token::Symbol +│ (PythonCall.C.exit_region)(%63, %64, %65) +│ %67 = @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} +└── return %67 + + +float: scalar_convert +MethodInstance for scalar_convert(::Val{Float64}, ::Py) + from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 +Static Parameters + T = Float64 +Arguments + #self#::Core.Const(Main.scalar_convert) + _::Core.Const(Val{Float64}()) + x::Py +Body::UNION{NOTHING, FLOAT64} +1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) +│ %2 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ %3 = Main.nothing::Core.Const(nothing) +│ %4 = (%1)(%2, x, %3)::UNION{NOTHING, FLOAT64} +└── return %4 + + +float: scalar_plain +MethodInstance for scalar_plain(::Val{Float64}, ::Py) + from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 +Static Parameters + T = Float64 +Arguments + #self#::Core.Const(Main.scalar_plain) + _::Core.Const(Val{Float64}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + @_7::Int64 + @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} +Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ %4 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %4 +2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %10 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ %11 = (%7)(%9, %10, x)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} +└── return %11 +3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%13)()) +│ %15 = task::Task +│ (state = (PythonCall.C.current_task_state)(%15)) +│ %17 = task::Task +│ %18 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%17, %18)) +4 ─ %20 = enter #7 +5 ─ (@_7 = -1) +│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %26 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ (@_8 = (%23)(%25, %26, x)) +│ (@_7 = 1) +└── $(Expr(:leave, :(%20))) +6 ─ goto #8 +7 ┄ %31 = task::Task +│ %32 = state::PythonCall.C.TaskState +│ %33 = token::Symbol +│ (PythonCall.C.exit_region)(%31, %32, %33) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%20))))) +└── Core.Const(:(return nothing)) +8 ┄ %38 = task::Task +│ %39 = state::PythonCall.C.TaskState +│ %40 = token::Symbol +│ (PythonCall.C.exit_region)(%38, %39, %40) +│ %42 = @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} +└── return %42 + + +float: scalar_first +MethodInstance for scalar_first(::Val{Float64}, ::Py) + from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 +Static Parameters + T = Float64 +Arguments + #self#::Core.Const(Main.scalar_first) + _::Core.Const(Val{Float64}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + selection::PythonCall.Convert.PyConvertSelection + ctx::PyConvertContext{Tuple{}} + @_9::Int64 + @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} +Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ Core.NewvarNode(:(selection)) +│ Core.NewvarNode(:(ctx)) +│ %6 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %6 +2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%8)()) +│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %13 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ %14 = Main.PythonCall::Core.Const(PythonCall) +│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) +│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%11)(%12, %13, %17)) +│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %22 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ %23 = selection::PythonCall.Convert.PyConvertSelection +│ %24 = (%20)(%21, %22, x, %23)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} +└── return %24 +3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%26)()) +│ %28 = task::Task +│ (state = (PythonCall.C.current_task_state)(%28)) +│ %30 = task::Task +│ %31 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%30, %31)) +4 ─ %33 = enter #7 +5 ─ (@_9 = -1) +│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%35)()) +│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %40 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ %41 = Main.PythonCall::Core.Const(PythonCall) +│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) +│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%38)(%39, %40, %44)) +│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %49 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ %50 = selection::PythonCall.Convert.PyConvertSelection +│ %51 = (%47)(%48, %49, x, %50)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} +│ (@_10 = %51) +│ (@_9 = 1) +└── $(Expr(:leave, :(%33))) +6 ─ goto #8 +7 ┄ %56 = task::Task +│ %57 = state::PythonCall.C.TaskState +│ %58 = token::Symbol +│ (PythonCall.C.exit_region)(%56, %57, %58) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%33))))) +└── Core.Const(:(return nothing)) +8 ┄ %63 = task::Task +│ %64 = state::PythonCall.C.TaskState +│ %65 = token::Symbol +│ (PythonCall.C.exit_region)(%63, %64, %65) +│ %67 = @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} +└── return %67 + + +bigint: scalar_convert +MethodInstance for scalar_convert(::Val{BigInt}, ::Py) + from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 +Static Parameters + T = BigInt +Arguments + #self#::Core.Const(Main.scalar_convert) + _::Core.Const(Val{BigInt}()) + x::Py +Body::UNION{NOTHING, BIGINT} +1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) +│ %2 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ %3 = Main.nothing::Core.Const(nothing) +│ %4 = (%1)(%2, x, %3)::UNION{NOTHING, BIGINT} +└── return %4 + + +bigint: scalar_plain +MethodInstance for scalar_plain(::Val{BigInt}, ::Py) + from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 +Static Parameters + T = BigInt +Arguments + #self#::Core.Const(Main.scalar_plain) + _::Core.Const(Val{BigInt}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + @_7::Int64 + @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} +Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ %4 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %4 +2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %10 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ %11 = (%7)(%9, %10, x)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} +└── return %11 +3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%13)()) +│ %15 = task::Task +│ (state = (PythonCall.C.current_task_state)(%15)) +│ %17 = task::Task +│ %18 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%17, %18)) +4 ─ %20 = enter #7 +5 ─ (@_7 = -1) +│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %26 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ (@_8 = (%23)(%25, %26, x)) +│ (@_7 = 1) +└── $(Expr(:leave, :(%20))) +6 ─ goto #8 +7 ┄ %31 = task::Task +│ %32 = state::PythonCall.C.TaskState +│ %33 = token::Symbol +│ (PythonCall.C.exit_region)(%31, %32, %33) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%20))))) +└── Core.Const(:(return nothing)) +8 ┄ %38 = task::Task +│ %39 = state::PythonCall.C.TaskState +│ %40 = token::Symbol +│ (PythonCall.C.exit_region)(%38, %39, %40) +│ %42 = @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} +└── return %42 + + +bigint: scalar_first +MethodInstance for scalar_first(::Val{BigInt}, ::Py) + from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 +Static Parameters + T = BigInt +Arguments + #self#::Core.Const(Main.scalar_first) + _::Core.Const(Val{BigInt}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + selection::PythonCall.Convert.PyConvertSelection + ctx::PyConvertContext{Tuple{}} + @_9::Int64 + @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} +Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ Core.NewvarNode(:(selection)) +│ Core.NewvarNode(:(ctx)) +│ %6 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %6 +2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%8)()) +│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %13 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ %14 = Main.PythonCall::Core.Const(PythonCall) +│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) +│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%11)(%12, %13, %17)) +│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %22 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ %23 = selection::PythonCall.Convert.PyConvertSelection +│ %24 = (%20)(%21, %22, x, %23)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} +└── return %24 +3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%26)()) +│ %28 = task::Task +│ (state = (PythonCall.C.current_task_state)(%28)) +│ %30 = task::Task +│ %31 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%30, %31)) +4 ─ %33 = enter #7 +5 ─ (@_9 = -1) +│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%35)()) +│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %40 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ %41 = Main.PythonCall::Core.Const(PythonCall) +│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) +│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%38)(%39, %40, %44)) +│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %49 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ %50 = selection::PythonCall.Convert.PyConvertSelection +│ %51 = (%47)(%48, %49, x, %50)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} +│ (@_10 = %51) +│ (@_9 = 1) +└── $(Expr(:leave, :(%33))) +6 ─ goto #8 +7 ┄ %56 = task::Task +│ %57 = state::PythonCall.C.TaskState +│ %58 = token::Symbol +│ (PythonCall.C.exit_region)(%56, %57, %58) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%33))))) +└── Core.Const(:(return nothing)) +8 ┄ %63 = task::Task +│ %64 = state::PythonCall.C.TaskState +│ %65 = token::Symbol +│ (PythonCall.C.exit_region)(%63, %64, %65) +│ %67 = @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} +└── return %67 + + +none: scalar_convert +MethodInstance for scalar_convert(::Val{Nothing}, ::Py) + from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 +Static Parameters + T = Nothing +Arguments + #self#::Core.Const(Main.scalar_convert) + _::Core.Const(Val{Nothing}()) + x::Py +Body::Nothing +1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) +│ %2 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ %3 = Main.nothing::Core.Const(nothing) +│ %4 = (%1)(%2, x, %3)::Core.Const(nothing) +└── return %4 + + +none: scalar_plain +MethodInstance for scalar_plain(::Val{Nothing}, ::Py) + from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 +Static Parameters + T = Nothing +Arguments + #self#::Core.Const(Main.scalar_plain) + _::Core.Const(Val{Nothing}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + @_7::Int64 + @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} +Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ %4 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %4 +2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %10 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ %11 = (%7)(%9, %10, x)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} +└── return %11 +3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%13)()) +│ %15 = task::Task +│ (state = (PythonCall.C.current_task_state)(%15)) +│ %17 = task::Task +│ %18 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%17, %18)) +4 ─ %20 = enter #7 +5 ─ (@_7 = -1) +│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %26 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ (@_8 = (%23)(%25, %26, x)) +│ (@_7 = 1) +└── $(Expr(:leave, :(%20))) +6 ─ goto #8 +7 ┄ %31 = task::Task +│ %32 = state::PythonCall.C.TaskState +│ %33 = token::Symbol +│ (PythonCall.C.exit_region)(%31, %32, %33) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%20))))) +└── Core.Const(:(return nothing)) +8 ┄ %38 = task::Task +│ %39 = state::PythonCall.C.TaskState +│ %40 = token::Symbol +│ (PythonCall.C.exit_region)(%38, %39, %40) +│ %42 = @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} +└── return %42 + + +none: scalar_first +MethodInstance for scalar_first(::Val{Nothing}, ::Py) + from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 +Static Parameters + T = Nothing +Arguments + #self#::Core.Const(Main.scalar_first) + _::Core.Const(Val{Nothing}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + selection::PythonCall.Convert.PyConvertSelection + ctx::PyConvertContext{Tuple{}} + @_9::Int64 + @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} +Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ Core.NewvarNode(:(selection)) +│ Core.NewvarNode(:(ctx)) +│ %6 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %6 +2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%8)()) +│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %13 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ %14 = Main.PythonCall::Core.Const(PythonCall) +│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) +│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%11)(%12, %13, %17)) +│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %22 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ %23 = selection::PythonCall.Convert.PyConvertSelection +│ %24 = (%20)(%21, %22, x, %23)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} +└── return %24 +3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%26)()) +│ %28 = task::Task +│ (state = (PythonCall.C.current_task_state)(%28)) +│ %30 = task::Task +│ %31 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%30, %31)) +4 ─ %33 = enter #7 +5 ─ (@_9 = -1) +│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%35)()) +│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %40 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ %41 = Main.PythonCall::Core.Const(PythonCall) +│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) +│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%38)(%39, %40, %44)) +│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %49 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ %50 = selection::PythonCall.Convert.PyConvertSelection +│ %51 = (%47)(%48, %49, x, %50)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} +│ (@_10 = %51) +│ (@_9 = 1) +└── $(Expr(:leave, :(%33))) +6 ─ goto #8 +7 ┄ %56 = task::Task +│ %57 = state::PythonCall.C.TaskState +│ %58 = token::Symbol +│ (PythonCall.C.exit_region)(%56, %57, %58) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%33))))) +└── Core.Const(:(return nothing)) +8 ┄ %63 = task::Task +│ %64 = state::PythonCall.C.TaskState +│ %65 = token::Symbol +│ (PythonCall.C.exit_region)(%63, %64, %65) +│ %67 = @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} +└── return %67 diff --git a/benchmark/convert-scalars-final-repeat.tsv b/benchmark/convert-scalars-final-repeat.tsv new file mode 100644 index 000000000..e3ed91c32 --- /dev/null +++ b/benchmark/convert-scalars-final-repeat.tsv @@ -0,0 +1,16 @@ +round case min_ns median_ns bytes allocs +1 int 249.9974358974359 294.35641025641024 0 0 +1 float 250.91717791411043 295.0920245398773 0 0 +1 bigint 1059.95 1140.0 216 7 +1 none 230.32747252747254 271.4263736263736 0 0 +1 int_large 249.60574412532637 256.9190600522193 0 0 +2 int_large 249.5016501650165 286.1353135313531 0 0 +2 int 243.4543209876543 250.12345679012347 0 0 +2 float 251.1723237597911 295.5613577023499 0 0 +2 bigint 928.5238095238095 1000.0 216 7 +2 none 242.04275534441805 256.29216152019 0 0 +3 none 230.07090464547676 236.4278728606357 0 0 +3 int_large 243.60052219321148 286.42036553524804 0 0 +3 int 249.54109589041096 250.4543378995434 0 0 +3 float 250.39313984168865 258.30870712401054 0 0 +3 bigint 947.6190476190476 985.7142857142857 216 7 diff --git a/benchmark/convert-scalars-final.tsv b/benchmark/convert-scalars-final.tsv new file mode 100644 index 000000000..f932458a8 --- /dev/null +++ b/benchmark/convert-scalars-final.tsv @@ -0,0 +1,25 @@ +case path min_ns median_ns bytes allocs +int dynamic 352.6018957345972 404.2654028436019 0 0 +int typed 239.70702179176754 274.3317191283293 0 0 +int discard 240.91767554479418 268.2784503631961 0 0 +int try 237.2123287671233 243.83333333333334 0 0 +int plain 249.88111888111888 279.4848484848485 0 0 +int first 264.25113122171945 280.31447963800906 0 0 +float dynamic 351.1961722488038 384.688995215311 16 1 +float typed 239.85780885780886 271.09324009324007 0 0 +float discard 241.25641025641025 258.97202797202794 0 0 +float try 238.8575129533679 286.0077720207254 0 0 +float plain 266.559375 294.059375 0 0 +float first 264.8909574468085 284.0398936170213 0 0 +bigint dynamic 1219.9 1299.9 216 7 +bigint typed 943.4347826086956 1056.5217391304348 216 7 +bigint discard 991.304347826087 1060.8260869565217 216 7 +bigint try 943.3 973.3333333333334 232 8 +bigint plain 1005.2631578947369 1052.6315789473683 216 7 +bigint first 1037.4583333333333 1183.2916666666667 216 7 +none dynamic 389.4688995215311 412.4354066985646 0 0 +none typed 253.87899543378995 261.64383561643837 0 0 +none discard 228.47608695652173 229.12826086956522 0 0 +none try 228.44612068965517 247.41163793103448 0 0 +none plain 229.40941176470588 255.52941176470588 0 0 +none first 225.49667405764967 226.60532150776052 0 0 diff --git a/benchmark/convert-scalars-optimized-allocations.txt b/benchmark/convert-scalars-optimized-allocations.txt new file mode 100644 index 000000000..9d2a3f600 --- /dev/null +++ b/benchmark/convert-scalars-optimized-allocations.txt @@ -0,0 +1,113 @@ + +int + +float +Float64: 16 bytes + (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 + eval(m::Module, e::Any) at boot.jl:489 + +bigint +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:51 [inlined] + pynew at Py.jl:55 [inlined] + macro expansion at Py.jl:108 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at Py.jl:102 [inlined] + macro expansion at regions.jl:296 [inlined] + pyint(x::Py) at builtins.jl:689 + macro expansion at rules.jl:97 [inlined] + macro expansion at regions.jl:296 [inlined] + pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 + pyconvert_first at pyconvert.jl:288 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:305 + pytryconvert_raw at pyconvert.jl:324 [inlined] + macro expansion at pyconvert.jl:400 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:399 + #pyconvert#36 at pyconvert.jl:405 [inlined] + pyconvert at pyconvert.jl:405 [inlined] + scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 + (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 + eval(m::Module, e::Any) at boot.jl:489 +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:51 [inlined] + pynew at Py.jl:55 [inlined] + macro expansion at regions.jl:296 [inlined] + pystr(x::Py) at builtins.jl:592 + pystr at builtins.jl:598 [inlined] + macro expansion at rules.jl:98 [inlined] + macro expansion at regions.jl:296 [inlined] + pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 + pyconvert_first at pyconvert.jl:288 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:305 + pytryconvert_raw at pyconvert.jl:324 [inlined] + macro expansion at pyconvert.jl:400 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:399 + #pyconvert#36 at pyconvert.jl:405 [inlined] + pyconvert at pyconvert.jl:405 [inlined] + scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 + (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 + eval(m::Module, e::Any) at boot.jl:489 +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:51 [inlined] + pynew at Py.jl:55 [inlined] + macro expansion at regions.jl:296 [inlined] + pystr_asUTF8bytes(x::Py) at builtins.jl:600 + pystr_asstring(x::Py) at builtins.jl:603 + pystr at builtins.jl:598 [inlined] + macro expansion at rules.jl:98 [inlined] + macro expansion at regions.jl:296 [inlined] + pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 + pyconvert_first at pyconvert.jl:288 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:305 + pytryconvert_raw at pyconvert.jl:324 [inlined] + macro expansion at pyconvert.jl:400 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:399 + #pyconvert#36 at pyconvert.jl:405 [inlined] + pyconvert at pyconvert.jl:405 [inlined] + scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 + (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 + eval(m::Module, e::Any) at boot.jl:489 +String: 70 bytes + pybytes_asUTF8string at builtins.jl:654 [inlined] + pystr_asstring(x::Py) at builtins.jl:604 + pystr at builtins.jl:598 [inlined] + macro expansion at rules.jl:98 [inlined] + macro expansion at regions.jl:296 [inlined] + pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 + pyconvert_first at pyconvert.jl:288 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:305 + pytryconvert_raw at pyconvert.jl:324 [inlined] + macro expansion at pyconvert.jl:400 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:399 + #pyconvert#36 at pyconvert.jl:405 [inlined] + pyconvert at pyconvert.jl:405 [inlined] + scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 + (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 + eval(m::Module, e::Any) at boot.jl:489 +BigInt: 32 bytes + _ at gmp.jl:70 [inlined] + BigInt at gmp.jl:69 [inlined] + tryparse_internal(::Type{BigInt}, s::String, startpos::Int64, endpos::Int64, base_::Int64, raise::Bool) at gmp.jl:302 + macro expansion at rules.jl:100 [inlined] + macro expansion at regions.jl:296 [inlined] + pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 + pyconvert_first at pyconvert.jl:288 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:305 + pytryconvert_raw at pyconvert.jl:324 [inlined] + macro expansion at pyconvert.jl:400 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:399 + #pyconvert#36 at pyconvert.jl:405 [inlined] + pyconvert at pyconvert.jl:405 [inlined] + scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 + (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 + eval(m::Module, e::Any) at boot.jl:489 + +none diff --git a/benchmark/convert-scalars-optimized-inference.txt b/benchmark/convert-scalars-optimized-inference.txt new file mode 100644 index 000000000..ec78abe6f --- /dev/null +++ b/benchmark/convert-scalars-optimized-inference.txt @@ -0,0 +1,663 @@ + +int: scalar_convert +MethodInstance for scalar_convert(::Val{Int64}, ::Py) + from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 +Static Parameters + T = Int64 +Arguments + #self#::Core.Const(Main.scalar_convert) + _::Core.Const(Val{Int64}()) + x::Py +Body::UNION{NOTHING, INT64} +1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) +│ %2 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ %3 = Main.nothing::Core.Const(nothing) +│ %4 = (%1)(%2, x, %3)::UNION{NOTHING, INT64} +└── return %4 + + +int: scalar_plain +MethodInstance for scalar_plain(::Val{Int64}, ::Py) + from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 +Static Parameters + T = Int64 +Arguments + #self#::Core.Const(Main.scalar_plain) + _::Core.Const(Val{Int64}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + @_7::Int64 + @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} +Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ %4 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %4 +2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %10 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ %11 = (%7)(%9, %10, x)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} +└── return %11 +3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%13)()) +│ %15 = task::Task +│ (state = (PythonCall.C.current_task_state)(%15)) +│ %17 = task::Task +│ %18 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%17, %18)) +4 ─ %20 = enter #7 +5 ─ (@_7 = -1) +│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %26 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ (@_8 = (%23)(%25, %26, x)) +│ (@_7 = 1) +└── $(Expr(:leave, :(%20))) +6 ─ goto #8 +7 ┄ %31 = task::Task +│ %32 = state::PythonCall.C.TaskState +│ %33 = token::Symbol +│ (PythonCall.C.exit_region)(%31, %32, %33) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%20))))) +└── Core.Const(:(return nothing)) +8 ┄ %38 = task::Task +│ %39 = state::PythonCall.C.TaskState +│ %40 = token::Symbol +│ (PythonCall.C.exit_region)(%38, %39, %40) +│ %42 = @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} +└── return %42 + + +int: scalar_first +MethodInstance for scalar_first(::Val{Int64}, ::Py) + from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 +Static Parameters + T = Int64 +Arguments + #self#::Core.Const(Main.scalar_first) + _::Core.Const(Val{Int64}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + selection::PythonCall.Convert.PyConvertSelection + ctx::PyConvertContext{Tuple{}} + @_9::Int64 + @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} +Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ Core.NewvarNode(:(selection)) +│ Core.NewvarNode(:(ctx)) +│ %6 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %6 +2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%8)()) +│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %13 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ %14 = Main.PythonCall::Core.Const(PythonCall) +│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) +│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%11)(%12, %13, %17)) +│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %22 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ %23 = selection::PythonCall.Convert.PyConvertSelection +│ %24 = (%20)(%21, %22, x, %23)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} +└── return %24 +3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%26)()) +│ %28 = task::Task +│ (state = (PythonCall.C.current_task_state)(%28)) +│ %30 = task::Task +│ %31 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%30, %31)) +4 ─ %33 = enter #7 +5 ─ (@_9 = -1) +│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%35)()) +│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %40 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ %41 = Main.PythonCall::Core.Const(PythonCall) +│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) +│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%38)(%39, %40, %44)) +│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %49 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ %50 = selection::PythonCall.Convert.PyConvertSelection +│ %51 = (%47)(%48, %49, x, %50)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} +│ (@_10 = %51) +│ (@_9 = 1) +└── $(Expr(:leave, :(%33))) +6 ─ goto #8 +7 ┄ %56 = task::Task +│ %57 = state::PythonCall.C.TaskState +│ %58 = token::Symbol +│ (PythonCall.C.exit_region)(%56, %57, %58) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%33))))) +└── Core.Const(:(return nothing)) +8 ┄ %63 = task::Task +│ %64 = state::PythonCall.C.TaskState +│ %65 = token::Symbol +│ (PythonCall.C.exit_region)(%63, %64, %65) +│ %67 = @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} +└── return %67 + + +float: scalar_convert +MethodInstance for scalar_convert(::Val{Float64}, ::Py) + from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 +Static Parameters + T = Float64 +Arguments + #self#::Core.Const(Main.scalar_convert) + _::Core.Const(Val{Float64}()) + x::Py +Body::UNION{NOTHING, FLOAT64} +1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) +│ %2 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ %3 = Main.nothing::Core.Const(nothing) +│ %4 = (%1)(%2, x, %3)::UNION{NOTHING, FLOAT64} +└── return %4 + + +float: scalar_plain +MethodInstance for scalar_plain(::Val{Float64}, ::Py) + from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 +Static Parameters + T = Float64 +Arguments + #self#::Core.Const(Main.scalar_plain) + _::Core.Const(Val{Float64}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + @_7::Int64 + @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} +Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ %4 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %4 +2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %10 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ %11 = (%7)(%9, %10, x)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} +└── return %11 +3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%13)()) +│ %15 = task::Task +│ (state = (PythonCall.C.current_task_state)(%15)) +│ %17 = task::Task +│ %18 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%17, %18)) +4 ─ %20 = enter #7 +5 ─ (@_7 = -1) +│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %26 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ (@_8 = (%23)(%25, %26, x)) +│ (@_7 = 1) +└── $(Expr(:leave, :(%20))) +6 ─ goto #8 +7 ┄ %31 = task::Task +│ %32 = state::PythonCall.C.TaskState +│ %33 = token::Symbol +│ (PythonCall.C.exit_region)(%31, %32, %33) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%20))))) +└── Core.Const(:(return nothing)) +8 ┄ %38 = task::Task +│ %39 = state::PythonCall.C.TaskState +│ %40 = token::Symbol +│ (PythonCall.C.exit_region)(%38, %39, %40) +│ %42 = @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} +└── return %42 + + +float: scalar_first +MethodInstance for scalar_first(::Val{Float64}, ::Py) + from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 +Static Parameters + T = Float64 +Arguments + #self#::Core.Const(Main.scalar_first) + _::Core.Const(Val{Float64}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + selection::PythonCall.Convert.PyConvertSelection + ctx::PyConvertContext{Tuple{}} + @_9::Int64 + @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} +Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ Core.NewvarNode(:(selection)) +│ Core.NewvarNode(:(ctx)) +│ %6 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %6 +2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%8)()) +│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %13 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ %14 = Main.PythonCall::Core.Const(PythonCall) +│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) +│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%11)(%12, %13, %17)) +│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %22 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ %23 = selection::PythonCall.Convert.PyConvertSelection +│ %24 = (%20)(%21, %22, x, %23)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} +└── return %24 +3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%26)()) +│ %28 = task::Task +│ (state = (PythonCall.C.current_task_state)(%28)) +│ %30 = task::Task +│ %31 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%30, %31)) +4 ─ %33 = enter #7 +5 ─ (@_9 = -1) +│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%35)()) +│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %40 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ %41 = Main.PythonCall::Core.Const(PythonCall) +│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) +│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%38)(%39, %40, %44)) +│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %49 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ %50 = selection::PythonCall.Convert.PyConvertSelection +│ %51 = (%47)(%48, %49, x, %50)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} +│ (@_10 = %51) +│ (@_9 = 1) +└── $(Expr(:leave, :(%33))) +6 ─ goto #8 +7 ┄ %56 = task::Task +│ %57 = state::PythonCall.C.TaskState +│ %58 = token::Symbol +│ (PythonCall.C.exit_region)(%56, %57, %58) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%33))))) +└── Core.Const(:(return nothing)) +8 ┄ %63 = task::Task +│ %64 = state::PythonCall.C.TaskState +│ %65 = token::Symbol +│ (PythonCall.C.exit_region)(%63, %64, %65) +│ %67 = @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} +└── return %67 + + +bigint: scalar_convert +MethodInstance for scalar_convert(::Val{BigInt}, ::Py) + from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 +Static Parameters + T = BigInt +Arguments + #self#::Core.Const(Main.scalar_convert) + _::Core.Const(Val{BigInt}()) + x::Py +Body::UNION{NOTHING, BIGINT} +1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) +│ %2 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ %3 = Main.nothing::Core.Const(nothing) +│ %4 = (%1)(%2, x, %3)::UNION{NOTHING, BIGINT} +└── return %4 + + +bigint: scalar_plain +MethodInstance for scalar_plain(::Val{BigInt}, ::Py) + from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 +Static Parameters + T = BigInt +Arguments + #self#::Core.Const(Main.scalar_plain) + _::Core.Const(Val{BigInt}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + @_7::Int64 + @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} +Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ %4 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %4 +2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %10 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ %11 = (%7)(%9, %10, x)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} +└── return %11 +3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%13)()) +│ %15 = task::Task +│ (state = (PythonCall.C.current_task_state)(%15)) +│ %17 = task::Task +│ %18 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%17, %18)) +4 ─ %20 = enter #7 +5 ─ (@_7 = -1) +│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %26 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ (@_8 = (%23)(%25, %26, x)) +│ (@_7 = 1) +└── $(Expr(:leave, :(%20))) +6 ─ goto #8 +7 ┄ %31 = task::Task +│ %32 = state::PythonCall.C.TaskState +│ %33 = token::Symbol +│ (PythonCall.C.exit_region)(%31, %32, %33) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%20))))) +└── Core.Const(:(return nothing)) +8 ┄ %38 = task::Task +│ %39 = state::PythonCall.C.TaskState +│ %40 = token::Symbol +│ (PythonCall.C.exit_region)(%38, %39, %40) +│ %42 = @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} +└── return %42 + + +bigint: scalar_first +MethodInstance for scalar_first(::Val{BigInt}, ::Py) + from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 +Static Parameters + T = BigInt +Arguments + #self#::Core.Const(Main.scalar_first) + _::Core.Const(Val{BigInt}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + selection::PythonCall.Convert.PyConvertSelection + ctx::PyConvertContext{Tuple{}} + @_9::Int64 + @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} +Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ Core.NewvarNode(:(selection)) +│ Core.NewvarNode(:(ctx)) +│ %6 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %6 +2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%8)()) +│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %13 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ %14 = Main.PythonCall::Core.Const(PythonCall) +│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) +│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%11)(%12, %13, %17)) +│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %22 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ %23 = selection::PythonCall.Convert.PyConvertSelection +│ %24 = (%20)(%21, %22, x, %23)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} +└── return %24 +3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%26)()) +│ %28 = task::Task +│ (state = (PythonCall.C.current_task_state)(%28)) +│ %30 = task::Task +│ %31 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%30, %31)) +4 ─ %33 = enter #7 +5 ─ (@_9 = -1) +│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%35)()) +│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %40 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ %41 = Main.PythonCall::Core.Const(PythonCall) +│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) +│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%38)(%39, %40, %44)) +│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %49 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ %50 = selection::PythonCall.Convert.PyConvertSelection +│ %51 = (%47)(%48, %49, x, %50)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} +│ (@_10 = %51) +│ (@_9 = 1) +└── $(Expr(:leave, :(%33))) +6 ─ goto #8 +7 ┄ %56 = task::Task +│ %57 = state::PythonCall.C.TaskState +│ %58 = token::Symbol +│ (PythonCall.C.exit_region)(%56, %57, %58) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%33))))) +└── Core.Const(:(return nothing)) +8 ┄ %63 = task::Task +│ %64 = state::PythonCall.C.TaskState +│ %65 = token::Symbol +│ (PythonCall.C.exit_region)(%63, %64, %65) +│ %67 = @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} +└── return %67 + + +none: scalar_convert +MethodInstance for scalar_convert(::Val{Nothing}, ::Py) + from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 +Static Parameters + T = Nothing +Arguments + #self#::Core.Const(Main.scalar_convert) + _::Core.Const(Val{Nothing}()) + x::Py +Body::Nothing +1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) +│ %2 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ %3 = Main.nothing::Core.Const(nothing) +│ %4 = (%1)(%2, x, %3)::Core.Const(nothing) +└── return %4 + + +none: scalar_plain +MethodInstance for scalar_plain(::Val{Nothing}, ::Py) + from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 +Static Parameters + T = Nothing +Arguments + #self#::Core.Const(Main.scalar_plain) + _::Core.Const(Val{Nothing}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + @_7::Int64 + @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} +Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ %4 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %4 +2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %10 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ %11 = (%7)(%9, %10, x)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} +└── return %11 +3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%13)()) +│ %15 = task::Task +│ (state = (PythonCall.C.current_task_state)(%15)) +│ %17 = task::Task +│ %18 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%17, %18)) +4 ─ %20 = enter #7 +5 ─ (@_7 = -1) +│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %26 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ (@_8 = (%23)(%25, %26, x)) +│ (@_7 = 1) +└── $(Expr(:leave, :(%20))) +6 ─ goto #8 +7 ┄ %31 = task::Task +│ %32 = state::PythonCall.C.TaskState +│ %33 = token::Symbol +│ (PythonCall.C.exit_region)(%31, %32, %33) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%20))))) +└── Core.Const(:(return nothing)) +8 ┄ %38 = task::Task +│ %39 = state::PythonCall.C.TaskState +│ %40 = token::Symbol +│ (PythonCall.C.exit_region)(%38, %39, %40) +│ %42 = @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} +└── return %42 + + +none: scalar_first +MethodInstance for scalar_first(::Val{Nothing}, ::Py) + from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 +Static Parameters + T = Nothing +Arguments + #self#::Core.Const(Main.scalar_first) + _::Core.Const(Val{Nothing}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + selection::PythonCall.Convert.PyConvertSelection + ctx::PyConvertContext{Tuple{}} + @_9::Int64 + @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} +Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ Core.NewvarNode(:(selection)) +│ Core.NewvarNode(:(ctx)) +│ %6 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %6 +2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%8)()) +│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %13 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ %14 = Main.PythonCall::Core.Const(PythonCall) +│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) +│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%11)(%12, %13, %17)) +│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %22 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ %23 = selection::PythonCall.Convert.PyConvertSelection +│ %24 = (%20)(%21, %22, x, %23)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} +└── return %24 +3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%26)()) +│ %28 = task::Task +│ (state = (PythonCall.C.current_task_state)(%28)) +│ %30 = task::Task +│ %31 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%30, %31)) +4 ─ %33 = enter #7 +5 ─ (@_9 = -1) +│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%35)()) +│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %40 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ %41 = Main.PythonCall::Core.Const(PythonCall) +│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) +│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%38)(%39, %40, %44)) +│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %49 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ %50 = selection::PythonCall.Convert.PyConvertSelection +│ %51 = (%47)(%48, %49, x, %50)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} +│ (@_10 = %51) +│ (@_9 = 1) +└── $(Expr(:leave, :(%33))) +6 ─ goto #8 +7 ┄ %56 = task::Task +│ %57 = state::PythonCall.C.TaskState +│ %58 = token::Symbol +│ (PythonCall.C.exit_region)(%56, %57, %58) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%33))))) +└── Core.Const(:(return nothing)) +8 ┄ %63 = task::Task +│ %64 = state::PythonCall.C.TaskState +│ %65 = token::Symbol +│ (PythonCall.C.exit_region)(%63, %64, %65) +│ %67 = @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} +└── return %67 diff --git a/benchmark/convert-scalars-optimized-repeat.tsv b/benchmark/convert-scalars-optimized-repeat.tsv new file mode 100644 index 000000000..b8fe53c3c --- /dev/null +++ b/benchmark/convert-scalars-optimized-repeat.tsv @@ -0,0 +1,16 @@ +round case min_ns median_ns bytes allocs +1 int 240.89526184538653 249.62344139650872 0 0 +1 float 274.10688836104515 282.4228028503563 0 0 +1 bigint 959.9 1030.0 216 7 +1 none 226.5912087912088 252.3054945054945 0 0 +1 int_large 247.20983606557377 283.2754098360656 0 0 +2 int_large 247.43333333333334 267.94615384615383 0 0 +2 int 247.0296803652968 260.7283105022831 0 0 +2 float 246.38154613466335 247.38154613466335 0 0 +2 bigint 960.0 1000.0 216 7 +2 none 232.14855875831486 239.02217294900223 0 0 +3 none 232.3054945054945 238.6791208791209 0 0 +3 int_large 267.5785536159601 283.2917705735661 0 0 +3 int 274.51290322580644 283.2258064516129 0 0 +3 float 246.44416243654823 266.74873096446703 0 0 +3 bigint 990.0 1120.0 216 7 diff --git a/benchmark/convert-scalars-optimized.tsv b/benchmark/convert-scalars-optimized.tsv new file mode 100644 index 000000000..47860d4bd --- /dev/null +++ b/benchmark/convert-scalars-optimized.tsv @@ -0,0 +1,25 @@ +case path min_ns median_ns bytes allocs +int dynamic 349.04761904761904 388.8071428571428 0 0 +int typed 260.10372340425533 267.8164893617021 0 0 +int discard 247.65185185185186 254.320987654321 0 0 +int try 245.43150684931507 252.28310502283105 0 0 +int plain 239.49543378995435 265.5251141552511 0 0 +int first 232.5901234567901 258.02222222222224 0 0 +float dynamic 391.6617647058824 428.921568627451 16 1 +float typed 239.70702179176754 246.24455205811137 0 0 +float discard 246.61771561771562 254.7762237762238 0 0 +float try 238.84652278177458 272.8992805755396 0 0 +float plain 244.65320665083135 265.5558194774347 0 0 +float first 261.7409200968523 277.2397094430993 0 0 +bigint dynamic 1190.0 1260.0 216 7 +bigint typed 968.6875 1131.25 216 7 +bigint discard 949.9545454545455 1000.0 216 7 +bigint try 979.9333333333333 1033.3333333333333 232 8 +bigint plain 1059.0454545454545 1100.0 216 7 +bigint first 1023.0769230769231 1107.6923076923076 216 7 +none dynamic 341.00921658986175 369.12442396313367 0 0 +none typed 235.60554371002132 236.24733475479744 0 0 +none discard 229.86199095022624 235.97285067873304 0 0 +none try 234.34782608695653 261.08478260869566 0 0 +none plain 226.6945701357466 233.0316742081448 0 0 +none first 240.1652719665272 254.18410041841005 0 0 diff --git a/benchmark/convert-scalars-report.md b/benchmark/convert-scalars-report.md new file mode 100644 index 000000000..0ff34a0fc --- /dev/null +++ b/benchmark/convert-scalars-report.md @@ -0,0 +1,124 @@ +# Final scalar, result-representation and inference findings + +**Current update:** [convert-unwrapped-report.md](convert-unwrapped-report.md) +records minimal built-in result wrapping. Scalar allocation counts and public +inferred bounds remain unchanged; arrays/native containers lose their unnecessary +outer wrappers. Its focused validation passed 1,765 checks with one existing skip. + +This report uses the final working tree, including source aliases/shorthand and +the agreed numeric-source policy. It supersedes the earlier scalar-optimization +snapshots. [convert-report.md](convert-report.md) contains implementation details, +validation status, environment and reproduction. + +## Before/after cached conversion + +Times are nanoseconds: median of three serial trial minima from the shared +convert-final.jl harness. Trial order was reversed in the middle round. +There were no concurrent tests. Both versions used Julia 1.13.2 and the same +Python 3.15.0 executable. Allocation figures are Julia bytes/counts. + +| Target | Typed before ns | Typed after ns | Typed B / allocs before → after | Runtime-target before ns | Runtime-target after ns | +| --- | ---: | ---: | --- | ---: | ---: | +| Int | 223 | 240 | 0 / 0 → 0 / 0 | 341 | 360 | +| Integer | 590 | 242 | 0 / 0 → 0 / 0 | 705 | 361 | +| BigInt | 977 | 970 | 216 / 7 → 216 / 7 | 1140 | 1170 | +| Float64 | 240 | 240 | 0 / 0 → 0 / 0 | 352 | 362 | +| Bool | 232 | 254 | 0 / 0 → 0 / 0 | 349 | 369 | +| String | 297 | 311 | 48 / 2 → 48 / 2 | 406 | 429 | +| Nothing | 211 | 230 | 0 / 0 → 0 / 0 | 318 | 356 | +| Failure | 239 | 232 | 0 / 0 → 0 / 0 | 352 | 330 | + +The typed caller carries the requested type in Val. The runtime-target caller +interpolates a Julia Type object, which can hide its identity from inference. +In the latter, both revisions allocate an additional 16-byte box for Float64 +and for Int=10000; the value is outside Julia's small boxed-integer cache. +These caller effects must not be presented as conversion-only allocations. + +The final implementation's cached Int, Float64 and Nothing paths allocate zero. +BigInt has returned to the baseline 216 bytes / seven allocations. The initial +redesign's Float64 dispatch box was removed by checking the type before crossing +the dispatch return boundary; the integer shortcut uses the shared raw kernel +rather than allowing Some{BigInt} to escape. + +None is not slower than Int in the final paired measurements. The additional +interleaved scalar-only run produced typed minima of approximately 230–242 ns +for None, 243–250 ns for Int, and 250–251 ns for Float64. This run confirms +allocation behavior and variability; its timings are not mixed into the paired +before/after aggregate. + +## Public try-conversion and inference + +The final scalar-only run measured pytryconvert at zero allocations for Int, +Float64 and Nothing. BigInt try-conversion uses 232 bytes / eight allocations: +the additional 16-byte Some is part of the public success representation. +Ordinary pyconvert(BigInt, ...) uses 216 / seven. + +Final inferred public return bounds in convert-inference-final.txt: + +| Requested type | Return bound | +| --- | --- | +| Int | Union{Nothing,Some{Int}} | +| Integer | Union{Nothing,Some{T} where T<:Integer} | +| Union{Int,Nothing} | Union{Nothing,Some{Nothing},Some{Int}} | +| Any | Union{Nothing,Some} | + +Raw scalar dispatch remains bounded by the concrete value type and the private +failure sentinel. The Float64 allocation in the profiling artifact is at the +unspecialized profiling caller, not inside scalar dispatch. There is no +Some{BigInt} object in the ordinary conversion profile. + +## Result representation comparison + +convert-results.jl models the original Union{T,Unconverted} representation and +Some/nothing with specialized result bounds. It covers successful and failed +calls, direct results, results escaping through Ref{Any}, and typed loops. +These deliberately dynamic/escaping harnesses test return boundaries; their +figures are not lower bounds on optimized Some construction. + +Successful escaping model results, including the common Ref{Any} allocation: + +| Target | Raw B / allocs | Some B / allocs | +| --- | ---: | ---: | +| Int64 | 16 / 1 | 32 / 2 | +| Float64 | 48 / 3 | 48 / 3 | +| String | 16 / 1 | 48 / 3 | +| Vector{Int} | 16 / 1 | 48 / 3 | +| Integer | 16 / 1 | 32 / 2 | +| AbstractArray | 16 / 1 | 48 / 3 | +| Union{Int64,Nothing} | 16 / 1 | 32 / 2 | +| Any | 16 / 1 | 32 / 2 | + +Both 100-element typed loops allocate zero (roughly 288 ns raw versus 268 ns +Some in this short run). Do not interpret that small timing difference as a +general representation advantage. Full successful/failed and escaping/direct +measurements are in convert-results-final.tsv. + +The measurements justify the ergonomic Some/nothing API with optimized raw +internal dispatch. The earlier all-Some internal experiment introduced +per-element allocations and slowed large-vector conversion; its historical +artifacts are retained, while final container results are in the main report. + +## Numeric-source policy and validation + +Generic numbers.Real/Complex fallback rules now apply only to Python +float/complex sources. Integral and Rational sources retain exact intermediates; +supported NumPy scalars retain dedicated rules. Other numeric types require +explicit rules. An out-of-range integer can no longer decline exact conversion +and then succeed after float rounding. + +Tests include throwing __float__/__complex__ methods on integer/rational/custom +numeric sources, nonintegral fractions, float/complex subclasses, explicit rule +opt-in, NumPy scalars, singleton-rule mutations and inferred scalar returns. +Latest local validation: 605 conversion checks and 15 ordinary Python tests +passed, with no broken conversion checks. Final full suites and supported +version coverage are assigned to CI. + +## Artifacts and reproduction + +Use benchmark/run-convert-final.sh and summarize-convert-final.py as described +in the main report. The paired results live in convert-final-{before,after}-r*, +with source/environment records. The scalar-only diagnostic run uses +convert-scalars-final.tsv, -repeat.tsv, -inference.txt and -allocations.txt. +Representation and public inference outputs are convert-results-final.tsv and +convert-inference-final.txt. Earlier before/optimized/source-policy files are +historical snapshots, not current failures or current comparison tables. diff --git a/benchmark/convert-scalars-source-policy-allocations.txt b/benchmark/convert-scalars-source-policy-allocations.txt new file mode 100644 index 000000000..33cf76cd7 --- /dev/null +++ b/benchmark/convert-scalars-source-policy-allocations.txt @@ -0,0 +1,113 @@ + +int + +float +Float64: 16 bytes + (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 + eval(m::Module, e::Any) at boot.jl:489 + +bigint +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at Py.jl:109 [inlined] + macro expansion at regions.jl:296 [inlined] + macro expansion at Py.jl:103 [inlined] + macro expansion at regions.jl:296 [inlined] + pyint(x::Py) at builtins.jl:689 + macro expansion at rules.jl:97 [inlined] + macro expansion at regions.jl:296 [inlined] + pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 + pyconvert_first at pyconvert.jl:305 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] + scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 + (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 + eval(m::Module, e::Any) at boot.jl:489 +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at regions.jl:296 [inlined] + pystr(x::Py) at builtins.jl:592 + pystr at builtins.jl:598 [inlined] + macro expansion at rules.jl:98 [inlined] + macro expansion at regions.jl:296 [inlined] + pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 + pyconvert_first at pyconvert.jl:305 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] + scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 + (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 + eval(m::Module, e::Any) at boot.jl:489 +Py: 16 bytes + Py at types.jl:17 [inlined] + pynew at Py.jl:52 [inlined] + pynew at Py.jl:56 [inlined] + macro expansion at regions.jl:296 [inlined] + pystr_asUTF8bytes(x::Py) at builtins.jl:600 + pystr_asstring(x::Py) at builtins.jl:603 + pystr at builtins.jl:598 [inlined] + macro expansion at rules.jl:98 [inlined] + macro expansion at regions.jl:296 [inlined] + pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 + pyconvert_first at pyconvert.jl:305 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] + scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 + (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 + eval(m::Module, e::Any) at boot.jl:489 +String: 70 bytes + pybytes_asUTF8string at builtins.jl:654 [inlined] + pystr_asstring(x::Py) at builtins.jl:604 + pystr at builtins.jl:598 [inlined] + macro expansion at rules.jl:98 [inlined] + macro expansion at regions.jl:296 [inlined] + pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 + pyconvert_first at pyconvert.jl:305 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] + scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 + (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 + eval(m::Module, e::Any) at boot.jl:489 +BigInt: 32 bytes + _ at gmp.jl:70 [inlined] + BigInt at gmp.jl:69 [inlined] + tryparse_internal(::Type{BigInt}, s::String, startpos::Int64, endpos::Int64, base_::Int64, raise::Bool) at gmp.jl:302 + macro expansion at rules.jl:100 [inlined] + macro expansion at regions.jl:296 [inlined] + pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 + pyconvert_first at pyconvert.jl:305 [inlined] + pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:322 + pytryconvert_raw at pyconvert.jl:341 [inlined] + macro expansion at pyconvert.jl:417 [inlined] + macro expansion at regions.jl:302 [inlined] + pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:416 + #pyconvert#36 at pyconvert.jl:422 [inlined] + pyconvert at pyconvert.jl:422 [inlined] + scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 + (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 + eval(m::Module, e::Any) at boot.jl:489 + +none diff --git a/benchmark/convert-scalars-source-policy-inference.txt b/benchmark/convert-scalars-source-policy-inference.txt new file mode 100644 index 000000000..ec78abe6f --- /dev/null +++ b/benchmark/convert-scalars-source-policy-inference.txt @@ -0,0 +1,663 @@ + +int: scalar_convert +MethodInstance for scalar_convert(::Val{Int64}, ::Py) + from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 +Static Parameters + T = Int64 +Arguments + #self#::Core.Const(Main.scalar_convert) + _::Core.Const(Val{Int64}()) + x::Py +Body::UNION{NOTHING, INT64} +1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) +│ %2 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ %3 = Main.nothing::Core.Const(nothing) +│ %4 = (%1)(%2, x, %3)::UNION{NOTHING, INT64} +└── return %4 + + +int: scalar_plain +MethodInstance for scalar_plain(::Val{Int64}, ::Py) + from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 +Static Parameters + T = Int64 +Arguments + #self#::Core.Const(Main.scalar_plain) + _::Core.Const(Val{Int64}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + @_7::Int64 + @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} +Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ %4 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %4 +2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %10 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ %11 = (%7)(%9, %10, x)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} +└── return %11 +3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%13)()) +│ %15 = task::Task +│ (state = (PythonCall.C.current_task_state)(%15)) +│ %17 = task::Task +│ %18 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%17, %18)) +4 ─ %20 = enter #7 +5 ─ (@_7 = -1) +│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %26 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ (@_8 = (%23)(%25, %26, x)) +│ (@_7 = 1) +└── $(Expr(:leave, :(%20))) +6 ─ goto #8 +7 ┄ %31 = task::Task +│ %32 = state::PythonCall.C.TaskState +│ %33 = token::Symbol +│ (PythonCall.C.exit_region)(%31, %32, %33) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%20))))) +└── Core.Const(:(return nothing)) +8 ┄ %38 = task::Task +│ %39 = state::PythonCall.C.TaskState +│ %40 = token::Symbol +│ (PythonCall.C.exit_region)(%38, %39, %40) +│ %42 = @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} +└── return %42 + + +int: scalar_first +MethodInstance for scalar_first(::Val{Int64}, ::Py) + from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 +Static Parameters + T = Int64 +Arguments + #self#::Core.Const(Main.scalar_first) + _::Core.Const(Val{Int64}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + selection::PythonCall.Convert.PyConvertSelection + ctx::PyConvertContext{Tuple{}} + @_9::Int64 + @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} +Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ Core.NewvarNode(:(selection)) +│ Core.NewvarNode(:(ctx)) +│ %6 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %6 +2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%8)()) +│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %13 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ %14 = Main.PythonCall::Core.Const(PythonCall) +│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) +│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%11)(%12, %13, %17)) +│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %22 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ %23 = selection::PythonCall.Convert.PyConvertSelection +│ %24 = (%20)(%21, %22, x, %23)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} +└── return %24 +3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%26)()) +│ %28 = task::Task +│ (state = (PythonCall.C.current_task_state)(%28)) +│ %30 = task::Task +│ %31 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%30, %31)) +4 ─ %33 = enter #7 +5 ─ (@_9 = -1) +│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%35)()) +│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %40 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ %41 = Main.PythonCall::Core.Const(PythonCall) +│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) +│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%38)(%39, %40, %44)) +│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %49 = $(Expr(:static_parameter, 1))::Core.Const(Int64) +│ %50 = selection::PythonCall.Convert.PyConvertSelection +│ %51 = (%47)(%48, %49, x, %50)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} +│ (@_10 = %51) +│ (@_9 = 1) +└── $(Expr(:leave, :(%33))) +6 ─ goto #8 +7 ┄ %56 = task::Task +│ %57 = state::PythonCall.C.TaskState +│ %58 = token::Symbol +│ (PythonCall.C.exit_region)(%56, %57, %58) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%33))))) +└── Core.Const(:(return nothing)) +8 ┄ %63 = task::Task +│ %64 = state::PythonCall.C.TaskState +│ %65 = token::Symbol +│ (PythonCall.C.exit_region)(%63, %64, %65) +│ %67 = @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} +└── return %67 + + +float: scalar_convert +MethodInstance for scalar_convert(::Val{Float64}, ::Py) + from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 +Static Parameters + T = Float64 +Arguments + #self#::Core.Const(Main.scalar_convert) + _::Core.Const(Val{Float64}()) + x::Py +Body::UNION{NOTHING, FLOAT64} +1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) +│ %2 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ %3 = Main.nothing::Core.Const(nothing) +│ %4 = (%1)(%2, x, %3)::UNION{NOTHING, FLOAT64} +└── return %4 + + +float: scalar_plain +MethodInstance for scalar_plain(::Val{Float64}, ::Py) + from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 +Static Parameters + T = Float64 +Arguments + #self#::Core.Const(Main.scalar_plain) + _::Core.Const(Val{Float64}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + @_7::Int64 + @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} +Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ %4 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %4 +2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %10 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ %11 = (%7)(%9, %10, x)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} +└── return %11 +3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%13)()) +│ %15 = task::Task +│ (state = (PythonCall.C.current_task_state)(%15)) +│ %17 = task::Task +│ %18 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%17, %18)) +4 ─ %20 = enter #7 +5 ─ (@_7 = -1) +│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %26 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ (@_8 = (%23)(%25, %26, x)) +│ (@_7 = 1) +└── $(Expr(:leave, :(%20))) +6 ─ goto #8 +7 ┄ %31 = task::Task +│ %32 = state::PythonCall.C.TaskState +│ %33 = token::Symbol +│ (PythonCall.C.exit_region)(%31, %32, %33) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%20))))) +└── Core.Const(:(return nothing)) +8 ┄ %38 = task::Task +│ %39 = state::PythonCall.C.TaskState +│ %40 = token::Symbol +│ (PythonCall.C.exit_region)(%38, %39, %40) +│ %42 = @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} +└── return %42 + + +float: scalar_first +MethodInstance for scalar_first(::Val{Float64}, ::Py) + from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 +Static Parameters + T = Float64 +Arguments + #self#::Core.Const(Main.scalar_first) + _::Core.Const(Val{Float64}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + selection::PythonCall.Convert.PyConvertSelection + ctx::PyConvertContext{Tuple{}} + @_9::Int64 + @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} +Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ Core.NewvarNode(:(selection)) +│ Core.NewvarNode(:(ctx)) +│ %6 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %6 +2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%8)()) +│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %13 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ %14 = Main.PythonCall::Core.Const(PythonCall) +│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) +│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%11)(%12, %13, %17)) +│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %22 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ %23 = selection::PythonCall.Convert.PyConvertSelection +│ %24 = (%20)(%21, %22, x, %23)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} +└── return %24 +3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%26)()) +│ %28 = task::Task +│ (state = (PythonCall.C.current_task_state)(%28)) +│ %30 = task::Task +│ %31 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%30, %31)) +4 ─ %33 = enter #7 +5 ─ (@_9 = -1) +│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%35)()) +│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %40 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ %41 = Main.PythonCall::Core.Const(PythonCall) +│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) +│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%38)(%39, %40, %44)) +│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %49 = $(Expr(:static_parameter, 1))::Core.Const(Float64) +│ %50 = selection::PythonCall.Convert.PyConvertSelection +│ %51 = (%47)(%48, %49, x, %50)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} +│ (@_10 = %51) +│ (@_9 = 1) +└── $(Expr(:leave, :(%33))) +6 ─ goto #8 +7 ┄ %56 = task::Task +│ %57 = state::PythonCall.C.TaskState +│ %58 = token::Symbol +│ (PythonCall.C.exit_region)(%56, %57, %58) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%33))))) +└── Core.Const(:(return nothing)) +8 ┄ %63 = task::Task +│ %64 = state::PythonCall.C.TaskState +│ %65 = token::Symbol +│ (PythonCall.C.exit_region)(%63, %64, %65) +│ %67 = @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} +└── return %67 + + +bigint: scalar_convert +MethodInstance for scalar_convert(::Val{BigInt}, ::Py) + from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 +Static Parameters + T = BigInt +Arguments + #self#::Core.Const(Main.scalar_convert) + _::Core.Const(Val{BigInt}()) + x::Py +Body::UNION{NOTHING, BIGINT} +1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) +│ %2 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ %3 = Main.nothing::Core.Const(nothing) +│ %4 = (%1)(%2, x, %3)::UNION{NOTHING, BIGINT} +└── return %4 + + +bigint: scalar_plain +MethodInstance for scalar_plain(::Val{BigInt}, ::Py) + from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 +Static Parameters + T = BigInt +Arguments + #self#::Core.Const(Main.scalar_plain) + _::Core.Const(Val{BigInt}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + @_7::Int64 + @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} +Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ %4 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %4 +2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %10 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ %11 = (%7)(%9, %10, x)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} +└── return %11 +3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%13)()) +│ %15 = task::Task +│ (state = (PythonCall.C.current_task_state)(%15)) +│ %17 = task::Task +│ %18 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%17, %18)) +4 ─ %20 = enter #7 +5 ─ (@_7 = -1) +│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %26 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ (@_8 = (%23)(%25, %26, x)) +│ (@_7 = 1) +└── $(Expr(:leave, :(%20))) +6 ─ goto #8 +7 ┄ %31 = task::Task +│ %32 = state::PythonCall.C.TaskState +│ %33 = token::Symbol +│ (PythonCall.C.exit_region)(%31, %32, %33) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%20))))) +└── Core.Const(:(return nothing)) +8 ┄ %38 = task::Task +│ %39 = state::PythonCall.C.TaskState +│ %40 = token::Symbol +│ (PythonCall.C.exit_region)(%38, %39, %40) +│ %42 = @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} +└── return %42 + + +bigint: scalar_first +MethodInstance for scalar_first(::Val{BigInt}, ::Py) + from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 +Static Parameters + T = BigInt +Arguments + #self#::Core.Const(Main.scalar_first) + _::Core.Const(Val{BigInt}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + selection::PythonCall.Convert.PyConvertSelection + ctx::PyConvertContext{Tuple{}} + @_9::Int64 + @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} +Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ Core.NewvarNode(:(selection)) +│ Core.NewvarNode(:(ctx)) +│ %6 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %6 +2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%8)()) +│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %13 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ %14 = Main.PythonCall::Core.Const(PythonCall) +│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) +│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%11)(%12, %13, %17)) +│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %22 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ %23 = selection::PythonCall.Convert.PyConvertSelection +│ %24 = (%20)(%21, %22, x, %23)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} +└── return %24 +3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%26)()) +│ %28 = task::Task +│ (state = (PythonCall.C.current_task_state)(%28)) +│ %30 = task::Task +│ %31 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%30, %31)) +4 ─ %33 = enter #7 +5 ─ (@_9 = -1) +│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%35)()) +│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %40 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ %41 = Main.PythonCall::Core.Const(PythonCall) +│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) +│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%38)(%39, %40, %44)) +│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %49 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) +│ %50 = selection::PythonCall.Convert.PyConvertSelection +│ %51 = (%47)(%48, %49, x, %50)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} +│ (@_10 = %51) +│ (@_9 = 1) +└── $(Expr(:leave, :(%33))) +6 ─ goto #8 +7 ┄ %56 = task::Task +│ %57 = state::PythonCall.C.TaskState +│ %58 = token::Symbol +│ (PythonCall.C.exit_region)(%56, %57, %58) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%33))))) +└── Core.Const(:(return nothing)) +8 ┄ %63 = task::Task +│ %64 = state::PythonCall.C.TaskState +│ %65 = token::Symbol +│ (PythonCall.C.exit_region)(%63, %64, %65) +│ %67 = @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} +└── return %67 + + +none: scalar_convert +MethodInstance for scalar_convert(::Val{Nothing}, ::Py) + from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 +Static Parameters + T = Nothing +Arguments + #self#::Core.Const(Main.scalar_convert) + _::Core.Const(Val{Nothing}()) + x::Py +Body::Nothing +1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) +│ %2 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ %3 = Main.nothing::Core.Const(nothing) +│ %4 = (%1)(%2, x, %3)::Core.Const(nothing) +└── return %4 + + +none: scalar_plain +MethodInstance for scalar_plain(::Val{Nothing}, ::Py) + from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 +Static Parameters + T = Nothing +Arguments + #self#::Core.Const(Main.scalar_plain) + _::Core.Const(Val{Nothing}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + @_7::Int64 + @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} +Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ %4 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %4 +2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %10 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ %11 = (%7)(%9, %10, x)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} +└── return %11 +3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%13)()) +│ %15 = task::Task +│ (state = (PythonCall.C.current_task_state)(%15)) +│ %17 = task::Task +│ %18 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%17, %18)) +4 ─ %20 = enter #7 +5 ─ (@_7 = -1) +│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) +│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) +│ %26 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ (@_8 = (%23)(%25, %26, x)) +│ (@_7 = 1) +└── $(Expr(:leave, :(%20))) +6 ─ goto #8 +7 ┄ %31 = task::Task +│ %32 = state::PythonCall.C.TaskState +│ %33 = token::Symbol +│ (PythonCall.C.exit_region)(%31, %32, %33) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%20))))) +└── Core.Const(:(return nothing)) +8 ┄ %38 = task::Task +│ %39 = state::PythonCall.C.TaskState +│ %40 = token::Symbol +│ (PythonCall.C.exit_region)(%38, %39, %40) +│ %42 = @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} +└── return %42 + + +none: scalar_first +MethodInstance for scalar_first(::Val{Nothing}, ::Py) + from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 +Static Parameters + T = Nothing +Arguments + #self#::Core.Const(Main.scalar_first) + _::Core.Const(Val{Nothing}()) + x::Py +Locals + token::Symbol + state::PythonCall.C.TaskState + task::Task + selection::PythonCall.Convert.PyConvertSelection + ctx::PyConvertContext{Tuple{}} + @_9::Int64 + @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} +Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} +1 ─ Core.NewvarNode(:(token)) +│ Core.NewvarNode(:(state)) +│ Core.NewvarNode(:(task)) +│ Core.NewvarNode(:(selection)) +│ Core.NewvarNode(:(ctx)) +│ %6 = (PythonCall.C.has_tstate)()::Bool +└── goto #3 if not %6 +2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%8)()) +│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %13 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ %14 = Main.PythonCall::Core.Const(PythonCall) +│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) +│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%11)(%12, %13, %17)) +│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %22 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ %23 = selection::PythonCall.Convert.PyConvertSelection +│ %24 = (%20)(%21, %22, x, %23)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} +└── return %24 +3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) +│ (task = (%26)()) +│ %28 = task::Task +│ (state = (PythonCall.C.current_task_state)(%28)) +│ %30 = task::Task +│ %31 = state::PythonCall.C.TaskState +└── (token = (PythonCall.C.enter_region)(%30, %31)) +4 ─ %33 = enter #7 +5 ─ (@_9 = -1) +│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) +│ (ctx = (%35)()) +│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) +│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %40 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ %41 = Main.PythonCall::Core.Const(PythonCall) +│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) +│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) +│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} +│ (selection = (%38)(%39, %40, %44)) +│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) +│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) +│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) +│ %49 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) +│ %50 = selection::PythonCall.Convert.PyConvertSelection +│ %51 = (%47)(%48, %49, x, %50)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} +│ (@_10 = %51) +│ (@_9 = 1) +└── $(Expr(:leave, :(%33))) +6 ─ goto #8 +7 ┄ %56 = task::Task +│ %57 = state::PythonCall.C.TaskState +│ %58 = token::Symbol +│ (PythonCall.C.exit_region)(%56, %57, %58) +│ Base.rethrow() +│ Core.Const(:($(Expr(:pop_exception, :(%33))))) +└── Core.Const(:(return nothing)) +8 ┄ %63 = task::Task +│ %64 = state::PythonCall.C.TaskState +│ %65 = token::Symbol +│ (PythonCall.C.exit_region)(%63, %64, %65) +│ %67 = @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} +└── return %67 diff --git a/benchmark/convert-scalars-source-policy-repeat.tsv b/benchmark/convert-scalars-source-policy-repeat.tsv new file mode 100644 index 000000000..f743cbdba --- /dev/null +++ b/benchmark/convert-scalars-source-policy-repeat.tsv @@ -0,0 +1,16 @@ +round case min_ns median_ns bytes allocs +1 int 240.95744680851064 292.8164893617021 0 0 +1 float 270.25384615384615 304.1 0 0 +1 bigint 1085.642857142857 2085.714285714286 216 7 +1 none 234.72307692307692 278.2395604395604 0 0 +1 int_large 241.02307692307693 268.9717948717949 0 0 +2 int_large 275.7210144927536 292.7536231884058 0 0 +2 int 241.43493150684932 255.81849315068493 0 0 +2 float 242.56153846153848 284.87051282051283 0 0 +2 bigint 1000.0 1110.0 216 7 +2 none 228.56923076923076 261.756043956044 0 0 +3 none 228.78947368421052 278.6377708978328 0 0 +3 int_large 247.6749226006192 284.20743034055727 0 0 +3 int 247.39595375722544 302.8901734104046 0 0 +3 float 249.70294117647057 317.6470588235294 0 0 +3 bigint 1080.0 1260.0 216 7 diff --git a/benchmark/convert-scalars-source-policy.tsv b/benchmark/convert-scalars-source-policy.tsv new file mode 100644 index 000000000..dff71638a --- /dev/null +++ b/benchmark/convert-scalars-source-policy.tsv @@ -0,0 +1,25 @@ +case path min_ns median_ns bytes allocs +int dynamic 354.97156398104266 395.25592417061614 0 0 +int typed 241.40193704600483 242.37046004842614 0 0 +int discard 236.4484412470024 250.11870503597123 0 0 +int try 233.2517814726841 266.0332541567696 0 0 +int plain 245.24660633484163 264.70361990950227 0 0 +int first 248.70474137931035 262.9288793103448 0 0 +float dynamic 377.9856459330144 417.70334928229664 16 1 +float typed 241.23456790123456 258.2691358024691 0 0 +float discard 237.5283950617284 254.56543209876543 0 0 +float try 235.02073732718895 270.0437788018433 0 0 +float plain 241.64406779661016 263.9200968523002 0 0 +float first 233.7876712328767 260.5 0 0 +bigint dynamic 1080.0 1180.0 216 7 +bigint typed 1041.6666666666667 1150.0 216 7 +bigint discard 1050.0 1116.6666666666667 216 7 +bigint try 962.4375 1006.25 232 8 +bigint plain 1037.5 1100.0 216 7 +bigint first 1058.3333333333333 1133.25 216 7 +none dynamic 363.46153846153845 383.1730769230769 0 0 +none typed 236.60878661087867 256.6924686192469 0 0 +none discard 230.65 231.08478260869566 0 0 +none try 231.08695652173913 238.2586956521739 0 0 +none plain 229.66813186813187 263.07472527472527 0 0 +none first 246.02301255230125 260.8765690376569 0 0 diff --git a/benchmark/convert-scalars.jl b/benchmark/convert-scalars.jl new file mode 100644 index 000000000..211bfaa22 --- /dev/null +++ b/benchmark/convert-scalars.jl @@ -0,0 +1,80 @@ +# Run in the benchmark environment with an optional output label. +# Val keeps the requested type visible to the benchmark caller's inference. +using PythonCall, BenchmarkTools, InteractiveUtils, Profile +const ScalarConvert = PythonCall.Convert +scalar_convert(::Val{T}, x) where T = pyconvert(T, x, nothing) +scalar_sink(::Val{T}, x) where T = (pyconvert(T, x, nothing); nothing) +scalar_try(::Val{T}, x) where T = pytryconvert(T, x) +function scalar_plain(::Val{T}, x) where T + @pyregion ScalarConvert.pytryconvert_plain(PyConvertContext(), T, x) +end +function scalar_first(::Val{T}, x) where T + @pyregion begin + ctx = PyConvertContext() + selection = ScalarConvert.pyconvert_selection(ctx, T, PythonCall.C.Py_Type(x)) + ScalarConvert.pyconvert_first(ctx, T, x, selection) + end +end + +label = isempty(ARGS) ? "current" : first(ARGS) +fixtures = [("int", Int, pyint(42)), ("float", Float64, pyfloat(1.5)), + ("bigint", BigInt, pyint(big(2)^200)), + ("none", Nothing, pybuiltins.None)] +open(joinpath(@__DIR__, "convert-scalars-$label.tsv"), "w") do io + println(io, "case\tpath\tmin_ns\tmedian_ns\tbytes\tallocs") + for (name, T, x) in fixtures + tag = Val(T) + scalar_convert(tag, x) + dynamic = @benchmark pyconvert($T, $x, nothing) seconds=0.5 samples=2000 + m, d = minimum(dynamic), median(dynamic) + println(io, "$name\tdynamic\t$(m.time)\t$(d.time)\t$(m.memory)\t$(m.allocs)") + for (path, f) in (("typed", scalar_convert), ("discard", scalar_sink), + ("try", scalar_try), ("plain", scalar_plain), + ("first", scalar_first)) + trial = @benchmark $f($tag, $x) seconds=0.5 samples=2000 + m, d = minimum(trial), median(trial) + println(io, "$name\t$path\t$(m.time)\t$(d.time)\t$(m.memory)\t$(m.allocs)") + end + flush(io) + end +end +open(joinpath(@__DIR__, "convert-scalars-$label-inference.txt"), "w") do io + for (name, T, x) in fixtures, f in (scalar_convert, scalar_plain, scalar_first) + println(io, "\n$name: $f") + inferred = IOBuffer() + code_warntype(inferred, f, Tuple{Val{T},Py}; debuginfo=:none) + println(io, rstrip(String(take!(inferred)))) + end +end +open(joinpath(@__DIR__, "convert-scalars-$label-allocations.txt"), "w") do io + for (name, T, x) in fixtures + tag = Val(T) + scalar_convert(tag,x) + Profile.Allocs.clear() + Profile.Allocs.@profile sample_rate=1.0 scalar_convert(tag,x) + println(io, "\n$name") + for a in Profile.Allocs.fetch().allocs + println(io, "$(a.type): $(a.size) bytes") + for frame in a.stacktrace + file = string(frame.file) + if occursin("PythonCall",file) || occursin("gmp",file) || occursin("boot.jl",file) + println(io, " ", frame) + end + end + end + end +end + +# Interleave the important public calls so one unusually fast/slow short trial +# does not determine the comparison of None with Int. Include an Int outside +# Julia's small boxed-integer cache to expose otherwise hidden boxing. +open(joinpath(@__DIR__, "convert-scalars-$label-repeat.tsv"), "w") do io + println(io,"round\tcase\tmin_ns\tmedian_ns\tbytes\tallocs") + repeated=[fixtures; [("int_large",Int,pyint(10000))]] + for round=1:3, (name,T,x) in circshift(repeated,round-1) + tag=Val(T) + trial=@benchmark scalar_convert($tag,$x) seconds=0.5 samples=5000 + m,d=minimum(trial),median(trial) + println(io,"$round\t$name\t$(m.time)\t$(d.time)\t$(m.memory)\t$(m.allocs)") + end +end diff --git a/benchmark/convert-unwrapped-report.md b/benchmark/convert-unwrapped-report.md new file mode 100644 index 000000000..a174c575d --- /dev/null +++ b/benchmark/convert-unwrapped-report.md @@ -0,0 +1,119 @@ +# Minimal rule-result wrapping + +The optimization succeeds: ordinary built-in rules now return their values +directly, wrapping only successful nothing/Some values. Public pytryconvert +continues to wrap every success. No registry, ordering, scope, preference or +failure/exception policy changed, and no additional fast path was introduced. + +This report supersedes affected allocation/timing results in the earlier full +benchmark refresh. Its baseline is the implementation immediately before this +optimization, **not original v1**. + +## Change and validation + +The internal success helper returns ordinary values directly; its Nothing/Some +method wraps them once. Internal result readers accept both forms. Checked Julia +conversion uses this encoding, and vector/dictionary/integer rules no longer +construct unconditional Some results. Existing array builders/rules already use +these helpers, so they benefit without an array-specific implementation. + +Only src/Convert/pyconvert.jl and rules.jl change at runtime. The isolated diff +is saved as convert-unwrapped.patch. Source-author documentation now recommends +ordinary success values. Tests exercise successful nothing, nested Some, +wrapped Julia values and nested native containers, preserving exact values. + +Focused conversion, Python-wrapper and Julia-wrapper tests: **1,765 passed, +one existing optional-dependency skip** (the NumPy copy=False test is gated by +Setup.devdeps with the Null backend). Full suites/version coverage remain for CI. + +Inferred public try-conversion bounds remain unchanged for Int, Integer, +Union{Int,Nothing} and Any. The generic array rule now infers +Union{Nothing,Array}, rather than an existential Some-wrapped array. Arrays +still have runtime-discovered element/rank types, but their existing object +references can cross that boundary directly. + +## Method + +Three sequential before/after rounds on Julia 1.13.2, Python 3.15.0, NumPy 2.5.4 +and BenchmarkTools 1.8.0, with no concurrent tests. The saved pre-change source +was developed into a separate environment. Round order: before/after, +after/before, before/after. Both use the same Python executable/Null backend. + +Times are microseconds: median of three trial minima, using up to 5,000 samples / +one second per warm trial. Julia bytes/counts exclude Python allocations. +Source paths/fingerprints, trial medians and round ranges are retained. These +short runs do not establish confidence intervals. The unchanged DAG/cold-path +mechanism was not remeasured in this follow-up. + +## Arrays + +| Case | Before us | After us | Change | Before B / allocs | After B / allocs | +| --- | ---: | ---: | ---: | ---: | ---: | +| Buffer-only native | 7.325 | 7.150 | -2.4% | 8856 / 26 | 8712 / 23 | +| Buffer-only wrapper | 5.583 | 5.283 | -5.4% | 768 / 22 | 640 / 20 | +| Interface-only native | 22.200 | 21.700 | -2.3% | 9368 / 55 | 9224 / 52 | +| Array-method-only native | 8.133 | 7.633 | -6.1% | 9016 / 30 | 8872 / 27 | +| ndarray native | 4.867 | 4.686 | -3.7% | 8888 / 23 | 8744 / 20 | +| ndarray wrapper | 3.388 | 3.288 | -3.0% | 800 / 19 | 672 / 17 | + +All six cases remove the predicted 128 bytes / two objects for wrappers, +144 bytes / three objects for native arrays. Their allocation counts/bytes +now match the original-v1 protocol fixtures. This does not establish timing +equivalence to original v1; this experiment isolates the newer wrapper change. + +Profile.Allocs confirms the disappearance of Some{PyArray{...}}, the additional +boxed PyArray during unwrapping, and Some{Vector{T}} for native copying. The +post-change profile contains no Some objects for the four profiled array cases. +See convert-array-allocations-unwrapped.txt; the earlier pre-change stacks are +in convert-array-allocations-after.txt. + +## Other containers and scalars + +| Case | Before us | After us | Change | Before B / allocs | After B / allocs | +| --- | ---: | ---: | ---: | ---: | ---: | +| Vector, 10 integers | 7.120 | 6.560 | -7.9% | 720 / 18 | 704 / 17 | +| Vector, 10,000 integers | 4714.836 | 4624.435 | -1.9% | 513880 / 19508 | 513864 / 19507 | +| Vector{Int}, 10,000 integers | 4084.732 | 4036.031 | -1.2% | 362024 / 10018 | 362008 / 10017 | +| Nested concrete vectors | 6.950 | 6.920 | -0.4% | 768 / 29 | 720 / 26 | +| Nested Any conversion | 10.800 | 9.800 | -9.3% | 864 / 32 | 816 / 29 | +| Dict, inferred values | 6.480 | 6.540 | +0.9% | 1280 / 24 | 1264 / 23 | +| Dict{String,Float64} | 3.675 | 3.613 | -1.7% | 672 / 16 | 656 / 15 | +| Empty Vector | 1.240 | 1.130 | -8.9% | 112 / 5 | 96 / 4 | +| Empty Dict | 1.040 | 1.036 | -0.3% | 208 / 5 | 192 / 4 | + +Each native container loses its outer 16-byte result wrapper; nested vectors +lose one per converted vector. Timing changes vary, including the slightly +slower inferred dictionary despite fewer allocations. Do not infer a fixed +speedup from removing one allocation. + +Cached Int/Float64/Nothing remain allocation-free; BigInt remains 216 bytes / +seven allocations. Their typed minima before/after are 241/240 ns, 240/237 ns, +232/232 ns and 935/980 ns respectively. BigInt's +4.8% and incompatible-string +failure's +3.4% remain reported in the summary; round ranges overlap and no +additional allocations or inferred-type regressions were found. Other small +scalar timing changes are similarly not treated as established improvements. + +## Artifacts and reproduction + +Current data: convert-final-unwrapped-{before,after}-r{1,2,3}.tsv and +convert-expanded-unwrapped-{before,after}-r{1,2,3}.tsv, each with an environment +record. The aggregate is convert-unwrapped-summary.tsv (43 cases/modes). +Both revisions passed all benchmark fixture assertions. Allocation differences +are constant across all three rounds. + +Reconstruct the pre-change source by copying the current checkout and reversing +convert-unwrapped.patch **inside that copy**. Develop it into an isolated Julia +environment with BenchmarkTools 1.8.0. For each revision/round, sequentially run: + +~~~sh +julia --project=/path/to/revision-env benchmark/convert-final.jl unwrapped-before-r1 +julia --project=/path/to/revision-env benchmark/convert-expanded.jl unwrapped-before-r1 warm +~~~ + +Use labels before/after and rounds 1/2/3, with the order described above; keep +the same installed Python/backend for both revisions. Then aggregate/profile: + +~~~sh +python3 benchmark/summarize-convert-final.py unwrapped +julia --project=benchmark benchmark/convert-array-allocations.jl unwrapped +~~~ diff --git a/benchmark/convert-unwrapped-summary.tsv b/benchmark/convert-unwrapped-summary.tsv new file mode 100644 index 000000000..7778f25a2 --- /dev/null +++ b/benchmark/convert-unwrapped-summary.tsv @@ -0,0 +1,44 @@ +group case mode before_ns after_ns change_percent before_p50_ns after_p50_ns before_low_ns before_high_ns after_low_ns after_high_ns before_bytes before_allocs after_bytes after_allocs +common int typed 240.86294416243655 239.5964467005076 -0.5258166491043159 275.89086294416245 280.96700507614213 240.14251781472683 242.8595641646489 234.9246231155779 247.71689497716895 0 0 0 0 +common int runtime_target 392.5422885572139 380.19323671497585 -3.1459163005409962 406.505 440.28909952606637 363.9423076923077 393.0 360.2870813397129 410.4265402843602 16 1 16 1 +common integer typed 242.22222222222223 237.46223564954684 -1.9651320712880005 285.68148148148146 278.8622327790974 242.13317191283292 243.8280871670702 236.17021276595744 243.46793349168647 0 0 0 0 +common integer runtime_target 386.2068965517241 356.3380281690141 -7.733903420523136 414.35885167464113 414.76190476190476 362.20095693779905 389.6039603960396 356.1320754716981 361.9095238095238 0 0 0 0 +common bigint typed 934.7826086956521 980.0 4.837209302325585 1004.3913043478261 1060.1 932.0 1070.0 953.8461538461538 1042.1052631578948 216 7 216 7 +common bigint runtime_target 1200.0 1110.0 -7.499999999999996 1250.0 1300.0 1190.0 1280.0 1110.0 1190.0 216 7 216 7 +common float typed 240.38004750593825 237.28813559322035 -1.2862597976820545 275.061757719715 266.7579787234043 234.5679012345679 249.72375690607734 236.5641646489104 239.63031914893617 0 0 0 0 +common float runtime_target 393.0348258706468 383.66336633663366 -2.3843840080210565 427.05797101449275 443.0693069306931 370.5314009661836 429.1457286432161 373.30582524271847 391.04477611940297 16 1 16 1 +common bool typed 257.2755417956656 255.58823529411765 -0.6558363417569102 296.2750716332378 303.1777777777778 254.00890207715133 259.025787965616 251.11111111111111 273.93882978723406 0 0 0 0 +common bool runtime_target 441.9191919191919 395.0980392156863 -10.594957983193275 445.9646464646465 418.3623188405797 431.15577889447235 445.9646464646465 385.02415458937196 421.28712871287127 0 0 0 0 +common string typed 318.0257510729614 311.4035087719298 -2.0822975116604026 369.82758620689657 367.5438596491228 313.79741379310343 319.91525423728814 309.880658436214 313.8655462184874 48 2 48 2 +common string runtime_target 445.95959595959596 426.2676767676768 -4.4156285390713474 516.1666666666666 474.75252525252523 431.8181818181818 454.04545454545456 425.6281407035176 427.1356783919598 48 2 48 2 +common none typed 231.83856502242153 231.80125523012552 -0.016093005187645115 251.347533632287 258.1610878661088 225.57077625570776 240.55944055944056 225.9356846473029 236.30365296803652 0 0 0 0 +common none runtime_target 354.50236966824644 345.23809523809524 -2.613318054494529 395.2654028436019 387.1518691588785 337.8995433789954 364.5980861244019 340.0 375.23364485981307 0 0 0 0 +common failure typed 230.824200913242 238.68778280542986 3.4067406541758105 242.35254988913525 262.5570776255708 229.93569844789357 231.52391304347827 229.68036529680364 263.56164383561645 0 0 0 0 +common failure runtime_target 371.5 335.02764976958525 -9.81759090993668 426.005 373.2718894009217 341.2844036697248 378.2608695652174 333.1838565022422 338.7142857142857 0 0 0 0 +common list10 typed 7120.0 6560.0 -7.86516853932584 7620.0 7500.0 6680.0 7760.0 6440.2 7080.0 720 18 704 17 +common list10000 typed 4714836.0 4624435.0 -1.917373159957203 5624843.0 5467642.0 4687736.0 4854337.0 4545035.0 4805737.0 513880 19508 513864 19507 +common list10000_concrete typed 4084732.0 4036031.0 -1.1922691623342696 4452634.5 4755336.0 3978430.0 4225432.0 4018131.0 4094831.0 362024 10018 362008 10017 +common mixed_numeric typed 3971.4285714285716 3800.125 -4.313399280575547 4475.125 3962.5 3837.625 4000.0 3800.0 4225.0 352 13 336 12 +common heterogeneous typed 4871.428571428572 4842.857142857143 -0.5865102639296182 5614.428571428572 5300.0 4828.571428571428 5400.0 4728.571428571428 5057.142857142857 384 14 368 13 +common nested_concrete typed 6950.0 6920.0 -0.4316546762589968 7340.0 7820.0 6940.0 7050.0 6920.0 8075.0 768 29 720 26 +common nested_any typed 10800.0 9800.0 -9.259259259259256 11600.0 10300.0 9900.0 10800.0 9500.0 10701.0 864 32 816 29 +common dict typed 6480.0 6540.0 0.92592592592593 7380.2 7620.0 6360.0 6500.0 6540.0 7580.0 1280 24 1264 23 +common dict_concrete typed 3675.0 3612.625 -1.6972789115646258 4062.625 4200.0 3675.0 3925.0 3612.5 3950.0 672 16 656 15 +common empty_list typed 1240.0 1130.0 -8.870967741935488 1400.0 1200.0 1210.0 1260.0 1120.0 1180.0 112 5 96 4 +common empty_dict typed 1040.0 1036.3636363636363 -0.34965034965035446 1220.0 1163.6363636363637 1040.0 1120.0 1030.0 1080.0 208 5 192 4 +common wrapper typed 400.49751243781094 399.505 -0.24781987577640052 428.363184079602 453.23880597014926 394.02985074626866 416.005 395.02487562189054 404.97512437810946 16 1 16 1 +common iterator typed 402.0 398.99497487437185 -0.7475186879671969 467.5 405.5 401.0 406.5 397.505 400.5 16 1 16 1 +expanded single_rule warm 405.5 386.69950738916253 -4.636373023634388 473.005 444.3349753694581 393.10837438423647 413.0 382.3529411764706 392.5422885572139 0 0 0 0 +expanded decline_then_success warm 557.6086956521739 543.0904255319149 -2.6036663763427392 642.2513368983957 573.4095744680851 550.8108108108108 560.9679144385027 525.7894736842105 547.5989304812834 0 0 0 0 +expanded three_declines_then_success warm 875.4716981132076 964.1509433962265 10.12931034482758 1016.3636363636364 1028.3207547169811 865.4545454545455 930.5555555555555 880.7692307692307 989.1090909090909 0 0 0 0 +expanded sixteen_scoped_decliners warm 405.97512437810946 377.27272727272725 -7.069989115552289 463.505 395.57142857142856 402.5 460.30150753768845 375.3694581280788 401.5151515151515 0 0 0 0 +expanded virtual_mapping_abc warm 411.6751269035533 382.9145728643216 -6.986225827039016 464.14141414141415 438.19095477386935 405.55555555555554 448.9949494949495 379.3103448275862 393.0693069306931 0 0 0 0 +expanded buffer_only_native warm 7325.0 7150.0 -2.3890784982935176 8325.0 7875.0 6950.0 7550.0 6925.0 7375.0 8856 26 8712 23 +expanded buffer_only_wrapper warm 5583.5 5283.333333333333 -5.375958926599211 6166.833333333333 5900.166666666667 5416.666666666667 5680.0 5250.0 5366.666666666667 768 22 640 20 +expanded interface_only_native warm 22200.0 21700.0 -2.2522522522522515 25000.0 24600.0 22100.0 23300.0 21600.0 22000.0 9368 55 9224 52 +expanded array_method_only_native warm 8133.333333333333 7633.333333333333 -6.147540983606559 9133.666666666666 8300.0 8033.333333333333 8366.666666666666 7600.0 7867.0 9016 30 8872 27 +expanded ndarray_native warm 4866.666666666667 4685.714285714285 -3.718199608610584 5416.666666666667 5214.285714285715 4666.666666666667 4983.333333333333 4585.714285714285 4700.0 8888 23 8744 20 +expanded ndarray_wrapper warm 3387.5 3287.5 -2.9520295202952074 3862.625 3800.0 3325.0 3550.0 3200.125 3337.5 800 19 672 17 +expanded two_matching_first_success warm 3437.5 3500.0 1.8181818181818077 3850.0 3925.0 3362.5 3725.0 3475.0 3562.5 560 18 560 18 +expanded two_matching_first_declines warm 4228.571428571428 4428.714285714285 4.733108108108097 5057.142857142857 5157.285714285715 4200.0 4528.571428571428 4400.0 4671.428571428572 720 24 720 24 +expanded two_matching_decline_then_ordinary warm 4528.571428571428 4657.142857142857 2.8391167192429068 4728.714285714285 5443.0 4528.571428571428 4528.571428571428 4628.571428571428 5214.285714285715 752 25 752 25 diff --git a/benchmark/convert-unwrapped.patch b/benchmark/convert-unwrapped.patch new file mode 100644 index 000000000..ef9b25b81 --- /dev/null +++ b/benchmark/convert-unwrapped.patch @@ -0,0 +1,29 @@ +--- a/src/Convert/pyconvert.jl ++++ b/src/Convert/pyconvert.jl +@@ -96,2 +96,4 @@ +-# Internal helpers use the same representation as public pytryconvert. +-@inline pyconvert_return(x) = Some(x) ++# Rule results only need a wrapper when the successful value is ambiguous. ++# Public pytryconvert still wraps every success in Some. ++@inline pyconvert_return(x) = x ++@inline pyconvert_return(x::Union{Nothing,Some}) = Some(x) +@@ -101,0 +104,2 @@ ++@inline pyconvert_result(::Type{T}, x) where T = x::T ++@inline pyconvert_result(x) = x +@@ -135 +139 @@ +-pyconvert_tryconvert(::Type{T}, x::T) where T = Some(x) ++pyconvert_tryconvert(::Type{T}, x::T) where T = pyconvert_return(x) +@@ -138 +142 @@ +- Some(convert(T, x)::T) ++ pyconvert_return(convert(T, x)::T) +--- a/src/Convert/rules.jl ++++ b/src/Convert/rules.jl +@@ -63 +63 @@ +- result === PYCONVERT_FAILED ? nothing : Some(pyconvert_unpack(result)) ++ result === PYCONVERT_FAILED ? nothing : pyconvert_return(pyconvert_unpack(result)) +@@ -215 +215 @@ +- return Some(T0 === Union{} ? Vector{T1}() : ans) ++ return pyconvert_return(T0 === Union{} ? Vector{T1}() : ans) +@@ -290 +290 @@ +- return Some(isempty(ans) ? Dict{K0 === Union{} ? K1 : K0,V0 === Union{} ? V1 : V0}() : ans) ++ return pyconvert_return(isempty(ans) ? Dict{K0 === Union{} ? K1 : K0,V0 === Union{} ? V1 : V0}() : ans) diff --git a/benchmark/run-convert-final.sh b/benchmark/run-convert-final.sh new file mode 100644 index 000000000..bb9fbe9d1 --- /dev/null +++ b/benchmark/run-convert-final.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# Sequential runs: no overlapping benchmark/test processes launched by this script. +# Supply the absolute Julia executable and an environment developed against the +# original v1 revision, with BenchmarkTools installed. The installed Python +# executable/backend are inherited from the environment and shared by all runs. +set -euo pipefail +if [[ $# != 2 ]]; then + printf 'Usage: bash benchmark/run-convert-final.sh JULIA_EXECUTABLE BASELINE_ENV\n' >&2 + exit 2 +fi +julia_exe=$1 +baseline_env=$2 +repo_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd) +for round in 1 2 3; do + if [[ $round == 2 ]]; then + revisions=(after before) + else + revisions=(before after) + fi + for revision in "${revisions[@]}"; do + project=$baseline_env + if [[ $revision == after ]]; then + project=$repo_dir/benchmark + fi + printf 'Measuring %s round %s\n' "$revision" "$round" + "$julia_exe" --project="$project" "$repo_dir/benchmark/convert-final.jl" "$revision-r$round" + "$julia_exe" --project="$project" "$repo_dir/benchmark/convert-expanded.jl" "final-$revision-r$round" + done +done +"$julia_exe" --project="$repo_dir/benchmark" "$repo_dir/benchmark/convert-scalars.jl" final +"$julia_exe" --project="$repo_dir/benchmark" "$repo_dir/benchmark/convert-results.jl" final +"$julia_exe" --project="$repo_dir/benchmark" "$repo_dir/benchmark/convert-dispatch.jl" final +printf 'Final conversion benchmarks complete\n' diff --git a/benchmark/summarize-convert-final.py b/benchmark/summarize-convert-final.py new file mode 100644 index 000000000..779d76281 --- /dev/null +++ b/benchmark/summarize-convert-final.py @@ -0,0 +1,56 @@ +"""Aggregate three serial before/after rounds; keep per-trial TSVs as raw data.""" +import csv +import statistics +import sys +from pathlib import Path + +root = Path(__file__).parent +experiment = sys.argv[1] if len(sys.argv) > 1 else "" +common_prefix = "convert-final" + ("-" + experiment if experiment else "") +expanded_prefix = "convert-expanded-" + (experiment or "final") +fields = ("group", "case", "mode", "before_ns", "after_ns", "change_percent", + "before_p50_ns", "after_p50_ns", "before_low_ns", "before_high_ns", + "after_low_ns", "after_high_ns", "before_bytes", "before_allocs", + "after_bytes", "after_allocs") +summary = [] +for group, prefix in (("common", common_prefix), ("expanded", expanded_prefix)): + data = {} + for side in ("before", "after"): + rounds = [] + environments = [] + for round_number in (1, 2, 3): + stem = f"{prefix}-{side}-r{round_number}" + with (root / f"{stem}.tsv").open() as source: + rounds.append({(r["case"], r["mode"]): r for r in + csv.DictReader(source, delimiter="\t") + if r.get("status", "measured") == "measured"}) + environments.append((root / f"{stem}-environment.txt").read_text()) + assert all(e == environments[0] for e in environments), (group, side) + assert all(set(r) == set(rounds[0]) for r in rounds), (group, side) + data[side] = rounds + keys = list(data["before"][0]) + keys.extend(k for k in data["after"][0] if k not in keys) + for key in keys: + result = dict.fromkeys(fields, "") + result.update(group=group, case=key[0], mode=key[1]) + for side in ("before", "after"): + if key not in data[side][0]: + continue + rows = [r[key] for r in data[side]] + times = [float(r["min_ns"]) for r in rows] + result[side + "_ns"] = statistics.median(times) + result[side + "_p50_ns"] = statistics.median(float(r["median_ns"]) for r in rows) + result[side + "_low_ns"] = min(times) + result[side + "_high_ns"] = max(times) + for field in ("bytes", "allocs"): + assert len({r[field] for r in rows}) == 1, (group, side, key, field) + result[side + "_" + field] = int(rows[0][field]) + if result["before_ns"] != "" and result["after_ns"] != "": + result["change_percent"] = 100 * (result["after_ns"] / result["before_ns"] - 1) + summary.append(result) + +with (root / ("convert-" + (experiment or "final") + "-summary.tsv")).open("w") as destination: + writer = csv.DictWriter(destination, fields, delimiter="\t", lineterminator="\n") + writer.writeheader() + writer.writerows(summary) +print(f"Summarized {len(summary)} cases/modes from three before/after rounds") diff --git a/docs/make.jl b/docs/make.jl index ac3a4662e..67e0730a1 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -10,7 +10,7 @@ write("docs/src/releasenotes.md", changelog) makedocs( sitename = "PythonCall & JuliaCall", modules = [PythonCall], - format = Documenter.HTML(assets = ["assets/favicon.ico"]), + format = Documenter.HTML(assets = ["assets/favicon.ico"], edit_link = "v1"), warnonly = [:missing_docs], # avoid raising error when docs are missing pages = [ "Home" => "index.md", diff --git a/docs/src/conversion-to-julia.md b/docs/src/conversion-to-julia.md index 5c65a2aa4..7b2b1b742 100644 --- a/docs/src/conversion-to-julia.md +++ b/docs/src/conversion-to-julia.md @@ -1,74 +1,163 @@ # [Conversion to Julia](@id py2jl) -## [Conversion Rules](@id py2jl-conversion) - -The following table specifies the conversion rules used whenever converting a Python object to a Julia object. If the initial Python type matches the "From" column and the desired type `T` intersects with the "To" column, then that conversion is attempted. Conversions are tried in priority order, then in specificity order. - -From Julia, one can convert Python objects to a desired type using `pyconvert(T, x)` for example. - -From Python, the arguments to a Julia function will be converted according to these rules with `T=Any`. - -| From | To | -| :----------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------- | -| **Top priority (wrapped values).** | | -| `juliacall.Jl` | `Any` | -| **Very high priority (arrays).** | | -| Objects satisfying the buffer or array interface (inc. `bytes`, `bytearray`, `array.array`, `numpy.ndarray`) | `PyArray` | -| **High priority (canonical conversions).** | | -| `None` | `Nothing` | -| `bool` | `Bool` | -| `numbers.Integral` (inc. `int`) | `Integer` (prefers `Int`, or `BigInt` on overflow) | -| `float` | `Float64` | -| `complex` | `Complex{Float64}` | -| `range` | `StepRange` | -| `str` | `String` | -| `tuple` | `Tuple` | -| `collections.abc.Mapping` (inc. `dict`) | `PyDict` | -| `collections.abc.Sequence` (inc. `list`) | `PyList` | -| `collections.abc.Set` (inc. `set`, `frozenset`) | `PySet` | -| `io.IOBase` (includes open files) | `PyIO` | -| `BaseException` | `PyException` | -| `datetime.date`/`datetime.time`/`datetime.datetime` | `Date`/`Time`/`DateTime` | -| `datetime.timedelta` | `Microsecond` (or `Millisecond` or `Second` on overflow) | -| `numpy.intXX`/`numpy.uintXX`/`numpy.floatXX` | `IntXX`/`UIntXX`/`FloatXX` | -| `numpy.datetime64` | `NumpyDates.DateTime64` | -| `numpy.timedelta64` | `NumpyDates.TimeDelta64` | -| **Standard priority (other reasonable conversions).** | | -| `None` | `Missing` | -| `bytes` | `Vector{UInt8}`, `Vector{Int8}`, `String` | -| `str` | `String`, `Symbol`, `Char`, `Vector{UInt8}`, `Vector{Int8}` | -| `range` | `UnitRange` | -| `collections.abc.Mapping` | `Dict` | -| `collections.abc.Iterable` | `Vector`, `Set`, `Tuple`, `NamedTuple`, `Pair` | -| `datetime.timedelta` | `Dates.CompoundPeriod` | -| `numbers.Integral` | `Integer`, `Rational`, `Real`, `Number` | -| `numbers.Real` | `AbstractFloat`, `Number`, `Missing`/`Nothing` (if NaN) | -| `numbers.Complex` | `Complex`, `Number` | -| `ctypes.c_int` and other integers | `Integer`, `Rational`, `Real`, `Number` | -| `ctypes.c_float`/`ctypes.c_double` | `Cfloat`/`Cdouble`, `AbstractFloat`, `Real`, `Number` | -| `ctypes.c_voidp` | `Ptr{Cvoid}`, `Ptr` | -| `ctypes.c_char_p` | `Cstring`, `Ptr{Cchar}`, `Ptr` | -| `ctypes.c_wchar_p` | `Cwstring`, `Ptr{Cwchar}`, `Ptr` | -| `numpy.bool_`/`numpy.intXX`/`numpy.uintXX`/`numpy.floatXX` | `Bool`, `Integer`, `Rational`, `Real`, `Number` | -| `numpy.datetime64` | `NumpyDates.InlineDateTime64`, `Dates.DateTime` | -| `numpy.timedelta64` | `NumpyDates.InlineTimeDelta64`, `Dates.Period` | -| Objects satisfying the buffer or array interface | `Array`, `AbstractArray` | -| **Low priority (fallback to `Py`).** | | -| Anything | `Py` | -| **Bottom priority (must be explicitly specified by excluding `Py`).** | | -| Objects satisfying the buffer interface | `PyBuffer` | -| Anything | `PyRef` | - -See [here](@ref python-wrappers) for an explanation of the `Py*` wrapper types (`PyList`, `PyIO`, etc). +## [Conversion rules](@id py2jl-conversion) + +Use `pyconvert(T, x)` to convert a Python object to a Julia type. With +`pyconvert(T, x, default)`, a declined conversion returns `default`. +Exceptions raised during conversion propagate in either form. +JuliaCall uses `T=Any` when passing Python arguments into Julia. + +`Py` is the identity/fallback representation: `pyconvert(Py, x::Py)` returns +`x` directly. Rules should produce Julia representations rather than transform +one Python object into another through a `Py` target. + +Canonical conversions prefer native Julia values: integers become `Int` or +`BigInt` according to their value; floats, complex numbers, strings and +`None` become `Float64`, `ComplexF64`, `String` and `nothing`. +Numeric conversion uses each supported source's representation: integral and +rational sources convert through Julia integers and rationals, while Python +`float` and `complex` use their stored floating-point representations. Supported +NumPy scalars have dedicated rules. Other numeric types need explicit rules; +membership in `numbers.Real` or `numbers.Complex`, or implementing `__float__` +or `__complex__`, does not by itself enable conversion. An exact conversion +that declines cannot be retried through those potentially inexact methods. + +Lists become vectors, dictionaries become dictionaries, sets become sets, +and tuples become tuples (named tuples retain their names). +Array and buffer protocols produce native arrays before generic iterable +conversion. Explicit `PyList`, `PyDict`, `PySet` and `PyArray` targets +select Python-backed wrappers. Generic iterables remain lazy `PyIterable` +wrappers; canonical conversion never consumes an arbitrary iterator. + +Native vector element types are inferred using Julia's `Base.promote_typejoin`, +without converting the individual values to a promoted numeric type. +Dictionary keys and values are inferred independently. Empty unconstrained +containers use `Any`. Explicit element types are honored; abstract bounds, +such as `Vector{<:Real}`, constrain each recursive conversion and the inferred +element type. Cyclic containers are unsupported and may overflow the stack. + +## Preferences and context + +```julia +pyconvert(Any, x; prefer=( + "list" => PyList, + "dict" => PyDict, + "numpy:ndarray" => PyArray, +)) +ctx = PyConvertContext(; prefer=("list" => PyList,)) +pyconvert(ctx, Vector, x) +``` + +Preferences are tried in supplied order. Each matching source attempts normal +conversion to the intersection of the preferred type and the requested type. +A decline continues to the next preference; an exception propagates. +Ordinary conversion follows all preferences and does not reapply them at +that level. Preferences do not alter the registry or source ordering. +They are most useful for representation families; a narrow scalar preference +such as `Int8` can override a more appropriate canonical conversion. + +Context propagation is explicit: a rule calls `pyconvert(ctx, T, child)` +to propagate preferences, or `pyconvert(T, child)` for independent conversion. +Built-in native vector and dictionary rules propagate context. A rule ignoring +context does not propagate preferences to its children. ## [Custom rules](@id py2jl-conversion-custom) -To add a custom conversion rule, you must define a function to do the conversion and call -`pyconvert_add_rule` to register it. +A rule advertises a Python source `t`, Julia output `T`, destination +`scope=S` (default `T`), and conversion function. Register rules in +`__init__`, rather than during precompilation. + +```julia +function from_python(ctx, ::Type{MyArray}, x) + child = pytryconvert(ctx, Vector, x) + child === nothing && return nothing + MyArray(something(child)) +end +id = pyconvert_add_rule("builtins:list", MyArray, from_python; scope=MyArray) +pyconvert_replace_rule(id, "builtins:list", MyArray, from_python; scope=MyArray) +pyconvert_remove_rule(id) +``` + +Every add creates a unique, increasing ID, even for identical rules. +Replacement preserves the ID and creation position. Unknown IDs throw +`KeyError`. Additions, removals, replacements and resolution of pending +rules invalidate conversion caches. + +A rule is eligible for requested type `R` when `typeintersect(T,R)` +is nonempty and `R <: S`. For normalized unions, at least one arm must +be a subtype of `S`. Julia's union normalization can erase an explicit +subtype opt-in: `Union{AbstractArray,MyArray}` is just `AbstractArray`. +Abstract and UnionAll output and scope types are supported. + +Canonical rules use `scope=Any`. Only the owner of the Python source +should register them; PythonCall owns Python built-ins and standard-library +types for this purpose. Other packages must own their destination scope. +For example, a `list -> MyArray` rule scoped to `MyArray` cannot affect +`pyconvert(Any,x)` or `pyconvert(AbstractArray,x)`. + +Rules return `nothing` to decline, an ordinary value to succeed, or +`Some(value)` for explicit success. Use `Some(nothing)` to successfully +return `nothing`, and `Some(Some(value))` to return an actual `Some`. +Prefer returning ordinary values directly. An unnecessary `Some` can allocate +when its concrete type crosses a dispatch boundary; built-in rules wrap only +successful `nothing` and `Some` values. +`pytryconvert([ctx,] T,x)` always returns `nothing` on failure and +`Some(value)` on success. Both `f(ctx,T,x)` and `f(T,x)` rules are +supported; the context-aware form is preferred when applicable to that target. +A rule receives a non-union target: each arm of the output/request +intersection is tried before moving to the next rule. Union arm order is +unspecified. Declines continue through all eligible rules. Exceptions propagate. +There is an implicit final `Py` fallback only when the requested type admits it. + +### Source ordering + +Registered source types form a global DAG using strict Python `issubclass` +relationships, including ABC relationships. More-specific sources precede +their ancestors. Ordering never depends on the converted object's MRO or on +Julia output-type specificity. Per-call rule selection filters this global +order without reordering it. + +Independent virtual matchers ``, ``, +`` and `` test the corresponding type attributes or buffer +support. A supporting registered real type precedes the protocol; protocols +precede `object`. No array protocol falsely implies buffer conformance. + +Internal source priorities put Julia wrappers first, then array protocols, +then buffers, then ordinary types. Subtypes inherit the maximum ancestor +priority. Within a priority, stable topological sorting respects subtype +edges and breaks ties by source registration order. Rules on the same source +run in creation order. Incomparable array matchers use definition order: +array struct, array interface, then array. A specific ndarray rule can +override its generic protocol rules. + +### Lazy resolution and diagnostics + +Source names in rules and preferences use `"module:name"`, where `name` is an +attribute path (possibly dotted) looked up on the loaded module. It need not +match the type's `__module__` or `__qualname__`: a public re-export such as +`"mypackage:PublicType"` works even if the type is defined in an internal module. +A bare name abbreviates a built-in: `"list"` means `"builtins:list"`, so +`prefer=("list" => PyList,)` opts into list wrappers. Aliases resolving to the +same Python type share source ordering; their rules retain creation order. + +Optional modules are never imported merely to resolve rules or preferences. +Pending rules enter the global order when their module is +available in `sys.modules` and the named type can be resolved. Encountering +a new Python source module checks pending rules; cache hits do not. +Modules should define their relevant types and complete ABC registrations +before conversion begins. Arbitrary later `ABC.register()` mutations are +unsupported. Cached Python type identities retain owning references. -You must not do this while precompiling, so these calls will normally be in the `__init__` -function of your module. +`pyconvert_rules(T,x)` lists source-matching rules in global order, including +ID, source, advertised output, scope, effective source priority and destination +eligibility. The internal `PythonCall.Convert.pyconvert_preferred_type(t)` +reports the first canonical candidate, which may decline for a particular value. ```@docs PythonCall.pyconvert_add_rule +PythonCall.PyConvertContext +PythonCall.pytryconvert +PythonCall.pyconvert_remove_rule +PythonCall.pyconvert_replace_rule +PythonCall.pyconvert_rules ``` diff --git a/docs/src/v1-migration-guide.md b/docs/src/v1-migration-guide.md index 253578870..b28416630 100644 --- a/docs/src/v1-migration-guide.md +++ b/docs/src/v1-migration-guide.md @@ -2,6 +2,34 @@ Use this guide to help with migrating code from v0.9 to v1. +## Conversion rules + +`pyconvert(Any, x)` now prefers native vectors, dictionaries, sets and arrays for +materialized Python containers. Generic iterators remain lazy `PyIterable` +wrappers. Request `PyList`, `PyDict` or `PyArray` explicitly, or use source-specific +preferences such as `prefer=("builtins:list" => PyList,)` to select wrappers. + +Generic `numbers.Real` and `numbers.Complex` conversions through `__float__` and +`__complex__` have been removed: those methods can lose information before the +requested Julia conversion is attempted. Integral and rational sources keep +their exact representation rules; Python `float`, `complex` and supported NumPy +scalars keep dedicated rules. Other numeric types must register their own rules. + +Rule priorities have been removed. Register rules with +`pyconvert_add_rule(source, T, f; scope=T)`. Use `scope=Any` for canonical rules +only when you own the Python source type. Otherwise scope the rule to a Julia +destination type you own. Each registration returns a unique ID; use +`pyconvert_remove_rule(id)` or `pyconvert_replace_rule(id, source, T, f; scope=T)` +to remove or update it. + +Rules now return `nothing` to decline, a value to succeed, or `Some(value)` for +explicit success. Replace `pyconvert_unconverted()` with `nothing` and +`pyconvert_return(x)` with `Some(x)` (or simply `x` when it is neither `nothing` +nor a `Some`). `pytryconvert(T,x)` consistently returns `nothing` or `Some(value)`. +Rule functions may accept `(ctx,T,x)` to propagate preferences explicitly with +`pyconvert(ctx,T,child)`. See [conversion to Julia](@ref py2jl) for scope, ordering +and context details. + ## Core functionality Comparisons (`==`, `<`, etc.) between Python objects `Py`, diff --git a/pytest/test_convert_v1.py b/pytest/test_convert_v1.py new file mode 100644 index 000000000..ba12e9573 --- /dev/null +++ b/pytest/test_convert_v1.py @@ -0,0 +1,17 @@ +def test_native_containers_at_juliacall_boundary(): + from juliacall import Main as jl + + jl.jl_eval("using PythonCall") + assert bool(jl.jl_eval("x -> x isa Vector{Int}")([1, 2])) + assert bool(jl.jl_eval("x -> x isa Dict{String,Int}")({"a": 1})) + assert bool(jl.jl_eval("x -> x isa Vector{Real}")([1, 2.5])) + assert bool(jl.jl_eval("x -> x isa PyIterable")(iter([1, 2]))) + + +def test_native_conversion_does_not_consume_iterators(): + from juliacall import Main as jl + + jl.jl_eval("using PythonCall") + iterator = iter([1, 2, 3]) + assert bool(jl.jl_eval("x -> x isa PyIterable")(iterator)) + assert next(iterator) == 1 diff --git a/src/API/exports.jl b/src/API/exports.jl index d2a048fc2..a61c97dfc 100644 --- a/src/API/exports.jl +++ b/src/API/exports.jl @@ -106,13 +106,10 @@ export unsafe_pydel export @pyconvert export pyconvert export pyconvert_add_rule -export PYCONVERT_PRIORITY_ARRAY -export PYCONVERT_PRIORITY_CANONICAL -export PYCONVERT_PRIORITY_FALLBACK -export PYCONVERT_PRIORITY_NORMAL -export PYCONVERT_PRIORITY_WRAP -export pyconvert_return -export pyconvert_unconverted +export pytryconvert +export pyconvert_remove_rule +export pyconvert_replace_rule +export pyconvert_rules # Wrap export PyArray diff --git a/src/API/functions.jl b/src/API/functions.jl index 77492f7ad..f8b6e90c4 100644 --- a/src/API/functions.jl +++ b/src/API/functions.jl @@ -102,8 +102,10 @@ function unsafe_pydel end # Convert function pyconvert end function pyconvert_add_rule end -function pyconvert_return end -function pyconvert_unconverted end +function pytryconvert end +function pyconvert_remove_rule end +function pyconvert_replace_rule end +function pyconvert_rules end # JlWrap function pybinaryio end diff --git a/src/API/types.jl b/src/API/types.jl index 14acece88..79252afbb 100644 --- a/src/API/types.jl +++ b/src/API/types.jl @@ -1,13 +1,3 @@ -# Convert - -@enum PyConvertPriority begin - PYCONVERT_PRIORITY_WRAP = 400 - PYCONVERT_PRIORITY_ARRAY = 300 - PYCONVERT_PRIORITY_CANONICAL = 200 - PYCONVERT_PRIORITY_NORMAL = 0 - PYCONVERT_PRIORITY_FALLBACK = -100 -end - # Core """ diff --git a/src/Convert/Convert.jl b/src/Convert/Convert.jl index fc506fc60..7939769f9 100644 --- a/src/Convert/Convert.jl +++ b/src/Convert/Convert.jl @@ -16,19 +16,20 @@ using Dates: Date, Time, DateTime, Second, Millisecond, Microsecond, Nanosecond import ..PythonCall: @pyconvert, pyconvert_add_rule, - pyconvert_return, - pyconvert_unconverted, pyconvert, - PyConvertPriority - -export pyconvert_isunconverted, - pyconvert_result, + pytryconvert, + pyconvert_remove_rule, + pyconvert_replace_rule, + pyconvert_rules + +export pyconvert_return, + PyConvertContext, + pyconvert_isunconverted, pyconvert_result, pyconvert_tryconvert, pyconvert_unconverted, pyconvertarg - include("pyconvert.jl") include("rules.jl") include("ctypes.jl") diff --git a/src/Convert/numpy.jl b/src/Convert/numpy.jl index 73383d54a..309eb4e2a 100644 --- a/src/Convert/numpy.jl +++ b/src/Convert/numpy.jl @@ -112,7 +112,7 @@ function init_numpy() rule = pyconvert_rule_numpysimplevalue{T,false}() saferule = pyconvert_rule_numpysimplevalue{T,true}() - pyconvert_add_rule(name, T, saferule, PYCONVERT_PRIORITY_ARRAY) + pyconvert_add_rule(name, T, saferule; scope=Any) isuint && pyconvert_add_rule(name, UInt, sizeof(T) ≤ sizeof(UInt) ? saferule : rule) isuint && pyconvert_add_rule(name, Int, sizeof(T) < sizeof(Int) ? saferule : rule) isint && @@ -131,7 +131,7 @@ function init_numpy() "numpy:datetime64", DateTime64, pyconvert_rule_datetime64, - PYCONVERT_PRIORITY_ARRAY, + ; scope=Any, ) pyconvert_add_rule("numpy:datetime64", InlineDateTime64, pyconvert_rule_datetime64) pyconvert_add_rule( @@ -147,7 +147,7 @@ function init_numpy() "numpy:timedelta64", TimeDelta64, pyconvert_rule_timedelta64, - PYCONVERT_PRIORITY_ARRAY, + ; scope=Any, ) pyconvert_add_rule("numpy:timedelta64", InlineTimeDelta64, pyconvert_rule_timedelta64) pyconvert_add_rule( diff --git a/src/Convert/pandas.jl b/src/Convert/pandas.jl index 65786f1cf..cc38c9cb7 100644 --- a/src/Convert/pandas.jl +++ b/src/Convert/pandas.jl @@ -6,7 +6,7 @@ function init_pandas() "pandas._libs.missing:NAType", Missing, pyconvert_rule_pandas_na, - PYCONVERT_PRIORITY_CANONICAL, + ; scope=Any, ) pyconvert_add_rule("pandas._libs.missing:NAType", Nothing, pyconvert_rule_pandas_na) end diff --git a/src/Convert/pyconvert.jl b/src/Convert/pyconvert.jl index 3df5f7f67..10b449348 100644 --- a/src/Convert/pyconvert.jl +++ b/src/Convert/pyconvert.jl @@ -1,519 +1,529 @@ struct PyConvertRule + id::Int + source::String type::Type + scope::Type func::Function - priority::PyConvertPriority end -const PYCONVERT_RULES = Dict{String,Vector{PyConvertRule}}() -const PYCONVERT_EXTRATYPES = Py[] +# Source nodes retain their first registration position, including across replacement. +mutable struct PyConvertSource + name::String + type::Py + index::Int + priority::Int +end +const PYCONVERT_RULES = PyConvertRule[] +const PYCONVERT_SOURCES = PyConvertSource[] +const PYCONVERT_PENDING = Set{String}() +const PYCONVERT_ORDER = PyConvertRule[] +const PYCONVERT_NEXT_ID = Ref(0) +const PYCONVERT_DIRTY = Ref(true) +const PYCONVERT_MODULES = Set{String}() +const PYCONVERT_PROTOCOLS = ("", "", "", "") + +# Normalize at registration/context construction, rather than during dispatch. +pyconvert_source_name(name::String) = + name in PYCONVERT_PROTOCOLS || ':' in name ? name : "builtins:" * name """ - pyconvert_add_rule(tname::String, T::Type, func::Function, priority::PyConvertPriority=PYCONVERT_PRIORITY_NORMAL) - -Add a new conversion rule for `pyconvert`. - -### Arguments + PyConvertContext(; prefer=()) -- `tname` is a string of the form `"__module__:__qualname__"` identifying a Python type `t`, - such as `"builtins:dict"` or `"sympy.core.symbol:Symbol"`. This rule only applies to - Python objects of this type. -- `T` is a Julia type, such that this rule only applies when the target type intersects - with `T`. -- `func` is the function implementing the rule. -- `priority` determines whether to prioritise this rule above others. - -When `pyconvert(R, x)` is called, all rules such that `typeintersect(T, R) != Union{}` -and `pyisinstance(x, t)` are considered. These rules are sorted first by priority, -then by the specificity of `t` (e.g. `bool` is more specific than `int` is more specific -than `object`) then by the order they were added. The rules are tried in turn until one -succeeds. +Explicit conversion context. Preferences are ordered `"module:name" => JuliaType` +pairs, resolved by attribute lookup in loaded modules. A bare name abbreviates +`"builtins:name"`. Rules propagate preferences by calling `pyconvert(ctx, T, child)` +explicitly. +""" +struct PyConvertContext{P} + prefer::P +end +PyConvertContext(; prefer=()) = PyConvertContext(map(p -> pyconvert_source_name(first(p)) => Val(last(p)), prefer)) +const PYCONVERT_DEFAULT_CONTEXT = PyConvertContext() -### Implementing `func` +function pyconvert_invalidate!() + empty!.(values(PYCONVERT_RULES_CACHE)) + empty!(PYCONVERT_MODULES) + PYCONVERT_DIRTY[] = true +end -`func` is called as `func(S, x::Py)` for some `S <: T`. +function pyconvert_source!(name::String) + any(s -> s.name == name, PYCONVERT_SOURCES) && return + push!(PYCONVERT_SOURCES, PyConvertSource(name, PyNULL, length(PYCONVERT_SOURCES)+1, 0)) + name in PYCONVERT_PROTOCOLS || push!(PYCONVERT_PENDING, name) +end -It must return one of: -- `pyconvert_return(ans)` where `ans` is the result of the conversion (and must be an `S`). -- `pyconvert_unconverted()` if the conversion was not possible (e.g. converting a `list` to - `Vector{Int}` might fail if some of the list items are not integers). +""" + pyconvert_add_rule(source, T, f; scope=T) -> id + +Register a new rule. Source names use `"module:name"` (or just `"name"` for +builtins). Resolution lazily looks up attributes, including dotted paths, in +loaded modules; names need not match the type's __module__ or __qualname__. +A rule is eligible when its output intersects the requested type R and R is a +subtype of scope (or a normalized union arm is). Own the source for scope=Any, +or own the destination scope. Rules return nothing to decline, a value to succeed, +or Some(value) to explicitly succeed (required for a successful nothing/Some). +Functions may accept `(ctx, T, x)` or `(T, x)`; the former is preferred. +""" +function pyconvert_add_rule(source::String, T::Type, f::Function; scope::Type=T) + source = pyconvert_source_name(source) + pyconvert_source!(source) + id = (PYCONVERT_NEXT_ID[] += 1) + push!(PYCONVERT_RULES, PyConvertRule(id, source, T, scope, f)) + pyconvert_invalidate!() + id +end -The target type `S` is never a union or the empty type, i.e. it is always a data type or -union-all. +"""Remove a conversion rule by ID. Unknown IDs throw KeyError.""" +function pyconvert_remove_rule(id::Integer) + i = findfirst(r -> r.id == id, PYCONVERT_RULES) + i === nothing && throw(KeyError(id)) + deleteat!(PYCONVERT_RULES, i) + pyconvert_invalidate!() + nothing +end -### Priority +"""Replace a rule, preserving its ID and creation position.""" +function pyconvert_replace_rule(id::Integer, source::String, T::Type, f::Function; scope::Type=T) + i = findfirst(r -> r.id == id, PYCONVERT_RULES) + i === nothing && throw(KeyError(id)) + source = pyconvert_source_name(source) + pyconvert_source!(source) + PYCONVERT_RULES[i] = PyConvertRule(id, source, T, scope, f) + pyconvert_invalidate!() + id +end -Most rules should have priority `PYCONVERT_PRIORITY_NORMAL` (the default) which is for any -reasonable conversion rule. +# Rule results only need a wrapper when the successful value is ambiguous. +# Public pytryconvert still wraps every success in Some. +@inline pyconvert_return(x) = x +@inline pyconvert_return(x::Union{Nothing,Some}) = Some(x) +@inline pyconvert_unconverted() = nothing +@inline pyconvert_isunconverted(x) = x === nothing +@inline pyconvert_result(::Type{T}, x::Some) where T = something(x)::T +@inline pyconvert_result(x::Some) = something(x) +@inline pyconvert_result(::Type{T}, x) where T = x::T +@inline pyconvert_result(x) = x +function _pyconvert_returntype(T::Type) + T === Any && return Union{Nothing,Some} + T isa Union && return Union{_pyconvert_returntype(T.a),_pyconvert_returntype(T.b)} + isconcretetype(T) && return Union{Nothing,Some{T}} + Union{Nothing,Some{<:T}} +end +@generated pyconvert_returntype(::Type{T}) where T = QuoteNode(_pyconvert_returntype(T)) +# Avoid allocating an escaping Some for every element of an inferred container. +# The public/rule contract remains Some/nothing. Only dispatch uses this private +# sentinel, with an escape for values that happen to use our internal types. +struct PyConvertFailure end +struct PyConvertEscape{T} + value::T +end +const PYCONVERT_FAILED = PyConvertFailure() +@inline pyconvert_pack(x) = x isa Union{PyConvertFailure,PyConvertEscape} ? PyConvertEscape(x) : x +@inline pyconvert_unpack(x) = x +@inline pyconvert_unpack(x::PyConvertEscape) = x.value +# Check before returning across the dispatch boundary, so a concrete bits value +# can use Julia's inferred return convention instead of being boxed as Any. +@inline function pyconvert_check_raw(::Type{T}, x) where T + x === PYCONVERT_FAILED && return PYCONVERT_FAILED + T === Any ? x : pyconvert_pack(pyconvert_unpack(x)::T) +end +@inline pyconvert_raw(::Nothing) = PYCONVERT_FAILED +@inline pyconvert_raw(x::Some) = pyconvert_pack(something(x)) +@inline pyconvert_raw(x) = pyconvert_pack(x) +@inline function pyconvert_raw(::Type{T}, x) where T + x === nothing && return PYCONVERT_FAILED + value = x isa Some ? something(x) : x + pyconvert_pack(value::T) +end -Use priority `PYCONVERT_PRIORITY_CANONICAL` for **canonical** conversion rules. Immutable -objects may be canonically converted to their corresponding Julia type, such as `int` to -`Integer`. Mutable objects **must** be converted to a wrapper type, such that the original -Python object can be retrieved. For example a `list` is canonically converted to `PyList` -and not to a `Vector`. There should not be more than one canonical conversion rule for a -given Python type. +pyconvert_tryconvert(::Type{T}, x::T) where T = pyconvert_return(x) +function pyconvert_tryconvert(::Type{T}, x) where T + try + pyconvert_return(convert(T, x)::T) + catch exc + # Expected numeric/representation failures only. User errors propagate. + (exc isa Union{InexactError,OverflowError} || + (exc isa MethodError && exc.f === convert)) || rethrow() + nothing + end +end -Other priorities are reserved for internal use. -""" -function pyconvert_add_rule( - pytypename::String, - type::Type, - func::Function, - priority::PyConvertPriority = PYCONVERT_PRIORITY_NORMAL, -) - @nospecialize type func - push!( - get!(Vector{PyConvertRule}, PYCONVERT_RULES, pytypename), - PyConvertRule(type, func, priority), - ) - empty!.(values(PYCONVERT_RULES_CACHE)) - return +pyconvert_typename(t::Py) = "$(pygetattr(t, "__module__", "")):$(pygetattr(t, "__qualname__", ""))" +function pyconvert_protocol(name, t::Py) + name == "" && return C.PyType_CheckBuffer(t) + name == "" && return pyhasattr(t, "__array__") + name == "" && return pyhasattr(t, "__array_interface__") + name == "" && return pyhasattr(t, "__array_struct__") + false end -# Alternative ways to represent the result of conversion. -if true - # Returns either the result or Unconverted(). - struct Unconverted end - @inline pyconvert_return(x) = x - @inline pyconvert_unconverted() = Unconverted() - @inline pyconvert_returntype(::Type{T}) where {T} = Union{T,Unconverted} - @inline pyconvert_isunconverted(r) = r === Unconverted() - @inline pyconvert_result(::Type{T}, r) where {T} = r::T -elseif false - # Stores the result in PYCONVERT_RESULT. - # This is global state, probably best avoided. - const PYCONVERT_RESULT = Ref{Any}(nothing) - @inline pyconvert_return(x) = (PYCONVERT_RESULT[] = x; true) - @inline pyconvert_unconverted() = false - @inline pyconvert_returntype(::Type{T}) where {T} = Bool - @inline pyconvert_isunconverted(r::Bool) = !r - @inline pyconvert_result(::Type{T}, r::Bool) where {T} = - (ans = PYCONVERT_RESULT[]::T; PYCONVERT_RESULT[] = nothing; ans) -else - # Same as the previous scheme, but with special handling for bits types. - # This is global state, probably best avoided. - const PYCONVERT_RESULT = Ref{Any}(nothing) - const PYCONVERT_RESULT_ISBITS = Ref{Bool}(false) - const PYCONVERT_RESULT_TYPE = Ref{Type}(Union{}) - const PYCONVERT_RESULT_BITSLEN = 1024 - const PYCONVERT_RESULT_BITS = fill(0x00, PYCONVERT_RESULT_BITSLEN) - function pyconvert_return(x::T) where {T} - if isbitstype(T) && sizeof(T) ≤ PYCONVERT_RESULT_BITSLEN - unsafe_store!(Ptr{T}(pointer(PYCONVERT_RESULT_BITS)), x) - PYCONVERT_RESULT_ISBITS[] = true - PYCONVERT_RESULT_TYPE[] = T - else - PYCONVERT_RESULT[] = x - PYCONVERT_RESULT_ISBITS[] = false - end - return true +# Never import optional modules as a side effect of conversion. +function pyconvert_resolve(name::String) + name = pyconvert_source_name(name) + name == "builtins:NoneType" && return pytype(pybuiltins.None) + parts = split(name, ':'; limit=2) + length(parts) == 2 || throw(ArgumentError("invalid Python source name: $name")) + m = pygetitem(pyimport("sys").modules, parts[1], PyNULL) + pyisnull(m) && return PyNULL + for part in split(parts[2], '.') + m = pygetattr(m, part, PyNULL) + pyisnull(m) && return PyNULL end - @inline pyconvert_unconverted() = false - @inline pyconvert_returntype(::Type{T}) where {T} = Bool - @inline pyconvert_isunconverted(r::Bool) = !r - function pyconvert_result(::Type{T}, r::Bool) where {T} - if isbitstype(T) - if sizeof(T) ≤ PYCONVERT_RESULT_BITSLEN - @assert PYCONVERT_RESULT_ISBITS[] - @assert PYCONVERT_RESULT_TYPE[] == T - return unsafe_load(Ptr{T}(pointer(PYCONVERT_RESULT_BITS)))::T + pyisinstance(m, pybuiltins.type) || throw(ArgumentError("$name is not a Python type")) + m +end +function pyconvert_resolve_pending!(encountered=PyNULL) + changed = false + for s in PYCONVERT_SOURCES + s.name in PYCONVERT_PENDING || continue + t = pyconvert_resolve(s.name) + # Types made with exec need not be exported by their named module. + # Resolve registered real ancestors by identity, without using MRO order. + if pyisnull(t) && !pyisnull(encountered) + for base in encountered.__mro__ + if pyconvert_typename(base) == s.name + t = base + break + end end - elseif PYCONVERT_RESULT_ISBITS[] - t = PYCONVERT_RESULT_TYPE[] - @assert isbitstype(t) - @assert sizeof(t) ≤ PYCONVERT_RESULT_BITSLEN - @assert t <: T - @assert isconcretetype(t) - return unsafe_load(Ptr{t}(pointer(PYCONVERT_RESULT_BITS)))::T end - # general case - ans = PYCONVERT_RESULT[]::T - PYCONVERT_RESULT[] = nothing - return ans::T + pyisnull(t) && continue + s.type = t + delete!(PYCONVERT_PENDING, s.name) + changed = true end + changed && pyconvert_invalidate!() end -pyconvert_result(r) = pyconvert_result(Any, r) +function pyconvert_subtype(a::PyConvertSource, b::PyConvertSource) + a === b && return false + av, bv = a.name in PYCONVERT_PROTOCOLS, b.name in PYCONVERT_PROTOCOLS + av && return !bv && b.name == "builtins:object" + bv && return pyconvert_protocol(b.name, a.type) + pyissubclass(a.type, b.type) && !pyissubclass(b.type, a.type) +end -pyconvert_tryconvert(::Type{T}, x::T) where {T} = pyconvert_return(x) -pyconvert_tryconvert(::Type{T}, x) where {T} = - try - pyconvert_return(convert(T, x)::T) - catch - pyconvert_unconverted() +# Stable Kahn ordering. All strict subtype edges participate, not just MRO edges. +function pyconvert_toposort(edges, priorities, indices) + remaining = collect(eachindex(priorities)) + order = Int[] + while !isempty(remaining) + ready = filter(i -> !any(j -> edges[j,i], remaining), remaining) + isempty(ready) && error("cyclic pyconvert source relationships") + i = first(sort!(ready; by=i -> (-priorities[i], indices[i]))) + push!(order, i) + deleteat!(remaining, findfirst(==(i), remaining)) end - -function pyconvert_typename(t::Py) - m = pygetattr(t, "__module__", "") - n = pygetattr(t, "__name__", "") - return "$m:$n" + order end - -function _pyconvert_get_rules(pytype::Py) - pyisin(x, ys) = any(pyis(x, y) for y in ys) - - # get the MROs of all base types we are considering - omro = collect(pytype.__mro__) - basetypes = Py[pytype] - basemros = Vector{Py}[omro] - for xtype in PYCONVERT_EXTRATYPES - # find the topmost supertype of - xbase = PyNULL - for base in omro - if pyissubclass(base, xtype) - xbase = base - end - end - if !pyisnull(xbase) - push!(basetypes, xtype) - xmro = collect(xtype.__mro__) - pyisin(xbase, xmro) || pushfirst!(xmro, xbase) - push!(basemros, xmro) +function pyconvert_order!() + PYCONVERT_DIRTY[] || return + sources = filter(s -> !(s.name in PYCONVERT_PENDING) && + (s.name in PYCONVERT_PROTOCOLS || s.name in ("builtins:object","juliacall:JlBase") || + any(r -> r.source == s.name, PYCONVERT_RULES)), PYCONVERT_SOURCES) + edges = [pyconvert_subtype(a,b) for a in sources, b in sources] + priorities = [s.name == "juliacall:JlBase" ? 30 : + s.name == "" ? 10 : s.name in PYCONVERT_PROTOCOLS ? 20 : 0 for s in sources] + # Public re-exports are the same source type, including its built-in priority. + for i in eachindex(sources), j in eachindex(sources) + if !pyisnull(sources[i].type) && pyis(sources[i].type,sources[j].type) + priorities[i] = max(priorities[i],priorities[j]) end end - for xbase in basetypes[2:end] - push!(basemros, [xbase]) + # Propagate maximum priority from every ancestor to every descendant. + for _ in eachindex(sources), i in eachindex(sources), j in eachindex(sources) + edges[i,j] && (priorities[i] = max(priorities[i], priorities[j])) end - - # merge the MROs - # this is a port of the merge() function at the bottom of: - # https://www.python.org/download/releases/2.3/mro/ - mro = Py[] - while !isempty(basemros) - # find the first head not contained in any tail - ok = false - b = PyNULL - for bmro in basemros - b = bmro[1] - if all(bmro -> !pyisin(b, bmro[2:end]), basemros) - ok = true - break - end - end - ok || error( - "Fatal inheritance error: could not merge MROs (mro=$mro, basemros=$basemros)", - ) - # add it to the list - push!(mro, b) - # remove it from consideration - for bmro in basemros - filter!(t -> !pyis(t, b), bmro) - end - # remove empty lists - filter!(x -> !isempty(x), basemros) + order = pyconvert_toposort(edges, priorities, [s.index for s in sources]) + empty!(PYCONVERT_ORDER) + emitted = Set{String}() + for i in order + sources[i].priority = priorities[i] + sources[i].name in emitted && continue + aliases = [s.name for s in sources if s.name == sources[i].name || + (!pyisnull(s.type) && !pyisnull(sources[i].type) && pyis(s.type,sources[i].type))] + union!(emitted,aliases) + append!(PYCONVERT_ORDER, filter(r -> r.source in aliases, PYCONVERT_RULES)) end - # check the original MRO is preserved - omro_ = filter(t -> pyisin(t, omro), mro) - @assert length(omro) == length(omro_) - @assert all(pyis(x, y) for (x, y) in zip(omro, omro_)) - - # get the names of the types in the MRO of pytype - xmro = [String[pyconvert_typename(t)] for t in mro] + PYCONVERT_DIRTY[] = false +end +pyconvert_scope(R, S) = R isa Union ? pyconvert_scope(R.a,S) || pyconvert_scope(R.b,S) : R <: S +pyconvert_eligible(r, R) = pyconvert_scope(R,r.scope) && typeintersect(r.type,R) !== Union{} +function pyconvert_matches(name, t) + name in PYCONVERT_PROTOCOLS && return pyconvert_protocol(name,t) + s = findfirst(s -> s.name == name, PYCONVERT_SOURCES) + s === nothing && return (u = pyconvert_resolve(name); !pyisnull(u) && pyissubclass(t,u)) + u = PYCONVERT_SOURCES[s].type + pyisnull(u) && (u = pyconvert_resolve(name)) + !pyisnull(u) && pyissubclass(t,u) +end - # add special names corresponding to certain interfaces - # these get inserted just above the topmost type satisfying the interface - for (t, x) in reverse(collect(zip(mro, xmro))) - if pyhasattr(t, "__array_struct__") - push!(x, "") - break - end - end - for (t, x) in reverse(collect(zip(mro, xmro))) - if pyhasattr(t, "__array_interface__") - push!(x, "") - break - end +# Closures capture the calling convention once, for this context and target type. +function pyconvert_fix(ctx, ::Type{T}, f) where T + if applicable(f, ctx, T, PyNULL) + (ctx, x) -> pyconvert_raw(T,f(ctx,T,x)) + else + (ctx, x) -> pyconvert_raw(T,f(T,x)) end - for (t, x) in reverse(collect(zip(mro, xmro))) - if pyhasattr(t, "__array__") - push!(x, "") - break - end +end +struct PyConvertSelection + type::Py # Own a reference: cached pointers can never be recycled underneath us. + rules::Vector{Function} + firstfunc::Any + firsttarget::Type +end +const PYCONVERT_RULES_CACHE = Dict{Tuple{Type,Type},Dict{C.PyPtr,PyConvertSelection}}() +@generated pyconvert_rules_cache(::Type{CTX}, ::Type{T}) where {CTX,T} = + get!(Dict{C.PyPtr,PyConvertSelection}, PYCONVERT_RULES_CACHE, (CTX,T)) +function pyconvert_selection(ctx, ::Type{R}, tptr) where R + cache = pyconvert_rules_cache(typeof(ctx), R) + haskey(cache,tptr) && return cache[tptr] + t = pynew(incref(tptr)) + mod = pystr(String, pygetattr(t,"__module__","")) + if !(mod in PYCONVERT_MODULES) + pyconvert_resolve_pending!(t) + push!(PYCONVERT_MODULES,mod) end - for (t, x) in reverse(collect(zip(mro, xmro))) - if C.PyType_CheckBuffer(t) - push!(x, "") - break + pyconvert_order!() + rules = Function[] + firstfunc, firsttarget = nothing, Union{} + for r in PYCONVERT_ORDER + pyconvert_eligible(r,R) && pyconvert_matches(r.source,t) || continue + for T in Utils.explode_union(typeintersect(r.type,R)) + T === Union{} && continue + if isempty(rules) + firstfunc, firsttarget = r.func, T + end + push!(rules,pyconvert_fix(ctx,T,r.func)) end end - - # flatten to get the MRO as a list of strings - mro = String[x for xs in xmro for x in xs] - - # get corresponding rules - rules = PyConvertRule[ - rule for tname in mro for - rule in get!(Vector{PyConvertRule}, PYCONVERT_RULES, tname) - ] - - # order the rules by priority, then by original order - order = sort(axes(rules, 1), by = i -> (rules[i].priority, -i), rev = true) - rules = rules[order] - - @debug "pyconvert" pytype mro = join(mro, " ") - return rules + cache[tptr] = PyConvertSelection(t,rules,firstfunc,firsttarget) end -const PYCONVERT_PREFERRED_TYPE = Dict{Py,Type}() - -pyconvert_preferred_type(pytype::Py) = - get!(PYCONVERT_PREFERRED_TYPE, pytype) do - if pyissubclass(pytype, pybuiltins.int) - Union{Int,BigInt} - else - _pyconvert_get_rules(pytype)[1].type +# Direct calls only when the cache proves this is the first selected rule and +# target. Registry mutations clear the proof together with the selected rules. +@inline function pyconvert_first(ctx, ::Type{T}, x, selection) where T + f = selection.firstfunc + if selection.firsttarget === T + if T === Int || T === BigInt || T === Integer + f === pyconvert_rule_int && return pyconvert_check_raw(T,pyconvert_rule_int_raw(T,x)) + elseif T === Float64 + f === pyconvert_rule_float && return pyconvert_check_raw(T,pyconvert_raw(pyconvert_rule_float(T,x))) + elseif T === Bool + f === pyconvert_rule_bool && return pyconvert_check_raw(T,pyconvert_raw(pyconvert_rule_bool(T,x))) + elseif T === String + f === pyconvert_rule_str && return pyconvert_check_raw(T,pyconvert_raw(pyconvert_rule_str(T,x))) + elseif T === Nothing + f === pyconvert_rule_none && return nothing end end - -function pyconvert_get_rules(type::Type, pytype::Py) - @nospecialize type - - # this could be cached - rules = _pyconvert_get_rules(pytype) - - # intersect rules with type - rules = PyConvertRule[ - PyConvertRule(typeintersect(rule.type, type), rule.func, rule.priority) for - rule in rules - ] - - # explode out unions - rules = [ - PyConvertRule(type, rule.func, rule.priority) for rule in rules for - type in Utils.explode_union(rule.type) - ] - - # filter out empty rules - rules = [rule for rule in rules if rule.type != Union{}] - - # filter out repeated rules - rules = [ - rule for (i, rule) in enumerate(rules) if !any( - (rule.func === rules[j].func) && ((rule.type) <: (rules[j].type)) for - j = 1:(i-1) - ) - ] - - @debug "pyconvert" type rules - return Function[pyconvert_fix(rule.type, rule.func) for rule in rules] + pyconvert_check_raw(T,@pyregionbreak(selection.rules[1](ctx,x))) end -pyconvert_fix(::Type{T}, func) where {T} = x -> func(T, x) - -const PYCONVERT_RULES_CACHE = Dict{Type,Dict{C.PyPtr,Vector{Function}}}() - -@generated pyconvert_rules_cache(::Type{T}) where {T} = - get!(Dict{C.PyPtr,Vector{Function}}, PYCONVERT_RULES_CACHE, T) - -function pyconvert_rule_fast(::Type{T}, x::Py) where {T} - if T isa Union - a = pyconvert_rule_fast(T.a, x)::pyconvert_returntype(T.a) - pyconvert_isunconverted(a) || return a - b = pyconvert_rule_fast(T.b, x)::pyconvert_returntype(T.b) - pyconvert_isunconverted(b) || return b - elseif (T == Nothing) | (T == Missing) - pyisnone(x) && return pyconvert_return(T()) - elseif (T == Bool) - pyisFalse(x) && return pyconvert_return(false) - pyisTrue(x) && return pyconvert_return(true) - elseif (T == Int) | (T == BigInt) - pyisint(x) && return pyconvert_rule_int(T, x) - elseif (T == Float64) - pyisfloat(x) && return pyconvert_return(T(pyfloat_asdouble(x))) - elseif (T == ComplexF64) - pyiscomplex(x) && return pyconvert_return(T(pycomplex_ascomplex(x))) - elseif (T == String) | (T == Char) | (T == Symbol) - pyisstr(x) && return pyconvert_rule_str(T, x) - elseif (T == Vector{UInt8}) | (T == Base.CodeUnits{UInt8,String}) - pyisbytes(x) && return pyconvert_rule_bytes(T, x) - elseif (T <: StepRange) | (T <: UnitRange) - pyisrange(x) && return pyconvert_rule_range(T, x) +function pytryconvert_plain(ctx, ::Type{T}, x::Py) where T + selection = pyconvert_selection(ctx,T,C.Py_Type(x)) + if !isempty(selection.rules) + ans = pyconvert_first(ctx,T,x,selection) + ans === PYCONVERT_FAILED || return ans + for i in 2:length(selection.rules) + ans = @pyregionbreak(selection.rules[i](ctx,x)) + ans === PYCONVERT_FAILED || return pyconvert_check_raw(T, ans) + end end - pyconvert_unconverted() + Py <: T ? x : PYCONVERT_FAILED end - -function pytryconvert(::Type{T}, x_) where {T} - # Convert the input to a Py +pyconvert_preference_type(::Val{T}) where T = T +function pytryconvert_raw(ctx::PyConvertContext, ::Type{T}, x_) where T x = Py(x_) - - # We can optimize the conversion for some types by overloading pytryconvert_fast. - # It MUST give the same results as via the slower route using rules. - ans1 = pyconvert_rule_fast(T, x)::pyconvert_returntype(T) - pyconvert_isunconverted(ans1) || return ans1 - - # get rules from the cache - # TODO: we should hold weak references and clear the cache if types get deleted - tptr = C.Py_Type(x) - trules = pyconvert_rules_cache(T) - rules = get!(trules, tptr) do - t = pynew(incref(tptr)) - ans = pyconvert_get_rules(T, t)::Vector{Function} - unsafe_pydel(t) - ans + for (source, preferred) in ctx.prefer + pyconvert_matches(source,pytype(x)) || continue + Q = typeintersect(T,pyconvert_preference_type(preferred)) + Q === Union{} && continue + ans = pytryconvert_plain(ctx,Q,x) + ans === PYCONVERT_FAILED || return ans end + pytryconvert_plain(ctx,T,x) +end +""" + pytryconvert(T, x; prefer=()) + pytryconvert(ctx::PyConvertContext, T, x) - # apply the rules - for rule in rules - # Conversion rules are user-extensible Julia code and may yield. - ans2 = @pyregionbreak(rule(x))::pyconvert_returntype(T) - pyconvert_isunconverted(ans2) || return ans2 +Return `Some(value)` on successful conversion and `nothing` on decline. +The successful value is a `T`; exceptions from conversion rules propagate. +""" +function pytryconvert(ctx::PyConvertContext, ::Type{T}, x) where T + @pyregion begin + ans = pytryconvert_raw(ctx,T,x) + ans === PYCONVERT_FAILED && return nothing + Some(pyconvert_unpack(ans)::T)::pyconvert_returntype(T) end - - return pyconvert_unconverted() +end +pytryconvert(::Type{T}, x; prefer=()) where T = pytryconvert(PyConvertContext(;prefer),T,x) + +"""Inspect source-matching rules in global order, including destination eligibility.""" +function pyconvert_rules(R::Type, x) + t = pytype(Py(x)) + pyconvert_resolve_pending!() + pyconvert_order!() + [(; r.id, r.source, output=r.type, r.scope, + priority=only(s.priority for s in PYCONVERT_SOURCES if s.name==r.source), + order=i, eligible=pyconvert_eligible(r,R)) + for (i,r) in enumerate(PYCONVERT_ORDER) if pyconvert_matches(r.source,t)] +end +function pyconvert_preferred_type(t::Py) + pyconvert_resolve_pending!() + pyconvert_order!() + for r in PYCONVERT_ORDER + pyconvert_eligible(r,Any) && pyconvert_matches(r.source,t) && return r.type + end + Py end """ @pyconvert(T, x, [onfail]) + @pyconvert(ctx, T, x, onfail) -Convert the Python object `x` to a `T`. - -On failure, evaluates to `onfail`, which defaults to `return pyconvert_unconverted()` (mainly useful for writing conversion rules). +Convert a child in a rule, returning failure from the rule unless onfail is given. """ -macro pyconvert(T, x, onfail = :(return $pyconvert_unconverted())) +macro pyconvert(args...) + if length(args) == 4 + ctx,T,x,onfail = args + else + T,x = args[1:2] + ctx = :($PYCONVERT_DEFAULT_CONTEXT) + onfail = length(args)==3 ? args[3] : :(return nothing) + end quote @pyregion begin - T = $(esc(T)) - x = $(esc(x)) - ans = pytryconvert(T, x) - if pyconvert_isunconverted(ans) - $(esc(onfail)) - else - pyconvert_result(T, ans) - end + target = $(esc(T)) + ans = pytryconvert($(esc(ctx)),target,$(esc(x))) + ans === nothing ? $(esc(onfail)) : pyconvert_result(target,ans) end end end """ - pyconvert(T, x, [d]) - -Convert the Python object `x` to a `T`. - -If `d` is specified, it is returned on failure instead of throwing an error. -""" -pyconvert(::Type{T}, x) where {T} = @autopy x @pyconvert T x_ error( - "cannot convert this Python '$(pytype(x_).__name__)' to a Julia '$T'", -) -pyconvert(::Type{T}, x, d) where {T} = @autopy x @pyconvert T x_ d + pyconvert(T, x, [default]; prefer=()) + pyconvert(ctx::PyConvertContext, T, x, [default]) +Convert to T, preferring native containers. Source-specific preferences run in +order before ordinary conversion. Failure throws, or returns default if supplied. """ - pyconvertarg(T, x, name) - -Convert the Python object `x` to a `T`. - -On failure, throws a Python `TypeError` saying that the argument `name` could not be converted. -""" -pyconvertarg(::Type{T}, x, name) where {T} = @autopy x @pyconvert T x_ begin - errset( - pybuiltins.TypeError, - "Cannot convert argument '$name' to a Julia '$T', got a '$(pytype(x_).__name__)'", - ) - pythrow() +function pyconvert(ctx::PyConvertContext, ::Type{T}, x) where T + @pyregion begin + ans = pytryconvert_raw(ctx,T,x) + ans === PYCONVERT_FAILED && error("cannot convert Python object to Julia '$T'") + pyconvert_unpack(ans)::T + end +end +function pyconvert(ctx::PyConvertContext, ::Type{T}, x, default) where T + @pyregion begin + ans = pytryconvert_raw(ctx,T,x) + ans === PYCONVERT_FAILED ? default : pyconvert_unpack(ans)::T + end +end +pyconvert(::Type{T}, x; prefer=()) where T = pyconvert(PyConvertContext(;prefer),T,x) +pyconvert(::Type{T}, x, default; prefer=()) where T = pyconvert(PyConvertContext(;prefer),T,x,default) +function pyconvertarg(::Type{T}, x, name) where T + @autopy x @pyconvert T x_ begin + errset(pybuiltins.TypeError,"Cannot convert argument '$name' to a Julia '$T'") + pythrow() + end end function init_pyconvert() - push!(PYCONVERT_EXTRATYPES, pyimport("io" => "IOBase")) - push!( - PYCONVERT_EXTRATYPES, - pyimport("numbers" => ("Number", "Complex", "Real", "Rational", "Integral"))..., - ) - push!( - PYCONVERT_EXTRATYPES, - pyimport("collections.abc" => ("Iterable", "Sequence", "Set", "Mapping"))..., - ) - - priority = PYCONVERT_PRIORITY_CANONICAL - pyconvert_add_rule("builtins:NoneType", Nothing, pyconvert_rule_none, priority) - pyconvert_add_rule("builtins:bool", Bool, pyconvert_rule_bool, priority) - pyconvert_add_rule("builtins:float", Float64, pyconvert_rule_float, priority) + pyimport("numbers") + pyimport("collections.abc") + pyimport("io") + pyconvert_source!("builtins:object") + pyconvert_add_rule("builtins:NoneType", Nothing, pyconvert_rule_none; scope=Any) + pyconvert_add_rule("builtins:bool", Bool, pyconvert_rule_bool; scope=Any) + pyconvert_add_rule("builtins:float", Float64, pyconvert_rule_float; scope=Any) pyconvert_add_rule( "builtins:complex", Complex{Float64}, - pyconvert_rule_complex, - priority, + pyconvert_rule_complex; + scope = Any, ) - pyconvert_add_rule("numbers:Integral", Integer, pyconvert_rule_int, priority) - pyconvert_add_rule("builtins:str", String, pyconvert_rule_str, priority) + pyconvert_add_rule("numbers:Integral", Integer, pyconvert_rule_int; scope=Any) + pyconvert_add_rule("builtins:str", String, pyconvert_rule_str; scope=Any) pyconvert_add_rule( "builtins:bytes", Base.CodeUnits{UInt8,String}, - pyconvert_rule_bytes, - priority, + pyconvert_rule_bytes; + scope = Any, ) pyconvert_add_rule( "builtins:range", StepRange{<:Integer,<:Integer}, - pyconvert_rule_range, - priority, + pyconvert_rule_range; + scope = Any, ) pyconvert_add_rule( "numbers:Rational", Rational{<:Integer}, - pyconvert_rule_fraction, - priority, + pyconvert_rule_fraction; + scope = Any, ) - pyconvert_add_rule("builtins:tuple", NamedTuple, pyconvert_rule_iterable, priority) - pyconvert_add_rule("builtins:tuple", Tuple, pyconvert_rule_iterable, priority) - pyconvert_add_rule("datetime:datetime", DateTime, pyconvert_rule_datetime, priority) - pyconvert_add_rule("datetime:date", Date, pyconvert_rule_date, priority) - pyconvert_add_rule("datetime:time", Time, pyconvert_rule_time, priority) + pyconvert_add_rule("builtins:tuple", NamedTuple, pyconvert_rule_iterable; scope=Any) + pyconvert_add_rule("builtins:tuple", Tuple, pyconvert_rule_iterable; scope=Any) + pyconvert_add_rule("datetime:datetime", DateTime, pyconvert_rule_datetime; scope=Any) + pyconvert_add_rule("datetime:date", Date, pyconvert_rule_date; scope=Any) + pyconvert_add_rule("datetime:time", Time, pyconvert_rule_time; scope=Any) pyconvert_add_rule( "datetime:timedelta", Microsecond, - pyconvert_rule_timedelta, - priority, + pyconvert_rule_timedelta; + scope = Any, ) pyconvert_add_rule( "builtins:BaseException", PyException, - pyconvert_rule_exception, - priority, + pyconvert_rule_exception; + scope = Any, ) - priority = PYCONVERT_PRIORITY_NORMAL - pyconvert_add_rule("builtins:NoneType", Missing, pyconvert_rule_none, priority) - pyconvert_add_rule("builtins:bool", Number, pyconvert_rule_bool, priority) - pyconvert_add_rule("numbers:Real", Number, pyconvert_rule_float, priority) - pyconvert_add_rule("builtins:float", Nothing, pyconvert_rule_float, priority) - pyconvert_add_rule("builtins:float", Missing, pyconvert_rule_float, priority) - pyconvert_add_rule("numbers:Complex", Number, pyconvert_rule_complex, priority) - pyconvert_add_rule("numbers:Integral", Number, pyconvert_rule_int, priority) - pyconvert_add_rule("builtins:str", Symbol, pyconvert_rule_str, priority) - pyconvert_add_rule("builtins:str", Char, pyconvert_rule_str, priority) - pyconvert_add_rule("builtins:bytes", Vector{UInt8}, pyconvert_rule_bytes, priority) + pyconvert_add_rule("builtins:NoneType", Missing, pyconvert_rule_none) + pyconvert_add_rule("builtins:bool", Number, pyconvert_rule_bool) + # Real/Complex ABC membership does not promise lossless __float__/__complex__. + # Integral and Rational sources have their own exact representation rules. + pyconvert_add_rule("builtins:float", Number, pyconvert_rule_float) + pyconvert_add_rule("builtins:float", Nothing, pyconvert_rule_float) + pyconvert_add_rule("builtins:float", Missing, pyconvert_rule_float) + pyconvert_add_rule("builtins:complex", Number, pyconvert_rule_complex) + pyconvert_add_rule("numbers:Integral", Number, pyconvert_rule_int) + pyconvert_add_rule("builtins:str", Symbol, pyconvert_rule_str) + pyconvert_add_rule("builtins:str", Char, pyconvert_rule_str) + pyconvert_add_rule("builtins:bytes", Vector{UInt8}, pyconvert_rule_bytes) pyconvert_add_rule( "builtins:range", UnitRange{<:Integer}, - pyconvert_rule_range, - priority, + pyconvert_rule_range; + scope = AbstractRange, ) - pyconvert_add_rule("numbers:Rational", Number, pyconvert_rule_fraction, priority) + pyconvert_add_rule("numbers:Rational", Number, pyconvert_rule_fraction) pyconvert_add_rule( "collections.abc:Iterable", Vector, pyconvert_rule_iterable, - priority, ) - pyconvert_add_rule("collections.abc:Iterable", Tuple, pyconvert_rule_iterable, priority) - pyconvert_add_rule("collections.abc:Iterable", Pair, pyconvert_rule_iterable, priority) - pyconvert_add_rule("collections.abc:Iterable", Set, pyconvert_rule_iterable, priority) + pyconvert_add_rule("collections.abc:Iterable", Tuple, pyconvert_rule_iterable) + pyconvert_add_rule("collections.abc:Iterable", Pair, pyconvert_rule_iterable) + pyconvert_add_rule("collections.abc:Iterable", Set, pyconvert_rule_iterable) pyconvert_add_rule( "collections.abc:Sequence", Vector, pyconvert_rule_iterable, - priority, ) - pyconvert_add_rule("collections.abc:Sequence", Tuple, pyconvert_rule_iterable, priority) - pyconvert_add_rule("collections.abc:Set", Set, pyconvert_rule_iterable, priority) - pyconvert_add_rule("collections.abc:Mapping", Dict, pyconvert_rule_mapping, priority) + pyconvert_add_rule("collections.abc:Sequence", Tuple, pyconvert_rule_iterable) + pyconvert_add_rule("collections.abc:Set", Set, pyconvert_rule_iterable) + pyconvert_add_rule("collections.abc:Mapping", Dict, pyconvert_rule_mapping) pyconvert_add_rule( "datetime:timedelta", Millisecond, pyconvert_rule_timedelta, - priority, ) - pyconvert_add_rule("datetime:timedelta", Second, pyconvert_rule_timedelta, priority) - pyconvert_add_rule("datetime:timedelta", Nanosecond, pyconvert_rule_timedelta, priority) + pyconvert_add_rule("datetime:timedelta", Second, pyconvert_rule_timedelta) + pyconvert_add_rule("datetime:timedelta", Nanosecond, pyconvert_rule_timedelta) - priority = PYCONVERT_PRIORITY_FALLBACK - pyconvert_add_rule("builtins:object", Py, pyconvert_rule_object, priority) end diff --git a/src/Convert/rules.jl b/src/Convert/rules.jl index 7d514c7fb..2dc3c0b50 100644 --- a/src/Convert/rules.jl +++ b/src/Convert/rules.jl @@ -58,13 +58,20 @@ pyconvert_rule_bytes(::Type{Base.CodeUnits{UInt8,String}}, x::Py) = ### int -pyconvert_rule_int(::Type{T}, x::Py) where {T<:Number} = @pyregion begin +@inline function pyconvert_rule_int(::Type{T}, x::Py) where {T<:Number} + result = pyconvert_rule_int_raw(T, x) + result === PYCONVERT_FAILED ? nothing : pyconvert_return(pyconvert_unpack(result)) +end + +# The dispatcher can use the same numeric conversion without making a Some +# escape the kernel's return boundary (notably Some{BigInt}). +pyconvert_rule_int_raw(::Type{T}, x::Py) where {T<:Number} = @pyregion begin # First try to convert to Clonglong (or Culonglong if unsigned). Conversion rules # run outside their caller's region because user-defined rules may yield. v = T <: Unsigned ? C.PyLong_AsUnsignedLongLong(x) : C.PyLong_AsLongLong(x) if !iserrset_ambig(v) # success - return pyconvert_tryconvert(T, v) + return pyconvert_raw(pyconvert_tryconvert(T, v)) elseif errmatches(pybuiltins.OverflowError) # overflows Clonglong or Culonglong errclear() @@ -84,14 +91,14 @@ pyconvert_rule_int(::Type{T}, x::Py) where {T<:Number} = @pyregion begin typemin(typeof(v)) ≤ typemin(T) && typemax(T) ≤ typemax(typeof(v)) # definitely overflows S, give up now - return pyconvert_unconverted() + return PYCONVERT_FAILED else # try converting -> int -> str -> BigInt -> T x_int = pyint(x) x_str = pystr(String, x_int) unsafe_pydel(x_int) v = parse(BigInt, x_str) - return pyconvert_tryconvert(T, v) + return pyconvert_raw(pyconvert_tryconvert(T, v)) end else # other error @@ -198,25 +205,30 @@ end # Vector -function _pyconvert_rule_iterable(ans::Vector{T0}, it::Py, ::Type{T1}) where {T0,T1} +_pyconvert_join(A, B, bound) = typeintersect(Base.promote_typejoin(A, B), bound) + +function _pyconvert_rule_iterable(ctx, ans::Vector{T0}, it::Py, ::Type{T1}) where {T0,T1} @label again x_ = unsafe_pynext(it) if pyisnull(x_) unsafe_pydel(it) - return pyconvert_return(ans) + return pyconvert_return(T0 === Union{} ? Vector{T1}() : ans) end - x = @pyconvert(T1, x_) + result = pytryconvert_raw(ctx, T1, x_) + result === PYCONVERT_FAILED && return nothing + x = pyconvert_unpack(result)::T1 if x isa T0 push!(ans, x) @goto again end - T2 = Utils._promote_type_bounded(T0, typeof(x), T1) + T2 = _pyconvert_join(T0, typeof(x), T1) ans2 = Vector{T2}(ans) push!(ans2, x) - return _pyconvert_rule_iterable(ans2, it, T1) + return _pyconvert_rule_iterable(ctx, ans2, it, T1) end function pyconvert_rule_iterable( + ctx::PyConvertContext, ::Type{R}, x::Py, ::Type{Vector{T0}} = Utils._type_lb(R), @@ -224,9 +236,12 @@ function pyconvert_rule_iterable( ) where {R<:Vector,T0,T1} it = pyiter(x) ans = Vector{T0}() - return _pyconvert_rule_iterable(ans, it, T1) + return _pyconvert_rule_iterable(ctx, ans, it, T1) end +pyconvert_rule_iterable(ctx::PyConvertContext, ::Type{R}, x::Py) where {R} = + pyconvert_rule_iterable(R, x) + # Set function _pyconvert_rule_iterable(ans::Set{T0}, it::Py, ::Type{T1}) where {T0,T1} @@ -261,6 +276,7 @@ end # Dict function _pyconvert_rule_mapping( + ctx::PyConvertContext, ans::Dict{K0,V0}, x::Py, it::Py, @@ -271,23 +287,28 @@ function _pyconvert_rule_mapping( k_ = unsafe_pynext(it) if pyisnull(k_) unsafe_pydel(it) - return pyconvert_return(ans) + return pyconvert_return(isempty(ans) ? Dict{K0 === Union{} ? K1 : K0,V0 === Union{} ? V1 : V0}() : ans) end v_ = pygetitem(x, k_) - k = @pyconvert(K1, k_) - v = @pyconvert(V1, v_) + kr = pytryconvert_raw(ctx, K1, k_) + kr === PYCONVERT_FAILED && return nothing + vr = pytryconvert_raw(ctx, V1, v_) + vr === PYCONVERT_FAILED && return nothing + k = pyconvert_unpack(kr)::K1 + v = pyconvert_unpack(vr)::V1 if k isa K0 && v isa V0 push!(ans, k => v) @goto again end - K2 = Utils._promote_type_bounded(K0, typeof(k), K1) - V2 = Utils._promote_type_bounded(V0, typeof(v), V1) + K2 = _pyconvert_join(K0, typeof(k), K1) + V2 = _pyconvert_join(V0, typeof(v), V1) ans2 = Dict{K2,V2}(ans) push!(ans2, k => v) - return _pyconvert_rule_mapping(ans2, x, it, K1, V1) + return _pyconvert_rule_mapping(ctx, ans2, x, it, K1, V1) end function pyconvert_rule_mapping( + ctx::PyConvertContext, ::Type{R}, x::Py, ::Type{Dict{K0,V0}} = Utils._type_lb(R), @@ -295,7 +316,7 @@ function pyconvert_rule_mapping( ) where {R<:Dict,K0,V0,K1,V1} it = pyiter(x) ans = Dict{K0,V0}() - return _pyconvert_rule_mapping(ans, x, it, K1, V1) + return _pyconvert_rule_mapping(ctx, ans, x, it, K1, V1) end # Tuple diff --git a/src/Core/Py.jl b/src/Core/Py.jl index b769a2505..cf7f4d766 100644 --- a/src/Core/Py.jl +++ b/src/Core/Py.jl @@ -28,6 +28,7 @@ py_finalizer(x::Py) = GC.enqueue(getptr(x)) ispy(::Py) = true getptr(x::Py) = C.PyPtr(getfield(x, :ptr)) +# Py is the identity/fallback representation, not a Python-object transform. pyconvert(::Type{Py}, x::Py) = x setptr!(x::Py, ptr::C.PyPtr) = (setfield!(x, :ptr, Ptr{Cvoid}(ptr)); x) diff --git a/src/JlWrap/JlWrap.jl b/src/JlWrap/JlWrap.jl index dfdf9ff28..06a4f005e 100644 --- a/src/JlWrap/JlWrap.jl +++ b/src/JlWrap/JlWrap.jl @@ -11,6 +11,7 @@ using ..NumpyDates: NumpyDates using ..C using ..Core using ..Convert +using ..Convert: pyconvert_return using ..GC: GC import ..PythonCall: diff --git a/src/JlWrap/base.jl b/src/JlWrap/base.jl index e736bdb07..6f56692df 100644 --- a/src/JlWrap/base.jl +++ b/src/JlWrap/base.jl @@ -26,8 +26,7 @@ function init_base() pyjuliacallmodule._init_jlwrap() # conversion rule - priority = PYCONVERT_PRIORITY_WRAP - pyconvert_add_rule("juliacall:JlBase", Any, pyconvert_rule_jlvalue, priority) + pyconvert_add_rule("juliacall:JlBase", Any, pyconvert_rule_jlvalue; scope=Any) end pyconvert_rule_jlvalue(::Type{T}, x::Py) where {T} = diff --git a/src/PythonCall.jl b/src/PythonCall.jl index a6dec7345..97f567093 100644 --- a/src/PythonCall.jl +++ b/src/PythonCall.jl @@ -9,6 +9,8 @@ include("C/C.jl") include("GC/GC.jl") include("Core/Core.jl") include("Convert/Convert.jl") +using .Convert: PyConvertContext +export PyConvertContext include("PyMacro/PyMacro.jl") include("Wrap/Wrap.jl") include("JlWrap/JlWrap.jl") diff --git a/src/Wrap/PyArray.jl b/src/Wrap/PyArray.jl index dc87f16fe..6b5ad0658 100644 --- a/src/Wrap/PyArray.jl +++ b/src/Wrap/PyArray.jl @@ -27,6 +27,13 @@ function pyconvert_rule_array(::Type{A}, x::Py) where {A<:AbstractArray} end end +# Expected unsupported representations may decline; arbitrary errors must propagate. +struct PyArrayUnsupported <: Exception + message::String +end +Base.showerror(io::IO, exc::PyArrayUnsupported) = print(io, exc.message) +pyarray_unsupported(message) = throw(PyArrayUnsupported(message)) + abstract type PyArraySource end function pyarray_make( @@ -42,6 +49,7 @@ function pyarray_make( try return pyarray_make(A, x, PyArraySource_ArrayStruct(x, xa)) catch exc + exc isa PyArrayUnsupported || rethrow() @debug "failed to make PyArray from __array_struct__" exc = exc end end @@ -49,6 +57,7 @@ function pyarray_make( try return pyarray_make(A, x, PyArraySource_ArrayInterface(x, xi)) catch exc + exc isa PyArrayUnsupported || rethrow() @debug "failed to make PyArray from __array_interface__" exc = exc end end @@ -56,6 +65,7 @@ function pyarray_make( try return pyarray_make(A, x, PyArraySource_Buffer(x)) catch exc + exc isa PyArrayUnsupported || rethrow() @debug "failed to make PyArray from buffer" exc = exc end end @@ -65,6 +75,7 @@ function pyarray_make( try return pyarray_make(A, y, PyArraySource_ArrayStruct(y, ya)) catch exc + exc isa PyArrayUnsupported || rethrow() @debug "failed to make PyArray from __array__().__array_interface__" exc = exc end @@ -73,6 +84,7 @@ function pyarray_make( try return pyarray_make(A, y, PyArraySource_ArrayInterface(y, yi)) catch exc + exc isa PyArrayUnsupported || rethrow() @debug "failed to make PyArray from __array__().__array_interface__" exc = exc end @@ -93,13 +105,13 @@ function pyarray_make( if T0 == T1 T = T1 R = pyarray_get_R(T) - R′ == R || error("eltype $T is incompatible with array data of type $R′") + R′ == R || pyarray_unsupported("eltype $T is incompatible with array data of type $R′") else T = pyarray_get_T(R′, T0, T1)::DataType - T <: T1 || error("computed eltype $T out of bounds, should be <: $T1") - T >: T0 || error("computed eltype $T out of bounds, should be >: $T0") + T <: T1 || pyarray_unsupported("computed eltype $T out of bounds, should be <: $T1") + T >: T0 || pyarray_unsupported("computed eltype $T out of bounds, should be >: $T0") R = pyarray_get_R(T) - R′ == R || error("computed eltype $T is incompatible with array data of type $R′") + R′ == R || pyarray_unsupported("computed eltype $T is incompatible with array data of type $R′") end # ptr ptr = pyarray_get_ptr(info)::Ptr{Cvoid} @@ -107,7 +119,7 @@ function pyarray_make( N′ = pyarray_get_N(info)::Int if N0 == N1 N = N1 isa Int ? N1 : Int(N1) - N == N′ || error("number of dimensions $N incorrect, expecting $N′") + N == N′ || pyarray_unsupported("number of dimensions $N incorrect, expecting $N′") else N = N′ end @@ -122,11 +134,11 @@ function pyarray_make( Flist = Symbol[] if F0 == F1 F = F1::Tuple{Vararg{Symbol}} - (:mutable in F) && (!M) && error(":mutable flag given but array is not mutable") - (:linear in F) && (!L) && error(":linear flag given but array is not evenly spaced") + (:mutable in F) && (!M) && pyarray_unsupported(":mutable flag given but array is not mutable") + (:linear in F) && (!L) && pyarray_unsupported(":linear flag given but array is not evenly spaced") (:contiguous in F) && (!C) && - error(":contiguous flag given but array is not contiguous") + pyarray_unsupported(":contiguous flag given but array is not contiguous") else M && push!(Flist, :mutable) L && push!(Flist, :linear) @@ -153,9 +165,9 @@ function PyArraySource_ArrayInterface(x::Py, d::Py = x.__array_interface__) # offset # TODO: how is the offset measured? offset = pyconvert(Int, @py d.get("offset", 0)) - offset == 0 || error("not supported: non-zero offset") + offset == 0 || pyarray_unsupported("not supported: non-zero offset") # mask - @py("mask" in d) && error("not supported: mask") + @py("mask" in d) && pyarray_unsupported("not supported: mask") # data data = @py d.get("data") if pyistuple(data) @@ -180,14 +192,14 @@ pyarray_typestrdescr_to_type(ts::String, descr::Py) = begin bs = bsc == '<' ? !Utils.islittleendian() : bsc == '>' ? Utils.islittleendian() : - bsc == '|' ? false : error("endianness character not supported: $ts") - bs && error("byte-swapping not supported: $ts") + bsc == '|' ? false : pyarray_unsupported("endianness character not supported: $ts") + bs && pyarray_unsupported("byte-swapping not supported: $ts") # element type etc = ts[2] if etc == 'b' sz = parse(Int, ts[3:end]) sz == sizeof(Bool) && return Bool - error("bool of this size not supported: $ts") + pyarray_unsupported("bool of this size not supported: $ts") elseif etc == 'i' sz = parse(Int, ts[3:end]) sz == 1 && return Int8 @@ -195,7 +207,7 @@ pyarray_typestrdescr_to_type(ts::String, descr::Py) = begin sz == 4 && return Int32 sz == 8 && return Int64 sz == 16 && return Int128 - error("signed int of this size not supported: $ts") + pyarray_unsupported("signed int of this size not supported: $ts") elseif etc == 'u' sz = parse(Int, ts[3:end]) sz == 1 && return UInt8 @@ -203,36 +215,36 @@ pyarray_typestrdescr_to_type(ts::String, descr::Py) = begin sz == 4 && return UInt32 sz == 8 && return UInt64 sz == 16 && return UInt128 - error("unsigned int of this size not supported: $ts") + pyarray_unsupported("unsigned int of this size not supported: $ts") elseif etc == 'f' sz = parse(Int, ts[3:end]) sz == 2 && return Float16 sz == 4 && return Float32 sz == 8 && return Float64 - error("float of this size not supported: $ts") + pyarray_unsupported("float of this size not supported: $ts") elseif etc == 'c' sz = parse(Int, ts[3:end]) sz == 4 && return Complex{Float16} sz == 8 && return Complex{Float32} sz == 16 && return Complex{Float64} - error("complex of this size not supported: $ts") + pyarray_unsupported("complex of this size not supported: $ts") elseif etc == 'U' sz = parse(Int, ts[3:end]) return Utils.StaticString{UInt32,sz} elseif etc == 'O' return UnsafePyObject elseif etc == 'V' - pyisnull(descr) && error("not supported: void dtype with null descr") + pyisnull(descr) && pyarray_unsupported("not supported: void dtype with null descr") sz = parse(Int, ts[3:end]) T = pyarray_descr_to_type(descr) sizeof(T) == sz || - error("size mismatch: itemsize=$sz but sizeof(descr)=$(sizeof(T))") + pyarray_unsupported("size mismatch: itemsize=$sz but sizeof(descr)=$(sizeof(T))") return T elseif etc == 'M' || etc == 'm' m = match(r"^([0-9]+)(\[([0-9]+)?([a-zA-Z]+)\])?$", ts[3:end]) - m === nothing && error("could not parse type: $ts") + m === nothing && pyarray_unsupported("could not parse type: $ts") sz = parse(Int, m[1]) - sz == sizeof(Int64) || error( + sz == sizeof(Int64) || pyarray_unsupported( "$(etc == 'M' ? "datetime" : "timedelta") of this size not supported: $sz", ) s = m[3] === nothing ? 1 : parse(Int, m[3]) @@ -252,14 +264,14 @@ pyarray_typestrdescr_to_type(ts::String, descr::Py) = begin us == "ps" ? NumpyDates.PICOSECONDS : us == "fs" ? NumpyDates.FEMTOSECONDS : us == "as" ? NumpyDates.ATTOSECONDS : - error("not supported: $(etc == 'M' ? "datetime" : "timedelta") unit: $us") + pyarray_unsupported("not supported: $(etc == 'M' ? "datetime" : "timedelta") unit: $us") if etc == 'M' return NumpyDates.InlineDateTime64{s == 1 ? u : (u, s)} else return NumpyDates.InlineTimeDelta64{s == 1 ? u : (u, s)} end else - error("not supported: dtype of kind: $(repr(etc))") + pyarray_unsupported("not supported: dtype of kind: $(repr(etc))") end end @@ -308,9 +320,9 @@ function pyarray_descr_to_type(descr::Py) # TODO: support non-aligned dtypes by packing them into a custom type and reinterpreting T = Tuple{ftypes...} for (i, o) in pairs(foffsets) - fieldoffset(T, i) == o || error("not supported: dtype that is not aligned: $descr") + fieldoffset(T, i) == o || pyarray_unsupported("not supported: dtype that is not aligned: $descr") end - sizeof(T) == curoffset || error("not supported: dtype with end padding: $descr") + sizeof(T) == curoffset || pyarray_unsupported("not supported: dtype with end padding: $descr") # return the tuple type if the field names are f0, f1, ..., else return a named tuple if fnames == [Symbol(:f, i - 1) for i = 1:length(fnames)] return T @@ -371,14 +383,14 @@ end function pyarray_get_R(src::PyArraySource_ArrayStruct) swapped = !Utils.isflagset(src.info.flags, C.NPY_ARRAY_NOTSWAPPED) hasdescr = Utils.isflagset(src.info.flags, C.NPY_ARR_HAS_DESCR) - swapped && error("byte-swapping not supported") + swapped && pyarray_unsupported("byte-swapping not supported") kind = src.info.typekind size = src.info.itemsize if kind == 98 # b = bool if size == sizeof(Bool) return Bool else - error("bool of this size not supported: $size") + pyarray_unsupported("bool of this size not supported: $size") end elseif kind == 105 # i = int if size == 1 @@ -390,7 +402,7 @@ function pyarray_get_R(src::PyArraySource_ArrayStruct) elseif size == 8 return Int64 else - error("int of this size not supported: $size") + pyarray_unsupported("int of this size not supported: $size") end elseif kind == 117 # u = uint if size == 1 @@ -402,7 +414,7 @@ function pyarray_get_R(src::PyArraySource_ArrayStruct) elseif size == 8 return UInt64 else - error("uint of this size not supported: $size") + pyarray_unsupported("uint of this size not supported: $size") end elseif kind == 102 # f = float if size == 2 @@ -412,7 +424,7 @@ function pyarray_get_R(src::PyArraySource_ArrayStruct) elseif size == 8 return Float64 else - error("float of this size not supported: $size") + pyarray_unsupported("float of this size not supported: $size") end elseif kind == 99 # c = complex if size == 4 @@ -423,29 +435,29 @@ function pyarray_get_R(src::PyArraySource_ArrayStruct) return ComplexF64 end elseif kind == 109 # m = timedelta - error("timedelta not supported") + pyarray_unsupported("timedelta not supported") elseif kind == 77 # M = datetime - error("datetime not supported") + pyarray_unsupported("datetime not supported") elseif kind == 79 # O = object if size == sizeof(C.PyPtr) return UnsafePyObject else - error("object pointer of this size not supported: $size") + pyarray_unsupported("object pointer of this size not supported: $size") end elseif kind == 83 # S = byte string - error("byte strings not supported") + pyarray_unsupported("byte strings not supported") elseif kind == 85 # U = unicode string - mod(size, 4) == 0 || error("unicode size must be a multiple of 4: $size") + mod(size, 4) == 0 || pyarray_unsupported("unicode size must be a multiple of 4: $size") return Utils.StaticString{UInt32,div(size, 4)} elseif kind == 86 # V = void (should have descr) - hasdescr || error("not supported: void dtype with no descr") + hasdescr || pyarray_unsupported("not supported: void dtype with no descr") descr = pynew(incref(src.info.descr)) T = pyarray_descr_to_type(descr) sizeof(T) == size || - error("size mismatch: itemsize=$size but sizeof(descr)=$(sizeof(T))") + pyarray_unsupported("size mismatch: itemsize=$size but sizeof(descr)=$(sizeof(T))") return T else - error("not supported: dtype of kind: $(Char(kind))") + pyarray_unsupported("not supported: dtype of kind: $(Char(kind))") end @assert false end @@ -492,7 +504,7 @@ function PyArraySource_Buffer(x::Py) memview = pybuiltins.memoryview(x) buf = C.UnsafePtr(C.PyMemoryView_GET_BUFFER(memview)) buf.suboffsets[] == C_NULL || - error("PyArray does not support buffers with non-trivial suboffsets (PIL-style indirect layout)") + pyarray_unsupported("PyArray does not support buffers with non-trivial suboffsets (PIL-style indirect layout)") PyArraySource_Buffer(x, memview, buf) end @@ -534,7 +546,7 @@ const PYARRAY_BUFFERFORMAT_TO_TYPE = let c = Utils.islittleendian() ? '<' : '>' end pyarray_bufferformat_to_type(fmt::String) = get( - () -> error("not implemented: buffer format $(repr(fmt))"), + () -> pyarray_unsupported("not implemented: buffer format $(repr(fmt))"), PYARRAY_BUFFERFORMAT_TO_TYPE, fmt, ) @@ -681,14 +693,14 @@ end if T0 <: Py <: T1 Py else - error("impossible") + pyarray_unsupported("incompatible object element type") end elseif R <: Tuple - error("not implemented") + pyarray_unsupported("tuple array element types are not implemented") elseif T0 <: R <: T1 R else - error("impossible") + pyarray_unsupported("incompatible array element type") end end @@ -724,6 +736,6 @@ end elseif T <: Tuple Tuple{map(pyarray_get_R, T.parameters)...} else - error("unsupported eltype $T") + pyarray_unsupported("unsupported eltype $T") end end diff --git a/src/Wrap/Wrap.jl b/src/Wrap/Wrap.jl index d3b30ff2b..9a8da5768 100644 --- a/src/Wrap/Wrap.jl +++ b/src/Wrap/Wrap.jl @@ -11,6 +11,7 @@ using ..NumpyDates using ..C using ..Core using ..Convert +using ..Convert: pyconvert_return using ..PyMacro import ..PythonCall: @@ -32,55 +33,31 @@ include("PyTable.jl") include("PyPandasDataFrame.jl") function __init__() - priority = PYCONVERT_PRIORITY_ARRAY - pyconvert_add_rule("", PyArray, pyconvert_rule_array_nocopy, priority) - pyconvert_add_rule("", PyArray, pyconvert_rule_array_nocopy, priority) - pyconvert_add_rule("", PyArray, pyconvert_rule_array_nocopy, priority) - pyconvert_add_rule("", PyArray, pyconvert_rule_array_nocopy, priority) - - priority = PYCONVERT_PRIORITY_CANONICAL - pyconvert_add_rule( - "collections.abc:Iterable", - PyIterable, - pyconvert_rule_iterable, - priority, - ) - pyconvert_add_rule( - "collections.abc:Sequence", - PyList, - pyconvert_rule_sequence, - priority, - ) - pyconvert_add_rule("collections.abc:Set", PySet, pyconvert_rule_set, priority) - pyconvert_add_rule("collections.abc:Mapping", PyDict, pyconvert_rule_mapping, priority) - pyconvert_add_rule("io:IOBase", PyIO, pyconvert_rule_io, priority) - pyconvert_add_rule("_io:_IOBase", PyIO, pyconvert_rule_io, priority) - for typename in ["pandas.core.frame:DataFrame", "pandas:DataFrame"] - pyconvert_add_rule( - typename, - PyPandasDataFrame, - pyconvert_rule_pandasdataframe, - priority, - ) + # Native materialized containers precede explicit wrappers on the same source. + pyconvert_add_rule("builtins:list", Vector, Convert.pyconvert_rule_iterable; scope=Any) + pyconvert_add_rule("builtins:dict", Dict, Convert.pyconvert_rule_mapping; scope=Any) + for source in ("builtins:set", "builtins:frozenset") + pyconvert_add_rule(source, Set, Convert.pyconvert_rule_iterable; scope=Any) end - for typename in ["pandas.core.arrays.base:ExtensionArray", "pandas.api.extensions:ExtensionArray"] - pyconvert_add_rule( - typename, - PyList, - pyconvert_rule_sequence, - priority, - ) + # Definition order retains struct/interface/array/buffer precedence. Protocols + # are independent matchers; no protocol implies another protocol. + for source in ("", "", "", "") + pyconvert_add_rule(source, Array, pyconvert_rule_array; scope=Any) + pyconvert_add_rule(source, PyArray, pyconvert_rule_array_nocopy) + pyconvert_add_rule(source, AbstractArray, pyconvert_rule_array) + end + pyconvert_add_rule("collections.abc:Iterable", PyIterable, pyconvert_rule_iterable; scope=Any) + pyconvert_add_rule("collections.abc:Sequence", PyList, pyconvert_rule_sequence) + pyconvert_add_rule("collections.abc:Set", PySet, pyconvert_rule_set) + pyconvert_add_rule("collections.abc:Mapping", PyDict, pyconvert_rule_mapping) + pyconvert_add_rule("io:IOBase", PyIO, pyconvert_rule_io; scope=Any) + pyconvert_add_rule("_io:_IOBase", PyIO, pyconvert_rule_io; scope=Any) + for source in ("pandas.core.frame:DataFrame", "pandas:DataFrame") + pyconvert_add_rule(source, PyPandasDataFrame, pyconvert_rule_pandasdataframe; scope=Any) + end + for source in ("pandas.core.arrays.base:ExtensionArray", "pandas.api.extensions:ExtensionArray") + pyconvert_add_rule(source, PyList, pyconvert_rule_sequence; scope=Any) end - - priority = PYCONVERT_PRIORITY_NORMAL - pyconvert_add_rule("", Array, pyconvert_rule_array, priority) - pyconvert_add_rule("", Array, pyconvert_rule_array, priority) - pyconvert_add_rule("", Array, pyconvert_rule_array, priority) - pyconvert_add_rule("", Array, pyconvert_rule_array, priority) - pyconvert_add_rule("", AbstractArray, pyconvert_rule_array, priority) - pyconvert_add_rule("", AbstractArray, pyconvert_rule_array, priority) - pyconvert_add_rule("", AbstractArray, pyconvert_rule_array, priority) - pyconvert_add_rule("", AbstractArray, pyconvert_rule_array, priority) end end diff --git a/test/Convert.jl b/test/Convert.jl index 2765440fc..55fbc4911 100644 --- a/test/Convert.jl +++ b/test/Convert.jl @@ -334,6 +334,7 @@ end "$(t.__module__):$(t.__qualname__)", String, (_, _) -> "Hello!!", + ; scope=Any, ) @test pyconvert(String, x) == "Hello!!" @test pyconvert(Any, x) == "Hello!!" # Broken before PR #365 diff --git a/test/ConvertRedesign.jl b/test/ConvertRedesign.jl new file mode 100644 index 000000000..24a3c1bc8 --- /dev/null +++ b/test/ConvertRedesign.jl @@ -0,0 +1,503 @@ +@testitem "conversion registry, scopes and global ordering" begin + using PythonCall + const CV = PythonCall.Convert + ns = pyimport("types").ModuleType("convert_redesign_test") + pyimport("sys").modules["convert_redesign_test"] = ns + pyexec("""class A: pass +class B: pass +class C(A, B): pass +class D(C): pass +class E(B, A): pass +class Protocol: + __array_interface__ = {} +class Both(Protocol): + def __array__(self): pass +""", ns.__dict__) + ids = Int[] + add(name,T,f;scope=T) = (id=pyconvert_add_rule("convert_redesign_test:"*name,T,f;scope); push!(ids,id); id) + try + b = add("B",String, (_,_) -> "B"; scope=Any) + a = add("A",String, (_,_) -> "A"; scope=Any) + @test pyconvert(Any, ns.C()) == "B" + @test pyconvert(Any, ns.D()) == "B" + @test pyconvert(Any, ns.E()) == "B" # opposite MRO + selected(x) = [r.id for r in pyconvert_rules(Any,x) if r.eligible] + @test selected(ns.C()) == selected(ns.D()) == selected(ns.E()) + c = add("C",String, (_,_) -> "C"; scope=Any) + @test pyconvert(Any,ns.D()) == "C" + @test pyconvert_replace_rule(c,"convert_redesign_test:C",String,(_,_) -> nothing;scope=Any) == c + @test pyconvert(Any,ns.C()) == "B" + duplicate = add("B",String,(_,_) -> "later"; scope=Any) + @test duplicate > c > a > b + @test pyconvert(Any,ns.C()) == "B" + pyconvert_remove_rule(b); filter!(!=(b),ids) + @test pyconvert(Any,ns.C()) == "later" + @test_throws KeyError pyconvert_remove_rule(b) + scoped = add("A",Vector,(_,_) -> [1]; scope=Vector) + @test pyconvert(Vector,ns.A()) == [1] + @test pyconvert(Any,ns.A()) == "A" + @test pytryconvert(AbstractArray,ns.A()) === nothing + @test pyconvert(Union{Vector,Nothing},ns.A()) == [1] + @test pytryconvert(Union{AbstractArray,Vector},ns.A()) === nothing + @test pytryconvert(Union{},ns.A()) === nothing + @test all(!r.eligible for r in pyconvert_rules(Any,ns.A()) if r.id==scoped) + @test CV.pyconvert_protocol("",ns.Both) + @test CV.pyconvert_protocol("",ns.Both) + @test !CV.pyconvert_protocol("",ns.Both) + # Explicit rule outranks its generic virtual protocol parent. + p = add("Both",String,(_,_) -> "specific";scope=Any) + @test pyconvert(Any,ns.Both()) == "specific" + rows = pyconvert_rules(Any,ns.Both()) + @test first(rows).id == p + @test first(rows).priority >= maximum(r.priority for r in rows) + finally + foreach(pyconvert_remove_rule,ids) + pyimport("sys").modules.pop("convert_redesign_test") + end +end + +@testitem "native containers and preferences" begin + using PythonCall + cases = [(Any[],Any), ([1,2],Int), (Any[1,2.5],Real), + ([1,"two"],Any), ([nothing,1],Union{Nothing,Int})] + for (values,T) in cases + result = pyconvert(Any,pylist(values)) + @test result isa Vector{T} + @test isequal(result,values) + end + @test pyconvert(Any,pylist([big(2)^200,1])) isa Vector{<:Integer} + @test pyconvert(Vector{Int},pylist([1,2])) == [1,2] + @test pyconvert(Vector{<:Real},pylist(Any[1,2.5])) isa Vector{Real} + @test typeof.(pyconvert(Any,pylist(Any[1,2.5]))) == [Int,Float64] + @test pytryconvert(Vector{Int},pylist([1,"bad"])) === nothing + @test pyconvert(Any,pydict()) isa Dict{Any,Any} + d = pyconvert(Any,pydict("a"=>1,"b"=>2.5)) + @test d isa Dict{String,Real} + @test d == Dict("a"=>1,"b"=>2.5) + @test pyconvert(Any,pylist([pylist([1,2])])) == [[1,2]] + @test pyconvert(Any,pyiter(pylist([1,2]))) isa PyIterable + @test eltype(pyconvert(Any,pyiter(pylist([1,2])))) === Any + pref = ("builtins:list"=>PyList, "builtins:dict"=>PyDict) + @test pyconvert(Any,pylist([1,2]);prefer=pref) isa PyList + @test pyconvert(Any,pydict();prefer=pref) isa PyDict + @test pyconvert(Vector,pylist([1,2]);prefer=pref) isa Vector + @test pyconvert(Any,pylist([1]);prefer=("builtins:dict"=>PyDict,)) isa Vector + ctx = PyConvertContext(;prefer=pref) + @test pyconvert(ctx,Vector,pylist([pylist([1])]))[1] isa PyList + @test pyconvert(Any,pylist([1]);prefer=("builtins:list"=>Int8,)) == [1] + @test pyconvert(Any,pylist([1]);prefer=("builtins:list"=>PyList,"builtins:list"=>Vector)) isa PyList +end + +@testitem "scopes with parametric bounds and union normalization" begin + using PythonCall + CV = PythonCall.Convert + rule(T,S) = CV.PyConvertRule(1,"builtins:list",T,S,(_,_) -> error("ineligible")) + @test CV.pyconvert_eligible(rule(Vector,AbstractVector),Vector{Int}) + @test CV.pyconvert_eligible(rule(Vector,AbstractVector),Vector{<:Real}) + @test !CV.pyconvert_eligible(rule(Vector,Vector),AbstractVector) + @test !CV.pyconvert_eligible(rule(Vector,Vector),Any) + @test CV.pyconvert_eligible(rule(Vector{<:Real},Any),Vector) + @test !CV.pyconvert_eligible(rule(Vector{String},Any),Vector{<:Real}) + nested = Vector{Vector{T}} where T<:Real + @test CV.pyconvert_eligible(rule(nested,nested),Vector{Vector{Int}}) + @test !CV.pyconvert_eligible(rule(nested,nested),Vector{Vector{String}}) + @test CV.pyconvert_eligible(rule(nested,nested),Union{Nothing,Vector{Vector{Int}}}) + @test !CV.pyconvert_eligible(rule(Vector,Vector),Union{AbstractVector,Vector}) + @test !CV.pyconvert_eligible(rule(Union{},Any),Any) + @test !CV.pyconvert_eligible(rule(Any,Any),Union{}) + @test !CV.pyconvert_eligible(rule(Vector,Union{}),Vector) +end + +@testitem "protocol ordering, ABCs and cached scalar overrides" begin + using PythonCall + CV=PythonCall.Convert + ns=pyimport("types").ModuleType("convert_protocol_test") + pyimport("sys").modules["convert_protocol_test"]=ns + pyexec(""" +import abc +import numpy +class A(metaclass=abc.ABCMeta): pass +class B: pass +A.register(B) +class C(B): pass +class IntSubclass(int): pass +class FloatSubclass(float): pass +class Both(numpy.ndarray): pass +""",ns.__dict__) + ids=Int[] + add(source,T,f;scope=Any)=(id=pyconvert_add_rule(source,T,f;scope);push!(ids,id);id) + try + add("convert_protocol_test:A",String,(_,_) -> "ABC") + @test pyconvert(Any,ns.B()) == pyconvert(Any,ns.C()) == "ABC" + # Prime the scalar cache, then register a stricter source rule. + @test pyconvert(Int,ns.IntSubclass(2)) == 2 + bigrule=add("convert_protocol_test:IntSubclass",BigInt,(_,_) -> big(7);scope=BigInt) + @test pyconvert(BigInt,ns.IntSubclass(2)) == big(7) + @test pyconvert(Any,ns.IntSubclass(2)) === 2 + pyconvert_replace_rule(bigrule,"convert_protocol_test:IntSubclass",BigInt,(_,_) -> nothing;scope=BigInt) + @test pyconvert(BigInt,ns.IntSubclass(2)) == big(2) + pyconvert_remove_rule(bigrule);filter!(!=(bigrule),ids) + i=add("convert_protocol_test:IntSubclass",Int,(_,_) -> 3) + @test pyconvert(Int,ns.IntSubclass(2)) == 3 + pyconvert_replace_rule(i,"convert_protocol_test:IntSubclass",Int,(_,_) -> 4;scope=Any) + @test pyconvert(Int,ns.IntSubclass(2)) == 4 + pyconvert_remove_rule(i);filter!(!=(i),ids) + @test pyconvert(Int,ns.IntSubclass(2)) == 2 + @test pyconvert(Float64,ns.FloatSubclass(2)) == 2.0 + add("convert_protocol_test:FloatSubclass",Float64,(_,_) -> 3.0) + @test pyconvert(Float64,ns.FloatSubclass(2)) == 3.0 + a=ns.numpy.arange(3).view(ns.Both) + @test pyconvert(Any,a) isa Vector{<:Integer} + rows=pyconvert_rules(Any,a) + protocols=unique(r.source for r in rows if startswith(r.source,"<")) + @test collect(protocols) == ["","","",""] + i=add("numpy:ndarray",String,(_,_) -> "ndarray") + @test pyconvert(Any,a) == "ndarray" + rows=pyconvert_rules(Any,a) + @test first(rows).id==i + @test first(rows).priority==maximum(r.priority for r in rows) + @test pyconvert(Any,pyjl([1,2])) == [1,2] + @test first(pyconvert_rules(Any,pyjl([1,2]))).source=="juliacall:JlBase" + @test pyconvert(Any,ns.numpy.arange(2);prefer=("numpy:ndarray"=>PyArray,)) isa PyArray + finally + foreach(pyconvert_remove_rule,ids) + pyimport("sys").modules.pop("convert_protocol_test") + end +end + +@testitem "conversion exceptions and explicit context boundaries" begin + using PythonCall + ns=pyimport("types").ModuleType("convert_context_test") + pyimport("sys").modules["convert_context_test"]=ns + pyexec(""" +class Value: + child = [1,2] +class Iterator: + def __iter__(self): + yield 1 + raise RuntimeError('iterator failed') +class BadArray: + def __array__(self): + raise RuntimeError('array failed') +""",ns.__dict__) + source="convert_context_test:Value" + id=pyconvert_add_rule(source,Any,(ctx,T,x)->pyconvert(ctx,Any,x.child);scope=Any) + try + pref=(source=>String,"builtins:list"=>PyList) + # Failed preference for String then ordinary conversion propagates context. + # Restrict the advertised output so the String attempt genuinely declines. + pyconvert_replace_rule(id,source,AbstractVector,(ctx,T,x)->pyconvert(ctx,Any,x.child);scope=Any) + @test pyconvert(Any,ns.Value();prefer=pref) isa PyList + pyconvert_replace_rule(id,source,AbstractVector,(T,x)->pyconvert(Any,x.child);scope=Any) + @test pyconvert(Any,ns.Value();prefer=pref) isa Vector + @test_throws "iterator failed" pyconvert(Vector,ns.Iterator()) + @test pyconvert(Any,ns.Iterator()) isa PyIterable + @test_throws "array failed" pyconvert(Any,ns.BadArray()) + pyconvert_replace_rule(id,source,AbstractVector,(T,x)->error("preference failed");scope=Any) + @test_throws "preference failed" pyconvert(Any,ns.Value();prefer=(source=>Vector,)) + finally + pyconvert_remove_rule(id) + pyimport("sys").modules.pop("convert_context_test") + end +end + +@testitem "rule result convention and context signatures" begin + using PythonCall + const CV = PythonCall.Convert + ns = pyimport("types").ModuleType("convert_result_test") + pyimport("sys").modules["convert_result_test"] = ns + pyexec("class Value: pass",ns.__dict__) + source = "convert_result_test:Value" + x = ns.Value() + id = pyconvert_add_rule(source,Any,(_,_) -> Some(nothing);scope=Any) + try + @test pytryconvert(Any,x) === Some(nothing) + @test pyconvert(Any,x) === nothing + pyconvert_replace_rule(id,source,Any,(_,_) -> missing;scope=Any) + @test pyconvert(Any,x) === missing + pyconvert_replace_rule(id,source,Any,(_,_) -> Some(Some(2));scope=Any) + @test pyconvert(Any,x) === Some(2) + for value in (CV.PYCONVERT_FAILED, CV.PyConvertEscape(1), Some(nothing)) + pyconvert_replace_rule(id,source,Any,(_,_) -> Some(value);scope=Any) + @test pyconvert(Any,x) === value + @test pytryconvert(Any,x) === Some(value) + @test pyconvert(typeof(value),x) === value + end + # Built-in result encoding must preserve ambiguous values exactly once. + for value in (nothing, missing, Some(1), Some(nothing), Some(Some(1)), + [1,2], CV.PYCONVERT_FAILED, CV.PyConvertEscape(1)) + pyconvert_replace_rule(id,source,Any,(_,_) -> CV.pyconvert_return(value);scope=Any) + @test pyconvert(Any,x) === value + @test pytryconvert(typeof(value),x) === Some(value) + @test pyconvert(Any,pyjl(value)) === value + @test pytryconvert(typeof(value),pyjl(value)) === Some(value) + end + @test pyconvert(Any,pylist([pyjl(Some(1)),pyjl(nothing)])) == [Some(1),nothing] + @test pyconvert(Any,pydict("some"=>pyjl(Some(1)),"none"=>pyjl(nothing))) == + Dict("some"=>Some(1),"none"=>nothing) + pyconvert_replace_rule(id,source,Any,(_,_) -> nothing;scope=Any) + @test pyconvert(Any,x) === x # implicit fallback + @test pytryconvert(Int,x) === nothing + pyconvert_replace_rule(id,source,Any,(_,_) -> error("rule error");scope=Any) + @test_throws "rule error" pyconvert(Any,x) + function rule(::Type{Int},x) + 1 + end + function rule(ctx,::Type{String},x) + "context" + end + function rule(::Type{String},x) + "legacy" + end + pyconvert_replace_rule(id,source,Union{Int,String},rule;scope=Any) + @test pyconvert(Int,x) == 1 + @test pyconvert(String,x) == "context" + @test pyconvert(Union{Int,String},x) in (1,"context") + calls=Any[] + pyconvert_replace_rule(id,source,Union{Int,String},(T,x)->(push!(calls,T);nothing);scope=Any) + second=pyconvert_add_rule(source,Union{Int,String},(T,x)->(push!(calls,:second);T===Int ? 1 : "ok");scope=Any) + try + @test pyconvert(Union{Int,String},x) in (1,"ok") + @test Set(calls[1:2]) == Set([Int,String]) + @test calls[3] === :second + finally + pyconvert_remove_rule(second) + end + @test Some(1) isa CV.pyconvert_returntype(Integer) + @test Some(nothing) isa CV.pyconvert_returntype(Union{Int,Nothing}) + @test Some(1) isa CV.pyconvert_returntype(Any) + @test CV.pyconvert_returntype(Int) === Union{Nothing,Some{Int}} + @test CV.pyconvert_returntype(Union{Int,Nothing}) === Union{Nothing,Some{Int},Some{Nothing}} + @test (@inferred pyconvert(Int,pyint(1))) === 1 + @test pytryconvert(Nothing,pybuiltins.None) === Some(nothing) + finally + pyconvert_remove_rule(id) + pyimport("sys").modules.pop("convert_result_test") + end +end + +@testitem "scalar dispatch preserves singleton rules and overflow behavior" begin + using PythonCall + CV=PythonCall.Convert + original=only(r for r in CV.PYCONVERT_RULES if r.source=="builtins:NoneType" && r.type===Nothing) + x=pybuiltins.None + @test pyconvert(Nothing,x) === nothing + calls=Ref(0) + try + pyconvert_replace_rule(original.id,original.source,Nothing,(T,x)->(calls[]+=1;Some(nothing));scope=Any) + @test pyconvert(Nothing,x) === nothing + @test calls[]==1 + pyconvert_replace_rule(original.id,original.source,Nothing,(T,x)->nothing;scope=Any) + @test pytryconvert(Nothing,x) === nothing + @test pyconvert(Nothing,x,:declined) === :declined + pyconvert_replace_rule(original.id,original.source,Nothing,(T,x)->error("singleton rule");scope=Any) + @test_throws "singleton rule" pyconvert(Nothing,x) + finally + pyconvert_replace_rule(original.id,original.source,original.type,original.func;scope=original.scope) + end + @test pytryconvert(Nothing,x) === Some(nothing) + @test (@inferred pyconvert(Float64,pyfloat(1.5))) === 1.5 + @test (@inferred pyconvert(Int,pyint(10000))) === 10000 + for n in (big(2)^200,-big(2)^200,big(typemax(Int))+1) + p=pyint(n) + @test pyconvert(BigInt,p)==n + @test pyconvert(Integer,p)==n + @test pyconvert(Any,p)==n + @test pytryconvert(Int,p) === nothing + end + # An exact integer decline must not retry through a rounded float/complex. + below_min=pyint(big(typemin(Int))-1) + @test CV.pyconvert_rule_int(Int,below_min) === nothing + @test pytryconvert(Int,below_min) === nothing + @test pyconvert(BigInt,pyint(42))==42 + @test pyconvert(UInt,pyint(typemax(UInt)))==typemax(UInt) + @test pytryconvert(UInt,pyint(-1)) === nothing +end + +@testitem "numeric conversion uses source representations" begin + using PythonCall + ns = pyimport("types").ModuleType("convert_numeric_source_test") + pyimport("sys").modules["convert_numeric_source_test"] = ns + pyexec(""" +import numbers +from fractions import Fraction +class Integral(int): + def __float__(self): raise AssertionError('integral __float__ called') + def __complex__(self): raise AssertionError('integral __complex__ called') +class Rational(Fraction): + def __float__(self): raise AssertionError('rational __float__ called') + def __complex__(self): raise AssertionError('rational __complex__ called') +class Float(float): + def __float__(self): raise AssertionError('float override called') + def __complex__(self): raise AssertionError('float complex override called') +class Complex(complex): + def __complex__(self): raise AssertionError('complex override called') +class ApproximateReal: + def __float__(self): raise AssertionError('real __float__ called') + def __complex__(self): raise AssertionError('real __complex__ called') +class ApproximateComplex: + def __complex__(self): raise AssertionError('complex __complex__ called') +numbers.Real.register(ApproximateReal) +numbers.Complex.register(ApproximateComplex) +""", ns.__dict__) + try + n = big(typemin(Int))-1 + for x in (pyint(n), ns.Integral(pyint(n)), ns.Rational(pyint(n),1)) + @test pytryconvert(Int,x) === nothing + @test pyconvert(BigInt,x) == n + @test pyconvert(Float64,x) == Float64(n) + @test pyconvert(ComplexF64,x) == ComplexF64(n) + end + @test pyconvert(Int,ns.Integral(3)) === 3 + @test pyconvert(Int,ns.Rational(6,2)) === 3 + @test pyconvert(Rational,ns.Rational(1,3)) == 1//3 + @test pyconvert(Float64,ns.Rational(1,3)) === Float64(1//3) + @test pytryconvert(Int,ns.Rational(pyint(big(2)^63+1),2)) === nothing + for x in (ns.ApproximateReal(),ns.ApproximateComplex()) + for T in (Int,Float64,ComplexF64,Number) + @test pytryconvert(T,x) === nothing + end + @test pyconvert(Any,x) === x + end + @test pyconvert(Int,pyfloat(3.0)) === 3 + @test pytryconvert(Int,pyfloat(3.5)) === nothing + @test pyconvert(Int,pycomplex(3,0)) === 3 + @test pytryconvert(Int,pycomplex(3,1)) === nothing + @test pyconvert(Any,ns.Float(1.5)) === 1.5 + @test pyconvert(ComplexF64,ns.Float(1.5)) === 1.5+0.0im + @test pyconvert(Any,ns.Complex(1,2)) === 1.0+2.0im + id = pyconvert_add_rule("convert_numeric_source_test:ApproximateReal",Float64,(_,_) -> 1.5) + try + @test pyconvert(Float64,ns.ApproximateReal()) === 1.5 + @test pytryconvert(Number,ns.ApproximateReal()) === nothing + finally + pyconvert_remove_rule(id) + end + # Supported NumPy scalars use their own representation-reading rules. + np = pyimport("numpy") + @test pyconvert(Int,np.int64(3)) === 3 + @test pyconvert(Float64,np.float32(1.5)) === 1.5 + @test pyconvert(ComplexF64,np.complex64(pycomplex(1,2))) === 1.0+2.0im + @test pytryconvert(Int,np.float64(3.5)) === nothing + finally + pyimport("sys").modules.pop("convert_numeric_source_test") + end +end + +@testitem "effective source priorities are monotonic" begin + using PythonCall + CV=PythonCall.Convert + pyconvert_rules(Any,pyint(1)) + active=Set(r.source for r in CV.PYCONVERT_ORDER) + sources=filter(s->s.name in active || s.name=="builtins:object",CV.PYCONVERT_SOURCES) + for a in sources, b in sources + CV.pyconvert_subtype(a,b) || continue + @test a.priority >= b.priority + end +end + +@testitem "lazy rule resolution" begin + using PythonCall + id = pyconvert_add_rule("convert_late_test:Value",String,(_,_) -> "late";scope=Any) + try + @test pyconvert(Int,pyint(1)) == 1 + ns = pyimport("types").ModuleType("convert_late_test") + pyexec("class Value: pass",ns.__dict__) + pyimport("sys").modules["convert_late_test"] = ns + @test pyconvert(Any,ns.Value()) == "late" + finally + pyconvert_remove_rule(id) + pyimport("sys").modules.pop("convert_late_test",nothing) + end +end + +@testitem "source names resolve public aliases and built-in shorthand" begin + using PythonCall + CV = PythonCall.Convert + modules = pyimport("sys").modules + types = pyimport("types") + impl = types.ModuleType("convert_names_internal") + api = types.ModuleType("convert_names_public") + modules["convert_names_internal"] = impl + pyexec(""" +class Base: pass +class Outer: + class Internal(Base): pass +class Child(Outer.Internal): pass +""", impl.__dict__) + api.Public = impl.Outer.Internal + api.Namespace = types.SimpleNamespace(Value=impl.Outer.Internal) + ids = Int[] + add(source,T,f;scope=T) = (id=pyconvert_add_rule(source,T,f;scope);push!(ids,id);id) + try + base = add("convert_names_internal:Base",String,(_,_) -> "base";scope=Any) + firstalias = add("convert_names_public:Public",String,(_,_) -> nothing;scope=Any) + secondalias = add("convert_names_public:Namespace.Value",String,(_,_) -> "alias";scope=Any) + # Registration and unrelated conversion do not import an optional module. + @test !pycontains(modules,"convert_names_public") + @test pyconvert(Int,pyint(1)) === 1 + @test "convert_names_public:Public" in CV.PYCONVERT_PENDING + modules["convert_names_public"] = api + @test pyconvert(String,api.Public.__module__) == "convert_names_internal" + @test pyconvert(String,api.Public.__qualname__) == "Outer.Internal" + @test pyconvert(Any,impl.Child()) == "alias" + rows = pyconvert_rules(Any,impl.Child()) + @test [r.id for r in rows if r.id in ids] == [firstalias,secondalias,base] + @test !("convert_names_public:Public" in CV.PYCONVERT_PENDING) + # Preference lookup also works for an unregistered public alias. + api.OtherName = impl.Outer.Internal + @test pyconvert(Any,impl.Child();prefer=("convert_names_public:OtherName"=>Py,)) isa Py + @test pyconvert(Any,impl.Child();prefer=("convert_names_missing:Public"=>Py,)) == "alias" + @test !pycontains(modules,"convert_names_missing") + # Bare builtins work in preferences, contexts, rule adds and replacements. + x = pylist([1,2]) + @test pyconvert(Any,x;prefer=("list"=>PyList,)) isa PyList + ctx = PyConvertContext(;prefer=("list"=>PyList,"dict"=>PyDict)) + @test pyconvert(ctx,Any,pydict()) isa PyDict + @test pyconvert(ctx,Vector,pylist([x]))[1] isa PyList + @test pyconvert(Vector,x;prefer=("list"=>PyList,)) == [1,2] + @test pyconvert(Any,x;prefer=("dict"=>PyDict,)) == [1,2] + id = add("list",String,(_,_) -> "list rule") + @test pyconvert(String,x) == "list rule" + @test only(r.source for r in pyconvert_rules(String,x) if r.id==id) == "builtins:list" + @test pyconvert(Any,x) == [1,2] + @test pyconvert_replace_rule(id,"dict",String,(_,_) -> "dict rule") == id + @test pytryconvert(String,x) === nothing + @test pyconvert(String,pydict()) == "dict rule" + @test only(r.source for r in pyconvert_rules(String,pydict()) if r.id==id) == "builtins:dict" + @test pyis(CV.pyconvert_resolve("list"),pybuiltins.list) + @test pyis(CV.pyconvert_resolve("NoneType"),pytype(pybuiltins.None)) + # An API alias also retains priorities attached to special source types. + api.JuliaValue = pyimport("juliacall").JlBase + wrapid = add("convert_names_public:JuliaValue",String,(_,_) -> nothing) + rows = pyconvert_rules(String,pyjl([1,2])) + canonical = only(r.priority for r in rows if r.source=="juliacall:JlBase") + @test only(r.priority for r in rows if r.id==wrapid) == canonical + finally + foreach(pyconvert_remove_rule,ids) + modules.pop("convert_names_public",nothing) + modules.pop("convert_names_internal",nothing) + end +end + +@testitem "priority topological sort agrees with grouped sorting" begin + using PythonCall + CV = PythonCall.Convert + # Enumerate DAGs with monotonic priorities; independent tie breaker reference. + for mask in 0:63 + edges = falses(4,4) + for (bit,(i,j)) in enumerate([(i,j) for i=1:4 for j=i+1:4]) + edges[i,j] = (mask >> (bit-1)) & 1 == 1 + end + priorities = [0,10,20,0] + for _=1:4, i=1:4, j=1:4 + edges[i,j] && (priorities[i]=max(priorities[i],priorities[j])) + end + grouped = Int[] + for p in sort(unique(priorities);rev=true) + group = findall(==(p),priorities) + append!(grouped,group[CV.pyconvert_toposort(edges[group,group],zeros(Int,length(group)),group)]) + end + @test grouped == CV.pyconvert_toposort(edges,priorities,collect(1:4)) + end +end From 9554a4925242b18bb9ef37c8a422f1aa5a5a87d8 Mon Sep 17 00:00:00 2001 From: Christopher Rowley Date: Sun, 8 Nov 2026 20:13:56 +0000 Subject: [PATCH 2/7] Remove generated conversion benchmark outputs --- benchmark/convert-array-allocations-after.txt | 1533 ----------------- .../convert-array-allocations-before.txt | 1389 --------------- .../convert-array-allocations-unwrapped.txt | 1389 --------------- benchmark/convert-baseline.tsv | 16 - benchmark/convert-dispatch-final.tsv | 10 - benchmark/convert-dispatch.tsv | 12 - .../convert-expanded-after-environment.txt | 7 - benchmark/convert-expanded-after.tsv | 37 - .../convert-expanded-before-environment.txt | 7 - benchmark/convert-expanded-before.tsv | 37 - ...rt-expanded-final-after-r1-environment.txt | 10 - benchmark/convert-expanded-final-after-r1.tsv | 37 - ...rt-expanded-final-after-r2-environment.txt | 10 - benchmark/convert-expanded-final-after-r2.tsv | 37 - ...rt-expanded-final-after-r3-environment.txt | 10 - benchmark/convert-expanded-final-after-r3.tsv | 37 - ...t-expanded-final-before-r1-environment.txt | 10 - .../convert-expanded-final-before-r1.tsv | 37 - ...t-expanded-final-before-r2-environment.txt | 10 - .../convert-expanded-final-before-r2.tsv | 37 - ...t-expanded-final-before-r3-environment.txt | 10 - .../convert-expanded-final-before-r3.tsv | 37 - benchmark/convert-expanded-report.md | 147 -- ...xpanded-unwrapped-after-r1-environment.txt | 10 - .../convert-expanded-unwrapped-after-r1.tsv | 15 - ...xpanded-unwrapped-after-r2-environment.txt | 10 - .../convert-expanded-unwrapped-after-r2.tsv | 15 - ...xpanded-unwrapped-after-r3-environment.txt | 10 - .../convert-expanded-unwrapped-after-r3.tsv | 15 - ...panded-unwrapped-before-r1-environment.txt | 10 - .../convert-expanded-unwrapped-before-r1.tsv | 15 - ...panded-unwrapped-before-r2-environment.txt | 10 - .../convert-expanded-unwrapped-before-r2.tsv | 15 - ...panded-unwrapped-before-r3-environment.txt | 10 - .../convert-expanded-unwrapped-before-r3.tsv | 15 - .../convert-final-after-r1-environment.txt | 30 - benchmark/convert-final-after-r1.tsv | 30 - .../convert-final-after-r2-environment.txt | 30 - benchmark/convert-final-after-r2.tsv | 30 - .../convert-final-after-r3-environment.txt | 30 - benchmark/convert-final-after-r3.tsv | 30 - .../convert-final-before-r1-environment.txt | 30 - benchmark/convert-final-before-r1.tsv | 30 - .../convert-final-before-r2-environment.txt | 30 - benchmark/convert-final-before-r2.tsv | 30 - .../convert-final-before-r3-environment.txt | 30 - benchmark/convert-final-before-r3.tsv | 30 - benchmark/convert-final-summary.tsv | 66 - ...t-final-unwrapped-after-r1-environment.txt | 30 - .../convert-final-unwrapped-after-r1.tsv | 30 - ...t-final-unwrapped-after-r2-environment.txt | 30 - .../convert-final-unwrapped-after-r2.tsv | 30 - ...t-final-unwrapped-after-r3-environment.txt | 30 - .../convert-final-unwrapped-after-r3.tsv | 30 - ...-final-unwrapped-before-r1-environment.txt | 30 - .../convert-final-unwrapped-before-r1.tsv | 30 - ...-final-unwrapped-before-r2-environment.txt | 30 - .../convert-final-unwrapped-before-r2.tsv | 30 - ...-final-unwrapped-before-r3-environment.txt | 30 - .../convert-final-unwrapped-before-r3.tsv | 30 - benchmark/convert-inference-final.txt | 63 - benchmark/convert-inference.txt | 63 - benchmark/convert-redesign.tsv | 16 - benchmark/convert-report.md | 197 --- benchmark/convert-results-final.tsv | 67 - benchmark/convert-results.tsv | 67 - benchmark/convert-scalaropt.tsv | 16 - .../convert-scalars-before-allocations.txt | 139 -- .../convert-scalars-before-inference.txt | 663 ------- benchmark/convert-scalars-before.tsv | 25 - .../convert-scalars-final-allocations.txt | 113 -- benchmark/convert-scalars-final-inference.txt | 663 ------- benchmark/convert-scalars-final-repeat.tsv | 16 - benchmark/convert-scalars-final.tsv | 25 - .../convert-scalars-optimized-allocations.txt | 113 -- .../convert-scalars-optimized-inference.txt | 663 ------- .../convert-scalars-optimized-repeat.tsv | 16 - benchmark/convert-scalars-optimized.tsv | 25 - benchmark/convert-scalars-report.md | 124 -- ...vert-scalars-source-policy-allocations.txt | 113 -- ...onvert-scalars-source-policy-inference.txt | 663 ------- .../convert-scalars-source-policy-repeat.tsv | 16 - benchmark/convert-scalars-source-policy.tsv | 25 - benchmark/convert-unwrapped-report.md | 119 -- benchmark/convert-unwrapped-summary.tsv | 44 - benchmark/convert-unwrapped.patch | 29 - 86 files changed, 9885 deletions(-) delete mode 100644 benchmark/convert-array-allocations-after.txt delete mode 100644 benchmark/convert-array-allocations-before.txt delete mode 100644 benchmark/convert-array-allocations-unwrapped.txt delete mode 100644 benchmark/convert-baseline.tsv delete mode 100644 benchmark/convert-dispatch-final.tsv delete mode 100644 benchmark/convert-dispatch.tsv delete mode 100644 benchmark/convert-expanded-after-environment.txt delete mode 100644 benchmark/convert-expanded-after.tsv delete mode 100644 benchmark/convert-expanded-before-environment.txt delete mode 100644 benchmark/convert-expanded-before.tsv delete mode 100644 benchmark/convert-expanded-final-after-r1-environment.txt delete mode 100644 benchmark/convert-expanded-final-after-r1.tsv delete mode 100644 benchmark/convert-expanded-final-after-r2-environment.txt delete mode 100644 benchmark/convert-expanded-final-after-r2.tsv delete mode 100644 benchmark/convert-expanded-final-after-r3-environment.txt delete mode 100644 benchmark/convert-expanded-final-after-r3.tsv delete mode 100644 benchmark/convert-expanded-final-before-r1-environment.txt delete mode 100644 benchmark/convert-expanded-final-before-r1.tsv delete mode 100644 benchmark/convert-expanded-final-before-r2-environment.txt delete mode 100644 benchmark/convert-expanded-final-before-r2.tsv delete mode 100644 benchmark/convert-expanded-final-before-r3-environment.txt delete mode 100644 benchmark/convert-expanded-final-before-r3.tsv delete mode 100644 benchmark/convert-expanded-report.md delete mode 100644 benchmark/convert-expanded-unwrapped-after-r1-environment.txt delete mode 100644 benchmark/convert-expanded-unwrapped-after-r1.tsv delete mode 100644 benchmark/convert-expanded-unwrapped-after-r2-environment.txt delete mode 100644 benchmark/convert-expanded-unwrapped-after-r2.tsv delete mode 100644 benchmark/convert-expanded-unwrapped-after-r3-environment.txt delete mode 100644 benchmark/convert-expanded-unwrapped-after-r3.tsv delete mode 100644 benchmark/convert-expanded-unwrapped-before-r1-environment.txt delete mode 100644 benchmark/convert-expanded-unwrapped-before-r1.tsv delete mode 100644 benchmark/convert-expanded-unwrapped-before-r2-environment.txt delete mode 100644 benchmark/convert-expanded-unwrapped-before-r2.tsv delete mode 100644 benchmark/convert-expanded-unwrapped-before-r3-environment.txt delete mode 100644 benchmark/convert-expanded-unwrapped-before-r3.tsv delete mode 100644 benchmark/convert-final-after-r1-environment.txt delete mode 100644 benchmark/convert-final-after-r1.tsv delete mode 100644 benchmark/convert-final-after-r2-environment.txt delete mode 100644 benchmark/convert-final-after-r2.tsv delete mode 100644 benchmark/convert-final-after-r3-environment.txt delete mode 100644 benchmark/convert-final-after-r3.tsv delete mode 100644 benchmark/convert-final-before-r1-environment.txt delete mode 100644 benchmark/convert-final-before-r1.tsv delete mode 100644 benchmark/convert-final-before-r2-environment.txt delete mode 100644 benchmark/convert-final-before-r2.tsv delete mode 100644 benchmark/convert-final-before-r3-environment.txt delete mode 100644 benchmark/convert-final-before-r3.tsv delete mode 100644 benchmark/convert-final-summary.tsv delete mode 100644 benchmark/convert-final-unwrapped-after-r1-environment.txt delete mode 100644 benchmark/convert-final-unwrapped-after-r1.tsv delete mode 100644 benchmark/convert-final-unwrapped-after-r2-environment.txt delete mode 100644 benchmark/convert-final-unwrapped-after-r2.tsv delete mode 100644 benchmark/convert-final-unwrapped-after-r3-environment.txt delete mode 100644 benchmark/convert-final-unwrapped-after-r3.tsv delete mode 100644 benchmark/convert-final-unwrapped-before-r1-environment.txt delete mode 100644 benchmark/convert-final-unwrapped-before-r1.tsv delete mode 100644 benchmark/convert-final-unwrapped-before-r2-environment.txt delete mode 100644 benchmark/convert-final-unwrapped-before-r2.tsv delete mode 100644 benchmark/convert-final-unwrapped-before-r3-environment.txt delete mode 100644 benchmark/convert-final-unwrapped-before-r3.tsv delete mode 100644 benchmark/convert-inference-final.txt delete mode 100644 benchmark/convert-inference.txt delete mode 100644 benchmark/convert-redesign.tsv delete mode 100644 benchmark/convert-report.md delete mode 100644 benchmark/convert-results-final.tsv delete mode 100644 benchmark/convert-results.tsv delete mode 100644 benchmark/convert-scalaropt.tsv delete mode 100644 benchmark/convert-scalars-before-allocations.txt delete mode 100644 benchmark/convert-scalars-before-inference.txt delete mode 100644 benchmark/convert-scalars-before.tsv delete mode 100644 benchmark/convert-scalars-final-allocations.txt delete mode 100644 benchmark/convert-scalars-final-inference.txt delete mode 100644 benchmark/convert-scalars-final-repeat.tsv delete mode 100644 benchmark/convert-scalars-final.tsv delete mode 100644 benchmark/convert-scalars-optimized-allocations.txt delete mode 100644 benchmark/convert-scalars-optimized-inference.txt delete mode 100644 benchmark/convert-scalars-optimized-repeat.tsv delete mode 100644 benchmark/convert-scalars-optimized.tsv delete mode 100644 benchmark/convert-scalars-report.md delete mode 100644 benchmark/convert-scalars-source-policy-allocations.txt delete mode 100644 benchmark/convert-scalars-source-policy-inference.txt delete mode 100644 benchmark/convert-scalars-source-policy-repeat.tsv delete mode 100644 benchmark/convert-scalars-source-policy.tsv delete mode 100644 benchmark/convert-unwrapped-report.md delete mode 100644 benchmark/convert-unwrapped-summary.tsv delete mode 100644 benchmark/convert-unwrapped.patch diff --git a/benchmark/convert-array-allocations-after.txt b/benchmark/convert-array-allocations-after.txt deleted file mode 100644 index 0baedfc78..000000000 --- a/benchmark/convert-array-allocations-after.txt +++ /dev/null @@ -1,1533 +0,0 @@ -Julia: 1.13.2; PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl - -ndarray_native -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at regions.jl:296 [inlined] - pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 - pystr_fromUTF8 at builtins.jl:585 [inlined] - pystr at builtins.jl:593 [inlined] - Py at Py.jl:117 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at Py.jl:103 [inlined] - macro expansion at builtins.jl:63 [inlined] - macro expansion at regions.jl:302 [inlined] - pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at builtins.jl:72 [inlined] - macro expansion at regions.jl:302 [inlined] - pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -PythonCall.Wrap.PyArraySource_ArrayStruct: 80 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Tuple{Int64}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Core.SimpleVector: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -DataType: 56 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -UnionAll: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -PythonCall.Wrap.PyArraySource_ArrayStruct: 80 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Tuple{Int64}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Core.SimpleVector: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -DataType: 56 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -UnionAll: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Vector{Symbol}: 32 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:134 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Memory{Symbol}: 40 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:143 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Tuple{Symbol, Symbol, Symbol}: 24 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:146 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Ptr{Nothing}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -PyArray{Int64, 1, (:mutable, :linear, :contiguous)}: 64 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Some{PyArray{Int64, 1, (:mutable, :linear, :contiguous)}}: 64 bytes - pyconvert_return at pyconvert.jl:97 [inlined] - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:152 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -PyArray{Int64, 1, (:mutable, :linear, :contiguous)}: 48 bytes - pyconvert_result at pyconvert.jl:100 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Profile.Allocs.BufferType: 8000 bytes - pyconvert_tryconvert(::Type{Array}, x::PyArray{Int64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:138 - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Memory{Int64}: 24 bytes - pyconvert_tryconvert(::Type{Array}, x::PyArray{Int64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:138 - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Vector{Int64}: 32 bytes - pyconvert_tryconvert(::Type{Array}, x::PyArray{Int64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:138 - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Some{Vector{Int64}}: 16 bytes - pyconvert_tryconvert(::Type{Array}, x::PyArray{Int64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:138 - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] - -ndarray_wrapper -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at regions.jl:296 [inlined] - pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 - pystr_fromUTF8 at builtins.jl:585 [inlined] - pystr at builtins.jl:593 [inlined] - Py at Py.jl:117 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at Py.jl:103 [inlined] - macro expansion at builtins.jl:63 [inlined] - macro expansion at regions.jl:302 [inlined] - pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at builtins.jl:72 [inlined] - macro expansion at regions.jl:302 [inlined] - pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -PythonCall.Wrap.PyArraySource_ArrayStruct: 80 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Tuple{Int64}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Core.SimpleVector: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -DataType: 56 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -UnionAll: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -PythonCall.Wrap.PyArraySource_ArrayStruct: 80 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Tuple{Int64}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Core.SimpleVector: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -DataType: 56 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -UnionAll: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Vector{Symbol}: 32 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:134 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Memory{Symbol}: 40 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:143 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Tuple{Symbol, Symbol, Symbol}: 24 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:146 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Ptr{Nothing}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -PyArray{Int64, 1, (:mutable, :linear, :contiguous)}: 64 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Some{PyArray{Int64, 1, (:mutable, :linear, :contiguous)}}: 64 bytes - pyconvert_return at pyconvert.jl:97 [inlined] - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:152 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -PyArray{Int64, 1, (:mutable, :linear, :contiguous)}: 48 bytes - pyconvert_raw at pyconvert.jl:131 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] - -buffer_native -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at regions.jl:296 [inlined] - pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 - pystr_fromUTF8 at builtins.jl:585 [inlined] - pystr at builtins.jl:593 [inlined] - Py at Py.jl:117 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at Py.jl:103 [inlined] - macro expansion at builtins.jl:63 [inlined] - macro expansion at regions.jl:302 [inlined] - pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at regions.jl:296 [inlined] - pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 - pystr_fromUTF8 at builtins.jl:585 [inlined] - pystr at builtins.jl:593 [inlined] - Py at Py.jl:117 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at Py.jl:103 [inlined] - macro expansion at builtins.jl:63 [inlined] - macro expansion at regions.jl:302 [inlined] - pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:56 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at regions.jl:302 [inlined] - pynulltuple(len::Int64) at builtins.jl:848 - macro expansion at builtins.jl:? [inlined] - pytuple_fromiter at builtins.jl:877 [inlined] - #pycall#21 at builtins.jl:220 [inlined] - pycall at builtins.jl:211 [inlined] - #_#9 at Py.jl:350 [inlined] - Py at Py.jl:350 [inlined] - PyArraySource_Buffer at PyArray.jl:504 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at regions.jl:302 [inlined] - pycallargs(f::Py, args::Py) at builtins.jl:202 - #pycall#21 at builtins.jl:221 [inlined] - pycall at builtins.jl:211 [inlined] - #_#9 at Py.jl:350 [inlined] - Py at Py.jl:350 [inlined] - PyArraySource_Buffer at PyArray.jl:504 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -String: 10 bytes - pyarray_get_R at PyArray.jl:556 [inlined] - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:104 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -PythonCall.Wrap.PyArraySource_Buffer: 32 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Tuple{Int64}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Core.SimpleVector: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -DataType: 56 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -UnionAll: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -PythonCall.Wrap.PyArraySource_Buffer: 32 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Tuple{Int64}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Core.SimpleVector: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -DataType: 56 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -UnionAll: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Vector{Symbol}: 32 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:134 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Memory{Symbol}: 40 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:143 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Tuple{Symbol, Symbol, Symbol}: 24 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:146 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Ptr{Nothing}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -PyArray{Float64, 1, (:mutable, :linear, :contiguous)}: 64 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Some{PyArray{Float64, 1, (:mutable, :linear, :contiguous)}}: 64 bytes - pyconvert_return at pyconvert.jl:97 [inlined] - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:152 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -PyArray{Float64, 1, (:mutable, :linear, :contiguous)}: 48 bytes - pyconvert_result at pyconvert.jl:100 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Profile.Allocs.BufferType: 8000 bytes - pyconvert_tryconvert(::Type{Array}, x::PyArray{Float64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:138 - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Memory{Float64}: 24 bytes - pyconvert_tryconvert(::Type{Array}, x::PyArray{Float64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:138 - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Vector{Float64}: 32 bytes - pyconvert_tryconvert(::Type{Array}, x::PyArray{Float64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:138 - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Some{Vector{Float64}}: 16 bytes - pyconvert_tryconvert(::Type{Array}, x::PyArray{Float64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:138 - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] - -buffer_wrapper -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at regions.jl:296 [inlined] - pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 - pystr_fromUTF8 at builtins.jl:585 [inlined] - pystr at builtins.jl:593 [inlined] - Py at Py.jl:117 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at Py.jl:103 [inlined] - macro expansion at builtins.jl:63 [inlined] - macro expansion at regions.jl:302 [inlined] - pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at regions.jl:296 [inlined] - pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 - pystr_fromUTF8 at builtins.jl:585 [inlined] - pystr at builtins.jl:593 [inlined] - Py at Py.jl:117 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at Py.jl:103 [inlined] - macro expansion at builtins.jl:63 [inlined] - macro expansion at regions.jl:302 [inlined] - pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:56 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at regions.jl:302 [inlined] - pynulltuple(len::Int64) at builtins.jl:848 - macro expansion at builtins.jl:? [inlined] - pytuple_fromiter at builtins.jl:877 [inlined] - #pycall#21 at builtins.jl:220 [inlined] - pycall at builtins.jl:211 [inlined] - #_#9 at Py.jl:350 [inlined] - Py at Py.jl:350 [inlined] - PyArraySource_Buffer at PyArray.jl:504 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at regions.jl:302 [inlined] - pycallargs(f::Py, args::Py) at builtins.jl:202 - #pycall#21 at builtins.jl:221 [inlined] - pycall at builtins.jl:211 [inlined] - #_#9 at Py.jl:350 [inlined] - Py at Py.jl:350 [inlined] - PyArraySource_Buffer at PyArray.jl:504 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -String: 10 bytes - pyarray_get_R at PyArray.jl:556 [inlined] - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:104 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -PythonCall.Wrap.PyArraySource_Buffer: 32 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Tuple{Int64}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Core.SimpleVector: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -DataType: 56 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -UnionAll: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -PythonCall.Wrap.PyArraySource_Buffer: 32 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Tuple{Int64}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Core.SimpleVector: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -DataType: 56 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -UnionAll: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Vector{Symbol}: 32 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:134 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Memory{Symbol}: 40 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:143 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Tuple{Symbol, Symbol, Symbol}: 24 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:146 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Ptr{Nothing}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -PyArray{Float64, 1, (:mutable, :linear, :contiguous)}: 64 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -Some{PyArray{Float64, 1, (:mutable, :linear, :contiguous)}}: 64 bytes - pyconvert_return at pyconvert.jl:97 [inlined] - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:152 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] -PyArray{Float64, 1, (:mutable, :linear, :contiguous)}: 48 bytes - pyconvert_raw at pyconvert.jl:131 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:262 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:316 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] diff --git a/benchmark/convert-array-allocations-before.txt b/benchmark/convert-array-allocations-before.txt deleted file mode 100644 index 0972c3f2b..000000000 --- a/benchmark/convert-array-allocations-before.txt +++ /dev/null @@ -1,1389 +0,0 @@ -Julia: 1.13.2; PythonCall source: /tmp/pythoncall-convert-baseline.HAfFfi/src/PythonCall.jl - -ndarray_native -Py: 16 bytes - Py at types.jl:27 [inlined] - pynew at Py.jl:51 [inlined] - pynew at Py.jl:55 [inlined] - macro expansion at regions.jl:296 [inlined] - pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 - pystr_fromUTF8 at builtins.jl:585 [inlined] - pystr at builtins.jl:593 [inlined] - Py at Py.jl:116 [inlined] - macro expansion at Py.jl:107 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at Py.jl:102 [inlined] - macro expansion at builtins.jl:63 [inlined] - macro expansion at regions.jl:302 [inlined] - pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:41 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -Py: 16 bytes - Py at types.jl:27 [inlined] - pynew at Py.jl:51 [inlined] - pynew at Py.jl:55 [inlined] - macro expansion at builtins.jl:72 [inlined] - macro expansion at regions.jl:302 [inlined] - pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:41 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -PythonCall.Wrap.PyArraySource_ArrayStruct: 80 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -Tuple{Int64}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -Core.SimpleVector: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -DataType: 56 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -UnionAll: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -PythonCall.Wrap.PyArraySource_ArrayStruct: 80 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -Tuple{Int64}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -Core.SimpleVector: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -DataType: 56 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -UnionAll: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -Vector{Symbol}: 32 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:122 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -Memory{Symbol}: 40 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:131 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -Tuple{Symbol, Symbol, Symbol}: 24 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:134 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -Ptr{Nothing}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:139 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -PyArray{Int64, 1, (:mutable, :linear, :contiguous)}: 64 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:139 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -Profile.Allocs.BufferType: 8000 bytes - pyconvert_tryconvert(::Type{Array}, x::PyArray{Int64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:140 - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -Memory{Int64}: 24 bytes - pyconvert_tryconvert(::Type{Array}, x::PyArray{Int64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:140 - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -Vector{Int64}: 32 bytes - pyconvert_tryconvert(::Type{Array}, x::PyArray{Int64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:140 - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 - -ndarray_wrapper -Py: 16 bytes - Py at types.jl:27 [inlined] - pynew at Py.jl:51 [inlined] - pynew at Py.jl:55 [inlined] - macro expansion at regions.jl:296 [inlined] - pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 - pystr_fromUTF8 at builtins.jl:585 [inlined] - pystr at builtins.jl:593 [inlined] - Py at Py.jl:116 [inlined] - macro expansion at Py.jl:107 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at Py.jl:102 [inlined] - macro expansion at builtins.jl:63 [inlined] - macro expansion at regions.jl:302 [inlined] - pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:41 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -Py: 16 bytes - Py at types.jl:27 [inlined] - pynew at Py.jl:51 [inlined] - pynew at Py.jl:55 [inlined] - macro expansion at builtins.jl:72 [inlined] - macro expansion at regions.jl:302 [inlined] - pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:41 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -PythonCall.Wrap.PyArraySource_ArrayStruct: 80 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -Tuple{Int64}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -Core.SimpleVector: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -DataType: 56 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -UnionAll: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -PythonCall.Wrap.PyArraySource_ArrayStruct: 80 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -Tuple{Int64}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -Core.SimpleVector: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -DataType: 56 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -UnionAll: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -Vector{Symbol}: 32 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:122 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -Memory{Symbol}: 40 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:131 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -Tuple{Symbol, Symbol, Symbol}: 24 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:134 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -Ptr{Nothing}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:139 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -PyArray{Int64, 1, (:mutable, :linear, :contiguous)}: 64 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:139 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:43 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 - -buffer_native -Py: 16 bytes - Py at types.jl:27 [inlined] - pynew at Py.jl:51 [inlined] - pynew at Py.jl:55 [inlined] - macro expansion at regions.jl:296 [inlined] - pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 - pystr_fromUTF8 at builtins.jl:585 [inlined] - pystr at builtins.jl:593 [inlined] - Py at Py.jl:116 [inlined] - macro expansion at Py.jl:107 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at Py.jl:102 [inlined] - macro expansion at builtins.jl:63 [inlined] - macro expansion at regions.jl:302 [inlined] - pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:41 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -Py: 16 bytes - Py at types.jl:27 [inlined] - pynew at Py.jl:51 [inlined] - pynew at Py.jl:55 [inlined] - macro expansion at regions.jl:296 [inlined] - pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 - pystr_fromUTF8 at builtins.jl:585 [inlined] - pystr at builtins.jl:593 [inlined] - Py at Py.jl:116 [inlined] - macro expansion at Py.jl:107 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at Py.jl:102 [inlined] - macro expansion at builtins.jl:63 [inlined] - macro expansion at regions.jl:302 [inlined] - pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -Py: 16 bytes - Py at types.jl:27 [inlined] - pynew at Py.jl:51 [inlined] - pynew at Py.jl:55 [inlined] - macro expansion at regions.jl:302 [inlined] - pynulltuple(len::Int64) at builtins.jl:848 - macro expansion at builtins.jl:? [inlined] - pytuple_fromiter at builtins.jl:877 [inlined] - #pycall#21 at builtins.jl:220 [inlined] - pycall at builtins.jl:211 [inlined] - #_#9 at Py.jl:349 [inlined] - Py at Py.jl:349 [inlined] - PyArraySource_Buffer at PyArray.jl:492 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -Py: 16 bytes - Py at types.jl:27 [inlined] - pynew at Py.jl:51 [inlined] - pynew at Py.jl:55 [inlined] - macro expansion at regions.jl:302 [inlined] - pycallargs(f::Py, args::Py) at builtins.jl:202 - #pycall#21 at builtins.jl:221 [inlined] - pycall at builtins.jl:211 [inlined] - #_#9 at Py.jl:349 [inlined] - Py at Py.jl:349 [inlined] - PyArraySource_Buffer at PyArray.jl:492 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -String: 10 bytes - pyarray_get_R at PyArray.jl:544 [inlined] - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:92 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -PythonCall.Wrap.PyArraySource_Buffer: 32 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -Tuple{Int64}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -Core.SimpleVector: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -DataType: 56 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -UnionAll: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -PythonCall.Wrap.PyArraySource_Buffer: 32 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -Tuple{Int64}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -Core.SimpleVector: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -DataType: 56 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -UnionAll: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -Vector{Symbol}: 32 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:122 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -Memory{Symbol}: 40 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:131 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -Tuple{Symbol, Symbol, Symbol}: 24 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:134 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -Ptr{Nothing}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:139 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -PyArray{Float64, 1, (:mutable, :linear, :contiguous)}: 64 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:139 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -Profile.Allocs.BufferType: 8000 bytes - pyconvert_tryconvert(::Type{Array}, x::PyArray{Float64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:140 - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -Memory{Float64}: 24 bytes - pyconvert_tryconvert(::Type{Array}, x::PyArray{Float64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:140 - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 -Vector{Float64}: 32 bytes - pyconvert_tryconvert(::Type{Array}, x::PyArray{Float64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:140 - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{Array}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{Array}, x::Py, d::Nothing) at pyconvert.jl:396 - -buffer_wrapper -Py: 16 bytes - Py at types.jl:27 [inlined] - pynew at Py.jl:51 [inlined] - pynew at Py.jl:55 [inlined] - macro expansion at regions.jl:296 [inlined] - pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 - pystr_fromUTF8 at builtins.jl:585 [inlined] - pystr at builtins.jl:593 [inlined] - Py at Py.jl:116 [inlined] - macro expansion at Py.jl:107 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at Py.jl:102 [inlined] - macro expansion at builtins.jl:63 [inlined] - macro expansion at regions.jl:302 [inlined] - pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:41 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -Py: 16 bytes - Py at types.jl:27 [inlined] - pynew at Py.jl:51 [inlined] - pynew at Py.jl:55 [inlined] - macro expansion at regions.jl:296 [inlined] - pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 - pystr_fromUTF8 at builtins.jl:585 [inlined] - pystr at builtins.jl:593 [inlined] - Py at Py.jl:116 [inlined] - macro expansion at Py.jl:107 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at Py.jl:102 [inlined] - macro expansion at builtins.jl:63 [inlined] - macro expansion at regions.jl:302 [inlined] - pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -Py: 16 bytes - Py at types.jl:27 [inlined] - pynew at Py.jl:51 [inlined] - pynew at Py.jl:55 [inlined] - macro expansion at regions.jl:302 [inlined] - pynulltuple(len::Int64) at builtins.jl:848 - macro expansion at builtins.jl:? [inlined] - pytuple_fromiter at builtins.jl:877 [inlined] - #pycall#21 at builtins.jl:220 [inlined] - pycall at builtins.jl:211 [inlined] - #_#9 at Py.jl:349 [inlined] - Py at Py.jl:349 [inlined] - PyArraySource_Buffer at PyArray.jl:492 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -Py: 16 bytes - Py at types.jl:27 [inlined] - pynew at Py.jl:51 [inlined] - pynew at Py.jl:55 [inlined] - macro expansion at regions.jl:302 [inlined] - pycallargs(f::Py, args::Py) at builtins.jl:202 - #pycall#21 at builtins.jl:221 [inlined] - pycall at builtins.jl:211 [inlined] - #_#9 at Py.jl:349 [inlined] - Py at Py.jl:349 [inlined] - PyArraySource_Buffer at PyArray.jl:492 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -String: 10 bytes - pyarray_get_R at PyArray.jl:544 [inlined] - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:92 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -PythonCall.Wrap.PyArraySource_Buffer: 32 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -Tuple{Int64}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -Core.SimpleVector: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -DataType: 56 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -UnionAll: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:115 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -PythonCall.Wrap.PyArraySource_Buffer: 32 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -Tuple{Int64}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -Core.SimpleVector: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -DataType: 56 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -UnionAll: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:117 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -Vector{Symbol}: 32 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:122 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -Memory{Symbol}: 40 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:131 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -Tuple{Symbol, Symbol, Symbol}: 24 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:134 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -Ptr{Nothing}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:139 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 -PyArray{Float64, 1, (:mutable, :linear, :contiguous)}: 64 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:139 - pyarray_make at PyArray.jl:92 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:57 - pyarray_make at PyArray.jl:32 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##0#pyconvert_fix##1"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(x::Py) at pyconvert.jl:300 - macro expansion at regions.jl:323 [inlined] - pytryconvert(::Type{PyArray}, x_::Py) at pyconvert.jl:357 - macro expansion at pyconvert.jl:376 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at pyconvert.jl:373 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:302 [inlined] - macro expansion at Py.jl:102 [inlined] - pyconvert(::Type{PyArray}, x::Py, d::Nothing) at pyconvert.jl:396 diff --git a/benchmark/convert-array-allocations-unwrapped.txt b/benchmark/convert-array-allocations-unwrapped.txt deleted file mode 100644 index 23732a8f7..000000000 --- a/benchmark/convert-array-allocations-unwrapped.txt +++ /dev/null @@ -1,1389 +0,0 @@ -Julia: 1.13.2; PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl - -ndarray_native -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at regions.jl:296 [inlined] - pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 - pystr_fromUTF8 at builtins.jl:585 [inlined] - pystr at builtins.jl:593 [inlined] - Py at Py.jl:117 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at Py.jl:103 [inlined] - macro expansion at builtins.jl:63 [inlined] - macro expansion at regions.jl:302 [inlined] - pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at builtins.jl:72 [inlined] - macro expansion at regions.jl:302 [inlined] - pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -PythonCall.Wrap.PyArraySource_ArrayStruct: 80 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Tuple{Int64}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Core.SimpleVector: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -DataType: 56 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -UnionAll: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -PythonCall.Wrap.PyArraySource_ArrayStruct: 80 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Tuple{Int64}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Core.SimpleVector: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -DataType: 56 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -UnionAll: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Vector{Symbol}: 32 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:134 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Memory{Symbol}: 40 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:143 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Tuple{Symbol, Symbol, Symbol}: 24 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:146 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Ptr{Nothing}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -PyArray{Int64, 1, (:mutable, :linear, :contiguous)}: 64 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Profile.Allocs.BufferType: 8000 bytes - pyconvert_tryconvert(::Type{Array}, x::PyArray{Int64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:142 - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Memory{Int64}: 24 bytes - pyconvert_tryconvert(::Type{Array}, x::PyArray{Int64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:142 - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Vector{Int64}: 32 bytes - pyconvert_tryconvert(::Type{Array}, x::PyArray{Int64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:142 - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] - -ndarray_wrapper -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at regions.jl:296 [inlined] - pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 - pystr_fromUTF8 at builtins.jl:585 [inlined] - pystr at builtins.jl:593 [inlined] - Py at Py.jl:117 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at Py.jl:103 [inlined] - macro expansion at builtins.jl:63 [inlined] - macro expansion at regions.jl:302 [inlined] - pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at builtins.jl:72 [inlined] - macro expansion at regions.jl:302 [inlined] - pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -PythonCall.Wrap.PyArraySource_ArrayStruct: 80 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Tuple{Int64}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Core.SimpleVector: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -DataType: 56 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -UnionAll: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -PythonCall.Wrap.PyArraySource_ArrayStruct: 80 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Tuple{Int64}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Core.SimpleVector: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -DataType: 56 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -UnionAll: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Vector{Symbol}: 32 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:134 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Memory{Symbol}: 40 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:143 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Tuple{Symbol, Symbol, Symbol}: 24 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:146 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Ptr{Nothing}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -PyArray{Int64, 1, (:mutable, :linear, :contiguous)}: 64 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_ArrayStruct, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:50 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] - -buffer_native -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at regions.jl:296 [inlined] - pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 - pystr_fromUTF8 at builtins.jl:585 [inlined] - pystr at builtins.jl:593 [inlined] - Py at Py.jl:117 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at Py.jl:103 [inlined] - macro expansion at builtins.jl:63 [inlined] - macro expansion at regions.jl:302 [inlined] - pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at regions.jl:296 [inlined] - pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 - pystr_fromUTF8 at builtins.jl:585 [inlined] - pystr at builtins.jl:593 [inlined] - Py at Py.jl:117 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at Py.jl:103 [inlined] - macro expansion at builtins.jl:63 [inlined] - macro expansion at regions.jl:302 [inlined] - pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:56 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at regions.jl:302 [inlined] - pynulltuple(len::Int64) at builtins.jl:848 - macro expansion at builtins.jl:? [inlined] - pytuple_fromiter at builtins.jl:877 [inlined] - #pycall#21 at builtins.jl:220 [inlined] - pycall at builtins.jl:211 [inlined] - #_#9 at Py.jl:350 [inlined] - Py at Py.jl:350 [inlined] - PyArraySource_Buffer at PyArray.jl:504 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at regions.jl:302 [inlined] - pycallargs(f::Py, args::Py) at builtins.jl:202 - #pycall#21 at builtins.jl:221 [inlined] - pycall at builtins.jl:211 [inlined] - #_#9 at Py.jl:350 [inlined] - Py at Py.jl:350 [inlined] - PyArraySource_Buffer at PyArray.jl:504 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -String: 10 bytes - pyarray_get_R at PyArray.jl:556 [inlined] - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:104 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -PythonCall.Wrap.PyArraySource_Buffer: 32 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Tuple{Int64}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Core.SimpleVector: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -DataType: 56 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -UnionAll: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -PythonCall.Wrap.PyArraySource_Buffer: 32 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Tuple{Int64}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Core.SimpleVector: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -DataType: 56 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -UnionAll: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Vector{Symbol}: 32 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:134 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Memory{Symbol}: 40 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:143 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Tuple{Symbol, Symbol, Symbol}: 24 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:146 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Ptr{Nothing}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -PyArray{Float64, 1, (:mutable, :linear, :contiguous)}: 64 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:22 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Profile.Allocs.BufferType: 8000 bytes - pyconvert_tryconvert(::Type{Array}, x::PyArray{Float64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:142 - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Memory{Float64}: 24 bytes - pyconvert_tryconvert(::Type{Array}, x::PyArray{Float64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:142 - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Vector{Float64}: 32 bytes - pyconvert_tryconvert(::Type{Array}, x::PyArray{Float64, 1, (:mutable, :linear, :contiguous)}) at pyconvert.jl:142 - pyconvert_rule_array(::Type{Array}, x::Py) at PyArray.jl:26 - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{Array, typeof(PythonCall.Wrap.pyconvert_rule_array)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Array}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] - -buffer_wrapper -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at regions.jl:296 [inlined] - pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 - pystr_fromUTF8 at builtins.jl:585 [inlined] - pystr at builtins.jl:593 [inlined] - Py at Py.jl:117 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at Py.jl:103 [inlined] - macro expansion at builtins.jl:63 [inlined] - macro expansion at regions.jl:302 [inlined] - pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:48 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at regions.jl:296 [inlined] - pystr_fromUTF8(x::Ptr{UInt8}, n::Int64) at builtins.jl:583 - pystr_fromUTF8 at builtins.jl:585 [inlined] - pystr at builtins.jl:593 [inlined] - Py at Py.jl:117 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at Py.jl:103 [inlined] - macro expansion at builtins.jl:63 [inlined] - macro expansion at regions.jl:302 [inlined] - pygetattr(x::Py, k::String, d::Py) at builtins.jl:62 - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:56 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at regions.jl:302 [inlined] - pynulltuple(len::Int64) at builtins.jl:848 - macro expansion at builtins.jl:? [inlined] - pytuple_fromiter at builtins.jl:877 [inlined] - #pycall#21 at builtins.jl:220 [inlined] - pycall at builtins.jl:211 [inlined] - #_#9 at Py.jl:350 [inlined] - Py at Py.jl:350 [inlined] - PyArraySource_Buffer at PyArray.jl:504 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at regions.jl:302 [inlined] - pycallargs(f::Py, args::Py) at builtins.jl:202 - #pycall#21 at builtins.jl:221 [inlined] - pycall at builtins.jl:211 [inlined] - #_#9 at Py.jl:350 [inlined] - Py at Py.jl:350 [inlined] - PyArraySource_Buffer at PyArray.jl:504 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -String: 10 bytes - pyarray_get_R at PyArray.jl:556 [inlined] - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:104 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -PythonCall.Wrap.PyArraySource_Buffer: 32 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Tuple{Int64}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Core.SimpleVector: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -DataType: 56 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -UnionAll: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:127 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -PythonCall.Wrap.PyArraySource_Buffer: 32 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Tuple{Int64}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Core.SimpleVector: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -DataType: 56 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -UnionAll: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:129 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Vector{Symbol}: 32 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:134 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Memory{Symbol}: 40 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:143 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Tuple{Symbol, Symbol, Symbol}: 24 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:146 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -Ptr{Nothing}: 16 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] -PyArray{Float64, 1, (:mutable, :linear, :contiguous)}: 64 bytes - pyarray_make(::Type{PyArray}, x::Py, info::PythonCall.Wrap.PyArraySource_Buffer, ::Type{PyArray{Union{}, Union{}, Union{}}}, ::Type{PyArray{Any, Any, Any}}) at PyArray.jl:151 - pyarray_make at PyArray.jl:104 [inlined] - pyarray_make(::Type{PyArray}, x::Py; array::Bool, buffer::Bool, copy::Bool) at PyArray.jl:66 - pyarray_make at PyArray.jl:39 [inlined] - pyconvert_rule_array_nocopy at PyArray.jl:18 [inlined] - (::PythonCall.Convert.var"#pyconvert_fix##2#pyconvert_fix##3"{PyArray, typeof(PythonCall.Wrap.pyconvert_rule_array_nocopy)})(ctx::PyConvertContext{Tuple{}}, x::Py) at pyconvert.jl:266 - macro expansion at regions.jl:323 [inlined] - pyconvert_first at pyconvert.jl:320 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py) at pyconvert.jl:326 - pytryconvert_raw at pyconvert.jl:345 [inlined] - macro expansion at pyconvert.jl:421 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{PyArray}, x::Py, default::Nothing) at pyconvert.jl:420 - #pyconvert#36 at pyconvert.jl:426 [inlined] - pyconvert at pyconvert.jl:426 [inlined] diff --git a/benchmark/convert-baseline.tsv b/benchmark/convert-baseline.tsv deleted file mode 100644 index 588a89e1c..000000000 --- a/benchmark/convert-baseline.tsv +++ /dev/null @@ -1,16 +0,0 @@ -case ns bytes allocs -int 379.32211538461536 0 0 -integer 716.6590909090909 0 0 -bigint 1140.0 216 7 -float 380.9707317073171 16 1 -bool 420.3744075829384 0 0 -string 529.0765306122449 48 2 -none 349.76056338028167 0 0 -failure 366.33658536585364 0 0 -list10 9299.0 704 17 -list10000 7.432131e6 513864 19507 -mixed 7449.75 608 20 -nested 575.6850828729282 16 1 -dict 8699.75 1248 22 -wrapper 558.0591397849462 16 1 -iterator 579.5524861878453 16 1 diff --git a/benchmark/convert-dispatch-final.tsv b/benchmark/convert-dispatch-final.tsv deleted file mode 100644 index e1bef004a..000000000 --- a/benchmark/convert-dispatch-final.tsv +++ /dev/null @@ -1,10 +0,0 @@ -case ns bytes allocs -no_preference 9700.0 864 32 -one_preference 1899.9 256 11 -multiple_preferences 3475.0 576 21 -unmatched_preferences 22099.0 2304 93 -nested_context 5283.333333333333 608 26 -ndarray_native 5014.285714285715 8888 23 -ndarray_wrapper 3225.0 800 19 -bytes_explicit 584.0604395604396 128 4 -scope_filtered 5216.5 688 17 diff --git a/benchmark/convert-dispatch.tsv b/benchmark/convert-dispatch.tsv deleted file mode 100644 index 78a9c13fe..000000000 --- a/benchmark/convert-dispatch.tsv +++ /dev/null @@ -1,12 +0,0 @@ -case ns bytes allocs -no_preference 11100.0 864 32 -one_preference 1740.0 192 9 -multiple_preferences 3437.375 448 17 -unmatched_preferences 26399.0 2240 91 -nested_context 5300.0 544 24 -ndarray_native 4614.142857142857 8888 23 -ndarray_wrapper 3662.5 800 19 -buffer 710.608938547486 128 4 -scope_filtered 8400.0 864 28 -selection_miss 37799.0 2160 76 -registry_rebuild 2.484981e6 1310488 19575 diff --git a/benchmark/convert-expanded-after-environment.txt b/benchmark/convert-expanded-after-environment.txt deleted file mode 100644 index 355c75eca..000000000 --- a/benchmark/convert-expanded-after-environment.txt +++ /dev/null @@ -1,7 +0,0 @@ -Julia: 1.13.2 -Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] -Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python -NumPy: 2.5.4 -BenchmarkTools: 1.8.0 -PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl -New API: true diff --git a/benchmark/convert-expanded-after.tsv b/benchmark/convert-expanded-after.tsv deleted file mode 100644 index b08ebc35e..000000000 --- a/benchmark/convert-expanded-after.tsv +++ /dev/null @@ -1,37 +0,0 @@ -case mode status min_ns median_ns bytes allocs -single_rule warm measured 380.3872549019608 424.5049019607843 0 0 -single_rule selection_miss measured 66399.0 67099.0 8304 261 -single_rule invalidated measured 2.59848e6 2.999976e6 1535216 22416 -decline_then_success warm measured 535.7842105263157 537.3684210526316 0 0 -decline_then_success selection_miss measured 72299.0 81800.0 8400 264 -decline_then_success invalidated measured 2.670179e6 3.0039265e6 1535312 22419 -three_declines_then_success warm measured 861.4142857142857 869.9857142857143 0 0 -three_declines_then_success selection_miss measured 76100.0 83699.0 8688 271 -three_declines_then_success invalidated measured 2.662079e6 2.8253285e6 1535600 22426 -sixteen_scoped_decliners warm measured 401.9850746268657 414.4228855721393 0 0 -sixteen_scoped_decliners selection_miss measured 69900.0 78999.0 8304 261 -sixteen_scoped_decliners invalidated measured 2.65408e6 2.7655285e6 1535216 22416 -virtual_mapping_abc warm measured 401.9655172413793 413.7881773399015 0 0 -virtual_mapping_abc selection_miss measured 66700.0 76700.0 8304 261 -virtual_mapping_abc invalidated measured 2.672779e6 2.843228e6 1535216 22416 -buffer_only_native warm measured 7199.75 7650.0 8856 26 -buffer_only_native selection_miss measured 40199.0 45049.5 9880 62 -buffer_only_native invalidated measured 2.640482e6 2.723231e6 1535928 22205 -buffer_only_wrapper warm measured 5599.833333333333 6250.0 768 22 -buffer_only_wrapper selection_miss measured 36800.0 39899.0 1920 58 -buffer_only_wrapper invalidated measured 2.646981e6 3.003029e6 1527968 22201 -interface_only_native warm measured 22600.0 23500.0 9368 55 -interface_only_native selection_miss measured 59700.0 68399.0 10408 91 -interface_only_native invalidated measured 2.978079e6 3.2996265e6 1567848 23253 -array_method_only_native warm measured 7774.75 8450.0 9016 30 -array_method_only_native selection_miss measured 41200.0 45399.0 10056 66 -array_method_only_native invalidated measured 2.663281e6 2.7410805e6 1536968 22221 -ndarray_native warm measured 4966.666666666667 5550.0 8888 23 -ndarray_native selection_miss measured 36400.0 39199.0 10872 84 -ndarray_native invalidated measured 2.740381e6 2.8986295e6 1536920 22227 -ndarray_wrapper warm measured 3362.5 3537.375 800 19 -ndarray_wrapper selection_miss measured 34600.0 37399.0 3488 86 -ndarray_wrapper invalidated measured 2.688781e6 3.030328e6 1529536 22229 -two_matching_first_success warm measured 3275.0 3487.5 432 14 -two_matching_first_declines warm measured 3812.5 3962.5 592 20 -two_matching_decline_then_ordinary warm measured 4171.428571428572 4257.142857142857 624 21 diff --git a/benchmark/convert-expanded-before-environment.txt b/benchmark/convert-expanded-before-environment.txt deleted file mode 100644 index aee3d1309..000000000 --- a/benchmark/convert-expanded-before-environment.txt +++ /dev/null @@ -1,7 +0,0 @@ -Julia: 1.13.2 -Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] -Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python -NumPy: 2.5.4 -BenchmarkTools: 1.8.0 -PythonCall source: /tmp/pythoncall-convert-baseline.HAfFfi/src/PythonCall.jl -New API: false diff --git a/benchmark/convert-expanded-before.tsv b/benchmark/convert-expanded-before.tsv deleted file mode 100644 index 3adcb9207..000000000 --- a/benchmark/convert-expanded-before.tsv +++ /dev/null @@ -1,37 +0,0 @@ -case mode status min_ns median_ns bytes allocs -single_rule warm measured 393.5323383084577 404.4726368159204 0 0 -single_rule selection_miss measured 26500.0 29000.0 4976 149 -single_rule invalidated measured 21400.0 23150.0 4976 149 -decline_then_success warm measured 547.3351063829788 548.3989361702128 0 0 -decline_then_success selection_miss measured 27700.0 29749.5 5840 174 -decline_then_success invalidated measured 29400.0 30499.5 5840 174 -three_declines_then_success warm measured 871.1346153846154 875.0 0 0 -three_declines_then_success selection_miss measured 30299.0 33450.0 8752 234 -three_declines_then_success invalidated measured 34000.0 35750.0 8752 234 -sixteen_scoped_decliners warm measured 4114.142857142857 4157.0 0 0 -sixteen_scoped_decliners selection_miss measured 65999.0 74499.5 31344 797 -sixteen_scoped_decliners invalidated measured 72500.0 78150.0 31344 797 -virtual_mapping_abc warm measured 397.029702970297 398.509900990099 0 0 -virtual_mapping_abc selection_miss measured 49999.0 54400.0 18752 539 -virtual_mapping_abc invalidated measured 65799.0 70549.5 18752 539 -buffer_only_native warm measured 7050.0 7612.375 8712 23 -buffer_only_native selection_miss measured 79599.0 99699.5 35784 778 -buffer_only_native invalidated measured 105799.0 116549.0 35784 778 -buffer_only_wrapper warm measured 5266.5 5983.333333333333 640 20 -buffer_only_wrapper selection_miss measured 82000.0 95449.5 26816 757 -buffer_only_wrapper invalidated measured 87900.0 98599.0 26816 757 -interface_only_native warm measured 21400.0 22600.0 9224 52 -interface_only_native selection_miss measured 66200.0 77599.5 15896 244 -interface_only_native invalidated measured 240499.0 272048.0 64232 1579 -array_method_only_native warm measured 7733.333333333333 8233.0 8872 27 -array_method_only_native selection_miss measured 44700.0 51500.0 15544 219 -array_method_only_native invalidated measured 50500.0 55050.0 15544 219 -ndarray_native warm measured 4485.714285714285 4864.214285714286 8744 20 -ndarray_native selection_miss measured 73899.0 84599.0 35208 788 -ndarray_native invalidated measured 83000.0 88999.5 35208 788 -ndarray_wrapper warm measured 3112.5 3312.5 672 17 -ndarray_wrapper selection_miss measured 67099.0 79599.5 28208 803 -ndarray_wrapper invalidated measured 82400.0 87399.5 28208 803 -two_matching_first_success warm unsupported NA NA NA NA -two_matching_first_declines warm unsupported NA NA NA NA -two_matching_decline_then_ordinary warm unsupported NA NA NA NA diff --git a/benchmark/convert-expanded-final-after-r1-environment.txt b/benchmark/convert-expanded-final-after-r1-environment.txt deleted file mode 100644 index fce316d62..000000000 --- a/benchmark/convert-expanded-final-after-r1-environment.txt +++ /dev/null @@ -1,10 +0,0 @@ -Julia: 1.13.2 -Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] -Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python -NumPy: 2.5.4 -BenchmarkTools: 1.8.0 -PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl -New API: true -Convert/pyconvert.jl SHA256: 7d8337b08370a90127dcc5a9d7b9b79f743ee2998c5ac6154a671725682aad6e -Convert/rules.jl SHA256: d42b0af459b0243412a5f9befa62caccc5039a8e0561be414cf9f941a6c328e4 -Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a diff --git a/benchmark/convert-expanded-final-after-r1.tsv b/benchmark/convert-expanded-final-after-r1.tsv deleted file mode 100644 index 256344ff8..000000000 --- a/benchmark/convert-expanded-final-after-r1.tsv +++ /dev/null @@ -1,37 +0,0 @@ -case mode status min_ns median_ns bytes allocs -single_rule warm measured 377.9362745098039 388.2352941176471 0 0 -single_rule selection_miss measured 63999.0 72299.0 8304 261 -single_rule invalidated measured 2.562281e6 3.059677e6 1474960 21262 -decline_then_success warm measured 528.7905759162304 586.9057591623036 0 0 -decline_then_success selection_miss measured 62999.0 63600.0 8400 264 -decline_then_success invalidated measured 2.542581e6 2.897078e6 1475056 21265 -three_declines_then_success warm measured 842.8214285714286 989.2857142857143 0 0 -three_declines_then_success selection_miss measured 62499.0 66550.0 8688 271 -three_declines_then_success invalidated measured 2.508581e6 2.6649795e6 1475344 21272 -sixteen_scoped_decliners warm measured 380.87745098039215 401.4656862745098 0 0 -sixteen_scoped_decliners selection_miss measured 71500.0 78699.5 8304 261 -sixteen_scoped_decliners invalidated measured 2.500481e6 2.6097305e6 1474960 21262 -virtual_mapping_abc warm measured 379.40686274509807 433.3333333333333 0 0 -virtual_mapping_abc selection_miss measured 71599.0 81300.0 8304 261 -virtual_mapping_abc invalidated measured 2.533781e6 2.7204295e6 1474960 21262 -buffer_only_native warm measured 7399.75 8300.0 8856 26 -buffer_only_native selection_miss measured 43600.0 48399.5 9880 62 -buffer_only_native invalidated measured 2.75358e6 3.167676e6 1475672 21051 -buffer_only_wrapper warm measured 5549.833333333333 6608.25 768 22 -buffer_only_wrapper selection_miss measured 31700.0 33300.0 1920 58 -buffer_only_wrapper invalidated measured 2.525881e6 2.667029e6 1467712 21047 -interface_only_native warm measured 22999.0 24100.0 9368 55 -interface_only_native selection_miss measured 57999.0 65000.0 10408 91 -interface_only_native invalidated measured 2.864778e6 3.1550755e6 1507208 22091 -array_method_only_native warm measured 8000.0 9533.0 9016 30 -array_method_only_native selection_miss measured 36100.0 38799.0 10056 66 -array_method_only_native invalidated measured 2.679379e6 2.944427e6 1476712 21067 -ndarray_native warm measured 4750.0 5150.0 8888 23 -ndarray_native selection_miss measured 38400.0 41149.5 10872 84 -ndarray_native invalidated measured 2.58148e6 2.6334295e6 1476664 21073 -ndarray_wrapper warm measured 3287.5 3637.5 800 19 -ndarray_wrapper selection_miss measured 34300.0 37100.0 3488 86 -ndarray_wrapper invalidated measured 2.870077e6 3.0517765e6 1469280 21075 -two_matching_first_success warm measured 3375.0 3975.0 560 18 -two_matching_first_declines warm measured 4128.428571428572 4871.428571428572 720 24 -two_matching_decline_then_ordinary warm measured 4685.714285714285 5014.142857142857 752 25 diff --git a/benchmark/convert-expanded-final-after-r2-environment.txt b/benchmark/convert-expanded-final-after-r2-environment.txt deleted file mode 100644 index fce316d62..000000000 --- a/benchmark/convert-expanded-final-after-r2-environment.txt +++ /dev/null @@ -1,10 +0,0 @@ -Julia: 1.13.2 -Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] -Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python -NumPy: 2.5.4 -BenchmarkTools: 1.8.0 -PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl -New API: true -Convert/pyconvert.jl SHA256: 7d8337b08370a90127dcc5a9d7b9b79f743ee2998c5ac6154a671725682aad6e -Convert/rules.jl SHA256: d42b0af459b0243412a5f9befa62caccc5039a8e0561be414cf9f941a6c328e4 -Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a diff --git a/benchmark/convert-expanded-final-after-r2.tsv b/benchmark/convert-expanded-final-after-r2.tsv deleted file mode 100644 index 4617dd310..000000000 --- a/benchmark/convert-expanded-final-after-r2.tsv +++ /dev/null @@ -1,37 +0,0 @@ -case mode status min_ns median_ns bytes allocs -single_rule warm measured 402.44607843137254 403.4313725490196 0 0 -single_rule selection_miss measured 71199.0 79449.5 8304 261 -single_rule invalidated measured 2.58888e6 2.990877e6 1474960 21262 -decline_then_success warm measured 573.3989361702128 638.2925531914893 0 0 -decline_then_success selection_miss measured 67899.0 77000.0 8400 264 -decline_then_success invalidated measured 2.66258e6 3.0398265e6 1475056 21265 -three_declines_then_success warm measured 936.0 954.0 0 0 -three_declines_then_success selection_miss measured 62399.0 65800.0 8688 271 -three_declines_then_success invalidated measured 2.62558e6 2.725679e6 1475344 21272 -sixteen_scoped_decliners warm measured 402.00502512562815 473.86934673366835 0 0 -sixteen_scoped_decliners selection_miss measured 60900.0 79249.5 8304 261 -sixteen_scoped_decliners invalidated measured 2.872478e6 4.6828645e6 1474960 21262 -virtual_mapping_abc warm measured 391.6617647058824 434.79901960784315 0 0 -virtual_mapping_abc selection_miss measured 71499.0 76850.0 8304 261 -virtual_mapping_abc invalidated measured 2.60008e6 2.741429e6 1474960 21262 -buffer_only_native warm measured 7675.0 8550.0 8856 26 -buffer_only_native selection_miss measured 41900.0 46700.0 9880 62 -buffer_only_native invalidated measured 2.608181e6 2.942877e6 1475672 21051 -buffer_only_wrapper warm measured 5619.8 6020.0 768 22 -buffer_only_wrapper selection_miss measured 35099.0 36900.0 1920 58 -buffer_only_wrapper invalidated measured 2.528881e6 2.8052785e6 1467712 21047 -interface_only_native warm measured 22600.0 24000.0 9368 55 -interface_only_native selection_miss measured 58600.0 66699.0 10408 91 -interface_only_native invalidated measured 2.890477e6 2.9367265e6 1507208 22091 -array_method_only_native warm measured 7933.333333333333 9033.0 9016 30 -array_method_only_native selection_miss measured 38999.0 42200.0 10056 66 -array_method_only_native invalidated measured 2.648979e6 2.903577e6 1476712 21067 -ndarray_native warm measured 4950.0 5666.666666666667 8888 23 -ndarray_native selection_miss measured 41300.0 46949.5 10872 84 -ndarray_native invalidated measured 2.949576e6 3.063675e6 1476664 21073 -ndarray_wrapper warm measured 3612.5 3925.0 800 19 -ndarray_wrapper selection_miss measured 33899.0 36899.5 3488 86 -ndarray_wrapper invalidated measured 2.649578e6 3.021126e6 1469280 21075 -two_matching_first_success warm measured 3499.875 3750.0 560 18 -two_matching_first_declines warm measured 4228.428571428572 4642.857142857143 720 24 -two_matching_decline_then_ordinary warm measured 5285.714285714285 5671.428571428572 752 25 diff --git a/benchmark/convert-expanded-final-after-r3-environment.txt b/benchmark/convert-expanded-final-after-r3-environment.txt deleted file mode 100644 index fce316d62..000000000 --- a/benchmark/convert-expanded-final-after-r3-environment.txt +++ /dev/null @@ -1,10 +0,0 @@ -Julia: 1.13.2 -Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] -Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python -NumPy: 2.5.4 -BenchmarkTools: 1.8.0 -PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl -New API: true -Convert/pyconvert.jl SHA256: 7d8337b08370a90127dcc5a9d7b9b79f743ee2998c5ac6154a671725682aad6e -Convert/rules.jl SHA256: d42b0af459b0243412a5f9befa62caccc5039a8e0561be414cf9f941a6c328e4 -Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a diff --git a/benchmark/convert-expanded-final-after-r3.tsv b/benchmark/convert-expanded-final-after-r3.tsv deleted file mode 100644 index b59ee3ce7..000000000 --- a/benchmark/convert-expanded-final-after-r3.tsv +++ /dev/null @@ -1,37 +0,0 @@ -case mode status min_ns median_ns bytes allocs -single_rule warm measured 376.3497536945813 393.5960591133005 0 0 -single_rule selection_miss measured 71800.0 81699.5 8304 261 -single_rule invalidated measured 2.59368e6 2.987577e6 1474960 21262 -decline_then_success warm measured 540.2063492063492 541.7936507936508 0 0 -decline_then_success selection_miss measured 72899.0 80699.5 8400 264 -decline_then_success invalidated measured 2.60238e6 2.9269775e6 1475056 21265 -three_declines_then_success warm measured 994.719298245614 1031.578947368421 0 0 -three_declines_then_success selection_miss measured 71799.0 81649.5 8688 271 -three_declines_then_success invalidated measured 2.588081e6 2.753979e6 1475344 21272 -sixteen_scoped_decliners warm measured 384.7241379310345 440.38916256157637 0 0 -sixteen_scoped_decliners selection_miss measured 70199.0 77199.5 8304 261 -sixteen_scoped_decliners invalidated measured 2.58768e6 2.6627795e6 1474960 21262 -virtual_mapping_abc warm measured 375.6048780487805 417.0682926829268 0 0 -virtual_mapping_abc selection_miss measured 61300.0 62000.0 8304 261 -virtual_mapping_abc invalidated measured 2.61728e6 2.9357275e6 1474960 21262 -buffer_only_native warm measured 7474.75 8300.0 8856 26 -buffer_only_native selection_miss measured 44899.0 48900.0 9880 62 -buffer_only_native invalidated measured 2.60498e6 2.937977e6 1475672 21051 -buffer_only_wrapper warm measured 5633.166666666667 6433.166666666667 768 22 -buffer_only_wrapper selection_miss measured 35000.0 36949.5 1920 58 -buffer_only_wrapper invalidated measured 2.58308e6 2.6519795e6 1467712 21047 -interface_only_native warm measured 21800.0 24500.0 9368 55 -interface_only_native selection_miss measured 58100.0 67999.5 10408 91 -interface_only_native invalidated measured 3.192776e6 3.325924e6 1507208 22091 -array_method_only_native warm measured 8233.333333333334 9100.0 9016 30 -array_method_only_native selection_miss measured 39300.0 42400.0 10056 66 -array_method_only_native invalidated measured 2.55408e6 2.731279e6 1476712 21067 -ndarray_native warm measured 4816.5 5166.666666666667 8888 23 -ndarray_native selection_miss measured 39000.0 41199.5 10872 84 -ndarray_native invalidated measured 2.58278e6 2.6616295e6 1476664 21073 -ndarray_wrapper warm measured 3725.0 4112.5 800 19 -ndarray_wrapper selection_miss measured 35399.0 37300.0 3488 86 -ndarray_wrapper invalidated measured 2.875978e6 3.184225e6 1469280 21075 -two_matching_first_success warm measured 3325.0 3937.5 560 18 -two_matching_first_declines warm measured 4114.285714285715 4571.428571428572 720 24 -two_matching_decline_then_ordinary warm measured 5142.857142857143 5442.714285714285 752 25 diff --git a/benchmark/convert-expanded-final-before-r1-environment.txt b/benchmark/convert-expanded-final-before-r1-environment.txt deleted file mode 100644 index f248d0560..000000000 --- a/benchmark/convert-expanded-final-before-r1-environment.txt +++ /dev/null @@ -1,10 +0,0 @@ -Julia: 1.13.2 -Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] -Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python -NumPy: 2.5.4 -BenchmarkTools: 1.8.0 -PythonCall source: /tmp/pythoncall-convert-baseline.HAfFfi/src/PythonCall.jl -New API: false -Convert/pyconvert.jl SHA256: 5509bf4deca224297091884d72a684ead91a2f1b42444c46047f228ff75d4619 -Convert/rules.jl SHA256: 3c1c30262bcc1f2e940d8d64593b4b3c869d2523d0789f7d13da76638db9032c -Wrap/PyArray.jl SHA256: 10e270400fab16e3941fc127021fc4f25a4c3c0a0847b5abd547be125f825d3c diff --git a/benchmark/convert-expanded-final-before-r1.tsv b/benchmark/convert-expanded-final-before-r1.tsv deleted file mode 100644 index 30358aebe..000000000 --- a/benchmark/convert-expanded-final-before-r1.tsv +++ /dev/null @@ -1,37 +0,0 @@ -case mode status min_ns median_ns bytes allocs -single_rule warm measured 393.5273631840796 450.7412935323383 0 0 -single_rule selection_miss measured 26899.0 28200.0 4976 149 -single_rule invalidated measured 27599.0 29199.5 4976 149 -decline_then_success warm measured 547.0534759358288 612.8288770053476 0 0 -decline_then_success selection_miss measured 28100.0 30299.5 5840 174 -decline_then_success invalidated measured 29500.0 30499.0 5840 174 -three_declines_then_success warm measured 883.5901639344262 909.8360655737705 0 0 -three_declines_then_success selection_miss measured 32599.0 34900.0 8752 234 -three_declines_then_success invalidated measured 34200.0 36150.0 8752 234 -sixteen_scoped_decliners warm measured 4000.0 4128.571428571428 0 0 -sixteen_scoped_decliners selection_miss measured 65500.0 76599.0 31344 797 -sixteen_scoped_decliners invalidated measured 75699.0 79249.0 31344 797 -virtual_mapping_abc warm measured 393.995 426.495 0 0 -virtual_mapping_abc selection_miss measured 57399.0 66750.0 18752 539 -virtual_mapping_abc invalidated measured 66000.0 71649.5 18752 539 -buffer_only_native warm measured 6925.0 7500.0 8712 23 -buffer_only_native selection_miss measured 84900.0 106049.5 35784 778 -buffer_only_native invalidated measured 104499.0 112649.5 35784 778 -buffer_only_wrapper warm measured 5433.166666666667 6658.25 640 20 -buffer_only_wrapper selection_miss measured 80600.0 97749.0 26816 757 -buffer_only_wrapper invalidated measured 97500.0 107199.0 26816 757 -interface_only_native warm measured 20800.0 23100.0 9224 52 -interface_only_native selection_miss measured 55699.0 61649.5 15896 244 -interface_only_native invalidated measured 238999.0 272998.0 64232 1579 -array_method_only_native warm measured 7633.333333333333 8400.0 8872 27 -array_method_only_native selection_miss measured 45099.0 49100.0 15544 219 -array_method_only_native invalidated measured 50200.0 51850.0 15544 219 -ndarray_native warm measured 4257.142857142857 4671.428571428572 8744 20 -ndarray_native selection_miss measured 72600.0 85349.0 35208 788 -ndarray_native invalidated measured 85699.0 90299.0 35208 788 -ndarray_wrapper warm measured 3312.5 3537.5 672 17 -ndarray_wrapper selection_miss measured 63399.0 75949.5 28208 803 -ndarray_wrapper invalidated measured 71599.0 78949.5 28208 803 -two_matching_first_success warm unsupported NA NA NA NA -two_matching_first_declines warm unsupported NA NA NA NA -two_matching_decline_then_ordinary warm unsupported NA NA NA NA diff --git a/benchmark/convert-expanded-final-before-r2-environment.txt b/benchmark/convert-expanded-final-before-r2-environment.txt deleted file mode 100644 index f248d0560..000000000 --- a/benchmark/convert-expanded-final-before-r2-environment.txt +++ /dev/null @@ -1,10 +0,0 @@ -Julia: 1.13.2 -Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] -Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python -NumPy: 2.5.4 -BenchmarkTools: 1.8.0 -PythonCall source: /tmp/pythoncall-convert-baseline.HAfFfi/src/PythonCall.jl -New API: false -Convert/pyconvert.jl SHA256: 5509bf4deca224297091884d72a684ead91a2f1b42444c46047f228ff75d4619 -Convert/rules.jl SHA256: 3c1c30262bcc1f2e940d8d64593b4b3c869d2523d0789f7d13da76638db9032c -Wrap/PyArray.jl SHA256: 10e270400fab16e3941fc127021fc4f25a4c3c0a0847b5abd547be125f825d3c diff --git a/benchmark/convert-expanded-final-before-r2.tsv b/benchmark/convert-expanded-final-before-r2.tsv deleted file mode 100644 index e383f99b7..000000000 --- a/benchmark/convert-expanded-final-before-r2.tsv +++ /dev/null @@ -1,37 +0,0 @@ -case mode status min_ns median_ns bytes allocs -single_rule warm measured 393.495 463.495 0 0 -single_rule selection_miss measured 27100.0 28600.0 4976 149 -single_rule invalidated measured 27799.0 29600.0 4976 149 -decline_then_success warm measured 535.1010638297872 628.1914893617021 0 0 -decline_then_success selection_miss measured 28100.0 30800.0 5840 174 -decline_then_success invalidated measured 30199.0 31150.0 5840 174 -three_declines_then_success warm measured 979.2264150943396 1016.9811320754717 0 0 -three_declines_then_success selection_miss measured 33200.0 35699.0 8752 234 -three_declines_then_success invalidated measured 34799.0 36650.0 8752 234 -sixteen_scoped_decliners warm measured 4100.0 4471.428571428572 0 0 -sixteen_scoped_decliners selection_miss measured 65999.0 75849.5 31344 797 -sixteen_scoped_decliners invalidated measured 76200.0 79150.0 31344 797 -virtual_mapping_abc warm measured 389.5990099009901 400.490099009901 0 0 -virtual_mapping_abc selection_miss measured 58200.0 66999.5 18752 539 -virtual_mapping_abc invalidated measured 65300.0 72249.0 18752 539 -buffer_only_native warm measured 7000.0 7625.0 8712 23 -buffer_only_native selection_miss measured 80999.0 101399.0 35784 778 -buffer_only_native invalidated measured 105599.0 116649.0 35784 778 -buffer_only_wrapper warm measured 5483.333333333333 6500.0 640 20 -buffer_only_wrapper selection_miss measured 75499.0 84949.0 26816 757 -buffer_only_wrapper invalidated measured 78099.0 86049.5 26816 757 -interface_only_native warm measured 21500.0 22400.0 9224 52 -interface_only_native selection_miss measured 68099.0 80549.0 15896 244 -interface_only_native invalidated measured 246598.0 280597.5 64232 1579 -array_method_only_native warm measured 7899.666666666667 8800.0 8872 27 -array_method_only_native selection_miss measured 48100.0 55549.5 15544 219 -array_method_only_native invalidated measured 53500.0 57000.0 15544 219 -ndarray_native warm measured 4799.857142857143 5314.285714285715 8744 20 -ndarray_native selection_miss measured 71399.0 76099.5 35208 788 -ndarray_native invalidated measured 96299.0 103049.5 35208 788 -ndarray_wrapper warm measured 3199.875 3837.375 672 17 -ndarray_wrapper selection_miss measured 70900.0 83499.0 28208 803 -ndarray_wrapper invalidated measured 84099.0 90650.0 28208 803 -two_matching_first_success warm unsupported NA NA NA NA -two_matching_first_declines warm unsupported NA NA NA NA -two_matching_decline_then_ordinary warm unsupported NA NA NA NA diff --git a/benchmark/convert-expanded-final-before-r3-environment.txt b/benchmark/convert-expanded-final-before-r3-environment.txt deleted file mode 100644 index f248d0560..000000000 --- a/benchmark/convert-expanded-final-before-r3-environment.txt +++ /dev/null @@ -1,10 +0,0 @@ -Julia: 1.13.2 -Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] -Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python -NumPy: 2.5.4 -BenchmarkTools: 1.8.0 -PythonCall source: /tmp/pythoncall-convert-baseline.HAfFfi/src/PythonCall.jl -New API: false -Convert/pyconvert.jl SHA256: 5509bf4deca224297091884d72a684ead91a2f1b42444c46047f228ff75d4619 -Convert/rules.jl SHA256: 3c1c30262bcc1f2e940d8d64593b4b3c869d2523d0789f7d13da76638db9032c -Wrap/PyArray.jl SHA256: 10e270400fab16e3941fc127021fc4f25a4c3c0a0847b5abd547be125f825d3c diff --git a/benchmark/convert-expanded-final-before-r3.tsv b/benchmark/convert-expanded-final-before-r3.tsv deleted file mode 100644 index 583455f22..000000000 --- a/benchmark/convert-expanded-final-before-r3.tsv +++ /dev/null @@ -1,37 +0,0 @@ -case mode status min_ns median_ns bytes allocs -single_rule warm measured 384.995 439.995 0 0 -single_rule selection_miss measured 26100.0 28450.0 4976 149 -single_rule invalidated measured 27300.0 28700.0 4976 149 -decline_then_success warm measured 533.6844919786096 644.9144385026738 0 0 -decline_then_success selection_miss measured 27900.0 29949.5 5840 174 -decline_then_success invalidated measured 29600.0 30550.0 5840 174 -three_declines_then_success warm measured 982.0 1027.98 0 0 -three_declines_then_success selection_miss measured 25899.0 27349.5 8752 234 -three_declines_then_success invalidated measured 34599.0 35749.5 8752 234 -sixteen_scoped_decliners warm measured 4071.285714285714 4700.0 0 0 -sixteen_scoped_decliners selection_miss measured 64800.0 74899.5 31344 797 -sixteen_scoped_decliners invalidated measured 74700.0 79050.0 31344 797 -virtual_mapping_abc warm measured 396.5124378109453 443.2786069651741 0 0 -virtual_mapping_abc selection_miss measured 48300.0 55900.0 18752 539 -virtual_mapping_abc invalidated measured 64499.0 69699.5 18752 539 -buffer_only_native warm measured 7225.0 8000.0 8712 23 -buffer_only_native selection_miss measured 87899.0 105749.0 35784 778 -buffer_only_native invalidated measured 100799.0 114299.0 35784 778 -buffer_only_wrapper warm measured 5133.333333333333 5966.666666666667 640 20 -buffer_only_wrapper selection_miss measured 71699.0 83649.0 26816 757 -buffer_only_wrapper invalidated measured 96500.0 106599.0 26816 757 -interface_only_native warm measured 21199.0 22700.0 9224 52 -interface_only_native selection_miss measured 66700.0 77249.5 15896 244 -interface_only_native invalidated measured 248098.0 275248.0 64232 1579 -array_method_only_native warm measured 7266.333333333333 8199.833333333332 8872 27 -array_method_only_native selection_miss measured 44699.0 51799.0 15544 219 -array_method_only_native invalidated measured 51099.0 57050.0 15544 219 -ndarray_native warm measured 4471.428571428572 5157.142857142857 8744 20 -ndarray_native selection_miss measured 71099.0 82699.0 35208 788 -ndarray_native invalidated measured 80199.0 88549.0 35208 788 -ndarray_wrapper warm measured 3125.0 3474.9375 672 17 -ndarray_wrapper selection_miss measured 70500.0 81749.5 28208 803 -ndarray_wrapper invalidated measured 80999.0 87749.5 28208 803 -two_matching_first_success warm unsupported NA NA NA NA -two_matching_first_declines warm unsupported NA NA NA NA -two_matching_decline_then_ordinary warm unsupported NA NA NA NA diff --git a/benchmark/convert-expanded-report.md b/benchmark/convert-expanded-report.md deleted file mode 100644 index cab3f4736..000000000 --- a/benchmark/convert-expanded-report.md +++ /dev/null @@ -1,147 +0,0 @@ -# Final rule dispatch, protocols and preferences - -**Current update:** [convert-unwrapped-report.md](convert-unwrapped-report.md) -records the subsequent optimization: all extra Some/reboxing allocations below -are removed, with approximately 2–6% faster array conversions in its direct -before/after experiment. The tables below retain the earlier full original-v1 -comparison, including cold-path measurements. - -These results cover the final working tree, including public source aliases, -built-in shorthand and the numeric-source policy. They supersede the earlier -single-run table. See [convert-report.md](convert-report.md) for environment, -implementation, final validation status and reproduction. - -## Fixtures and method - -The same harness ran on original v1 commit -25f82cc8effbd6c487ddceaffc34aa7cbe86505b and current v1. Three before/after rounds -ran sequentially with the middle round reversed. No tests ran concurrently. -Each process records loaded source paths/hashes and environment versions. - -The buffer-only fixture is array.array('d', ...): it has the C buffer protocol -and none of the array attributes. Assertions verify the first selected converter -is the protocol array converter on both revisions. Interface-only and -__array__-only fixtures lack buffers. Each array has 1,000 elements, and shape, -element type and endpoint values are checked outside timing. - -Synthetic classes exercise one rule, decline/success, three declines/success, -destination scope filtering and virtual collections.abc.Mapping membership. -Eligible counts are checked: 1/2/4 on both revisions; scoped filtering changes -17 callbacks to one eligible callback. There are 27 synthetic/scoped registrations. -Every input is created before timing; requested types remain visible through Val. - -All times are microseconds: median of three trial minima. Warm trials use up to -5,000 samples / one second. Julia allocations exclude Python allocations. Raw -minimum/median data and round ranges are in convert-final-summary.tsv and -convert-expanded-final-{before,after}-r{1,2,3}.tsv. No confidence intervals are claimed. - -## Warm conversion - -| Case | Before us | After us | Change | Before B / allocs | After B / allocs | -| --- | ---: | ---: | ---: | ---: | ---: | -| Single rule | 0.393 | 0.378 | -4.0% | 0 / 0 | 0 / 0 | -| Decline then success | 0.535 | 0.540 | +1.0% | 0 / 0 | 0 / 0 | -| Three declines then success | 0.979 | 0.936 | -4.4% | 0 / 0 | 0 / 0 | -| Sixteen scoped decliners | 4.071 | 0.385 | -90.6% | 0 / 0 | 0 / 0 | -| Virtual Mapping ABC | 0.394 | 0.379 | -3.7% | 0 / 0 | 0 / 0 | -| Buffer-only native | 7.000 | 7.475 | +6.8% | 8712 / 23 | 8856 / 26 | -| Buffer-only wrapper | 5.433 | 5.620 | +3.4% | 640 / 20 | 768 / 22 | -| Interface-only native | 21.199 | 22.600 | +6.6% | 9224 / 52 | 9368 / 55 | -| Array-method-only native | 7.633 | 8.000 | +4.8% | 8872 / 27 | 9016 / 30 | -| ndarray native | 4.471 | 4.816 | +7.7% | 8744 / 20 | 8888 / 23 | -| ndarray wrapper | 3.200 | 3.612 | +12.9% | 672 / 17 | 800 / 19 | - -Scope filtering measures the intended exclusion of sixteen callbacks, rather -than faster execution of the same callback work. - -### Do extra array allocations translate to slower conversion? - -The final end-to-end measurements show modest regressions, with important -variation between rounds/statistics. The following ranges are the lowest/highest -trial minima, while the last columns are medians of the three trial medians: - -| Case | Before minimum range us | After minimum range us | Before p50 us | After p50 us | -| --- | ---: | ---: | ---: | ---: | -| Buffer-only native | 6.925–7.225 | 7.400–7.675 | 7.625 | 8.300 | -| Buffer-only wrapper | 5.133–5.483 | 5.550–5.633 | 6.500 | 6.433 | -| Interface-only native | 20.800–21.500 | 21.800–22.999 | 22.700 | 24.100 | -| Array-method-only native | 7.266–7.900 | 7.933–8.233 | 8.400 | 9.100 | -| ndarray native | 4.257–4.800 | 4.750–4.950 | 5.157 | 5.167 | -| ndarray wrapper | 3.125–3.312 | 3.288–3.725 | 3.538 | 3.925 | - -ndarray wrapping's median latency also rises about 11%; native ndarray median -latency is essentially unchanged despite the worse minimum. Buffer wrapping's -median also does not regress. Therefore the extra allocations do not imply a -fixed slowdown across every workload or statistic. These experiments compare -the whole old/new conversion paths; they cannot assign all timing changes to -allocation alone. - -### Allocation attribution - -Separate warmed Profile.Allocs runs on both revisions identify two extra objects -for wrappers: Some{PyArray{...}} created in pyarray_make/pyconvert_return, and a -boxed PyArray when the result is unwrapped in pyconvert_raw. Native conversion -also creates Some{Vector{...}} in pyconvert_tryconvert, and unwraps the temporary -PyArray through pyconvert_result. These account for the additional object counts. - -The profiles report requested object sizes; BenchmarkTools reports allocator -byte totals. Use the stable measured differences of 128 bytes / two allocations -for wrappers and 144 bytes / three allocations for native arrays. Raw stacks -are in convert-array-allocations-before.txt and -after.txt. No array runtime -optimization was made in this refresh. - -## Selection misses and invalidation - -Cache clearing is BenchmarkTools setup, outside timing, with evals=1. -A selection miss clears only target/context selections and preserves the global -order. Full invalidation also dirties the global order. Old v1 has no equivalent -global DAG rebuild. Timings include converting the fixture. - -Selection-miss trials use up to 200 samples / 0.4 seconds; invalidation trials -use up to 40. Aggregate values again use the median of three trial minima. - -| Case | Selection before us | Selection after us | Invalidated before us | Invalidated after us | -| --- | ---: | ---: | ---: | ---: | -| Single rule | 26.899 | 71.199 | 27.599 | 2588.880 | -| Decline then success | 28.100 | 67.899 | 29.600 | 2602.380 | -| Three declines then success | 32.599 | 62.499 | 34.599 | 2588.081 | -| Sixteen scoped decliners | 65.500 | 70.199 | 75.699 | 2587.680 | -| Virtual Mapping ABC | 57.399 | 71.499 | 65.300 | 2600.080 | -| Buffer-only native | 84.900 | 43.600 | 104.499 | 2608.181 | -| Buffer-only wrapper | 75.499 | 35.000 | 96.500 | 2528.881 | -| Interface-only native | 66.700 | 58.100 | 246.598 | 2890.477 | -| Array-method-only native | 45.099 | 38.999 | 51.099 | 2648.979 | -| ndarray native | 71.399 | 39.000 | 85.699 | 2582.780 | -| ndarray wrapper | 70.500 | 34.300 | 80.999 | 2870.077 | - -Full rebuilding is a real rare-path cost: approximately 1.47 MB / 21,262 -allocations for the single-rule fixture, compared with 4,976 B / 149 before. -Ordinary protocol selection misses generally improve, while simple synthetic -classes regress. No registry-size scaling study was performed. - -## Multiple matching preferences - -Both supplied source names match one controlled class. Its String rule declines -and its Int rule succeeds with 42. The two preference attempts always have -nonempty intersections with Any. Context construction is included in timing. - -| Ordered attempts | After us | B / allocs | -| --- | ---: | ---: | -| Int succeeds before String | 3.375 | 560 / 18 | -| String declines, then Int succeeds | 4.128 | 720 / 24 | -| String/Float64 decline, then ordinary conversion succeeds | 5.143 | 752 / 25 | - -Old v1 is explicitly recorded as unsupported. These scalar fixtures make -fallthrough controllable; they do not recommend narrow scalar preferences. -Additional unmatched/wrapper/nested cases are in convert-dispatch-final.tsv. -Those include deliberate representation/work differences: matching wrapper -preferences avoid copying, whereas an unmatched preference is checked again -by context-propagating child conversions. - -## Reproduction - -Run benchmark/run-convert-final.sh as documented in the main report, then -python3 benchmark/summarize-convert-final.py. For allocation profiles, run -convert-array-allocations.jl with labels before/after in their respective -Julia environments, using the same installed Python. Profiling runs occur -after timing and do not overlap it. diff --git a/benchmark/convert-expanded-unwrapped-after-r1-environment.txt b/benchmark/convert-expanded-unwrapped-after-r1-environment.txt deleted file mode 100644 index 224e533e6..000000000 --- a/benchmark/convert-expanded-unwrapped-after-r1-environment.txt +++ /dev/null @@ -1,10 +0,0 @@ -Julia: 1.13.2 -Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] -Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python -NumPy: 2.5.4 -BenchmarkTools: 1.8.0 -PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl -New API: true -Convert/pyconvert.jl SHA256: b9ff0cdfadc7561bd9725c0862cdcd0b08ba38958faab6e24053a42241b244ea -Convert/rules.jl SHA256: 2a064304ea9cd4edc2143621ffd0309d5b2a660326e38a6033b7b0ca2a8afc43 -Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a diff --git a/benchmark/convert-expanded-unwrapped-after-r1.tsv b/benchmark/convert-expanded-unwrapped-after-r1.tsv deleted file mode 100644 index 638236e41..000000000 --- a/benchmark/convert-expanded-unwrapped-after-r1.tsv +++ /dev/null @@ -1,15 +0,0 @@ -case mode status min_ns median_ns bytes allocs -single_rule warm measured 392.5422885572139 465.1741293532338 0 0 -decline_then_success warm measured 547.5989304812834 613.9090909090909 0 0 -three_declines_then_success warm measured 880.7692307692307 1015.4038461538462 0 0 -sixteen_scoped_decliners warm measured 401.5151515151515 438.3888888888889 0 0 -virtual_mapping_abc warm measured 393.0693069306931 450.5 0 0 -buffer_only_native warm measured 6925.0 7875.0 8712 23 -buffer_only_wrapper warm measured 5366.666666666667 6533.333333333333 640 20 -interface_only_native warm measured 22000.0 25500.0 9224 52 -array_method_only_native warm measured 7600.0 8200.0 8872 27 -ndarray_native warm measured 4700.0 5257.142857142857 8744 20 -ndarray_wrapper warm measured 3337.5 3962.5 672 17 -two_matching_first_success warm measured 3562.5 3925.0 560 18 -two_matching_first_declines warm measured 4671.428571428572 5014.285714285715 720 24 -two_matching_decline_then_ordinary warm measured 4657.142857142857 5314.428571428572 752 25 diff --git a/benchmark/convert-expanded-unwrapped-after-r2-environment.txt b/benchmark/convert-expanded-unwrapped-after-r2-environment.txt deleted file mode 100644 index 224e533e6..000000000 --- a/benchmark/convert-expanded-unwrapped-after-r2-environment.txt +++ /dev/null @@ -1,10 +0,0 @@ -Julia: 1.13.2 -Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] -Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python -NumPy: 2.5.4 -BenchmarkTools: 1.8.0 -PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl -New API: true -Convert/pyconvert.jl SHA256: b9ff0cdfadc7561bd9725c0862cdcd0b08ba38958faab6e24053a42241b244ea -Convert/rules.jl SHA256: 2a064304ea9cd4edc2143621ffd0309d5b2a660326e38a6033b7b0ca2a8afc43 -Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a diff --git a/benchmark/convert-expanded-unwrapped-after-r2.tsv b/benchmark/convert-expanded-unwrapped-after-r2.tsv deleted file mode 100644 index b91d4652f..000000000 --- a/benchmark/convert-expanded-unwrapped-after-r2.tsv +++ /dev/null @@ -1,15 +0,0 @@ -case mode status min_ns median_ns bytes allocs -single_rule warm measured 382.3529411764706 383.828431372549 0 0 -decline_then_success warm measured 525.7894736842105 567.9 0 0 -three_declines_then_success warm measured 989.1090909090909 1029.1090909090908 0 0 -sixteen_scoped_decliners warm measured 375.3694581280788 395.57142857142856 0 0 -virtual_mapping_abc warm measured 382.9145728643216 438.19095477386935 0 0 -buffer_only_native warm measured 7375.0 8150.0 8712 23 -buffer_only_wrapper warm measured 5250.0 5900.166666666667 640 20 -interface_only_native warm measured 21600.0 22600.0 9224 52 -array_method_only_native warm measured 7867.0 9100.0 8872 27 -ndarray_native warm measured 4585.714285714285 4985.857142857143 8744 20 -ndarray_wrapper warm measured 3287.5 3650.0 672 17 -two_matching_first_success warm measured 3475.0 3662.5 560 18 -two_matching_first_declines warm measured 4400.0 5314.285714285715 720 24 -two_matching_decline_then_ordinary warm measured 4628.571428571428 5443.0 752 25 diff --git a/benchmark/convert-expanded-unwrapped-after-r3-environment.txt b/benchmark/convert-expanded-unwrapped-after-r3-environment.txt deleted file mode 100644 index 224e533e6..000000000 --- a/benchmark/convert-expanded-unwrapped-after-r3-environment.txt +++ /dev/null @@ -1,10 +0,0 @@ -Julia: 1.13.2 -Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] -Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python -NumPy: 2.5.4 -BenchmarkTools: 1.8.0 -PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl -New API: true -Convert/pyconvert.jl SHA256: b9ff0cdfadc7561bd9725c0862cdcd0b08ba38958faab6e24053a42241b244ea -Convert/rules.jl SHA256: 2a064304ea9cd4edc2143621ffd0309d5b2a660326e38a6033b7b0ca2a8afc43 -Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a diff --git a/benchmark/convert-expanded-unwrapped-after-r3.tsv b/benchmark/convert-expanded-unwrapped-after-r3.tsv deleted file mode 100644 index ae1d39a2e..000000000 --- a/benchmark/convert-expanded-unwrapped-after-r3.tsv +++ /dev/null @@ -1,15 +0,0 @@ -case mode status min_ns median_ns bytes allocs -single_rule warm measured 386.69950738916253 444.3349753694581 0 0 -decline_then_success warm measured 543.0904255319149 573.4095744680851 0 0 -three_declines_then_success warm measured 964.1509433962265 1028.3207547169811 0 0 -sixteen_scoped_decliners warm measured 377.27272727272725 379.2979797979798 0 0 -virtual_mapping_abc warm measured 379.3103448275862 410.8374384236453 0 0 -buffer_only_native warm measured 7150.0 7600.25 8712 23 -buffer_only_wrapper warm measured 5283.333333333333 5850.0 640 20 -interface_only_native warm measured 21700.0 24600.0 9224 52 -array_method_only_native warm measured 7633.333333333333 8300.0 8872 27 -ndarray_native warm measured 4685.714285714285 5214.285714285715 8744 20 -ndarray_wrapper warm measured 3200.125 3800.0 672 17 -two_matching_first_success warm measured 3500.0 4175.0 560 18 -two_matching_first_declines warm measured 4428.714285714285 5157.285714285715 720 24 -two_matching_decline_then_ordinary warm measured 5214.285714285715 5471.571428571428 752 25 diff --git a/benchmark/convert-expanded-unwrapped-before-r1-environment.txt b/benchmark/convert-expanded-unwrapped-before-r1-environment.txt deleted file mode 100644 index 215c3d52a..000000000 --- a/benchmark/convert-expanded-unwrapped-before-r1-environment.txt +++ /dev/null @@ -1,10 +0,0 @@ -Julia: 1.13.2 -Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] -Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python -NumPy: 2.5.4 -BenchmarkTools: 1.8.0 -PythonCall source: /tmp/pythoncall-some-before.LlDQq5/src/PythonCall.jl -New API: true -Convert/pyconvert.jl SHA256: 7d8337b08370a90127dcc5a9d7b9b79f743ee2998c5ac6154a671725682aad6e -Convert/rules.jl SHA256: d42b0af459b0243412a5f9befa62caccc5039a8e0561be414cf9f941a6c328e4 -Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a diff --git a/benchmark/convert-expanded-unwrapped-before-r1.tsv b/benchmark/convert-expanded-unwrapped-before-r1.tsv deleted file mode 100644 index 7d83b4ce7..000000000 --- a/benchmark/convert-expanded-unwrapped-before-r1.tsv +++ /dev/null @@ -1,15 +0,0 @@ -case mode status min_ns median_ns bytes allocs -single_rule warm measured 413.0 473.005 0 0 -decline_then_success warm measured 557.6086956521739 604.8967391304348 0 0 -three_declines_then_success warm measured 930.5555555555555 1072.2222222222222 0 0 -sixteen_scoped_decliners warm measured 460.30150753768845 475.3819095477387 0 0 -virtual_mapping_abc warm measured 411.6751269035533 414.21319796954316 0 0 -buffer_only_native warm measured 6950.0 7500.25 8856 26 -buffer_only_wrapper warm measured 5416.666666666667 6166.833333333333 768 22 -interface_only_native warm measured 23300.0 25000.0 9368 55 -array_method_only_native warm measured 8366.666666666666 9133.666666666666 9016 30 -ndarray_native warm measured 4866.666666666667 5333.333333333333 8888 23 -ndarray_wrapper warm measured 3550.0 3862.625 800 19 -two_matching_first_success warm measured 3362.5 3775.0 560 18 -two_matching_first_declines warm measured 4200.0 5057.142857142857 720 24 -two_matching_decline_then_ordinary warm measured 4528.571428571428 4928.571428571428 752 25 diff --git a/benchmark/convert-expanded-unwrapped-before-r2-environment.txt b/benchmark/convert-expanded-unwrapped-before-r2-environment.txt deleted file mode 100644 index 215c3d52a..000000000 --- a/benchmark/convert-expanded-unwrapped-before-r2-environment.txt +++ /dev/null @@ -1,10 +0,0 @@ -Julia: 1.13.2 -Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] -Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python -NumPy: 2.5.4 -BenchmarkTools: 1.8.0 -PythonCall source: /tmp/pythoncall-some-before.LlDQq5/src/PythonCall.jl -New API: true -Convert/pyconvert.jl SHA256: 7d8337b08370a90127dcc5a9d7b9b79f743ee2998c5ac6154a671725682aad6e -Convert/rules.jl SHA256: d42b0af459b0243412a5f9befa62caccc5039a8e0561be414cf9f941a6c328e4 -Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a diff --git a/benchmark/convert-expanded-unwrapped-before-r2.tsv b/benchmark/convert-expanded-unwrapped-before-r2.tsv deleted file mode 100644 index 01c1c47e1..000000000 --- a/benchmark/convert-expanded-unwrapped-before-r2.tsv +++ /dev/null @@ -1,15 +0,0 @@ -case mode status min_ns median_ns bytes allocs -single_rule warm measured 393.10837438423647 477.8374384236453 0 0 -decline_then_success warm measured 550.8108108108108 649.7351351351351 0 0 -three_declines_then_success warm measured 875.4716981132076 905.6792452830189 0 0 -sixteen_scoped_decliners warm measured 402.5 463.505 0 0 -virtual_mapping_abc warm measured 448.9949494949495 464.14141414141415 0 0 -buffer_only_native warm measured 7550.0 8450.0 8856 26 -buffer_only_wrapper warm measured 5583.5 6166.833333333333 768 22 -interface_only_native warm measured 22100.0 27700.0 9368 55 -array_method_only_native warm measured 8133.333333333333 9033.333333333334 9016 30 -ndarray_native warm measured 4666.666666666667 5416.666666666667 8888 23 -ndarray_wrapper warm measured 3325.0 3575.125 800 19 -two_matching_first_success warm measured 3725.0 4025.0 560 18 -two_matching_first_declines warm measured 4528.571428571428 4900.142857142857 720 24 -two_matching_decline_then_ordinary warm measured 4528.571428571428 4728.714285714285 752 25 diff --git a/benchmark/convert-expanded-unwrapped-before-r3-environment.txt b/benchmark/convert-expanded-unwrapped-before-r3-environment.txt deleted file mode 100644 index 215c3d52a..000000000 --- a/benchmark/convert-expanded-unwrapped-before-r3-environment.txt +++ /dev/null @@ -1,10 +0,0 @@ -Julia: 1.13.2 -Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] -Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python -NumPy: 2.5.4 -BenchmarkTools: 1.8.0 -PythonCall source: /tmp/pythoncall-some-before.LlDQq5/src/PythonCall.jl -New API: true -Convert/pyconvert.jl SHA256: 7d8337b08370a90127dcc5a9d7b9b79f743ee2998c5ac6154a671725682aad6e -Convert/rules.jl SHA256: d42b0af459b0243412a5f9befa62caccc5039a8e0561be414cf9f941a6c328e4 -Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a diff --git a/benchmark/convert-expanded-unwrapped-before-r3.tsv b/benchmark/convert-expanded-unwrapped-before-r3.tsv deleted file mode 100644 index a1997a548..000000000 --- a/benchmark/convert-expanded-unwrapped-before-r3.tsv +++ /dev/null @@ -1,15 +0,0 @@ -case mode status min_ns median_ns bytes allocs -single_rule warm measured 405.5 465.005 0 0 -decline_then_success warm measured 560.9679144385027 642.2513368983957 0 0 -three_declines_then_success warm measured 865.4545454545455 1016.3636363636364 0 0 -sixteen_scoped_decliners warm measured 405.97512437810946 452.7412935323383 0 0 -virtual_mapping_abc warm measured 405.55555555555554 465.66161616161617 0 0 -buffer_only_native warm measured 7325.0 8325.0 8856 26 -buffer_only_wrapper warm measured 5680.0 6620.0 768 22 -interface_only_native warm measured 22200.0 23101.0 9368 55 -array_method_only_native warm measured 8033.333333333333 9167.0 9016 30 -ndarray_native warm measured 4983.333333333333 5683.333333333333 8888 23 -ndarray_wrapper warm measured 3387.5 3950.125 800 19 -two_matching_first_success warm measured 3437.5 3850.0 560 18 -two_matching_first_declines warm measured 4228.571428571428 5242.857142857143 720 24 -two_matching_decline_then_ordinary warm measured 4528.571428571428 4671.428571428572 752 25 diff --git a/benchmark/convert-final-after-r1-environment.txt b/benchmark/convert-final-after-r1-environment.txt deleted file mode 100644 index 0f1136c17..000000000 --- a/benchmark/convert-final-after-r1-environment.txt +++ /dev/null @@ -1,30 +0,0 @@ -Julia: 1.13.2 -Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] -Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python -BenchmarkTools: 1.8.0 -PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl -New API: true -Convert/pyconvert.jl SHA256: 7d8337b08370a90127dcc5a9d7b9b79f743ee2998c5ac6154a671725682aad6e -Convert/rules.jl SHA256: d42b0af459b0243412a5f9befa62caccc5039a8e0561be414cf9f941a6c328e4 -Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a -int result type: Int64 -integer result type: Int64 -bigint result type: BigInt -float result type: Float64 -bool result type: Bool -string result type: String -none result type: Nothing -failure result type: Nothing -list10 result type: Vector{Int64} -list10000 result type: Vector{Int64} -list10000_concrete result type: Vector{Int64} -mixed_numeric result type: Vector{Real} -heterogeneous result type: Vector{Any} -nested_concrete result type: Vector{Vector{Int64}} -nested_any result type: Vector{Vector{Int64}} -dict result type: Dict{String, Real} -dict_concrete result type: Dict{String, Float64} -empty_list result type: Vector{Any} -empty_dict result type: Dict{Any, Any} -wrapper result type: PyList{Any} -iterator result type: PyIterable{Any} diff --git a/benchmark/convert-final-after-r1.tsv b/benchmark/convert-final-after-r1.tsv deleted file mode 100644 index 438123c80..000000000 --- a/benchmark/convert-final-after-r1.tsv +++ /dev/null @@ -1,30 +0,0 @@ -case mode min_ns median_ns bytes allocs -int typed 240.43341404358353 275.180387409201 0 0 -int runtime_target 386.1857142857143 412.37619047619046 16 1 -integer typed 241.56532066508314 242.51543942992873 0 0 -integer runtime_target 359.70388349514565 382.0388349514563 0 0 -bigint typed 943.4347826086956 969.5652173913044 216 7 -bigint runtime_target 1130.0 1189.9 216 7 -float typed 239.75061728395062 240.49135802469135 0 0 -float runtime_target 361.7177033492823 403.3492822966507 16 1 -bool typed 247.27507163323781 260.45558739255017 0 0 -bool runtime_target 366.82211538461536 378.3605769230769 0 0 -string typed 345.8287037037037 397.2175925925926 48 2 -string runtime_target 452.79187817258884 525.8832487309645 48 2 -none typed 230.02421307506054 263.43825665859566 0 0 -none runtime_target 370.04347826086956 422.7004830917874 0 0 -failure typed 230.9630681818182 264.20170454545456 0 0 -failure runtime_target 329.64159292035396 334.9513274336283 0 0 -list10 typed 7439.8 7800.0 720 18 -list10000 typed 4.852463e6 5.23921e6 513880 19508 -list10000_concrete typed 4.122169e6 4.4618665e6 362024 10018 -mixed_numeric typed 3799.875 3912.375 352 13 -heterogeneous typed 4785.571428571428 5114.285714285715 384 14 -nested_concrete typed 7060.0 7820.0 768 29 -nested_any typed 9399.0 9900.0 864 32 -dict typed 7079.8 7560.0 1280 24 -dict_concrete typed 3750.0 3837.5 672 16 -empty_list typed 1139.9 1190.0 112 5 -empty_dict typed 1129.9 1180.0 208 5 -wrapper typed 389.1039603960396 433.16831683168317 16 1 -iterator typed 385.56716417910445 397.5124378109453 16 1 diff --git a/benchmark/convert-final-after-r2-environment.txt b/benchmark/convert-final-after-r2-environment.txt deleted file mode 100644 index 0f1136c17..000000000 --- a/benchmark/convert-final-after-r2-environment.txt +++ /dev/null @@ -1,30 +0,0 @@ -Julia: 1.13.2 -Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] -Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python -BenchmarkTools: 1.8.0 -PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl -New API: true -Convert/pyconvert.jl SHA256: 7d8337b08370a90127dcc5a9d7b9b79f743ee2998c5ac6154a671725682aad6e -Convert/rules.jl SHA256: d42b0af459b0243412a5f9befa62caccc5039a8e0561be414cf9f941a6c328e4 -Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a -int result type: Int64 -integer result type: Int64 -bigint result type: BigInt -float result type: Float64 -bool result type: Bool -string result type: String -none result type: Nothing -failure result type: Nothing -list10 result type: Vector{Int64} -list10000 result type: Vector{Int64} -list10000_concrete result type: Vector{Int64} -mixed_numeric result type: Vector{Real} -heterogeneous result type: Vector{Any} -nested_concrete result type: Vector{Vector{Int64}} -nested_any result type: Vector{Vector{Int64}} -dict result type: Dict{String, Real} -dict_concrete result type: Dict{String, Float64} -empty_list result type: Vector{Any} -empty_dict result type: Dict{Any, Any} -wrapper result type: PyList{Any} -iterator result type: PyIterable{Any} diff --git a/benchmark/convert-final-after-r2.tsv b/benchmark/convert-final-after-r2.tsv deleted file mode 100644 index 55486ff0b..000000000 --- a/benchmark/convert-final-after-r2.tsv +++ /dev/null @@ -1,30 +0,0 @@ -case mode min_ns median_ns bytes allocs -int typed 249.74102564102563 286.66410256410256 0 0 -int runtime_target 360.4714285714286 391.9047619047619 16 1 -integer typed 246.1164383561644 268.0342465753425 0 0 -integer runtime_target 370.04347826086956 401.44444444444446 0 0 -bigint typed 970.0 1060.0 216 7 -bigint runtime_target 1220.0 1340.0 216 7 -float typed 269.0048426150121 285.22760290556903 0 0 -float runtime_target 371.14903846153845 403.84134615384613 16 1 -bool typed 253.98670212765958 291.88563829787233 0 0 -bool runtime_target 385.2167487684729 387.192118226601 0 0 -string typed 309.0085836909871 363.9442060085837 48 2 -string runtime_target 425.6281407035176 431.15577889447235 48 2 -none typed 230.1076923076923 264.3934065934066 0 0 -none runtime_target 354.24528301886795 383.48820754716985 0 0 -failure typed 232.16333333333333 257.99833333333333 0 0 -failure runtime_target 371.6849315068493 384.013698630137 0 0 -list10 typed 6759.8 7340.0 720 18 -list10000 typed 4.821463e6 5.093261e6 513880 19508 -list10000_concrete typed 4.122068e6 4.728164e6 362024 10018 -mixed_numeric typed 3774.875 3875.0 352 13 -heterogeneous typed 4899.857142857143 5214.285714285715 384 14 -nested_concrete typed 7324.75 7900.0 768 29 -nested_any typed 10700.0 11300.0 864 32 -dict typed 6700.0 6900.0 1280 24 -dict_concrete typed 3662.375 4237.5 672 16 -empty_list typed 1290.0 1350.0 112 5 -empty_dict typed 1009.0 1172.7272727272727 208 5 -wrapper typed 387.495 398.995 16 1 -iterator typed 394.5273631840796 428.3532338308458 16 1 diff --git a/benchmark/convert-final-after-r3-environment.txt b/benchmark/convert-final-after-r3-environment.txt deleted file mode 100644 index 0f1136c17..000000000 --- a/benchmark/convert-final-after-r3-environment.txt +++ /dev/null @@ -1,30 +0,0 @@ -Julia: 1.13.2 -Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] -Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python -BenchmarkTools: 1.8.0 -PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl -New API: true -Convert/pyconvert.jl SHA256: 7d8337b08370a90127dcc5a9d7b9b79f743ee2998c5ac6154a671725682aad6e -Convert/rules.jl SHA256: d42b0af459b0243412a5f9befa62caccc5039a8e0561be414cf9f941a6c328e4 -Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a -int result type: Int64 -integer result type: Int64 -bigint result type: BigInt -float result type: Float64 -bool result type: Bool -string result type: String -none result type: Nothing -failure result type: Nothing -list10 result type: Vector{Int64} -list10000 result type: Vector{Int64} -list10000_concrete result type: Vector{Int64} -mixed_numeric result type: Vector{Real} -heterogeneous result type: Vector{Any} -nested_concrete result type: Vector{Vector{Int64}} -nested_any result type: Vector{Vector{Int64}} -dict result type: Dict{String, Real} -dict_concrete result type: Dict{String, Float64} -empty_list result type: Vector{Any} -empty_dict result type: Dict{Any, Any} -wrapper result type: PyList{Any} -iterator result type: PyIterable{Any} diff --git a/benchmark/convert-final-after-r3.tsv b/benchmark/convert-final-after-r3.tsv deleted file mode 100644 index b5c80a00e..000000000 --- a/benchmark/convert-final-after-r3.tsv +++ /dev/null @@ -1,30 +0,0 @@ -case mode min_ns median_ns bytes allocs -int typed 234.70319634703196 254.10730593607306 0 0 -int runtime_target 351.41037735849056 414.14622641509436 16 1 -integer typed 239.5 266.2955801104972 0 0 -integer runtime_target 360.7607655502392 373.20095693779905 0 0 -bigint typed 1100.0 1190.0 216 7 -bigint runtime_target 1169.9 1310.0 216 7 -float typed 235.8646080760095 242.27790973871734 0 0 -float runtime_target 354.32211538461536 419.22596153846155 16 1 -bool typed 253.98936170212767 291.48670212765956 0 0 -bool runtime_target 368.9271844660194 371.84466019417476 0 0 -string typed 311.42448979591836 377.1387755102041 48 2 -string runtime_target 428.63819095477385 491.45226130653265 48 2 -none typed 226.48173515981736 266.43607305936075 0 0 -none runtime_target 355.9194312796209 418.0047393364929 0 0 -failure typed 254.54261363636363 270.45170454545456 0 0 -failure runtime_target 329.2237442922374 341.0913242009132 0 0 -list10 typed 6440.0 7660.0 720 18 -list10000 typed 4.650965e6 5.387959e6 513880 19508 -list10000_concrete typed 4.058069e6 4.295168e6 362024 10018 -mixed_numeric typed 3837.375 4400.0 352 13 -heterogeneous typed 4771.428571428572 5057.142857142857 384 14 -nested_concrete typed 6880.0 7400.0 768 29 -nested_any typed 9500.0 10600.0 864 32 -dict typed 6660.0 6820.0 1280 24 -dict_concrete typed 3900.0 4312.5 672 16 -empty_list typed 1130.0 1180.0 112 5 -empty_dict typed 1099.9 1210.0 208 5 -wrapper typed 386.63366336633663 407.4207920792079 16 1 -iterator typed 388.6089108910891 431.6831683168317 16 1 diff --git a/benchmark/convert-final-before-r1-environment.txt b/benchmark/convert-final-before-r1-environment.txt deleted file mode 100644 index 781de5898..000000000 --- a/benchmark/convert-final-before-r1-environment.txt +++ /dev/null @@ -1,30 +0,0 @@ -Julia: 1.13.2 -Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] -Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python -BenchmarkTools: 1.8.0 -PythonCall source: /tmp/pythoncall-convert-baseline.HAfFfi/src/PythonCall.jl -New API: false -Convert/pyconvert.jl SHA256: 5509bf4deca224297091884d72a684ead91a2f1b42444c46047f228ff75d4619 -Convert/rules.jl SHA256: 3c1c30262bcc1f2e940d8d64593b4b3c869d2523d0789f7d13da76638db9032c -Wrap/PyArray.jl SHA256: 10e270400fab16e3941fc127021fc4f25a4c3c0a0847b5abd547be125f825d3c -int result type: Int64 -integer result type: Int64 -bigint result type: BigInt -float result type: Float64 -bool result type: Bool -string result type: String -none result type: Nothing -failure result type: Nothing -list10 result type: Vector{Int64} -list10000 result type: Vector{Int64} -list10000_concrete result type: Vector{Int64} -mixed_numeric result type: Vector{Float64} -heterogeneous result type: Vector{Any} -nested_concrete result type: Vector{Vector{Int64}} -nested_any result type: PyList{Any} -dict result type: Dict{String, Float64} -dict_concrete result type: Dict{String, Float64} -empty_list result type: Vector{Union{}} -empty_dict result type: Dict{Union{}, Union{}} -wrapper result type: PyList{Any} -iterator result type: PyIterable{Any} diff --git a/benchmark/convert-final-before-r1.tsv b/benchmark/convert-final-before-r1.tsv deleted file mode 100644 index 22e3d8e2e..000000000 --- a/benchmark/convert-final-before-r1.tsv +++ /dev/null @@ -1,30 +0,0 @@ -case mode min_ns median_ns bytes allocs -int typed 228.7648401826484 241.32191780821918 0 0 -int runtime_target 339.4319248826291 359.61971830985914 16 1 -integer typed 590.2119565217391 610.320652173913 0 0 -integer runtime_target 716.6597222222222 774.9930555555555 0 0 -bigint typed 977.2727272727273 1027.2727272727273 216 7 -bigint runtime_target 1120.0 1190.0 216 7 -float typed 239.99764705882353 253.88 0 0 -float runtime_target 350.719806763285 361.8357487922705 16 1 -bool typed 232.47058823529412 258.11764705882354 0 0 -bool runtime_target 349.0607476635514 369.1542056074766 0 0 -string typed 302.6988416988417 336.6756756756757 48 2 -string runtime_target 409.5427135678392 427.1356783919598 48 2 -none typed 212.14107142857142 217.85535714285714 0 0 -none runtime_target 317.69135802469134 326.7489711934156 0 0 -failure typed 243.0109589041096 263.56164383561645 0 0 -failure runtime_target 371.8398058252427 393.20388349514565 0 0 -list10 typed 9100.0 9300.0 704 17 -list10000 typed 7.292249e6 8.0350435e6 513864 19507 -list10000_concrete typed 3.848273e6 4.20647e6 362008 10017 -mixed_numeric typed 4471.428571428572 4800.0 320 11 -heterogeneous typed 5766.666666666667 6150.0 368 13 -nested_concrete typed 7424.75 7725.0 720 26 -nested_any typed 400.4925373134328 435.32338308457713 16 1 -dict typed 7025.0 7250.0 1248 22 -dict_concrete typed 3237.5 3550.0 656 15 -empty_list typed 1199.9 1220.0 64 3 -empty_dict typed 1053.8461538461538 1100.0 112 3 -wrapper typed 383.5771144278607 395.0199004975124 16 1 -iterator typed 390.5422885572139 401.4875621890547 16 1 diff --git a/benchmark/convert-final-before-r2-environment.txt b/benchmark/convert-final-before-r2-environment.txt deleted file mode 100644 index 781de5898..000000000 --- a/benchmark/convert-final-before-r2-environment.txt +++ /dev/null @@ -1,30 +0,0 @@ -Julia: 1.13.2 -Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] -Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python -BenchmarkTools: 1.8.0 -PythonCall source: /tmp/pythoncall-convert-baseline.HAfFfi/src/PythonCall.jl -New API: false -Convert/pyconvert.jl SHA256: 5509bf4deca224297091884d72a684ead91a2f1b42444c46047f228ff75d4619 -Convert/rules.jl SHA256: 3c1c30262bcc1f2e940d8d64593b4b3c869d2523d0789f7d13da76638db9032c -Wrap/PyArray.jl SHA256: 10e270400fab16e3941fc127021fc4f25a4c3c0a0847b5abd547be125f825d3c -int result type: Int64 -integer result type: Int64 -bigint result type: BigInt -float result type: Float64 -bool result type: Bool -string result type: String -none result type: Nothing -failure result type: Nothing -list10 result type: Vector{Int64} -list10000 result type: Vector{Int64} -list10000_concrete result type: Vector{Int64} -mixed_numeric result type: Vector{Float64} -heterogeneous result type: Vector{Any} -nested_concrete result type: Vector{Vector{Int64}} -nested_any result type: PyList{Any} -dict result type: Dict{String, Float64} -dict_concrete result type: Dict{String, Float64} -empty_list result type: Vector{Union{}} -empty_dict result type: Dict{Union{}, Union{}} -wrapper result type: PyList{Any} -iterator result type: PyIterable{Any} diff --git a/benchmark/convert-final-before-r2.tsv b/benchmark/convert-final-before-r2.tsv deleted file mode 100644 index 01e8bdb7b..000000000 --- a/benchmark/convert-final-before-r2.tsv +++ /dev/null @@ -1,30 +0,0 @@ -case mode min_ns median_ns bytes allocs -int typed 219.510162601626 244.71341463414635 0 0 -int runtime_target 341.0913242009132 398.63013698630135 16 1 -integer typed 625.5380434782609 662.4945652173913 0 0 -integer runtime_target 692.8967741935484 777.4129032258064 0 0 -bigint typed 956.25 1006.1875 216 7 -bigint runtime_target 1139.9 1300.0 216 7 -float typed 255.24885844748857 270.7739726027397 0 0 -float runtime_target 353.91244239631334 407.8294930875576 16 1 -bool typed 229.53892215568862 255.4870259481038 0 0 -bool runtime_target 329.27477477477476 356.7522522522523 0 0 -string typed 293.1123188405797 344.92753623188406 48 2 -string runtime_target 404.495 417.0 48 2 -none typed 209.165 219.99833333333333 0 0 -none runtime_target 321.69787234042553 368.51063829787233 0 0 -failure typed 229.28496042216358 241.68601583113457 0 0 -failure runtime_target 336.40552995391704 346.5437788018433 0 0 -list10 typed 9899.0 10600.0 704 17 -list10000 typed 7.243345e6 7.9604895e6 513864 19507 -list10000_concrete typed 3.91897e6 4.278517e6 362008 10017 -mixed_numeric typed 4371.285714285715 4685.714285714285 320 11 -heterogeneous typed 5466.5 6150.0 368 13 -nested_concrete typed 7974.75 8550.0 720 26 -nested_any typed 389.6502463054187 446.30049261083747 16 1 -dict typed 7424.75 8024.75 1248 22 -dict_concrete typed 3212.5 3387.5 656 15 -empty_list typed 1289.9 1310.0 64 3 -empty_dict typed 970.5294117647059 988.2352941176471 112 3 -wrapper typed 377.0682926829268 421.45853658536583 16 1 -iterator typed 389.6502463054187 402.95073891625617 16 1 diff --git a/benchmark/convert-final-before-r3-environment.txt b/benchmark/convert-final-before-r3-environment.txt deleted file mode 100644 index 781de5898..000000000 --- a/benchmark/convert-final-before-r3-environment.txt +++ /dev/null @@ -1,30 +0,0 @@ -Julia: 1.13.2 -Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] -Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python -BenchmarkTools: 1.8.0 -PythonCall source: /tmp/pythoncall-convert-baseline.HAfFfi/src/PythonCall.jl -New API: false -Convert/pyconvert.jl SHA256: 5509bf4deca224297091884d72a684ead91a2f1b42444c46047f228ff75d4619 -Convert/rules.jl SHA256: 3c1c30262bcc1f2e940d8d64593b4b3c869d2523d0789f7d13da76638db9032c -Wrap/PyArray.jl SHA256: 10e270400fab16e3941fc127021fc4f25a4c3c0a0847b5abd547be125f825d3c -int result type: Int64 -integer result type: Int64 -bigint result type: BigInt -float result type: Float64 -bool result type: Bool -string result type: String -none result type: Nothing -failure result type: Nothing -list10 result type: Vector{Int64} -list10000 result type: Vector{Int64} -list10000_concrete result type: Vector{Int64} -mixed_numeric result type: Vector{Float64} -heterogeneous result type: Vector{Any} -nested_concrete result type: Vector{Vector{Int64}} -nested_any result type: PyList{Any} -dict result type: Dict{String, Float64} -dict_concrete result type: Dict{String, Float64} -empty_list result type: Vector{Union{}} -empty_dict result type: Dict{Union{}, Union{}} -wrapper result type: PyList{Any} -iterator result type: PyIterable{Any} diff --git a/benchmark/convert-final-before-r3.tsv b/benchmark/convert-final-before-r3.tsv deleted file mode 100644 index 27b66180a..000000000 --- a/benchmark/convert-final-before-r3.tsv +++ /dev/null @@ -1,30 +0,0 @@ -case mode min_ns median_ns bytes allocs -int typed 222.79260780287476 262.42094455852157 0 0 -int runtime_target 365.561320754717 377.82547169811323 16 1 -integer typed 575.4098360655738 642.0710382513661 0 0 -integer runtime_target 704.7876712328767 708.2191780821918 0 0 -bigint typed 1072.2222222222222 1144.4444444444443 216 7 -bigint runtime_target 1159.9 1320.0 216 7 -float typed 231.46620046620046 265.4988344988345 0 0 -float runtime_target 352.3317757009346 425.2289719626168 16 1 -bool typed 233.82452431289641 246.08668076109936 0 0 -bool runtime_target 355.1839622641509 408.0141509433962 0 0 -string typed 296.6804979253112 313.27385892116183 48 2 -string runtime_target 405.995 419.5 48 2 -none typed 210.52456140350878 221.75263157894736 0 0 -none runtime_target 317.42323651452284 362.23651452282155 0 0 -failure typed 238.73849878934624 241.40193704600483 0 0 -failure runtime_target 351.7363184079602 415.4179104477612 0 0 -list10 typed 10499.0 11400.0 704 17 -list10000 typed 7.226144e6 7.739141e6 513864 19507 -list10000_concrete typed 3.92657e6 4.363367e6 362008 10017 -mixed_numeric typed 4657.0 4985.714285714285 320 11 -heterogeneous typed 5416.5 5749.833333333333 368 13 -nested_concrete typed 8050.0 8525.0 720 26 -nested_any typed 374.871921182266 395.5665024630542 16 1 -dict typed 7599.75 8499.75 1248 22 -dict_concrete typed 3550.0 3950.0 656 15 -empty_list typed 1359.9 1420.0 64 3 -empty_dict typed 1099.95 1180.0 112 3 -wrapper typed 378.320197044335 443.3497536945813 16 1 -iterator typed 376.47058823529414 388.23039215686276 16 1 diff --git a/benchmark/convert-final-summary.tsv b/benchmark/convert-final-summary.tsv deleted file mode 100644 index 7d4f1700b..000000000 --- a/benchmark/convert-final-summary.tsv +++ /dev/null @@ -1,66 +0,0 @@ -group case mode before_ns after_ns change_percent before_p50_ns after_p50_ns before_low_ns before_high_ns after_low_ns after_high_ns before_bytes before_allocs after_bytes after_allocs -common int typed 222.79260780287476 240.43341404358353 7.918039298825041 244.71341463414635 275.180387409201 219.510162601626 228.7648401826484 234.70319634703196 249.74102564102563 0 0 0 0 -common int runtime_target 341.0913242009132 360.4714285714286 5.681793407064162 377.82547169811323 412.37619047619046 339.4319248826291 365.561320754717 351.41037735849056 386.1857142857143 16 1 16 1 -common integer typed 590.2119565217391 241.56532066508314 -59.07142883233243 642.0710382513661 266.2955801104972 575.4098360655738 625.5380434782609 239.5 246.1164383561644 0 0 0 0 -common integer runtime_target 704.7876712328767 360.7607655502392 -48.81284388542656 774.9930555555555 382.0388349514563 692.8967741935484 716.6597222222222 359.70388349514565 370.04347826086956 0 0 0 0 -common bigint typed 977.2727272727273 970.0 -0.7441860465116301 1027.2727272727273 1060.0 956.25 1072.2222222222222 943.4347826086956 1100.0 216 7 216 7 -common bigint runtime_target 1139.9 1169.9 2.631809807877894 1300.0 1310.0 1120.0 1159.9 1130.0 1220.0 216 7 216 7 -common float typed 239.99764705882353 239.75061728395062 -0.10293008198216658 265.4988344988345 242.27790973871734 231.46620046620046 255.24885844748857 235.8646080760095 269.0048426150121 0 0 0 0 -common float runtime_target 352.3317757009346 361.7177033492823 2.6639458305102393 407.8294930875576 403.84134615384613 350.719806763285 353.91244239631334 354.32211538461536 371.14903846153845 16 1 16 1 -common bool typed 232.47058823529412 253.98670212765958 9.255413364630893 255.4870259481038 291.48670212765956 229.53892215568862 233.82452431289641 247.27507163323781 253.98936170212767 0 0 0 0 -common bool runtime_target 349.0607476635514 368.9271844660194 5.691398112060608 369.1542056074766 378.3605769230769 329.27477477477476 355.1839622641509 366.82211538461536 385.2167487684729 0 0 0 0 -common string typed 296.6804979253112 311.42448979591836 4.969653203938917 336.6756756756757 377.1387755102041 293.1123188405797 302.6988416988417 309.0085836909871 345.8287037037037 48 2 48 2 -common string runtime_target 405.995 428.63819095477385 5.577209314098419 419.5 491.45226130653265 404.495 409.5427135678392 425.6281407035176 452.79187817258884 48 2 48 2 -common none typed 210.52456140350878 230.02421307506054 9.262411730751507 219.99833333333333 264.3934065934066 209.165 212.14107142857142 226.48173515981736 230.1076923076923 0 0 0 0 -common none runtime_target 317.69135802469134 355.9194312796209 12.033085662959198 362.23651452282155 418.0047393364929 317.42323651452284 321.69787234042553 354.24528301886795 370.04347826086956 0 0 0 0 -common failure typed 238.73849878934624 232.16333333333333 -2.754128676085288 241.68601583113457 264.20170454545456 229.28496042216358 243.0109589041096 230.9630681818182 254.54261363636363 0 0 0 0 -common failure runtime_target 351.7363184079602 329.64159292035396 -6.2816161798736285 393.20388349514565 341.0913242009132 336.40552995391704 371.8398058252427 329.2237442922374 371.6849315068493 0 0 0 0 -common list10 typed 9899.0 6759.8 -31.7122941711284 10600.0 7660.0 9100.0 10499.0 6440.0 7439.8 704 17 720 18 -common list10000 typed 7243345.0 4821463.0 -33.4359608716691 7960489.5 5239210.0 7226144.0 7292249.0 4650965.0 4852463.0 513864 19507 513880 19508 -common list10000_concrete typed 3918970.0 4122068.0 5.182433139319764 4278517.0 4461866.5 3848273.0 3926570.0 4058069.0 4122169.0 362008 10017 362024 10018 -common mixed_numeric typed 4471.428571428572 3799.875 -15.018769968051116 4800.0 3912.375 4371.285714285715 4657.0 3774.875 3837.375 320 11 352 13 -common heterogeneous typed 5466.5 4785.571428571428 -12.456390220956216 6150.0 5114.285714285715 5416.5 5766.666666666667 4771.428571428572 4899.857142857143 368 13 384 14 -common nested_concrete typed 7974.75 7060.0 -11.470579015016147 8525.0 7820.0 7424.75 8050.0 6880.0 7324.75 720 26 768 29 -common nested_any typed 389.6502463054187 9500.0 2338.0839201506974 435.32338308457713 10600.0 374.871921182266 400.4925373134328 9399.0 10700.0 16 1 864 32 -common dict typed 7424.75 6700.0 -9.761271423280249 8024.75 6900.0 7025.0 7599.75 6660.0 7079.8 1248 22 1280 24 -common dict_concrete typed 3237.5 3750.0 15.83011583011582 3550.0 4237.5 3212.5 3550.0 3662.375 3900.0 656 15 672 16 -common empty_list typed 1289.9 1139.9 -11.628808434762384 1310.0 1190.0 1199.9 1359.9 1130.0 1290.0 64 3 112 5 -common empty_dict typed 1053.8461538461538 1099.9 4.370072992700735 1100.0 1180.0 970.5294117647059 1099.95 1009.0 1129.9 112 3 208 5 -common wrapper typed 378.320197044335 387.495 2.425142254456447 421.45853658536583 407.4207920792079 377.0682926829268 383.5771144278607 386.63366336633663 389.1039603960396 16 1 16 1 -common iterator typed 389.6502463054187 388.6089108910891 -0.26724875043794283 401.4875621890547 428.3532338308458 376.47058823529414 390.5422885572139 385.56716417910445 394.5273631840796 16 1 16 1 -expanded single_rule warm 393.495 377.9362745098039 -3.9539830214351035 450.7412935323383 393.5960591133005 384.995 393.5273631840796 376.3497536945813 402.44607843137254 0 0 0 0 -expanded single_rule selection_miss 26899.0 71199.0 164.6901371798208 28450.0 79449.5 26100.0 27100.0 63999.0 71800.0 4976 149 8304 261 -expanded single_rule invalidated 27599.0 2588880.0 9280.3398673865 29199.5 2990877.0 27300.0 27799.0 2562281.0 2593680.0 4976 149 1474960 21262 -expanded decline_then_success warm 535.1010638297872 540.2063492063492 0.95407871926525 628.1914893617021 586.9057591623036 533.6844919786096 547.0534759358288 528.7905759162304 573.3989361702128 0 0 0 0 -expanded decline_then_success selection_miss 28100.0 67899.0 141.63345195729536 30299.5 77000.0 27900.0 28100.0 62999.0 72899.0 5840 174 8400 264 -expanded decline_then_success invalidated 29600.0 2602380.0 8691.824324324323 30550.0 2926977.5 29500.0 30199.0 2542581.0 2662580.0 5840 174 1475056 21265 -expanded three_declines_then_success warm 979.2264150943396 936.0 -4.414343243607776 1016.9811320754717 989.2857142857143 883.5901639344262 982.0 842.8214285714286 994.719298245614 0 0 0 0 -expanded three_declines_then_success selection_miss 32599.0 62499.0 91.7206049265315 34900.0 66550.0 25899.0 33200.0 62399.0 71799.0 8752 234 8688 271 -expanded three_declines_then_success invalidated 34599.0 2588081.0 7380.2190814763435 36150.0 2725679.0 34200.0 34799.0 2508581.0 2625580.0 8752 234 1475344 21272 -expanded sixteen_scoped_decliners warm 4071.285714285714 384.7241379310345 -90.55030364041812 4471.428571428572 440.38916256157637 4000.0 4100.0 380.87745098039215 402.00502512562815 0 0 0 0 -expanded sixteen_scoped_decliners selection_miss 65500.0 70199.0 7.174045801526718 75849.5 78699.5 64800.0 65999.0 60900.0 71500.0 31344 797 8304 261 -expanded sixteen_scoped_decliners invalidated 75699.0 2587680.0 3318.3806919510166 79150.0 2662779.5 74700.0 76200.0 2500481.0 2872478.0 31344 797 1474960 21262 -expanded virtual_mapping_abc warm 393.995 379.40686274509807 -3.7026198948976297 426.495 433.3333333333333 389.5990099009901 396.5124378109453 375.6048780487805 391.6617647058824 0 0 0 0 -expanded virtual_mapping_abc selection_miss 57399.0 71499.0 24.564887890032928 66750.0 76850.0 48300.0 58200.0 61300.0 71599.0 18752 539 8304 261 -expanded virtual_mapping_abc invalidated 65300.0 2600080.0 3881.7457886676875 71649.5 2741429.0 64499.0 66000.0 2533781.0 2617280.0 18752 539 1474960 21262 -expanded buffer_only_native warm 7000.0 7474.75 6.782142857142848 7625.0 8300.0 6925.0 7225.0 7399.75 7675.0 8712 23 8856 26 -expanded buffer_only_native selection_miss 84900.0 43600.0 -48.64546525323911 105749.0 48399.5 80999.0 87899.0 41900.0 44899.0 35784 778 9880 62 -expanded buffer_only_native invalidated 104499.0 2608181.0 2395.8908697690886 114299.0 2942877.0 100799.0 105599.0 2604980.0 2753580.0 35784 778 1475672 21051 -expanded buffer_only_wrapper warm 5433.166666666667 5619.8 3.4350746955428058 6500.0 6433.166666666667 5133.333333333333 5483.333333333333 5549.833333333333 5633.166666666667 640 20 768 22 -expanded buffer_only_wrapper selection_miss 75499.0 35000.0 -53.64177008967006 84949.0 36900.0 71699.0 80600.0 31700.0 35099.0 26816 757 1920 58 -expanded buffer_only_wrapper invalidated 96500.0 2528881.0 2520.6020725388603 106599.0 2667029.0 78099.0 97500.0 2525881.0 2583080.0 26816 757 1467712 21047 -expanded interface_only_native warm 21199.0 22600.0 6.608802301995387 22700.0 24100.0 20800.0 21500.0 21800.0 22999.0 9224 52 9368 55 -expanded interface_only_native selection_miss 66700.0 58100.0 -12.89355322338831 77249.5 66699.0 55699.0 68099.0 57999.0 58600.0 15896 244 10408 91 -expanded interface_only_native invalidated 246598.0 2890477.0 1072.1412987939884 275248.0 3155075.5 238999.0 248098.0 2864778.0 3192776.0 64232 1579 1507208 22091 -expanded array_method_only_native warm 7633.333333333333 8000.0 4.8034934497816595 8400.0 9100.0 7266.333333333333 7899.666666666667 7933.333333333333 8233.333333333334 8872 27 9016 30 -expanded array_method_only_native selection_miss 45099.0 38999.0 -13.525798798199517 51799.0 42200.0 44699.0 48100.0 36100.0 39300.0 15544 219 10056 66 -expanded array_method_only_native invalidated 51099.0 2648979.0 5084.013385780543 57000.0 2903577.0 50200.0 53500.0 2554080.0 2679379.0 15544 219 1476712 21067 -expanded ndarray_native warm 4471.428571428572 4816.5 7.717252396166141 5157.142857142857 5166.666666666667 4257.142857142857 4799.857142857143 4750.0 4950.0 8744 20 8888 23 -expanded ndarray_native selection_miss 71399.0 39000.0 -45.37738623790249 82699.0 41199.5 71099.0 72600.0 38400.0 41300.0 35208 788 10872 84 -expanded ndarray_native invalidated 85699.0 2582780.0 2913.780790907712 90299.0 2661629.5 80199.0 96299.0 2581480.0 2949576.0 35208 788 1476664 21073 -expanded ndarray_wrapper warm 3199.875 3612.5 12.895034962303221 3537.5 3925.0 3125.0 3312.5 3287.5 3725.0 672 17 800 19 -expanded ndarray_wrapper selection_miss 70500.0 34300.0 -51.34751773049646 81749.5 37100.0 63399.0 70900.0 33899.0 35399.0 28208 803 3488 86 -expanded ndarray_wrapper invalidated 80999.0 2870077.0 3443.348683317078 87749.5 3051776.5 71599.0 84099.0 2649578.0 2875978.0 28208 803 1469280 21075 -expanded two_matching_first_success warm 3375.0 3937.5 3325.0 3499.875 560 18 -expanded two_matching_first_declines warm 4128.428571428572 4642.857142857143 4114.285714285715 4228.428571428572 720 24 -expanded two_matching_decline_then_ordinary warm 5142.857142857143 5442.714285714285 4685.714285714285 5285.714285714285 752 25 diff --git a/benchmark/convert-final-unwrapped-after-r1-environment.txt b/benchmark/convert-final-unwrapped-after-r1-environment.txt deleted file mode 100644 index 2e84f861a..000000000 --- a/benchmark/convert-final-unwrapped-after-r1-environment.txt +++ /dev/null @@ -1,30 +0,0 @@ -Julia: 1.13.2 -Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] -Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python -BenchmarkTools: 1.8.0 -PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl -New API: true -Convert/pyconvert.jl SHA256: b9ff0cdfadc7561bd9725c0862cdcd0b08ba38958faab6e24053a42241b244ea -Convert/rules.jl SHA256: 2a064304ea9cd4edc2143621ffd0309d5b2a660326e38a6033b7b0ca2a8afc43 -Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a -int result type: Int64 -integer result type: Int64 -bigint result type: BigInt -float result type: Float64 -bool result type: Bool -string result type: String -none result type: Nothing -failure result type: Nothing -list10 result type: Vector{Int64} -list10000 result type: Vector{Int64} -list10000_concrete result type: Vector{Int64} -mixed_numeric result type: Vector{Real} -heterogeneous result type: Vector{Any} -nested_concrete result type: Vector{Vector{Int64}} -nested_any result type: Vector{Vector{Int64}} -dict result type: Dict{String, Real} -dict_concrete result type: Dict{String, Float64} -empty_list result type: Vector{Any} -empty_dict result type: Dict{Any, Any} -wrapper result type: PyList{Any} -iterator result type: PyIterable{Any} diff --git a/benchmark/convert-final-unwrapped-after-r1.tsv b/benchmark/convert-final-unwrapped-after-r1.tsv deleted file mode 100644 index 312c5fbe2..000000000 --- a/benchmark/convert-final-unwrapped-after-r1.tsv +++ /dev/null @@ -1,30 +0,0 @@ -case mode min_ns median_ns bytes allocs -int typed 247.71689497716895 284.02054794520546 0 0 -int runtime_target 380.19323671497585 444.20531400966183 16 1 -integer typed 236.17021276595744 285.1090425531915 0 0 -integer runtime_target 356.1320754716981 366.0377358490566 0 0 -bigint typed 980.0 1060.1 216 7 -bigint runtime_target 1110.0 1300.0 216 7 -float typed 236.5641646489104 249.63922518159805 0 0 -float runtime_target 391.04477611940297 449.2587064676617 16 1 -bool typed 273.93882978723406 306.65159574468083 0 0 -bool runtime_target 421.28712871287127 447.03465346534654 0 0 -string typed 309.880658436214 355.14814814814815 48 2 -string runtime_target 425.6281407035176 487.94472361809045 48 2 -none typed 225.9356846473029 232.1597510373444 0 0 -none runtime_target 340.0 349.54545454545456 0 0 -failure typed 263.56164383561645 279.4547945205479 0 0 -failure runtime_target 335.02764976958525 373.2718894009217 0 0 -list10 typed 7080.0 7560.0 704 17 -list10000 typed 4.624435e6 5.458141e6 513864 19507 -list10000_concrete typed 4.018131e6 4.755336e6 362008 10017 -mixed_numeric typed 3800.125 3912.5 336 12 -heterogeneous typed 4728.571428571428 5214.428571428572 368 13 -nested_concrete typed 6920.0 7080.0 720 26 -nested_any typed 9500.0 9701.0 816 29 -dict typed 7580.0 8040.0 1264 23 -dict_concrete typed 3950.0 4325.0 656 15 -empty_list typed 1130.0 1180.0 96 4 -empty_dict typed 1080.0 1200.0 192 4 -wrapper typed 395.02487562189054 453.23880597014926 16 1 -iterator typed 397.505 469.5 16 1 diff --git a/benchmark/convert-final-unwrapped-after-r2-environment.txt b/benchmark/convert-final-unwrapped-after-r2-environment.txt deleted file mode 100644 index 2e84f861a..000000000 --- a/benchmark/convert-final-unwrapped-after-r2-environment.txt +++ /dev/null @@ -1,30 +0,0 @@ -Julia: 1.13.2 -Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] -Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python -BenchmarkTools: 1.8.0 -PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl -New API: true -Convert/pyconvert.jl SHA256: b9ff0cdfadc7561bd9725c0862cdcd0b08ba38958faab6e24053a42241b244ea -Convert/rules.jl SHA256: 2a064304ea9cd4edc2143621ffd0309d5b2a660326e38a6033b7b0ca2a8afc43 -Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a -int result type: Int64 -integer result type: Int64 -bigint result type: BigInt -float result type: Float64 -bool result type: Bool -string result type: String -none result type: Nothing -failure result type: Nothing -list10 result type: Vector{Int64} -list10000 result type: Vector{Int64} -list10000_concrete result type: Vector{Int64} -mixed_numeric result type: Vector{Real} -heterogeneous result type: Vector{Any} -nested_concrete result type: Vector{Vector{Int64}} -nested_any result type: Vector{Vector{Int64}} -dict result type: Dict{String, Real} -dict_concrete result type: Dict{String, Float64} -empty_list result type: Vector{Any} -empty_dict result type: Dict{Any, Any} -wrapper result type: PyList{Any} -iterator result type: PyIterable{Any} diff --git a/benchmark/convert-final-unwrapped-after-r2.tsv b/benchmark/convert-final-unwrapped-after-r2.tsv deleted file mode 100644 index 6ebecadab..000000000 --- a/benchmark/convert-final-unwrapped-after-r2.tsv +++ /dev/null @@ -1,30 +0,0 @@ -case mode min_ns median_ns bytes allocs -int typed 234.9246231155779 243.09170854271355 0 0 -int runtime_target 360.2870813397129 410.5311004784689 16 1 -integer typed 243.46793349168647 278.8622327790974 0 0 -integer runtime_target 361.9095238095238 414.76190476190476 0 0 -bigint typed 953.8461538461538 1007.6923076923077 216 7 -bigint runtime_target 1190.0 1300.0 216 7 -float typed 239.63031914893617 266.7579787234043 0 0 -float runtime_target 383.66336633663366 443.0693069306931 16 1 -bool typed 255.58823529411765 292.06176470588235 0 0 -bool runtime_target 395.0980392156863 418.1421568627451 0 0 -string typed 313.8655462184874 371.43277310924367 48 2 -string runtime_target 426.2676767676768 474.75252525252523 48 2 -none typed 231.80125523012552 258.1610878661088 0 0 -none runtime_target 345.23809523809524 395.23809523809524 0 0 -failure typed 229.68036529680364 262.5570776255708 0 0 -failure runtime_target 333.1838565022422 351.1255605381166 0 0 -list10 typed 6440.2 7500.0 704 17 -list10000 typed 4.805737e6 5.634343e6 513864 19507 -list10000_concrete typed 4.036031e6 4.764337e6 362008 10017 -mixed_numeric typed 4225.0 4512.5 336 12 -heterogeneous typed 5057.142857142857 5443.0 368 13 -nested_concrete typed 6920.0 7820.0 720 26 -nested_any typed 10701.0 11300.0 816 29 -dict typed 6540.0 7620.0 1264 23 -dict_concrete typed 3612.625 4200.0 656 15 -empty_list typed 1120.0 1200.0 96 4 -empty_dict typed 1036.3636363636363 1163.6363636363637 192 4 -wrapper typed 404.97512437810946 466.1741293532338 16 1 -iterator typed 400.5 405.5 16 1 diff --git a/benchmark/convert-final-unwrapped-after-r3-environment.txt b/benchmark/convert-final-unwrapped-after-r3-environment.txt deleted file mode 100644 index 2e84f861a..000000000 --- a/benchmark/convert-final-unwrapped-after-r3-environment.txt +++ /dev/null @@ -1,30 +0,0 @@ -Julia: 1.13.2 -Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] -Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python -BenchmarkTools: 1.8.0 -PythonCall source: /home/doris/.julia/dev/PythonCall/src/PythonCall.jl -New API: true -Convert/pyconvert.jl SHA256: b9ff0cdfadc7561bd9725c0862cdcd0b08ba38958faab6e24053a42241b244ea -Convert/rules.jl SHA256: 2a064304ea9cd4edc2143621ffd0309d5b2a660326e38a6033b7b0ca2a8afc43 -Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a -int result type: Int64 -integer result type: Int64 -bigint result type: BigInt -float result type: Float64 -bool result type: Bool -string result type: String -none result type: Nothing -failure result type: Nothing -list10 result type: Vector{Int64} -list10000 result type: Vector{Int64} -list10000_concrete result type: Vector{Int64} -mixed_numeric result type: Vector{Real} -heterogeneous result type: Vector{Any} -nested_concrete result type: Vector{Vector{Int64}} -nested_any result type: Vector{Vector{Int64}} -dict result type: Dict{String, Real} -dict_concrete result type: Dict{String, Float64} -empty_list result type: Vector{Any} -empty_dict result type: Dict{Any, Any} -wrapper result type: PyList{Any} -iterator result type: PyIterable{Any} diff --git a/benchmark/convert-final-unwrapped-after-r3.tsv b/benchmark/convert-final-unwrapped-after-r3.tsv deleted file mode 100644 index f624f61dc..000000000 --- a/benchmark/convert-final-unwrapped-after-r3.tsv +++ /dev/null @@ -1,30 +0,0 @@ -case mode min_ns median_ns bytes allocs -int typed 239.5964467005076 280.96700507614213 0 0 -int runtime_target 410.4265402843602 440.28909952606637 16 1 -integer typed 237.46223564954684 278.8549848942598 0 0 -integer runtime_target 356.3380281690141 420.1924882629108 0 0 -bigint typed 1042.1052631578948 1121.0526315789473 216 7 -bigint runtime_target 1110.0 1170.0 216 7 -float typed 237.28813559322035 271.18886198547216 0 0 -float runtime_target 373.30582524271847 428.6456310679612 16 1 -bool typed 251.11111111111111 303.1777777777778 0 0 -bool runtime_target 385.02415458937196 418.3623188405797 0 0 -string typed 311.4035087719298 367.5438596491228 48 2 -string runtime_target 427.1356783919598 452.76884422110555 48 2 -none typed 236.30365296803652 270.32191780821915 0 0 -none runtime_target 375.23364485981307 387.1518691588785 0 0 -failure typed 238.68778280542986 251.58597285067873 0 0 -failure runtime_target 338.7142857142857 376.0414746543779 0 0 -list10 typed 6560.0 6940.0 704 17 -list10000 typed 4.545035e6 5.467642e6 513864 19507 -list10000_concrete typed 4.094831e6 4.7470365e6 362008 10017 -mixed_numeric typed 3800.0 3962.5 336 12 -heterogeneous typed 4842.857142857143 5300.0 368 13 -nested_concrete typed 8075.0 8425.0 720 26 -nested_any typed 9800.0 10300.0 816 29 -dict typed 6540.0 7220.0 1264 23 -dict_concrete typed 3612.5 3687.625 656 15 -empty_list typed 1180.0 1370.0 96 4 -empty_dict typed 1030.0 1060.0 192 4 -wrapper typed 399.505 422.005 16 1 -iterator typed 398.99497487437185 402.5175879396985 16 1 diff --git a/benchmark/convert-final-unwrapped-before-r1-environment.txt b/benchmark/convert-final-unwrapped-before-r1-environment.txt deleted file mode 100644 index d0e4169d0..000000000 --- a/benchmark/convert-final-unwrapped-before-r1-environment.txt +++ /dev/null @@ -1,30 +0,0 @@ -Julia: 1.13.2 -Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] -Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python -BenchmarkTools: 1.8.0 -PythonCall source: /tmp/pythoncall-some-before.LlDQq5/src/PythonCall.jl -New API: true -Convert/pyconvert.jl SHA256: 7d8337b08370a90127dcc5a9d7b9b79f743ee2998c5ac6154a671725682aad6e -Convert/rules.jl SHA256: d42b0af459b0243412a5f9befa62caccc5039a8e0561be414cf9f941a6c328e4 -Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a -int result type: Int64 -integer result type: Int64 -bigint result type: BigInt -float result type: Float64 -bool result type: Bool -string result type: String -none result type: Nothing -failure result type: Nothing -list10 result type: Vector{Int64} -list10000 result type: Vector{Int64} -list10000_concrete result type: Vector{Int64} -mixed_numeric result type: Vector{Real} -heterogeneous result type: Vector{Any} -nested_concrete result type: Vector{Vector{Int64}} -nested_any result type: Vector{Vector{Int64}} -dict result type: Dict{String, Real} -dict_concrete result type: Dict{String, Float64} -empty_list result type: Vector{Any} -empty_dict result type: Dict{Any, Any} -wrapper result type: PyList{Any} -iterator result type: PyIterable{Any} diff --git a/benchmark/convert-final-unwrapped-before-r1.tsv b/benchmark/convert-final-unwrapped-before-r1.tsv deleted file mode 100644 index 70877c21b..000000000 --- a/benchmark/convert-final-unwrapped-before-r1.tsv +++ /dev/null @@ -1,30 +0,0 @@ -case mode min_ns median_ns bytes allocs -int typed 240.14251781472683 270.4299287410926 0 0 -int runtime_target 363.9423076923077 395.67788461538464 16 1 -integer typed 242.13317191283292 270.22033898305085 0 0 -integer runtime_target 362.20095693779905 414.35885167464113 0 0 -bigint typed 1070.0 1160.0 216 7 -bigint runtime_target 1280.0 1390.0 216 7 -float typed 240.38004750593825 275.061757719715 0 0 -float runtime_target 370.5314009661836 427.05797101449275 16 1 -bool typed 257.2755417956656 294.73993808049534 0 0 -bool runtime_target 431.15577889447235 434.678391959799 0 0 -string typed 319.91525423728814 348.7330508474576 48 2 -string runtime_target 431.8181818181818 481.3131313131313 48 2 -none typed 231.83856502242153 251.347533632287 0 0 -none runtime_target 337.8995433789954 376.25570776255705 0 0 -failure typed 229.93569844789357 242.35254988913525 0 0 -failure runtime_target 341.2844036697248 389.45412844036696 0 0 -list10 typed 7120.0 7620.0 720 18 -list10000 typed 4.687736e6 5.057489e6 513880 19508 -list10000_concrete typed 4.084732e6 4.4526345e6 362024 10018 -mixed_numeric typed 3837.625 4475.125 352 13 -heterogeneous typed 4828.571428571428 5614.428571428572 384 14 -nested_concrete typed 6940.0 7340.0 768 29 -nested_any typed 9900.0 10900.0 864 32 -dict typed 6500.0 7580.0 1280 24 -dict_concrete typed 3675.0 4062.625 672 16 -empty_list typed 1260.0 1340.0 112 5 -empty_dict typed 1120.0 1230.1 208 5 -wrapper typed 394.02985074626866 428.363184079602 16 1 -iterator typed 402.0 462.505 16 1 diff --git a/benchmark/convert-final-unwrapped-before-r2-environment.txt b/benchmark/convert-final-unwrapped-before-r2-environment.txt deleted file mode 100644 index d0e4169d0..000000000 --- a/benchmark/convert-final-unwrapped-before-r2-environment.txt +++ /dev/null @@ -1,30 +0,0 @@ -Julia: 1.13.2 -Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] -Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python -BenchmarkTools: 1.8.0 -PythonCall source: /tmp/pythoncall-some-before.LlDQq5/src/PythonCall.jl -New API: true -Convert/pyconvert.jl SHA256: 7d8337b08370a90127dcc5a9d7b9b79f743ee2998c5ac6154a671725682aad6e -Convert/rules.jl SHA256: d42b0af459b0243412a5f9befa62caccc5039a8e0561be414cf9f941a6c328e4 -Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a -int result type: Int64 -integer result type: Int64 -bigint result type: BigInt -float result type: Float64 -bool result type: Bool -string result type: String -none result type: Nothing -failure result type: Nothing -list10 result type: Vector{Int64} -list10000 result type: Vector{Int64} -list10000_concrete result type: Vector{Int64} -mixed_numeric result type: Vector{Real} -heterogeneous result type: Vector{Any} -nested_concrete result type: Vector{Vector{Int64}} -nested_any result type: Vector{Vector{Int64}} -dict result type: Dict{String, Real} -dict_concrete result type: Dict{String, Float64} -empty_list result type: Vector{Any} -empty_dict result type: Dict{Any, Any} -wrapper result type: PyList{Any} -iterator result type: PyIterable{Any} diff --git a/benchmark/convert-final-unwrapped-before-r2.tsv b/benchmark/convert-final-unwrapped-before-r2.tsv deleted file mode 100644 index aadb29a92..000000000 --- a/benchmark/convert-final-unwrapped-before-r2.tsv +++ /dev/null @@ -1,30 +0,0 @@ -case mode min_ns median_ns bytes allocs -int typed 242.8595641646489 286.2009685230024 0 0 -int runtime_target 392.5422885572139 413.43283582089555 16 1 -integer typed 242.22222222222223 285.68148148148146 0 0 -integer runtime_target 386.2068965517241 397.04926108374383 0 0 -bigint typed 932.0 1004.0 216 7 -bigint runtime_target 1190.0 1250.0 216 7 -float typed 249.72375690607734 296.6878453038674 0 0 -float runtime_target 393.0348258706468 397.5124378109453 16 1 -bool typed 259.025787965616 296.2750716332378 0 0 -bool runtime_target 445.9646464646465 526.2676767676768 0 0 -string typed 318.0257510729614 375.9699570815451 48 2 -string runtime_target 445.95959595959596 516.1666666666666 48 2 -none typed 240.55944055944056 276.9230769230769 0 0 -none runtime_target 354.50236966824644 395.2654028436019 0 0 -failure typed 231.52391304347827 258.045652173913 0 0 -failure runtime_target 371.5 426.005 0 0 -list10 typed 7760.0 8120.0 720 18 -list10000 typed 4.854337e6 5.624843e6 513880 19508 -list10000_concrete typed 4.225432e6 4.674036e6 362024 10018 -mixed_numeric typed 4000.0 4175.0 352 13 -heterogeneous typed 5400.0 6000.0 384 14 -nested_concrete typed 7050.0 8600.0 768 29 -nested_any typed 10800.0 11600.0 864 32 -dict typed 6360.0 7380.2 1280 24 -dict_concrete typed 3675.0 3950.125 672 16 -empty_list typed 1210.0 1400.0 112 5 -empty_dict typed 1040.0 1090.0 208 5 -wrapper typed 400.49751243781094 412.93532338308455 16 1 -iterator typed 401.0 485.505 16 1 diff --git a/benchmark/convert-final-unwrapped-before-r3-environment.txt b/benchmark/convert-final-unwrapped-before-r3-environment.txt deleted file mode 100644 index d0e4169d0..000000000 --- a/benchmark/convert-final-unwrapped-before-r3-environment.txt +++ /dev/null @@ -1,30 +0,0 @@ -Julia: 1.13.2 -Python: 3.15.0 | packaged by conda-forge | (main, Oct 12 2026, 17:49:39) [GCC 15.3.0] -Python executable: /home/doris/.julia/dev/PythonCall/benchmark/.CondaPkg/.pixi/envs/default/bin/python -BenchmarkTools: 1.8.0 -PythonCall source: /tmp/pythoncall-some-before.LlDQq5/src/PythonCall.jl -New API: true -Convert/pyconvert.jl SHA256: 7d8337b08370a90127dcc5a9d7b9b79f743ee2998c5ac6154a671725682aad6e -Convert/rules.jl SHA256: d42b0af459b0243412a5f9befa62caccc5039a8e0561be414cf9f941a6c328e4 -Wrap/PyArray.jl SHA256: ad549c18d502b12aad07329001ee0ec1a83ea907b5d8f2153bd23ce6e0b08c4a -int result type: Int64 -integer result type: Int64 -bigint result type: BigInt -float result type: Float64 -bool result type: Bool -string result type: String -none result type: Nothing -failure result type: Nothing -list10 result type: Vector{Int64} -list10000 result type: Vector{Int64} -list10000_concrete result type: Vector{Int64} -mixed_numeric result type: Vector{Real} -heterogeneous result type: Vector{Any} -nested_concrete result type: Vector{Vector{Int64}} -nested_any result type: Vector{Vector{Int64}} -dict result type: Dict{String, Real} -dict_concrete result type: Dict{String, Float64} -empty_list result type: Vector{Any} -empty_dict result type: Dict{Any, Any} -wrapper result type: PyList{Any} -iterator result type: PyIterable{Any} diff --git a/benchmark/convert-final-unwrapped-before-r3.tsv b/benchmark/convert-final-unwrapped-before-r3.tsv deleted file mode 100644 index 2e19c285a..000000000 --- a/benchmark/convert-final-unwrapped-before-r3.tsv +++ /dev/null @@ -1,30 +0,0 @@ -case mode min_ns median_ns bytes allocs -int typed 240.86294416243655 275.89086294416245 0 0 -int runtime_target 393.0 406.505 16 1 -integer typed 243.8280871670702 288.38014527845036 0 0 -integer runtime_target 389.6039603960396 447.529702970297 0 0 -bigint typed 934.7826086956521 1004.3913043478261 216 7 -bigint runtime_target 1200.0 1250.0 216 7 -float typed 234.5679012345679 240.99012345679012 0 0 -float runtime_target 429.1457286432161 499.50251256281405 16 1 -bool typed 254.00890207715133 299.7032640949555 0 0 -bool runtime_target 441.9191919191919 445.9646464646465 0 0 -string typed 313.79741379310343 369.82758620689657 48 2 -string runtime_target 454.04545454545456 521.7222222222222 48 2 -none typed 225.57077625570776 250.2283105022831 0 0 -none runtime_target 364.5980861244019 420.0956937799043 0 0 -failure typed 230.824200913242 231.73744292237444 0 0 -failure runtime_target 378.2608695652174 438.6497584541063 0 0 -list10 typed 6680.0 6960.2 720 18 -list10000 typed 4.714836e6 5.668843e6 513880 19508 -list10000_concrete typed 3.97843e6 4.284532e6 362024 10018 -mixed_numeric typed 3971.4285714285716 4614.285714285715 352 13 -heterogeneous typed 4871.428571428572 5471.428571428572 384 14 -nested_concrete typed 6950.0 7250.25 768 29 -nested_any typed 10800.0 11600.0 864 32 -dict typed 6480.0 6740.2 1280 24 -dict_concrete typed 3925.0 4525.0 672 16 -empty_list typed 1240.0 1530.0 112 5 -empty_dict typed 1040.0 1220.0 208 5 -wrapper typed 416.005 466.505 16 1 -iterator typed 406.5 467.5 16 1 diff --git a/benchmark/convert-inference-final.txt b/benchmark/convert-inference-final.txt deleted file mode 100644 index 45c0f1119..000000000 --- a/benchmark/convert-inference-final.txt +++ /dev/null @@ -1,63 +0,0 @@ - -pytryconvert(Int64, ::Py) -MethodInstance for pytryconvert(::Type{Int64}, ::Py) - from pytryconvert(::Type{T}, x; prefer) where T @ PythonCall.Convert ~/.julia/dev/PythonCall/src/Convert/pyconvert.jl:357 -Static Parameters - T = Int64 -Arguments - #self#::Core.Const(PythonCall.pytryconvert) - @_2::Core.Const(Int64) - x::Py -Body::UNION{NOTHING, SOME{INT64}} -1 ─ %1 = PythonCall.Convert.:(var"#pytryconvert#30")::Core.Const(PythonCall.Convert.var"#pytryconvert#30") -│ %2 = ()::Core.Const(()) -│ %3 = (%1)(%2, #self#, @_2, x)::UNION{NOTHING, SOME{INT64}} -└── return %3 - - -pytryconvert(Integer, ::Py) -MethodInstance for pytryconvert(::Type{Integer}, ::Py) - from pytryconvert(::Type{T}, x; prefer) where T @ PythonCall.Convert ~/.julia/dev/PythonCall/src/Convert/pyconvert.jl:357 -Static Parameters - T = Integer -Arguments - #self#::Core.Const(PythonCall.pytryconvert) - @_2::Core.Const(Integer) - x::Py -Body::UNION{NOTHING, SOME{T} WHERE T<:INTEGER} -1 ─ %1 = PythonCall.Convert.:(var"#pytryconvert#30")::Core.Const(PythonCall.Convert.var"#pytryconvert#30") -│ %2 = ()::Core.Const(()) -│ %3 = (%1)(%2, #self#, @_2, x)::UNION{NOTHING, SOME{T} WHERE T<:INTEGER} -└── return %3 - - -pytryconvert(Union{Nothing, Int64}, ::Py) -MethodInstance for pytryconvert(::Type{Union{Nothing, Int64}}, ::Py) - from pytryconvert(::Type{T}, x; prefer) where T @ PythonCall.Convert ~/.julia/dev/PythonCall/src/Convert/pyconvert.jl:357 -Static Parameters - T = Union{Nothing, Int64} -Arguments - #self#::Core.Const(PythonCall.pytryconvert) - @_2::Type{Union{Nothing, Int64}} - x::Py -Body::UNION{SOME{NOTHING}, NOTHING, SOME{INT64}} -1 ─ %1 = PythonCall.Convert.:(var"#pytryconvert#30")::Core.Const(PythonCall.Convert.var"#pytryconvert#30") -│ %2 = ()::Core.Const(()) -│ %3 = (%1)(%2, #self#, @_2, x)::UNION{SOME{NOTHING}, NOTHING, SOME{INT64}} -└── return %3 - - -pytryconvert(Any, ::Py) -MethodInstance for pytryconvert(::Type{Any}, ::Py) - from pytryconvert(::Type{T}, x; prefer) where T @ PythonCall.Convert ~/.julia/dev/PythonCall/src/Convert/pyconvert.jl:357 -Static Parameters - T = Any -Arguments - #self#::Core.Const(PythonCall.pytryconvert) - @_2::Core.Const(Any) - x::Py -Body::UNION{NOTHING, SOME} -1 ─ %1 = PythonCall.Convert.:(var"#pytryconvert#30")::Core.Const(PythonCall.Convert.var"#pytryconvert#30") -│ %2 = ()::Core.Const(()) -│ %3 = (%1)(%2, #self#, @_2, x)::UNION{NOTHING, SOME} -└── return %3 diff --git a/benchmark/convert-inference.txt b/benchmark/convert-inference.txt deleted file mode 100644 index 842b44d42..000000000 --- a/benchmark/convert-inference.txt +++ /dev/null @@ -1,63 +0,0 @@ - -pytryconvert(Int64, ::Py) -MethodInstance for pytryconvert(::Type{Int64}, ::Py) - from pytryconvert(::Type{T}, x; prefer) where T @ PythonCall.Convert ~/.julia/dev/PythonCall/src/Convert/pyconvert.jl:327 -Static Parameters - T = Int64 -Arguments - #self#::Core.Const(PythonCall.pytryconvert) - @_2::Core.Const(Int64) - x::Py -Body::UNION{NOTHING, SOME{INT64}} -1 ─ %1 = PythonCall.Convert.:(var"#pytryconvert#30")::Core.Const(PythonCall.Convert.var"#pytryconvert#30") -│ %2 = ()::Core.Const(()) -│ %3 = (%1)(%2, #self#, @_2, x)::UNION{NOTHING, SOME{INT64}} -└── return %3 - - -pytryconvert(Integer, ::Py) -MethodInstance for pytryconvert(::Type{Integer}, ::Py) - from pytryconvert(::Type{T}, x; prefer) where T @ PythonCall.Convert ~/.julia/dev/PythonCall/src/Convert/pyconvert.jl:327 -Static Parameters - T = Integer -Arguments - #self#::Core.Const(PythonCall.pytryconvert) - @_2::Core.Const(Integer) - x::Py -Body::UNION{NOTHING, SOME{T} WHERE T<:INTEGER} -1 ─ %1 = PythonCall.Convert.:(var"#pytryconvert#30")::Core.Const(PythonCall.Convert.var"#pytryconvert#30") -│ %2 = ()::Core.Const(()) -│ %3 = (%1)(%2, #self#, @_2, x)::UNION{NOTHING, SOME{T} WHERE T<:INTEGER} -└── return %3 - - -pytryconvert(Union{Nothing, Int64}, ::Py) -MethodInstance for pytryconvert(::Type{Union{Nothing, Int64}}, ::Py) - from pytryconvert(::Type{T}, x; prefer) where T @ PythonCall.Convert ~/.julia/dev/PythonCall/src/Convert/pyconvert.jl:327 -Static Parameters - T = Union{Nothing, Int64} -Arguments - #self#::Core.Const(PythonCall.pytryconvert) - @_2::Type{Union{Nothing, Int64}} - x::Py -Body::UNION{SOME{NOTHING}, NOTHING, SOME{INT64}} -1 ─ %1 = PythonCall.Convert.:(var"#pytryconvert#30")::Core.Const(PythonCall.Convert.var"#pytryconvert#30") -│ %2 = ()::Core.Const(()) -│ %3 = (%1)(%2, #self#, @_2, x)::UNION{SOME{NOTHING}, NOTHING, SOME{INT64}} -└── return %3 - - -pytryconvert(Any, ::Py) -MethodInstance for pytryconvert(::Type{Any}, ::Py) - from pytryconvert(::Type{T}, x; prefer) where T @ PythonCall.Convert ~/.julia/dev/PythonCall/src/Convert/pyconvert.jl:327 -Static Parameters - T = Any -Arguments - #self#::Core.Const(PythonCall.pytryconvert) - @_2::Core.Const(Any) - x::Py -Body::UNION{NOTHING, SOME} -1 ─ %1 = PythonCall.Convert.:(var"#pytryconvert#30")::Core.Const(PythonCall.Convert.var"#pytryconvert#30") -│ %2 = ()::Core.Const(()) -│ %3 = (%1)(%2, #self#, @_2, x)::UNION{NOTHING, SOME} -└── return %3 diff --git a/benchmark/convert-redesign.tsv b/benchmark/convert-redesign.tsv deleted file mode 100644 index ac05470e9..000000000 --- a/benchmark/convert-redesign.tsv +++ /dev/null @@ -1,16 +0,0 @@ -case ns bytes allocs -int 375.2378640776699 0 0 -integer 393.495 0 0 -bigint 1319.9 232 8 -float 424.0 32 2 -bool 408.3743842364532 0 0 -string 451.015306122449 48 2 -none 451.7363184079602 0 0 -failure 402.803738317757 0 0 -list10 7760.0 720 18 -list10000 5.007263e6 513880 19508 -mixed 6900.0 608 20 -nested 11000.0 864 32 -dict 6739.8 1280 24 -wrapper 558.5967741935484 16 1 -iterator 547.5882352941177 16 1 diff --git a/benchmark/convert-report.md b/benchmark/convert-report.md deleted file mode 100644 index 69c1249bc..000000000 --- a/benchmark/convert-report.md +++ /dev/null @@ -1,197 +0,0 @@ -# v1 pyconvert final implementation report - -The redesign is implemented on v1. The latest minimal-wrapping optimization and -current performance totals are in [convert-unwrapped-report.md](convert-unwrapped-report.md). -Latest local checks: **1,765 conversion/wrapper/Julia-wrapper checks passed**, with -one existing optional-dependency skip. The most recent 15-test ordinary Python -run predates that optimization. The -maintainer assigned final full-suite/notebook/docs and version-matrix validation -to CI; those checks were not rerun for this benchmark refresh. Work is uncommitted. - -## Design implemented - -- Rules store source, advertised output, scope, function and increasing ID. Adds - always create entries; replacement preserves identity/order. Mutations invalidate - all selections. Pending sources resolve without importing optional modules. -- A global strict-subclass DAG includes ABC relationships and independent array/ - buffer matchers. Inherited priorities are monotonic; stable topological sorting - uses source registration order, then rule creation order. Aliases share ordering - and priority. Per-call selection filters without reordering. -- Output intersection and destination scope determine eligibility, including - normalized union arms. Each rule receives non-union intersections, rule-first; - union-arm order is unspecified. The final Py fallback is outside the registry. -- Source names resolve loaded-module attributes, including public re-exports and - dotted paths. Bare names abbreviate builtins. Legacy exec-defined ancestors - can also resolve from an encountered class hierarchy. Cached Python type - references prevent pointer reuse. -- Cached invocations select context-aware/legacy signatures once per target and - context type. Scalar shortcuts require a matching cached first rule/target. - Explicit contexts carry ordered source-specific preferences and propagate - recursively when requested, with no task-local state. -- Canonical materialized containers become native Julia containers. Vector/dict - types widen with Base.promote_typejoin within requested bounds; unconstrained - empties use Any. Generic iterables remain lazy PyIterable values. -- Rules accept values, nothing for decline, and Some for explicit success. - Public pytryconvert always returns Some/nothing. Internal raw values, a private - failure sentinel and an escape avoid per-element Some allocations. Exceptions - propagate; preferred-type introspection returns a candidate, not a guarantee. - Built-in success helpers wrap only actual nothing/Some values; array and - native-container results cross dispatch boundaries directly. - -Public additions: PyConvertContext, pytryconvert, pyconvert_remove_rule, -pyconvert_replace_rule, pyconvert_rules, scope and prefer. Public rule priorities -and result helpers were removed. Main changes are in src/Convert/pyconvert.jl, -rules.jl, NumPy/pandas registrations, Wrap/PyArray, JlWrap, API declarations, -conversion documentation, migration guide and tests. - -## Agreed decisions and limitations - -The maintainer accepted pyconvert(Py, x::Py) as an identity shortcut. Generic -numbers.Real/Complex coercions were replaced by float/complex source rules: -integral/rational sources retain exact intermediates, supported NumPy scalars -retain dedicated rules, and other numeric types require explicit rules. Python -float-to-Int remains available when exact and in range. This fixes integer -overflow being hidden by an intermediate rounded Float64. - -The optimized internal result representation is explicitly allowed by the -specification; the public contract is unchanged. v1 calls its iterator wrapper -PyIterable rather than PyIterator. Ownership remains an API contract. -Cycles/identity preservation, dynamic ABC mutations, arbitrary module/type -replacement and method changes without invalidation remain unsupported. -Copy-policy frameworks and public priority controls were deliberately omitted. - -## Final benchmark method - -The full original-v1 comparison below measures the implementation immediately -before minimal result wrapping. The linked follow-up supersedes affected -allocation/timing totals and compares directly against that pre-change snapshot. - -Baseline: original v1 commit 25f82cc8effbd6c487ddceaffc34aa7cbe86505b, extracted -into an isolated checkout/environment. After: the final working tree, including -the alias/shorthand and numeric-source changes. Environment records include -source paths and SHA256 fingerprints. - -Linux x86_64, Intel Core i7-8750H, Julia 1.13.2, Python 3.15.0, NumPy 2.5.4, -BenchmarkTools 1.8.0. Both revisions use the same Python executable and Null -CondaPkg backend. All processes ran sequentially without concurrent tests. -Round order: before/after, after/before, before/after. - -Tables use microseconds and the **median of three trial minima**. Warm trials -use up to 5,000 samples / one second. Julia bytes/allocation counts exclude -Python allocations. Trial medians and round ranges remain in -convert-final-summary.tsv. These are short local trials, not confidence intervals. - -## Cached scalars - -The requested type is visible to inference through Val. Runtime-target variants -are separately recorded; those can box values in the benchmark caller. - -| Target/source | Before us | After us | Change | Before B / allocs | After B / allocs | -| --- | ---: | ---: | ---: | ---: | ---: | -| Int / int | 0.223 | 0.240 | +7.9% | 0 / 0 | 0 / 0 | -| Integer / int | 0.590 | 0.242 | -59.1% | 0 / 0 | 0 / 0 | -| BigInt / large int | 0.977 | 0.970 | -0.7% | 216 / 7 | 216 / 7 | -| Float64 / float | 0.240 | 0.240 | -0.1% | 0 / 0 | 0 / 0 | -| Bool / bool | 0.232 | 0.254 | +9.3% | 0 / 0 | 0 / 0 | -| String / str | 0.297 | 0.311 | +5.0% | 48 / 2 | 48 / 2 | -| Nothing / None | 0.211 | 0.230 | +9.3% | 0 / 0 | 0 / 0 | -| Int / incompatible str | 0.239 | 0.232 | -2.8% | 0 / 0 | 0 / 0 | - -Positive scalar differences are tens of nanoseconds and remain visible in the -report. None is not slower than Int in the final implementation. -Float64/BigInt no longer retain the initial redesign's extra allocation. - -## Containers - -| Case | Before us | After us | Change | Before B / allocs | After B / allocs | -| --- | ---: | ---: | ---: | ---: | ---: | -| Vector, 10 integers | 9.899 | 6.760 | -31.7% | 704 / 17 | 720 / 18 | -| Vector, 10,000 integers | 7243.345 | 4821.463 | -33.4% | 513864 / 19507 | 513880 / 19508 | -| Vector{Int}, 10,000 integers | 3918.970 | 4122.068 | +5.2% | 362008 / 10017 | 362024 / 10018 | -| Vector, mixed numeric | 4.471 | 3.800 | -15.0% | 320 / 11 | 352 / 13 | -| Vector, heterogeneous | 5.466 | 4.786 | -12.5% | 368 / 13 | 384 / 14 | -| Vector{Vector{Int}}, nested | 7.975 | 7.060 | -11.5% | 720 / 26 | 768 / 29 | -| Dict, heterogeneous values | 7.425 | 6.700 | -9.8% | 1248 / 22 | 1280 / 24 | -| Dict{String,Float64} | 3.237 | 3.750 | +15.8% | 656 / 15 | 672 / 16 | -| Empty Vector | 1.290 | 1.140 | -11.6% | 64 / 3 | 112 / 5 | -| Empty Dict | 1.054 | 1.100 | +4.4% | 112 / 3 | 208 / 5 | - -Mixed numeric outputs intentionally change from promoted Float64 to Real while -preserving individual values; dictionary value types change similarly. Empty -types change from bottom to Any. Nested Any changes from wrapping (0.390 us, -16 B / 1 allocation) to recursive copying (9.500 us, 864 B / 32 allocations); -those perform different work. Explicit PyList and iterator wrapping remain -about 0.39 us / 16 B / 1 allocation. - -## Arrays, dispatch and preferences - -In this pre-optimization snapshot, array wrappers retain 128 extra bytes / two allocations, native arrays 144 bytes / -three allocations. Median trial minima rise 3.4% for buffer wrapping, 12.9% for -ndarray wrapping, and 4.8–7.7% for native arrays. Native ndarray trial medians -are essentially unchanged, while ndarray wrapper trial medians rise about 11%. -These end-to-end timings do not isolate allocation cost from other dispatch -changes. See [convert-expanded-report.md](convert-expanded-report.md) for ranges, -complete protocol/cold-path tables and allocation attribution. - -Cached single-rule/decline-chain dispatch stays allocation-free at roughly -0.38/0.54/0.94 us. Scope filtering excludes sixteen callbacks (4.07 to 0.38 us), -an intentional work difference. Selection misses are mixed: the simple fixture -rises from 26.9 to 71.2 us, while most protocol cases improve. - -Full invalidation/global rebuilding costs about 2.5–2.9 ms and 1.47–1.51 MB -with builtins plus 27 synthetic registrations, versus tens/hundreds of -microseconds in the old per-type scheme. Warm calls never rebuild the DAG. -This remains a measured cold-path regression, not a registry scaling study. - -New-API matching-preference cases cost 3.38/4.13/5.14 us for first success, -first decline then success, and all preferences declining before ordinary -conversion. Context-construction/source checks are included. Old v1 is marked -unsupported. Broader nested preferences are in convert-dispatch-final.tsv. - -## Result representation and inference - -Final raw-Unconverted versus Some/nothing models cover successful/failed Int64, -Float64, String, Vector{Int}, Integer, AbstractArray, Union{Int64,Nothing}, Any, -escaping results and typed 100-element loops. Both loops allocate zero; -escaping Some values can allocate, including an extra 16 bytes in the Int case. -This supports optimized internal dispatch behind the ergonomic public API. - -Inference preserves Some{Int} for Int, existential Some subtypes for Integer, -separate Some alternatives for Union{Int,Nothing}, and Some for Any. Scalar -profiles confirm no internal Float64 box or Some{BigInt} allocation. See -convert-results-final.tsv, convert-inference-final.txt, convert-scalars-final-* -and [convert-scalars-report.md](convert-scalars-report.md). - -## Reproduction and artifacts - -Use the same Julia executable and installed Python/backend in all runs. Prepare -an isolated baseline environment without changing the working tree: - -~~~sh -convert_baseline_src=$(mktemp -d) -convert_baseline_env=$(mktemp -d) -git archive 25f82cc8effbd6c487ddceaffc34aa7cbe86505b | tar -x -C "$convert_baseline_src" -/absolute/path/to/julia --project="$convert_baseline_env" -e \ - 'using Pkg; Pkg.develop(path=ARGS[1]); Pkg.add(PackageSpec(name="BenchmarkTools",version="1.8.0"))' \ - "$convert_baseline_src" -~~~ - -With the checkout's benchmark dependencies installed, run: - -~~~sh -JULIA_CONDAPKG_BACKEND=Null JULIA_PYTHONCALL_EXE=/absolute/path/to/python \ - bash benchmark/run-convert-final.sh /absolute/path/to/julia "$convert_baseline_env" -python3 benchmark/summarize-convert-final.py -~~~ - -The runner serializes three paired common/expanded rounds, then final scalar, -result/inference and preference suites. Fixture assertions passed on both -revisions. Allocation attribution can be reproduced with -convert-array-allocations.jl before/after in the respective environments. - -Authoritative paired data use convert-final-{before,after}-r{1,2,3} and -convert-expanded-final-{before,after}-r{1,2,3}; each includes an environment record. -The summarizer validates constant source snapshots and allocation counts across -rounds. Older TSV/profile files are historical snapshots, superseded by these -final measurements. No runtime policy or conversion optimization changed during -this refresh. diff --git a/benchmark/convert-results-final.tsv b/benchmark/convert-results-final.tsv deleted file mode 100644 index 258c73248..000000000 --- a/benchmark/convert-results-final.tsv +++ /dev/null @@ -1,67 +0,0 @@ -type representation success escaping ns bytes allocs -Int64 raw true true 133.56128293241696 16 1 -Int64 raw true false 140.57028571428572 0 0 -Int64 raw false true 131.88952164009112 16 1 -Int64 raw false false 136.09421112372303 0 0 -Int64 some true true 141.46225319396052 32 2 -Int64 some true false 129.4501679731243 16 1 -Int64 some false true 128.3783783783784 16 1 -Int64 some false false 121.34103410341034 0 0 -Float64 raw true true 154.18021201413427 48 3 -Float64 raw true false 150.46503496503496 32 2 -Float64 raw false true 140.2582159624413 32 2 -Float64 raw false false 141.6945412311266 16 1 -Float64 some true true 140.34970760233918 48 3 -Float64 some true false 147.3672514619883 32 2 -Float64 some false true 134.84562996594778 32 2 -Float64 some false false 133.56401384083046 16 1 -String raw true true 132.6867881548975 16 1 -String raw true false 121.21546961325967 0 0 -String raw false true 139.52050113895217 16 1 -String raw false false 132.4313063063063 0 0 -String some true true 144.3417142857143 48 3 -String some true false 129.49772209567197 16 1 -String some false true 134.55444444444444 16 1 -String some false false 134.27922814982975 0 0 -Vector{Int64} raw true true 147.74971164936562 16 1 -Vector{Int64} raw true false 115.62046204620462 0 0 -Vector{Int64} raw false true 137.38310185185185 16 1 -Vector{Int64} raw false false 124.88973799126637 0 0 -Vector{Int64} some true true 164.4159509202454 48 3 -Vector{Int64} some true false 142.7884160756501 16 1 -Vector{Int64} some false true 141.43075117370893 16 1 -Vector{Int64} some false false 146.85198135198135 0 0 -Integer raw true true 150.1153846153846 16 1 -Integer raw true false 146.5311004784689 0 0 -Integer raw false true 152.11150234741785 16 1 -Integer raw false false 158.29020100502512 0 0 -Integer some true true 143.2612293144208 32 2 -Integer some true false 146.2163120567376 16 1 -Integer some false true 145.27068557919623 16 1 -Integer some false false 142.7884160756501 0 0 -AbstractArray raw true true 204.7527733755943 16 1 -AbstractArray raw true false 182.4802919708029 0 0 -AbstractArray raw false true 189.55299539170508 16 1 -AbstractArray raw false false 192.02753623188406 0 0 -AbstractArray some true true 215.9274336283186 48 3 -AbstractArray some true false 196.75162337662337 16 1 -AbstractArray some false true 200.30804953560371 16 1 -AbstractArray some false false 194.56709265175718 0 0 -Union{Nothing, Int64} raw true true 67.51685393258427 16 1 -Union{Nothing, Int64} raw true false 60.957186544342505 0 0 -Union{Nothing, Int64} raw false true 61.671763506625894 16 1 -Union{Nothing, Int64} raw false false 60.38594704684318 0 0 -Union{Nothing, Int64} some true true 70.79815573770492 32 2 -Union{Nothing, Int64} some true false 72.08486707566462 16 1 -Union{Nothing, Int64} some false true 65.91734693877551 16 1 -Union{Nothing, Int64} some false false 69.8661899897855 0 0 -Any raw true true 184.297256097561 16 1 -Any raw true false 199.17326732673268 0 0 -Any raw false true 188.1981845688351 16 1 -Any raw false false 202.78068739770868 0 0 -Any some true true 204.17217391304348 32 2 -Any some true false 223.92678571428573 16 1 -Any some false true 197.70703764320785 16 1 -Any some false false 223.06007751937983 0 0 -loop100 raw true false 288.4364161849711 0 0 -loop100 some true false 268.33 0 0 diff --git a/benchmark/convert-results.tsv b/benchmark/convert-results.tsv deleted file mode 100644 index 4a81e5ddc..000000000 --- a/benchmark/convert-results.tsv +++ /dev/null @@ -1,67 +0,0 @@ -type representation success escaping ns bytes allocs -Int64 raw true true 143.5885780885781 16 1 -Int64 raw true false 123.2547065337763 0 0 -Int64 raw false true 138.77199074074073 16 1 -Int64 raw false false 136.21262458471762 0 0 -Int64 some true true 134.82130584192439 32 2 -Int64 some true false 139.79123414071512 16 1 -Int64 some false true 131.4189189189189 16 1 -Int64 some false false 133.48405466970388 0 0 -Float64 raw true true 159.75337423312882 48 3 -Float64 raw true false 160.53125 32 2 -Float64 raw false true 171.75757575757575 32 2 -Float64 raw false false 136.2156862745098 16 1 -Float64 some true true 138.22727272727272 48 3 -Float64 some true false 136.68865740740742 32 2 -Float64 some false true 135.42742857142858 32 2 -Float64 some false false 139.18806306306305 16 1 -String raw true true 201.98439716312058 16 1 -String raw true false 172.75950920245398 0 0 -String raw false true 180.2822695035461 16 1 -String raw false false 163.56658291457288 0 0 -String some true true 165.17843866171003 48 3 -String some true false 131.87317620650953 16 1 -String some false true 167.3064903846154 16 1 -String some false false 140.67482517482517 0 0 -Vector{Int64} raw true true 129.61599099099098 16 1 -Vector{Int64} raw true false 142.24122310305776 0 0 -Vector{Int64} raw false true 128.94144144144144 16 1 -Vector{Int64} raw false false 131.35273159144893 0 0 -Vector{Int64} some true true 160.5524798154556 48 3 -Vector{Int64} some true false 128.7150900900901 16 1 -Vector{Int64} some false true 130.45912653975364 16 1 -Vector{Int64} some false false 125.85148514851485 0 0 -Integer raw true true 169.8123543123543 16 1 -Integer raw true false 135.0504009163803 0 0 -Integer raw false true 149.58164481525625 16 1 -Integer raw false false 134.7356725146199 0 0 -Integer some true true 147.2476076555024 32 2 -Integer some true false 139.3927738927739 16 1 -Integer some false true 143.66079812206573 16 1 -Integer some false false 135.27436440677965 0 0 -AbstractArray raw true true 202.2711038961039 16 1 -AbstractArray raw true false 219.1542207792208 0 0 -AbstractArray raw false true 231.69322033898305 16 1 -AbstractArray raw false false 232.12443438914028 0 0 -AbstractArray some true true 213.45607476635513 48 3 -AbstractArray some true false 196.5663026521061 16 1 -AbstractArray some false true 213.09557522123893 16 1 -AbstractArray some false false 199.36450079239302 0 0 -Union{Nothing, Int64} raw true true 76.3023493360572 16 1 -Union{Nothing, Int64} raw true false 63.68158697863682 0 0 -Union{Nothing, Int64} raw false true 63.738508682328906 16 1 -Union{Nothing, Int64} raw false false 57.63747454175153 0 0 -Union{Nothing, Int64} some true true 71.23848515864893 32 2 -Union{Nothing, Int64} some true false 71.0204081632653 16 1 -Union{Nothing, Int64} some false true 71.3265306122449 16 1 -Union{Nothing, Int64} some false false 65.30925737538149 0 0 -Any raw true true 196.61674718196457 16 1 -Any raw true false 192.86687797147385 0 0 -Any raw false true 204.8685064935065 16 1 -Any raw false false 199.83166666666668 0 0 -Any some true true 273.9698630136986 32 2 -Any some true false 226.34860883797054 16 1 -Any some false true 278.32637075718014 16 1 -Any some false false 190.18333333333334 0 0 -loop100 raw true false 306.11436170212767 0 0 -loop100 some true false 253.29041916167665 0 0 diff --git a/benchmark/convert-scalaropt.tsv b/benchmark/convert-scalaropt.tsv deleted file mode 100644 index 2d9c6b16e..000000000 --- a/benchmark/convert-scalaropt.tsv +++ /dev/null @@ -1,16 +0,0 @@ -case ns bytes allocs -int 379.121359223301 0 0 -integer 362.85238095238094 0 0 -bigint 1189.9 216 7 -float 367.3076923076923 16 1 -bool 381.45853658536583 0 0 -string 489.3888888888889 48 2 -none 355.70319634703196 0 0 -failure 352.37619047619046 0 0 -list10 7160.0 720 18 -list10000 5.30626e6 513880 19508 -mixed 6459.8 608 20 -nested 9499.0 864 32 -dict 6719.8 1280 24 -wrapper 574.9945652173913 16 1 -iterator 574.2105263157895 16 1 diff --git a/benchmark/convert-scalars-before-allocations.txt b/benchmark/convert-scalars-before-allocations.txt deleted file mode 100644 index 4838eec36..000000000 --- a/benchmark/convert-scalars-before-allocations.txt +++ /dev/null @@ -1,139 +0,0 @@ - -int - -float -Float64: 16 bytes - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{Float64}, x::Py) at pyconvert.jl:296 - pytryconvert_raw at pyconvert.jl:318 [inlined] - macro expansion at pyconvert.jl:394 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{Float64}, x::Py, default::Nothing) at pyconvert.jl:393 - #pyconvert#36 at pyconvert.jl:399 [inlined] - pyconvert at pyconvert.jl:399 [inlined] - scalar_convert(::Val{Float64}, x::Py) at convert-scalars.jl:5 - (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 - eval(m::Module, e::Any) at boot.jl:489 -Float64: 16 bytes - (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 - eval(m::Module, e::Any) at boot.jl:489 - -bigint -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:51 [inlined] - pynew at Py.jl:55 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at Py.jl:102 [inlined] - macro expansion at regions.jl:296 [inlined] - pyint(x::Py) at builtins.jl:689 - macro expansion at rules.jl:90 [inlined] - macro expansion at regions.jl:296 [inlined] - pyconvert_rule_int(::Type{BigInt}, x::Py) at rules.jl:61 - pyconvert_first at pyconvert.jl:282 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:299 - pytryconvert_raw at pyconvert.jl:318 [inlined] - macro expansion at pyconvert.jl:394 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:393 - #pyconvert#36 at pyconvert.jl:399 [inlined] - pyconvert at pyconvert.jl:399 [inlined] - scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 - (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 - eval(m::Module, e::Any) at boot.jl:489 -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:51 [inlined] - pynew at Py.jl:55 [inlined] - macro expansion at regions.jl:296 [inlined] - pystr(x::Py) at builtins.jl:592 - pystr at builtins.jl:598 [inlined] - macro expansion at rules.jl:91 [inlined] - macro expansion at regions.jl:296 [inlined] - pyconvert_rule_int(::Type{BigInt}, x::Py) at rules.jl:61 - pyconvert_first at pyconvert.jl:282 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:299 - pytryconvert_raw at pyconvert.jl:318 [inlined] - macro expansion at pyconvert.jl:394 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:393 - #pyconvert#36 at pyconvert.jl:399 [inlined] - pyconvert at pyconvert.jl:399 [inlined] - scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 - (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 - eval(m::Module, e::Any) at boot.jl:489 -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:51 [inlined] - pynew at Py.jl:55 [inlined] - macro expansion at regions.jl:296 [inlined] - pystr_asUTF8bytes(x::Py) at builtins.jl:600 - pystr_asstring(x::Py) at builtins.jl:603 - pystr at builtins.jl:598 [inlined] - macro expansion at rules.jl:91 [inlined] - macro expansion at regions.jl:296 [inlined] - pyconvert_rule_int(::Type{BigInt}, x::Py) at rules.jl:61 - pyconvert_first at pyconvert.jl:282 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:299 - pytryconvert_raw at pyconvert.jl:318 [inlined] - macro expansion at pyconvert.jl:394 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:393 - #pyconvert#36 at pyconvert.jl:399 [inlined] - pyconvert at pyconvert.jl:399 [inlined] - scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 - (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 - eval(m::Module, e::Any) at boot.jl:489 -String: 70 bytes - pybytes_asUTF8string at builtins.jl:654 [inlined] - pystr_asstring(x::Py) at builtins.jl:604 - pystr at builtins.jl:598 [inlined] - macro expansion at rules.jl:91 [inlined] - macro expansion at regions.jl:296 [inlined] - pyconvert_rule_int(::Type{BigInt}, x::Py) at rules.jl:61 - pyconvert_first at pyconvert.jl:282 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:299 - pytryconvert_raw at pyconvert.jl:318 [inlined] - macro expansion at pyconvert.jl:394 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:393 - #pyconvert#36 at pyconvert.jl:399 [inlined] - pyconvert at pyconvert.jl:399 [inlined] - scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 - (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 - eval(m::Module, e::Any) at boot.jl:489 -BigInt: 32 bytes - _ at gmp.jl:70 [inlined] - BigInt at gmp.jl:69 [inlined] - tryparse_internal(::Type{BigInt}, s::String, startpos::Int64, endpos::Int64, base_::Int64, raise::Bool) at gmp.jl:302 - macro expansion at rules.jl:93 [inlined] - macro expansion at regions.jl:296 [inlined] - pyconvert_rule_int(::Type{BigInt}, x::Py) at rules.jl:61 - pyconvert_first at pyconvert.jl:282 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:299 - pytryconvert_raw at pyconvert.jl:318 [inlined] - macro expansion at pyconvert.jl:394 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:393 - #pyconvert#36 at pyconvert.jl:399 [inlined] - pyconvert at pyconvert.jl:399 [inlined] - scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 - (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 - eval(m::Module, e::Any) at boot.jl:489 -Some{BigInt}: 16 bytes - macro expansion at rules.jl:94 [inlined] - macro expansion at regions.jl:296 [inlined] - pyconvert_rule_int(::Type{BigInt}, x::Py) at rules.jl:61 - pyconvert_first at pyconvert.jl:282 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:299 - pytryconvert_raw at pyconvert.jl:318 [inlined] - macro expansion at pyconvert.jl:394 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:393 - #pyconvert#36 at pyconvert.jl:399 [inlined] - pyconvert at pyconvert.jl:399 [inlined] - scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 - (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 - eval(m::Module, e::Any) at boot.jl:489 - -none diff --git a/benchmark/convert-scalars-before-inference.txt b/benchmark/convert-scalars-before-inference.txt deleted file mode 100644 index 38aa8b8d0..000000000 --- a/benchmark/convert-scalars-before-inference.txt +++ /dev/null @@ -1,663 +0,0 @@ - -int: scalar_convert -MethodInstance for scalar_convert(::Val{Int64}, ::Py) - from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 -Static Parameters - T = Int64 -Arguments - #self#::Core.Const(Main.scalar_convert) - _::Core.Const(Val{Int64}()) - x::Py -Body::UNION{NOTHING, INT64} -1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) -│ %2 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ %3 = Main.nothing::Core.Const(nothing) -│ %4 = (%1)(%2, x, %3)::UNION{NOTHING, INT64} -└── return %4 - - -int: scalar_plain -MethodInstance for scalar_plain(::Val{Int64}, ::Py) - from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 -Static Parameters - T = Int64 -Arguments - #self#::Core.Const(Main.scalar_plain) - _::Core.Const(Val{Int64}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - @_7::Int64 - @_8::ANY -Body::ANY -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ %4 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %4 -2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %10 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ %11 = (%7)(%9, %10, x)::ANY -└── return %11 -3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%13)()) -│ %15 = task::Task -│ (state = (PythonCall.C.current_task_state)(%15)) -│ %17 = task::Task -│ %18 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%17, %18)) -4 ─ %20 = enter #7 -5 ─ (@_7 = -1) -│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %26 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ (@_8 = (%23)(%25, %26, x)) -│ (@_7 = 1) -└── $(Expr(:leave, :(%20))) -6 ─ goto #8 -7 ┄ %31 = task::Task -│ %32 = state::PythonCall.C.TaskState -│ %33 = token::Symbol -│ (PythonCall.C.exit_region)(%31, %32, %33) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%20))))) -└── Core.Const(:(return nothing)) -8 ┄ %38 = task::Task -│ %39 = state::PythonCall.C.TaskState -│ %40 = token::Symbol -│ (PythonCall.C.exit_region)(%38, %39, %40) -│ %42 = @_8::ANY -└── return %42 - - -int: scalar_first -MethodInstance for scalar_first(::Val{Int64}, ::Py) - from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 -Static Parameters - T = Int64 -Arguments - #self#::Core.Const(Main.scalar_first) - _::Core.Const(Val{Int64}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - selection::PythonCall.Convert.PyConvertSelection - ctx::PyConvertContext{Tuple{}} - @_9::Int64 - @_10::ANY -Body::ANY -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ Core.NewvarNode(:(selection)) -│ Core.NewvarNode(:(ctx)) -│ %6 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %6 -2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%8)()) -│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %13 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ %14 = Main.PythonCall::Core.Const(PythonCall) -│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) -│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%11)(%12, %13, %17)) -│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %22 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ %23 = selection::PythonCall.Convert.PyConvertSelection -│ %24 = (%20)(%21, %22, x, %23)::ANY -└── return %24 -3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%26)()) -│ %28 = task::Task -│ (state = (PythonCall.C.current_task_state)(%28)) -│ %30 = task::Task -│ %31 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%30, %31)) -4 ─ %33 = enter #7 -5 ─ (@_9 = -1) -│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%35)()) -│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %40 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ %41 = Main.PythonCall::Core.Const(PythonCall) -│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) -│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%38)(%39, %40, %44)) -│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %49 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ %50 = selection::PythonCall.Convert.PyConvertSelection -│ %51 = (%47)(%48, %49, x, %50)::ANY -│ (@_10 = %51) -│ (@_9 = 1) -└── $(Expr(:leave, :(%33))) -6 ─ goto #8 -7 ┄ %56 = task::Task -│ %57 = state::PythonCall.C.TaskState -│ %58 = token::Symbol -│ (PythonCall.C.exit_region)(%56, %57, %58) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%33))))) -└── Core.Const(:(return nothing)) -8 ┄ %63 = task::Task -│ %64 = state::PythonCall.C.TaskState -│ %65 = token::Symbol -│ (PythonCall.C.exit_region)(%63, %64, %65) -│ %67 = @_10::ANY -└── return %67 - - -float: scalar_convert -MethodInstance for scalar_convert(::Val{Float64}, ::Py) - from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 -Static Parameters - T = Float64 -Arguments - #self#::Core.Const(Main.scalar_convert) - _::Core.Const(Val{Float64}()) - x::Py -Body::UNION{NOTHING, FLOAT64} -1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) -│ %2 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ %3 = Main.nothing::Core.Const(nothing) -│ %4 = (%1)(%2, x, %3)::UNION{NOTHING, FLOAT64} -└── return %4 - - -float: scalar_plain -MethodInstance for scalar_plain(::Val{Float64}, ::Py) - from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 -Static Parameters - T = Float64 -Arguments - #self#::Core.Const(Main.scalar_plain) - _::Core.Const(Val{Float64}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - @_7::Int64 - @_8::ANY -Body::ANY -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ %4 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %4 -2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %10 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ %11 = (%7)(%9, %10, x)::ANY -└── return %11 -3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%13)()) -│ %15 = task::Task -│ (state = (PythonCall.C.current_task_state)(%15)) -│ %17 = task::Task -│ %18 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%17, %18)) -4 ─ %20 = enter #7 -5 ─ (@_7 = -1) -│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %26 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ (@_8 = (%23)(%25, %26, x)) -│ (@_7 = 1) -└── $(Expr(:leave, :(%20))) -6 ─ goto #8 -7 ┄ %31 = task::Task -│ %32 = state::PythonCall.C.TaskState -│ %33 = token::Symbol -│ (PythonCall.C.exit_region)(%31, %32, %33) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%20))))) -└── Core.Const(:(return nothing)) -8 ┄ %38 = task::Task -│ %39 = state::PythonCall.C.TaskState -│ %40 = token::Symbol -│ (PythonCall.C.exit_region)(%38, %39, %40) -│ %42 = @_8::ANY -└── return %42 - - -float: scalar_first -MethodInstance for scalar_first(::Val{Float64}, ::Py) - from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 -Static Parameters - T = Float64 -Arguments - #self#::Core.Const(Main.scalar_first) - _::Core.Const(Val{Float64}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - selection::PythonCall.Convert.PyConvertSelection - ctx::PyConvertContext{Tuple{}} - @_9::Int64 - @_10::ANY -Body::ANY -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ Core.NewvarNode(:(selection)) -│ Core.NewvarNode(:(ctx)) -│ %6 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %6 -2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%8)()) -│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %13 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ %14 = Main.PythonCall::Core.Const(PythonCall) -│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) -│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%11)(%12, %13, %17)) -│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %22 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ %23 = selection::PythonCall.Convert.PyConvertSelection -│ %24 = (%20)(%21, %22, x, %23)::ANY -└── return %24 -3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%26)()) -│ %28 = task::Task -│ (state = (PythonCall.C.current_task_state)(%28)) -│ %30 = task::Task -│ %31 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%30, %31)) -4 ─ %33 = enter #7 -5 ─ (@_9 = -1) -│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%35)()) -│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %40 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ %41 = Main.PythonCall::Core.Const(PythonCall) -│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) -│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%38)(%39, %40, %44)) -│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %49 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ %50 = selection::PythonCall.Convert.PyConvertSelection -│ %51 = (%47)(%48, %49, x, %50)::ANY -│ (@_10 = %51) -│ (@_9 = 1) -└── $(Expr(:leave, :(%33))) -6 ─ goto #8 -7 ┄ %56 = task::Task -│ %57 = state::PythonCall.C.TaskState -│ %58 = token::Symbol -│ (PythonCall.C.exit_region)(%56, %57, %58) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%33))))) -└── Core.Const(:(return nothing)) -8 ┄ %63 = task::Task -│ %64 = state::PythonCall.C.TaskState -│ %65 = token::Symbol -│ (PythonCall.C.exit_region)(%63, %64, %65) -│ %67 = @_10::ANY -└── return %67 - - -bigint: scalar_convert -MethodInstance for scalar_convert(::Val{BigInt}, ::Py) - from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 -Static Parameters - T = BigInt -Arguments - #self#::Core.Const(Main.scalar_convert) - _::Core.Const(Val{BigInt}()) - x::Py -Body::UNION{NOTHING, BIGINT} -1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) -│ %2 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ %3 = Main.nothing::Core.Const(nothing) -│ %4 = (%1)(%2, x, %3)::UNION{NOTHING, BIGINT} -└── return %4 - - -bigint: scalar_plain -MethodInstance for scalar_plain(::Val{BigInt}, ::Py) - from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 -Static Parameters - T = BigInt -Arguments - #self#::Core.Const(Main.scalar_plain) - _::Core.Const(Val{BigInt}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - @_7::Int64 - @_8::ANY -Body::ANY -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ %4 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %4 -2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %10 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ %11 = (%7)(%9, %10, x)::ANY -└── return %11 -3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%13)()) -│ %15 = task::Task -│ (state = (PythonCall.C.current_task_state)(%15)) -│ %17 = task::Task -│ %18 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%17, %18)) -4 ─ %20 = enter #7 -5 ─ (@_7 = -1) -│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %26 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ (@_8 = (%23)(%25, %26, x)) -│ (@_7 = 1) -└── $(Expr(:leave, :(%20))) -6 ─ goto #8 -7 ┄ %31 = task::Task -│ %32 = state::PythonCall.C.TaskState -│ %33 = token::Symbol -│ (PythonCall.C.exit_region)(%31, %32, %33) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%20))))) -└── Core.Const(:(return nothing)) -8 ┄ %38 = task::Task -│ %39 = state::PythonCall.C.TaskState -│ %40 = token::Symbol -│ (PythonCall.C.exit_region)(%38, %39, %40) -│ %42 = @_8::ANY -└── return %42 - - -bigint: scalar_first -MethodInstance for scalar_first(::Val{BigInt}, ::Py) - from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 -Static Parameters - T = BigInt -Arguments - #self#::Core.Const(Main.scalar_first) - _::Core.Const(Val{BigInt}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - selection::PythonCall.Convert.PyConvertSelection - ctx::PyConvertContext{Tuple{}} - @_9::Int64 - @_10::ANY -Body::ANY -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ Core.NewvarNode(:(selection)) -│ Core.NewvarNode(:(ctx)) -│ %6 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %6 -2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%8)()) -│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %13 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ %14 = Main.PythonCall::Core.Const(PythonCall) -│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) -│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%11)(%12, %13, %17)) -│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %22 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ %23 = selection::PythonCall.Convert.PyConvertSelection -│ %24 = (%20)(%21, %22, x, %23)::ANY -└── return %24 -3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%26)()) -│ %28 = task::Task -│ (state = (PythonCall.C.current_task_state)(%28)) -│ %30 = task::Task -│ %31 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%30, %31)) -4 ─ %33 = enter #7 -5 ─ (@_9 = -1) -│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%35)()) -│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %40 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ %41 = Main.PythonCall::Core.Const(PythonCall) -│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) -│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%38)(%39, %40, %44)) -│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %49 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ %50 = selection::PythonCall.Convert.PyConvertSelection -│ %51 = (%47)(%48, %49, x, %50)::ANY -│ (@_10 = %51) -│ (@_9 = 1) -└── $(Expr(:leave, :(%33))) -6 ─ goto #8 -7 ┄ %56 = task::Task -│ %57 = state::PythonCall.C.TaskState -│ %58 = token::Symbol -│ (PythonCall.C.exit_region)(%56, %57, %58) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%33))))) -└── Core.Const(:(return nothing)) -8 ┄ %63 = task::Task -│ %64 = state::PythonCall.C.TaskState -│ %65 = token::Symbol -│ (PythonCall.C.exit_region)(%63, %64, %65) -│ %67 = @_10::ANY -└── return %67 - - -none: scalar_convert -MethodInstance for scalar_convert(::Val{Nothing}, ::Py) - from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 -Static Parameters - T = Nothing -Arguments - #self#::Core.Const(Main.scalar_convert) - _::Core.Const(Val{Nothing}()) - x::Py -Body::Nothing -1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) -│ %2 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ %3 = Main.nothing::Core.Const(nothing) -│ %4 = (%1)(%2, x, %3)::Core.Const(nothing) -└── return %4 - - -none: scalar_plain -MethodInstance for scalar_plain(::Val{Nothing}, ::Py) - from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 -Static Parameters - T = Nothing -Arguments - #self#::Core.Const(Main.scalar_plain) - _::Core.Const(Val{Nothing}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - @_7::Int64 - @_8::ANY -Body::ANY -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ %4 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %4 -2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %10 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ %11 = (%7)(%9, %10, x)::ANY -└── return %11 -3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%13)()) -│ %15 = task::Task -│ (state = (PythonCall.C.current_task_state)(%15)) -│ %17 = task::Task -│ %18 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%17, %18)) -4 ─ %20 = enter #7 -5 ─ (@_7 = -1) -│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %26 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ (@_8 = (%23)(%25, %26, x)) -│ (@_7 = 1) -└── $(Expr(:leave, :(%20))) -6 ─ goto #8 -7 ┄ %31 = task::Task -│ %32 = state::PythonCall.C.TaskState -│ %33 = token::Symbol -│ (PythonCall.C.exit_region)(%31, %32, %33) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%20))))) -└── Core.Const(:(return nothing)) -8 ┄ %38 = task::Task -│ %39 = state::PythonCall.C.TaskState -│ %40 = token::Symbol -│ (PythonCall.C.exit_region)(%38, %39, %40) -│ %42 = @_8::ANY -└── return %42 - - -none: scalar_first -MethodInstance for scalar_first(::Val{Nothing}, ::Py) - from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 -Static Parameters - T = Nothing -Arguments - #self#::Core.Const(Main.scalar_first) - _::Core.Const(Val{Nothing}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - selection::PythonCall.Convert.PyConvertSelection - ctx::PyConvertContext{Tuple{}} - @_9::Int64 - @_10::ANY -Body::ANY -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ Core.NewvarNode(:(selection)) -│ Core.NewvarNode(:(ctx)) -│ %6 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %6 -2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%8)()) -│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %13 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ %14 = Main.PythonCall::Core.Const(PythonCall) -│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) -│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%11)(%12, %13, %17)) -│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %22 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ %23 = selection::PythonCall.Convert.PyConvertSelection -│ %24 = (%20)(%21, %22, x, %23)::ANY -└── return %24 -3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%26)()) -│ %28 = task::Task -│ (state = (PythonCall.C.current_task_state)(%28)) -│ %30 = task::Task -│ %31 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%30, %31)) -4 ─ %33 = enter #7 -5 ─ (@_9 = -1) -│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%35)()) -│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %40 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ %41 = Main.PythonCall::Core.Const(PythonCall) -│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) -│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%38)(%39, %40, %44)) -│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %49 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ %50 = selection::PythonCall.Convert.PyConvertSelection -│ %51 = (%47)(%48, %49, x, %50)::ANY -│ (@_10 = %51) -│ (@_9 = 1) -└── $(Expr(:leave, :(%33))) -6 ─ goto #8 -7 ┄ %56 = task::Task -│ %57 = state::PythonCall.C.TaskState -│ %58 = token::Symbol -│ (PythonCall.C.exit_region)(%56, %57, %58) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%33))))) -└── Core.Const(:(return nothing)) -8 ┄ %63 = task::Task -│ %64 = state::PythonCall.C.TaskState -│ %65 = token::Symbol -│ (PythonCall.C.exit_region)(%63, %64, %65) -│ %67 = @_10::ANY -└── return %67 diff --git a/benchmark/convert-scalars-before.tsv b/benchmark/convert-scalars-before.tsv deleted file mode 100644 index 8f502c50f..000000000 --- a/benchmark/convert-scalars-before.tsv +++ /dev/null @@ -1,25 +0,0 @@ -case path min_ns median_ns bytes allocs -int dynamic 364.7294685990338 367.6328502415459 0 0 -int typed 238.51604938271606 245.18271604938272 0 0 -int discard 247.4227642276423 254.739837398374 0 0 -int try 238.69095477386935 245.4748743718593 0 0 -int plain 235.38584474885846 242.9200913242009 0 0 -int first 235.8951048951049 255.7086247086247 0 0 -float dynamic 372.33009708737865 380.09708737864077 32 2 -float typed 251.4878048780488 272.8970189701897 16 1 -float discard 254.54261363636363 255.9659090909091 16 1 -float try 243.81451612903226 250.80376344086022 16 1 -float plain 248.66755319148936 249.99734042553192 16 1 -float first 242.89027431421445 249.37655860349128 16 1 -bigint dynamic 1220.0 1300.0 232 8 -bigint typed 1060.0 1130.0 232 8 -bigint discard 1049.9 1100.0 232 8 -bigint try 1040.0 1110.0 248 9 -bigint plain 1009.9 1069.9 232 8 -bigint first 1021.4285714285714 1135.7142857142858 232 8 -none dynamic 341.73853211009174 370.63761467889907 0 0 -none typed 235.84246575342465 255.7054794520548 0 0 -none discard 236.07077625570776 242.9200913242009 0 0 -none try 235.3846153846154 236.26153846153846 0 0 -none plain 230.54725274725274 237.14065934065934 0 0 -none first 219.44820295983087 226.00211416490487 0 0 diff --git a/benchmark/convert-scalars-final-allocations.txt b/benchmark/convert-scalars-final-allocations.txt deleted file mode 100644 index 33cf76cd7..000000000 --- a/benchmark/convert-scalars-final-allocations.txt +++ /dev/null @@ -1,113 +0,0 @@ - -int - -float -Float64: 16 bytes - (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 - eval(m::Module, e::Any) at boot.jl:489 - -bigint -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at Py.jl:109 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at Py.jl:103 [inlined] - macro expansion at regions.jl:296 [inlined] - pyint(x::Py) at builtins.jl:689 - macro expansion at rules.jl:97 [inlined] - macro expansion at regions.jl:296 [inlined] - pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 - pyconvert_first at pyconvert.jl:305 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] - scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 - (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 - eval(m::Module, e::Any) at boot.jl:489 -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at regions.jl:296 [inlined] - pystr(x::Py) at builtins.jl:592 - pystr at builtins.jl:598 [inlined] - macro expansion at rules.jl:98 [inlined] - macro expansion at regions.jl:296 [inlined] - pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 - pyconvert_first at pyconvert.jl:305 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] - scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 - (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 - eval(m::Module, e::Any) at boot.jl:489 -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at regions.jl:296 [inlined] - pystr_asUTF8bytes(x::Py) at builtins.jl:600 - pystr_asstring(x::Py) at builtins.jl:603 - pystr at builtins.jl:598 [inlined] - macro expansion at rules.jl:98 [inlined] - macro expansion at regions.jl:296 [inlined] - pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 - pyconvert_first at pyconvert.jl:305 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] - scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 - (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 - eval(m::Module, e::Any) at boot.jl:489 -String: 70 bytes - pybytes_asUTF8string at builtins.jl:654 [inlined] - pystr_asstring(x::Py) at builtins.jl:604 - pystr at builtins.jl:598 [inlined] - macro expansion at rules.jl:98 [inlined] - macro expansion at regions.jl:296 [inlined] - pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 - pyconvert_first at pyconvert.jl:305 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] - scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 - (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 - eval(m::Module, e::Any) at boot.jl:489 -BigInt: 32 bytes - _ at gmp.jl:70 [inlined] - BigInt at gmp.jl:69 [inlined] - tryparse_internal(::Type{BigInt}, s::String, startpos::Int64, endpos::Int64, base_::Int64, raise::Bool) at gmp.jl:302 - macro expansion at rules.jl:100 [inlined] - macro expansion at regions.jl:296 [inlined] - pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 - pyconvert_first at pyconvert.jl:305 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] - scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 - (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 - eval(m::Module, e::Any) at boot.jl:489 - -none diff --git a/benchmark/convert-scalars-final-inference.txt b/benchmark/convert-scalars-final-inference.txt deleted file mode 100644 index ec78abe6f..000000000 --- a/benchmark/convert-scalars-final-inference.txt +++ /dev/null @@ -1,663 +0,0 @@ - -int: scalar_convert -MethodInstance for scalar_convert(::Val{Int64}, ::Py) - from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 -Static Parameters - T = Int64 -Arguments - #self#::Core.Const(Main.scalar_convert) - _::Core.Const(Val{Int64}()) - x::Py -Body::UNION{NOTHING, INT64} -1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) -│ %2 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ %3 = Main.nothing::Core.Const(nothing) -│ %4 = (%1)(%2, x, %3)::UNION{NOTHING, INT64} -└── return %4 - - -int: scalar_plain -MethodInstance for scalar_plain(::Val{Int64}, ::Py) - from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 -Static Parameters - T = Int64 -Arguments - #self#::Core.Const(Main.scalar_plain) - _::Core.Const(Val{Int64}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - @_7::Int64 - @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} -Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ %4 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %4 -2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %10 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ %11 = (%7)(%9, %10, x)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} -└── return %11 -3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%13)()) -│ %15 = task::Task -│ (state = (PythonCall.C.current_task_state)(%15)) -│ %17 = task::Task -│ %18 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%17, %18)) -4 ─ %20 = enter #7 -5 ─ (@_7 = -1) -│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %26 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ (@_8 = (%23)(%25, %26, x)) -│ (@_7 = 1) -└── $(Expr(:leave, :(%20))) -6 ─ goto #8 -7 ┄ %31 = task::Task -│ %32 = state::PythonCall.C.TaskState -│ %33 = token::Symbol -│ (PythonCall.C.exit_region)(%31, %32, %33) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%20))))) -└── Core.Const(:(return nothing)) -8 ┄ %38 = task::Task -│ %39 = state::PythonCall.C.TaskState -│ %40 = token::Symbol -│ (PythonCall.C.exit_region)(%38, %39, %40) -│ %42 = @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} -└── return %42 - - -int: scalar_first -MethodInstance for scalar_first(::Val{Int64}, ::Py) - from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 -Static Parameters - T = Int64 -Arguments - #self#::Core.Const(Main.scalar_first) - _::Core.Const(Val{Int64}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - selection::PythonCall.Convert.PyConvertSelection - ctx::PyConvertContext{Tuple{}} - @_9::Int64 - @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} -Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ Core.NewvarNode(:(selection)) -│ Core.NewvarNode(:(ctx)) -│ %6 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %6 -2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%8)()) -│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %13 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ %14 = Main.PythonCall::Core.Const(PythonCall) -│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) -│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%11)(%12, %13, %17)) -│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %22 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ %23 = selection::PythonCall.Convert.PyConvertSelection -│ %24 = (%20)(%21, %22, x, %23)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} -└── return %24 -3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%26)()) -│ %28 = task::Task -│ (state = (PythonCall.C.current_task_state)(%28)) -│ %30 = task::Task -│ %31 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%30, %31)) -4 ─ %33 = enter #7 -5 ─ (@_9 = -1) -│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%35)()) -│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %40 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ %41 = Main.PythonCall::Core.Const(PythonCall) -│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) -│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%38)(%39, %40, %44)) -│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %49 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ %50 = selection::PythonCall.Convert.PyConvertSelection -│ %51 = (%47)(%48, %49, x, %50)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} -│ (@_10 = %51) -│ (@_9 = 1) -└── $(Expr(:leave, :(%33))) -6 ─ goto #8 -7 ┄ %56 = task::Task -│ %57 = state::PythonCall.C.TaskState -│ %58 = token::Symbol -│ (PythonCall.C.exit_region)(%56, %57, %58) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%33))))) -└── Core.Const(:(return nothing)) -8 ┄ %63 = task::Task -│ %64 = state::PythonCall.C.TaskState -│ %65 = token::Symbol -│ (PythonCall.C.exit_region)(%63, %64, %65) -│ %67 = @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} -└── return %67 - - -float: scalar_convert -MethodInstance for scalar_convert(::Val{Float64}, ::Py) - from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 -Static Parameters - T = Float64 -Arguments - #self#::Core.Const(Main.scalar_convert) - _::Core.Const(Val{Float64}()) - x::Py -Body::UNION{NOTHING, FLOAT64} -1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) -│ %2 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ %3 = Main.nothing::Core.Const(nothing) -│ %4 = (%1)(%2, x, %3)::UNION{NOTHING, FLOAT64} -└── return %4 - - -float: scalar_plain -MethodInstance for scalar_plain(::Val{Float64}, ::Py) - from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 -Static Parameters - T = Float64 -Arguments - #self#::Core.Const(Main.scalar_plain) - _::Core.Const(Val{Float64}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - @_7::Int64 - @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} -Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ %4 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %4 -2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %10 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ %11 = (%7)(%9, %10, x)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} -└── return %11 -3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%13)()) -│ %15 = task::Task -│ (state = (PythonCall.C.current_task_state)(%15)) -│ %17 = task::Task -│ %18 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%17, %18)) -4 ─ %20 = enter #7 -5 ─ (@_7 = -1) -│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %26 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ (@_8 = (%23)(%25, %26, x)) -│ (@_7 = 1) -└── $(Expr(:leave, :(%20))) -6 ─ goto #8 -7 ┄ %31 = task::Task -│ %32 = state::PythonCall.C.TaskState -│ %33 = token::Symbol -│ (PythonCall.C.exit_region)(%31, %32, %33) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%20))))) -└── Core.Const(:(return nothing)) -8 ┄ %38 = task::Task -│ %39 = state::PythonCall.C.TaskState -│ %40 = token::Symbol -│ (PythonCall.C.exit_region)(%38, %39, %40) -│ %42 = @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} -└── return %42 - - -float: scalar_first -MethodInstance for scalar_first(::Val{Float64}, ::Py) - from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 -Static Parameters - T = Float64 -Arguments - #self#::Core.Const(Main.scalar_first) - _::Core.Const(Val{Float64}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - selection::PythonCall.Convert.PyConvertSelection - ctx::PyConvertContext{Tuple{}} - @_9::Int64 - @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} -Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ Core.NewvarNode(:(selection)) -│ Core.NewvarNode(:(ctx)) -│ %6 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %6 -2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%8)()) -│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %13 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ %14 = Main.PythonCall::Core.Const(PythonCall) -│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) -│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%11)(%12, %13, %17)) -│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %22 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ %23 = selection::PythonCall.Convert.PyConvertSelection -│ %24 = (%20)(%21, %22, x, %23)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} -└── return %24 -3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%26)()) -│ %28 = task::Task -│ (state = (PythonCall.C.current_task_state)(%28)) -│ %30 = task::Task -│ %31 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%30, %31)) -4 ─ %33 = enter #7 -5 ─ (@_9 = -1) -│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%35)()) -│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %40 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ %41 = Main.PythonCall::Core.Const(PythonCall) -│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) -│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%38)(%39, %40, %44)) -│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %49 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ %50 = selection::PythonCall.Convert.PyConvertSelection -│ %51 = (%47)(%48, %49, x, %50)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} -│ (@_10 = %51) -│ (@_9 = 1) -└── $(Expr(:leave, :(%33))) -6 ─ goto #8 -7 ┄ %56 = task::Task -│ %57 = state::PythonCall.C.TaskState -│ %58 = token::Symbol -│ (PythonCall.C.exit_region)(%56, %57, %58) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%33))))) -└── Core.Const(:(return nothing)) -8 ┄ %63 = task::Task -│ %64 = state::PythonCall.C.TaskState -│ %65 = token::Symbol -│ (PythonCall.C.exit_region)(%63, %64, %65) -│ %67 = @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} -└── return %67 - - -bigint: scalar_convert -MethodInstance for scalar_convert(::Val{BigInt}, ::Py) - from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 -Static Parameters - T = BigInt -Arguments - #self#::Core.Const(Main.scalar_convert) - _::Core.Const(Val{BigInt}()) - x::Py -Body::UNION{NOTHING, BIGINT} -1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) -│ %2 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ %3 = Main.nothing::Core.Const(nothing) -│ %4 = (%1)(%2, x, %3)::UNION{NOTHING, BIGINT} -└── return %4 - - -bigint: scalar_plain -MethodInstance for scalar_plain(::Val{BigInt}, ::Py) - from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 -Static Parameters - T = BigInt -Arguments - #self#::Core.Const(Main.scalar_plain) - _::Core.Const(Val{BigInt}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - @_7::Int64 - @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} -Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ %4 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %4 -2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %10 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ %11 = (%7)(%9, %10, x)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} -└── return %11 -3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%13)()) -│ %15 = task::Task -│ (state = (PythonCall.C.current_task_state)(%15)) -│ %17 = task::Task -│ %18 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%17, %18)) -4 ─ %20 = enter #7 -5 ─ (@_7 = -1) -│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %26 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ (@_8 = (%23)(%25, %26, x)) -│ (@_7 = 1) -└── $(Expr(:leave, :(%20))) -6 ─ goto #8 -7 ┄ %31 = task::Task -│ %32 = state::PythonCall.C.TaskState -│ %33 = token::Symbol -│ (PythonCall.C.exit_region)(%31, %32, %33) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%20))))) -└── Core.Const(:(return nothing)) -8 ┄ %38 = task::Task -│ %39 = state::PythonCall.C.TaskState -│ %40 = token::Symbol -│ (PythonCall.C.exit_region)(%38, %39, %40) -│ %42 = @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} -└── return %42 - - -bigint: scalar_first -MethodInstance for scalar_first(::Val{BigInt}, ::Py) - from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 -Static Parameters - T = BigInt -Arguments - #self#::Core.Const(Main.scalar_first) - _::Core.Const(Val{BigInt}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - selection::PythonCall.Convert.PyConvertSelection - ctx::PyConvertContext{Tuple{}} - @_9::Int64 - @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} -Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ Core.NewvarNode(:(selection)) -│ Core.NewvarNode(:(ctx)) -│ %6 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %6 -2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%8)()) -│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %13 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ %14 = Main.PythonCall::Core.Const(PythonCall) -│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) -│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%11)(%12, %13, %17)) -│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %22 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ %23 = selection::PythonCall.Convert.PyConvertSelection -│ %24 = (%20)(%21, %22, x, %23)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} -└── return %24 -3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%26)()) -│ %28 = task::Task -│ (state = (PythonCall.C.current_task_state)(%28)) -│ %30 = task::Task -│ %31 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%30, %31)) -4 ─ %33 = enter #7 -5 ─ (@_9 = -1) -│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%35)()) -│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %40 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ %41 = Main.PythonCall::Core.Const(PythonCall) -│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) -│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%38)(%39, %40, %44)) -│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %49 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ %50 = selection::PythonCall.Convert.PyConvertSelection -│ %51 = (%47)(%48, %49, x, %50)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} -│ (@_10 = %51) -│ (@_9 = 1) -└── $(Expr(:leave, :(%33))) -6 ─ goto #8 -7 ┄ %56 = task::Task -│ %57 = state::PythonCall.C.TaskState -│ %58 = token::Symbol -│ (PythonCall.C.exit_region)(%56, %57, %58) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%33))))) -└── Core.Const(:(return nothing)) -8 ┄ %63 = task::Task -│ %64 = state::PythonCall.C.TaskState -│ %65 = token::Symbol -│ (PythonCall.C.exit_region)(%63, %64, %65) -│ %67 = @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} -└── return %67 - - -none: scalar_convert -MethodInstance for scalar_convert(::Val{Nothing}, ::Py) - from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 -Static Parameters - T = Nothing -Arguments - #self#::Core.Const(Main.scalar_convert) - _::Core.Const(Val{Nothing}()) - x::Py -Body::Nothing -1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) -│ %2 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ %3 = Main.nothing::Core.Const(nothing) -│ %4 = (%1)(%2, x, %3)::Core.Const(nothing) -└── return %4 - - -none: scalar_plain -MethodInstance for scalar_plain(::Val{Nothing}, ::Py) - from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 -Static Parameters - T = Nothing -Arguments - #self#::Core.Const(Main.scalar_plain) - _::Core.Const(Val{Nothing}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - @_7::Int64 - @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} -Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ %4 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %4 -2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %10 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ %11 = (%7)(%9, %10, x)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} -└── return %11 -3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%13)()) -│ %15 = task::Task -│ (state = (PythonCall.C.current_task_state)(%15)) -│ %17 = task::Task -│ %18 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%17, %18)) -4 ─ %20 = enter #7 -5 ─ (@_7 = -1) -│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %26 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ (@_8 = (%23)(%25, %26, x)) -│ (@_7 = 1) -└── $(Expr(:leave, :(%20))) -6 ─ goto #8 -7 ┄ %31 = task::Task -│ %32 = state::PythonCall.C.TaskState -│ %33 = token::Symbol -│ (PythonCall.C.exit_region)(%31, %32, %33) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%20))))) -└── Core.Const(:(return nothing)) -8 ┄ %38 = task::Task -│ %39 = state::PythonCall.C.TaskState -│ %40 = token::Symbol -│ (PythonCall.C.exit_region)(%38, %39, %40) -│ %42 = @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} -└── return %42 - - -none: scalar_first -MethodInstance for scalar_first(::Val{Nothing}, ::Py) - from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 -Static Parameters - T = Nothing -Arguments - #self#::Core.Const(Main.scalar_first) - _::Core.Const(Val{Nothing}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - selection::PythonCall.Convert.PyConvertSelection - ctx::PyConvertContext{Tuple{}} - @_9::Int64 - @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} -Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ Core.NewvarNode(:(selection)) -│ Core.NewvarNode(:(ctx)) -│ %6 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %6 -2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%8)()) -│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %13 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ %14 = Main.PythonCall::Core.Const(PythonCall) -│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) -│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%11)(%12, %13, %17)) -│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %22 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ %23 = selection::PythonCall.Convert.PyConvertSelection -│ %24 = (%20)(%21, %22, x, %23)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} -└── return %24 -3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%26)()) -│ %28 = task::Task -│ (state = (PythonCall.C.current_task_state)(%28)) -│ %30 = task::Task -│ %31 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%30, %31)) -4 ─ %33 = enter #7 -5 ─ (@_9 = -1) -│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%35)()) -│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %40 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ %41 = Main.PythonCall::Core.Const(PythonCall) -│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) -│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%38)(%39, %40, %44)) -│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %49 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ %50 = selection::PythonCall.Convert.PyConvertSelection -│ %51 = (%47)(%48, %49, x, %50)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} -│ (@_10 = %51) -│ (@_9 = 1) -└── $(Expr(:leave, :(%33))) -6 ─ goto #8 -7 ┄ %56 = task::Task -│ %57 = state::PythonCall.C.TaskState -│ %58 = token::Symbol -│ (PythonCall.C.exit_region)(%56, %57, %58) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%33))))) -└── Core.Const(:(return nothing)) -8 ┄ %63 = task::Task -│ %64 = state::PythonCall.C.TaskState -│ %65 = token::Symbol -│ (PythonCall.C.exit_region)(%63, %64, %65) -│ %67 = @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} -└── return %67 diff --git a/benchmark/convert-scalars-final-repeat.tsv b/benchmark/convert-scalars-final-repeat.tsv deleted file mode 100644 index e3ed91c32..000000000 --- a/benchmark/convert-scalars-final-repeat.tsv +++ /dev/null @@ -1,16 +0,0 @@ -round case min_ns median_ns bytes allocs -1 int 249.9974358974359 294.35641025641024 0 0 -1 float 250.91717791411043 295.0920245398773 0 0 -1 bigint 1059.95 1140.0 216 7 -1 none 230.32747252747254 271.4263736263736 0 0 -1 int_large 249.60574412532637 256.9190600522193 0 0 -2 int_large 249.5016501650165 286.1353135313531 0 0 -2 int 243.4543209876543 250.12345679012347 0 0 -2 float 251.1723237597911 295.5613577023499 0 0 -2 bigint 928.5238095238095 1000.0 216 7 -2 none 242.04275534441805 256.29216152019 0 0 -3 none 230.07090464547676 236.4278728606357 0 0 -3 int_large 243.60052219321148 286.42036553524804 0 0 -3 int 249.54109589041096 250.4543378995434 0 0 -3 float 250.39313984168865 258.30870712401054 0 0 -3 bigint 947.6190476190476 985.7142857142857 216 7 diff --git a/benchmark/convert-scalars-final.tsv b/benchmark/convert-scalars-final.tsv deleted file mode 100644 index f932458a8..000000000 --- a/benchmark/convert-scalars-final.tsv +++ /dev/null @@ -1,25 +0,0 @@ -case path min_ns median_ns bytes allocs -int dynamic 352.6018957345972 404.2654028436019 0 0 -int typed 239.70702179176754 274.3317191283293 0 0 -int discard 240.91767554479418 268.2784503631961 0 0 -int try 237.2123287671233 243.83333333333334 0 0 -int plain 249.88111888111888 279.4848484848485 0 0 -int first 264.25113122171945 280.31447963800906 0 0 -float dynamic 351.1961722488038 384.688995215311 16 1 -float typed 239.85780885780886 271.09324009324007 0 0 -float discard 241.25641025641025 258.97202797202794 0 0 -float try 238.8575129533679 286.0077720207254 0 0 -float plain 266.559375 294.059375 0 0 -float first 264.8909574468085 284.0398936170213 0 0 -bigint dynamic 1219.9 1299.9 216 7 -bigint typed 943.4347826086956 1056.5217391304348 216 7 -bigint discard 991.304347826087 1060.8260869565217 216 7 -bigint try 943.3 973.3333333333334 232 8 -bigint plain 1005.2631578947369 1052.6315789473683 216 7 -bigint first 1037.4583333333333 1183.2916666666667 216 7 -none dynamic 389.4688995215311 412.4354066985646 0 0 -none typed 253.87899543378995 261.64383561643837 0 0 -none discard 228.47608695652173 229.12826086956522 0 0 -none try 228.44612068965517 247.41163793103448 0 0 -none plain 229.40941176470588 255.52941176470588 0 0 -none first 225.49667405764967 226.60532150776052 0 0 diff --git a/benchmark/convert-scalars-optimized-allocations.txt b/benchmark/convert-scalars-optimized-allocations.txt deleted file mode 100644 index 9d2a3f600..000000000 --- a/benchmark/convert-scalars-optimized-allocations.txt +++ /dev/null @@ -1,113 +0,0 @@ - -int - -float -Float64: 16 bytes - (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 - eval(m::Module, e::Any) at boot.jl:489 - -bigint -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:51 [inlined] - pynew at Py.jl:55 [inlined] - macro expansion at Py.jl:108 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at Py.jl:102 [inlined] - macro expansion at regions.jl:296 [inlined] - pyint(x::Py) at builtins.jl:689 - macro expansion at rules.jl:97 [inlined] - macro expansion at regions.jl:296 [inlined] - pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 - pyconvert_first at pyconvert.jl:288 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:305 - pytryconvert_raw at pyconvert.jl:324 [inlined] - macro expansion at pyconvert.jl:400 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:399 - #pyconvert#36 at pyconvert.jl:405 [inlined] - pyconvert at pyconvert.jl:405 [inlined] - scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 - (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 - eval(m::Module, e::Any) at boot.jl:489 -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:51 [inlined] - pynew at Py.jl:55 [inlined] - macro expansion at regions.jl:296 [inlined] - pystr(x::Py) at builtins.jl:592 - pystr at builtins.jl:598 [inlined] - macro expansion at rules.jl:98 [inlined] - macro expansion at regions.jl:296 [inlined] - pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 - pyconvert_first at pyconvert.jl:288 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:305 - pytryconvert_raw at pyconvert.jl:324 [inlined] - macro expansion at pyconvert.jl:400 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:399 - #pyconvert#36 at pyconvert.jl:405 [inlined] - pyconvert at pyconvert.jl:405 [inlined] - scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 - (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 - eval(m::Module, e::Any) at boot.jl:489 -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:51 [inlined] - pynew at Py.jl:55 [inlined] - macro expansion at regions.jl:296 [inlined] - pystr_asUTF8bytes(x::Py) at builtins.jl:600 - pystr_asstring(x::Py) at builtins.jl:603 - pystr at builtins.jl:598 [inlined] - macro expansion at rules.jl:98 [inlined] - macro expansion at regions.jl:296 [inlined] - pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 - pyconvert_first at pyconvert.jl:288 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:305 - pytryconvert_raw at pyconvert.jl:324 [inlined] - macro expansion at pyconvert.jl:400 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:399 - #pyconvert#36 at pyconvert.jl:405 [inlined] - pyconvert at pyconvert.jl:405 [inlined] - scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 - (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 - eval(m::Module, e::Any) at boot.jl:489 -String: 70 bytes - pybytes_asUTF8string at builtins.jl:654 [inlined] - pystr_asstring(x::Py) at builtins.jl:604 - pystr at builtins.jl:598 [inlined] - macro expansion at rules.jl:98 [inlined] - macro expansion at regions.jl:296 [inlined] - pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 - pyconvert_first at pyconvert.jl:288 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:305 - pytryconvert_raw at pyconvert.jl:324 [inlined] - macro expansion at pyconvert.jl:400 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:399 - #pyconvert#36 at pyconvert.jl:405 [inlined] - pyconvert at pyconvert.jl:405 [inlined] - scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 - (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 - eval(m::Module, e::Any) at boot.jl:489 -BigInt: 32 bytes - _ at gmp.jl:70 [inlined] - BigInt at gmp.jl:69 [inlined] - tryparse_internal(::Type{BigInt}, s::String, startpos::Int64, endpos::Int64, base_::Int64, raise::Bool) at gmp.jl:302 - macro expansion at rules.jl:100 [inlined] - macro expansion at regions.jl:296 [inlined] - pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 - pyconvert_first at pyconvert.jl:288 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:305 - pytryconvert_raw at pyconvert.jl:324 [inlined] - macro expansion at pyconvert.jl:400 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:399 - #pyconvert#36 at pyconvert.jl:405 [inlined] - pyconvert at pyconvert.jl:405 [inlined] - scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 - (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 - eval(m::Module, e::Any) at boot.jl:489 - -none diff --git a/benchmark/convert-scalars-optimized-inference.txt b/benchmark/convert-scalars-optimized-inference.txt deleted file mode 100644 index ec78abe6f..000000000 --- a/benchmark/convert-scalars-optimized-inference.txt +++ /dev/null @@ -1,663 +0,0 @@ - -int: scalar_convert -MethodInstance for scalar_convert(::Val{Int64}, ::Py) - from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 -Static Parameters - T = Int64 -Arguments - #self#::Core.Const(Main.scalar_convert) - _::Core.Const(Val{Int64}()) - x::Py -Body::UNION{NOTHING, INT64} -1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) -│ %2 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ %3 = Main.nothing::Core.Const(nothing) -│ %4 = (%1)(%2, x, %3)::UNION{NOTHING, INT64} -└── return %4 - - -int: scalar_plain -MethodInstance for scalar_plain(::Val{Int64}, ::Py) - from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 -Static Parameters - T = Int64 -Arguments - #self#::Core.Const(Main.scalar_plain) - _::Core.Const(Val{Int64}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - @_7::Int64 - @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} -Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ %4 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %4 -2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %10 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ %11 = (%7)(%9, %10, x)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} -└── return %11 -3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%13)()) -│ %15 = task::Task -│ (state = (PythonCall.C.current_task_state)(%15)) -│ %17 = task::Task -│ %18 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%17, %18)) -4 ─ %20 = enter #7 -5 ─ (@_7 = -1) -│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %26 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ (@_8 = (%23)(%25, %26, x)) -│ (@_7 = 1) -└── $(Expr(:leave, :(%20))) -6 ─ goto #8 -7 ┄ %31 = task::Task -│ %32 = state::PythonCall.C.TaskState -│ %33 = token::Symbol -│ (PythonCall.C.exit_region)(%31, %32, %33) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%20))))) -└── Core.Const(:(return nothing)) -8 ┄ %38 = task::Task -│ %39 = state::PythonCall.C.TaskState -│ %40 = token::Symbol -│ (PythonCall.C.exit_region)(%38, %39, %40) -│ %42 = @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} -└── return %42 - - -int: scalar_first -MethodInstance for scalar_first(::Val{Int64}, ::Py) - from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 -Static Parameters - T = Int64 -Arguments - #self#::Core.Const(Main.scalar_first) - _::Core.Const(Val{Int64}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - selection::PythonCall.Convert.PyConvertSelection - ctx::PyConvertContext{Tuple{}} - @_9::Int64 - @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} -Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ Core.NewvarNode(:(selection)) -│ Core.NewvarNode(:(ctx)) -│ %6 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %6 -2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%8)()) -│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %13 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ %14 = Main.PythonCall::Core.Const(PythonCall) -│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) -│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%11)(%12, %13, %17)) -│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %22 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ %23 = selection::PythonCall.Convert.PyConvertSelection -│ %24 = (%20)(%21, %22, x, %23)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} -└── return %24 -3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%26)()) -│ %28 = task::Task -│ (state = (PythonCall.C.current_task_state)(%28)) -│ %30 = task::Task -│ %31 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%30, %31)) -4 ─ %33 = enter #7 -5 ─ (@_9 = -1) -│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%35)()) -│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %40 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ %41 = Main.PythonCall::Core.Const(PythonCall) -│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) -│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%38)(%39, %40, %44)) -│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %49 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ %50 = selection::PythonCall.Convert.PyConvertSelection -│ %51 = (%47)(%48, %49, x, %50)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} -│ (@_10 = %51) -│ (@_9 = 1) -└── $(Expr(:leave, :(%33))) -6 ─ goto #8 -7 ┄ %56 = task::Task -│ %57 = state::PythonCall.C.TaskState -│ %58 = token::Symbol -│ (PythonCall.C.exit_region)(%56, %57, %58) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%33))))) -└── Core.Const(:(return nothing)) -8 ┄ %63 = task::Task -│ %64 = state::PythonCall.C.TaskState -│ %65 = token::Symbol -│ (PythonCall.C.exit_region)(%63, %64, %65) -│ %67 = @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} -└── return %67 - - -float: scalar_convert -MethodInstance for scalar_convert(::Val{Float64}, ::Py) - from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 -Static Parameters - T = Float64 -Arguments - #self#::Core.Const(Main.scalar_convert) - _::Core.Const(Val{Float64}()) - x::Py -Body::UNION{NOTHING, FLOAT64} -1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) -│ %2 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ %3 = Main.nothing::Core.Const(nothing) -│ %4 = (%1)(%2, x, %3)::UNION{NOTHING, FLOAT64} -└── return %4 - - -float: scalar_plain -MethodInstance for scalar_plain(::Val{Float64}, ::Py) - from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 -Static Parameters - T = Float64 -Arguments - #self#::Core.Const(Main.scalar_plain) - _::Core.Const(Val{Float64}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - @_7::Int64 - @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} -Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ %4 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %4 -2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %10 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ %11 = (%7)(%9, %10, x)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} -└── return %11 -3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%13)()) -│ %15 = task::Task -│ (state = (PythonCall.C.current_task_state)(%15)) -│ %17 = task::Task -│ %18 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%17, %18)) -4 ─ %20 = enter #7 -5 ─ (@_7 = -1) -│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %26 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ (@_8 = (%23)(%25, %26, x)) -│ (@_7 = 1) -└── $(Expr(:leave, :(%20))) -6 ─ goto #8 -7 ┄ %31 = task::Task -│ %32 = state::PythonCall.C.TaskState -│ %33 = token::Symbol -│ (PythonCall.C.exit_region)(%31, %32, %33) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%20))))) -└── Core.Const(:(return nothing)) -8 ┄ %38 = task::Task -│ %39 = state::PythonCall.C.TaskState -│ %40 = token::Symbol -│ (PythonCall.C.exit_region)(%38, %39, %40) -│ %42 = @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} -└── return %42 - - -float: scalar_first -MethodInstance for scalar_first(::Val{Float64}, ::Py) - from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 -Static Parameters - T = Float64 -Arguments - #self#::Core.Const(Main.scalar_first) - _::Core.Const(Val{Float64}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - selection::PythonCall.Convert.PyConvertSelection - ctx::PyConvertContext{Tuple{}} - @_9::Int64 - @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} -Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ Core.NewvarNode(:(selection)) -│ Core.NewvarNode(:(ctx)) -│ %6 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %6 -2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%8)()) -│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %13 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ %14 = Main.PythonCall::Core.Const(PythonCall) -│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) -│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%11)(%12, %13, %17)) -│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %22 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ %23 = selection::PythonCall.Convert.PyConvertSelection -│ %24 = (%20)(%21, %22, x, %23)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} -└── return %24 -3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%26)()) -│ %28 = task::Task -│ (state = (PythonCall.C.current_task_state)(%28)) -│ %30 = task::Task -│ %31 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%30, %31)) -4 ─ %33 = enter #7 -5 ─ (@_9 = -1) -│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%35)()) -│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %40 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ %41 = Main.PythonCall::Core.Const(PythonCall) -│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) -│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%38)(%39, %40, %44)) -│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %49 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ %50 = selection::PythonCall.Convert.PyConvertSelection -│ %51 = (%47)(%48, %49, x, %50)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} -│ (@_10 = %51) -│ (@_9 = 1) -└── $(Expr(:leave, :(%33))) -6 ─ goto #8 -7 ┄ %56 = task::Task -│ %57 = state::PythonCall.C.TaskState -│ %58 = token::Symbol -│ (PythonCall.C.exit_region)(%56, %57, %58) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%33))))) -└── Core.Const(:(return nothing)) -8 ┄ %63 = task::Task -│ %64 = state::PythonCall.C.TaskState -│ %65 = token::Symbol -│ (PythonCall.C.exit_region)(%63, %64, %65) -│ %67 = @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} -└── return %67 - - -bigint: scalar_convert -MethodInstance for scalar_convert(::Val{BigInt}, ::Py) - from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 -Static Parameters - T = BigInt -Arguments - #self#::Core.Const(Main.scalar_convert) - _::Core.Const(Val{BigInt}()) - x::Py -Body::UNION{NOTHING, BIGINT} -1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) -│ %2 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ %3 = Main.nothing::Core.Const(nothing) -│ %4 = (%1)(%2, x, %3)::UNION{NOTHING, BIGINT} -└── return %4 - - -bigint: scalar_plain -MethodInstance for scalar_plain(::Val{BigInt}, ::Py) - from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 -Static Parameters - T = BigInt -Arguments - #self#::Core.Const(Main.scalar_plain) - _::Core.Const(Val{BigInt}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - @_7::Int64 - @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} -Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ %4 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %4 -2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %10 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ %11 = (%7)(%9, %10, x)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} -└── return %11 -3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%13)()) -│ %15 = task::Task -│ (state = (PythonCall.C.current_task_state)(%15)) -│ %17 = task::Task -│ %18 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%17, %18)) -4 ─ %20 = enter #7 -5 ─ (@_7 = -1) -│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %26 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ (@_8 = (%23)(%25, %26, x)) -│ (@_7 = 1) -└── $(Expr(:leave, :(%20))) -6 ─ goto #8 -7 ┄ %31 = task::Task -│ %32 = state::PythonCall.C.TaskState -│ %33 = token::Symbol -│ (PythonCall.C.exit_region)(%31, %32, %33) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%20))))) -└── Core.Const(:(return nothing)) -8 ┄ %38 = task::Task -│ %39 = state::PythonCall.C.TaskState -│ %40 = token::Symbol -│ (PythonCall.C.exit_region)(%38, %39, %40) -│ %42 = @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} -└── return %42 - - -bigint: scalar_first -MethodInstance for scalar_first(::Val{BigInt}, ::Py) - from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 -Static Parameters - T = BigInt -Arguments - #self#::Core.Const(Main.scalar_first) - _::Core.Const(Val{BigInt}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - selection::PythonCall.Convert.PyConvertSelection - ctx::PyConvertContext{Tuple{}} - @_9::Int64 - @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} -Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ Core.NewvarNode(:(selection)) -│ Core.NewvarNode(:(ctx)) -│ %6 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %6 -2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%8)()) -│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %13 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ %14 = Main.PythonCall::Core.Const(PythonCall) -│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) -│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%11)(%12, %13, %17)) -│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %22 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ %23 = selection::PythonCall.Convert.PyConvertSelection -│ %24 = (%20)(%21, %22, x, %23)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} -└── return %24 -3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%26)()) -│ %28 = task::Task -│ (state = (PythonCall.C.current_task_state)(%28)) -│ %30 = task::Task -│ %31 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%30, %31)) -4 ─ %33 = enter #7 -5 ─ (@_9 = -1) -│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%35)()) -│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %40 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ %41 = Main.PythonCall::Core.Const(PythonCall) -│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) -│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%38)(%39, %40, %44)) -│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %49 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ %50 = selection::PythonCall.Convert.PyConvertSelection -│ %51 = (%47)(%48, %49, x, %50)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} -│ (@_10 = %51) -│ (@_9 = 1) -└── $(Expr(:leave, :(%33))) -6 ─ goto #8 -7 ┄ %56 = task::Task -│ %57 = state::PythonCall.C.TaskState -│ %58 = token::Symbol -│ (PythonCall.C.exit_region)(%56, %57, %58) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%33))))) -└── Core.Const(:(return nothing)) -8 ┄ %63 = task::Task -│ %64 = state::PythonCall.C.TaskState -│ %65 = token::Symbol -│ (PythonCall.C.exit_region)(%63, %64, %65) -│ %67 = @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} -└── return %67 - - -none: scalar_convert -MethodInstance for scalar_convert(::Val{Nothing}, ::Py) - from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 -Static Parameters - T = Nothing -Arguments - #self#::Core.Const(Main.scalar_convert) - _::Core.Const(Val{Nothing}()) - x::Py -Body::Nothing -1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) -│ %2 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ %3 = Main.nothing::Core.Const(nothing) -│ %4 = (%1)(%2, x, %3)::Core.Const(nothing) -└── return %4 - - -none: scalar_plain -MethodInstance for scalar_plain(::Val{Nothing}, ::Py) - from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 -Static Parameters - T = Nothing -Arguments - #self#::Core.Const(Main.scalar_plain) - _::Core.Const(Val{Nothing}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - @_7::Int64 - @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} -Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ %4 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %4 -2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %10 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ %11 = (%7)(%9, %10, x)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} -└── return %11 -3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%13)()) -│ %15 = task::Task -│ (state = (PythonCall.C.current_task_state)(%15)) -│ %17 = task::Task -│ %18 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%17, %18)) -4 ─ %20 = enter #7 -5 ─ (@_7 = -1) -│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %26 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ (@_8 = (%23)(%25, %26, x)) -│ (@_7 = 1) -└── $(Expr(:leave, :(%20))) -6 ─ goto #8 -7 ┄ %31 = task::Task -│ %32 = state::PythonCall.C.TaskState -│ %33 = token::Symbol -│ (PythonCall.C.exit_region)(%31, %32, %33) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%20))))) -└── Core.Const(:(return nothing)) -8 ┄ %38 = task::Task -│ %39 = state::PythonCall.C.TaskState -│ %40 = token::Symbol -│ (PythonCall.C.exit_region)(%38, %39, %40) -│ %42 = @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} -└── return %42 - - -none: scalar_first -MethodInstance for scalar_first(::Val{Nothing}, ::Py) - from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 -Static Parameters - T = Nothing -Arguments - #self#::Core.Const(Main.scalar_first) - _::Core.Const(Val{Nothing}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - selection::PythonCall.Convert.PyConvertSelection - ctx::PyConvertContext{Tuple{}} - @_9::Int64 - @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} -Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ Core.NewvarNode(:(selection)) -│ Core.NewvarNode(:(ctx)) -│ %6 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %6 -2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%8)()) -│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %13 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ %14 = Main.PythonCall::Core.Const(PythonCall) -│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) -│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%11)(%12, %13, %17)) -│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %22 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ %23 = selection::PythonCall.Convert.PyConvertSelection -│ %24 = (%20)(%21, %22, x, %23)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} -└── return %24 -3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%26)()) -│ %28 = task::Task -│ (state = (PythonCall.C.current_task_state)(%28)) -│ %30 = task::Task -│ %31 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%30, %31)) -4 ─ %33 = enter #7 -5 ─ (@_9 = -1) -│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%35)()) -│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %40 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ %41 = Main.PythonCall::Core.Const(PythonCall) -│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) -│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%38)(%39, %40, %44)) -│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %49 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ %50 = selection::PythonCall.Convert.PyConvertSelection -│ %51 = (%47)(%48, %49, x, %50)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} -│ (@_10 = %51) -│ (@_9 = 1) -└── $(Expr(:leave, :(%33))) -6 ─ goto #8 -7 ┄ %56 = task::Task -│ %57 = state::PythonCall.C.TaskState -│ %58 = token::Symbol -│ (PythonCall.C.exit_region)(%56, %57, %58) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%33))))) -└── Core.Const(:(return nothing)) -8 ┄ %63 = task::Task -│ %64 = state::PythonCall.C.TaskState -│ %65 = token::Symbol -│ (PythonCall.C.exit_region)(%63, %64, %65) -│ %67 = @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} -└── return %67 diff --git a/benchmark/convert-scalars-optimized-repeat.tsv b/benchmark/convert-scalars-optimized-repeat.tsv deleted file mode 100644 index b8fe53c3c..000000000 --- a/benchmark/convert-scalars-optimized-repeat.tsv +++ /dev/null @@ -1,16 +0,0 @@ -round case min_ns median_ns bytes allocs -1 int 240.89526184538653 249.62344139650872 0 0 -1 float 274.10688836104515 282.4228028503563 0 0 -1 bigint 959.9 1030.0 216 7 -1 none 226.5912087912088 252.3054945054945 0 0 -1 int_large 247.20983606557377 283.2754098360656 0 0 -2 int_large 247.43333333333334 267.94615384615383 0 0 -2 int 247.0296803652968 260.7283105022831 0 0 -2 float 246.38154613466335 247.38154613466335 0 0 -2 bigint 960.0 1000.0 216 7 -2 none 232.14855875831486 239.02217294900223 0 0 -3 none 232.3054945054945 238.6791208791209 0 0 -3 int_large 267.5785536159601 283.2917705735661 0 0 -3 int 274.51290322580644 283.2258064516129 0 0 -3 float 246.44416243654823 266.74873096446703 0 0 -3 bigint 990.0 1120.0 216 7 diff --git a/benchmark/convert-scalars-optimized.tsv b/benchmark/convert-scalars-optimized.tsv deleted file mode 100644 index 47860d4bd..000000000 --- a/benchmark/convert-scalars-optimized.tsv +++ /dev/null @@ -1,25 +0,0 @@ -case path min_ns median_ns bytes allocs -int dynamic 349.04761904761904 388.8071428571428 0 0 -int typed 260.10372340425533 267.8164893617021 0 0 -int discard 247.65185185185186 254.320987654321 0 0 -int try 245.43150684931507 252.28310502283105 0 0 -int plain 239.49543378995435 265.5251141552511 0 0 -int first 232.5901234567901 258.02222222222224 0 0 -float dynamic 391.6617647058824 428.921568627451 16 1 -float typed 239.70702179176754 246.24455205811137 0 0 -float discard 246.61771561771562 254.7762237762238 0 0 -float try 238.84652278177458 272.8992805755396 0 0 -float plain 244.65320665083135 265.5558194774347 0 0 -float first 261.7409200968523 277.2397094430993 0 0 -bigint dynamic 1190.0 1260.0 216 7 -bigint typed 968.6875 1131.25 216 7 -bigint discard 949.9545454545455 1000.0 216 7 -bigint try 979.9333333333333 1033.3333333333333 232 8 -bigint plain 1059.0454545454545 1100.0 216 7 -bigint first 1023.0769230769231 1107.6923076923076 216 7 -none dynamic 341.00921658986175 369.12442396313367 0 0 -none typed 235.60554371002132 236.24733475479744 0 0 -none discard 229.86199095022624 235.97285067873304 0 0 -none try 234.34782608695653 261.08478260869566 0 0 -none plain 226.6945701357466 233.0316742081448 0 0 -none first 240.1652719665272 254.18410041841005 0 0 diff --git a/benchmark/convert-scalars-report.md b/benchmark/convert-scalars-report.md deleted file mode 100644 index 0ff34a0fc..000000000 --- a/benchmark/convert-scalars-report.md +++ /dev/null @@ -1,124 +0,0 @@ -# Final scalar, result-representation and inference findings - -**Current update:** [convert-unwrapped-report.md](convert-unwrapped-report.md) -records minimal built-in result wrapping. Scalar allocation counts and public -inferred bounds remain unchanged; arrays/native containers lose their unnecessary -outer wrappers. Its focused validation passed 1,765 checks with one existing skip. - -This report uses the final working tree, including source aliases/shorthand and -the agreed numeric-source policy. It supersedes the earlier scalar-optimization -snapshots. [convert-report.md](convert-report.md) contains implementation details, -validation status, environment and reproduction. - -## Before/after cached conversion - -Times are nanoseconds: median of three serial trial minima from the shared -convert-final.jl harness. Trial order was reversed in the middle round. -There were no concurrent tests. Both versions used Julia 1.13.2 and the same -Python 3.15.0 executable. Allocation figures are Julia bytes/counts. - -| Target | Typed before ns | Typed after ns | Typed B / allocs before → after | Runtime-target before ns | Runtime-target after ns | -| --- | ---: | ---: | --- | ---: | ---: | -| Int | 223 | 240 | 0 / 0 → 0 / 0 | 341 | 360 | -| Integer | 590 | 242 | 0 / 0 → 0 / 0 | 705 | 361 | -| BigInt | 977 | 970 | 216 / 7 → 216 / 7 | 1140 | 1170 | -| Float64 | 240 | 240 | 0 / 0 → 0 / 0 | 352 | 362 | -| Bool | 232 | 254 | 0 / 0 → 0 / 0 | 349 | 369 | -| String | 297 | 311 | 48 / 2 → 48 / 2 | 406 | 429 | -| Nothing | 211 | 230 | 0 / 0 → 0 / 0 | 318 | 356 | -| Failure | 239 | 232 | 0 / 0 → 0 / 0 | 352 | 330 | - -The typed caller carries the requested type in Val. The runtime-target caller -interpolates a Julia Type object, which can hide its identity from inference. -In the latter, both revisions allocate an additional 16-byte box for Float64 -and for Int=10000; the value is outside Julia's small boxed-integer cache. -These caller effects must not be presented as conversion-only allocations. - -The final implementation's cached Int, Float64 and Nothing paths allocate zero. -BigInt has returned to the baseline 216 bytes / seven allocations. The initial -redesign's Float64 dispatch box was removed by checking the type before crossing -the dispatch return boundary; the integer shortcut uses the shared raw kernel -rather than allowing Some{BigInt} to escape. - -None is not slower than Int in the final paired measurements. The additional -interleaved scalar-only run produced typed minima of approximately 230–242 ns -for None, 243–250 ns for Int, and 250–251 ns for Float64. This run confirms -allocation behavior and variability; its timings are not mixed into the paired -before/after aggregate. - -## Public try-conversion and inference - -The final scalar-only run measured pytryconvert at zero allocations for Int, -Float64 and Nothing. BigInt try-conversion uses 232 bytes / eight allocations: -the additional 16-byte Some is part of the public success representation. -Ordinary pyconvert(BigInt, ...) uses 216 / seven. - -Final inferred public return bounds in convert-inference-final.txt: - -| Requested type | Return bound | -| --- | --- | -| Int | Union{Nothing,Some{Int}} | -| Integer | Union{Nothing,Some{T} where T<:Integer} | -| Union{Int,Nothing} | Union{Nothing,Some{Nothing},Some{Int}} | -| Any | Union{Nothing,Some} | - -Raw scalar dispatch remains bounded by the concrete value type and the private -failure sentinel. The Float64 allocation in the profiling artifact is at the -unspecialized profiling caller, not inside scalar dispatch. There is no -Some{BigInt} object in the ordinary conversion profile. - -## Result representation comparison - -convert-results.jl models the original Union{T,Unconverted} representation and -Some/nothing with specialized result bounds. It covers successful and failed -calls, direct results, results escaping through Ref{Any}, and typed loops. -These deliberately dynamic/escaping harnesses test return boundaries; their -figures are not lower bounds on optimized Some construction. - -Successful escaping model results, including the common Ref{Any} allocation: - -| Target | Raw B / allocs | Some B / allocs | -| --- | ---: | ---: | -| Int64 | 16 / 1 | 32 / 2 | -| Float64 | 48 / 3 | 48 / 3 | -| String | 16 / 1 | 48 / 3 | -| Vector{Int} | 16 / 1 | 48 / 3 | -| Integer | 16 / 1 | 32 / 2 | -| AbstractArray | 16 / 1 | 48 / 3 | -| Union{Int64,Nothing} | 16 / 1 | 32 / 2 | -| Any | 16 / 1 | 32 / 2 | - -Both 100-element typed loops allocate zero (roughly 288 ns raw versus 268 ns -Some in this short run). Do not interpret that small timing difference as a -general representation advantage. Full successful/failed and escaping/direct -measurements are in convert-results-final.tsv. - -The measurements justify the ergonomic Some/nothing API with optimized raw -internal dispatch. The earlier all-Some internal experiment introduced -per-element allocations and slowed large-vector conversion; its historical -artifacts are retained, while final container results are in the main report. - -## Numeric-source policy and validation - -Generic numbers.Real/Complex fallback rules now apply only to Python -float/complex sources. Integral and Rational sources retain exact intermediates; -supported NumPy scalars retain dedicated rules. Other numeric types require -explicit rules. An out-of-range integer can no longer decline exact conversion -and then succeed after float rounding. - -Tests include throwing __float__/__complex__ methods on integer/rational/custom -numeric sources, nonintegral fractions, float/complex subclasses, explicit rule -opt-in, NumPy scalars, singleton-rule mutations and inferred scalar returns. -Latest local validation: 605 conversion checks and 15 ordinary Python tests -passed, with no broken conversion checks. Final full suites and supported -version coverage are assigned to CI. - -## Artifacts and reproduction - -Use benchmark/run-convert-final.sh and summarize-convert-final.py as described -in the main report. The paired results live in convert-final-{before,after}-r*, -with source/environment records. The scalar-only diagnostic run uses -convert-scalars-final.tsv, -repeat.tsv, -inference.txt and -allocations.txt. -Representation and public inference outputs are convert-results-final.tsv and -convert-inference-final.txt. Earlier before/optimized/source-policy files are -historical snapshots, not current failures or current comparison tables. diff --git a/benchmark/convert-scalars-source-policy-allocations.txt b/benchmark/convert-scalars-source-policy-allocations.txt deleted file mode 100644 index 33cf76cd7..000000000 --- a/benchmark/convert-scalars-source-policy-allocations.txt +++ /dev/null @@ -1,113 +0,0 @@ - -int - -float -Float64: 16 bytes - (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 - eval(m::Module, e::Any) at boot.jl:489 - -bigint -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at Py.jl:109 [inlined] - macro expansion at regions.jl:296 [inlined] - macro expansion at Py.jl:103 [inlined] - macro expansion at regions.jl:296 [inlined] - pyint(x::Py) at builtins.jl:689 - macro expansion at rules.jl:97 [inlined] - macro expansion at regions.jl:296 [inlined] - pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 - pyconvert_first at pyconvert.jl:305 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] - scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 - (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 - eval(m::Module, e::Any) at boot.jl:489 -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at regions.jl:296 [inlined] - pystr(x::Py) at builtins.jl:592 - pystr at builtins.jl:598 [inlined] - macro expansion at rules.jl:98 [inlined] - macro expansion at regions.jl:296 [inlined] - pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 - pyconvert_first at pyconvert.jl:305 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] - scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 - (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 - eval(m::Module, e::Any) at boot.jl:489 -Py: 16 bytes - Py at types.jl:17 [inlined] - pynew at Py.jl:52 [inlined] - pynew at Py.jl:56 [inlined] - macro expansion at regions.jl:296 [inlined] - pystr_asUTF8bytes(x::Py) at builtins.jl:600 - pystr_asstring(x::Py) at builtins.jl:603 - pystr at builtins.jl:598 [inlined] - macro expansion at rules.jl:98 [inlined] - macro expansion at regions.jl:296 [inlined] - pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 - pyconvert_first at pyconvert.jl:305 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] - scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 - (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 - eval(m::Module, e::Any) at boot.jl:489 -String: 70 bytes - pybytes_asUTF8string at builtins.jl:654 [inlined] - pystr_asstring(x::Py) at builtins.jl:604 - pystr at builtins.jl:598 [inlined] - macro expansion at rules.jl:98 [inlined] - macro expansion at regions.jl:296 [inlined] - pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 - pyconvert_first at pyconvert.jl:305 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] - scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 - (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 - eval(m::Module, e::Any) at boot.jl:489 -BigInt: 32 bytes - _ at gmp.jl:70 [inlined] - BigInt at gmp.jl:69 [inlined] - tryparse_internal(::Type{BigInt}, s::String, startpos::Int64, endpos::Int64, base_::Int64, raise::Bool) at gmp.jl:302 - macro expansion at rules.jl:100 [inlined] - macro expansion at regions.jl:296 [inlined] - pyconvert_rule_int_raw(::Type{BigInt}, x::Py) at rules.jl:68 - pyconvert_first at pyconvert.jl:305 [inlined] - pytryconvert_plain(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py) at pyconvert.jl:322 - pytryconvert_raw at pyconvert.jl:341 [inlined] - macro expansion at pyconvert.jl:417 [inlined] - macro expansion at regions.jl:302 [inlined] - pyconvert(ctx::PyConvertContext{Tuple{}}, ::Type{BigInt}, x::Py, default::Nothing) at pyconvert.jl:416 - #pyconvert#36 at pyconvert.jl:422 [inlined] - pyconvert at pyconvert.jl:422 [inlined] - scalar_convert(::Val{BigInt}, x::Py) at convert-scalars.jl:5 - (::var"#8#9")(io::IOStream) at convert-scalars.jl:52 - eval(m::Module, e::Any) at boot.jl:489 - -none diff --git a/benchmark/convert-scalars-source-policy-inference.txt b/benchmark/convert-scalars-source-policy-inference.txt deleted file mode 100644 index ec78abe6f..000000000 --- a/benchmark/convert-scalars-source-policy-inference.txt +++ /dev/null @@ -1,663 +0,0 @@ - -int: scalar_convert -MethodInstance for scalar_convert(::Val{Int64}, ::Py) - from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 -Static Parameters - T = Int64 -Arguments - #self#::Core.Const(Main.scalar_convert) - _::Core.Const(Val{Int64}()) - x::Py -Body::UNION{NOTHING, INT64} -1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) -│ %2 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ %3 = Main.nothing::Core.Const(nothing) -│ %4 = (%1)(%2, x, %3)::UNION{NOTHING, INT64} -└── return %4 - - -int: scalar_plain -MethodInstance for scalar_plain(::Val{Int64}, ::Py) - from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 -Static Parameters - T = Int64 -Arguments - #self#::Core.Const(Main.scalar_plain) - _::Core.Const(Val{Int64}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - @_7::Int64 - @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} -Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ %4 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %4 -2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %10 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ %11 = (%7)(%9, %10, x)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} -└── return %11 -3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%13)()) -│ %15 = task::Task -│ (state = (PythonCall.C.current_task_state)(%15)) -│ %17 = task::Task -│ %18 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%17, %18)) -4 ─ %20 = enter #7 -5 ─ (@_7 = -1) -│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %26 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ (@_8 = (%23)(%25, %26, x)) -│ (@_7 = 1) -└── $(Expr(:leave, :(%20))) -6 ─ goto #8 -7 ┄ %31 = task::Task -│ %32 = state::PythonCall.C.TaskState -│ %33 = token::Symbol -│ (PythonCall.C.exit_region)(%31, %32, %33) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%20))))) -└── Core.Const(:(return nothing)) -8 ┄ %38 = task::Task -│ %39 = state::PythonCall.C.TaskState -│ %40 = token::Symbol -│ (PythonCall.C.exit_region)(%38, %39, %40) -│ %42 = @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} -└── return %42 - - -int: scalar_first -MethodInstance for scalar_first(::Val{Int64}, ::Py) - from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 -Static Parameters - T = Int64 -Arguments - #self#::Core.Const(Main.scalar_first) - _::Core.Const(Val{Int64}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - selection::PythonCall.Convert.PyConvertSelection - ctx::PyConvertContext{Tuple{}} - @_9::Int64 - @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} -Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ Core.NewvarNode(:(selection)) -│ Core.NewvarNode(:(ctx)) -│ %6 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %6 -2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%8)()) -│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %13 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ %14 = Main.PythonCall::Core.Const(PythonCall) -│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) -│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%11)(%12, %13, %17)) -│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %22 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ %23 = selection::PythonCall.Convert.PyConvertSelection -│ %24 = (%20)(%21, %22, x, %23)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} -└── return %24 -3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%26)()) -│ %28 = task::Task -│ (state = (PythonCall.C.current_task_state)(%28)) -│ %30 = task::Task -│ %31 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%30, %31)) -4 ─ %33 = enter #7 -5 ─ (@_9 = -1) -│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%35)()) -│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %40 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ %41 = Main.PythonCall::Core.Const(PythonCall) -│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) -│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%38)(%39, %40, %44)) -│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %49 = $(Expr(:static_parameter, 1))::Core.Const(Int64) -│ %50 = selection::PythonCall.Convert.PyConvertSelection -│ %51 = (%47)(%48, %49, x, %50)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} -│ (@_10 = %51) -│ (@_9 = 1) -└── $(Expr(:leave, :(%33))) -6 ─ goto #8 -7 ┄ %56 = task::Task -│ %57 = state::PythonCall.C.TaskState -│ %58 = token::Symbol -│ (PythonCall.C.exit_region)(%56, %57, %58) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%33))))) -└── Core.Const(:(return nothing)) -8 ┄ %63 = task::Task -│ %64 = state::PythonCall.C.TaskState -│ %65 = token::Symbol -│ (PythonCall.C.exit_region)(%63, %64, %65) -│ %67 = @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, INT64} -└── return %67 - - -float: scalar_convert -MethodInstance for scalar_convert(::Val{Float64}, ::Py) - from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 -Static Parameters - T = Float64 -Arguments - #self#::Core.Const(Main.scalar_convert) - _::Core.Const(Val{Float64}()) - x::Py -Body::UNION{NOTHING, FLOAT64} -1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) -│ %2 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ %3 = Main.nothing::Core.Const(nothing) -│ %4 = (%1)(%2, x, %3)::UNION{NOTHING, FLOAT64} -└── return %4 - - -float: scalar_plain -MethodInstance for scalar_plain(::Val{Float64}, ::Py) - from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 -Static Parameters - T = Float64 -Arguments - #self#::Core.Const(Main.scalar_plain) - _::Core.Const(Val{Float64}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - @_7::Int64 - @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} -Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ %4 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %4 -2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %10 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ %11 = (%7)(%9, %10, x)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} -└── return %11 -3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%13)()) -│ %15 = task::Task -│ (state = (PythonCall.C.current_task_state)(%15)) -│ %17 = task::Task -│ %18 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%17, %18)) -4 ─ %20 = enter #7 -5 ─ (@_7 = -1) -│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %26 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ (@_8 = (%23)(%25, %26, x)) -│ (@_7 = 1) -└── $(Expr(:leave, :(%20))) -6 ─ goto #8 -7 ┄ %31 = task::Task -│ %32 = state::PythonCall.C.TaskState -│ %33 = token::Symbol -│ (PythonCall.C.exit_region)(%31, %32, %33) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%20))))) -└── Core.Const(:(return nothing)) -8 ┄ %38 = task::Task -│ %39 = state::PythonCall.C.TaskState -│ %40 = token::Symbol -│ (PythonCall.C.exit_region)(%38, %39, %40) -│ %42 = @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} -└── return %42 - - -float: scalar_first -MethodInstance for scalar_first(::Val{Float64}, ::Py) - from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 -Static Parameters - T = Float64 -Arguments - #self#::Core.Const(Main.scalar_first) - _::Core.Const(Val{Float64}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - selection::PythonCall.Convert.PyConvertSelection - ctx::PyConvertContext{Tuple{}} - @_9::Int64 - @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} -Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ Core.NewvarNode(:(selection)) -│ Core.NewvarNode(:(ctx)) -│ %6 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %6 -2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%8)()) -│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %13 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ %14 = Main.PythonCall::Core.Const(PythonCall) -│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) -│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%11)(%12, %13, %17)) -│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %22 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ %23 = selection::PythonCall.Convert.PyConvertSelection -│ %24 = (%20)(%21, %22, x, %23)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} -└── return %24 -3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%26)()) -│ %28 = task::Task -│ (state = (PythonCall.C.current_task_state)(%28)) -│ %30 = task::Task -│ %31 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%30, %31)) -4 ─ %33 = enter #7 -5 ─ (@_9 = -1) -│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%35)()) -│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %40 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ %41 = Main.PythonCall::Core.Const(PythonCall) -│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) -│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%38)(%39, %40, %44)) -│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %49 = $(Expr(:static_parameter, 1))::Core.Const(Float64) -│ %50 = selection::PythonCall.Convert.PyConvertSelection -│ %51 = (%47)(%48, %49, x, %50)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} -│ (@_10 = %51) -│ (@_9 = 1) -└── $(Expr(:leave, :(%33))) -6 ─ goto #8 -7 ┄ %56 = task::Task -│ %57 = state::PythonCall.C.TaskState -│ %58 = token::Symbol -│ (PythonCall.C.exit_region)(%56, %57, %58) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%33))))) -└── Core.Const(:(return nothing)) -8 ┄ %63 = task::Task -│ %64 = state::PythonCall.C.TaskState -│ %65 = token::Symbol -│ (PythonCall.C.exit_region)(%63, %64, %65) -│ %67 = @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, FLOAT64} -└── return %67 - - -bigint: scalar_convert -MethodInstance for scalar_convert(::Val{BigInt}, ::Py) - from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 -Static Parameters - T = BigInt -Arguments - #self#::Core.Const(Main.scalar_convert) - _::Core.Const(Val{BigInt}()) - x::Py -Body::UNION{NOTHING, BIGINT} -1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) -│ %2 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ %3 = Main.nothing::Core.Const(nothing) -│ %4 = (%1)(%2, x, %3)::UNION{NOTHING, BIGINT} -└── return %4 - - -bigint: scalar_plain -MethodInstance for scalar_plain(::Val{BigInt}, ::Py) - from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 -Static Parameters - T = BigInt -Arguments - #self#::Core.Const(Main.scalar_plain) - _::Core.Const(Val{BigInt}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - @_7::Int64 - @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} -Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ %4 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %4 -2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %10 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ %11 = (%7)(%9, %10, x)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} -└── return %11 -3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%13)()) -│ %15 = task::Task -│ (state = (PythonCall.C.current_task_state)(%15)) -│ %17 = task::Task -│ %18 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%17, %18)) -4 ─ %20 = enter #7 -5 ─ (@_7 = -1) -│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %26 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ (@_8 = (%23)(%25, %26, x)) -│ (@_7 = 1) -└── $(Expr(:leave, :(%20))) -6 ─ goto #8 -7 ┄ %31 = task::Task -│ %32 = state::PythonCall.C.TaskState -│ %33 = token::Symbol -│ (PythonCall.C.exit_region)(%31, %32, %33) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%20))))) -└── Core.Const(:(return nothing)) -8 ┄ %38 = task::Task -│ %39 = state::PythonCall.C.TaskState -│ %40 = token::Symbol -│ (PythonCall.C.exit_region)(%38, %39, %40) -│ %42 = @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} -└── return %42 - - -bigint: scalar_first -MethodInstance for scalar_first(::Val{BigInt}, ::Py) - from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 -Static Parameters - T = BigInt -Arguments - #self#::Core.Const(Main.scalar_first) - _::Core.Const(Val{BigInt}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - selection::PythonCall.Convert.PyConvertSelection - ctx::PyConvertContext{Tuple{}} - @_9::Int64 - @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} -Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ Core.NewvarNode(:(selection)) -│ Core.NewvarNode(:(ctx)) -│ %6 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %6 -2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%8)()) -│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %13 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ %14 = Main.PythonCall::Core.Const(PythonCall) -│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) -│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%11)(%12, %13, %17)) -│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %22 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ %23 = selection::PythonCall.Convert.PyConvertSelection -│ %24 = (%20)(%21, %22, x, %23)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} -└── return %24 -3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%26)()) -│ %28 = task::Task -│ (state = (PythonCall.C.current_task_state)(%28)) -│ %30 = task::Task -│ %31 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%30, %31)) -4 ─ %33 = enter #7 -5 ─ (@_9 = -1) -│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%35)()) -│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %40 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ %41 = Main.PythonCall::Core.Const(PythonCall) -│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) -│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%38)(%39, %40, %44)) -│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %49 = $(Expr(:static_parameter, 1))::Core.Const(BigInt) -│ %50 = selection::PythonCall.Convert.PyConvertSelection -│ %51 = (%47)(%48, %49, x, %50)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} -│ (@_10 = %51) -│ (@_9 = 1) -└── $(Expr(:leave, :(%33))) -6 ─ goto #8 -7 ┄ %56 = task::Task -│ %57 = state::PythonCall.C.TaskState -│ %58 = token::Symbol -│ (PythonCall.C.exit_region)(%56, %57, %58) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%33))))) -└── Core.Const(:(return nothing)) -8 ┄ %63 = task::Task -│ %64 = state::PythonCall.C.TaskState -│ %65 = token::Symbol -│ (PythonCall.C.exit_region)(%63, %64, %65) -│ %67 = @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, BIGINT} -└── return %67 - - -none: scalar_convert -MethodInstance for scalar_convert(::Val{Nothing}, ::Py) - from scalar_convert(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:5 -Static Parameters - T = Nothing -Arguments - #self#::Core.Const(Main.scalar_convert) - _::Core.Const(Val{Nothing}()) - x::Py -Body::Nothing -1 ─ %1 = Main.pyconvert::Core.Const(PythonCall.pyconvert) -│ %2 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ %3 = Main.nothing::Core.Const(nothing) -│ %4 = (%1)(%2, x, %3)::Core.Const(nothing) -└── return %4 - - -none: scalar_plain -MethodInstance for scalar_plain(::Val{Nothing}, ::Py) - from scalar_plain(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:8 -Static Parameters - T = Nothing -Arguments - #self#::Core.Const(Main.scalar_plain) - _::Core.Const(Val{Nothing}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - @_7::Int64 - @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} -Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ %4 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %4 -2 ─ %6 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %7 = Base.getproperty(%6, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %9 = (%8)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %10 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ %11 = (%7)(%9, %10, x)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} -└── return %11 -3 ─ %13 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%13)()) -│ %15 = task::Task -│ (state = (PythonCall.C.current_task_state)(%15)) -│ %17 = task::Task -│ %18 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%17, %18)) -4 ─ %20 = enter #7 -5 ─ (@_7 = -1) -│ %22 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %23 = Base.getproperty(%22, :pytryconvert_plain)::Core.Const(PythonCall.Convert.pytryconvert_plain) -│ %24 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ %25 = (%24)()::Core.Const(PyConvertContext{Tuple{}}(())) -│ %26 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ (@_8 = (%23)(%25, %26, x)) -│ (@_7 = 1) -└── $(Expr(:leave, :(%20))) -6 ─ goto #8 -7 ┄ %31 = task::Task -│ %32 = state::PythonCall.C.TaskState -│ %33 = token::Symbol -│ (PythonCall.C.exit_region)(%31, %32, %33) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%20))))) -└── Core.Const(:(return nothing)) -8 ┄ %38 = task::Task -│ %39 = state::PythonCall.C.TaskState -│ %40 = token::Symbol -│ (PythonCall.C.exit_region)(%38, %39, %40) -│ %42 = @_8::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} -└── return %42 - - -none: scalar_first -MethodInstance for scalar_first(::Val{Nothing}, ::Py) - from scalar_first(::Val{T}, x) where T @ Main ~/.julia/dev/PythonCall/benchmark/convert-scalars.jl:11 -Static Parameters - T = Nothing -Arguments - #self#::Core.Const(Main.scalar_first) - _::Core.Const(Val{Nothing}()) - x::Py -Locals - token::Symbol - state::PythonCall.C.TaskState - task::Task - selection::PythonCall.Convert.PyConvertSelection - ctx::PyConvertContext{Tuple{}} - @_9::Int64 - @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} -Body::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} -1 ─ Core.NewvarNode(:(token)) -│ Core.NewvarNode(:(state)) -│ Core.NewvarNode(:(task)) -│ Core.NewvarNode(:(selection)) -│ Core.NewvarNode(:(ctx)) -│ %6 = (PythonCall.C.has_tstate)()::Bool -└── goto #3 if not %6 -2 ─ %8 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%8)()) -│ %10 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %11 = Base.getproperty(%10, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %12 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %13 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ %14 = Main.PythonCall::Core.Const(PythonCall) -│ %15 = Base.getproperty(%14, :C)::Core.Const(PythonCall.C) -│ %16 = Base.getproperty(%15, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %17 = (%16)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%11)(%12, %13, %17)) -│ %19 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %20 = Base.getproperty(%19, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %21 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %22 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ %23 = selection::PythonCall.Convert.PyConvertSelection -│ %24 = (%20)(%21, %22, x, %23)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} -└── return %24 -3 ─ %26 = PythonCall.C.current_task::Core.Const(current_task) -│ (task = (%26)()) -│ %28 = task::Task -│ (state = (PythonCall.C.current_task_state)(%28)) -│ %30 = task::Task -│ %31 = state::PythonCall.C.TaskState -└── (token = (PythonCall.C.enter_region)(%30, %31)) -4 ─ %33 = enter #7 -5 ─ (@_9 = -1) -│ %35 = Main.PyConvertContext::Core.Const(PyConvertContext) -│ (ctx = (%35)()) -│ %37 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %38 = Base.getproperty(%37, :pyconvert_selection)::Core.Const(PythonCall.Convert.pyconvert_selection) -│ %39 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %40 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ %41 = Main.PythonCall::Core.Const(PythonCall) -│ %42 = Base.getproperty(%41, :C)::Core.Const(PythonCall.C) -│ %43 = Base.getproperty(%42, :Py_Type)::Core.Const(PythonCall.C.Py_Type) -│ %44 = (%43)(x)::Ptr{PythonCall.C.PyObject} -│ (selection = (%38)(%39, %40, %44)) -│ %46 = Main.ScalarConvert::Core.Const(PythonCall.Convert) -│ %47 = Base.getproperty(%46, :pyconvert_first)::Core.Const(PythonCall.Convert.pyconvert_first) -│ %48 = ctx::Core.Const(PyConvertContext{Tuple{}}(())) -│ %49 = $(Expr(:static_parameter, 1))::Core.Const(Nothing) -│ %50 = selection::PythonCall.Convert.PyConvertSelection -│ %51 = (%47)(%48, %49, x, %50)::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} -│ (@_10 = %51) -│ (@_9 = 1) -└── $(Expr(:leave, :(%33))) -6 ─ goto #8 -7 ┄ %56 = task::Task -│ %57 = state::PythonCall.C.TaskState -│ %58 = token::Symbol -│ (PythonCall.C.exit_region)(%56, %57, %58) -│ Base.rethrow() -│ Core.Const(:($(Expr(:pop_exception, :(%33))))) -└── Core.Const(:(return nothing)) -8 ┄ %63 = task::Task -│ %64 = state::PythonCall.C.TaskState -│ %65 = token::Symbol -│ (PythonCall.C.exit_region)(%63, %64, %65) -│ %67 = @_10::UNION{PYTHONCALL.CONVERT.PYCONVERTFAILURE, NOTHING} -└── return %67 diff --git a/benchmark/convert-scalars-source-policy-repeat.tsv b/benchmark/convert-scalars-source-policy-repeat.tsv deleted file mode 100644 index f743cbdba..000000000 --- a/benchmark/convert-scalars-source-policy-repeat.tsv +++ /dev/null @@ -1,16 +0,0 @@ -round case min_ns median_ns bytes allocs -1 int 240.95744680851064 292.8164893617021 0 0 -1 float 270.25384615384615 304.1 0 0 -1 bigint 1085.642857142857 2085.714285714286 216 7 -1 none 234.72307692307692 278.2395604395604 0 0 -1 int_large 241.02307692307693 268.9717948717949 0 0 -2 int_large 275.7210144927536 292.7536231884058 0 0 -2 int 241.43493150684932 255.81849315068493 0 0 -2 float 242.56153846153848 284.87051282051283 0 0 -2 bigint 1000.0 1110.0 216 7 -2 none 228.56923076923076 261.756043956044 0 0 -3 none 228.78947368421052 278.6377708978328 0 0 -3 int_large 247.6749226006192 284.20743034055727 0 0 -3 int 247.39595375722544 302.8901734104046 0 0 -3 float 249.70294117647057 317.6470588235294 0 0 -3 bigint 1080.0 1260.0 216 7 diff --git a/benchmark/convert-scalars-source-policy.tsv b/benchmark/convert-scalars-source-policy.tsv deleted file mode 100644 index dff71638a..000000000 --- a/benchmark/convert-scalars-source-policy.tsv +++ /dev/null @@ -1,25 +0,0 @@ -case path min_ns median_ns bytes allocs -int dynamic 354.97156398104266 395.25592417061614 0 0 -int typed 241.40193704600483 242.37046004842614 0 0 -int discard 236.4484412470024 250.11870503597123 0 0 -int try 233.2517814726841 266.0332541567696 0 0 -int plain 245.24660633484163 264.70361990950227 0 0 -int first 248.70474137931035 262.9288793103448 0 0 -float dynamic 377.9856459330144 417.70334928229664 16 1 -float typed 241.23456790123456 258.2691358024691 0 0 -float discard 237.5283950617284 254.56543209876543 0 0 -float try 235.02073732718895 270.0437788018433 0 0 -float plain 241.64406779661016 263.9200968523002 0 0 -float first 233.7876712328767 260.5 0 0 -bigint dynamic 1080.0 1180.0 216 7 -bigint typed 1041.6666666666667 1150.0 216 7 -bigint discard 1050.0 1116.6666666666667 216 7 -bigint try 962.4375 1006.25 232 8 -bigint plain 1037.5 1100.0 216 7 -bigint first 1058.3333333333333 1133.25 216 7 -none dynamic 363.46153846153845 383.1730769230769 0 0 -none typed 236.60878661087867 256.6924686192469 0 0 -none discard 230.65 231.08478260869566 0 0 -none try 231.08695652173913 238.2586956521739 0 0 -none plain 229.66813186813187 263.07472527472527 0 0 -none first 246.02301255230125 260.8765690376569 0 0 diff --git a/benchmark/convert-unwrapped-report.md b/benchmark/convert-unwrapped-report.md deleted file mode 100644 index a174c575d..000000000 --- a/benchmark/convert-unwrapped-report.md +++ /dev/null @@ -1,119 +0,0 @@ -# Minimal rule-result wrapping - -The optimization succeeds: ordinary built-in rules now return their values -directly, wrapping only successful nothing/Some values. Public pytryconvert -continues to wrap every success. No registry, ordering, scope, preference or -failure/exception policy changed, and no additional fast path was introduced. - -This report supersedes affected allocation/timing results in the earlier full -benchmark refresh. Its baseline is the implementation immediately before this -optimization, **not original v1**. - -## Change and validation - -The internal success helper returns ordinary values directly; its Nothing/Some -method wraps them once. Internal result readers accept both forms. Checked Julia -conversion uses this encoding, and vector/dictionary/integer rules no longer -construct unconditional Some results. Existing array builders/rules already use -these helpers, so they benefit without an array-specific implementation. - -Only src/Convert/pyconvert.jl and rules.jl change at runtime. The isolated diff -is saved as convert-unwrapped.patch. Source-author documentation now recommends -ordinary success values. Tests exercise successful nothing, nested Some, -wrapped Julia values and nested native containers, preserving exact values. - -Focused conversion, Python-wrapper and Julia-wrapper tests: **1,765 passed, -one existing optional-dependency skip** (the NumPy copy=False test is gated by -Setup.devdeps with the Null backend). Full suites/version coverage remain for CI. - -Inferred public try-conversion bounds remain unchanged for Int, Integer, -Union{Int,Nothing} and Any. The generic array rule now infers -Union{Nothing,Array}, rather than an existential Some-wrapped array. Arrays -still have runtime-discovered element/rank types, but their existing object -references can cross that boundary directly. - -## Method - -Three sequential before/after rounds on Julia 1.13.2, Python 3.15.0, NumPy 2.5.4 -and BenchmarkTools 1.8.0, with no concurrent tests. The saved pre-change source -was developed into a separate environment. Round order: before/after, -after/before, before/after. Both use the same Python executable/Null backend. - -Times are microseconds: median of three trial minima, using up to 5,000 samples / -one second per warm trial. Julia bytes/counts exclude Python allocations. -Source paths/fingerprints, trial medians and round ranges are retained. These -short runs do not establish confidence intervals. The unchanged DAG/cold-path -mechanism was not remeasured in this follow-up. - -## Arrays - -| Case | Before us | After us | Change | Before B / allocs | After B / allocs | -| --- | ---: | ---: | ---: | ---: | ---: | -| Buffer-only native | 7.325 | 7.150 | -2.4% | 8856 / 26 | 8712 / 23 | -| Buffer-only wrapper | 5.583 | 5.283 | -5.4% | 768 / 22 | 640 / 20 | -| Interface-only native | 22.200 | 21.700 | -2.3% | 9368 / 55 | 9224 / 52 | -| Array-method-only native | 8.133 | 7.633 | -6.1% | 9016 / 30 | 8872 / 27 | -| ndarray native | 4.867 | 4.686 | -3.7% | 8888 / 23 | 8744 / 20 | -| ndarray wrapper | 3.388 | 3.288 | -3.0% | 800 / 19 | 672 / 17 | - -All six cases remove the predicted 128 bytes / two objects for wrappers, -144 bytes / three objects for native arrays. Their allocation counts/bytes -now match the original-v1 protocol fixtures. This does not establish timing -equivalence to original v1; this experiment isolates the newer wrapper change. - -Profile.Allocs confirms the disappearance of Some{PyArray{...}}, the additional -boxed PyArray during unwrapping, and Some{Vector{T}} for native copying. The -post-change profile contains no Some objects for the four profiled array cases. -See convert-array-allocations-unwrapped.txt; the earlier pre-change stacks are -in convert-array-allocations-after.txt. - -## Other containers and scalars - -| Case | Before us | After us | Change | Before B / allocs | After B / allocs | -| --- | ---: | ---: | ---: | ---: | ---: | -| Vector, 10 integers | 7.120 | 6.560 | -7.9% | 720 / 18 | 704 / 17 | -| Vector, 10,000 integers | 4714.836 | 4624.435 | -1.9% | 513880 / 19508 | 513864 / 19507 | -| Vector{Int}, 10,000 integers | 4084.732 | 4036.031 | -1.2% | 362024 / 10018 | 362008 / 10017 | -| Nested concrete vectors | 6.950 | 6.920 | -0.4% | 768 / 29 | 720 / 26 | -| Nested Any conversion | 10.800 | 9.800 | -9.3% | 864 / 32 | 816 / 29 | -| Dict, inferred values | 6.480 | 6.540 | +0.9% | 1280 / 24 | 1264 / 23 | -| Dict{String,Float64} | 3.675 | 3.613 | -1.7% | 672 / 16 | 656 / 15 | -| Empty Vector | 1.240 | 1.130 | -8.9% | 112 / 5 | 96 / 4 | -| Empty Dict | 1.040 | 1.036 | -0.3% | 208 / 5 | 192 / 4 | - -Each native container loses its outer 16-byte result wrapper; nested vectors -lose one per converted vector. Timing changes vary, including the slightly -slower inferred dictionary despite fewer allocations. Do not infer a fixed -speedup from removing one allocation. - -Cached Int/Float64/Nothing remain allocation-free; BigInt remains 216 bytes / -seven allocations. Their typed minima before/after are 241/240 ns, 240/237 ns, -232/232 ns and 935/980 ns respectively. BigInt's +4.8% and incompatible-string -failure's +3.4% remain reported in the summary; round ranges overlap and no -additional allocations or inferred-type regressions were found. Other small -scalar timing changes are similarly not treated as established improvements. - -## Artifacts and reproduction - -Current data: convert-final-unwrapped-{before,after}-r{1,2,3}.tsv and -convert-expanded-unwrapped-{before,after}-r{1,2,3}.tsv, each with an environment -record. The aggregate is convert-unwrapped-summary.tsv (43 cases/modes). -Both revisions passed all benchmark fixture assertions. Allocation differences -are constant across all three rounds. - -Reconstruct the pre-change source by copying the current checkout and reversing -convert-unwrapped.patch **inside that copy**. Develop it into an isolated Julia -environment with BenchmarkTools 1.8.0. For each revision/round, sequentially run: - -~~~sh -julia --project=/path/to/revision-env benchmark/convert-final.jl unwrapped-before-r1 -julia --project=/path/to/revision-env benchmark/convert-expanded.jl unwrapped-before-r1 warm -~~~ - -Use labels before/after and rounds 1/2/3, with the order described above; keep -the same installed Python/backend for both revisions. Then aggregate/profile: - -~~~sh -python3 benchmark/summarize-convert-final.py unwrapped -julia --project=benchmark benchmark/convert-array-allocations.jl unwrapped -~~~ diff --git a/benchmark/convert-unwrapped-summary.tsv b/benchmark/convert-unwrapped-summary.tsv deleted file mode 100644 index 7778f25a2..000000000 --- a/benchmark/convert-unwrapped-summary.tsv +++ /dev/null @@ -1,44 +0,0 @@ -group case mode before_ns after_ns change_percent before_p50_ns after_p50_ns before_low_ns before_high_ns after_low_ns after_high_ns before_bytes before_allocs after_bytes after_allocs -common int typed 240.86294416243655 239.5964467005076 -0.5258166491043159 275.89086294416245 280.96700507614213 240.14251781472683 242.8595641646489 234.9246231155779 247.71689497716895 0 0 0 0 -common int runtime_target 392.5422885572139 380.19323671497585 -3.1459163005409962 406.505 440.28909952606637 363.9423076923077 393.0 360.2870813397129 410.4265402843602 16 1 16 1 -common integer typed 242.22222222222223 237.46223564954684 -1.9651320712880005 285.68148148148146 278.8622327790974 242.13317191283292 243.8280871670702 236.17021276595744 243.46793349168647 0 0 0 0 -common integer runtime_target 386.2068965517241 356.3380281690141 -7.733903420523136 414.35885167464113 414.76190476190476 362.20095693779905 389.6039603960396 356.1320754716981 361.9095238095238 0 0 0 0 -common bigint typed 934.7826086956521 980.0 4.837209302325585 1004.3913043478261 1060.1 932.0 1070.0 953.8461538461538 1042.1052631578948 216 7 216 7 -common bigint runtime_target 1200.0 1110.0 -7.499999999999996 1250.0 1300.0 1190.0 1280.0 1110.0 1190.0 216 7 216 7 -common float typed 240.38004750593825 237.28813559322035 -1.2862597976820545 275.061757719715 266.7579787234043 234.5679012345679 249.72375690607734 236.5641646489104 239.63031914893617 0 0 0 0 -common float runtime_target 393.0348258706468 383.66336633663366 -2.3843840080210565 427.05797101449275 443.0693069306931 370.5314009661836 429.1457286432161 373.30582524271847 391.04477611940297 16 1 16 1 -common bool typed 257.2755417956656 255.58823529411765 -0.6558363417569102 296.2750716332378 303.1777777777778 254.00890207715133 259.025787965616 251.11111111111111 273.93882978723406 0 0 0 0 -common bool runtime_target 441.9191919191919 395.0980392156863 -10.594957983193275 445.9646464646465 418.3623188405797 431.15577889447235 445.9646464646465 385.02415458937196 421.28712871287127 0 0 0 0 -common string typed 318.0257510729614 311.4035087719298 -2.0822975116604026 369.82758620689657 367.5438596491228 313.79741379310343 319.91525423728814 309.880658436214 313.8655462184874 48 2 48 2 -common string runtime_target 445.95959595959596 426.2676767676768 -4.4156285390713474 516.1666666666666 474.75252525252523 431.8181818181818 454.04545454545456 425.6281407035176 427.1356783919598 48 2 48 2 -common none typed 231.83856502242153 231.80125523012552 -0.016093005187645115 251.347533632287 258.1610878661088 225.57077625570776 240.55944055944056 225.9356846473029 236.30365296803652 0 0 0 0 -common none runtime_target 354.50236966824644 345.23809523809524 -2.613318054494529 395.2654028436019 387.1518691588785 337.8995433789954 364.5980861244019 340.0 375.23364485981307 0 0 0 0 -common failure typed 230.824200913242 238.68778280542986 3.4067406541758105 242.35254988913525 262.5570776255708 229.93569844789357 231.52391304347827 229.68036529680364 263.56164383561645 0 0 0 0 -common failure runtime_target 371.5 335.02764976958525 -9.81759090993668 426.005 373.2718894009217 341.2844036697248 378.2608695652174 333.1838565022422 338.7142857142857 0 0 0 0 -common list10 typed 7120.0 6560.0 -7.86516853932584 7620.0 7500.0 6680.0 7760.0 6440.2 7080.0 720 18 704 17 -common list10000 typed 4714836.0 4624435.0 -1.917373159957203 5624843.0 5467642.0 4687736.0 4854337.0 4545035.0 4805737.0 513880 19508 513864 19507 -common list10000_concrete typed 4084732.0 4036031.0 -1.1922691623342696 4452634.5 4755336.0 3978430.0 4225432.0 4018131.0 4094831.0 362024 10018 362008 10017 -common mixed_numeric typed 3971.4285714285716 3800.125 -4.313399280575547 4475.125 3962.5 3837.625 4000.0 3800.0 4225.0 352 13 336 12 -common heterogeneous typed 4871.428571428572 4842.857142857143 -0.5865102639296182 5614.428571428572 5300.0 4828.571428571428 5400.0 4728.571428571428 5057.142857142857 384 14 368 13 -common nested_concrete typed 6950.0 6920.0 -0.4316546762589968 7340.0 7820.0 6940.0 7050.0 6920.0 8075.0 768 29 720 26 -common nested_any typed 10800.0 9800.0 -9.259259259259256 11600.0 10300.0 9900.0 10800.0 9500.0 10701.0 864 32 816 29 -common dict typed 6480.0 6540.0 0.92592592592593 7380.2 7620.0 6360.0 6500.0 6540.0 7580.0 1280 24 1264 23 -common dict_concrete typed 3675.0 3612.625 -1.6972789115646258 4062.625 4200.0 3675.0 3925.0 3612.5 3950.0 672 16 656 15 -common empty_list typed 1240.0 1130.0 -8.870967741935488 1400.0 1200.0 1210.0 1260.0 1120.0 1180.0 112 5 96 4 -common empty_dict typed 1040.0 1036.3636363636363 -0.34965034965035446 1220.0 1163.6363636363637 1040.0 1120.0 1030.0 1080.0 208 5 192 4 -common wrapper typed 400.49751243781094 399.505 -0.24781987577640052 428.363184079602 453.23880597014926 394.02985074626866 416.005 395.02487562189054 404.97512437810946 16 1 16 1 -common iterator typed 402.0 398.99497487437185 -0.7475186879671969 467.5 405.5 401.0 406.5 397.505 400.5 16 1 16 1 -expanded single_rule warm 405.5 386.69950738916253 -4.636373023634388 473.005 444.3349753694581 393.10837438423647 413.0 382.3529411764706 392.5422885572139 0 0 0 0 -expanded decline_then_success warm 557.6086956521739 543.0904255319149 -2.6036663763427392 642.2513368983957 573.4095744680851 550.8108108108108 560.9679144385027 525.7894736842105 547.5989304812834 0 0 0 0 -expanded three_declines_then_success warm 875.4716981132076 964.1509433962265 10.12931034482758 1016.3636363636364 1028.3207547169811 865.4545454545455 930.5555555555555 880.7692307692307 989.1090909090909 0 0 0 0 -expanded sixteen_scoped_decliners warm 405.97512437810946 377.27272727272725 -7.069989115552289 463.505 395.57142857142856 402.5 460.30150753768845 375.3694581280788 401.5151515151515 0 0 0 0 -expanded virtual_mapping_abc warm 411.6751269035533 382.9145728643216 -6.986225827039016 464.14141414141415 438.19095477386935 405.55555555555554 448.9949494949495 379.3103448275862 393.0693069306931 0 0 0 0 -expanded buffer_only_native warm 7325.0 7150.0 -2.3890784982935176 8325.0 7875.0 6950.0 7550.0 6925.0 7375.0 8856 26 8712 23 -expanded buffer_only_wrapper warm 5583.5 5283.333333333333 -5.375958926599211 6166.833333333333 5900.166666666667 5416.666666666667 5680.0 5250.0 5366.666666666667 768 22 640 20 -expanded interface_only_native warm 22200.0 21700.0 -2.2522522522522515 25000.0 24600.0 22100.0 23300.0 21600.0 22000.0 9368 55 9224 52 -expanded array_method_only_native warm 8133.333333333333 7633.333333333333 -6.147540983606559 9133.666666666666 8300.0 8033.333333333333 8366.666666666666 7600.0 7867.0 9016 30 8872 27 -expanded ndarray_native warm 4866.666666666667 4685.714285714285 -3.718199608610584 5416.666666666667 5214.285714285715 4666.666666666667 4983.333333333333 4585.714285714285 4700.0 8888 23 8744 20 -expanded ndarray_wrapper warm 3387.5 3287.5 -2.9520295202952074 3862.625 3800.0 3325.0 3550.0 3200.125 3337.5 800 19 672 17 -expanded two_matching_first_success warm 3437.5 3500.0 1.8181818181818077 3850.0 3925.0 3362.5 3725.0 3475.0 3562.5 560 18 560 18 -expanded two_matching_first_declines warm 4228.571428571428 4428.714285714285 4.733108108108097 5057.142857142857 5157.285714285715 4200.0 4528.571428571428 4400.0 4671.428571428572 720 24 720 24 -expanded two_matching_decline_then_ordinary warm 4528.571428571428 4657.142857142857 2.8391167192429068 4728.714285714285 5443.0 4528.571428571428 4528.571428571428 4628.571428571428 5214.285714285715 752 25 752 25 diff --git a/benchmark/convert-unwrapped.patch b/benchmark/convert-unwrapped.patch deleted file mode 100644 index ef9b25b81..000000000 --- a/benchmark/convert-unwrapped.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- a/src/Convert/pyconvert.jl -+++ b/src/Convert/pyconvert.jl -@@ -96,2 +96,4 @@ --# Internal helpers use the same representation as public pytryconvert. --@inline pyconvert_return(x) = Some(x) -+# Rule results only need a wrapper when the successful value is ambiguous. -+# Public pytryconvert still wraps every success in Some. -+@inline pyconvert_return(x) = x -+@inline pyconvert_return(x::Union{Nothing,Some}) = Some(x) -@@ -101,0 +104,2 @@ -+@inline pyconvert_result(::Type{T}, x) where T = x::T -+@inline pyconvert_result(x) = x -@@ -135 +139 @@ --pyconvert_tryconvert(::Type{T}, x::T) where T = Some(x) -+pyconvert_tryconvert(::Type{T}, x::T) where T = pyconvert_return(x) -@@ -138 +142 @@ -- Some(convert(T, x)::T) -+ pyconvert_return(convert(T, x)::T) ---- a/src/Convert/rules.jl -+++ b/src/Convert/rules.jl -@@ -63 +63 @@ -- result === PYCONVERT_FAILED ? nothing : Some(pyconvert_unpack(result)) -+ result === PYCONVERT_FAILED ? nothing : pyconvert_return(pyconvert_unpack(result)) -@@ -215 +215 @@ -- return Some(T0 === Union{} ? Vector{T1}() : ans) -+ return pyconvert_return(T0 === Union{} ? Vector{T1}() : ans) -@@ -290 +290 @@ -- return Some(isempty(ans) ? Dict{K0 === Union{} ? K1 : K0,V0 === Union{} ? V1 : V0}() : ans) -+ return pyconvert_return(isempty(ans) ? Dict{K0 === Union{} ? K1 : K0,V0 === Union{} ? V1 : V0}() : ans) From a9e4ce688a6d18e55d7b43c6598210a1fbf9c0a1 Mon Sep 17 00:00:00 2001 From: Christopher Rowley Date: Sun, 8 Nov 2026 20:25:32 +0000 Subject: [PATCH 3/7] Register conversion rules through public Python API locations --- src/Convert/pandas.jl | 5 +++-- src/Convert/pyconvert.jl | 5 +++-- src/Wrap/Wrap.jl | 9 +++------ test/ConvertRedesign.jl | 30 +++++++++++++++++++++++++++++- 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/src/Convert/pandas.jl b/src/Convert/pandas.jl index cc38c9cb7..aedb603eb 100644 --- a/src/Convert/pandas.jl +++ b/src/Convert/pandas.jl @@ -2,11 +2,12 @@ pyconvert_rule_pandas_na(::Type{Nothing}, x::Py) = pyconvert_return(nothing) pyconvert_rule_pandas_na(::Type{Missing}, x::Py) = pyconvert_return(missing) function init_pandas() + # pandas.NA is public across supported versions, even where NAType is not. pyconvert_add_rule( - "pandas._libs.missing:NAType", + "pandas:NA.__class__", Missing, pyconvert_rule_pandas_na, ; scope=Any, ) - pyconvert_add_rule("pandas._libs.missing:NAType", Nothing, pyconvert_rule_pandas_na) + pyconvert_add_rule("pandas:NA.__class__", Nothing, pyconvert_rule_pandas_na) end diff --git a/src/Convert/pyconvert.jl b/src/Convert/pyconvert.jl index 10b449348..d36abafd3 100644 --- a/src/Convert/pyconvert.jl +++ b/src/Convert/pyconvert.jl @@ -432,11 +432,12 @@ function pyconvertarg(::Type{T}, x, name) where T end function init_pyconvert() + pyimport("types") pyimport("numbers") pyimport("collections.abc") pyimport("io") pyconvert_source!("builtins:object") - pyconvert_add_rule("builtins:NoneType", Nothing, pyconvert_rule_none; scope=Any) + pyconvert_add_rule("types:NoneType", Nothing, pyconvert_rule_none; scope=Any) pyconvert_add_rule("builtins:bool", Bool, pyconvert_rule_bool; scope=Any) pyconvert_add_rule("builtins:float", Float64, pyconvert_rule_float; scope=Any) pyconvert_add_rule( @@ -483,7 +484,7 @@ function init_pyconvert() scope = Any, ) - pyconvert_add_rule("builtins:NoneType", Missing, pyconvert_rule_none) + pyconvert_add_rule("types:NoneType", Missing, pyconvert_rule_none) pyconvert_add_rule("builtins:bool", Number, pyconvert_rule_bool) # Real/Complex ABC membership does not promise lossless __float__/__complex__. # Integral and Rational sources have their own exact representation rules. diff --git a/src/Wrap/Wrap.jl b/src/Wrap/Wrap.jl index 9a8da5768..a638e443b 100644 --- a/src/Wrap/Wrap.jl +++ b/src/Wrap/Wrap.jl @@ -51,13 +51,10 @@ function __init__() pyconvert_add_rule("collections.abc:Set", PySet, pyconvert_rule_set) pyconvert_add_rule("collections.abc:Mapping", PyDict, pyconvert_rule_mapping) pyconvert_add_rule("io:IOBase", PyIO, pyconvert_rule_io; scope=Any) + # This private C base is distinct from the public io.IOBase ABC. pyconvert_add_rule("_io:_IOBase", PyIO, pyconvert_rule_io; scope=Any) - for source in ("pandas.core.frame:DataFrame", "pandas:DataFrame") - pyconvert_add_rule(source, PyPandasDataFrame, pyconvert_rule_pandasdataframe; scope=Any) - end - for source in ("pandas.core.arrays.base:ExtensionArray", "pandas.api.extensions:ExtensionArray") - pyconvert_add_rule(source, PyList, pyconvert_rule_sequence; scope=Any) - end + pyconvert_add_rule("pandas:DataFrame", PyPandasDataFrame, pyconvert_rule_pandasdataframe; scope=Any) + pyconvert_add_rule("pandas.api.extensions:ExtensionArray", PyList, pyconvert_rule_sequence; scope=Any) end end diff --git a/test/ConvertRedesign.jl b/test/ConvertRedesign.jl index 24a3c1bc8..0337079dd 100644 --- a/test/ConvertRedesign.jl +++ b/test/ConvertRedesign.jl @@ -279,7 +279,7 @@ end @testitem "scalar dispatch preserves singleton rules and overflow behavior" begin using PythonCall CV=PythonCall.Convert - original=only(r for r in CV.PYCONVERT_RULES if r.source=="builtins:NoneType" && r.type===Nothing) + original=only(r for r in CV.PYCONVERT_RULES if r.source=="types:NoneType" && r.type===Nothing) x=pybuiltins.None @test pyconvert(Nothing,x) === nothing calls=Ref(0) @@ -480,6 +480,34 @@ class Child(Outer.Internal): pass end end +@testitem "built-in rules use public source locations" begin + using PythonCall + CV = PythonCall.Convert + @test pyconvert(Any,pybuiltins.None) === nothing + @test first(pyconvert_rules(Any,pybuiltins.None)).source == "types:NoneType" + @test pyis(CV.pyconvert_resolve("types:NoneType"),pytype(pybuiltins.None)) + io = pyimport("io") + privatebase = pyimport("_io")._IOBase + @test !pyis(io.IOBase,privatebase) + @test pyconvert(Any,io.BytesIO()) isa PyIO + @test pyconvert(PyIO,privatebase()) isa PyIO + if pyis(pyimport("importlib.util").find_spec("pandas"),pybuiltins.None) + @test_skip false # pandas is an optional development dependency + else + pd = pyimport("pandas") + @test pyconvert(Any,pd.NA) === missing + @test pytryconvert(Nothing,pd.NA) === Some(nothing) + @test all(r.source=="pandas:NA.__class__" for r in pyconvert_rules(Any,pd.NA)) + df = pd.DataFrame() + @test pyconvert(Any,df) isa PyPandasDataFrame + @test count(r->r.source=="pandas:DataFrame",pyconvert_rules(Any,df)) == 1 + a = pd.array(pylist([1,2]);dtype="Int64") + @test pyconvert(PyList,a) isa PyList + @test count(r->r.source=="pandas.api.extensions:ExtensionArray",pyconvert_rules(PyList,a)) == 1 + @test !any(r->startswith(r.source,"pandas.core.") || startswith(r.source,"pandas._libs."),CV.PYCONVERT_RULES) + end +end + @testitem "priority topological sort agrees with grouped sorting" begin using PythonCall CV = PythonCall.Convert From e48cf2ffe498157d80eefe30aad3cb45f92ad984 Mon Sep 17 00:00:00 2001 From: Christopher Rowley Date: Sun, 8 Nov 2026 20:35:57 +0000 Subject: [PATCH 4/7] Support None as a conversion source shorthand --- docs/src/conversion-to-julia.md | 2 ++ src/Convert/pyconvert.jl | 7 +++++-- test/ConvertRedesign.jl | 25 +++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/docs/src/conversion-to-julia.md b/docs/src/conversion-to-julia.md index 7b2b1b742..4bdaa6de2 100644 --- a/docs/src/conversion-to-julia.md +++ b/docs/src/conversion-to-julia.md @@ -139,6 +139,8 @@ match the type's `__module__` or `__qualname__`: a public re-export such as A bare name abbreviates a built-in: `"list"` means `"builtins:list"`, so `prefer=("list" => PyList,)` opts into list wrappers. Aliases resolving to the same Python type share source ordering; their rules retain creation order. +The special shorthand `"None"` means `"types:NoneType"`; for example, +`pyconvert(Any, x; prefer=("None" => Missing,))` converts Python None to missing. Optional modules are never imported merely to resolve rules or preferences. Pending rules enter the global order when their module is diff --git a/src/Convert/pyconvert.jl b/src/Convert/pyconvert.jl index d36abafd3..7c592c7aa 100644 --- a/src/Convert/pyconvert.jl +++ b/src/Convert/pyconvert.jl @@ -23,15 +23,18 @@ const PYCONVERT_MODULES = Set{String}() const PYCONVERT_PROTOCOLS = ("", "", "", "") # Normalize at registration/context construction, rather than during dispatch. -pyconvert_source_name(name::String) = +function pyconvert_source_name(name::String) + name == "None" && return "types:NoneType" name in PYCONVERT_PROTOCOLS || ':' in name ? name : "builtins:" * name +end """ PyConvertContext(; prefer=()) Explicit conversion context. Preferences are ordered `"module:name" => JuliaType` pairs, resolved by attribute lookup in loaded modules. A bare name abbreviates -`"builtins:name"`. Rules propagate preferences by calling `pyconvert(ctx, T, child)` +`"builtins:name"`, except `"None"` abbreviates `"types:NoneType"`. +Rules propagate preferences by calling `pyconvert(ctx, T, child)` explicitly. """ struct PyConvertContext{P} diff --git a/test/ConvertRedesign.jl b/test/ConvertRedesign.jl index 0337079dd..002b95bf2 100644 --- a/test/ConvertRedesign.jl +++ b/test/ConvertRedesign.jl @@ -508,6 +508,31 @@ end end end +@testitem "None source shorthand" begin + using PythonCall + CV = PythonCall.Convert + x = pybuiltins.None + pref = ("None"=>Missing,) + @test pyis(CV.pyconvert_resolve("None"),pytype(x)) + @test pyconvert(Any,x;prefer=pref) === missing + @test pytryconvert(Any,x;prefer=pref) === Some(missing) + @test pyconvert(Nothing,x;prefer=pref) === nothing + @test pyconvert(Any,pyint(1);prefer=pref) === 1 + ctx = PyConvertContext(;prefer=pref) + @test pyconvert(ctx,Any,x) === missing + @test isequal(pyconvert(ctx,Vector,pylist([x])),[missing]) + @test pyconvert(Any,x) === nothing + id = pyconvert_add_rule("None",String,(_,_) -> "none") + try + @test pyconvert(String,x) == "none" + @test only(r.source for r in pyconvert_rules(String,x) if r.id==id) == "types:NoneType" + @test pyconvert_replace_rule(id,"None",String,(_,_) -> "replaced") == id + @test pyconvert(String,x) == "replaced" + finally + pyconvert_remove_rule(id) + end +end + @testitem "priority topological sort agrees with grouped sorting" begin using PythonCall CV = PythonCall.Convert From c3fc640b20243eb7c193802dd759f7594bad8248 Mon Sep 17 00:00:00 2001 From: Christopher Rowley Date: Sun, 8 Nov 2026 20:40:34 +0000 Subject: [PATCH 5/7] Keep conversion tests independent of optional NumPy installation --- AGENTS.md | 4 ++++ test/ConvertRedesign.jl | 43 ++++++++++++++++++++++++----------------- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index be3cce5cd..643cdb550 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -32,6 +32,10 @@ The majority of tests live in the Julia package; Python tests cover functionalit - For numeric Python fixtures, use `pycomplex(real, imag)` when a Python complex value is needed. Passing a Julia `Complex` directly to a Python constructor can produce a Julia wrapper, which NumPy may treat as a sequence rather than a scalar. +- External-interpreter Julia CI jobs do not install NumPy/pandas development + dependencies. Keep synthetic conversion tests independent of them, and guard + library-specific checks with module availability (without hiding import errors + when a module is installed). Conda-backed jobs exercise those optional checks. - The benchmark suite is shared across the compared revisions: `main` uses `pydel!`, while `v1` uses `unsafe_pydel`. - `main` does not have `@pyregion`. Benchmark region wrappers must select a plain-body fallback before macro expansion; a runtime conditional around an unavailable macro still fails when loading the suite. - Julia CI caches can preserve Conda's build metadata without its root environment. Rebuild `Conda` before building `PyCall` or running tests to recreate that directory. diff --git a/test/ConvertRedesign.jl b/test/ConvertRedesign.jl index 002b95bf2..c6fa0a448 100644 --- a/test/ConvertRedesign.jl +++ b/test/ConvertRedesign.jl @@ -115,14 +115,12 @@ end pyimport("sys").modules["convert_protocol_test"]=ns pyexec(""" import abc -import numpy class A(metaclass=abc.ABCMeta): pass class B: pass A.register(B) class C(B): pass class IntSubclass(int): pass class FloatSubclass(float): pass -class Both(numpy.ndarray): pass """,ns.__dict__) ids=Int[] add(source,T,f;scope=Any)=(id=pyconvert_add_rule(source,T,f;scope);push!(ids,id);id) @@ -146,19 +144,24 @@ class Both(numpy.ndarray): pass @test pyconvert(Float64,ns.FloatSubclass(2)) == 2.0 add("convert_protocol_test:FloatSubclass",Float64,(_,_) -> 3.0) @test pyconvert(Float64,ns.FloatSubclass(2)) == 3.0 - a=ns.numpy.arange(3).view(ns.Both) - @test pyconvert(Any,a) isa Vector{<:Integer} - rows=pyconvert_rules(Any,a) - protocols=unique(r.source for r in rows if startswith(r.source,"<")) - @test collect(protocols) == ["","","",""] - i=add("numpy:ndarray",String,(_,_) -> "ndarray") - @test pyconvert(Any,a) == "ndarray" - rows=pyconvert_rules(Any,a) - @test first(rows).id==i - @test first(rows).priority==maximum(r.priority for r in rows) @test pyconvert(Any,pyjl([1,2])) == [1,2] @test first(pyconvert_rules(Any,pyjl([1,2]))).source=="juliacall:JlBase" - @test pyconvert(Any,ns.numpy.arange(2);prefer=("numpy:ndarray"=>PyArray,)) isa PyArray + if pyis(pyimport("importlib.util").find_spec("numpy"),pybuiltins.None) + @test_skip false # external interpreters need not have development dependencies + else + pyexec("import numpy\nclass Both(numpy.ndarray): pass",ns.__dict__) + a=ns.numpy.arange(3).view(ns.Both) + @test pyconvert(Any,a) isa Vector{<:Integer} + rows=pyconvert_rules(Any,a) + protocols=unique(r.source for r in rows if startswith(r.source,"<")) + @test collect(protocols) == ["","","",""] + i=add("numpy:ndarray",String,(_,_) -> "ndarray") + @test pyconvert(Any,a) == "ndarray" + rows=pyconvert_rules(Any,a) + @test first(rows).id==i + @test first(rows).priority==maximum(r.priority for r in rows) + @test pyconvert(Any,ns.numpy.arange(2);prefer=("numpy:ndarray"=>PyArray,)) isa PyArray + end finally foreach(pyconvert_remove_rule,ids) pyimport("sys").modules.pop("convert_protocol_test") @@ -374,11 +377,15 @@ numbers.Complex.register(ApproximateComplex) pyconvert_remove_rule(id) end # Supported NumPy scalars use their own representation-reading rules. - np = pyimport("numpy") - @test pyconvert(Int,np.int64(3)) === 3 - @test pyconvert(Float64,np.float32(1.5)) === 1.5 - @test pyconvert(ComplexF64,np.complex64(pycomplex(1,2))) === 1.0+2.0im - @test pytryconvert(Int,np.float64(3.5)) === nothing + if pyis(pyimport("importlib.util").find_spec("numpy"),pybuiltins.None) + @test_skip false # NumPy is optional for external-interpreter test jobs + else + np = pyimport("numpy") + @test pyconvert(Int,np.int64(3)) === 3 + @test pyconvert(Float64,np.float32(1.5)) === 1.5 + @test pyconvert(ComplexF64,np.complex64(pycomplex(1,2))) === 1.0+2.0im + @test pytryconvert(Int,np.float64(3.5)) === nothing + end finally pyimport("sys").modules.pop("convert_numeric_source_test") end From f5c1823df24f735ec780f9b0afd426af98db3ac2 Mon Sep 17 00:00:00 2001 From: Christopher Rowley Date: Sun, 8 Nov 2026 21:18:28 +0000 Subject: [PATCH 6/7] Normalize pytryconvert successes to raw values when unambiguous --- benchmark/convert-results.jl | 16 +++++++++++--- docs/src/conversion-to-julia.md | 8 +++++-- docs/src/v1-migration-guide.md | 5 ++++- src/Convert/pyconvert.jl | 22 ++++++++++++------- test/ConvertRedesign.jl | 38 +++++++++++++++++++++++++++------ 5 files changed, 68 insertions(+), 21 deletions(-) diff --git a/benchmark/convert-results.jl b/benchmark/convert-results.jl index b59a529c3..83822dff6 100644 --- a/benchmark/convert-results.jl +++ b/benchmark/convert-results.jl @@ -7,7 +7,17 @@ struct UnconvertedBaseline end (success ? (x::T) : UnconvertedBaseline())::Union{T,UnconvertedBaseline} end @noinline function new_result(::Type{T}, x, success) where T - (success ? Some(x::T) : nothing)::PythonCall.Convert.pyconvert_returntype(T) + (success ? Some(x::T) : nothing)::some_result_returntype(T) +end +# This candidate intentionally wraps every success, independently of the public API. +function some_result_bound(T) + T === Any && return Union{Nothing,Some} + T isa Union && return Union{some_result_bound(T.a),some_result_bound(T.b)} + isconcretetype(T) ? Union{Nothing,Some{T}} : Union{Nothing,Some{<:T}} +end +@generated some_result_returntype(::Type{T}) where T = QuoteNode(some_result_bound(T)) +@noinline function normalized_result(::Type{T}, x, success) where T + (success ? PythonCall.Convert.pyconvert_return(x::T) : nothing)::PythonCall.Convert.pyconvert_returntype(T) end @noinline escaping(x) = Ref{Any}(x) function consume(f,::Type{T},values) where T @@ -22,13 +32,13 @@ cases = [(Int64,1), (Float64,1.5), (String,"hello"), (Vector{Int},[1,2]), (Integer,1), (AbstractArray,[1,2]), (Union{Int64,Nothing},1), (Any,1)] open(joinpath(@__DIR__,"convert-results$label.tsv"),"w") do io println(io,"type\trepresentation\tsuccess\tescaping\tns\tbytes\tallocs") - for (T,x) in cases, (name,f) in (("raw",old_result),("some",new_result)), success in (true,false), escape in (true,false) + for (T,x) in cases, (name,f) in (("raw",old_result),("some",new_result),("normalized",normalized_result)), success in (true,false), escape in (true,false) b = escape ? (@benchmark escaping($f($T,$x,$success)) seconds=0.1 samples=500) : (@benchmark $f($T,$x,$success) seconds=0.1 samples=500) m=minimum(b) println(io,"$T\t$name\t$success\t$escape\t$(m.time)\t$(m.memory)\t$(m.allocs)") end - for (name,f) in (("raw",old_result),("some",new_result)) + for (name,f) in (("raw",old_result),("some",new_result),("normalized",normalized_result)) values=collect(1:100) m=minimum(@benchmark consume($f,Int,$values) seconds=0.1 samples=500) println(io,"loop100\t$name\ttrue\tfalse\t$(m.time)\t$(m.memory)\t$(m.allocs)") diff --git a/docs/src/conversion-to-julia.md b/docs/src/conversion-to-julia.md index 4bdaa6de2..b80137392 100644 --- a/docs/src/conversion-to-julia.md +++ b/docs/src/conversion-to-julia.md @@ -101,8 +101,12 @@ return `nothing`, and `Some(Some(value))` to return an actual `Some`. Prefer returning ordinary values directly. An unnecessary `Some` can allocate when its concrete type crosses a dispatch boundary; built-in rules wrap only successful `nothing` and `Some` values. -`pytryconvert([ctx,] T,x)` always returns `nothing` on failure and -`Some(value)` on success. Both `f(ctx,T,x)` and `f(T,x)` rules are +`pytryconvert([ctx,] T,x)` returns `nothing` on failure and normalizes successes +to the same convention: ordinary values directly, `Some(nothing)` for a +successful nothing, and `Some(Some(value))` for an actual Some value. +Check `result === nothing` for failure; `something(result)` unwraps a success, +and `something(result, default)` handles both outcomes with a default. +Both `f(ctx,T,x)` and `f(T,x)` rules are supported; the context-aware form is preferred when applicable to that target. A rule receives a non-union target: each arm of the output/request intersection is tried before moving to the next rule. Union arm order is diff --git a/docs/src/v1-migration-guide.md b/docs/src/v1-migration-guide.md index b28416630..dcffb9e58 100644 --- a/docs/src/v1-migration-guide.md +++ b/docs/src/v1-migration-guide.md @@ -25,7 +25,10 @@ to remove or update it. Rules now return `nothing` to decline, a value to succeed, or `Some(value)` for explicit success. Replace `pyconvert_unconverted()` with `nothing` and `pyconvert_return(x)` with `Some(x)` (or simply `x` when it is neither `nothing` -nor a `Some`). `pytryconvert(T,x)` consistently returns `nothing` or `Some(value)`. +nor a `Some`). `pytryconvert(T,x)` uses the same normalized convention: failure is +`nothing`, ordinary successes are raw values, and successful `nothing`/`Some` +values are wrapped once. Test `r === nothing` for failure and use `something(r)` +to recover a success, or `something(r, default)` for a default on failure. Rule functions may accept `(ctx,T,x)` to propagate preferences explicitly with `pyconvert(ctx,T,child)`. See [conversion to Julia](@ref py2jl) for scope, ordering and context details. diff --git a/src/Convert/pyconvert.jl b/src/Convert/pyconvert.jl index 7c592c7aa..485a9911e 100644 --- a/src/Convert/pyconvert.jl +++ b/src/Convert/pyconvert.jl @@ -97,7 +97,7 @@ function pyconvert_replace_rule(id::Integer, source::String, T::Type, f::Functio end # Rule results only need a wrapper when the successful value is ambiguous. -# Public pytryconvert still wraps every success in Some. +# The same encoding is used for normalized public pytryconvert results. @inline pyconvert_return(x) = x @inline pyconvert_return(x::Union{Nothing,Some}) = Some(x) @inline pyconvert_unconverted() = nothing @@ -107,14 +107,18 @@ end @inline pyconvert_result(::Type{T}, x) where T = x::T @inline pyconvert_result(x) = x function _pyconvert_returntype(T::Type) - T === Any && return Union{Nothing,Some} + T === Any && return Any + T === Union{} && return Nothing T isa Union && return Union{_pyconvert_returntype(T.a),_pyconvert_returntype(T.b)} - isconcretetype(T) && return Union{Nothing,Some{T}} - Union{Nothing,Some{<:T}} + T <: Nothing && return Union{Nothing,Some{Nothing}} + if T <: Some + return isconcretetype(T) ? Union{Nothing,Some{T}} : Union{Nothing,Some{<:T}} + end + Union{Nothing,T} end @generated pyconvert_returntype(::Type{T}) where T = QuoteNode(_pyconvert_returntype(T)) # Avoid allocating an escaping Some for every element of an inferred container. -# The public/rule contract remains Some/nothing. Only dispatch uses this private +# Public/rule results wrap only ambiguous successes. Dispatch uses this private # sentinel, with an escape for values that happen to use our internal types. struct PyConvertFailure end struct PyConvertEscape{T} @@ -351,14 +355,16 @@ end pytryconvert(T, x; prefer=()) pytryconvert(ctx::PyConvertContext, T, x) -Return `Some(value)` on successful conversion and `nothing` on decline. -The successful value is a `T`; exceptions from conversion rules propagate. +Return `nothing` on decline and otherwise the converted value directly, except +successful `nothing` and `Some` values are wrapped in `Some`. After checking for +failure, `something(result)` recovers the successful value, which is a `T`. +Exceptions from conversion rules propagate. """ function pytryconvert(ctx::PyConvertContext, ::Type{T}, x) where T @pyregion begin ans = pytryconvert_raw(ctx,T,x) ans === PYCONVERT_FAILED && return nothing - Some(pyconvert_unpack(ans)::T)::pyconvert_returntype(T) + pyconvert_return(pyconvert_unpack(ans)::T)::pyconvert_returntype(T) end end pytryconvert(::Type{T}, x; prefer=()) where T = pytryconvert(PyConvertContext(;prefer),T,x) diff --git a/test/ConvertRedesign.jl b/test/ConvertRedesign.jl index c6fa0a448..dfa20491c 100644 --- a/test/ConvertRedesign.jl +++ b/test/ConvertRedesign.jl @@ -218,12 +218,17 @@ end @test pyconvert(Any,x) === nothing pyconvert_replace_rule(id,source,Any,(_,_) -> missing;scope=Any) @test pyconvert(Any,x) === missing + @test pytryconvert(Any,x) === missing + pyconvert_replace_rule(id,source,Any,(_,_) -> Some(42);scope=Any) + @test pytryconvert(Int,x) === 42 + @test pytryconvert(Any,x) === 42 pyconvert_replace_rule(id,source,Any,(_,_) -> Some(Some(2));scope=Any) @test pyconvert(Any,x) === Some(2) for value in (CV.PYCONVERT_FAILED, CV.PyConvertEscape(1), Some(nothing)) pyconvert_replace_rule(id,source,Any,(_,_) -> Some(value);scope=Any) @test pyconvert(Any,x) === value - @test pytryconvert(Any,x) === Some(value) + expected = value isa Union{Nothing,Some} ? Some(value) : value + @test pytryconvert(Any,x) === expected @test pyconvert(typeof(value),x) === value end # Built-in result encoding must preserve ambiguous values exactly once. @@ -231,15 +236,17 @@ end [1,2], CV.PYCONVERT_FAILED, CV.PyConvertEscape(1)) pyconvert_replace_rule(id,source,Any,(_,_) -> CV.pyconvert_return(value);scope=Any) @test pyconvert(Any,x) === value - @test pytryconvert(typeof(value),x) === Some(value) + expected = value isa Union{Nothing,Some} ? Some(value) : value + @test pytryconvert(typeof(value),x) === expected @test pyconvert(Any,pyjl(value)) === value - @test pytryconvert(typeof(value),pyjl(value)) === Some(value) + @test pytryconvert(typeof(value),pyjl(value)) === expected end @test pyconvert(Any,pylist([pyjl(Some(1)),pyjl(nothing)])) == [Some(1),nothing] @test pyconvert(Any,pydict("some"=>pyjl(Some(1)),"none"=>pyjl(nothing))) == Dict("some"=>Some(1),"none"=>nothing) pyconvert_replace_rule(id,source,Any,(_,_) -> nothing;scope=Any) @test pyconvert(Any,x) === x # implicit fallback + @test pytryconvert(Any,x) === x @test pytryconvert(Int,x) === nothing pyconvert_replace_rule(id,source,Any,(_,_) -> error("rule error");scope=Any) @test_throws "rule error" pyconvert(Any,x) @@ -266,12 +273,29 @@ end finally pyconvert_remove_rule(second) end - @test Some(1) isa CV.pyconvert_returntype(Integer) + @test 1 isa CV.pyconvert_returntype(Integer) @test Some(nothing) isa CV.pyconvert_returntype(Union{Int,Nothing}) @test Some(1) isa CV.pyconvert_returntype(Any) - @test CV.pyconvert_returntype(Int) === Union{Nothing,Some{Int}} - @test CV.pyconvert_returntype(Union{Int,Nothing}) === Union{Nothing,Some{Int},Some{Nothing}} + @test CV.pyconvert_returntype(Int) === Union{Nothing,Int} + @test CV.pyconvert_returntype(Integer) === Union{Nothing,Integer} + @test CV.pyconvert_returntype(Any) === Any + @test CV.pyconvert_returntype(Union{}) === Nothing + @test CV.pyconvert_returntype(Union{Int,Nothing}) === Union{Nothing,Int,Some{Nothing}} + @test CV.pyconvert_returntype(Some{Int}) === Union{Nothing,Some{Some{Int}}} + @test CV.pyconvert_returntype(Union{Int,Some{Int}}) === Union{Nothing,Int,Some{Some{Int}}} + @test Some(Some(1)) isa CV.pyconvert_returntype(Some{<:Integer}) + @test CV.pyconvert_returntype(Vector{<:Real}) == Union{Nothing,Vector{<:Real}} @test (@inferred pyconvert(Int,pyint(1))) === 1 + @test (@inferred Nothing pytryconvert(Int,pyint(1))) === 1 + @test (@inferred Nothing pytryconvert(Float64,pyfloat(1.5))) === 1.5 + @test pytryconvert(Union{Nothing,Int},pyint(1)) === 1 + @test pytryconvert(Union{Nothing,Int},pybuiltins.None) === Some(nothing) + @test pytryconvert(Some{Int},pyjl(Some(1))) === Some(Some(1)) + @test pytryconvert(Union{Int,Some{Int}},pyjl(Some(1))) === Some(Some(1)) + @test only(Base.return_types(pytryconvert,Tuple{Type{Integer},Py})) === Union{Nothing,Integer} + @test something(pytryconvert(Int,pystr("bad")),:default) === :default + @test something(pytryconvert(Nothing,pybuiltins.None),:default) === nothing + @test something(pytryconvert(Some{Int},pyjl(Some(1)))) === Some(1) @test pytryconvert(Nothing,pybuiltins.None) === Some(nothing) finally pyconvert_remove_rule(id) @@ -522,7 +546,7 @@ end pref = ("None"=>Missing,) @test pyis(CV.pyconvert_resolve("None"),pytype(x)) @test pyconvert(Any,x;prefer=pref) === missing - @test pytryconvert(Any,x;prefer=pref) === Some(missing) + @test pytryconvert(Any,x;prefer=pref) === missing @test pyconvert(Nothing,x;prefer=pref) === nothing @test pyconvert(Any,pyint(1);prefer=pref) === 1 ctx = PyConvertContext(;prefer=pref) From 99f65d56737a3e2577b3636f049e012d9f9b8440 Mon Sep 17 00:00:00 2001 From: Christopher Rowley Date: Sun, 8 Nov 2026 22:22:12 +0000 Subject: [PATCH 7/7] Address review feedback on API ownership and conversion rule placement --- src/API/exports.jl | 1 + src/API/types.jl | 14 ++++++++++++++ src/Convert/Convert.jl | 2 +- src/Convert/pyconvert.jl | 29 +++++++++++++++++------------ src/Convert/rules.jl | 11 +++++++++++ src/JlWrap/JlWrap.jl | 1 - src/PythonCall.jl | 2 -- src/Wrap/PyArray.jl | 9 --------- src/Wrap/Wrap.jl | 14 ++------------ test/ConvertRedesign.jl | 9 +++++++++ 10 files changed, 55 insertions(+), 37 deletions(-) diff --git a/src/API/exports.jl b/src/API/exports.jl index a61c97dfc..dae455d0c 100644 --- a/src/API/exports.jl +++ b/src/API/exports.jl @@ -103,6 +103,7 @@ export pyxor export unsafe_pydel # Convert +export PyConvertContext export @pyconvert export pyconvert export pyconvert_add_rule diff --git a/src/API/types.jl b/src/API/types.jl index 79252afbb..099eb80e8 100644 --- a/src/API/types.jl +++ b/src/API/types.jl @@ -1,3 +1,17 @@ +# Convert + +""" + PyConvertContext(; prefer=()) + +Explicit conversion context. Preferences are ordered `"module:name" => JuliaType` +pairs, resolved by attribute lookup in loaded modules. A bare name abbreviates +`"builtins:name"`, except `"None"` abbreviates `"types:NoneType"`. +Rules propagate preferences by calling `pyconvert(ctx, T, child)` explicitly. +""" +struct PyConvertContext{P} + prefer::P +end + # Core """ diff --git a/src/Convert/Convert.jl b/src/Convert/Convert.jl index 7939769f9..2f95accb1 100644 --- a/src/Convert/Convert.jl +++ b/src/Convert/Convert.jl @@ -14,6 +14,7 @@ using ..NumpyDates using Dates: Date, Time, DateTime, Second, Millisecond, Microsecond, Nanosecond import ..PythonCall: + PyConvertContext, @pyconvert, pyconvert_add_rule, pyconvert, @@ -23,7 +24,6 @@ import ..PythonCall: pyconvert_rules export pyconvert_return, - PyConvertContext, pyconvert_isunconverted, pyconvert_result, pyconvert_tryconvert, diff --git a/src/Convert/pyconvert.jl b/src/Convert/pyconvert.jl index 485a9911e..c260c7764 100644 --- a/src/Convert/pyconvert.jl +++ b/src/Convert/pyconvert.jl @@ -28,18 +28,6 @@ function pyconvert_source_name(name::String) name in PYCONVERT_PROTOCOLS || ':' in name ? name : "builtins:" * name end -""" - PyConvertContext(; prefer=()) - -Explicit conversion context. Preferences are ordered `"module:name" => JuliaType` -pairs, resolved by attribute lookup in loaded modules. A bare name abbreviates -`"builtins:name"`, except `"None"` abbreviates `"types:NoneType"`. -Rules propagate preferences by calling `pyconvert(ctx, T, child)` -explicitly. -""" -struct PyConvertContext{P} - prefer::P -end PyConvertContext(; prefer=()) = PyConvertContext(map(p -> pyconvert_source_name(first(p)) => Val(last(p)), prefer)) const PYCONVERT_DEFAULT_CONTEXT = PyConvertContext() @@ -536,4 +524,21 @@ function init_pyconvert() pyconvert_add_rule("datetime:timedelta", Second, pyconvert_rule_timedelta) pyconvert_add_rule("datetime:timedelta", Nanosecond, pyconvert_rule_timedelta) + pyconvert_add_rule("builtins:list", Vector, pyconvert_rule_iterable; scope=Any) + pyconvert_add_rule("builtins:dict", Dict, pyconvert_rule_mapping; scope=Any) + for source in ("builtins:set", "builtins:frozenset") + pyconvert_add_rule(source, Set, pyconvert_rule_iterable; scope=Any) + end + # Independent protocol matchers retain their definition-order precedence. + for source in PYCONVERT_PROTOCOLS + pyconvert_add_rule(source, Array, pyconvert_rule_array; scope=Any) + end +end + +# Wrap calls this after registering explicit PyArray rules. Within each protocol +# source, wrapper requests must try those before the generic AbstractArray rule. +function init_pyconvert_array_fallbacks() + for source in PYCONVERT_PROTOCOLS + pyconvert_add_rule(source, AbstractArray, pyconvert_rule_array) + end end diff --git a/src/Convert/rules.jl b/src/Convert/rules.jl index 2dc3c0b50..4a1bf18fa 100644 --- a/src/Convert/rules.jl +++ b/src/Convert/rules.jl @@ -201,6 +201,17 @@ function pyconvert_rule_fraction(::Type{T}, x::Py) where {T<:Number} pyconvert_tryconvert(T, @pyconvert(Rational{<:Integer}, x)) end +### arrays + +function pyconvert_rule_array(::Type{A}, x::Py) where {A<:AbstractArray} + r = PythonCall.Wrap.pyarray_make(PyArray, x) + if pyconvert_isunconverted(r) + return pyconvert_unconverted() + else + return pyconvert_tryconvert(A, pyconvert_result(PyArray, r)) + end +end + ### collections # Vector diff --git a/src/JlWrap/JlWrap.jl b/src/JlWrap/JlWrap.jl index 06a4f005e..dfdf9ff28 100644 --- a/src/JlWrap/JlWrap.jl +++ b/src/JlWrap/JlWrap.jl @@ -11,7 +11,6 @@ using ..NumpyDates: NumpyDates using ..C using ..Core using ..Convert -using ..Convert: pyconvert_return using ..GC: GC import ..PythonCall: diff --git a/src/PythonCall.jl b/src/PythonCall.jl index 97f567093..a6dec7345 100644 --- a/src/PythonCall.jl +++ b/src/PythonCall.jl @@ -9,8 +9,6 @@ include("C/C.jl") include("GC/GC.jl") include("Core/Core.jl") include("Convert/Convert.jl") -using .Convert: PyConvertContext -export PyConvertContext include("PyMacro/PyMacro.jl") include("Wrap/Wrap.jl") include("JlWrap/JlWrap.jl") diff --git a/src/Wrap/PyArray.jl b/src/Wrap/PyArray.jl index 6b5ad0658..0d20777d9 100644 --- a/src/Wrap/PyArray.jl +++ b/src/Wrap/PyArray.jl @@ -18,15 +18,6 @@ end pyconvert_rule_array_nocopy(::Type{A}, x::Py) where {A<:PyArray} = pyarray_make(A, x, copy = false) -function pyconvert_rule_array(::Type{A}, x::Py) where {A<:AbstractArray} - r = pyarray_make(PyArray, x) - if pyconvert_isunconverted(r) - return pyconvert_unconverted() - else - return pyconvert_tryconvert(A, pyconvert_result(PyArray, r)) - end -end - # Expected unsupported representations may decline; arbitrary errors must propagate. struct PyArrayUnsupported <: Exception message::String diff --git a/src/Wrap/Wrap.jl b/src/Wrap/Wrap.jl index a638e443b..f8633dd38 100644 --- a/src/Wrap/Wrap.jl +++ b/src/Wrap/Wrap.jl @@ -11,7 +11,6 @@ using ..NumpyDates using ..C using ..Core using ..Convert -using ..Convert: pyconvert_return using ..PyMacro import ..PythonCall: @@ -33,19 +32,10 @@ include("PyTable.jl") include("PyPandasDataFrame.jl") function __init__() - # Native materialized containers precede explicit wrappers on the same source. - pyconvert_add_rule("builtins:list", Vector, Convert.pyconvert_rule_iterable; scope=Any) - pyconvert_add_rule("builtins:dict", Dict, Convert.pyconvert_rule_mapping; scope=Any) - for source in ("builtins:set", "builtins:frozenset") - pyconvert_add_rule(source, Set, Convert.pyconvert_rule_iterable; scope=Any) - end - # Definition order retains struct/interface/array/buffer precedence. Protocols - # are independent matchers; no protocol implies another protocol. - for source in ("", "", "", "") - pyconvert_add_rule(source, Array, pyconvert_rule_array; scope=Any) + for source in Convert.PYCONVERT_PROTOCOLS pyconvert_add_rule(source, PyArray, pyconvert_rule_array_nocopy) - pyconvert_add_rule(source, AbstractArray, pyconvert_rule_array) end + Convert.init_pyconvert_array_fallbacks() pyconvert_add_rule("collections.abc:Iterable", PyIterable, pyconvert_rule_iterable; scope=Any) pyconvert_add_rule("collections.abc:Sequence", PyList, pyconvert_rule_sequence) pyconvert_add_rule("collections.abc:Set", PySet, pyconvert_rule_set) diff --git a/test/ConvertRedesign.jl b/test/ConvertRedesign.jl index dfa20491c..018291aa9 100644 --- a/test/ConvertRedesign.jl +++ b/test/ConvertRedesign.jl @@ -58,6 +58,15 @@ end @testitem "native containers and preferences" begin using PythonCall + @test parentmodule(PyConvertContext) === PythonCall + # Explicit wrappers must precede the generic native-array fallback even + # though the registrations are initialized by different modules. + CV = PythonCall.Convert + for source in CV.PYCONVERT_PROTOCOLS + rules = filter(r->r.source==source,CV.PYCONVERT_RULES) + @test [r.type for r in rules] == [Array,PyArray,AbstractArray] + @test first(filter(r->CV.pyconvert_eligible(r,PyArray),rules)).type === PyArray + end cases = [(Any[],Any), ([1,2],Int), (Any[1,2.5],Real), ([1,"two"],Any), ([nothing,1],Union{Nothing,Int})] for (values,T) in cases