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.

PythonCall.pybuiltinsModule
pybuiltins

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

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

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.

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

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

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.

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.

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.

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

Construct a Python range. Unspecified arguments default to None.

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.

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.

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

Construct a Python slice. Unspecified arguments default to None.

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.

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.

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

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

PythonCall.pyhasattrFunction
pyhasattr(x, k)

Equivalent to hasattr(x, k) in Python.

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

PythonCall.pyhasitemFunction
pyhasitem(x, k)

Test if pygetitem(x, k) raises a KeyError or AttributeError.

PythonCall.pyhashFunction
pyhash(x)

Equivalent to hash(x) in Python, converted to an Integer.

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.

PythonCall.pyisFunction
pyis(x, y)

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

PythonCall.pyisinstanceFunction
pyisinstance(x, t)

Test if x is of type t. Equivalent to isinstance(x, t) in Python.

PythonCall.pyissubclassFunction
pyissubclass(s, t)

Test if s is a subclass of t. Equivalent to issubclass(s, t) in Python.

PythonCall.pylenFunction
pylen(x)

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

PythonCall.pysetattrFunction
pysetattr(x, k, v)

Equivalent to setattr(x, k, v) or x.k = v in Python.

PythonCall.pysetitemFunction
pysetitem(x, k, v)

Equivalent to setitem(x, k, v) or x[k] = v in Python.

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.

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.

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

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

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.

PythonCall.pyisjlFunction
pyisjl(x)

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

PythonCall.pybinaryioFunction
pybinaryio(io::IO)

Wrap io as a Python binary IO object.

This is the default behaviour of Py(io).

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.pypowFunction
pypow(x, y, z=None)

Equivalent to x ** y or pow(x, y, z) in Python.

PythonCall.pyiaddFunction
pyiadd(x, y)

In-place add. x = pyiadd(x, y) is equivalent to x += y in Python.

PythonCall.pyisubFunction
pyisub(x, y)

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

PythonCall.pyimulFunction
pyimul(x, y)

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

PythonCall.pyimatmulFunction
pyimatmul(x, y)

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

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

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

PythonCall.pyifloordivFunction
pyifloordiv(x, y)

In-place floor divide. x = pyifloordiv(x, y) is equivalent to x //= y in Python.

PythonCall.pyitruedivFunction
pyitruediv(x, y)

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

PythonCall.pyimodFunction
pyimod(x, y)

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

PythonCall.pyilshiftFunction
pyilshift(x, y)

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

PythonCall.pyirshiftFunction
pyirshift(x, y)

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

PythonCall.pyiandFunction
pyiand(x, y)

In-place and. x = pyiand(x, y) is equivalent to x &= y in Python.

PythonCall.pyixorFunction
pyixor(x, y)

In-place xor. x = pyixor(x, y) is equivalent to x ^= y in Python.

PythonCall.pyiorFunction
pyior(x, y)

In-place or. x = pyior(x, y) is equivalent to x |= y in Python.

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.

PythonCall.pynotFunction
pynot(x)

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

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

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

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

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

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

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

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

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

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

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

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

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

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(
        name = "__init__",
        doc = """
        Specify x and y to store in the Foo.

        If omitted, y defaults to None.
        """,
        function (self, x, y = nothing)
            self.x = x
            self.y = y
            return
        end,
    ),

    pyfunc(
        name = "__repr__",
        self -> "Foo($(self.x), $(self.y))",
    ),

    pyclassmethod(
        name = "frompair",
        doc = "Construct a Foo from a tuple of length two.",
        (cls, xy) -> cls(xy...),
    ),

    pystaticmethod(
        name = "hello",
        doc = "Prints a friendly greeting.",
        (name) -> println("Hello, $name"),
    ),

    "xy" => pyproperty(
        doc = "A tuple of x and y.",
        get = (self) -> (self.x, self.y),
        set = function (self, xy)
            (x, y) = xy
            self.x = x
            self.y = y
            nothing
        end,
    ),
])
PythonCall.pyfuncFunction
pyfunc(f; name=nothing, qualname=name, doc=nothing, signature=nothing)

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.

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.

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.

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.

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.

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.

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.

PythonCall.PyIterableType
PyIterable{T=Py}(x)

This object iterates over iterable Python object x, yielding values of type T.

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. Equal to T for scalar numeric types.
PythonCall.PyIOType
PyIO(x; own=false, text=missing, 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.

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.

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

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

# Says that the object is a wrapper.
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.

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

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.

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.

PythonCall.getptrFunction
getptr(x)

Get the underlying pointer from the Python object x.

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.

PythonCall.unsafe_pynextFunction
unsafe_pynext(x)

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