JuliaPy / JuliaPy/PythonCall.jl

`@pyexec` fails to define functions or set global variables

オープン
#370 コメント 2 件 リアクション 0 件 担当者 0 名 GitHub で見る
bug
主要言語
Julia
スター
1.1k
フォーク
86
平均マージ
1日 22時間
マージ済み PR(30日)
3

説明

**Affects:** PythonCall

When I run `pyexec("x = 1", Main)`, it successfully sets the global variable. When, on the other hand, I run `@pyexec "x = 1"`, it does not. This extends to defining functions as well. It feels like a pretty serious bug to me. Maybe I'm misunderstanding how global environment management works?

```julia
julia> pyexec("x = 1", Main)

julia> pyeval("x", Main)
Python: 1

julia> @pyexec "y = 2"

julia> @pyeval "y"
ERROR: Python: NameError: name 'y' is not defined
Python stacktrace:
[1]
@ REPL[5]:1:1
Stacktrace:
[1] pythrow()
@ PythonCall ~/.julia/packages/PythonCall/qTEA1/src/err.jl:94
[2] errcheck
@ ~/.julia/packages/PythonCall/qTEA1/src/err.jl:10 [inlined]
[3] pycallargs(f::Py, args::Py)
@ PythonCall ~/.julia/packages/PythonCall/qTEA1/src/abstract/object.jl:210
[4] pycall(::Py, ::Py, ::Vararg{Py}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ PythonCall ~/.julia/packages/PythonCall/qTEA1/src/abstract/object.jl:228
[5] pycall
@ ~/.julia/packages/PythonCall/qTEA1/src/abstract/object.jl:218 [inlined]
[6] #_#11
@ ~/.julia/packages/PythonCall/qTEA1/src/Py.jl:341 [inlined]
[7] Py
@ ~/.julia/packages/PythonCall/qTEA1/src/Py.jl:341 [inlined]
[8] pyeval(::Type{Py}, code::Py, globals::Module, locals::Tuple{})
@ PythonCall ~/.julia/packages/PythonCall/qTEA1/src/concrete/code.jl:43
[9] top-level scope
@ ~/.julia/packages/PythonCall/qTEA1/src/concrete/code.jl:146
```

Full log

```julia
(@v1.9) pkg> activate --temp
Activating new project at `/var/folders/hc/fn82kz1j5vl8w7lwd4l079y80000gn/T/jl_NIT4tY`

(jl_NIT4tY) pkg> add PythonCall
[ Info: Use `./PythonCall` to add or develop the local directory at `~/.julia/dev/PythonCall`.
Resolving package versions...
Installed CondaPkg ─ v0.2.20
Updating `/private/var/folders/hc/fn82kz1j5vl8w7lwd4l079y80000gn/T/jl_NIT4tY/Project.toml`
[6099a3de] + PythonCall v0.9.14
Updating `/private/var/folders/hc/fn82kz1j5vl8w7lwd4l079y80000gn/T/jl_NIT4tY/Manifest.toml`
[992eb4ea] + CondaPkg v0.2.20
[9a962f9c] + DataAPI v1.15.0
[e2d170a0] + DataValueInterfaces v1.0.0
[82899510] + IteratorInterfaceExtensions v1.0.0
[692b3bcd] + JLLWrappers v1.5.0
[0f8b85d8] + JSON3 v1.13.2
[1914dd2f] + MacroTools v0.5.11
[0b3b1443] + MicroMamba v0.1.14
[bac558e1] + OrderedCollections v1.6.2
[69de0a69] + Parsers v2.7.2
[fa939f87] + Pidfile v1.3.0
[aea7be01] + PrecompileTools v1.2.0
[21216c6a] + Preferences v1.4.1
[6099a3de] + PythonCall v0.9.14
[ae029012] + Requires v1.3.0
[6c6a2e73] + Scratch v1.2.0
[856f2bd8] + StructTypes v1.10.0
[3783bdb8] + TableTraits v1.0.1
[bd369af6] + Tables v1.11.0
[e17b2a0c] + UnsafePointers v1.0.0
[f8abcde7] + micromamba_jll v1.4.9+0
[0dad84c5] + ArgTools v1.1.1
[56f22d72] + Artifacts
[2a0f44e3] + Base64
[ade2ca70] + Dates
[f43a241f] + Downloads v1.6.0
[7b1f6079] + FileWatching
[b77e0a4c] + InteractiveUtils
[4af54fe1] + LazyArtifacts
[b27032c2] + LibCURL v0.6.3
[76f85450] + LibGit2
[8f399da3] + Libdl
[37e2e46d] + LinearAlgebra
[56ddb016] + Logging
[d6f4376e] + Markdown
[a63ad114] + Mmap
[ca575930] + NetworkOptions v1.2.0
[44cfe95a] + Pkg v1.9.2
[de0858da] + Printf
[3fa0cd96] + REPL
[9a3f8284] + Random
[ea8e919c] + SHA v0.7.0
[9e88b42a] + Serialization
[6462fe0b] + Sockets
[fa267f1f] + TOML v1.0.3
[a4e569a6] + Tar v1.10.0
[8dfed614] + Test
[cf7118a7] + UUIDs
[4ec0a83e] + Unicode
[e66e0078] + CompilerSupportLibraries_jll v1.0.5+0
[deac9b47] + LibCURL_jll v7.84.0+0
[29816b5a] + LibSSH2_jll v1.10.2+0
[c8ffd9c3] + MbedTLS_jll v2.28.2+0
[14a3606d] + MozillaCACerts_jll v2022.10.11
[4536629a] + OpenBLAS_jll v0.3.21+4
[83775a58] + Zlib_jll v1.2.13+0
[8e850b90] + libblastrampoline_jll v5.8.0+0
[8e850ede] + nghttp2_jll v1.48.0+0
[3f19e933] + p7zip_jll v17.4.0+0
Precompiling project...
5 dependencies successfully precompiled in 12 seconds. 20 already precompiled.

julia> using PythonCall
[ Info: Precompiling PythonCall [6099a3de-0909-46bc-b1f4-468b9a2dfc0d]
CondaPkg Found dependencies: /Users/x/.julia/packages/PythonCall/qTEA1/CondaPkg.toml
CondaPkg Found dependencies: /Users/x/.julia/packages/SymPyPythonCall/yNd8x/CondaPkg.toml
CondaPkg Resolving changes
+ python
+ sympy
CondaPkg Creating environment
│ /Users/x/.julia/artifacts/5767a45b62528e0be4c40dbae502ad3e132f1d62/bin/micromamba
│ -r /Users/x/.julia/scratchspaces/0b3b1443-0f03-428d-bdfb-f27f9c1191ea/root
│ create
│ -y
│ -p /var/folders/hc/fn82kz1j5vl8w7lwd4l079y80000gn/T/jl_NIT4tY/.CondaPkg/env
│ --override-channels
│ --no-channel-priority
│ python[version='>=3.7,<4',channel='conda-forge',build='*cpython*']
│ python[version='*']
│ sympy[version='*']
└ -c conda-forge
conda-forge/noarch 12.5MB @ 3.0MB/s 4.2s
conda-forge/osx-arm64 6.8MB @ 1.1MB/s 6.4s

Transaction

Prefix: /private/var/folders/hc/fn82kz1j5vl8w7lwd4l079y80000gn/T/jl_NIT4tY/.CondaPkg/env

Updating specs:

- conda-forge::python[version='>=3.7,<4',build=*cpython*]
- python=*
- sympy=*

Package Version Build Channel Size
────────────────────────────────────────────────────────────────────────────
Install:
────────────────────────────────────────────────────────────────────────────

+ xz 5.2.6 h57fd34a_0 conda-forge Cached
+ libexpat 2.5.0 hb7217d7_1 conda-forge Cached
+ ncurses 6.4 h7ea286d_0 conda-forge Cached
+ libffi 3.4.2 h3422bc3_5 conda-forge Cached
+ libzlib 1.2.13 h53f4e23_5 conda-forge Cached
+ ca-certificates 2023.7.22 hf0a4a13_0 conda-forge Cached
+ python_abi 3.11 4_cp311 conda-forge Cached
+ libcxx 16.0.6 h4653b0c_0 conda-forge Cached
+ bzip2 1.0.8 h3422bc3_4 conda-forge Cached
+ readline 8.2 h92ec313_1 conda-forge Cached
+ libsqlite 3.43.0 hb31c410_0 conda-forge Cached
+ tk 8.6.12 he1e0b03_0 conda-forge Cached
+ openssl 3.1.3 h53f4e23_0 conda-forge Cached
+ gmp 6.2.1 h9f76cd9_0 conda-forge Cached
+ mpfr 4.2.0 he09a6ba_0 conda-forge Cached
+ mpc 1.3.1 h91ba8db_0 conda-forge Cached
+ tzdata 2023c h71feb2d_0 conda-forge Cached
+ python 3.11.5 h47c9636_0_cpython conda-forge Cached
+ wheel 0.41.2 pyhd8ed1ab_0 conda-forge Cached
+ setuptools 68.2.2 pyhd8ed1ab_0 conda-forge Cached
+ pip 23.2.1 pyhd8ed1ab_0 conda-forge Cached
+ mpmath 1.3.0 pyhd8ed1ab_0 conda-forge Cached
+ gmpy2 2.1.2 py311h2ba9262_1 conda-forge Cached
+ sympy 1.12 pypyh9d50eac_103 conda-forge Cached

Summary:

Install: 24 packages

Total download: 0 B

────────────────────────────────────────────────────────────────────────────

Transaction starting
Linking xz-5.2.6-h57fd34a_0
Linking libexpat-2.5.0-hb7217d7_1
Linking ncurses-6.4-h7ea286d_0
Linking libffi-3.4.2-h3422bc3_5
Linking libzlib-1.2.13-h53f4e23_5
Linking ca-certificates-2023.7.22-hf0a4a13_0
Linking python_abi-3.11-4_cp311
Linking libcxx-16.0.6-h4653b0c_0
Linking bzip2-1.0.8-h3422bc3_4
Linking readline-8.2-h92ec313_1
Linking libsqlite-3.43.0-hb31c410_0
Linking tk-8.6.12-he1e0b03_0
Linking openssl-3.1.3-h53f4e23_0
Linking gmp-6.2.1-h9f76cd9_0
Linking mpfr-4.2.0-he09a6ba_0
Linking mpc-1.3.1-h91ba8db_0
Linking tzdata-2023c-h71feb2d_0
Linking python-3.11.5-h47c9636_0_cpython
Linking wheel-0.41.2-pyhd8ed1ab_0
Linking setuptools-68.2.2-pyhd8ed1ab_0
Linking pip-23.2.1-pyhd8ed1ab_0
Linking mpmath-1.3.0-pyhd8ed1ab_0
Linking gmpy2-2.1.2-py311h2ba9262_1
Linking sympy-1.12-pypyh9d50eac_103

Transaction finished

To activate this environment, use:

micromamba activate /private/var/folders/hc/fn82kz1j5vl8w7lwd4l079y80000gn/T/jl_NIT4tY/.CondaPkg/env

Or to execute a single command in this environment, use:

micromamba run -p /private/var/folders/hc/fn82kz1j5vl8w7lwd4l079y80000gn/T/jl_NIT4tY/.CondaPkg/env mycommand

julia> pyexec("x = 1", Main)

julia> pyeval("x", Main)
Python: 1

julia> @pyexec "y = 2"

julia> @pyeval "y"
ERROR: Python: NameError: name 'y' is not defined
Python stacktrace:
[1]
@ REPL[7]:1:1
Stacktrace:
[1] pythrow()
@ PythonCall ~/.julia/packages/PythonCall/qTEA1/src/err.jl:94
[2] errcheck
@ ~/.julia/packages/PythonCall/qTEA1/src/err.jl:10 [inlined]
[3] pycallargs(f::Py, args::Py)
@ PythonCall ~/.julia/packages/PythonCall/qTEA1/src/abstract/object.jl:210
[4] pycall(::Py, ::Py, ::Vararg{Py}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ PythonCall ~/.julia/packages/PythonCall/qTEA1/src/abstract/object.jl:228
[5] pycall
@ ~/.julia/packages/PythonCall/qTEA1/src/abstract/object.jl:218 [inlined]
[6] #_#11
@ ~/.julia/packages/PythonCall/qTEA1/src/Py.jl:341 [inlined]
[7] Py
@ ~/.julia/packages/PythonCall/qTEA1/src/Py.jl:341 [inlined]
[8] pyeval(::Type{Py}, code::Py, globals::Module, locals::Tuple{})
@ PythonCall ~/.julia/packages/PythonCall/qTEA1/src/concrete/code.jl:43
[9] top-level scope
@ ~/.julia/packages/PythonCall/qTEA1/src/concrete/code.jl:146

julia> @pyexec "y"
ERROR: Python: NameError: name 'y' is not defined
Python stacktrace:
[1]
@ REPL[8]:1:1
Stacktrace:
[1] pythrow()
@ PythonCall ~/.julia/packages/PythonCall/qTEA1/src/err.jl:94
[2] errcheck
@ ~/.julia/packages/PythonCall/qTEA1/src/err.jl:10 [inlined]
[3] pycallargs(f::Py, args::Py)
@ PythonCall ~/.julia/packages/PythonCall/qTEA1/src/abstract/object.jl:210
[4] pycall(::Py, ::Py, ::Vararg{Py}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ PythonCall ~/.julia/packages/PythonCall/qTEA1/src/abstract/object.jl:228
[5] pycall
@ ~/.julia/packages/PythonCall/qTEA1/src/abstract/object.jl:218 [inlined]
[6] #_#11
@ ~/.julia/packages/PythonCall/qTEA1/src/Py.jl:341 [inlined]
[7] Py
@ ~/.julia/packages/PythonCall/qTEA1/src/Py.jl:341 [inlined]
[8] pyexec(::Type{Nothing}, code::Py, globals::Module, locals::Tuple{})
@ PythonCall ~/.julia/packages/PythonCall/qTEA1/src/concrete/code.jl:98
[9] top-level scope
@ ~/.julia/packages/PythonCall/qTEA1/src/concrete/code.jl:146

julia> @pyexec """
def f(x):
return x + 1
"""

julia> @pyeval "f(1)"
ERROR: Python: NameError: name 'f' is not defined
Python stacktrace:
[1]
@ REPL[10]:1:1
Stacktrace:
[1] pythrow()
@ PythonCall ~/.julia/packages/PythonCall/qTEA1/src/err.jl:94
[2] errcheck
@ ~/.julia/packages/PythonCall/qTEA1/src/err.jl:10 [inlined]
[3] pycallargs(f::Py, args::Py)
@ PythonCall ~/.julia/packages/PythonCall/qTEA1/src/abstract/object.jl:210
[4] pycall(::Py, ::Py, ::Vararg{Py}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ PythonCall ~/.julia/packages/PythonCall/qTEA1/src/abstract/object.jl:228
[5] pycall
@ ~/.julia/packages/PythonCall/qTEA1/src/abstract/object.jl:218 [inlined]
[6] #_#11
@ ~/.julia/packages/PythonCall/qTEA1/src/Py.jl:341 [inlined]
[7] Py
@ ~/.julia/packages/PythonCall/qTEA1/src/Py.jl:341 [inlined]
[8] pyeval(::Type{Py}, code::Py, globals::Module, locals::Tuple{})
@ PythonCall ~/.julia/packages/PythonCall/qTEA1/src/concrete/code.jl:43
[9] top-level scope
@ ~/.julia/packages/PythonCall/qTEA1/src/concrete/code.jl:146

julia> pyeval("f(1)", Main)
ERROR: Python: NameError: name 'f' is not defined
Python stacktrace:
[1]
@ :1
Stacktrace:
[1] pythrow()
@ PythonCall ~/.julia/packages/PythonCall/qTEA1/src/err.jl:94
[2] errcheck
@ ~/.julia/packages/PythonCall/qTEA1/src/err.jl:10 [inlined]
[3] pycallargs(f::Py, args::Py)
@ PythonCall ~/.julia/packages/PythonCall/qTEA1/src/abstract/object.jl:210
[4] pycall(::Py, ::String, ::Vararg{Any}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ PythonCall ~/.julia/packages/PythonCall/qTEA1/src/abstract/object.jl:228
[5] pycall
@ ~/.julia/packages/PythonCall/qTEA1/src/abstract/object.jl:218 [inlined]
[6] #_#11
@ ~/.julia/packages/PythonCall/qTEA1/src/Py.jl:341 [inlined]
[7] Py
@ ~/.julia/packages/PythonCall/qTEA1/src/Py.jl:341 [inlined]
[8] pyeval
@ ~/.julia/packages/PythonCall/qTEA1/src/concrete/code.jl:43 [inlined]
[9] pyeval
@ ~/.julia/packages/PythonCall/qTEA1/src/concrete/code.jl:47 [inlined]
[10] pyeval(code::String, globals::Module)
@ PythonCall ~/.julia/packages/PythonCall/qTEA1/src/concrete/code.jl:47
[11] top-level scope
@ REPL[11]:1

julia> @pyeval "x"
Python: 1

(jl_NIT4tY) pkg> st -m
Status `/private/var/folders/hc/fn82kz1j5vl8w7lwd4l079y80000gn/T/jl_NIT4tY/Manifest.toml`
[992eb4ea] CondaPkg v0.2.20
[9a962f9c] DataAPI v1.15.0
[e2d170a0] DataValueInterfaces v1.0.0
[82899510] IteratorInterfaceExtensions v1.0.0
[692b3bcd] JLLWrappers v1.5.0
[0f8b85d8] JSON3 v1.13.2
[1914dd2f] MacroTools v0.5.11
[0b3b1443] MicroMamba v0.1.14
[bac558e1] OrderedCollections v1.6.2
[69de0a69] Parsers v2.7.2
[fa939f87] Pidfile v1.3.0
[aea7be01] PrecompileTools v1.2.0
[21216c6a] Preferences v1.4.1
[6099a3de] PythonCall v0.9.14
[ae029012] Requires v1.3.0
[6c6a2e73] Scratch v1.2.0
[856f2bd8] StructTypes v1.10.0
[3783bdb8] TableTraits v1.0.1
[bd369af6] Tables v1.11.0
[e17b2a0c] UnsafePointers v1.0.0
[f8abcde7] micromamba_jll v1.4.9+0
[0dad84c5] ArgTools v1.1.1
[56f22d72] Artifacts
[2a0f44e3] Base64
[ade2ca70] Dates
[f43a241f] Downloads v1.6.0
[7b1f6079] FileWatching
[b77e0a4c] InteractiveUtils
[4af54fe1] LazyArtifacts
[b27032c2] LibCURL v0.6.3
[76f85450] LibGit2
[8f399da3] Libdl
[37e2e46d] LinearAlgebra
[56ddb016] Logging
[d6f4376e] Markdown
[a63ad114] Mmap
[ca575930] NetworkOptions v1.2.0
[44cfe95a] Pkg v1.9.2
[de0858da] Printf
[3fa0cd96] REPL
[9a3f8284] Random
[ea8e919c] SHA v0.7.0
[9e88b42a] Serialization
[6462fe0b] Sockets
[fa267f1f] TOML v1.0.3
[a4e569a6] Tar v1.10.0
[8dfed614] Test
[cf7118a7] UUIDs
[4ec0a83e] Unicode
[e66e0078] CompilerSupportLibraries_jll v1.0.5+0
[deac9b47] LibCURL_jll v7.84.0+0
[29816b5a] LibSSH2_jll v1.10.2+0
[c8ffd9c3] MbedTLS_jll v2.28.2+0
[14a3606d] MozillaCACerts_jll v2022.10.11
[4536629a] OpenBLAS_jll v0.3.21+4
[83775a58] Zlib_jll v1.2.13+0
[8e850b90] libblastrampoline_jll v5.8.0+0
[8e850ede] nghttp2_jll v1.48.0+0
[3f19e933] p7zip_jll v17.4.0+0

julia> versioninfo()
Julia Version 1.9.3
Commit bed2cd540a1 (2023-08-24 14:43 UTC)
Build Info:
Official https://julialang.org/ release
Platform Info:
OS: macOS (arm64-apple-darwin22.4.0)
CPU: 8 × Apple M2
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-14.0.6 (ORCJIT, apple-m1)
Threads: 1 on 4 virtual cores
Environment:
JULIA_EDITOR = code
```

コントリビューションガイド

このリポジトリのコントリビューションガイドは索引されていません

調査の方向性

Reproduce the difference between the @pyexec macro and pyexec(code, Main), then trace the @pyexec, @pyeval, pyexec, and pyeval entry points shown in concrete/code.jl. Compare behavior for assignments and function definitions, and consider the issue complete when both forms expose those definitions through subsequent evaluation.

索引モデルが issue の本文から書いたものです。

評価

技術スタック
python
領域
backend
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
35/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。