Skip to content

Commit cf48508

Browse files
authored
Merge branch 'master' into pv/preferences
2 parents 71abd46 + e3e3008 commit cf48508

File tree

4 files changed

+40
-2
lines changed

4 files changed

+40
-2
lines changed

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ def sinpi(x):
165165
py"sinpi"(1)
166166
```
167167

168+
You can also execute a whole script `"foo.py"` via `@pyinclude("foo.py")` as if you had pasted it into a `py"""..."""` string.
169+
168170
When creating a Julia module, it is a useful pattern to define Python
169171
functions or classes in Julia's `__init__` and then use it in Julia
170172
function with `py"..."`.
@@ -197,7 +199,7 @@ cannot be accessed outside `MyModule`.
197199

198200
Here are solutions to some common problems:
199201

200-
* By default, PyCall [doesn't include the current directory in the Python search path](https://github.com/JuliaPy/PyCall.jl/issues/48). If you want to do that (in order to load a Python module from the current directory), just run `pushfirst!(PyVector(pyimport("sys")."path"), "")`.
202+
* By default, PyCall [doesn't include the current directory in the Python search path](https://github.com/JuliaPy/PyCall.jl/issues/48). If you want to do that (in order to load a Python module from the current directory), just run `pushfirst!(pyimport("sys")."path", "")`.
201203

202204
## Python object interfaces
203205

@@ -390,6 +392,11 @@ and also by providing more type information to the Julia compiler.
390392
`__init__`. Side-effect in Python occurred at top-level Julia scope
391393
cannot be used at run-time for precompiled modules.
392394

395+
You can also execute a Python script file `"foo.py"` by running `@pyinclude("foo.py")`, and it will be as if you had pasted the
396+
script into a `py"..."` string. (`@pyinclude` does not support
397+
interpolating Julia variables with `$var`, however — the script
398+
must be pure Python.)
399+
393400
* `pybuiltin(s)`: Look up `s` (a string or symbol) among the global Python
394401
builtins. If `s` is a string it returns a `PyObject`, while if `s` is a
395402
symbol it returns the builtin converted to `PyAny`. (You can also use `py"s"`

src/PyCall.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export pycall, pycall!, pyimport, pyimport_e, pybuiltin, PyObject, PyReverseDims
1515
pyraise, pytype_mapping, pygui, pygui_start, pygui_stop,
1616
pygui_stop_all, @pylab, set!, PyTextIO, @pysym, PyNULL, ispynull, @pydef,
1717
pyimport_conda, @py_str, @pywith, @pycall, pybytes, pyfunction, pyfunctionret,
18-
pywrapfn, pysetarg!, pysetargs!
18+
pywrapfn, pysetarg!, pysetargs!, @pyinclude
1919

2020
import Base: size, ndims, similar, copy, getindex, setindex!, stride,
2121
convert, pointer, summary, convert, show, haskey, keys, values,

src/pyeval.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,3 +232,24 @@ macro py_str(code, options...)
232232
ret
233233
end
234234
end
235+
236+
"""
237+
@pyinclude(filename)
238+
239+
Execute the Python script in the file `filename` as if
240+
it were in a `py\"\"\" ... \"\"\"` block, e.g. so that
241+
any globals defined in `filename` are available to
242+
subsequent `py"..."` evaluations.
243+
244+
(Unlike `py"..."`, however, `@pyinclude` does not
245+
interpolate Julia variables into `\$var` expressions —
246+
the `filename` script must be pure Python.)
247+
"""
248+
macro pyinclude(fname)
249+
quote
250+
m = pynamespace($__module__)
251+
fname = $(esc(fname))
252+
pyeval_(read(fname, String), m, m, Py_file_input, fname)
253+
nothing
254+
end
255+
end

test/runtests.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,3 +835,13 @@ include("testpybuffer.jl")
835835
if lowercase(get(ENV, "JULIA_PKGEVAL", "false")) != "true"
836836
include("test_venv.jl")
837837
end
838+
839+
@testset "@pyinclude" begin
840+
mktemp() do path, io
841+
print(io, "foo1 = 1\nbar2 = 2\n")
842+
close(io)
843+
@pyinclude(path)
844+
@test py"foo1" == 1
845+
@test py"bar2" == 2
846+
end
847+
end

0 commit comments

Comments
 (0)