# Python Functions

PyO3 supports two ways to define a free function in Python. Both require registering the function to a [module](./module.md).

One way is annotating a function with `#[pyfunction]` and then adding it to the module using the `wrap_pyfunction!` macro.

```rust
use pyo3::prelude::*;

#[pyfunction]
fn double(x: usize) -> usize {
    x * 2
}

#[pymodule]
fn my_extension(py: Python, m: &PyModule) -> PyResult<()> {
    m.add_function(wrap_pyfunction!(double, m)?)?;
    Ok(())
}
```

Alternatively, there is a shorthand: the function can be placed inside the module definition and
annotated with `#[pyfn]`, as below:

```rust
use pyo3::prelude::*;

#[pymodule]
fn my_extension(py: Python, m: &PyModule) -> PyResult<()> {

    #[pyfn(m)]
    fn double(x: usize) -> usize {
        x * 2
    }

    Ok(())
}
```

`#[pyfn(m)]` is just syntactic sugar for `#[pyfunction]`, and takes all the same options
documented in the rest of this chapter. The code above is expanded to the following:

```rust
use pyo3::prelude::*;

#[pymodule]
fn my_extension(py: Python, m: &PyModule) -> PyResult<()> {

    #[pyfunction]
    fn double(x: usize) -> usize {
        x * 2
    }

    m.add_function(wrap_pyfunction!(double, m)?)?;
    Ok(())
}
```

## Function options

The `#[pyo3]` attribute can be used to modify properties of the generated Python function. It can take any combination of the following options:

  - `#[pyo3(name = "...")]`

    Overrides the name generated in Python:

    ```rust
    use pyo3::prelude::*;

    #[pyfunction]
    #[pyo3(name = "no_args")]
    fn no_args_py() -> usize { 42 }

    #[pymodule]
    fn module_with_functions(py: Python, m: &PyModule) -> PyResult<()> {
        m.add_function(wrap_pyfunction!(no_args_py, m)?)?;
        Ok(())
    }

    # Python::with_gil(|py| {
    #     let m = pyo3::wrap_pymodule!(module_with_functions)(py);
    #     assert!(m.getattr(py, "no_args").is_ok());
    #     assert!(m.getattr(py, "no_args_py").is_err());
    # });
    ```

## Argument parsing

The `#[pyfunction]` attribute supports specifying details of argument parsing. The details are given in the section ["Method arguments" of the Classes chapter](class.md#method-arguments).  Here is an example for a function that accepts arbitrary keyword arguments (`**kwargs` in Python syntax) and returns the number that was passed:

```rust
use pyo3::prelude::*;
use pyo3::types::PyDict;

#[pyfunction(kwds="**")]
fn num_kwds(kwds: Option<&PyDict>) -> usize {
    kwds.map_or(0, |dict| dict.len())
}

#[pymodule]
fn module_with_functions(py: Python, m: &PyModule) -> PyResult<()> {
    m.add_function(wrap_pyfunction!(num_kwds, m)?).unwrap();
    Ok(())
}

# fn main() {}
```

## Making the function signature available to Python

In order to make the function signature available to Python to be retrieved via
`inspect.signature`, use the `#[pyo3(text_signature)]` annotation as in the example
below. The `/` signifies the end of positional-only arguments. (This
is not a feature of this library in particular, but the general format used by
CPython for annotating signatures of built-in functions.)

```rust
use pyo3::prelude::*;

/// This function adds two unsigned 64-bit integers.
#[pyfunction]
#[pyo3(text_signature = "(a, b, /)")]
fn add(a: u64, b: u64) -> u64 {
    a + b
}
```

This also works for classes and methods:

```rust
use pyo3::prelude::*;
use pyo3::types::PyType;

// it works even if the item is not documented:

#[pyclass]
#[pyo3(text_signature = "(c, d, /)")]
struct MyClass {}

#[pymethods]
impl MyClass {
    // the signature for the constructor is attached
    // to the struct definition instead.
    #[new]
    fn new(c: i32, d: &str) -> Self {
        Self {}
    }
    // the self argument should be written $self
    #[pyo3(text_signature = "($self, e, f)")]
    fn my_method(&self, e: i32, f: i32) -> i32 {
        e + f
    }
    #[classmethod]
    #[pyo3(text_signature = "(cls, e, f)")]
    fn my_class_method(cls: &PyType, e: i32, f: i32) -> i32 {
        e + f
    }
    #[staticmethod]
    #[pyo3(text_signature = "(e, f)")]
    fn my_static_method(e: i32, f: i32) -> i32 {
        e + f
    }
}
```

Note that `text_signature` on classes is not compatible with compilation in
`abi3` mode until Python 3.10 or greater.

### Making the function signature available to Python (old method)

Alternatively, simply make sure the first line of your docstring is
formatted like in the following example. Please note that the newline after the
`--` is mandatory. The `/` signifies the end of positional-only arguments.

`#[pyo3(text_signature)]` should be preferred, since it will override automatically
generated signatures when those are added in a future version of PyO3.

```rust
use pyo3::prelude::*;

/// add(a, b, /)
/// --
///
/// This function adds two unsigned 64-bit integers.
#[pyfunction]
fn add(a: u64, b: u64) -> u64 {
    a + b
}

// a function with a signature but without docs. Both blank lines after the `--` are mandatory.

/// sub(a, b, /)
/// --
///
///
#[pyfunction]
fn sub(a: u64, b: u64) -> u64 {
    a - b
}
```

When annotated like this, signatures are also correctly displayed in IPython.

```ignore
>>> pyo3_test.add?
Signature: pyo3_test.add(a, b, /)
Docstring: This function adds two unsigned 64-bit integers.
Type:      builtin_function_or_method
```

## Closures

Currently, there are no conversions between `Fn`s in Rust and callables in Python. This would
definitely be possible and very useful, so contributions are welcome. In the meantime, you can do
the following:

### Calling Python functions in Rust

You can pass Python `def`'d functions and built-in functions to Rust functions [`PyFunction`]
corresponds to regular Python functions while [`PyCFunction`] describes built-ins such as
`repr()`.

You can also use [`PyAny::is_callable`] to check if you have a callable object. `is_callable` will
return `true` for functions (including lambdas), methods and objects with a `__call__` method.
You can call the object with [`PyAny::call`] with the args as first parameter and the kwargs
(or `None`) as second parameter. There are also [`PyAny::call0`] with no args and [`PyAny::call1`]
with only positional args.

### Calling Rust functions in Python

If you have a static function, you can expose it with `#[pyfunction]` and use [`wrap_pyfunction!`]
to get the corresponding [`PyCFunction`]. For dynamic functions, e.g. lambdas and functions that
were passed as arguments, you must put them in some kind of owned container, e.g. a `Box`.
(A long-term solution will be a special container similar to wasm-bindgen's `Closure`). You can
then use a `#[pyclass]` struct with that container as a field as a way to pass the function over
the FFI barrier. You can even make that class callable with `__call__` so it looks like a function
in Python code.

[`PyAny::is_callable`]: {{#PYO3_DOCS_URL}}/pyo3/struct.PyAny.html#tymethod.is_callable
[`PyAny::call`]: {{#PYO3_DOCS_URL}}/pyo3/struct.PyAny.html#tymethod.call
[`PyAny::call0`]: {{#PYO3_DOCS_URL}}/pyo3/struct.PyAny.html#tymethod.call0
[`PyAny::call1`]: {{#PYO3_DOCS_URL}}/pyo3/struct.PyAny.html#tymethod.call1
[`PyObject`]: {{#PYO3_DOCS_URL}}/pyo3/type.PyObject.html
[`wrap_pyfunction!`]: {{#PYO3_DOCS_URL}}/pyo3/macro.wrap_pyfunction.html
[`PyFunction`]: {{#PYO3_DOCS_URL}}/pyo3/types/struct.PyFunction.html
[`PyCFunction`]: {{#PYO3_DOCS_URL}}/pyo3/types/struct.PyCFunction.html

### Accessing the module of a function

It is possible to access the module of a `#[pyfunction]` in the function body by using `#[pyo3(pass_module)]` option:

```rust
use pyo3::prelude::*;

#[pyfunction]
#[pyo3(pass_module)]
fn pyfunction_with_module(module: &PyModule) -> PyResult<&str> {
    module.name()
}

#[pymodule]
fn module_with_fn(py: Python, m: &PyModule) -> PyResult<()> {
    m.add_function(wrap_pyfunction!(pyfunction_with_module, m)?)
}

# fn main() {}
```

If `pass_module` is set, the first argument **must** be the `&PyModule`. It is then possible to use the module
in the function body.

## Accessing the FFI functions

In order to make Rust functions callable from Python, PyO3 generates an `extern "C"`
function whose exact signature depends on the Rust signature.  (PyO3 chooses the optimal
Python argument passing convention.) It then embeds the call to the Rust function inside this
FFI-wrapper function. This wrapper handles extraction of the regular arguments and the keyword
arguments from the input `PyObject`s.

The `wrap_pyfunction` macro can be used to directly get a `PyCFunction` given a
`#[pyfunction]` and a `PyModule`: `wrap_pyfunction!(rust_fun, module)`.
