Code Monkey home page Code Monkey logo

ipybind's Introduction

ipybind is an IPython extension that allows building and importing pybind11 modules in IPython environment, such as IPython console or Jupyter notebooks running a Python kernel.

%%pybind11

Enabling the extension

To enable ipybind extension in the current kernel:

%load_ext ipybind

In all examples that follow we assume that the extension has been previously loaded.

Basic usage example

%%pybind11

PYBIND11_PLUGIN(example) {
    py::module m("example");
    m.def("add", [](int x, int y) { return x + y; });
    return m.ptr();
}

This will build the extension module and import all symbols from it into the current namespace:

>>> add(1, 2)
3

Caching and recompilation

Each compiled module is assigned a hash based on the code contents, arguments to %%pybind magic and Python interpreter version. Sources for compiled modules and the binaries are stored under $IPYTHONDIR/pybind11 (on Linux / macOS it's ~/.ipython/pybind11 by default). If a compiled module binary with matching hash is found, it is not rebuilt and is instead imported directly.

It is also possible to force recompilation by assigning a new unique hash (this is useful, for instance, in cases when module's code depends on 3rd-party code that may change) – this can be done by passing -f flag:

%pybind11 -f

Error reporting and verbosity

All compiler output is captured and shown in the IPython environment (as opposed to the standard error of the shell where the kernel was launched). By default, compiler output is shown only if compilation fails; to always show all compiler output (like warnings), use -v flag:

%pybind11 -v

The following example should compile silently if built via %%pybind11 with no arguments:

%%pybind11 -vf;

PYBIND11_PLUGIN(example) {
    int x;                    // cell line 4
    py::module m("example");
    return m.ptr();
}

Building it with -v flag will display compiler warning:

--------------------------------------------------------------------------------
<source>:4:9: warning: unused variable 'x' [-Wunused-variable]
    int x;
        ^
1 warning generated.
--------------------------------------------------------------------------------

As can be seen in the above example, line numbers in reported error and warning messages should match line numbers in the input cell, including the cell magic line itself. (Line numbers can be shown in Jupyter notebooks by pressing L in command mode).

Setting C++ standard

If C++ standard is not specified, it defaults to C++14. If it's not supported by the compiler, it falls back to C++11. It is also possible to specify the standard manually by passing -std option; for example:

%%pybind11 -std=c++17

Compiler and linker flags

Additional compiler and linker flags can be passed via -c and -Wl options respectively. Flags containing spaces or starting with a dash should be passed using -c="..." syntax; double quotes can be escaped via \". Both of these options can be specified multiple times.

%%pybind11 -c="-Wextra -fno-inline" -c="-Os"

On Linux and macOS, extensions are compiled with -flto and -fvisibility=hidden provided those flags are supported by the compiler. On Windows, extensions are built with /MP /bigobj /EHsc. The rest of the flags are provided by distutils.

Include and library directories

Include and library directories can be specified via -I and -L options. Both of these options can be passed multiple times:

%%pybind11 -v -I /foo/bar -I="/foo bar/baz" -L/baz

Note: in conda environments, $PREFIX/include is always added to include paths and $PREFIX/lib is added to library paths (on Windows, it's $PREFIX/Library/include and $PREFIX/Library/lib).

Notebook integration

Syntax highlighting

Starting a cell with %%pybind11 changes its syntax highlighting to C++ and enables additional visual styles (so that C/C++ keywords are highlighted).

Code indentation

Since the whole cell starting with %%pybind11 is considered as C++ by syntax highlighter, this also includes the cell magic itself (the very first line). If it's not terminated with a semicolon, the indentation on the following lines is likely to be off. For this reason, a trailing semilocon is always ignored, such as in this example:

%%pybind11 -f -v;

Compatibility

OS Python Compiler requirements
Linux 3.4+ GCC 4.8 or newer
macOS 3.4+ Clang 3.3 or newer
Windows 3.5+ MSVC 2015 Update 3 or newer

Why no Python 2?

Python 2 support was dropped in IPython 6.x release entirely and the clock is ticking so it makes little sense for us to support it here either.

Python 3.5+ on Windows

Starting from Python 3.5, the official Windows distribution switched from MSVC 10.0 to MSVC 14.0 as a default build toolchain. The former is too ancient to work with pybind11, so we require Python 3.5 or newer.

ipybind's People

Contributors

aldanor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

ipybind's Issues

Support system commands for include/link flags

It'd be handy for the cell magic to support something like this:

%%pybind11 -I=`gsl-config --cflags` -I=`python -c "import numpy;print(numpy.get_include())"`

When using other Python packages that provide headers, it'd be great not to have to hard-code in the linker paths.

Would such a thing be possible?

cppyy backend?

Hi there,

I really like the idea of this extension, but I think it could be even more general than just pybind11. I had a brief look over the source and I think it should be possible to generalise ipybind to support cppyy [1] as an alternative backend. What do you think? cppyy is quite nice because it has an extensible automatic "Pythonization" API (disclosure: I contributed to this), that tries to make C++ classes as idiomatically Pythonic as possible by default, and allow users to extend the built-in capabilities by adding more automatic "Pythonizations". Moreover, cppyy doesn't require any extra code or special syntax, or an explicit compilation stage, and it works on both CPython and PyPy. It would be really cool to be able to take advantage of both cppyy and ipybind's neat notebook features.

[1] http://cppyy.readthedocs.io/en/latest/index.html

How to build?

Hi, how can I build this package to try the notebook example? Thanks

AttributeError: module 'distutils.spawn' has no attribute '_nt_quote_args'

I successfully installed ipybind with pip from git

pip install git+https://github.com/aldanor/ipybind.git
...
Successfully installed ipybind-0.1.0

and am trying to use this in a jupyter notebook where i have a

%load_ext ipybind

in one cell
and a

%%pybind11 -v

in another
but whatever i'm trying i always get a long traceback with a

C:\prog\Python39\lib\site-packages\ipybind\spawn.py in spawn(cmd, search_path, verbose, dry_run)
     43             return
     44         if log_commands:
---> 45             distutils.log.info(' '.join(distutils.spawn._nt_quote_args(list(cmd))))
     46         try:
     47             p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

AttributeError: module 'distutils.spawn' has no attribute '_nt_quote_args'

at the end from the cell with the %%pybind11.
Is this a known issue?

Here are the version infos:

D:\dev>python --version
Python 3.9.1

D:\dev>jupyter --version
jupyter core     : 4.7.1
jupyter-notebook : 6.2.0
qtconsole        : 5.0.2
ipython          : 7.20.0
ipykernel        : 5.4.3
jupyter client   : 6.1.11
jupyter lab      : 3.0.7
nbconvert        : 6.0.7
ipywidgets       : 7.6.3
nbformat         : 5.1.2
traitlets        : 5.0.5

ipybind

@wjakob @jagerman @dean0x7d

Hi – tagging you to take a look, what do you think? Cython has a dedicated cell magic, so we should have one (preferably a better one) too :) If you think it would be useful we can provided a link on pybind11's page.

Was quite a bit of pain to make it work properly on Windows, partially due to my inexperience with it and msvc stack in particular, but it looks like things generally work ok. There's a minor amount of things to finish, like adding a few nbval tests, mostly error reporting and stream capturing, documenting a few more things in readme, maybe minor code reshuffling – but most of it is done.

One thing that can be done to is adding a few lines to pybind11's __init__.py, so that one coud do %load_ext pybind11 which is arguably nicer:

def load_ipython_extension(ip):
    try:
        import ipybind
        ipybind.load_ipython_extension(ip)
    except ImportError:
        pass  # or maybe show a warning "ipybind has to be installed for this to work"

(Potential other TODOs I have written down: add a line magic to build external C++ file; allow exporting the module to a user-specified path while figuring the name automatically; expose the building API without wrapping it in IPython's magics, kind of like in cppimport - since there's a bunch of useful stuff here; replace PYBIND11_PLUGIN with PYBIND11_MODULE eventually in the readme)

(It is also possible to compile a big tutorial notebook with various examples from pybind11's documentation and host it in pybind11's repo so users can view it online rendered by github but also run it / play around with it)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.