diff --git a/dev/compat/index.html b/dev/compat/index.html index 4479dbfc..2a372086 100644 --- a/dev/compat/index.html +++ b/dev/compat/index.html @@ -1,5 +1,5 @@ -Compatibility Tools · PythonCall & JuliaCall

Compatibility Tools

Some packages require a little extra help to work nicely with PythonCall.

Some of these are "fixes" that are silently applied for you, and some are just extra functions to bridge a gap. We aim to keep these as minimal as possible.

Python standard library

Whenever a Python exception is displayed by Julia, sys.last_traceback and friends are set. This allows the post-mortem debugger pdb.pm() to work. Disable by setting PythonCall.CONFIG.auto_sys_last_traceback = false.

Tabular data / Pandas

The abstract type PyTable is for wrapper types around Python tables, providing the Tables.jl interface. PyTable(x) is shorthand for pyconvert(PyTable, x).

The subtype PyPandasDataFrame wraps a pandas.DataFrame.

For example, if x is a pandas.DataFrame then PyTable(x) is a PyPandasDataFrame and DataFrame(PyTable(x)) is a DataFrame.

In the other direction, the following functions can be used to convert any Tables.jl-compatible table to a Python table.

PythonCall.pytableFunction
pytable(src, format=:pandas; ...)

Construct a Python table from the Tables.jl-compatible table src.

The format controls the type of the resulting table, and is one of:

  • :pandas: A pandas.DataFrame. Keyword arguments are passed to the DataFrame constructor.
  • :columns: A dict mapping column names to columns.
  • :rows: A list of rows, which are namedtuples.
  • :rowdicts: A list of rows, which are dicts.
source

MatPlotLib / PyPlot / Seaborn

MatPlotLib figures can be shown with Julia's display mechanism, like display(fig) or display(mime, fig).

This means that if you return a figure from a Jupyter or Pluto notebook cell, it will be shown. You can call display(plt.gcf()) to display the current figure.

We also provide a simple MatPlotLib backend: mpl.use("module://juliacall.matplotlib"). Now you can call plt.show() to display the figure with Julia's display mechanism. You can specify the format like plt.show(format="png").

Python GUIs (including MatPlotLib)

Event loops

If for example you wish to use PyPlot in interactive mode (matplotlib.pyplot.ion()) then activating the correct event loop will allow it to work.

PythonCall.event_loop_onFunction
event_loop_on(g::Symbol; interval=0.04, fix=false)

Activate an event loop for the GUI framework g, so that the framework can run in the background of a Julia session.

The event loop runs every interval seconds. If fix is true and g is a Qt framework, then fix_qt_plugin_path is called.

Supported values of g (and the Python module they relate to) are: :pyqt4 (PyQt4), :pyqt5 (PyQt5), :pyside (PySide), :pyside2 (PySide2), :gtk (gtk), :gtk3 (gi), :wx (wx), :tkinter (tkinter).

source

Qt path fix

PythonCall.fix_qt_plugin_pathFunction
fix_qt_plugin_path()

Try to set the QT_PLUGIN_PATH environment variable in Python, if not already set.

This fixes the problem that Qt does not know where to find its qt.conf file, because it always looks relative to sys.executable, which can be the Julia executable not the Python one when using this package.

If CONFIG.auto_fix_qt_plugin_path is true, then this is run automatically before PyQt4, PyQt5, PySide or PySide2 are imported.

source

IPython

The juliacall IPython extension adds these features to your IPython session:

  • The line magic %julia code executes the given Julia code in-line.
  • The cell magic %%julia executes a cell of Julia code.
  • Julia's stdout and stderr are redirected to IPython.
  • Calling display(x) from Julia will display x in IPython.

The extension is experimental and unstable - the API can change at any time.

Enable the extension with %load_ext juliacall. See the IPython docs.

The %%julia cell magic can synchronise variables between Julia and Python by listing them on the first line:

In [1]: %load_ext juliacall
+Compatibility Tools · PythonCall & JuliaCall

Compatibility Tools

Some packages require a little extra help to work nicely with PythonCall.

Some of these are "fixes" that are silently applied for you, and some are just extra functions to bridge a gap. We aim to keep these as minimal as possible.

Python standard library

Whenever a Python exception is displayed by Julia, sys.last_traceback and friends are set. This allows the post-mortem debugger pdb.pm() to work. Disable by setting PythonCall.CONFIG.auto_sys_last_traceback = false.

Tabular data / Pandas

The abstract type PyTable is for wrapper types around Python tables, providing the Tables.jl interface. PyTable(x) is shorthand for pyconvert(PyTable, x).

The subtype PyPandasDataFrame wraps a pandas.DataFrame.

For example, if x is a pandas.DataFrame then PyTable(x) is a PyPandasDataFrame and DataFrame(PyTable(x)) is a DataFrame.

In the other direction, the following functions can be used to convert any Tables.jl-compatible table to a Python table.

PythonCall.pytableFunction
pytable(src, format=:pandas; ...)

Construct a Python table from the Tables.jl-compatible table src.

The format controls the type of the resulting table, and is one of:

  • :pandas: A pandas.DataFrame. Keyword arguments are passed to the DataFrame constructor.
  • :columns: A dict mapping column names to columns.
  • :rows: A list of rows, which are namedtuples.
  • :rowdicts: A list of rows, which are dicts.
source

MatPlotLib / PyPlot / Seaborn

MatPlotLib figures can be shown with Julia's display mechanism, like display(fig) or display(mime, fig).

This means that if you return a figure from a Jupyter or Pluto notebook cell, it will be shown. You can call display(plt.gcf()) to display the current figure.

We also provide a simple MatPlotLib backend: mpl.use("module://juliacall.matplotlib"). Now you can call plt.show() to display the figure with Julia's display mechanism. You can specify the format like plt.show(format="png").

Python GUIs (including MatPlotLib)

Event loops

If for example you wish to use PyPlot in interactive mode (matplotlib.pyplot.ion()) then activating the correct event loop will allow it to work.

PythonCall.event_loop_onFunction
event_loop_on(g::Symbol; interval=0.04, fix=false)

Activate an event loop for the GUI framework g, so that the framework can run in the background of a Julia session.

The event loop runs every interval seconds. If fix is true and g is a Qt framework, then fix_qt_plugin_path is called.

Supported values of g (and the Python module they relate to) are: :pyqt4 (PyQt4), :pyqt5 (PyQt5), :pyside (PySide), :pyside2 (PySide2), :gtk (gtk), :gtk3 (gi), :wx (wx), :tkinter (tkinter).

source

Qt path fix

PythonCall.fix_qt_plugin_pathFunction
fix_qt_plugin_path()

Try to set the QT_PLUGIN_PATH environment variable in Python, if not already set.

This fixes the problem that Qt does not know where to find its qt.conf file, because it always looks relative to sys.executable, which can be the Julia executable not the Python one when using this package.

If CONFIG.auto_fix_qt_plugin_path is true, then this is run automatically before PyQt4, PyQt5, PySide or PySide2 are imported.

source

IPython

The juliacall IPython extension adds these features to your IPython session:

  • The line magic %julia code executes the given Julia code in-line.
  • The cell magic %%julia executes a cell of Julia code.
  • Julia's stdout and stderr are redirected to IPython.
  • Calling display(x) from Julia will display x in IPython.

The extension is experimental and unstable - the API can change at any time.

Enable the extension with %load_ext juliacall. See the IPython docs.

The %%julia cell magic can synchronise variables between Julia and Python by listing them on the first line:

In [1]: %load_ext juliacall
 
 In [2]: x = 2
 
@@ -11,4 +11,4 @@
    ...:
 
 In [5]: z
-Out[5]: '2^8 = 256'

Asynchronous Julia code (including Makie)

Asynchronous Julia code will not normally run while Python is executing, unless it is in a separate thread.

This can be fixed by calling jl.yield() periodically from Python code, allowing the Julia scheduler to run.

When working at the Python REPL, you may call juliacall.interactive() which will allow Julia async code to run while the prompt is showing. This will allow interactive plots such as Makie to work.

+Out[5]: '2^8 = 256'

Asynchronous Julia code (including Makie)

Asynchronous Julia code will not normally run while Python is executing, unless it is in a separate thread.

This can be fixed by calling jl.yield() periodically from Python code, allowing the Julia scheduler to run.

When working at the Python REPL, you may call juliacall.interactive() which will allow Julia async code to run while the prompt is showing. This will allow interactive plots such as Makie to work.

diff --git a/dev/conversion-to-julia/index.html b/dev/conversion-to-julia/index.html index ae0c645c..9175aeb6 100644 --- a/dev/conversion-to-julia/index.html +++ b/dev/conversion-to-julia/index.html @@ -1,2 +1,2 @@ -Python to Julia · PythonCall & JuliaCall

Conversion to Julia

Conversion Rules

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.

FromTo
Top priority (wrapped values).
juliacall.AnyValueAny
Very high priority (arrays).
Objects satisfying the buffer or array interface (inc. bytes, bytearray, array.array, numpy.ndarray)PyArray
High priority (canonical conversions).
NoneNothing
boolBool
numbers.Integral (inc. int)Integer (prefers Int, or BigInt on overflow)
floatFloat64
complexComplex{Float64}
rangeStepRange
strString
tupleTuple
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
BaseExceptionPyException
datetime.date/datetime.time/datetime.datetimeDate/Time/DateTime
datetime.timedeltaMicrosecond (or Millisecond or Second on overflow)
numpy.intXX/numpy.uintXX/numpy.floatXXIntXX/UIntXX/FloatXX
Standard priority (other reasonable conversions).
NoneMissing
bytesVector{UInt8}, Vector{Int8}, String
strString, Symbol, Char, Vector{UInt8}, Vector{Int8}
rangeUnitRange
collections.abc.MappingDict
collections.abc.IterableVector, Set, Tuple, NamedTuple, Pair
datetime.timedeltaDates.CompoundPeriod
numbers.IntegralInteger, Rational, Real, Number
numbers.RealAbstractFloat, Number, Missing/Nothing (if NaN)
numbers.ComplexComplex, Number
ctypes.c_int and other integersInteger, Rational, Real, Number
ctypes.c_float/ctypes.c_doubleCfloat/Cdouble, AbstractFloat, Real, Number
ctypes.c_voidpPtr{Cvoid}, Ptr
ctypes.c_char_pCstring, Ptr{Cchar}, Ptr
ctypes.c_wchar_pCwstring, Ptr{Cwchar}, Ptr
numpy.intXX/numpy.uintXX/numpy.floatXXInteger, Rational, Real, Number
Objects satisfying the buffer or array interfaceArray, AbstractArray
Low priority (fallback to Py).
AnythingPy
Bottom priority (must be explicitly specified by excluding Py).
Objects satisfying the buffer interfacePyBuffer
AnythingPyRef

See here for an explanation of the Py* wrapper types (PyList, PyIO, etc).

Custom rules

To add a custom conversion rule, you must define a function to do the conversion and call pyconvert_add_rule to register it.

You must not do this while precompiling, so these calls will normally be in the __init__ function of your module.

PythonCall.pyconvert_add_ruleFunction
pyconvert_add_rule(tname::String, T::Type, func::Function, priority::PyConvertPriority=PYCONVERT_PRIORITY_NORMAL)

Add a new conversion rule for pyconvert.

Arguments

  • tname is a string of the form "__module__:__qualname__" identifying a Python type t, such as "builtins:dict". 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.

Implementing func

func is called as func(S, x::Py) for some S <: T.

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).

The target type S is never a union or the empty type, i.e. it is always a data type or union-all.

Priority

Most rules should have priority PYCONVERT_PRIORITY_NORMAL (the default) which is for any reasonable conversion rule.

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.

Other priorities are reserved for internal use.

source
+Python to Julia · PythonCall & JuliaCall

Conversion to Julia

Conversion Rules

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.

FromTo
Top priority (wrapped values).
juliacall.AnyValueAny
Very high priority (arrays).
Objects satisfying the buffer or array interface (inc. bytes, bytearray, array.array, numpy.ndarray)PyArray
High priority (canonical conversions).
NoneNothing
boolBool
numbers.Integral (inc. int)Integer (prefers Int, or BigInt on overflow)
floatFloat64
complexComplex{Float64}
rangeStepRange
strString
tupleTuple
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
BaseExceptionPyException
datetime.date/datetime.time/datetime.datetimeDate/Time/DateTime
datetime.timedeltaMicrosecond (or Millisecond or Second on overflow)
numpy.intXX/numpy.uintXX/numpy.floatXXIntXX/UIntXX/FloatXX
Standard priority (other reasonable conversions).
NoneMissing
bytesVector{UInt8}, Vector{Int8}, String
strString, Symbol, Char, Vector{UInt8}, Vector{Int8}
rangeUnitRange
collections.abc.MappingDict
collections.abc.IterableVector, Set, Tuple, NamedTuple, Pair
datetime.timedeltaDates.CompoundPeriod
numbers.IntegralInteger, Rational, Real, Number
numbers.RealAbstractFloat, Number, Missing/Nothing (if NaN)
numbers.ComplexComplex, Number
ctypes.c_int and other integersInteger, Rational, Real, Number
ctypes.c_float/ctypes.c_doubleCfloat/Cdouble, AbstractFloat, Real, Number
ctypes.c_voidpPtr{Cvoid}, Ptr
ctypes.c_char_pCstring, Ptr{Cchar}, Ptr
ctypes.c_wchar_pCwstring, Ptr{Cwchar}, Ptr
numpy.intXX/numpy.uintXX/numpy.floatXXInteger, Rational, Real, Number
Objects satisfying the buffer or array interfaceArray, AbstractArray
Low priority (fallback to Py).
AnythingPy
Bottom priority (must be explicitly specified by excluding Py).
Objects satisfying the buffer interfacePyBuffer
AnythingPyRef

See here for an explanation of the Py* wrapper types (PyList, PyIO, etc).

Custom rules

To add a custom conversion rule, you must define a function to do the conversion and call pyconvert_add_rule to register it.

You must not do this while precompiling, so these calls will normally be in the __init__ function of your module.

PythonCall.pyconvert_add_ruleFunction
pyconvert_add_rule(tname::String, T::Type, func::Function, priority::PyConvertPriority=PYCONVERT_PRIORITY_NORMAL)

Add a new conversion rule for pyconvert.

Arguments

  • tname is a string of the form "__module__:__qualname__" identifying a Python type t, such as "builtins:dict". 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.

Implementing func

func is called as func(S, x::Py) for some S <: T.

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).

The target type S is never a union or the empty type, i.e. it is always a data type or union-all.

Priority

Most rules should have priority PYCONVERT_PRIORITY_NORMAL (the default) which is for any reasonable conversion rule.

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.

Other priorities are reserved for internal use.

source
diff --git a/dev/conversion-to-python/index.html b/dev/conversion-to-python/index.html index 105b898d..14e22cef 100644 --- a/dev/conversion-to-python/index.html +++ b/dev/conversion-to-python/index.html @@ -1,2 +1,2 @@ -Julia to Python · PythonCall & JuliaCall

Conversion to Python

Conversion Rules

The following table specifies the conversion rules used whenever converting a Julia object to a Python object.

From Julia, this occurs explicitly with Py(x) or implicitly when passing Julia objects as the argument to a Python function. To avoid this automatic conversion, the user can convert objects explicitly, such as by calling pylist or pydict.

From Python, this occurs when converting the return value of a Julia function.

FromTo
Any Python object type (Py, PyList, etc.)itself
Nothing, MissingNone
Boolbool
Standard integer (IntXX, UIntXX, BigInt)int
Standard rational (Rational{T}, T a standard integer)fractions.Fraction
Standard float (FloatXX)float
Standard complex (Complex{T}, T a standard float)complex
Standard string/char (String and SubString{String}, Char)str
Tupletuple
Standard integer range (AbstractRange{T}, T a standard integer)range
Date, Time, DateTime (from Dates)date, time, datetime (from datetime)
Second, Millisecond, Microsecond, Nanosecond (from Dates)timedelta (from datetime)
Numberjuliacall.NumberValue, juliacall.ComplexValue, etc.
AbstractArrayjuliacall.ArrayValue, juliacall.VectorValue
AbstractDictjuliacall.DictValue
AbstractSetjuliacall.SetValue
IOjuliacall.BufferedIOValue
Modulejuliacall.ModuleValue
Typejuliacall.TypeValue
Anything elsejuliacall.AnyValue

See here for an explanation of the juliacall.*Value wrapper types.

Custom rules

You may define a new conversion rule for your new type T by overloading Py(::T).

If T is a wrapper type (such as PyList) where Py(x) simply returns the stored Python object, then also define ispy(::T) = true.

PythonCall.ispyFunction
ispy(x)

True if x is a Python object.

This includes Py and Python wrapper types such as PyList.

source

Alternatively, if you define a wrapper type (a subtype of juliacall.AnyValue) then you may instead define pyjltype(::T) to be that type.

PythonCall.pyjltypeFunction
pyjltype(x)

The subtype of juliacall.AnyValue which the Julia object x is wrapped as by pyjl(x).

Overload pyjltype(::T) to define a custom conversion for your type T.

source
+Julia to Python · PythonCall & JuliaCall

Conversion to Python

Conversion Rules

The following table specifies the conversion rules used whenever converting a Julia object to a Python object.

From Julia, this occurs explicitly with Py(x) or implicitly when passing Julia objects as the argument to a Python function. To avoid this automatic conversion, the user can convert objects explicitly, such as by calling pylist or pydict.

From Python, this occurs when converting the return value of a Julia function.

FromTo
Any Python object type (Py, PyList, etc.)itself
Nothing, MissingNone
Boolbool
Standard integer (IntXX, UIntXX, BigInt)int
Standard rational (Rational{T}, T a standard integer)fractions.Fraction
Standard float (FloatXX)float
Standard complex (Complex{T}, T a standard float)complex
Standard string/char (String and SubString{String}, Char)str
Tupletuple
Standard integer range (AbstractRange{T}, T a standard integer)range
Date, Time, DateTime (from Dates)date, time, datetime (from datetime)
Second, Millisecond, Microsecond, Nanosecond (from Dates)timedelta (from datetime)
Numberjuliacall.NumberValue, juliacall.ComplexValue, etc.
AbstractArrayjuliacall.ArrayValue, juliacall.VectorValue
AbstractDictjuliacall.DictValue
AbstractSetjuliacall.SetValue
IOjuliacall.BufferedIOValue
Modulejuliacall.ModuleValue
Typejuliacall.TypeValue
Anything elsejuliacall.AnyValue

See here for an explanation of the juliacall.*Value wrapper types.

Custom rules

You may define a new conversion rule for your new type T by overloading Py(::T).

If T is a wrapper type (such as PyList) where Py(x) simply returns the stored Python object, then also define ispy(::T) = true.

PythonCall.ispyFunction
ispy(x)

True if x is a Python object.

This includes Py and Python wrapper types such as PyList.

source

Alternatively, if you define a wrapper type (a subtype of juliacall.AnyValue) then you may instead define pyjltype(::T) to be that type.

PythonCall.pyjltypeFunction
pyjltype(x)

The subtype of juliacall.AnyValue which the Julia object x is wrapped as by pyjl(x).

Overload pyjltype(::T) to define a custom conversion for your type T.

source
diff --git a/dev/faq/index.html b/dev/faq/index.html index bd47f38a..1ab062a8 100644 --- a/dev/faq/index.html +++ b/dev/faq/index.html @@ -11,4 +11,4 @@ init() File "/home/dingraha/projects/pythoncall_import_error/venv/lib/python3.9/site-packages/juliacall/__init__.py", line 214, in init raise Exception('PythonCall.jl did not start properly') -Exception: PythonCall.jl did not start properly

The likely problem is that the "other" Python library (matplotlib, whatever) is loading the system libstdc++.so, which isn't compatible with the libstdc++.so that Julia ships with. Linux distributions with older libstdc++ versions seem more likely to suffer from this issue. The solution is to either:

Related issues: #255

Can I use JuliaCall to run Julia inside applications with embedded Python?

Yes, it may be possible. See an example of how to have Julia running inside the Python that is running inside Blender here https://discourse.julialang.org/t/running-julia-inside-blender-through-vscode-using-pythoncall-juliacall/96838.

+Exception: PythonCall.jl did not start properly

The likely problem is that the "other" Python library (matplotlib, whatever) is loading the system libstdc++.so, which isn't compatible with the libstdc++.so that Julia ships with. Linux distributions with older libstdc++ versions seem more likely to suffer from this issue. The solution is to either:

Related issues: #255

Can I use JuliaCall to run Julia inside applications with embedded Python?

Yes, it may be possible. See an example of how to have Julia running inside the Python that is running inside Blender here https://discourse.julialang.org/t/running-julia-inside-blender-through-vscode-using-pythoncall-juliacall/96838.

diff --git a/dev/index.html b/dev/index.html index fade3f5f..fab1a6ec 100644 --- a/dev/index.html +++ b/dev/index.html @@ -1,2 +1,2 @@ -Home · PythonCall & JuliaCall

PythonCall & JuliaCall

Bringing Python® and Julia together in seamless harmony:

  • Call Python code from Julia and Julia code from Python via a symmetric interface.
  • Simple syntax, so the Python code looks like Python and the Julia code looks like Julia.
  • Intuitive and flexible conversions between Julia and Python: anything can be converted, you are in control.
  • Fast non-copying conversion of numeric arrays in either direction: modify Python arrays (e.g. bytes, array.array, numpy.ndarray) from Julia or Julia arrays from Python.
  • Helpful wrappers: interpret Python sequences, dictionaries, arrays, dataframes and IO streams as their Julia counterparts, and vice versa.
  • Beautiful stack-traces.
  • Works anywhere: tested on Windows, MacOS and Linux, 32- and 64-bit, Julia Julia 1.6.1 upwards and Python 3.7 upwards.
+Home · PythonCall & JuliaCall

PythonCall & JuliaCall

Bringing Python® and Julia together in seamless harmony:

  • Call Python code from Julia and Julia code from Python via a symmetric interface.
  • Simple syntax, so the Python code looks like Python and the Julia code looks like Julia.
  • Intuitive and flexible conversions between Julia and Python: anything can be converted, you are in control.
  • Fast non-copying conversion of numeric arrays in either direction: modify Python arrays (e.g. bytes, array.array, numpy.ndarray) from Julia or Julia arrays from Python.
  • Helpful wrappers: interpret Python sequences, dictionaries, arrays, dataframes and IO streams as their Julia counterparts, and vice versa.
  • Beautiful stack-traces.
  • Works anywhere: tested on Windows, MacOS and Linux, 32- and 64-bit, Julia Julia 1.6.1 upwards and Python 3.7 upwards.
diff --git a/dev/juliacall-reference/index.html b/dev/juliacall-reference/index.html index 923b89a5..72aed51a 100644 --- a/dev/juliacall-reference/index.html +++ b/dev/juliacall-reference/index.html @@ -2,4 +2,4 @@ Reference · PythonCall & JuliaCall

JuliaCall API Reference

Constants

juliacall.MainConstant

The Julia Main module, as a ModuleValue.

In interactive scripts, you can use this as the main entry-point to JuliaCall:

from juliacall import Main as jl
 jl.println("Hello, world!")

In packages, use newmodule instead.

The modules Base, Core and PythonCall are also available.

Utilities

juliacall.convertFunction
convert(T, x)

Convert x to a Julia object of type T.

You can use this to pass an argument to a Julia function of a specific type.

Wrapper types

Apart from a few fundamental immutable types, all Julia values are by default converted into Python to some AnyValue object, which wraps the original value, but giving it a Pythonic interface.

Subclasses of AnyValue provide additional Python semantics. For example a Julia vector is converted to a VectorValue which satisfies the Python sequence interface and behaves very similar to a list.

There is also a RawValue object, which gives a stricter "Julia-only" interface, documented below. These types all inherit from ValueBase:

juliacall.AnyValueClass

Wraps any Julia object, giving it some basic Python semantics. Subtypes provide extra semantics.

Supports repr(x), str(x), attributes (x.attr), calling (x(a,b)), iteration, comparisons, len(x), a in x, dir(x).

Calling, indexing, attribute access, etc. will convert the result to a Python object according to this table. This is typically a builtin Python type (for immutables) or a subtype of AnyValue.

Attribute access can be used to access Julia properties as well as normal class members. In the case of a name clash, the class member will take precedence. For convenience with Julia naming conventions, _b at the end of an attribute is replaced with ! and _bb is replaced with !!.

Members

  • _jl_raw(): Convert to a RawValue. (See also pyjlraw.)
  • _jl_display(): Display the object using Julia's display mechanism.
  • _jl_help(): Display help for the object.
juliacall.NumberValueClass

This wraps any Julia Number value. It is a subclass of numbers.Number and behaves similar to other Python numbers.

There are also subtypes ComplexValue, RealValue, RationalValue, IntegerValue which wrap values of the corresponding Julia types, and are subclasses of the corresponding numbers ABC.

juliacall.ArrayValueClass

This wraps any Julia AbstractArray value. It is a subclass of collections.abc.Collection.

It supports zero-up indexing, and can be indexed with integers or slices. Slicing returns a view of the original array.

If the array is strided and its eltype is supported (i.e. Bool, IntXX, UIntXX, FloatXX, Complex{FloatXX}, Ptr{Cvoid} or Tuple or NamedTuple of these) then it supports the buffer protocol and the numpy array interface. This means that numpy.asarray(this) will yield a view of the original array, so mutations are visible on the original.

Otherwise, the numpy __array__ method is supported, and this returns an array of Python objects converted from the contents of the array. In this case, numpy.asarray(this) is a copy of the original array.

Members

  • ndim: The number of dimensions.
  • shape: Tuple of lengths in each dimension.
  • copy(): A copy of the array.
  • reshape(shape): A reshaped view of the array.
  • to_numpy(dtype=None, copy=True, order="K"): Convert to a numpy array.
juliacall.VectorValueClass

This wraps any Julia AbstractVector value. It is a subclass of juliacall.ArrayValue and collections.abc.MutableSequence and behaves similar to a Python list.

Members

  • resize(size): Change the length of the vector.
  • sort(reverse=False, key=None): Sort the vector in-place.
  • reverse(): Reverse the vector.
  • clear(): Empty the vector.
  • insert(index, value): Insert the value at the given index.
  • append(value): Append the value to the end of the vector.
  • extend(values): Append the values to the end of the vector.
  • pop(index=-1): Remove and return the item at the given index.
  • remove(value): Remove the first item equal to the value.
  • index(value): The index of the first item equal to the value.
  • count(value): The number of items equal to the value.
juliacall.DictValueClass

This wraps any Julia AbstractDict value. It is a subclass of collections.abc.Mapping and behaves similar to a Python dict.

juliacall.SetValueClass

This wraps any Julia AbstractSet value. It is a subclass of collections.abc.Set and behaves similar to a Python set.

juliacall.IOValueClass

This wraps any Julia IO value. It is a subclass of io.IOBase and behaves like Python files.

There are also subtypes BinaryIOValue and TextIOValue, which are subclasses of io.BufferedIOBase (buffered bytes) and io.TextIOBase (text).

juliacall.ModuleValueClass

This wraps any Julia Module value.

It is the same as AnyValue except for one additional convenience method:

  • seval([module=self], code): Evaluates the given code (a string) in the given module.
juliacall.TypeValueClass

This wraps any Julia Type value.

It is the same as AnyValue except that indexing is used to access Julia's "curly" syntax for specifying parametric types:

from juliacall import Main as jl
 # equivalent to Vector{Int}() in Julia
-jl.Vector[jl.Int]()
juliacall.RawValueClass

Wraps any Julia value with a rigid interface suitable for generic programming.

Supports repr(x), str(x), attributes (x.attr), calling (x(a,b)), len(x), dir(x).

This is very similar to AnyValue except that indexing, calling, etc. will always return a RawValue.

Indexing with a tuple corresponds to indexing in Julia with multiple values. To index with a single tuple, it will need to be wrapped in another tuple.

Members

  • _jl_any(): Convert to a AnyValue (or subclass). (See also pyjl.)
+jl.Vector[jl.Int]()
juliacall.RawValueClass

Wraps any Julia value with a rigid interface suitable for generic programming.

Supports repr(x), str(x), attributes (x.attr), calling (x(a,b)), len(x), dir(x).

This is very similar to AnyValue except that indexing, calling, etc. will always return a RawValue.

Indexing with a tuple corresponds to indexing in Julia with multiple values. To index with a single tuple, it will need to be wrapped in another tuple.

Members

diff --git a/dev/juliacall/index.html b/dev/juliacall/index.html index 39130134..9b58b1e8 100644 --- a/dev/juliacall/index.html +++ b/dev/juliacall/index.html @@ -25,4 +25,4 @@ "version": "0.5, 0.6" } } -}

Alternatively you can use add, rm, etc. from JuliaPkg to edit this file.

See JuliaPkg for more details.

Configuration

Some features of the Julia process, such as the optimization level or number of threads, may be configured in two ways:

-X optionEnvironment VariableDescription
-X juliacall-home=<dir>PYTHON_JULIACALL_BINDIR=<dir>The directory containing the julia executable.
-X juliacall-check-bounds=<yes|no|auto>PYTHON_JULIACALL_CHECK_BOUNDS=<yes|no|auto>Enable or disable bounds checking.
-X juliacall-compile=<yes|no|all|min>PYTHON_JULIACALL_COMPILE=<yes|no|all|min>Enable or disable JIT compilation.
-X juliacall-compiled-modules=<yes|no>PYTHON_JULIACALL_COMPILED_MODULES=<yes|no>Enable or disable incrementally compiling modules.
-X juliacall-depwarn=<yes|no|error>PYTHON_JULIACALL_DEPWARN=<yes|no|error>Enable or disable deprecation warnings.
-X juliacall-handle-signals=<yes|no>PYTHON_JULIACALL_HANDLE_SIGNALS=<yes|no>Enable or disable Julia signal handling.
-X juliacall-inline=<yes|no>PYTHON_JULIACALL_INLINE=<yes|no>Enable or disable inlining.
-X juliacall-min-optlevel=<0|1|2|3>PYTHON_JULIACALL_MIN_OPTLEVEL=<0|1|2|3>Optimization level.
-X juliacall-optimize=<0|1|2|3>PYTHON_JULIACALL_OPTIMIZE=<0|1|2|3>Minimum optimization level.
-X juliacall-procs=<N|auto>PYTHON_JULIACALL_PROCS=<N|auto>Launch N local worker process.
`-X juliacall-startup-file=<yesno>``PYTHONJULIACALLSTARTUP_FILE=<yes
-X juliacall-sysimage=<file>PYTHON_JULIACALL_SYSIMAGE=<file>Use the given system image.
-X juliacall-threads=<N|auto>PYTHON_JULIACALL_THREADS=<N|auto>Launch N threads.
-X juliacall-warn-overwrite=<yes|no>PYTHON_JULIACALL_WARN_OVERWRITE=<yes|no>Enable or disable method overwrite warnings.
+}

Alternatively you can use add, rm, etc. from JuliaPkg to edit this file.

See JuliaPkg for more details.

Configuration

Some features of the Julia process, such as the optimization level or number of threads, may be configured in two ways:

-X optionEnvironment VariableDescription
-X juliacall-home=<dir>PYTHON_JULIACALL_BINDIR=<dir>The directory containing the julia executable.
-X juliacall-check-bounds=<yes|no|auto>PYTHON_JULIACALL_CHECK_BOUNDS=<yes|no|auto>Enable or disable bounds checking.
-X juliacall-compile=<yes|no|all|min>PYTHON_JULIACALL_COMPILE=<yes|no|all|min>Enable or disable JIT compilation.
-X juliacall-compiled-modules=<yes|no>PYTHON_JULIACALL_COMPILED_MODULES=<yes|no>Enable or disable incrementally compiling modules.
-X juliacall-depwarn=<yes|no|error>PYTHON_JULIACALL_DEPWARN=<yes|no|error>Enable or disable deprecation warnings.
-X juliacall-handle-signals=<yes|no>PYTHON_JULIACALL_HANDLE_SIGNALS=<yes|no>Enable or disable Julia signal handling.
-X juliacall-inline=<yes|no>PYTHON_JULIACALL_INLINE=<yes|no>Enable or disable inlining.
-X juliacall-min-optlevel=<0|1|2|3>PYTHON_JULIACALL_MIN_OPTLEVEL=<0|1|2|3>Optimization level.
-X juliacall-optimize=<0|1|2|3>PYTHON_JULIACALL_OPTIMIZE=<0|1|2|3>Minimum optimization level.
-X juliacall-procs=<N|auto>PYTHON_JULIACALL_PROCS=<N|auto>Launch N local worker process.
`-X juliacall-startup-file=<yesno>``PYTHONJULIACALLSTARTUP_FILE=<yes
-X juliacall-sysimage=<file>PYTHON_JULIACALL_SYSIMAGE=<file>Use the given system image.
-X juliacall-threads=<N|auto>PYTHON_JULIACALL_THREADS=<N|auto>Launch N threads.
-X juliacall-warn-overwrite=<yes|no>PYTHON_JULIACALL_WARN_OVERWRITE=<yes|no>Enable or disable method overwrite warnings.
diff --git a/dev/pycall/index.html b/dev/pycall/index.html index 377ac07e..17c3593b 100644 --- a/dev/pycall/index.html +++ b/dev/pycall/index.html @@ -3,4 +3,4 @@ PyObject(x).append("baz") @show x # --> ["foo", "bar"]

whereas with PythonCall the following does mutate x:

x = ["foo", "bar"]
 Py(x).append("baz")
-@show x # --> ["foo", "bar", "baz"]

In fact, PythonCall has the policy that any mutable object will by default be wrapped in this way, which not only preserves mutability but makes conversion faster for large containers since it does not require taking a copy of all the data.

Automatic conversion

In PyCall, most function calls, attribute accesses, indexing, etc. of Python object by default automatically convert their result to a Julia object. This means that the following

pyimport("sys").modules["KEY"] = "VALUE"

does not actually modify the modules dict because it was copied to a new Julia Dict. This was probably not intended, plus it wasted time copying the whole dictionary. Instead you must do

set!(pyimport(os)."environ", "KEY", "VALUE")

In PythonCall, we don't do any such automatic conversion: we always return Py. This means that the first piece of code above does what you think.

Which Python

PyCall uses some global installation of Python - typically the version of Python installed on the system or used by Conda.

PythonCall uses a separate Conda environment for each Julia environment/project/package and installs Python (and other Python packages) into that. This means that different Julia projects can maintain an isolated set of Python dependencies (including the Python version itself).

Corresponding Python packages

PyCall has the corresponding Python package PyJulia for calling Julia from Python, and PythonCall similarly has JuliaCall.

One difference is between them is their code size: PyJulia is a large package, whereas JuliaCall is very small, with most of the implementation being in PythonCall itself. The practical up-shot is that PythonCall/JuliaCall have very symmetric interfaces; for example they use identical conversion policies and have the same set of wrapper types available.

Note also that JuliaCall will use a separate Julia project for each virtual/conda environment. This means that different Python environments can maintain an isolated set of Julia dependencies, including the versions of Julia and PythonCall themselves.

Compatibility

PyCall supports Julia 0.7+ and Python 2.7+, whereas PythonCall supports Julia 1.6.1+ and Python 3.7+. PyCall requires numpy to be installed, PythonCall doesn't (it provides the same fast array access through the buffer protocol and array interface).

+@show x # --> ["foo", "bar", "baz"]

In fact, PythonCall has the policy that any mutable object will by default be wrapped in this way, which not only preserves mutability but makes conversion faster for large containers since it does not require taking a copy of all the data.

Automatic conversion

In PyCall, most function calls, attribute accesses, indexing, etc. of Python object by default automatically convert their result to a Julia object. This means that the following

pyimport("sys").modules["KEY"] = "VALUE"

does not actually modify the modules dict because it was copied to a new Julia Dict. This was probably not intended, plus it wasted time copying the whole dictionary. Instead you must do

set!(pyimport(os)."environ", "KEY", "VALUE")

In PythonCall, we don't do any such automatic conversion: we always return Py. This means that the first piece of code above does what you think.

Which Python

PyCall uses some global installation of Python - typically the version of Python installed on the system or used by Conda.

PythonCall uses a separate Conda environment for each Julia environment/project/package and installs Python (and other Python packages) into that. This means that different Julia projects can maintain an isolated set of Python dependencies (including the Python version itself).

Corresponding Python packages

PyCall has the corresponding Python package PyJulia for calling Julia from Python, and PythonCall similarly has JuliaCall.

One difference is between them is their code size: PyJulia is a large package, whereas JuliaCall is very small, with most of the implementation being in PythonCall itself. The practical up-shot is that PythonCall/JuliaCall have very symmetric interfaces; for example they use identical conversion policies and have the same set of wrapper types available.

Note also that JuliaCall will use a separate Julia project for each virtual/conda environment. This means that different Python environments can maintain an isolated set of Julia dependencies, including the versions of Julia and PythonCall themselves.

Compatibility

PyCall supports Julia 0.7+ and Python 2.7+, whereas PythonCall supports Julia 1.6.1+ and Python 3.7+. PyCall requires numpy to be installed, PythonCall doesn't (it provides the same fast array access through the buffer protocol and array interface).

diff --git a/dev/pythoncall-reference/index.html b/dev/pythoncall-reference/index.html index ac96deb9..7a2b703c 100644 --- a/dev/pythoncall-reference/index.html +++ b/dev/pythoncall-reference/index.html @@ -1,18 +1,18 @@ -Reference · PythonCall & JuliaCall

PythonCall API Reference

Py objects

PythonCall.PyType
Py(x)

Convert x to a Python object, of type Py.

Conversion happens according to these rules.

Such an object supports attribute access (obj.attr), indexing (obj[idx]), calling (obj(arg1, arg2)), iteration (for x in obj), arithmetic (obj + obj2) and comparison (obj > obj2), among other things. These operations convert all their arguments to Py and return Py.

source
PythonCall.pybuiltinsModule
pybuiltins

An object whose fields are the Python builtins, of type Py.

For example pybuiltins.None, pybuiltins.int, pybuiltins.ValueError.

source

Constructors

These functions construct Python objects of builtin types from Julia values.

PythonCall.pycollistFunction
pycollist(x::AbstractArray)

Create a nested Python list-of-lists from the elements of x. For matrices, this is a list of columns.

source
PythonCall.pycomplexFunction
pycomplex(x=0.0)
-pycomplex(re, im)

Convert x to a Python complex, or create one from given real and imaginary parts.

source
PythonCall.pydictFunction
pydict(x)
-pydict(; x...)

Convert x to a Python dict. In the second form, the keys are strings.

If x is a Python object, this is equivalent to dict(x) in Python. Otherwise x must iterate over key-value pairs.

source
PythonCall.pyfrozensetFunction
pyfrozenset(x=())

Convert x to a Python frozenset.

If x is a Python object, this is equivalent to frozenset(x) in Python. Otherwise x must be iterable.

source
PythonCall.pylistFunction
pylist(x=())

Convert x to a Python list.

If x is a Python object, this is equivalent to list(x) in Python. Otherwise x must be iterable.

source
PythonCall.pyrangeFunction
pyrange([[start], [stop]], [step])

Construct a Python range. Unspecified arguments default to None.

source
PythonCall.pyrowlistFunction
pyrowlist(x::AbstractArray)

Create a nested Python list-of-lists from the elements of x. For matrices, this is a list of rows.

source
PythonCall.pysetFunction
pyset(x=())

Convert x to a Python set.

If x is a Python object, this is equivalent to set(x) in Python. Otherwise x must be iterable.

source
PythonCall.pysliceFunction
pyslice([start], stop, [step])

Construct a Python slice. Unspecified arguments default to None.

source
PythonCall.pytupleFunction
pytuple(x=())

Convert x to a Python tuple.

If x is a Python object, this is equivalent to tuple(x) in Python. Otherwise x must be iterable.

source

Builtins

These functions mimic the Python builtin functions or keywords of the same name.

PythonCall.pycallFunction
pycall(f, args...; kwargs...)

Call the Python object f with the given arguments.

source
PythonCall.pyevalFunction
pyeval([T=Py], code, globals, locals=nothing)

Evaluate the given Python code, returning the result as a T.

If globals is a Module, then a persistent dict unique to that module is used.

By default the code runs in global scope (i.e. locals===globals). To use a temporary local scope, set locals to (), or to a NamedTuple of variables to include in the scope.

See also @pyeval.

Examples

The following computes 1.1+2.2 in the Main module as a Float64:

pyeval(Float64, "x+y", Main, (x=1.1, y=2.2))  # returns 3.3
source
PythonCall.@pyevalMacro
@pyeval [inputs =>] code [=> T]

Evaluate the given code in a new local scope and return the answer as a T.

The global scope is persistent and unique to the current module.

The code must be a literal string or command.

The inputs is a tuple of inputs of the form v=expr to be included in the local scope. Only v is required, expr defaults to v.

Examples

The following computes 1.1+2.2 and returns a Float64:

@pyeval (x=1.1, y=2.2) => `x+y` => Float64  # returns 3.3
source
PythonCall.pyexecFunction
pyexec([T=Nothing], code, globals, locals=nothing)

Execute the given Python code.

If globals is a Module, then a persistent dict unique to that module is used.

By default the code runs in global scope (i.e. locals===globals). To use a temporary local scope, set locals to (), or to a NamedTuple of variables to include in the scope.

If T==Nothing then returns nothing. Otherwise T must be a concrete NamedTuple type and the corresponding items from locals are extracted and returned.

See also @pyexec.

Examples

The following computes 1.1+2.2 in the Main module as a Float64:

pyexec(@NamedTuple{ans::Float64}, "ans=x+y", Main, (x=1.1, y=2.2))  # returns (ans = 3.3,)

Marking variables as global saves them into the module scope, so that they are available in subsequent invocations:

pyexec("global x; x=12", Main)
-pyeval(Int, "x", Main)  # returns 12
source
PythonCall.@pyexecMacro
@pyexec [inputs =>] code [=> outputs]

Execute the given code in a new local scope.

The global scope is persistent and unique to the current module.

The code must be a literal string or command.

The inputs is a tuple of inputs of the form v=expr to be included in the local scope. Only v is required, expr defaults to v.

The outputs is a tuple of outputs of the form x::T=v, meaning that v is extracted from locals, converted to T and assigned to x. Only x is required: T defaults to Py and v defaults to x.

Examples

The following computes 1.1+2.2 and assigns its value to ans as a Float64:

@pyexec (x=1.1, y=2.2) => `ans=x+y` => ans::Float64  # returns 3.3

Marking variables as global saves them into the module scope, so that they are available in subsequent invocations:

@pyexec `global x; x=12`
-@pyeval `x` => Int  # returns 12
source
PythonCall.pygetattrFunction
pygetattr(x, k, [d])

Equivalent to getattr(x, k) or x.k in Python.

If d is specified, it is returned if the attribute does not exist.

source
PythonCall.pygetitemFunction
pygetitem(x, k, [d])

Equivalent x[k] in Python.

If d is specified, it is returned if the item does not exist (i.e. if x[k] raises a KeyError or IndexError).

source
PythonCall.pyhasattrFunction
pyhasattr(x, k)

Equivalent to hasattr(x, k) in Python.

Tests if getattr(x, k) raises an AttributeError.

source
PythonCall.pyimportFunction
pyimport(m)
+Reference · PythonCall & JuliaCall

PythonCall API Reference

Py objects

PythonCall.PyType
Py(x)

Convert x to a Python object, of type Py.

Conversion happens according to these rules.

Such an object supports attribute access (obj.attr), indexing (obj[idx]), calling (obj(arg1, arg2)), iteration (for x in obj), arithmetic (obj + obj2) and comparison (obj > obj2), among other things. These operations convert all their arguments to Py and return Py.

source
PythonCall.pybuiltinsModule
pybuiltins

An object whose fields are the Python builtins, of type Py.

For example pybuiltins.None, pybuiltins.int, pybuiltins.ValueError.

source

Constructors

These functions construct Python objects of builtin types from Julia values.

PythonCall.pycollistFunction
pycollist(x::AbstractArray)

Create a nested Python list-of-lists from the elements of x. For matrices, this is a list of columns.

source
PythonCall.pycomplexFunction
pycomplex(x=0.0)
+pycomplex(re, im)

Convert x to a Python complex, or create one from given real and imaginary parts.

source
PythonCall.pydictFunction
pydict(x)
+pydict(; x...)

Convert x to a Python dict. In the second form, the keys are strings.

If x is a Python object, this is equivalent to dict(x) in Python. Otherwise x must iterate over key-value pairs.

source
PythonCall.pyfrozensetFunction
pyfrozenset(x=())

Convert x to a Python frozenset.

If x is a Python object, this is equivalent to frozenset(x) in Python. Otherwise x must be iterable.

source
PythonCall.pylistFunction
pylist(x=())

Convert x to a Python list.

If x is a Python object, this is equivalent to list(x) in Python. Otherwise x must be iterable.

source
PythonCall.pyrangeFunction
pyrange([[start], [stop]], [step])

Construct a Python range. Unspecified arguments default to None.

source
PythonCall.pyrowlistFunction
pyrowlist(x::AbstractArray)

Create a nested Python list-of-lists from the elements of x. For matrices, this is a list of rows.

source
PythonCall.pysetFunction
pyset(x=())

Convert x to a Python set.

If x is a Python object, this is equivalent to set(x) in Python. Otherwise x must be iterable.

source
PythonCall.pysliceFunction
pyslice([start], stop, [step])

Construct a Python slice. Unspecified arguments default to None.

source
PythonCall.pytupleFunction
pytuple(x=())

Convert x to a Python tuple.

If x is a Python object, this is equivalent to tuple(x) in Python. Otherwise x must be iterable.

source

Builtins

These functions mimic the Python builtin functions or keywords of the same name.

PythonCall.pycallFunction
pycall(f, args...; kwargs...)

Call the Python object f with the given arguments.

source
PythonCall.pyevalFunction
pyeval([T=Py], code, globals, locals=nothing)

Evaluate the given Python code, returning the result as a T.

If globals is a Module, then a persistent dict unique to that module is used.

By default the code runs in global scope (i.e. locals===globals). To use a temporary local scope, set locals to (), or to a NamedTuple of variables to include in the scope.

See also @pyeval.

Examples

The following computes 1.1+2.2 in the Main module as a Float64:

pyeval(Float64, "x+y", Main, (x=1.1, y=2.2))  # returns 3.3
source
PythonCall.@pyevalMacro
@pyeval [inputs =>] code [=> T]

Evaluate the given code in a new local scope and return the answer as a T.

The global scope is persistent and unique to the current module.

The code must be a literal string or command.

The inputs is a tuple of inputs of the form v=expr to be included in the local scope. Only v is required, expr defaults to v.

Examples

The following computes 1.1+2.2 and returns a Float64:

@pyeval (x=1.1, y=2.2) => `x+y` => Float64  # returns 3.3
source
PythonCall.pyexecFunction
pyexec([T=Nothing], code, globals, locals=nothing)

Execute the given Python code.

If globals is a Module, then a persistent dict unique to that module is used.

By default the code runs in global scope (i.e. locals===globals). To use a temporary local scope, set locals to (), or to a NamedTuple of variables to include in the scope.

If T==Nothing then returns nothing. Otherwise T must be a concrete NamedTuple type and the corresponding items from locals are extracted and returned.

See also @pyexec.

Examples

The following computes 1.1+2.2 in the Main module as a Float64:

pyexec(@NamedTuple{ans::Float64}, "ans=x+y", Main, (x=1.1, y=2.2))  # returns (ans = 3.3,)

Marking variables as global saves them into the module scope, so that they are available in subsequent invocations:

pyexec("global x; x=12", Main)
+pyeval(Int, "x", Main)  # returns 12
source
PythonCall.@pyexecMacro
@pyexec [inputs =>] code [=> outputs]

Execute the given code in a new local scope.

The global scope is persistent and unique to the current module.

The code must be a literal string or command.

The inputs is a tuple of inputs of the form v=expr to be included in the local scope. Only v is required, expr defaults to v.

The outputs is a tuple of outputs of the form x::T=v, meaning that v is extracted from locals, converted to T and assigned to x. Only x is required: T defaults to Py and v defaults to x.

Examples

The following computes 1.1+2.2 and assigns its value to ans as a Float64:

@pyexec (x=1.1, y=2.2) => `ans=x+y` => ans::Float64  # returns 3.3

Marking variables as global saves them into the module scope, so that they are available in subsequent invocations:

@pyexec `global x; x=12`
+@pyeval `x` => Int  # returns 12
source
PythonCall.pygetattrFunction
pygetattr(x, k, [d])

Equivalent to getattr(x, k) or x.k in Python.

If d is specified, it is returned if the attribute does not exist.

source
PythonCall.pygetitemFunction
pygetitem(x, k, [d])

Equivalent x[k] in Python.

If d is specified, it is returned if the item does not exist (i.e. if x[k] raises a KeyError or IndexError).

source
PythonCall.pyhasattrFunction
pyhasattr(x, k)

Equivalent to hasattr(x, k) in Python.

Tests if getattr(x, k) raises an AttributeError.

source
PythonCall.pyimportFunction
pyimport(m)
 pyimport(m => k)
 pyimport(m => (k1, k2, ...))
-pyimport(m1, m2, ...)

Import a module m, or an attribute k, or a tuple of attributes.

If several arguments are given, return the results of importing each one in a tuple.

source
PythonCall.pyisFunction
pyis(x, y)

True if x and y are the same Python object. Equivalent to x is y in Python.

source
PythonCall.pylenFunction
pylen(x)

The length of x. Equivalent to len(x) in Python, converted to an Integer.

source
PythonCall.pywithFunction
pywith(f, o, d=nothing)

Equivalent to with o as x: f(x) in Python, where x is a Py.

On success, the value of f(x) is returned.

If an exception occurs but is suppressed then d is returned.

source

Conversion to Julia

These functions convert Python values to Julia values, using the rules documented here.

PythonCall.pyconvertFunction
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.

source
PythonCall.@pyconvertMacro
@pyconvert(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).

source

Wrap Julia values

These functions explicitly wrap Julia values into Python objects, documented here.

As documented here, Julia values are wrapped like this automatically on conversion to Python, unless the value is immutable and has a corresponding Python type.

PythonCall.pyjlFunction
pyjl([t=pyjltype(x)], x)

Create a Python object wrapping the Julia object x.

If x is mutable, then mutating the returned object also mutates x, and vice versa.

Its Python type is normally inferred from the type of x, but can be specified with t.

For example if x is an AbstractVector then the object will have type juliacall.VectorValue. This object will satisfy the Python sequence interface, so for example uses 0-up indexing.

To define a custom conversion for your type T, overload pyjltype(::T).

source
PythonCall.pyjlrawFunction
pyjlraw(v)

Create a Python object wrapping the Julia object x.

It has type juliacall.RawValue. This has a much more rigid "Julian" interface than pyjl(v). For example, accessing attributes or calling this object will always return a RawValue.

source
PythonCall.pyisjlFunction
pyisjl(x)

Test whether x is a wrapped Julia value, namely an instance of juliacall.ValueBase.

source
PythonCall.pybinaryioFunction
pybinaryio(io::IO)

Wrap io as a Python binary IO object.

This is the default behaviour of Py(io).

source

Arithmetic

These functions are equivalent to the corresponding Python arithmetic operators.

Note that the equivalent Julia operators are overloaded to call these when all arguments are Py (or Number). Hence the following are equivalent: Py(1)+Py(2), Py(1)+2, pyadd(1, 2), pyadd(Py(1), Py(2)), etc.

PythonCall.pyisubFunction
pyisub(x, y)

In-place subtract. x = pyisub(x, y) is equivalent to x -= y in Python.

source
PythonCall.pyimulFunction
pyimul(x, y)

In-place multiply. x = pyimul(x, y) is equivalent to x *= y in Python.

source
PythonCall.pyimatmulFunction
pyimatmul(x, y)

In-place matrix multiply. x = pyimatmul(x, y) is equivalent to x @= y in Python.

source
PythonCall.pyipowFunction
pyipow(x, y, z=None)

In-place power. x = pyipow(x, y) is equivalent to x **= y in Python.

source
PythonCall.pyitruedivFunction
pyitruediv(x, y)

In-place true division. x = pyitruediv(x, y) is equivalent to x /= y in Python.

source
PythonCall.pyimodFunction
pyimod(x, y)

In-place subtraction. x = pyimod(x, y) is equivalent to x %= y in Python.

source
PythonCall.pyilshiftFunction
pyilshift(x, y)

In-place left shift. x = pyilshift(x, y) is equivalent to x <<= y in Python.

source
PythonCall.pyirshiftFunction
pyirshift(x, y)

In-place right shift. x = pyirshift(x, y) is equivalent to x >>= y in Python.

source

Logic

These functions are equivalent to the corresponding Python logical operators.

Note that the equivalent Julia operators are overloaded to call these when all arguments are Py (or Number). Hence the following are equivalent: Py(1) < Py(2), Py(1) < 2, pylt(1, 2), pylt(Py(1), Py(2)), etc.

Note that the binary operators by default return Py (not Bool) since comparisons in Python do not necessarily return bool.

PythonCall.pytruthFunction
pytruth(x)

The truthyness of x. Equivalent to bool(x) in Python, converted to a Bool.

source
PythonCall.pynotFunction
pynot(x)

The falsyness of x. Equivalent to not x in Python, converted to a Bool.

source
PythonCall.pyeqFunction
pyeq(x, y)
-pyeq(Bool, x, y)

Equivalent to x == y in Python. The second form converts to Bool.

source
PythonCall.pyneFunction
pyne(x, y)
-pyne(Bool, x, y)

Equivalent to x != y in Python. The second form converts to Bool.

source
PythonCall.pyleFunction
pyle(x, y)
-pyle(Bool, x, y)

Equivalent to x <= y in Python. The second form converts to Bool.

source
PythonCall.pyltFunction
pylt(x, y)
-pylt(Bool, x, y)

Equivalent to x < y in Python. The second form converts to Bool.

source
PythonCall.pygeFunction
pyge(x, y)
-pyge(Bool, x, y)

Equivalent to x >= y in Python. The second form converts to Bool.

source
PythonCall.pygtFunction
pygt(x, y)
-pygt(Bool, x, y)

Equivalent to x > y in Python. The second form converts to Bool.

source

Create classes

These functions can be used to create new Python classes where the functions are implemented in Julia. You can instead use @pyeval etc. to create pure-Python classes.

PythonCall.pytypeMethod
pytype(name, bases, dict)

Create a new type. Equivalent to type(name, bases, dict) in Python.

If bases is not a Python object, it is converted to one using pytuple.

The dict may either by a Python object or a Julia iterable. In the latter case, each item may either be a name => value pair or a Python object with a __name__ attribute.

In order to use a Julia Function as an instance method, it must be wrapped into a Python function with pyfunc. Similarly, see also pyclassmethod, pystaticmethod or pyproperty. In all these cases, the arguments passed to the function always have type Py. See the example below.

Example

Foo = pytype("Foo", (), [
+pyimport(m1, m2, ...)

Import a module m, or an attribute k, or a tuple of attributes.

If several arguments are given, return the results of importing each one in a tuple.

source
PythonCall.pyisFunction
pyis(x, y)

True if x and y are the same Python object. Equivalent to x is y in Python.

source
PythonCall.pylenFunction
pylen(x)

The length of x. Equivalent to len(x) in Python, converted to an Integer.

source
PythonCall.pywithFunction
pywith(f, o, d=nothing)

Equivalent to with o as x: f(x) in Python, where x is a Py.

On success, the value of f(x) is returned.

If an exception occurs but is suppressed then d is returned.

source

Conversion to Julia

These functions convert Python values to Julia values, using the rules documented here.

PythonCall.pyconvertFunction
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.

source
PythonCall.@pyconvertMacro
@pyconvert(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).

source

Wrap Julia values

These functions explicitly wrap Julia values into Python objects, documented here.

As documented here, Julia values are wrapped like this automatically on conversion to Python, unless the value is immutable and has a corresponding Python type.

PythonCall.pyjlFunction
pyjl([t=pyjltype(x)], x)

Create a Python object wrapping the Julia object x.

If x is mutable, then mutating the returned object also mutates x, and vice versa.

Its Python type is normally inferred from the type of x, but can be specified with t.

For example if x is an AbstractVector then the object will have type juliacall.VectorValue. This object will satisfy the Python sequence interface, so for example uses 0-up indexing.

To define a custom conversion for your type T, overload pyjltype(::T).

source
PythonCall.pyjlrawFunction
pyjlraw(v)

Create a Python object wrapping the Julia object x.

It has type juliacall.RawValue. This has a much more rigid "Julian" interface than pyjl(v). For example, accessing attributes or calling this object will always return a RawValue.

source
PythonCall.pyisjlFunction
pyisjl(x)

Test whether x is a wrapped Julia value, namely an instance of juliacall.ValueBase.

source
PythonCall.pybinaryioFunction
pybinaryio(io::IO)

Wrap io as a Python binary IO object.

This is the default behaviour of Py(io).

source

Arithmetic

These functions are equivalent to the corresponding Python arithmetic operators.

Note that the equivalent Julia operators are overloaded to call these when all arguments are Py (or Number). Hence the following are equivalent: Py(1)+Py(2), Py(1)+2, pyadd(1, 2), pyadd(Py(1), Py(2)), etc.

PythonCall.pyisubFunction
pyisub(x, y)

In-place subtract. x = pyisub(x, y) is equivalent to x -= y in Python.

source
PythonCall.pyimulFunction
pyimul(x, y)

In-place multiply. x = pyimul(x, y) is equivalent to x *= y in Python.

source
PythonCall.pyimatmulFunction
pyimatmul(x, y)

In-place matrix multiply. x = pyimatmul(x, y) is equivalent to x @= y in Python.

source
PythonCall.pyipowFunction
pyipow(x, y, z=None)

In-place power. x = pyipow(x, y) is equivalent to x **= y in Python.

source
PythonCall.pyitruedivFunction
pyitruediv(x, y)

In-place true division. x = pyitruediv(x, y) is equivalent to x /= y in Python.

source
PythonCall.pyimodFunction
pyimod(x, y)

In-place subtraction. x = pyimod(x, y) is equivalent to x %= y in Python.

source
PythonCall.pyilshiftFunction
pyilshift(x, y)

In-place left shift. x = pyilshift(x, y) is equivalent to x <<= y in Python.

source
PythonCall.pyirshiftFunction
pyirshift(x, y)

In-place right shift. x = pyirshift(x, y) is equivalent to x >>= y in Python.

source

Logic

These functions are equivalent to the corresponding Python logical operators.

Note that the equivalent Julia operators are overloaded to call these when all arguments are Py (or Number). Hence the following are equivalent: Py(1) < Py(2), Py(1) < 2, pylt(1, 2), pylt(Py(1), Py(2)), etc.

Note that the binary operators by default return Py (not Bool) since comparisons in Python do not necessarily return bool.

PythonCall.pytruthFunction
pytruth(x)

The truthyness of x. Equivalent to bool(x) in Python, converted to a Bool.

source
PythonCall.pynotFunction
pynot(x)

The falsyness of x. Equivalent to not x in Python, converted to a Bool.

source
PythonCall.pyeqFunction
pyeq(x, y)
+pyeq(Bool, x, y)

Equivalent to x == y in Python. The second form converts to Bool.

source
PythonCall.pyneFunction
pyne(x, y)
+pyne(Bool, x, y)

Equivalent to x != y in Python. The second form converts to Bool.

source
PythonCall.pyleFunction
pyle(x, y)
+pyle(Bool, x, y)

Equivalent to x <= y in Python. The second form converts to Bool.

source
PythonCall.pyltFunction
pylt(x, y)
+pylt(Bool, x, y)

Equivalent to x < y in Python. The second form converts to Bool.

source
PythonCall.pygeFunction
pyge(x, y)
+pyge(Bool, x, y)

Equivalent to x >= y in Python. The second form converts to Bool.

source
PythonCall.pygtFunction
pygt(x, y)
+pygt(Bool, x, y)

Equivalent to x > y in Python. The second form converts to Bool.

source

Create classes

These functions can be used to create new Python classes where the functions are implemented in Julia. You can instead use @pyeval etc. to create pure-Python classes.

PythonCall.pytypeMethod
pytype(name, bases, dict)

Create a new type. Equivalent to type(name, bases, dict) in Python.

If bases is not a Python object, it is converted to one using pytuple.

The dict may either by a Python object or a Julia iterable. In the latter case, each item may either be a name => value pair or a Python object with a __name__ attribute.

In order to use a Julia Function as an instance method, it must be wrapped into a Python function with pyfunc. Similarly, see also pyclassmethod, pystaticmethod or pyproperty. In all these cases, the arguments passed to the function always have type Py. See the example below.

Example

Foo = pytype("Foo", (), [
     "__module__" => "__main__",
 
     pyfunc(
@@ -56,9 +56,9 @@
             nothing
         end,
     ),
-])
source
PythonCall.pyfuncFunction
pyfunc(f; [name], [qualname], [doc], [signature])

Wrap the callable f as an ordinary Python function.

The name, qualname, docstring or signature can optionally be set with name, qualname, doc or signature.

Unlike Py(f) (or pyjl(f)), the arguments passed to f are always of type Py, i.e. they are never converted.

source
PythonCall.pyclassmethodFunction
pyclassmethod(f; ...)

Convert callable f to a Python class method.

If f is not a Python object (e.g. if f is a Function) then it is converted to one with pyfunc. In particular this means the arguments passed to f are always of type Py. Keyword arguments are passed to pyfunc.

source
PythonCall.pystaticmethodFunction
pystaticmethod(f; ...)

Convert callable f to a Python static method.

If f is not a Python object (e.g. if f is a Function) then it is converted to one with pyfunc. In particular this means the arguments passed to f are always of type Py. Any keyword arguments are passed to pyfunc.

source
PythonCall.pypropertyFunction
pyproperty(; get=nothing, set=nothing, del=nothing, doc=nothing)
-pyproperty(get)

Create a Python property with the given getter, setter and deleter.

If get, set or del is not a Python object (e.g. if it is a Function) then it is converted to one with pyfunc. In particular this means the arguments passed to it are always of type Py.

source

Wrapper types

The following types wrap a Python object, giving it the semantics of a Julia object. For example PyList(x) interprets the Python sequence x as a Julia abstract vector.

Apart from a few fundamental immutable types, conversion from Python to Julia Any will return a wrapper type such as one of these, or simply Py if no wrapper type is suitable.

PythonCall.PyListType
PyList{T=Py}([x])

Wraps the Python list x (or anything satisfying the sequence interface) as an AbstractVector{T}.

If x is not a Python object, it is converted to one using pylist.

source
PythonCall.PySetType
PySet{T=Py}([x])

Wraps the Python set x (or anything satisfying the set interface) as an AbstractSet{T}.

If x is not a Python object, it is converted to one using pyset.

source
PythonCall.PyDictType
PyDict{K=Py,V=Py}([x])

Wraps the Python dict x (or anything satisfying the mapping interface) as an AbstractDict{K,V}.

If x is not a Python object, it is converted to one using pydict.

source
PythonCall.PyArrayType
PyArray{T,N,M,L,R}(x; copy=true, array=true, buffer=true)

Wrap the Python array x as a Julia AbstractArray{T,N}.

The input x can be bytes, bytearray, array.array, numpy.ndarray or anything satisfying the buffer protocol (if buffer=true) or the numpy array interface (if array=true).

If copy=false then the resulting array is guaranteed to directly wrap the data in x. If copy=true then a copy is taken if necessary to produce an array.

The type parameters are all optional, and are:

  • T: The element type.
  • N: The number of dimensions.
  • M: True if the array is mutable.
  • L: True if the array supports fast linear indexing.
  • R: The element type of the underlying buffer. Often equal to T.
source
PythonCall.PyIOType
PyIO(x; own=false, text=missing, line_buffering=false, buflen=4096)

Wrap the Python IO stream x as a Julia IO stream.

When this goes out of scope and is finalized, it is automatically flushed. If own=true then it is also closed.

If text=false then x must be a binary stream and arbitrary binary I/O is possible. If text=true then x must be a text stream and only UTF-8 must be written (i.e. use print not write). If text is not specified then it is chosen automatically. If x is a text stream and you really need a binary stream, then often PyIO(x.buffer) will work.

If line_buffering=true then output is flushed at each line.

For efficiency, reads and writes are buffered before being sent to x. The size of the buffers is buflen. The buffers are cleared using flush.

source
PythonCall.PyPandasDataFrameType
PyPandasDataFrame(x; [indexname::Union{Nothing,Symbol}], [columnnames::Function], [columntypes::Function])

Wraps the pandas DataFrame x as a Tables.jl-compatible table.

  • indexname: The name of the column including the index. The default is nothing, meaning to exclude the index.
  • columnnames: A function mapping the Python column name (a Py) to the Julia one (a Symbol). The default is x -> Symbol(x).
  • columntypes: A function taking the column name (a Symbol) and returning either the desired element type of the column, or nothing to indicate automatic inference.
source
PythonCall.PyObjectArrayType
PyObjectArray(undef, dims...)
-PyObjectArray(array)

An array of Pys which supports the Python buffer protocol.

Internally, the objects are stored as an array of pointers.

source

Custom wrappers

Here is a minimal example of defining a wrapper type. You may add methods, fields and a supertype to the type to specialise its behaviour. See any of the above wrapper types for examples.

# The new type with a field for the Python object being wrapped.
+])
source
PythonCall.pyfuncFunction
pyfunc(f; [name], [qualname], [doc], [signature])

Wrap the callable f as an ordinary Python function.

The name, qualname, docstring or signature can optionally be set with name, qualname, doc or signature.

Unlike Py(f) (or pyjl(f)), the arguments passed to f are always of type Py, i.e. they are never converted.

source
PythonCall.pyclassmethodFunction
pyclassmethod(f; ...)

Convert callable f to a Python class method.

If f is not a Python object (e.g. if f is a Function) then it is converted to one with pyfunc. In particular this means the arguments passed to f are always of type Py. Keyword arguments are passed to pyfunc.

source
PythonCall.pystaticmethodFunction
pystaticmethod(f; ...)

Convert callable f to a Python static method.

If f is not a Python object (e.g. if f is a Function) then it is converted to one with pyfunc. In particular this means the arguments passed to f are always of type Py. Any keyword arguments are passed to pyfunc.

source
PythonCall.pypropertyFunction
pyproperty(; get=nothing, set=nothing, del=nothing, doc=nothing)
+pyproperty(get)

Create a Python property with the given getter, setter and deleter.

If get, set or del is not a Python object (e.g. if it is a Function) then it is converted to one with pyfunc. In particular this means the arguments passed to it are always of type Py.

source

Wrapper types

The following types wrap a Python object, giving it the semantics of a Julia object. For example PyList(x) interprets the Python sequence x as a Julia abstract vector.

Apart from a few fundamental immutable types, conversion from Python to Julia Any will return a wrapper type such as one of these, or simply Py if no wrapper type is suitable.

PythonCall.PyListType
PyList{T=Py}([x])

Wraps the Python list x (or anything satisfying the sequence interface) as an AbstractVector{T}.

If x is not a Python object, it is converted to one using pylist.

source
PythonCall.PySetType
PySet{T=Py}([x])

Wraps the Python set x (or anything satisfying the set interface) as an AbstractSet{T}.

If x is not a Python object, it is converted to one using pyset.

source
PythonCall.PyDictType
PyDict{K=Py,V=Py}([x])

Wraps the Python dict x (or anything satisfying the mapping interface) as an AbstractDict{K,V}.

If x is not a Python object, it is converted to one using pydict.

source
PythonCall.PyArrayType
PyArray{T,N,M,L,R}(x; copy=true, array=true, buffer=true)

Wrap the Python array x as a Julia AbstractArray{T,N}.

The input x can be bytes, bytearray, array.array, numpy.ndarray or anything satisfying the buffer protocol (if buffer=true) or the numpy array interface (if array=true).

If copy=false then the resulting array is guaranteed to directly wrap the data in x. If copy=true then a copy is taken if necessary to produce an array.

The type parameters are all optional, and are:

  • T: The element type.
  • N: The number of dimensions.
  • M: True if the array is mutable.
  • L: True if the array supports fast linear indexing.
  • R: The element type of the underlying buffer. Often equal to T.
source
PythonCall.PyIOType
PyIO(x; own=false, text=missing, line_buffering=false, buflen=4096)

Wrap the Python IO stream x as a Julia IO stream.

When this goes out of scope and is finalized, it is automatically flushed. If own=true then it is also closed.

If text=false then x must be a binary stream and arbitrary binary I/O is possible. If text=true then x must be a text stream and only UTF-8 must be written (i.e. use print not write). If text is not specified then it is chosen automatically. If x is a text stream and you really need a binary stream, then often PyIO(x.buffer) will work.

If line_buffering=true then output is flushed at each line.

For efficiency, reads and writes are buffered before being sent to x. The size of the buffers is buflen. The buffers are cleared using flush.

source
PythonCall.PyPandasDataFrameType
PyPandasDataFrame(x; [indexname::Union{Nothing,Symbol}], [columnnames::Function], [columntypes::Function])

Wraps the pandas DataFrame x as a Tables.jl-compatible table.

  • indexname: The name of the column including the index. The default is nothing, meaning to exclude the index.
  • columnnames: A function mapping the Python column name (a Py) to the Julia one (a Symbol). The default is x -> Symbol(x).
  • columntypes: A function taking the column name (a Symbol) and returning either the desired element type of the column, or nothing to indicate automatic inference.
source
PythonCall.PyObjectArrayType
PyObjectArray(undef, dims...)
+PyObjectArray(array)

An array of Pys which supports the Python buffer protocol.

Internally, the objects are stored as an array of pointers.

source

Custom wrappers

Here is a minimal example of defining a wrapper type. You may add methods, fields and a supertype to the type to specialise its behaviour. See any of the above wrapper types for examples.

# The new type with a field for the Python object being wrapped.
 struct MyType
     py::Py
 end
@@ -67,4 +67,4 @@
 ispy(x::MyType) = true
 
 # Says how to access the underlying Python object.
-Py(x::MyType) = x.py

@py and @pyconst

PythonCall.@pyMacro
@py expr

Evaluate the given expression using Pythonic semantics.

For example:

  • f(x, y) is translated to pycall(f, x, y)
  • x + y is translated to pyadd(x, y)
  • x === y is translated to pyis(x, y)
  • x.foo is translated to pygetattr(x, "foo")

Compound statements such as begin, if, while and for are supported.

See the online documentation for more details.

Warning

This macro is experimental. It may be modified or removed in a future release.

source
PythonCall.@pyconstMacro
@pyconst ex

Equivalent to Py(ex) but always returns the exact same Julia object.

That is, if foo() = @pyconst ex then foo() === foo().

The expression ex is evaluated the first time the code is run.

If ex is a string literal, the string is interned.

Do not use this macro at the top level of a module. Instead, use pynew() and pycopy!().

source

Low-level API

The functions here are not exported. They are mostly unsafe in the sense that you can crash Julia by using them incorrectly.

PythonCall.pynewFunction
pynew([ptr])

A new Py representing the Python object at ptr (NULL by default).

If ptr is given and non-NULL, this function steals a reference to the Python object it points at, i.e. the new Py object owns a reference.

Note that NULL Python objects are not safe in the sense that most API functions will probably crash your Julia session if you pass a NULL argument.

source
PythonCall.pycopy!Function
pycopy!(dst::Py, src)

Copy the Python object src into dst, so that they both represent the same object.

This function exists to support module-level constant Python objects. It is illegal to call most PythonCall API functions at the top level of a module (i.e. before __init__() has run) so you cannot do const x = pything() at the top level. Instead do const x = pynew() at the top level then pycopy!(x, pything()) inside __init__().

Assumes dst is NULL, otherwise a memory leak will occur.

source
PythonCall.pydel!Function
pydel!(x::Py)

Delete the Python object x.

DANGER! Use this function ONLY IF the Julia object x could have been garbage-collected anyway, i.e. was about to become unreachable. This means you MUST KNOW that no other part of the program has the Julia object x.

This decrements the reference count, sets the pointer to NULL and appends x to a cache of unused objects (PYNULL_CACHE).

This is an optimization to avoid excessive allocation and deallocation in Julia, which can be a significant source of slow-down in code which uses a lot of Python objects. It allows pynew() to pop an item from PYNULL_CACHE instead of allocating one, and avoids calling the relatively slow finalizer on x.

source
+Py(x::MyType) = x.py

@py and @pyconst

PythonCall.@pyMacro
@py expr

Evaluate the given expression using Pythonic semantics.

For example:

  • f(x, y) is translated to pycall(f, x, y)
  • x + y is translated to pyadd(x, y)
  • x === y is translated to pyis(x, y)
  • x.foo is translated to pygetattr(x, "foo")

Compound statements such as begin, if, while and for are supported.

See the online documentation for more details.

Warning

This macro is experimental. It may be modified or removed in a future release.

source
PythonCall.@pyconstMacro
@pyconst ex

Equivalent to Py(ex) but always returns the exact same Julia object.

That is, if foo() = @pyconst ex then foo() === foo().

The expression ex is evaluated the first time the code is run.

If ex is a string literal, the string is interned.

Do not use this macro at the top level of a module. Instead, use pynew() and pycopy!().

source

Low-level API

The functions here are not exported. They are mostly unsafe in the sense that you can crash Julia by using them incorrectly.

PythonCall.pynewFunction
pynew([ptr])

A new Py representing the Python object at ptr (NULL by default).

If ptr is given and non-NULL, this function steals a reference to the Python object it points at, i.e. the new Py object owns a reference.

Note that NULL Python objects are not safe in the sense that most API functions will probably crash your Julia session if you pass a NULL argument.

source
PythonCall.pyisnullFunction
pyisnull(x)

True if the Python object x is NULL.

source
PythonCall.pycopy!Function
pycopy!(dst::Py, src)

Copy the Python object src into dst, so that they both represent the same object.

This function exists to support module-level constant Python objects. It is illegal to call most PythonCall API functions at the top level of a module (i.e. before __init__() has run) so you cannot do const x = pything() at the top level. Instead do const x = pynew() at the top level then pycopy!(x, pything()) inside __init__().

Assumes dst is NULL, otherwise a memory leak will occur.

source
PythonCall.getptrFunction
getptr(x)

Get the underlying pointer from the Python object x.

source
PythonCall.pydel!Function
pydel!(x::Py)

Delete the Python object x.

DANGER! Use this function ONLY IF the Julia object x could have been garbage-collected anyway, i.e. was about to become unreachable. This means you MUST KNOW that no other part of the program has the Julia object x.

This decrements the reference count, sets the pointer to NULL and appends x to a cache of unused objects (PYNULL_CACHE).

This is an optimization to avoid excessive allocation and deallocation in Julia, which can be a significant source of slow-down in code which uses a lot of Python objects. It allows pynew() to pop an item from PYNULL_CACHE instead of allocating one, and avoids calling the relatively slow finalizer on x.

source
PythonCall.unsafe_pynextFunction
unsafe_pynext(x)

Return the next item in the iterator x. When there are no more items, return NULL.

source
diff --git a/dev/pythoncall/index.html b/dev/pythoncall/index.html index f917afd0..f1cb3513 100644 --- a/dev/pythoncall/index.html +++ b/dev/pythoncall/index.html @@ -123,4 +123,4 @@ end

or even cache the imported function

module MyModule
   using PythonCall
   bar() = @pyconst(pyimport("foo").bar)()
-end

Dependencies

If your package depends on some Python packages, you must generate a CondaPkg.toml file. See Installing Python packages.

+end

Dependencies

If your package depends on some Python packages, you must generate a CondaPkg.toml file. See Installing Python packages.

diff --git a/dev/releasenotes/index.html b/dev/releasenotes/index.html index a86d42e1..6e75c27b 100644 --- a/dev/releasenotes/index.html +++ b/dev/releasenotes/index.html @@ -1,2 +1,2 @@ -Release Notes · PythonCall & JuliaCall

Release Notes

Unreleased

  • JuliaCall now supports -X juliacall-startup-file=no to disable running startup.jl.

0.9.14 (2023-07-26)

  • Wrapped Julia values support truthiness (__bool__) better: all values are true, except for zero numbers and empty arrays, dicts and sets.
  • JuliaCall now supports the Julia --handle-signals option. Setting this to yes allows allocating multithreaded Julia code to be called from JuliaCall without segfaulting. The default is no while compatibility concerns are investigated, and may be changed to yes in a future release.

0.9.13 (2023-05-14)

  • Conversion to wrapper types PyList, PySet, PyDict or PyIterable now default to having element type Any instead of Py.
  • The __repr__ method of wrapped Julia objects now uses the 3-arg show method for nicer (richer and truncated) display at the Python REPL.
  • The IPython extension can now be loaded as just %load_ext juliacall.
  • The %%julia IPython magic can now synchronise variables between Python and Julia.
  • Bug fixes.

0.9.12 (2023-02-28)

  • Bug fixes.

0.9.11 (2023-02-15)

  • In PyArray{T}(x), the eltype T no longer needs to exactly match the stored data type. If x has numeric elements, then any number type T is allowed. If x has string elements, then any string type T is allowed.
  • StaticString (the inline string type used by PyArray) supports the AbstractString interface better.

0.9.10 (2022-12-02)

  • Bug fixes.

0.9.9 (2022-10-20)

  • Bug fixes.

0.9.8 (2022-10-18)

  • Adds line_buffering option to PyIO.
  • Improvements to stdout when using juliacall.ipython including line-buffering.

0.9.7 (2022-10-11)

  • If CondaPkg is using the Null backend, PythonCall will now use python from the PATH.
  • Bug fixes.

0.9.6 (2022-09-09)

  • When using JuliaCall from an interactive Python session, Julia is put into interactive mode: isinteractive() is true, InteractiveUtils is loaded, and a nicer display is used.
  • Wrapped Julia values now truncate their output when displayed via _repr_mimebundle_.
  • Numpy arrays with structured dtypes can now be converted to PyArray, provided the fields are aligned.
  • Python named tuples can be converted to Julia named tuples.
  • Bug fixes.

0.9.5 (2022-08-19)

  • Adds PythonCall.GC.disable() and PythonCall.GC.enable().
  • Experimental new function juliacall.interactive() allows the Julia async event loop to run in the background of the Python REPL.
  • Experimental new IPython extension juliacall.ipython providing the %julia and %%julia magics for executing Julia code.
  • Experimental new module juliacall.importer allowing you to write Python modules in Julia.
  • Bug fixes.

0.9.4 (2022-07-26)

  • Bug fixes.

0.9.3 (2022-07-02)

  • Bug fixes.

0.9.2 (2022-07-02)

  • Many Julia CLI options (such sysimage or number of threads) can be set from JuliaCall.
  • Bug fixes.

0.9.1 (2022-06-18)

  • PyArray can be constructed using the __array_struct__ part of the Numpy array interface. Constructing PyArray(x) is now about 50x faster, or 175x faster if you fully specify the type.
  • JuliaCall can now be imported on Apple M1.

0.9.0 (2022-05-27)

  • Breaking. Removes getpy: you may now overload Py directly, which now need not always return a new object (e.g. for singletons or wrappers).
  • Breaking. Conversion rules no longer take a new object every time.
  • Breaking. Improved Tables-interface support for PyPandasDataFrame: better inferred column types; better handling of non-string column names; columns are usually wrappers (PyArray or PyList). Constructor arguments have changed. Dict methods have been removed (basically only the Tables interface is supported).
  • Breaking. A Py which is convertible to PyTable is no longer considered to be a table itself; you must convert explicitly.
  • Adds pyhasitem and 3-arg pygetitem.
  • Extends Base.get, Base.get!, Base.haskey and 2-arg Base.hash for Py.
  • PyArray can now have any element type when the underlying array is of Python objects.
  • Adds ArrayValue.to_numpy().
  • Bug fixes.

v0.8.0 (2022-03-17)

  • Breaking: Removes pymethod and pyclass. In the future, pyclass may become sugar for types.new_class (namely you can specify a metaclass).
  • Adds pyfunc, pyclassmethod, pystaticmethod and pyproperty.
  • pyconvert_add_rule is now documented. Its semantics have changed, including the separator of the first argument from / to :.
  • A pandas <NA> value is now converted to missing.
  • A NaN in a PyPandasDataFrame is converted to missing.
  • Breaking: Removes using and As from JuliaCall.
  • Adds convert to JuliaCall (replacing As).
  • Bug fixes.

v0.6.1 (2022-02-21)

  • Conversions from simple ctypes types, e.g. ctypes.c_float to Cfloat.
  • Conversions from simple numpy types, e.g. numpy.float32 to Float32.
  • Bug fixes.

v0.6.0 (2022-02-17)

  • Breaking: JuliaCall now uses JuliaPkg to manage Julia dependencies.
  • Bug fixes.

v0.5.1 (2022-01-24)

  • Bug fixes.

v0.5.0 (2021-12-11)

  • Breaking: PythonCall now uses CondaPkg to manage Python dependencies.
  • Python objects can be shared with PyCall provided it uses the same interpreter, using methods PythonCall.Py(::PyCall.PyObject) and PyCall.PyObject(::PythonCall.Py).
  • Adds PythonDisplay which displays objects by printing to Python's sys.stdout. Used automatically in IPython in addition to IPythonDisplay.
  • Removes the GLOBAL mode from @pyexec. Use global in the code instead.
  • Bug fixes.
+Release Notes · PythonCall & JuliaCall

Release Notes

Unreleased

  • JuliaCall now supports -X juliacall-startup-file=no to disable running startup.jl.

0.9.14 (2023-07-26)

  • Wrapped Julia values support truthiness (__bool__) better: all values are true, except for zero numbers and empty arrays, dicts and sets.
  • JuliaCall now supports the Julia --handle-signals option. Setting this to yes allows allocating multithreaded Julia code to be called from JuliaCall without segfaulting. The default is no while compatibility concerns are investigated, and may be changed to yes in a future release.

0.9.13 (2023-05-14)

  • Conversion to wrapper types PyList, PySet, PyDict or PyIterable now default to having element type Any instead of Py.
  • The __repr__ method of wrapped Julia objects now uses the 3-arg show method for nicer (richer and truncated) display at the Python REPL.
  • The IPython extension can now be loaded as just %load_ext juliacall.
  • The %%julia IPython magic can now synchronise variables between Python and Julia.
  • Bug fixes.

0.9.12 (2023-02-28)

  • Bug fixes.

0.9.11 (2023-02-15)

  • In PyArray{T}(x), the eltype T no longer needs to exactly match the stored data type. If x has numeric elements, then any number type T is allowed. If x has string elements, then any string type T is allowed.
  • StaticString (the inline string type used by PyArray) supports the AbstractString interface better.

0.9.10 (2022-12-02)

  • Bug fixes.

0.9.9 (2022-10-20)

  • Bug fixes.

0.9.8 (2022-10-18)

  • Adds line_buffering option to PyIO.
  • Improvements to stdout when using juliacall.ipython including line-buffering.

0.9.7 (2022-10-11)

  • If CondaPkg is using the Null backend, PythonCall will now use python from the PATH.
  • Bug fixes.

0.9.6 (2022-09-09)

  • When using JuliaCall from an interactive Python session, Julia is put into interactive mode: isinteractive() is true, InteractiveUtils is loaded, and a nicer display is used.
  • Wrapped Julia values now truncate their output when displayed via _repr_mimebundle_.
  • Numpy arrays with structured dtypes can now be converted to PyArray, provided the fields are aligned.
  • Python named tuples can be converted to Julia named tuples.
  • Bug fixes.

0.9.5 (2022-08-19)

  • Adds PythonCall.GC.disable() and PythonCall.GC.enable().
  • Experimental new function juliacall.interactive() allows the Julia async event loop to run in the background of the Python REPL.
  • Experimental new IPython extension juliacall.ipython providing the %julia and %%julia magics for executing Julia code.
  • Experimental new module juliacall.importer allowing you to write Python modules in Julia.
  • Bug fixes.

0.9.4 (2022-07-26)

  • Bug fixes.

0.9.3 (2022-07-02)

  • Bug fixes.

0.9.2 (2022-07-02)

  • Many Julia CLI options (such sysimage or number of threads) can be set from JuliaCall.
  • Bug fixes.

0.9.1 (2022-06-18)

  • PyArray can be constructed using the __array_struct__ part of the Numpy array interface. Constructing PyArray(x) is now about 50x faster, or 175x faster if you fully specify the type.
  • JuliaCall can now be imported on Apple M1.

0.9.0 (2022-05-27)

  • Breaking. Removes getpy: you may now overload Py directly, which now need not always return a new object (e.g. for singletons or wrappers).
  • Breaking. Conversion rules no longer take a new object every time.
  • Breaking. Improved Tables-interface support for PyPandasDataFrame: better inferred column types; better handling of non-string column names; columns are usually wrappers (PyArray or PyList). Constructor arguments have changed. Dict methods have been removed (basically only the Tables interface is supported).
  • Breaking. A Py which is convertible to PyTable is no longer considered to be a table itself; you must convert explicitly.
  • Adds pyhasitem and 3-arg pygetitem.
  • Extends Base.get, Base.get!, Base.haskey and 2-arg Base.hash for Py.
  • PyArray can now have any element type when the underlying array is of Python objects.
  • Adds ArrayValue.to_numpy().
  • Bug fixes.

v0.8.0 (2022-03-17)

  • Breaking: Removes pymethod and pyclass. In the future, pyclass may become sugar for types.new_class (namely you can specify a metaclass).
  • Adds pyfunc, pyclassmethod, pystaticmethod and pyproperty.
  • pyconvert_add_rule is now documented. Its semantics have changed, including the separator of the first argument from / to :.
  • A pandas <NA> value is now converted to missing.
  • A NaN in a PyPandasDataFrame is converted to missing.
  • Breaking: Removes using and As from JuliaCall.
  • Adds convert to JuliaCall (replacing As).
  • Bug fixes.

v0.6.1 (2022-02-21)

  • Conversions from simple ctypes types, e.g. ctypes.c_float to Cfloat.
  • Conversions from simple numpy types, e.g. numpy.float32 to Float32.
  • Bug fixes.

v0.6.0 (2022-02-17)

  • Breaking: JuliaCall now uses JuliaPkg to manage Julia dependencies.
  • Bug fixes.

v0.5.1 (2022-01-24)

  • Bug fixes.

v0.5.0 (2021-12-11)

  • Breaking: PythonCall now uses CondaPkg to manage Python dependencies.
  • Python objects can be shared with PyCall provided it uses the same interpreter, using methods PythonCall.Py(::PyCall.PyObject) and PyCall.PyObject(::PythonCall.Py).
  • Adds PythonDisplay which displays objects by printing to Python's sys.stdout. Used automatically in IPython in addition to IPythonDisplay.
  • Removes the GLOBAL mode from @pyexec. Use global in the code instead.
  • Bug fixes.
diff --git a/dev/search/index.html b/dev/search/index.html index 9495b698..bf138b44 100644 --- a/dev/search/index.html +++ b/dev/search/index.html @@ -1,2 +1,2 @@ -Search · PythonCall & JuliaCall

Loading search...

    +Search · PythonCall & JuliaCall

    Loading search...