pax_global_header00006660000000000000000000000064147476001270014522gustar00rootroot0000000000000052 comment=4ccbe6e005fc017652312305f280742da49d3dd5 wjakob-nanobind-6c4457b/000077500000000000000000000000001474760012700151255ustar00rootroot00000000000000wjakob-nanobind-6c4457b/.github/000077500000000000000000000000001474760012700164655ustar00rootroot00000000000000wjakob-nanobind-6c4457b/.github/ISSUE_TEMPLATE/000077500000000000000000000000001474760012700206505ustar00rootroot00000000000000wjakob-nanobind-6c4457b/.github/ISSUE_TEMPLATE/all-other.yml000066400000000000000000000016371474760012700232710ustar00rootroot00000000000000name: Other description: Ask a question or request a new feature title: "[OTHER]: " body: - type: markdown attributes: value: | ## Important information For all types of questions, feature requests, and other issues that aren't nanobind bugs, please start a post on the separate "Discussions" tab and *not* under "Issues". If have found a nanobind bug, then please open a ticket with a reproducer using the separate "Bug Report" template. - type: textarea id: description attributes: label: Please don't use. placeholder: >- For all types of questions, feature requests, and other issues that aren't nanobind bugs, please start a post on the separate "Discussions" tab and *not* under "Issues". If have found a nanobind bug, then please open a ticket with a reproducer using the separate "Bug Report" template. validations: required: true wjakob-nanobind-6c4457b/.github/ISSUE_TEMPLATE/bug-report.yml000066400000000000000000000026051474760012700234640ustar00rootroot00000000000000name: Bug report description: File an issue about a critical issue in nanobind title: "[BUG]: " body: - type: markdown attributes: value: | ## Important information The author's time for processing GitHub issues is unfortunately very limited. Because of this, _nanobind_ cannot accept feature requests. Furthermore, questions should not be submitted here, please use the separate "Discussions" tab. I will unfortunately need to close feature requests or questions maquerading as bug reports. - type: textarea id: description attributes: label: Problem description placeholder: >- Provide a short description, state the expected behavior and what actually happens. Include relevant information like what version of Python and nanobind you are using, what system you are on, and any useful commands / output. validations: required: true - type: textarea id: code attributes: label: Reproducible example code placeholder: >- The code should be minimal, have no external dependencies, and isolate the function(s) that cause breakage. Please submit matched and complete C++ and Python snippets that can be easily compiled and run to diagnose the issue. If possible, make a PR with a failing test to provide a starting point for me to work on. render: text wjakob-nanobind-6c4457b/.github/workflows/000077500000000000000000000000001474760012700205225ustar00rootroot00000000000000wjakob-nanobind-6c4457b/.github/workflows/ci.yml000066400000000000000000000101211474760012700216330ustar00rootroot00000000000000name: Tests on: workflow_dispatch: pull_request: push: branches: - master - stable - v* concurrency: group: test-${{ github.ref }} cancel-in-progress: false jobs: # This is the "main" test suite, which tests a large number of different # versions of default compilers and Python versions in GitHub Actions. standard: strategy: fail-fast: false matrix: os: ['ubuntu-latest', 'windows-2022', 'macos-13'] python: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13.0-rc.2', 'pypy3.9-v7.3.16', 'pypy3.10-v7.3.17'] name: "Python ${{ matrix.python }} / ${{ matrix.os }}" runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 with: submodules: true - name: Setup Python ${{ matrix.python }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} cache: 'pip' - name: Install the latest CMake uses: lukka/get-cmake@latest - name: Install Eigen if: matrix.os == 'ubuntu-latest' run: sudo apt-get -y install libeigen3-dev - name: Install PyTest run: | python -m pip install pytest pytest-github-actions-annotate-failures typing_extensions - name: Install NumPy if: ${{ !startsWith(matrix.python, 'pypy') && !contains(matrix.python, 'rc.2') }} run: | python -m pip install numpy scipy - name: Configure run: > cmake -S . -B build -DNB_TEST_STABLE_ABI=ON -DNB_TEST_SHARED_BUILD="$(python3 -c 'import sys; print(int(sys.version_info.minor>=11))')" - name: Build C++ run: cmake --build build -j 2 - name: Run tests run: > cd build; python -m pytest nvcc-ubuntu: runs-on: ubuntu-latest container: nvidia/cuda:12.5.1-devel-ubuntu24.04 name: "Python 3 / NVCC (CUDA 12.6.1) / ubuntu-latest" steps: - name: Install dependencies run: apt-get update && DEBIAN_FRONTEND="noninteractive" apt-get install -y cmake git python3-dev python3-pytest python3-pip libeigen3-dev python3-typing-extensions python3-numpy - uses: actions/checkout@v4 with: submodules: true - name: Configure run: > cmake -S . -B build -DNB_TEST_CUDA=ON - name: Build C++ run: cmake --build build -j 2 - name: Run tests run: > cd build; python3 -m pytest old-compilers: strategy: fail-fast: false matrix: include: - cc: gcc-8 cxx: g++-8 apt: gcc-8 g++-8 - cc: gcc-9 cxx: g++-9 apt: gcc-9 - cc: clang-8 cxx: clang++-8 apt: clang-8 - cc: clang-9 cxx: clang++-9 apt: clang-9 - cc: clang-10 cxx: clang++-10 apt: clang-10 runs-on: ubuntu-20.04 name: "${{matrix.cc}} on Ubuntu 20.04" env: CC: ${{matrix.cc}} CXX: ${{matrix.cxx}} steps: - name: Install dependencies run: | sudo apt-get update sudo apt-get install python3-numpy python3-pytest libeigen3-dev ${{matrix.apt}} python3 -m pip install typing_extensions - uses: actions/checkout@v4 with: submodules: true - name: Configure run: cmake -S . -B build - name: Build C++ run: cmake --build build -j 2 - name: Run tests run: > cd build; python -m pytest free-threaded: name: "Python 3.13-dev / ubuntu.latest [free-threaded]" runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: submodules: true - uses: deadsnakes/action@v3.1.0 with: python-version: 3.13-dev nogil: true - name: Install the latest CMake uses: lukka/get-cmake@latest - name: Install PyTest run: | python -m pip install pytest pytest-github-actions-annotate-failures - name: Configure run: > cmake -S . -B build -DNB_TEST_FREE_THREADED=ON - name: Build C++ run: cmake --build build -j 2 - name: Run tests run: > cd build; python -m pytest wjakob-nanobind-6c4457b/.github/workflows/nvcc-win.yml000066400000000000000000000016321474760012700227730ustar00rootroot00000000000000name: Tests on: workflow_dispatch: jobs: nvcc-windows: runs-on: windows-latest name: "Python 3.12.7 / NVCC (CUDA 12.5.0) / windows-latest" steps: - uses: actions/checkout@v4 with: submodules: true - uses: Jimver/cuda-toolkit@v0.2.17 id: cuda-toolkit with: cuda: '12.5.0' - name: Setup Python 3.12.5 uses: actions/setup-python@v5 with: python-version: 3.12.5 cache: 'pip' - name: Install PyTest run: | python -m pip install pytest pytest-github-actions-annotate-failures typing_extensions - name: Install NumPy run: | python -m pip install numpy scipy - name: Configure run: > cmake -S . -B build -DNB_TEST_CUDA=ON - name: Build C++ run: cmake --build build -j 2 --config Release - name: Run tests run: > cd build; python3 -m pytest wjakob-nanobind-6c4457b/.gitignore000066400000000000000000000011761474760012700171220ustar00rootroot00000000000000libnanobind-static.a libnanobind-static-abi3.a libnanobind-static-ft.a libnanobind.so libnanobind-abi3.so libnanobind-ft.so libnanobind.dylib libnanobind-abi3.dylib libnanobind-ft.dylib nanobind.dll nanobind-abi3.dll nanobind-ft.dll libinter_module.dylib libinter_module.so inter_module.dll /.ninja_deps /.ninja_log /.cache /build.ninja /build /src/nanobind/cmake /src/nanobind/include /src/nanobind/ext /src/nanobind/src /dist /bench compile_commands.json CMakeFiles CMakeCache.txt cmake_install.cmake nanobind-config-version.cmake \.DS_Store \.cmake __pycache__ nanobind.egg-info test_*_ext*.so test_*_ext*.pyd py\.typed .mypy_cache wjakob-nanobind-6c4457b/.gitmodules000066400000000000000000000001351474760012700173010ustar00rootroot00000000000000[submodule "ext/robin_map"] path = ext/robin_map url = https://github.com/Tessil/robin-map wjakob-nanobind-6c4457b/.readthedocs.yaml000066400000000000000000000003351474760012700203550ustar00rootroot00000000000000version: 2 build: os: ubuntu-22.04 apt_packages: - librsvg2-bin tools: python: "3.11" sphinx: configuration: docs/conf.py python: install: - requirements: docs/requirements.txt formats: - pdf wjakob-nanobind-6c4457b/CMakeLists.txt000066400000000000000000000140671474760012700176750ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.15...3.27) # --------------------------------------------------------------------------- # Read the project version from nanobind.h # --------------------------------------------------------------------------- file(STRINGS "include/nanobind/nanobind.h" _nanobind_h_version REGEX "^#define NB_VERSION_.*$") string(REGEX MATCH "#define NB_VERSION_MAJOR ([0-9]+)" _ "${_nanobind_h_version}") set(_major ${CMAKE_MATCH_1}) string(REGEX MATCH "#define NB_VERSION_MINOR ([0-9]+)" _ "${_nanobind_h_version}") set(_minor ${CMAKE_MATCH_1}) string(REGEX MATCH "#define NB_VERSION_PATCH ([0-9]+)" _ "${_nanobind_h_version}") set(_patch ${CMAKE_MATCH_1}) project(nanobind LANGUAGES NONE VERSION "${_major}.${_minor}.${_patch}") # --------------------------------------------------------------------------- # Only build tests by default if this is the top-level CMake project # --------------------------------------------------------------------------- if (CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) set(NB_MASTER_PROJECT ON) else() set(NB_MASTER_PROJECT OFF) endif() option(NB_CREATE_INSTALL_RULES "Create installation rules" ${NB_MASTER_PROJECT}) option(NB_USE_SUBMODULE_DEPS "Use the nanobind dependencies shipped as a git submodule of this repository" ON) option(NB_TEST "Compile nanobind tests?" ${NB_MASTER_PROJECT}) option(NB_TEST_STABLE_ABI "Test the stable ABI interface?" OFF) option(NB_TEST_SHARED_BUILD "Build a shared nanobind library for the test suite?" OFF) option(NB_TEST_CUDA "Force the use of the CUDA/NVCC compiler for testing purposes" OFF) option(NB_TEST_FREE_THREADED "Build free-threaded extensions for the test suite?" ON) if (NOT MSVC) option(NB_TEST_SANITIZERS_ASAN "Build tests with the address sanitizer?" OFF) option(NB_TEST_SANITIZERS_UBSAN "Build tests with the address undefined behavior sanitizer?" OFF) option(NB_TEST_SANITIZERS_TSAN "Build tests with the thread sanitizer?" OFF) endif() # --------------------------------------------------------------------------- # Do a release build if nothing was specified # --------------------------------------------------------------------------- if (NB_MASTER_PROJECT AND NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message(STATUS "nanobind: setting build type to 'Release' as none was specified.") set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE) set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") endif() # --------------------------------------------------------------------------- # Check whether all dependencies are present # --------------------------------------------------------------------------- if (NB_USE_SUBMODULE_DEPS AND NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/ext/robin_map/include") message(FATAL_ERROR "The nanobind dependencies are missing! " "You probably did not clone the project with --recursive. It is possible to recover " "by invoking\n$ git submodule update --init --recursive") endif() # --------------------------------------------------------------------------- # Installation rules # --------------------------------------------------------------------------- if(NB_CREATE_INSTALL_RULES AND NOT CMAKE_SKIP_INSTALL_RULES) # Silence warning in GNUInstallDirs due to no enabled languages set(CMAKE_INSTALL_LIBDIR "") include(GNUInstallDirs) set(NB_INSTALL_DATADIR "nanobind" CACHE PATH "Installation path for read-only architecture-independent nanobind data files") # Normally these would be configurable by the user, but we can't allow that # because the lookup paths are hard-coded in 'cmake/nanobind-config.cmake' set(NB_INSTALL_INC_DIR "${NB_INSTALL_DATADIR}/include") set(NB_INSTALL_SRC_DIR "${NB_INSTALL_DATADIR}/src") set(NB_INSTALL_EXT_DIR "${NB_INSTALL_DATADIR}/ext") set(NB_INSTALL_MODULE_DIR "${NB_INSTALL_DATADIR}") set(NB_INSTALL_CMAKE_DIR "${NB_INSTALL_DATADIR}/cmake") install( DIRECTORY include/ DESTINATION "${NB_INSTALL_INC_DIR}" ) install( DIRECTORY src/ DESTINATION "${NB_INSTALL_SRC_DIR}" PATTERN "*.py" EXCLUDE ) install( DIRECTORY src/ DESTINATION "${NB_INSTALL_MODULE_DIR}" FILES_MATCHING PATTERN "*\.py" ) if(NB_USE_SUBMODULE_DEPS) install( FILES ext/robin_map/include/tsl/robin_map.h ext/robin_map/include/tsl/robin_hash.h ext/robin_map/include/tsl/robin_growth_policy.h DESTINATION "${NB_INSTALL_EXT_DIR}/robin_map/include/tsl" ) endif() install( FILES cmake/nanobind-config.cmake cmake/darwin-ld-cpython.sym cmake/darwin-ld-pypy.sym DESTINATION "${NB_INSTALL_CMAKE_DIR}" ) include(CMakePackageConfigHelpers) write_basic_package_version_file( ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake COMPATIBILITY SameMajorVersion ) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake DESTINATION "${NB_INSTALL_CMAKE_DIR}" ) endif() # Return early to skip finding needless dependencies if the user only wishes to # install nanobind if (NB_MASTER_PROJECT AND NOT NB_TEST) return() else() enable_language(CXX) endif() # --------------------------------------------------------------------------- # Find the Python interpreter and development libraries # --------------------------------------------------------------------------- if (NOT TARGET Python::Module OR NOT TARGET Python::Interpreter) set(Python_FIND_FRAMEWORK LAST) # Prefer Brew/Conda to Apple framework python if (CMAKE_VERSION VERSION_LESS 3.18) set(NB_PYTHON_DEV_MODULE Development) else() set(NB_PYTHON_DEV_MODULE Development.Module) endif() find_package(Python 3.8 REQUIRED COMPONENTS Interpreter ${NB_PYTHON_DEV_MODULE} OPTIONAL_COMPONENTS Development.SABIModule) endif() # --------------------------------------------------------------------------- # Include nanobind cmake functionality # --------------------------------------------------------------------------- include(cmake/nanobind-config.cmake) if (NB_TEST) add_subdirectory(tests) endif() wjakob-nanobind-6c4457b/LICENSE000066400000000000000000000027611474760012700161400ustar00rootroot00000000000000Copyright (c) 2022 Wenzel Jakob , All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. wjakob-nanobind-6c4457b/README.md000066400000000000000000000056341474760012700164140ustar00rootroot00000000000000# nanobind: tiny and efficient C++/Python bindings [![Documentation](https://img.shields.io/readthedocs/nanobind/latest)](https://nanobind.readthedocs.io/en/latest/) [![Continuous Integration](https://img.shields.io/github/actions/workflow/status/wjakob/nanobind/ci.yml?label=tests)](https://github.com/wjakob/nanobind/actions/workflows/ci.yml) [![](https://img.shields.io/pypi/v/nanobind.svg?color=brightgreen)](https://pypi.org/pypi/nanobind/) ![](https://img.shields.io/pypi/l/nanobind.svg?color=brightgreen) [![](https://img.shields.io/badge/Example-Link-brightgreen)](https://github.com/wjakob/nanobind_example) [![](https://img.shields.io/badge/Changelog-Link-brightgreen)](https://nanobind.readthedocs.io/en/latest/changelog.html)

nanobind logo

_nanobind_ is a small binding library that exposes C++ types in Python and vice versa. It is reminiscent of [Boost.Python](https://www.boost.org/doc/libs/1_64_0/libs/python/doc/html) and [pybind11](https://github.com/pybind/pybind11) and uses near-identical syntax. In contrast to these existing tools, nanobind is more efficient: bindings compile in a shorter amount of time, produce smaller binaries, and have better runtime performance. More concretely, [benchmarks](https://nanobind.readthedocs.io/en/latest/benchmark.html) show up to **~4× faster** compile time, **~5× smaller** binaries, and **~10× lower** runtime overheads compared to pybind11. nanobind also outperforms Cython in important metrics (**3-12×** binary size reduction, **1.6-4×** compilation time reduction, similar runtime performance). ## Documentation Please see the following links for tutorial and reference documentation in [HTML](https://nanobind.readthedocs.io/en/latest/) and [PDF](https://nanobind.readthedocs.io/_/downloads/en/latest/pdf/) formats. ## License and attribution All material in this repository is licensed under a three-clause [BSD license](LICENSE). Please use the following BibTeX template to cite nanobind in scientific discourse: ```bibtex @misc{nanobind, author = {Wenzel Jakob}, year = {2022}, note = {https://github.com/wjakob/nanobind}, title = {nanobind: tiny and efficient C++/Python bindings} } ``` The nanobind logo was designed by [AndoTwin Studio](https://andotwinstudio.com) (high-resolution download: [light](https://rgl.s3.eu-central-1.amazonaws.com/media/uploads/wjakob/2023/03/27/nanobind_logo.jpg), [dark](https://rgl.s3.eu-central-1.amazonaws.com/media/uploads/wjakob/2023/03/28/nanobind_logo_dark_1.png)). wjakob-nanobind-6c4457b/cmake/000077500000000000000000000000001474760012700162055ustar00rootroot00000000000000wjakob-nanobind-6c4457b/cmake/collect-symbols-pypy.py000066400000000000000000000015051474760012700226720ustar00rootroot00000000000000from urllib.request import urlopen import tarfile import subprocess funcs: "set[str]" = set() files = [ ('https://downloads.python.org/pypy/pypy3.9-v7.3.11-macos_arm64.tar.bz2', 'pypy3.9-v7.3.11-macos_arm64/bin/libpypy3.9-c.dylib') ] for f in files: fs = urlopen(f[0]) ft = tarfile.open(fileobj=fs, mode="r|bz2") success = False for member in ft: # move to the next file each loop if member.name == f[1]: ft.extract(member, path='tmp') success = True assert success out = subprocess.check_output(['nm', '-gjU', 'tmp/' + f[1]]) for line in out.decode().split('\n'): if line.startswith('_Py') or line.startswith('__Py'): funcs.add(line) with open("darwin-ld-pypy.sym", "w") as f: for func in sorted(list(funcs)): f.write(f'-U _{func}\n') wjakob-nanobind-6c4457b/cmake/collect-symbols.py000066400000000000000000000025521474760012700216760ustar00rootroot00000000000000#!/usr/bin/env python3 # # This script collects a list of symbols that are considered to be part of the # CPython API. The result is used to inform the macOS linker that it's fine for # those symbols to be undefined when an extension module is linked, as they # will be provided when the extension module is loaded into the interpreter. from urllib.request import urlopen import re funcs: "set[str]" = set() for ver in ['3.7', '3.8', '3.9']: url = f'https://raw.githubusercontent.com/python/cpython/{ver}/PC/python3.def' output = urlopen(url).read().decode('utf-8') for match in re.findall(r" (.*)=.*", output): funcs.add(match) for ver in ['3.10', '3.11', 'main']: url = f'https://raw.githubusercontent.com/python/cpython/{ver}/PC/python3dll.c' output = urlopen(url).read().decode('utf-8') for match in re.findall(r"EXPORT_FUNC\((.*)\)", output): funcs.add(match) funcs.remove('name') # Add a few more functions that nanobind uses and which aren't in the above list funcs |= { 'PyFrame_GetBack', 'PyGILState_Check', 'PyObject_LengthHint', 'Py_CompileStringExFlags', '_PyInterpreterState_Get', '_PyObject_MakeTpCall', '_PyObject_NextNotImplemented', '_Py_CheckFunctionResult', '_Py_RefTotal' } with open("darwin-ld-cpython.sym", "w") as f: for func in sorted(list(funcs)): f.write(f'-U _{func}\n') wjakob-nanobind-6c4457b/cmake/darwin-ld-cpython.sym000066400000000000000000000533341474760012700223120ustar00rootroot00000000000000-U _PyAIter_Check -U _PyArg_Parse -U _PyArg_ParseTuple -U _PyArg_ParseTupleAndKeywords -U _PyArg_UnpackTuple -U _PyArg_VaParse -U _PyArg_VaParseTupleAndKeywords -U _PyArg_ValidateKeywordArguments -U _PyBaseObject_Type -U _PyBool_FromLong -U _PyBool_Type -U _PyBuffer_FillContiguousStrides -U _PyBuffer_FillInfo -U _PyBuffer_FromContiguous -U _PyBuffer_GetPointer -U _PyBuffer_IsContiguous -U _PyBuffer_Release -U _PyBuffer_SizeFromFormat -U _PyBuffer_ToContiguous -U _PyByteArrayIter_Type -U _PyByteArray_AsString -U _PyByteArray_Concat -U _PyByteArray_FromObject -U _PyByteArray_FromStringAndSize -U _PyByteArray_Resize -U _PyByteArray_Size -U _PyByteArray_Type -U _PyBytesIter_Type -U _PyBytes_AsString -U _PyBytes_AsStringAndSize -U _PyBytes_Concat -U _PyBytes_ConcatAndDel -U _PyBytes_DecodeEscape -U _PyBytes_FromFormat -U _PyBytes_FromFormatV -U _PyBytes_FromObject -U _PyBytes_FromString -U _PyBytes_FromStringAndSize -U _PyBytes_Repr -U _PyBytes_Size -U _PyBytes_Type -U _PyCFunction_Call -U _PyCFunction_ClearFreeList -U _PyCFunction_GetFlags -U _PyCFunction_GetFunction -U _PyCFunction_GetSelf -U _PyCFunction_New -U _PyCFunction_NewEx -U _PyCFunction_Type -U _PyCMethod_New -U _PyCallIter_New -U _PyCallIter_Type -U _PyCallable_Check -U _PyCapsule_GetContext -U _PyCapsule_GetDestructor -U _PyCapsule_GetName -U _PyCapsule_GetPointer -U _PyCapsule_Import -U _PyCapsule_IsValid -U _PyCapsule_New -U _PyCapsule_SetContext -U _PyCapsule_SetDestructor -U _PyCapsule_SetName -U _PyCapsule_SetPointer -U _PyCapsule_Type -U _PyClassMethodDescr_Type -U _PyCodec_BackslashReplaceErrors -U _PyCodec_Decode -U _PyCodec_Decoder -U _PyCodec_Encode -U _PyCodec_Encoder -U _PyCodec_IgnoreErrors -U _PyCodec_IncrementalDecoder -U _PyCodec_IncrementalEncoder -U _PyCodec_KnownEncoding -U _PyCodec_LookupError -U _PyCodec_NameReplaceErrors -U _PyCodec_Register -U _PyCodec_RegisterError -U _PyCodec_ReplaceErrors -U _PyCodec_StreamReader -U _PyCodec_StreamWriter -U _PyCodec_StrictErrors -U _PyCodec_Unregister -U _PyCodec_XMLCharRefReplaceErrors -U _PyComplex_AsCComplex -U _PyComplex_FromCComplex -U _PyComplex_FromDoubles -U _PyComplex_ImagAsDouble -U _PyComplex_RealAsDouble -U _PyComplex_Type -U _PyDescr_NewClassMethod -U _PyDescr_NewGetSet -U _PyDescr_NewMember -U _PyDescr_NewMethod -U _PyDictItems_Type -U _PyDictIterItem_Type -U _PyDictIterKey_Type -U _PyDictIterValue_Type -U _PyDictKeys_Type -U _PyDictProxy_New -U _PyDictProxy_Type -U _PyDictValues_Type -U _PyDict_Clear -U _PyDict_Contains -U _PyDict_Copy -U _PyDict_DelItem -U _PyDict_DelItemString -U _PyDict_GetItem -U _PyDict_GetItemString -U _PyDict_GetItemWithError -U _PyDict_Items -U _PyDict_Keys -U _PyDict_Merge -U _PyDict_MergeFromSeq2 -U _PyDict_New -U _PyDict_Next -U _PyDict_SetItem -U _PyDict_SetItemString -U _PyDict_Size -U _PyDict_Type -U _PyDict_Update -U _PyDict_Values -U _PyEllipsis_Type -U _PyEnum_Type -U _PyErr_BadArgument -U _PyErr_BadInternalCall -U _PyErr_CheckSignals -U _PyErr_Clear -U _PyErr_Display -U _PyErr_ExceptionMatches -U _PyErr_Fetch -U _PyErr_Format -U _PyErr_FormatV -U _PyErr_GetExcInfo -U _PyErr_GetHandledException -U _PyErr_GetRaisedException -U _PyErr_GivenExceptionMatches -U _PyErr_NewException -U _PyErr_NewExceptionWithDoc -U _PyErr_NoMemory -U _PyErr_NormalizeException -U _PyErr_Occurred -U _PyErr_Print -U _PyErr_PrintEx -U _PyErr_ProgramText -U _PyErr_ResourceWarning -U _PyErr_Restore -U _PyErr_SetExcFromWindowsErr -U _PyErr_SetExcFromWindowsErrWithFilename -U _PyErr_SetExcFromWindowsErrWithFilenameObject -U _PyErr_SetExcFromWindowsErrWithFilenameObjects -U _PyErr_SetExcInfo -U _PyErr_SetFromErrno -U _PyErr_SetFromErrnoWithFilename -U _PyErr_SetFromErrnoWithFilenameObject -U _PyErr_SetFromErrnoWithFilenameObjects -U _PyErr_SetFromWindowsErr -U _PyErr_SetFromWindowsErrWithFilename -U _PyErr_SetHandledException -U _PyErr_SetImportError -U _PyErr_SetImportErrorSubclass -U _PyErr_SetInterrupt -U _PyErr_SetInterruptEx -U _PyErr_SetNone -U _PyErr_SetObject -U _PyErr_SetRaisedException -U _PyErr_SetString -U _PyErr_SyntaxLocation -U _PyErr_SyntaxLocationEx -U _PyErr_WarnEx -U _PyErr_WarnExplicit -U _PyErr_WarnFormat -U _PyErr_WriteUnraisable -U _PyEval_AcquireLock -U _PyEval_AcquireThread -U _PyEval_CallFunction -U _PyEval_CallMethod -U _PyEval_CallObjectWithKeywords -U _PyEval_EvalCode -U _PyEval_EvalCodeEx -U _PyEval_EvalFrame -U _PyEval_EvalFrameEx -U _PyEval_GetBuiltins -U _PyEval_GetCallStats -U _PyEval_GetFrame -U _PyEval_GetFuncDesc -U _PyEval_GetFuncName -U _PyEval_GetGlobals -U _PyEval_GetLocals -U _PyEval_InitThreads -U _PyEval_ReInitThreads -U _PyEval_ReleaseLock -U _PyEval_ReleaseThread -U _PyEval_RestoreThread -U _PyEval_SaveThread -U _PyEval_ThreadsInitialized -U _PyExc_ArithmeticError -U _PyExc_AssertionError -U _PyExc_AttributeError -U _PyExc_BaseException -U _PyExc_BlockingIOError -U _PyExc_BrokenPipeError -U _PyExc_BufferError -U _PyExc_BytesWarning -U _PyExc_ChildProcessError -U _PyExc_ConnectionAbortedError -U _PyExc_ConnectionError -U _PyExc_ConnectionRefusedError -U _PyExc_ConnectionResetError -U _PyExc_DeprecationWarning -U _PyExc_EOFError -U _PyExc_EnvironmentError -U _PyExc_Exception -U _PyExc_FileExistsError -U _PyExc_FileNotFoundError -U _PyExc_FloatingPointError -U _PyExc_FutureWarning -U _PyExc_GeneratorExit -U _PyExc_IOError -U _PyExc_ImportError -U _PyExc_ImportWarning -U _PyExc_IndentationError -U _PyExc_IndexError -U _PyExc_InterruptedError -U _PyExc_IsADirectoryError -U _PyExc_KeyError -U _PyExc_KeyboardInterrupt -U _PyExc_LookupError -U _PyExc_MemoryError -U _PyExc_ModuleNotFoundError -U _PyExc_NameError -U _PyExc_NotADirectoryError -U _PyExc_NotImplementedError -U _PyExc_OSError -U _PyExc_OverflowError -U _PyExc_PendingDeprecationWarning -U _PyExc_PermissionError -U _PyExc_ProcessLookupError -U _PyExc_RecursionError -U _PyExc_ReferenceError -U _PyExc_ResourceWarning -U _PyExc_RuntimeError -U _PyExc_RuntimeWarning -U _PyExc_StopAsyncIteration -U _PyExc_StopIteration -U _PyExc_SyntaxError -U _PyExc_SyntaxWarning -U _PyExc_SystemError -U _PyExc_SystemExit -U _PyExc_TabError -U _PyExc_TimeoutError -U _PyExc_TypeError -U _PyExc_UnboundLocalError -U _PyExc_UnicodeDecodeError -U _PyExc_UnicodeEncodeError -U _PyExc_UnicodeError -U _PyExc_UnicodeTranslateError -U _PyExc_UnicodeWarning -U _PyExc_UserWarning -U _PyExc_ValueError -U _PyExc_Warning -U _PyExc_WindowsError -U _PyExc_ZeroDivisionError -U _PyExceptionClass_Name -U _PyException_GetCause -U _PyException_GetContext -U _PyException_GetTraceback -U _PyException_SetCause -U _PyException_SetContext -U _PyException_SetTraceback -U _PyFile_FromFd -U _PyFile_GetLine -U _PyFile_WriteObject -U _PyFile_WriteString -U _PyFilter_Type -U _PyFloat_AsDouble -U _PyFloat_FromDouble -U _PyFloat_FromString -U _PyFloat_GetInfo -U _PyFloat_GetMax -U _PyFloat_GetMin -U _PyFloat_Type -U _PyFrame_GetBack -U _PyFrame_GetCode -U _PyFrame_GetLineNumber -U _PyFrozenSet_New -U _PyFrozenSet_Type -U _PyGC_Collect -U _PyGC_Disable -U _PyGC_Enable -U _PyGC_IsEnabled -U _PyGILState_Check -U _PyGILState_Ensure -U _PyGILState_GetThisThreadState -U _PyGILState_Release -U _PyGetSetDescr_Type -U _PyImport_AddModule -U _PyImport_AddModuleObject -U _PyImport_AppendInittab -U _PyImport_Cleanup -U _PyImport_ExecCodeModule -U _PyImport_ExecCodeModuleEx -U _PyImport_ExecCodeModuleObject -U _PyImport_ExecCodeModuleWithPathnames -U _PyImport_GetImporter -U _PyImport_GetMagicNumber -U _PyImport_GetMagicTag -U _PyImport_GetModule -U _PyImport_GetModuleDict -U _PyImport_Import -U _PyImport_ImportFrozenModule -U _PyImport_ImportFrozenModuleObject -U _PyImport_ImportModule -U _PyImport_ImportModuleLevel -U _PyImport_ImportModuleLevelObject -U _PyImport_ImportModuleNoBlock -U _PyImport_ReloadModule -U _PyIndex_Check -U _PyInterpreterState_Clear -U _PyInterpreterState_Delete -U _PyInterpreterState_Get -U _PyInterpreterState_GetDict -U _PyInterpreterState_GetID -U _PyInterpreterState_New -U _PyIter_Check -U _PyIter_Next -U _PyIter_Send -U _PyListIter_Type -U _PyListRevIter_Type -U _PyList_Append -U _PyList_AsTuple -U _PyList_GetItem -U _PyList_GetSlice -U _PyList_Insert -U _PyList_New -U _PyList_Reverse -U _PyList_SetItem -U _PyList_SetSlice -U _PyList_Size -U _PyList_Sort -U _PyList_Type -U _PyLongRangeIter_Type -U _PyLong_AsDouble -U _PyLong_AsLong -U _PyLong_AsLongAndOverflow -U _PyLong_AsLongLong -U _PyLong_AsLongLongAndOverflow -U _PyLong_AsSize_t -U _PyLong_AsSsize_t -U _PyLong_AsUnsignedLong -U _PyLong_AsUnsignedLongLong -U _PyLong_AsUnsignedLongLongMask -U _PyLong_AsUnsignedLongMask -U _PyLong_AsVoidPtr -U _PyLong_FromDouble -U _PyLong_FromLong -U _PyLong_FromLongLong -U _PyLong_FromSize_t -U _PyLong_FromSsize_t -U _PyLong_FromString -U _PyLong_FromUnsignedLong -U _PyLong_FromUnsignedLongLong -U _PyLong_FromVoidPtr -U _PyLong_GetInfo -U _PyLong_Type -U _PyMap_Type -U _PyMapping_Check -U _PyMapping_GetItemString -U _PyMapping_HasKey -U _PyMapping_HasKeyString -U _PyMapping_Items -U _PyMapping_Keys -U _PyMapping_Length -U _PyMapping_SetItemString -U _PyMapping_Size -U _PyMapping_Values -U _PyMarshal_ReadObjectFromString -U _PyMarshal_WriteObjectToString -U _PyMem_Calloc -U _PyMem_Free -U _PyMem_Malloc -U _PyMem_Realloc -U _PyMemberDescr_Type -U _PyMember_GetOne -U _PyMember_SetOne -U _PyMemoryView_FromBuffer -U _PyMemoryView_FromMemory -U _PyMemoryView_FromObject -U _PyMemoryView_GetContiguous -U _PyMemoryView_Type -U _PyMethodDescr_Type -U _PyModuleDef_Init -U _PyModuleDef_Type -U _PyModule_AddFunctions -U _PyModule_AddIntConstant -U _PyModule_AddObject -U _PyModule_AddObjectRef -U _PyModule_AddStringConstant -U _PyModule_AddType -U _PyModule_Create2 -U _PyModule_ExecDef -U _PyModule_FromDefAndSpec2 -U _PyModule_GetDef -U _PyModule_GetDict -U _PyModule_GetFilename -U _PyModule_GetFilenameObject -U _PyModule_GetName -U _PyModule_GetNameObject -U _PyModule_GetState -U _PyModule_New -U _PyModule_NewObject -U _PyModule_SetDocString -U _PyModule_Type -U _PyNullImporter_Type -U _PyNumber_Absolute -U _PyNumber_Add -U _PyNumber_And -U _PyNumber_AsSsize_t -U _PyNumber_Check -U _PyNumber_Divmod -U _PyNumber_Float -U _PyNumber_FloorDivide -U _PyNumber_InPlaceAdd -U _PyNumber_InPlaceAnd -U _PyNumber_InPlaceFloorDivide -U _PyNumber_InPlaceLshift -U _PyNumber_InPlaceMatrixMultiply -U _PyNumber_InPlaceMultiply -U _PyNumber_InPlaceOr -U _PyNumber_InPlacePower -U _PyNumber_InPlaceRemainder -U _PyNumber_InPlaceRshift -U _PyNumber_InPlaceSubtract -U _PyNumber_InPlaceTrueDivide -U _PyNumber_InPlaceXor -U _PyNumber_Index -U _PyNumber_Invert -U _PyNumber_Long -U _PyNumber_Lshift -U _PyNumber_MatrixMultiply -U _PyNumber_Multiply -U _PyNumber_Negative -U _PyNumber_Or -U _PyNumber_Positive -U _PyNumber_Power -U _PyNumber_Remainder -U _PyNumber_Rshift -U _PyNumber_Subtract -U _PyNumber_ToBase -U _PyNumber_TrueDivide -U _PyNumber_Xor -U _PyODictItems_Type -U _PyODictIter_Type -U _PyODictKeys_Type -U _PyODictValues_Type -U _PyODict_DelItem -U _PyODict_New -U _PyODict_SetItem -U _PyODict_Type -U _PyOS_AfterFork -U _PyOS_CheckStack -U _PyOS_FSPath -U _PyOS_InitInterrupts -U _PyOS_InputHook -U _PyOS_InterruptOccurred -U _PyOS_ReadlineFunctionPointer -U _PyOS_double_to_string -U _PyOS_getsig -U _PyOS_mystricmp -U _PyOS_mystrnicmp -U _PyOS_setsig -U _PyOS_snprintf -U _PyOS_string_to_double -U _PyOS_strtol -U _PyOS_strtoul -U _PyOS_vsnprintf -U _PyObject_ASCII -U _PyObject_AsCharBuffer -U _PyObject_AsFileDescriptor -U _PyObject_AsReadBuffer -U _PyObject_AsWriteBuffer -U _PyObject_Bytes -U _PyObject_Call -U _PyObject_CallFunction -U _PyObject_CallFunctionObjArgs -U _PyObject_CallMethod -U _PyObject_CallMethodObjArgs -U _PyObject_CallNoArgs -U _PyObject_CallObject -U _PyObject_Calloc -U _PyObject_CheckBuffer -U _PyObject_CheckReadBuffer -U _PyObject_ClearWeakRefs -U _PyObject_CopyData -U _PyObject_DelAttr -U _PyObject_DelAttrString -U _PyObject_DelItem -U _PyObject_DelItemString -U _PyObject_Dir -U _PyObject_Format -U _PyObject_Free -U _PyObject_GetTypeData -U _PyObject_GC_Del -U _PyObject_GC_IsFinalized -U _PyObject_GC_IsTracked -U _PyObject_GC_Track -U _PyObject_GC_UnTrack -U _PyObject_GenericGetAttr -U _PyObject_GenericGetDict -U _PyObject_GenericSetAttr -U _PyObject_GenericSetDict -U _PyObject_GetAIter -U _PyObject_GetAttr -U _PyObject_GetAttrString -U _PyObject_GetBuffer -U _PyObject_GetItem -U _PyObject_GetIter -U _PyObject_HasAttr -U _PyObject_HasAttrString -U _PyObject_Hash -U _PyObject_HashNotImplemented -U _PyObject_Init -U _PyObject_InitVar -U _PyObject_IsInstance -U _PyObject_IsSubclass -U _PyObject_IsTrue -U _PyObject_Length -U _PyObject_LengthHint -U _PyObject_Malloc -U _PyObject_Not -U _PyObject_Realloc -U _PyObject_Repr -U _PyObject_RichCompare -U _PyObject_RichCompareBool -U _PyObject_SelfIter -U _PyObject_SetAttr -U _PyObject_SetAttrString -U _PyObject_SetItem -U _PyObject_Size -U _PyObject_Str -U _PyObject_Type -U _PyObject_Vectorcall -U _PyObject_VectorcallMethod -U _PyParser_SimpleParseFileFlags -U _PyParser_SimpleParseStringFlags -U _PyParser_SimpleParseStringFlagsFilename -U _PyProperty_Type -U _PyRangeIter_Type -U _PyRange_Type -U _PyReversed_Type -U _PySeqIter_New -U _PySeqIter_Type -U _PySequence_Check -U _PySequence_Concat -U _PySequence_Contains -U _PySequence_Count -U _PySequence_DelItem -U _PySequence_DelSlice -U _PySequence_Fast -U _PySequence_GetItem -U _PySequence_GetSlice -U _PySequence_In -U _PySequence_InPlaceConcat -U _PySequence_InPlaceRepeat -U _PySequence_Index -U _PySequence_Length -U _PySequence_List -U _PySequence_Repeat -U _PySequence_SetItem -U _PySequence_SetSlice -U _PySequence_Size -U _PySequence_Tuple -U _PySetIter_Type -U _PySet_Add -U _PySet_Clear -U _PySet_Contains -U _PySet_Discard -U _PySet_New -U _PySet_Pop -U _PySet_Size -U _PySet_Type -U _PySlice_AdjustIndices -U _PySlice_GetIndices -U _PySlice_GetIndicesEx -U _PySlice_New -U _PySlice_Type -U _PySlice_Unpack -U _PySortWrapper_Type -U _PyState_AddModule -U _PyState_FindModule -U _PyState_RemoveModule -U _PyStructSequence_GetItem -U _PyStructSequence_New -U _PyStructSequence_NewType -U _PyStructSequence_SetItem -U _PySuper_Type -U _PySys_AddWarnOption -U _PySys_AddWarnOptionUnicode -U _PySys_AddXOption -U _PySys_FormatStderr -U _PySys_FormatStdout -U _PySys_GetObject -U _PySys_GetXOptions -U _PySys_HasWarnOptions -U _PySys_ResetWarnOptions -U _PySys_SetArgv -U _PySys_SetArgvEx -U _PySys_SetObject -U _PySys_SetPath -U _PySys_WriteStderr -U _PySys_WriteStdout -U _PyThreadState_Clear -U _PyThreadState_Delete -U _PyThreadState_DeleteCurrent -U _PyThreadState_Get -U _PyThreadState_GetDict -U _PyThreadState_GetFrame -U _PyThreadState_GetID -U _PyThreadState_GetInterpreter -U _PyThreadState_New -U _PyThreadState_SetAsyncExc -U _PyThreadState_Swap -U _PyThread_GetInfo -U _PyThread_ReInitTLS -U _PyThread_acquire_lock -U _PyThread_acquire_lock_timed -U _PyThread_allocate_lock -U _PyThread_create_key -U _PyThread_delete_key -U _PyThread_delete_key_value -U _PyThread_exit_thread -U _PyThread_free_lock -U _PyThread_get_key_value -U _PyThread_get_stacksize -U _PyThread_get_thread_ident -U _PyThread_get_thread_native_id -U _PyThread_init_thread -U _PyThread_release_lock -U _PyThread_set_key_value -U _PyThread_set_stacksize -U _PyThread_start_new_thread -U _PyThread_tss_alloc -U _PyThread_tss_create -U _PyThread_tss_delete -U _PyThread_tss_free -U _PyThread_tss_get -U _PyThread_tss_is_created -U _PyThread_tss_set -U _PyTraceBack_Here -U _PyTraceBack_Print -U _PyTraceBack_Type -U _PyTupleIter_Type -U _PyTuple_ClearFreeList -U _PyTuple_GetItem -U _PyTuple_GetSlice -U _PyTuple_New -U _PyTuple_Pack -U _PyTuple_SetItem -U _PyTuple_Size -U _PyTuple_Type -U _PyType_ClearCache -U _PyType_FromMetaclass -U _PyType_FromModuleAndSpec -U _PyType_FromSpec -U _PyType_FromSpecWithBases -U _PyType_GenericAlloc -U _PyType_GenericNew -U _PyType_GetFlags -U _PyType_GetModule -U _PyType_GetModuleState -U _PyType_GetName -U _PyType_GetQualName -U _PyType_GetSlot -U _PyType_IsSubtype -U _PyType_Modified -U _PyType_Ready -U _PyType_Type -U _PyType_GetTypeDataSize -U _PyUnicodeDecodeError_Create -U _PyUnicodeDecodeError_GetEncoding -U _PyUnicodeDecodeError_GetEnd -U _PyUnicodeDecodeError_GetObject -U _PyUnicodeDecodeError_GetReason -U _PyUnicodeDecodeError_GetStart -U _PyUnicodeDecodeError_SetEnd -U _PyUnicodeDecodeError_SetReason -U _PyUnicodeDecodeError_SetStart -U _PyUnicodeEncodeError_GetEncoding -U _PyUnicodeEncodeError_GetEnd -U _PyUnicodeEncodeError_GetObject -U _PyUnicodeEncodeError_GetReason -U _PyUnicodeEncodeError_GetStart -U _PyUnicodeEncodeError_SetEnd -U _PyUnicodeEncodeError_SetReason -U _PyUnicodeEncodeError_SetStart -U _PyUnicodeIter_Type -U _PyUnicodeTranslateError_GetEnd -U _PyUnicodeTranslateError_GetObject -U _PyUnicodeTranslateError_GetReason -U _PyUnicodeTranslateError_GetStart -U _PyUnicodeTranslateError_SetEnd -U _PyUnicodeTranslateError_SetReason -U _PyUnicodeTranslateError_SetStart -U _PyUnicode_Append -U _PyUnicode_AppendAndDel -U _PyUnicode_AsASCIIString -U _PyUnicode_AsCharmapString -U _PyUnicode_AsDecodedObject -U _PyUnicode_AsDecodedUnicode -U _PyUnicode_AsEncodedObject -U _PyUnicode_AsEncodedString -U _PyUnicode_AsEncodedUnicode -U _PyUnicode_AsLatin1String -U _PyUnicode_AsMBCSString -U _PyUnicode_AsRawUnicodeEscapeString -U _PyUnicode_AsUCS4 -U _PyUnicode_AsUCS4Copy -U _PyUnicode_AsUTF16String -U _PyUnicode_AsUTF32String -U _PyUnicode_AsUTF8AndSize -U _PyUnicode_AsUTF8String -U _PyUnicode_AsUnicodeEscapeString -U _PyUnicode_AsWideChar -U _PyUnicode_AsWideCharString -U _PyUnicode_BuildEncodingMap -U _PyUnicode_ClearFreeList -U _PyUnicode_Compare -U _PyUnicode_CompareWithASCIIString -U _PyUnicode_Concat -U _PyUnicode_Contains -U _PyUnicode_Count -U _PyUnicode_Decode -U _PyUnicode_DecodeASCII -U _PyUnicode_DecodeCharmap -U _PyUnicode_DecodeCodePageStateful -U _PyUnicode_DecodeFSDefault -U _PyUnicode_DecodeFSDefaultAndSize -U _PyUnicode_DecodeLatin1 -U _PyUnicode_DecodeLocale -U _PyUnicode_DecodeLocaleAndSize -U _PyUnicode_DecodeMBCS -U _PyUnicode_DecodeMBCSStateful -U _PyUnicode_DecodeRawUnicodeEscape -U _PyUnicode_DecodeUTF16 -U _PyUnicode_DecodeUTF16Stateful -U _PyUnicode_DecodeUTF32 -U _PyUnicode_DecodeUTF32Stateful -U _PyUnicode_DecodeUTF7 -U _PyUnicode_DecodeUTF7Stateful -U _PyUnicode_DecodeUTF8 -U _PyUnicode_DecodeUTF8Stateful -U _PyUnicode_DecodeUnicodeEscape -U _PyUnicode_EncodeCodePage -U _PyUnicode_EncodeFSDefault -U _PyUnicode_EncodeLocale -U _PyUnicode_FSConverter -U _PyUnicode_FSDecoder -U _PyUnicode_Find -U _PyUnicode_FindChar -U _PyUnicode_Format -U _PyUnicode_FromEncodedObject -U _PyUnicode_FromFormat -U _PyUnicode_FromFormatV -U _PyUnicode_FromObject -U _PyUnicode_FromOrdinal -U _PyUnicode_FromString -U _PyUnicode_FromStringAndSize -U _PyUnicode_FromWideChar -U _PyUnicode_GetDefaultEncoding -U _PyUnicode_GetLength -U _PyUnicode_GetSize -U _PyUnicode_InternFromString -U _PyUnicode_InternImmortal -U _PyUnicode_InternInPlace -U _PyUnicode_IsIdentifier -U _PyUnicode_Join -U _PyUnicode_Partition -U _PyUnicode_RPartition -U _PyUnicode_RSplit -U _PyUnicode_ReadChar -U _PyUnicode_Replace -U _PyUnicode_Resize -U _PyUnicode_RichCompare -U _PyUnicode_Split -U _PyUnicode_Splitlines -U _PyUnicode_Substring -U _PyUnicode_Tailmatch -U _PyUnicode_Translate -U _PyUnicode_Type -U _PyUnicode_WriteChar -U _PyVectorcall_Call -U _PyVectorcall_NARGS -U _PyWeakref_GetObject -U _PyWeakref_NewProxy -U _PyWeakref_NewRef -U _PyWrapperDescr_Type -U _PyWrapper_New -U _PyZip_Type -U _Py_AddPendingCall -U _Py_AtExit -U _Py_BuildValue -U _Py_BytesMain -U _Py_CompileString -U _Py_CompileStringExFlags -U _Py_DecRef -U _Py_DecodeLocale -U _Py_EncodeLocale -U _Py_EndInterpreter -U _Py_EnterRecursiveCall -U _Py_Exit -U _Py_FatalError -U _Py_FileSystemDefaultEncodeErrors -U _Py_FileSystemDefaultEncoding -U _Py_Finalize -U _Py_FinalizeEx -U _Py_GenericAlias -U _Py_GenericAliasType -U _Py_GetArgcArgv -U _Py_GetBuildInfo -U _Py_GetCompiler -U _Py_GetCopyright -U _Py_GetExecPrefix -U _Py_GetPath -U _Py_GetPlatform -U _Py_GetPrefix -U _Py_GetProgramFullPath -U _Py_GetProgramName -U _Py_GetPythonHome -U _Py_GetRecursionLimit -U _Py_GetVersion -U _Py_HasFileSystemDefaultEncoding -U _Py_IncRef -U _Py_Initialize -U _Py_InitializeEx -U _Py_Is -U _Py_IsFalse -U _Py_IsFinalizing -U _Py_IsInitialized -U _Py_IsNone -U _Py_IsTrue -U _Py_LeaveRecursiveCall -U _Py_Main -U _Py_MakePendingCalls -U _Py_NewInterpreter -U _Py_NewRef -U _Py_ReprEnter -U _Py_ReprLeave -U _Py_SetPath -U _Py_SetProgramName -U _Py_SetPythonHome -U _Py_SetRecursionLimit -U _Py_SymtableString -U _Py_UTF8Mode -U _Py_VaBuildValue -U _Py_XNewRef -U __PyArg_ParseTupleAndKeywords_SizeT -U __PyArg_ParseTuple_SizeT -U __PyArg_Parse_SizeT -U __PyArg_VaParseTupleAndKeywords_SizeT -U __PyArg_VaParse_SizeT -U __PyErr_BadInternalCall -U __PyInterpreterState_Get -U __PyObject_CallFunction_SizeT -U __PyObject_CallMethod_SizeT -U __PyObject_GC_Malloc -U __PyObject_GC_New -U __PyObject_GC_NewVar -U __PyObject_GC_Resize -U __PyObject_MakeTpCall -U __PyObject_New -U __PyObject_NewVar -U __PyObject_NextNotImplemented -U __PyState_AddModule -U __PyThreadState_Init -U __PyThreadState_Prealloc -U __PyTrash_delete_later -U __PyTrash_delete_nesting -U __PyTrash_deposit_object -U __PyTrash_destroy_chain -U __PyTrash_thread_deposit_object -U __PyTrash_thread_destroy_chain -U __PyWeakref_CallableProxyType -U __PyWeakref_ProxyType -U __PyWeakref_RefType -U __Py_IsFinalizing -U __Py_BuildValue_SizeT -U __Py_CheckFunctionResult -U __Py_CheckRecursionLimit -U __Py_CheckRecursiveCall -U __Py_Dealloc -U __Py_DecRef -U __Py_EllipsisObject -U __Py_FalseStruct -U __Py_IncRef -U __Py_NegativeRefcount -U __Py_NoneStruct -U __Py_NotImplementedStruct -U __Py_RefTotal -U __Py_SwappedOp -U __Py_TrueStruct -U __Py_VaBuildValue_SizeT -U _Py_Version -U __Py_MergeZeroLocalRefcount -U __Py_DecRefShared -U __Py_DecRefSharedDebug -U __Py_DECREF_DecRefTotal -U __Py_INCREF_IncRefTotal -U __PyObject_GetDictPtr -U _PyList_GetItemRef -U _PyDict_GetItemRef -U _PyDict_GetItemStringRef -U _PyDict_SetDefault -U _PyDict_SetDefaultRef -U _PyWeakref_GetRef -U _PyImport_AddModuleRef -U _PyUnstable_Module_SetGIL -U _PyMutex_Unlock -U _PyMutex_Lock -U _PyObject_IS_GC -U _PyCriticalSection_Begin -U _PyCriticalSection_End -U _PyCriticalSection2_Begin -U _PyCriticalSection2_End -U _PyUnicode_AsUTF8 wjakob-nanobind-6c4457b/cmake/darwin-ld-pypy.sym000066400000000000000000000601571474760012700216300ustar00rootroot00000000000000-U _PyArg_ValidateKeywordArguments -U _PyModule_AddType -U _PyPyAnySet_Check -U _PyPyAnySet_CheckExact -U _PyPyArg_Parse -U _PyPyArg_ParseTuple -U _PyPyArg_ParseTupleAndKeywords -U _PyPyArg_UnpackTuple -U _PyPyArg_VaParse -U _PyPyArg_VaParseTupleAndKeywords -U _PyPyBaseObject_Type -U _PyPyBool_FromLong -U _PyPyBool_Type -U _PyPyBuffer_FillInfo -U _PyPyBuffer_FromContiguous -U _PyPyBuffer_GetPointer -U _PyPyBuffer_IsContiguous -U _PyPyBuffer_Release -U _PyPyBuffer_ToContiguous -U _PyPyBufferable_Type -U _PyPyByteArray_AsString -U _PyPyByteArray_Check -U _PyPyByteArray_CheckExact -U _PyPyByteArray_Concat -U _PyPyByteArray_FromObject -U _PyPyByteArray_FromStringAndSize -U _PyPyByteArray_Resize -U _PyPyByteArray_Size -U _PyPyByteArray_Type -U _PyPyBytes_AS_STRING -U _PyPyBytes_AsString -U _PyPyBytes_AsStringAndSize -U _PyPyBytes_Concat -U _PyPyBytes_ConcatAndDel -U _PyPyBytes_FromFormat -U _PyPyBytes_FromFormatV -U _PyPyBytes_FromObject -U _PyPyBytes_FromString -U _PyPyBytes_FromStringAndSize -U _PyPyBytes_Size -U _PyPyBytes_Type -U _PyPyCFunction_Call -U _PyPyCFunction_Check -U _PyPyCFunction_GetFunction -U _PyPyCFunction_Type -U _PyPyCFunction_NewEx -U _PyPyCMethod_New -U _PyPyCallIter_New -U _PyPyCallable_Check -U _PyPyCapsule_GetContext -U _PyPyCapsule_GetDestructor -U _PyPyCapsule_GetName -U _PyPyCapsule_GetPointer -U _PyPyCapsule_Import -U _PyPyCapsule_IsValid -U _PyPyCapsule_New -U _PyPyCapsule_SetContext -U _PyPyCapsule_SetDestructor -U _PyPyCapsule_SetName -U _PyPyCapsule_SetPointer -U _PyPyCapsule_Type -U _PyPyCell_Type -U _PyPyClassMethodDescr_Type -U _PyPyClassMethod_New -U _PyPyClassMethod_Type -U _PyPyCode_Addr2Line -U _PyPyCode_Check -U _PyPyCode_CheckExact -U _PyPyCode_GetNumFree -U _PyPyCode_New -U _PyPyCode_NewEmpty -U _PyPyCodec_Decode -U _PyPyCodec_Decoder -U _PyPyCodec_Encode -U _PyPyCodec_Encoder -U _PyPyCodec_IncrementalDecoder -U _PyPyCodec_IncrementalEncoder -U _PyPyComplex_AsCComplex -U _PyPyComplex_Check -U _PyPyComplex_CheckExact -U _PyPyComplex_FromCComplex -U _PyPyComplex_FromDoubles -U _PyPyComplex_ImagAsDouble -U _PyPyComplex_RealAsDouble -U _PyPyComplex_Type -U _PyPyContextVar_Get -U _PyPyContextVar_New -U _PyPyContextVar_Set -U _PyPyCoro_Check -U _PyPyCoro_CheckExact -U _PyPyDateTimeAPI -U _PyPyDateTime_Check -U _PyPyDateTime_CheckExact -U _PyPyDateTime_DATE_GET_HOUR -U _PyPyDateTime_DATE_GET_MICROSECOND -U _PyPyDateTime_DATE_GET_MINUTE -U _PyPyDateTime_DATE_GET_SECOND -U _PyPyDateTime_DELTA_GET_DAYS -U _PyPyDateTime_DELTA_GET_MICROSECONDS -U _PyPyDateTime_DELTA_GET_SECONDS -U _PyPyDateTime_FromTimestamp -U _PyPyDateTime_GET_DAY -U _PyPyDateTime_GET_FOLD -U _PyPyDateTime_GET_MONTH -U _PyPyDateTime_GET_YEAR -U _PyPyDateTime_TIME_GET_FOLD -U _PyPyDateTime_TIME_GET_HOUR -U _PyPyDateTime_TIME_GET_MICROSECOND -U _PyPyDateTime_TIME_GET_MINUTE -U _PyPyDateTime_TIME_GET_SECOND -U _PyPyDate_Check -U _PyPyDate_CheckExact -U _PyPyDate_FromTimestamp -U _PyPyDelta_Check -U _PyPyDelta_CheckExact -U _PyPyDescr_NewClassMethod -U _PyPyDescr_NewGetSet -U _PyPyDescr_NewMethod -U _PyPyDictKeys_Type -U _PyPyDictProxy_Check -U _PyPyDictProxy_CheckExact -U _PyPyDictProxy_New -U _PyPyDictProxy_Type -U _PyPyDictValues_Type -U _PyPyDict_Clear -U _PyPyDict_Contains -U _PyPyDict_Copy -U _PyPyDict_DelItem -U _PyPyDict_DelItemString -U _PyPyDict_GetItem -U _PyPyDict_GetItemString -U _PyPyDict_GetItemWithError -U _PyPyDict_Items -U _PyPyDict_Keys -U _PyPyDict_Merge -U _PyPyDict_New -U _PyPyDict_Next -U _PyPyDict_SetDefault -U _PyPyDict_SetItem -U _PyPyDict_SetItemString -U _PyPyDict_Size -U _PyPyDict_Type -U _PyPyDict_Update -U _PyPyDict_Values -U _PyPyErr_BadArgument -U _PyPyErr_BadInternalCall -U _PyPyErr_CheckSignals -U _PyPyErr_Clear -U _PyPyErr_Display -U _PyPyErr_ExceptionMatches -U _PyPyErr_Fetch -U _PyPyErr_Format -U _PyPyErr_GetExcInfo -U _PyPyErr_GivenExceptionMatches -U _PyPyErr_NewException -U _PyPyErr_NewExceptionWithDoc -U _PyPyErr_NoMemory -U _PyPyErr_NormalizeException -U _PyPyErr_Occurred -U _PyPyErr_Print -U _PyPyErr_PrintEx -U _PyPyErr_Restore -U _PyPyErr_SetExcInfo -U _PyPyErr_SetFromErrno -U _PyPyErr_SetFromErrnoWithFilename -U _PyPyErr_SetFromErrnoWithFilenameObject -U _PyPyErr_SetFromErrnoWithFilenameObjects -U _PyPyErr_SetInterrupt -U _PyPyErr_SetNone -U _PyPyErr_SetObject -U _PyPyErr_SetString -U _PyPyErr_Warn -U _PyPyErr_WarnEx -U _PyPyErr_WarnExplicit -U _PyPyErr_WarnFormat -U _PyPyErr_WriteUnraisable -U _PyPyEval_AcquireThread -U _PyPyEval_CallFunction -U _PyPyEval_CallMethod -U _PyPyEval_CallObjectWithKeywords -U _PyPyEval_EvalCode -U _PyPyEval_GetBuiltins -U _PyPyEval_GetFrame -U _PyPyEval_GetGlobals -U _PyPyEval_GetLocals -U _PyPyEval_InitThreads -U _PyPyEval_MergeCompilerFlags -U _PyPyEval_ReleaseThread -U _PyPyEval_RestoreThread -U _PyPyEval_SaveThread -U _PyPyEval_ThreadsInitialized -U _PyPyExc_ArithmeticError -U _PyPyExc_AssertionError -U _PyPyExc_AttributeError -U _PyPyExc_BaseException -U _PyPyExc_BlockingIOError -U _PyPyExc_BrokenPipeError -U _PyPyExc_BufferError -U _PyPyExc_BytesWarning -U _PyPyExc_ChildProcessError -U _PyPyExc_ConnectionAbortedError -U _PyPyExc_ConnectionError -U _PyPyExc_ConnectionRefusedError -U _PyPyExc_ConnectionResetError -U _PyPyExc_DeprecationWarning -U _PyPyExc_EOFError -U _PyPyExc_Exception -U _PyPyExc_FileExistsError -U _PyPyExc_FileNotFoundError -U _PyPyExc_FloatingPointError -U _PyPyExc_FutureWarning -U _PyPyExc_GeneratorExit -U _PyPyExc_ImportError -U _PyPyExc_ImportWarning -U _PyPyExc_IndentationError -U _PyPyExc_IndexError -U _PyPyExc_InterruptedError -U _PyPyExc_IsADirectoryError -U _PyPyExc_KeyError -U _PyPyExc_KeyboardInterrupt -U _PyPyExc_LookupError -U _PyPyExc_MemoryError -U _PyPyExc_ModuleNotFoundError -U _PyPyExc_NameError -U _PyPyExc_NotADirectoryError -U _PyPyExc_NotImplementedError -U _PyPyExc_OSError -U _PyPyExc_OverflowError -U _PyPyExc_PendingDeprecationWarning -U _PyPyExc_PermissionError -U _PyPyExc_ProcessLookupError -U _PyPyExc_RecursionError -U _PyPyExc_ReferenceError -U _PyPyExc_ResourceWarning -U _PyPyExc_RuntimeError -U _PyPyExc_RuntimeWarning -U _PyPyExc_StopAsyncIteration -U _PyPyExc_StopIteration -U _PyPyExc_SyntaxError -U _PyPyExc_SyntaxWarning -U _PyPyExc_SystemError -U _PyPyExc_SystemExit -U _PyPyExc_TabError -U _PyPyExc_TimeoutError -U _PyPyExc_TypeError -U _PyPyExc_UnboundLocalError -U _PyPyExc_UnicodeDecodeError -U _PyPyExc_UnicodeEncodeError -U _PyPyExc_UnicodeError -U _PyPyExc_UnicodeTranslateError -U _PyPyExc_UnicodeWarning -U _PyPyExc_UserWarning -U _PyPyExc_ValueError -U _PyPyExc_Warning -U _PyPyExc_ZeroDivisionError -U _PyPyExceptionInstance_Class -U _PyPyException_GetCause -U _PyPyException_GetContext -U _PyPyException_GetTraceback -U _PyPyException_SetCause -U _PyPyException_SetContext -U _PyPyException_SetTraceback -U _PyPyFile_FromFd -U _PyPyFile_FromString -U _PyPyFile_GetLine -U _PyPyFile_WriteObject -U _PyPyFile_WriteString -U _PyPyFloat_AS_DOUBLE -U _PyPyFloat_AsDouble -U _PyPyFloat_Check -U _PyPyFloat_CheckExact -U _PyPyFloat_FromDouble -U _PyPyFloat_FromString -U _PyPyFloat_Type -U _PyPyFrame_New -U _PyPyFrozenSet_Check -U _PyPyFrozenSet_CheckExact -U _PyPyFrozenSet_New -U _PyPyFrozenSet_Type -U _PyPyFunction_Check -U _PyPyFunction_CheckExact -U _PyPyFunction_GetCode -U _PyPyFunction_Type -U _PyPyGILState_Check -U _PyPyGILState_Ensure -U _PyPyGILState_Release -U _PyPyGen_Check -U _PyPyGen_CheckExact -U _PyPyGetSetDescr_Type -U _PyPyImport_AddModule -U _PyPyImport_ExecCodeModule -U _PyPyImport_ExecCodeModuleEx -U _PyPyImport_GetModule -U _PyPyImport_GetModuleDict -U _PyPyImport_Import -U _PyPyImport_ImportModule -U _PyPyImport_ImportModuleLevelObject -U _PyPyImport_ImportModuleNoBlock -U _PyPyImport_ReloadModule -U _PyPyIndex_Check -U _PyPyInstanceMethod_Check -U _PyPyInstanceMethod_Function -U _PyPyInstanceMethod_GET_FUNCTION -U _PyPyInstanceMethod_New -U _PyPyInstanceMethod_Type -U _PyPyInterpreterState_GetID -U _PyPyInterpreterState_Head -U _PyPyInterpreterState_Next -U _PyPyIter_Check -U _PyPyIter_Next -U _PyPyList_Append -U _PyPyList_AsTuple -U _PyPyList_GET_ITEM -U _PyPyList_GET_SIZE -U _PyPyList_GetItem -U _PyPyList_GetSlice -U _PyPyList_Insert -U _PyPyList_New -U _PyPyList_Reverse -U _PyPyList_SET_ITEM -U _PyPyList_SetItem -U _PyPyList_SetSlice -U _PyPyList_Size -U _PyPyList_Sort -U _PyPyList_Type -U _PyPyLong_AsDouble -U _PyPyLong_AsLong -U _PyPyLong_AsLongAndOverflow -U _PyPyLong_AsLongLong -U _PyPyLong_AsLongLongAndOverflow -U _PyPyLong_AsSize_t -U _PyPyLong_AsSsize_t -U _PyPyLong_AsUnsignedLong -U _PyPyLong_AsUnsignedLongLong -U _PyPyLong_AsUnsignedLongLongMask -U _PyPyLong_AsUnsignedLongMask -U _PyPyLong_AsVoidPtr -U _PyPyLong_FromDouble -U _PyPyLong_FromLong -U _PyPyLong_FromLongLong -U _PyPyLong_FromSize_t -U _PyPyLong_FromSsize_t -U _PyPyLong_FromString -U _PyPyLong_FromUnicode -U _PyPyLong_FromUnicodeObject -U _PyPyLong_FromUnsignedLong -U _PyPyLong_FromUnsignedLongLong -U _PyPyLong_FromVoidPtr -U _PyPyLong_Type -U _PyPyMapping_Check -U _PyPyMapping_GetItemString -U _PyPyMapping_HasKey -U _PyPyMapping_HasKeyString -U _PyPyMapping_Items -U _PyPyMapping_Keys -U _PyPyMapping_Length -U _PyPyMapping_SetItemString -U _PyPyMapping_Size -U _PyPyMapping_Values -U _PyPyMarshal_ReadObjectFromString -U _PyPyMarshal_WriteObjectToString -U _PyPyMem_Calloc -U _PyPyMem_Free -U _PyPyMem_Malloc -U _PyPyMem_RawCalloc -U _PyPyMem_RawFree -U _PyPyMem_RawMalloc -U _PyPyMem_RawRealloc -U _PyPyMem_Realloc -U _PyPyMemberDescr_Type -U _PyPyMember_GetOne -U _PyPyMember_SetOne -U _PyPyMemoryView_Check -U _PyPyMemoryView_CheckExact -U _PyPyMemoryView_FromBuffer -U _PyPyMemoryView_FromMemory -U _PyPyMemoryView_FromObject -U _PyPyMemoryView_GetContiguous -U _PyPyMemoryView_Type -U _PyPyMethodDescr_Check -U _PyPyMethodDescr_CheckExact -U _PyPyMethodDescr_Type -U _PyPyMethod_Check -U _PyPyMethod_CheckExact -U _PyPyMethod_Function -U _PyPyMethod_New -U _PyPyMethod_Self -U _PyPyMethod_Type -U _PyPyModuleDef_Init -U _PyPyModule_AddFunctions -U _PyPyModule_AddIntConstant -U _PyPyModule_AddObject -U _PyPyModule_AddStringConstant -U _PyPyModule_Check -U _PyPyModule_CheckExact -U _PyPyModule_Create2 -U _PyPyModule_ExecDef -U _PyPyModule_GetDef -U _PyPyModule_GetDict -U _PyPyModule_GetName -U _PyPyModule_GetState -U _PyPyModule_New -U _PyPyModule_NewObject -U _PyPyModule_Type -U _PyPyNumber_Absolute -U _PyPyNumber_Add -U _PyPyNumber_And -U _PyPyNumber_AsSsize_t -U _PyPyNumber_Check -U _PyPyNumber_Divide -U _PyPyNumber_Divmod -U _PyPyNumber_Float -U _PyPyNumber_FloorDivide -U _PyPyNumber_InPlaceAdd -U _PyPyNumber_InPlaceAnd -U _PyPyNumber_InPlaceDivide -U _PyPyNumber_InPlaceFloorDivide -U _PyPyNumber_InPlaceLshift -U _PyPyNumber_InPlaceMatrixMultiply -U _PyPyNumber_InPlaceMultiply -U _PyPyNumber_InPlaceOr -U _PyPyNumber_InPlacePower -U _PyPyNumber_InPlaceRemainder -U _PyPyNumber_InPlaceRshift -U _PyPyNumber_InPlaceSubtract -U _PyPyNumber_InPlaceTrueDivide -U _PyPyNumber_InPlaceXor -U _PyPyNumber_Index -U _PyPyNumber_Invert -U _PyPyNumber_Long -U _PyPyNumber_Lshift -U _PyPyNumber_MatrixMultiply -U _PyPyNumber_Multiply -U _PyPyNumber_Negative -U _PyPyNumber_Or -U _PyPyNumber_Positive -U _PyPyNumber_Power -U _PyPyNumber_Remainder -U _PyPyNumber_Rshift -U _PyPyNumber_Subtract -U _PyPyNumber_ToBase -U _PyPyNumber_TrueDivide -U _PyPyNumber_Xor -U _PyPyOS_AfterFork -U _PyPyOS_FSPath -U _PyPyOS_InputHook -U _PyPyOS_InterruptOccurred -U _PyPyOS_double_to_string -U _PyPyOS_getsig -U _PyPyOS_setsig -U _PyPyOS_snprintf -U _PyPyOS_string_to_double -U _PyPyOS_vsnprintf -U _PyPyObject_ASCII -U _PyPyObject_AsCharBuffer -U _PyPyObject_AsFileDescriptor -U _PyPyObject_AsReadBuffer -U _PyPyObject_AsWriteBuffer -U _PyPyObject_Bytes -U _PyPyObject_Call -U _PyPyObject_CallFinalizerFromDealloc -U _PyPyObject_CallFunction -U _PyPyObject_CallFunctionObjArgs -U _PyPyObject_CallMethod -U _PyPyObject_CallMethodNoArgs -U _PyPyObject_CallMethodObjArgs -U _PyPyObject_CallMethodOneArg -U _PyPyObject_CallNoArgs -U _PyPyObject_CallObject -U _PyPyObject_CallOneArg -U _PyPyObject_Calloc -U _PyPyObject_CheckReadBuffer -U _PyPyObject_ClearWeakRefs -U _PyPyObject_Del -U _PyPyObject_DelAttr -U _PyPyObject_DelAttrString -U _PyPyObject_DelItem -U _PyPyObject_DelItemString -U _PyPyObject_Dir -U _PyPyObject_Format -U _PyPyObject_Free -U _PyPyObject_GC_Del -U _PyPyObject_GenericGetAttr -U _PyPyObject_GenericGetDict -U _PyPyObject_GenericSetAttr -U _PyPyObject_GenericSetDict -U _PyPyObject_GetAttr -U _PyPyObject_GetAttrString -U _PyPyObject_GetBuffer -U _PyPyObject_GetItem -U _PyPyObject_GetIter -U _PyPyObject_HasAttr -U _PyPyObject_HasAttrString -U _PyPyObject_Hash -U _PyPyObject_HashNotImplemented -U _PyPyObject_Init -U _PyPyObject_InitVar -U _PyPyObject_IsInstance -U _PyPyObject_IsSubclass -U _PyPyObject_IsTrue -U _PyPyObject_LengthHint -U _PyPyObject_Malloc -U _PyPyObject_Not -U _PyPyObject_Print -U _PyPyObject_Realloc -U _PyPyObject_Repr -U _PyPyObject_RichCompare -U _PyPyObject_RichCompareBool -U _PyPyObject_SelfIter -U _PyPyObject_SetAttr -U _PyPyObject_SetAttrString -U _PyPyObject_SetItem -U _PyPyObject_Size -U _PyPyObject_Str -U _PyPyObject_Type -U _PyPyObject_Unicode -U _PyPyObject_Vectorcall -U _PyPyObject_VectorcallDict -U _PyPyObject_VectorcallMethod -U _PyPyProperty_Type -U _PyPyRange_Type -U _PyPyReversed_Type -U _PyPyRun_File -U _PyPyRun_SimpleString -U _PyPyRun_String -U _PyPyRun_StringFlags -U _PyPySeqIter_New -U _PyPySequence_Check -U _PyPySequence_Concat -U _PyPySequence_Contains -U _PyPySequence_DelItem -U _PyPySequence_DelSlice -U _PyPySequence_Fast -U _PyPySequence_Fast_GET_ITEM -U _PyPySequence_Fast_GET_SIZE -U _PyPySequence_Fast_ITEMS -U _PyPySequence_GetItem -U _PyPySequence_GetSlice -U _PyPySequence_ITEM -U _PyPySequence_InPlaceConcat -U _PyPySequence_InPlaceRepeat -U _PyPySequence_Index -U _PyPySequence_Length -U _PyPySequence_List -U _PyPySequence_Repeat -U _PyPySequence_SetItem -U _PyPySequence_SetSlice -U _PyPySequence_Size -U _PyPySequence_Tuple -U _PyPySet_Add -U _PyPySet_Check -U _PyPySet_CheckExact -U _PyPySet_Clear -U _PyPySet_Contains -U _PyPySet_Discard -U _PyPySet_GET_SIZE -U _PyPySet_New -U _PyPySet_Pop -U _PyPySet_Size -U _PyPySet_Type -U _PyPySlice_AdjustIndices -U _PyPySlice_GetIndices -U _PyPySlice_GetIndicesEx -U _PyPySlice_New -U _PyPySlice_Type -U _PyPySlice_Unpack -U _PyPyState_AddModule -U _PyPyState_RemoveModule -U _PyPyStaticMethod_New -U _PyPyStaticMethod_Type -U _PyPyStructSequence_GetItem -U _PyPyStructSequence_InitType -U _PyPyStructSequence_InitType2 -U _PyPyStructSequence_New -U _PyPyStructSequence_NewType -U _PyPyStructSequence_SetItem -U _PyPyStructSequence_UnnamedField -U _PyPySys_GetObject -U _PyPySys_SetObject -U _PyPySys_WriteStderr -U _PyPySys_WriteStdout -U _PyPyTZInfo_Check -U _PyPyTZInfo_CheckExact -U _PyPyThreadState_Clear -U _PyPyThreadState_Delete -U _PyPyThreadState_DeleteCurrent -U _PyPyThreadState_Get -U _PyPyThreadState_GetDict -U _PyPyThreadState_New -U _PyPyThreadState_SetAsyncExc -U _PyPyThreadState_Swap -U _PyPyThread_ReInitTLS -U _PyPyThread_acquire_lock -U _PyPyThread_allocate_lock -U _PyPyThread_create_key -U _PyPyThread_delete_key -U _PyPyThread_delete_key_value -U _PyPyThread_exit_thread -U _PyPyThread_free_lock -U _PyPyThread_get_key_value -U _PyPyThread_get_thread_ident -U _PyPyThread_init_thread -U _PyPyThread_release_lock -U _PyPyThread_set_key_value -U _PyPyThread_start_new_thread -U _PyPyTime_Check -U _PyPyTime_CheckExact -U _PyPyTraceBack_Check -U _PyPyTraceBack_Here -U _PyPyTraceBack_Print -U _PyPyTraceBack_Type -U _PyPyTraceMalloc_Track -U _PyPyTraceMalloc_Untrack -U _PyPyTuple_GetItem -U _PyPyTuple_GetSlice -U _PyPyTuple_New -U _PyPyTuple_Pack -U _PyPyTuple_SetItem -U _PyPyTuple_Size -U _PyPyTuple_Type -U _PyPyType_FromModuleAndSpec -U _PyPyType_FromSpec -U _PyPyType_FromSpecWithBases -U _PyPyType_GenericAlloc -U _PyPyType_GenericNew -U _PyPyType_GetModule -U _PyPyType_GetModuleState -U _PyPyType_GetSlot -U _PyPyType_IsSubtype -U _PyPyType_Modified -U _PyPyType_Ready -U _PyPyType_Type -U _PyPyUnicode_Append -U _PyPyUnicode_AppendAndDel -U _PyPyUnicode_AsASCIIString -U _PyPyUnicode_AsEncodedObject -U _PyPyUnicode_AsEncodedString -U _PyPyUnicode_AsLatin1String -U _PyPyUnicode_AsUCS4 -U _PyPyUnicode_AsUCS4Copy -U _PyPyUnicode_AsUTF16String -U _PyPyUnicode_AsUTF32String -U _PyPyUnicode_AsUTF8 -U _PyPyUnicode_AsUTF8AndSize -U _PyPyUnicode_AsUTF8String -U _PyPyUnicode_AsUnicode -U _PyPyUnicode_AsUnicodeAndSize -U _PyPyUnicode_AsUnicodeEscapeString -U _PyPyUnicode_AsWideChar -U _PyPyUnicode_AsWideCharString -U _PyPyUnicode_Check -U _PyPyUnicode_CheckExact -U _PyPyUnicode_Compare -U _PyPyUnicode_CompareWithASCIIString -U _PyPyUnicode_Concat -U _PyPyUnicode_Contains -U _PyPyUnicode_Count -U _PyPyUnicode_Decode -U _PyPyUnicode_DecodeASCII -U _PyPyUnicode_DecodeFSDefault -U _PyPyUnicode_DecodeFSDefaultAndSize -U _PyPyUnicode_DecodeLatin1 -U _PyPyUnicode_DecodeLocale -U _PyPyUnicode_DecodeLocaleAndSize -U _PyPyUnicode_DecodeUTF16 -U _PyPyUnicode_DecodeUTF32 -U _PyPyUnicode_DecodeUTF8 -U _PyPyUnicode_EncodeASCII -U _PyPyUnicode_EncodeDecimal -U _PyPyUnicode_EncodeFSDefault -U _PyPyUnicode_EncodeLatin1 -U _PyPyUnicode_EncodeLocale -U _PyPyUnicode_EncodeUTF8 -U _PyPyUnicode_FSConverter -U _PyPyUnicode_FSDecoder -U _PyPyUnicode_Find -U _PyPyUnicode_FindChar -U _PyPyUnicode_Format -U _PyPyUnicode_FromEncodedObject -U _PyPyUnicode_FromFormat -U _PyPyUnicode_FromFormatV -U _PyPyUnicode_FromKindAndData -U _PyPyUnicode_FromObject -U _PyPyUnicode_FromOrdinal -U _PyPyUnicode_FromString -U _PyPyUnicode_FromStringAndSize -U _PyPyUnicode_FromUnicode -U _PyPyUnicode_FromWideChar -U _PyPyUnicode_GetDefaultEncoding -U _PyPyUnicode_GetLength -U _PyPyUnicode_GetMax -U _PyPyUnicode_GetSize -U _PyPyUnicode_InternFromString -U _PyPyUnicode_InternInPlace -U _PyPyUnicode_Join -U _PyPyUnicode_New -U _PyPyUnicode_ReadChar -U _PyPyUnicode_Replace -U _PyPyUnicode_Resize -U _PyPyUnicode_Split -U _PyPyUnicode_Splitlines -U _PyPyUnicode_Substring -U _PyPyUnicode_Tailmatch -U _PyPyUnicode_TransformDecimalToASCII -U _PyPyUnicode_Type -U _PyPyUnicode_WriteChar -U _PyPyVectorcall_Call -U _PyPyWeakref_Check -U _PyPyWeakref_CheckProxy -U _PyPyWeakref_CheckRef -U _PyPyWeakref_CheckRefExact -U _PyPyWeakref_GET_OBJECT -U _PyPyWeakref_GetObject -U _PyPyWeakref_LockObject -U _PyPyWeakref_NewProxy -U _PyPyWeakref_NewRef -U _PyPyWrapperDescr_Type -U _PyPy_AddPendingCall -U _PyPy_AtExit -U _PyPy_BuildValue -U _PyPy_BytesWarningFlag -U _PyPy_CompileStringFlags -U _PyPy_DebugFlag -U _PyPy_DecRef -U _PyPy_DontWriteBytecodeFlag -U _PyPy_EnterRecursiveCall -U _PyPy_FatalError -U _PyPy_FindMethod -U _PyPy_FrozenFlag -U _PyPy_GenericAlias -U _PyPy_GetProgramName -U _PyPy_GetRecursionLimit -U _PyPy_GetVersion -U _PyPy_HashRandomizationFlag -U _PyPy_IgnoreEnvironmentFlag -U _PyPy_IncRef -U _PyPy_InspectFlag -U _PyPy_InteractiveFlag -U _PyPy_IsInitialized -U _PyPy_IsolatedFlag -U _PyPy_LeaveRecursiveCall -U _PyPy_MakePendingCalls -U _PyPy_NoSiteFlag -U _PyPy_NoUserSiteDirectory -U _PyPy_OptimizeFlag -U _PyPy_QuietFlag -U _PyPy_ReprEnter -U _PyPy_ReprLeave -U _PyPy_SetRecursionLimit -U _PyPy_UNICODE_COPY -U _PyPy_UNICODE_ISALNUM -U _PyPy_UNICODE_ISALPHA -U _PyPy_UNICODE_ISDECIMAL -U _PyPy_UNICODE_ISDIGIT -U _PyPy_UNICODE_ISLINEBREAK -U _PyPy_UNICODE_ISLOWER -U _PyPy_UNICODE_ISNUMERIC -U _PyPy_UNICODE_ISSPACE -U _PyPy_UNICODE_ISTITLE -U _PyPy_UNICODE_ISUPPER -U _PyPy_UNICODE_TODECIMAL -U _PyPy_UNICODE_TODIGIT -U _PyPy_UNICODE_TOLOWER -U _PyPy_UNICODE_TONUMERIC -U _PyPy_UNICODE_TOTITLE -U _PyPy_UNICODE_TOUPPER -U _PyPy_UnbufferedStdioFlag -U _PyPy_VaBuildValue -U _PyPy_VerboseFlag -U _PySlice_AdjustIndices -U _PyState_FindModule -U _PyThread_tss_alloc -U _PyThread_tss_create -U _PyThread_tss_delete -U _PyThread_tss_free -U _PyThread_tss_get -U _PyThread_tss_is_created -U _PyThread_tss_set -U _PyType_GetFlags -U _Py_FileSystemDefaultEncoding -U __PyArg_BadArgument -U __PyArg_CheckPositional -U __PyArg_NoKeywords -U __PyArg_NoKwnames -U __PyArg_NoPositional -U __PyArg_ParseStack -U __PyArg_ParseStackAndKeywords -U __PyArg_ParseStackAndKeywords_SizeT -U __PyArg_ParseStack_SizeT -U __PyArg_ParseTupleAndKeywordsFast -U __PyArg_ParseTupleAndKeywordsFast_SizeT -U __PyArg_UnpackKeywords -U __PyArg_UnpackStack -U __PyArg_VaParseTupleAndKeywordsFast -U __PyArg_VaParseTupleAndKeywordsFast_SizeT -U __PyExc_ArithmeticError -U __PyExc_AssertionError -U __PyExc_AttributeError -U __PyExc_BaseException -U __PyExc_BlockingIOError -U __PyExc_BrokenPipeError -U __PyExc_BufferError -U __PyExc_BytesWarning -U __PyExc_ChildProcessError -U __PyExc_ConnectionAbortedError -U __PyExc_ConnectionError -U __PyExc_ConnectionRefusedError -U __PyExc_ConnectionResetError -U __PyExc_DeprecationWarning -U __PyExc_EOFError -U __PyExc_Exception -U __PyExc_FileExistsError -U __PyExc_FileNotFoundError -U __PyExc_FloatingPointError -U __PyExc_FutureWarning -U __PyExc_GeneratorExit -U __PyExc_ImportError -U __PyExc_ImportWarning -U __PyExc_IndentationError -U __PyExc_IndexError -U __PyExc_InterruptedError -U __PyExc_IsADirectoryError -U __PyExc_KeyError -U __PyExc_KeyboardInterrupt -U __PyExc_LookupError -U __PyExc_MemoryError -U __PyExc_ModuleNotFoundError -U __PyExc_NameError -U __PyExc_NotADirectoryError -U __PyExc_NotImplementedError -U __PyExc_OSError -U __PyExc_OverflowError -U __PyExc_PendingDeprecationWarning -U __PyExc_PermissionError -U __PyExc_ProcessLookupError -U __PyExc_RecursionError -U __PyExc_ReferenceError -U __PyExc_ResourceWarning -U __PyExc_RuntimeError -U __PyExc_RuntimeWarning -U __PyExc_StopAsyncIteration -U __PyExc_StopIteration -U __PyExc_SyntaxError -U __PyExc_SyntaxWarning -U __PyExc_SystemError -U __PyExc_SystemExit -U __PyExc_TabError -U __PyExc_TimeoutError -U __PyExc_TypeError -U __PyExc_UnboundLocalError -U __PyExc_UnicodeDecodeError -U __PyExc_UnicodeEncodeError -U __PyExc_UnicodeError -U __PyExc_UnicodeTranslateError -U __PyExc_UnicodeWarning -U __PyExc_UserWarning -U __PyExc_ValueError -U __PyExc_Warning -U __PyExc_ZeroDivisionError -U __PyLong_AsTime_t -U __PyLong_FromTime_t -U __PyPyArg_ParseTupleAndKeywords_SizeT -U __PyPyArg_ParseTuple_SizeT -U __PyPyArg_Parse_SizeT -U __PyPyArg_VaParseTupleAndKeywords_SizeT -U __PyPyArg_VaParse_SizeT -U __PyPyBytes_Eq -U __PyPyBytes_Join -U __PyPyBytes_Resize -U __PyPyComplex_AsCComplex -U __PyPyComplex_FromCComplex -U __PyPyDateTime_FromDateAndTime -U __PyPyDateTime_FromDateAndTimeAndFold -U __PyPyDateTime_FromTimestamp -U __PyPyDateTime_Import -U __PyPyDate_FromDate -U __PyPyDate_FromTimestamp -U __PyPyDelta_FromDelta -U __PyPyDict_GetItemStringWithError -U __PyPyDict_HasOnlyStringKeys -U __PyPyErr_FormatFromCause -U __PyPyErr_WriteUnraisableMsg -U __PyPyEval_SliceIndex -U __PyPyFloat_Unpack4 -U __PyPyFloat_Unpack8 -U __PyPyImport_AcquireLock -U __PyPyImport_ReleaseLock -U __PyPyList_Extend -U __PyPyLong_AsByteArrayO -U __PyPyLong_FromByteArray -U __PyPyLong_NumBits -U __PyPyLong_Sign -U __PyPyNamespace_New -U __PyPyNone_Type -U __PyPyNotImplemented_Type -U __PyPyObject_CallFunction_SizeT -U __PyPyObject_CallMethod_SizeT -U __PyPyObject_FastCall -U __PyPyObject_GC_Malloc -U __PyPyObject_GC_New -U __PyPyObject_GC_NewVar -U __PyPyObject_GetDictPtr -U __PyPyObject_New -U __PyPyObject_NewVar -U __PyPyObject_Vectorcall -U __PyPyPyGC_AddMemoryPressure -U __PyPyPy_Free -U __PyPyPy_Malloc -U __PyPySet_Next -U __PyPySet_NextEntry -U __PyPyThreadState_UncheckedGet -U __PyPyTimeZone_FromTimeZone -U __PyPyTime_FromTime -U __PyPyTime_FromTimeAndFold -U __PyPyTuple_Resize -U __PyPyType_Lookup -U __PyPyUnicode_EQ -U __PyPyUnicode_EqualToASCIIString -U __PyPyUnicode_Ready -U __PyPy_BuildValue_SizeT -U __PyPy_Dealloc -U __PyPy_EllipsisObject -U __PyPy_FalseStruct -U __PyPy_HashDouble -U __PyPy_HashPointer -U __PyPy_IsFinalizing -U __PyPy_NoneStruct -U __PyPy_NotImplementedStruct -U __PyPy_PackageContext -U __PyPy_RestoreSignals -U __PyPy_TrueStruct -U __PyPy_VaBuildValue_SizeT -U __PyPy_get_PyOS_InputHook -U __PyPy_get_capsule_type -U __PyPy_object_dealloc -U __PyPy_setfilesystemdefaultencoding -U __PyPy_strhex -U __PyPy_strhex_bytes -U __PyPy_subtype_dealloc -U __PyPy_tuple_dealloc -U __PyPy_tuple_new -U __PyTime_AsMicroseconds -U __PyTime_AsMilliseconds -U __PyTime_AsNanosecondsObject -U __PyTime_AsSecondsDouble -U __PyTime_AsTimeval -U __PyTime_AsTimevalTime_t -U __PyTime_AsTimeval_noraise -U __PyTime_FromMillisecondsObject -U __PyTime_FromNanoseconds -U __PyTime_FromNanosecondsObject -U __PyTime_FromSeconds -U __PyTime_FromSecondsObject -U __PyTime_GetMonotonicClock -U __PyTime_GetMonotonicClockWithInfo -U __PyTime_GetSystemClock -U __PyTime_GetSystemClockWithInfo -U __PyTime_Init -U __PyTime_ObjectToTime_t -U __PyTime_ObjectToTimespec -U __PyTime_ObjectToTimeval -U __PyTime_gmtime -U __PyTime_localtime -U __PyType_Name wjakob-nanobind-6c4457b/cmake/nanobind-config.cmake000066400000000000000000000375741474760012700222620ustar00rootroot00000000000000include_guard(GLOBAL) if (NOT TARGET Python::Module) message(FATAL_ERROR "You must invoke 'find_package(Python COMPONENTS Interpreter Development REQUIRED)' prior to including nanobind.") endif() # Determine the right suffix for ordinary and stable ABI extensions. # We always need to know the extension if(WIN32) set(NB_SUFFIX_EXT ".pyd") else() set(NB_SUFFIX_EXT "${CMAKE_SHARED_MODULE_SUFFIX}") endif() # Check if FindPython/scikit-build-core defined a SOABI/SOSABI variable if(DEFINED SKBUILD_SOABI) set(NB_SOABI "${SKBUILD_SOABI}") elseif(DEFINED Python_SOABI) set(NB_SOABI "${Python_SOABI}") endif() if(DEFINED SKBUILD_SOSABI) set(NB_SOSABI "${SKBUILD_SOSABI}") elseif(DEFINED Python_SOSABI) set(NB_SOSABI "${Python_SOSABI}") endif() # PyPy sets an invalid SOABI (platform missing), causing older FindPythons to # report an incorrect value. Only use it if it looks correct (X-X-X form). if(DEFINED NB_SOABI AND "${NB_SOABI}" MATCHES ".+-.+-.+") set(NB_SUFFIX ".${NB_SOABI}${NB_SUFFIX_EXT}") endif() if(DEFINED NB_SOSABI) if(NB_SOSABI STREQUAL "") set(NB_SUFFIX_S "${NB_SUFFIX_EXT}") else() set(NB_SUFFIX_S ".${NB_SOSABI}${NB_SUFFIX_EXT}") endif() endif() # Extract Python version and extensions (e.g. free-threaded build) string(REGEX REPLACE "[^-]*-([^-]*)-.*" "\\1" NB_ABI "${NB_SOABI}") # If either suffix is missing, call Python to compute it if(NOT DEFINED NB_SUFFIX OR NOT DEFINED NB_SUFFIX_S) # Query Python directly to get the right suffix. execute_process( COMMAND "${Python_EXECUTABLE}" "-c" "import sysconfig; print(sysconfig.get_config_var('EXT_SUFFIX'))" RESULT_VARIABLE NB_SUFFIX_RET OUTPUT_VARIABLE EXT_SUFFIX OUTPUT_STRIP_TRAILING_WHITESPACE) if(NB_SUFFIX_RET AND NOT NB_SUFFIX_RET EQUAL 0) message(FATAL_ERROR "nanobind: Python sysconfig query to " "find 'EXT_SUFFIX' property failed!") endif() if(NOT DEFINED NB_SUFFIX) set(NB_SUFFIX "${EXT_SUFFIX}") endif() if(NOT DEFINED NB_SUFFIX_S) get_filename_component(NB_SUFFIX_EXT "${EXT_SUFFIX}" LAST_EXT) if(WIN32) set(NB_SUFFIX_S "${NB_SUFFIX_EXT}") else() set(NB_SUFFIX_S ".abi3${NB_SUFFIX_EXT}") endif() endif() endif() # Stash these for later use set(NB_SUFFIX ${NB_SUFFIX} CACHE INTERNAL "") set(NB_SUFFIX_S ${NB_SUFFIX_S} CACHE INTERNAL "") set(NB_ABI ${NB_ABI} CACHE INTERNAL "") get_filename_component(NB_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) get_filename_component(NB_DIR "${NB_DIR}" PATH) set(NB_DIR ${NB_DIR} CACHE INTERNAL "") set(NB_OPT $,$> CACHE INTERNAL "") set(NB_OPT_SIZE $,$,$> CACHE INTERNAL "") # --------------------------------------------------------------------------- # Helper function to handle undefined CPython API symbols on macOS # --------------------------------------------------------------------------- function (nanobind_link_options name) if (APPLE) if (Python_INTERPRETER_ID STREQUAL "PyPy") set(NB_LINKER_RESPONSE_FILE darwin-ld-pypy.sym) else() set(NB_LINKER_RESPONSE_FILE darwin-ld-cpython.sym) endif() target_link_options(${name} PRIVATE "-Wl,@${NB_DIR}/cmake/${NB_LINKER_RESPONSE_FILE}") endif() endfunction() # --------------------------------------------------------------------------- # Create shared/static library targets for nanobind's non-templated core # --------------------------------------------------------------------------- function (nanobind_build_library TARGET_NAME) cmake_parse_arguments(PARSE_ARGV 1 ARG "AS_SYSINCLUDE" "" "") if (TARGET ${TARGET_NAME}) return() endif() if (TARGET_NAME MATCHES "-static") set (TARGET_TYPE STATIC) else() set (TARGET_TYPE SHARED) endif() if (${ARG_AS_SYSINCLUDE}) set (AS_SYSINCLUDE SYSTEM) endif() add_library(${TARGET_NAME} ${TARGET_TYPE} EXCLUDE_FROM_ALL ${NB_DIR}/include/nanobind/make_iterator.h ${NB_DIR}/include/nanobind/nanobind.h ${NB_DIR}/include/nanobind/nb_accessor.h ${NB_DIR}/include/nanobind/nb_attr.h ${NB_DIR}/include/nanobind/nb_call.h ${NB_DIR}/include/nanobind/nb_cast.h ${NB_DIR}/include/nanobind/nb_class.h ${NB_DIR}/include/nanobind/nb_defs.h ${NB_DIR}/include/nanobind/nb_descr.h ${NB_DIR}/include/nanobind/nb_enums.h ${NB_DIR}/include/nanobind/nb_error.h ${NB_DIR}/include/nanobind/nb_func.h ${NB_DIR}/include/nanobind/nb_lib.h ${NB_DIR}/include/nanobind/nb_misc.h ${NB_DIR}/include/nanobind/nb_python.h ${NB_DIR}/include/nanobind/nb_traits.h ${NB_DIR}/include/nanobind/nb_tuple.h ${NB_DIR}/include/nanobind/nb_types.h ${NB_DIR}/include/nanobind/ndarray.h ${NB_DIR}/include/nanobind/trampoline.h ${NB_DIR}/include/nanobind/typing.h ${NB_DIR}/include/nanobind/operators.h ${NB_DIR}/include/nanobind/stl/array.h ${NB_DIR}/include/nanobind/stl/bind_map.h ${NB_DIR}/include/nanobind/stl/bind_vector.h ${NB_DIR}/include/nanobind/stl/detail ${NB_DIR}/include/nanobind/stl/detail/nb_array.h ${NB_DIR}/include/nanobind/stl/detail/nb_dict.h ${NB_DIR}/include/nanobind/stl/detail/nb_list.h ${NB_DIR}/include/nanobind/stl/detail/nb_set.h ${NB_DIR}/include/nanobind/stl/detail/traits.h ${NB_DIR}/include/nanobind/stl/filesystem.h ${NB_DIR}/include/nanobind/stl/function.h ${NB_DIR}/include/nanobind/stl/list.h ${NB_DIR}/include/nanobind/stl/map.h ${NB_DIR}/include/nanobind/stl/optional.h ${NB_DIR}/include/nanobind/stl/pair.h ${NB_DIR}/include/nanobind/stl/set.h ${NB_DIR}/include/nanobind/stl/shared_ptr.h ${NB_DIR}/include/nanobind/stl/string.h ${NB_DIR}/include/nanobind/stl/string_view.h ${NB_DIR}/include/nanobind/stl/tuple.h ${NB_DIR}/include/nanobind/stl/unique_ptr.h ${NB_DIR}/include/nanobind/stl/unordered_map.h ${NB_DIR}/include/nanobind/stl/unordered_set.h ${NB_DIR}/include/nanobind/stl/variant.h ${NB_DIR}/include/nanobind/stl/vector.h ${NB_DIR}/include/nanobind/eigen/dense.h ${NB_DIR}/include/nanobind/eigen/sparse.h ${NB_DIR}/src/buffer.h ${NB_DIR}/src/hash.h ${NB_DIR}/src/nb_internals.h ${NB_DIR}/src/nb_internals.cpp ${NB_DIR}/src/nb_func.cpp ${NB_DIR}/src/nb_type.cpp ${NB_DIR}/src/nb_enum.cpp ${NB_DIR}/src/nb_ndarray.cpp ${NB_DIR}/src/nb_static_property.cpp ${NB_DIR}/src/nb_ft.h ${NB_DIR}/src/nb_ft.cpp ${NB_DIR}/src/common.cpp ${NB_DIR}/src/error.cpp ${NB_DIR}/src/trampoline.cpp ${NB_DIR}/src/implicit.cpp ) if (TARGET_TYPE STREQUAL "SHARED") nanobind_link_options(${TARGET_NAME}) target_compile_definitions(${TARGET_NAME} PRIVATE -DNB_BUILD) target_compile_definitions(${TARGET_NAME} PUBLIC -DNB_SHARED) nanobind_lto(${TARGET_NAME}) nanobind_strip(${TARGET_NAME}) elseif(NOT WIN32 AND NOT APPLE) target_compile_options(${TARGET_NAME} PUBLIC $<${NB_OPT_SIZE}:-ffunction-sections -fdata-sections>) target_link_options(${TARGET_NAME} PUBLIC $<${NB_OPT_SIZE}:-Wl,--gc-sections>) endif() set_target_properties(${TARGET_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON) if (MSVC) # Do not complain about vsnprintf target_compile_definitions(${TARGET_NAME} PRIVATE -D_CRT_SECURE_NO_WARNINGS) else() # Generally needed to handle type punning in Python code target_compile_options(${TARGET_NAME} PRIVATE -fno-strict-aliasing) endif() if (WIN32) if (${TARGET_NAME} MATCHES "-abi3") target_link_libraries(${TARGET_NAME} PUBLIC Python::SABIModule) else() target_link_libraries(${TARGET_NAME} PUBLIC Python::Module) endif() endif() if (TARGET_NAME MATCHES "-ft") target_compile_definitions(${TARGET_NAME} PUBLIC NB_FREE_THREADED) endif() # Nanobind performs many assertion checks -- detailed error messages aren't # included in Release/MinSizeRel modes target_compile_definitions(${TARGET_NAME} PRIVATE $<${NB_OPT_SIZE}:NB_COMPACT_ASSERTIONS>) # If nanobind was installed without submodule dependencies, then the # dependencies directory won't exist and we need to find them. # However, if the directory _does_ exist, then the user is free to choose # whether nanobind uses them (based on `NB_USE_SUBMODULE_DEPS`), with a # preference to choose them if `NB_USE_SUBMODULE_DEPS` is not defined if (NOT IS_DIRECTORY ${NB_DIR}/ext/robin_map/include OR (DEFINED NB_USE_SUBMODULE_DEPS AND NOT NB_USE_SUBMODULE_DEPS)) include(CMakeFindDependencyMacro) find_dependency(tsl-robin-map) target_link_libraries(${TARGET_NAME} PRIVATE tsl::robin_map) else() target_include_directories(${TARGET_NAME} PRIVATE ${NB_DIR}/ext/robin_map/include) endif() target_include_directories(${TARGET_NAME} ${AS_SYSINCLUDE} PUBLIC ${Python_INCLUDE_DIRS} ${NB_DIR}/include) target_compile_features(${TARGET_NAME} PUBLIC cxx_std_17) nanobind_set_visibility(${TARGET_NAME}) if (MSVC) # warning #1388-D: base class dllexport/dllimport specification differs from that of the derived class target_compile_options(${TARGET_NAME} PUBLIC $<$:-Xcudafe --diag_suppress=1388>) endif() endfunction() # --------------------------------------------------------------------------- # Define a convenience function for creating nanobind targets # --------------------------------------------------------------------------- function(nanobind_opt_size name) if (MSVC) target_compile_options(${name} PRIVATE $<${NB_OPT_SIZE}:$<$:/Os>>) else() target_compile_options(${name} PRIVATE $<${NB_OPT_SIZE}:$<$:-Os>>) endif() endfunction() function(nanobind_disable_stack_protector name) if (NOT MSVC) # The stack protector affects binding size negatively (+8% on Linux in my # benchmarks). Protecting from stack smashing in a Python VM seems in any # case futile, so let's get rid of it by default in optimized modes. target_compile_options(${name} PRIVATE $<${NB_OPT}:-fno-stack-protector>) endif() endfunction() function(nanobind_extension name) set_target_properties(${name} PROPERTIES PREFIX "" SUFFIX "${NB_SUFFIX}") endfunction() function(nanobind_extension_abi3 name) set_target_properties(${name} PROPERTIES PREFIX "" SUFFIX "${NB_SUFFIX_S}") endfunction() function (nanobind_lto name) set_target_properties(${name} PROPERTIES INTERPROCEDURAL_OPTIMIZATION_RELEASE ON INTERPROCEDURAL_OPTIMIZATION_MINSIZEREL ON) endfunction() function (nanobind_compile_options name) if (MSVC) target_compile_options(${name} PRIVATE $<$:/bigobj /MP>) endif() endfunction() function (nanobind_strip name) if (APPLE) target_link_options(${name} PRIVATE $<${NB_OPT}:-Wl,-dead_strip -Wl,-x -Wl,-S>) elseif (NOT WIN32) target_link_options(${name} PRIVATE $<${NB_OPT}:-Wl,-s>) endif() endfunction() function (nanobind_set_visibility name) set_target_properties(${name} PROPERTIES CXX_VISIBILITY_PRESET hidden) endfunction() function (nanobind_musl_static_libcpp name) if ("$ENV{AUDITWHEEL_PLAT}" MATCHES "musllinux") target_link_options(${name} PRIVATE -static-libstdc++ -static-libgcc) endif() endfunction() function(nanobind_add_module name) cmake_parse_arguments(PARSE_ARGV 1 ARG "STABLE_ABI;FREE_THREADED;NB_STATIC;NB_SHARED;PROTECT_STACK;LTO;NOMINSIZE;NOSTRIP;MUSL_DYNAMIC_LIBCPP;NB_SUPPRESS_WARNINGS" "NB_DOMAIN" "") add_library(${name} MODULE ${ARG_UNPARSED_ARGUMENTS}) nanobind_compile_options(${name}) nanobind_link_options(${name}) set_target_properties(${name} PROPERTIES LINKER_LANGUAGE CXX) if (ARG_NB_SHARED AND ARG_NB_STATIC) message(FATAL_ERROR "NB_SHARED and NB_STATIC cannot be specified at the same time!") elseif (NOT ARG_NB_SHARED) set(ARG_NB_STATIC TRUE) endif() # Stable ABI builds require CPython >= 3.12 and Python::SABIModule if ((Python_VERSION VERSION_LESS 3.12) OR (NOT Python_INTERPRETER_ID STREQUAL "Python") OR (NOT TARGET Python::SABIModule)) set(ARG_STABLE_ABI FALSE) endif() if (NB_ABI MATCHES "t") set(ARG_STABLE_ABI FALSE) else(ARG_STABLE_ABI) set(ARG_FREE_THREADED FALSE) endif() set(libname "nanobind") if (ARG_NB_STATIC) set(libname "${libname}-static") endif() if (ARG_STABLE_ABI) set(libname "${libname}-abi3") endif() if (ARG_FREE_THREADED) set(libname "${libname}-ft") endif() if (ARG_NB_DOMAIN AND ARG_NB_SHARED) set(libname ${libname}-${ARG_NB_DOMAIN}) endif() if (ARG_NB_SUPPRESS_WARNINGS) set(EXTRA_LIBRARY_PARAMS AS_SYSINCLUDE) endif() nanobind_build_library(${libname} ${EXTRA_LIBRARY_PARAMS}) if (ARG_NB_DOMAIN) target_compile_definitions(${name} PRIVATE NB_DOMAIN=${ARG_NB_DOMAIN}) endif() if (ARG_STABLE_ABI) target_compile_definitions(${libname} PUBLIC -DPy_LIMITED_API=0x030C0000) nanobind_extension_abi3(${name}) else() nanobind_extension(${name}) endif() if (ARG_FREE_THREADED) target_compile_definitions(${name} PRIVATE NB_FREE_THREADED) endif() target_link_libraries(${name} PRIVATE ${libname}) if (NOT ARG_PROTECT_STACK) nanobind_disable_stack_protector(${name}) endif() if (NOT ARG_NOMINSIZE) nanobind_opt_size(${name}) endif() if (NOT ARG_NOSTRIP) nanobind_strip(${name}) endif() if (ARG_LTO) nanobind_lto(${name}) endif() if (ARG_NB_STATIC AND NOT ARG_MUSL_DYNAMIC_LIBCPP) nanobind_musl_static_libcpp(${name}) endif() nanobind_set_visibility(${name}) endfunction() function (nanobind_add_stub name) cmake_parse_arguments(PARSE_ARGV 1 ARG "VERBOSE;INCLUDE_PRIVATE;EXCLUDE_DOCSTRINGS;INSTALL_TIME;EXCLUDE_FROM_ALL" "MODULE;OUTPUT;MARKER_FILE;COMPONENT;PATTERN_FILE" "PYTHON_PATH;DEPENDS") if (EXISTS ${NB_DIR}/src/stubgen.py) set(NB_STUBGEN "${NB_DIR}/src/stubgen.py") elseif (EXISTS ${NB_DIR}/stubgen.py) set(NB_STUBGEN "${NB_DIR}/stubgen.py") else() message(FATAL_ERROR "nanobind_add_stub(): could not locate 'stubgen.py'!") endif() if (NOT ARG_VERBOSE) list(APPEND NB_STUBGEN_ARGS -q) else() set(NB_STUBGEN_EXTRA USES_TERMINAL) endif() if (ARG_INCLUDE_PRIVATE) list(APPEND NB_STUBGEN_ARGS -P) endif() if (ARG_EXCLUDE_DOCSTRINGS) list(APPEND NB_STUBGEN_ARGS -D) endif() foreach (TMP IN LISTS ARG_PYTHON_PATH) list(APPEND NB_STUBGEN_ARGS -i "${TMP}") endforeach() if (ARG_PATTERN_FILE) list(APPEND NB_STUBGEN_ARGS -p "${ARG_PATTERN_FILE}") endif() if (ARG_MARKER_FILE) list(APPEND NB_STUBGEN_ARGS -M "${ARG_MARKER_FILE}") list(APPEND NB_STUBGEN_OUTPUTS "${ARG_MARKER_FILE}") endif() if (NOT ARG_MODULE) message(FATAL_ERROR "nanobind_add_stub(): a 'MODULE' argument must be specified!") else() list(APPEND NB_STUBGEN_ARGS -m "${ARG_MODULE}") endif() if (NOT ARG_OUTPUT) message(FATAL_ERROR "nanobind_add_stub(): an 'OUTPUT' argument must be specified!") else() list(APPEND NB_STUBGEN_ARGS -o "${ARG_OUTPUT}") list(APPEND NB_STUBGEN_OUTPUTS "${ARG_OUTPUT}") endif() file(TO_CMAKE_PATH ${Python_EXECUTABLE} NB_Python_EXECUTABLE) set(NB_STUBGEN_CMD "${NB_Python_EXECUTABLE}" "${NB_STUBGEN}" ${NB_STUBGEN_ARGS}) if (NOT ARG_INSTALL_TIME) add_custom_command( OUTPUT ${NB_STUBGEN_OUTPUTS} COMMAND ${NB_STUBGEN_CMD} WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" DEPENDS ${ARG_DEPENDS} "${NB_STUBGEN}" "${ARG_PATTERN_FILE}" ${NB_STUBGEN_EXTRA} ) add_custom_target(${name} ALL DEPENDS ${NB_STUBGEN_OUTPUTS}) else() set(NB_STUBGEN_EXTRA "") if (ARG_COMPONENT) list(APPEND NB_STUBGEN_EXTRA COMPONENT ${ARG_COMPONENT}) endif() if (ARG_EXCLUDE_FROM_ALL) list(APPEND NB_STUBGEN_EXTRA EXCLUDE_FROM_ALL) endif() # \${CMAKE_INSTALL_PREFIX} has same effect as $ # This is for compatibility with CMake < 3.27. # For more info: https://github.com/wjakob/nanobind/issues/420#issuecomment-1971353531 install(CODE "set(CMD \"${NB_STUBGEN_CMD}\")\nexecute_process(\n COMMAND \$\{CMD\}\n WORKING_DIRECTORY \"\${CMAKE_INSTALL_PREFIX}\"\n)" ${NB_STUBGEN_EXTRA}) endif() endfunction() wjakob-nanobind-6c4457b/docs/000077500000000000000000000000001474760012700160555ustar00rootroot00000000000000wjakob-nanobind-6c4457b/docs/api_bazel.rst000066400000000000000000000115431474760012700205410ustar00rootroot00000000000000.. _api_bazel: Bazel API Reference (3rd party) =============================== This page contains a reference of the basic APIs of `nanobind-bazel `__. .. _rules-bazel: Rules ----- nanobind-bazel's rules can be used to declare different types of targets in your Bazel project. Each of these rules is a thin wrapper around a corresponding builtin Bazel rule producing the equivalent C++ target. The main tool to build nanobind extensions is the ``nanobind_extension`` rule. .. py:function:: nanobind_extension Declares a Bazel target representing a nanobind extension, which contains the Python bindings of your C++ code. .. code-block:: python def nanobind_extension( name, domain = "", srcs = [], copts = [], deps = [], local_defines = [], **kwargs): It corresponds directly to the builtin `cc_binary `__ rule, with all keyword arguments being directly forwarded to a ``cc_binary`` target. The ``domain`` argument can be used to build the target extension under a different ABI domain, as described in the :ref:`FAQ ` section. To generate typing stubs for an extension, you can use the ``nanobind_stubgen`` rule. .. py:function:: nanobind_stubgen Declares a Bazel target for generating a stub file from a previously built nanobind bindings extension. .. code-block:: python def nanobind_stubgen( name, module, output_file = None, imports = [], pattern_file = None, marker_file = None, include_private_members = False, exclude_docstrings = False): It generates a `py_binary `__ rule with a corresponding runfiles distribution, which invokes nanobind's builtin stubgen script, outputs a stub file and, optionally, a typing marker file into the build output directory (commonly called "bindir" in Bazel terms). All arguments (except the name, which is used only to refer to the target in Bazel) correspond directly to nanobind's stubgen command line interface, which is described in more detail in the :ref:`typing documentation `. *New in nanobind-bazel version 2.1.0.* To build a C++ library with nanobind as a dependency, use the ``nanobind_library`` rule. .. py:function:: nanobind_library Declares a Bazel target representing a C++ library depending on nanobind. .. code-block:: python def nanobind_library( name, copts = [], deps = [], **kwargs): It corresponds directly to the builtin `cc_library `__ rule, with all keyword arguments being directly forwarded to a ``cc_library`` target. To build a C++ shared library with nanobind as a dependency, use the ``nanobind_shared_library`` rule. .. py:function:: nanobind_shared_library Declares a Bazel target representing a C++ shared library depending on nanobind. .. code-block:: python def nanobind_shared_library( name, deps = [], **kwargs): It corresponds directly to the builtin `cc_shared_library `__ rule, with all keyword arguments being directly forwarded to a ``cc_shared_library`` target. *New in nanobind-bazel version 2.1.0.* To build a C++ test target requiring nanobind, use the ``nanobind_test`` rule. .. py:function:: nanobind_test Declares a Bazel target representing a C++ test depending on nanobind. .. code-block:: python def nanobind_test( name, copts = [], deps = [], **kwargs): It corresponds directly to the builtin `cc_test `__ rule, with all keyword arguments being directly forwarded to a ``cc_test`` target. .. _flags-bazel: Flags ----- To customize some of nanobind's build options, nanobind-bazel exposes the following flag settings. .. py:function:: @nanobind_bazel//:minsize (boolean) Apply nanobind's size optimizations to the built extensions. Size optimizations are turned on by default, similarly to the CMake build. To turn off size optimizations, you can use the shorthand notation ``--no@nanobind_bazel//:minsize``. .. py:function:: @nanobind_bazel//:py-limited-api (string) Build nanobind extensions against the stable ABI of the configured Python version. Allowed values are ``"cp312"``, ``"cp313"``, which target the stable ABI starting from Python 3.12 or 3.13, respectively. By default, all extensions are built without any ABI limitations. wjakob-nanobind-6c4457b/docs/api_cmake.rst000066400000000000000000000500741474760012700205260ustar00rootroot00000000000000.. _api_cmake: CMake API Reference =================== nanobind's CMake API simplifies the process of building python extension modules. This is needed because quite a few steps are involved: nanobind must build the module, a library component, link the two together, and add a different set of compilation and linker flags depending on the target platform. If you prefer another build system, then you have the following options: - `Nicholas Junge `__ has created a `Bazel interface `__ to nanobind. Please report Bazel-specific issues there. - `Will Ayd `__ has created a `Meson WrapDB package `__ for nanobind. Please report Meson-specific issues on the `Meson WrapDB `__ repository. - You could create a new build system from scratch that takes care of these steps. See `this file `__ for inspiration on how to do this on Linux. Note that you will be on your own if you choose to go this route---I unfortunately do not have the time to respond to GitHub tickets related to custom build systems. The section on :ref:`building extensions ` provided an introductory example of how to set up a basic build system via the :cmake:command:`nanobind_add_module` command, which is the :ref:`high level ` build interface. The defaults chosen by this function are somewhat opinionated, however. For this reason, nanobind also provides an alternative :ref:`low level ` interface that decomposes it into smaller steps. A later part of this section explains how a Git submodule dependency can be :ref:`avoided ` in exchange for a system-provided package. Finally, the section ends with an explanation of the CMake convenience interface for :ref:`stub generation `. .. _highlevel-cmake: High-level interface -------------------- The high-level interface consists of just one CMake command: .. cmake:command:: nanobind_add_module Compile a nanobind extension module using the specified target name, optional flags, and source code files. Use it as follows: .. code-block:: cmake nanobind_add_module( my_ext # Target name NB_STATIC STABLE_ABI LTO # Optional flags (see below) my_ext.h # Source code files below my_ext.cpp) It supports the following optional parameters: .. list-table:: * - ``STABLE_ABI`` - Perform a `stable ABI `__ build, making it possible to use a compiled extension across Python minor versions. The flag is ignored on Python versions older than < 3.12. * - ``FREE_THREADED`` - Compile an Python extension that opts into free-threaded (i.e., GIL-less) Python behavior, which requires a special free-threaded build of Python 3.13 or newer. The flag is ignored on unsupported Python versions. * - ``NB_STATIC`` - Compile the core nanobind library as a static library. This simplifies redistribution but can increase the combined binary storage footprint when a project contains many Python extensions (this is the default). * - ``NB_SHARED`` - The opposite of ``NB_STATIC``: compile the core nanobind library as a shared library for use in projects that consist of multiple extensions. * - ``NB_SUPPRESS_WARNINGS`` - Mark the include directories of nanobind and Python as [SYSTEM](https://cmake.org/cmake/help/latest/command/include_directories.html) include directories, which suppresses any potential warning messages originating there. This is mainly of relevance if your project artificially raises the warning level via flags like `-pedantic`, ``-Wcast-qual``, ``-Wsign-conversion``. * - ``PROTECT_STACK`` - Don't remove stack smashing-related protections. * - ``LTO`` - Perform link time optimization. * - ``NOMINSIZE`` - Don't perform optimizations to minimize binary size. * - ``NOSTRIP`` - Don't strip unneded symbols and debug information from the compiled extension when performing release builds. * - ``NB_DOMAIN `` - Restrict the inter-extension type visibility to a named subdomain. See the associated :ref:`FAQ entry ` for details. * - ``MUSL_DYNAMIC_LIBCPP`` - When `cibuildwheel `__ is used to produce `musllinux `__ wheels, don't statically link against ``libstdc++`` and ``libgcc`` (which is an optimization that nanobind does by default in this specific case). If this explanation sounds confusing, then you can ignore it. See the detailed description below for more information on this step. :cmake:command:`nanobind_add_module` performs the following steps to produce bindings. - It creates a CMake library via ``add_library(target_name MODULE ...)`` and enables the use of C++17 features during compilation. - It creates a CMake target for an internal library component required by nanobind (named ``nanobind-..`` where ``..`` depends on the compilation flags). This is only done once when compiling multiple extensions. This library component can either be a static or shared library depending on whether the optional ``NB_STATIC`` or ``NB_SHARED`` parameter was provided to ``nanobind_add_module()``. The default is a static build, which simplifies redistribution (only one shared library must be deployed). When a project contains many Python extensions, a shared build is preferable to avoid unnecessary binary size overheads that arise from redundant copies of the ``nanobind-...`` component. - It links the newly created library against the ``nanobind-..`` target. - It appends the library suffix (e.g., ``.cpython-39-darwin.so``) based on information provided by CMake’s ``FindPython`` module. - When requested via the optional ``STABLE_ABI`` parameter, the build system will create a `stable ABI `_ extension module with a different suffix (e.g., ``.abi3.so``). Once compiled, a stable ABI extension can be reused across Python minor versions. In contrast, ordinary builds are only compatible across patch versions. This feature requires Python >= 3.12 and is ignored on older versions. Note that use of the stable ABI come at a small performance cost since nanobind can no longer access the internals of various data structures directly. If in doubt, benchmark your code to see if the cost is acceptable. - In non-debug modes, it compiles with *size optimizations* (i.e., ``-Os``). This is generally the mode that you will want to use for C++/Python bindings. Switching to ``-O3`` would enable further optimizations like vectorization, loop unrolling, etc., but these all increase compilation time and binary size with no real benefit for bindings. If your project contains portions that benefit from ``-O3``-level optimizations, then it’s better to run two separate compilation steps. An example is shown below: .. code:: cmake # Compile project code with current optimization mode configured in CMake add_library(example_lib STATIC source_1.cpp source_2.cpp) # Need position independent code (-fPIC) to link into 'example_ext' below set_target_properties(example_lib PROPERTIES POSITION_INDEPENDENT_CODE ON) # Compile extension module with size optimization and add 'example_lib' nanobind_add_module(example_ext common.h source_1.cpp source_2.cpp) target_link_libraries(example_ext PRIVATE example_lib) Size optimizations can be disabled by specifying the optional ``NOMINSIZE`` argument, though doing so is not recommended. - ``nanobind_add_module()`` also disables stack-smashing protections (i.e., it specifies ``-fno-stack-protector`` to Clang/GCC). Protecting against such vulnerabilities in a Python VM seems futile, and it adds non-negligible extra cost (+8% binary size in benchmarks). This behavior can be disabled by specifying the optional ``PROTECT_STACK`` flag. Either way, is not recommended that you use nanobind in a setting where it presents an attack surface. - It sets the default symbol visibility to ``hidden`` so that only functions and types specifically marked for export generate symbols in the resulting binary. This substantially reduces the size of the generated binary. - In release builds, it strips unreferenced functions and debug information names from the resulting binary. This can substantially reduce the size of the generated binary and can be disabled using the optional ``NOSTRIP`` argument. - Link-time optimization (LTO) is *not active* by default; benefits compared to pybind11 are relatively low, and this can make linking a build bottleneck. That said, the optional ``LTO`` argument can be specified to enable LTO in release builds. - nanobind's CMake build system is often combined with `cibuildwheel `__ to automate the generation of wheels for many different platforms. One such platform called `musllinux `__ exists to create tiny self-contained binaries that are cheap to install in a container environment (Docker, etc.). An issue of the combination with nanobind is that ``musllinux`` doesn't include the ``libstdc++`` and ``libgcc`` libraries which nanobind depends on. ``cibuildwheel`` then has to ship those along in each wheel, which actually increases their size rather dramatically (by a factor of >5x for small projects). To avoid this, nanobind prefers to link against these libraries *statically* when it detects a ``cibuildwheel`` build targeting ``musllinux``. Pass the ``MUSL_DYNAMIC_LIBCPP`` parameter to avoid this behavior. - If desired (via the optional ``NB_DOMAIN`` parameter), nanobind will restrict the visibility of symbols to a named subdomain to avoid conflicts between bindings. See the associated :ref:`FAQ entry ` for details. .. _lowlevel-cmake: Low-level interface ------------------- Instead of :cmake:command:`nanobind_add_module` nanobind also exposes a more fine-grained interface to the underlying operations. The following .. code-block:: cmake nanobind_add_module(my_ext NB_SHARED LTO my_ext.cpp) is equivalent to .. code-block:: cmake # Build the core parts of nanobind once nanobind_build_library(nanobind SHARED) # Compile an extension library add_library(my_ext MODULE my_ext.cpp) # .. and link it against the nanobind parts target_link_libraries(my_ext PRIVATE nanobind) # .. enable size optimizations nanobind_opt_size(my_ext) # .. enable link time optimization nanobind_lto(my_ext) # .. set the default symbol visibility to 'hidden' nanobind_set_visibility(my_ext) # .. strip unneeded symbols and debug info from the binary (only active in release builds) nanobind_strip(my_ext) # .. disable the stack protector nanobind_disable_stack_protector(my_ext) # .. set the Python extension suffix nanobind_extension(my_ext) # .. set important compilation flags nanobind_compile_options(my_ext) # .. set important linker flags nanobind_link_options(my_ext) # Statically link against libstdc++/libgcc when targeting musllinux nanobind_musl_static_libcpp(my_ext) The various commands are described below: .. cmake:command:: nanobind_build_library Compile the core nanobind library. The function expects only the target name and uses a slightly unusual parameter passing policy: its behavior changes based on whether or not one the following substrings is detected in the target name: .. list-table:: :widths: 10 50 * - ``-static`` - Perform a static library build (without this suffix, a shared build is used) * - ``-abi3`` - Perform a stable ABI build targeting Python v3.12+. * - ``-ft`` - Perform a build that opts into the Python 3.13+ free-threaded behavior. .. code-block:: cmake # Normal shared library build nanobind_build_library(nanobind) # Static ABI3 build nanobind_build_library(nanobind-static-abi3) .. cmake:command:: nanobind_opt_size This function enable size optimizations in ``Release``, ``MinSizeRel``, ``RelWithDebInfo`` builds. It expects a single target as argument, as in .. code-block:: cmake nanobind_opt_size(my_target) .. cmake:command:: nanobind_set_visibility This function sets the default symbol visibility to ``hidden`` so that only functions and types specifically marked for export generate symbols in the resulting binary. It expects a single target as argument, as in .. code-block:: cmake nanobind_trim(my_target) This substantially reduces the size of the generated binary. .. cmake:command:: nanobind_strip This function strips unused and debug symbols in ``Release`` and ``MinSizeRel`` builds on Linux and macOS. It expects a single target as argument, as in .. code-block:: cmake nanobind_strip(my_target) .. cmake:command:: nanobind_disable_stack_protector The stack protector affects the binary size of bindings negatively (+8% on Linux in benchmarks). Protecting from stack smashing in a Python VM seems in any case futile, so this function disables it for the specified target when performing a build with optimizations. Use it as follows: .. code-block:: cmake nanobind_disable_stack_protector(my_target) .. cmake:command:: nanobind_extension This function assigns an extension name to the compiled binding, e.g., ``.cpython-311-darwin.so``. Use it as follows: .. code-block:: cmake nanobind_extension(my_target) .. cmake:command:: nanobind_extension_abi3 This function assigns a stable ABI extension name to the compiled binding, e.g., ``.abi3.so``. Use it as follows: .. code-block:: cmake nanobind_extension_abi3(my_target) .. cmake:command:: nanobind_compile_options This function sets recommended compilation flags. Currently, it specifies ``/bigobj`` and ``/MP`` on MSVC builds, and it does nothing other platforms or compilers. Use it as follows: .. code-block:: cmake nanobind_compile_options(my_target) .. cmake:command:: nanobind_link_options This function sets recommended linker flags. Currently, it controls link time handling of undefined symbols on Apple platforms related to Python C API calls, and it does nothing other platforms. Use it as follows: .. code-block:: cmake nanobind_link_options(my_target) .. cmake:command:: nanobind_musl_static_libcpp This function passes the linker flags ``-static-libstdc++`` and ``-static-libgcc`` to ``gcc`` when the environment variable ``AUDITWHEEL_PLAT`` contains the string ``musllinux``, which indicates a cibuildwheel build targeting that platform. The function expects a single target as argument, as in .. code-block:: cmake nanobind_musl_static_libcpp(my_target) .. _submodule_deps: Submodule dependencies ---------------------- nanobind includes a dependency (a fast hash map named ``tsl::robin_map``) as a Git submodule. If you prefer to use another (e.g., system-provided) version of this dependency, set the ``NB_USE_SUBMODULE_DEPS`` variable before importing nanobind into CMake. In this case, nanobind's CMake scripts will internally invoke ``find_dependency(tsl-robin-map)`` to locate the associated header files. .. _stub_generation_cmake: Stub generation --------------- Nanobind's CMake tooling includes a convenience command to interface with the ``stubgen`` program explained in the section on :ref:`stub generation `. .. cmake:command:: nanobind_add_stub Import the specified module (``MODULE`` parameter), generate a stub, and write it to the specified file (``OUTPUT`` parameter). Here is an example use: .. code-block:: cmake nanobind_add_stub( my_ext_stub MODULE my_ext OUTPUT my_ext.pyi PYTHON_PATH $ DEPENDS my_ext ) The target name (``my_ext_stub`` in this example) must be unique but has no other significance. ``stubgen`` will add all paths specified as part of the ``PYTHON_PATH`` block and then execute ``import my_ext`` in a Python session. If the extension is not importable, this will cause stub generation to fail. This command supports the following parameters: .. list-table:: * - ``INSTALL_TIME`` - By default, stub generation takes place at build time following generation of all dependencies (see ``DEPENDS``). When this parameter is specified, stub generation is instead postponed to the installation phase. * - ``MODULE`` - Specifies the name of the module that should be imported. Mandatory. * - ``OUTPUT`` - Specifies the name of the stub file that should be written. The path is relative to ``CMAKE_CURRENT_BINARY_DIR`` for build-time stub generation and relative to ``CMAKE_INSTALL_PREFIX`` for install-time stub generation. Mandatory. * - ``PYTHON_PATH`` - List of search paths that should be considered when importing the module. The paths are relative to ``CMAKE_CURRENT_BINARY_DIR`` for build-time stub generation and relative to ``CMAKE_INSTALL_PREFIX`` for install-time stub generation. The current directory (``"."``) is always included and does not need to be specified. The parameter may contain CMake `generator expressions `__ when :cmake:command:`nanobind_add_stub` is used for build-time stub generation. Otherwise, generator expressions should not be used. Optional. * - ``DEPENDS`` - Any targets listed here will be marked as a dependencies. This should generally be used to list the target names of one or more prior :cmake:command:`nanobind_add_module` declarations. Note that this parameter tracks *build-time* dependencies and does not need to be specified when stub generation occurs at install time (see ``INSTALL_TIME``). Optional. * - ``VERBOSE`` - Show status messages generated by ``stubgen``. * - ``EXCLUDE_DOCSTRINGS`` - Generate a stub containing only typed signatures without docstrings. * - ``INCLUDE_PRIVATE`` - Also include private members, whose names begin or end with a single underscore. * - ``MARKER_FILE`` - Typed extensions normally identify themselves via the presence of an empty file named ``py.typed`` in each module directory. When this parameter is specified, :cmake:command:`nanobind_add_stub` will automatically generate such an empty file as well. * - ``PATTERN_FILE`` - Specify a pattern file used to replace declarations in the stub. The syntax is described in the section on :ref:`stub generation `. * - ``COMPONENT`` - Specify a component when ``INSTALL_TIME`` stub generation is used. This is analogous to ``install(..., COMPONENT [name])`` in other install targets. * - ``EXCLUDE_FROM_ALL`` - If specified, the file is only installed as part of a component-specific installation when ``INSTALL_TIME`` stub generation is used. This is analogous to ``install(..., EXCLUDE_FROM_ALL)`` in other install targets. wjakob-nanobind-6c4457b/docs/api_core.rst000066400000000000000000003556221474760012700204050ustar00rootroot00000000000000.. _api: .. cpp:namespace:: nanobind C++ API Reference (Core) ======================== Macros ------ .. c:macro:: NB_MODULE(name, variable) This macro creates the entry point that will be invoked when the Python interpreter imports an extension module. The module name is given as the first argument and it should not be in quotes. It **must** match the module name given to the :cmake:command:`nanobind_add_module()` function in the CMake build system. The second macro argument defines a variable of type :cpp:class:`module_`. The body of the declaration typically contains a sequence of operations that populate the module variable with contents. .. code-block:: cpp NB_MODULE(example, m) { m.doc() = "Example module"; // Add bindings here m.def("add", []() { return "Hello, World!"; }); } .. c:macro:: NB_MAKE_OPAQUE(T) The macro registers a partial template specialization pattern for the type `T` that marks it as *opaque*, meaning that nanobind won't try to run its type casting template machinery on it. This is useful when trying to register a binding for `T` that is simultaneously also covered by an existing type caster. This macro should be used at the top level (outside of namespaces and program code). Python object API ----------------- Nanobind ships with a wide range of Python wrapper classes like :cpp:class:`object`, :cpp:class:`list`, etc. Besides class-specific operations (e.g., :cpp:func:`list::append`), these classes also implement core operations that can be performed on *any* Python object. Since it would be tedious to implement this functionality over and over again, it is realized by the following mixin class that lives in the ``nanobind::detail`` namespace. .. cpp:namespace:: nanobind::detail .. cpp:class:: template api This mixin class adds common functionality to various nanobind types using the `curiously recurring template pattern `_ (CRTP). The only requirement for the `Derived` template parameter is that it implements the member function ``PyObject *ptr() const`` that gives access to the underlying Python object pointer. .. cpp:function:: Derived &derived() Obtain a mutable reference to the derived class. .. cpp:function:: const Derived &derived() const Obtain a const reference to the derived class. .. cpp:function:: handle inc_ref() const Increases the reference count and returns a reference to the Python object. .. cpp:function:: handle dec_ref() const Decreases the reference count and returns a reference to the Python object. .. cpp:function:: iterator begin() const Return a forward iterator analogous to ``iter()`` in Python. The object must be a collection that supports the iteration protocol. This interface provides a generic iterator that works any type of Python object. The :cpp:class:`tuple`, :cpp:class:`list`, and :cpp:class:`dict` wrappers provide more efficient specialized alternatives. .. cpp:function:: iterator end() const Return a sentinel that ends the iteration. .. cpp:function:: handle type() const Return a :cpp:class:`handle` to the underlying Python type object. .. cpp:function:: operator handle() const Return a :cpp:class:`handle` wrapping the underlying ``PyObject*`` pointer. .. cpp:function:: detail::accessor attr(handle key) const Analogous to ``self.key`` in Python, where ``key`` is a Python object. The result is wrapped in an :cpp:class:`accessor ` so that it can be read and written. .. cpp:function:: detail::accessor attr(const char * key) const Analogous to ``self.key`` in Python, where ``key`` is a C-style string. The result is wrapped in an :cpp:class:`accessor ` so that it can be read and written. .. cpp:function:: detail::accessor doc() const Analogous to ``self.__doc__``. The result is wrapped in an :cpp:class:`accessor ` so that it can be read and written. .. cpp:function:: detail::accessor operator[](handle key) const Analogous to ``self[key]`` in Python, where ``key`` is a Python object. The result is wrapped in an :cpp:class:`accessor ` so that it can be read and written. .. cpp:function:: detail::accessor operator[](const char * key) const Analogous to ``self[key]`` in Python, where ``key`` is a C-style string. The result is wrapped in an :cpp:class:`accessor ` so that it can be read and written. .. cpp:function:: template > = 1> detail::accessor operator[](T key) const Analogous to ``self[key]`` in Python, where ``key`` is an arithmetic type (e.g., an integer). The result is wrapped in an :cpp:class:`accessor ` so that it can be read and written. .. cpp:function:: template object operator()(Args &&...args) const Assuming the Python object is a function or implements the ``__call__`` protocol, `operator()` invokes the underlying function, passing an arbitrary set of parameters, while expanding any detected variable length argument and keyword argument packs. The result is returned as an :cpp:class:`object` and may need to be converted back into a Python object using :cpp:func:`cast()`. Type conversion is performed using the return value policy `policy` When type conversion of arguments or return value fails, the function raises a :cpp:type:`cast_error`. When the Python function call fails, it instead raises a :cpp:class:`python_error`. .. cpp:function:: args_proxy operator*() const Given a a tuple or list, this helper function performs variable argument list unpacking in function calls resembling the ``*`` operator in Python. Applying `operator*()` twice yields ``**`` keyword argument unpacking for dictionaries. .. cpp:function:: bool is(handle value) const Analogous to ``self is value`` in Python. .. cpp:function:: bool is_none() const Analogous to ``self is None`` in Python. .. cpp:function:: bool is_type() const Analogous to ``isinstance(self, type)`` in Python. .. cpp:function:: bool is_valid() const Checks if this wrapper contains a valid Python object (in the sense that the ``PyObject *`` pointer is non-null). .. cpp:function:: template bool equal(const api &other) Equivalent to ``self == other`` in Python. .. cpp:function:: template bool not_equal(const api &other) Equivalent to ``self != other`` in Python. .. cpp:function:: template bool operator<(const api &other) Equivalent to ``self < other`` in Python. .. cpp:function:: template bool operator<=(const api &other) Equivalent to ``self <= other`` in Python. .. cpp:function:: template bool operator>(const api &other) Equivalent to ``self > other`` in Python. .. cpp:function:: template bool operator>=(const api &other) Equivalent to ``self >= other`` in Python. .. cpp:function:: object operator-() Equivalent to ``-self`` in Python. .. cpp:function:: object operator~() Equivalent to ``~self`` in Python. .. cpp:function:: template object operator+(const api &other) Equivalent to ``self + other`` in Python. .. cpp:function:: template object operator-(const api &other) Equivalent to ``self - other`` in Python. .. cpp:function:: template object operator*(const api &other) Equivalent to ``self * other`` in Python. .. cpp:function:: template object operator/(const api &other) Equivalent to ``self / other`` in Python. .. cpp:function:: template object floor_div(const api &other) Equivalent to ``self // other`` in Python. .. cpp:function:: template object operator|(const api &other) Equivalent to ``self | other`` in Python. .. cpp:function:: template object operator&(const api &other) Equivalent to ``self & other`` in Python. .. cpp:function:: template object operator^(const api &other) Equivalent to ``self ^ other`` in Python. .. cpp:function:: template object operator<<(const api &other) Equivalent to ``self << other`` in Python. .. cpp:function:: template object operator>>(const api &other) Equivalent to ``self >> other`` in Python. .. cpp:function:: template object operator+=(const api &other) Equivalent to ``self += other`` in Python. Note that the `api` version of the in-place operator does not update the ``self`` reference, which may lead to unexpected results when working with immutable types that return their result instead of updating ``self``. The :cpp:class:`object` class and subclasses override the in-place operators to achieve more intuitive behavior. .. cpp:function:: template object operator-=(const api &other) Equivalent to ``self -= other`` in Python. See :cpp:func:`operator+=` for limitations. .. cpp:function:: template object operator*=(const api &other) Equivalent to ``self *= other`` in Python. See :cpp:func:`operator+=` for limitations. .. cpp:function:: template object operator/=(const api &other) Equivalent to ``self /= other`` in Python. See :cpp:func:`operator+=` for limitations. .. cpp:function:: template object operator|=(const api &other) Equivalent to ``self |= other`` in Python. See :cpp:func:`operator+=` for limitations. .. cpp:function:: template object operator&=(const api &other) Equivalent to ``self &= other`` in Python. See :cpp:func:`operator+=` for limitations. .. cpp:function:: template object operator^=(const api &other) Equivalent to ``self ^= other`` in Python. See :cpp:func:`operator+=` for limitations. .. cpp:function:: template object operator<<=(const api &other) Equivalent to ``self <<= other`` in Python. See :cpp:func:`operator+=` for limitations. .. cpp:function:: template object operator>>=(const api &other) Equivalent to ``self >>= other`` in Python. See :cpp:func:`operator+=` for limitations. .. cpp:class:: template accessor This helper class facilitates attribute and item access. Casting an :cpp:class:`accessor` to a :cpp:class:`handle` or :cpp:class:`object` subclass causes a corresponding call to ``__getitem__`` or ``__getattr__`` depending on the template argument `Impl`. Assigning a :cpp:class:`handle` or :cpp:class:`object` subclass causes a call to ``__setitem__`` or ``__setattr__``. .. cpp:namespace:: nanobind Handles and objects ------------------- nanobind provides two styles of Python object wrappers: classes without reference counting deriving from :cpp:class:`handle`, and reference-counted wrappers deriving from :cpp:class:`object`. Reference counting bugs can be really tricky to track down, hence it is recommended that you always prefer :cpp:class:`object`-style wrappers unless there are specific reasons that warrant the use of raw handles. Without reference counting ^^^^^^^^^^^^^^^^^^^^^^^^^^ .. cpp:class:: handle: public detail::api This class provides a thin wrapper around a raw ``PyObject *`` pointer. Its main purpose is to intercept various C++ operations and convert them into Python C API calls. It does *not* do any reference counting and can be somewhat unsafe to use. .. cpp:function:: handle() = default Default constructor. Creates an invalid handle wrapping a null pointer. (:cpp:func:`detail::api::is_valid()` is ``false``) .. cpp:function:: handle(const handle &) = default Default copy constructor. .. cpp:function:: handle(handle &&) = default Default move constructor. .. cpp:function:: handle(const PyObject * o) Initialize a handle from a Python object pointer. Does not change the reference count of `o`. .. cpp:function:: handle(const PyTypeObject * o) Initialize a handle from a Python type object pointer. Does not change the reference count of `o`. .. cpp:function:: handle &operator=(const handle &) = default Default copy assignment operator. .. cpp:function:: handle &operator=(handle &&) = default Default move assignment operator. .. cpp:function:: explicit operator bool() const Check if the handle refers to a valid Python object. Equivalent to :cpp:func:`detail::api::is_valid()` .. cpp:function:: handle inc_ref() const noexcept Increases the reference count and returns a reference to the Python object. Never raises an exception. .. cpp:function:: handle dec_ref() const noexcept Decreases the reference count and returns a reference to the Python object. Never raises an exception. .. cpp:function:: PyObject * ptr() const Return the underlying ``PyObject*`` pointer. With reference counting ^^^^^^^^^^^^^^^^^^^^^^^ .. cpp:class:: object: public handle This class provides a convenient `RAII `_ wrapper around a ``PyObject*`` pointer. Like :cpp:class:`handle`, it intercepts various C++ operations and converts them into Python C API calls. The main difference to :cpp:class:`handle` is that it uses reference counting to keep the underlying Python object alive. Use the :cpp:func:`borrow()` and :cpp:func:`steal()` functions to create an :cpp:class:`object` from a :cpp:class:`handle` or ``PyObject*`` pointer. .. cpp:function:: object() = default Default constructor. Creates an invalid object wrapping a null pointer. (:cpp:func:`detail::api::is_valid()` is ``false``) .. cpp:function:: object(object &&o) Move constructor. Steals the object from `o` without changing its reference count. .. cpp:function:: object(const object &o) Copy constructor. Acquires a new reference to `o` (if valid). .. cpp:function:: ~object() Decrease the reference count of the referenced Python object (if valid). .. cpp:function:: object& operator=(object &&o) Move assignment operator. Decreases the reference count of the currently held object (if valid) and steals the object from `o` without changing its reference count. .. cpp:function:: object& operator=(const object &o) Copy assignment operator. Decreases the reference count of the currently held object (if valid) and acquires a new reference to the object `o` (if valid). .. cpp:function:: void reset() Decreases the reference count of the currently held object (if valid) and resets the internal pointer to ``nullptr``. .. cpp:function:: handle release() Resets the internal pointer to ``nullptr`` and returns its previous contents as a :cpp:class:`handle`. This operation does not change the object's reference count and should be used carefully. .. cpp:function:: template object& operator+=(const api &other) Equivalent to ``self += other`` in Python. .. cpp:function:: template object& operator-=(const api &other) Equivalent to ``self -= other`` in Python. .. cpp:function:: template object& operator*=(const api &other) Equivalent to ``self *= other`` in Python. .. cpp:function:: template object& operator/=(const api &other) Equivalent to ``self /= other`` in Python. .. cpp:function:: template object& operator|=(const api &other) Equivalent to ``self |= other`` in Python. .. cpp:function:: template object& operator&=(const api &other) Equivalent to ``self &= other`` in Python. .. cpp:function:: template object& operator^=(const api &other) Equivalent to ``self ^= other`` in Python. .. cpp:function:: template object& operator<<=(const api &other) Equivalent to ``self <<= other`` in Python. .. cpp:function:: template object& operator>>=(const api &other) Equivalent to ``self >>= other`` in Python. .. cpp:function:: template T borrow(handle h) Create a reference-counted Python object wrapper of type `T` from a raw handle or ``PyObject *`` pointer. The target type `T` must be :cpp:class:`object` (the default) or one of its derived classes. The function does not perform any conversions or checks---it is up to the user to make sure that the target type is correct. The function *borrows* a reference, which means that it will increase the reference count while constructing ``T``. For example, consider the Python C API function `PyList_GetItem() `_, whose documentation states that it returns a borrowed reference. An interface between this API and nanobind could look as follows: .. code-block:: cpp PyObject* list = ...; Py_ssize_t index = ...; nb::object o = nb::borrow(PyList_GetItem(list, index)); Using :cpp:func:`steal()` in this setting is incorrect and would lead to a reference underflow. .. cpp:function:: template T steal(handle h) Create a reference-counted Python object wrapper of type `T` from a raw handle or ``PyObject *`` pointer. The target type `T` must be :cpp:class:`object` (the default) or one of its derived classes. The function does not perform any conversions or checks---it is up to the user to make sure that the target type is correct. The function *steals* a reference, which means that constructing ``T`` leaves the object's reference count unchanged. For example, consider the Python C API function `PyObject_Str() `_, whose documentation states that it returns a *new reference*. An interface between this API and nanobind could look as follows: .. code-block:: cpp PyObject* value = ...; nb::object o = nb::steal(PyObject_Str(value)); Using :cpp:func:`borrow()` in this setting is incorrect and would lead to a reference leak. Attribute access ---------------- .. cpp:function:: bool hasattr(handle h, const char * key) noexcept Check if the given object has an attribute string ``key``. The function never raises an exception and returns ``false`` in case of an internal error. Equivalent to ``hasattr(h, key)`` in Python. .. cpp:function:: bool hasattr(handle h, handle key) noexcept Check if the given object has a attribute represented by the Python object ``key``. The function never raises an exception and returns ``false`` in case of an internal error. Equivalent to ``hasattr(h, key)`` in Python. .. cpp:function:: object getattr(handle h, const char * key) Equivalent to ``h.key`` and ``getattr(h, key)`` in Python. Raises :cpp:class:`python_error` if the operation fails. .. cpp:function:: object getattr(handle h, handle key) Equivalent to ``h.key`` and ``getattr(h, key)`` in Python. Raises :cpp:class:`python_error` if the operation fails. .. cpp:function:: object getattr(handle h, const char * key, handle def) noexcept Equivalent to ``getattr(h, key, def)`` in Python. Never raises an exception and returns ``def`` when the operation fails, or when the desired attribute could not be found. .. cpp:function:: object getattr(handle h, handle key, handle def) noexcept Equivalent to ``getattr(h, key, def)`` in Python. Never raises an exception and returns ``def`` when the operation fails, or when the desired attribute could not be found. .. cpp:function:: void setattr(handle h, const char * key, handle value) Equivalent to ``h.key = value`` and ``setattr(h, key, value)`` in Python. Raises :cpp:class:`python_error` if the operation fails. .. cpp:function:: void setattr(handle h, handle key, handle value) Equivalent to ``h.key = value`` and ``setattr(h, key, value)`` in Python. Raises :cpp:class:`python_error` if the operation fails. .. cpp:function:: void delattr(handle h, const char * key) Equivalent to ``del h.key`` and ``delattr(h, key)`` in Python. Raises :cpp:class:`python_error` if the operation fails. .. cpp:function:: void delattr(handle h, handle key) Equivalent to ``del h.key`` and ``delattr(h, key)`` in Python. Raises :cpp:class:`python_error` if the operation fails. .. cpp:function:: template void del(detail::accessor &) Remove an element from a sequence or mapping. The C++ statement .. code-block:: cpp nb::del(o[key]); is equivalent to ``del o[key]`` in Python. When the element cannot be removed, the function will raise :cpp:class:`python_error` wrapping either a Python ``IndexError`` (for sequence types) or a ``KeyError`` (for mapping types). .. cpp:function:: template void del(detail::accessor &&) Rvalue equivalent of the above expression. Size queries ------------ .. cpp:function:: size_t len(handle h) Equivalent to ``len(h)`` in Python. Raises :cpp:class:`python_error` if the operation fails. .. cpp:function:: size_t len(const tuple &t) Equivalent to ``len(t)`` in Python. Optimized variant for tuples. .. cpp:function:: size_t len(const list &l) Equivalent to ``len(l)`` in Python. Optimized variant for lists. .. cpp:function:: size_t len(const dict &d) Equivalent to ``len(d)`` in Python. Optimized variant for dictionaries. .. cpp:function:: size_t len(const set &d) Equivalent to ``len(d)`` in Python. Optimized variant for sets. .. cpp:function:: size_t len_hint(handle h) Equivalent to ``operator.length_hint(h)`` in Python. Raises :cpp:class:`python_error` if the operation fails. Type queries ------------ .. cpp:function:: template isinstance(handle h) Checks if the Python object `h` represents a valid instance of the C++ type `T`. This works for bound C++ classes, basic types (``int``, ``bool``, etc.), and Python type wrappers ( :cpp:class:`list`, :cpp:class:`dict`, :cpp:class:`module_`, etc.). *Note*: the check even works when `T` involves a type caster (e.g., an STL types like ``std::vector``). However, this involve a wasteful attempt to convert the object to C++. It may be more efficient to just perform the conversion using :cpp:func:`cast` and catch potential raised exceptions. .. cpp:function:: isinstance(handle inst, handle cls) Checks if the Python object `inst` is an instance of the Python type `cls`. .. cpp:function:: template handle type() noexcept Returns the Python type object associated with the C++ type `T`. When the type not been bound via nanobind, the function returns an invalid handle (:cpp:func:`detail::api::is_valid()` is ``false``). *Note*: in contrast to the :cpp:func:`isinstance()` function above, builtin types, type wrappers, and types handled using type casters, are *not* supported. Wrapper classes --------------- .. cpp:class:: tuple: public object Wrapper class representing Python ``tuple`` instances. Use the standard ``operator[]`` C++ operator with an integer argument to read tuple elements (the bindings for this operator are provided by the parent class and not listed here). Once created, the set is immutable and its elements cannot be replaced. Use the :py:func:`make_tuple` function to create new tuples. .. cpp:function:: tuple() Create an empty tuple .. cpp:function:: tuple(handle h) Attempt to convert a given Python object into a tuple. Analogous to the expression ``tuple(h)`` in Python. .. cpp:function:: size_t size() const Return the number of tuple elements. .. cpp:function:: detail::fast_iterator begin() const Return a forward iterator analogous to ``iter()`` in Python. The function overrides a generic version in :cpp:class:`detail::api` and is more efficient for tuples. .. cpp:function:: detail::fast_iterator end() const Return a sentinel that ends the iteration. .. cpp:function:: template > = 1> detail::accessor operator[](T key) const Analogous to ``self[key]`` in Python, where ``key`` is an arithmetic type (e.g., an integer). The result is wrapped in an :cpp:class:`accessor ` so that it can be read and converted. Write access is not possible. The function overrides the generic version in :cpp:class:`detail::api` and is more efficient for tuples. .. cpp:class:: list : public object Wrapper class representing Python ``list`` instances. Use the standard ``operator[]`` C++ operator with an integer argument to read and write list elements (the bindings for this operator are provided by the parent class and not listed here). Use the :cpp:func:`nb::del ` function to remove elements. .. cpp:function:: list() Create an empty list .. cpp:function:: list(handle h) Attempt to convert a given Python object into a list. Analogous to the expression ``list(h)`` in Python. .. cpp:function:: size_t size() const Return the number of list elements. .. cpp:function:: template void append(T&& value) Append an element to the list. When `T` does not already represent a wrapped Python object, the function performs a cast. .. cpp:function:: template void insert(Py_ssize_t index, T&& value) Insert an element to the list (at index ``index``, which may also be negative). When `T` does not already represent a wrapped Python object, the function performs a cast. .. cpp:function:: void clear() Clear the list entries. .. cpp:function:: void extend(handle h) Analogous to the ``.extend(h)`` method of ``list`` in Python. .. cpp:function:: void sort() Analogous to the ``.sort()`` method of ``list`` in Python. .. cpp:function:: void reverse() Analogous to the ``.reverse()`` method of ``list`` in Python. .. cpp:function:: template > = 1> detail::accessor operator[](T key) const Analogous to ``self[key]`` in Python, where ``key`` is an arithmetic type (e.g., an integer). The result is wrapped in an :cpp:class:`accessor ` so that it can be read and written. The function overrides the generic version in :cpp:class:`detail::api` and is more efficient for lists. .. cpp:function:: detail::fast_iterator begin() const Return a forward iterator analogous to ``iter()`` in Python. The operator provided here overrides the generic version in :cpp:class:`detail::api` and is more efficient for lists. .. cpp:function:: detail::fast_iterator end() const Return a sentinel that ends the iteration. .. cpp:class:: dict: public object Wrapper class representing Python ``dict`` instances. Use the standard ``operator[]`` C++ operator to read and write dictionary elements (the bindings for this operator are provided by the parent class and not listed here). Use the :cpp:func:`nb::del ` function to remove elements. .. cpp:function:: dict() Create an empty dictionary .. cpp:function:: size_t size() const Return the number of dictionary elements. .. cpp:function:: template bool contains(T&& key) const Check whether the dictionary contains a particular key. When `T` does not already represent a wrapped Python object, the function performs a cast. .. cpp:function:: detail::dict_iterator begin() const Return an item iterator that returns ``std::pair`` key-value pairs analogous to ``iter(dict.items())`` in Python. In free-threaded Python, the :cpp:class:``detail::dict_iterator`` class acquires a lock to the underlying dictionary to enable the use of the efficient but thread-unsafe ``PyDict_Next()`` Python C traversal routine. .. cpp:function:: detail::dict_iterator end() const Return a sentinel that ends the iteration. .. cpp:function:: list keys() const Return a list containing all dictionary keys. .. cpp:function:: list values() const Return a list containing all dictionary values. .. cpp:function:: list items() const Return a list containing all dictionary items as ``(key, value)`` pairs. .. cpp:function:: void clear() Clear the contents of the dictionary. .. cpp:function:: void update(handle h) Analogous to the ``.update(h)`` method of ``dict`` in Python. .. cpp:class:: set: public object Wrapper class representing Python ``set`` instances. .. cpp:function:: set() Create an empty set .. cpp:function:: set(handle h) Attempt to convert a given Python object into a set. Analogous to the expression ``set(h)`` in Python. .. cpp:function:: size_t size() const Return the number of set elements. .. cpp:function:: template void add(T&& key) Add a key to the set. When `T` does not already represent a wrapped Python object, the function performs a cast. .. cpp:function:: template bool contains(T&& key) const Check whether the set contains a particular key. When `T` does not already represent a wrapped Python object, the function performs a cast. .. cpp:function:: void clear() Clear the contents of the set. .. cpp:function:: template bool discard(T&& key) Analogous to the ``.discard(h)`` method of the ``set`` type in Python. Returns ``true`` if the item was deleted successfully, and ``false`` if the value was not present. When `T` does not already represent a wrapped Python object, the function performs a cast. .. cpp:class:: module_: public object Wrapper class representing Python ``module`` instances. The underscore at the end disambiguates the class name from the C++20 ``module`` declaration. .. cpp:function:: template module_ &def(const char * name, Func &&f, const Extra &...extra) Bind the function `f` to the identifier `name` within the module. Returns a reference to ``*this`` so that longer sequences of binding declarations can be chained, as in ``m.def(...).def(...);``. The variable length `extra` parameter can be used to pass docstrings and other :ref:`function binding annotations `. Example syntax: .. code-block:: cpp void test() { printf("Hello world!"); } NB_MODULE(example, m) { // here, "m" is variable of type 'module_'. m.def("test", &test, "A test function") .def(...); // more binding declarations } .. cpp:function:: module_ import_(const char * name) Import the Python module with the specified name and return a reference to it. The underscore at the end disambiguates the function name from the C++20 ``import`` statement. Example usage: .. code-block:: cpp nb::module_ np = nb::module_::import_("numpy"); nb::object np_array = np.attr("array"); .. cpp:function:: module_ import_(handle name) Import the Python module with the specified name and return a reference to it. In contrast to the version above, this function expects a Python object as key. .. cpp:function:: module_ def_submodule(const char * name, const char * doc = nullptr) Create a Python submodule within an existing module and return a reference to it. Can be chained recursively. Example usage: .. code-block:: cpp NB_MODULE(example, m) { nb::module_ m2 = m.def_submodule("sub", "A submodule of 'example'"); nb::module_ m3 = m2.def_submodule("subsub", "A submodule of 'example.sub'"); } .. cpp:class:: capsule: public object Capsules are small opaque Python objects that wrap a C or C++ pointer and a cleanup routine. .. cpp:function:: capsule(const void * ptr, void (* cleanup)(void*) noexcept = nullptr) Construct an *unnamed* capsule wrapping the pointer `p`. When the capsule is garbage collected, Python will call the destructor `cleanup` (if provided) with the value of `p`. .. cpp:function:: capsule(const void * ptr, const char * name, void (* cleanup)(void*) noexcept = nullptr) Construct a *named* capsule with name `name` wrapping the pointer `p`. When the capsule is garbage collected, Python will call the destructor `cleanup` (if provided) with the value of `p`. .. cpp:function:: const char * name() const Return the capsule name (or ``nullptr`` when the capsule is unnamed) .. cpp:function:: void * data() const Return the pointer wrapped by the capsule. .. cpp:class:: bool_: public object This wrapper class represents Python ``bool`` instances. .. cpp:function:: bool_(handle h) Performs a boolean cast within Python. This is equivalent to the Python expression ``bool(h)``. .. cpp:function:: explicit bool_(bool value) Convert an C++ boolean instance into a Python ``bool``. .. cpp:function:: explicit operator bool() const Extract the boolean value underlying this object. .. cpp:class:: int_: public object This wrapper class represents Python ``int`` instances. It can handle large numbers requiring more than 64 bits of storage. .. cpp:function:: int_(handle h) Performs an integer cast within Python. This is equivalent to the Python expression ``int(h)``. .. cpp:function:: template > = 0> explicit int_(T value) Convert an C++ arithmetic type into a Python integer. .. cpp:function:: template > = 0> explicit operator T() const Convert a Python integer into a C++ arithmetic type. .. cpp:class:: float_: public object This wrapper class represents Python ``float`` instances. .. cpp:function:: float_(handle h) Performs an floating point cast within Python. This is equivalent to the Python expression ``float(h)``. .. cpp:function:: explicit float_(double value) Convert an C++ double value into a Python float objecct .. cpp:function:: explicit operator double() const Convert a Python float object into a C++ double value .. cpp:class:: str: public object This wrapper class represents Python unicode ``str`` instances. .. cpp:function:: str(handle h) Performs a string cast within Python. This is equivalent equivalent to the Python expression ``str(h)``. .. cpp:function:: str(const char * s) Convert a null-terminated C-style string in UTF-8 encoding into a Python string. .. cpp:function:: str(const char * s, size_t n) Convert a C-style string in UTF-8 encoding of length ``n`` bytes into a Python string. .. cpp:function:: const char * c_str() const Convert a Python string into a null-terminated C-style string with UTF-8 encoding. *Note*: The C string will be deleted when the `str` instance is garbage collected. .. cpp:function:: template str format(Args&&... args) C++ analog of the Python routine ``str.format``. Can be called with positional and keyword arguments. .. cpp:class:: bytes: public object This wrapper class represents Python unicode ``bytes`` instances. .. cpp:function:: bytes(handle h) Performs a cast within Python. This is equivalent to the Python expression ``bytes(h)``. .. cpp:function:: bytes(const char * s) Convert a null-terminated C-style string encoding into a Python ``bytes`` object. .. cpp:function:: bytes(const void * buf, size_t n) Convert a byte buffer ``buf`` of length ``n`` bytes into a Python ``bytes`` object. The buffer can contain embedded null bytes. .. cpp:function:: const char * c_str() const Convert a Python bytes object into a null-terminated C-style string. .. cpp:function:: size_t size() const Return the size in bytes. .. cpp:function:: const void * data() const Convert a Python ``bytes`` object into a byte buffer of length :cpp:func:`bytes::size()` bytes. .. cpp:class:: bytearray: public object This wrapper class represents Python ``bytearray`` instances. .. cpp:function:: bytearray() Create an empty ``bytearray``. .. cpp:function:: bytearray(handle h) Performs a cast within Python. This is equivalent to the Python expression ``bytearray(h)``. .. cpp:function:: bytearray(const void * buf, size_t n) Convert a byte buffer ``buf`` of length ``n`` bytes into a Python ``bytearray`` object. The buffer can contain embedded null bytes. .. cpp:function:: const char * c_str() const Convert a Python ``bytearray`` object into a null-terminated C-style string. .. cpp:function:: size_t size() const Return the size in bytes. .. cpp:function:: void * data() Convert a Python ``bytearray`` object into a byte buffer of length :cpp:func:`bytearray::size()` bytes. .. cpp:function:: const void * data() const Convert a Python ``bytearray`` object into a byte buffer of length :cpp:func:`bytearray::size()` bytes. .. cpp:function:: void resize(size_t n) Resize the internal buffer of a Python ``bytearray`` object to ``n``. Any space added by this method, which calls `PyByteArray_Resize`, will not be initialized and may contain random data. .. cpp:class:: type_object: public object Wrapper class representing Python ``type`` instances. .. cpp:class:: sequence: public object Wrapper class representing arbitrary Python sequence types. .. cpp:class:: mapping : public object Wrapper class representing arbitrary Python mapping types. .. cpp:function:: template bool contains(T&& key) const Check whether the map contains a particular key. When `T` does not already represent a wrapped Python object, the function performs a cast. .. cpp:function:: list keys() const Return a list containing all of the map's keys. .. cpp:function:: list values() const Return a list containing all of the map's values. .. cpp:function:: list items() const Return a list containing all of the map's items as ``(key, value)`` pairs. .. cpp:class:: iterator : public object Wrapper class representing a Python iterator. .. cpp:function:: iterator& operator++() Advance to the next element (pre-increment form). .. cpp:function:: iterator& operator++(int) Advance to the next element (post-increment form). .. cpp:function:: handle operator*() const Return the item at the current position. .. cpp:function:: handle operator->() const Convenience routine for pointer-style access. .. static iterator sentinel(); Return a sentinel that ends the iteration. .. cpp:function:: friend bool operator==(const iterator &a, const iterator &b); Iterator equality comparison operator. .. cpp:function:: friend bool operator!=(const iterator &a, const iterator &b); Iterator inequality comparison operator. .. cpp:class:: iterable : public object Wrapper class representing an object that can be iterated upon (in the sense that calling :cpp:func:`iter()` is valid). .. cpp:class:: slice : public object Wrapper class representing a Python slice object. .. cpp:function:: slice(handle start, handle stop, handle step) Create the slice object given by ``slice(start, stop, step)`` in Python. .. cpp:function:: template > = 0> slice(T stop) Create the slice object ``slice(stop)``, where `stop` is represented by a C++ integer type. .. cpp:function:: template > = 0> slice(T start, T stop) Create the slice object ``slice(start, stop)``, where `start` and `stop` are represented by a C++ integer type. .. cpp:function:: template > = 0> slice(T start, T stop, T step) Create the slice object ``slice(start, stop, step)``, where `start`, `stop`, and `step` are represented by a C++ integer type. .. cpp:function:: detail::tuple compute(size_t size) const Adjust the slice to the `size` value of a given container. Returns a tuple containing ``(start, stop, step, slice_length)``. .. cpp:class:: ellipsis: public object Wrapper class representing a Python ellipsis (``...``) object. .. cpp:function:: ellipsis() Create a wrapper referencing the unique Python ``Ellipsis`` object. .. cpp:class:: not_implemented: public object Wrapper class representing a Python ``NotImplemented`` object. .. cpp:function:: not_implemented() Create a wrapper referencing the unique Python ``NotImplemented`` object. .. cpp:class:: callable: public object Wrapper class representing a callable Python object. .. cpp:class:: weakref: public object Wrapper class representing a Python weak reference object. .. cpp:function:: explicit weakref(handle obj, handle callback = { }) Construct a new weak reference that points to `obj`. If provided, Python will invoke the callable `callback` when `obj` expires. .. cpp:class:: args : public tuple Variable argument keyword list for use in function argument declarations. .. cpp:class:: kwargs : public dict Variable keyword argument keyword list for use in function argument declarations. .. cpp:class:: any : public object This wrapper class represents Python ``typing.Any``-typed values. On the C++ end, this type is interchangeable with :py:class:`object`. The only difference is the type signature when used in function arguments and return values. Parameterized wrapper classes ----------------------------- .. cpp:class:: template handle_t : public handle Wrapper class representing a handle to a subclass of the C++ type `T`. It can be used to bind functions that take the associated Python object in its wrapped form, while rejecting objects with a different type (i.e., it is more discerning than :cpp:class:`handle`, which accepts *any* Python object). .. code-block:: cpp // Bind the class A class A { int value; }; nb::class_(m, "A"); // Bind a function that takes a Python object representing a 'A' instance m.def("process_a", [](nb::handle_t h) { PyObject * a_py = h.ptr(); // PyObject* pointer to wrapper A &a_cpp = nb::cast(h); // Reference to C++ instance }); .. cpp:class:: template type_object_t : public type_object Wrapper class representing a Python type object that is a subtype of the C++ type `T`. It can be used to bind functions that only accept type objects satisfying this criterion (i.e., it is more discerning than :cpp:class:`type_object`, which accepts *any* Python type object). Error management ---------------- nanobind provides a range of functionality to convert C++ exceptions into equivalent Python exceptions and raise captured Python error state in C++. The :cpp:class:`exception` class is also relevant in this context, but is listed in the reference section on :ref:`class binding `. .. cpp:struct:: error_scope RAII helper class that temporarily stashes any existing Python error status. This is important when running Python code in the context of an existing failure that must be processed (e.g., to generate an error message). .. cpp:function:: error_scope() Stash the current error status (if any) .. cpp:function:: ~error_scope() Restore the stashed error status (if any) .. cpp:struct:: python_error : public std::exception Exception that represents a detected Python error status. .. cpp:function:: python_error() This constructor may only be called when a Python error has occurred (``PyErr_Occurred()`` must be ``true``). It creates a C++ exception object that represents this error and clears the Python error status. .. cpp:function:: python_error(const python_error &) Copy constructor .. cpp:function:: python_error(python_error &&) noexcept Move constructor .. cpp:function:: const char * what() noexcept Return a stringified version of the exception. nanobind internally normalizes the exception and generates a traceback that is included as part of this string. This can be a relatively costly operation and should only be used if all of this detail is actually needed. .. cpp:function:: bool matches(handle exc) noexcept Checks whether the exception has the same type as `exc`. The argument to this function is usually one of the `Standard Exceptions `_. .. cpp:function:: void restore() noexcept Restore the error status in Python and clear the `python_error` contents. This may only be called once, and you should not reraise the `python_error` in C++ afterward. .. cpp:function:: void discard_as_unraisable(handle context) noexcept Pass the error to Python's :py:func:`sys.unraisablehook`, which prints a traceback to :py:data:`sys.stderr` by default but may be overridden. Like :cpp:func:`restore`, this consumes the error and you should not reraise the exception in C++ afterward. The *context* argument should be some object whose ``repr()`` helps identify the location of the error. The default :py:func:`sys.unraisablehook` prints a traceback that begins with the text ``Exception ignored in:`` followed by the result of ``repr(context)``. Example use case: handling a Python error that occurs in a C++ destructor where you cannot raise a C++ exception. .. cpp:function:: void discard_as_unraisable(const char * context) noexcept Convenience wrapper around the above function, which takes a C-style string for the ``context`` argument. .. cpp:function:: handle type() const Returns a handle to the exception type .. cpp:function:: handle value() const Returns a handle to the exception value .. cpp:function:: object traceback() const Returns a handle to the exception's traceback object .. cpp:class:: cast_error The function :cpp:func:`cast` raises this exception to indicate that a cast was unsuccessful. .. cpp:function:: cast_error() Constructor .. cpp:class:: next_overload Raising this special exception from a bound function informs nanobind that the function overload detected incompatible inputs. nanobind will then try other overloads before reporting a ``TypeError``. This feature is useful when a multiple overloads of a function accept overlapping or identical input types (e.g. :cpp:class:`object`) and must run code at runtime to select the right overload. You should probably write a thorough docstring that explicitly mentions the expected inputs in this case, since the behavior won't be obvious from the auto-generated function signature. It can be frustrating when a function call fails with an error message stating that the provided arguments aren't compatible with any overload, when the associated error message suggests otherwise. .. cpp:function:: next_overload() Constructor .. cpp:class:: builtin_exception : public std::runtime_error General-purpose class to propagate builtin Python exceptions from C++. A number of convenience functions (see below) instantiate it. .. cpp:function:: builtin_exception stop_iteration(const char * what = nullptr) Convenience wrapper to create a :cpp:class:`builtin_exception` C++ exception instance that nanobind will re-raise as a Python ``StopIteration`` exception when it crosses the C++ ↔ Python interface. .. cpp:function:: builtin_exception index_error(const char * what = nullptr) Convenience wrapper to create a :cpp:class:`builtin_exception` C++ exception instance that nanobind will re-raise as a Python ``IndexError`` exception when it crosses the C++ ↔ Python interface. .. cpp:function:: builtin_exception key_error(const char * what = nullptr) Convenience wrapper to create a :cpp:class:`builtin_exception` C++ exception instance that nanobind will re-raise as a Python ``KeyError`` exception when it crosses the C++ ↔ Python interface. .. cpp:function:: builtin_exception value_error(const char * what = nullptr) Convenience wrapper to create a :cpp:class:`builtin_exception` C++ exception instance that nanobind will re-raise as a Python ``ValueError`` exception when it crosses the C++ ↔ Python interface. .. cpp:function:: builtin_exception type_error(const char * what = nullptr) Convenience wrapper to create a :cpp:class:`builtin_exception` C++ exception instance that nanobind will re-raise as a Python ``TypeError`` exception when it crosses the C++ ↔ Python interface. .. cpp:function:: builtin_exception buffer_error(const char * what = nullptr) Convenience wrapper to create a :cpp:class:`builtin_exception` C++ exception instance that nanobind will re-raise as a Python ``BufferError`` exception when it crosses the C++ ↔ Python interface. .. cpp:function:: builtin_exception import_error(const char * what = nullptr) Convenience wrapper to create a :cpp:class:`builtin_exception` C++ exception instance that nanobind will re-raise as a Python ``ImportError`` exception when it crosses the C++ ↔ Python interface. .. cpp:function:: builtin_exception attribute_error(const char * what = nullptr) Convenience wrapper to create a :cpp:class:`builtin_exception` C++ exception instance that nanobind will re-raise as a Python ``AttributeError`` exception when it crosses the C++ ↔ Python interface. .. cpp:function:: void register_exception_translator(void (* exception_translator)(const std::exception_ptr &, void*), void * payload = nullptr) Install an exception translator callback that will be invoked whenever nanobind's function call dispatcher catches a previously unknown C++ exception. This exception translator should follow a standard structure of re-throwing an exception, catching a specific type, and converting this into a Python error status upon "success". Here is an example for a hypothetical ``ZeroDivisionException``. .. code-block:: cpp register_exception_translator( [](const std::exception_ptr &p, void * /*payload*/) { try { std::rethrow_exception(p); } catch (const ZeroDivisionException &e) { PyErr_SetString(PyExc_ZeroDivisionError, e.what()); } }, nullptr /*payload*/); Generally, you will want to use the more convenient exception binding interface provided by :cpp:class:`exception` class. This function provides an escape hatch for more specialized use cases. .. cpp:function:: void chain_error(handle type, const char * fmt, ...) noexcept Raise a Python error of type ``type`` using the format string ``fmt`` interpreted by ``PyErr_FormatV``. If a Python error state was already set prior to calling this method, then the new error is *chained* on top of the existing one. Otherwise, the function creates a new error without initializing its ``__cause__`` field. .. cpp:function:: void raise_from(python_error &e, handle type, const char * fmt, ...) Convenience wrapper around :cpp:func:`chain_error `. It takes an existing Python error (e.g. caught in a ``catch`` block) and creates an additional Python exception with the current error as cause. It then re-raises :cpp:class:`python_error`. The argument ``fmt`` is a ``printf``-style format string interpreted by ``PyErr_FormatV``. Usage of this function is explained in the documentation section on :ref:`exception chaining `. .. cpp:function:: void raise(const char * fmt, ...) This function takes a ``printf``-style format string with arguments and then raises a ``std::runtime_error`` with the formatted string. The function has no dependence on Python, and nanobind merely includes it for convenience. .. cpp:function:: void raise_type_error(const char * fmt, ...) This function is analogous to :cpp:func:`raise`, except that it raises a :cpp:class:`builtin_exception` that will convert into a Python ``TypeError`` when crossing the language interface. .. cpp:function:: void raise_python_error() This function should only be called if a Python error status was set by a prior operation, which should now be raised as a C++ exception. The function is analogous to the statement ``throw python_error();`` but compiles into more compact code. Casting ------- .. cpp:function:: template T cast(const detail::api &value, bool convert = true) Convert the Python object `value` (typically a :cpp:class:`handle` or a :cpp:class:`object` subclass) into a C++ object of type `T`. When the `convert` argument is set to ``true`` (the default), the implementation may also attempt *implicit conversions* to perform the cast. The function raises a :cpp:type:`cast_error` when the conversion fails. See :cpp:func:`try_cast()` for an alternative that never raises. .. cpp:function:: template bool try_cast(const detail::api &value, T &out, bool convert = true) noexcept Convert the Python object `value` (typically a :cpp:class:`handle` or a :cpp:class:`object` subclass) into a C++ object of type `T`, and store it in the output parameter `out`. When the `convert` argument is set to ``true`` (the default), the implementation may also attempt *implicit conversions* to perform the cast. The function returns ``false`` when the conversion fails. In this case, the `out` parameter is left untouched. See :cpp:func:`cast()` for an alternative that instead raises an exception in this case. .. cpp:function:: template object cast(T &&value, rv_policy policy = rv_policy::automatic_reference) Convert the C++ object ``value`` into a Python object. The return value policy `policy` is used to handle ownership-related questions when a new Python object must be created. The function raises a :cpp:type:`cast_error` when the conversion fails. .. cpp:function:: template object cast(T &&value, rv_policy policy, handle parent) Convert the C++ object ``value`` into a Python object. The return value policy `policy` is used to handle ownership-related questions when a new Python object must be created. A valid `parent` object is required when specifying a `reference_internal` return value policy. The function raises a :cpp:type:`cast_error` when the conversion fails. .. cpp:function:: template object find(const T &value) noexcept Return the Python object associated with the C++ instance `value`. When no such object can be found, the function it returns an invalid object (:cpp:func:`detail::api::is_valid()` is ``false``). .. cpp:function:: template tuple make_tuple(Args&&... args) Create a Python tuple from a sequence of C++ objects ``args...``. The return value policy `policy` is used to handle ownership-related questions when a new Python objects must be created. The function raises a :cpp:type:`cast_error` when the conversion fails. Common binding annotations -------------------------- The following annotations can be specified in both function and class bindings. .. cpp:struct:: scope .. cpp:function:: scope(handle value) Captures the Python scope (e.g., a :cpp:class:`module_` or :cpp:class:`type_object`) in which the function or class should be registered. .. _function_binding_annotations: Function binding annotations ---------------------------- The following annotations can be specified using the variable-length ``Extra`` parameter of :cpp:func:`module_::def`, :cpp:func:`class_::def`, :cpp:func:`cpp_function`, etc. .. cpp:struct:: name .. cpp:function:: name(const char * value) Specify this annotation to override the name of the function. nanobind will internally copy the string when creating a function binding, hence dynamically generated arguments with a limited lifetime are legal. .. cpp:struct:: arg Function argument annotation to enable keyword-based calling, default arguments, passing ``None``, and implicit conversion hints. Note that when a function argument should be annotated, you *must* specify annotations for all arguments of that function. Example use: .. code-block:: cpp m.def("add", [](int a, int b) { return a + b; }, nb::arg("a"), nb::arg("b")); It is usually convenient to add the following ``using`` declaration to your binding code. .. code-block:: cpp using namespace nb::literals; In this case, the argument annotations can be shortened: .. code-block:: cpp m.def("add", [](int a, int b) { return a + b; }, "a"_a, "b"_a); .. cpp:function:: explicit arg(const char * name = nullptr) Create a function argument annotation. The name is optional. .. cpp:function:: template arg_v operator=(T &&value) const Return an argument annotation that is like this one but also assigns a default value to the argument. The default will be converted into a Python object immediately, so its bindings must have already been defined. .. cpp:function:: arg &none(bool value = true) Set a flag noting that the function argument accepts ``None``. Can only be used for python wrapper types (e.g. :cpp:class:`handle`, :cpp:class:`int_`) and types that have been bound using :cpp:class:`class_`. You cannot use this to implement functions that accept null pointers to builtin C++ types like ``int *i = nullptr``. .. cpp:function:: arg &noconvert(bool value = true) Set a flag noting that implicit conversion should never be performed for this function argument. .. cpp:function:: arg &sig(const char * sig) Override the signature of the default argument value. This is useful when the argument value is unusually complex so that the default method to explain it in docstrings and stubs (``str(value)``) does not produce acceptable output. .. cpp:function:: arg_locked lock() Return an argument annotation that is like this one but also requests that this argument be locked when dispatching a function call in free-threaded Python extensions. It does nothing in regular GIL-protected extensions. .. cpp:struct:: is_method Indicate that the bound function is a method. .. cpp:struct:: is_operator Indicate that the bound operator represents a special double underscore method (``__add__``, ``__radd__``, etc.) that implements an arithmetic operation. When a bound functions with this annotation is called with incompatible arguments, it will return ``NotImplemented`` rather than raising a ``TypeError``. .. cpp:struct:: is_implicit Indicate that the bound constructor can be used to perform implicit conversions. .. cpp:struct:: lock_self Indicate that the implicit ``self`` argument of a method should be locked when dispatching a call in a free-threaded extension. This annotation does nothing in regular GIL-protected extensions. .. cpp:struct:: template call_guard Invoke the call guard(s) `Ts` when the bound function executes. The RAII helper :cpp:struct:`gil_scoped_release` is often combined with this feature. .. cpp:struct:: template keep_alive Following evaluation of the bound function, keep the object referenced by index ``Patient`` alive *as long as* the object with index ``Nurse`` exists. This uses the following indexing convention: - Index ``0`` refers to the return value of methods. It should not be used in constructors or functions that do not return a result. - Index ``1`` refers to the first argument. In methods and constructors, index ``1`` refers to the implicit ``this`` pointer, while regular arguments begin at index ``2``. The annotation has the following runtime characteristics: - It does nothing when the nurse or patient object are ``None``. - It raises an exception when the nurse object is neither weak-referenceable nor an instance of a binding created via :cpp:class:`nb::class_\<..\> `. Two additional caveats regarding :cpp:class:`keep_alive ` are noteworthy: - It *usually* doesn't make sense to specify a ``Nurse`` or ``Patient`` for an argument or return value handled by a :ref:`type caster ` (e.g., a STL vector handled via the include directive ``#include ``). That's because type casters copy-convert the Python object into an equivalent C++ object, whose lifetime is decoupled from the original Python object. However, the :cpp:class:`keep_alive ` annotation *only* affects the lifetime of Python objects *and not their C++ copy*. - Dispatching a Python → C++ function call may require the :ref:`implicit conversion ` of function arguments. In this case, the objects passed to the C++ function differ from the originally specified arguments. The ``Nurse`` and ``Patient`` annotation always refer to the *final* object following implicit conversion. .. cpp:struct:: sig .. cpp:function:: sig(const char * value) This is *both* a class and a function binding annotation. 1. When used in functions bindings, it provides complete control over the function's type signature by replacing the automatically generated version with ``value``. You can use it to add or change arguments and return values, tweak how default values are rendered, and add custom decorators. Here is an example: .. code-block:: cpp nb::def("function_name", &function_name, nb::sig( "@decorator(decorator_args..)\n "def function_name(arg_1: type_1 = def_1, ...) -> ret" )); 2. When used in class bindings, the annotation enables complete control over how the class is rendered by nanobind's ``stubgen`` program. You can use it add decorators, specify ``typing.TypeVar``-parameterized base classes, metaclasses, etc. Here is an example: .. code-block:: cpp nb::class_(m, "Class", nb::sig( "@decorator(decorator_args..)\n" "class Class(Base1[T], Base2, meta=Meta)" )); Deviating significantly from the nanobind-generated signature likely means that the class or function declaration is a *lie*, but such lies can be useful to type-check complex binding projects. Specifying decorators isn't required---the above are just examples to show that this is possible. nanobind will internally copy the signature during function/type creation, hence dynamically generated strings with a limited lifetime are legal. The provided string should be valid Python signature, but *without* a trailing colon (``":"``) or trailing newline. Furthermore, nanobind analyzes the string and expects to find the name of the function or class on the *last line* between the ``"def"`` / ``"class"`` prefix and the opening parenthesis. For function bindings, this name must match the specified function name in ``.def("name", ..)``-style binding declarations, and for class bindings, the specified name must match the ``name`` argument of :cpp:class:`nb::class_ `. .. cpp:enum-class:: rv_policy A return value policy determines the question of *ownership* when a bound function returns a previously unknown C++ instance that must now be converted into a Python object. Return value policies apply to functions that return values handled using :ref:`class bindings `, which means that their Python equivalent was registered using :cpp:class:`class_\<...\> `. They are ignored in most other cases. One exception are STL types handled using :ref:`type casters ` (e.g. ``std::vector``), which contain a nested type ``T`` handled using class bindings. In this case, the return value policy also applies recursively. A return value policy is unnecessary when the type itself clarifies ownership (e.g., ``std::unique_ptr``, ``std::shared_ptr``, a type with :ref:`intrusive reference counting `). The following policies are available (where `automatic` is the default). Please refer to the :ref:`return value policy section ` of the main documentation, which clarifies the list below using concrete examples. .. cpp:enumerator:: take_ownership Create a Python object that wraps the existing C++ instance and takes full ownership of it. No copies are made. Python will call the C++ destructor and ``delete`` operator when the Python wrapper is garbage collected at some later point. The C++ side *must* relinquish ownership and is not allowed to destruct the instance, or undefined behavior will ensue. .. cpp:enumerator:: copy Copy-construct a new Python object from the C++ instance. The new copy will be owned by Python, while C++ retains ownership of the original. .. cpp:enumerator:: move Move-construct a new Python object from the C++ instance. The new object will be owned by Python, while C++ retains ownership of the original (whose contents were likely invalidated by the move operation). .. cpp:enumerator:: reference Create a Python object that wraps the existing C++ instance *without taking ownership* of it. No copies are made. Python will never call the destructor or ``delete`` operator, even when the Python wrapper is garbage collected. .. cpp:enumerator:: reference_internal A safe extension of the `reference` policy for methods that implement some form of attribute access. It creates a Python object that wraps the existing C++ instance *without taking ownership* of it. Additionally, it adjusts reference counts to keeps the method's implicit ``self`` argument alive until the newly created object has been garbage collected. .. cpp:enumerator:: none This is the most conservative policy: it simply refuses the cast unless the C++ instance already has a corresponding Python object, in which case the question of ownership becomes moot. .. cpp:enumerator:: automatic This is the default return value policy, which falls back to `take_ownership` when the return value is a pointer, `move` when it is a rvalue reference, and `copy` when it is a lvalue reference. .. cpp:enumerator:: automatic_reference This policy matches `automatic` but falls back to `reference` when the return value is a pointer. .. cpp:struct:: kw_only Indicate that all following function parameters are keyword-only. This may only be used if you supply an :cpp:struct:`arg` annotation for each parameters, because keyword-only parameters are useless if they don't have names. For example, if you write .. code-block:: cpp int some_func(int one, const char* two); m.def("some_func", &some_func, nb::arg("one"), nb::kw_only(), nb::arg("two")); then in Python you can write ``some_func(42, two="hi")``, or ``some_func(one=42, two="hi")``, but not ``some_func(42, "hi")``. Just like in Python, any parameters appearing after variadic :cpp:class:`*args ` are implicitly keyword-only. You don't need to include the :cpp:struct:`kw_only` annotation in this case, but if you do include it, it must be in the correct position: immediately after the :cpp:struct:`arg` annotation for the variadic :cpp:class:`*args ` parameter. .. cpp:struct:: template for_getter When defining a property with a getter and a setter, you can use this to only pass a function binding attribute to the getter part. An example is shown below. .. code-block:: cpp nb::class_(m, "MyClass") .def_prop_rw("value", &MyClass::value, nb::for_getter(nb::sig("def value(self, /) -> int")), nb::for_setter(nb::sig("def value(self, value: int, /) -> None")), nb::for_getter("docstring for getter"), nb::for_setter("docstring for setter")); .. cpp:struct:: template for_setter Analogous to :cpp:struct:`for_getter`, but for setters. .. cpp:struct:: template call_policy Request that custom logic be inserted around each call to the bound function, by calling ``Policy::precall(args, nargs, cleanup)`` before Python-to-C++ argument conversion, and ``Policy::postcall(args, nargs, ret)`` after C++-to-Python return value conversion. If multiple call policy annotations are provided for the same function, then their precall and postcall hooks will both execute left-to-right according to the order in which the annotations were specified when binding the function. The :cpp:struct:`nb::call_guard\() ` annotation should be preferred over ``call_policy`` unless the wrapper logic depends on the function arguments or return value. If both annotations are combined, then :cpp:struct:`nb::call_guard\() ` always executes on the "inside" (closest to the bound function, after argument conversions and before return value conversion) regardless of its position in the function annotations list. Your ``Policy`` class must define two static member functions: .. cpp:function:: static void precall(PyObject **args, size_t nargs, detail::cleanup_list *cleanup); A hook that will be invoked before calling the bound function. More precisely, it is called after any :ref:`argument locks ` have been obtained, but before the Python arguments are converted to C++ objects for the function call. This hook may access or modify the function arguments using the *args* array, which holds borrowed references in one-to-one correspondence with the C++ arguments of the bound function. If the bound function is a method, then ``args[0]`` is its *self* argument. *nargs* is the number of function arguments. It is actually passed as ``std::integral_constant()``, so you can match on that type if you want to do compile-time checks with it. The *cleanup* list may be used as it is used in type casters, to cause some Python object references to be released at some point after the bound function completes. (If the bound function is part of an overload set, the cleanup list isn't released until all overloads have been tried.) ``precall()`` may choose to throw a C++ exception. If it does, it will preempt execution of the bound function, and the exception will be treated as if the bound function had thrown it. .. cpp:function:: static void postcall(PyObject **args, size_t nargs, handle ret); A hook that will be invoked after calling the bound function and converting its return value to a Python object, but only if the bound function returned normally. *args* stores the Python object arguments, with the same semantics as in ``precall()``, except that arguments that participated in implicit conversions will have had their ``args[i]`` pointer updated to reflect the new Python object that the implicit conversion produced. *nargs* is the number of arguments, passed as a ``std::integral_constant`` in the same way as for ``precall()``. *ret* is the bound function's return value. If the bound function returned normally but its C++ return value could not be converted to a Python object, then ``postcall()`` will execute with *ret* set to null, and the Python error indicator might or might not be set to explain why. If the bound function did not return normally -- either because its Python object arguments couldn't be converted to the appropriate C++ types, or because the C++ function threw an exception -- then ``postcall()`` **will not execute**. If you need some cleanup logic to run even in such cases, your ``precall()`` can add a capsule object to the cleanup list; its destructor will run eventually, but with no promises as to when. A :cpp:struct:`nb::call_guard ` might be a better choice. ``postcall()`` may choose to throw a C++ exception. If it does, the result of the wrapped function will be destroyed, and the exception will be raised in its place, as if the bound function had thrown it just before returning. Here is an example policy to demonstrate. ``nb::call_policy>()`` behaves like :cpp:class:`nb::keep_alive\<0, I\>() `, except that the return value is a treated as a list of objects rather than a single one. .. code-block:: cpp template struct returns_references_to { static void precall(PyObject **, size_t, nb::detail::cleanup_list *) {} template static void postcall(PyObject **args, std::integral_constant, nb::handle ret) { static_assert(I > 0 && I < N, "I in returns_references_to must be in the " "range [1, number of C++ function arguments]"); if (!nb::isinstance(ret)) { throw std::runtime_error("return value should be a sequence"); } for (nb::handle nurse : ret) { nb::detail::keep_alive(nurse.ptr(), args[I]); } } }; For a more complex example (binding an object that uses trivially-copyable callbacks), see ``tests/test_callbacks.cpp`` in the nanobind source distribution. .. _class_binding_annotations: Class binding annotations ------------------------- The following annotations can be specified using the variable-length ``Extra`` parameter of the constructor :cpp:func:`class_::class_`. Besides the below options, also refer to the :cpp:class:`sig` which is usable in both function and class bindings. It can be used to override class declarations in generated :ref:`stubs `, .. cpp:struct:: is_final Indicate that a type cannot be subclassed. .. cpp:struct:: dynamic_attr Indicate that instances of a type require a Python dictionary to support the dynamic addition of attributes. .. cpp:struct:: is_weak_referenceable Indicate that instances of a type require a weak reference list so that they can be referenced by the Python ``weakref.*`` types. .. cpp:struct:: is_generic If present, nanobind will add a ``__class_getitem__`` function to the newly created type that permits constructing *parameterized* versions (e.g., ``MyType[int]``). The implementation of this function is equivalent to .. code-block:: python def __class_getitem__(cls, value): import types return types.GenericAlias(cls, value) See the section on :ref:`creating generic types ` for an example. This feature is only supported on Python 3.9+. Nanobind will ignore the attribute in Python 3.8 builds. .. cpp:struct:: template supplement Indicate that ``sizeof(T)`` bytes of memory should be set aside to store supplemental data in the type object. See :ref:`Supplemental type data ` for more information. .. cpp:struct:: type_slots .. cpp:function:: type_slots(PyType_Slot * value) nanobind uses the ``PyType_FromSpec`` Python C API interface to construct types. In certain advanced use cases, it may be helpful to append additional type slots during type construction. This class binding annotation can be used to accomplish this. The provided list should be followed by a zero-initialized ``PyType_Slot`` element. See :ref:`Customizing type creation ` for more information about this feature. .. cpp:struct:: template intrusive_ptr nanobind provides a custom interface for intrusive reference-counted C++ types that nicely integrate with Python reference counting. See the :ref:`separate section ` on this topic. This annotation marks a type as compatible with this interface. .. cpp:function:: intrusive_ptr(void (* set_self_py)(T*, PyObject*) noexcept) Declares a callback that will be invoked when a C++ instance is first cast into a Python object. .. _enum_binding_annotations: Enum binding annotations ------------------------ The following annotations can be specified using the variable-length ``Extra`` parameter of the constructor :cpp:func:`enum_::enum_`. .. cpp:struct:: is_arithmetic Indicate that the enumeration supports arithmetic operations. This enables both unary (``-``, ``~``, ``abs()``) and binary (``+``, ``-``, ``*``, ``//``, ``&``, ``|``, ``^``, ``<<``, ``>>``) operations with operands of either enumeration or numeric types. The result will be as if the operands were first converted to integers. (So ``Shape(2) + Shape(1) == 3`` and ``Shape(2) * 1.5 == 3.0``.) It is unspecified whether operations on mixed enum types (such as ``Shape.Circle + Color.Red``) are permissible. Passing this annotation changes the Python enumeration parent class to either :py:class:`enum.IntEnum` or :py:class:`enum.IntFlag`, depending on whether or not the flag enumeration attribute is also specified (see :cpp:class:`is_flag`). .. cpp:struct:: is_flag Indicate that the enumeration supports bit-wise operations. This enables the operators (``|``, ``&``, ``^``, and ``~``) with two enumerators as operands. The result has the same type as the operands, i.e., ``Shape(2) | Shape(1)`` will be equivalent to ``Shape(3)``. Passing this annotation changes the Python enumeration parent class to either :py:class:`enum.IntFlag` or :py:class:`enum.Flag`, depending on whether or not the enumeration is also marked to support arithmetic operations (see :cpp:class:`is_arithmetic`). Function binding ---------------- .. cpp:function:: object cpp_function(Func &&f, const Extra&... extra) Convert the function `f` into a Python callable. This function has a few overloads (not shown here) to separately deal with function/method pointers and lambda functions. The variable length `extra` parameter can be used to pass a docstring and other :ref:`function binding annotations `. .. _class_binding: Class binding ------------- .. cpp:class:: template class_ : public object Binding helper class to expose a custom C++ type `T` (declared using either the ``class`` or ``struct`` keyword) in Python. The variable length parameter `Ts` is optional and can be used to specify the base class of `T` and/or an alias needed to realize :ref:`trampoline classes `. When the type ``T`` was previously already registered (either within the same extension or another extension), the ``class_<..>`` declaration is redundant. nanobind will print a warning message in this case: .. code-block:: text RuntimeWarning: nanobind: type 'MyType' was already registered! The ``class_<..>`` instance will subsequently wrap the original type object instead of creating a new one. .. cpp:function:: template class_(handle scope, const char * name, const Extra &... extra) Bind the type `T` to the identifier `name` within the scope `scope`. The variable length `extra` parameter can be used to pass a docstring and other :ref:`class binding annotations `. .. cpp:function:: template class_ &def(const char * name, Func &&f, const Extra &... extra) Bind the function `f` and assign it to the class member `name`. The variable length `extra` parameter can be used to pass a docstring and other :ref:`function binding annotations `. This function has two overloads (listed just below) to handle constructor binding declarations. **Example**: .. code-block:: cpp struct A { void f() { /*...*/ } }; nb::class_(m, "A") .def(nb::init<>()) // Bind the default constructor .def("f", &A::f); // Bind the method A::f .. cpp:function:: template class_ &def(init arg, const Extra &... extra) Bind a constructor. The variable length `extra` parameter can be used to pass a docstring and other :ref:`function binding annotations `. .. cpp:function:: template class_ &def(init_implicit arg, const Extra &... extra) Bind a constructor that may be used for implicit type conversions. The constructor must take a single argument of an unspecified type `Arg`. When nanobind later tries to dispatch a function call requiring an argument of type `T` while `Arg` was actually provided, it will run this constructor to perform the necessary conversion. The variable length `extra` parameter can be used to pass a docstring and other :ref:`function binding annotations `. This constructor generates more compact code than a separate call to :cpp:func:`implicitly_convertible`, but is otherwise equivalent. .. cpp:function:: template class_ &def(new_ arg, const Extra &... extra) Bind a C++ factory function as a Python object constructor (``__new__``). This is an advanced feature; prefer :cpp:struct:`nb::init\<..\> ` where possible. See the discussion of :ref:`customizing object creation ` for more details. .. cpp:function:: template class_ &def(def_visitor arg, const Extra &... extra) Dispatch to custom user-provided binding logic implemented by the type ``Visitor``, passing it the binding annotations ``extra...``. See the documentation of :cpp:struct:`nb::def_visitor\<..\> ` for details. .. cpp:function:: template class_ &def_rw(const char * name, D C::* p, const Extra &...extra) Bind the field `p` and assign it to the class member `name`. nanobind constructs a ``property`` object with *read-write* access (hence the ``rw`` suffix) to do so. Every access from Python will read from or write to the C++ field while performing a suitable conversion (using :ref:`type casters `, :ref:`bindings `, or :ref:`wrappers `) as determined by its type. The variable length `extra` parameter can be used to pass a docstring and other :ref:`function binding annotations ` that are forwarded to the anonymous functions used to construct the property. Use the :cpp:struct:`nb::for_getter ` and :cpp:struct:`nb::for_setter ` to pass annotations specifically to the setter or getter part. **Example**: .. code-block:: cpp struct A { int value; }; nb::class_(m, "A") .def_rw("value", &A::value); // Enable mutable access to the field A::value .. cpp:function:: template class_ &def_ro(const char * name, D C::* p, const Extra &...extra) Bind the field `p` and assign it to the class member `name`. nanobind constructs a ``property`` object with *read only* access (hence the ``ro`` suffix) to do so. Every access from Python will read the C++ field while performing a suitable conversion (using :ref:`type casters `, :ref:`bindings `, or :ref:`wrappers `) as determined by its type. The variable length `extra` parameter can be used to pass a docstring and other :ref:`function binding annotations ` that are forwarded to the anonymous functions used to construct the property. **Example**: .. code-block:: cpp struct A { int value; }; nb::class_(m, "A") .def_ro("value", &A::value); // Enable read-only access to the field A::value .. cpp:function:: template class_ &def_prop_rw(const char * name, Getter &&getter, Setter &&setter, const Extra &...extra) Construct a *mutable* (hence the ``rw`` suffix) Python ``property`` and assign it to the class member `name`. Every read access will call the function ``getter`` with the `T` instance, and every write access will call the ``setter`` with the `T` instance and value to be assigned. The variable length `extra` parameter can be used to pass a docstring and other :ref:`function binding annotations `. Use the :cpp:struct:`nb::for_getter ` and :cpp:struct:`nb::for_setter ` to pass annotations specifically to the setter or getter part. Note that this function implicitly assigns the :cpp:enumerator:`rv_policy::reference_internal` return value policy to `getter` (as opposed to the usual :cpp:enumerator:`rv_policy::automatic`). Provide an explicit return value policy as part of the `extra` argument to override this. **Example**: the example below uses `def_prop_rw` to expose a C++ setter/getter pair as a more "Pythonic" property: .. code-block:: cpp class A { public: A(int value) : m_value(value) { } void set_value(int value) { m_value = value; } int value() const { return m_value; } private: int m_value; }; nb::class_(m, "A") .def(nb::init()) .def_prop_rw("value", [](A &t) { return t.value() ; }, [](A &t, int value) { t.set_value(value); }); .. cpp:function:: template class_ &def_prop_ro(const char * name, Getter &&getter, const Extra &...extra) Construct a *read-only* (hence the ``ro`` suffix) Python ``property`` and assign it to the class member `name`. Every read access will call the function ``getter`` with the `T` instance. The variable length `extra` parameter can be used to pass a docstring and other :ref:`function binding annotations `. Note that this function implicitly assigns the :cpp:enumerator:`rv_policy::reference_internal` return value policy to `getter` (as opposed to the usual :cpp:enumerator:`rv_policy::automatic`). Provide an explicit return value policy as part of the `extra` argument to override this. **Example**: the example below uses `def_prop_ro` to expose a C++ getter as a more "Pythonic" property: .. code-block:: cpp class A { public: A(int value) : m_value(value) { } int value() const { return m_value; } private: int m_value; }; nb::class_(m, "A") .def(nb::init()) .def_prop_ro("value", [](A &t) { return t.value() ; }); .. cpp:function:: template class_ &def_static(const char * name, Func &&f, const Extra &... extra) Bind the *static* function `f` and assign it to the class member `name`. The variable length `extra` parameter can be used to pass a docstring and other :ref:`function binding annotations `. **Example**: .. code-block:: cpp struct A { static void f() { /*...*/ } }; nb::class_(m, "A") .def_static("f", &A::f); // Bind the static method A::f .. cpp:function:: template class_ &def_rw_static(const char * name, D* p, const Extra &...extra) Bind the *static* field `p` and assign it to the class member `name`. nanobind constructs a class ``property`` object with *read-write* access (hence the ``rw`` suffix) to do so. Every access from Python will read from or write to the static C++ field while performing a suitable conversion (using :ref:`type casters `, :ref:`bindings `, or :ref:`wrappers `) as determined by its type. The variable length `extra` parameter can be used to pass a docstring and other :ref:`function binding annotations ` that are forwarded to the anonymous functions used to construct the property Use the :cpp:struct:`nb::for_getter ` and :cpp:struct:`nb::for_setter ` to pass annotations specifically to the setter or getter part. **Example**: .. code-block:: cpp struct A { inline static int value = 5; }; nb::class_(m, "A") // Enable mutable access to the static field A::value .def_rw_static("value", &A::value); .. cpp:function:: template class_ &def_ro_static(const char * name, D* p, const Extra &...extra) Bind the *static* field `p` and assign it to the class member `name`. nanobind constructs a class ``property`` object with *read-only* access (hence the ``ro`` suffix) to do so. Every access from Python will read the static C++ field while performing a suitable conversion (using :ref:`type casters `, :ref:`bindings `, or :ref:`wrappers `) as determined by its type. The variable length `extra` parameter can be used to pass a docstring and other :ref:`function binding annotations ` that are forwarded to the anonymous functions used to construct the property **Example**: .. code-block:: cpp struct A { inline static int value = 5; }; nb::class_(m, "A") // Enable read-only access to the static field A::value .def_ro_static("value", &A::value); .. cpp:function:: template class_ &def_prop_rw_static(const char * name, Getter &&getter, Setter &&setter, const Extra &...extra) Construct a *mutable* (hence the ``rw`` suffix) Python ``property`` and assign it to the class member `name`. Every read access will call the function ``getter`` with `T`'s Python type object, and every write access will call the ``setter`` with `T`'s Python type object and value to be assigned. The variable length `extra` parameter can be used to pass a docstring and other :ref:`function binding annotations `. Use the :cpp:struct:`nb::for_getter ` and :cpp:struct:`nb::for_setter ` to pass annotations specifically to the setter or getter part. Note that this function implicitly assigns the :cpp:enumerator:`rv_policy::reference` return value policy to `getter` (as opposed to the usual :cpp:enumerator:`rv_policy::automatic`). Provide an explicit return value policy as part of the `extra` argument to override this. **Example**: the example below uses `def_prop_rw_static` to expose a static C++ setter/getter pair as a more "Pythonic" property: .. code-block:: cpp class A { public: static void set_value(int value) { s_value = value; } static int value() { return s_value; } private: inline static int s_value = 5; }; nb::class_(m, "A") .def_prop_rw_static("value", [](nb::handle /*unused*/) { return A::value() ; }, [](nb::handle /*unused*/, int value) { A::set_value(value); }); .. cpp:function:: template class_ &def_prop_ro_static(const char * name, Getter &&getter, const Extra &...extra) Construct a *read-only* (hence the ``ro`` suffix) Python ``property`` and assign it to the class member `name`. Every read access will call the function ``getter`` with `T`'s Python type object. The variable length `extra` parameter can be used to pass a docstring and other :ref:`function binding annotations `. Note that this function implicitly assigns the :cpp:enumerator:`rv_policy::reference` return value policy to `getter` (as opposed to the usual :cpp:enumerator:`rv_policy::automatic`). Provide an explicit return value policy as part of the `extra` argument to override this. **Example**: the example below uses `def_prop_ro_static` to expose a static C++ getter as a more "Pythonic" property: .. code-block:: cpp class A { public: static int value() { return s_value; } private: inline static int s_value = 5; }; nb::class_(m, "A") .def_prop_ro_static("value", [](nb::handle /*unused*/) { return A::value() ; }); .. cpp:function:: template class_ &def(const detail::op_ &op, const Extra&... extra) This interface provides convenient syntax sugar to replace relatively lengthy method bindings with shorter operator bindings. To use it, you will need an extra include directive: .. code-block:: cpp #include Below is an example type with three arithmetic operators in C++ (unary negation and 2 binary subtraction overloads) along with corresponding bindings. **Example**: .. code-block:: cpp struct A { float value; A operator-() const { return { -value }; } A operator-(const A &o) const { return { value - o.value }; } A operator-(float o) const { return { value - o }; } }; nb::class_(m, "A") .def(nb::init()) .def(-nb::self) .def(nb::self - nb::self) .def(nb::self - float()); Bind an arithmetic or comparison operator expressed in short-hand form (e.g., ``.def(nb::self + nb::self)``). .. cpp:function:: template class_ &def_cast(const detail::op_ &op, const Extra&... extra) Like the above ``.def()`` variant, but furthermore cast the result of the operation back to `T`. .. cpp:class:: template enum_ : public class_ Class binding helper for scoped and unscoped C++ enumerations. .. cpp:function:: template NB_INLINE enum_(handle scope, const char * name, const Extra &...extra) Bind the enumeration of type `T` to the identifier `name` within the scope `scope`. The variable length `extra` parameter can be used to pass a docstring and other :ref:`enum binding annotations ` (currently, only :cpp:class:`is_arithmetic` is supported). .. cpp:function:: enum_ &value(const char * name, T value, const char * doc = nullptr) Add the entry `value` to the enumeration using the identifier `name`, potentially with a docstring provided via `doc` (optional). .. cpp:function:: enum_ &export_values() Export all entries of the enumeration into the parent scope. .. cpp:class:: template exception : public object Class binding helper for declaring new Python exception types .. cpp:function:: exception(handle scope, const char * name, handle base = PyExc_Exception) Create a new exception type identified by `name` that derives from `base`, and install it in `scope`. The constructor also calls :cpp:func:`register_exception_translator()` to register a new exception translator that converts caught C++ exceptions of type `T` into the newly created Python equivalent. .. cpp:struct:: template init nanobind uses this simple helper class to capture the signature of a constructor. It is only meant to be used in binding declarations done via :cpp:func:`class_::def()`. Sometimes, it is necessary to bind constructors that don't exist in the underlying C++ type (meaning that they are specific to the Python bindings). Because `init` only works for existing C++ constructors, this requires a manual workaround noting that .. code-block:: cpp nb::class_(m, "MyType") .def(nb::init()); is syntax sugar for the following lower-level implementation using "`placement new `_": .. code-block:: cpp nb::class_(m, "MyType") .def("__init__", [](MyType* t, const char* arg0, int arg1) { new (t) MyType(arg0, arg1); }); The provided lambda function will be called with a pointer to uninitialized memory that has already been allocated (this memory region is co-located with the Python object for reasons of efficiency). The lambda function can then either run an in-place constructor and return normally (in which case the instance is assumed to be correctly constructed) or fail by raising an exception. .. cpp:struct:: template init_implicit See :cpp:class:`init` for detail on binding constructors. The main difference between :cpp:class:`init` and `init_implicit` is that the latter only supports constructors taking a single argument `Arg`, and that it marks the constructor as usable for implicit conversions from `Arg`. Sometimes, it is necessary to bind implicit conversion-capable constructors that don't exist in the underlying C++ type (meaning that they are specific to the Python bindings). This can be done manually noting that .. code-block:: cpp nb::class_(m, "MyType") .def(nb::init_implicit()); can be replaced by the lower-level code .. code-block:: cpp nb::class_(m, "MyType") .def("__init__", [](MyType* t, const char* arg0) { new (t) MyType(arg0); }); nb::implicitly_convertible(); .. cpp:struct:: template new_ This is a small helper class that indicates to :cpp:func:`class_::def()` that a particular lambda or static method provides a Python object constructor (``__new__``) for the class being bound. Normally, you would use :cpp:class:`init` instead if possible, in order to cooperate with nanobind's usual object creation process. Using :cpp:class:`new_` replaces that process entirely. This is principally useful when some C++ type of interest can only provide pointers to its instances, rather than allowing them to be constructed directly. Like :cpp:class:`init`, the only use of a :cpp:class:`new_` object is as an argument to :cpp:func:`class_::def()`. Example use: .. code-block:: cpp class MyType { private: MyType(); public: static std::shared_ptr create(); int value = 0; }; nb::class_(m, "MyType") .def(nb::new_(&MyType::create)); Given this example code, writing ``MyType()`` in Python would produce a Python object wrapping the result of ``MyType::create()`` in C++. If multiple calls to ``create()`` return pointers to the same C++ object, these will turn into references to the same Python object as well. See the discussion of :ref:`customizing Python object creation ` for more information. .. cpp:struct:: template def_visitor An empty base object which serves as a tag to allow :cpp:func:`class_::def()` to dispatch to custom logic implemented by the type ``Visitor``. This is the same mechanism used by :cpp:class:`init`, :cpp:class:`init_implicit`, and :cpp:class:`new_`; it's exposed publicly so that you can create your own reusable abstractions for binding logic. To define a ``def_visitor``, you would write something like: .. code-block:: cpp struct my_ops : nb::def_visitor { template void execute(Class &cl, const Extra&... extra) { /* series of def() statements on `cl`, which is a nb::class_ */ } }; Then use it like: .. code-block:: cpp nb::class_(m, "MyType") .def("some_method", &MyType::some_method) .def(my_ops()) ... ; Any arguments to :cpp:func:`class_::def()` after the ``def_visitor`` object get passed through as the ``Extra...`` parameters to ``execute()``. As with any other C++ object, data needed by the ``def_visitor`` can be passed through template arguments or ordinary constructor arguments. The ``execute()`` method may be static if it doesn't need to access anything in ``*this``. GIL Management -------------- These two `RAII `_ helper classes acquire and release the *Global Interpreter Lock* (GIL) in a given scope. The :cpp:struct:`gil_scoped_release` helper is often combined with the :cpp:struct:`call_guard`, as in .. code-block:: cpp m.def("expensive", &expensive, nb::call_guard()); This releases the interpreter lock while `expensive` is running, which permits running it in parallel from multiple Python threads. .. cpp:struct:: gil_scoped_acquire .. cpp:function:: gil_scoped_acquire() Acquire the GIL .. cpp:function:: ~gil_scoped_acquire() Release the GIL .. cpp:struct:: gil_scoped_release .. cpp:function:: gil_scoped_release() Release the GIL (**must** be currently held) In :ref:`free-threaded extensions `, this operation also temporarily releases all :ref:`argument locks ` held by the current thread. .. cpp:function:: ~gil_scoped_release() Reacquire the GIL Free-threading -------------- Nanobind provides abstractions to implement *additional* locking that is needed to ensure the correctness of free-threaded Python extensions. .. cpp:struct:: ft_mutex Object-oriented wrapper representing a `PyMutex `__. It can be slightly more efficient than OS/language-provided primitives (e.g., ``std::thread``, ``pthread_mutex_t``) and should generally be preferred when adding critical sections to Python bindings. In Python builds *without* free-threading, this class does nothing. It has no attributes and the :cpp:func:`lock` and :cpp:func:`unlock` functions return immediately. .. cpp:function:: ft_mutex() Create a new (unlocked) mutex. .. cpp:function:: void lock() Acquire the mutex. .. cpp:function:: void unlock() Release the mutex. .. cpp:struct:: ft_lock_guard This class provides a RAII lock guard analogous to ``std::lock_guard`` and ``std::unique_lock``. .. cpp:function:: ft_lock_guard(ft_mutex &mutex) Call :cpp:func:`mutex.lock() ` (no-op in non-free-threaded builds). .. cpp:function:: ~ft_lock_guard() Call :cpp:func:`mutex.unlock() ` (no-op in non-free-threaded builds). .. cpp:struct:: ft_object_guard This class provides a RAII guard that locks a single Python object within a local scope (in contrast to :cpp:class:`ft_lock_guard`, which locks a mutex). It is a thin wrapper around the Python `critical section API `__. Please refer to the Python documentation for details on the semantics of this relaxed form of critical section (in particular, Python critical sections may release previously held locks). In Python builds *without* free-threading, this class does nothing---the constructor and destructor return immediately. .. cpp:function:: ft_object_guard(handle h) Lock the object ``h`` (no-op in non-free-threaded builds) .. cpp:function:: ~ft_object_guard() Unlock the object ``h`` (no-op in non-free-threaded builds) .. cpp:struct:: ft_object2_guard This class provides a RAII guard that locks *two* Python object within a local scope (in contrast to :cpp:class:`ft_lock_guard`, which locks a mutex). It is a thin wrapper around the Python `critical section API `__. Please refer to the Python documentation for details on the semantics of this relaxed form of critical section (in particular, Python critical sections may release previously held locks). In Python builds *without* free-threading, this class does nothing---the constructor and destructor return immediately. .. cpp:function:: ft_object2_guard(handle h1, handle h2) Lock the objects ``h1`` and ``h2`` (no-op in non-free-threaded builds) .. cpp:function:: ~ft_object2_guard() Unlock the objects ``h1`` and ``h2`` (no-op in non-free-threaded builds) Low-level type and instance access ---------------------------------- nanobind exposes a low-level interface to provide fine-grained control over the sequence of steps that instantiates a Python object wrapping a C++ instance. A thorough explanation of these features is provided in a :ref:`separate section `. Type objects ^^^^^^^^^^^^ .. cpp:function:: bool type_check(handle h) Returns ``true`` if ``h`` is a type that was previously bound via :cpp:class:`class_`. .. cpp:function:: size_t type_size(handle h) Assuming that `h` represents a bound type (see :cpp:func:`type_check`), return its size in bytes. .. cpp:function:: size_t type_align(handle h) Assuming that `h` represents a bound type (see :cpp:func:`type_check`), return its alignment in bytes. .. cpp:function:: const std::type_info& type_info(handle h) Assuming that `h` represents a bound type (see :cpp:func:`type_check`), return its C++ RTTI record. .. cpp:function:: template T &type_supplement(handle h) Return a reference to supplemental data stashed in a type object. The type ``T`` must exactly match the type specified in the :cpp:class:`nb::supplement\ ` annotation used when creating the type; no type check is performed, and invalid supplement accesses may crash the interpreter. Also refer to :cpp:class:`nb::supplement\ `. .. cpp:function:: str type_name(handle h) Return the full (module-qualified) name of a type object as a Python string. .. cpp:function:: void * type_get_slot(handle h, int slot_id) On Python 3.10+, this function is a simple wrapper around the Python C API function ``PyType_GetSlot`` that provides stable API-compatible access to type object members. On Python 3.9 and earlier, the official function did not work on non-heap types. The nanobind version consistently works on heap and non-heap types across Python versions. Instances ^^^^^^^^^ The documentation below refers to two per-instance flags with the following meaning: - *ready*: is the instance fully constructed? nanobind will not permit passing the instance to a bound C++ function when this flag is unset. - *destruct*: should nanobind call the C++ destructor when the instance is garbage-collected? .. cpp:function:: bool inst_check(handle h) Returns ``true`` if `h` represents an instance of a type that was previously bound via :cpp:class:`class_`. .. cpp:function:: template T * inst_ptr(handle h) Assuming that `h` represents an instance of a type that was previously bound via :cpp:class:`class_`, return a pointer to the underlying C++ instance. The function *does not check* that `h` actually contains an instance with C++ type `T`. .. cpp:function:: object inst_alloc(handle h) Assuming that `h` represents a type object that was previously created via :cpp:class:`class_` (see :cpp:func:`type_check`), allocate an unitialized object of type `h` and return it. The *ready* and *destruct* flags of the returned instance are both set to ``false``. .. cpp:function:: object inst_alloc_zero(handle h) Assuming that `h` represents a type object that was previously created via :cpp:class:`class_` (see :cpp:func:`type_check`), allocate a zero-initialized object of type `h` and return it. The *ready* and *destruct* flags of the returned instance are both set to ``true``. This operation is equivalent to calling :cpp:func:`inst_alloc` followed by :cpp:func:`inst_zero`. .. cpp:function:: object inst_reference(handle h, void * p, handle parent = handle()) Assuming that `h` represents a type object that was previously created via :cpp:class:`class_` (see :cpp:func:`type_check`) create an object of type `h` that wraps an existing C++ instance `p`. The *ready* and *destruct* flags of the returned instance are respectively set to ``true`` and ``false``. This is analogous to casting a C++ object with return value policy :cpp:enumerator:`rv_policy::reference`. If a `parent` object is specified, the instance keeps this parent alive while the newly created object exists. This is analogous to casting a C++ object with return value policy :cpp:enumerator:`rv_policy::reference_internal`. .. cpp:function:: object inst_take_ownership(handle h, void * p) Assuming that `h` represents a type object that was previously created via :cpp:class:`class_` (see :cpp:func:`type_check`) create an object of type `h` that wraps an existing C++ instance `p`. The *ready* and *destruct* flags of the returned instance are both set to ``true``. This is analogous to casting a C++ object with return value policy :cpp:enumerator:`rv_policy::take_ownership`. .. cpp:function:: void inst_zero(handle h) Zero-initialize the contents of `h`. Sets the *ready* and *destruct* flags to ``true``. .. cpp:function:: bool inst_ready(handle h) Query the *ready* flag of the instance `h`. .. cpp:function:: std::pair inst_state(handle h) Separately query the *ready* and *destruct* flags of the instance `h`. .. cpp:function:: void inst_mark_ready(handle h) Simultaneously set the *ready* and *destruct* flags of the instance `h` to ``true``. .. cpp:function:: void inst_set_state(handle h, bool ready, bool destruct) Separately set the *ready* and *destruct* flags of the instance `h`. .. cpp:function:: void inst_destruct(handle h) Destruct the instance `h`. This entails calling the C++ destructor if the *destruct* flag is set and then setting the *ready* and *destruct* fields to ``false``. .. cpp:function:: void inst_copy(handle dst, handle src) Copy-construct the contents of `src` into `dst` and set the *ready* and *destruct* flags of `dst` to ``true``. `dst` should be an uninitialized instance of the same type. Note that setting the *destruct* flag may be problematic if `dst` is an offset into an existing object created using :cpp:func:`inst_reference` (the destructor will be called multiple times in this case). If so, you must use :cpp:func:`inst_set_state` to disable the flag following the call to :cpp:func:`inst_copy`. *New in nanobind v2.0.0*: The function is a no-op when ``src`` and ``dst`` refer to the same object. .. cpp:function:: void inst_move(handle dst, handle src) Analogous to :cpp:func:`inst_copy`, except that the move constructor is used instead of the copy constructor. .. cpp:function:: void inst_replace_copy(handle dst, handle src) Destruct the contents of `dst` (even if the *destruct* flag is ``false``). Next, copy-construct the contents of `src` into `dst` and set the *ready* flag of ``dst``. The value of the *destruct* flag is subsequently set to its value prior to the call. This operation is useful to replace the contents of one instance with that of another regardless of whether `dst` has been created using :cpp:func:`inst_alloc`, :cpp:func:`inst_reference`, or :cpp:func:`inst_take_ownership`. *New in nanobind v2.0.0*: The function is a no-op when ``src`` and ``dst`` refer to the same object. .. cpp:function:: void inst_replace_move(handle dst, handle src) Analogous to :cpp:func:`inst_replace_copy`, except that the move constructor is used instead of the copy constructor. .. cpp:function:: str inst_name(handle h) Return the full (module-qualified) name of the instance's type object as a Python string. Global flags ------------ .. cpp:function:: bool leak_warnings() noexcept Returns whether nanobind warns if any nanobind instances, types, or functions are still alive when the Python interpreter shuts down. .. cpp:function:: bool implicit_cast_warnings() noexcept Returns whether nanobind warns if an implicit conversion was not successful. .. cpp:function:: void set_leak_warnings(bool value) noexcept By default, nanobind loudly complains when any nanobind instances, types, or functions are still alive when the Python interpreter shuts down. Call this function to disable or re-enable leak warnings. .. cpp:function:: void set_implicit_cast_warnings(bool value) noexcept By default, nanobind loudly complains when it attempts to perform an implicit conversion, and when that conversion is not successful. Call this function to disable or re-enable the warnings. .. cpp:function:: inline bool is_alive() noexcept The function returns ``true`` when nanobind is initialized and ready for use. It returns ``false`` when the Python interpreter has shut down, causing the destruction various nanobind-internal data structures. Having access to this liveness status can be useful to avoid operations that are illegal in the latter context. Miscellaneous ------------- .. cpp:function:: str repr(handle h) Return a stringified version of the provided Python object. Equivalent to ``repr(h)`` in Python. .. cpp:function:: void print(handle value, handle end = handle(), handle file = handle()) Invoke the Python ``print()`` function to print the object `value`. If desired, a line ending `end` and file handle `file` can be specified. .. cpp:function:: void print(const char * str, handle end = handle(), handle file = handle()) Invoke the Python ``print()`` function to print the null-terminated C-style string `str` that is encoded using UTF-8 encoding. If desired, a line ending `end` and file handle `file` can be specified. .. cpp:function:: iterator iter(handle h) Equivalent to ``iter(h)`` in Python. .. cpp:function:: object none() Return an object representing the value ``None``. .. cpp:function:: dict builtins() Return the ``__builtins__`` dictionary. .. cpp:function:: dict globals() Return the ``globals()`` dictionary. .. cpp:function:: Py_hash_t hash(handle h) Hash the given argument like ``hash()`` in pure Python. The type of the return value (``Py_hash_t``) is an implementation-specific signed integer type. .. cpp:function:: template void implicitly_convertible() Indicate that the type `Source` is implicitly convertible into `Target` (which must refer to a type that was previously bound via :cpp:class:`class_`). *Note*: the :cpp:struct:`init_implicit` interface generates more compact code and should be preferred, i.e., use .. code-block:: cpp nb::class_(m, "Target") .def(nb::init_implicit()); instead of .. code-block:: cpp nb::class_(m, "Target") .def(nb::init()); nb::implicitly_convertible(); The function is provided for reasons of compatibility with pybind11, and as an escape hatch to enable use cases where :cpp:struct:`init_implicit` is not available (e.g., for custom binding-specific constructors that don't exist in `Target` type). .. cpp:class:: template typed This helper class provides an interface to parameterize generic types to improve generated Python function signatures (e.g., to turn ``list`` into ``list[MyType]``). Consider the following binding that iterates over a Python list. .. code-block:: cpp m.def("f", [](nb::list l) { for (handle h : l) { // ... } }); Suppose that ``f`` expects a list of ``MyType`` objects, which is not clear from the signature. To make this explicit, use the ``nb::typed`` wrapper to pass additional type parameters. This has no effect besides clarifying the signature---in particular, nanobind does *not* insert additional runtime checks! At runtime, a ``nb::typed`` behaves exactly like a ``T``. .. code-block:: cpp m.def("f", [](nb::typed l) { for (nb::handle h : l) { // ... } }); ``nb::typed`` and ``nb::typed`` are treated specially: they generate a signature that refers just to ``T``, rather than to the nonsensical ``object[T]`` that would otherwise be produced. This can be useful if you want to replace the type of a parameter instead of augmenting it. Note that at runtime these perform no checks at all, since ``nb::object`` and ``nb::handle`` can refer to any Python object. To support callable types, you can specify a C++ function signature in ``nb::typed`` and nanobind will attempt to convert it to a Python callable signature. ``nb::typed`` becomes ``Callable[[float, str], int]``, while ``nb::typed`` becomes ``Callable[..., int]``. Type checkers will verify that any callable passed for such an argument has a compatible signature. (At runtime, any sort of callable object will be accepted.) wjakob-nanobind-6c4457b/docs/api_extra.rst000066400000000000000000001613721474760012700205750ustar00rootroot00000000000000C++ API Reference (Extras) ========================== .. cpp:namespace:: nanobind Operator overloading -------------------- The following optional include directive imports the special value :cpp:var:`self`. .. code-block:: cpp #include The underlying type exposes various C++ operators that enable a shorthand notation to bind operators to python. See the :ref:`operator overloading ` example in the main documentation for details. .. cpp:class:: detail::self_t This is an internal class that should be accessed through the singleton :cpp:var:`self` value. It supports the overloaded operators listed below. Depending on whether :cpp:var:`self` is the left or right argument of a binary operation, the binding will map to different Python methods as shown below. .. list-table:: :header-rows: 1 :widths: 50 50 * - C++ operator - Python method (left or right) * - ``operator-`` - ``__sub__``, ``__rsub__`` * - ``operator+`` - ``__add__``, ``__radd__`` * - ``operator*`` - ``__mul__``, ``__rmul__`` * - ``operator/`` - ``__truediv__``, ``__rtruediv__`` * - ``operator%`` - ``__mod__``, ``__rmod__`` * - ``operator<<`` - ``__lshift__``, ``__rlshift__`` * - ``operator>>`` - ``__rshift__``, ``__rrshift__`` * - ``operator&`` - ``__and__``, ``__rand__`` * - ``operator^`` - ``__xor__``, ``__rxor__`` * - ``operator|`` - ``__or__``, ``__ror__`` * - ``operator>`` - ``__gt__``, ``__lt__`` * - ``operator>=`` - ``__ge__``, ``__le__`` * - ``operator<`` - ``__lt__``, ``__gt__`` * - ``operator<=`` - ``__le__``, ``__ge__`` * - ``operator==`` - ``__eq__`` * - ``operator!=`` - ``__ne__`` * - ``operator+=`` - ``__iadd__`` * - ``operator-=`` - ``__isub__`` * - ``operator*=`` - ``__mul__`` * - ``operator/=`` - ``__itruediv__`` * - ``operator%=`` - ``__imod__`` * - ``operator<<=`` - ``__ilrshift__`` * - ``operator>>=`` - ``__ilrshift__`` * - ``operator&=`` - ``__iand__`` * - ``operator^=`` - ``__ixor__`` * - ``operator|=`` - ``__ior__`` * - ``operator-`` (unary) - ``__neg__`` * - ``operator+`` (unary) - ``__pos__`` * - ``operator~`` (unary) - ``__invert__`` * - ``operator!`` (unary) - ``__bool__`` (with extra negation) * - ``nb::abs(..)`` - ``__abs__`` * - ``nb::hash(..)`` - ``__hash__`` .. cpp:var:: detail::self_t self Trampolines ----------- The following macros to implement trampolines that forward virtual function calls to Python require an additional include directive: .. code-block:: cpp #include See the section on :ref:`trampolines ` for further detail. .. c:macro:: NB_TRAMPOLINE(base, size) Install a trampoline in an alias class to enable dispatching C++ virtual function calls to a Python implementation. Refer to the documentation on :ref:`trampolines ` to see how this macro can be used. .. c:macro:: NB_OVERRIDE(func, ...) Dispatch the call to a Python method named ``"func"`` if it is overloaded on the Python side, and forward the function arguments specified in the variable length argument ``...``. Otherwise, call the C++ implementation `func` in the base class. Refer to the documentation on :ref:`trampolines ` to see how this macro can be used. .. c:macro:: NB_OVERRIDE_PURE(func, ...) Dispatch the call to a Python method named ``"func"`` if it is overloaded on the Python side, and forward the function arguments specified in the variable length argument ``...``. Otherwise, raise an exception. This macro should be used when the C++ function is pure virtual. Refer to the documentation on :ref:`trampolines ` to see how this macro can be used. .. c:macro:: NB_OVERRIDE_NAME(name, func, ...) Dispatch the call to a Python method named ``name`` if it is overloaded on the Python side, and forward the function arguments specified in the variable length argument ``...``. Otherwise, call the C++ function `func` in the base class. This function differs from :c:macro:`NB_OVERRIDE() ` in that C++ and Python functions can be named differently (e.g., ``operator+`` and ``__add__``). Refer to the documentation on :ref:`trampolines ` to see how this macro can be used. .. c:macro:: NB_OVERRIDE_PURE_NAME(name, func, ...) Dispatch the call to a Python method named ``name`` if it is overloaded on the Python side, and forward the function arguments specified in the variable length argument ``...``. Otherwise, raise an exception. This macro should be used when the C++ function is pure virtual. This function differs from :c:macro:`NB_OVERRIDE_PURE() ` in that C++ and Python functions can be named differently (e.g., ``operator+`` and ``__add__``). Although the C++ base implementation cannot be called, its name is still important since nanobind uses it to infer the return value type. Refer to the documentation on :ref:`trampolines ` to see how this macro can be used. .. _vector_bindings: STL vector bindings ------------------- The following function can be used to expose ``std::vector<...>`` variants in Python. It is not part of the core nanobind API and requires an additional include directive: .. code-block:: cpp #include .. cpp:function:: template class_ bind_vector(handle scope, const char * name, Args &&...args) Bind the STL vector-derived type `Vector` to the identifier `name` and place it in `scope` (e.g., a :cpp:class:`module_`). The variable argument list can be used to pass a docstring and other :ref:`class binding annotations `. The type includes the following methods resembling ``list``: .. list-table:: :header-rows: 1 :widths: 50 50 * - Signature - Documentation * - ``__init__(self)`` - Default constructor * - ``__init__(self, arg: Vector)`` - Copy constructor * - ``__init__(self, arg: typing.Sequence)`` - Construct from another sequence type * - ``__len__(self) -> int`` - Return the number of elements * - ``__repr__(self) -> str`` - Generate a string representation * - ``__contains__(self, arg: Value)`` - Check if the vector contains ``arg`` * - ``__eq__(self, arg: Vector)`` - Check if the vector is equal to ``arg`` * - ``__ne__(self, arg: Vector)`` - Check if the vector is not equal to ``arg`` * - ``__bool__(self) -> bool`` - Check whether the vector is empty * - ``__iter__(self) -> iterator`` - Instantiate an iterator to traverse the elements * - ``__getitem__(self, arg: int) -> Value`` - Return an element from the list (supports negative indexing) * - ``__setitem__(self, arg0: int, arg1: Value)`` - Assign an element in the list (supports negative indexing) * - ``__delitem__(self, arg: int)`` - Delete an item from the list (supports negative indexing) * - ``__getitem__(self, arg: slice) -> Vector`` - Slice-based getter * - ``__setitem__(self, arg0: slice, arg1: Value)`` - Slice-based assignment * - ``__delitem__(self, arg: slice)`` - Slice-based deletion * - ``clear(self)`` - Remove all items from the list * - ``append(self, arg: Value)`` - Append a list item * - ``insert(self, arg0: int, arg1: Value)`` - Insert a list item (supports negative indexing) * - ``pop(self, index: int = -1)`` - Pop an element at position ``index`` (the end by default) * - ``extend(self, arg: Vector)`` - Extend ``self`` by appending elements from ``arg``. * - ``count(self, arg: Value)`` - Count the number of times that ``arg`` is contained in the vector * - ``remove(self, arg: Value)`` - Remove all occurrences of ``arg``. In contrast to ``std::vector<...>``, all bound functions perform range checks to avoid undefined behavior. When the type underlying the vector is not comparable or copy-assignable, some of these functions will not be generated. The binding operation is a no-op if the vector type has already been registered with nanobind. .. warning:: While this function creates a type resembling a Python ``list``, it has a major caveat: the item accessor ``__getitem__`` copies the accessed element by default (the bottom of this paragraph explains how this copy can be avoided). Consequently, writes to elements may not propagate in the expected way. Consider the following C++ bindings: .. code-block:: cpp struct A { int value; }; nb::class_(m, "A") .def(nb::init()) .def_rw("value", &A::value); nb::bind_vector>(m, "VecA"); On the Python end, they yield the following surprising behavior: .. code-block:: python from my_ext import A, VecA va = VecA() va.append(A(123)) va[0].value = 456 assert va[0].value == 456 # <-- assertion fails! To actually modify ``va``, another write is needed. .. code-block:: python v = va[0] v.value = 456 va[0] = v This may seem like a strange design, so it is worth explaining why the implementation works in this way. The key issue is that any particular value (e.g., ``va[0]``) lies within a memory buffer managed by the ``std::vector``. It is not safe for nanobind to refer to objects within this buffer using their absolute or relative memory address. For example, inserting an element at position 0 will rearrange the buffer's contents and shift all subsequent ``A`` instances. If nanobind ``A`` objects could be "views" into the ``std::vector``, then an insertion would cause the contents of unrelated ``A`` Python objects to change unexpectedly. Insertion may also require reallocation of the buffer, invalidating all current addresses, and this could lead to undefined behavior (use-after-free) if nanobind did not make a copy. There are three situations in which the surprising behavior is avoided: 1. If the modification of the array is performed using in-place operations like .. code-block:: python v[i] += 5 In-place operators automatically perform an array assignment, causing the issue to disappear. This means that if you work with a vector type like ``std::vector`` or ``std::vector`` with an immutable element type like ``int`` or ``str`` on the Python end, it will behave completely naturally in Python. 2. If the array contains STL shared pointers (e.g., ``std::vector>``), the added indirection and ownership tracking removes the need for extra copies. 3. If the array contains pointers to reference-counted objects (e.g., ``std::vector>`` via the :cpp:class:`ref` wrapper) and ``T`` uses the intrusive reference counting approach explained :ref:`here `, the added indirection and ownership tracking removes the need for extra copies. (It is usually unsafe to use this class to bind pointer-valued vectors ``std::vector`` when ``T`` does not use intrusive reference counting, because then there is nothing to prevent the Python objects returned by ``__getitem__`` from outliving the C++ ``T`` objects that they point to. But if you are able to guarantee through other means that the ``T`` objects will live long enough, the intrusive reference counting is not strictly required.) .. note:: Previous versions of nanobind (before 2.0) and pybind11 return Python objects from ``__getitem__`` that wrap *references* (i.e., views), meaning that they are only safe to use until the next insertion or deletion in the vector they were drawn from. As discussed above, any use after that point could **corrupt memory or crash your program**, which is why reference semantics are no longer the default. If you truly need the unsafe reference semantics, and if you can guarantee that all use of your bindings will respect the memory layout and reference-invalidation rules of the underlying C++ container type, you can request the old behavior by passing a second template argument of :cpp:enumerator:`rv_policy::reference_internal` to :cpp:func:`bind_vector`. This will override nanobind's usual choice of :cpp:enumerator:`rv_policy::copy` for ``__getitem__``. .. code-block:: cpp nb::bind_vector, nb::rv_policy::reference_internal>(m, "ExampleVec"); Again, please avoid this if at all possible. It is *very* easy to cause problems if you're not careful, as the following example demonstrates. .. code-block:: python def looks_fine_but_crashes(vec: ext.ExampleVec) -> None: # Trying to remove all the elements too much older than the last: last = vec[-1] # Even being careful to iterate backwards so we visit each # index only once... for idx in range(len(vec) - 2, -1, -1): if last.timestamp - vec[idx].timestamp > 5: del vec[idx] # Oops! After the first deletion, 'last' now refers to # uninitialized memory. .. _map_bindings: STL map bindings ---------------- The following function can be used to expose ``std::map<...>`` or ``std::unordered_map<...>`` variants in Python. It is not part of the core nanobind API and requires an additional include directive: .. code-block:: cpp #include .. cpp:function:: template class_ bind_map(handle scope, const char * name, Args &&...args) Bind the STL map-derived type `Map` (ordered or unordered) to the identifier `name` and place it in `scope` (e.g., a :cpp:class:`module_`). The variable argument list can be used to pass a docstring and other :ref:`class binding annotations `. The type includes the following methods resembling ``dict``: .. list-table:: :header-rows: 1 :widths: 50 50 * - Signature - Documentation * - ``__init__(self)`` - Default constructor * - ``__init__(self, arg: Map)`` - Copy constructor * - ``__init__(self, arg: dict)`` - Construct from a Python dictionary * - ``__len__(self) -> int`` - Return the number of elements * - ``__repr__(self) -> str`` - Generate a string representation * - ``__contains__(self, arg: Key)`` - Check if the map contains ``arg`` * - ``__eq__(self, arg: Map)`` - Check if the map is equal to ``arg`` * - ``__ne__(self, arg: Map)`` - Check if the map is not equal to ``arg`` * - ``__bool__(self) -> bool`` - Check whether the map is empty * - ``__iter__(self) -> iterator`` - Instantiate an iterator to traverse the set of map keys * - ``__getitem__(self, arg: Key) -> Value`` - Return an element from the map * - ``__setitem__(self, arg0: Key, arg1: Value)`` - Assign an element in the map * - ``__delitem__(self, arg: Key)`` - Delete an item from the map * - ``clear(self)`` - Remove all items from the list * - ``update(self, arg: Map)`` - Update the map with elements from ``arg``. * - ``keys(self, arg: Map) -> Map.KeyView`` - Returns an iterable view of the map's keys * - ``values(self, arg: Map) -> Map.ValueView`` - Returns an iterable view of the map's values * - ``items(self, arg: Map) -> Map.ItemView`` - Returns an iterable view of the map's items The binding operation is a no-op if the map type has already been registered with nanobind. The binding routine ideally expects the involved types to be: - copy-constructible - copy-assignable - equality-comparable If not all of these properties are available, then a subset of the above methods will be omitted. Please refer to ``bind_map.h`` for details on the logic. .. warning:: While this function creates a type resembling a Python ``dict``, it has a major caveat: the item accessor ``__getitem__`` copies the accessed element by default. Please refer to the :ref:`STL vector bindings ` for a discussion of the problem and possible solutions. Everything applies equally to the map case. .. note:: Unlike ``std::vector``, the ``std::map`` and ``std::unordered_map`` containers are *node-based*, meaning their elements do have a consistent address for as long as they're stored in the map. (Note that this is generally *not* true of third-party containers with similar interfaces, such as ``absl::flat_hash_map``.) If you are binding a node-based container type, and you want ``__getitem__`` to return a reference to the accessed element rather than copying it, it is *somewhat* safer than it would be with :cpp:func:`bind_vector` to use the unsafe workaround discussed there: .. code-block:: cpp nb::bind_map, nb::rv_policy::reference_internal>(m, "ExampleMap"); With a node-based container, the only situation where a reference returned from ``__getitem__`` would be invalidated is if the individual element that it refers to were removed from the map. Unlike with ``std::vector``, additions and removals of *other* elements would not present a danger. It is still easy to cause problems if you're not careful, though: .. code-block:: python def unsafe_pop(map: ext.ExampleMap, key: str) -> ext.SomeValue: value = map[key] del map[key] # Oops! `value` now points to a dangling element. Anything you # do with it now is liable to crash the interpreter. return value # uh-oh... Unique pointer deleter ---------------------- The following *deleter* should be used to gain maximal flexibility in combination with ``std::unique_ptr<..>``. It requires the following additional include directive: .. code-block:: cpp #include See the two documentation sections on unique pointers for further detail (:ref:`#1 `, :ref:`#2 `). .. cpp:struct:: template deleter .. cpp:function:: deleter() = default Create a deleter that destroys the object using a ``delete`` expression. .. cpp:function:: deleter(handle h) Create a deleter that destroys the object by reducing the Python reference count. .. cpp:function:: bool owned_by_python() const Check if the object is owned by Python. .. cpp:function:: bool owned_by_cpp() const Check if the object is owned by C++. .. cpp:function:: void operator()(void * p) noexcept Destroy the object at address `p`. .. _iterator_bindings: Iterator bindings ----------------- The following functions can be used to expose existing C++ iterators in Python. They are not part of the core nanobind API and require an additional include directive: .. code-block:: cpp #include .. cpp:function:: template auto make_iterator(handle scope, const char * name, Iterator first, Sentinel last, Extra &&...extra) Create a Python iterator wrapping the C++ iterator represented by the range ``[first, last)``. The `Extra` parameter can be used to pass additional function binding annotations. This function lazily creates a new Python iterator type identified by `name`, which is stored in the given `scope`. Usually, some kind of :cpp:class:`keep_alive` annotation is needed to tie the lifetime of the parent container to that of the iterator. The return value is a typed iterator (:cpp:class:`iterator` wrapped using :cpp:class:`typed`), whose template parameter is given by the type of ``*first``. Here is an example of what this might look like for a STL vector: .. code-block:: cpp using IntVec = std::vector; nb::class_(m, "IntVec") .def("__iter__", [](const IntVec &v) { return nb::make_iterator(nb::type(), "iterator", v.begin(), v.end()); }, nb::keep_alive<0, 1>()); .. note:: Pre-2.0 versions of nanobind and pybind11 return *references* (views) into the underlying sequence. This is convenient when 1. Iterated elements are used to modify the underlying container. 2. Iterated elements should reflect separately made changes to the underlying container. But this strategy is *unsafe* if the allocated memory region or layout of the container could change (e.g., through insertion of removal of elements). Because of this, iterators now copy by default. There are two ways to still obtain references to the target elements: 1. If the iterator is over STL shared pointers, the added indirection and ownership tracking removes the need for extra copies. 2. If the iterator is over reference-counted objects (e.g., ``ref`` via the :cpp:class:`ref` wrapper) and ``T`` uses the intrusive reference counting approach explained :ref:`here `, the added indirection and ownership tracking removes the need for extra copies. If you truly need the unsafe reference semantics, and if you can guarantee that all use of your bindings will respect the memory layout and reference-invalidation rules of the underlying C++ container type, you can request the old behavior by passing :cpp:enumerator:`rv_policy::reference_internal` to the ``Policy`` template argument of this function. .. cpp:function:: template auto make_iterator(handle scope, const char * name, Type &value, Extra &&...extra) This convenience wrapper calls the above :cpp:func:`make_iterator` variant with ``first`` and ``last`` set to ``std::begin(value)`` and ``std::end(value)``, respectively. .. cpp:function:: template iterator make_key_iterator(handle scope, const char * name, Iterator first, Sentinel last, Extra &&...extra) :cpp:func:`make_iterator` specialization for C++ iterators that return key-value pairs. `make_key_iterator` returns the first pair element to iterate over keys. The return value is a typed iterator (:cpp:class:`iterator` wrapped using :cpp:class:`typed`), whose template parameter is given by the type of ``(*first).first``. .. cpp:function:: template iterator make_value_iterator(handle scope, const char * name, Iterator first, Sentinel last, Extra &&...extra) :cpp:func:`make_iterator` specialization for C++ iterators that return key-value pairs. `make_value_iterator` returns the second pair element to iterate over values. The return value is a typed iterator (:cpp:class:`iterator` wrapped using :cpp:class:`typed`), whose template parameter is given by the type of ``(*first).second``. N-dimensional array type ------------------------ The following type can be used to exchange n-dimension arrays with frameworks like NumPy, PyTorch, Tensorflow, JAX, CuPy, and others. It requires an additional include directive: .. code-block:: cpp #include Detailed documentation including example code is provided in a :ref:`separate section `. .. cpp:function:: bool ndarray_check(handle h) noexcept Test whether the Python object represents an ndarray. Objects with a ``__dlpack__`` attribute or objects that implement the buffer protocol are considered as ndarray objects. In addition, arrays from NumPy, PyTorch, TensorFlow and XLA are also regarded as ndarrays. .. cpp:class:: template ndarray .. cpp:type:: Scalar The scalar type underlying the array (or ``void`` if not specified) .. cpp:var:: static constexpr bool ReadOnly A ``constexpr`` Boolean value that is ``true`` if the ndarray template arguments (`Args... `) include the ``nb::ro`` annotation or a ``const``-qualified scalar type. .. cpp:var:: static constexpr char Order A ``constexpr`` character value set based on the ndarray template arguments (`Args... `). It equals - ``'C'`` if :cpp:class:`c_contig` is specified, - ``'F'`` if :cpp:class:`f_contig` is specified, - ``'A'`` if :cpp:class:`any_contig` is specified, - ``'\0'`` otherwise. .. cpp:var:: static constexpr int DeviceType A ``constexpr`` integer value set to the device type ID extracted from the ndarray template arguments (`Args... `), or :cpp:struct:`device::none::value ` when none was specified. .. cpp:type:: VoidPtr = std::conditional_t A potentially ``const``-qualified ``void*`` pointer type used by some of the ``ndarray`` constructors. .. cpp:function:: ndarray() = default Create an invalid array. .. cpp:function:: template explicit ndarray(const ndarray &other) Reinterpreting constructor that wraps an existing nd-array (parameterized by `Args... `) into a new ndarray (parameterized by `Args2... `). No copy or conversion is made. Dropping parameters is always safe. For example, a function that returns different array types could call it to convert ``ndarray`` to ``ndarray<>``. When adding constraints, the constructor is only safe to use following a runtime check to ensure that newly created array actually possesses the advertised properties. .. cpp:function:: ndarray(const ndarray &) Copy constructor. Increases the reference count of the referenced array. .. cpp:function:: ndarray(ndarray &&) Move constructor. Steals the referenced array without changing reference counts. .. cpp:function:: ~ndarray() Decreases the reference count of the referenced array and potentially destroy it. .. cpp:function:: ndarray& operator=(const ndarray &) Copy assignment operator. Increases the reference count of the referenced array. Decreases the reference count of the previously referenced array and potentially destroy it. .. cpp:function:: ndarray& operator=(ndarray &&) Move assignment operator. Steals the referenced array without changing reference counts. Decreases the reference count of the previously referenced array and potentially destroy it. .. _ndarray_dynamic_constructor: .. cpp:function:: ndarray(VoidPtr data, const std::initializer_list shape = { }, handle owner = { }, std::initializer_list strides = { }, dlpack::dtype dtype = nanobind::dtype(), int32_t device_type = DeviceType, int32_t device_id = 0, char order = Order) Create an array wrapping an existing memory allocation. Only the `data` parameter is strictly required, while some other parameters can be be inferred from static :cpp:class:`nb::ndarray\<...\> ` template parameters. The parameters have the following meaning: - `data`: a CPU/GPU/.. pointer to the memory region storing the array data. When the array is parameterized by a ``const`` scalar type, or when it has a :cpp:class:`nb::ro ` read-only annotation, a ``const`` pointer can be passed here. - `shape`: an initializer list that simultaneously specifies the number of dimensions and the size along each axis. If left at its default ``{}``, the :cpp:class:`nb::shape ` template parameter will take precedence (if present). - `owner`: if provided, the array will hold a reference to this object until its destruction. This makes it possible to create zero-copy views into other data structures, while guaranteeing the memory safety of array accesses. - `strides`: an initializer list explaining the layout of the data in memory. Each entry denotes the number of elements to jump over to advance to the next item along the associated axis. `strides` must either have the same size as `shape` or be empty. In the latter case, strides are automatically computed according to the `order` parameter. Note that strides in nanobind express *element counts* rather than *byte counts*. This convention differs from other frameworks (e.g., NumPy) and is a consequence of the underlying `DLPack `_ protocol. - `dtype` describes the numeric data type of array elements (e.g., floating point, signed/unsigned integer) and their bit depth. You can use the :cpp:func:`nb::dtype\() ` function to obtain the right value for a given type. - `device_type` and `device_id` specify where the array data is stored. The `device_type` must be an enumerant like :cpp:class:`nb::device::cuda::value `, while the meaning of the device ID is unspecified and platform-dependent. Note that the `device_id` is set to ``0`` by default and cannot be inferred by nanobind. If your extension creates arrays on multiple different compute accelerators, you *must* provide this parameter. - The `order` parameter denotes the coefficient order in memory and is only relevant when `strides` is empty. Specify ``'C'`` for C-style or ``'F'`` for Fortran-style. When this parameter is not explicitly specified, the implementation uses the order specified as an ndarray template argument, or C-style order as a fallback. Both ``strides`` and ``shape`` will be copied by the constructor, hence the targets of these initializer lists do not need to remain valid following the constructor call. .. warning:: The Python *global interpreter lock* (GIL) must be held when calling this function. .. cpp:function:: ndarray(VoidPtr data, size_t ndim, const size_t * shape, handle owner, const int64_t * strides = nullptr, dlpack::dtype dtype = nanobind::dtype(), int device_type = DeviceType, int device_id = 0, char order = Order) Alternative form of the above constructor, which accepts the `shape` and `strides` arguments using pointers instead of initializer lists. The number of dimensions must be specified via the `ndim` parameter in this case. See the previous constructor for details, the remaining behavior is identical. .. cpp:function:: dlpack::dtype dtype() const Return the data type underlying the array .. cpp:function:: size_t ndim() const Return the number of dimensions. .. cpp:function:: size_t size() const Return the size of the array (i.e. the product of all dimensions). .. cpp:function:: size_t itemsize() const Return the size of a single array element in bytes. The returned value is rounded up to the next full byte in case of bit-level representations (query :cpp:member:`dtype::bits` for bit-level granularity). .. cpp:function:: size_t nbytes() const Return the size of the entire array bytes. The returned value is rounded up to the next full byte in case of bit-level representations. .. cpp:function:: size_t shape(size_t i) const Return the size of dimension `i`. .. cpp:function:: int64_t stride(size_t i) const Return the stride (in number of elements) of dimension `i`. .. cpp:function:: const int64_t* shape_ptr() const Return a pointer to the shape array. Note that the return type is ``const int64_t*``, which may be unexpected as the scalar version :cpp:func:`shape()` casts its result to a ``size_t``. This is a consequence of the DLPack tensor representation that uses signed 64-bit integers for all of these fields. .. cpp:function:: const int64_t* stride_ptr() const Return pointer to the stride array. .. cpp:function:: bool is_valid() const Check whether the array is in a valid state. .. cpp:function:: int device_type() const ID denoting the type of device hosting the array. This will match the ``value`` field of a device class, such as :cpp:class:`device::cpu::value ` or :cpp:class:`device::cuda::value `. .. cpp:function:: int device_id() const In a multi-device/GPU setup, this function returns the ID of the device storing the array. .. cpp:function:: Scalar * data() const Return a pointer to the array data. If :cpp:var:`ReadOnly` is true, a pointer-to-const is returned. .. cpp:function:: template auto& operator()(Args2... indices) Return a reference to the element stored at the provided index/indices. If :cpp:var:`ReadOnly` is true, a reference-to-const is returned. Note that ``sizeof...(Args2)`` must match :cpp:func:`ndim()`. This accessor is only available when the scalar type and array dimension were specified as template parameters. This function should only be used when the array storage is accessible through the CPU's virtual memory address space. .. cpp:function:: template auto view() Returns an nd-array view that is optimized for fast array access on the CPU. You may optionally specify additional ndarray constraints via the `Extra` parameter (though a runtime check should first be performed to ensure that the array possesses these properties). The returned view provides the operations ``data()``, ``ndim()``, ``shape()``, ``stride()``, and ``operator()`` following the conventions of the `ndarray` type. .. cpp:function:: auto cast(rv_policy policy = rv_policy::automatic_reference, handle parent = {}) The expression ``array.cast(policy, parent)`` is almost equivalent to :cpp:func:`nb::cast(array, policy, parent) `. The main difference is that the return type of :cpp:func:`nb::cast ` is :cpp:class:`nb::object `, which renders as a rather non-descriptive ``object`` in Python bindings. The ``.cast()`` method returns a custom wrapper type that still derives from :cpp:class:`nb::object `, but whose type signature in bindings reproduces that of the original nd-array. Data types ^^^^^^^^^^ Nanobind uses the `DLPack `_ ABI to represent metadata describing n-dimensional arrays (even when they are exchanged using the buffer protocol). Consequently, the set of possible dtypes is :ref:`more restricted ` than that of other nd-array libraries (e.g., NumPy). Relevant data structures are located in the ``nanobind::dlpack`` sub-namespace. .. cpp:enum-class:: dlpack::dtype_code : uint8_t This enumeration characterizes the elementary array data type regardless of bit depth. .. cpp:enumerator:: Int = 0 Signed integer format .. cpp:enumerator:: UInt = 1 Unsigned integer format .. cpp:enumerator:: Float = 2 IEEE-754 floating point format .. cpp:enumerator:: Bfloat = 4 "Brain" floating point format .. cpp:enumerator:: Complex = 5 Complex numbers parameterized by real and imaginary component .. cpp:struct:: dlpack::dtype Represents the data type underlying an n-dimensional array. Use the :cpp:func:`dtype\() <::nanobind::dtype>` function to return a populated instance of this data structure given a scalar C++ arithmetic type. .. cpp:member:: uint8_t code = 0; This field must contain the value of one of the :cpp:enum:`dlpack::dtype_code` enumerants. .. cpp:member:: uint8_t bits = 0; Number of bits per entry (e.g., 32 for a C++ single precision ``float``) .. cpp:member:: uint16_t lanes = 0; Number of SIMD lanes (typically ``1``) .. cpp:function:: template dlpack::dtype dtype() Returns a populated instance of the :cpp:class:`dlpack::dtype` structure given a scalar C++ arithmetic type. Array annotations ^^^^^^^^^^^^^^^^^ The :cpp:class:`ndarray\<..\> ` class admits optional template parameters. They constrain the type of array arguments that may be passed to a function. The following are supported: Data type +++++++++ The data type of the underlying scalar element. The following are supported. - ``[u]int8_t`` up to ``[u]int64_t`` and other variations (``unsigned long long``, etc.) - ``float``, ``double`` - ``bool`` Annotate the data type with ``const`` to indicate a read-only array. Note that only the buffer protocol/NumPy interface considers ``const``-ness at the moment; data exchange with other array libraries will ignore this annotation. When the is unspecified (e.g., to accept arbitrary input arrays), the :cpp:class:`ro` annotation can instead be used to denote read-only access: .. cpp:class:: ro Indicate read-only access (use only when no data type is specified.) nanobind does not support non-standard types as documented in the section on :ref:`dtype limitations `. Shape +++++ .. cpp:class:: template shape Require the array to have ``sizeof...(Is)`` dimensions. Each entry of `Is` specifies a fixed size constraint for that specific dimension. An entry equal to ``-1`` indicates that *any* size should be accepted for this dimension. (An alias named ``nb::any`` representing ``-1`` was removed in nanobind 2). .. cpp:class:: template ndim Alternative to the above that only constrains the array dimension. ``nb::ndim<2>`` is equivalent to ``nb::shape<-1, -1>``. Contiguity ++++++++++ .. cpp:class:: c_contig Request that the array storage uses a C-contiguous representation. .. cpp:class:: f_contig Request that the array storage uses a F (Fortran)-contiguous representation. .. cpp:class:: any_contig Accept both C- and F-contiguous arrays. If you prefer not to require contiguity, simply do not provide any of the ``*_contig`` template parameters listed above. Device type +++++++++++ .. cpp:class:: device The following helper classes can be used to constrain the device and address space of an array. Each class has a ``static constexpr int32_t value`` field that will then match up with :cpp:func:`ndarray::device_id()`. .. cpp:class:: cpu CPU heap memory .. cpp:class:: cuda NVIDIA CUDA device memory .. cpp:class:: cuda_host NVIDIA CUDA host-pinned memory .. cpp:class:: cuda_managed NVIDIA CUDA managed memory .. cpp:class:: vulkan Vulkan device memory .. cpp:class:: metal Apple Metal device memory .. cpp:class:: rocm AMD ROCm device memory .. cpp:class:: rocm_host AMD ROCm host memory .. cpp:class:: oneapi Intel OneAPI device memory Framework +++++++++ Framework annotations cause :cpp:class:`nb::ndarray ` objects to convert into an equivalent representation in one of the following frameworks: .. cpp:class:: numpy .. cpp:class:: tensorflow .. cpp:class:: pytorch .. cpp:class:: jax .. cpp:class:: cupy Eigen convenience type aliases ------------------------------ The following helper type aliases require an additional include directive: .. code-block:: cpp #include .. cpp:type:: DStride = Eigen::Stride This type alias refers to an Eigen stride object that is sufficiently flexible so that can be easily called with NumPy arrays and array slices. .. cpp:type:: template DRef = Eigen::Ref This templated type alias creates an ``Eigen::Ref<..>`` with flexible strides for zero-copy data exchange between Eigen and NumPy. .. cpp:type:: template DMap = Eigen::Map This templated type alias creates an ``Eigen::Map<..>`` with flexible strides for zero-copy data exchange between Eigen and NumPy. .. _chrono_conversions: Timestamp and duration conversions ---------------------------------- nanobind supports bidirectional conversions of timestamps and durations between their standard representations in Python (:py:class:`datetime.datetime`, :py:class:`datetime.timedelta`) and in C++ (``std::chrono::time_point``, ``std::chrono::duration``). A few unidirectional conversions from other Python types to these C++ types are also provided and explained below. These type casters require an additional include directive: .. code-block:: cpp #include .. The rest of this section is adapted from pybind11/docs/advanced/cast/chrono.rst An overview of clocks in C++11 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The C++11 standard defines three different clocks, and users can define their own. Each ``std::chrono::time_point`` is defined relative to a particular clock. When using the ``chrono`` type caster, you must be aware that only ``std::chrono::system_clock`` is guaranteed to convert to a Python :py:class:`~datetime.datetime` object; other clocks may convert to :py:class:`~datetime.timedelta` if they don't represent calendar time. The first clock defined by the standard is ``std::chrono::system_clock``. This clock measures the current date and time, much like the Python :py:func:`time.time` function. It can change abruptly due to administrative actions, daylight savings time transitions, or synchronization with an external time server. That makes this clock a poor choice for timing purposes, but a good choice for wall-clock time. The second clock defined by the standard is ``std::chrono::steady_clock``. This clock ticks at a steady rate and is never adjusted, like :py:func:`time.monotonic` in Python. That makes it excellent for timing purposes, but the value in this clock does not correspond to the current date and time. Often this clock will measure the amount of time your system has been powered on. This clock will never be the same clock as the system clock, because the system clock can change but steady clocks cannot. The third clock defined in the standard is ``std::chrono::high_resolution_clock``. This clock is the clock that has the highest resolution out of all the clocks in the system. It is normally an alias for either ``system_clock`` or ``steady_clock``, but can be its own independent clock. Due to this uncertainty, conversions of time measured on the ``high_resolution_clock`` to Python produce platform-dependent types: you'll get a :py:class:`~datetime.datetime` if ``high_resolution_clock`` is an alias for ``system_clock`` on your system, or a :py:class:`~datetime.timedelta` value otherwise. Provided conversions ^^^^^^^^^^^^^^^^^^^^ The C++ types described in this section may be instantiated with any precision. Conversions to a less-precise type will round towards zero. Since Python's built-in date and time objects support only microsecond precision, any precision beyond that on the C++ side will be lost when converting to Python. .. rubric:: C++ to Python - ``std::chrono::system_clock::time_point`` → :py:class:`datetime.datetime` A system clock time will be converted to a Python :py:class:`~datetime.datetime` instance. The result describes a time in the local timezone, but does not have any timezone information attached to it (it is a naive datetime object). - ``std::chrono::duration`` → :py:class:`datetime.timedelta` A duration will be converted to a Python :py:class:`~datetime.timedelta`. Any precision beyond microseconds is lost by rounding towards zero. - ``std::chrono::[other_clock]::time_point`` → :py:class:`datetime.timedelta` A time on any clock except the system clock will be converted to a Python :py:class:`~datetime.timedelta`, which measures the number of seconds between the clock's epoch and the time point of interest. .. rubric:: Python to C++ - :py:class:`datetime.datetime` or :py:class:`datetime.date` or :py:class:`datetime.time` → ``std::chrono::system_clock::time_point`` A Python date, time, or datetime object can be converted into a system clock timepoint. A :py:class:`~datetime.time` with no date information is treated as that time on January 1, 1970. A :py:class:`~datetime.date` with no time information is treated as midnight on that date. **Any timezone information is ignored.** - :py:class:`datetime.timedelta` → ``std::chrono::duration`` A Python time delta object can be converted into a duration that describes the same number of seconds (modulo precision limitations). - :py:class:`datetime.timedelta` → ``std::chrono::[other_clock]::time_point`` A Python time delta object can be converted into a timepoint on a clock other than the system clock. The resulting timepoint will be that many seconds after the target clock's epoch time. - ``float`` → ``std::chrono::duration`` A floating-point value can be converted into a duration. The input is treated as a number of seconds, and fractional seconds are supported to the extent representable. - ``float`` → ``std::chrono::[other_clock]::time_point`` A floating-point value can be converted into a timepoint on a clock other than the system clock. The input is treated as a number of seconds, and fractional seconds are supported to the extent representable. The resulting timepoint will be that many seconds after the target clock's epoch time. Evaluating Python expressions from strings ------------------------------------------ The following functions can be used to evaluate Python functions and expressions. They require an additional include directive: .. code-block:: cpp #include Detailed documentation including example code is provided in a :ref:`separate section `. .. cpp:enum-class:: eval_mode This enumeration specifies how the content of a string should be interpreted. Used in Py_CompileString(). .. cpp:enumerator:: eval_expr = Py_eval_input Evaluate a string containing an isolated expression .. cpp:enumerator:: eval_single_statement = Py_single_input Evaluate a string containing a single statement. Returns \c None .. cpp:enumerator:: eval_statements = Py_file_input Evaluate a string containing a sequence of statement. Returns \c None .. cpp:function:: template object eval(const char (&s)[N], handle global = handle(), handle local = handle()) Evaluate the given Python code in the given global/local scopes, and return the value. .. cpp:function:: inline void exec(const str &expr, handle global = handle(), handle local = handle()) Execute the given Python code in the given global/local scopes. Intrusive reference counting helpers ------------------------------------ The following functions and classes can be used to augment user-provided classes with intrusive reference counting that greatly simplifies shared ownership in larger C++/Python binding projects. This functionality requires the following include directives: .. code-block:: cpp #include #include These headers reference several functions, whose implementation must be provided. You can do so by including the following file from a single ``.cpp`` file of your project: .. code-block:: cpp #include The functionality in these files consist of the following classes and functions: .. cpp:class:: intrusive_counter Simple atomic reference counter that can optionally switch over to Python-based reference counting. The various copy/move assignment/constructors intentionally don't transfer the reference count. This is so that the contents of classes containing an ``intrusive_counter`` can be copied/moved without disturbing the reference counts of the associated instances. .. cpp:function:: intrusive_counter() noexcept = default Initialize with a reference count of zero. .. cpp:function:: intrusive_counter(const intrusive_counter &o) Copy constructor, which produces a zero-initialized counter. Does *not* copy the reference count from `o`. .. cpp:function:: intrusive_counter(intrusive_counter &&o) Move constructor, which produces a zero-initialized counter. Does *not* copy the reference count from `o`. .. cpp:function:: intrusive_counter &operator=(const intrusive_counter &o) Copy assignment operator. Does *not* copy the reference count from `o`. .. cpp:function:: intrusive_counter &operator=(intrusive_counter &&o) Move assignment operator. Does *not* copy the reference count from `o`. .. cpp:function:: void inc_ref() const noexcept Increase the reference count. When the counter references an object managed by Python, the operation calls ``Py_INCREF()`` to increase the reference count of the Python object instead. The :cpp:func:`inc_ref() ` top-level function encapsulates this logic for subclasses of :cpp:class:`intrusive_base`. .. cpp:function:: bool dec_ref() const noexcept Decrease the reference count. When the counter references an object managed by Python, the operation calls ``Py_DECREF()`` to decrease the reference count of the Python object instead. When the C++-managed reference count reaches zero, the operation returns ``true`` to signal to the caller that it should use a *delete expression* to destroy the instance. The :cpp:func:`dec_ref() ` top-level function encapsulates this logic for subclasses of :cpp:class:`intrusive_base`. .. cpp:function:: void set_self_py(PyObject * self) Set the Python object associated with this instance. This operation is usually called by nanobind when ownership is transferred to the Python side. Any references from prior calls to :cpp:func:`intrusive_counter::inc_ref()` are converted into Python references by calling ``Py_INCREF()`` repeatedly. .. cpp:function:: PyObject * self_py() Return the Python object associated with this instance (or ``nullptr``). .. cpp:class:: intrusive_base Simple polymorphic base class for a intrusively reference-counted object hierarchy. The member functions expose corresponding functionality of :cpp:class:`intrusive_counter`. .. cpp:function:: void inc_ref() const noexcept See :cpp:func:`intrusive_counter::inc_ref()`. .. cpp:function:: bool dec_ref() const noexcept See :cpp:func:`intrusive_counter::dec_ref()`. .. cpp:function:: void set_self_py(PyObject * self) See :cpp:func:`intrusive_counter::set_self_py()`. .. cpp:function:: PyObject * self_py() See :cpp:func:`intrusive_counter::self_py()`. .. cpp:function:: void intrusive_init(void (* intrusive_inc_ref_py)(PyObject * ) noexcept, void (* intrusive_dec_ref_py)(PyObject * ) noexcept) Function to register reference counting hooks with the intrusive reference counter class. This allows its implementation to not depend on Python. You would usually call this function as follows from the initialization routine of a Python extension: .. code-block:: cpp NB_MODULE(my_ext, m) { nb::intrusive_init( [](PyObject * o) noexcept { nb::gil_scoped_acquire guard; Py_INCREF(o); }, [](PyObject * o) noexcept { nb::gil_scoped_acquire guard; Py_DECREF(o); }); // ... } .. cpp:function:: inline void inc_ref(intrusive_base * o) noexcept Reference counting helper function that calls ``o->inc_ref()`` if ``o`` is not equal to ``nullptr``. .. cpp:function:: inline void dec_ref(intrusive_base * o) noexcept Reference counting helper function that calls ``o->dec_ref()`` if ``o`` is not equal to ``nullptr`` and ``delete o`` when the reference count reaches zero. .. cpp:class:: template ref RAII scoped reference counting helper class :cpp:class:`ref\ ` is a simple RAII wrapper class that encapsulates a pointer to an instance with intrusive reference counting. It takes care of increasing and decreasing the reference count as needed and deleting the instance when the count reaches zero. For this to work, compatible functions :cpp:func:`inc_ref()` and :cpp:func:`dec_ref()` must be defined before including the file ``nanobind/intrusive/ref.h``. Default implementations for subclasses of the type :cpp:class:`intrusive_base` are already provided as part of the file ``counter.h``. .. cpp:function:: ref() = default Create a null reference .. cpp:function:: ref(T * ptr) Create a reference from a pointer. Increases the reference count of the object (if not ``nullptr``). .. cpp:function:: ref(const ref &r) Copy a reference. Increase the reference count of the object (if not ``nullptr``). .. cpp:function:: ref(ref &&r) noexcept Move a reference. Object reference counts are unaffected by this operation. .. cpp:function:: ~ref() Destroy a reference. Decreases the reference count of the object (if not ``nullptr``). .. cpp:function:: ref& operator=(ref &&r) noexcept Move-assign another reference into this one. .. cpp:function:: ref& operator=(const ref &r) Copy-assign another reference into this one. .. cpp:function:: ref& operator=(const T * ptr) Overwrite this reference with a pointer to another object .. cpp:function:: void reset() Clear the reference and reduces the reference count of the object (if not ``nullptr``) .. cpp:function:: bool operator==(const ref &r) const Compare this reference with another reference (pointer equality) .. cpp:function:: bool operator!=(const ref &r) const Compare this reference with another reference (pointer inequality) .. cpp:function:: bool operator==(const T * ptr) const Compare this reference with another object (pointer equality) .. cpp:function:: bool operator!=(const T * ptr) const Compare this reference with another object (pointer inequality) .. cpp:function:: T * operator->() Access the object referenced by this reference .. cpp:function:: const T * operator->() const Access the object referenced by this reference (const version) .. cpp:function:: T& operator*() Return a C++ reference to the referenced object .. cpp:function:: const T& operator*() const Return a C++ reference to the referenced object (const version) .. cpp:function:: T* get() Return a C++ pointer to the referenced object .. cpp:function:: const T* get() const Return a C++ pointer to the referenced object (const version) Typing ------ The following functions for typing-related functionality require an additional include directive: .. code-block:: cpp #include .. cpp:function:: template object type_var(Args&&... args) Create a `type variable `__ (i.e., an instance of ``typing.TypeVar``). All arguments of the original Python construction are supported, e.g.: .. code-block:: cpp m.attr("T") = nb::type_var("T", "contravariant"_a = true, "covariant"_a = false, "bound"_a = nb::type()); .. cpp:function:: template object type_var_tuple(Args&&... args) Analogousto :cpp:func:`type_var`, create a `type variable tuple `__ (i.e., an instance of ``typing.TypeVarTuple``). .. cpp:function:: object any_type() Convenience wrapper, which returns ``typing.Any``. wjakob-nanobind-6c4457b/docs/basics.rst000066400000000000000000000350611474760012700200600ustar00rootroot00000000000000.. _basics: .. cpp:namespace:: nanobind Creating your first extension ############################# This section assumes that you have followed the instructions to :ref:`install ` nanobind and set up a basic :ref:`build system `. We are now ready to define a first basic extension that wraps a function to add two numbers. Create a new file ``my_ext.cpp`` with the following contents (the meaning of this code will be explained shortly): .. code-block:: cpp #include int add(int a, int b) { return a + b; } NB_MODULE(my_ext, m) { m.def("add", &add); } Afterwards, you should be able to compile and run the extension. Building using CMake -------------------- Launch ``cmake`` in the project directory to set up a build system that will write all output into a separate ``build`` subdirectory. .. code-block:: bash cmake -S . -B build .. note:: If this step fails with an error message saying that Python cannot be found, you will need to install a suitable Python 3 development package. For example, on Ubuntu you would run: .. code-block:: bash apt install libpython3-dev On Windows, you we recommend downloading and running one of the `installers `_ provided by the Python foundation. .. note:: If you have multiple versions of Python on your system, the CMake build system may not find the specific version you had in mind. This is problematic: extension built for one version of Python usually won't run on another version. You can provide a hint to the build system to help it find a specific version. In this case, delete the ``build`` folder (if you already created one) and re-run `cmake` while specifying the command line parameter ``-DPython_EXECUTABLE=``. .. code-block:: bash rm -Rf build cmake -S . -B build -DPython_EXECUTABLE= Assuming the ``cmake`` ran without issues, you can now compile the extension using the following command: .. code-block:: bash cmake --build build Finally, navigate into the ``build`` directory and launch an interactive Python session: .. code-block:: bash cd build python3 (The default build output directory is different on Windows: use ``cd build\Debug`` and ``python`` instead of the above.) You should be able to import the extension and call the newly defined function ``my_ext.add()``. .. code-block:: pycon Python 3.11.1 (main, Dec 23 2022, 09:28:24) [Clang 14.0.0 (clang-1400.0.29.202)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import my_ext >>> my_ext.add(1, 2) 3 Binding functions ----------------- Let's step through the example binding code to understand what each line does. The directive on the first line includes the core parts of nanobind: .. code-block:: cpp #include nanobind also provides many optional add-on components that are aren't included by default. They are discussed throughout this documentation along with pointers to the header files that must be included when using them. Next is the function to be exposed in Python, followed by the mysterious-looking :c:macro:`NB_MODULE` macro. .. code-block:: cpp int add(int a, int b) { return a + b; } NB_MODULE(my_ext, m) { m.def("add", &add); } :c:macro:`NB_MODULE(my_ext, m) ` declares the extension with the name ``my_ext``. This name **must** match the extension name provided to the ``nanobind_add_module()`` function in the CMake build system---otherwise, importing the extension will fail with an obscure error about a missing symbol. The second argument (``m``) names a variable of type :cpp:class:`nanobind::module_` that represents the created module. The part within curly braces (``{``, ``}``) consists of a sequence of statements that initialize the desired function and class bindings. It is best thought of as the ``main()`` function that will run when a user imports the extension into a running Python session. In this case, there is only one binding declaration that wraps the ``add`` referenced using the ampersand (``&``) operator. nanobind determines the function's type signature and generates the necessary binding code. All of this happens automatically at compile time. .. note:: Notice how little code was needed to expose our function to Python: all details regarding the function’s parameters and return value were automatically inferred using template metaprogramming. This overall approach and the used syntax go back to `Boost.Python `_, though the implementation in nanobind is very different. .. _keyword_and_default_args: Keyword and default arguments ----------------------------- There are limits to what nanobind can determine at compile time. For example, the argument names were lost and calling ``add()`` in Python using keyword arguments fails: .. code-block:: pycon >>> my_ext.add(a=1, b=2) TypeError: add(): incompatible function arguments. The following argument types are supported: 1. add(arg0: int, arg1: int, /) -> int Invoked with types: kwargs = { a: int, b: int } Let's improve the bindings to fix this. We will also add a docstring and a default ``b`` argument so that ``add()`` increments when only one value is provided. The modified binding code looks as follows: .. code-block:: cpp #include namespace nb = nanobind; using namespace nb::literals; int add(int a, int b = 1) { return a + b; } NB_MODULE(my_ext, m) { m.def("add", &add, "a"_a, "b"_a = 1, "This function adds two numbers and increments if only one is provided."); } Let's go through all of the changed lines. The first sets up a short namespace alias named ``nb``: .. code-block:: cpp namespace nb = nanobind; This is convenient because binding code usually ends up referencing many classes and functions from this namespace. The subsequent ``using`` declaration is optional and enables a convenient syntax for annotating function arguments: .. code-block:: cpp using namespace nb::literals; Without it, you would have to change every occurrence of the pattern ``"..."_a`` to the more verbose ``nb::arg("...")``. The function binding declaration includes several changes. It is common to pile on a few attributes and modifiers in :cpp:func:`.def(...) ` binding declarations, which can be specified in any order. .. code-block:: cpp m.def("add", &add, "a"_a, "b"_a = 1, "This function adds two numbers and increments if only one is provided."); The string at the end is a `docstring `_ that will later show up in generated documentation. The argument annotations (``"a"_a, "b"_a``) associate parameters with names for keyword-based argument passing. Besides argument names, nanobind also cannot infer *default arguments*---you *must repeat them* in the binding declaration. In the above snippet, the ``"b"_a = 1`` annotation informs nanobind about the value of the default argument. Exporting values ---------------- To export a value, use the :cpp:func:`attr() ` function to register it in the module as shown below. Bound classes and built-in types are automatically converted when they are assigned in this way. .. code-block:: cpp m.attr("the_answer") = 42; .. _docstrings: Docstrings ---------- Let's add one more bit of flourish by assigning a docstring to the extension module itself. Include the following line anywhere in the body of the ``NB_MODULE() {...}`` declaration: .. code-block:: cpp m.doc() = "A simple example python extension"; After recompiling the extension, you should be able to view the associated documentation using the ``help()`` builtin or the ``?`` operator in IPython. .. code-block:: pycon >>> import my_ext >>> help(my_ext) Help on module my_ext: NAME my_ext - A simple example python extension DATA add = add(a: int, b: int = 1) -> int This function adds two numbers and increments if only one is provided the_answer = 42 FILE /Users/wjakob/my_ext/my_ext.cpython-311-darwin.so The automatically generated documentation covers functions, classes, parameter and return value type information, argument names, and default arguments. .. _binding_types: Binding a custom type --------------------- Let's now turn to an object oriented example. We will create bindings for a simple C++ type named ``Dog`` defined as follows: .. code-block:: cpp #include struct Dog { std::string name; std::string bark() const { return name + ": woof!"; } }; The ``Dog`` bindings look as follows: .. code-block:: cpp #include #include namespace nb = nanobind; NB_MODULE(my_ext, m) { nb::class_(m, "Dog") .def(nb::init<>()) .def(nb::init()) .def("bark", &Dog::bark) .def_rw("name", &Dog::name); } Let's look at selected lines of this example, starting with the added include directive: .. code-block:: cpp #include nanobind has a minimal core and initially doesn't know how to deal with STL types like ``std::string``. This line imports a *type caster* that realizes a bidirectional conversion (C++ ``std::string`` ↔ Python ``str``) to make the example usable. An upcoming :ref:`documentation section ` will provide more detail on type casters and other alternatives. The class binding declaration :class:`nb::class_\() ` supports both ``class`` and ``struct``-style data structures. .. code-block:: cpp nb::class_(m, "Dog") Here, it associates the C++ type ``Dog`` with a new Python type named ``"Dog"`` and installs it in the :cpp:class:`nb::module_ ` ``m``. Initially, this type is completely empty---it has no members and cannot be instantiated. The subsequent chain of binding declarations binds two constructor overloads (via :cpp:class:`nb::init\<...\>() `), a method, and the mutable ``name`` field (via :cpp:func:`.def_rw(..) `, where ``rw`` stands for read/write access). .. code-block:: cpp .def(nb::init<>()) .def(nb::init()) .def("bark", &Dog::bark) .def_rw("name", &Dog::name); An interactive Python session demonstrating this example is shown below: .. code-block:: pycon Python 3.11.1 (main, Dec 23 2022, 09:28:24) [Clang 14.0.0 (clang-1400.0.29.202)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import my_ext >>> d = my_ext.Dog('Max') >>> print(d) >>> d.name 'Max' >>> d.name = 'Charlie' >>> d.bark() 'Charlie: woof!' The example showed how to bind constructors, methods, and mutable fields. Many other things can be bound using analogous :cpp:class:`nb::class_\<...\> ` methods: .. list-table:: :widths: 40 60 :header-rows: 1 * - Type - Method * - Methods & constructors - :cpp:func:`.def() ` * - Fields - :cpp:func:`.def_ro() `, :cpp:func:`.def_rw() ` * - Properties - :cpp:func:`.def_prop_ro() `, :cpp:func:`.def_prop_rw() ` * - Static methods - :cpp:func:`.def_static() ` * - Static fields - :cpp:func:`.def_ro_static() `, :cpp:func:`.def_rw_static() ` * - Static properties - :cpp:func:`.def_prop_ro_static() `, :cpp:func:`.def_prop_rw_static() ` .. note:: All of these binding declarations support :ref:`docstrings `, :ref:`keyword, and default argument ` annotations as before. .. _binding_lambdas: Binding lambda functions ------------------------ Note how ``print(d)`` produced a rather useless summary in the example above: .. code-block:: pycon >>> print(d) To address this, we can add a special Python method named ``__repr__`` that returns a human-readable summary. Unfortunately, a corresponding function with such functionality does not currently exist in the C++ type, and it would be nice if we did not have to modify it. We can bind a *lambda function* to achieve both goals: .. code-block:: cpp nb::class_(m, "Dog") // ... skipped ... .def("__repr__", [](const Dog &p) { return ""; }); nanobind supports both stateless [#f1]_ and stateful lambda closures. Higher order functions ---------------------- nanobind's support for higher-order functions [#f2]_ further blurs the language boundary. The snippet below extends the ``Dog`` class with higher-order function ``bark_later()`` that calls :cpp:func:`nb::cpp_function() ` to convert and return a *stateful* C++ lambda function (``callback``) as a Python function object. .. code-block:: cpp nb::class_(m, "Dog") // ... skipped ... .def("bark_later", [](const Dog &p) { auto callback = [name = p.name] { nb::print(nb::str("{}: woof!").format(name)); }; return nb::cpp_function(callback); }); The lambda function captures the ``Dog::name()`` property (a C++ ``std::string``) and in turn calls Python functions (:cpp:func:`nb::print() `, :cpp:func:`nb::str::format() `) to print onto the console. Here is an example use of the binding in Python: .. code-block:: pycon >>> f = d.bark_later() >>> f >>> f() Charlie: woof! Wrap-up ------- This concludes the basic part of the documentation, which provided a first taste of nanobind and typical steps needed to create a custom extension. The upcoming intermediate-level material covers performance and safety-critical points: - C++ and Python can exchange information in various different ways. *Which one is best for a particular task?* - A bound object can simultaneously exist in both C++ and Python. *Who owns it?* *When is it safe to delete it?* Following these topics, the documentation revisits function and class bindings in full detail. .. [#f1] Stateless closures are those with an empty pair of brackets ``[]`` as the capture object. .. [#f2] Higher-order functions are functions that take functions as arguments and/or return them. wjakob-nanobind-6c4457b/docs/bazel.rst000066400000000000000000000166351474760012700177170ustar00rootroot00000000000000.. _bazel: Building extensions using Bazel =============================== If you prefer the Bazel build system to CMake, you can build extensions using the `nanobind-bazel `__ project. .. note:: This project is a community contribution maintained by `Nicholas Junge `__, please report issues directly in the nanobind-bazel repository linked above. .. _bazel-setup: Adding nanobind-bazel to your Bazel project ------------------------------------------- To use nanobind-bazel in your project, you need to add it to your project's dependency graph. Using bzlmod, the de-facto dependency management system in Bazel starting with version 7.0, you can simply specify it as a ``bazel_dep`` in your MODULE.bazel file: .. code-block:: python # Place this in your MODULE.bazel file. # The major version of nanobind-bazel is equal to the version # of the internally used nanobind. # In this case, we are building bindings with nanobind v2.4.0. bazel_dep(name = "nanobind_bazel", version = "2.4.0") To instead use a development version from GitHub, you can declare the dependency as a ``git_override()`` in your MODULE.bazel: .. code-block:: python # MODULE.bazel bazel_dep(name = "nanobind_bazel", version = "") git_override( module_name = "nanobind_bazel", commit = COMMIT_SHA, # replace this with the actual commit you want. remote = "https://github.com/nicholasjng/nanobind-bazel", ) In local development scenarios, you can clone nanobind-bazel to your machine, and then declare it as a ``local_path_override()`` dependency: .. code-block:: python # MODULE.bazel bazel_dep(name = "nanobind_bazel", version = "") local_path_override( module_name = "nanobind_bazel", path = "/path/to/nanobind-bazel/", # replace this with the actual path. ) .. note:: At minimum, Bazel version 7.0.0 is required to use nanobind-bazel. .. _bazel-build: Declaring and building nanobind extension targets ------------------------------------------------- The main tool to build nanobind C++ extensions for your Python bindings is the :py:func:`nanobind_extension` rule. Like all public nanobind-bazel APIs, it resides in the ``build_defs`` submodule. To import it into a BUILD file, use the builtin ``load`` command: .. code-block:: python # In a BUILD file, e.g. my_project/BUILD load("@nanobind_bazel//:build_defs.bzl", "nanobind_extension") nanobind_extension( name = "my_ext", srcs = ["my_ext.cpp"], ) In this short snippet, a nanobind Python module called ``my_ext`` is declared, with its contents coming from the C++ source file of the same name. Conveniently, only the actual module name must be declared - its place in your Python project hierarchy is automatically determined by the location of your build file. For a comprehensive list of all available build rules in nanobind-bazel, refer to the rules section in the :ref:`nanobind-bazel API reference `. .. _bazel-stable-abi: Building against the stable ABI ------------------------------- As in nanobind's CMake config, you can build bindings targeting Python's stable ABI, starting from version 3.12. To do this, specify the target version using the ``@nanobind_bazel//:py-limited-api`` flag. For example, to build extensions against the CPython 3.12 stable ABI, pass the option ``@nanobind_bazel//:py-limited-api="cp312"`` to your ``bazel build`` command. For more information about available flags, refer to the flags section in the :ref:`nanobind-bazel API reference `. Generating stubs for built extensions ------------------------------------- You can also use Bazel to generate stubs for an extension directly at build time with the ``nanobind_stubgen`` macro. Here is an example of a nanobind extension with a stub file generation target declared directly alongside it: .. code-block:: python # Same as before in a BUILD file load( "@nanobind_bazel//:build_defs.bzl", "nanobind_extension", "nanobind_stubgen", ) nanobind_extension( name = "my_ext", srcs = ["my_ext.cpp"], ) nanobind_stubgen( name = "my_ext_stubgen", module = ":my_ext", ) You can then generate stubs on an extension by invoking ``bazel run //my_project:my_ext_stubgen``. Note that this requires actually running the target instead of only building it via ``bazel build``, since a Python script needs to be executed for stub generation. Naturally, since stub generation relies on the given shared object files, the actual extensions are built in the process before invocation of the stub generation script. Building extensions for free-threaded Python -------------------------------------------- Starting from CPython 3.13, bindings extensions can be built for a free-threaded CPython interpreter. This requires two things: First, an eligible toolchain must be defined in your MODULE.bazel file, e.g. like so: .. code-block:: python bazel_dep(name = "rules_python", version = "1.0.0") python = use_extension("@rules_python//python/extensions:python.bzl", "python") python.toolchain(python_version = "3.13") And secondly, the ``@rules_python//python/config_settings:py_freethreaded`` flag must be set to "yes" when building your nanobind extension target, e.g. as ``bazel build //path/to:my_ext --@rules_python//python/config_settings:py_freethreaded=yes``. Then, ``rules_python`` will bootstrap a free-threaded version of your target interpreter, and ``nanobind_bazel`` will define the ``NB_FREE_THREADED`` macro for the libnanobind build, indicating that nanobind should be built with free-threading support. For a comprehensive overview on nanobind with free-threaded Python, refer to the :ref:`free-threading documentation `. nanobind-bazel and Python packaging ----------------------------------- Unlike CMake, which has a variety of projects supporting PEP517-style Python package builds, Bazel does not currently have a fully featured PEP517-compliant packaging backend available. To produce Python wheels containing bindings built with nanobind-bazel, you have various options, with two of the most prominent strategies being 1. Using a wheel builder script with the facilities provided by a Bazel support package for Python, such as ``py_binary`` or ``py_wheel`` from `rules_python `__. This is a lower-level, more complex workflow, but it provides more granular control of how your Python wheel is built. 2. Building all extensions with Bazel through a subprocess, by extending a Python build backend such as ``setuptools``. This allows you to stick to those well-established build tools, like ``setuptools``, at the expense of more boilerplate Python code and slower build times, since Bazel is only invoked to build the bindings extensions (and their dependencies). In general, while the latter method requires less setup and customization, its drawbacks weigh more severely for large projects with more extensions. .. note:: An example of packaging with the mentioned setuptools customization method can be found in the `nanobind_example `__ repository, specifically, on the ``bazel`` branch. It also contains an example of how to customize flag names and set default build options across platforms with a ``.bazelrc`` file. wjakob-nanobind-6c4457b/docs/benchmark.rst000066400000000000000000000172551474760012700205530ustar00rootroot00000000000000.. _benchmarks: Benchmarks ========== .. note:: **TL;DR**: nanobind bindings compile up to **~4× faster** and produce **~5× smaller** binaries with **~10× lower** runtime overheads compared to pybind11. nanobind also outperforms Cython in important metrics (**3-12×** binary size reduction, **1.6-4×** compilation time reduction, similar runtime performance). The following experiments analyze the performance of a large function-heavy (``func``) and class-heavy (``class``) binding microbenchmark compiled using `Boost.Python `__, `Cython `__, `pybind11 `__. The ``pybind11 + smart_holder`` results below refer to a `special branch `__ that addresses long-standing issues related to holder types in pybind11. Each experiment is shown twice: light gray ``[debug]`` columns provide data for a debug build, and ``[opt]`` shows a size-optimized build that is representative of a deployment scenario. The former is included to show that nanobind performance is also good during a typical development workflow. A comparison with `cppyy `_, which uses dynamic compilation, is also shown later. Details on the experimental setup can be found :ref:`below `. Compilation time ---------------- The first plot contrasts the compilation time, where “*number* ×” annotations denote the amount of time spent relative to nanobind. As shown below, nanobind achieves a ~\ **2.7-4.4× improvement** compared to pybind11 and a **1.6-4.4x improvement** compared to Cython. .. image:: images/times.svg :width: 800 :alt: Compilation time benchmark Binary size ----------- The extremely large size of generated binaries has been a persistent problem of many prior binding libraries. nanobind significantly improves this metric in size-optimized builds. There is a ~\ **11× improvement** compared to Boost.Python, a **3-5× improvement** compared to pybind11, and a **3-12× improvement** compared to Cython. .. image:: images/sizes.svg :width: 800 :alt: Compilation size benchmark Performance ----------- The last experiment compares the runtime performance overheads by calling a bound function many times in a loop. Here, it is also interesting to additionally compare against `cppyy `__ (green bar) and a pure Python implementation that runs bytecode without binding overheads (hatched gray bar). The `smart_holder` branch of pybind11 is not explicitly listed since its runtime performance matches the base version. .. image:: images/perf.svg :width: 850 :alt: Runtime performance benchmark This data shows that the overhead of calling a nanobind function is lower than that of an equivalent function call done within CPython. The functions benchmarked here don’t perform CPU-intensive work, so this this mainly measures the overheads of performing a function call, boxing/unboxing arguments and return values, etc. The difference to pybind11 is **significant**: a ~\ **3× improvement** for simple functions, and an **~10× improvement** when classes are being passed around. Complexities in pybind11 related to overload resolution, multiple inheritance, and holders are the main reasons for this difference. Those features were either simplified or completely removed in nanobind. The runtime performance of Cython and nanobind are similar (Cython leads in one experiment and trails in another one). Cython generates specialized binding code for every function and class, which is highly redundant (long compile times, large binaries) but can also be beneficial for performance. Finally, there is a **~1.6-2.1× improvement** in both experiments compared to cppyy (please ignore the two ``[debug]`` columns—I did not feel comfortable adjusting the JIT compilation flags; all cppyy bindings are therefore optimized.) Discussion ---------- Performance improvements compared to pybind11 are the result of optimizations discussed in the :ref:`previous section `. `cppyy `_ also achieves good performance in the comparison above. It is based on dynamic parsing of C++ code and *just-in-time* (JIT) compilation of bindings via the LLVM compiler infrastructure. The authors of cppyy report that their tool produces bindings with much lower overheads compared to pybind11, and the above plots show that this is indeed true. While nanobind retakes the performance lead, there are other qualitative factors make these two tools appropriate to different audiences: cppyy has its origin in CERN's ROOT mega-project and must be highly dynamic to work with that codebase: it can parse header files to generate bindings as needed. cppyy works particularly well together with PyPy and can avoid boxing/unboxing overheads with this combination. The main downside of cppyy is that it depends on Cling/Clang/LLVM that must be deployed on the user's side and then run there. There isn't a way of pre-generating bindings and then shipping just the output of this process. nanobind is relatively static in comparison: you must tell it which functions to expose via binding declarations. These declarations offer a high degree of flexibility that users will typically use to create bindings that feel *pythonic*. At compile-time, those declarations turn into a sequence of CPython API calls, which produces self-contained bindings that are easy to redistribute via `PyPI `_ or elsewhere. Tools like `cibuildwheel `_ and `scikit-build `_ can fully automate the process of generating *Python wheels* for each target platform. A `minimal example project `_ shows how to do this automatically via `GitHub Actions `_. .. _benchmark_details: Details ------- The microbenchmark wraps a *large* number of trivial functions that only perform a few additions. The objective of this is to quantify the overhead of bindings on compilation time, binary size, and runtime performance. The function-heavy benchmark (``func_*``) consists of 720 declarations of the form (with permuted integer types) .. code-block:: cpp m.def("test_0050", [](uint16_t a, int64_t b, int32_t c, uint64_t d, uint32_t e, float f) { return a+b+c+d+e+f; }); while the latter (``class_*``) does exactly the same computation but packaged up in ``struct``\ s with bindings. .. code-block:: cpp struct Struct50 { uint16_t a; int64_t b; int32_t c; uint64_t d; uint32_t e; float f; Struct50(uint16_t a, int64_t b, int32_t c, uint64_t d, uint32_t e, float f) : a(a), b(b), c(c), d(d), e(e), f(f) { } float sum() const { return a+b+c+d+e+f; } }; py::class_(m, "Struct50") .def(py::init()) .def("sum", &Struct50::sum); The code to generate the plots shown above is available `here `_. Each test was compiled in debug mode (``debug``) and with optimizations (``opt``) that minimize size (i.e., ``-Os``). Benchmarking was performed on a AMD Ryzen 9 7950X workstation running Ubuntu 22.04.2 LTS. CPU boost was disabled, and all core clock frequencies were pinned. Reported timings are the median of five runs. Compilation used clang++ 15.0.7 with consistent compilation flags for all experiments (see the referenced notebook file for detail). The used package versions were Python 3.10.6, cppyy 1.12.13, Cython 0.29.28, and nanobind 1.2.0. wjakob-nanobind-6c4457b/docs/building.rst000066400000000000000000000111371474760012700204070ustar00rootroot00000000000000.. _building: Setting up a build system ######################### This section assumes that you have followed the instructions to :ref:`install ` nanobind. The easiest way to compile a nanobind-based extension involves a CMake-based build system. Other build systems can likely be used as well, but they are not officially supported. (The first section of the :ref:`CMake API reference ` mentions some alternatives.) Here, we will create a new package from scratch. If you already have an existing CMake build system, it should be straightforward to merge some of the following snippets into it. Preliminaries ------------- Begin by creating a new file named ``CMakeLists.txt`` in the root directory of your project. It should start with the following lines that declare a project name and tested CMake version range. The third line line searches for Python >= 3.8 including the ``Development.Module`` component required by nanobind. The name of this module changed across CMake versions, hence the additional conditional check. .. code-block:: cmake cmake_minimum_required(VERSION 3.15...3.27) project(my_project) # Replace 'my_project' with the name of your project if (CMAKE_VERSION VERSION_LESS 3.18) set(DEV_MODULE Development) else() set(DEV_MODULE Development.Module) endif() find_package(Python 3.8 COMPONENTS Interpreter ${DEV_MODULE} REQUIRED) Add the following lines below. They configure CMake to perform an optimized *release* build by default unless another build type is specified. Without this addition, binding code may run slowly and produce large binaries. .. code-block:: cmake if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE) set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") endif() Finding nanobind ---------------- Next, we must inform CMake about the presence of nanobind so that it can load the functionality needed to compile extension modules. The details of this step depend on *how you installed* nanobind, in the :ref:`previous section `. 1. If you installed nanobind as a Pip or Conda package, append the following lines at the end of ``CMakeLists.txt``. They query the package to determine its installation path and then import it. .. code-block:: cmake # Detect the installed nanobind package and import it into CMake execute_process( COMMAND "${Python_EXECUTABLE}" -m nanobind --cmake_dir OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE nanobind_ROOT) find_package(nanobind CONFIG REQUIRED) 2. If you installed nanobind as a `Git submodule `_, append the following lines at the end of ``CMakeLists.txt`` to point CMake to the directory where nanobind is checked out. .. code-block:: cmake add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/ext/nanobind) Building an extension --------------------- Finally, we are ready to build an extension! Append the following line at the end of ``CMakeLists.txt``. It will compile a new extension named ``my_ext`` from the source code contained in the file ``my_ext.cpp``. .. code-block:: cmake nanobind_add_module(my_ext my_ext.cpp) :cmake:command:`nanobind_add_module` resembles standard CMake commands like ``add_executable()`` and ``add_library()``. Any number of source code and header files can be declared when the extension is more complex and spread out over multiple files. .. note:: One opinionated choice of :cmake:command:`nanobind_add_module` is that it optimizes the *size* of the extension by default (i.e., ``-Os`` is passed to the compiler regardless of the project-wide settings). You must specify the ``NOMINSIZE`` parameter to the command to disable this behavior and, e.g., optimize extension code for speed (i.e., ``-O3``): .. code-block:: cmake nanobind_add_module(my_ext NOMINSIZE my_ext.cpp) The default is chosen this way since extension code usually wraps existing C++ libraries, in which the main computation takes place. Optimizing the bindings for speed does not measurably improve performance, but it does make the bindings *significantly* larger. If you observe slowdowns when porting a pybind11 extension, or if your extension performs significant amounts of work within the binding layer, then you may want to experiment with passing the ``NOMINSIZE`` parameter. The :ref:`next section ` will review the contents of example module implementation in ``my_ext.cpp``. wjakob-nanobind-6c4457b/docs/changelog.rst000066400000000000000000002225661474760012700205530ustar00rootroot00000000000000.. _changelog: .. cpp:namespace:: nanobind Changelog ######### nanobind uses a `semantic versioning `__ policy for its API. It also has a separate ABI version that is *not* subject to semantic versioning. The ABI version is relevant whenever a type binding from one extension module should be visible in another nanobind-based extension module. In this case, both modules must use the same nanobind ABI version, or they will be isolated from each other. Releases that don't explicitly mention an ABI version below inherit that of the preceding release. Version 2.5.0 (Feb 2, 2025) --------------------------- - Added :cpp:class:`nb::def_visitor\<..\> `, which can be used to define your own binding logic that operates on a :cpp:class:`nb::class_\<..\> ` when an instance of the visitor object is passed to :cpp:func:`class_::def()`. This generalizes the mechanism used by :cpp:class:`init`, :cpp:class:`new_`, etc, so that you can create binding abstractions that "feel like" the built-in ones. (PR `#884 `__) - Added some special forms for :cpp:class:`nb::typed\ ` (PR `#835 `__): - ``nb::typed`` or ``nb::typed`` produces a parameter or return value that will be described like ``T`` in function signatures but accepts any Python object at runtime. - ``nb::typed`` produces a Python callable signature ``Callable[[Args...], R]``; similarly, ``nb::typed`` (with a literal ellipsis) produces the Python ``Callable[..., R]``. - It is now possible to create Python subclasses of C++ classes that define their constructor bindings using :cpp:struct:`nb::new_() `. Previously, attempting to instantiate such a Python subclass would instead produce an instance of the base C++ type. Note that it is still not possible to override virtual methods in such a Python subclass, because the object returned by the :cpp:struct:`new_() ` constructor will generally not be an instance of the alias/trampoline type. (PR `#859 `__) - Fixed the :cpp:class:`nb::int_ ` constructor so that it casts to an integer when invoked with a floating point argument. - Multi-level inheritance (e.g., `A → B → C`) previously did not work on Python 3.12+ when a base class (e.g., ``A``) provided a trampoline implementation. This is now fixed. (commit `92d9cb `__). - Fixed (benign) reference leads that could occur when ``std::shared_ptr`` instances were still alive at interpreter shutdown time. (commit `fb8157 `__). - The floating-point type caster now only performs value-changing narrowing conversions during the implicit conversion phase. They can be entirely avoided by passing the :cpp:func:`.noconvert() ` argument annotation (PR `#829 `__). - The ``std::complex`` type caster now only performs value-changing narrowing conversions during the implicit conversion phase. They can be entirely avoided by passing the :cpp:func:`.noconvert() ` argument annotation. Also, during the implicit conversion phase, if the Python object is not a complex number object but has a ``__complex__()`` method, it will be called (PR `#854 `__). - Fixed an overly strict check that could cause a function taking an :cpp:class:`nb::ndarray\<...\> ` to refuse specific types of column-major input without implicit conversion. (PR `#847 `__, commit `b95eb7 `__). Fixes for free-threaded builds ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Fixed a race condition in free-threaded extensions that could occur when :cpp:func:`nb::make_iterator ` was concurrently used by multiple threads (PR `#832 `__). - Fixed a race condition in free-threaded extensions that could occur when multiple threads access the Python object associated with the same C++ instance, which does not exist yet and therefore must be created. (issue `#867 `__, PR `#887 `__). - Removed double-checked locking patterns in accesses to internal data structures to ensure correct free-threaded behavior on architectures with weak memory ordering such as ARM (PR `#819 `__). Version 2.4.0 (Dec 6, 2024) --------------------------- - Added a function annotation :cpp:class:`nb::call_policy\() ` which supports custom function wrapping logic, calling ``Policy::precall()`` before the bound function and ``Policy::postcall()`` after. This is a low-level interface intended for advanced users. The precall and postcall hooks are able to observe the Python objects forming the function arguments and return value, and the precall hook can change the arguments. See the linked documentation for more details, important caveats, and an example policy. (PR `#767 `__) - :cpp:func:`nb::make_iterator ` now accepts its iterator arguments by value, rather than by forwarding reference, in order to eliminate the hazard of storing a dangling C++ iterator reference in the returned Python iterator object. (PR `#788 `__) - The ``std::variant`` type_caster now does two passes when converting from Python. The first pass is done without implicit conversions. This fixes an issue where ``std::variant`` might cast a Python object wrapping a ``T`` to a ``U`` if there is an implicit conversion available from ``T`` to ``U``. (issue `#769 `__) - Restored support for constructing types with an overloaded ``__new__`` that takes no arguments, which regressed with the constructor vector call acceleration that was added in nanobind 2.2.0. (issue `#786 `__) - Bindings for augmented assignment operators (as generated, for example, by ``.def(nb::self += nb::self)``) now return the same object in Python in the typical case where the C++ operator returns a reference to ``*this``. Previously, after ``a += b``, ``a`` would be replaced with a copy. (PR `#803 `__) - Added an overload to :cpp:func:`nb::isinstance ` which tests if a Python object is an instance of a Python class. This is in addition to the existing overload, which tests if a Python object is an instance of a bound C++ class. (PR `#805 `__). - Added support for overriding static properties, such as those defined using ``def_prop_ro_static``, in subclasses. Previously this would fail with an error. (PR `#806 `__). - Other minor fixes and improvements. (PRs `#771 `__, `#772 `__, `#748 `__, and `#753 `__) Version 2.3.0 ------------- There is no version 2.3.0 due to a deployment mishap. Version 2.2.0 (October 3, 2024) ------------------------------- - nanobind can now target `free-threaded Python `__, which replaces the `Global Interpreter Lock (GIL) `__ with a fine-grained locking scheme (see `PEP 703 `__) to better leverage multi-core parallelism. A :ref:`separate documentation page ` explains this in detail (PRs `#695 `__, `#720 `__) - nanobind has always used `PEP 590 vector calls `__ to efficiently dispatch calls to function and method bindings, but it lacked the ability to do so for constructors (e.g., ``MyType(arg1, arg2, ...)``). Version 2.2.0 adds this missing part, which accelerates object construction by up to a factor of 2×. The difference is especially pronounced when passing keyword arguments to constructors. Note that this improvement only applies to Python version 3.9 and newer (PR `#706 `__, commits `#e24d7f `__, `#0acecb `__, `#77f910 `__, `#2c96d5 `__). * A new :cpp:class:`nb::is_flag() ` annotation in :cpp:class:`nb::enum_\() ` produces enumeration bindings deriving from :py:class:`enum.Flag`, which enables bit-wise combination using compatible operators (``&``, ``|``, ``^``, and ``~``). Further combining the annotation with :cpp:class:`nb::is_arithmetic() ` creates enumerations deriving from :py:class:`enum.IntFlag`. (PRs `#599 `__, `#688 `__, `#688 `__, `#727 `__, `#732 `__) * A refactor of :cpp:class:`nb::ndarray\<...\> ` was an opportunity to realize three usability improvements: 1. The constructor used to return new nd-arrays from C++ now considers all template arguments: - **Memory order**: :cpp:class:`c_contig`, :cpp:class:`f_contig`. - **Shape**: :cpp:class:`nb::shape\<3, 4, 5\> `, etc. - **Device type**: :cpp:class:`nb::device::cpu `, :cpp:class:`nb::device::cuda `, etc. - **Framework**: :cpp:class:`nb::numpy `, :cpp:class:`nb::pytorch `, etc. - **Data type**: ``uint64_t``, ``std::complex``, etc. Previously, only the **framework** and **data type** annotations were taken into account when returning nd-arrays, while all of them were examined when *accepting* arrays during overload resolution. This inconsistency was a repeated source of confusion among users. To give an example, the following now works out of the box without the need to redundantly specify the shape and strides to the ``Array`` constructor below: .. code-block:: cpp using Array = nb::ndarray, nb::f_contig>; struct Matrix4f { float m[4][4]; Array data() { return Array(m); } }; nb::class_(m, "Matrix4f") .def("data", &Matrix4f::data, nb::rv_policy::reference_internal); 2. A new nd-array :cpp:func:`.cast() ` method forces the immediate creation of a Python object with the specified target framework and return value policy, while preserving the type signature in return values. This is useful to :ref:`return temporaries (e.g. stack-allocated memory) ` from functions. 3. Added a new and more general mechanism ``nanobind::detail::dtype_traits`` to declare custom ndarray data types like ``float16`` or ``bfloat16``. The old interface (``nanobind::ndarray_traits``) still exists but is deprecated and will be removed in the next major release. See the :ref:`documentation ` for details. There are two minor but potentially breaking changes: 1. The nd-array type caster now interprets the :cpp:enumerator:`nb::rv_policy::automatic_reference ` return value policy analogously to the :cpp:enumerator:`nb::rv_policy::automatic `, which means that it references a memory region when the user specifies an ``owner``, and it otherwise copies. This makes it safe to use the :cpp:func:`nb::cast() ` and :cpp:func:`nb::ndarray::cast() ` functions that use this policy as a default. 2. The :cpp:class:`nb::any_contig ` memory order annotation, which previously did nothing, now accepts C- or F-contiguous arrays and rejects non-contiguous ones. For further details on the nd-array changes, see PR `#721 `__, For further details on the nd-array changes, see PR `#742 `__, and commit `4647ef `__. - The NVIDIA CUDA compiler (``nvcc``) is now explicitly supported and included in nanobind's CI test suite (PR `#710 `__). * Added support for return value policy customization to the type casters of ``Eigen::Ref<...>`` and ``Eigen::Map<...>`` (commit `67316e `__). * Added the :cpp:class:`bytearray` wrapper type. (PR `#654 `__) * The :cpp:class:`nb::ellipsis ` type now renders as ``...`` when used in :cpp:class:`nb::typed\<...\> ` (PR `#705 `__). * The :cpp:class:`nb::sig("...") ` annotation now supports `inline type parameter lists `__ such as ``def first[T](l: Sequence[T]) -> T`` (PR `#704 `__). * Fixed implicit conversion of complex nd-arrays. (issue `#709 `__) * Casting via :cpp:func:`nb::cast ` can now specify an owner object for use with the :cpp:enumerator:`nb::rv_policy::reference_internal ` return value policy (PR `#667 `__). * The ``std::optional`` type caster is now implemented in such a way that it can also accommodate non-STL frameworks, such as Boost, Abseil, etc. (PR `#675 `__) * ABI version 15. * Minor fixes and improvements (PRs `#703 `__, `#724 `__, `#723 `__, `#722 `__, `#715 `__, `#696 `__, `#693 `__, commit `75d259 `__). Version 2.1.0 (Aug 11, 2024) ---------------------------- * Temporary workaround for a internal compiler error in version 17.10 of the MSVC compiler. This workaround will be removed once fixed versions are deployed on GitHub actions. (issue `#613 `__, commit `f2438b `__). * nanobind no longer prevents casting to a C++ container of pointers ``T*`` where ``T`` is a type with a user-defined type caster if the caster seems to operate by extracting a ``T*`` from the Python object rather than a ``T``. This change was prompted by discussion `#605 `__. * Switched nanobind wheel generation from `setuptools `__ to `scikit-build-core `__ (PR `#618 `__). * Improved handling of ``const``-ness in :cpp:class:`nb::ndarray ` (PR `#491 `__). * Keyword argument annotations are now properly supported with :cpp:struct:`nb::new_ `, passed in the same way they would be with :cpp:struct:`nb::init `. (issue `#668 `__) * Ability to use :cpp:func:`nb::cast ` to create object with the :cpp:enumerator:`nb::rv_policy::reference_internal ` return value policy (PR `#667 `__). * Enable ``char`` type caster to produce ``'\0'`` (PR `#661 `__). * Added ``.def_static()`` member to :cpp:class:`nb::enum_ `, which had been lost in a redesign of the enumeration implementation in nanobind version 2.0.0. (commit `38990e `__). * Fixes for two minor sources of memory leaks (PR `#595 `__, `#647 `__). * The nd-array wrapper :cpp:class:`nb::ndarray ` now properly handles CuPy arrays (`#594 `__). * Added :cpp:func:`nb::hash() `, a wrapper for the Python ``hash()`` function (commit `91fafa5 `__). * Various minor ``stubgen`` fixes (PRs `#667 `__, `#658 `__, `#632 `__, `#620 `__, `#592 `__). Version 2.0.0 (May 23, 2024) ---------------------------- The 2.0.0 release of nanobind is entirely dedicated to *types* [#f1]_! The project has always advertised seamless Python ↔ C++ interoperability, and this release tries to bring a similar level of interoperability to static type checkers like `MyPy `__, `PyRight `__, `PyType `__, and editors with interactive autocompletion like `Visual Studio Code `__, `PyCharm `__, and many other `LSP `__-compatible IDEs. This required work on three fronts: 1. **Stub generation**: the above tools all analyze Python code statically without running it. Because the import mechanism of compiled extensions depends the Python interpreter, these tools weren't able to inspect the contents of nanobind-based extensions. The usual solution involves writing `stubs `__ that expose the module contents to static analysis tools. However, writing stubs by hand is tedious and error-prone. This release adds tooling to automatically extract stubs from existing extensions. The process is fully integrated into the CMake-based build system and explained in a :ref:`new documentation section `. 2. **Better default annotations**: once stubs were available, this revealed the next problem: the default nanobind-provided function and class signatures were too rudimentary, and this led to a user poor experience. The release therefore improves many builtin type caster so that they produce more accurate type signatures. For example, the STL ``std::vector`` caster now renders as ``collections.abc.Sequence[T]`` in stubs when it is used as an *input*, and ``list[T]`` when it is used as part of a return value. The :cpp:func:`nb::make_*_iterator() ` family of functions return typed iterators, etc. 3. **Advanced customization**: a subset of the type signatures in larger binding projects will generally require further customization. The features listed below aim to enable precisely this: * In Python, many built-in types are *generic* and can be *parameterized* (e.g., ``list[int]``). The :cpp:class:`nb::typed\ ` wrapper enables such parameterization within C++ (for example, the ``int``-specialized list would be written as ``nb::typed``). :ref:`Read more `. * The opposite is also possible: passing :cpp:class:`nb::is_generic() ` to the class binding constructor .. code-block:: cpp nb::class_(m, "MyType", nb::is_generic()) produces a *generic* type that can be parameterized in Python (e.g. ``MyType[int]``). :ref:`Read more `. * The :cpp:class:`nb::sig ` annotation overrides the signature of a function or method, e.g.: .. code-block:: cpp m.def("f", &f, nb::sig("def f(x: Foo = Foo(0)) -> None"), "docstring"); Each binding of an overloaded function can be customized separately. This feature can be used to add decorators or control how default arguments are rendered. :ref:`Read more `. * The :cpp:class:`nb::sig ` annotation can also override *class signatures* in generated stubs. Stubs often take certain liberties in deviating somewhat from the precise type signature of the underlying implementation. For example, the following annotation adds an abstract base class advertising that the class implements a typed iterator. .. code-block:: cpp using IntVec = std::vector; nb::class_(m, "IntVec", nb::sig("class IntVec(collections.abc.Iterable[int])")); Nanobind can't subclass Python types, hence this declaration is technically untrue. On the flipside, such a declaration can assist static checkers and improve auto-completion in visual IDEs. This is fine since these tools only perform a static analysis and never import the actual extension. :ref:`Read more `. * The :cpp:struct:`nb::for_setter ` and :cpp:struct:`nb::for_getter ` annotations enable passing function binding annotations (e.g., signature overrides) specifically to the setter or the getter part of a property. * The :cpp:class:`nb::arg("name") ` argument annotation (and ``"name"_a`` shorthand) now have a :cpp:func:`.sig("signature") ` member to control how a default value is rendered in the stubs and docstrings. This provides more targeted control compared to overriding the entire function signature. * Finally, nanobind's stub generator supports :ref:`pattern files ` containing custom stub replacement rules. This catch-all solution addresses the needs of advanced binding projects, for which the above list of features may still not be sufficient. Most importantly, it was possible to support these improvements with minimal changes to the core parts of nanobind. These release breaks API and ABI compatibility, requiring a new major version according to `SemVer `__. The following changes are noteworthy: * The :cpp:class:`nb::enum_\() ` binding declaration is now a wrapper that creates either a :py:class:`enum.Enum` or :py:class:`enum.IntEnum`-derived type. Previously, nanobind relied on a custom enumeration base class that was a frequent source of friction for users. This change may break code that casts entries to integers, which now only works for arithmetic (:py:class:`enum.IntEnum`-derived) enumerations. Replace ``int(my_enum_entry)`` with ``my_enum_entry.value`` to work around the issue. * The :cpp:func:`nb::bind_vector\() ` and :cpp:func:`nb::bind_map\() ` interfaces were found to be severely flawed since element access (``__getitem__``) created views into the internal state of the STL type that were not stable across subsequent modifications. This could lead to unexpected changes to array elements and undefined behavior when the underlying storage was reallocated (i.e., use-after-free). nanobind 2.0.0 improves these types so that they are safe to use, but this means that element access must now copy by default, potentially making them less convenient. The documentation of :cpp:func:`nb::bind_vector\() ` discusses the issue at length and presents alternative solutions. * The functions :cpp:func:`nb::make_iterator() `, :cpp:func:`nb::make_value_iterator() ` and :cpp:func:`nb::make_key_iterator() ` suffer from the same issue as :cpp:func:`nb::bind_vector() ` explained above. nanobind 2.0.0 improves these operations so that they are safe to use, but this means that iterator access must now copy by default, potentially making them less convenient. The documentation of :cpp:func:`nb::make_iterator() ` discusses the issue and presents alternative solutions. * The ``nb::raw_doc`` annotation was found to be too inflexible and was removed in this version. * The ``nb::typed`` wrapper listed above actually already existed in previous nanobind versions but was awkward to use, as it required the user to provide a custom type formatter. This release makes the interface more convenient. * The ``nb::any`` placeholder to specify an unconstrained :cpp:class:`nb::ndarray ` axis was removed. This name was given to a new wrapper type :cpp:class:`nb::any` indicating ``typing.Any``-typed values. All use of ``nb::any`` in existing code must be replaced with ``-1`` (for example, ``nb::shape<3, nb::any, 4>`` → ``nb::shape<3, -1, 4>``). * :ref:`Keyword-only arguments ` are now supported, and can be indicated using the new :cpp:struct:`nb::kw_only() ` function annotation. (PR `#448 `__). * nanobind classes now permit overriding ``__new__``, in order to support C++ singletons, caches, and other types that expose factory functions rather than ordinary constructors. Read the section on :ref:`customizing Python object creation ` for more details. (PR `#473 `__). * When binding methods on a class ``T``, nanobind will now produce a Python function that expects a self argument of type ``T``. Previously, it would use the type of the member pointer to determine the Python function signature, which could be a base of ``T``, which would create problems if nanobind did not know about that base. (PR `#471 `__). * nanobind can now handle keyword arguments that are not interned, which avoids spurious ``TypeError`` exceptions in constructs like ``fn(**pickle.loads(...))``. The speed of normal function calls (which generally do have interned keyword arguments) should be unaffected. (PR `#469 `__). * The ``owner=nb::handle()`` default value of the :cpp:class:`nb::ndarray ` constructor was removed since it was bug-prone. You now have to specify the owner explicitly. The previous default (``nb::handle()``) continues to be a valid argument. * There have been some changes to the API for type casters in order to avoid undefined behavior in certain cases. (PR `#549 `__). * Type casters that implement custom cast operators must now define a member function template ``can_cast()``, which returns false if ``operator cast_t()`` would raise an exception and true otherwise. ``can_cast()`` will be called only after a successful call to ``from_python()``, and might not be called at all if the caller of ``operator cast_t()`` can cope with a raised exception. (Users of the ``NB_TYPE_CASTER()`` convenience macro need not worry about this; it produces cast operators that never raise exceptions, and therefore provides a ``can_cast()`` that always returns true.) * Many type casters for container types (``std::vector``, ``std::optional``, etc) implement their ``from_python()`` methods by delegating to another, "inner" type caster (``T`` in these examples) that is allocated on the stack inside ``from_python()``. Container casters implemented in this way should make two changes in order to take advantage of the new safety features: * Wrap your ``flags`` (received as an argument of the outer caster's ``from_python`` method) in ``flags_for_local_caster()`` before passing them to ``inner_caster.from_python()``. This allows nanobind to prevent some casts that would produce dangling pointers or references. * If ``inner_caster.from_python()`` succeeds, then also verify ``inner_caster.template can_cast()`` before you execute ``inner_caster.operator cast_t()``. A failure of ``can_cast()`` should be treated the same as a failure of ``from_python()``. This avoids the possibility of an exception being raised through the noexcept ``load_python()`` method, which would crash the interpreter. The previous ``cast_flags::none_disallowed`` flag has been removed; it existed to avoid one particular source of exceptions from a cast operator, but ``can_cast()`` now handles that problem more generally. * ABI version 14. .. rubric:: Footnote .. [#f1] The author of this library had somewhat of a revelation after switching to a `new editor `__ and experiencing the benefits of interactive Python code completion and type checking for the first time. This experience also showed how nanobind-based extension were previously a second-class citizen in this typed world, prompting the changes in this release. Version 1.9.2 (Feb 23, 2024) ---------------------------- * Nanobind instances can now be :ref:`made weak-referenceable ` by specifying the :cpp:class:`nb::is_weak_referenceable ` tag in the :cpp:class:`nb::class_\<..\> ` constructor. (PR `#335 `__, commits `fc7709 `__, `3562f6 `__). * Added a :cpp:class:`nb::bool_ ` wrapper type. (PR `#382 `__, commit `90dfba `__). * Ensure that the GIL is held when releasing :cpp:class:`nb::ndarray `. (issue `#377 `__, commit `a968e8 `__). * :cpp:func:`nb::try_cast() ` no longer crashes the interpreter when attempting to cast a Python ``None`` to a C++ type that was bound using :cpp:class:`nb::class_\<...\> `. Previously this would raise an exception from the cast operator, which would result in a call to ``std::terminate()`` because :cpp:func:`try_cast() ` is declared ``noexcept``. (PR `#386 `__). * Fixed memory corruption in a PyPy-specific code path in :cpp:func:`nb::module_::def_submodule() ` (commit `21eaff `__). * Don't implicitly convert complex to non-complex nd-arrays. (issue `#364 `__, commit `ea2569 `__). * Support for non-assignable types in the ``std::optional`` type caster (PR `#358 `__, commit `9c9b64 `__). * nanobind no longer assumes that docstrings provided to function binding (of type ``const char *``) have an infinite lifetime and it makes copy. (issue `#393 `__, commit `b3b6f4 `__). * Don't pass compiler flags if they may be unsupported by the used compiler. This gets NVCC to work out of the box (that said, this change does not elevate NVCC to being an *officially* supported compiler). (issue `#383 `__, commit `a307ea `__). * Added a CMake install target to the nanobind build system. (PR `#356 `__, commit `6bde65 `__, commit `978dbb `__, commit `f5d8de `__). * ABI version 13. * Minor fixes and improvements. Version 1.9.0-1.9.1 (Feb 18, 2024) ---------------------------------- Releases withdrawn because of a regression. The associated changes are listed above in the 1.9.2 release notes. Version 1.8.0 (Nov 2, 2023) --------------------------- * nanobind now considers two C++ ``std::type_info`` instances to be equal when their mangled names match. The previously used pointer comparison was fast but fragile and often caused multi-part extensions to not recognize each other's types. This version introduces a two-level caching scheme (search by pointer, then by name) to fix such problems once and for all, while avoiding the cost of constantly comparing very long mangled names. (commit `b515b1 `__). * Fixed casting of complex-valued constant :cpp:class:`nb::ndarray\ ` instances. (PR `#338 `__, commit `ba8c7f `__). * Added a type caster for ``std::nullopt_t`` (PR `#350 `__). * Added the missing C++ → Python portion of the type caster for ``Eigen::Ref<..>`` (PR `#334 `__). * Minor fixes and improvements. * ABI version 12. Version 1.7.0 (Oct 19, 2023) ---------------------------- New features ^^^^^^^^^^^^ * The nd-array class :cpp:class:`nb::ndarray\ ` now supports complex-valued ``T`` (e.g., ``std::complex``). For this, the header file ``nanobind/stl/complex.h`` must be included. (PR `#319 `__, commit `6cbd13 `__). * Added the function :cpp:func:`nb::del() `, which takes an arbitrary accessor object as input and tries to delete the associated entry. The C++ statement .. code-block:: cpp nb::del(o[key]); is equivalent to ``del o[key]`` in Python. (commit `4dd745 `__). * Exposed several convenience functions for raising exceptions as public API: :cpp:func:`nb::raise `, :cpp:func:`nb::raise_type_error `, and :cpp:func:`nb::raise_python_error `. (commit `0b7f3b `__). * Added :cpp:func:`nb::globals() `. (PR `#311 `__, commit `f0a9eb `__). * The ``char*`` type caster now accepts ``nullptr`` and converts it into a Python ``None`` object. (PR `#318 `__, commit `30a6ba `__). * Added the function :cpp:func:`nb::is_alive() `, which returns ``false`` when nanobind was destructed by Python (e.g., during interpreter shutdown) making further use of the API illegal. (commit `b431d0 `__). * Minor fixes and improvements. * ABI version 11. Bugfixes ^^^^^^^^ * The behavior of the :cpp:class:`nb::keep_alive\ ` function binding annotation was changed as follows: when the function call requires the implicit conversion of an argument, the lifetime constraint now applies to the newly produced argument instead of the original object. The change was rolled into a minor release since the former behavior is arguably undesirable and dangerous. (commit `9d4b2e `__). * STL type casters previously raised an exception when casting a Python container containing a ``None`` element into a C++ container that was not able to represent ``nullptr`` (e.g., ``std::vector`` instead of ``std::vector``). However, this exception was raised in a context where exceptions were not allowed, causing the process to be ``abort()``-ed, which is very bad. This issue is now fixed, and such conversions are refused. (PR `#318 `__, commits `d1ad3b `__ and `5f25ae `__). * The STL sequence casters (``std::vector``, etc.) now refuse to unpack ``str`` and ``bytes`` objects analogous to pybind11. (commit `7e4a88 `__). Version 1.6.2 (Oct 3, 2023) --------------------------- * Added a missing include file used by the new intrusive reference counting sample implementation from v1.6.0. (commit `31d115 `__). Version 1.6.1 (Oct 2, 2023) --------------------------- * Added missing namespace declaration to the :cpp:class:`ref` intrusive reference counting RAII helper class added in version 1.6.0. (commit `3ba352 `__). Version 1.6.0 (Oct 2, 2023) --------------------------- New features ^^^^^^^^^^^^ * Several :cpp:class:`nb::ndarray\<..\> ` improvements: 1. CPU loops involving nanobind nd-arrays weren't getting properly vectorized. This release of nanobind adds *views*, which provide an efficient abstraction that enables better code generation. See the documentation section on :ref:`array views ` for details. (commit `8f602e `__). 2. Added support for nonstandard arithmetic types (e.g., ``__int128`` or ``__fp16``) in nd-arrays. See the :ref:`documentation section ` for details. (commit `49eab2 `__). 3. Shape constraints like :cpp:class:`nb::shape\ ` are tedious to write. Now, there is a shorter form: :cpp:class:`nb::ndim\<3\> `. (commit `1350a5 `__). 4. Added an explicit constructor that can be used to add or remove nd-array constraints. (commit `a1ac207 `__). * Added the wrapper class :cpp:class:`nb::weakref `. (commit `78887f `__). * Added the methods :cpp:func:`nb::dict::contains() ` and :cpp:func:`nb::mapping::contains() ` to the Python type wrappers. (commit `64d87a `__). * Added :cpp:func:`nb::exec() ` and :cpp:func:`nb:eval() `. (PR `#299 `__). * Added a type caster for ``std::complex``. (PR `#292 `__, commit `dcbed4 `__). * Added an officially supported sample implementation of :ref:`intrusive reference counting ` via the :cpp:class:`intrusive_counter` :cpp:class:`intrusive_base`, and :cpp:class:`ref` classes. (commit `3fa1af `__). Bugfixes ^^^^^^^^ * Fixed a serious issue involving combinations of bound types (e.g., ``T``) and type casters (e.g., ``std::vector``), where nanobind was too aggressive in its use of *move semantics*. Calling a bound function from Python taking such a list (e.g., ``f([t1, t2, ..])``) would destruct ``t1, t2, ..`` if the type ``T`` exposed a move constructor, which is highly non-intuitive and no longer happens as of this fix. Further investigation also revealed inefficiencies in the previous implementation where moves were actually possible but not done (e.g., for functions taking an STL vector by value). Some binding projects may see speedups as a consequence of this change. (issue `#307 `__, commit `122015 `__). Version 1.5.2 (Aug 24, 2023) ---------------------------- * Fixed a severe issue with inheritance of the ``Py_TPFLAGS_HAVE_GC`` flag affecting classes that derive from other classes with a :cpp:class:`nb::dynamic_attr ` annotation. (issue `#279 `__, commit `dbedad `__). * Implicit conversion of nd-arrays to conform to contiguity constraints such as :cpp:class:`c_contig` and :cpp:class:`f_contig` previously failed in some cases that are now addressed. (issue `#278 `__ commit `ed929b `__). Version 1.5.1 (Aug 23, 2023) ---------------------------- * Fixed serious reference counting issue introduced in nanobind version 1.5.0, which affected the functions :cpp:func:`python_error::traceback()` and :cpp:func:`python_error::what()`, causing undefined behavior via use-after-free. Also addressed an unrelated minor UB sanitizer warning. (issue `#277 `__, commits `30d30c `__ and `c48b18 `__). * Extended the internal data structure tag so that it isolates different MSVC versions from each other (they are often not ABI compatible, see pybind11 issue `#4779 `__). This means that nanobind 1.5.1 effectively bumps the ABI version to "10.5" when compiling for MSVC, and the internals will be isolated from extensions built with nanobind v1.5.0 or older. (commit `c7f3cd `__). * Incorporated fixes so that nanobind works with PyPy 3.10. (commits `fb5508 `__ and `2ed10a `__). * Fixed type caster for ``std::vector``. (PR `#256 `__). * Fixed compilation in debug mode on MSVC. (PR `#253 `__). Version 1.5.0 (Aug 7, 2023) --------------------------- * Support for creating :ref:`chained exceptions ` via the :cpp:func:`nb::raise_from() ` and :cpp:func:`nb::chain_error() ` functions. (commits `041520 `__ and `beb699 `__). * Many improvements to the handling of return value policies in :cpp:class:`nb::ndarray\<..\> ` to avoid unnecessary copies. (commit `ffd22b `__, `a79575 `__, and `6f0c3f `__). * The :cpp:class:`nb::ndarray\<..\> ` class now has an additional convenience constructor that takes the shape and (optionally) strides using ``std::initializer_list``. (commit `de1117 `__). * Added a non-throwing function :cpp:func:`nb::try_cast() ` as an alternative to :cpp:func:`nb::cast() `. (commit `6ca852 `__). * The ``nb::list`` and ``nb::tuple`` default constructors now construct an empty list/tuple instead of an invalid null-initialized handle. (commit `506185 `__) * New low-level interface for wrapping existing C++ instances via :cpp:func:`nb::inst_take_ownership() ` :cpp:func:`nb::inst_reference() `. Also added convenience functions to replace the contents of an instance with that of another. :cpp:func:`nb::inst_replace_copy() ` along with :cpp:func:`nb::inst_replace_move() ` (commit `1c462d `__). * Added a low-level abstraction around :cpp:func:`nb::type_get_slot() ` around ``PyType_GetSlot``, but with more consistent behavior across Python versions. (commit `d555e9 `__). * The :cpp:func:`nb::list::append() ` method now performs perfect forwarding. (commit `2219d0 `__). * Inference of ``automatic*`` return value policy was entirely moved to the base C++ class type caster. (commit `1ff9df `__). * Switch to the new Python 3.12 error status API if available. (commit `36751c `__). * Various minor fixes and improvements. * ABI version 10. Version 1.4.0 (June 8, 2023) ---------------------------- * Improved the efficiency of the function dispatch loop. (PR `#227 `__). * Significant improvements to the Eigen type casters (generalized stride handling to avoid unnecessary copies, support for conversion via ``nb::cast()``, many refinements to the ``Eigen::Ref`` interface). (PR `#215 `__). * Added a ``NB_DOMAIN`` parameter to :cmake:command:`nanobind_add_module` which can isolate extensions from each other to avoid binding clashes. See the associated :ref:`FAQ entry ` for details. (commit `977119 `__). * Reduced the severity of nanobind encountering a duplicate type binding (commits `f3b0e6 `__, and `2c9124 `__). * Support for pickling/unpickling nanobind objects. (commit `59843e `__). * ABI version 9. Version 1.3.2 (June 2, 2023) ---------------------------- * Fixed compilation on 32 bit processors (only ``i686`` tested so far). (PR `#224 `__). * Fixed compilation on PyPy 3.8. (commit `cd8135 `__). * Reduced binary bloat of musllinux wheels. (commit `f52513 `__). Version 1.3.1 (May 31, 2023) ---------------------------- * CMake build system improvements for stable ABI wheel generation. (PR `#222 `__). Version 1.3.0 (May 31, 2023) ---------------------------- This is a big release. The sections below cover added features, efficiency improvements, and miscellaneous fixes and improvements. New features ^^^^^^^^^^^^ * nanobind now supports binding types that inherit from ``std::enable_shared_from_this``. See the :ref:`advanced section on object ownership ` for more details. (PR `#212 `__). * Added a type caster between Python ``datetime``/``timedelta`` objects and C++ ``std::chrono::duration``/``std::chrono::time_point``, ported from pybind11. (PR `#175 `__). * The :cpp:class:`nb::ndarray\<..\> ` class can now use the buffer protocol to receive and return arrays representing read-only memory. (PR `#217 `__). * Added :cpp:func:`nb::python_error::discard_as_unraisable() ` as a wrapper around ``PyErr_WriteUnraisable()``. (PR `#175 `__). Efficiency improvements: ^^^^^^^^^^^^^^^^^^^^^^^^ * Reduced the per-instance overhead of nanobind by 1 pointer and simplified the internal hash table types to crunch ``libnanobind``. (commit `de018d `__). * Supplemental type data specified via :cpp:class:`nb::supplement\() ` is now stored directly within the type object instead of being referenced through an indirection. (commit `d82ca9 `__). * Reduced the number of exception-related exports to further crunch ``libnanobind``. (commit `763962 `__). * Reduced the size of nanobind type objects by 5 pointers. (PR `#194 `__, `#195 `__, and commit `d82ca9 `__). * Internal nanobind types (``nb_type``, ``nb_static_property``, ``nb_ndarray``) are now constructed on demand. This reduces the size of the ``libnanobind`` component in static (``NB_STATIC``) builds when those features are not used. (commits `95e45a `__, `375083 `__, and `e033c8 `__). * Added a small function cache to improve code generation in limited API builds. (commit `f0f4aa `__). * Refined compiler and linker flags across platforms to ensure compact binaries especially in ``NB_STATIC`` builds. (commit `5ead9f `__) * nanobind enums now take advantage of :ref:`supplemental data ` to improve the speed of object and name lookups. Note that this prevents use of ``nb::supplement()`` with enums for other purposes. (PR `#195 `__). Miscellaneous fixes and improvements ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * Use the new `PEP-697 `__ interface to access data in type objects when compiling stable ABI3 wheels. This improves forward compatibility (the Python team may at some point significantly refactor the layout and internals of type objects). (PR `#211 `__): * Added introspection attributes ``__self__`` and ``__func__`` to nanobind bound methods, to make them more like regular Python bound methods. Fixed a bug where ``some_obj.method.__call__()`` would behave differently than ``some_obj.method()``. (PR `#216 `__). * Updated the implementation of :cpp:class:`nb::enum_ ` so it does not take advantage of any private nanobind type details. As a side effect, the construct ``nb::class_(..., nb::is_enum(...))`` is no longer permitted; use ``nb::enum_(...)`` instead. (PR `#195 `__). * Added the :cpp:class:`nb::type_slots_callback` class binding annotation, similar to :cpp:class:`nb::type_slots` but allowing more dynamic choices. (PR `#195 `__). * nanobind type objects now treat attributes specially whose names begin with ``@``. These attributes can be set once, but not rebound or deleted. This safeguard allows a borrowed reference to the attribute value to be safely stashed in the type supplement, allowing arbitrary Python data associated with the type to be accessed without a dictionary lookup while keeping this data visible to the garbage collector. (PR `#195 `__). * Fixed surprising behavior in enumeration comparisons and arithmetic (PR `#207 `__): * Enum equality comparisons (``==`` and ``!=``) now can only be true if both operands have the same enum type, or if one is an enum and the other is an ``int``. This resolves some confusing results and ensures that enumerators of different types have a distinct identity, which is important if they're being put into the same set or used as keys in the same dictionary. All of the following were previously true but will now evaluate as false: * ``FooEnum(1) == BarEnum(1)`` * ``FooEnum(1) == 1.2`` * ``FooEnum(1) == "1"`` * Enum ordering comparisons (``<``, ``<=``, ``>=``, ``>``) and arithmetic operations (when using the :cpp:struct:`is_arithmetic` annotation) now require that any non-enum operand be a Python number (an object that defines ``__int__``, ``__float__``, and/or ``__index__``) and will avoid truncating non-integer operands to integers. Note that unlike with equality comparisons, ordering and arithmetic operations *do* still permit two operands that are enums of different types. Some examples of changed behavior: * ``FooEnum(1) < 1.2`` is now true (used to be false) * ``FooEnum(2) * 1.5`` is now 3.0 (used to be 2) * ``FooEnum(3) - "2"`` now raises an exception (used to be 1) * Enum comparisons and arithmetic operations with unsupported types now return `NotImplemented` rather than raising an exception. This means equality comparisons such as ``some_enum == None`` will return unequal rather than failing; order comparisons such as ``some_enum < None`` will still fail, but now with a more informative error. * ABI version 8. Version 1.2.0 (April 24, 2023) ------------------------------ * Improvements to the internal C++ → Python instance map data structure to improve performance and address type confusion when returning previously registered instances. (commit `716354 `__, discussion `189 `__). * Added up-to-date nanobind benchmarks on Linux including comparisons to Cython. (commit `834cf3 `__ and `39e163 `__). * Removed the superfluous ``nb_enum`` metaclass. (commit `9c1985 `__). * Fixed a corner case that prevented ``nb::cast`` from working. (commit `9ae320 `__). Version 1.1.1 (April 6, 2023) ----------------------------- * Added documentation on packaging and distributing nanobind modules. (commit `0715b2 `__). * Made the conversion :cpp:func:`handle::operator bool() ` explicit. (PR `#173 `__). * Support :cpp:class:`nb::typed\<..\> ` in return values. (PR `#174 `__). * Tweaks to definitions in ``nb_types.h`` to improve compatibility with further C++ compilers (that said, there is no change about the official set of supported compilers). (commit `b8bd10 `__) Version 1.1.0 (April 5, 2023) ----------------------------- * Added :cpp:func:`size `, :cpp:func:`shape_ptr `, :cpp:func:`stride_ptr ` members to to the :cpp:class:`nb::ndarray\<..\> ` class. (PR `#161 `__). * Allow macros in :c:macro:`NB_MODULE(..) ` name parameter. (PR `#168 `__). * The :cpp:class:`nb::ndarray\<..\> ` interface is more tolerant when converting Python (PyTorch/NumPy/..) arrays with a size-0 dimension that have mismatched strides. (PR `#162 `__). * Removed the ```` label from docstrings of anonymous functions, which caused issues in MyPy. (PR `#172 `__). * Fixed an issue in the propagation of return value policies that broke user-provided/custom policies in properties (PR `#170 `__). * The Eigen interface now converts 1x1 matrices to 1x1 NumPy arrays instead of scalars. (commit `445781 `__). * The ``nanobind`` package now has a simple command line interface. (commit `d5ccc8 `__). Version 1.0.0 (March 28, 2023) ------------------------------ * Nanobind now has a logo. (commit `b65d31 `__). * Fixed a subtle issue involving function/method properties and the IPython command line interface. (PR `#151 `__). * Added a boolean type to the :cpp:class:`nb::ndarray\<..\> ` interface. (PR `#150 `__). * Minor fixes and improvements. Version 0.3.1 (March 8, 2023) ----------------------------- * Added a type caster for ``std::filesystem::path``. (PR `#138 `__ and commit `0b05cd `__). * Fixed technical issues involving implicit conversions (commits `022935 `__ and `5aefe3 `__) and construction of type hierarchies with custom garbage collection hooks (commit `022935 `__). * Re-enabled the 'chained fixups' linker optimization for recent macOS deployment targets. (commit `2f29ec `__). Version 0.3.0 (March 8, 2023) ----------------------------- * Botched release, replaced by 0.3.1 on the same day. Version 0.2.0 (March 3, 2023) ----------------------------- * Nanobind now features documentation on `readthedocs `__. * The documentation process revealed a number of inconsistencies in the :cpp:func:`class_\::def* ` naming scheme. nanobind will from now on use the following shortened and more logical interface: .. list-table:: :widths: 40 60 :header-rows: 1 * - Type - method * - Methods & constructors - :cpp:func:`.def() ` * - Fields - :cpp:func:`.def_ro() `, :cpp:func:`.def_rw() ` * - Properties - :cpp:func:`.def_prop_ro() `, :cpp:func:`.def_prop_rw() ` * - Static methods - :cpp:func:`.def_static() ` * - Static fields - :cpp:func:`.def_ro_static() `, :cpp:func:`.def_rw_static() ` * - Static properties - :cpp:func:`.def_prop_ro_static() `, :cpp:func:`.def_prop_rw_static() ` Compatibility wrappers with deprecation warnings were also added to help port existing code. They will be removed when nanobind reaches version 1.0. (commits `cb0dc3 `__ and `b5ed96 `__) * The ``nb::tensor<..>`` class has been renamed to :cpp:class:`nb::ndarray\<..\> `, and it is now located in a different header file (``nanobind/ndarray.h``). A compatibility wrappers with a deprecation warning was retained in the original header file. It will be removed when nanobind reaches version 1.0. (commit `a6ab8b `__). * Dropped the first two arguments of the :c:macro:`NB_OVERRIDE_*() ` macros that turned out to be unnecessary in nanobind. (commit `22bc21 `__). * Added casters for dense matrix/array types from the `Eigen library `__. (PR `#120 `__). * Added casters for sparse matrix/array types from the `Eigen library `__. (PR `#126 `_). * Implemented `nb::bind_vector\() ` analogous to similar functionality in pybind11. (commit `f2df8a `__). * Implemented :cpp:func:`nb::bind_map\() ` analogous to similar functionality in pybind11. (PR `#114 `__). * nanobind now :ref:`automatically downcasts ` polymorphic objects in return values analogous to pybind11. (commit `cab96a `__). * nanobind now supports :ref:`tag-based polymorphism `. (commit `6ade94 `__). * Updated tuple/list iterator to satisfy the ``std::forward_iterator`` concept. (PR `#117 `__). * Fixed issues with non-writeable tensors in NumPy. (commit `25cc3c `__). * Removed use of some C++20 features from the codebase. This now makes it possible to use nanobind on Visual Studio 2017 and GCC 7.3.1 (used on RHEL 7). (PR `#115 `__). * Added the :cpp:class:`nb::typed\<...\> ` wrapper to override the type signature of an argument in a bound function in the generated docstring. (commit `b3404c4 `__). * Added an :cpp:func:`nb::implicit_convertible\() ` function analogous to the one in pybind11. (commit `aba4af `__). * Updated :cpp:func:`nb::make_*_iterator\<..\>() ` so that it returns references of elements, not copies. (commit `8916f5 `__). * Changed the CMake build system so that the library component (``libnanobind``) is now compiled statically by default. (commit `8418a4 `__). * Switched shared library linking on macOS back to a two-level namespace. (commit `fe4965 `__). * Various minor fixes and improvements. * ABI version 7. Version 0.1.0 (January 3, 2023) ------------------------------- * Allow nanobind methods on non-nanobind) classes. (PR `#104 `__). * Fix dangling `tp_members` pointer in type initialization. (PR `#99 `__). * Added a runtime setting to suppress leak warnings. (PR `#109 `__). * Added the ability to hash ``nb::enum_<..>`` instances (PR `#106 `__). * Fixed the signature of ``nb::enum_<..>::export_values()``. (commit `714d17 `__). * Double-check GIL status when performing reference counting operations in debug mode. (commit `a1b245 `__). * Fixed a reference leak that occurred when module initialization fails. (commit `adfa9e `__). * Improved robustness of ``nb::tensor<..>`` caster. (commit `633672 `__). * Upgraded the internally used ``tsl::robin_map<>`` hash table to address a rare `overflow issue `__ discovered in this codebase. (commit `3b81b1 `__). * Various minor fixes and improvements. * ABI version 6. Version 0.0.9 (Nov 23, 2022) ---------------------------- * PyPy 7.3.10 or newer is now supported subject to `certain limitations `__. (commits `f935f93 `__ and `b343bbd `__). * Three changes that reduce the binary size and improve runtime performance of binding libraries. (commits `07b4e1fc `__, `9a803796 `__, and `cba4d285 `__). * Fixed a reference leak in ``python_error::what()`` (commit `61393ad `__). * Adopted a new policy for function type annotations. (commit `c855c90 `__). * Improved the effectiveness of link-time-optimization when building extension modules with the ``NB_STATIC`` flag. This leads to smaller binaries. (commit `f64d2b9 `__). * Nanobind now relies on standard mechanisms to inherit the ``tp_traverse`` and ``tp_clear`` type slots instead of trying to reimplement the underlying CPython logic (commit `efa09a6b `__). * Moved nanobind internal data structures from ``builtins`` to Python interpreter state dictionary. (issue `#96 `__, commit `ca23da7 `__). * Various minor fixes and improvements. Version 0.0.8 (Oct 27, 2022) ---------------------------- * Caster for ``std::array<..>``. (commit `be34b16 `__). * Caster for ``std::set<..>`` and ``std::unordered_set`` (PR `#87 `__). * Ported ``nb::make[_key_,_value]_iterator()`` from pybind11. (commit `34d0be1 `__). * Caster for untyped ``void *`` pointers. (commit `6455fff `__). * Exploit move constructors in ``nb::class_::def_readwrite()`` and ``nb::class_::def_readwrite_static()`` (PR `#94 `__). * Redesign of the ``std::function<>`` caster to enable cyclic garbage collector traversal through inter-language callbacks (PR `#95 `__). * New interface for specifying custom type slots during Python type construction. (commit `38ba18a `__). * Fixed potential undefined behavior related to ``nb_func`` garbage collection by Python's cyclic garbage collector. (commit `662e1b9 `__). * Added a workaround for spurious reference leak warnings caused by other extension modules in conjunction with ``typing.py`` (commit `5e11e80 `__). * Various minor fixes and improvements. * ABI version 5. Version 0.0.7 (Oct 14, 2022) ---------------------------- * Fixed a regression involving function docstrings in ``pydoc``. (commit `384f4a `__). Version 0.0.6 (Oct 14, 2022) ---------------------------- * Fixed undefined behavior that could lead to crashes when nanobind types were freed. (commit `39266e `__). * Refactored nanobind so that it works with ``Py_LIMITED_API`` (PR `#37 `__). * Dynamic instance attributes (PR `#38 `__). * Intrusive pointer support (PR `#43 `__). * Byte string support (PR `#62 `__). * Casters for ``std::variant<..>`` and ``std::optional<..>`` (PR `#67 `__). * Casters for ``std::map<..>`` and ``std::unordered_map<..>`` (PR `#73 `__). * Caster for ``std::string_view<..>`` (PR `#68 `__). * Custom exception support (commit `41b7da `__). * Register nanobind functions with Python's cyclic garbage collector (PR `#86 `__). * Various minor fixes and improvements. * ABI version 3. Version 0.0.5 (May 13, 2022) ---------------------------- * Enumeration export. * Implicit number conversion for numpy scalars. * Various minor fixes and improvements. Version 0.0.4 (May 13, 2022) ---------------------------- * Botched release, replaced by 0.0.5 on the same day. Version 0.0.3 (Apr 14, 2022) ---------------------------- * DLPack support. * Iterators for various Python type wrappers. * Low-level interface to instance creation. * Docstring generation improvements. * Various minor fixes and improvements. Version 0.0.2 (Mar 10, 2022) ---------------------------- * Initial release of the nanobind codebase. * ABI version 1. Version 0.0.1 (Feb 21, 2022) ---------------------------- * Placeholder package on PyPI. wjakob-nanobind-6c4457b/docs/classes.rst000066400000000000000000001072051474760012700202510ustar00rootroot00000000000000.. _classes: .. cpp:namespace:: nanobind Classes ======= The material below builds on the section on :ref:`binding custom types ` and reviews advanced scenarios involving object-oriented code. Frequently used --------------- Click on the following :cpp:class:`nb::class_\<..\>::def_* ` members for examples on how to bind various different kinds of methods, fields, etc. .. list-table:: :widths: 40 60 :header-rows: 1 * - Type - method * - Methods & constructors - :cpp:func:`.def() ` * - Fields - :cpp:func:`.def_ro() `, :cpp:func:`.def_rw() ` * - Properties - :cpp:func:`.def_prop_ro() `, :cpp:func:`.def_prop_rw() ` * - Static methods - :cpp:func:`.def_static() ` * - Static fields - :cpp:func:`.def_ro_static() `, :cpp:func:`.def_rw_static() ` * - Static properties - :cpp:func:`.def_prop_ro_static() `, :cpp:func:`.def_prop_rw_static() ` .. _inheritance: Subclasses ---------- Consider the following two data structures with an inheritance relationship: .. code-block:: cpp struct Pet { std::string name; }; struct Dog : Pet { std::string bark() const { return name + ": woof!"; } }; To indicate the inheritance relationship to nanobind, specify the C++ base class as an extra template parameter of :cpp:class:`nb::class_\<..\> `: .. code-block:: cpp :emphasize-lines: 8 #include NB_MODULE(my_ext, m) { nb::class_(m, "Pet") .def(nb::init()) .def_rw("name", &Pet::name); nb::class_(m, "Dog") .def(nb::init()) .def("bark", &Dog::bark); } Alternatively, you can also pass the type object as an ordinary parameter. .. code-block:: cpp :emphasize-lines: 5 auto pet = nb::class_(m, "Pet") .def(nb::init()) .def_rw("name", &Pet::name); nb::class_(m, "Dog", pet /* <- Parent type object */) .def(nb::init()) .def("bark", &Dog::bark); Instances expose fields and methods of both types as expected: .. code-block:: pycon >>> d = my_ext.Dog("Molly") >>> d.name 'Molly' >>> d.bark() 'Molly: woof!' .. _automatic_downcasting: Automatic downcasting --------------------- nanobind obeys signatures when returning regular non-polymorphic C++ objects from functions: building on the :ref:`previous example `, consider the following function that returns a ``Dog`` object as a ``Pet`` base pointer. .. code-block:: cpp m.def("pet_store", []() { return (Pet *) new Dog{"Molly"}; }); nanobind cannot safely determine that this is in fact an instance of the ``Dog`` subclass. Consequently, only fields and methods of the base type remain accessible: .. code-block:: pycon >>> p = my_ext.pet_store() >>> type(p) >>> p.bark() AttributeError: 'Pet' object has no attribute 'bark' In C++, a type is only considered `polymorphic `_ if it (or one of its base classes) has at least one *virtual function*. Let's add a virtual default destructor to make ``Pet`` and its subtypes polymorphic. .. code-block:: cpp struct Pet { virtual ~Pet() = default; std::string name; }; With this change, nanobind is able to inspect the returned C++ instance's `virtual table `_ and infer that it can be represented by a more specialized Python object of type ``my_ext.Dog``. .. code-block:: pycon >>> p = my_ext.pet_store() >>> type(p) >>> p.bark() 'Molly: woof!' .. note:: Automatic downcasting of polymorphic instances is only supported when the subtype has been registered using :cpp:class:`nb::class_\<..\> `. Otherwise, the return type listed in the function signature takes precedence. .. _overloaded_methods: Overloaded methods ------------------ Sometimes there are several overloaded C++ methods with the same name taking different kinds of input arguments: .. code-block:: cpp struct Pet { Pet(const std::string &name, int age) : name(name), age(age) { } void set(int age_) { age = age_; } void set(const std::string &name_) { name = name_; } std::string name; int age; }; Attempting to bind ``Pet::set`` will cause an error since the compiler does not know which method the user intended to select. We can disambiguate by casting them to function pointers. Binding multiple functions to the same Python name automatically creates a chain of function overloads that will be tried in sequence. .. code-block:: cpp nb::class_(m, "Pet") .def(nb::init()) .def("set", nb::overload_cast(&Pet::set), "Set the pet's age") .def("set", nb::overload_cast(&Pet::set), "Set the pet's name"); Here, :cpp:func:`nb::overload_cast ` only requires the parameter types to be specified, and it deduces the return type. .. note:: In cases where a function overloads by ``const``-ness, an additional ``nb::const_`` parameter is needed to select the right overload, e.g., ``nb::overload_cast(&Pet::get, nb::const_)``. To define overloaded constructors, simply declare one after the other using the normal :cpp:class:`.def(nb::init\<...\>()) ` syntax. The overload signatures are also visible in the method's docstring: .. code-block:: pycon >>> help(my_ext.Pet) class Pet(builtins.object) | Methods defined here: | | __init__(...) | __init__(self, arg0: str, arg1: int, /) -> None | | set(...) | set(self, arg: int, /) -> None | set(self, arg: str, /) -> None | | Overloaded function. | | 1. ``set(self, arg: int, /) -> None`` | | Set the pet's age | | 2. ``set(self, arg: str, /) -> None`` | | Set the pet's name The format of the docstring with a leading overload list followed by a repeated list with details is designed to be compatible with the `Sphinx `_ documentation generator. .. _enumerations_and_internal: Enumerations and internal types ------------------------------- Let's now suppose that the example class contains internal types like enumerations, e.g.: .. code-block:: cpp struct Pet { enum Kind { Dog = 0, Cat }; struct Attributes { float age = 0; }; Pet(const std::string &name, Kind type) : name(name), type(type) { } std::string name; Kind type; Attributes attr; }; The binding code for this example looks as follows: .. code-block:: cpp nb::class_ pet(m, "Pet"); pet.def(nb::init()) .def_rw("name", &Pet::name) .def_rw("type", &Pet::type) .def_rw("attr", &Pet::attr); nb::enum_(pet, "Kind") .value("Dog", Pet::Kind::Dog) .value("Cat", Pet::Kind::Cat) .export_values(); nb::class_(pet, "Attributes") .def(nb::init<>()) .def_rw("age", &Pet::Attributes::age); To ensure that the nested types ``Kind`` and ``Attributes`` are created within the scope of ``Pet``, the ``pet`` type object is passed as the ``scope`` argument of the subsequent :cpp:class:`nb::enum_\ ` and :cpp:class:`nb::class_\ ` binding declarations. The :cpp:func:`.export_values() ` function exports the enumeration entries into the parent scope, which should be skipped for newer C++11-style strongly typed enumerations. .. code-block:: pycon >>> from my_ext import Pet >>> p = Pet("Lucy", Pet.Cat) >>> p.attr.age = 3 >>> p.type my_ext.Kind.Cat >>> p.type.__name__ 'Cat' >>> int(p.type) 1 .. note:: When the annotation :cpp:class:`nb::is_arithmetic() ` is passed to :cpp:class:`nb::enum_\ `, the resulting Python type will support arithmetic and bit-level operations (and, or, xor, negation). The operands of these operations may be either enumerators. When the annotation :cpp:class:`nb::is_flag() ` is passed to :cpp:class:`nb::enum_\ `, the resulting Python type will be a class derived from ``enum.Flag``, meaning its enumerators can be combined using bit-wise operators in a type-safe way: the result will have the same enumeration type as the operands, and only enumerators of the same type can be combined. When passing both ``is_arithmetic`` and ``is_flag``, the resulting Python type will be ``enum.IntFlag``, supporting both arithmetic and bit-wise operations. .. code-block:: cpp nb::enum_(pet, "Kind", nb::is_arithmetic()) ... By default, these are omitted. .. _dynamic_attributes: Dynamic attributes ------------------ Native Python classes can pick up new attributes dynamically: .. code-block:: pycon >>> class Pet: ... name = "Molly" ... >>> p = Pet() >>> p.name = "Charly" # overwrite existing >>> p.age = 2 # dynamically add a new attribute By default, classes exported from C++ do not support this and the only writable attributes are the ones explicitly defined using :func:`class_::def_rw` or :func:`class_::def_prop_rw`. .. code-block:: cpp nb::class_(m, "Pet") .def(nb::init<>()) .def_rw("name", &Pet::name); Trying to set any other attribute results in an error: .. code-block:: pycon >>> p = my_ext.Pet() >>> p.name = "Charly" # OK, attribute defined in C++ >>> p.age = 2 # fail AttributeError: 'Pet' object has no attribute 'age' To enable dynamic attributes for C++ classes, the :class:`nb::dynamic_attr ` tag must be added to the :class:`nb::class_ ` constructor: .. code-block:: cpp nb::class_(m, "Pet", nb::dynamic_attr()) .def(nb::init<>()) .def_rw("name", &Pet::name); Now everything works as expected: .. code-block:: pycon >>> p = my_ext.Pet() >>> p.name = "Charly" # OK, overwrite value in C++ >>> p.age = 2 # OK, dynamically add a new attribute Note that there is a small runtime cost for a class with dynamic attributes. Not only because of the addition of an instance dictionary, but also because of more expensive garbage collection tracking which must be activated to resolve possible circular references. Native Python classes incur this same cost by default, so this is not anything to worry about. By default, nanobind classes are more efficient than native Python classes. Enabling dynamic attributes just brings them on par. .. _weak_refs: Weak references --------------- By default, nanobind instances cannot be referenced via Python's ``weakref`` class, and attempting to do so will raise an exception. To support this, add the :class:`nb::is_weak_referenceable ` tag to the :class:`nb::class_ ` constructor. Note that this will increase the size of every instance by ``sizeof(void*)`` due to the need to store a weak reference list. .. code-block:: cpp nb::class_(m, "Pet", nb::is_weak_referenceable()); .. _inheriting_in_python: Extending C++ classes in Python ------------------------------- Bound C++ types can be extended within Python, which is helpful to dynamically extend compiled code with further fields and other functionality. Bind classes with the :cpp:class:`is_final` annotation to forbid subclassing. Consider the following example bindings of a ``Dog`` and ``DogHouse`` class. .. code-block:: cpp #include namespace nb = nanobind; struct Dog { std::string name; std::string bark() const { return name + ": woof!"; } }; struct DogHouse { Dog dog; }; NB_MODULE(my_ext, m) { nb::class_(m, "Dog") .def(nb::init()) .def("bark", &Dog::bark) .def_rw("name", &Dog::name); nb::class_(m, "DogHouse") .def(nb::init()) .def_rw("dog", &DogHouse::dog); } The following Python snippet creates a new ``GuardDog`` type that extends ``Dog`` with an ``.alarm()`` method. .. code-block:: pycon >>> import my_ext >>> class GuardDog(my_ext.Dog): ... def alarm(self, count = 3): ... for i in range(count): ... print(self.bark()) ... >>> gd = GuardDog("Max") >>> gd.alarm() Max: woof! Max: woof! Max: woof! This Python subclass is best thought of as a "rich wrapper" around an existing C++ base object. By default, that wrapper will disappear when nanobind makes a copy or transfers ownership to C++. .. code-block:: pycon >>> d = my_ext.DogHouse() >>> d.dog = gd >>> d.dog.alarm() AttributeError: 'Dog' object has no attribute 'alarm' To preserve it, adopt a shared ownership model using :ref:`shared pointers ` or :ref:`intrusive reference counting `. For example, updating the code as follows fixes the problem: .. code-block:: cpp #include struct DogHouse { std::shared_ptr dog; }; .. code-block:: pycon >>> d = my_ext.DogHouse() >>> d.dog = gd >>> d.dog.alarm() Max: woof! Max: woof! Max: woof! .. _trampolines: Overriding virtual functions in Python -------------------------------------- Building on the previous example on :ref:`inheriting C++ types in Python `, let's investigate how a C++ *virtual function* can be overridden in Python. In the code below, the virtual method ``bark()`` is called by a global ``alarm()`` function (now written in C++). .. code-block:: cpp :emphasize-lines: 6 #include struct Dog { std::string name; Dog(const std::string &name) : name(name) { } virtual std::string bark() const { return name + ": woof!"; } }; void alarm(Dog *dog, size_t count = 3) { for (size_t i = 0; i < count; ++i) std::cout << dog->bark() << std::endl; } Normally, the binding code would look as follows: .. code-block:: cpp #include namespace nb = nanobind; using namespace nb::literals; NB_MODULE(my_ext, m) { nb::class_(m, "Dog") .def(nb::init()) .def("bark", &Dog::bark) .def_rw("name", &Dog::name); m.def("alarm", &alarm, "dog"_a, "count"_a = 3); } However, this don't work as expected. We can subclass and override without problems, but virtual function calls originating from C++ aren't being propagated to Python: .. code-block:: pycon >>> class ShihTzu(my_ext.Dog): ... def bark(self): ... return self.name + ": yip!" ... >>> dog = ShihTzu("Mr. Fluffles") >>> dog.bark() Mr. Fluffles: yip! >>> my_ext.alarm(dog) Mr. Fluffles: woof! # <-- oops, alarm() is calling the base implementation Mr. Fluffles: woof! Mr. Fluffles: woof! To fix this behavior, you must implement a *trampoline class*. A trampoline has the sole purpose of capturing virtual function calls in C++ and forwarding them to Python. .. code-block:: cpp #include struct PyDog : Dog { NB_TRAMPOLINE(Dog, 1); std::string bark() const override { NB_OVERRIDE(bark); } }; This involves an additional include directive and the line :c:macro:`NB_TRAMPOLINE(Dog, 1) ` to mark the class as a trampoline for the ``Dog`` base type. The count (``1``) denotes to the total number of virtual method slots that can be overridden within Python. .. note:: The number of virtual method slots is used to preallocate memory. Trampoline declarations with an insufficient size may eventually trigger a Python ``RuntimeError`` exception with a descriptive label, e.g.: .. code-block:: text nanobind::detail::get_trampoline('PyDog::bark()'): the trampoline ran out of slots (you will need to increase the value provided to the NB_TRAMPOLINE() macro) The macro :c:macro:`NB_OVERRIDE(bark) ` intercepts the virtual function call, checks if a Python override exists, and forwards the call in that case. If no override was found, it falls back to the base class implementation. You will need to replicate this pattern for every method that should support overriding in Python. The macro accepts an variable argument list to pass additional parameters. For example, suppose that the virtual function ``bark()`` had an additional ``int volume`` parameter---in that case, the syntax would need to be adapted as follows: .. code-block:: cpp std::string bark(int volume) const override { NB_OVERRIDE(bark, volume); } The macro :c:macro:`NB_OVERRIDE_PURE() ` should be used for pure virtual functions, and :c:macro:`NB_OVERRIDE() ` should be used for functions which have a default implementation. There are also two alternate macros :c:macro:`NB_OVERRIDE_PURE_NAME() ` and :c:macro:`NB_OVERRIDE_NAME() ` which take a string as first argument to specify the name of function in Python. This is useful when the C++ and Python versions of the function have different names (e.g., ``operator+`` vs ``__add__``). The binding code needs a tiny adaptation (highlighted) to inform nanobind of the trampoline that will be used whenever Python code extends the C++ class. .. code-block:: cpp nb::class_(m, "Dog") If the :cpp:class:`nb::class_\<..\> ` declaration also specifies a base class, you may specify it and the trampoline in either order. Also, note that binding declarations should be made against the actual class, not the trampoline: .. code-block:: cpp nb::class_(m, "Dog") .def(nb::init()) .def("bark", &PyDog::bark); /* <--- THIS IS WRONG, use &Dog::bark */ With the trampoline in place, our example works as expected: .. code-block:: pycon >>> my_ext.alarm(dog) Mr. Fluffles: yip! Mr. Fluffles: yip! Mr. Fluffles: yip! The following special case needs to be mentioned: you *may not* implement a Python trampoline for a method that returns a reference or pointer to a type requiring :ref:`type casting `. For example, attempting to expose a hypothetical virtual method ``const std::string &get_name() const`` as follows .. code-block:: cpp const std::string &get_name() const override { NB_OVERRIDE(get_name); } will fail with a static assertion failure: .. code-block:: text include/nanobind/nb_cast.h:352:13: error: static_assert failed due to requirement '...' "nanobind::cast(): cannot return a reference to a temporary." This is not a fluke. The Python would return a ``str`` object that nanobind can easily type-cast into a temporary ``std::string`` instance. However, when the virtual function call returns on the C++ side, that temporary will already have expired. There isn't a good solution to this problem, and nanobind therefore simply refuses to do it. You will need to change your approach by either using :ref:`bindings ` instead of :ref:`type casters ` or changing your virtual method interfaces to return by value. .. _operator_overloading: Operator overloading -------------------- Suppose that we're given the following ``Vector2`` class with a vector addition and scalar multiplication operation, all implemented using overloaded operators in C++. .. code-block:: cpp class Vector2 { public: Vector2(float x, float y) : x(x), y(y) { } Vector2 operator+(const Vector2 &v) const { return Vector2(x + v.x, y + v.y); } Vector2 operator*(float value) const { return Vector2(x * value, y * value); } Vector2 operator-() const { return Vector2(-x, -y); } Vector2& operator+=(const Vector2 &v) { x += v.x; y += v.y; return *this; } Vector2& operator*=(float v) { x *= v; y *= v; return *this; } friend Vector2 operator*(float f, const Vector2 &v) { return Vector2(f * v.x, f * v.y); } std::string to_string() const { return "[" + std::to_string(x) + ", " + std::to_string(y) + "]"; } private: float x, y; }; The following snippet shows how the above operators can be conveniently exposed to Python. .. code-block:: cpp #include NB_MODULE(my_ext, m) { nb::class_(m, "Vector2") .def(nb::init()) .def(nb::self + nb::self) .def(nb::self += nb::self) .def(nb::self *= float()) .def(float() * nb::self) .def(nb::self * float()) .def(-nb::self) .def("__repr__", &Vector2::to_string); } Note that a line involving :cpp:var:`nb::self ` like .. code-block:: cpp .def(nb::self * float()) is really just short hand notation for .. code-block:: cpp .def("__mul__", [](const Vector2 &a, float b) { return a * b; }, nb::is_operator()) This can be useful for exposing additional operators that don't exist on the C++ side, or to perform other types of customization. The :cpp:class:`nb::is_operator() ` flag marker is needed to inform nanobind that this is an operator, which returns ``NotImplemented`` when invoked with incompatible arguments rather than throwing a type error. When binding *in-place* operators such as ``operator+=``, and when their implementation is guaranteed to end with ``return *this``, it is recommended that you set a return value policy of :cpp:enumerator:`rv_policy::none`, i.e., .. code-block:: cpp .def(nb::self += nb::self, nb::rv_policy::none) Otherwise, the function binding will return a new copy of the object, which is usually not desired. Binding protected member functions ---------------------------------- It's normally not possible to expose ``protected`` member functions to Python: .. code-block:: cpp class A { protected: int foo() const { return 42; } }; nb::class_(m, "A") .def("foo", &A::foo); // error: 'foo' is a protected member of 'A' On one hand, this is good because non-``public`` members aren't meant to be accessed from the outside. But we may want to make use of ``protected`` functions in derived Python classes. The following pattern makes this possible: .. code-block:: cpp class A { protected: int foo() const { return 42; } }; class Publicist : public A { // helper type for exposing protected functions public: using A::foo; // inherited with different access modifier }; nb::class_(m, "A") // bind the primary class .def("foo", &Publicist::foo); // expose protected methods via the publicist This works because ``&Publicist::foo`` is exactly the same function as ``&A::foo`` (same signature and address), just with a different access modifier. The only purpose of the ``Publicist`` helper class is to make the function name ``public``. If the intent is to expose ``protected`` ``virtual`` functions which can be overridden in Python, the publicist pattern can be combined with the previously described trampoline: .. code-block:: cpp class A { public: virtual ~A() = default; protected: virtual int foo() const { return 42; } }; class Trampoline : public A { public: NB_TRAMPOLINE(A, 1); int foo() const override { NB_OVERRIDE(foo); } }; class Publicist : public A { public: using A::foo; }; nb::class_(m, "A") // <-- `Trampoline` here .def("foo", &Publicist::foo); // <-- `Publicist` here, not `Trampoline`! Binding classes with template parameters ---------------------------------------- nanobind can also wrap classes that have template parameters. Consider these classes: .. code-block:: cpp struct Cat {}; struct Dog {}; template struct PetHouse { PetHouse(PetType& pet); PetType& get(); }; C++ templates may only be instantiated at compile time, so nanobind can only wrap instantiated templated classes. You cannot wrap a non-instantiated template: .. code-block:: cpp // BROKEN (this will not compile) nb::class_(m, "PetHouse"); .def("get", &PetHouse::get); You must explicitly specify each template/type combination that you want to wrap separately. .. code-block:: cpp // ok nb::class_>(m, "CatHouse") .def("get", &PetHouse::get); // ok nb::class_>(m, "DogHouse") .def("get", &PetHouse::get); If your class methods have template parameters you can wrap those as well, but once again each instantiation must be explicitly specified: .. code-block:: cpp typename struct MyClass { template T fn(V v); }; nb::class_>(m, "MyClassT") .def("fn", &MyClass::fn); .. _tag_based_polymorphism: Tag-based polymorphism ---------------------- The section on :ref:`automatic downcasting ` explained how nanobind can infer the type of polymorphic C++ objects at runtime. It can be desirable to extend this automatic downcasting behavior to non-polymorphic classes, for example to support *tag-based polymorphism*. In this case, instances expose a method or field to identify their type. For example, consider the following class hierarchy where ``Pet::kind`` serves this purpose: .. code-block:: cpp #include namespace nb = nanobind; enum class PetKind { Cat, Dog }; struct Pet { const PetKind kind; }; struct Dog : Pet { Dog() : Pet{PetKind::Dog} { } }; struct Cat : Pet { Cat() : Pet{PetKind::Cat} { } }; namespace nb = nanobind; NB_MODULE(my_ext, m) { nb::class_(m, "Pet"); nb::class_(m, "Dog"); nb::class_(m, "Cat"); nb::enum_(m, "PetKind") .value("Cat", PetKind::Cat) .value("Dog", PetKind::Dog); m.def("make_pet", [](PetKind kind) -> Pet* { switch (kind) { case PetKind::Dog: return new Dog(); case PetKind::Cat: return new Cat(); } }); } This code initially doesn't work as expected (the ``make_pet`` function binding always creates instances of the ``Pet`` base class). .. code-block:: pycon >>> my_ext.make_pet(my_ext.PetKind.Cat) >>> my_ext.make_pet(my_ext.PetKind.Dog) To fix this, partially specialize the ``type_hook`` class to provide the ``type_hook::get()`` method: .. code-block:: cpp namespace nanobind::detail { template <> struct type_hook { static const std::type_info *get(Pet *p) { if (p) { switch (p->kind) { case PetKind::Dog: return &typeid(Dog); case PetKind::Cat: return &typeid(Cat); } } return &typeid(Pet); } }; } // namespace nanobind::detail The method will be invoked whenever nanobind needs to convert a C++ pointer of type ``T*`` to a Python object. It should inspect the instance and return a pointer to a suitable RTTI record. With this override, downcasting works as expected: .. code-block:: pycon >>> my_ext.make_pet(my_ext.PetKind.Cat) >>> my_ext.make_pet(my_ext.PetKind.Dog) Binding unions -------------- :cpp:class:`nb::class_\<..\> ` can also be used to provide bindings for `unions `__. A basic and useless example: .. code-block:: cpp union Example { int ival; double dval; std::string to_string(size_t active_idx) const { return active_idx == 1 ? std::to_string(dval) : std::to_string(ival); } }; static_assert(sizeof(Example) == sizeof(double)); nb::class_(m, "Example") .def_rw("ival", &Example::ival) .def_rw("dval", &Example::dval) .def("to_string", &Example::to_string); .. code-block:: pycon >>> u = my_ext.Example() >>> u.ival = 42 >>> u.to_string(0) '42' >>> u.dval = 1.25 >>> u.to_string(1) '1.250000' Direct binding of union variant members is only safe if all members of the union are trivially copyable types (as in this example), but more complex unions can also be supported by binding lambdas or member functions that enforce the necessary invariants. This is a low-level feature and should be used with care; even when all members are trivially copyable, reading from a union member other than the most recently written one produces undefined behavior in C++. Unless you need to bind an existing API that uses union types, you're probably better off using ``std::variant<..>``, which knows what member is active and can thus enforce all the ncessary invariants for you. Pickling -------- To pickle and unpickle objects bound using nanobind, expose the ``__getstate__`` and ``__setstate__`` methods. They should return and retrieve the internal instance state using representations that themselves support pickling. The example below, e.g., does this using a tuple. The ``__setstate__`` method should construct the object in-place analogous to custom ``__init__``-style constructors. .. code-block:: cpp #include struct Pet { std::string name; int age; Pet(const std::string &name, int age) : name(name), age(age) { } }; NB_MODULE(my_ext, m) { nb::class_(m, "Pet") // ... .def("__getstate__", [](const Pet &pet) { return std::make_tuple(pet.name, pet.age); }) .def("__setstate__", [](Pet &pet, const std::tuple &state) { new (&pet) Pet( std::get<0>(state), std::get<1>(state) ); }); } .. _custom_new: Customizing Python object creation ---------------------------------- Sometimes you might need to bind a class that can't be constructed in the usual way: .. code-block:: cpp class Pet { private: Pet(/* ... */); public: static std::unique_ptr make(std::string name, int age); void speak(); }; You can use :cpp:func:`.def_static() ` to produce bindings that let you write ``Pet.make("Fido", 2)`` in Python, just like you would write ``Pet::make("Fido", 2)`` in C++. But sometimes it's nice to provide a more Pythonic interface than that, like ``Pet("Fido", 2)``. To do that, nanobind lets you override ``__new__``. Since this is a rarely-used feature in Python, let's recap. Object initialization in Python occurs in two phases: * the *constructor*, ``__new__``, allocates memory for the object; * the *initializer*, ``__init__``, sets up the object's initial state. So far, all the ways we've seen of binding C++ constructors (:cpp:struct:`nb::init\<..\>() `, ``.def("__init__", ...)``) produce Python object *initializers*. nanobind augments these with its own Python object constructor, which allocates a Python object that has space in its memory layout for the C++ object to slot in. The ``__init__`` method then fills in that space by calling a C++ constructor. This split between ``__new__`` and ``__init__`` has a lot of benefits, including a reduction in unnecessary allocations, but it does mean that anything created from Python must be able to control where its C++ innards are stored. Sometimes, as with the example of ``Pet`` above, that's not feasible. In such cases, you can go down one level and override ``__new__`` directly: .. code-block:: cpp nb::class_(m, "Pet") .def(nb::new_(&Pet::make), "name"_a, "age"_a) .def("speak", &Pet::speak); Passing :cpp:struct:`nb::new_ ` to :cpp:func:`.def() ` here creates two magic methods on ``Pet``: * A ``__new__`` that uses the given function to produce a new ``Pet``. It is converted to a Python object in the same way as the return value of any other function you might write bindings for. In particular, you can pass a :cpp:enum:`nb::rv_policy ` as an additional argument to :cpp:func:`.def() ` to control how this conversion occurs. * A ``__init__`` that takes the same arguments as ``__new__`` but performs no operation. This is necessary because Python automatically calls ``__init__`` on the object returned by ``__new__`` in most cases. You can provide a lambda as the argument of :cpp:struct:`nb::new_ `. This is most useful when the lambda returns a pointer or smart pointer; if it's returning a value, then ``.def("__init__", ...)`` will have better performance. Additionally, you can chain multiple calls to ``.def(nb::new_(...))`` in order to create an overload set. The following example demonstrates both of these capabilities: .. code-block:: cpp nb::class_(m, "Pet") .def(nb::new_([]() { return Pet::make(getRandomName(), 0); })) .def(nb::new_(&Pet::make), "name"_a, "age"_a) .def("speak", &Pet::speak); If you need even more control, perhaps because you need to access the type object that Python passes as the first argument of ``__new__`` (which :cpp:struct:`nb::new_ ` discards), you can write a ``.def_static("__new__", ...)`` and matching ``.def("__init__", ...)`` yourself. Two limitations of :cpp:struct:`nb::new_ ` are worth noting: * The possibilities for Python-side inheritance from C++ classes that are bound using :cpp:struct:`nb::new_ ` constructors are substantially reduced. Simple inheritance situations (``class PyPet(Pet): ...``) should work OK, but you can't :ref:`override virtual functions ` in Python (because the C++ object returned by :cpp:struct:`new_ ` doesn't contain the Python trampoline glue), and if :cpp:struct:`new_ ` is used to implement a polymorphic factory (like if ``Pet::make()`` could return an instance of ``Cat``) then Python-side inheritance won't work at all. * A given C++ class must expose all of its constructors via ``__new__`` or all via ``__init__``, rather than a mixture of the two. The only case where a class should bind both of these methods is if the ``__init__`` methods are all stubs that do nothing. This is because nanobind internally optimizes object instantiation by caching the method that should be used for constructing instances of each given type, and that optimization doesn't support trying both methods. If you really need to combine nontrivial ``__new__`` and nontrivial ``__init__`` in the same type, you can disable the optimization by defining a :ref:`custom type slot ` of ``Py_tp_new`` or ``Py_tp_init``. .. note:: Unpickling an object of type ``Foo`` normally requires that ``Foo.__new__(Foo)`` produce something that ``__setstate__`` can be called on. Any custom :cpp:struct:`nb::new_ ` methods will not satisfy this requirement, because they return a fully-constructed object. In order to maintain pickle compatibility, nanobind by default will add an additional ``__new__`` overload that takes no extra arguments and calls the nanobind built-in :cpp:func:`inst_alloc`. This won't make your class constructible with no arguments, because there's no corresponding ``__init__``; it just helps unpickling work. If your first :cpp:struct:`nb::new_ ` method is one that takes no arguments, then nanobind won't add its own, and you'll have to deal with unpickling some other way. wjakob-nanobind-6c4457b/docs/conf.py000066400000000000000000000177021474760012700173630ustar00rootroot00000000000000#!/usr/bin/env python3 # import os import re # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. # needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ "sphinx_copybutton", "sphinxcontrib.rsvgconverter", "sphinxcontrib.moderncmakedomain", "sphinx.ext.intersphinx", ] intersphinx_mapping = { "python": ("https://docs.python.org/3", None), } # Add any paths that contain templates here, relative to this directory. templates_path = [".templates"] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # source_suffix = ['.rst', '.md'] source_suffix = ".rst" # The encoding of source files. # source_encoding = 'utf-8-sig' # The master toctree document. master_doc = "index" # General information about the project. project = "nanobind" copyright = "2023, Wenzel Jakob" author = "Wenzel Jakob" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # Read the listed version VERSION_REGEX = re.compile( r"^\s*#\s*define\s+NB_VERSION_([A-Z]+)\s+(.*)$", re.MULTILINE) this_directory = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) with open(os.path.join(this_directory, "include/nanobind/nanobind.h")) as f: matches = dict(VERSION_REGEX.findall(f.read())) version = "{MAJOR}.{MINOR}.{PATCH}".format(**matches) # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. language = "en" # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: # today = '' # Else, today_fmt is used as the format for a strftime call. # today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = [".build", "release.rst"] # The reST default role (used for this markup: `text`) to use for all # documents. default_role = "any" # If true, '()' will be appended to :func: etc. cross-reference text. # add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). # add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. # show_authors = False # The name of the Pygments (syntax highlighting) style to use. # pygments_style = 'monokai' # A list of ignored prefixes for module index sorting. # modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. # keep_warnings = False # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = False # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = "furo" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. # html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. # html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". # html_title = None # A shorter title for the navigation bar. Default is the same as html_title. # html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. # html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. # html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". # html_static_path = ["_static"] # html_css_files = [ ] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. # html_extra_path = [] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. # html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. # html_use_smartypants = True # Custom sidebar templates, maps document names to template names. # html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. # html_additional_pages = {} # If false, no module index is generated. # html_domain_indices = True # If false, no index is generated. # html_use_index = True # If true, the index is split into individual pages for each letter. # html_split_index = False # If true, links to the reST sources are added to the pages. # html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. # html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. # html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. # html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). # html_file_suffix = None # Language to be used for generating the HTML full-text search index. # Sphinx supports the following languages: # 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja' # 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr' # html_search_language = 'en' # A dictionary with options for the search language support, empty by default. # Now only 'ja' uses this config value # html_search_options = {'type': 'default'} # The name of a javascript file (relative to the configuration directory) that # implements a search results scorer. If empty, the default will be used. # html_search_scorer = 'scorer.js' # Output file base name for HTML help builder. htmlhelp_basename = "nanobind_doc" # -- Options for LaTeX output --------------------------------------------- latex_engine = "pdflatex" latex_elements = { 'papersize': 'a4paper', 'pointsize': '10pt', "classoptions": ",openany,oneside", "preamble": r""" \usepackage{MnSymbol} \DeclareUnicodeCharacter{25CB}{\ensuremath{\circ}} \DeclareUnicodeCharacter{25CF}{\ensuremath{\bullet}} \DeclareUnicodeCharacter{21B5}{\ensuremath{\rhookswarrow}} \DeclareUnicodeCharacter{2194}{\ensuremath{\leftrightarrow}} """, } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ (master_doc, "nanobind.tex", "nanobind Documentation", author, "manual"), ] # The name of an image file (relative to this directory) to place at the top of # the title page. # latex_logo = 'nanobind-logo.png' # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. # latex_use_parts = False # If true, show page references after internal links. # latex_show_pagerefs = False # If true, show URL addresses after external links. # latex_show_urls = False # Documents to append as an appendix to all manuals. # latex_appendices = [] # If false, no module index is generated. # latex_domain_indices = True primary_domain = "cpp" highlight_language = "cpp" wjakob-nanobind-6c4457b/docs/cppyy.h000066400000000000000000000006601474760012700173740ustar00rootroot00000000000000float test_0000(uint16_t a, int32_t b, uint32_t c, int64_t d, uint64_t e, float f) { return a + b + c + d + e + f; } struct Struct0 { uint16_t a; int32_t b; uint32_t c; int64_t d; uint64_t e; float f; Struct0(uint16_t a, int32_t b, uint32_t c, int64_t d, uint64_t e, float f) : a(a), b(b), c(c), d(d), e(e), f(f) {} float sum() const { return a + b + c + d + e + f; } }; wjakob-nanobind-6c4457b/docs/eigen.rst000066400000000000000000000104551474760012700177030ustar00rootroot00000000000000.. cpp:namespace:: nanobind .. _eigen: The *Eigen* linear algebra library ================================== `Eigen `__ is a header-only C++ library for linear algebra that offers dense and sparse matrix types along with a host of algorithms that operate on them. Owing to its widespread use in many scientific projects, nanobind includes custom type casters that enable bidirectional conversion between Eigen and Python array programming libraries. These casters build on the previously discussed :ref:`n-dimensional array ` class. You can therefore think of this section as an easier interface to the same features that is preferable if your project uses Eigen. Dense matrices and vectors -------------------------- Add the following include directive to your binding code to exchange dense Eigen types: .. code-block:: cpp #include Following this, you should be able to bind functions that accept and return values of type ``Eigen::Matrix<..>``, ``Eigen::Array<..>``, ``Eigen::Vector<..>``, ``Eigen::Ref<..>``, ``Eigen::Map<..>``, and their various specializations. Unevaluated expression templates are also supported. nanobind may need to evaluate or copy the matrix/vector contents during type casting, which is sometimes undesirable. The following cases explain when copying is needed, and how it can be avoided. C++ → Python ^^^^^^^^^^^^ Consider the following C++ function returning a dense Eigen type (``Eigen::MatrixXf`` in this example). The bound Python version of ``f()`` returns this data in the form of a ``numpy.ndarray``. .. code-block:: cpp Eigen::MatrixXf f() { ... } If the C++ function returns *by value*, and when the Eigen type represents an evaluated expression, nanobind will capture and wrap it in a NumPy array without making a copy. All other cases (returning by reference, returning an unevaluated expression template) either evaluate or copy the array. Python → C++ ^^^^^^^^^^^^ The reverse direction is more tricky. Consider the following 3 functions taking variations of a dense ``Eigen::MatrixXf``: .. code-block:: cpp void f1(const Eigen::MatrixXf &x) { ... } void f2(const Eigen::Ref &x) { ... } void f3(const nb::DRef &x) { ... } The Python bindings of these three functions can be called using any of a number of different CPU-resident 2D array types (NumPy arrays, PyTorch/Tensorflow/JAX tensors, etc.). However, the following limitations apply: - ``f1()`` will always perform a copy of the array contents when called from Python. This is because ``Eigen::MatrixXf`` is designed to *own* the underlying storage, which is sadly incompatible with the idea of creating a view of an existing Python array. - ``f2()`` very likely copies as well! This may seem non-intuitive, since ``Eigen::Ref<..>`` exists to avoid this exact problem. The problem is that Eigen normally expects a very specific memory layout (Fortran/column-major layout), while Python array frameworks actually use the *opposite* by default (C/row-major layout). Array slices are even more problematic and always require a copy. - ``f3()`` uses :cpp:type:`nb::DRef ` to support *any* memory layout (row-major, column-major, slices) without copying. It may still perform an implicit conversion when called with the *wrong data type*---for example, the function expects a single precision array, but NumPy matrices often use double precision. If that is undesirable, you may bind the function as follows, in which case nanobind will report a ``TypeError`` if an implicit conversion would be needed. .. code-block:: cpp m.def("f1", &f1, nb::arg("x").noconvert()); This parameter passing convention can also be used to mutate function parameters, e.g.: .. code-block:: cpp void f4(nb::DRef x) { x *= 2; } Sparse matrices --------------- Add the following include directive to your binding code to exchange sparse Eigen types: .. code-block:: cpp #include The ``Eigen::SparseMatrix<..>`` type maps to either ``scipy.sparse.csr_matrix`` or ``scipy.sparse.csc_matrix`` depending on whether row- or column-major storage is used. There is no support for Eigen sparse vectors because an equivalent type does not exist as part of ``scipy.sparse``. wjakob-nanobind-6c4457b/docs/exceptions.rst000066400000000000000000000252751474760012700210030ustar00rootroot00000000000000.. cpp:namespace:: nanobind .. _exceptions: Exceptions ========== .. _exception_conversion: Automatic conversion of C++ exceptions -------------------------------------- When Python calls a C++ function, that function might raise an exception instead of returning a result. In such a case, nanobind will capture the C++ exception and then raise an equivalent exception within Python. This automatic conversion supports ``std::exception``, common subclasses, and several classes that convert to specific Python exceptions as shown below: .. list-table:: :widths: 40 60 :header-rows: 1 * - Exception thrown by C++ - Translated to Python exception type * - ``std::exception`` - ``RuntimeError`` * - ``std::bad_alloc`` - ``MemoryError`` * - ``std::domain_error`` - ``ValueError`` * - ``std::invalid_argument`` - ``ValueError`` * - ``std::length_error`` - ``ValueError`` * - ``std::out_of_range`` - ``IndexError`` * - ``std::range_error`` - ``ValueError`` * - ``std::overflow_error`` - ``OverflowError`` * - :cpp:func:`nb::stop_iteration ` - ``StopIteration`` (used to implement custom iterator) * - :cpp:func:`nb::index_error ` - ``IndexError`` (used to indicate out of bounds access in ``__getitem__``, ``__setitem__``, etc.) * - :cpp:func:`nb::key_error ` - ``KeyError`` (used to indicate an invalid access in ``__getitem__``, ``__setitem__``, etc.) * - :cpp:func:`nb::value_error ` - ``ValueError`` (used to indicate an invalid value in operations like ``container.remove(...)``) * - :cpp:func:`nb::type_error ` - ``TypeError`` * - :cpp:func:`nb::buffer_error ` - ``BufferError`` * - :cpp:func:`nb::import_error ` - ``ImportError`` * - :cpp:func:`nb::attribute_error ` - ``AttributeError`` * - Any other exception - ``SystemError`` Exception translation is not bidirectional. A C++ ``catch (nb::key_error)`` block will not catch a Python ``KeyError``. Use :cpp:class:`nb::python_error ` for this purpose (see the :ref:`example below ` for details). The is also a special exception :cpp:class:`nb::cast_error ` that may be raised by the call operator :cpp:func:`nb::handle::operator() ` and :cpp:func:`nb::cast() ` when argument(s) cannot be converted to Python objects. .. _custom_exceptions: Handling custom exceptions -------------------------- nanobind can also expose custom exception types. The :cpp:class:`nb::exception\ ` helper resembles :cpp:class:`nb::class_\ ` and registers a new exception type within the provided scope. .. code-block:: cpp NB_MODULE(my_ext, m) { nb::exception(m, "PyExp"); } Here, it creates ``my_ext.PyExp``. Subsequently, any C++ exception of type ``CppExp`` crossing the language barrier will automatically convert to ``my_ext.PyExp``. A Python exception base class can optionally be specified. For example, the snippet below causes ``PyExp`` to inherit from ``RuntimeError`` (the default is ``Exception``). The built-in Python exception classes are listed `here `__. .. code-block:: cpp nb::exception(module, "PyExp", PyExc_RuntimeError); In more complex cases, :cpp:func:`nb::register_exception_translator() ` can be called to register a custom exception translation routine. It takes a stateless callable (e.g. a function pointer or a lambda function without captured variables) with the call signature ``void(const std::exception_ptr &, void*)`` and an optional payload pointer value that will be passed to the second parameter of the callable. When a C++ exception is captured by nanobind, all registered exception translators are tried in reverse order of registration (i.e. the last registered translator has the first chance of handling the exception). Inside the translator, call ``std::rethrow_exception()`` within a ``try``-``catch`` block to re-throw the exception and capture supported exception types. The ``catch`` block should call ``PyErr_SetString`` or ``PyErr_Format`` (`1 `__, `2 `__) to set a suitable Python error status. The following example demonstrates this pattern to convert ``MyCustomException`` into a Python ``IndexError``. .. code-block:: cpp nb::register_exception_translator( [](const std::exception_ptr &p, void * /* unused */) { try { std::rethrow_exception(p); } catch (const MyCustomException &e) { PyErr_SetString(PyExc_IndexError, e.what()); } }); Multiple exceptions can be handled by a single translator. nanobind captures unhandled exceptions and forwards them to the preceding translator. If none of the exception translators succeeds, it will convert according to the previously discussed default rules. .. note:: When the exception translator returns normally, it must have set a Python error status. Otherwise, Python will crash with the message ``SystemError: error return without exception set``. Unsupported exception types should not be caught, or may be explicitly (re-)thrown to delegate them to the other exception translators. .. _handling_python_exceptions_cpp: Capturing Python exceptions within C++ -------------------------------------- When nanobind-based C++ code calls a Python function that raises an exception, it will automatically convert into a :class:`nb::python_error ` raised on the C++ side. This exception type can be caught and handled in C++ or propagate back into Python, where it will undergo reverse conversion. .. list-table:: :widths: 40 60 :header-rows: 1 * - Exception raised in Python - Translated to C++ exception type * - Any Python ``Exception`` - :cpp:class:`nb::python_error ` The class exposes various members to obtain further information about the exception. The :cpp:func:`.type() ` and :cpp:func:`.value() ` methods provide information about the exception type and value, while :cpp:func:`.what() ` generates a human-readable representation including a backtrace. A use of the :cpp:func:`.matches() ` method to distinguish different exception types is shown below: .. code-block:: cpp try { nb::object file = nb::module_::import_("io").attr("open")("file.txt", "r"); nb::object text = file.attr("read")(); file.attr("close")(); } catch (const nb::python_error &e) { if (e.matches(PyExc_FileNotFoundError)) { nb::print("file.txt not found"); } else if (e.matches(PyExc_PermissionError)) { nb::print("file.txt found but not accessible"); } else { throw; } } Note that the previously discussed :ref:`automatic conversion ` of C++ exception does not apply here. Errors raised from Python *always* convert to :cpp:class:`nb::python_error `. Handling errors from the Python C API ------------------------------------- Whenever possible, use :ref:`nanobind wrappers ` instead of calling the Python C API directly. Otherwise, you must carefully manage reference counts and adhere to the nanobind error protocol outlined below. When a Python C API call fails with an error status, you must immediately ``throw nb::python_error();`` to capture the error and handle it using appropriate C++ mechanisms. This includes calls to error setting functions such as ``PyErr_SetString`` (:ref:`custom exception translators ` are excluded from this rule). .. code-block:: cpp PyErr_SetString(PyExc_TypeError, "C API type error demo"); throw nb::python_error(); // But it would be easier to simply... throw nb::type_error("nanobind wrapper type error"); Alternately, to ignore the error, call `PyErr_Clear() `__. Any Python error must be thrown or cleared, or nanobind will be left in an invalid state. .. _exception_chaining: Chaining exceptions ('raise from') ---------------------------------- Python has a mechanism for indicating that exceptions were caused by other exceptions: .. code-block:: py try: print(1 / 0) except Exception as exc: raise RuntimeError("could not divide by zero") from exc To do a similar thing in nanobind, you can use the :cpp:func:`nb::raise_from ` function, which requires a :cpp:class:`nb::python_error ` and re-raises it with a chained exception object. .. code-block:: cpp nb::callable f = ...; int arg = 123; try { f(arg); } catch (nb::python_error &e) { nb::raise_from(e, PyExc_RuntimeError, "Could not call 'f' with %i", arg); } The function is internally based on the Python function ``PyErr_FormatV`` and takes ``printf``-style arguments following the format descriptor. An even lower-level interface is available via :cpp:func:`nb::chain_error `. Handling unraisable exceptions ------------------------------ If a Python function invoked from a C++ destructor or any function marked ``noexcept(true)`` (collectively, "noexcept functions") throws an exception, there is no way to propagate the exception, as such functions may not throw. Should they throw or fail to catch any exceptions in their call graph, the C++ runtime calls ``std::terminate()`` to abort immediately. Similarly, Python exceptions raised in a class's ``__del__`` method do not propagate, but are logged by Python as an unraisable error. In Python 3.8+, a `system hook is triggered `_ and an auditing event is logged. Any noexcept function should have a try-catch block that traps :cpp:class:`nb::python_error ` (or any other exception that can occur). A useful approach is to convert them to Python exceptions and then ``discard_as_unraisable`` as shown below. .. code-block:: cpp void nonthrowing_func() noexcept(true) { try { // ... } catch (nb::python_error &e) { // Discard the Python error using Python APIs, using the C++ magic // variable __func__. Python already knows the type and value and of the // exception object. e.discard_as_unraisable(__func__); } catch (const std::exception &e) { // Log and discard C++ exceptions. third_party::log(e); } } wjakob-nanobind-6c4457b/docs/exchanging.rst000066400000000000000000000333541474760012700207320ustar00rootroot00000000000000.. cpp:namespace:: nanobind .. _exchange: Exchanging information ====================== nanobind offers three fundamentally different ways of exchanging information between Python and C++. Depending on the task at hand, one will usually be preferable over the others, hence it is important to be aware of their advantages and disadvantages. .. _type_casters: Option 1: Type Casters ---------------------- A *type caster* translates C++ objects into equivalent Python objects and vice versa. The illustration below shows a translation between C++ (blue) and Python (green) worlds, where a ``std::vector`` instance converts from/to a Python ``list`` containing ``int`` objects. .. only:: not latex .. image:: images/caster-light.svg :width: 400 :align: center :class: only-light .. image:: images/caster-dark.svg :width: 400 :align: center :class: only-dark .. only:: latex .. image:: images/caster-light.svg :width: 400 :align: center **Example**: The following function doubles the entries of an STL vector and returns the result. .. code-block:: cpp using IntVector = std::vector; IntVector double_it(const IntVector &in) { IntVector out(in.size()); for (size_t i = 0; i < in.size(); ++i) out[i] = in[i] * 2; return out; } To expose it in Python, we can use the ``std::vector<...>`` type caster that is located in an optional header file named ``nanobind/stl/vector.h``: .. code-block:: cpp #include NB_MODULE(my_ext, m) { m.def("double_it", &double_it); } That's all there is to it. The Python version of the function features an automatically generated docstring, type checks, and (if needed) error reporting. .. code-block:: pycon >>> import my_ext >>> my_ext.double_it([1, 2, 3]) [2, 4, 6] >>> my_ext.double_it([1, 2, 'foo']) TypeError: double_it(): incompatible function arguments. The following argument types are supported: 1. double_it(arg: list[int], /) -> list[int] What are the implications of using type casters? **Pro**: this approach is simple and convenient, especially when standard (STL) types are involved. Usually, all that is needed is an ``#include`` directive to pull in the right header file. Complex nested types (e.g. vectors of hash tables of strings) work automatically by combining type casters recursively. The following table lists the currently available type casters along with links to external projects that provide further casters: .. list-table:: :widths: 42 48 :header-rows: 1 * - Type - Type caster header * - ``char``, ``char*``, ``void*``, ``nullptr_t``, ``bool``, ``int``, ``unsigned int``, ``long``, ``unsigned long``, ... - Built-in (no include file needed) * - ``std::array<..>`` - ``#include `` * - ``std::chrono::duration<..>``, ``std::chrono::time_point<..>`` (:ref:`more details `) - ``#include `` * - ``std::complex<..>`` - ``#include `` * - ``std::filesystem::path`` - ``#include `` * - ``std::function<..>`` - ``#include `` * - ``std::list<..>`` - ``#include `` * - ``std::map<..>`` - ``#include `` * - ``std::optional<..>`` - ``#include `` * - ``std::pair<..>`` - ``#include `` * - ``std::set<..>`` - ``#include `` * - ``std::string`` - ``#include `` * - ``std::string_view`` - ``#include `` * - ``std::wstring`` - ``#include `` * - ``std::tuple<..>`` - ``#include `` * - ``std::shared_ptr<..>`` - ``#include `` * - ``std::unique_ptr<..>`` - ``#include `` * - ``std::unordered_set<..>`` - ``#include `` * - ``std::unordered_map<..>`` - ``#include `` * - ``std::variant<..>`` - ``#include `` * - ``std::vector<..>`` - ``#include `` * - ``nb::ndarray<..>`` - ``#include `` * - ``Eigen::Matrix<..>``, ``Eigen::Array<..>``, ``Eigen::Ref<..>``, ``Eigen::Map<..>`` - ``#include `` * - ``Eigen::SparseMatrix<..>`` - ``#include `` * - Apache Arrow types - `https://github.com/maximiliank/nanobind_pyarrow `__ * - ... - Please reach out if you have additions to this list. **Con**: Every transition between the Python and C++ side will generally require a conversion step (in this case, to re-create all list elements). This can be wasteful when the other side only needs to access a small part of the data. Conversely, the overhead should not be a problem when the data is fully "consumed" following conversion. A select few type casters (``std::unique_ptr<..>``, ``std::shared_ptr<..>``, :cpp:class:`nb::ndarray `, and ``Eigen::*``) are special in the sense that they can perform a type conversion *without* copying the underlying data. Besides those few exceptions type casting always implies that a copy is made. .. _type_caster_mutable: Mutable reference issue ^^^^^^^^^^^^^^^^^^^^^^^ Another subtle limitation of type casters is that they don't propagate updates through mutable references. Consider the following alternative implementation of the ``double_it`` function: .. code-block:: cpp void double_it(IntVector &in) { for (int &value : in) value *= 2; } nanobind can wrap this function without problems, but it won't behave as expected: .. code-block:: pycon >>> x = [1, 2, 3] >>> my_ext.double_it(x) >>> x [1, 2, 3] # <-- oops, unchanged! *How could this happen?* The reason is that type casters convert function arguments and return values once, but further changes will not automatically propagate across the language barrier because the representations are not intrinsically linked to each other. This problem is not specific to STL types---for example, the following function will similarly not update its argument once exposed in Python. .. code-block:: cpp void double_it(int &in) { in *= 2; } This is because builtin types like ``int``, ``str``, ``bool``, etc., are all handled by type casters. A simple alternative to propagate updates while retaining the convenience of type casters is to bind a small wrapper lambda function that returns a tuple with all output arguments. An example: .. code-block:: cpp int foo(int &in) { in *= 2; return std::sqrt(in); } And the binding code .. code-block:: cpp m.def("foo", [](int i) { int rv = foo(i); return std::make_tuple(rv, i); }); In this case, a type caster (``#include `` return value. .. _bindings: Option 2: Bindings ------------------ *Bindings* expose C++ types in Python; the ability to create them is the main feature of nanobind. In the list-of-integer example, they cause Python to interpret ``std::vector`` as a new Python type called ``my_ext.IntVector``. .. only:: not latex .. image:: images/binding-light.svg :width: 400 :align: center :class: only-light .. image:: images/binding-dark.svg :width: 400 :align: center :class: only-dark .. only:: latex .. image:: images/binding-light.svg :width: 400 :align: center **Example**: to switch the previous example to bindings, we first replace the type caster header (`nanobind/stl/vector.h `_) by its binding variant (`nanobind/stl/bind_vector.h `_) and then invoke the :cpp:func:`nb::bind_vector\() ` function to create a *new Python type named* ``IntVector`` within the module ``m``. .. code-block:: cpp :emphasize-lines: 1, 9 #include using IntVector = std::vector; IntVector double_it(const IntVector &in) { /* .. omitted .. */ } namespace nb = nanobind; NB_MODULE(my_ext, m) { nb::bind_vector(m, "IntVector"); m.def("double_it", &double_it); } Any function taking or returning integer vectors will now use the type binding. In the Python session below, nanobind performs an implicit conversion from the Python list ``[1, 2, 3]`` to a ``my_ext.IntVector`` before calling the ``double_it`` function. .. code-block:: pycon >>> import my_ext >>> my_ext.double_it([1, 2, 3]) my_ext.IntVector([2, 4, 6]) >>> my_ext.double_it.__doc__ 'double_it(arg: my_ext.IntVector, /) -> my_ext.IntVector' Let's go through the implications of using bindings: **Pro**: bindings don't require the costly conversion step when crossing the language boundary. They also support mutable references, so the :ref:`issue discussed in the context of type casters ` does not arise. Sometimes, binding is the only available option: when a C++ type does not have an equivalent Python type, casting simply does not make sense. **Con**: Creating good bindings that feel natural in Python requires some additional work. We cheated in this example by relying on the :cpp:func:`nb::bind_vector\() ` helper function that did all the heavy lifting. Such helpers are currently only available for a few special cases (vectors, ordered/unordered maps, iterators): .. list-table:: :widths: 42 48 :header-rows: 1 * - Type - Binding helper header * - ``std::vector<..>`` - ``#include `` (:ref:`docs `) * - ``std::map<..>`` - ``#include `` (:ref:`docs `) * - ``std::unordered_map<..>`` - ``#include `` (:ref:`docs `) * - Forward iterators - ``#include `` (:ref:`docs `) * - Other types - See the previous example on :ref:`binding custom types `. In general, you will need to write the binding code yourself. The previous section on :ref:`binding custom types ` showed an example of such a type binding. .. _wrappers: Option 3: Wrappers ------------------ The last option is only rarely used, but it can be powerful alternative in some cases. nanobind provides *wrapper* classes to use Python types within C++. You can think of this as a kind of *reverse binding*. For example, a Python list can be accessed through the :cpp:class:`nb::list ` type: .. only:: not latex .. image:: images/wrapper-light.svg :width: 400 :align: center :class: only-light .. image:: images/wrapper-dark.svg :width: 400 :align: center :class: only-dark .. only:: latex .. image:: images/wrapper-light.svg :width: 400 :align: center This is what the example looks like when expressed using :cpp:class:`nb::list ` and :cpp:class:`nb::int_ `. .. code-block:: cpp #include namespace nb = nanobind; nb::list double_it(nb::list l) { nb::list result; for (nb::handle h: l) result.append(h * nb::int_(2)); return result; } NB_MODULE(my_ext, m) { m.def("double_it", &double_it); } The implications of using wrappers are: **Pro**: Wrappers require no copying or type conversion. With them, C++ begins to resemble dynamically typed Python code and can perform highly general operations on Python objects. Wrappers are useful to tap into the powerful Python software ecosystem (NumPy, Matplotlib, PyTorch, etc). **Con**: Functions based on wrappers cannot run without Python. In contrast to option 1 (:ref:`type casters `) and 2 (:ref:`bindings `), we can no longer reuse an existing function and process its arguments and return value to interface the Python and C++ worlds: the entire function must be rewritten using nanobind-specific wrapper types. Every operation will translate into a corresponding Python C API call, which means that wrappers aren't suitable for performance-critical loops or multithreaded computations. The following wrappers are available and require no additional include directives: :cpp:class:`any`, :cpp:class:`bytearray`, :cpp:class:`bytes`, :cpp:class:`callable`, :cpp:class:`capsule`, :cpp:class:`dict`, :cpp:class:`ellipsis`, :cpp:class:`handle`, :cpp:class:`handle_t\ `, :cpp:class:`bool_`, :cpp:class:`int_`, :cpp:class:`float_`, :cpp:class:`iterable`, :cpp:class:`iterator`, :cpp:class:`list`, :cpp:class:`mapping`, :cpp:class:`module_`, :cpp:class:`object`, :cpp:class:`set`, :cpp:class:`sequence`, :cpp:class:`slice`, :cpp:class:`str`, :cpp:class:`tuple`, :cpp:class:`weakref`, :cpp:class:`type_object`, :cpp:class:`type_object_t\ `, :cpp:class:`args`, and :cpp:class:`kwargs`. Discussion ---------- The choices outlined above are more fine-grained than they may appear. For example, it is possible to use type casters, bindings, and wrappers to handle multiple arguments of *a single function*. They can also be combined *within* a single function argument. For example, you can type cast a ``std::vector`` containing bindings or wrappers. In general, we recommend that you use 1. type casters for STL containers, and 2. bindings for other custom types. If the former turn out to be a performance bottleneck, it is easy to replace them with bindings or wrappers later on. Wrappers are only rarely useful; you will usually know it when you need them. wjakob-nanobind-6c4457b/docs/faq.rst000066400000000000000000000474371474760012700173750ustar00rootroot00000000000000.. cpp:namespace:: nanobind .. _faq: Frequently asked questions ========================== Importing my module fails with an ``ImportError`` ------------------------------------------------- If importing the module fails as shown below, you have not specified a matching module name in :cmake:command:`nanobind_add_module()` and :c:macro:`NB_MODULE() `. .. code-block:: pycon >>> import my_ext ImportError: dynamic module does not define module export function (PyInit_my_ext) Importing fails due to missing ``[lib]nanobind.{dylib,so,dll}`` --------------------------------------------------------------- If importing the module fails as shown below, the extension cannot find the ``nanobind`` shared library component. .. code-block:: pycon >>> import my_ext ImportError: dlopen(my_ext.cpython-311-darwin.so, 0x0002): Library not loaded: '@rpath/libnanobind.dylib' This is really more of a general C++/CMake/build system issue than one of nanobind specifically. There are two solutions: 1. Build the library component statically by specifying the ``NB_STATIC`` flag in :cmake:command:`nanobind_add_module()` (this is the default starting with nanobind 0.2.0). 2. Ensure that the various shared libraries are installed in the right destination, and that their `rpath `_ is set so that they can find each other. You can control the build output directory of the shared library component using the following CMake command: .. code-block:: pycon set_target_properties(nanobind PROPERTIES LIBRARY_OUTPUT_DIRECTORY LIBRARY_OUTPUT_DIRECTORY_RELEASE LIBRARY_OUTPUT_DIRECTORY_DEBUG LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO LIBRARY_OUTPUT_DIRECTORY_MINSIZEREL ) Depending on the flags provided to :cmake:command:`nanobind_add_module()`, the shared library component may have a different name following the pattern ``nanobind[-abi3][-lto]``. The following CMake commands may be useful to adjust the build and install `rpath `_ of the extension: .. code-block:: cmake set_property(TARGET my_ext APPEND PROPERTY BUILD_RPATH "$") set_property(TARGET my_ext APPEND PROPERTY INSTALL_RPATH ".. ?? ..") Why are reference arguments not updated? ---------------------------------------- Functions like the following example can be exposed in Python, but they won't propagate updates to mutable reference arguments. .. code-block:: cpp void increment(int &i) { i++; } This isn't specific to builtin types but also applies to STL collections and other types when they are handled using :ref:`type casters `. Please read the full section on :ref:`information exchange between C++ and Python ` to understand the issue and alternatives. .. _leak-checker: Why am I getting errors about leaked functions and types? --------------------------------------------------------- When the Python interpreter shuts down, it informs nanobind about this using a ``Py_AtExit()`` callback. If any nanobind-created instances, functions, or types are still alive at this point, then *something went wrong* because they should have been deleted by the garbage collector. Although this does not always indicate a serious problem, the decision was made to have nanobind complain rather noisily about the presence of such leaks. Other binding tools (e.g., pybind11) are on the opposite of the spectrum: because they never report leaks, it is quite easy to accidentally introduce many of them until a developer eventually realizes that something is very wrong. Leaks mainly occur for four reasons: - **Reference counting bugs**. If you write raw Python C API code or use the nanobind wrappers including functions like ``Py_[X]INCREF()``, ``Py_[X]DECREF()``, :cpp:func:`nb::steal() `, :cpp:func:`nb::borrow() `, :cpp:func:`.dec_ref() `, :cpp:func:`.inc_ref() ` , etc., then incorrect use of such calls can cause a reference to leak that prevents the associated object from being deleted. - **Reference cycles**. Python's garbage collector frees unused objects that are part of a circular reference chains (e.g., ``A->B->C->A``). This requires all types in the cycle to implement the ``tp_traverse`` *type slot*, and at least one of them to implement the ``tp_clear`` type slot. See the section on :ref:`cyclic garbage collection ` for details on how to do this with nanobind. - **Interactions with other tools that leak references**. Python extension libraries---especially *huge* ones with C library components like PyTorch, Tensorflow, etc., have been observed to leak references to nanobind objects. Some of these frameworks cache JIT-compiled functions based on the arguments with which they were called, and such caching schemes could leak references to nanobind types if they aren't cleaned up by the responsible extensions (this is a hypothesis). In this case, the leak would be benign---even so, it should be fixed in the responsible framework so that leak warnings aren't cluttered with flukes and can be more broadly useful. - **Older Python versions**: Very old Python versions (e.g., 3.8) don't do a good job cleaning up global references when the interpreter shuts down. The following code may leak a reference if it is a top-level statement in a Python file or the REPL. .. code-block:: python a = my_ext.MyObject() Such a warning is benign and does not indicate an actual leak. It simply highlights a flaws in the interpreter shutdown logic of old Python versions. Wrap your code into a function to address this issue even on such versions: .. code-block:: python def run(): a = my_ext.MyObject() # ... if __name__ == '__main__': run() - **Exceptions**. Some exceptions such as ``AttributeError`` have been observed to hold references, e.g. to the object which lacked the desired attribute. If the last exception raised by the program references a nanobind instance, then this may be reported as a leak since Python finalization appears not to release the exception object. See `issue #376 `__ for a discussion. If you find leak warnings to be a nuisance, then you can disable them in the C++ binding code via the :cpp:func:`nb::set_leak_warnings() ` function. .. code-block:: python nb::set_leak_warnings(false); This is a *global flag* shared by all nanobind extension libraries in the same ABI domain. If you do so, then please isolate your extension from others by passing the ``NB_DOMAIN`` parameter to :cmake:command:`nanobind_add_module()`. Compilation fails with a static assertion mentioning ``NB_MAKE_OPAQUE()`` ------------------------------------------------------------------------- If your compiler generates an error of the following sort, you are mixing type casters and bindings in a way that has them competing for the same types: .. code-block:: text nanobind/include/nanobind/nb_class.h:207:40: error: static assertion failed: ↵ Attempted to create a constructor for a type that won't be handled by the nanobind's ↵ class type caster. Is it possible that you forgot to add NB_MAKE_OPAQUE() somewhere? For example, the following won't work: .. code-block:: cpp #include #include namespace nb = nanobind; NB_MODULE(my_ext, m) { // The following line cannot be compiled nb::bind_vector>(m, "VectorInt"); // This doesn't work either nb::class_>(m, "VectorInt"); } This is not specific to STL vectors and will happen whenever casters and bindings target overlapping types. :ref:`Type casters ` employ a pattern matching technique known as `partial template specialization `_. For example, ``nanobind/stl/vector.h`` installs a pattern that detects *any* use of ``std::vector``, which overlaps with the above binding of a specific vector type. The deeper reason for this conflict is that type casters enable a *compile-time* transformation of nanobind code, which can conflict with binding declarations that are a *runtime* construct. To fix the conflict in this example, add the line :c:macro:`NB_MAKE_OPAQUE(T) `, which adds another partial template specialization pattern for ``T`` that says: "ignore ``T`` and don't use a type caster to handle it". .. code-block:: cpp NB_MAKE_OPAQUE(std::vector); .. warning:: If your extension consists of multiple source code files that involve overlapping use of type casters and bindings, you are *treading on thin ice*. It is easy to violate the *One Definition Rule* (ODR) [`details `_] in such a case, which may lead to undefined behavior (miscompilations, etc.). Here is a hypothetical example of an ODR violation: an extension contains two source code files: ``src_1.cpp`` and ``src_2.cpp``. - ``src_1.cpp`` binds a function that returns an ``std::vector`` using a :ref:`type caster ` (``nanobind/stl/vector.h``). - ``src_2.cpp`` binds a function that returns an ``std::vector`` using a :ref:`binding ` (``nanobind/stl/bind_vector.h``), and it also installs the needed type binding. The problem is that a partially specialized class in the nanobind implementation namespace (specifically, ``nanobind::detail::type_caster>``) now resolves to *two different implementations* in the two compilation units. It is unclear how such a conflict should be resolved at the linking stage, and you should consider code using such constructions broken. To avoid this issue altogether, we recommend that you create a single include file (e.g., ``binding_core.h``) containing all of the nanobind include files (binding, type casters), your own custom type casters (if present), and :c:macro:`NB_MAKE_OPAQUE(T) ` declarations. Include this header consistently in all binding compilation units. The construction shown in the example (mixing type casters and bindings for the same type) is not allowed, and cannot occur when following the recommendation. How can I preserve the ``const``-ness of values in bindings? ------------------------------------------------------------ This is a limitation of nanobind, which casts away ``const`` in function arguments and return values. This is in line with the Python language, which has no concept of const values. Additional care is therefore needed to avoid bugs that would be caught by the type checker in a traditional C++ program. How can I reduce build time? ---------------------------- Large binding projects should be partitioned into multiple files, as shown in the following example: :file:`example.cpp`: .. code-block:: cpp void init_ex1(nb::module_ &); void init_ex2(nb::module_ &); /* ... */ NB_MODULE(my_ext, m) { init_ex1(m); init_ex2(m); /* ... */ } :file:`ex1.cpp`: .. code-block:: cpp void init_ex1(nb::module_ &m) { m.def("add", [](int a, int b) { return a + b; }); } :file:`ex2.cpp`: .. code-block:: cpp void init_ex2(nb::module_ &m) { m.def("sub", [](int a, int b) { return a - b; }); } As shown above, the various ``init_ex`` functions should be contained in separate files that can be compiled independently from one another, and then linked together into the same final shared object. Following this approach will: 1. reduce memory requirements per compilation unit. 2. enable parallel builds (if desired). 3. allow for faster incremental builds. For instance, when a single class definition is changed, only a subset of the binding code will generally need to be recompiled. .. _type-visibility: How can I avoid conflicts with other projects using nanobind? ------------------------------------------------------------- Suppose that a type binding in your project conflicts with another extension, for example because both expose a common type (e.g., ``std::latch``). nanobind will warn whenever it detects such a conflict: .. code-block:: text RuntimeWarning: nanobind: type 'latch' was already registered! In the worst case, this could actually break both packages (especially if the bindings of the two packages expose an inconsistent/incompatible API). The higher-level issue here is that nanobind will by default try to make type bindings visible across extensions because this is helpful to partition large binding projects into smaller parts. Such information exchange requires that the extensions: - use the same nanobind *ABI version* (see the :ref:`Changelog ` for details). - use the same compiler (extensions built with GCC and Clang are isolated from each other). - use ABI-compatible versions of the C++ library. - use the stable ABI interface consistently (stable and unstable builds are isolated from each other). - use debug/release mode consistently (debug and release builds are isolated from each other). In addition, nanobind provides a feature to intentionally scope extensions to a named domain to avoid conflicts with other extensions. To do so, specify the ``NB_DOMAIN`` parameter in CMake: .. code-block:: cmake nanobind_add_module(my_ext NB_DOMAIN my_project my_ext.cpp) In this case, inter-extension type visibility is furthermore restricted to extensions in the ``"my_project"`` domain. Can I use nanobind without RTTI or C++ exceptions? -------------------------------------------------- Certain environments (e.g., `Google-internal development `__, embedded devices, etc.) require compilation without C++ runtime type information (``-fno-rtti``) and exceptions (``-fno-exceptions``). nanobind requires both of these features and cannot be used when they are not available. RTTI provides the central index to look up types of bindings. Exceptions are needed because Python relies on exceptions that must be converted into something equivalent on the C++ side. PRs that refactor nanobind to work without RTTI or exceptions will not be accepted. For Googlers: there is already an exemption from the internal rules that specifically permits the use of RTTI/exceptions when a project relies on pybind11. Likely, this exemption could be extended to include nanobind as well. Can I make stable ABI extensions for pre-3.12 Python? ----------------------------------------------------- Stable ABI extensions are convenient because they can be reused across Python versions, but this unfortunately only works on Python 3.12 and newer. Nanobind crucially depends on several `features `__ that were added in version 3.12 (specifically, ``PyType_FromMetaclass()`` and limited API bindings of the vector call protocol). Policy on Clang-Tidy, ``-Wpedantic``, etc. ------------------------------------------ nanobind regularly receives requests from users who run it through Clang-Tidy, or who compile with increased warnings levels, like ``-Wpedantic``, ``-Wcast-qual``, ``-Wsign-conversion``, etc. (i.e., beyond the increased ``-Wall``, ``-Wextra`` and ``/W4`` warning levels that are already enabled) Their next step is to open a big pull request needed to silence all of the resulting messages. My policy on this is as follows: I am always happy to fix issues in the codebase. However, many of the resulting change requests are in the "ritual purification" category: things that cause churn, decrease readability, and which don't fix actual problems. It's a never-ending cycle because each new revision of such tooling adds further warnings and purification rites. So just to have a clear policy: I do not wish to pepper this codebase with ``const_cast`` and ``#pragmas`` or pragma-like comments to avoid warnings in various kinds of external tooling just so those users can have a "silent" build. I don't think it is reasonable for them to impose their own style on this project. As a workaround it is likely possible to restrict the scope of style checks to particular C++ namespaces or source code locations. I'd like to use this project, but with $BUILD_SYSTEM instead of CMake --------------------------------------------------------------------- A difficult aspect of C++ software development is the sheer number of competing build systems, including - `CMake `__, - `Meson `__, - `xmake `__, - `Premake `__, - `Bazel `__, - `Conan `__, - `Autotools `__, - and many others. The author of this project has some familiarity with CMake but lacks expertise with this large space of alternative tools. Maintaining and shipping support for other build systems is therefore considered beyond the scope of this *nano* project (see also the :ref:`why? ` part of the documentation that explains the rationale for being somewhat restrictive towards external contributions). If you wish to create and maintain an alternative interface to nanobind, then my request would be that you create and maintain separate repository (see, e.g., `pybind11_bazel `__ as an example how how this was handled in the case of pybind11). Please carefully review the file `nanobind-config.cmake `__. Besides getting things to compile, it specifies a number of platform-dependent compiler and linker options that are needed to produce *optimal* (small and efficient) binaries. Nanobind uses a `complicated and non-standard `__ set of linker parameters on macOS, which is the result of a `lengthy investigation `__. Other parameters like linker-level dead code elimination and size-based optimization were similarly added following careful analysis. The CMake build system provides the ability to compile ``libnanobind`` into either a shared or a static library, to optionally target the stable ABI, and to isolate it from other extensions via the ``NB_DOMAIN`` parameter. All of these are features that would be nice to retain in an alternative build system. If you've made a build system compatible with another tool that is sufficiently feature-complete, then please file an issue and I am happy to reference it in the documentation. Are there tools to generate nanobind bindings automatically? ------------------------------------------------------------ `litgen `__ is an automatic Python bindings generator compatible with both pybind11 and nanobind, designed to create documented and easily discoverable bindings. It reproduces header documentation directly in the bindings, making the generated API intuitive and well-documented for Python users. Powered by srcML (srcml.org), a high-performance, multi-language parsing tool, litgen takes a developer-centric approach. The C++ API to be exposed to Python must be C++14 compatible, although the implementation can leverage more modern C++ features. How to cite this project? ------------------------- Please use the following BibTeX template to cite nanobind in scientific discourse: .. code-block:: bibtex @misc{nanobind, author = {Wenzel Jakob}, year = {2022}, note = {https://github.com/wjakob/nanobind}, title = {nanobind: tiny and efficient C++/Python bindings} } wjakob-nanobind-6c4457b/docs/free_threaded.rst000066400000000000000000000313431474760012700213740ustar00rootroot00000000000000.. _free-threaded: .. cpp:namespace:: nanobind Free-threaded Python ==================== **Free-threading** is an experimental new Python feature that replaces the `Global Interpreter Lock (GIL) `__ with a fine-grained locking scheme to better leverage multi-core parallelism. The resulting benefits do not come for free: extensions must explicitly opt-in and generally require careful modifications to ensure correctness. Nanobind can target free-threaded Python since version 2.2.0. This page explains how to do so and discusses a few caveats. Besides this page, make sure to review `py-free-threading.github.io `__ for a more comprehensive discussion of free-threaded Python. `PEP 703 `__ explains the nitty gritty details. Opting in --------- To opt into free-threaded Python, pass the ``FREE_THREADED`` parameter to the :cmake:command:`nanobind_add_module()` CMake target command. For other build systems, refer to their respective documentation pages. .. code-block:: cmake nanobind_add_module( my_ext # Target name FREE_THREADED # Opt into free-threading my_ext.h # Source code files below my_ext.cpp) nanobind ignores the ``FREE_THREADED`` parameter when the registered Python version does not support free-threading. .. note:: **Stable ABI**: Note that there currently is no stable ABI for free-threaded Python, hence the ``STABLE_ABI`` parameter will be ignored in free-threaded extensions builds. It is valid to combine the ``STABLE_ABI`` and ``FREE_THREADED`` arguments: the build system will choose between the two depending on the detected Python version. .. warning:: Loading an Python extension that does not support free-threading disables free-threading globally. In larger binding projects with multiple extensions, all of them must be adapted. If free-threading was requested and is available, the build system will set the ``NB_FREE_THREADED`` preprocessor flag. This can be helpful to specialize binding code with ``#ifdef`` blocks, e.g.: .. code-block:: cpp #if !defined(NB_FREE_THREADED) ... // simple GIL-protected code #else ... // more complex thread-aware code #endif Caveats ------- Free-threading can violate implicit assumptions made by extension developers when previously serial operations suddenly run concurrently, producing undefined behavior (race conditions, crashes, etc.). Let's consider a concrete example: the binding code below defines a ``Counter`` class with an increment operation. .. code-block:: cpp struct Counter { int value = 0; void inc() { value++; } }; nb::class_(m, "Counter") .def("inc", &Counter::inc) .def_ro("value", &Counter::value); If multiple threads call the ``inc()`` method of a single ``Counter``, the final count will generally be incorrect, as the increment operation ``value++`` does not execute atomically. To fix this, we could modify the C++ type so that it protects its ``value`` member from concurrent modification, for example using an atomic number type (e.g., ``std::atomic``) or a critical section (e.g., based on ``std::mutex``). The race condition in the above example is relatively benign. However, in more complex projects, combinations of concurrency and unsafe memory accesses could introduce non-deterministic data corruption and crashes. Another common source of problems are *global variables* undergoing concurrent modification when no longer protected by the GIL. They will likewise require supplemental locking. The :ref:`next section ` explains a Python-specific locking primitive that can be used in binding code besides the solutions mentioned above. Multi-threaded code that concurrently returns the same C++ instance via the :cpp:enumerator:`nb::rv_policy::reference` policy may observe situations, where multiple Python objects are created that all wrap the same C++ instance (however, this is harmless aside from the duplication). .. _free-threaded-locks: Python locks ------------ Nanobind provides convenience functionality encapsulating the mutex implementation that is part of Python ("``PyMutex``"). It is slightly more efficient than OS/language-provided synchronization primitives and generally preferable within Python extensions. The class :cpp:class:`ft_mutex` is analogous to ``std::mutex``, and :cpp:class:`ft_lock_guard` is analogous to ``std::lock_guard``. Note that they only exist to add *supplemental* critical sections needed in free-threaded Python, while becoming inactive (no-ops) when targeting regular GIL-protected Python. With these abstractions, the previous ``Counter`` implementation could be rewritten as: .. code-block:: cpp :emphasize-lines: 3,6 struct Counter { int value = 0; nb::ft_mutex mutex; void inc() { nb::ft_lock_guard guard(mutex); value++; } }; These locks are very compact (``sizeof(nb::ft_mutex) == 1``), though this is a Python implementation detail that could change in the future. .. _argument-locks: Argument locking ---------------- Modifying class and function definitions as shown above may not always be possible. As an alternative, nanobind also provides a way to *retrofit* supplemental locking onto existing code. The idea is to lock individual arguments of a function *before* being allowed to invoke it. A built-in mutex present in every Python object enables this. To do so, call the :cpp:func:`.lock() ` member of :cpp:class:`nb::arg() ` annotations to indicate that an argument must be locked, e.g.: - :cpp:func:`nb::arg("my_parameter").lock() ` - :cpp:func:`"my_parameter"_a.lock() ` (short-hand form) In methods bindings, pass :cpp:struct:`nb::lock_self() ` to lock the implicit ``self`` argument. Note that at most 2 arguments can be locked per function, which is a limitation of the `Python locking API `__. The example below shows how this functionality can be used to protect ``inc()`` and a new ``merge()`` function that acquires two simultaneous locks. .. code-block:: cpp struct Counter { int value = 0; void inc() { value++; } void merge(Counter &other) { value += other.value; other.value = 0; } }; nb::class_(m, "Counter") .def("inc", &Counter::inc, nb::lock_self()) .def("merge", &Counter::merge, nb::lock_self(), "other"_a.lock()) .def_ro("value", &Counter::value); The above solution has an obvious drawback: it only protects *bindings* (i.e., transitions from Python to C++). For example, if some other part of a C++ codebase calls ``merge()`` directly, the binding layer won't be involved, and no locking takes place. If such behavior can introduce race conditions, a larger-scale redesign of your project may be in order. .. note:: Adding locking annotations indiscriminately is inadvisable because locked calls are more costly than unlocked ones. The :cpp:func:`.lock() ` and :cpp:struct:`nb::lock_self() ` annotations are ignored in GIL-protected builds, hence this added cost only applies to free-threaded extensions. Furthermore, when adding locking annotations to a function, consider keeping the arguments *unnamed* (i.e., :cpp:func:`nb::arg().lock() ` instead of :cpp:func:`nb::arg("name").lock() `) if the function will never be called with keyword arguments. Processing named arguments causes small :ref:`binding overheads ` that may be undesirable if a function that does very little is called at a very high rate. .. note:: **Python API and locking**: When the lock-protected function performs Python API calls (e.g., using :ref:`wrappers ` like :cpp:class:`nb::dict `), Python may temporarily release locks to avoid deadlocks. Here, even basic reference counting such as a :cpp:class:`nb::object ` variable expiring at the end of a scope counts as an API call. These locks will be reacquired following the Python API call. This behavior resembles ordinary (GIL-protected) Python code, where operations like `Py_DECREF() `__ can cause cause arbitrary Python code to execute. The semantics of this kind of relaxed critical section are described in the `Python documentation `__. Miscellaneous notes ------------------- API --- The following API specific to free-threading has been added: - :cpp:class:`nb::ft_mutex ` - :cpp:class:`nb::ft_lock_guard ` - :cpp:class:`nb::ft_object_guard ` - :cpp:class:`nb::ft_object2_guard ` - :cpp:func:`nb::arg::lock() ` API stability _____________ The interface explained in this is excluded from the project's semantic versioning policy. Free-threading is still experimental, and API breaks may be necessary based on future experience and changes in Python itself. Wrappers ________ :ref:`Wrapper types ` like :cpp:class:`nb::list ` may be used in multi-threaded code. Operations like :cpp:func:`nb::list::append() ` internally acquire locks and behave just like their ordinary Python counterparts. This means that race conditions can still occur without larger-scale synchronization, but such races won't jeopardize the memory safety of the program. GIL scope guards ________________ Prior to free-threaded Python, the nanobind scope guards :cpp:struct:`gil_scoped_acquire` and :cpp:struct:`gil_scoped_release` would normally be used to acquire/release the GIL and enable parallel regions. These remain useful and should not be removed from existing code: while no longer blocking operations, they set and unset the current Python thread context and inform the garbage collector. The :cpp:struct:`gil_scoped_release` RAII scope guard class plays a special role in free-threaded builds, since it releases all :ref:`argument locks ` held by the current thread. Immortalization _______________ Python relies on a technique called *reference counting* to determine when an object is no longer needed. This approach can become a bottleneck in multi-threaded programs, since increasing and decreasing reference counts requires coordination among multiple processor cores. Python type and function objects are especially sensitive, since their reference counts change at a very high rate. Similar to free-threaded Python itself, nanobind avoids this bottleneck by *immortalizing* functions (``nanobind.nb_func``, ``nanobind.nb_method``) and type bindings. Immortal objects don't require reference counting and therefore cannot cause the bottleneck mentioned above. The main downside of this approach is that these objects leak when the interpreter shuts down. Free-threaded nanobind extensions disable the internal :ref:`leak checker `, since it would produce many warning messages caused by immortal objects. Internal data structures ________________________ Nanobind maintains various internal data structures that store information about instances and function/type bindings. These data structures also play an important role to exchange type/instance data in larger projects that are split across several independent extension modules. The layout of these data structures differs between ordinary and free-threaded extensions, therefore nanobind isolates them from each other by assigning a different ABI version tag. This means that multi-module projects will need to consistently compile either free-threaded or non-free-threaded modules. Free-threaded nanobind uses thread-local and sharded data structures to avoid lock and atomic contention on the internal data structures, which would otherwise become a bottleneck in multi-threaded Python programs. Thread sanitizers _________________ The `thread sanitizer `__ (TSAN) offers an effective way of tracking down undefined behavior in multithreaded application. To use TSAN with nanonbind extensions, you *must* also create a custom Python build that has TSAN enabled. This is because nanobind internally builds on Python locks. If the implementation of the locks is not instrumented by TSAN, the tool will detect a large volume of false positives. To make a TSAN-instrumented Python build, download a Python source release and to pass the following options to its ``configure`` script: .. code-block:: bash $ ./configure --disable-gil --with-thread-sanitizer <.. other options ..> wjakob-nanobind-6c4457b/docs/functions.rst000066400000000000000000000471621474760012700206310ustar00rootroot00000000000000.. _functions: .. cpp:namespace:: nanobind Functions ========= Binding annotations ------------------- Besides :ref:`keyword and default arguments `, :ref:`docstrings `, and :ref:`return value policies `, other function binding annotations can be specified to achieve different goals as described below. Default arguments revisited --------------------------- A noteworthy point about the previously discussed way of specifying :ref:`default arguments ` is that nanobind immediately converts them into Python objects. Consider the following example: .. code-block:: cpp nb::class_(m, "MyClass") .def("f", &MyClass::f, "value"_a = SomeType(123)); nanobind must be set up to deal with values of the type ``SomeType`` (via a prior instantiation of ``nb::class_``), or an exception will be thrown. The "preview" of the default argument in the function signature is generated using the object's ``__str__`` method. If not available, the signature may not be very helpful, e.g.: .. code-block:: pycon >> help(my_ext.MyClass) class MyClass(builtins.object) | Methods defined here: .... | f(...) | f(self, value: my_ext.SomeType = ) -> None In such cases, you can either refine the implementation of the type in question or manually override how nanobind renders the default value using the :cpp:func:`.sig("string") method `: .. code-block:: cpp nb::class_(m, "MyClass") .def("f", &MyClass::f, "value"_a.sig("SomeType(123)") = SomeType(123)); .. _noconvert: Implicit conversions, and how to suppress them ---------------------------------------------- Consider the following function taking a floating point value as input: .. code-block:: cpp m.def("double", [](float x) { return 2.f * x; }); We can call this function using a Python ``float``, but an ``int`` works just as well: .. code-block:: pycon >>> my_ext.double(2) 4.0 nanobind performed a so-called *implicit conversion* for convenience. The same mechanism generalizes to custom types defining a :cpp:class:`nb::init_implicit\() `-style constructor: .. code-block:: cpp nb::class_(m, "A") // Following this line, nanobind will automatically convert 'B' -> 'A' if needed .def(nb::init_implicit()); This behavior is not always desirable---sometimes, it is better to give up or try another function overload. To achieve this behavior, use the :cpp:func:`.noconvert() ` method of the :cpp:class:`nb::arg ` annotation to mark the argument as *non-converting*. An example: .. code-block:: cpp m.def("double", [](float x) { return 2.f * x; }, nb::arg("x").noconvert()); The same experiment now fails with a ``TypeError``: .. code-block:: pycon >>> my_ext.double(2) TypeError: double(): incompatible function arguments. The following ↵ argument types are supported: 1. double(x: float) -> float Invoked with types: int You may, of course, combine this with the ``_a`` shorthand notation (see the section on :ref:`keyword arguments `) or specify *unnamed* non-converting arguments using :cpp:func:`nb::arg().noconvert() `. .. note:: The number of :cpp:class:`nb::arg ` annotations must match the argument count of the function. To enable no-convert behaviour for just one of several arguments, you will need to specify :cpp:func:`nb::arg().noconvert() ` for that argument, and :cpp:class:`nb::arg() ` for the remaining ones. .. _none_arguments: None arguments -------------- A common design pattern in C/C++ entails passing ``nullptr`` to pointer-typed arguments to indicate a missing value. Since nanobind cannot know whether a function uses such a convention, it refuses conversions from ``None`` to ``nullptr`` by default. For example, consider the following binding code: .. code-block:: cpp struct Dog { }; const char *bark(Dog *dog) { return dog != nullptr ? "woof!" : "(no dog)"; } NB_MODULE(my_ext, m) { nb::class_(m, "Dog") .def(nb::init<>()); m.def("bark", &bark); } Calling the function with ``None`` raises an exception: .. code-block:: pycon >>> my_ext.bark(my_ext.Dog()) 'woof!' >>> my_ext.bark(None) TypeError: bark(): incompatible function arguments. The following ↵ argument types are supported: 1. bark(arg: my_ext.Dog, /) -> str To switch to a more permissive behavior, call the :cpp:func:`.none() ` method of the :cpp:class:`nb::arg ` annotation: .. code-block:: cpp m.def("bark", &bark, nb::arg("dog").none()); With this change, the function accepts ``None``, and its signature also changes to reflect this fact. .. code-block:: pycon >>> my_ext.bark(None) '(no dog)' >>> my_ext.bark.__doc__ 'bark(dog: Optional[my_ext.Dog]) -> str' You may also specify a ``None`` default argument value, in which case the annotation can be omitted: .. code-block:: cpp m.def("bark", &bark, nb::arg("dog") = nb::none()); Note that passing values *by pointer* (including null pointers) is only supported for :ref:`bound ` types. :ref:`Type casters ` and :ref:`wrappers ` cannot be used in such cases and will produce compile-time errors. Alternatively, you can also use ``std::optional`` to pass an optional argument *by value*. To use it, you must include the header file associated needed by its type caster: .. code-block:: cpp #include NB_MODULE(my_ext, m) { m.def("bark", [](std::optional d) { ... }, nb::arg("dog") = nb::none()); } .. _overload_resolution: Overload resolution order ------------------------- nanobind relies on a two-pass scheme to determine the right implementation when a bound function or method with multiple overloads is called from Python. The first pass attempts to call each overload while disabling implicit argument conversion---it's as if every argument had a matching :cpp:func:`nb::arg().noconvert() ` annotation as described :ref:`above `. The process terminates successfully when nanobind finds an overload that is compatible with the provided arguments. If the first pass fails, a second pass retries all overloads while enabling implicit argument conversion. If the second pass also fails, the function dispatcher raises a ``TypeError``. Within each pass, nanobind tries overloads in the order in which they were registered. Consequently, it prefers an overload that does not require implicit conversion to one that does, but otherwise prefers earlier-defined overloads to later-defined ones. Within the second pass, the precise number of implicit conversions needed does not influence the order. The special exception :cpp:class:`nb::next_overload ` can also influence overload resolution. Raising this exception from an overloaded function causes it to be skipped, and overload resolution resumes. This can be helpful in complex situations where the value of a parameter must be inspected to see if a particular overload is eligible. .. _args_kwargs_1: Accepting \*args and \*\*kwargs ------------------------------- Python supports functions that accept an arbitrary number of positional and keyword arguments: .. code-block:: python def generic(*args, **kwargs): ... # do something with args and kwargs Such functions can also be created using nanobind: .. code-block:: cpp void generic(nb::args args, nb::kwargs kwargs) { for (auto v: args) nb::print(nb::str("Positional: {}").format(v)); for (auto kv: kwargs) nb::print(nb::str("Keyword: {} -> {}").format(kv.first, kv.second)); } // Binding code m.def("generic", &generic); The class :cpp:class:`nb::args ` derives from :cpp:class:`nb::tuple ` and :cpp:class:`nb::kwargs ` derives from :cpp:class:`nb::dict `. You may also use them individually or even combine them with ordinary parameters. Note that :cpp:class:`nb::kwargs ` must be the last parameter if it is specified, and any parameters after :cpp:class:`nb::args ` are implicitly :ref:`keyword-only `, just like in regular Python. .. _args_kwargs_2: Expanding \*args and \*\*kwargs ------------------------------- Conversely, nanobind can also expand standard containers to add positional and keyword arguments to a Python call. The example below shows how to do this using the wrapper types :cpp:class:`nb::object `, :cpp:class:`nb::callable `, :cpp:class:`nb::list `, :cpp:class:`nb::dict ` .. code-block:: cpp nb::object my_call(nb::callable callable) { nb::list list; nb::dict dict; list.append("positional"); dict["keyword"] = "value"; return callable(1, *list, **dict); } NB_MODULE(my_ext, m) { m.def("my_call", &my_call); } Here is an example use of the above extension in Python: .. code-block:: pycon >>> def x(*args, **kwargs): ... print(args) ... print(kwargs) ... >>> import my_ext >>> my_ext.my_call(x) (1, 'positional') {'keyword': 'value'} .. _kw_only: Keyword-only parameters ----------------------- Python supports keyword-only parameters; these can't be filled positionally, thus requiring the caller to specify their name. They can be used to enforce more clarity at call sites if a function has multiple paramaters that could be confused with each other, or to accept named options alongside variadic ``*args``. .. code-block:: python def example(val: int, *, check: bool) -> None: # val can be passed either way; check must be given as a keyword arg pass example(val=42, check=True) # good example(check=False, val=5) # good example(100, check=True) # good example(200, False) # TypeError: # example() takes 1 positional argument but 2 were given def munge(*args: int, invert: bool = False) -> int: return sum(args) * (-1 if invert else 1) munge(1, 2, 3) # 6 munge(4, 5, 6, invert=True) # -15 nanobind provides a :cpp:struct:`nb::kw_only() ` annotation that allows you to produce bindings that behave like these examples. It must be placed before the :cpp:struct:`nb::arg() ` annotation for the first keyword-only parameter; you can think of it as equivalent to the bare ``*,`` in a Python function signature. For example, the above examples could be written in C++ as: .. code-block:: cpp void example(int val, bool check); int munge(nb::args args, bool invert); m.def("example", &example, nb::arg("val"), nb::kw_only(), nb::arg("check")); // Parameters after *args are implicitly keyword-only: m.def("munge", &munge, nb::arg("args"), nb::arg("invert")); // But you can be explicit about it too, as long as you put the // kw_only annotation in the correct position: m.def("munge", &munge, nb::arg("args"), nb::kw_only(), nb::arg("invert")); .. note:: nanobind does *not* support the ``pos_only()`` argument annotation provided by pybind11, which marks the parameters before it as positional-only. However, a parameter can be made effectively positional-only by giving it no name (using an empty :cpp:struct:`nb::arg() ` specifier). .. _function_templates: Function templates ------------------ Consider the following function signature with a *template parameter*: .. code-block:: cpp template void process(T t); A template must be instantiated with concrete types to be usable, which is a compile-time operation. The generic version version therefore cannot be used in bindings: .. code-block:: cpp m.def("process", &process); // <-- this will not compile You must bind each instantiation separately, either as a single function with overloads, or as separately named functions. .. code-block:: cpp // Option 1: m.def("process", &process); m.def("process", &process); // Option 2: m.def("process_int", &process); m.def("process_string", &process); .. _lifetime_annotations: Lifetime annotations -------------------- The :cpp:class:`nb::keep_alive\() ` annotation indicates that the argument with index ``Patient`` should be kept alive at least until the argument with index ``Nurse`` is freed by the garbage collector. The example below applies the annotation to a hypothetical operation that appends an entry to a log data structure. .. code-block:: cpp nb::class_(m, "Log") .def("append", [](Log &log, Entry *entry) -> void { ... }, nb::keep_alive<1, 2>()); Here, ``Nurse = 1`` refers to the ``log`` argument, while ``Patient = 2`` refers to ``entry``. Setting ``Nurse/Patient = 0`` would select the function return value (here, the function doesn't return anything, so ``0`` is not a valid choice). The example uses the annotation to tie the lifetime of the ``entry`` to that of ``log``. Without it, Python could potentially delete ``entry`` *before* ``log``, which would be problematic if the ``log.append()`` operation causes ``log`` to reference ``entry`` through a pointer address instead of making a copy. Whether or not this is a good design is another question (for example, shared ownership via ``std::shared_ptr`` or intrusive reference counting would avoid the problem altogether). See the definition of :cpp:class:`nb::keep_alive ` for further discussion and limitations of this method. .. _call_guards: Call guards ----------- The :cpp:class:`nb::call_guard\() ` annotation allows any scope guard ``T`` to be placed around the function call. For example, this definition: .. code-block:: cpp m.def("foo", foo, nb::call_guard()); is equivalent to the following pseudocode: .. code-block:: cpp m.def("foo", [](args...) { T scope_guard; return foo(args...); // forwarded arguments }); The only requirement is that ``T`` is default-constructible, but otherwise any scope guard will work. This feature is often combined with :cpp:class:`nb::gil_scoped_release ` to release the Python *global interpreter lock* (GIL) during a long-running C++ routine to permit parallel execution. Multiple guards should be specified as :cpp:class:`nb::call_guard\ `. Construction occurs left to right, while destruction occurs in reverse. If your wrapping needs are more complex than :cpp:class:`nb::call_guard\() ` can handle, it is also possible to define a custom "call policy", which can observe or modify the Python object arguments and observe the return value. See the documentation of :cpp:class:`nb::call_policy\ ` for details. .. _higher_order_adv: Higher-order functions ---------------------- The C++11 standard introduced lambda functions and the generic polymorphic function wrapper ``std::function<>``, which enable powerful new ways of working with functions. Lambda functions come in two flavors: stateless lambda function resemble classic function pointers that link to an anonymous piece of code, while stateful lambda functions additionally depend on captured variables that are stored in an anonymous *lambda closure object*. Here is a simple example of a C++ function that takes an arbitrary function (stateful or stateless) with signature ``int -> int`` as an argument and runs it with the value 10. .. code-block:: cpp int func_arg(const std::function &f) { return f(10); } The example below is more involved: it takes a function of signature ``int -> int`` and returns another function of the same kind. The return value is a stateful lambda function, which stores the value ``f`` in the capture object and adds 1 to its return value upon execution. .. code-block:: cpp std::function func_ret(const std::function &f) { return [f](int i) { return f(i) + 1; }; } This example demonstrates using python named parameters in C++ callbacks which requires use of the :cpp:func:`nb::cpp_function ` conversion function. Usage is similar to defining methods of classes: .. code-block:: cpp nb::object func_cpp() { return nb::cpp_function([](int i) { return i+1; }, nb::arg("number")); } After including the extra header file :file:`nanobind/stl/function.h`, it is almost trivial to generate binding code for all of these functions. .. code-block:: cpp #include NB_MODULE(my_ext, m) { m.def("func_arg", &func_arg); m.def("func_ret", &func_ret); m.def("func_cpp", &func_cpp); } The following interactive session shows how to call them from Python. .. code-block:: pycon Python 3.11.1 (main, Dec 23 2022, 09:28:24) [Clang 14.0.0 (clang-1400.0.29.202)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import my_ext >>> def square(i): ... return i*i ... >>> my_ext.func_arg(square) 100 >>> square_plus_1 = my_ext.func_ret(square) >>> square_plus_1(4) 17 >>> plus_1 = my_ext.func_cpp() >>> plus_1.__doc__ '(number: int) -> int' >>> plus_1(number=43) 44 .. note:: This functionality is very useful when generating bindings for callbacks in C++ libraries (e.g. GUI libraries, asynchronous networking libraries, etc.). .. _binding-overheads: Minimizing binding overheads ---------------------------- The code that dispatches function calls from Python to C++ is in general :ref:`highly optimized `. When it is important to further reduce binding overheads to an absolute minimum, consider removing annotations for :ref:`keyword and default arguments ` along with other advanced binding annotations. In the snippet below, ``f1`` has lower binding overheads compared to ``f2``. .. code-block:: cpp NB_MODULE(my_ext, m) { m.def("f1", [](int) { /* no-op */ }); m.def("f2", [](int) { /* no-op */ }, "arg"_a); } This is because ``f1``: 1. Does *not* use any of the following advanced argument annotations features: - **Named function arguments**, e.g., :cpp:class:`nb::arg("name") ` or ``"name"_a``. - **Default argument values**, e.g., :cpp:func:`nb::arg() = 0 ` or ``"name"_a = false``. - **Nullability** or **implicit conversion** flags, e.g., :cpp:func:`nb::arg().none() ` or :cpp:func:`"name"_a.noconvert() `. 2. Has no :cpp:class:`nb::keep_alive\() ` annotations. 3. Takes no variable-length positional (:cpp:class:`nb::args `) or keyword (:cpp:class:`nb::kwargs `) arguments. 4. Has a to total of **8 or fewer** function arguments. If all of the above conditions are satisfied, nanobind switches to a specialized dispatcher that is optimized to handle a small number of positional arguments. Otherwise, it uses the default dispatcher that works in any situation. It is also worth noting that functions with many overloads generally execute more slowly, since nanobind must first select a suitable one. These differences are mainly of interest when a function that does *very little* is called at a *very high rate*, in which case binding overheads can become noticeable. Regarding point 1 of the above list, note that **locking** is okay, as long as the annotation does not provide an argument name. In other words, a function binding with a :cpp:func:`nb::arg().lock() ` for some of its arguments stays on the fast path. This is mainly of interest for :ref:`free-threaded ` extensions. wjakob-nanobind-6c4457b/docs/images/000077500000000000000000000000001474760012700173225ustar00rootroot00000000000000wjakob-nanobind-6c4457b/docs/images/binding-dark.svg000066400000000000000000000477551474760012700224160ustar00rootroot00000000000000 wjakob-nanobind-6c4457b/docs/images/binding-light.svg000066400000000000000000000473271474760012700225770ustar00rootroot00000000000000 wjakob-nanobind-6c4457b/docs/images/caster-dark.svg000066400000000000000000000433651474760012700222560ustar00rootroot00000000000000 wjakob-nanobind-6c4457b/docs/images/caster-light.svg000066400000000000000000000426451474760012700224440ustar00rootroot00000000000000 wjakob-nanobind-6c4457b/docs/images/logo.jpg000066400000000000000000015012521474760012700207720ustar00rootroot00000000000000!Adobed@       B@& 0! 1" @P`#p2A347B$'& #!1AQa"q2B#Rb3rC$ s0@PS4%`pctV³Dd5u&6vғTUef7E'!1AQaq" p0@2P`BRbr#3CS$c J"KTtRB1hQLY1bf s0] >^DEHD%Y21 Qp0L~tt\H8mKRK,aic),2E.K(XQ #18gK(B`.[P"-V28CHc0[Z,hd F$A$T(CObCLVTFPZH p%= #((hl2260 E2yvx hLzS-*ZA*2ud + Ki$P-)0"ʎ%lPAFD*G$" "$Q ],CG0Jr݄6t:JAD )w34:O>w:a+xMf0ŒjQx6Gbæ8ūp;Mc D0ؑ$T}[Q###@Zi˒+- KI`& v&NDK,_bmLrv+܆<&,`]9[ <<^B5j\!12ܻW[RS:gn3B"XpH#-əͿE@"Ih&T-S\\,W[j["nl٘llM3d"*P8bL.FD!$yЬMP($I(Yx|T|Lh!p6–PRT-Ei]kUZ\c;KIYl5iJT@,{9սXxlp30ddad1fgd|E(,|PthBp]Gn- KAR֒Iǫ0 ~k.fך-KRI"ng}4"XΡe)$r Ӊx]0-.ƲaAb1wŤD ޶G8J>P,@\PxQ8d$n-0\eK b.e,eJYU'5y J]Wӛz"Uj/d&6 XJXDXR"Ǫ\Kt.od%IJSs"ZK wef0 4XA9,Y(Y<"붭DaӸ[jYB29v"e|cV[[r&$<[̱]([E* A`t*\D2̔w6fΌs:91̋+4FsI'WyhEFDj;Xu[N%R ޻j1k}KbˋĒ9g-l+:!dTPRRDUlQ4%tCx Zbܶc>K۹71<[E ƅ $ȅM$FPL[I$Y\ظ,rH*;·kӸ<ױs13^VS@z3{cڛ2w|+4k4U^ᬷ&wRuOUs%R[$D xI-[FG@> ,4h|L]Nֿki3l] v=ILdf*3+) 2. %K) mf&p1T2B'B%J4G5cU1r[HT`@:4:zđQ+0hR沸D4ź 'Tרfs,1nl~{Mc~uhpymS6EWq=q#0|= ν2L5zCNG&,lxJGJ*# ź&,SYI5tֽGq׶c !"9l(MG6RBp`.&M.ԕDsnYr.G-Θ[WcZFB&;_ ^=7yA?^^:ϛ8tO-#\aX\VXe}2_nnw}ެk6ƊTH4F.H`Td xH(XpDɣ=!YL&\"qp y5P%R0Q_uO'hNѼ=y;>8nNtP.Ǒ׏]昨oQW+O׷.yι_\W+[H%" " TlQ@_xDxLOf|}uo֞}SϤXTVER߯^a^c]uƞekGl K`9kOVa؏QFp||ȸ,H EMKP>PQ$t|dR'&:e؊245V)cg˘([+s,Il`7\Hej[DdEl=a3[O;3f~owccvo>]=-9S1ߧroѾ.ڛc3 $[)VڣLzݚװ6y^:>MF(:LPDe3e BiDQe4S{5aoXl'M4caA !% RYR98pY4ZU8:pŎrId #s, dGK&:%N\L/Y9Ϧ鿗?ݎ|mDg֞=ɺxy_=9̼Vÿ?1ۿO8[Mzrմl̤#A.v瓶閺a,).TD\0=+6?J*M)ǩBE]PeF.e1խ_SXG $AJ4 P .Cb $j>$o9t涵|`XYUdetMyf"ː-ĸc]o#)]fݱN]1n]4.>}?|\_kvkտ-+U+^%s*ezLwxe7~+p;˖5&wޛ|'шf]x;MÜ.3~{svלI^@HY"TdjaRrR`9@ءc#ơkG2kHFҋB*C4JG$ >J$yvttHҗf0HZ qؒdԷ8.J h6ؓ5J.7-s[ ΰq`|?[G>||Q&SļE+Eu1aƋ~/~>vזkОw?v>{ Y N-t{q˟ELJi.&ԐoqE;5 ֖D$BIE (FjH1@*>T5_&A^rZ(E-u]{MK&B%uNۓ6qX^lIoՋ3ugb? f>73;Wn+_.9Y#Ӊnv3Z<{\Ϟ_vn{/OW_zx^_|~~?}־^>9m ߩn~c ߙ^nֿcۮ.>ywk=聩Nk] oI799^tIRʎ,4 pQA£Cd#ChE%De白G7D:vlfm"H:lC KtK4T!^#2ؾsq9g;{כg66}$qN 诡˗z_byrߓN+z:;ӆU:du>Zu,&˶Sk0iZt@ *G*4W$Pآ $BIVI$amv́sY64\b;P icMgـ %r󦺚1&/Ә3#:违ߣ>е|^=g5;Wi^ 93[? 2>߄/Oo?Խ}AQ}'Hf;GX\ #:VƸOg\Mm-3&ɼ[~mC|}GŽ>g#:b>5379ޞcz;|ݧF 282:E,PQ#D "C6Κs: KW7lm¥W+#`Ah,ɼf$-FxP&W"4c\u݇:ǧhk/a~z|oE>GEx4:lo57ƺV%t*\_oU!F5_˟=w쟉#Syw߿^_wrkqj/ܳϏO]Sl'Mb\f=~ۼ?i9w|K87^jve¾xΤc6?[r?J^~%SC6T@Tء#B (-9ӌ&>2Y˅:`GGyhe1&b֔&+ıR⹱%Xŏc8=ƿ5m_~/uWé~dGv?̻ Ҷ*ŠagW1_}K,qqG}17/OS/^;rvOv/W.YC]|ޅNtPeJA#I AQE ZL[*޲jtGTl 1B qj6G%G Q֠KqaJ G Jࠈc2ܦm1O=Xu޾ }VO??,?/WӜ-=Sg_aZZ(EUPQfGklo=ʿFo3ߙ~p?oyϯfxq}>/?xz.qO}myv/5ߓ.̀Iz9r'~yі3?[ ˱asq Z5ٝ,ޠ/n1HeJ TQAB@p@ E $GŚkLzX.{fIeri "GU"\@&e|t dr &Uf&tzG=ä/'x?f{ߟޖ>7?G<'yyNQEj*7a?6O}~FYJF1~_ [+st_(K^&p_ikt} ?oM<9'Pz3~^' kËye|qoi}uAS/{"?d}<.}_=;zr~VE $QA҃@#HBUj8H%hY]1X-%Ρ=D`PlU"10bɪs$!]% #Cr=^<^/i_E#'tW?ޘV?75/⟉~WgxFY~}}+o [+ۛOW.)qϭ__G,K'6r?ǞznǿO֜y?b2ᾄF>ߝ_yZB}1pG}xw'joY|f<ѽ1] |x7gM{-k>//GWŬ>-[WU]1O:/{m]A|T?־jl5_i7_+?;}W Yߕ>ߣg|~z_w?uG >ƾAO>dx7|koT>_l/~z~I~.[`4uy/^kѼ'l7^/ۦ=~{|@@(8E*(JV ^(]5YF"騡̗lJ  *HL$H IAVimZGxtc?_\O= oE>>&|/痨-_+գ~_&ֿzʋn7Xw#u:g7~d>rǯߦƿGkGx􏯃y{cyV'5c}} izy;t~wwN@Z1 9Υ?[}-9^}={t|pۿC8qgҼ8^}N(<: TXE EHQ"ʭE*9*l=}מFY tE3)\[ rk{,5(CQEK80 ǕyΑ[ê`T_\1G?#I͏ԩj>ok;㦸 ߏ{f|V^js\}//otp䟧ݿn_7kݝۦ+ѩ|z~W}|O4;sy9vG;rd䟷to/W_St>s_/Zx}GrjUjV[% |{_i?yߡZ~}_?_?Mq^)i?6nMkD~=<dzwqWO5oyQ`(,( #Ad *(xhh[@tlE$r[% l rsP MAejit&=qa#Dx5+RuJp/O=V|\/=?~~;35?U'@]z߿Q|,_8?>ލҾ6;ן0O^{zx|1G~+*ngӍ\1Gn\6wkշѶtwNelPnw?XS5C&3+?g~mK6<7L5܁g'O^vxUY>>-|3~/z{OGmgO͟ >vq%u}:ݷ]4^h>mGܷw)~W<^suf?;s>nyW֬ח2|/e~,k}S$征z (!W'&\lD6卍 "@رCcDdybb8xI!aJ2yvĹZ YlΥxEtk$:ZEfG6"Wsk7Vc;w6}v1Gv>Gv_D^I3~5{ʬ9b E3[ʿMK/\a~i|Eb*/:Yw>ӏGn|++َ]~w6Gxнl]#n\۞ʶc}:7>wm%3q9ux٭zf<]$o~W|`1V:c(ǫ-;.v=fqV{y2460FFU$ңCD !EG҃uAM:Ed(L4aVh+r!1UMEƖ[q[6\/RZJʩdfL~~Dި+ocG~ٿҿ4+Jd5~gi??ÿh?#2+>N?d#{/_oiN}/gl\޷lE1A i,5kŰ`>}|ݷ|f%3gۿ?7IGý2EPT !%Fzr{tCG|O3_.r᮰o˽I_;_\9+VXс; {ˎY̛nc{7ռ.yx~^^u}.v_WL ɎzLkږv|}/D/L1>Wկ՟կZyyq/ox^Kk'i'T>O9G=Ͽ>V'|G?}B?y~;2}\ߜWL(ԥA5B)R8FGk_77/8~Y|>'.cː} w'G?^y:7yG|=e:k˸Mu+<^t澕F>=~u{?<<=f']**K7IG$:2F1/<^/F\럤/Wn:>2/65/VBI$.x:y}^ۉKbvӨ-D);Ad0ppк%epEYd"ƄAlmlyfM\ŽVZ V(\eĚ.&ٹL $e4hwf _|cyGv߇[v|}tgɶ|}SUQ]#lj~u I<$/<>gg]s3)5\,UH,d겕C,z=i~[| {wwi7OSr[uy8_Ũ>y2$P uyvNYަO@HF5l&ϑ3}] XfDQ8q,Tmhi,(ėhn.la(Ђm# ,d29\.erhmٗ5Z5$H)x" z!˽lA#/: 5lzk3p8cѾg/x>}[vO|O>=џ7Dy8THE˝;ﯜg)O~_%{Jqopj6!H(,HqU}i?GS=xޝqJrW/pF~Q x!ֺv%\-LEtcgUM^ 0i{Z|=)ן~nyzחw7H?3џ6VV5ޜ?#O?G ?C/gg>u_|pt;wbѢP؋-Qη|w빤yӮ{s+ؕW]7Oy8,yfzgݓ:^aKI%>ȹԱ6: 4c }Xs" $rH&Stn)Ӎ_ .\60si6eV-DjL@*@o re^W& 鮦YaBK%s+b1AxpõKz7scݝ7M\:3ǣ~npכO7Tp+62[wmkͦi8W#Wwq+^Ksw7d뗷7XM`$w1 >rnaۚ>lN:|q{5FRRXG\/#z|oNğiGvy#/%]ogHWXY$kXɚ[S2>oMb/Kf}ݼ30 yn-1s6:ݬŜ rw::o4$ n$nrfYTjƴSKIM~͂ff8 c Lv<7{3aJg<=hю[V5vܺ:Wu6[{cx}}Vϟ*(cdk}h Zg-ԋLDvіi7u`nt|5?]." $a#A ЍmC$ w1]q>ldw8:؂y&:A5͎-z_c4qfδ^s ,xbZfV3ii<-7ˤ~z]gUwƊޤfۥ2/Gl;юZ- .n9׶>r}sξOz9a_LykrF\j:|OM7#_gzϓ%NTMŲ9󞌺֕pN4, 2&Ny9{rQ$HtM۱i6z`kX%Č̎(+%1B:[)14%1VlYv$+DT>:Mx:Yh3 =$ik)IL8yn.WNKåRv8^_-#(^޸w7asw:ݰ\+W(WMJjp|_Oh~/\2x壞IӍ/N]e|謻~?{>'<8Oڶ_YJ 4!큷VX &uZ 4Imvrxե?Mn.eiEa* I+T܎-̽,Iܔ ,Ixv4"z`[ ˡ9meZJx"v]HPڷ)-3QcRpm^eKs1ee꿟im͡[*ewۛ2uq^[)Gu9w}?Ƕ;W8SݮMf_ͣq^7^9Mo7(fg':u>Ɠ/N9t~>ůqu9O{zs~7ŀzton~9H҄RZPEJ%'XMcFlI6rTRڝ学}?60ThB4 J $ zE hG!SQ nqlyjCJ\@H*(BD%YJ ((ޝw %䘠عY)"W%LʳU͝.Ӕw9Z*#<̋H3?6WeŸך[݃[t} o cx62}|<׷^{:w'盠mM*pqDuBMcM\3Z:2r"&˙xE%P@$FJ#$r)AEPF"ڷ&C.횿T<:FEUbU\J(6(X4PU\ԫy9),٦X7'㨸|TfVMXEحujɨDj=<亱:ߩ?Oۿ2z7}IJtӎ1>̧-yՍ;Ýmb'{߯{s,IR!*j#Dv:(XZ)P%*HT#-[" *4L*Yc@HZ##X 4CǕjYpÙeg6>k2H@8.Q:Ӻ4ntO0w cǯWGz-߶8#oNX=ݛ7ܿ?z07ͬ=3]Zz:3߹.4)<+ʒFRQ$QQD81#L5/1Fj!l3b *GbE"J%D 0Y !Y\㌑Rlƶ\Y : phl4EUH66(H)T7 0=-!U e;*kZJCcM-Z̊,U:7n?>P|N'dK͎}]oջ4U_+7L ݵz:qo~N~GY~ګr1~RW'g#hB:*ʂ" „ .,GvruZrJ 6<2PqV48WD6Fp A`4TtEHeOn};Y84 KfW0QCDTPA$bJ@i[T yAE*6I,x\-bҦ R$uE9c5-L?g(\}g|-/~*8.=wW1oI7<^~uwrkyHKWio\(#2($R|㶭|$pl4+J"Z FP*URTJPhu]4葴dYQc|IB<0220B>3xOr2$R nnC \#*(HؑC#H(yVFJU#)AH㊔* Å%`rž(@pBFW!4 XŒ)b,M|^>L}|7>>xqܼ~^>?R|jR5_!ػ ۟,o;2o>ZGh 뫣8i$ txAZ8 k(ϝ<$ 楀X\مP܋ZH}RFXPtPJ\4,HKAB#eBGS68VG)'c|~`w2:/o菉g0EoZNeެgZśo[-{zc#ݰWg9\/oEy3EŝyidT*^6vyY/磳7f~]Ѿ?~Wgo@вANҭgԋU_#B@_-c\T"NUu͂ }oKɭl?m^>g}g??Gg ul׋ ` տ?5彷aXb'6r?/X23dycF^ael ʾ7ˠDJ>Cp+Y E >w͜ͱ@0{ pRޕ8vk]fKcHK;S\!Kyk% n%Rh-~w6sNY0I$hXq(5 B8"6LWGHHucNr'?N[|d<4 :g;(:>8C,gˎzr>7$zoM}kFdw2ZbY\ {sqꖳuFijY׊sv( ]쿧81?=zy6OԯGp>>1UDվyDl@4tg2,Gȷ>?@Ž(|O67Y(E$S:1W.8,P<&X髥n.K6[g~u4(l-|RP Gf.dPO6sNYR*:86TO4ϭ"FdaJ >9s0?EA t({:c;-"-I62Tk>N5[ޝ)Cgq˿Zy<]ğS8k\zƅD ')#3:6>Zmż}&/M^:ϳPx#8J#+򿎜*OmGF8#zlb1/Ӗn(0 "Ϟ;:A[,*4yy76k?F:@H %|wok""TYflj%Kp_͜13Ӗv>D(,Qwѿ_QxwʇWbE0d@~yҧXIVfޭ|Va5yvoɊkں,&:(E o3Ӏsϭ]zhpEϋ~}_;S\(Tn w-&p =9u` "GJB~ga}s!ZFJ#iA+>g|*s] xE':OΚ-Q\DUF꯮lxh|AV}_;S\Ё[F%dp(:N=<Σc9f5hEGU;+;Ѿ}s%DY$N$ gUMǭW Wd:_;LjD4^0 c fx/)ho{j9N}I\&/{^usD #ADF 3"3c۹5忼t=>;Z_՜\p,]Y_WЂ9YJ %/:X{>̈́yhPq1> (4}];ϥ8"Q9uϫHZ ؒ[m+݀J{,lO>|3͜11Ӗ`iUPE2G_ (3spT78k~ a~Xؠ*U 8_,tobu|tn؃~w^>.ϧu(IǪD"Jɉ1]}DkfVuam|]?߶3麟|$ c|Z ##bϓtv}zoCSP/>UBٚ}垊#ȡsOQV_}e?E( % u>5ɲ'@߀jI(x{:}噥ⴒ,̅pX; (w6T_>@XYPؑN=\`{zT+*sӶ3|;\~#^;j& E $ Ovq|TlIϑ}\=E}5+|㧛SQޜၡ`GYߊO-˖ʕ,kϬgXBJX!e 2/>ϧj} kHHu nqA<4$O6ؗNY<6ŏRѝT>q\*8P:; ?FczK󍎁ֱ궲0 <>7{F iU' M|c{zrבXY^j]_k//7?;vIzEc$q_>r3;3x;ON9/I~|>|^Cj-{沎!ck|[V@Qdk4uR"ґ1k?@:0 *|㧛SQ^r2P!TTYuv3|墣vS7U$*Hb zgQb"Ki YKsJ(b,e]#O6sطNY89(tu\|/u[ jHkE[Tg^n;,3+~Ծ??ՄK3 ][_X;oGҢ k/:T;YX n_tpY\-d <ۚ}oiLIW3R[w, |c#K&wg$ #>-xO]r hZuzi-&\%b2|gYcs,V#G9ߌyO+Rϋn}fgӆ൒E< ߽cMfBǔ^a~ء8N_ttu^_?>:">NΝA~ɟW|V`zk6># *|g|olbn;H<";<57}/G`A ][_X[ACb@$|g|IfSRM|㣇JW;ߛQHД 'tG|0xǻ˄rX,64_}_;S\e-fdny($-9ӞkQ2HX-T WL<6 @,\3,6IU<mc e"Ǐ'#|CC p:ǰz˅]u?6`gBrn~>:Nk߲ʾ³M3馳ƱwJ(Ə5qg<;;xz=8wUu}\Ǿ~|{Iڶ:."g~pAЖ}ao *iWQmb0Oo͉NYz<%H㇋YߋOM닗`M$OXY([ߚGQ!lpJ n[&Eǔ>v6NYaDZeZ sP;׷/-@Xx7PgAYrNkzuXu GYׂ}$ov6>vj-}(X.{v54NjIB{G}[ |2)dsG^u_conA4>|c_K:=%qekuu8T@QGȞ:zk,pԚ}嚑HT *xǝx{>ɲR2cįCnz_IU-:w[帰ҹ =.%KE<9u,G-TP:#;۾}r*J*c`(Xk!(ׂx}$o80t{c{/8qmߖtx=^mvjSO^f{ŭk}c܍}9_&15ۧT{:v5קI J *P gfڶQPq+k?@„>w15d9eG#33h>JYԾ gD TXqQJAc"fM]drYs.+Q;=<ΤW_ҫAeD'߁-#(X/wYSnA UHd>6N[$s(Xc}e@4|ѺB^??Xsۡ|c~~9|N\CȀì.b?}d7k;8z17\x+{/F+;)G)XR$zysƳ  ago>=t}cGYߕYSWP*4+(e<+/}qc CbJh;k?Bj#Tc.0b*k%;훟@hT`(6[ YPbJ"/Ms (Oe EG 1Nuׯ5:GEJUˤe_YD6mݾnKqGzs_SwVQ~%י/ջm2j5YL^_F᭑r2۷5oО['ǏwhgЯ}/7Ⲝ/V[ē 3uWM'G؁*0W<ۗ&60C% Zxuϡ64((2[ƜbWw, :TIQlJscZn0±;a#-5YVi(]d+D!8 @ĕJVJJ6,Z(l@(@P:Ph|R*8cݼx6?z#|<Qnp?W<4XFnskLrwEn|v]>}\s~ ?竿@ֲoV iVm$U TEh08 H> բ)PZ%Uu[EVJtlD#j:D (@& eQc-v_艩@ K, 8dpIVJZD $ŨqXDUB+)UP&Ō-H x=;[\r_F'|f~N>59qz+-Gsno䯧奵޽Cߏ˭gZG*@*I- i33O 5U" H- VAQ%J"‚ E68(@TpQ"TYEB(dj$XQ#((:!Tyہw\n'{Mϯ߉ݾ6V3^VXnh_ޠ{6_ƈGSKfzsRƷCTm*UR-e((XPZ" TAQbDEQbBW#•BE *2((dt|HHQ2o9@"V HEDt (0)U>@> C U G"TCh6i]E>r|V˞z1މl1~y/siJҪP򶍏KDH$Q ҂lZ46*!PT +I }]TXblA#-`p@$<]5$FIi%R(YQZdQRJ "%VIA"D+eHB6 DXH)![FǕf_^957ۆt34vxno7Fx\q?~$c[s݅u΅}>~nC]eTp`xhm:ʑ@Q$*GF(C` T8MZŊ$6F204FF q  .SSI:YeGDŕTIRUBUt *K !"U%#% b 5Z,zjN]w[ 9ѹt~6 wl϶=XO->M{x.3zzjˏA׹pcBQŢPHT )[+ D+bj(JTRY(||[:ȥ62^0426B*:B-âQf|[Zz)LPżltYA%QK$EGV@Q B[ IJAAB8FE6ӾV;rDb8g;ɏlG~E;n7[OgŽLKf5^:pnKnc=u1шITI :(J,lQ$cB"GVuR8%8A qR>8xz/˿kֵbC wL7,kP/%kgX.tyf+}yYtW:맾ЙўW^C|y|2%EGCꖔT,]#HY0ȵe(-Yk>KIkZJ`4K8:vrČ-Cdbq%KI7H!_E% srW8E(($P (6Btzs?GFfn5p9vǬd%̮mK;=#vdni3YW?~|?E>@^^<݁2бxZUM@֐P nʤ"@Hj$`^W 2FZ "Ũ>MreBb+,Z.fa@ w6ԹIԘdp.+0uel;ͱ"*QHPq# $dlt4ts|zS$LaKh2[2ǗVRbsc]*]ѡB 򈑂av)`(;ś/[߷N^!$Q% 5yki8]S; Th|TЭras J&鬥$牦Z[^, Yl2r4[iMBDdJ>dvI:Y87g\ۑ*$JJ"a.ι׋-TZMDrpX(( y7 t=X_j[dN펹mŶ/Qkz=G쏡~Om~NYοp'K睕ەu>v֛ȟf==uNgkj^&d<~|]!Qw>.mv:ʰypw^㏫ωzuέӠ=9ɴlPPMG&,d+:"RJP|GK\6M "Gf\1r kr+-rsv4 5e%œHY2ػV"Fk^w JB8 6$tl8(I9ɾQ1V^ђJ02K ^9[AVhxFJȨ/滃<-g|Jw?îśd[wS9_Gmsy0FXoc9 +ٿ7} <^nWܺZ}5oO3eFJImV3yfj4H*Z̓U҄3/+"GU f --E.9q֋42g1gj$ή盅-ğSy u;X΍b>$KhP G_1hkzLˉSb&"7T@D CFETP-ƖZ\]γ7cvX=,g<>wm_4{#ܗf.X1 s3jvk">|ߣEϯE~"PXP*KTvh0θ$P vklQ]|֕Vj9{(m&631%C-HWPC\1QqYBƉc$a QJPtiAђ(UymLn$a3i[1K@ EVĔGՒ:PdI)ZFŒFE#wcsy";ͨ/5yy-/V=S\<3X'nws5u\gS-j'OsM#۲s\MVQT#DuV28Pm)T%RjVi{5Vc/($qi΍_-1zv9đov3Y" !\@ cB&&VGT|HF^ltImG,# "h5nnȳ.< i5󶭂T}DR%[@B`a>T9?7KKs9ߙ7?aC:z9 5WO]IٓC]\9uMnOgͣӦx{tg78ryW'z"DdtuV(KT@б%DQ.Kntbe!Q*z}}뾺ֿ7~׼/ۜ..wo/]A B%)E@IVE"ʫ"cĐOZө.:eR91YIˤvٯWU\Mj-FUgD %ɣ}>4cɈU"j xkYm8 m%ؗ= A1yyL޺[ZEU%Ҳ4HKrhHء% ER8J%U$aX*k"L0?f366[;/|F俱9k_[Boս֋E HU E*8((x\4|gaĕ&8:l{n,%ՍV,"ʕ(FiקzeKKX6k=c3ד! 22EmCze՝glg?GAk֝{=GBQRQABJQ@U]IkT/:c/)WR2Ut^[|,&3ŒY0K5\´,@Fo[Add wIYsߎNJXJ]D=7e2d,AFw^}QKDu\$ Bh/{z}Zgc6yۯ\Xǚi: (0Q$yzy_+X||ּ}l+Ǽ~=<7.qyR2%02+(QCp `8uRlv#(VFkZ.FigsE ł3["[52L$5P0yV5-2.YH+sK՝&糒*)XI*b(^ZI%Ė vLK>.PWʤxpl# a{}G>EӞu Q;m_'s4GN^8_cc&eD׋^yn͇f.I=c>޸זn=:yAuADJ@6^R(qWR&:8#6G &\I1u~.Sy'}t'/Vrv)vϛ=yy~޻7:mO^wW{{}]5$z,JU$x|K3sŝRQDAq]GeEE**(匕'.kq':_0lIZ,,()13oSo6~us;x|˷|z>?/=>~yr.\/[}8\^^9XVor-cLbޝ﫷RzyZ-$*fkUɲO1+c:f AIBDthPQht`dᑚL>Y"*]5$ r UH &eeJ E*ReAd( BTȢeĕJK]0ֿk]-gzT Ε,F]~wo}tͥ>,VrtAWMv_ˮNȼ?O?isj]?Wӹǖz ,tp/V,wkvN_8GP ,jƶԓlm4]"1ZcF*9B(BƆJ$K4: M-" xd3mKfk4m/fQ,HY#J# ؑ(U2,q[J<VD "(uh*Q屚0ձhbkFKmy5B b5^Gg+O{]3t֭kݺSwIӠ&wJss^QpDN9'f7=q霦_{;o?'dk|ZߙUz}!h@-1:faΣ*^YFJF"E'ēH"o" .]-@Ffr.rH,P8: d%[Fpm0 xd@(H(TRְr됐ءe6̗ԴY[ё'}6?Y?.Ky]gDg6`}M+;ˡWgO1/(-~;}x6Qzl8~_7~,iR!Η1s+#ꦣ# DH08BXJ# D-VYvpi{&Ǣ췂PRBpPyYJ @DVC ( H9Ɏ "1*HUW224j}w%=͋X9k-ˏ=O?;7{׸D' yS:s.E}]=&}|\3k^uJ$X-uCXYui3.53R Uup%D AAt-ÂƊA&%#Z[].F@ ^Yxl}XFQbH,|0@b LTI,X$ +82uA0.1r7K7;:%IAs^kӦ[XZkݛ}{|v\j2iFt㖹6ü>+[JWחwtRi$UJG,ac dhXMsh 2D-GJѡNU!#𔒮o|W y٨B\m, ԘPJ9@" .B  ("N *I.RARA`]bEdɇj$llbU9B"!UB Q!y=vg߼$H2:L AiBCG.gF5rSr^N$uR!%F()T2YRdW `uK'`^D[wKuK e IDJ-eaQM.:+%,]HE '>7gM;m"O,t60Ns"Ŕ4,Q@k7ͯs::KW }Fʏ "#TqR a(H‚$Za+Mns7b)L":̥ULVilX6b.e,(b  GƌdKp0{5ZlHYC$1IXHK*i=H)qWIaJ9uiw &߱Hءda c;YӉP''FpxA-]J :$u^N^t K.H:9#AfFh' R@@IR"Hf@ddյrȻP 1ìČ>ˑ8%e\APs곢Rl$T87WK+cE;w6(J E5wyNӦ&}FG%Qm6%E+ȡƒʄI>E%B#OT +Q"6(B% j8D  &-d0V YeIh-ē7l{Ț/$bPh cbI E*-TTH(aPG E  V0C@ŷ$сJAdk(Z#">$DDѢ90GU"!(@L#* Hرʍ :E*86F% z XX)2v̷U 1k_$`&IKxhI$Q"lQQE GHR9 ࢤQ҄FGE# C#U2Δ.βՔ$ƓI#F ʊ\#(PJJ! %¤ |X $e6Yej:@$s5͔h $TPCFcD3t-H,Il0%9d `8B%2Cq84<bIByR\il:(pp< lh Q FH(R X"JcE/E1GIKR@(6:I!HDHr܅r(T # KBT.ljdRHj#Sh|Z6k$xY4da,n$],bXqlxƑrIR\ȤrH.+z ("D& $Bq\WOqqqX83qM\?ϯ?޸<ϯ?<\NkW55ss^(5s\ПN}~>?B+5\5s\Қs\\Юh's\5ssHqa扢h湮kʼ_kk松TkkN/|Ws\4MD4MZWy?ss\54X g^TPjh 4hcLiڝ%jjy=i_~q^ ,W74<_a^ZpHi L)OJ )h0?> QAT9IjIi&⤞ziqFsFBzkZcT/QZ'&W^tјОYF%GBjӊ\3ǁi*I*Y*YY'OFj7n(PqZ$nƦ3{"FQJA\55 *x'/ OZCs\5s\s??FƼyr[Azjw$e%jiWK-u 5kg^4VY7>O8*cf @Сyk湮k湮kk'&idd;ԲԒԳTKM%(LqBSBSZiwYYERkۋKsBNh^85>4;d@4LLJЙ[Ez0Bs\5^U^T s\53%sDqDQSrOyK⥗ZZi)-s\&TrzjKs'ʼԷ(ê~xФ&$Ǐj)Bl1) $XeP Q^=yh&} 5A5hq\l׏IsFsL@ێC槒Jy(54XK5iƞĊkvZG)ZN3qe-`Ic62ouJ %";ަFYʌɆElj[IU'4DS]TrD'4<P4 (,UO?y <E3}NZoqj%䩤dLVZJR` ԸJW8ҴKgva.WsZomͲ«/WqI$f3FƤ_ y<YTj99DKqvE_1SSZ5+P4 2]0C\?I<.(h|DW2Uܵs-O%O%HAjʬe2v@[AH+|ddG=Ba`LwMkp6yCFibx+ˁzӫʰc'No0=$F܁s4Ѳ"Ԋh_d%itֻ嵵? mn)/7qpdloU[۸iIBYPJnQY^efA*>/T~'ȤUnEkpp} ޵vx_-elcSbblQ5K[c'sՍs9&lVql&9 |GSdSn-ռU4"Gjh[s *rd(B3 bUd@CƠw#FT@IWb䌄`Քb&;7<ѼO4šSTRL*uJ*D>'sֳ9P\h߲Q#,`Hֹ]f+ŒomW䚗[-CjyR޸h_ؤrZ3$դ%55--Ghn#UEIfup#^$M&ΑAF]#KKzkkV, >~4hѦ˜STZjtҦJ*d^*_gb&d{jnOJ+'./E >[ℋ^[J9h\14%&yW5s\5sEщ MZh Km$exR`9cT^*9#x X IDan[-~.ϯE0¤ZjdJ*dRnNl-0Q1zY~Ƅc T  QK@PZ*V^LܳE%(4O"@&Uwr#>ŷǧ?A?["qN)H*DRJ::>jX⭮,ZQ'!T_iI'+X/3 |^,حjkaa [ͤ5^v*5ZZQB0qry3xHA/Q ]uV5uFy~u5%8 Z*TRJ:::x* mT; 3T,S湫5sS14X-n5.l˞ۧg_#qڨs}YIi{:)ZQJ(PCTqSƱ3+,Cxa C%n1z3oʛHGNkӏ?8}8/_z\s}cLh aL)֜TN"TTTO====SAM E^`*Hi#* **:*5ZQJ)E@PhK*NijooV7EZQ[ Y?@СCyӊ>?"S aNNO"sk h9ѣFQi)Ҟ:1Pօn)1SZqR[qOoM5x{5B*Xia Hj88)EiV( LhȠ%8 -x|>r7V{"qGǨs54h"LMan1N*Xx-ং (B Xia*8)"*H8ZU@Pe%GST@d|Ze"ͩmBcArO0$Cx).ј;ʒ/aL Ǩ1O(#O՚")Zeic Xx!BWԨ%KM K$4ц([BXi!H)#N)ViV( I(A>m]*.^-ZKTXʑ.)7~2*EOϐG3#*9ڐ[it"7E4kz9EDQZ+EkƂB޿U$M:hh^{5(CK ,4K,tAiViV( =I W-k#Hq/x[ccm#;H'~tp*ZqA"AuG`e4RfWU8C7?_k4E5W\zA= Ny4h"VZ54pEpE\tc"UюhEEK:XAh Q@PCʡMp,^4ZJG*#|RJ&RC?+"( ?z5qϬaNE+ۯnB: A(%Ah-@PS\,C+}d|Sܵ@YXxRBD"FFXDTS.MVi%B3r0Pm O?g⸮("x+9?j(xWxWPJ Ah-( +@$%xBG4~W ?էݣh~!V'-b`Ja0H(Xn`sQ>#⸮+ _qDE"+ƼkƼkƂWxPZ Ah +♂ ֬ek` 0 ,EĠF+q$ p+C O:xѷ QP/%;H\,% CbR>⸮+SDQZ \W+YV)&lv1kHDKR[`ʤbQM 2B0 Dv>/ FpV4G>Aǯq\Wq\Wq\Wq\W\Wq\zqC6o4eKhיPF &Oe⧹2W53?}qP}o}G$}G> akqOpod7I-8~hћ>\W!J{4R?5}>UmOG?oޣs\g}#?ʉHef25-cRME}"=[?24 g[F2*}?}G>ޣQG'귨?H(A_b70ݣ7$dcP$+PLd\^@)_OQoQ[}"kq?H5QoQԷoQI+A/5-5|]Z\Om`',d0}?UGXR~z}@gHA唚0їΤ9x+nXMkvQ)]ԯON Av#{J}>3[~#[}3>_jiM8)FXr1#,x$7?HY\ D*1(\tB{"B&6ğ`d}WޣP~[}3>_D!hL$,LsKi _VI!=A F>QoQ[~2=Ak湮k>ϨG׍^J]-maoanjHf׊{H\ s\5s\ e$b,k{)`v j*D"/>k湮k}Wޣ9*湮k湮}G-[}>g}#꿁Oc5pX+$1-glV{e%.l|ZPf W"U~*dp^2ԑw* 6IYhyI9Cg귨}aI}>g}#꿄< E .j?:Oo|~A.g02~ש4F_&ۉZx~gJoh t2_~S>PUq8>x׍x׍x׍xD\~ h x?\-JJW0@(hfhK\pc|# Wdkef%]47 Z=wS;ar\ 'T(C!/$B)Ng^.XUiZJ{ ..kQ \֣ͤ7VpB8XW1b44T2ۀ,:h-V^{t[9i걸B'"D1,U$cEJm<Ԗ/"/Gޥ=M$c)H,5qoɆ!P]JI4Nkyss B0.aȌ1⁧5,EhEHJBXBH )2l,a=qR[[E}FD- Tך`kƸ?0" 4= qA= K{~j{"m(۠ėZߊ~#u,(;5ٹo4rD~~O>ԑg^'I(/*A3/ V}4jkCPa>᱈FwgvҌ]3]V Z¦XٸuLU?_عG?o#V@Bc>@=GS.}kxd#q!Ŕ~6X}̕R<(SZ^5%y-r3xԳI#<'$$R:U #Z3,_+[F fOhT3^ψ(j*IA)rEY .nyPag2a->4%Jԭ64TIjQGޏLr:VF[pX@+aAG q\щM=#*ȼ+bSZ,uot 53iJe'ܸ55@%{M^ )_ťJm 6)?U7ڮʑAD(aRB̪O㚸-f~B{rOpPdԆ>ڂ֡(@BV(CsHxUsD_!q"3,&fX*Dan8Y!\QW4 s,qyMo2ۘ jp'rH'FO*kTUPG42 ܭO*I^i%"BJʯ >AJ觲,n՘1 MHV Hҏ| }A^hGBߊ rANp%*Pp߈kˆn)hccύ]bk ; +WEr(5ȧ=\PF(P]1p xQVGX)q7*mߚ@QN?}u6+P~5sC6Ġ+ySϹ5i&UJ<-YE<y C}s?5q8*漫ʹ9?#;G?>kN?\^_?K's\5s\5s\Ӿk9kIssss\5s05g?+I湮kx׈G9ks\~q ׍xd=?^PLy)5^+Šss\5ss\5sAq\Wq^5\Wqq\zq^5q\WEq\W _c\ⸯ +μ=8H(%}sϩ<_ykӊqAk ^5^4V(q^5q^4kƊZ⸮+">5!^B s⹮}8渡L? ?Ё@PkƼ+¼+½% +DQZ+Ek"+?yQO Mx8zq@P@PZ A(-^^{u׷^VQZ+DWVDWTQ<>(W?nkУ>~^(}8P@PZ A(-A+½½ RQJ)E((DQE\c@s\~U(N=z PZ JsB: xWxWRQZeVEDQ( z\zo&AǠ(RR*ҥ*RA(-+¼kƼk¼)-iF3_S^5 )eEDQE?WӊԟADN?4=Gp( R(JTJTJJ -KkƼk^xyb(}h?#ב#qyV4x>:ʹ *j5JAh-xq\Wq\U{IR/S(FHn4V 2Ƥ8mIree1O? >OsJ9Ե,ؘA`mY!y& (RР)E("bj3yci{j޽kz֯෱y6ԑqJ5ql sVs GpRsA3>.-/#nkIf'\r#o-l : ~D-lۛ"p>{FN_t-KB./zY̴L8'4? B ZZQQJJZZIz8"J< ( O31\Qͪ`ESds#["\'ʹ~z!D=OA*,Ux"P*Y< CX{kɞp |^bR|Lʤ**"V mqV͠?؃q@(P))i)} \VdK%KEG"WQpDNƎ1ފQ]6E?*qeޡIyj<>Q١>UKFMRkʼʹ .[vHT|T VRTKH& I+B?Ӹ:ҡsiaW"iM(>[sh q(5kHPBRZJ³1&pDҿ5E~+K'5sp"KrճG\Kk\P!Kq۷n4ckd ܀#^&╫j(aO.i$R7%湯Λ}ĸ ~JmW%y 4>P)ɬ}!e9P⹮k4 q СBZ>7^ٷ+ߧj%{!\PWdl ;QjnŭLI\PY2Q~ 0!)k&cJVSRsqJw]ŲTbF>QHxiS}ڵ~+hC$.jq\zykWF*~!(P4JSJihSj>k)o෽hȪLI4Ucvۚ5Ybj4iHFJomɶ 'H&Rz(P4CHi )4 IZ{T!鄵񨇡QDѫ[LsQZfQV5IribA$odgu*~B^{ri$$ZO%+$T@4 5)SLe4HLm<%RU䖬Cj[nrHUSJ9(}⼅q4>+q\q8Ή((PJiM!4Қ4 0!x?X\TkqhKqq棵i*R;Q=Ҩ`p\{f^Uk׸k5W^{W^ hMK)M"o2E9 %IrZܸ.4渡#FR&_qqK+sA?jhk (x}iM)4C@iӚߚ *H3VxomGI P4*L1ۋG@qFRԖSSQF E )\g! 15'&Վ8N.#1aV6F0*e?W\9zyΈ?kN(Oӊ}5}@z-)4CHԭ@ҵ@2sS[WVAq+R[<#gqr=Zb:ۊHhGmRI-Xė ʚy^Z514M4hB-0&yhDK znN=J1. TTs~^⼍5qB^\?ǧ5Ϩ5s7U 4ҚSJԦZZ╨5h4Om==.5%qJWM^#Yn͵e.2!jKr[Ij<`Z;ScLhѣG5n?CNJ )u,]y\I?2[*4Mrh?j-这<@hi5kR?h=??BxI?5ϡ!JW< SBҚSHiZ5PjF:0׳B P@= WFtKēTx٤up)ڝ14MF޸>!W+Ɍ1X±3% $ҷOhh_/O5+L DAy+ƅ0kƸ^ }Ahך'Ӛc:K@4ҚVjVj A=W5^UyW5sDjL\ N"ޒ()14h4hC*/>r8y>('_Bs^4(~TWT}}q&⏡<~ 9ʹ8ih} ҚVjVzWzBJBJA=* \5^TZQj-Dj-LLLƘ4MDѣ!kj4Ev9jLԧy_v#s B) 8q^t>(~T q^5\Nk9c5ϯ4Oj @ҚZ^׹{'ZPzAμʼʼE3Qjfjfj&4MD4h`Џj MxqE@ʑWA3EpF-%W-@WxR~L4(5sBځ8@Dq@B9}kȚ,kk}VHXaDW<~t[+'OʹP4 Jh JԭAܣ-{PJY(=:***-ES=jfLh&hN9 *Tpv<4Ɵc~X [[y4KY~_>SPW_yN(Т8^\}sz ԟU<~?s4Mǧ@qLBhh5^TsJRKI%+z ^u^u^TZzg^S5D4M>$sIfM-~E<ܢ抳n)I7U٩TaL OQ=/OΈ΁⸮88Fkހʸ⹮>qϣQ =sϯE?@hOn4(k-E˚z"R=+zAμ^jgzfD4MDX ([AdIn~+˚ZIV2V,Y~SʼkCqs^BYZڹ\Z Sy4O?MGs_3sAhh&kcHҵ#ҽ^uE^j-E&h>ɨ>4! 2}@Q4B5oR+n d8*Ǔ/1"8$~іi>4:Q.xu\QPM⹠h?bQʙ\4 @59⹤<jFz Aʼʋz/EZh&hHMGZiBS^TDnhzn}ͼDl袘x׵ƭB]aXجfB*'V,ODB:O++yʂPhWS}Aq=y湮kks@iQ?0iM**:-Ek&h&-Ch^!IpI1c1急Rk^ %4@JR|pXZEZL\ .Oj+ʼk@hh:?jc\nٓџ0k(Ph湯*h*&Q4M\5s5E+ k i>EƼ*@А =AdˍǴae/-jT%4O?K\וs\Ҋ#У(F? ^UCӚ湮k湢k湢k湮k -JV*?Њ&D?ۛCNk湮k湮k^j/%)ʏ&_攓MLW^I)U&W~>*⼫#=#~_Kx}" 1♈[x|"\{Vԇ&f//N*?̊`CyU>յ^<%oej}ȱKSG?2_MFUHM a@ׅ2O>C[ؙgdAwT4"ǡ+׉^&Mqӊ5k׉\z@q\Wq\Wq\Q_+⸮+H ⸮+⸮+⸮+>y5ľ iQ'Py~ U梌y~#\ޠ2z+LSFy h1GtT_G+E~Z\Wq\Wq\Wkߗ@s!}QH*/%"}y_Pdhrh>EE1 ň<ʡ<*[x\~HVko~^5s\5s\>>j湮k湮kVA}yk湮k湮}HH[@ԃARHM~ulT)ckʼy *N+*)imn]sB(_*:**sDqǫ~59k湮k湮}X}9>U^u^U^Uߗ@# y?}[)?G&!MHϡ51`8кx7[JWz>~!ߍ/C%~~_@}$oxkI?F >h PI wV>I"%>yUŏqVpr8綨Dl=$Q~VCտToPOVZ ƾQ<1,aoT %zƜԢRg|1F AST7jJec~5OV~1 ^'~z_VkI?GOSQ^H%JHv-DZ x @qO&j5E%f!HJ+Ezq\W=IycտTokƼMq\W=[/Cտ??Q_ѿgj10 /[ؼ:^=ھK%%ȏR$g4 UPbr+s9ZЙH!|SG''=[OV<}fG)}[A~5?Hz?xfv1஡{|-E, h+^\ԭ<s"+ƍpJ{l.4ry#EcU>~~15DQo yWyWyWyW! Q5?1HX<ʾE &3 rf2%V4" ^^TוL 44u5ỳG$r?+ʼʼʼʼʹ?T( DQoyWyוyוyWyQ?' Q% =@VG}`TIh'ZLOQ<׏4XBO.&2# p95R?o7{vo-i% ?3#Owd:PvLpe`.ExkhO?cxڤOphJ+MĖ&d /ڿ?APʱGoHkeVoqK)拚I>Kx*RV~|\x8:}FEUkevwbC8 iB.@r=0)8 R?b3yRG$_PTʖԲ] TmXmh}7>m3JCR[yT#}_&iBHb[aRKEb棐.M"_!8v>hFĨ/|iox{s^FW58?f_yQ4\y5iv`A(P(jf}hhMQ@QAF1F:(G/Rhh}~ߕk#Ф]&>BJ@@+0)kBݕyb>3Dxhg,ѯܩ4c>׍p(E+_0PQGEyPSW#ŕ,PTx_AC"Q@kz ?<<ڹއч)@qD=+Wך息Ο(,sJxZzq\k٩*)=#4c6W482ʼ6.70wJh.+! A(48+@xL>~tG4ZЎ)x4> ցq~7B~^z~^sϧ)⑹k|GK0kΠ@Xؘ GhhM??@?z_.)'(q}kog)׊7ϡW,rTpEyS?OC_CDyQ}6BN(?cM⇡y>W~?#DPnhD4Ê4ƒa_4?U""Rirߗ"L/|J74-E'Pq^ 榏hW4L/,?wB{F1R[yWZCxL}޸>S~BCC}_q1$k"^+M!JsBF rny/r~W$^Ch%b/u9܀-OWB|BXKĿs_ΈjO4n?^"zEG'~9ՇP~F%c/xe GqAH ,RNaW5ORߛ-YdOiM@ӏ+'+GcUWqЧ#^f^p׸k5 {$-0"Du"ER$05/jyhӚڇΉI`sǨ~zp׀M}Ƹo11*GFQ杸 *F ̜|yhkKDqTF(sLܿ_ʉ'iTn)^nh=@R 2hhEQ4 Q漹nEkQXq<:>n+ks\Dog ӟJqM'ҏ"PjZb,KDO"Xv:*E#"pEi~PJf"~u>c^fʼ\q\4~x[揠4O^םy4ǟ5ȮExEHQA7^i E栈5Fe*ԌW\W8ߚN9Ԋ:#YYgG;E ʟ#gW(^٢z")s4SNT~={)2WW LW1TWD@懡?zjӟq4>ڍqßr>/:qJөz?$j D^=ℕjha)ȮJI-vY4j`RbhL[IsDzsBO Т8HyQ*)\Т\4+I/94(5!(-[tg汲r* \Ii9kʿ:>?j'WqChW?ДW!^By@-4ArDM E (054%<xSJ)'ꨡz⸮?q))\W}Ur$R88~3^Gο?A'?q\W_<iOE 啁R+Oο?_ԷO?S⸮+⸮+⸮+q8\~7)<Ԋ )?UJXkkO΅ 4\QH + :? E0R =Oе`q+N+N+E~_H+*#ӚhЎ  -N {nUi'<84o_c\~H(HkݯtWFjMOW 1k<røW@\q\N(B8qC8+⸮+SF8?\Wq\WqG8?G>+q\@?q\z\WW`kؖO70A*^[-@v$W++OpR#<ӫԳ+kv~^Hbg)-)qQcdX6o>Ϝ6g 1 "7 *A"3*J 䴊(v=]Z ѹGVd r~q<*2]^Gq6Y79shڥa[CV5Pp?J!1Ge8br[%H6Ku@T%gҵ/{6ڄ-IkI{eYw[K;+NJ(Ye#]i%! ;AKCc *"?57Fsl&9mI}X2ay\>iF9o#7&ZX)5YcDo&n]"A ȓݻf7QZH&م21gτG DFX%K4Q$dwUe8nVsKۤLF oe 4k_mS$fM<aqc+OnQ$bE3I hZfHXnepFh,$qG!Tc3AVRDo?n&Ku3MjA%#3[Z፤=)ikn2k$\vvK*my>'R9q!rfs$`KyG#GILYُ!"E6AAܘ>V/Ii_dXeFXE}ZTFC+8$Dc"%O4As AfaƷKqs$Ԅ\To;!?صk;a~tP<hȪ7+ Ge[Hq eQn*fὖT8`8926$H^\-~̶YKkω!=iw=n) Z ?G㡇yI3쒼xY3U7lgXvݟb򘦷}`P&@)v<nXbUujn*WǃcXgܓ4B[fn, DPHXȌ1bXQ S,q*3c{Ye>i#9;{s+Tr\ r-)\clB]3v=<̰kcd+<s\M;|1nLJfjHBH ~\c{7tK;%ϹvE?}q]چ0 qITgx״2My{kgAkYb[<{/iڄS~C`K8:Dw7um5Kv#?t/OfCm;L2[Vu-l$B50hſib#IfX(7hd5$ERZ*%e- ՖnSYWȚ湮heV٧ Tļm]زvY>6 &V={ ]+k4ޣyM+S,• U JPyNX*|CA#2wW-r 4YSk`b6?Awo; 0(d#!ceg n7FRHC g!ܻ?UQ̈́o'b{l|.!),JXHA$VFiKR$1TDM3Dfiaime MZ1{;/yU*'4UR3,6 !G(<*=ٜT[Y\^e {[{lA}u7cpL|^v41"#,GM#ȪW*D< OmqqZV+{c%8F dHwk|B ]K%gk7fj2%fuI}齶mL$ +<[I @;,QxdfV!$i0 x9F)-XfxXGE%dݦOquEH_py[t\DŽ0`9 mn[]Af2ls-AV;۽څPђ~@y,Y{Ɏ>;LU_-Mc%mS lVv6z!؇S/DXq*E8cyZnGxcn1&]q oq@+oJ$Rl-!qfV[/4L}71 iMgbsA{/ $'+Aʧ)xUXxInhqS-'0jukh|BZ{KhتGHn %FX8Dҭ jIc<;ܖgɠLpӹ&+XGphA<FDEgur21[ۚ I7fctѭoUԱ i%[TY|L4XtH<[#unpxvR^VP8J RQw]1qȦ\YCw9-{+dokCAo.uK)-n^, eF*CNV%oѷ,H$7lJj`x x1T2>,L"Bmh[GhyoxIz1I;؎<,q{1ๆ;z!annpט؛=}sNB9#NJ-xU7dp&nsD6V=%0].+u[lr>bͦ~+ +j^KYpX 5g-{ sF$dXK%bXdFi"HUX7"!ccO]rw Óo;!6{fյqkx&fbLcd9hla|<xL'LKc'0FamkuP_D|H`~J=YGB0kv $/28!] rԲTWR+,7:t&"WGVop4KLiCHF?]## O@W^N ƭM3WYX5!2 x$E2rDwjF0?+Lq EM*.dl_+8 "._o۵h{al(\/SR*0Ty}Ġ")ټLf&G=҅$~CvVYi8ci7G};)dv ?`{+l;K/$A֖V{%fϟ4!2x/E,H*In}/D*Ϲ' c\yQ$?^A/tid\rاQ+F<O2bQQ}ZY@l䭿꺸Z&|{] 6\mdc8XMyk{|7 DL۠|Nk(]䦖8}g q{i$Q /yOn ehE^Cehc)<]~ŞU܈nC$fXJMňyRW DmcfIOw-v^3{I v5 KEm[7w~v\s7W̷y{-;<_k^>E4ʼnCExg#^(M5{ǖ%{WK5{%愔sFN)\Pos^(154e!^Ug>$Ak9!*=)ફ*-4U' 7XDW=$(}ЪїX!be)aok'pDRJI^I֭lvk_}`촗PK<Ոqgq67ܮ`3\Oe5NǾhb(^xkurXc0/ àKg3I&E(ii2KLfڠ/_۟`· k42KsBge.m=lo?v_hadE+J#ߨQO[l,7Wbcph#䯲3؋vLrpdr1a3?+SĞTS#(vSO/$d楔 2^挔ez׻Bc^ݡ-,e'KkU|ؾӳEo$t>ZJʣ .Ju xSb'-;yTT#FF TUT gwْݝ\^fQ(D9]XїCKHҕ{%݆,fMq:oo@ӓ9 UvdIt-1 37qɥi6j.|GGR3BL)o1=5WVUI?YG"0(^G&0#cJp82ma),aX,b5f3I-"|Pr,mڭ!b/Q'pDһS'ֵ+%x:+1ov:}1:o;܎pR߰;Sp8rfӚyPBB"L*Δn+wGȆ.Kdj{qUDҦY$H ,%Ũ1ࠞ{_  -c#,j5cYc>2X g7Sb8!v<:`W6isz3k>Ue[e󂕉)bCHX3Fonk+μkʼ⃊HwL'޹7Xٺ_z5ͶS;Zߨ;ږ7a4ꢧ!SpX/' \# yf,ྏ묦b hag!0"LKVc{kVwQ-طUz%YE(@7ʱP87! Y2Δ.rP.9h8/mOfUnXj־ڙ#He#W %)}-Q ?gn89ImXH$D>ղdNѶvF9SZm[0VW8K =ķGmk=gtS*5{H/`黸ےNęO!5d4Z=ysBϜ]Η'LKWm7o&oֽytYm}c_Յ\J>du\Ο6Hl3{$X)XIkݏU<x_}͞MiH"WcLDH$`a#&h@!bܰķ *(UR =¼In?X-`¹f.ȩJ H%wؘ۶nY>Fm:~:>ie;owGX%[_;q4!ZR$&wh /FY.)Z;ԷT<^ BE2R>)Bt-C w"abO2bD#-f,XViY, rA헶wc{._ft.ϬWU?~eTOl2xTo[1d<+°njpci\=Ϗ7a-۱{ӵ/o0جMTH7!P=9B5 ~T1W]wEgjS }ט{۫ɓ7ewe.f9Fcbyj:>=sm}'M7U콳l{9NɲOAܤcb$xBKƶ>ҵ7gQ[=$FVL؍P7o_ z۬}m.+Gf6&jCc$"n;|[YYUʏ"T-#).HG\@(m|_an*/7Dz[G-R~QYlcL6lYlS_屸b'kKrWs' =`c,$vApw )/ W%wlq܈9V]dǞYq\Cnatqo23Xbn--fN_qfqJd%klv}ݿH)ۊ-'N9 K4hi O??;=:YS/1k_`OEdug1}qiýnvy=;zWp:6ć_aky{}|lXhK?Sӯ6Y;xqϞ0 8+yd^9wms\lY^[e=8%z9lR iޟ5>V~g>7N7|Q|z1] %H1Tld .LjyBc'#%D#TVbm'&KEt@*dt~xhR6[1{"U%Й)@InEH+9iT,O'G#5KV{75VPY\D?lzЏƭ=ƙۮ%}o]bzyg9r֘Kkocp|-HԿ,1 %Εy-QZ|ajj<9ja0&&RٔzӶlXb#k=׫EZuYln3nյ=w=嬑G{jlg`YXke4L:!j}Y%fOB&6װѵ߱a6.{ۚMG[Ů淿[NX$?x3<J٬7ό~5ܞc9uQ-&D=]K4f(?IPa<4Wƚϗ7Tr5ID1{n]cA~sC+gM!VKM`ǩdՍek ] ٱull]K*-G(&(KD3$ 'HYYy Q.mrWWAK|W2˺fN>v~w VV=WѭY1-Nǧwk .\LƇއ'5%zVl%"c\sSmnjPQf7xshq|bfsLH'5&UC䆯\jj+eqP˖Z]l=mn_ =j]Vښ\ewf7W3ZOv{ޚm{g'غGt#_a;y:Xn=K[%nw8!2ێuKzO}֒AM%7=gyRg:}֮O.^ƫ&)zs{ؾ0}=*շ~=(@UK*+Hz ȍQbܺH@!#P!I"x"*n)UA%|!-l{{#2;:i.?]嬓14 ^HFOVlӗJIgbhJ槄$sF3< ,o_I7n.$JI.Aǟ +rЉ'qSHr\9 ו!{yX/qk[¯% X}ya-V [{ʲFoUo5<3۟]s:c!]݅tl;XlMCn]#Cw\n? wNg,2CԵ~yc"lV7Z/^Is}o ci' :r}[m=]:EͰv_^$4%#ngVEgi}˦  m̌]/b;4}73k_&CS;^/̓((8_8C!`AsPR?!(BYDj!<2%B'"",;#l/4lqcrz\YÔEp1E%wiɛXrYM I2qFc,= ۧ|5YI G^Uu8!)x c xN3M\U̲"/q WQg5K7(cc;,|(`M"XJu/q-JT[ sef\ݘbP=@zlK`*D[ 잱uwˋv8۲7R;c -mf|@}=mƽvC]b-~4|O %{δt7w[+̋ ַ ӜF3N 3jAڻP#@g^Z@ P]SPi\1c}ڔ/84Xό|jq@ %s%^fwn8R5!5~B4(<rkzݰK?b.>/N{Sd ԸKLs6Wd.!;ԸulfwiY;~>]>3.yٟ)z5I v2@2 98n+(i.SDۙ**FsoqgʜxXݢ[a*E4BP,J+SO!¬QV'U2bB%-i2& n晹?v bzaWD16$~В:Ⱦm \dNKP\r4g| jukҙ-'q=_/w4%ٹ\/+M6¸Lc`1s7ZlpX}ns6[u\oԳ77$l{z׷6\Uf!6n+=Vkum3}7mc`[O/\AԖ:`mj,w!츰ϯd"#ֶfn{mz״1ٌ&Z>,=Z}lHl.InR1x W" ޞSL!o'>XrxAc^,\,W jy nհ2")SIo41hs] mS"Lyy=Ҍsݫ{yb<ڸ{knlw2X'C,ZYXukXob3ۙ+ʄ |IY9U)DžY&fB( I'9RjGCI8%w/%d'Ȑl0% 5S_=+b۝g|`u꿔SiV_sl[ٹ=Rw߯a1ղo{mtD`5,s9Hڣb|k=;[lw G|3gsفerYvË:h F™d^ZKk :KTnM[5 \_cc7[cqaXiэ."-m]/X_@<3\1ۧ[HQE,X⪈$%jEj!B) G Z EŬ7nnp̸lF9;5aXɒ\.?ǭ`,q>ťbV>ekr;f,?3 2of^(D)``,xIF$j '5< A.E$RH(s'-B6B7&NL| ԟrHᩨRxw@PH"LHDi$"+P l55b$$ ^ׇp"r%Q{ {7b!u,v?ˬ~u|ܻ#U7OI=^u 9nubtp/Uf-; ]iИ?erYb2H䡴|]ܖMyEwY>-';;&i(ٷKYK|]k}N[6DkY7$5z+ ~-}}簬`ڣALg)^kBBB!dj,0 c x*T( AŹPD xrk_vӪet [W;\p_H_7"I[ɝ>He&*Fq'3"}x|IaZq$$IfZj -;3o$<*ZiyHAX;!qܻR1eNC>~VR~R)9P񿞒 IɼrI<)iI957{~c[/GDwuy{o3YϘ[~/0:E+n]>7GvغKMjW7lzWWzl^L7Ȯ-&5CN1e/״pIܙ]R0&{wogpn~[G2;al=`ro\ekߴavNWNG[lFL\\Zk땏kέ{7q֣i,z{e::[+0\ lbgA./Z]╸(x7-,\pAe(抎 pA(O{\XDAj * ACLA70whLUضl.]C9rKH+yQ:}Kj=ggFdO 3pP׉ EMmlJ񽵸d$<,D1(T+ XHYDޘy>Hd$R@2rCT0i nHo5Or1~}y5MWN|=h?>zϭ~Fƭ! fM|c}+{dz_->?MOGYdo?mko(d]][2lz7$aDWMgI_&zqO Q_:ɇ>@/ٝ æ9XiSYgn]i; >,rfYrmwFķ7n>j Vr߀ڢ0 FG<8]iO`Ԣ-g(ڶs'au+ Wܧ_sn:q^^YCrApkAc^ J*h(,u$SM!Er.~_o3>W3l5<R~ԴWFO9sŘ޹>fVL]=Wda8,&Kc]]Fd6=z%?[CesN__`5{U֩( ]W~GظlN6u ^Ke6t]uZùiMN%Z.{Vֵb  I!p(" T}}pJ9 qGJ}pLf$#>!H3<& qQqԑIWfuv*8ob7Aegkb]Z>'.,ηɕpyp*/XlZ񵺼3=#Z_:7No2^w՚y, L[UW x2Sɧmu;qoHRFcC5SRPrjE2QTqz42jO0:ʠq?\7ƐMěկ흓ڕ_5mf\vPDzY =lv|>wG^\|w];>{&CZXމk~6 ^'|Ej]T/ȉoznդ`ztj/a=M\.:=OicqVE5~Dծr;;cZ%8.lh=RG"B򴡁p" JAx-/s'tmg}w.nI2)_d|^@p>/yZ^E}J %#B!2Xqn08;_hOs ۬,mW\[UeඹbyeeXg$ :(EZI(3+Gg n}Л=ebk8W6c.A&>Yld^5GBH!qƊ `8S^@: #h/]xW .k\猶 &u50^"|{w ^xu`]kU.h} Q\_"7spk{m|g[.,lY_~n9wM]]qܝ:+swGAۺmwK׵n;VQk--k-N7{ssmgnKgNou(mٷzS5k:EkK;*=wk- 0Y]uҵbv%vdz_ߍw7HXJSʵx)'Rؽ_N`{]^:ӱ݇ZŝCVֵ;~Uٝu&͊0Q:xԪ~%MRL7 Ւ;'QՏPШk #9?9T,t`)s\l.<6SG"ʴ=?&/hHE ޻k)ܿ3W]˺+5{K[\}u\ _;ϑ=uk?+:ouv.]{Si?&/f~ޱ'>};oX]TH;otWd՝5SOGkrcl~#SuNĖ#ٴIESYl_}X] f|ծiy.Wjocdu:v#nqy V'u$W߈U\F߶K+ӛh4^9|FO{m1]J]a#CYʝp(xEWWI&R"iĨ6'tXop',~o'g6|lnO%ŜwoA1 :UŅ1&oe|)/w|ʎw4umt9g0 :]l{eX}SL˰6 LgC&[#Lo^jZ?ὕyB L 2` 0VH +(B@e.JFxoX}OҨE]b9) @7LZks V%ElGna=M4{A\5 jZ6hc-n֥쭶Dfc NN-ތK 1%ug͖lm#3kww?ԅd,}x34ciSĺePeH^)2 #5;%uEW"h.G&\],ҎOuiEu|m#o:l'V2ۍװXlnClTq]li fa:fgznٗ7ԹN.50$PLc;O.l/}|/Q,>זH=ue6rrx\uuz#:s^uV|6bI[dR4y.o;'i78㖐SKm4HU/HVeW$ih{F)XRyOFnBd+R!s̪HdC=P#GyV}-<No@IrX&vfkUݾY}t )0xя6һf|ZSrjjm.@ x~ i܄O! <-T7,r3"hԻ*SjU"͍>M#`hٻ_aZGMMlzWa^oV_K`[me%ԛH@6n !,iU |ÈݧÔ53#u[e{/{]ah0?-s/S?]1Y nvYU{.{/3asi}vqM_:t NiQ pc`/!QIHhO!%nc4\L!tY-;qxi\I/ZJE!$x$2(I5^6y!-^w#vWU|b?l.i ֶJm(/r1X ɿ^n.E0o,<+]1O>x1[Mv >}[v7rc=?,y{2eϤjɣkoN4rHsY7.%92bl~gvm5:#V,4+]7m6-2x(v3`);p|]x|gVq5OD1H#o$g5Aṟ-P~UxJ1Y뻌W n_ ;拥f5f!{wWڶV2#DW1-Sf_lEX- /bY_l"X9xIh`Yn|'p6y,~fnrMy@b8lc,xX%IסX K#ĩ- (c0v)CrŔ0@6ˊ{VՑܖ+c VLVic7]V/RLYx3r"E<(M(JL@E459f ǃ2)iCDΡ~ό!YO^7"lp럋=|GTiXa(y)ROvClpfw:<{uwgdGP0~ 6hY4Pgs`~MG3kf7o3[oY{^p2:oo89K#-$V'#$fpCy.Vc$PBh+wu8orNcv,EqkVv:V٫n2x3,UOjmz {{gIRQ\GL&2ݼud?[7/b}V0Z$1KdlA$;#dLJ&GdkG!|+>3OVMwx):Wm#y3%*)?/bzvFgr-ӔѴd^ڛ/s=ze\pjBqL{dQԣRG:(CFhi*1J5x׈x(-*HH|FjG!P}#CYgr1[YT93'|+#<6=41X~^ؾgc8܆6!Wk]َhR꘨\Uv?ͼ:W\6ۦ]Kw]nxrv^cOӷH6GQK0wgK02{/q_حе{|7W73s:g͵;n~d~'N_{S7n޷ 7gyn9ށHm\wv3\DE7 ^dG;k\R\ UZろR>qw=݂cY>q]~ 'cؽ7-mw`9j3[Ȭx<>ve[ ssxld2eGK.([(ͥGضM|TXrmSzܶk˹9VL nel0Kkgd'.-W(X,hx23ʞ)J`GX2ѽf>םE,I"y+ngҘ| x~w+O_&OMCm;^"c#_Eqymbal nrr~ƛI/C&3c=5}?`덳9 _?>kc7]uf[F`c'pI\^t{Fj>Pu١>@ٽKb35: gٸg/gjgw.:v6 R:V2Tr'5rш$`2F›Xy ԵG楬[KƉ`jgvXk0XoX6\K-ç6saI,Ԫшp#iKvI[xWk/Xh2_\cl-Ď{>m+{mkxC`O&Nd= cRlzG[O]F[]6VKŤp ݄2rT$;XvM3Skn,.vo.m077cf}vMijp"ᇌd̆R x<~Tc\m@b 4N%xQZ׏GR3B:)T yEjZ?*T~ j&,-}Q})m+:,۾ju^.]1h -^,6g7*<[^8Mmncz'^ZCzg9!>UuGt^A]R<>cq&^æL6콕Ι~el֖)pKB׽JBwRa\}ݥgu nm3 -5-+{qݰ.v2su_.3o: _Pv=?'u[Si;u.Qڢ[0SKm"Xݬ-㱒yeOy8%;.66 bɃaͽ)o-ﮢY]>aoZOUbᩃ#xψTwm:6um[Tlq^Y,Y|qv [m K?Hl?Pc Wˎ QAl(EE+qnf 4' SڑRE<4)RE,\RGR'c">ʂ@W(AݗhD8bL>UT G̫옍R YMMn7pޫ)zSXՅެcCj~5esa660n s7Բ6[ox|t2ZoDZa ׺׺J+}q6|cf@G0! ȭL m>i4۴ٳyI7X=/oJ)L[mon=sY/`4<1 7;м37b`/5o3m/wםZ]Sw *T3P57.e E||K[ -0ZŘ˟L6ˌ6ocGV_rv]wVPvgcVó / kgm}PcG@]B181?d( Q{m \i"۬~paUɌ̖oycWcdw^PLƾÈ_x:b潾6iwY2D7Q*I=-d@?"9V%FRDA$1[FZ.dL~f3}Ww3c;6,dsSTQNI~U^5Њ>@J4,$׷XĔcHC1T]@<5_BLvvIs7J^2n=gc:n28͇yʼn;;f %kַͺǼ-+l3F״6]Xײ$$ñ; k]3cm5N6fSo8.s=}gZR%oЭ)!n X[&~=tN'ڑ"k ˶v#i_?2g9Y{C3}Z '^ؿmo3?u)}sh{Z.Z.coU`7..aIƝtm8yb\EM4h^d/ᰘ^fIkh&5aa"{;yS#ڰ i*.ZPANydQ*f0Z"{텇_$`^7,0({F0ARpXWSK1PƜVѰXIKo7<棎{q^>W/"qS'4 Ƅ>TI`FPҏN@Niɝ?A@X7Vl ~[ GYjsZmlpC}sf|M/Ჩ9 7yuj1y= _0[Vvj]у\?cֻ. vqLl#B; C l;1n0poîw?4n x4ʮX"S@RR3-#Wcxzcmtrφaom/zpZC_]muYj޼u{W]񝵹%Outy-l}cug,m^վ֙ހn?:݇0$bvE&^ 9ooƂ'-'말e7~ntg&caic®ym|֓ut%~s)mi| .SM;oYp Am)ŜyDe#VX%78ῗN>(1|[^]Eh }A&SbPUIG1j?J*:WA\we>n{,]oX[ٽn/MkfѭR]B _6ktnd9'yA5xFKxݰ{ ٓ!՗\9l{ OHoͤ,l %ۈ%^3S8< %{m*6g]ǥhkî:bm6PTĩLĔ+G2cEEMI S-Êks^G&7]X|J"[Kћ=rM 2yxUo,?eEQ9rZ bEX ,Iܷ|_;K=? #UN#3,t}wZ]N3kyg?vh,nvn? px =VOh pQlۍfK ug2ڞ+Ӳbv,Yl&rPowp2I|7~=4AI7Y*TX٪Xú?Cx,X{k]vmi6O]2:y k~mZ5z tXͥZ?hl~mx2. C~Ab5 0`ʤnV4QĢ Nm.  򲖓eZ^$1^NԖY/#3af070.&sh ?_sɓE>XEi zPTEP=7$'W|u ]ߘu='Mbym+o's6z+K}g=Kw9bo=usc:LZw˺Um/:0nŶ>;rPZZ[5ܻ[u=/)S#Y(p}""g6O; U Aj/ ;#i!Ɵa*-:JsIXEd~(X!k҆˂ <ऎ ErAb~S1Jb|K_qV" G5vXZ5ǫ.4}yۥ|y<;O#> RLI'4c @ obkj2?.g ++'5mu]'`PɅk#}k.׎Mmm{bv׾O&]Ϭ]O-{Ky;ThݏhXb2Z7%-%e3 rR)pQT%333 7*MKN,JKJ 2//|6o勯/t.NHKȸ)w*G\Z$bYF7g y-JVXY!FsљX"+]* &;aR"Zs""c.̲{DpdJ#P[xf H'/ERB*$B7%Px:!-E4C1JԨiǂeF0!A!J7.iPc!6sW&Gwe&k2)2V{^my]#= ֯-z{jڻ[u|ۑ[ޱko?mGg/a֝{Eڭ:؏uPoPhܺwvXi`{_0wW&~KpJ$4I4$o~׳]y݁r_b+̲A*DG$Rdлn]guΧ-Cw?xꮾÁnv|3A}ilO;=_]nֺKV>\xJ 'ۇ<b*8_O‹1f).pOeo80VSDXdƒw._ŇcDbhj9HݶVm^q+ԑ[) npDN8O ;Irx$"6UbS %"G1 "P+|#pCR`xrB;HrH/uMi1`\ۿ>%|dY%'4_O,<,:*IoɈ@A nߺvY{uF SnrntnCv3gumo ~̲`M kFJ+6]ey7jO_'qmRau|UXwLuvk8laG7eaune]9OKܰB b¥.2{ɕ Cw׏yrxQ(*G榾dJxJ)$+, ih)y He$ܞ|I70TpUdAK0jJXHĹ#tV-gVEP|?I$4><*1z%@nO4*Im>=W#]/2I)c8.K[ Vs1Ǚ#%-<$-9ޔG'N+"p"{ )2+TQd^T]a*{ddj-!gb척(y<| eHod,ŋcYDp^ߍI2Vːy?#ţ{\az[v-{ht=߶:dZ[+K5&2_Vu0Msf"Ҡ[6XnV Qk 9vV Vę{u~Jي]0Բ*Sӟ"y2W,)C5{Ad.y3 -`JPAĬB|;UP" N=%ʋʤϐ f1?Ҥb`!vK2R1xE ^EbB,ٶE_{1hɒ0|e^]Yy4QL's-QUH-B{R*HhTPa&P-9# pU ¹iFqcC Mf {uhCYx)Qi܃$*1)Qd.]y) 0B2pQڼyR(>\VSuuVx-Xke컆MXtXѺ;W_6 $aLRc crm;a۷]Ja^\~rm`$?cEO<]e~s-5Ô{#/-b%k<~S\7LM, pn F^m|_cu޺6 u]"a%|yscx8_'V+/>Q{fyf~eR\ly5/.*9nE+@ x+/>, F)8dQeFxb9&54$ }ψjHd56,Ήf|{Roǒ F<]~v O! uhp{9ADL[o%\hsa{1y_ayaq;(-@~SIf3ί|h_u]k;򻺅MMwoyV}}׻?*)f8?9w?+{_G'?t/siOn# ϻ5TMf^# `TF+ 74 i`[O?{3!ûaf>X`|GvwukݸQVn|Ò9 eVOJqEmn3B(v],Oev+\[-Dl>O2.*Fs;Mӧlm}'}gv~Xvxܷ> A@=)bSnGc+_ɚu=;S;0~@ ~^}+湮kdWe~=bzg]6 5 cP <H4ɽi+n={:!Z|JB}RBו|Mm8;r+{Q]F_BwQ?u?,{*{5RBߵA,ӨZhDr1vgmi3嬤EEs\> *IIr22\~WKokkϋR.YRXTHcnK͒_gѷWv;/|Sc<3P'Oې߬^v&ů:X3BpV_M'OV&sX7;Qm=ؼU^f]ՆٚwiZoBZ_jYy?k->`cIq[:-d[]yk_gRu&mv -ף,Qc "dcZğz7tcʽW2(  f*Iq_ 2h*A4ʸ J績_/MD0󨜕c&ӠsxW̏?]s Ӳ -Xɚ$3(ɩe!'C[Lwv6$Zyn%%Ӂm:qca.D!˹z+Я/="vKcճmK޲c?vNz.ԣ]+*{Omuh+}3yGDDPSw7ղ8`ԋ!hG3w۳kt+ۭկ&ǚy(FJ%o{ˮxdӯ{`꽋O']I(bX o#|[aۯHsΜӐO+@te]v_GiWFn#=KIݥ#lwL(9'1,(/R8Z'f!qd{'0?^rÅ!QRܨ7VE-Y5-]̢X]LEҚeD[K2Q"<ֶn+Ȧmܫ4*5{멮SPrĐ01t$ vtVߴZl݃?SHYQ,>\xPb<9R0IZOsu#,ȂIY] 7ǧWen떎5B% (x<.._z3B,KyBVFcw+fWq1<}R&Oݕ7puDB^k[[?5L潅cKy֙z|쌛\v;[9ذݻe[^/i~SԳ{ccEx}/*Rfհ7?edz}+/}K[~GuZcp i|XmEpO,7K,J^y'# &c^M x^h#N ΣD{]_7ss+|| Xbj<DNTC_ĀOYX" XRJV =WniNI--hn-\r%ĥzf t7]"HBq3@6LvD mYj==F)n Ko3IlbR7^EFa&m$3GlI}owq-lXkDc wuu+!ȧ p~ӕr_ʎە4~i.q3+RFTpM42O"}jE<2|e5y+[u; -"^Đ4φO!)QOP[ДFWiѣuǧKɗC= p@JKi#e͛ uܶI}'GHr:xvm{CKv.%r^森~(V~/!|(V*$k'{rA{7X CYꍗMh|WY뻽1]3\nՍ뎽-bj ̫[sc6]>=bG$( 9*slnc{E;2/M+)_3/NGUC_ġ#LJOا D_ʨftr@2Oj,̊ {!*Z$zkԱ.iU{a^?vi(ByxJnѷ2jW9ܖ0s7Gj-2eQR5ep'" i1/txcpwaiYTFQB̿q\FGއ{[UU8%@ܦ_l*u\0T^n{gNw[l>gvĴ4*Ae?ˈoRzRFd8@|n85/CD|-.?ef;?\Z]t:* ~ui2W/t7Ca8KwMV鑣+ysU jPJ) |jtC m{{cZuٴ6&k[%`rko?ys3ۅyY۶]:d}0B+?Uvg2'^*X"&U>^'qM 0 kUV89'C y{f}˲vB*>/ ^BO% **ضگ8yws#"rX4ҫ,Iרi} 2^Gfh4LTJdcN7[>@*vfB8WC\*n/፡S~Ɲ|h"Jfp->nx+@{Gc|atv="= h@I >JU\y`8w,l̨X5/-Or8D%1y"*;y5}_ᬱc%ؖw/YⲚq6N^ׇ#r1ri}ge=.ͩzRl?ҏr2irҲP<3k˅]4M{iL@f?91y =Yhz IᴝJoqYß@尒EI_C_rNve|BҰo (O.QSNU^EW+z8.R**k8OIkxP} ZFj 4kV$]^i5{F5U25(5_e :SP)1'cm ޭu2;S7Y1O1P(R m_G߾X.'ϴx$5a _!w 6v![587SvJʹס YDJRiRbDD%~?njEʅRx(HzEY\Eݛ=Y?{OPIcimM'BI5D1TyKO9Y:Ɯ3~Hܐ Fd)N0%y_?=wp~7nN\Vm;q2יp8ϑ>sw5ߵWOQ% :տ(*'Pj?R}ʐ7 y7:.ak  L׬r|^kd;{6τNM6[%%MMRyΟD Ry 1oҫg uг5i]3 &A,B|N:/+$vj^?*Xwe^ӓA2ys#/j_HKJOf-2; zfo?w9V'\'D1{gf%.SuIUn 'alsi=aw'IR_ 1߳+~€LR!.ۡ%G!o$w|u9ڜ@T;&8`kǕf10V_cg -6i Z圄ixQ9 K􉼔0sG`,w;ي+"̰SbbJRQ o2XϜךg\I-{Noo^[ޖY!=ʶg{_MBT@7U=WnuM9V/"ȱ3*A&G_??a܅e-,hWLq=4MaůR` RY*_mxN^"C^G1@H~^?˩p:xIJń9D P-r쎒2F?D/4 8'wm~ܽIү,:m6#}бz5U$ٍ{cuk˦F+KeÃԮg&: gB_&hY<ɕJ#>4KP)]Y-vKl~8,` RW!G10Zp%E_\We^呁{V1TN\rJԊXyJ_jqH)Z2L )0-+VR4|DtWh72y]1[};=;WI5JHmocL0u$r2~ݚshֶJxZ¥ cw;ruzW??a(*Kx e6ws_ D"l:W^>n"O&@ ,Dy e&^O9J T7-1|7nui}zo/Ա//n^, 檿 ݵ{g 4HYC^UG2!p"Z_|~?-#p_GQ=Jȅ.@}IQā2*CHڎ"(̅\74^Uso"IoDj}cy ǰe?m5abhV+ӆ)<Tuc-@|*=Y&j"p8TI&]ֺ}Kfkì2Jŏ*'qq>YPx>*9 .}?%#(A=K+1^ F>jgrOP?F#[^e2߈:NLkmc[sa}V [Pح_Lnr\vߌ޻kUH\ͮ[`FE|1@nJU;*V) Lzhԍlh?/?NilK1\}:+U㳘/j;sZw2-[1jS.3Tzڷ~Vh>%KB9'y2!;BCO53(UZ#5.|}>.-ĵXK8r<5J4}Q7s 5/vUJ2,?o֏=Ek+mƓ,ȱp]jӰW],`3}BenZ"Nߴfkw ŰlWYUԈ£o]e^/"@ANԼ227UxYq'0P?*@P.WkT6N|su;*`ct~ЉC"C[7NP>IW!}酚%gPByU,Oz\sI'ڏk5c+A2h~FK"! sP3^,nJYYksmwMvUXɷϺ=wkw}s5{6ݺvʸ2!: ׶W8˟N=]b/SWЛ\CP[OξW?e}}d0|mҚc{Z5O5cێMgj{ oCm;jR/o[_ץ7Y+_!QM3ke$8j>VtnWRƷ_'n{9嫯1Ol퉶n']) +'R(燔{ȀL_uJݨ EAy2d(W˻֨O0x'h \2<_Z)ڦTf}?xz׷7n凰տާ / 2,^tmGWgS'Ɏ]8J_O&x""cj;9pm@-0;eF=A#IWWPWnT]S$f 2;,jyrD'~ePow4n9"Ycx{?u;v_(z"E^uGK! I_)grUb?˱s׾+S16B"W9U,"'ǏOo+?*|߮$잦 .籊1 kE]cQr%p&~gԻ?9*7H,~6 {'d=O{>WrGEwv<bl6asw+>M>ُ?4r?&W^Q3_1ƹoS՞^b9A (39IȖbۯYyXq#p6-,+~7Z1]26$[e%J%φ:fy~>b]5oR:?ǝpMkym;+" fm c@S"({K #m~ O} )cU,1JEm!SY=Zb/6g p8[0m"D;83i9,_S0AWJ)H]h/-Mf~߮t>D}Ҳ(?Į}WG >=Կ~Uw_B}g4\EBՇYeZ"nTV&']J }ov%mu{ѵcD}i..Tqyk߱Or]&=\ʦO(ƾ~?pKm~ou"kskO7iMsֶ=a iȴcn.:v[_S⵼R2X.Ǜ-Wӵ^˖Y6|~,C/N(/&:T,7D1?Rx'n7-j#u v#v@"%+*Nz]k~Yh+(?fPBr_J?.}zf>i^R $e!h DӚϏLorƭ.GXݩ >k2/$o_22V +?úFq\o! vqp~[-/+̐(<Öq DrFo[qIIo `&E xc+*+!_&GyKl+G=+3_DK$\$r]T܎wuϔtM vhұKfuoqvd{kA>N~u2,đÊ`"##fI$#QOI']짫/jo3:_I*\C/Y9䀾d(wr}}Qtƌ`2 =7ޯoXa |ʭpQyU,V׊NlAmK*Ś8c^yg3'7)Dy9vU#[mz'z;9y'8E=*J)In#tJ,fu7Đ㚾L'Ǿ į{Y w d2%<#cY8fWiQQcLhJ"#9֗·!#aR<-;SQ.[ȱYf0cB$1ȆUI%^@9S&A bÖS *A,׹O՚eg_[&ga׳'D:,vexq;Ng'p/ueս),3?iw UqϸjԲd5,ipv>rox=7=6 vk;fr:_6ahb<6p6hlGي4MHI'\/+(rU*yBe*yX`+KJ^!H,)Y MɢÐpH9~j2pd'%P@)vH,@fB#.U]BO`ErfQNkPEh+ EY/#y91&C$vx.d`n#C,ˁ7$vG$UU:#àA gVJU-E ,bIX؊TyT EcHZbxV$(ggBCȅYPh*ȢC ā$uuzHZ-}uf(܀B>>i@] /̦` yPtLʲG ~aR,^C`]XbX$:2K3p~Eȱw>K rh(lN?Ouv~݇W$Xd5c>;ji;>e-"8ͮwVϬ\|]v?Po+ͅ6+ 9ͫJm;'QmalqNJLųyؾ5|qkpPlh G`F:u9QUJσs#Rd ʐ8 Rq ž(DA/8hS2*U'!6aAKңr\>Jx|)эE8HЋ H4Jo 8pZs'V)hXP!BK(Eњd-IM32 bʏ,2KxZU d-}c}[e=6H!~V(G ?%2cVU (ҖVsc P}P/edQ$0) dHꡨnP9[0n|$ILjbJ.]rcC*Bz*8f+N!cQ%žwad[K˛]'a[m`4w/SJ5²0^7j]Km}g=w\{:&zR#kw6ňz>g5o])Buָ[#A7V1[j<& |ھ;|p8ٕ(tbybUXo*s*|UGO|&Y!AwdfxVf<)BCXt* IG )Ӓ9ep%#( > h ?W&Dky%2xl,UXː gd$GPV6g'3F#*.`XS* #Ȏ&IDg+MDK?|Y؈0B@3ȜWFH>&A*ʥ2FM2yIf`HoJ 2%E׵)7 |eYR9`@tr TGRTH_&/#G )Bʀ(+1^װ(DT(".F7jT5UPHR(, d_ОRARONJ@ RPyЄ-,lA0,d]&3;=Xvi5 ˃]n&b7|\7Q "Hd/d)Cnrtٲg4ml?fz;9LeƐJBHяdTLU@yA`Tx<%+')f e #<`UCȨB^?vQ bH3^˱eoFƁqC#n%,tP H~xo0GQi"mK/\6ldwQlXZgMݕb|v}M.kM=*,5NXk69|td72/v{Lfkёڵ[8^g;qqZ&|n ik윝9҆O'2qw198DUg#01||Gx)5ovtCL #4zb#BU|$JV*1d̞T2ۺP M4gEť.q$#BxDO_)d *rbjbd`*8ABj|qwz]}/j:<n/\)13rf@MXL&r'hxǕgx&G$MlpXcŌ.6f{"xӁ$DJPGn}"ql8m f=*@?ݕ_29Uyϗ LjV(c\1Td>qQY0;3c N8-^Iʦ׈P*@6z +:PyRڼ܆P`)A((8!]]xJ>dȌjWX%Z{;CYMzCbO.{8~Ӱ|kLݴ2M\}a8 NwW|2ԚZf&q0ZGwomg\EAK"_aYl։/QL~wf|[cېA+\;c):d'm7dAbw76ٽ)d?ev/ŬϘO~H?*g$' @gR-vzԧ{̓1y|V C=lqn\ӂhQT5knî\kN#wǺdVE,eV_ Gچe>?x񍉠# 2V;]%a6zSho'9pY82sa6Kt/ld_Wf?}NU ~*3\1"Nc8sЉtyrscuk7H!FBG^Jjux(̶V-]iwa;{M^òN#LeInsW ]<&3 U#iU@(LHj`\x*"È@Ӳlד;}g)dN/.|N3\7^߼;2Yu|-v{efPkNǰdL[d~u:T֗ i)X?mo+,^Xyp.գc.ݶnxT C,e|#H9l3w.?b p)^ː}}sa[Dz"k{u |Fgʘ́dE .)UJΞ$?,<@H.x%ⴤUjN/z?p޺C=B3윔YlgRI`Ǐ ķd"MK32pUcf0[Akrǀ;k[&W3p6عQ_j-#oc~eH|%Fr޲T76׽>L+uNBrʅ Hc) '-dewL{+ٶ0S/S &n#}\4fvжcM6RrZ6뜿Vvl}(JV,OdE xL9}j-q??VM}j $ <&)DKq:49956 Zېm7{u+l26#.Ӥw{! ,,ye5W2]#ϫj5 NVRSɚ/ !~* H"S<=?d g?Y0 lt&k.oqę8^i{m+ynq~\Yo͂K2{[m6^Cx蓦1׹mu'M[f77{s]m{gl|{v綜{ڭo_0"puo,=msyfn=pY(49[=>Opa\HbPZۿp-f m}r.G9/N&}y S^|@? b=zOhlgean7 cV!HQ(B0\_'\̗~{[ױ:es%r5qZmΡaC.&#wiB+r2,UIAe,,u5Lslؼv6LMqY;@O CpKph s~V^utMag Br}_mW Mz,GzFE|%u7Mv],pvfp * IҗfAb؊գ[y9y#VcSmR-9[!u Fipn@TH,2/ex "󦉑P?aQjB *¾I,mgkg&lvc/4 X ^;}[/L:9P!ٰٓo-ifsXqȠ7;+tq@?lχn#Un=Oi1h{ :uoKt_\v^B YAu+`d~H(\7pZnyAk̮ũ*MYDru_Gk ~V~덦ˈf#q ]l{.}[yİ]Jilo;v,vN~&G?&w uW:^閛܊=,%NwO$ oyub3j9G*h *f)8DT\)V]R3pϺ_O@+ ~] Hv`(&F*y /Z_ct-zI8 ːZmK=/2{G ɻv2:KRM*- 6 |5se`흆 gVl ˘`75.s K:{ËZiad~L\/vn׳:ݞ׻-mfP%Gf2=6'auB"0TR̾+@e9kZ_,3(";`xC"$e@),dfw~MkAهZ\[ҤWNo`d4YKrhTq#7\-o{1R^xYK;$ܬ{T$1CwMWbeZ5ν.aꠇ #SLbگ ja?v'2L#M%;ܥ?9#62Ghmk$ DT*S^rcx΀CY+L%ɹ-$=<[Zl0g=bdkhKi6XώW,܊fZB9R=ڂ8ni\EqLf3k6˙Ni~nEGE]o0:^ t~&RSyq@AQ\<-se+eX"33Iq[ R ^Z3>-k齹o.0r׽O_Mc?vLjܾQE |0 \6=Ӂe{+ŕŶ+qՑޠe<6vOeuJڵ.~FiXk,bv-[{Ƌ;@0[ͺC#7_ 2 (UYLp ?1IB"(U<,lC0 J{fo&&Ҳ$P5e9d<ek[:b>=cͺbcg"`!df1OcEI;Rs\\Nj|XUb%>ɦn[manvi 1+og!6ݼ[4+8[sŌ٪ٰ$񤁕 +`0bR{3"_`x3Xl>2`ogkdȋ leug]`?{o|z駘2V(!I7YmnÖ4-̖0]dxAye{}[9,^3Fp8<퉰90\N+"HP(R0&R<jL̇GxƾM@ȷ%cvܵ)JєDŦ?-..OJGJ==4:)O+f34(4Ar._K?⳱0 yL5biխZ}}{|֒lg~\e[mV'{C[s.1XGŤG fTaJKT?*!v- (՜US-|^3-ԗ7a[G{ {vk}ׇA;\dQY[C`u`Yidyp(iΗ||PAI\A%=G%XJ}rScP7˯Qfp;]p9Z][nel3c$kc+%ge>9kI%~l#ƪu,Yn׸iRgr YM-#eaS)5k\-u sqMqlOgl$H_ts™DyO"L14~D^D*_<۪6]ړo;7˚6.pr\o`b6O\v0jY^myݕ.ô\`Q#x*ѐBE<Ȟg쀯o~ Mk퀸tX7m%ޟ-/%Ckumd~.uu;?XS+~PXuwީyn"0ҿ%#e:VusųX0lngmӥk3Zy,f_&B92vVxw69wLNI4_.SC iWjS*xՇQC̱:lAG  $^@Hf CxjYcHQi92Q?5 ed?,#Arw29ܮm6k/6!NmjO,x^&s|\]DnFPΏq[E&sd,_f> ұ.ȁy#(;EVOTW66UR#ey?qc^`#ncyT^wZa2{,>LDJ^4O+*{ɄQ5]eKOk^\`I$ }i]Yg*YApwml"e'q$x.7.!Tl!E{|h| 2!a XЪTJ8 llAMkѵz2pNK7;ѤҐMxiOap4TF*"{$lnnvjK"6|ٕJ(C&V oei27צ(tD VS fKlb6նW=$t63kK#8+wwi#ll5ce-k$aB9KY.JFPnRH "Rl'J[=[J+gYmQoBk(쮣,+u.@ew?X*ܔnϽky]U; G!t\_l[WKtNe ?( {S+oϗi[Mis<ǒ'[XV6hIvN< ׶ vf静"˭5[W/.h !&xUX_/tjJ𘎠'oQ2Y[S+}aWie [mY/qTn̶;I.3X/:S7[IV˷os7WapXͥU9|3ۢu&׮+v'~Md"혱ש5j3igu=ɷ %C/ uu0dvϿi3ۢvF̘gEeH0%7XBW<|T*Lc?YgfOd<=m6]0峷6[|M28O xfr![17쎼v5f͎,ET$%{#Z~" X,K$m!*L|a*,S4CyE܆dq  8ǯi@FEXOz o}iǛ)_P:_j73xPeTpIc&A@8;Hώ YzdٺwfϬu*yn+)$Ykg|upcz~k#^@Ɲi]@Qv.iX}@w-:~g5nwiu{c:jfy I"3SڨGі07: MߵLZMOYLKkY_њ96k7Y >K+OM=ܹV<`wHs aݶFHm *qa&cXHM,fnzX|Fۣ47v%ӻfl.O,-]qɿ>=3o7k<'F5҄рIRߨri 2WfUi9,{xYl_`$zSYrpo1{+gWb1kز+pH,cjiJY% |#o1h0>-`zT5@+xA&uһ"*8zIS =ʁn``[T0 {u 6퍚;Ky;$r%08Ro&':M-y\MR+uu69z.@cEɧsO c$]'W%LAQ OR7ߨ⥐3 <$G /4[Ƽ>a$Or/`v6Bk fް;>n6>#cumL\֓dc{*ɭBTDΞ@(U vlx O[Y˲V[tPAsE\8Ӛ׭/swLkXo~, (p0|X4+"rѓaU+˖2ITX7 Aë;-YhG@y2,$O yĞCJAr147jpy\Ŝi6;^oAW,x aXvVXSNGo_ dΣgmv\ם{TcU"l 93xo㧿p-^5'zEn*9);ztV} P2}+4~Բ{zR)I^c֐a!^Aqo BTŴ(q¿I23#+9!' <J%IU +!Q<@ʆT*Rij8PP+b:UhfKB~I&WX%Զ'ҵhɗG\/"Q"`(Y:[*9KFTy 8R FUv*QK#ڕY\RC!w*sIDJꔕv AiB?FxMFL\/gnZ7xqom{N3XyeI$='G̴nٜȥ`ޡ̆7n﫮9ݏuնz)mĻV7'o哳=e3C ?e|V~7?Hj!~Dk}O㴺I/3XYfbحq][)|YX໓q&N&KH%6+]7pn~w vɫG=F+$żUXϔ[Rk"bkݲFXbq" N""FFq"R(噑$YS,YbTJ^I*FxYRC(B9FTq+D!%2A u%[ye;6F1q,cLL7,Uf-^V+VF񂬍 R]iR0*B1xĄ2'!Aˎ+-I:{ZC<#QU'R!!rH\42F T%]0>*@7YJy,w"o;[L>C!WWlkMh˫oc}wk

e-yNi?ǧXOoq&\ŵqϞձ^Ɉ86v mocmqicY%OPD@#^kW2Wz^y45o{q_hy(2D&R!ZY(a#lY}4xP & i)sv ,+,ѷmz3.p E$&΃S4jP*FyUX+ H2E"w2TMoPʱ"pKi2D^h.ciXKLke t+yMJ Mr.I;}fIo5~B73ڄ9's-"M ͧG{#ReJݢI).̳0/#8b&pO3 CK7/+J ʋ=ìrLJm9af6fIaK(:ג##yL Q0O]qŕE##c{زWYݎ{!ֳ=p}/Ws 俶4LC켗o2z뽭 ;?񟱱̆>CJ~ R<ۘt\F{&jbR,N~C-{&:Cu*g'k]2 V%T[whI 8+Ub?ɍi;+jLυ֬>ЃVrwOȏ(c)Q4cVS*P! .BR" E4M'R)%hǁn akm^Y|1]㇈]y ?)uæ>G[|Wl{]R"K([x݄jv72R۱6Ky4:l4]s-ơkwY8L}r[cT,iVwipB_F6ط[FDaKaεi7vA }ݮ!Q5Đj!{5طr<X*{D\֣+UKm3-i# B/c.h/aR$IpdLtCpy_-mbQ[1+LT k>C ק;ltY[efTVC[jNk&Pe 1@ShbyAZ6d>TvVX}{X]@p-GE5Ml0.&%qƅT#N@P o‚y+" ǒPUY,m:G$U18GvL=cNS:C[3YI[6./u2,x$>42f$EQƚVvյ6eE:A#I ^x~_f l"^im#%]ՎiMŝޫ$&[ [yU|}]CkV#m]GY |[Ʊ ɢT1I$'@YcFD |Z c{K ^ lT98om1O%Ia$'`Cy7"_?i$ ]Zx'D{eCh}q CbĒ}5n,qG= ~K Ltl^n]dVeƍ&g(iI}K7:WQ?æ㡙Es=C1f oygMon 9]\@#wֲ9IYncfe";*%؟9)`;nЕ(v3A_jv6OjVk-qp17W]'wyL0'!/d#r)$bhE`C]6Zʞ?*HHQ)POZbDedj]fws[LcqnXw|ٸz{ٸff*x ?%duyI=֒`H-;1B(?9k6C7 x!V,ZDo I2ڭTi#%Fk=N|oZ㐡>Ka~eZ% Ywf *5qI 8aNTgzh6SwqJſd?\/+cKkENyї!ӄ+"r`ȵH")`#I(ZL_VCBDd xa!aÝܝMc(4&򧑖KJ̵x(hΥL} P?L)-'_nbdbe i$If_ZIFDVi{TQBk]N!J\gSfC/ `BTʤu eFRLC)$xji !f 0T,9RC:`xWŝ@wiWW10e jF0 @ Y8 ~]w2՚NKqE$^q,tGeMgV k7K,q o!,岍EkiLgy!xq$lT($ @GUhJ!$C!fx"&doJy3hf@gI#Y"չE*@^1h`W>,R,J / Ux"% BG2F,źVC:H$r41HM25޼}2;8r)s$*ҲS+ =+ŠvL@+ʬx1E@\ٔ5,&d y&XuՕ[S;K8&XWjXU~4|qi4q\a|޴ i+l{gOt%i=ң&DI<%gD*CHBj%ٌmH\pX SJ2$C?2D]Abтg8|GR6BmBi2pYEDi 8c uT Ed9ϔ$Z݋Wd1,pH$Mn#L6.{mV֟?vwsN;b#h7k$"sow&)(B]Ti"R ?<$H^y<>Ҵc<7e`ġ%QMUhȱJUX|Z/zx 䲩hKS<* <+ X=4$F !btHXjc< 8$xLQOo۶Lcqb)LA]SOb k~""bJ?fgs!Y%81¥#D Ơxʊ_# Q)Wou >ct^X1 9_3( h $Ds(O%dxxh-{`"@bg3+4ŏ&SobqRlj8D),'Gz (d=1OyD[[ߌpxJov;L(<x3KRPAF)-K7: nm]K#b|҄gmz ƟK2^K^Oqa ıg-n\zcrrmWm<nѶ/YN;Jǥ.zB8DZ\&0{ m.V<6c=:խZHas&w;Ȳmla]w[v n8DJ7qJ?Q#yKN4a>3 0 -Ȳ[0K8&IG40`w8Rͪtnov0%Eh'/~i%jy I*J+촿%Eqe x!ԐG!G3QҨA\㣺9b!:+ {U-qW>L?6Ll|Cm)+:<҆b:nh.m2mX*cn2c=⭱*<2ւܽ= tTIԡnA6^%][j2-j["٢lB/5.Z<6|^U{KYݧ a (YxO줨F V-zH.OsܒWks~.5ktp,c5sBR`.{g\֠+ sgq*ӇvF"dHR ao4s:L&IwAZg.Kz{yvͽ̲$iX4yn%⤽Z uromu!s-ΧqwjqLd@ע3hө$Q-CpgnڗC svƹ-+9?ս#RIv :,ܬML:č.oah)e,,W]hX,j81)oY<=:xP?jL#-@??a [gǥX\]pPšR7",]]4${{ OaQT 埚Wj7GrsHʳ|YI1 bTD >Qqkm9)xh\MT%U' >툫ΧD0&PRi6ޏ233=0PzTbP'DKb'HA=Rz'PS&:^B(oHܖs /!Wt*ć(K9[Hs,a؅iyMB8ՉZb*q ytT) ?\tSO1@S}/#e m5 =1j "z#H11,>H<^!Sk=OD}O3O?@hT SI$+*D#O6ZrK`j‘)kOL0M+آ0LP F n>z|2!S۱f/0` {xmBXY5_*+ɀQOb C ٲi%%S}A]ApAb _ s\pD]X4FI xv ޸O9pwR5GxsП[ ;f;WK\lT@$A"‡S?%woZsn$[d2]Rj$s SgU0P@Z6a"EW[0(r)Ug6t9-]%"@B5 1sytZ*NEoOjtIs4rԇ* 9`a? އjMuXr*Gk^Uƛ?d E8# JƞX0߽Qd-_ZQO,|?5fKĕ-0;Z QS@uؙAT9 jfӀJ?njHẺ h够/qza*_hvB5/(zTc8ҚIoHl'qiD=ӎ6=5ZB4ST9F&&e r*jھg5|O31 `3[}nir|g7 ɉ4ÈB-Hz4]9 hIP4Gl}@_Oh *>й|EYbI ʆ"8*>ZWB܂(2/Re6!}4GdM@˽\̓J|onJȧUy5E;&++O= [QQ#/0ef <۴[b;:Yȅ1s"@ ՚e8>)Y.|=SRI0ъ96~FΡi;IvI-*= ()h.s*lYMgEY:G [4x"oڙ7"Zm"&UKXӗ=BP؅BD8 "?'_?]-VULڜ o%aO6j%2ly\ryudy߶Y})}n]t(J?'dsH0c$ )u`1o4OWW8'sެ-6⿇4*._\E"NU_0y$G*<#Lj$`s9jX=N2MQ k &VA8 "7X'Xٯb7'NS#b/]GX5?r_|}HL׹ o\пX=QͦnI~V;z*4< ]$I56yA lDɔj?z ev#?3_}D8j=h |iǹHAaGYi M\;زikaG/_7*X)PqQ]|m5t]4h1U$DIBi\;@kޅuf4pyQ .Mz{S.ZՅ(e'`VQ7#W&-1h5pI ,G⣣1ABhWrwܳUrA;eҞpQ(@Ng[7-bC|{"/bй,(;x~Lf$ib@ ڳrސl BE-;I*& dmD41\IHϰ [o'Y16HzedtA16&ئ%Y\"UA7޳={?D uЯ\ȓ7^ ruoo5.3T@f0ݍra >.Y ej @B|E5p7]TTt2d[(b@y؜'ۂwk1Ԧ):;a0:0[iE _N@y~a`(v;LL% kHbK9o'Qi `\.֨O>D%o<֦v0׹fsń\q-dhLej7N-Lv#61 {F:Y)TMW/@m!Nd44Ac5F[#r;LrQd7*m,!UP~}w&@@(A PUe=a2O-\G5"%#UU,D|a]p:zvk%qZ-e# Vh9K-pr EpL?E ^%Xl_WH8:܁S6=Bu*qYy_㥆2;|BOFh h07'͘l bLߘ`{dbRm.VNQpDZ8{q81HZ)[dlLD*@oGT[ 6.@ ((c$vs6D1[g''r5R[喦a\R'_ @ ^aCeɔP"IQ8Z@y(Ld?ETLaikmVj/d UfVzaԌ % 6ՔvC'M7LSLpYN,'T:.%T /+p\)jS Sݞ ݰW;dO[Ef w6oKE]c,荲_8LL$SA곑 篍ie'e%rp\N wx:,ZAeɌIML:qDkBOjpn:Ʀ򱬂显貝L=%ޞ=Tȓ3+B2v̪RYBŷ[b{&:fYͯ" lcn cwTwKa G)3|I t% ":z ~R"/-_ Ҁ/e2—6Y'uJ(r{lWcuvسU<,Tzosy%!uenDZ9۱ڡ.lSyhr_w"AYNY$ 9ߡӕ {,yliM@vxa)ޝ!k{]Y. w . WD̟ :{đwoL s=iN1 o\AuJהTJ5nՖclv- a8&4[<c%!{l'; cU]e\ ';CFcIYi:fú咗ęfU 1Mh.EQfx)6oMi94:` r8`Yh/꼈j"Pjk5'L5?j.uhe7uFH05Yp|P|N3fт>s di&jm3pLb6 剖wFyPWQ1@T\@E&Q-LbsD܁jAň0"he;aH7ghC&*F7S!R `Mٰw؁|ӁE߻Xba/8~f QBj=kܜi (XF@czsI+ i1]-&;/zvC 0eŸyU$exLm{6MS4@TTUFQ2dl] B]ȵ /jPBQݶqb5UvifE_fczezY@(|:p(O^VW&3\pMTAh U4` 4bi˱N=ee)Mv+;͢HXɡ˥P"`f<XMN;, ꖠ $=d-TEzjak'4  )kz?+$u mAU0OLu !N\Avn1H2v]N w`R QcQqqXꪦ-~)7F gef/v#X= cN{,f`ɩ+[.Pi+; o'55wvY>Y }J\a<1 '0{p^5}R!M`P^aB-g lPnY u IL߹C^+w&6G 5e꾭b6=L?v=LEy@>[WhSm7i ۯzzbjw2ZY`"ؼ 7z+YZ ?zp^2h~9!٠n6Mkڲb"mDG~SvYwU j1&w\5'MV#fALa#Aٓ Q $Q,ǻ$oF|.tl ~/DZdLN k؅$5o8ͪ.XܠKeNuPk(9ccd ,iFl|׸تL xY&fKpĪn "Ay'-8)MV(|VbXX&ב{2#W/IIM F%Dk)%;Q&]X(f}oE7<.m3DFId^z2_ C)MU8C/=c8E1 -FbNovP7h'ڜA2Luڝ5B (prح銇Bj'51V 5=(J:etLۭQ蘝0L&9P=SfiF!4ELVPQ,-}ZOw7 K_*8<|`FMnj)HHb %K[ <= ~eTwGجM0؎#[RfA~ ⸛x\1dj)$=ѻWOXqtШpIenU&a&=Rg F*,T4PL.;uB [,YI[Ш' Ҏm6+xbZv\7ʁ]nBeQx7o6!MpuX.+ dpz7n١TlH=: t&tYX j$p<5UVjs]BqRrz r1Xu;3 ;%n&fgc_ / N2iIw:s35{=)"*4Wlk P?TlT$A .._r{SτO(FZ8չ JhfpEdA)ab}Vj`:yP F86pl{ pE)?TԮ8o@@i+Fa}`Qqd&%׷DHv;n8 2o ˄8霆lp bBoQ/b w퉦 cFD<+4LOUL1}!'xߺ=yϰaQMd6M9c05E;L;XiӔ ce7n 3bfYis F:څ\0 Po\m޾F"S9[`ǹ4X/)/v(.Qt3,+vb)w*&Ck1Oٽc3KT& j r;Qk5)\UG qGL LʐL0qy@Q#}v,\5)"rr.n |eWLOw⟚9!@T8Vk1AF^%#|@` 0L -%PD9?Mb-YAuӖrAhSzp@~ n-4hwQ6NF1d! ,A]Jc"F-KP.:&L϶fX^C!H$V:*u뻱Eu?nj1oOWFuVsbj1 J bڡ&ipk=`~UJmN5ܚv% cNS% <.Sm޸Ci ޚƞVj앱N`e ӕ6b^ܷ ;T:wxiY:4$TSg{!K;XU'bi]D#HO~8m?zIad ]{P# ⻷bzMItRwDEh1LFBI.)weXmpTI7-$bC2 n@)ikkޜK~i*&^o; f蹓lkL&ᭊ$}S9ڝ 9v0Y fE N zpDcCڡO;E&lDVP2dI. {,\g(=1ӷ9%E(L; iY,v'Z a/g% $Ygp6^FiIʉ63Lż/v_Mjh^(ͥdlٲfb\o}ȉr z&hfbqp:`vԬ=O.#6L_*;TE0@z} &ߊ0hVxE3j=Bv D'NUq`g' Ef} ձ$I1f,6)~ 16jOgnܦkY ]aicՐIE0i:?GDłXQ1oӊJT:ٸΘmcԄHP!O?Aè5\wK5ۯr5UjM}?)6(:[芇*MՒUL}❻Cw.)Dl Š/f!+11$mڜJ-.?#tOg޾1YفOIpB"EEAGCh @ZKX({w!D7v8> v60ژM2QQRQba)Iә'N7à]c{   fƛ ׵CŐ&I]IA?A80P !bf}5;AnZf|=]9p=ev&NgZ"QzF΋}/(X*-J4ϡ6 E:q1+62N}JaᥪwkܘYo;P.al j$Y$*6 "hD4SZ\UsYvA4;@Lݵ0dW#5L{LD ?QYϵf;àO;k?R7.'6rzc-Nt:g@%"SvcO};Ff-e#m%%B&N~!D@Dw!4jhG^l=RRQ )5!{zQNCz ?"]z\49TECK7bS Yi m[.LDn fYzba>ô4Sؙ1YOM3%-KfnDX FdUAT4ciQfn,E@mqbW&j%5wpMͽ ^?1߇ayWTf]n{VS&Ւ N*xkU>Q紧QX(؉ yOT͗|VNf~+0Į2P@ד݈^Q\VQ >6'oz" s jl  "@|oNQ?00=Z|Ln:~N[4@̦ᘒ" %cZIuf/G)[vN&S5 &E ѻj78 Co@{#Ub̥vPSb61jAHjnŗ5]T0>fY=5Mтd1QDZKLS `c- Ht*64a+;4017>"31m^UYtG50"ĸpЀLc,[VL 6Z)<[^՞K&CYkb'+-(Eb::.abteɎYj3 ᦐ榼ÇVwP厈D$ᣅBXl55e4p6 Ih;D' 0E}Vl/5|C-A9MOjv1@M1LT:-N`O>!3tM.ihX1'E"{j0-dYK; $̱H1äc\\SHtT)X k;،)PKs uRE@- %>Ĝ&R @((tbQw4X5 3`;.]LtCE9ZQ"m /IeA7ojb^}v,Iױ<vf3:bj`4Eek\^ᡊm!Pp@!q4 dl1f!wUBwIj'gٯn Άk䞾{i~� h76mgD=qFas v/v(zV^_k$|S&*2 &fGAEШ<*)Y.M) p)ٶG\g_E߀ c͉wm{ ,*r;0: ol/vH@O`ɄJc jXZm!Sh8jٶ̠* T ;N ~o$O⎡KZ+=)OI f/AGDSeKK'P [(a3@R񕝸~Ĵ: ~ T̊|,9 qW,Yah #@j Zĸ,jE$' Uy&ZF'2R%%ţGL&d\^VR28hco izK{'r] ZCEXCMS~W[̀ H,l \}oz;t]C1<"Ē.vTrɉ,M.d1ӕBbMG^40ZH Mn3Q lq"G zslz(`ϊm0Pw#cMp^LH&f\1@hu G&:^֝Lv:a$ DI88'?Z#cw2>OfW/#M548#F3N[9gRĞUl'Oܘbeyb /}GH@xR-s"j#f[0"E>Iź3{C(iiwoGM?AGCAGCMc =S] * %M`Z[C勇U"`işnDK9Xk_XW MQFPKMQ?[d2R 0r&)QPM}NXi 0))Yel1j]pr'J:XhL:&[SSY%w؈*@|nyh%J$4g0J#8rIlq@rO ؞ruXvzࣣ,ED:ELt2aa[lY.wECDzNSSF FIp (]bbqCkFt"kd ~S('M9EF&nW.!7Bچ ];mNte5|cm ;C硖fM rHg;䈾tAC~!-/rm QU9 aT FZ=վ(6plcbn[^LtCߐ__ᠴ={7PF&zD⧐ `~S8(2[6B} Ht.d"|FB} !*82Mj=MڅqBkޘRFm<3x0MQb!'jbLg}/PNL> cJJ2yT'A9Com j"1l6#*,m/銉NH}'ئv`SF1n:O :N{\tC >ᥙ7Bj:EH1##?iY5dAy7/uNZ34BO@L#5 QQO :\'@2b>hT"$N#ne6CAyn2Zfmڙ;.gtxSҤOFZbJI3!sGo,@I.LG'l h.75{'& 3dTZ[VR$6) l5ÿE<rbT"WSOblNA`e ,k3'E`fDH|Z21j{6: G&Ef2Z1*2 7{pvP1Y)01uBQv%dIϊ 5Qh]jaٿPӇpݣGD/U oe ڱ[b뮡 b1*KJ'tOӎk5++h:n[_CX` ߨ6C݀D~ fD$߂7PwX&YBa$:B?èȨta?l[||?K6@fp$O\J*]J am֡jE+Jλ@,z(:`PT_MI*:NCΌEj83cϸƛcCr/eHhSkDa섆.j@#J dzv{MN.jҢ5ݥzCslfJH۶m(ZK70JNwF"KI aL0@ I=AAZ^bKyI`g iP*FG>Y7 Z\aDdiL5̓p@2̃PAXKq$fl(WBji8[!2=Ld rCk## 70^?cJS{xfJ2U5#_>n!wS!W+7W50 PѼMz]q$ >$V H M}AfQAP+>:b(=R t6¨%PXOSP0[uzSBǧO VW+@}.1N2iPTȍx$;+iڭT%]`h _ %$[I@թRJҸt_e7n"EQ_M:< Onqr@k2,r gsi@ҕ8-l&6|͐B**3=0&)BH А\Ow cbA/w:`OV:ztp˵ڟItRqPFe/ J:gYᄑdR!cx:~:UV",a`T͖zDpI,FSg֭\\.^-]gYU$I!?d `,%VC#na*P Tj?CmdcysXUV1)s8댙(W!5 /grDTjAz* Qg TeOH 7ZT#dhO 2DcM کQiY\%c9]…IlW*tqsgv&"ٮG]2JKm"8n=[BV_,IBdIIN+J|7J3֣みߑ-N xkmv[)i0ٴ5YLzOX%X\_,&͈֤F8xۂgrp*f Ic,jZ(̌U (%F7u5H ,ީ@|3O,WPSE@Iҟ 7 2mbw:*LXeʅR7CQ3I3PB\<1@L@JB\2~ 2(r!+9,u$gX F`d mv) οMp{2${ޖJt8[ IDgI煲M Y iVн\Fl2ZGwU+Aـj2WKeػETV!5m7wtURFYQ 34B#4%GLh4={F2zicp'=+WH'vSix#;%(#aMFIC359HI< *E+8KSVV:qtkS牉<'́ZSM0p:Lԍ -<)Jtq+ȵ?hu%ӇT+#0=P 3pc;# >skeH=Ky82H# BR)3/tG;9Gw0}D$<%TIKfS9+'@?XIc`K2Nƨ4Zh[KVEW@zJrhU9 c.3p E|EUuh2)mԂ<ǗM1sHq*Vu&CAc(] - m g6MFbs>9 ,[P>/,#H2MraSuĕ%2z ҥEk0Ct ¬#H(Qi9/FZhՕN*Q=pH@*C\HY@(r  km,JBHm:,G"Ǹ YTRkQLVU F  OPqh%F<\ yhd!2U^ZmR t|!pT"فMs#m.hKY-:'*i? i\>9e7 ݏN(u5qtx&ENPTI+Ol/*kHn˩9c"E BFB8RAȕ2\ VP5j39a"{jItLw*!i]ET`H)2)q vA;G ʙRJ=Hƣ!PgMp@nPėj/ZRѕU#-KF,A™ҿId]A[J{R3<MN u5jQC*2+0\* eА $P1P!fsNcVRHM2üBc4~U,ȤΫS-u!\Vzkd=E\22]5>ֿ GVQFsθ2!0z Մ@32f-QՒyF@ !ņ^* pmϭs:ccW%z)B8 ԜҘ ҙ}8r.1B6&ڊZ,ֺ5:QIy7P|qRTI-zT2maנýJ2B?@ֿF? MOڠ'SBY]fH5ZSJxx4 0'П(_C,jjeҤ n`QCnujS\1`&QīFVLkZKMZѩ=OC="nA UFc#X!^2TZD1qjr gCA"S%MHOp (@ԡi#T-:JI:A)Ll A\\zCh1Pnjk`F,t\{D7JCP>.:9Uʙ1CnPgZa%1O\2J# #pִ=@oR*FsqDYuN`W,Տb5sg|iֺl6UQJ bIm6ceȦ҂HD䋻m V1t`ܨ9i0{dg@cV9R>jsaLlTEZdy Z htj,#Xe9wW!L`1YWC;*jAەFD}8x1/OHuW!p MA0Ód~,(6FC/OlW:+ \Pk\PѱL9J}x-E)Ny@Gj1 j>\$߲3̌@uA`UrAOҘ%H*CdkS; FGO>#Bc*z?f 6#MU?5!W*ŊsBt?HísL<*p.f6嶞4:aĊ SJ?~2ʮNy:`h7_,HNaskRs]7 1s$ҿV3 #U4*u:CzwM s$3Ƕ9])]납J5zҭg # s~׊2Vt@zx`X4ȏOJx T}KPrV=1Q)CHv'ijgf@EwۖbI. h_X^:Sצ)u eMk3J͛#B>PuGфhzIu*)p&uGJ)RUd@6X3,j8>XdO(Fx^@?+ZkO rzLc@3$'@F *Gu& P& Aa,d0g1Ihw jT^fF<5ܬfl8m<鈒II\ёI燱y%gIsPHʙ9 l]vOí|(A%XJ˯я31*}8j{l\8DU?1=Տ۶^%s\Ӭ:#+2cۖbx23';xj:ᅏ7Kjۿ,N%Vza/ 渆)Ewi=DS?C1Ĝf{geP7a*qT~>ʹya0Ќ^(uu୞֤П `0Tz jARZaqtj)C.TOi"K񦇭F=3nDU$|ZyJⰟUV@N p(dR֞0U6eZSq^` =zB3 N@?f+)ORГBzD7QLtȞe&T&xݴr9u:Nr9y lH^?ՆT! x ?q/JgN5_Nt#\U@\kL JyVLm@5^80j*4̟..vN_\4$L$a@jkeWPkS; (sqh=òCQWOAlfP*GM0 b R5!cKzKb 5eye(Z(O!YF}tYʦ1!J[ 醇&$(Y$Uc,}iLLg`jĖd;Ǫ ^0BM䱍65"1ֽ0/"p%fRh,TNN~Z#C! jLsǶ )$8 E4c}6"B)xNlt^w.|}FmFzMsx}87LMBU%MU@>c38<{542Qt+Yt[K)Ilhk/ӧ6Op q0(c?dyQS40H3b|AҺPPԟMF'Nu\B}@yH ((: dwd=K *QE @2mAc^?hs ex>Nm8:q{t,1Վ,B(;"8^3Uf@i-˂ޘH9?K9Շފ FPa[+N[ 4/[@[ƎDh葂(4!',Cl~ɦLe{DSuc͉ zq'qvu m2K3)E`&E7G,H!0 DemwµG;[pkEqā$mn?z[ mfZt_*819 O݀+N(P$y|zc OI0.]k 쮴SVcJ#a(B3Wff:( ]|kO.(P Pi^~XaE*)@~PuIQǽ.S,,%zrVrH8]\;W&qq||/3!x& dfy9ib *LbCvt>$(.2ۑ<ᇕ8kkQ ,|ZTz넲`ά9>9x0o+}5*u?RdJQuoJ~5{ z@5 o%@>` z:-ݪ> vzE.%aGӂFWP0;n:dz}8݅* TWO hF t%-Wq49e_ o$ Rw*Hֺ.Ht ]+e)*78Q2#\ y7%iD4#,؎xen$FD '<[}fIF g!_P( 2a`hQT5W"HM3? %@j5QZdtj S*x0:፬Lf+hEP*X+dfKi%Ơ,*eڣcQ=F>#2+P2n>k#]\|d \(C_,{ISF 1ڤVp*E3;i5F(@*@9x1Gv} Pu 2%A^1GJ A8ٴ0et' sS.;cmSoX~>^s/b1{'3<#rGHLhw楈8eS5X/1-or6ʌmoaV,7i\Gڽm?ow9w4Q55`L$YVH=9SAҟyНwVutD xchδ_GQĂl4B徶6ԏ3*<#6xԍcE㓚^'mXf,."+m 鰖j_\u6[%Z{${A-spbN zOrNVa#$v1ga-q4\R%")@>Ox@C-jElȦ8jc4@wndSSo"@!a(Xd*~p66sRژ)37h5,ECS˜55Y9KHq92ϮA 9c"Y1[(FyIٝXu?=]CflJciIqLyyP֔Lmj}N. h+%O*}?qG鑊ۄVe*+vX-t*pe繋}*v6~f4#/{2wm7Rx]pۮ{s)r<i~#,U^"դ'䐙(1*H%iR+M0jVUd@#QEqr{_c#1\ϗ?uڜ¬шfZ&d|0ַw#fkK͑=I@/, I{Hp֗?6Zhi溟֭Ƞ0TbS\[D+"9(HLbo[.s2hpm]W!*ۚ,XʿqFe\?\ljWRۨQA4ӏc)LJJi'navJ_OLl#mZsRgtmRXȱqjzA*\)v}4>=~Q1 Ȧ$L!\?ǵ#PJe_ՃsZ24BƁkP|HB•& wFg |p/$$ intN޵(rν|CT2vҧ\3jEEGSᅎ:鑩u+*k ^‡ҍ2ԀTJb@vNR BHQBR ~ cM upB4 n#oT$TQD dH"R,fFf\rSi)M1cAALR7VʹgI }1$@*@Ez0&# P_u:b8$%xNuB ʤT~#?*2I)M+ALIj %n]iP|F1$'p vC"!4YJ+CQQ[[DTuY̱MeNZeǚ*OOZ;mUݴaD]! $-2; 5pO#შ4FZ 8 %hDxC.P1ԍ1anfZ72##bn$,.;RD+U,3M<14vWo5ͫ+q$[؈pʿ#1c[(?!ѽrO[^n;U٩]A@|pKqhvHm3,[MϞ*Ml VDP֍Sm1SNFџ`6mqsRgӠy`>s]: 2Аr\.?W 7ۘu²@(I- WzIEAbBw#!O(jX SEwm }u26 \Sc@=XTAl.F%|S:'< zuw3G N$2x*@*O ڑrE f:wTЊ *A4OBǴM>((+=hq%EՏӠgisF-j<2[G2H:mvgҹ`{Oݚ-SFtw,>f44P1?1,`W<øzf?,O\{hYǧESJ>9AVѼ7TVuı{B"mkiEm io+Qv2БO13 Ee۽[BOJY}HɶR @#t4"~bTHnYXVq*t=:`CH-7-m{5눢i#oih8-KeH?^7 #]# ˠğy'8hBV;@Pf|p2Zt>GPq,JqL@>kVЖ/P 5|+FaB"CEei#&kDҫL?^}E?䨮֔^*۶c^ h=0X}U, ӧL r}}n p,;u4i/_b`ȎB; -ń`r#ƅcw$rcE\%s (668偽LȢ$F'Mq\Y XM *q, @4~k*jtIc݅2zPsБ=OnqPP#!I5c8Gs]s'1wkAG! pse78X=:mF`~ϦW59Sju`3P2_"ק=ǯZ Ufk: % Z$FIa@H)r[DH%dW$DiSK)G$-(fL(4ֶ$6,$%\Y?7{Om'x܁mAoYE5IJVk3DK`ù-$Nj҇p}3s{T?6HkuˉZtC@]9 j5\ Is/hP!z3ʻi6[HjSM4=±,dW{>>x%muijHIlC0Dp&O/*cً5)g1 FHeMΘ-sʄWvAya/@:Em U:3xNzmA4H5|0bN9hY~??Tf?gcʣbB~!tj@ nbGM|'c<7&m-E\/jkC}wm*IHkeP[-0DAC1:ҵֽ3$ UZ[J|˚K|9L%̢U,QZYhsZgz)BvFJX `7䌐6.{R:ҹb;GiU!z֞t"/.*jP:RDgPϠ$4uUR7-V UȠ0BNe(C";NuP$S샛Yw"y+:"_m]v$ʽq4m+U* tgS2-(Y%]I|Jxf3ILeBqFt8Tg _²On~U^X+sZvWJS!ckX*I3̃6\n E?Jbn9{-qM]5@F=dNG;RVmb~[I+0uPI!JZKZ?r:]-Dg+JH1oj+j)Q]u\_ ~N" ؑ Tx+#nh?5}7=]ϩHoۆSq%3Oo¸=ƿ&UMr=,]5W!Ll:+)'vi+Jz?yy$iarS hq*B ҖH2*K~R2n 73ʎ^+{kB5#L[NZ-M%ӟ%uvfDo/\**Rԡx~?Z8^ПSS k[6pju?ҔW3Mrtc`4# $I hۡ?Wb bE P#={H_}8+t"X5x0X(o>ݍeP1'1Cgc -́#O2͕|=7`~و=uwlhM66y@<ݳÞ+WfۇZt?^6;N„ Ǘ riGj@"' p-ʒ4Aq)AΆ |AgO֝ݖVdiFBa?-{V$k3jycyȡ.[@K?`.X,g-#s#C,V+'kמJy`2Zf *xeç;WZֺSU$vrpik Z bjctFȊoJL:/Ǹ0Tvg[s0\ԍҸWtQq?)|4(|uv6н"SrkOqr\UA1t$aZ =CBBms"AEidUgJI+/x֓eh=ewl Q 8^;NXc>:xfcSlH-6삣P6=Ʊ^hq!;W@C#Z*$ܠ[XI*HFksMs}ʒrMqRAZ´;QS9}q? 42[ HCx ̘]}cQ~e.8 v_MŻRH0E+88DIj67`i|,H=ݹ:*O׆yI$ll\,GjBPu4"A$2" S@kZ ;(y}hӥǠ $zb79ţi~T;*(,k#MIcVEZHX: BY(i-*p.Z:"UPmoiQm7jҕ1 O!")¤4`Ez"L@wx\3ADU\ 1̺zk\­{yX1Fu$4FejH9zӅ9 I7dTWZS)De]ܣQx\! ZFYWǙϩ#•(JZG{ <\.झizkl-ޡUcGaq5z`] (*tM~` +x3R"k3g, yaaPE@J/7S:4%JCմTtֹ8LAZ4vF@P@g\QIf:yfrZUC,qrՠ4͈Q㗆 (r"L@a:g8+CRbe|GB,˜gE4ҿO_z\t=q]N4?: ǸNF3tǨݵsʄ|Տv-+n.K>zCiDu[XR"~%EOqX z8^jLφ(0B8-qF Z|zv(Ft\m`l|XMNX&*c, e?V*Rzd)J6_ݏIGg@xuV_$Qʇ82΃<*xc`Θ_劚=d eUȏ 5jtεma)S0NlV!i.5[cI.XhcSLL3Nw\]J~5Z DׯF (:*ԓ_X?F%i} "w2:}<\4|Etn2}!T yN?|}=m$c V&юs,w!e3ŔRD[ٶVԜw}0. +{Yx9{n$C0,Rph@$k[/ ֲb AtֻJo+JbDcUh2шГZ okz操_ڕ#q+TPPSrmmUU;a _1t$]ӡSʛ(w jzp6!d@1\~Ӆ4V#=XdJJxR>Od$<4ٝOzPNYxdBV6b\j)`[̯QmVM1+"(*b s,,`;85 VNzb;j6 +t8zgdzn G!$ju袆k)lEARO_,,lSdF60J+m М3ėJlj[{ Pч30ݸ@ҕFѣQmٓcO<$mLj60$,>FWOm9WI8#g(̷̔JyPUH*4# 6HډSSXEn TOׁq2dsU9ftw-D#S_&$ A5=?_PFjҿF SZf3\Iƒ4PgGht ߒ(*0SaFUW;PcS!z(4 |96#՘P~ `ڙh6O\U&~3 =J} gԷۍÌa{@r2[VBwwq GnGZ-OH۸B O,иC]>m8,d=z@-GJ jՏTYh U4? M1E3>8 Nc7:g\tuI%V|VNe8,g*UmE*E<ֵ5:8Rr:T_栝V*!M4,.w<ٖEK]_>xTn^Idm3fڳΧXgIi![>9f.nJ\ČQ\\՗52l,ƊiHO2 g.;VWu\6vVp?svH;ኈFӮ;E<77-9$$ZYs\$o?qK 6F)^5! BV#Sі;~J>cR@n̊!G!Od:+ӮퟏR D*3sVQĿ^KۉL-Mhs5X{TZm= A-/涇p95(+VgohT6e RFt"/+UIjրvgIC" @AajfBӈ6B# R^s:HTW\?0n.fz_#ZL{m"zHx>۪ę۶k>IB 2*RAڕ@Pmu+l+Uz@:;>FtEGٮJca;Ȣ +^XT-hzam`U31~w~`.(?^ eFUВAzCRRJ:rt_2Hxi@\F@ᄞ?mUkI>>" gaVei#gJA osm3lpQ +1D0h>jb3r03me0O¿^ 2F;zj9c"G ,UWa% f=k L %M$j2 r49_BZk%FQFݴ0f43EvsTRI:3ŗh? F/(!E>VO}@"\m =O@DotA\T^1pȿ߳aݷvN=p?~ىni@LX1J^ӎ;KF+阆Oz"F Isyn,y XWwrjGcm 4:=6S_ᓻ.f=FovfMcZxF~~6~;w!yI*;Hm %A_+K{WudEhҫ",v5L k(l-cAL,֘[H=e{V,L-IzC3fX1 _^Iw-s$d"v% Fm@9uV|9RhN_r^^ύ?klAc#ơ}Dea uk"Ɓ :ǵ еkQAN#9gԶ_{BT)_/0$o̹*AuPȨSOB4`EI#ۄ"m2Um|#M1dͣ ĶZ R6tԇ 0Ҵ+ an+^kR~`@ΔӮl+p`E:dLtRI#0p.>HE 98 vFNݪj g{=h[ӮpQneA)TSC=+)Qnʹks0ߕ\sn-BKϺYx7 =NJGlF9׊>='5͠A,VhURQKNE&)RfV2dgQCVh扁eVڴ"2q^c!pNE6:kVX܂[s,HN0\n"5KЊYr9f8@lR~xɪz}}0Zc:\Tk4iǨuΚcq4W0I+,gcGb3'*$=1Mu nʹҟI銾T-7|_xS 0$e\ nR=J`]+D SkybtwǦ8f@?g=OLP6~xeb*3X,n90'Ju\c՛d>Pg'<2q?LIȌ<*K,DZeקӀ62:v4#&Lg1w''g1]}$=)8֋@Fh LqwϷrach#(HdT@7PlG`xKx">BOlf̌y;+^^㚚9}mjА*ڒZdb" mjc99ĵ_VI4bfK_cDFmS;.Ô^HK“}jw=+b Riwm8qKib+ѷ>w'svrgq,aݶ$;TT\q߶W\`gg bJio ZS)!Rd?.ͭ@tX%8ZIM7G3!\?j7!wuo!q>b+TGoh32&րBY -CMvre*j2DgDٜ|rEѽD-r.`JME*:5H׫(6$1"mwZWO,H @:SXE 7!WQd*@ m uʢE<+TMh)*۳hVB)ON=ah i\,rʣ]0mKRm@<)*&h2fG|4UTQM'QZerJj_=3¸eVI-[-Tmu?^(̄8RԣJ}өaqi1V*wϦ]҂*W-hHaBYʁq=Q#suAJZJ!)\Ov=k} HLF"e HTjv_b⑅f4'sYAH#wo5 bMk84' P =kLJaDbdm0:`{UeF0u\Oݝ` M;f?RՍ Aj|SWS-/惁H?\sB=^AoIV 1.s4W֫ +ԣSӉri$qskK۽._ølʩ ֥T\5f}J[[_m\ ݑMIes\lvEC9+zI 3w1[rq1E ߮@1c(]3'Nx*bT\kS?,T~ QPuMA9cbF+b,eXƸcljIh;8>ehH<)-_(;ӄo>aNEb 'qTqlC*RkD+!O [L|ׂ!nx0q\q6UHovd$jY}_,0Hu jҴqfMiMq@N` PH˦ɨנ pz\UH ָ-PE|wL| "ҫRTF<~7HG8SgAde2U<Ǥjzg= 2Nt+]R3?N7(! 844>dž0,Xt-G9Ҹ c֠cjk~RE5XSʘ\]sV'qp7i?%%i,v7n;bIw0qe_]1I=mv<7Sc+  *He,,/~dI"I{R6,WZrGj{-u[n6"\i*UwP{N+BIլV"yl5 ?79cɷ!hm-%WH5Xc "9=^j;lnWRnEIJ1`%8tLOɗ,m8f@ fnq/+< S.%?f4şjqfՒkZf<E驠j )=]]jj*Ҁ)J:j 7@GC5C_27f:y,M_/8,B&V1iR 4S#ɳltGpaXr|~ 0\Lj(HTkܖ!=7YmZ< |n 9nfmg}1'VgQW[/-3w~1J"&ەVCsnA42^ TkiG8]qtX/d=R8Kh٨ @UI(kG`pD6Ŕك,\@GȮr>sz=)Z T #/B-LWKjё|08iwz|0Ez5AHȯ\q{eKPO1_d25B7[$/Kɟ.;vݵ'2|h2?͒GO?u)4<þ<庐ߚ-D%B dx.DyI7wipzD|ȸȿ/yk^>x]xSuQv$|<>3FDHbjF)W4>tX+ 8[ny|<Ԝ+19gа"!u*iOVcr*4 h(u?ݍі6J?~ @ Vǣ0zb3r^7<պ|qY3a9kNRK3V dDktAoU 6cU5X1TGrvҸbUoe w6ѐƽ %(Ƣ?czT -LZaZ҆ïyRX3775Q! )VLZv_Iu7pZ&'V cUA:nŜSkӔXd CXn⤲W^ٳ?f=Ց0UUTVTa x Xۏ|FL닎/_ĒCmklwNZGbYge{/usREl -Z wbn [.ZI!p,Z-m}LV3F$إB}$@ʵ f i\?3qvYI$cPROٮ_ ?tq}j S$?n?8iq*IE&Қԧl,Swqz|&)Wl0A1B)L~2wƳr;ύY/'wRGU\]w~]\Y9[s~1ҀIEQZbWڶ0^3lq7yr?#܇m>gwhoG23Vo`#bےpFYjė$=149㕞1vW{h+LwR`=-1IPPXdh W M8]Eʹku8X&\V0cVXfX.4%ҽ2 { eأE{{1'&Ie^^i%WEHIZ7p%dSRq畝+ٟkdNt)WjHv Uј:350Q\(|ka@Fӡ_h+O _z`45 6:8*|'\HWxj-)]Z=:^ou- *4$]H!e7|-kR#̩9h4RPh~ٶc[)-xUaVFԌŃRi.kyi$t/ =a 5 Y^K y.;xbI(}1RٺH ܷQqrXI)ч1EU*A4Ҁxep ʧ˜/ M)-SW*L{L, 8)23Km S2y+z\{ܸfmorhZ䂁e#dp2϶ ArtvVUIFW5ݵ0W:؇5B6: %=HVgl sȒ>'z*GB0jI<Ҹ$ WQ@xXEVf Ѳ Izqq (pRMF}uV2Bn%42:XRSOL1eT,}9gE|ֹnǺ)S]?4sXvRZZ'}ӎًlK&a墉=!fvR"krHU%~%=Ƹ }>H*+B2h;m֐sKu+/\Mu8%LP1_znX๋Ra͏hvo_v*ڥ,a K$)ҘNFȨ/cge[N}LPIj\k[8@ߞ)qrAWk2fެ\l\sl[+$^ i Mϔuː3$f܌ /|Om=vwo?d"E>\m6Lr~p04x` 4R)2!d$RтξU?9;VI2DRXAq\Sq"iჸf<Ճ*:4cӧ4:R>>XtY|zO/0:(Ǡd\!ՠ`Mr @~5#C z)jU jQ`Qvjh?v $e==2Hvq%Mo<-t&AHB5coR"=%M-ҭ3ل{zBєKm <Ƈmij SOOn (fhgHDې H&ieƑrf$$n`- Ҋ+4gLmxi@s{\AaYEOS#Sou6p `^~oCPħa=g'ub.3;{8WjChEU?q* O mj*5ߏrL txQ7\(28.a.qQ1ttmsVY-B:1m(ƺBw~W hs(ފ**(sG)S`bxcjJPTQ+ jcL{*Jݘ$)=Ż"+ff}qt]Z8Q j,`Bj +"?ŽWb 9}*5$b!8mw(9PjY{eT 6C_?OGq9|iӀWObXB1*G3[7W|RL(dY:|5nV'|R{fa&SMRB+Ĵ|xA:(*p &#{rua|m[noIRE>n2ØKt$.g i.~Z4:SfjE/<''kA[/s+-_QZ{>9Oa Ƿq5bGDx[XLz0#nC n:#qx3I(VE¼D"8P춊BbZ\>5הQF#q n22\Ag˴jV+9ͼϸf}檮IV$Z_q!6 LuSn(緿.djHX j #e1os3-y1[~Fd6gOqVdJ]i[k.lmPB["m &˙o ս($I 5i ҏ@~BYx{xiX6jYϭN}8< 3%eaq NFň?&~/F^&)+?+;>W*qJ E2੭ s)g.cCow>BM:+5; ̡W g92\Ol'5lrウBv6ۓ5Y64gL]~X^M';+z^r( xUY^q Ѯ0O~G'g y(w9Qn)"WC$lN9PFV</%sQa܌UiSN@Ԏ宙ჼ8ݙBk`m8$XI \s0 H MNftwA!iM0CCQJׯ 횓Q479z,yn`:excۨf$]0-MY@ pҲu +@=kC;M*|u/ OJzӡFP:+ܵ5CTZS?u0wpQ"\op3W`hkϖ*r.>ƍs(y+U0=ykw2q=\"DGVJiV;bfN.n=*z0֧ {qe]qk5pǶ?pjj6-8K6s\H"} )EjIeLr\}rG7P3>>&?H#=}1$V\g<s,7W:|_ 딭6PWxSQ$D | Fu:a%T}@:,-Ͳœe*~}(A[ Dj5,5LL*AMM|#=J|x <d$hh(OpOG HpSurHJi06 g#4p34>I{%ͤ :&cAQf%*0u/r;dmےٍ ScMzb8.fₙ0_霥16Ju1v:?՚IJ? G@Hwu?dj|B.:W ȳnpyZlsR fJC;W)pHsۮzZk3ma)U |\mb/xnwd-'U@*]۵ | 3F"0 yǠ.+:kG+euZp#Վ-;s!l-ⶇXm~$'ּ?nU'LS" FBP.-Jj]QL.z;.SHg@Pt#? c(+v:%n Hm"^\?qO=[;vZnQ]1;(js8!ej+2s^|V<}z%9OH=F9&-Mkt,2_@P$7W*Hd'\|caxgxY\|A/7(#|\7?}~eXGAY ox 7)H&; Kn쟎ːy.m~ ),v"(}9gedr!AoBz] i_˺xN~1𳸤 .ȡ2=@\nYqH{+{jWckY+W{?v6Vb#?S#oqd.]MK&O O΂P$TcLJfz?Ri QN'Hmtx`l&OI^+,9?_-]<{ˊ^Tֿ ݼ$Fo6B!SLQjUn@(bUUg_peC(mH$}XRL@::|? )5$1F=^g߽׫J"VwQne5^.*ywj[>^ۡ'"5 w)eY?-s5 Ӟ=k1Zҙ#,Q Ǹ@Ti>Y` 3\P_P$yC:uvzFUq*(2bF_.=oI̩`/dROSid0 Ǧ7vZPӨApHԥ *`2[q5cމKD-~J͟Z TRH*k#S˦7b#Ѐ~)̎_C4W9<+@u49LP5AZ”Кeb:RR4PеM#NpKM7ts@|q(=ծ[s0WX e&#DgHI4j|qk\Oc<殡FEm6<5ِEżBگ#WzP;qb{+wܙ/VNTeWՑ#o|Z,Y[Mmm*AR@iN{}~#- ~ 4]߸aW*ȃ ;3{mS¿G# Z1:drRAm 'bjLdž;H5P҅]&!QR:MGׇEHVP=N@+L°ddoס{JȕIeE"E+@{i"1Y#pBf&G@2+n0OQȩ5BDZƣ8 7D{ne %sbh>ݛ=1%*KTa%V#\ap Q;TyKx\ݥ:x}8)#Li?2:\~mv\tًQVss2rrmdw,iܜrip@= "84YB0xi:ILs0/k~!Y՚f(֬q\:qwq]_Ò}Fuʧ2~ PiJk_.bx8(];*8ˏ!s4"]r3dۜ13Kc9VMu}۸E~bqcm-̖0h(s ' `bܜn-&k=PE;bw/{^˘,X<0՛ݹFH;TL/fl.o!Ƴ^ZI QA܀9\եoN-;òoaK2AunGa *2*V#uZSVj5$?At0Q/F邢ـ+NveЃӧX2{4tz&g#5:´ >9/??mrI S?<ļp\cc,qŘ%2nwqJ|cHϺkfXR 5E5K?"Ib\<@,݈I嗸q>mL<6VD{Aɼ!47D=عKc(UM -4-iX}Eh* Pdb+}qg$<|V)OX@P*hk['8=-Z]vD)KmQҊW]REt-(Qp_MIgĂِЁx`Xwo*BiGbw~*2J"le5̞`ܪ#D= g1i;.@ f5f) w9AGV$(ǥ3WW.[- j3k M?Ikv,uzi+U;$zO 0w>{[@x}%XyxxW SJ2@APtc{[w ="=Fr:r/..Ce8LNc*j~wt܄!d4ت n9n69ec"4 Th(Q@c4FiurWko]҂A7|tMq{;[ebI= #}TTQqg}[{l K}qG$`eX#NxYjk(] }d_h=[2,_hFsr~clr܅'5r/ oJ ܐM)&29v:e濘n6ؐFb0)KԊ^j!j{Ȋb$ondV&F'F I[)l"a-,Nf"(La7iyKpe8[fIڡIjR1RK.{DA02V{W`7,U_V.Fa(9AJ!mJ)3c]B:mIA5LJ#d BO_6эd: $6CR;x+_G֣1A=V:<X9>lRI m@CzyE \C,n %$M 2mOf'+-^p TDTm p(ڝFu?-\]DO 4rVc}om},o6h4)2wjRw5O\I"he:T|[C}I 4p tk: f紻W eܫd[{P[qOOU4%g)yhɞyN> ڛX-I4@GQn-M2T0V:L!(/m\8##Vn^+zpTQJ}tZ> v D8 c"C >`PciW}zⓡPt:Vx'E)GV*j #}Rk5VkJ_jnq }ܙU? "δc`w qh+r}țrVHc=P_4ZXYVF42ݹjVŗkvcq9N6n 4qHJhvg?KVs"=cqR"R ^{eS!~6EMw~M>VF[>uQ~ k|dZhJ⹯~Ԁ϶$F#uh4d3#oCrSwJA6{rhI 4nVN#,U!B3Z?q/ GGb,VEY%]M"YDz;ku_ugX{0R=쪑ƻ4EH9vpH6{RxxI?/N8d"?rȲkUKv5T&bOÝ3rj#o{1k F^us,Ne܌i?m|qsm"2Z~TA`x7y Aw{_R3^-K83JAa P@LkaoB߅-UQ\X~W37 r hㄶcvKIVvܯ??0Iz"B U*ա2egel:Y*Չn cqsr2jdF]V.qӔG" PW*E*6{{9{-yo! +g%|\ -f_L-oFW1lh}T)\'$NG_\DFkk$(}]>$ t˳ċ28q]qx+v?Ie#G^NJ7Bm6SG+=ѰzFz}q1bE4̵ ;Z(; uujke.&mHڠ4TWzno;ˎ,eZjH@1um\pfnKŪ#s$CBfL|]óW-Z# }n3e܍=cGS8ځ.%P[uAT'FUF)V<6(<}ݘ k5RB,E+n88GD+jQ2Oek) Iǖ+(4_3|@E:A_,A,qǖ 1(u?])>8ަB3ìyX"҃ 0RTP*k\n5gƾxbq:WZXY/3)~ҸNu#`ǖWKJ4e(<39_︬bMR޻[D6KTPHѫ99 ela#>;xHݛH %7ᅁ;ͯV?K"%X9+xмK1YAgw 1(a0 I/㟓K{;gP>f6*-Ϥ0RhpE-)&:puVGL@sxb>Omc~B%^}8Z3:ddZ*ܹħEj٘IbF;ZŏoG#6n *Et+7,Ǚ"jh\iiՅjʔ#BiQph@hI 9lȮTQҿV=\`-wS3z`i5QXPjPp$jmM5 qIsEKVϩd"ܤ`J!iV :`a!$z'ʸ;e15!۷"~bk+ZJ>9FiӮ~8Z"\P0 'JyʴXE(r*J*=iﵼZnBI-:5̏ǫGJCݱ+G{4*V)b;f_O.Gm",sF(Yq-(4b[n-U~"mD6۞] k:7zTneFbkA6\YqB^,7LEP( ͱ#@R*]ґeWFbaNgb}=YRIPqL Sǵjc]Lzbn ܲ(MַLF1nT0l$ӤB'T(ŏ3cYac fJP3ŷ&,i*ȥ.LDkVc3iwMMr $\1yX4o1\pLK;xr*䫹w[jDKPji8^w[=Eoyg迈4OWRECl/w9'-ylH?-r& rgfgeql/GKE7IUBсcW_3mk"O48QR 0Y(I`3i+iCq4EMTPS=M,0{;+a=^2WVo{20ia uB=YKN񲆂|:Ϻ9unqoC*!4¯'~5aC;7ݏx8 -s/K >8HeOlq"! J5h4̿cHv%q%ұqXS "^vZK,[ :z*1ߘ{sX-yF[6oZV9>YVrfGesv'FmiU{{J9^,;dwsoUA1q;v^Nkb*-p(ȱ@i*rR$#ORKt G :*䢃V#L EAF#355ˆ'"wd2΀xO.V#&$t ?fSwۓIGz9CT׸Eܿ\=X,m",nBd@#PC)n'!I2ZMou~$OYDAhތ6.s{;ci,! )y%,UEsAC㍖8SMiW^L8*Itc\]ݻAmp2+4-j2yq$$Z;h2Pڞ-+Np.V)HIYb>9SzNf ʆf@ժ,M@ii>QVFC4]-˭p \Ȥ/ j8 '[{et Jdp%+_\F&v/?,9X۷1eբ .N|?'~wwW/k4Em#c\Ph5wIvk nf†7u ݴlp|K.\@tMtPWe+J5t Zp\OƺVx;2q%4~ Z](HJԀiO3h c|1WTQ"8-)ciQHAbYA5pXX級g^_=O1 1W]rU31 a*wƕj\Oiqnm&Yd)GZ~]s$jMh+tL*W/Ոϲ$样S0Eݽ"TEuaoɩY t@X1C ql{5I^Z, f2;N4cydqVtV*!$Pno7,@&f YYRdȉ#Ί $tCNːpIo!֩B`U6lTEࡅ V rskOM=mBXQZ@`َxhqvnpV9Ph'?k[QYB4-|K.ҀJRH /pRXKrElՍe'3|w/2-w F=h=&&7-?֡FjE(I=<*Ng|pT/!m[x4Cw ?v H*LʠH0QuZ>4v 6Tӡ=~ɦk(թP 9\y`E (^/ GGKw%?1#cCP~J_~AV:79ya ZWasf-Nx6(> Xa/HnhjI 4G--e?~mR۟{S qa8*jPFfDgOVlqq@ F4jա㻓m^Z7-qxBiT+5`y9%KHg#SX41$}Ww4GZ@ mRJH)E*F-n&e?>i9"cf"Bk T&Aۀ@d mZJT KOp-$gelr/,ܷz\Vx裍0@Y49p'Y&biX0-Pzؚ|/}5ϥ CueɈ3!>ݲA4_u= F7ogjr@]ir1 r4(kKg* l^\isOsvy3n3D 4Z3T"{j>Sr.8OM%|Q0`ѺF}Α ~{fѥ=XWԷtm8nH!de]2 %dCd= w \ H(w*?̎PW]vZZMɼ5Ԡ*m،k^ qwUB_oKSkMtE9N'/ #&)3 Bl6@♃;6wv 9UGܽH<%ygh`/1LYcW|A?.9\<&lc%V8SPzKӥ<|EA2?_v顧 1 A3qE55'@>=iV \쾜^>9u6%+Mq /Ru*ヶ"1 p@κ3*hƙh1 u~U#QNY>n5TQxεlkk$n$ιOh>< Pv6e(|2K qmqm,2d{C 89ڲC ?č+wǮ,M-k)POnP P*2sY7 ]omz)$DFDi`;k 4ʂy']Pkm۳=Qk!H]ڒFjE &ǿ޶v21۝{dՇEAeU[1Smw.NA=$2r~n*pTm} cͼ"3Yl(eGP MU;Գs|Tww(O~(Ϸ4 >)8K mLpT(I i306kCA@vǦ6hnc(ѳ AM2XP @8Kx؝ZK<釺t@v8Keq)b<.)%]R iݩ`*Cfi\{Glu U=+8) OAe&_xj$q2PK(T1ʚTzC`)~wf:S]diUTW-:4Ƕ#:|X8h( i>~^8 M!|+LnQLUkdCk=1kՂj3 #Rp6H:n$Tjk]яq Qd4<>{қֹ2K*K+;a'ᥦEVv9FY }AٚKGQ .Wܹxbߺ3ŗd%Hge5InPЬU5 nڣn=>ub:qLS@[3'_[x>g/Z[H hu~.:ו\m(U'4>jA^~UpHw][|QI|}b{,&yhWhhꧨtx5d[h[x MrѩiBPUgUH-liaQAo 4f@c١KsۙȑJЊa"eu!z>$c;_=]s\ɋrfԈ@-E3<[|$؝(]6SLI yʋ RDb*$Y`;_޼fe-q#<[@w:SCM'u4׷7 I$`i8P,QF=Zn$x!~;KHz5cWщt1Vq-*cC(_ ea8!YJЅN7|49 IܹRf_f}4y~X7pAIo{=;  h3H16絎!2-4R \Gs )7hqwU\Ẕhcj$7^% ſ>r\*p2S.hκ`Esopw[Ĭ3 /H?H*<X)L__,^LEm+RbJeC䥝nD#?d cbUu9PyL/-IZc#sǙ*V[PiŬw\cu-$U2\T>P17%ȞrY=,FM Ӯ-.xy+4 rSh&mqʃMEơW#EC\rV*9x$mX1m۹,+DynZWJj: sxrxA >`!C獠S?Je=t51C\Q9gMq\1mL 7Pza\Txbb2~ȃSM{+N)Z /SO,v(3ၸujk `0"hݯNwKsaV+V!r="54uM˩4gV-ʙr 8<[XK k yd +WjE[Gy`K6dP^;9%A HJz`$# Z(Ekۈ9 >em^(P -GY O&hvp0qiiu{c L*]ى4MiLvH'>` |0јiÆ6t&*DUr6@HX,M[] X(+Ǹ5:Չ"hX=:e7`*S?,a)Q̒/Y$5AHT`g)RA=?}X҂g7hmH3J凒2 6t2 c#%10ʂ=HAU$AX R@k~,gJimfܺ•6MZ־^}1N3ت\l`k,rp`sc~xhdV@1x-ixt/4qƚu܂ Zm"R>ߪ*5"n iSO\hUV)_L09~cZr?XS\%1\PCvm_TWcVD}G._?AS#C-,>'эrђ>EE%HԼtul=/-nKm&_c^\ XpT b%Ix؏8+^k?ԚPaG ZE"[ [()U c@OS_U*g#q>X%@'pH -A?-b D\BcGPL +eo*2uһA֚ې{U+Bv2%еAZ2j3Ep Z_iJcZ\vm>Zc5#=r㑱&+I/Y%!ݤʚfSj8Yn+B#̇tjĻ@gVM(,ImOuĠi,Jv\V~?AALkxʬXЏH#,mŧ[H9a"MX ʸKd$L-hlCJrHZm_vm8 #ȋY!!ø$> J%Em5!kkZD H CkSY2_`wv A7Nl&`O$mkZnvP}q2XNV9 m|\Ygai&1Jd6c\S5SS,z5ʴ38;@#BwZ1@#?1FkQM0r5ǬL+(€G$tiZS**TS]G^GU҇ibU|vu5^\ 0W5·S68҄ztĝ7m4fKlx8^n3Ĝ&\|ۏp h[x?h8mД8D6ﶻo7 ݎjI#cF@f,y>N[3I#ݞ16:Va9k-4PmֱlOT qu^~@[+v$1)*)"q/tW/Z5 Z|U[QªۡAjF] (Z9kScHNdnWk(Vdtی8VrCmNSFe?VPm|țs6LH2iaz=3I$H\HLP&suκblob5ۖXTEYa^.AMj6(zYq~jwWs#[S!bV_2|ZN!d9Hҟ|J*hl2 ̚I6)g7iNBi?߹yL=p9*6֕1g '?#u>֬ԠŏuiuX![N#?:WoܪYKm} :. \C'jr:[ \OSOPG눠MLL<:@iUeAS\IpH906tMSB<1\[4[\ɐ$ͭ>qVRVa h  Bi]q/q[Tpb)u: (n,:eP]@HIҌݻt鋮&hJEA$DQ+qT9c\+?墮j,scJa "yGjD=}=D}Pq.8-S@˙RrɆat5\40r<| $Zզ -3y][2,]Mo@99>=e}+M ծ-I^J k(UwQwZˡşd7,e܍W|I`"/h-`{D*c."-\ZՂy1]InR(աnYRtjSAʹVjS݅$Lk8 |2͒O6Z yu)@z8ҵJHvVpwSt:^(4 $&e$r(hH L\Cfo_1n:X1}ߒ߄N2pkw7Y3ޥ}*P닓y|\T0T)QQֻm\-qܥ̀J4ڽQ-{ihg#_Q$*ӇKnV@+(wŞW-r9Һ,z4/u E3 Kz3,ߍt<AUf-x}shgoAv);eq3|6?wkn7oo#^$`M5"fʻj##BqeܶS/s܈GTg w$; D"Qu ]]đqRR{yWdA%"ЩX ԂGERhqv'%7)5:N(΃ޣ>'v-goN h.AkfpcᤳچB*Dڤ[v͏A?&;^vp܇qrhK%z@B-xrNxt;E*W0hEs*yfuwEM># ܂m+I=iOJ!W}F#liqj?r #h*>VfAn() 4)*YCUU[%}j]gNߝ$IBc3gV H|JkMNaA(L1 r5МJm'x4r"GFXAxT2 iJܢ?b*w~TH F$i,hc $X,i0 s1Ej:M>Te9euCTq$1]GqDbs OLNf\>Ɵ{&0WV4RkOCTmZ~o<{~R"_(BSucqgڢG"[ŵ+H:Gm|()v;4yP\HBFfKPMh LC*q3pwZePVgp[rYu iSJh1S?V4)OҸiT4MޝScBܫ8]I$PJ*~t5k{ҫޠA5~c%˟[ beBkrr #7>۠mXn*|dž$ti6N.ڐut .HYv255\E1(hOV҃^ Ygejvcua,JY[jZf5kL3 @'[^⌨J2&U 5׮XߧMQ>SBH8܊kMI9 ϧ2\Mk UZbeJrj< Xj5)kXi+LgզZ~>L zp <0 ?Luz-8̿ H"J}/p?Bӱ#s4K4K8r6kiofג,^HnܲHY" "T6UA#Ql/gpvn=£H)Zj3˴@X1piЪI9-A9\;V9cu'`U:nK;k;hy當QNT+ M_poYR5_47HS~3bχKoq ܈tjkjMXCo,/!c%Dh^= |h2vOa"$|`?!n=a<[we_pb]['uFc;7!_"*Vұ(ީJ ?o{\IeyuSf-fdZ$w Jsp Wu5?X dzuu-cBPkz)D"RtT 2 V΄8SlRAڋ{efrkk?=*jsB+̨/a ۙtOLƈcfF .GnƄfik(ZBw+AiHMI_rU#,gƃ/bUbʾGvRR"{7y]6"FSPr@(_ZbT#\U5瀠I1@A0u?NkFΠ`W6:?~62ʴ8 0j*4=|V$f+*>Zg۸8fXe\W(?INo3#.i8nMȣH^⏲e.$׋7v ~ {ZOfDJwK^vR]o$:L'|i\qۜDIgs\X-L-xpzkZf)RT"X5' a:o[K- жq@sv٦ U\m,m ^\ڔcDAA1?tvinmRqdbFQ5 c50a̴ а*8HKM8 zc%\w#ܷh= $&c;{nx[sjkd&~Y*ki=Fy#Ri*\%VQH_Qf@ Q!8ҵ{glQݛ27hbGh%:GuHV--.^˰DfU>tAnxhif{b@ƥcv;$>ͭP3J*Mkc5FuE#FEtݣk\\_*, REWlqow֏oqcIuk;.G"PȃԌ2l-)[=БE%V?IVU,^ K?hCS8QQ@%Y O} ekujOы?x ޔ IVl,C[UUG(a#RH,Mj>Ik_~#+R\<*-ݵ!UXʸuY/}9uHј5na!;QB 4 ?D"Xzqv}Y_klEI$̀Ȭႀ( =qo$+~%+s,&J1C}uedfշp hr`hqor;"f2bW0*ՀSFf; h1}V?ݳNN9*|72,6(~g4F2f\n'.c>F9 Ҧx!sANѳ*R#چZ떝UQ<@b~&B8=.SM< V;v۔mR^K8--4.r hNy]#K4[ {Jo*4Reڼjv ^J~xGjo9b[;yai/^9YH$Q2R*yILǽc+aqͤWp֕Q #V,믏*SS1iSさFRb#LS: #:`VꏁTt늝GӊgT뀤lSrNH NJ:P cjPӍ }Oٍm\u?gL,wQ$ialq\q}ᵁ",< QZyW?y9j?O݀ƛX\/0R~?-+ 7(Fe4^GՈhZJytN#e;F\F1*Fu4 IBٶ^817Z1!~L,A4*Y A: OV_Hx3,Kg^ `!Z (n2߲,U"T @~9AK}ƥ^ZռƝp|VU9eNǿhjGM®U&@})gE)@ !F 7=XF**0N+,,5ع!;PiL0KDnwUd^0dբ>&X$qZd\R&zfKj*?VJzt8-fbƹ}Y}0jPk}8U܉ !j3,iګ0l{VEfZJ ӂsI޼=:b$Up1Y>WOӆǩI,g#Le46|eדHPJb9{V`r/cqI ޱDʂˏo?_q\i%Di.l(P?[rξݷq\Dxx+{+)2I4(6ꏕ ~־O76,8vKJeƯOiwP^qE =$s@*b۵-n}wG@V Dpn.%$Hr!UtV?͔Y{n SR vۛ2H̑\5ȕ;RŘe-8拉7 bx㎋ beB+hn\zU)u,Z.b;3Blo! KLV)451Kx%} EJVJ+*^?r+bUQHc^dog>3fRYP*((@KQj 0n"$324T+FH"97j Lb^Iv,/9cV)NJha\g\M/g*q̖q_FpgFm#Y @ _\9ݑ Ŵ .6ͤGׅM{Fw5.XRvB=!8o?rJs-G+7ۏHh#CR 'ٙ94eUYCSTS%(U(av$k[Fmj$Uv|qvӤ\()ie_oWl'3 r8djuW}I!GfAZ;Ѵ.ܑ_{jDy PWn`ъk`OS1G>|B*r 4㯆2LS P yۥu~?HLd)@!Jc=pjkt+J>t#%8$ 71 F6\1 pP8u'VT6mϰ6T@<0Qpʀ X0iʤSCL2% vSL>I 1{_?ׅ*4Vv5*1q@H>cC"b$7n[ biAZ3 743 (H1*C 4 eE@`%$+jA:E2Fk#HCU-\Eq$0  z) đr1bH/›jԓ֔v=9x+L'm7u%e9YKcpIaY?Rh§izZJJ% 3\xQ PwhBftS1ҸCjF<hX"Jy\9Z9af*E I"SeXT(ZF5j>;{r"Qx"MH# `[w7v]α|mx` ‡Ky8=뚻t*m*v'cvȲ2![5m ssO{HدF(b9lnh\^ԜGfі0Y*ɪFl+*H$W(TTK@w23NOSc^I R( A6,mB {$]ڤTSBŲ% 5* ْpK %+ܐT3-ՋNVOoFq${4S.{fCVS;-.Zi'<>5ڴs0@dkcTt5ҸSn/&\R_mLP վB37D@D>v)z;/KdCЃ@QVj W#cVS#T,j vTf>ZPt-%ǸZ) }!F-|)LunT6Cq/ X2h-j>jPaGoXfhBҙ1Z)+!wS2Ǻi 9"5=bVr鞧 -\К*etQdy}8f(w S]<7i%7vY%UJK!X׫ay۔SkӻY# s+5 Jf.9m;w jURe:+1t>6{d n"O`,сeFȑmiklD3}Y@݀+ Fxn򵼹*#;QZQd]N{_1M-O,18ۺ^Bqn~^0YXSCk9.oV9odjJ26|{msu hP;>T֜1~$ Nu,u oW/OЏ=F'N/.c!{Uuz,6nEK|=Fpל"j\ij#M,v-e.gŭ0Im`cbSId,c JxYv<=z*T yTc\GyOv$g? D˂XPjI[$1rʥ/9"'[r2~eڌ;r|PJꅢ9e}ۘjay.62oc[]ھJgS=mKiVV#ع*7,]܈ҪAR\\pZȱ/qIa L*|A{?"OiJŋ4Tj2՟7/uk}w3ɷy1*dZ5kQ\O{|h~XD #I>ԅF'{I9wNJi|$bV j Xx8+[kw I HkQʝPs177!d쐥2yWwi($j@jpOȨҁt5]|ewؔTL,ƘkJ_~Cu^BəW=GLF, ܑNx^納(HiBSx㑴Պ[="شhw@ub9e2"G,TZ5oyYoXJ}|Χ6f8%IQ`-hu\oZҘi 0p q}:DvqY=H"2)Z`>fՠ3n8[y/\s Ք.][fd4ʽK[cE4ʒ[gi DTuWS#SylEj+xTˀ.s;GC^K\K=qrK'MT?#ZO\]qߚJ5~j hSQ֧QXh:PGZIrr94pP)Gu}!b rݼQry Wv,YB6 J:^^ v@pʴFTcM) 98N@1:2`ղOim/U v}Ɨu7&ejǒnVGD[1.A,";Wnn 1mkN.ͅQGy!u6LfUX׍28KC|I;AyZI5W6VM^B>Ǿ-n 3V?(%Y(|qd=6ȡ8ƿ1f!˕LU\8T02njxM)Zd4ǧS6 kq+mTdNYb!T)jOO{wwC{2TGUx. FxzHt눥^o{Q?B} LjFķrID^Y&*V'P5aK򂼏(Xr1m$nV.Ab]7ͷ݇ 8ŅyE$eIkTK+azg MmRJPe fd<sKFYpC!biB@^;SupƞoJ L<[y#)-.3*ڹ8nxo,^Z- 77D bIymXTg9ҫ` ~iKQ?Sw{%dj+S:-8f$%[ؙCE:V0Ҙ>)x.2R9)?5Grη;FF m#29)94Be3[c܄\}]BKwaDnD%d$(_N93\ڛOreY%BTL/=% ,-[W jbRXk!Br&>l@(Sh: S!B+$MjC4xL 2;j9R,Bූߞ.ϴE ԭY7 qBX[{ؽpgDQ;%Rh\Yp;F?i#AzH hW5y *n G xPrr}4>eu"W ul2G fV(S R8.o46(RZ\.oUas-o...o%{K9ixjP} i-B Yx߸RVA>MbKs݃a!Bn(Y½r醼'~kf<ɭEqcsyc_QZ%Wms[>~L!bY ,v~ w <{yAUR3Nt9rRr\?TIm[Cusf- ("bTđJ\^q|2\FfhmWW`X);iƨ\\NucMTkeqNEuURHC딀2ƕW=k{ͫB68 mjk+ZM1PM>+CZ,Ov,'+޼a5v_Go.Qį!6=; q~AswW6[,QȊY`lӡ>]?09.LwmyW=!^GUZR^P栒FOU6Hjmku*t\[(AcC7D >h*z,m.HCN "ArڨmmPi҆Lh09nM NBȡX#*[BOe$bͭVSL{T;"h3?:d1L$f}Cf`_*˖tr4ĒF)U9˝Oi3혂{Qz֣6q`G,v479*Tj`XIx$ר4p,]͝@<+2V'/< >W">ffǎPwR.dDI_S[{y'kamIx^w2AEG 3q8~G2%stFgcDB`0w7ww͸uj5on?앆c~2'%3{nڻb*ʏY/%AipEz[[C{&껖E[;mdkmyqcBY)vCS+'`,.)W[GݧZ5fgOj sn6r G/ xXڣ۫mk9+eo<ַ01D q޻P/rn4iuy@uHBEF XܕM%ͥcKQN? G l,P k˞Ba]ATP=: +wWwr/M,,Sfanyyۧг:uƣdDΜӗmԞRl40Cq|zr&|p]-$%?@o^u DFqH9.∁[]>hN+o}dd?0?|ʨ>rѾhpxGCVixSktmud"bvRqu_?HIxqRAͮ7p}ȣ*B \S -"v,Em hҠ*-ݼO$C{í@ۊf:ŭs𖗭dH͜Я2*P+' Z]<Yr`wGI5խ 1ɼm5kdCPݘfQ׫P !xnUݺ /A1V|n]%(8br;ڊ8.Vh^X}rLdH;}N^P#@rsZqW\N 2fМS爯{8n#I25B&JlVA6\i3w6퓹r , RڵŽX6dۻY}T.8J3im'{R<LU5=I>g:b~'rͣ!5fy?w)ojMGyb."IZOq_EqOk$y;m:5Nh̅ByaK)OP,r9d&$%JQNMHyfPDPR'!j)AԠʠ@?:bxHlRߑc_L~"EGomb-X[_/]AڼSiKyⲻ*G&VHI ؽqvyZsClV/eJYJz6Zp[ۋ8#v!$hޒ՝qE۸-^夈<5K  [9QB-ٳn2^Op+i<{uve}:ƜwD|E܌ LMYB ĝc=Rq_pŤ}rX"ȋ,+n}OkN.3{y^^ _"G(ٛZq??֍s|_1} 7W9Vvx Fx&Tv!dc>zהoR,jxOv-wyqGotnodQhdщeC%Bn]?"X9Homn[嶖ɔ\-Ü!yOaaspe_\DCLjɚP%U^S cGE9LTY錪P|q?V6 hA/j:S)u4JxǺvӕGnU&l9Ή?RIZt/QZS\9aUaR5:}8CS#O1V?M?냳 W r+ +S5T-Im_-!vFz5Zˮ 51"Enc&q%Q]::#mVrJ) &!}B_3<-ljYX)4Q+և\-a 9 ǡ:aMSy@N1j)Z զ1ȥ3Rj:xa8Jp._0AiAO D4$i_`f V6bo?9zc޺9QQt,<_ 3 Du?VЮFzw'YJn&cSEԩ<_Fm9{˛d7\+MsH#[[IK`KIsVGᙸ5.nbs0,Q^u 3FFSaQcv6,%2#Ѝ\6Vzً/I{0!" !5HbwMDPw'!zc2 n]$Hdh=XK%rVcEPsQ N# ńCVp9u Rʣ.89f[HH&~ڤ:`}i=ⴱ5۴JG_,lR:W_K^CIgy&R\6,7 }r|%n:6YnmJ -!H);n5v^pKtAQk"MEB E}K_SY8niUaf75wm)F$QҜ-Ή6v|}9滙7nEozq@b.=S,Q~q8!~g#͞<pj`4V xF6x#A@r?c٨ٞ3ʌW<'u_Q`'ǰg|Ƥ$q3זB8Ի3,hI4Ľ2"y@Lrr ·#i1?:/'t9a_q=cfB*R!EcCw!+m'n_y:ZG|*LUM)};YyuM-c#K3L33$<Ť|ՊD$AmtCf*$b~nRֆHC3bd]EXE~u<\#P3/{{mmq` *4D*= #5#l<qeM<8zt|N6<*HX Cw _݌鞧Q|vp <Gt*xczH=\4rU*i<kiQ5]>1NnArg_ 71'~>O*H0\#J_bL}bVt5F&6#C%_r'd3RW{1 Wa6 v@+h`f2Ol(;g>[+.EM=X+vͺTl%MrmqܤٹkhC23*1/4NՖCDU}F&6p{gEz:VL*"F_d =T[;lm$wDQHKT˴2LAs7Gw+0F.vUDYdTg I( jnMʸYہm}^ 6Դpm(R`3!hІ}( mcvT@XI_R8א6em3!F ;o؇$fV #w&C\qr%B}pG0@5.rZHuww;e3l<ͻr%h]+=k@! eeͽ]R׊73kT>8bO]0&lrߓߝ d]lwPmvn.WI#ri4!v4+̯︯˫.ݼZe2qhdG+!`4r#GT-ym#=S4z1V#dZLpw[.Ls=U6GP+#N <}4ߏJ5wGOw'|2 5a5Mɮ8>=%Ks~1aT;nTݮX7rp}eؠ\|Kk*2Z*҆/dww|7G":]@Z;y}ͫ,jJCG?\7;x{s)ܝKj}Ln+|˙y;# Tbm#Tmj*O'9';0+^BWQSQjasY6<I~`7Vqċ*E[Xu[Xc]­g奔a;-Nl %V6HR޼q?]67,xȞd5Я)"H;sߚ#p (5Zn_ႂ4s (1N&@  HO\l\AGEE)k%VZZcܓp$QZt>xڋBpE6drW 39%r gAZP/npJ5)W:< AtxS;mm+Q53gIU#@:N6[jFܦeSPuLBcw6Na|OycDޣ!5SAN^\-E2V:uc6@Iv`hR/NNU?v5C\~6zudBiJN4ΧC!,%+_V,VjΠSS@'"z }8/w'%)I,|Dy;:U&Y&KUq*Io'ڊ-FRQ.R4=Mq 6rC@EKc_khT v8SI-&k{ua,{_dddb>3ChRqhnXK!A@IIBZI= !eq iz–6#E Rzm;ix=) yKv? jU~]AC8%F XʴٷLP1gnvBL\Ht#y(Ԑ1!{58ءR?r_jc{NBK$xIQ', U4dܹV>*A>W58ָ*q+ܱNHQG_%P<+o21Vy" ^ cEӃ3xמk}aJy`OHGU ,IV8ߓ'守 )BDb>F5o11&AE#|bOˮ&+8cH̉4) 7a"QOD2p4*%\'{d7l6Ǒ-mbY3+F]RG+0|r騐M*ʼn\&d8fOy5Cmx*<gYF=Y'\#=sp- `8V=+*Zjq W*71O ʚoJѳ?ĎΠgaPk׮^8Հ +/WeB:[|ʿ(4$MstG)Pj#3Cv*҂p2ۻ)Gs ,Ԩʸ#BҢ6s9$Skyw+)c߆ykD:#7.;2%6]>;*=//s^&phj/#W0c#({iJ1cLk?` RGL7Ρ뉻++W?gm~XeHHm`p{ǗׇDSlťZUYTqT/8$6PD h=1Z\Z$PU)B(qp\S-6~&\R?T˹$edƆ4WX(II%ZߴwsJaғ I`s\לs^:\\o;f&'ڠ;GGzԊxm1!Aܠ&18-fpeQ!xPHJ֣#}r g+6 YƤ=ݶ\pp^~jC[U)H>ޘ( @ǶI&ш?s)0AqCj)RB1ݴt替;~w7}֜P{hb*X>_d5 5F~0.3V:tF'^m,90ͥH|F뻭^N='> Bd.%I@//-]CүVZݚDJ,r][p$b׍+$lD~ܙR)K*!hV' rX$f =e Z2ޗFPoC I𼲴ÒSrF-^@"l٥RLLCHb^z~c1Jl^lR!KW,j /o8kHG%2,t z S,.ՌU؆B?+ڈmgyzs@tyITRM_Pi QBLŷ!xKI+ L[cCksoJH1:YXGrR ytd45>)ҸIb緻m^ҢqdkwKCvUtAz왹Ό9DF" )<'[#٦C*eӌ85N=Yzt(qCmqQp3gw+q'ysSsƸep9^5yaajDc[P\Fr[/".9-F $sy28:;kiH["R8"oى+Nul8.GXĝ(Y݂DPvk^snK~JQw-ռ숕724AŽ,rC2f7Iۓc k@6>ґ8UV_\r(fO]z_\GZ\\`aL =Gͪ|J8 ]GCv֧W3:n0^? *E+y_*ĜG~xu"TD R}&a52]iS$aNN68f*A*r>~##|3)ᇑIM~A?`z}Ayt LL}Ͻv6Գhʧ_ 6_iTzPPLsr7ۼi @%r}Iz(o&jO 3R zޭ).Eu's$HA Xޅ @L\?H҅j2pIJjCC[¢IA?rf]+#(HV:b1k _ne%V垸ey D{a]᧙\M{cwq12l,)s̎H>-fU]jާv5c9y/P_|sC\TE~ɮc]PwqF%RbS]ާڣ1#\Ē8̑R HHPv@wXfԓRS!WaMmPq72fDDnk:煎ET02 ǷZ5j<|pS<+]58,Is!@ $lr=J8NxxW񡱑w}3H[x=ѳ܏i_qMu@w )Y#MŞWRW=c]/ `L`ŹYlMqip u|ۋ{`m[E13g;c^7Ho$2($ڣ28{[^r˔C FR]dy wm]p̑͝',VY\L-bQMEPYM޼lw0Xt;UB͂ϋbF(FcP "j1/k~S?'ps|MuYy=e] I1.aV+w?9i1I[ [K5pO5voΖv{ߗmb77Rh"$hnVXoOxwMCy6ծ-&z)hJ8O\w/=l8C`b Z[XU+VP#~w~osݧȜd$\3VHt -OpEGVNOkq{7#%U] $y,uB7=Oۼ{rP[YvV5]cfXㅤ\w,{֖_ S}7~@X,G_̦ከmhn F6΀`U}#O|zc:ۇP::KNK828C-5ܱ#q$V%֐qWɸTT{UZЍ0}y®]2i^ӵK`2{RS% pIB R˦(F xS C R?]S_V(iU UE|5S\¬jBhfӯѦ?URZ_ 0R=OJQ<#RhNh+=zBd@ 9JiǮKuw rJYtDZd^HT R}4ε~0Zg>^I p@PZEu:Od}op]G AjB֦E;( *2[F'%x B$2)3TELel a8 p[0bBFXD(v\R{$Hbgf߽քJv5,b~>d+9X-ПݶP;T)Nfӷxh:#v|~,F֣bSh1?/Ogw h5fc{nږ"#{2r<>B;d~1s6ޖi6vYg|8eccp $n țEc3܂ҿwV'm)4=۷DkCE@F,S?V>e\ǝ>8i3qQ+_3qZ(?+cyuq7[->RcMqw.8?oy$K$P”L-grv%Ymp]։~_]wu͸иXf~W:`Sᖘ޺) +UI$\&cM)#z,ϭ156rgB@qS$fOʣ342Ku {n}JnJc-[<Ҹ-" dPHJ3Rpf#03V[d"s<|y$Inmy@m[s i\\wrx7{V԰cPVh c]ąyA}דi8뗟&c iv_ WrsYcq-)$4m qTueb iw /7\m7cpwVi v0[\r6a pX4 (JZKݖX9 [4 .cc8_Hp$xdm|l]"~hOJ]s-szROm;J& ]2n_v$qysxku%m^_I/B@ *)QGy߳8]B F',sܗ_;3 .Z*xom8)1Xc&nS`QJn왮[k=:Uŵ-udr[ DqY;GF+ncdwp!"jdqafsoq\BI]Y7[dz8>K̵(K.#eGg)Of+bUm{dbUQb.9N'e/scpYgiv/=F8vH\wox~uv\|~b\Ykus\k`]2Fs|\G+|>.K{^R)P^Gl? ܓ%dWo..{8#]Z9+8?[wBjPmܐ)brkg+؄+l[qM{wa-X{ q{sܭ$3§|k@H57c=a% ^QW祺$=+FxUS-Rx~nI `Yj<2ge>z i%56phj5Jצ)KfsHAk^.h1F֕ǪF29ǖ/}ݸp(nJ ?=&N:{@!")6[$O=}wm{ oihkXʃ$W=^q}ߝeڶwsIg_p7g {2ĩIHɡeхbea2k ˗oZ*M,@b7:cN#/?G4.$B}`j@B5?żS[xBeZ q(BFmJ4]d)ot;hwʕҿF dİ ݘʝk B)*AҊ4-CL*ARUTMMF6@ 'HQ*-6Nt?<7rIO=0ֹVm'?@FK n.?[I%dZšvǡf7EB{#!Rl0q7hۭ qq5.!fdypQ_Uuyȳ]X,.kD&$, y[ri=83U T{J{ʰHoe4KkmF+FYɑMh[PLLVP_I֥Oo6?ݬQWAa*Ѫ*A;pl.'+[˱eu -ɶ 6YC èco%g -polnSn䑭FiIbrݼ3IB*A {rSD}V[9;ں/x/vV3:z[[0yPi@rZa /mn=[hKp)cbNov|\(ФXF i(s1b>^T5o>O2qx!s1S*c)qcw'sܥoM5If?*"S%E=ip,xN؋kI!].o*v]jـd7ɬW]][z6}FV&{+D󜫘xbh@wx\.` _ oeJ-FؔcSܼ|=-a_%>t:SSASC r=pALPk)31vgGKQ$Гcsv}^^nD$[( ~{hS@Pٖ4c-9ii~@^ pQC$k^+ܺʞkZ:0Ajp~ Ty[mlbiy8E̳L qu[]Kec5E{X.9wE Q@*T`|t_\w/'e0Q*X Y(E痋ZAw|pMux+*\OoR;Tq d^=P,װq7rF#&$ʂٶmiYvsM{|,con2ȭ$I7J[[vG=?lA*^ [Y Ls'suO2Wvb(I#vQ.ܜO s7%ݼEUf[]g;|<*Wi3i'!{hڽ7W0L@8Ev[/r /ؕʭEAq1sE\|2*\ OujAk\Lx~;YY+Hd=N;ݽrf\ Jl+3yf!ZITU̜Ǥxs1]فRPHqWx>Z`ɷq# 0 Ԋх]zuPrmӑR|s57f ,i K{뻏ѭ,$%iJX,}r[qŇuGy{gwz 7Ȍj] Nߘ;J/o/M&J+lŘ`[6| QG;rmV6;澑+3VNd'I7-g6խcw14eUz]0cM܅Mf%=ХI}Sq\ʣ h '-:bn@Ī}I$0^*M3'L2\JqvUoEGMf|XmWT<ݴP*}ZTi !gZ>,p#4yW#,i$X<<a\*N/{_ ݎ9y0 nM3ŏgbN@t q[`dpr Uķ =Q6 3&xa'`Mtʛ񗌋kl`3Ȅ){ﱈpL|%I2V6CnH@#{~頨J.Yy mx@tATiJ*\92㕴 rx(V }wrZ 4|\А~=[K`\٨׉;ng+}=9ܺoB0 [O'n:KAeNzy ]^NPƨʨ{[%)J+64~ܿ/(O;jnxzRhI]Lޞ9"3*3T~U ղX^C5d`Co+s[6EhBӦ/ l&9)'P2 OAk!iaa}q$;y$V-(WEc{{F=\v&՝g:8)&s$W"K{P# B h7tw:ܜA[@ ,.QUF9X$vvmcg Pt,+,VxlVw@ M**/>20X9AMFtFj]1'bHy,ŭ2Y%`E%vNxnQIml RnK1>_48V;S\lPvL}~Pk ji_ʃ1YS\匶"4|+7[ToI88{ˋⰾ:{&JHZF^F?_$}L \IՒkR+fc8na柛2Y.Icr55+q)j G($`7 qyv-͌ʷ7}e8@#qq_?9ωlĶ^* ;8RZEQ`vy8 b]{!QEpan.l;Ko-$V R8a탟2x?ɮ-pRC6,5jZ)oA"@Aܼox{{kۈ{w-,WpZ7T;~93٩5V[5 Xsq"=!a${`"\Ltwnmq^4(4s,L К2>iaCWn/Zߊs;}!(e[of"ZRQq>D42S܈Q7)4j*28S¸|~XFASΟ zh3θ~n*_b GioKLLLa9V>;_Z$ JfUh38 9Y{EJRr֓>˗UƏl+$QDuݸq}ߜ◁EM2CaG1*/KIV>8!퉧Ѣk ;)-10y ,/}ǂkn߇ Umq-kl7snonv\7 ٲ$](3(V?^V' ~|=ϰHlC&DmkVB˰FQ2fUj71v\l=i qF}$o6Wd۸[^;-m"K41ĵXK>2d-l#xᤑ7 ~N Yg;)(xY[S#Gil}+PO*!$Jҋ@ ~+u%h#"帾@[&aZXnUjZ\Y@P -Y].rWf#*.EB:q3X0Uf)ҚSIJ!r$xXn2}ҙւ-/&rm :S\NF_?Y0 w25vœ"8g"75{ʳ-iZ{zUS%O욻A Idf[{#آmaz"\vq[^'Vq!eBr F쩈8nI%x#F5l@Ir;}Dled#&7>OsS5 i*@R1[s_voD5jշiGHݧ]5@ 7.3\߂^9`g%ԋI$UEY98kssj=hrU}\nB`tՁ#`ޘ.Wo΂Wl0Qe՟ gQC;̡f*NAw7C8{) \t~#cbh슜؊WquBPQ۲-r8zs<픨igfG=Vw3}X/Q.Х"1՝]ؖcq@jqF:8%TdqGZg:`}=<Jj@8(sFuYe@Ɵ\?2VjxhF U>Xa+Z 4׮u9?یޢ̭s?HbE'hWZu/aK"F)rpbo.9."u+9X-ؽ' af|4XP?\C{ߗO];[2E,oni$grMIk`5qoƎ]uI#9s>ʾ" B*iO<>Ȍim:#ə8,lJ*Ngo!,]~}͟ot~äQ vL ~ܕn,.2z@y+vݟagA_T! FϪIʁtc8`DbPʰiCSZkL'n٢~%H$\/"[d[2{ e@z|9π=NTEAF7oojniX~ky {mC {["V=$K;zҕ 6A]r){k,\3C1 nT- 7 pkcD'i8RfT4(C_NҰ[x0FJ+'i+ZFD ở ?əڈwGr/ OcmKVkJ188c BEQ(@($!b܍կ)'\4r7y+=_^Zyb̎䶚-Ϳkm,"k+<BM! 79Uk>oGwy;0% -"%mIV/ɭEk7-fAJn{{9{EKiU k˴x??wndO݊ rݳ('|,R_L`H6jzt8/mC".ZV;u|EV%h=ҽ1?g3o-3TIeD$ε .B,Z1=rJdu-ڪ+,x[^;{$]~$A$;\*(Zw~zrGov/jJ#a{눶y~fg?7|I3R0yv';Ǟ~ۖ㣂 e+ͥ-*jsw]Ig&͗I Ojir;%Bxox[!-}6sxD}svʍyl66m&!$u;~o{(>.ג97YM#o8:gF(QՉ*oK}]'jqѭ!\N$q2Gkp"b#i=AqXg;DƆ7U$Y#͆ ro%ŗ^2A$Dzx#ff1G*”ZbNH᷹m$X[ѤSZ֔ /bvo+}'u; =4 JwjT<@m&(i(T@΃!GMx ƾzc`jN$14B jqug9 #gC8d* zk]p 5jNqseߗy[rý%fhT!Dl!Uٗ xrW=8+9n&hM{Cq!6gZ (m; 0V1(t{ߵ9$#>rI l `Tצ'H nR;K7 6q&6+hN8+;Y8n/9\`grѸ8 E>l&5]r˸`oi!q"uGQ{7zTA:rvks;E,oQK0jm%nnYed/ږhEsK 59v񟓝V-8s~̍F@q {4<EXz6SU-4')㻐 .*IbfRX.yln:W!BUєj5# ͪq|lay+̲0.Ҍ;HG'Zv#z} qeP'%‘qCX:`=-Z|V T(_`JFKZXOb9̊~8)qR@;TSM|1P䝹 "Z~fu?@jHxm5 =]HרQ4-Pwk_ɼx{RՍ)S&bkiYMLЃ۪aaZxUe2Zy sĜw*AI$H+0)$2+t;) AQzS]X5w70FF (QjK*(y8h%gM)dF[ҌiC,-ȎCWڌr2<)-{Ǘn; @zF)dZIvW,|В,)fpĔ32)L]0"Iqo)TejC{C%-%ıhXH ~a,Kwjq)&ɐxK]g-.^FcB֘o"uu\M_[SieڏqTDڞ>f'N}P_ xY:1*tƸ,}kYe*3)3jG1x Vu$aO$ɢf^ٺe(C}i>EgSUcn/ `Ҋ}F`q{[㾵dT`W<wvJ۫դNS۶V`-ݿo#UQEnCӋ^/{u+<3KWGoe7XXȀ)eq=pUUCFڂ4ŭcqWpr)l_FٟR*=LTOBk^~8|w) D sWF2`/+pWB/8s/ d۳ $n3Aے6[g_j&/{K׹Y`-%p?oLQV}!ko_GG,vv+Mwr2(֬Udj "q=o,ӽ+i(o)@fnnZ6`Cr EQҘy[dE %#ܤVqeKnnQmk+k(M jjJh3 ۖX})RiL9NnefH{1B) pθC5 !.r3R Gq}7*)b41Isr,`( >!'՘9cssQ* P3(4=񟖼|85SrTಯhٵÈmmmtU|IՍIp SS74uP}x*<2'L'F( O { @QPJ: 1wŵem%ZV҆gs\lvm[X\ +~WD!%R7,{ 6޳帱-8r*nK+ *idu-Y~ %.X[Gj7A3yv 98@wD +l{]5/,$:,,ĎJH}DŽ Wquen-6vK"͢1w=ak%ŤV|mІrz[pjLzZJbị."WM!)qq ]{4"^IzzVv4!M2kwLs]M=3_"by!bj6N/+ nO*r\Mʏ=;(vs ;Wk/n6)I,ͷ?Ni_m;|综wN G:PMk縺듃d^3k~(iQ@y^LJCQ~"m.\=95v?66;0keM?BH8c H"3!6AF;Ö+[[ 9M6rJUx_s3[ng)MGYY ,˺1H3|"դZr"v>T]o#.ҶK2ق%U֦/?Ⅾ?um$*-QF1=06J# Pz`;Ϧ=mC^ENC<5@u+H5<# =z8&F F^p!Ѡʶ"Lrm{aMF,-yyXm;Il &MmTn3ѸeS.-,&3-sB, KR-)nbQp؛yv3fs Gv'_Wq=qKoƬ\{Jm8[8l{H}Bӏk]Pwz㋶;#֖L\;((~}Lj8.^B~'rO*A5F-="6=%w0ȍ0ڭ-W7qPxJ*D 3=ױ;w%xQ"[gbm]\()-$2㙹 ȸ"ƱъzZ72V_ ZNayʻjdM~d[KqsqLڻeKe9@ *XiZ @52qVU (aA5"~D=BLʊ+FaLw < ly@di:: Ιaw# Q %u\}x +f3:>F0 Tϭ:K3P] ު_,$06StS9?ӄF.@f3΄Z}Χ?e4P-D"BzWkh71wB1#.+:6dЯ.k= 9S~кN'BkO+A!#+U&˽xG@S{džrRRU_R&1l\SYpѕ $9ԝӧ%Jʷܚ{np` gVj֗K\*PbeEsfS[^XP=Ȃ &TRn8\ n90,䳑+֙q׶ynPYmlY\YDKA-]0n!^/-`}|I 1Ը k/ps#kWX᠆D4=0U I/e.8T~^we@s! #v|154MT!ФMXļ_~ShIP~cUPL}1S9Qt`;l#q=3~Tn7NDqLJ V;fX. Mgܾ5Ie'0҃$#*r=rK+& rz\( mG\: o@Wd3(ʵA'#¸LmV(M2^#dzIe{Զ+q%EKBFZ &6!j s7=ĿHz=-2G5!=p?08㿻qt`yhH$٫|ד.e-YgQdVmE*F-n:ϒȎ`n줂DRI??D_H+r\Din2'2';m؀h|s-%Ii #6剸n 'ng іF$++qЬΊBvT,>dfMk+g2FɭL2+B7vAnLỶNfeZG"F^F"!6,>l~.bv lǪsHI-7=KaŪ42rPrhm48HRqY[BQ ڑ-کM> m4^S׆g4~97 P 4g,n$4>GlOۍeAOrʕb[.M!)Ȍ(UՁVR2 \s?ߛ1&XxA9/!w)f5*Z8}ۊ{qFT/uQS3svhx)Gն3n(%khyYn*7#K k" aro}FM!pNN*M)Ҙ{n>ӏ$ZGd`*xkf~-8 Z4Qqqp e?\NR=Q3!GܜŠ<4XwJe18^Qyf>ᆲGz4$pT*:y? Nj˹Um;Э*.yuJC\o̻{)ǀoxCiE]^:zVbP;\12?{q#n.jjx`yr瓴xXhcIٚ!@R玺8;Q1M2sDww KIt ,XۛK>;hs*Ո,,9;_璶#[O՜1Ii"F5{ .ރm-G{{nXo$I%_B٪pn{߅7,m۠wŇnlwsn@ 3GMJcG2׉apTY*uތǷ9*7F~X1,h\WZSWi( ZcvngL_?,*II wn )9 Vke Nu*~I)rvJ6Ƕ*O 6FSxք/ njAAq4WDlI5ЌYd3JL3ǵ̴)ST*]p36Mhu8w$g0櫺 JГJ`] #喹ycoppu#3smWppA6MlNqjeXV^ܰ4}{ٰ" |p؃]Rz0 `j)Pg \z?M~tZP '!$V)yfAHdq7Ù',o`U"FF/>ޖ'g@n$q!2 \wVYvK؅*ᬬ֌:`ZqsdCTIp"\\&_fN_s(бC;1oȧȑ?P/t5 d-yn͑+FmmjO-pxD4gL[Kk@ĻާY-_4X-gK\ܯžxН0u>nwG \krTK>|uCYF27M1(  qwGua۶wɺv t1zБ^ہ,mfY_!Б|5W}R5$V1rN֋"XfN+XјѫĈ`Կ9*T2zUht -u:kჷ%:1K\:i$ PIJ7f 8Q$wHJ$(VT N'e2]L<\SVvrc_rļ$޳Y֧p;O2&pܿt]?tcK<ր@Br#؍DVes{9k>. gOϦ%sb_;_s7`~;@r3ؠ %jۚ>\P瞣\:OIgצ 9FOzg4ҵx)ʘ i)PT R\)|11X'IOd*0*}ur9tmxǷ9HU*1dx%1K,jߨ'N$4Q& [A 9y'a Y!Ȁԕ C:b˹y",Ѐ%S,aw  ׺73rglSC7rLn%)#Qr6sIavjPʹf~zV \ǹy7*DPnM\34ybg\1c,SLg8QxǤze).x:ukR1F5Bִ9P42=G]I6)Y`K3@Iļ_5Q[7)0iXPBCE"Kh2LYXd=sŏjڋco ^(35ˊP9'=e,q>%el2}ڭVbA!NJ{m\ɹ0 HorꙦC,K/;Y㰃1*b=F79 ~8n,+k::( ^MA Q\^ڷcSO&T#"4{Aeej$kǵVH8RF[5, O-$&4TRǪE*QAcY Imo1Ee0 4u'ZDtPM95$|Jkfb~'ږFʀ"{2$kZ֞X &wfAfr#mNt$s>" ⍁$*~UxwI=tK-$ө5&J?.aqEKRoiڤ" 'jCdPE*JaTM5@; :ViTxl4 hW*͍ eaLˮ+ιR;|Ӹ&-&eZ[K$AY֠bұ\w5"r=/ _)fU*v%MiwWOǷ/#l5\,񍺍WN8bNFK[#/3l*bhP#q'G9v7]Vigr[ҴL%3nu-1s\_s[7 y(qJ;+427WsD~ѷO/ؽQ[Y -kLQ5h8o%)kg,kCi噐5Bl r>FoⱰa]ngvYRvYwgrr'!}JAjH cәҘ6N]p@ҺteHs2IDM@|Iˮ8 {_udȵHɁCwTi-BܷFįBqsCIub220b8K}Oe B$m"Ҩ cQ\EemIlIξ:㒵?!ywm*Zn?Mt^n=l,,ɍ 64I'-4ٜwp]e@e *"}z$S*߄#[n6E8QB*4 Ձ( HMwtj? ']Hxeed&8?rluŴ߅^|b n7d>_cT75as$5Rd#N{q3O)C7V?A65V(2AU:t9 ~~2X(zUԀ+5 '/jF^Xy) Z>rw-?1n'N٧/\b&$m0g}$ q'g{{!cI]QZ_iUv&ay Dhm ưĖ)JgCn%[,Vy$Ah XKyd2nS%jx녶H"n#5f+:뽯. X)gz76)!` +{9qxwb/iƙS,e2 58~m5L Ach۞gJ u9 S< 58ٻ!Z'u-wҫꖆ3[o8u<\T}%ez.Dc,GtЛ-ҫ0j@:༄ 4$Q"0#o0=n.u1:މ:,+*g`d(@Sv]@o _z2*\dI&X`Zf4j MI/#H'Ui7B;71WW&N㼷I&A?AOB ǩ٘..(9 DvR8¥UԢK[c_GT(H\G/5^9H( X1FۍuUs@{25 ㈸>;xd&$*uaf{'UgT֢b>d/"kv"tH.&SsPڞa!_zkonvjZ\ d\0]w:A5#1V>72\?Jc"DB*0dm)9}xڧ\z&p6ԃ኏xľhMQ 0;XVKq3c~!&0F.[v@˻QpݼKÿY!@4Puŧ/C+ݼ]j誧Q 8R[n6Y`~Y6@ skL_iAux%`9$Z1q!M<1W^kSxPk#˻$c%!!5R^?m 5Ր=r*AV-8>s?DW)e`SizP_3{524퓲{gA0x@ƲƠu'B!%Kwf)VZ5FXw52N^3xeB[b,{,+q9c*}x)S|DNcFg46( P< iU1]TR2>5Zdp(3đ&.U+'#D'!H'?צ=aRwnuʻ}>Yu3R@g\ Aytק=:ڦV R*SJ1}s )ökx=0;;@p&ňԙD@XYdD!`fŽX*lASOzHcE$j`sܷVpy]ۜy<*"dX6" PDP*(T Pt=m_QWPPMr,z@tXG\mVe\QtNG}=q O\zy N6JiҔ8x ֊A9H!-Z;_MRLE޳B7 }laӤ{'b)(^R]@3|m[2a"0 Tdq.;0:U Ԡ$eiRٹ9'-ڠWrBTgq=R{pyJaL'H.nHJd0ݴFmԎHف <(OՌFO,fbS8F+\`ጇӀ[Lm'LlR)_)?Jp*j\_wo|q|EO=P:,j*;h@aBwDgANZN^}<r=w$5XI\g)'Zzkl%єB rjcr2_,GKx׊T&0pĽ瑵,i`Uz}؁xhw(#*75Њa,(ޗQJ-1y!n`n,<"ބ T˻xyQ+x/-]mG`{3Bߧ>xݼ#Dw\#+SWԞG<5v㸸!#huX:$Rȷ00{ +IBmNs14-.n"I6U"$5.jT(.ɺB6O^6ÉSk-1hkdeT$HLOݓi-D"(1)_j 2BƘ;sN*F{BӐy&1}O# jpWqd1C v3061KTvC=/dHmPһ.%Ȃ+LI8oc=r@KkG ޫU،G rE4R "1x!-Kmp;WnkRXcǬ{bߖVx-lfMwo* 5|v'G:\Xw}OmiOP"ꁁ}Ol=aM*#W|N"?:XKzb$h?M2iKG] v%rܩ7 1Pi̜4RAp:=#C@r5?V+Pn5Sᦸ*-S_1Hۘ~R21Nt_]D`tRvqZq\:c`͍2ğ MwuwWLcWSn"$u/|w'ii}EsM,y vjIp\Bˎ~ܗmorcB7*zTGVN6ÚoXs\;c塖FFIm~Bb>Fmg "xިҍړhS\'qqP?d}sͦbnwixX̰ٷ"Nϙ[vEu; ͲW<^g#H4CݓZqqv=Ⱥ1M$h>_q([/nxF_S*|UOmr\K%oԵŗ kڭq{XIam%(M>yet%i PlS"$ʬn` {HO//qRrVQca rhJU|[v/} ɽJH0S+{&K;i,خw479ZE8?y/15û@ќalj;G^:KQڒ5K: R7)mN># Q*0chI*]'>`놩 TZWB@鍺X-JZ {jkM\=>_5ׂ( _|0"jT|29~ݺ ncQj+\xhdiRbU5V$aHcy0Ep4V阥M<4ȍH-k$Sh_HJV֣Z Kj7L 醸3Ed]i\0K_l kR;[>]p*DsMaaF !4ܹ j2~9W\K2(P/Qg>1I'C H=N++VF+U}W uĖQcIB V;DhYAuL3Jnȋ_NdVqQ xTlnCDBk$g@eIDQhfn5}NAbRj25#ު Bһ laJŷ >f'R?V5d6j_ sۿ*1,}4 CvUR3^~3KZ**x"xLp(iQ_kaץzLm 'R2J22\AP@/:LV(U>Scj <ڀ3,s i*+&e[kogbBѬrEՀ'J9Ƹbl+F+56-ݨ c۩k VwрU?"KSu+C+L3-}9,nNU8Z|qt8'R3I 0R?U2i@Lnm ,)&kLSAxڣ>=?+{c$VEn\2+V>",om.d㤺!aX(eئ rY+fĖ)R-,C(ǡ),Egel&pɱU iP҃ԏAa(4bn6L4lGB*+Hn[2qx {sȽ+ ɩf5`YG:Pb{XWD+ I +V+Qe#mI,걩&&b>ĨJmE%VXḍ2{t8.d-sPGDjT5w ŲZfM}ZxfTxnйd!Y sFGz/LG7pqv{Q"(Ԏa8?nφF!@e$NkyAi಍4<N_x~mzO\9qgU ~U #XdfrثH#덻@݀@eҔO,5T?1o׏qkR@*z|0kEᗍ09SePA W>f',0B@Ƃ1LZq\V_'/}Ix8^E15+{T3X^Iq Fylr8](",_km<= .OUj*VvWrQpַQDqC1};h[D=̇b $Dc;ix$xy@^ۼQ'8^_vג{a,涎qm a,!w&,W |}7~kZ2($ƻrͪqv֗(i 8ROsK9cV5 jdqv߇(rC 2~`̻i]k7)*/=~zJ%2P@RXJ=(UN.1{㷿Iincb/"UدlXqu2Mq0X\@ Y;đF@pa]zyFKo߆[{Q0!kVSrV>K ݦm;a먽V҅{ ,qmָ>8 1\ARIi0C'X7&S?„]7Sp2ʢ|1F$i`$pI?,]N@`x]t{l?LUFV& M8 ֙|1JFӑ+ cܠը mup&pC҃5#A` _Lw\驯ҤPH2txgQp6F;;9Kb{$"6p o;yrkws`)*ѪrEv8ܼey xoqiQ!ejWǐ[([BXHTWJXn{k7l%HV:VIfk+\W zCXSjPx҃`:g|뎹/\z X*`ZW\zd2vm>r-^Ї,'қt~b]9ib%21$T$la {m´ t O*|1mgnоdqMCI/S]ENzK5K_~#y!5 =?mA_CA ,.b{k H) h(~`~PůG ,0s]7RBrg%*Y.Ԅʥe\C˛y{^" aqFl5Z$曶;jkXM^D§AX퐍^'5o9ʁ"H? RfzJۈLXʶqٵ)pԛĈv3W)#b,Tؽ% ٲSE i2( rnW7$) 9%.+.n2smxk{fˡjH\"b~u|-ȲU4M x kJ(GHR$7iZP1cC+[XMiisw+m +$zZE",UjƵ)PhڶP5mشhyWw]Yn!h9RZXJaeV$r '3SJ9J+6H!a H:a.'pg h7gh1-|weRJvb|۱iA}~m7F*2tk:WGkSJtM~x^䅔3%)H2[¹*71%Av\{KƗMdf )_!'Ӂ޿|{2)jTqQp4Q )*>+[O(A>֧>*NXkZK^sw(bhG(X$hbqtv\73I8XjCݫp}fw#TkyTmIbQ)Jes\m~.yQ41LZiqr=O\q@cu=@G11wo'wu%6v cϥf+֋ۏH $]m$5(Rq6D1x2 Q] QߛosOkv_K]i4%Ƣ4 ukEpR%9I$䭿9)p2-̭ݛ޽nʧ+o!nBH(USN=d|tS/ ʒe〬zҤg3raiZ JǸcmc$@N 0!ziJTW)QRXݸҙgLN PTb4?^ }hJS8Q]>8*A|H?=0ZlP3Țl}f+eǽ;/iF_4GPG+"Tڽ;M]ZbVܯor5ծ $BF룣tlVBБGAΦV4$UB2 T40`US*cle3%rSF!ȵI=iYItc#`T-2h/r \ SAQ֔O*@siCirQ%}^(#ȾkO\'!p?ÜeY˗P+a]S89=xxYԌCJx,Mm!ٜWݱrq;YÞhJ"Osp ,?.#C]@Mqc?P lthU]JAnoB09>Xo) QI ޑI@jj09N6. 9.P]F*6}U9^!.n$mW0F6  Eڿ/{!}ŗ|_1r|5nh`RE>Sr#?H\6}#\}FJiu ՅNyv*Eys X_t\=>-\B%WΥ(x9qV+n|S*jT+H&8FG¸ݖFW\*θڤ~Xڹ|sJ]+Chj3z 6iPNx ʘA~dp\dBy-"k9]HEik.BEū^nOĪ"9Uj F88Yk+6뒕-;p_ !㒴+ǼSsZ]oap[d_۶.+p_?x~8n+ìZqk{vI[q3bJ^F*~cOybpBn$u]CgFӿk/͞ny!B6H3_uR帥㻿fnGs%5:vs#'Z˝#s,WgmcVηhHT,G"LT2ϟ۾n=\ -Zr,v:ю;9~~6^19Hֳ, /#tOFSQhy%乙:<:X3{W떼Hß򭕊£@@ju$g!bewy2,v{c4fMeO` I+9iס,<ҟ^vֹXVcTs46Q=@A֞~b}6Ԑ-+ T% 8ڤ):xhNӧܛqr&u4];f, 7<3đPdz7eJyRme9.k&RhOQ S?UKgZ}8*ƥ9]p*2gL =#Jy0P6}+\\D*Ԩ_`C%dȎ k倐ZeJ|sѨXi])Q22-TԜǂОw~)$C0Ci?":O`Z,#Ǩ&TeTf8/l\ǁLRZZkxbO/<C(4eJ`֣g\x>ƚ`E5/1ro#.!+[ˆBSk 3O0;W\<*$ ZFHMipw9 bFM$T5\Kѻe&B L F1J ֬x"u 8kEnrR .Jf`_4=2ļ| ,)#e:#to!a-9;y x@$'*@@]m[Rxglڏr׋id5( PCk% e ^7@3r rkwZl'yqBT zSp#v*q\cE{q/.g'vw[peDd1vbY,Ymoww)$V+hn'?P= VݕPfN&n6H9+m匟u*wgprv -Ŭ2I+P@&~a5H-Vx wՎ׮o5׹7k M#pN ɽ婒C%Bw0![xdJn^6DaF'HXOSWoS 1Zm<^i%ɤjO,F9R=5̓ ?$ 3ԫ (F?o'D5731b3 )Ze1XU He$ʔj>{p\8OP`i\z}5>:Q$}N2 Ҹڦ?cPlS7?y`W3R, .oM=ougp9zZTw;/=y7#Mn-YZ3,R2E,ٖ9~]I~a ۝K!5 MY]TETbvN~K#[KfxnbʨPF;۟x~3/燌XFh ePEGyw3v7w.b2ٷ-&Y+NlP@fՍr|1/s[/5=[M~!\ grIRi >^㊜և:xUNcBz`'3` ֝}~WNSeeWΘ.OӨ1Jxb4t)늨xn 1Z r@4j1\p#`T-iӆTjZyS?s!Z+Vҧ?4GR~aRj8P|oqˇ  0A_AC!>IVj ,pAg}41Ln}ӹw2d@:XVX*)\!Hwsig\#.hi]p&BKKW*ֽ?D3c=:iIcsto+M#xi? 73xgVwAxF>‰kyI )?~*4ʧQaU`|GR HZS#xu %I"xVfPR$!7ӂEVB )1A4|<4:rceB*GOc'\ۛ2IVF^X! q@*¹IHNUMN]N Vuǡobθ4Ȝu7j_TG$xfpɡ\Pа#/R?8zm2P(t^Pʔ#?᥺Еp(rpmATt:J '|5ĐAq )l$m5t'L7$5@6F>o\v |hzJ~ّ֘֌H s3Ss)瑒Z;_|2cv'dY@*FtZmȎ3~ڄ-641 Z8(/.앏JZf!@b@>A֠hWH:Tu<"*IJ䢁~UtqM+?"|qV*1&}4;\W*O s:`Q\(E706B0rTǹv6/yuDnEִ`Q˨ :| "(9u߀~Lj DT*ҞDSL\vxqksVЌXX{3sq[#Uc4p"ޣ̏mix"7mmAw'7]ef"+. XLPcIa]ƬƙX?o3$;(X]ﵽQTնNZ~Csml((1wD#^4H`@$ ĕiij]b+, qs=;B:/m|w/ysmq3GF7-,;^* mr]kkM#Jm%^P0]4H3jNl{^\еʫ-Wi _Y:u}h'n?}_}8o;,z*INDqAtQ&]#Jdz\!;vkRiSL b[ɳT24PwT 2ƤR oFX-ZOʴTBH\? BvIahf,eWUS+JW ݼ͢"w4lF_mNӷ*<\[ @XS/*>V54S,}W&l.[ҷh3?nS&C,22T j5k6X kirn|p O"Gp=q~o^?/j-F,RN>X1e_߆VF@ h||B,t#/݂Et8 ރℂB u8=z  ]3M3xȍb1ǫMA뀀ygC=9SdkJ碕p*9ZO”@'h!ꢻtS?FTkgU?Ѫ(+<*zW1#cG! za'rSJUs{QQ^.3N !@5;1YJ@#kLU~6u 2kO ,̈mJp$?+ ^*RLɨ=zpreV A|1I0GyF VZi$(@M4R3ǻ::kpbͬg1햪 zNcༀ*_#_/73PTB:y@X"횝^GLR!Ҵ:eAT k ks5 ,OP=ixz<WAO S7mb>2:Tg%\Cn(يȥ 1?NA&t:sMeXDzn}!IwT`0pTTً6D3II +@ wdu=knEDrke9SԦ:~j!5)$6u鈸ʧ$1#)+C*apW#Lݲ$Z PUF*NdI Ǯ(:}CQ_=Zb?lNt_:9z_[,8r{p풨NXB}B;!m\1rW#_ ȷH0{^11r#Eޑu~>/ 0{q9ɯ˰[Na'eю=\?LkF5Nb O\WuR8$槮()FT8\Eͪ~'xb3(5#`u(IjMI,lCA!@\i半)jhFu4GL#/:c`3B]N &ӂMz0| iQ\T)t=:viOߊhpT#7B4\JTP8=&Xի6])D- ]pTkS0*s&et{`a9.r-nG|S+6tG s /")Bp{s2q|qHW&?bTU|֨z5gaC㕶<7.L!z=C20z㍬rK ꣦ #zh \~BnҵI<єapA5:5>Yauͦ LU.*1wx1ts3$EG%͡G7GQ]S$g'EpmjUMBRv]p>ICDխ<0 b™*t}G Z&I\He? :DڠU OȐ*^ h$ҙxuGF2qCWk~WtKHi%8h>%ubd܈f{0{sV~T WrsWR?.┿܃R0R /C"r~ 7ܯғX6ȶcp[9Wڼv%'5WJ; l# rݕ"OORuZ]>=qPIPPqu`zqZ[;]xD(i$0 +R&Bq- I\1cq61Nv+`Q c\Wrr1r1O]7r1r1Qܟ{ Wrr1Q܀ gܟ{ ܅ܔ?/p{r_Ո5l{d8Ð19Is\{UOq*"/*I5 *B8إkHҺ`zOZ K;BWi-qX:*@/x|5ȴ3'c ^v=eNZRk1kS@ 'I D0PΞF/OvP#U |Ć:w49z_2X]k5?]/c99%'feK/y`M3i""(GVŷuv+./lYqREGQ0Q_S >8ZʴA<zAW]|)CeeHngc@<^v7-y<6T4D-%TzHQBm`Ŗicr?..碆Ӽx# aeR`I%R]#*MXI_Q!Ӧ=!iZ0θSQ㏻ҕe0bq퓓]ǐHevp_S$`{V Y-n0~$k{;x#33O=?`'~`'܅ܟ{ T`%|0O]ܹ{/r:ӑOִ8]K#CEI#q࠻f y~ S4-IԘ,lrů|~_Vx٪Qѣtx+ȌhqW~)s偼3pԌ?F Xfrfuui(11~hs6/jvC$౫M~Au w nf h]ʥ>);-Devs熻jr|K5I7/i*[́$iE4 5z}++P):TOm,3= qRXѫԁ䅙 lo01Hw!ύs.$S%wM3*`FXص&\#Of68hF4նbI./e$RfN  kCt0&5`A +*5NyUBD|Q^xHW!9+(I:,4A%O#=Rߵ,;Twsжկ̽|"s\9o.g:H׋ywk02?`sWCThfhΘ$U4 2\:t.FGH;kA=Э(N4Os;]X˺wy#@ٴSH/OR&R; q",)!z nPc] O$ѩJ/ց)_<Vis:cd+s2Fjf@ 1f8rE`'*)k珼8^~e@q~L[]הcMM?yLW#5…4dx. u񖗱 {ftЏ 8a?Nw+ƄUo_ Ri0Bzcv<xkeWQȢN;݋XL ,"B.9ද waegٸ)Í9nng\ഉ2PSS% L9w1ja{ ts#ԤZk(f`'\F$]?vxKzB! D(o$Mѫ"Va4׎ݺWfըKUlsV-ݴCR{!U`4jZN a ZDj)?ImUG͇I;G%'3`KY)5I#bȌ#{a.vwyGE-~ӁQ DP 턦[),ce^FiETc31LK<{\3Z]%)wok[,хUT #"3ǧ;ֺpw5e;w,n=T+_} }tu?NK'uq{ƃb_uX\U-Yme+eU%|Gu&˓^cjc:K&UVձYjH"\Κ־$JujAȁXBV M:b¢,Q@Ar9//گ'k\thKWx BFNH p1# vu;?!䱟aw_X{?>+K2>%KI߽qܐ?'a=JWj4ZdmLS{y$'ғ;eqOola RXԌ2qPs:iJJTdև;B/Jyksܷȷ|ust4eE)e?0G\Q{5}awgXtKw,e]}݃W,ݟBc]><K^ns<%,Sr\}ŬnE** k]̝ϼ|/4).$m*ۍHD2$h~)#֠b̝?SBi5)ߗ', J +&mt=?؊]djI{{jj@_Oه 0 T&Sξ7+fj#* |qXOp&s|Ԁmlko_zm\*Yj.o!x$mA ;N.ylD϶ukJҟOS>)_Z'!OR%&H*qw@÷ߗ[85OH̡SᖕĶ?s5R 7-A1Ҿ>4Ec~^<[DzEyz6ƢZWmDl6=_IG8]Z8ok-ˠ& bY{r߈Cr6]X} ,?ڤSZոBv4N~'л㊾yo[Km#iU*kQ"N|mՍC'؟T>^ͮ}s|:MC 0HŢNՆI(l W #yfY7mJH!F vQYII"^ۺKKv)$S"9@ɑ&en8X0B,Troy^VS4۴V3GO\Bk4i~^駁x#&yaM$ d㙶%oUZ*ihw )cgJqnґS# YvXroTfH ^J] ry ɳ  }J?tFD1@Ab੭ *zSPw/ץ׈y+Fpb:g=Ds/0?m9 䮱r#_)n qly$j# G yTpc}ܞPQXq_]]s*n8I#Q}%l.xnb*2I C|`Xsd˘5ɣtx_Lre>4" wx$l*PSdpV=:}x`y u8t&ysԯT~OZOrđ5/&9br:St`t, W_K' ui4rG޲:0XAp;2>K_XKbuw,zǃ`FEw?,+[6J˦YUK/O1kQ%0_n:h(4R6q4944Ǩ?,V\ȩs͍#t$Q.Җ7磓Zl%r4'l <4d&y庼縸IfF,HVgv%&7\+/vv0Iq;y 02v<( |{ۃslz}t¸T[N4kˆ:o[9@V\ihS<tq${s՛ln'h&3Lg@?ѹ|OM<htn Ac@>_N+45a]6eu#O%vHfM) OL6e0B h;3QP@#"4Aah9e.1[l;ϭZ6XIom!!aB(u uËyezC O!Zq{%1-l$!~f*9Ȃ$駏=gR@9)M߃ZєZ,x;vr3gSXX%ou_Ooy㪆9S_V[yC5Dw09Y WkQ+[#-7!k3s"t 'd~r gOΤyM ,7-yp#~GQg'G`>T&u-]SYN) Ndy`E~c9\kQCMr8$v'W'J59o>f>񲋔7Vwk9#a (hA%y? "'#\Kap[zLS}aMQЫ ՁhF;S-=/Zv(.B}`fMs>O҉O*fphrRuhk HW?B\Uv3@ rq_qsLL*h)zJ Tqw>[X߀A1*z8JU;X浇oh.C,n(=$FprK]x$ %=lcB:?H;?.e2_|7vdN$ϸڤoak{cy'K1r-VBFbA FurXEa( *: @H PFF<r:TZ]˖z&8;*~?©Ko,(!ܽ!sv<7]n*2UR2r\qL\g)ij>sqj;AMƅkLI݉H&>$ lGN1P"(۴IE3xR/BU˔`eB|8ukŤ$4d`$eF=I: Avh,D{UbEPu"x -6W30(MJQ}\}+_"7SMTf"-YTW?e.G3P8,%t֡n']\0r*O3}ٶG vqM+֚c= O bN~6Ϙf{^B.#o4#8?AvFf{Iz} 蒗.xﱸ9>S ݝaH?ڟBCܵwL$ rd$LZTZB$Cz(wnV:љWx|?Oh3iܴf4*5㸞6e㧸K]+Ene {HBq5c'WWc3rLNk pKUAY,u$9sB vwgLq_Q {}!%iF!PV1Tyy]%ggfTRI%f9RTFOBK+#G"0ŧ1qV-Z4rLU$UT$q~O 2q_q 3ʛ82qJ+=$ tqDȟF$H8is}COm?c`=OLN *[OOLm#_Sqʕ9HQxz< #u >8o}pVB/RZYFR0{fiWȾ,HTiE"7eF;^oo{jƈK{R6K"yF=5k<1JZ QHe:_ iOӎgGBQ?KiڲOA0H֠\k\m&yeJ֚ckW_?'&/j w֮qQ,|7)f eF5xR]h}Fݐ-t i_<30顦#O!Je򃦣}Jn_Pmz0=T !Hԫ$= s:_62K! Z Rt"uV:pҪC7Luj0KɼOE' o9 l P > FeHF\J~}2Ң/ፑ'VOP9ץ0UkUJ I:Uh+j4ŏ{ZHYl\ۻ3}Jb>M] X|N5f_PՀPyECbiJ 5ʝF#p4$i:Zj<: !c<#:xۙj3&,D1y_x.R'bUr]]v!sq#f3 hmj i tʃ/, ~8 憺[`! 5RPrVbi.;#^b;{o_~&(+)xaW %#*v̼]]K$B=pr.U=i]ˋ;*.d\-!)T4OV VE>"S3GXM0!D"8FӼKTؑm4U; mEʌw$[A0MZ}Z9 浥pu܆Yd H-+DP9{wz_Ζ_9[P>#p&up_A"G:t#PO\aZxa zP|ץk~HΆpwxt4*fu$S MuMN `=+QLq :b+Xo$C42"b 2KۗGF#vѥpc|$rѸ*G㷻߅4HX}`H2(+qMki-V#*V gS<4?T~MՓ\4# *G2T LLs.06ׅoqҜ/0ki H nʌO\HRj4-ݮK:|M0CwKj Qf&Sza5 T3>Z)U&&RAQ"Sq\v~|źcFK7Ri5:.H#<ThrbqsˢsͲDqJF4>սHU)(ffiAXEUwTl**5"ı3& V52NnWܛ LA܁RF2jo,ˮx6ckS\ņ)>_8S#?<zOlGi#.]pkZ7ȴ ˮ 3IVVZ<VT>lrǭ6o2'1hOMHֿ٭&fr6 ?V$VՂ֧*˂2k\71u8]NG׍PAqeZG%GB(zc}NΘ=pDc1P>'q|7sWYd @ q'SeiٜkT /ݑD15 t;ϑi>kBKHIQEޜmNػ`?lfQ5TJjG~!c ܲuEybF6獀q_0U<<0I ܚj0:`.qDiwpqV~*)COa w\#$S!`¥r'!ҾxؠW]0ˮ^? Mip]qc堷_LU}rj xnVI $+% G@Wa|9:bKk~řف ð nq/=# od J IAŏ#zw{Iuw]۞hti$nU&qi-a6Ysw U V5)FC|zqw7qq%EÝQUg!N;w3*IJ]}%jpy^R6O5AnҙJ3jB3"8;r-[+kR:ȪQ T5ݲm4ȉ);n;/,ƊI=}nGywT(eŵ(F<K95XrξXP cӒcׯLT)\Hi־gS /߃vwoi[ZBZE>/kS4g]PZSPsuirl;?I.4^{;;-/%]~*-іYXd˿a5#1n쑭ZdOf*' I$շ247ݧwk/]֒ݐڬޤ$z:S.0-2qzSx"о6habqve0?& N{$8Ǹvjq{}uW|ۈ_,f}6GlUkd%[gmMII!A \OoWV\:N-Lm]@${%2ʭ ̓-88o{n㇘R>{2(@5Ε(i Xۗ㣛ץk~-Nuh&g: #xqPw2sX PzLU?A8wt0sepVP L迷?*<|~ k>*X!P<\},R_7(˩=a,P rt^?;²>tS߫Ƨ΃`6S,6W_?'xn6,x H(I"N@`:Pc&#?QO\ JDjiS˾}~dR!eqs_dVLUz:cdyZ_݊.Mk\Lk_O*b+I:}8˹"X[Qe>kh1QxnFN='VQ;gRksy{lJ x{c( MZG\5-d0jz:WthIҺSLQA>"๨P nr**IL  0HWBWFej##rYۡN2WZc'jWfe~9f0CG7K Es;Tr4S R>V*57A߀8َgy%kqȉd# VxX?T欹>-}P@>ncddIl+qH=zxЌw SAЯT~=OP|`#CJ\,~V, )ڟZOE' nPGiG8@ at'"V&5!I?n*\.$VƧZ֘K™7 5gFVGo ہ @G5=|9+N7}edFڡ?قM@b i$$}Tԓ㦘Z"y5֍Zը C!(r${ Ԣ05k9 e=z ί #cQȮ[zF$C>`sΞb.xWZdRv2QdX>zrӏvJ+`3)փ δp48 ]ʵ4F=lMFbmf>~xUΚ]tHN_ӆ x.2:W1UUj0vP:4~ ֵ9nPI⑊OO6w/{a*$T~6挰ơA p{CnX&fT<h?]͐^x#k\ɶ9̮nrv6r:LMU'lhEE7<A\:`Azmz`ឝ1$WAOx s<SL3Xb̚}q6x$G񶂾Y`=0Zq;nWQ!K~k?.™ I>׎oZXqWD?5yb㖺mg@XV,F^X5Z]m(|55B!\8'>8-~(IJqt?==Ԡŷww^r1C!"T5bžw9!U@= }'J*.A9kxP39_k/a4 $:*+@O;wȹ{*V JDp65I@փ!MzbW7U-J'hH@*q?NL" *~`EdЫ)H& ުS#0|qE>SRFڑ=L b'O¨ڐ2m7j4-$@X0d&@i1ib$VP RNӦr`ℏ/S8t>yx`#@NNFN|W$kN־߂,ǡЏ?dUcz}IMͰRW`cAbPד~`+J tdhsZcc>|AϠ9L]x҃/,\<6|u2\\\ȱ H7;EUQ$3q}CEuϪ7נEɭ#^zI=I9ORzƕ 2tbN~0vnFΆ+64nX>#;ۛZP*gءT>/,qFETP<9Me:ox2,{!ZK \'k>V׮i0S6(7P+de5y1)9'A \ni4_,~\nb>:NJdqFaovO\b쏵 v&rDž9KkQ2ڥAj*֞T1m!FՉGQGVeІ.]iQ^1@Ȏ(*NJSYP"JVaE"|U0кmFe`V# ŒR5cF`VFCeu.DVhRnjή8?~4B0%$ҹei}ʺ~5TPA%ф՘/ـHCJGh[N`:xa Tǥi˘Cj;&$,.ulԦ(6oEA8BH9~>.-N6V9|1F^P3^_o)q{G5$\$XnIP:Wx2FDPS35LJk!=̠01eTzA#_ဤgJPPTPk\3JaP(Yu˘)^1"ƔSLTtN@eQQ\ uߚ~EOA\wP'6ᇑ0o~7+Ʃ-OSC0bpEZi_M/$_h*~luFo <nF U(.>t#I$7s)$+\ԠAkOy2ccH9!FUB4R_I·w<^>f NB֫kX=%ȸWUZzd|Ų8w/lܢY,7tv  wV3@2ۊo:qLѓ .ӓVS9~V4~奫E,̻UI_:bnf4'd]UOZs6W๵`BIPe|Yt,UOaPE*+_,mQJ=k Ɂ+#5avj#r4 '{m8V{&Üc\[`OD pwm#x_QĩQP)!9ۂ ~jn.k,|]-==#XuwZ7"-dE2ƍB:C}'({Of4>hiVY|4l9ĴdVEUC!VhԆ7m`<|/yK)vڝ$,骲{V#pd%Ү!ujQW<ibî-.|*UA 5~GJOAEY8(P]^jEEBR J^'u3P@1!tƅ[=|%EH>"CqSEۖBg!BjWn>8U5h2~sRHsUOE' n˷`@ֿO݀ab+L{D Z(' :#nj(ujA韆ޅh sAr9 f d td?.MGk-n%fb.uWzHi; @DMJu뽎{#7d{pFo.,IA&gVʚckַ4s[hWcꉊT b,W`y ;34nXo99! $[Fՠݑ: G00 w՜ @At9fEP|- P¸ j:W3iʵ'( P´㽿v l3~޵%ҚkЁA]0*֔2qm}82br`I2E G x!GW:K~S/9ZNض k}=ڶ/ׁM+1đMN (x)SpG\}n<_ {zv?(s LЁG58b;']0YM>>˜ RƟ8 TǙԃ_I0BhG:Ph 5iAJ~oYavFah=@` MzZsU)]0fPX оGW<y=}'ZOolOK<_v/3xm䟍: _%:c}H* $99WN_,zNF\28™?A8(2S3\(3R5L 5~uF+W5E )R(i\.GP:<:DW7̠v=1BMĜ\+s,R4Ҁb;㯽˾)h"] B\:$s,\խ¼s5>H(q]4\Jnc^.uvyFIkӦ9A|^ES$GAL]y4\yGE;]}Tvk~7IzTN,9 0 {ѐ,wDZ_˶y" 9:,$J":#7k[bMu(d? >e9SGd3u~88B*Fx֕dJS*clZI\9on)Q* q}=/rwS^M9FcOAGb۱A\؂0dSO20r|WXa[_ىT*C(V$C-vSDVi*(XڬޕPH8ۏs&ˎnl* [.'hQmAw!];0@s_Z`'yw^ X[a'lnw+kY&k#eQ3I ))* }2JXYU̲23A]/oxٸڊaofHAPXGݢҮL_Usӛ۫J)B҅Z=+ɱ}"$#@$cޔ8;VQI4*B%@SBA2Y?7KOrMM+^MiCmkZZy  _Nn}rʸQ ynmJ,}Bi8-P(*8_W7_?' x?G="|+W9ld)'̌V/0P5\ ҝki>q?-`mr|q؊@$f\;#n ֤\=T<7_,8ε;b1vK#Ab+gfh\IAU>Pjj)#y`zc0|ɥJ/pwSNbAqZ`Ѝ͑ݐNcƹfq3jbL~ nc/ eR5D[NFX{yoZ oN:RPbKUMDmROR*4EۧP,I (hKUaZ}8e+I hJxWSJ-2ӧE) .Au<ՙE 9ҹA$'BMۤ́fJ^l]Yu_z2i +O׮ %A9W*hz` STeJhp-c]hji_N)Pzu(>>'K 8 'ׇTyxUǩ` $tF 4Yf)]"ACk:e˒E)o?;e2#\jEH|>)@BkRkָeSjh3?^mo\&l@M|iG[4o qMVz}^L<ݡȉd<^]qei.?%թtb}bJضOɮ{)yHї*Cj0R8DQ6(gASZ )`EQRYFG}Yȭ BLlaI٤R2\phA.ʬ#Z+r A㞘Qʕ=CJt)H+~_i wS`S3(#RAw(x-a%!d&аx m5ygڪZ%zZ´`^jMHu"5{o^?/Ci 9F])危 J_*e_Lz9UZ#Zynl2EѤ` 9evn.r?zFXHE20iܜ^+/H*"h= ^cThIk£h鍌M5pըrӥq[O|'gqGkI8'B<1 :3 8Q'v6o]+'Px]dRvoSqg5L6ֵgNZR ktǬPɨ ʴ<F~=@Sky@;R8@2F@:TZO Aӧ^Q[Z`b!vqR:0R@J^x"FkgiH]>*N@}5{t7{%q|2-Cf|oc^x\̑mV<RQOx)1ko~R^[b>60ZLljnz+(6GR@aL-$$aM CScbB tO@+Sq\pNU[.!ڷӠw4} 4)-\(SUET0f_vrj\] S7I(1EFP 3 #[ӑ&cg줽ej1aLg!ƒ7dCqS:~za,95׏k]qTLbJALUp\Z4⽄qo$45;pnǟ/C;=g ca` '߁1{h(!r+èl>! ,s/^o[KЬV7CBT֣_l}"eb׺;Fז.Ik{i(ɗ94e5WʊT4 nSQ+iNFӋԼAUf'%U1PN.,*~RPc傟V"> GmdUI.NUmvfPh9U.-͇h@.hhP1i[6ijnmNxK-岗eWp f7OPf[n+ZZPnHږ? ;뛾ψ|r).43iiT"v}C! e4WBhT,LT _;߽-̗)*"BDPv,m'k?+?%iZ {˨d2Fzdbr3%WhH ( F$py.wfDe}EfyXdƒ,s76.T kHzX k^Z{)QJw3(Zyc4Q7C>̫9]7Ťf'аi#f zg:6Y>5XV_+>Uiuಊv*Iݟů Š40BJFǠsߗv\UAl B g3Wqz4c{V\kmE H(UQ1@-G~7 ,izuV ӑ8(G3ԏ|'gqƴ822x⨠7TFfc:VcP: a?f'eAV&T፯V>^ ms ky*eF!AeO8Z*ܣ#9`ҤO,)3*d*pYt5Ul+,^S6 tqЀYsWJJHdFS 8F-?-+4ZŶNT2ʑ )Ja-9.}ȯlfKd^] _߀@/:WEh>buǪ:b tZgHx )8_ӯq˯2R_lUziJ+۸{g2)б#_P5k>ZX&s_pa"9ӡ-H<E+Hʭ:qk񠌡PӮ_,(X+X`KP4A4*mBŵ#M?wV'y$ @ LҸ]&2[y?-_;%XK[ \zE@m g EhOZ`5&}@(M4wu,@3\T;년KHFQ|t{ue@z,)ncxP{TQّ$n+U1js "A[.<`ѤezALKƁ7AY+>t8K-oV.oCGR.m?g-$[Ȯۚ'sb!m_,Hb8ai]';XH'ڗr)ɌBHodWݓ b]*6K۝HlR wI$TTK`Op?]<0'o Xs6(K~ʖn?;纸;y}0k 4/E9qS"4jNdc DbTΤO!]Cd QbCIH4USBBs/']D`eu 7$-Z606bĴJAOv3}x 0p<3=A.y$\SUjCRkV?1`>nhHȝLMSOݡ#cqWS})x5[^f8\ UbXEAM+@)O߀*k@u_V?.%性[UXԊiaVT P.A ”¬c̒hp"g۸U[u3YFAH  Ђ`0r?_?;nZK2`p=m2{HG.0Q,L\;mὁOOp0wv%I ?^+maOIo3S&Ӏߘ=j=_f_/^77~3Nfҕ>NkF?1;XEɩC@(ǯӅV>Oq҃i]ASPYp L1TdGтќq98 %B#[Ͻin^&{: H+0A#}G族#Br: #hr\rj<4θʾο wQ r?;v!4mz~>VU$hF*tb*Ł{OuIqۥ$pXIb,ഹ@%z9Ng\miO19Si^?/GO=!%SS9kQCd VW֟2}'(Oi+5)JX.lbdjwmXsgwE4M%nUaUa POяc$_я}CxI0$K}?nXK6N`O.15#s5,kgAqRMLg39an ZN\2õZC+#.ڣtVj+adqlU:yglqTYXUYZ'5=D\Omê 4 ̳PS7)1+lJh2'kFb"v|zJSk2=(V NoNuo*?~;k#㠕'B|vNya?hWB+HlM+xcvB@3î@9S_xZJWګB ~ mwm%̼WsGWaw4P*O8^qn9F rsԐstgug,ͣ)kP}]iָWP2=߿*qX׉;>]12b Fj"1qf!,t% J.$! n>˂c ӡ>}Gil+;DO*/|P&ݍNf9 hkzu МgX7x?>l಺z)Rq0q<7^s D -;Z邡46.wPSJcm*Lu06A݉^"Y-nj:L #5FwFhX$61L]@iTeXj(OAґMh: \ڹS ox弪ȍ#>H;mZ̋O4%G:b;4J]^ Ɂ_isoqۭacX\W rS5}/s" Z;ZGf isrI1Kj9{wb7xR^;̗QErۼ V:Fť2Kܿu4-\J 1>s9+9.S$VP"#>g]&^ m{ͬ*ҍ,%VfV6ܿt-f)(4U4)\r|OtZ{膃ؒ@VE1P^ܫre լ a4_2&0pTb9kL{ld;t_pP,u2f44\7e^[mqOOnxN9FjP:\M'i98hx|ˆFt4xRPRX\hĥcA'^÷KTXHg ؛2ގ.vIf@e$>P5iog}{%̑"U X{ 3ImIN DCUWUæ,⡹_fy$-F\:5.y[WXaS#\LDR(bůͺ.E{q;⡘q `]],I$$4P"rs >Zyy(i0X&H'fxu1C6O dG=M.uC'fyﮔ w{qz$'PdX㕷AoGv8RP}j35 7!U"*TaU]ɝOQ#e$eT2^i4:9U T3Y=## ǫ1Ա$O3J@ 7i2pAZ w.9{V!e"z2 b+_4 wl|1!u.zbc[(|J^ P lQ?ӈxhdjSܚF@yPpg0Okz-N FuW ~80UrvM sp܅LF^2/F'0 U3єXAЏgF^.ӋYsq0 H@(kPkhA> s(ƞ x$zc068Tg=Ͳ'Lj#V 0C_$x<#p= A$ +Kn{Lq_bIH.?($\vw aR#.$OP۩?c"wieF T\=2 |W`Z >۔aI|0?HRב7֛&FiN%X^2YrJ3o1պpxnஃ[I68Faju7ee϶FCROhnw`k lJYH5֌zm FvUOupcS"BBEhA 3z\gaO:}'ܝ;- 2[ 䪤X( ҀSƿ L2LWΛIҢFVQZp:4=z WgU֕&\{RĒA> QjNhE3gok#wH4R+[$P:Ց;dž˝r6\" R*֘=Q,*6"1>DL#NA' 6gCOB@"a˴u2pkS,0 Z嗛Wk| Q'ι+Ҁtg6_Z7G4R 23A %e%rcE/n Vta3m_=%45HI):CI \ˠtXAޓ@aQt VN+MƠӯрzIxgrUr"4L=~vܬ§i3- ߗq_kBĔe)wr {P7Āe\14Ixu(;^3Ǚ_ݬi^pTk/?8N?8mcNֺoFz|\EwK#%q2(pz‡шZ(ZH.|h oq6dhI, EvTm;}fxnlke!r\;F݇Os#fPQ4bԍ'nMs[񼗲ftάX`w+!Lʦ9ܑ4 Bm6Xn") _WLyir!wmLCHQg"r^'TW$b-yOk2ZqsAQ$d|3 FSN qC\k{.[rYl9-X1Rh lk"d2(tYWpL=wk0wgn/\n2J{~Mau~|Ms̴ R#{dI/+Q}^ڌA7dVݝ,7mʌ{85' ݒqM2c9 f"4bv嵟C'<܀(2UZ"* HjfI֟*~B%Va-  @|$A=l i6?pH"M2*S/Ukrw!7eCF,*MKWV:@0 1DThQq)TSP4IMHGfX-UL O^TTTV¹|F $`VjPLPѪ5&LrU>:㍇3!AָPHץ0tj[U3 $c`%ԑJd?ov=7=ix`j++4hhtFjAg)S3~&Wu Qr|nT[;XH+"e,;__[DMVBB*µ.>&aHIrU.>bIuӡ+X@JJ'a+L%\9boL\}mJy{I=.#*h&Pd*Aٍ}ms1QfxCO8'5Rh Tb?94nN] -r@},|= t8 @qJW\SƘ,&ʿnzOqu+۞x.Z:`"΃,62)uHS'\PV1C]îgPiƵ'Z 6Ah59(kA\P=EI55]s NUvi8%sh>A\6Ӑ1V3`|00R1Zd+Nf4cXTɳ? Ѩrx Z> )0X-*ih?~QC1A-+`eFW劶Tjsz@A M(æ P&|rcC_ҕ,**GS9x` ~7ʭº$cn&W [&'vJYX}?O]1-TqT3S-\,_=/MrI6:{drUOCŅRIOƹ2,…~XWz.)U 0{HΦU̐e24+ԡM0YH5kM 5(=iC[YKZnԠCL4[+ГJ4G ke_~ aR[#LWjxTkOI:W*֘ePe0B@aZS:RBpwi5tʾ8\`O\B5caqʴA@h:J4݌c\g4V>P+_5"i\tõ'*~`%ʤkekCRpF6R,*m&1px2oAui >{@mz1Vtu_<~c*\UktJUNY1MqudH9ֿ fa\W%=MN* Txu l sW1<1)aKkጪ i]k8WM_dzO='ln\Kwk١%6׌l)rl7ljGNRHAc ŝ,lmfY$MO\Mۙ-㟔Oj]a˥Iapy*޲XY-njފP~e$LCy0$㏻d-cRY(75Lqp^Ee-̓R`rc%n23Ŝ=ak55mePwJ-P1o 6G R$SEb'1}g{$s2񷖤, )hmfQҐw<5/m4kBs4Lf=pVwrGj]ϲ`QmB},m ,xTnFZX+%ㅘi5dmۙ3nҟ홧[A@f=S}4'LYpVmr-mAįo7izvwKr'ocLMKu {lWrS1{+mb RCsѕ-V3+)pqnK8bk+N#}:7=퐎1;+@517QIۮKNaL1Zd &jלaZ R6[RC$8lZrv+iLq,J$sU6"McKK+溱1' ]ۡ@hRmO Xگud4FR;E+r}׶]C-9i睜]6fb@o4 vn%Sv,A'pϐ䑣فR6zh-X<5[8`$ʬ)ž57-%t7F &\NaWgW;d+QA I©Y[ =@DSRqi5RJp. GZDor8qو!3ݸR)ٞ(T)R|NX V݃>\ hrTPx6Z s58+\5?ߊd: hzي}  Jk:ݍ=g,gL<=wbx~o`:PuzԚ z1zPhqHFX!2W*38)]Z@3*j-82kQZP+ Ҵ ( @=pr8>'#Z}>~ۭt>8`T Νq )G͎leh+ruj)TuS0KO==1LC*L29CeL0PO7EOc 2g8)D<1SL²R<n`**A=|1YCZTǶ@ *?㍱j ^E+ԁJ}4 *p)BㅎMz!Iԑ]E3$||fmA ҵB" Tmsu H(PNmޥN}'Q3dp*k$$6r JxXZFֹЌVțS{84V;}{qI 1%'xd֤xB6xB*GnXќJ;B̓UT;#姁k@ڻYM75EC4o!hnVS"}sb:|2KOOVFYx|pJy`ʛQEfa5 fst 3d'`½p\ɨyƵ dcL(| s5T<:{r ~րy&5tǪM<|pz1 Π5*zӭp(Osd6IzȨ?ki6\=;rAoAҞXif1: 6F H$n0:k3 PZ~zkLz֘!T~ -J_2x`Wu9Vj>dvR>|:nsSÍS4֣Džrʧk_(۝s E)?8Uܢ\ZsQVi,d*1q {̷jnwdڹNM)VҖb.$zԑa{"nUY/*\̧ʶ]2ny;W)"]*2 8=q35OUyX6)Th kl0`UEt?axߏ@Xk,L(%d <<|bXxK&2F9F 4R);%1rIWV^[G? (Wܑ("+6k4vmphEoTllxQgeHو"owmvqo #u Ѩ(ž(s76"k(yTk Q\*k'8RwBqii;GIjnx8IӋEЬ+ 6jCrI)*-_8kedf]JFT.S(nRqD%+;jIjh(+ۿ\$6{ŸxlrU &M6nj+nE-ȵTgIr&]Lہg* q{:m}y[#GF췲-,7772=Ҿ6jvm;FXFwм*NEEE+0rs$PD[5 k8징9 3]{, 4%Qe*5ZHp&삅4X~~/p*hgR~P6 %irm"e ]ε~NGZy xuv9jvU?[~G71ɔ#5*uv18ۡzcWqΚe5a: luبc]0&ع`ITdrgMj|ZW,QzxUrb3'\m ??bS^Ε/2ҹSp( P@S:g2_OـNX;3ilSh:fNd|A>h}瀥NֺSXs"#jX |j"kͺ M)y/SӅ[RiBjLI$S}1(M2a|kc 4,BW=u눂zFUU r)h0iҙ94%jčM~4+p.-(v#kݐW e{&ROZkPA)Һىwf=?f ǧVs\Hiz ?&t V9e\ ,UIbjEĜ $Pd+eA֞8eMFMPEcjhE+|O6T1WP.TӨ1Tcw^s Q\:WZSM1Och)/Lp<:0\ SFy=k[*RAl_ fE5!s`4^QH;,o+CWJҧFUs|q\\zB_Հ|qQXtci' n"z~ H4⢔>ƸS?0ife JE~5qj6-v}k  k4 $p:1OӁO dk?13`+\f;4#}W,cs$d2 qNO,_H&XQe%@4I,35$)-E Fŗ/Yu ›CQ%`6܍I d ,l@gvԌZh`V$dJ_1.~;xː.UYᅘ?)҃ m--V_v['s0*V'oKIV#pۘV/kQ^6Jd >u95 c{:F:B ɴ3]qsv(mM圱{2jvZGPNedImrki Ut k59EnZ[8DS,nCM_V)485eWݲ8r@s5\,\M4eTdtyԂ~mH8+߼#nZd4, V$W r[-KkXشjBoаvwrS(2H"SD2ʿ6do"l+"JR CjɹXsq7#_M&S $P5Z[(Mu{..*Nœ#d:kLYqMIC1ظ.^΍LԹ1z[]l$2dj^=MrW ⏺. j3QAa˨8#C_ف%h*W\#G CMx~(鍴k]1$ T[ Ve*b@$@: jI=tYPۍ2$3E>]Ϋb:ӮV@rQ@A@M7֣Ztƣ Q#fݢO5<װȰ0ȹjI4Hju }_bX\P$bEVmf#F_ mЕȎ7e\`boNF;Z@uo2o#QQL2P@CKk_ m2F~с jGC(ִH)('"0P˭>эzi4e`In\F AQ8&i*C#2J I9 gxⲨ Rθ 3 dX #M Jஊ)ҾX9SX~4Xs8ʔqJd1xܾY`kL7.D7I'S^7@:WHEv7mT֧Q[:00rYENXzE~?F[|^fs郘#R<\O s n#1 ChNp@v7F;KK/nr,HK+渿rі<򽖠e$fL5?OLO#6p ; jh9#XJGJeJ[.Kp hT6ZZ|2<ռ/Vb(6Ȓ b+2S ACJ $;|OA$ rniu(9VloVoz@265\KxFeFP7A@Wk ۄ~ c;Ḋp(dnq'?-.&a ͍UB@mvaBN-^(8Rqmm#K7WqT8h(埏'$9ni[!V]Tx,InEg,i*cAZbߵ=操ZKY.Ky#4dr6H NhK+1bH"_K,a:CbɖG&Qaf#uP:ay^[3;W,FF'fРk'6l/넾CRLypwWi#3_=1Z2k!w"}ಡ4Phh ʗ3HD]%FWJ}0|" 1%dSEĨVթyH9Ia4E cv֥qmHp0?3˲KP t\ Uc_5'cp 񳴓C4oydYѴa>(ioo.e5 H"~?٫һTW2K/nGcI#|7 I,b˞>>;pM֒IG>m.) ,Dn̲AM/]=5:R#BHe`, hc?V;J`x$V'3lA'B>])Lt*x=)"A (p y19N 9b4 ZǢ<*8g:dpTǻRhfF71Z|_fM} VJ=z so?ѮR@P炴*z ܜMH`{zx jAʘM)7T+уiQROd:ICښgLsS0PT`A#3Q7R|zc\砦."biZfzb}8;z RNY,t3 WLj۪F6jgMq$#fF,t`Io]kui:v\܏RjsS#,O;bed^an"1IX #܈%͢,VC,G5zN8nF[l ђ@•PPw \qV=8X-~p5!-x [$JRY@x[9\ m;r4uU7l4ڟˮ nnd"e%,7߮όQti$#h((UF@AaGS僼s~" W8gZN#196бQJ9Mqis>ˮZh\?C'+vQv}Rx&$Pn1@{vX%VhM$K (J M5|w1sw@O+VEix{T $+"9̬%us=qw~\\K07ݖF8T7krvQg7+k^7J1\'sv%,xCGTj4r!ɑ W?eA69M>:J# B(D>mcxֆA5j )?Y#@Zքx2 e@+5. Xj87w_ -/a>Gys%!1RTh\? e*X2 AzxabV[f-&Xs\_b;B?i dMPƞxIac*@$<i=<0l *A 5-<8'%/AF 2Ҙi"BYAj0J(~DsAV!tubd|PpkZo5#*dhpUѪ3,:_))N:()L,~8hiy"S?V7+Ũ4ʘTj5L]2 5b8κav :\W!0wm,J!Ǣ ~+F͑L1\lc (=N%GlA]j^H|FG;Z߀COVxoBHY\c|2Z'hAđY)ީ.Qv2 q 4Wvo5Wzʄ: * E+\.576=_ b/^2\$Wr(ܢ%XKXLvtD+$K\Y0 EܒC fMԭ8ǂ,&~:i, 5fvVޤœL6帞U1YB9;<P-Im3٬TyfE rۉ-? z:nCHָ--rfMu.jWsvz|1s{@y2࢏Y'R9{*i+#Wqē[LziMǮK^IUBw E#ޯ=waa\u4P9D2TɺW\%8b4݄.@ZKg3PknXX;۴/cʳq]%%XM>GVV׮UE*bEQ8Uc0&F2:ѕT獙N1]*gLPSn<|>zN1ztՂ=()\U4ʣ<pN4 4Sy4f<) I뀋@I֟ iSL~uF6|'p\[v#@$ $q> a(x6c <ԝI̜]/x s C`6/8 Xv%_ZYԀXPK Ҹǹy"H-QHж!Sy_.BE}#d, ,+PvߙqsI7KH+YՕ@"3;Ӟx~HUBQX28nrm/xح:=m+X 1/dwAeVh]↫vr#h^ޝ޺<~۷1:#n>5CƆӧ\{;Mj?`8@ LNDVRO+Ӯ Ubfhficu.!.E(?~ A9nT6t_T1F/? E=515@uM0щ{-M|\:Z6#Y6h5ք*ʬYS.u>RiZI T8d]͕hDt FHdR2W~: WZ5zQV5LnےP:Sש E#@A,Ft&g);tpcv_uGTxQEEN2Tx#saCb@_iy+oG2wa!69c{eAN7֝p*jz 6tiHi;_ۍ!@nc_ :ezA瀴קL 8M4ǷZ<~Rt†85h1ZyqFk5q,p,fiIVt"N=jF{kCP|?aIkS?sӦ6և_ߎNOn-N23A5m=)yafkAVc=0czncA]`{V)c)lqoW*h<Y`֦=H>S{fM>*hn&k}-Ç&wČ7MY-:(.\~[O3rԑ,Zz,fUFb@>3ů'KmkijҳRjRsyMlIV_<]IE/y(v'!wq\F;$ziB[2i [+VbAH Nػ ֌i? m]iF.ȕh'',Ư$ƙ ((: xGXC@fs#hy8+i;Ww2ԭ=9<vDIJ !UM N$/!$.M)lxب z8-s`Thpg8;$gNS!OqN_ rō-.8KH9/~9LFomVe|30mɸ`j+YkXy+9a:JC3*T6܊7b^R^Qfkg ֪cvKn]y,qp|%kX&K넞$Ǹ_5 8 ׺llQ2R2$A#hA[CiNC-uzd {(\I̜PLUGׂ_I< ҃Su: cJhp(9Ӧ̜zN^݊)*`ꮃ\awk0N 15֘{~C潻;dٚf+x*aXAEQz}_roOm V|HUJJfA#r$vTvdJ I15&2 Mv/:DeǶcFa傎W ɫZxxa[K,&t4ȏ,A+y}N@*K,P**-Qŭ֗I,ER/oہ PQ,wܼ|vI,F듹3L-wzGuŗvGuc:ַ09cɂ:9㨪1>O˓,Crq"x 0#n?PzWXkehs t40J;c/\ęp+b3ЀBҔ#=>Qwz7** pSh}i9{1O]Bw%6 5ԑV"rs9Vᕉ.A,t-^=pZ;0͈?X0 |+k彋[DP($$`1dKifw e@IBrP\׶;RG,rGM;UXfT C+VPw!m='L.&;[98ƔjQ*K1ťarm)dE/bʨ\@U#+'|-<\̑kKVhGJ"0Rd8V|h|1S0JP?L(9~cbԞt V1Jt$7Z<|09qC<`2f LQ  599SCAN`8*Hxt&8 )}#>=q7'LvѼ!G 1aR啄R5)4=Vr5 ۶6\4Go(+Q=0y~--foXrC;ݪ (vH_I/;W;늷[#`@44fSZ.󀝑_߉-̪=؅~~/9K>J:gyUS10Cjpלo ƣbmxxo)KĶVZB\w')w+{1TnL:P£P_՟9q|Sfb}i'} UW\?7nٚ]kHS$Rbƻz[w7mL'㮔oB ё殧&STV ]G>}qQ],L#:ℊSOׂOo׮(C+'O Vb*ڀW8{1'-$"2>Br2|ͭɛaDDZlQAp$pQM nzEAF2YJWB<6.W+Gчd&}輲9\kt291LۨȔE rI:%}H=>1h 0] G.cXdPd5۱ByTZ ՟$mB}^uw\Ju3[[kBƆL~.墎}\l:UI]FdT܊\z5rw֩HA9hZhe%K,+~2٢e%QDA@S\f0B7+ćs*P*W\OWH^wڕ7zԒ=5-qngC4k`v+b( dMSE<_)gO,ɶ7*HRԯm5*gt|eZ^+\#4-dˠb>pyHw +9QV6s&3퐲젮3zx S_eV yMq$k5H]~4M*֬+>hng+G8K{iP%C_Bր@ u腬VRATTrRn8w##im׎bBw0w5Jzk{=b& &,Ђ &8N>d*Jjkwj]{bndqH:qP0_ UA>c % 5ZSLC\؍0CyTqE\׮=?-s85۞Ybl,SGc '9K[[xikh<=hfy`ZH[% >;97M9>hmS-^5f=ulM% FB:J}@;TWR@Εж~L3$^?"0yZ-\7n~p\[Ĭ%:\7lr2Gu$f4Mdqq x-yKͻybqS @&R.揎YdWwڛʳVRWW%/1[9$~{uʤ9MGsY1@ֵ?Hmixe!Cu47GVJ˨xYcfT+; y4j6PO#;1cvJҸc:A;?1L٘1Q\Ҵ>pCb_k]߂\u"Oo6`W]|ӡ,Y*m ;@ʕ(Kv,Hw>3[0QUd?V?rD] ~a'}%bt< 445s-3N |--T Ⱦz B.tCǹ͉sm[[V*#+BIB(NXr(RFmmrd=Cp,Ňe^AUz,[AY(zV5%ʆӖXZxV HR}E]Y-N,V;l|7D. l>&1.RyL(;\E WsWfʯ /<*|p72hF m#HeO_ Rk6LPjp]|(0 ta]M r1ZӦ3>]qg,c\)=r_N;UѶ  'foZmȂp=[WDmq%PQEIhvrs\S";R^12k!{1g+S*vUxYk$@[腪WָˎF.N(汇dTiUT5o<1uakKsg&eH}FeW$i=qo=,]9# =^T\֘.J^wݤr6*!hk~Ԇ.{k mon;#ER7 k#ZրdlR7h$Y/#0m@ڣ%0xld+I 8ȥZ5Ѻ @ʻ*)_ |is'%: [>5?Oa0q QZ$󗰿( 3FY z]te#˙x7a3Fb_ڙG$MZ`:9Rc~_ 1LmoíV6)ִӮ=f6k\ `f5ȂGXTXܧMzejMkZ 1Eqmw<unN>Es.mZ{f9ȻM%?eҩ-}4θn ݫܪ?b_PSR:bNC{oc*NJO~4w@2$(={?ܪйLhEG٣%s<:raP =3XI ,ܾ}@Mp"l̕5:"\kZ,I}Q#S xm-pmn;F{T& hF9=eǫb,(vnT'at{[@AɁ\E{pȓ Vb?(}Yg ;ȚkIu48!*\ 6ڷ;Ap4d#j!iCe⒤Paҫ\7-1:"q&4 hBo$Rq\-5"\YO I.N=g D"Z=}YE[cTWXMĭ,Df27)Ps +.+|deP6])%T.Qgs9^P6]P.]^7'%JA3Z!:OV 5Z>[9{ghHm.n%3BDSH@jycĻyy{ 5g[Hm$%FQ5TPN-EC {rG nM#U|krqi+En\[T*&anpO=䯽4rv*2)AԖ(zZV7(W '_%b>ˈ$9+ ]U4UaXcI%!BjTzwe~A&KځAVv/$ɒdu 4e- rBtՑhPdOZWr牣mm{z;xKy-c621ncܩn%F8M,eA0)]jrN6CZT덵ԀikPMl+IX%Y +NNYL2 eSMb|'y'ِʥ![i MTIXW7Y ﹣Fr!nFC t`2>YSЃҔцv jEpvT9S㗆 3 sޝzkQO,UIt^oxԞZGPGv܋N6)cI%"PI%(/{c +vg2 ۑsSN?*{Ilvrr;"Y! #PeSSgBh=~Z6R;I퍹fijJdPXWfͻ~8.GqpJ )$,H؀ͪrNZmGhnm'#޶>x dT.[KƖ4vQ5 LXr=͵͗$33@Cn#rntļ{|OnJ )#i{M]U4sUPT'9nb"))_nu;yqs1csVEaX0P~e_Ǹf>|p₠+mҺPTa8GO/߈ A&цAVT @FPsl`|yPRbүTfTx/yZc} ЅR?{͛ _ E~?yxEfNևbNH5v\m,? a$Ī;30,*(^Tڐ ?׏l9+bﹹ!7la{M!TErd;RpGI2 :͘( ex"Mf2H`hL2 6RW!t*΍%F4̿++#8}tn#F{CI@7F>[;d"gdW%MT4rB2 F(˴RF8l7sw\qGKH'{h4~jMnvsǨz,6pIxn*Ȋ+:|qgjNCэM(?bj0 uEI3J GV4r' x*rn^^8 [ lZĦFM/{Z#K;K%՜/u4V{F`=ü[er ڼ6`l$R c-noUm-&q=̊8ƊiiGs#{rڱv+NiR+-籲oP5Z^'_[&d,#OkR[xlC~ =έeRm m porr-{i9'BqonOU!3/!ǨVQf~?潰l$0%0#^ GF9 ђ^6 M7iJPPv+1pӖ)$hK=W dGG Qſ)`hw0 +ObHO#mj(Fց $1!隮Ub4wrc)4jmšF?s`Z-)]F#Z[y 2I _Z(Ιfqۍ -(h+\Ls<&1+@Y/ ObPJ0q}:>9onFvU{hqo5.j lRT䌻+A :\)BG|dF!丛R׮ J/@i# Y"+Z֚,X"`Ib(&r4joP Fc dHgJf!w7hR mʄ }: .wb;ly\Y<@Ԛ?T7!I J/kCq6WEwx@K=61] 7#P-~ *MUqw$͕ջkoOq娉P;zZ^>9hZ.VkIvFrDaJF-1&qgi=sD-d5 7.ߑh)t-yxP'QUU:vS+C1OǤ( T 鍻H\\vE#B0jYYdf_vP}mE3m!K4B 1XꞶy*;+,cEF+IvW~u4J0betJt$s[PbhYeOQ "K[skF=Ej9`bg-Aoj7ՔW_wGˢ%qHbv`G4`pV*~bPt#:ڵiqk ~b3}|d-#Q]34?~@*ፆ @' Uڬjw*B$hr5ەbzʸ]K0akN( Pr5R:\0g壥7 USUamaVdƕWW5 9ؒ%̫H,xh-4j.ET=H2 @: ȁhw4,%O*\G. A҇a"x 1#p^\/,\շ#uؼ!eD G@;=99,H]g1R )tn۷21߶ܐʂ Zb^6+gMG thaJH!b9k\+6Ӱ+ѲKjUS0smը3"1%H$X3n]y-ʹk/q3czh(qP*OL#LZ  ֿ 7g "_,R3u9YeI59eU n'!R|p+_2֣*|hGClX$tʽp(@ PEt8*O$Jߌi?ȗRC;1֋Uc{rf/ =R:ƟH$*S8a/qά=HY7JUB)gW݃̈' 4w+#ěJ";zdv(&.;܍_ym𥬬^5+_n8Qn2P׶󐰳{3Z4\(yvn&ӻ>JEx%6hPFî{G2߶9 6WEeI:OTi*XiBwxOXnٙik( uI<'|/*ljIᵳ{vcѷIo‘͆ Mw}iܭѸ?}gm?q46VmkB?<燃NaR-$q $k{C͏\F4|B<6qKK!"+f\^G!nO' SEF-94h})Q@2 .ynJIn=Jݦ1V NEJ郶a\:*N0&xc\Oz5cfGqI58>ښS*r` 5• ΃󗱭L@cZNj[aVfA1/U(G&ծ~P/t9{HHu`G 3P(a0e-TV\a${I]Wu`Ns>G# K<2RxgJV0q-@aڦθ/-lV;WR [},71F\d1H%-ԨJuzC\LLo)(vLR#X?djL*G\NlqKF <6qmo325FH;  rҤWw[p9I2z`C91>i^H'C}_ȕṁ:F²>Zb㹝c䑡V3W쳊dp"Q--攒5;ce+{YBhfDeASePnG+2z@bs廒&Yxё~1٭"@hUeo38Zڄ3R=sNLθ~W I]=z٫҇X]/i?rQwpEixNk}2$_lX"Id5l„P-2ė]#{2Y]kfλcTAvwutW̨.)U`j}{-^]-ԉXo(}"ԌokH3()s&{m.H%IB4ruVWbnmI%eHhXVbƴ>,nyi<1JeӥP2 e8[NZ~:+ȿ [/ȮʀPP &3OݗK:DZU4ԩ)k ^Iiq2A+sty5ɱp=%enxNK7wyG-WT )$L̴;R!؁vUo+^A8,XDąHE2nX{y%KxDaG|(E-A{.&g3+Q<7 epHNu={޻mf/-Ոv<wjъ#ƭVK^em0ngGd:W,Y,kC]uij;x#1#2quoK[r#)!uL3ymB8OXsr|JI'mks$;i-.G)t@UPi@ZOc4sxޱ+&{!T?1#xR8#@'8DZXv5j|@q?N佌\Ϊe$4WsZՎifz3P8$6ѭDz*MwGS؋ Ek2X|]s2;V.rlY5j,W +S(0m7yei?q(!&zhΧMn#c6+n`>"aPҢҴ]D'RiV6ޙ}^U{L V'ـJTiOz , ³{Aϩ@oy+ "L֨Wn% <[XcRV(k{N>Om3{CuViLDYzRihY1o 9I(WZq7pqh4wQ1,"fCm]J/ mf\<+4@͹:(:SC bu#4ET ~ dhr፨}N=1ֵҚt, v=A Qis1:2#@rbBHƙbB1.uDNNd:bAmOrK ͉%T%]}.FjV8yn9nBq1Be;h6^bzAmamې%й%t`j.ZF (9o¼ ކ3KM[ԊI(meC;jtV9]eBi&flK/=#[o/%9l; '$ ya~TagZz+./x{7${Gq2'@+v,(yvܓ-܃4JC $(tiq|v;C-٬ eHцv1q\UO=6_[~9ll'eC{36죇G$(4bL"W[v|I٢e>3F64֩)5 6Zߋg[Iy wv^IAv-K׮9̩Fy`(E{kO|THӦ I03`銌5$7(T>8(ٓ`J!\{ye`zT5kJӊ"Z}zwj)ׂ?F^N`]VY#`]XQ)ȩrMdy 'SVs/l5d"oޙ_ddr<5[^9_u{1F7> ]pJAeU9 &?2^~'q%̾ ?L|c"oc]>=2|۵*3kks=j(8+l2OJіe$zs:Ԋqu8+kծn:$C({{y슴6ې}r և<]/q3¢B  Z6_XVgr\ZēY4q  PAA&Db^~F5)?gYTUYvJ Vn)$$sT{+EcbN%9A5}+_Xa&:Gi8v=ۋ)nY q) gr +V m%beJ%r5mu9/P_r\$ (HАDPf$XrgueKee*UQC ۸,rſɏ'%u'vіS(لb=8NVПdĪ .B81dH?N.~B+[yck bLG]˘V4a{- +m#'紴ׯJv-yO>T3˼Lq2xUW{=jћK -ʇW b@6ſ/\~;,][e̲D}UROp`w?y},I?XaHSv)+Qp ]'\P5<.(}@R}k5H,d*5b=*.>Gk(ߍ Vajd$5ןyqp^GiXI*3 em\_r T PR櫖^[Џi{m$z;XZw(6Y6(Q3Jg?vc{6$zmFj0H"L4u-2H󫜽JpmAAXrZV}8@SwHi]- 10TFjr_è9i Rl*ΤSTbVDt'Ćb+UW2G.$m5 M+5 +\Yc f)|]zEFXT@v}>Zz3fuҧg6]FOS֝`:5!Wr B{Cl4PnnւG*sT*6c_m؍ @XKO2ju\~*M2X gSPd)P>FgӀXd|k\5jzeほB:GDvȇAj3*83 :wLmzrV>͂ЃQ2rb?#ſ3爐|}6lњm)!P̋+١E+EHq[ܻW Mͫ.!^H媟NЈ!SbٶavV]tǿhV!TnK"pwMas׋/Zo,#mM 9`.Nn \wџL1*zzĖF%#$TR?~G=aRj[[ۡ v@  vʱJەۑKۼ۽6ncwutX$sVΊ؎n:'e$pcAn[w{fe#| 5}s#srC[cHw )L\seǫ.+˰* a4JA"$oC[T9)ʼnkJ+V.Q*S ,#.֖EvB1*љ r= I$pG-7boZ{8UED ga,IycmLF1K%]+U } )]rN4" u( Lw-z,AUTfUIe6ְZ-f`go˹2׷8:Os4/ tB Vbڠr=nk-2[Zr7!Hw?xMo$Z[X,9I%$yv,B [lhX2!mk2BtpE<%61w*X%mujQE}j+w1m-a.dc \zr|/&啤S\hP*Ǝjv07Y%ͭZ {K} $ijʽԍe!4t02/CB"m,M0v/A@*;[^rҐ#'a۷5B鮧vJl>*"Ts޷-![ԣ/}A!ԃiL`3* 3ϨՅeȃC@"3A J + ,DEr:hºt9Y򜭴39iP=*<2SA\2P ut*+_hj́jIhhkL{w*āF"Όjh0O6^4웩pCxK=UVwr(pƛ W;kMM~H쨐L25@ >VII mݸiȦZGtY6;e@n4L\ymA@Ơ˯:BuZW\Z,4끴eOǪ|ܿ9y 2,q >Q_ܴ|ut -W#`zb^6϶ị- *Q/hk =2|m\ m#0\a{ k,wn3o1 '6$P k=Tt4s5qGqi{r2:D.*\FxKn!<T[vzJ֦ #4QᏳA7SSJt:m d29נ ֚uՆTҘik 납̟H4ҽk`{@|?^6 ^67ms1B=#2+J 6S*݄?1Ʌ[װ?j6)=Oܼ--%l%t/jU7!F̿2 ȑQYր#7BosܰPF=4gY9: DpGv=X!V5PeZT0*/=ZI 9Iu* %+[K(8܂֞Ő>I-\g1u-.YrI+ Xf,}PS>; S>: Im^ݸc,.*E)#Q#lE+{2n3DVmv\WW֗\ot.%15_?,%vƃ1 ѱmBj%经y{e0x5O$5b-BX t!ޣϘbRDZ-".{J D6ڪ_R0kZF%[{i)my@䌫Qġ"L>A$xhsjb}$\3R \ͧ-}. H6`*1!4Z49[Xn'z1]q!ȅNWl^{aF-h`Ԩ\Xw'mvr%TȢCd6U48Ȇ>/_y]eLٕo+-qqUaBĥ-ne#ޝ4dR*rx$gC]w[[a io} qmr~-u`;ڵڒm xQ\zy)OO²51\d|1DƂ]|0FF7]=dFB*|1O]F kT=[j|rh|?V&灻nxScr8c"<f*y⧦ZD ':/{"q/II)o8Z[`᷼a\[Q1up^J3~eJġI6LKZAp`e)4޸>i1v;D Z- 6GGRqo s:]O5gLo^e9>ev.Y}#Y@F`z8;>IB] %xLiF Wpӧk( hzӮ4>dֵ=|iVpTW-k0}k<5ta`V3.sf"PRL%(GA*t8h'_ tʀ0#%kP$ }? 0\U][_SBiY` E02%uz@)Ǵ韀3d+0P:}pF>85ГKQ_-Ǧ( \P⪧ZRܢ\i έOߌQQJȟ,7a~[eMVKs!][i_Di*)?(,ݩE/4rTz"Z2(iif *3f~;^x{k[mZ{wEh1BIPyq_5x5h(" "ڥWuQ?|oYl8R@m_r)'Z0qt+SQWSМSBӌz m*u0r *qq"y7fof8bna wWKz>ۚ,Δ]uT62H%0!jZߝZv=s4ݽ(1VxeX49&ׁh&a'(6wq.9NF[Kn@FO O1*g܅1$wvYqokn0=r+|X m'ev$2r| ~-m. '˔p(xK=򮼂M˰3ݽq֔(6FyQwa%#i,(WPݷo .ӵVDơJ~VV۹g]u;qvV䟃6ps4,:5ػ[kq>eVsPiA>ZdF+ק )MO)C\ʕBpņ^C<m]pp?݁\ʝ+jf#c禵!hp9^`h:c\:igt_~=+eQKVeո-oYm{[YsvKE ڨ@wDC0m/*5+JIZ2s<=7H;iRH xxga{tb-X-ۆ1Q,4< # (xHd CUť=KuTThU`l`l+n^޳C-=2H"*%Z. //9(\ڤ J Fj@DŽkIZMH Ƭi m{UHVP0RFĶ# rWS\E!2fc,]՗Rrş3ޗp,ibӐU^i__J Ĝ ݭ$,uIR5?H,N&{}[ؚ~r\7?i$f⨉E!e%+\rMM%IJSia$"h#!pgMFpx{_L76O}J$S eߟ2%xk3\ j}Fj %X%r¾cO>F|jTSbf? ‡\/ )5$Ps?=ByaKdcFB'%b-" Jҭm&ET]AZ64Ͳ8F?`V孭dbS 3-j@5|P%_5 :JB[:R7kumb_@v'0nIɹqs1h} m̛pBK4Ur$xBHR h;TYB)Os[{RrVڣ,Pqc_]B(*@O\߱@yw{vr~HSl=`=P򁐧4o}FzfЀ”|Y_2]ČiÛTP6+#ǭ>!1U=N6'`-Q4-QbI̓´. j2z9UNr' ݖ/4{ NlٍE4'M1 PV\G>uai|GӂXeEX*ֵڠTJWi\)ٞ3)P UMI\NILMUE@ǣr_,  ֺaN^;(/=̋j:՘m仈55*ǚL-K xYyBz 0'e'npkoE5A?xI9r+[IMxח JU8OrYgIZ-r䗙#0&>Ŵw-.:Y3*D]"̑xDńSJŴrEZen fN&?g(,kmmi% l{\ ˩ZsVjsvTݜ8MTֳq{[ϛG Z+Fx_hB4|R\6D`,s=ۻm[_߰Ĝo)q< @[)܉M'MjTS,sGH,;͒-1$xg`TxA1.B8Y ȘlrnlW36jo}?dvP$`1}$KY+G[KVLR [@O%aagXBֻ.1u( l1с])>WrD[a,<ʵ[0m.i%(׀o`(O Қax>KN6_r 3ʊ*) |9 N%{ z@GƥX}X{ )7oIU1r`ČsqqŠh4P7iu=qeȲMvP*jB+Nx1X3QukQLΘPI<ڊԧ^1c9h9L=JCR[C!pv#u=4jk]3Rqc`O/mrX$ VPO?y\)p)Bt 鮘K0im6s(J=wm;8K.^I,S"AҴ*HQ2x/W!6qz (;LۼDs8e_:(e V[T4JŽ :T3~j XV%swm D,o@Qjs<2mō! ƫ G񉸲|=kw\s\7SCmAvB-'`I*Zu,vB3s5-k1kx %U܎;*b!}ܤ]Os,`o0[$m8-kI=3Eö4&jHM4 T=XeO?,/S jV ·j@#z|O6AZ0CjLG)u8 `=NX#J~68(B6^8ڌ}$(AH8UḌudxNax^KQr[cfޡVF-OHĦEIo[[ P T9l u|Q7G4Z*B a78.M2 *k]s5)4 p4@qB+GO֡k|*RLuƻf.[g>2ȊOWC%^ B ےS*18VN_&k{=Pom(}#hy6I-1RO\A$[5jmhCbm^FE3ݯ(DTNa[;XZ./zShJrU;܍q w Rm5m GГt{;S} Xzvs}UC Ќ[.n8իGtbPs%8u_P1 dpJUa t]|za@q+Z :Tg7 RgBEN^gLV/t !+xi=A^p&BE#Z\i@dB5[S 2)۶ҊZyju+3RjE?jb5ZqH} Ϗ|pT낱Zʘ-)g5Z,WFc-?O%8-inLEz~UuuNvX݂ W@I$SM~b r {f0!G6865F@w,gvHRt A$ X+Ze PRֶ<)b,SۙeIW`c.ynNycRn)XHe特yki JGăJ(P1$UIW.zmێ8E$Oz "Qq9nG\-R T/A_NL ؟w\޸iۘ>xIΉͬMĉl T'AFP )኱-O PLQ5>4ʧ-L"kM @rW'qe)]M#T| csKqa; fϥ?~ aZS`+s`H_VӚ&ϚS\Iˏnm94|F ໗율nWw1!+?,y;am(n:^&?bd67 Kk̴H#Ԅd+-gFjU–v2 SV4 ໪+2 v%L,eiJ2IaԆR5y:lxPM"yVITFzbn3SݱQ+vUtJ&L`+@ɑ9r%r$9%60r~t/j;rk;MIK&Mwxw L#GB`ԣ bKD׼u'2bCU]ލr8籊ͬ "bǥWҪ*MqrM/%[yXFA4;q]mo~vh(3,[X>XT7kێW2gz (~P 鍀G@s:Zӓ_*`W=Ll?d f~pVu8ji8,/e] @x**"@%|֟]15 H )Zb-MtǦ6ЊeZcvfxzd~aSzb[f6}\y'wܒ%:,L{\Km9K`c heQT)e'n d,QEՎk_lsI s#L\Q hspL67Oܻ!$?8@Oԑ $Y3N<2 G8NΞX,i+CQKiP4yȭ DTcij°_DV9xS)QTihk` mT9 '3`Pץ4(s:8UT "9.gVQ0wGpZKsɴt3 2ݵ+xl!ؚC!.їD (UC?n)aI{H$Ud M/Z ƴX奶Kuַ7.#R 9,ekMN;nZy 9DVoEX{DUSNtᅖY(uK>DF< r{ (_zZ uimogImv$MλNA*NԮ!Y e9Z_i2|>I}6 7!Ial`I*P4Zg9~$YQ!!r) T<#Ya@nx+UPugF AԓM'/;Ӻwmࢴ77(r)rĈYlي0$/csxƲ[Hj,+FvƻEd[[;LuS: $6P'\Augp{4wα1Ϯ.Qۼb3e{7}dTm>o+u-{r\Ƽ\Iw+APUW6\'(ZV}"_J r\g-`Dk˅ n`QĄF go[XH.N#nm`i~p$tK0-{;ŹejٸRk+ ES,{)qKzH(5rCe}csZ𖶌gk %4eS:miŷmm{o06x$Z֦D} @]u=q۴mP L@"IUj0>3m#JKXY Yb] wU? $UOtAC7=v럁2-@dB5LgZJϨCNNҴ ]3h@$\h 1廯_ ;}X*,҂v"uE yd1;wy4&}+86Fۼn #qX2(>^=< 齤O)?sq4Budce"w :3ڣP<|i郘ʃ=~{ruW/|O(ONc_)A:`*C9,r({:[]ҍ-[H~#W`efcTӸU&F% ș D$Fx;aw1)*LAhxf湫 vo̷QpB[v cGiozZgf,T*1ex1Γ9FX]kQМTj2=0Y"zt䞇hihi+OdNCZcdҸ(ixA6et/1lk +\9!rmc4h)ՅSnӐTpX#qɜ/ݮ7wԮ`;K QaOO¸u2ǯ^nK4PZ,)6;qLIE<1II Yzi!IUʙ}/#xf*vm`MTsuԕ~! j_L{@k %x #jjV8cdK#*K9p Y/8Fvk[eG4_n8i@Zۋ[ EH⟗7`#q8lVЬa}?;i نfYEԱt닾~F.?Zq)̓ G9" , 0.. R-~2z})MbV('i:p~grv$v{xXl{OvyG5m/͕!8'ݫ Hlë69݉'-sl<E!rK>~sż9$Y8LR#A!~>|w9w-e?J8TnWASͮxyhZ aEuԟqF>pf~ 0-lկJI*jK,(vy.#?!y2*]ۆ\ |=#zrWV wX$`d 2ƃWswNthLJ/n:WOqwNCi9 $m;cIJ#nom6yC|3혧 {|m%~4,Gc}ooKL+ʫ-CF̀eVT)FdG_!`LV@־~~Xy#,@)9m J򕑮/4k#noeL0 \.l?/XTT2ԂS0GMsvq'e؆q=W1qe8Z Iz~#T iqTjץ)`+~`h2ӮP6k13dH8a"INs"* 1ui~!E!Hy[1]چHR}-X-;gUMqsO&ODsMbվ\_v\1wdVٻoquzQ\cV㧊N$”s`+JָXH#ܥ}43gpYҌ =~VW%q] b?nLV36l6^Չ Uz98M7H}yEGZB4p7=wJ$K%Sj}"3L껈3k  XE>~F}/AU;F di9nJWA`k"AlPM3᧊?b5}"5-\ݞ}OAO;k]&fkC?+phb(+m쌡ƀx`\q[of2vYOLLD]YHq9AQI+NP\;Nfb=NJ1?XK-=C!WqIԤN$;B0vQ*RsX!>ѫ++,ӃIPP< `=j(cr2ˬQ?78291Z01=ܽI-Ȗg[V;$Sp'w>SB.nI n#+dR蜊:qKP8vFay&.޵(hZz [F)UBN;R7Rҁi`ws[u $8;j:WRpmő:)f$nl"|Gn'9wvI- z)Z@Z79n]yl`aPt E<ڬ>n肍z91/ZX3 sZH 0.xz,26d!zVYxolo9ɁNӨ, [k}*dSA0(-#] JAi zfg_o%ʛqqK&n?~ԩ $CgoqI'|Dğ7OWch ָ̍rǨӦ`1̌ST1Zcgxↄ|4NLRMy=51U p)iX[uys)E*Yݏb/G7p ''FijD1].H&ʭ$]|M1kV!q]o6 Be@tS-vM͍IvՉㄻ{[DȅeqRd)d仃[17Ci`BH޲ERbÒ崇eE(R˶H-VEɴ*j1{rQƒZqM%, (+oZToۖ8iœ=*$E>z畊E᡹ qvd%_pTЃ?裚f4X,Y%W F߿8nyo EnJ~i҂aeF;[q\]vj6r k} 54ɔUFz0 go$KHT\pvjᣭf5R%\+9jFBRC)QRHc e${ڸЬe>ufS24 {Q4г9tApͤ0XB=/C&"{wYd5dKԓ]I4MJG@pȤ 9)PKI\ނkhi¾Yp?@ҽ>O1 :)pMDnfy8;ڪt,5熕nXԬ!GP'An"JT@~ #I5 m9ҽq%ʰ4'%,h-s:iI BTdT?2ل3%O͞D 0u7JyĐa#r3$s N34?u'#~E,ԁ"\I$t`@)ksMtYK{ ̆ى*73bquRÎjEt$qt/w^=*6D;YW.mlWRqpuF-Mg,K7i*\螁Nx)L|D\UԑKzF%i|'qBXjAi¸9+5HpK*>V6,a/7no&v dqЮTTݦoZ*TdoRhmOX-U~֖spGBtD#J/SSS4WM*Q3t. n*+Zh|0|`Iϯ8-^L6r=AX6?.{nH|PwiOv+YbY$#kyXrX*b~;kc/x;HMjepvWR͢8)fL,p9Z yK =g=R?ê5= HN\uC$dtRi=b{ wc/T9Ea As>8,H#Xv[q @P)*;^z4x+YhgvkoIUá'\/y)巒HL壍IV@i8^% !** m@2kV ^9l6|IK CB(Vp[chiI#nz'iks3M E vb"c]#Ԗ6VW0J.5 TQF,xcr%d+/*U8-`6ʩu-ɼC~T),~Za.nG}n#소b~ŸLquM:,eaGUVbӖx"*Iy}ѶSy 0xfBPB yw ݁ik[bV1OP1 ][]-{ۦn䍪A6ըL\My>ZIP:#T'Q\B/sJy~fi@2JO%*(rR]֗-djD@X(msdݑ=q1/CajzEVl0"57P h%ԳH?4`#dĻRpVKK)npmd2IbRգ.9KNRdV+maKhIQ3dja_^Cylt+dZ *1_I9RXwo{4Kkq qUbKpvt{[-""ޣJ a5VIp*jjM+UܕXXSiYWҭL,I%%Ei+@ta>ng"`s/y?b63#+4Xc}I:k89x`H?f=S*1Bt$b%/+TjYk꤃7sofc_tI%=ROՉ{3~(8n 戲ݢi[_q|ljA{蹹M眂ޓ۫!S쓖볿2.>'Tk|5(o_i-g绖IRHOT tw |V|!6E.,hU I$K~>BDWEH(n4?FkҔix`u#c\m² E L (+Zh0HBkJwVҸQiV|Vw|ohFPqVZY9~-O%Ʃ}h@4B섛խ%W~:A?/2}&* N8~f^KdCJKnL2Wrac!Z*5NdSObFJbRhMs'# ṼクB1=s|煋6ESxkz)U(Fbiq$s˻i:@)Je֘*҇hM I9D](s? wRλmC_\b* @:Wۅ r'u3ɞ+xvKj4.hn(&u4W2^ {Q~8 ~6zrR֔ǩfP(5=p5h2?niֺA LG0Ppܯk33lK۷>6Kg Ȟ@[[}(89[ Y")>Dޤ2C3,SVCs[.Y%}ysQhL^XZ늢/%#"Յ=ek gu:fp}n er#㥨j)uVkJV>l5 u\Oh5"NU[f(  j3!3.}\tq5EdzL ώ'+vN^Ls$Ǩ2*NC{sur55x16bn[ӯ$/* )}RBۃlm.nRk iE-$gp*CU@L} w'ᏵWcv۳U`\LkAq=o+qn&k"GdQxʹ(]v6n Jo1Gn/,mRh5pbVӸ$)e>YXSڦJBĜt vJi49ֹZ-9"] n1D0lՇr 6=PL sZ-\Eusap 5K352U %绮&X ZeNK;;+s<1ږH6@F$Sr 48 ;X)ɤ04ɸwRDrjKa޼71Ht tY1FBu[W"i9"W?]ܮnRc!TFyz,8$^(G EVYYO6 :bn-|{e Q ԑKjhUZmQi㰸Cم V1EPBU#9< Auox?}X4csIyy$vYd`(gc5']ݞXI^YQB-oLX?ő%Ǵi)ahvBWMsfw9"a;ٸkc׸8$ kK>ɾk]D9M9;At/wyƱCYH!NQl+Hʘs=,a}n^q\K" ER ;%K6lE&MU> cZ+9%I6ұ-wgUQL+瞿 U&ӭq#S քWx2m 0}{jSGm=5j240%]W)B5^Gr6SN;S܅hC Kۜ|G.VtbVK[!S,vX؃#Os*B9'ѩʡ*zfzZGӂXSabjj ڐ!9ă% (&&"HdP┩>_*hu5 ?g #)!uץ>UMZ(ϨO<T%00p#g:b][o(+L=IX2r=AJ`9%4`NM@4YMk@5?? 0vLe[źt鏹 VE\XxWJi6T'cP H_b"ԓZNV7ۉvB n]AJA# CE?N0%I qb!j% KszBJN@$~9W2;fZޥy .ޣֺ RNYt 4U APiz`0_PQZ`{^ˮ(E 55fMs;SiZrO,\Wu|e^ \5*s4,s8#JS!_ۍ^kspZdE_qF4SP4+B@pXj40M1/0qwT;9qsCLE+{uN`).%B3x}sGrp=Ks+#AeS#GJ3P_kXkm g[KPV" RSZ(&[F nIb;ؕc#>' LE_|5{q$ZspEռK'FXؙqX'Xd}VxOLf2M6YCe.فy>bO_)sYK#I),uķ6Qe0.2_C 0ҵ)19+='Lr}+mb3!Lt-w&Y/EؚR4θ^y+~ ~ExZF>cx4'wT682Ni$UI %Vv=伥Av1)$"rS2q=9TW5 j=9q~\Oi,W-#g$x=-SNA}XoyC:Uy̥υ2QE$c {vdxY>۫e9]M#lhwBd&^8/8EJ-{VX}o**K6رMqf҉= ju4̈́宧EkPdT%F{Vˮ/z[㹠9a`HxI6쌏F *GqM<0AG89:L*s>z޷'9hc`72#-wg ᷮaia8>ԼP=;/!]6ZVeUXEB's]5Ua7zWi"x9Eݤq=*BU+.KC ŝmHPu?b%]GʙgLKNa-j)Mwx <:Tx&C:a|5 %<=p1ϧמ"ZT}GZA(]j婲J{}ңuA@hk*CǶ\_q!m_.D L3beByg\jOmJ 嘠n@Ī@,|<#lrs*~?V?D+_m֭XX4ԟ bE_pݼ||pp39Vd$S (_k݄efZǼE&$v+0ų4A _#DϴY٣CPSSO@hɣ( HX[kEGI ;2ڕW*3&W2lzĪdw 2$u2)4 Q(Q(T穯L1jrz eҺu0"Zr9t+EՖ9 EA:'F⌇HOa6&aT&19 $`?=/# .O2ޫxDq $)A', *;kx8TbV:bC\p}1ySm'/*wut$+D  >=yK{]BFnV)m%c@NL$6TX|e +p_oqm!f-W']V܏qMskR)"OZ|-+o89 ]=T#ţJayF; ,1G(kZb[Yr0'Y]JSv,-\&:.Ks*7UεŃeݽz@5>c"Hk@s%Fir{XѨ -ۋnovXXx+o{sѧ/A4C ړqځN J=ꑼm 1=oy{`#{Mp6ʑ!!TP1[~-{<ʷ\1ڋjĄ$Քc}pVOâr)Q#,':ӜEs\GJ-^v1h40P9dF6mqˮ$&+ 0删qɘ+ܵ[)fkk7gᥕ6G e۔&mv{;cEVa!#Pq|qƷx#x'EE Gx4;3!"r&HUCrgU4,{Zϕi.9TnV$YI겋mO|.F#Jn`"֛=)ڀAOMMzq~>+\fB>6-(T# $ҵ'(ʞ5_ui!>Ƙs6֟xf *u=i˕Fu4\X~Y mw4C-6׵`g IZDѤZm;jgZhsq0d iJt5,ZeRO~:c"mX0j@⠫BZ;g+WƘfS֊BO T1ը} Q#e$AֹɻqM@*0@ZX00 Ѐ<"44ȯ-ҺuĆqXZi WȲ-F~zF_F^^8+kB31*>=j4劂7݊P*El(0?0 EU"u5}c󼴼Gt(e^;Ryao3\}p@ɍ͟ٻy+mxqE2k.Qn*p|]Yx˻kpL(T,{}Bc׃sg 2cLQd)?c`*Y$Zſ/L7q,M1QcL,hP2gHT_;Tddk٠s,LEյ+({rU5 2+L.;% RhTJ=6s bC("XܴJ5-qqݣAi_N{?]5b̚NeO.ýHYD"c`ZGv+'R>ˑ`4b6Uf1)$ $D2ne}g _֋-c]]ТS#/{{wuyf!,TBqŜRCS.n? ui,CTՈS#ZFsq.Q٤R33wcx7 ’:tts\I5x2>kf:t>X߲{j촒_ܑOL`TDEkщ.{ۀ.Y^W:U1Zt?5/sVKil8נ")iԫ=\u՝d{ |X ˖MFޘ]icscZ.ã%3Ȃ'^#Er^Q_40ڱIeᠶ"H}rȮBtfPs|7yl~A=ʱ͗hxVe"sƎk\5G54^ݑ3\!x=YDdx1t۶sDt#:0 n H0< nG}u!k̵#Ah^x于knE,r(B 5Q$616#+*ʤl1@UQ/nڧ'\Ӥ$76iԙNPs܍mv?iqqpvP#@sm~~$M ѣ}ƵN9 גǜ2[\ HDpFh6tZK.W_΁C=A"›j*J%xw)>T ME_i8nbd)򼱐@#)Ϧ$k>ǷrjV_W,ȹјUb_SUVnٷK.#"1EAdq5 ǹyR,BgZQ@|0A9kB(N}|7qwmV_<7p%QZ=SUhd91awd9p^;(EFR!1kMh;(+I(FIOF G( 7$~u'™W#_ z gCpYRRhAOCMv!j Wh4O:ȱC2ѐT9Y+.jju(Z.">8_bIv=7L+]elFBZ:λMME+ߪȡ҇LVu cG$Su79(p@!PI?$ 0Ox̬O!AmYk'`߸ ?ׅXVi΂}?l.6֕',PP1= 1W:SF9eQNB'Ld~4 k\M*2F7)epR`-h:S^aר SA]q@ rxW-1Fs늇# î^S}8c$_S A!FC=)W4sGf4tYϤ>dF"PIqMIlXl)pXPGӁ*ЃC XU2OF.=4ŎS,Yh}+[)5rXz?U1#}9qVYGB(hwqm̲-/eqi 0^]Gji {6F^]/!zf!_fgtK*'`iQbŗ&IBw-LN  Q)SMkb\<) w$ڕRho oX$4W{i,S zZht-5ŏjv9Yw6mGt4&M:AM<a;F!p FθyWH'jb> $QRJ 19(8Y;{xdLnI$0BQ@ _I۷nxrܯ\T셧e/$*ziBGӲo鐩AmIXY7cv=KS~>R]A;R%h ҘʈGc {9N[9n%&gX/ 7<3W o \dmN/ {[K9mLi T qr7!iۥ6#\qG"HVN-˓~楋63Z_31PpL[𜼗Sp\ʠ-*]2nM1=nHl8r\-˩Oq~YWU` k{Q@'l}H| F%#s5\q\ikc\Kh0K~1\lq}89lm#+cVCJ N2cgMy7ĒM>ZК߄L3P$* iwDm"KqBvCPՔ<5-~".l\\W%n4@`^<To!(;@ N+mp H4p S9CW᭚FH3@J(-&S1k?`ҟutPI&W5/3zb{nX۲bnjj•*!Gs{tDPTU,bdyoZěcGSRZW*9v2)U-|]q/R9.\}5h)I?kqTgܠSC XݵڶMk$_Qtk_\<Ȍ=rьb>w \׽{2Osϙ}WG -JZdm>üubF>^`3 YdyEm6ՠU yq$* H\2"% R`*()eG$#@4V5G]V HqL8C ]vcWvOxfR5EiLgh373Gua b(Q".^r۶^4£ƒh4P}$k ¬!~1{kGL<>]k$l/ bVS0}ʒdkh%E(i"&`lS<4|V\?uqQ֟ dFC/H&|/*iLn-kM ?MF7 k 8ҵ\.GJև1t|#.3xN*ݥ+%РMA,,NV~' }hI5o*cdA@k W/ (Iݩ8XC_?DzsOWMKQZV`DJ XTkZ5#]1Nշ/f?(|4ļl7q-r.XqK0~q ]{sajbH뤂*U;kH7}rV?l tnD">8X8N޻]G%gXԪDD{oD7c\ RG'| +im-nnۺӜO~`vg s^V7)ЬsH&Zm8?ͮAxÎ(⽊Bݴu$V^:16|Mhȃ6R\%Dw_uncqvܱypCw'5M,0;J2N2(ΘBnzMvKɼdJT>k7LҲA'ȕV⳵m@˼Uj&iSኝt }VlqPirUjC/B6呭.M+~sBSu5_3(L2-̼|I=no҈ _kQ*S]gȱC:3Ƣ@`bۑIji. 2,thї=QN CLcVhA$\$nD#U[A֌bGvBH?2x?4/̛v:be2?#U x3|$QC3'bKe2]#M~O@%R7L)΢鉿/FnFH.c4i፾>hM[ 7q }O ֗~zt ~],&獵%-xG;E r\(Q0.䶵)0$MV(~)F2bN,Gh˭r{A;XF$z  Q: YT@}_O\gx2$P:N36rc٫{g0B<_prP՚~q#^1%E 럎 0PG;~hAh4>r䞥v:'3Ҹ2Xix8H71ZJՍH5\Cvmr!4-F 5Mh;|F?q$QT9sE cXEdb/Z Ɉ*ka6QCfPMB#: OKny \jA|?^~nEzӦMzaَAW3rvb)O:f9Wϧ=\M4'*k@AӮL #&5ޠT~'jf\{[Qֽ1TʣQk@38/fOa|0_x+W*19z*Ld7EPi@L < ~ {ʽ=l4Nx163.fG=¡hc]=@e C (9u0dpX(.+dQ2eW\*vzS^XTSPA djGQ H3劾gSG0%Rv&T5OC]+Z-ҷor"NwZ=2j k.QJnZiM<9/+b;cדQ,dݲU<}{swa,vkws 2Rji@5A4ʹ89K)x>8ɺb{k]y.!uݼ'p!(q9)I\C/xmtOo+H * qP4RBQ'?_~]p/Uܣ9HĖRv7*& 4#)H hFj62Aѐ0{_ ֘nmGMrܞu1q w\7pZZm{.e@f=nJnRP FB)Zyclb -db܆R7TQSV\v<狊y.hZK PfaޛeFS"N#x;/!k+ˈs+akOwr 9b.,x08 \˷)9O^z+RV ~Y̑>򣝒p׊rCui,mj&)OP0RpC-I 0f[piQTa5 pf&>xy!9k(wK<"4={k5TeRF;xdH7xVpQƴW0pPWU Az-2_ze] pk{2\9HW\s|dw H{Ȅ1)uwtone6z5A$\CvՔ KQ訠Z⏠g6TΙet0ʝq]ƤP2kZ8Yt}_Pk#,eiF:wp$^jK$e"]A:,яPڮ $j0u ܾG9SƸ~9g ݮy6nW>5 {qf 2/^+@txFMhb'MDNxTA!҆?p2;P615ݱ[KF%op~e%[wЋݻ[(\GA4u 1q?v̥{[*+d J(ڥ#d`S<9!:Ww QѭF6jж@Ҙ23l$҂%iZMR -Nu^bBg4:S!=!wQu>Z~8HbajZ > V2To4HrUbz J\b~9eqd"Il^ ʱ)Czh*NZ,}cS6Ie:T f=4kTD|F V]39e$a- XFȭI #}ŸuĒ0Y{hIzG:eڻNiO SM+EOP5VR5XC +ꩥr$f~Į:x6PEHtQUziz6|xQ in3AQa㻈GB\̫GSo_v͖G*)"JU*v9Iktsr@ߋVH.$2U]oy+a/em,o Rbv튪6d +nc6\mݨ )3"{ӽcJ~)¾*-k=v5v=kos[@pD J2b(Bŏ+siƽsY[[Zw!8  !i ;~ϖau'J.# ȰSmqMqﭥ oud*YF L[_taĻC:I@s XC.ꔋo,\;D0c,*)sOઑ(2m#ZQlLЌ+B <1*O$ݍB24=\7UEim>1F^D 2 /+Q-x@EդvzJx48k^Xa nOQF7:ͺG3* žڹnf~,dlG2U'ec'8FFdɱ 3j _iQ4m5y^AdcJeRMO\v+M F0y2ixi늹W? ))AǸ֞R Ab+:dkJ`Ȭw&E`knv55|Np<yP"? }m*6$|dҙRFX[^= (XPjNx*Y*gqM2 Q6  PGӀHVەGL TZ ~rr[ԉK4ń]vsOrR@DtFp rKu6MEY3DKC'3K./`pa;-)h`L#e6EbKB򈕏8>޸ߺҶ1 +r@+Zݰs];rǻ3sjEHHA델YIK4uUSbH5b`Ev="9&3!U@j~&?{#;r_Ydf# #2-ӁSeBFGASlj*r'>ˮ$*ِ2ȜW@E ·ZW +jizǴtt%V$%PHSb1v\q7@g Jles'Ey7+E~UѦT`I0;B׾"|U"_;\-5 Ȓ >ZS/yV?%QW& M2 zw}ܻF_YGSRxK+(Ե֠iOىd(RVZаㆸ Œ҃?Mze$ 1&mziR|FǺ!ޔr)֟ %=Ԙ$2҃C y dI2`@^k#}@`)@:ƫ"1uʔփ@zX"PMhP@RO,qً ՟M[))6~$ᆒ(6֠,k妄/7pS`T p!_uU(!uwp :]MMAA`1eS: PkJi!Q(q_]q_v|HRwQM֞5#> r?\DVfʍQ@#Qf(( 35@HӞXK-*@ 56+',##L" ]($>4@ 4;֔0uzQԓeYFKбoF1]Cg 3H=: KPjL%ӶaBևιg%b eЍ65#6MCFRuV0F |rʟF M+slreȚd|>G}gSlZzAAOZzn oːTҀ'ycݲDX}AtSn=ܿVJVg2Bt C-A}kᄶ# 򮸢1()_ y5dpiܬ6^X@8$-*}U:u `khJ9eϸU4/V?3XFYlPF\sc pd2.mM*PhrDf2W>8eָ*,j@`~v||fQ\ `3rSZz r40UV\1]@u]1w׮8^2 Ow+FOy ;#ac ٨,@I i78cGW ~,9fgDI ImfyMUT3-5C>}Q49*(U0FӰqJS@rՈ"IKR g!ֻrϮ.$eo*SL<7Hz{LNh)" _y5o \D'#xxkue37R)+e$]UsBZ6`\fEOHiT-HVm6yi%fNj*)}q-'+* Zy]:amWɕ@駤,s^.wQLJS pƣa%P Q]tǵRZBA43<$ߙԥQM:gz 0VOVHvթ7:gYO/PSq-Aڥh>}5H`u#r\4^W-|i뵤 \kR6܀#PFx6v"X-'\{3tt)ΌT E2¬M@7иpۖQz3Bi ȍSmzT {UPBO\=Kʚm=7WYH4mΘ5-OR<1@^-ZTTg0 (ң?cjr9bU ,Yxq}]x/C@4U]jnBUd  xUjA͕ c߳^޽̷vܝܷK& +}Ōoq,~6-oqY8&hrG EBG໗wU#f2y;RK<>M$F 2M 1u|p^$H1j?"XɰXJN82>:qUu4+'ъ ![N1j\T\ }1I\?3>a\7ƿ!9Rxi?N6@F:<9j+9`jz|0J.HkQ(( pwNǹP%6J Rՙ;S)8e]j($*G={q.#Vø=aKH m.xq{E9>ֽp8n/D;U,睪)E+O 쒿v\Ow:ʃ9e!8[4r p7QigS1%QA!]W"3VQL^$nZH>k/r:ZO!xmye9d1 n&9jcI ;EMMFGZ6zx`0@JOH,w}&N%*F!)&4)G.~c7$2P4>JR 좫( }!ՂShj" LAvlaaJd C燊I6őjҦ|5Q%&JքSAOO&@BED[st?N b%Eq f L=@u> {+㲡*NTC+HX[~bSQPĉnq5c)d:G5LhۨNc,pY3r+:Tl8@ٸu׈-VhcS`+L\On`, 7Ptq:S-XkMZ֊2#go|RT>Z6aeKS&Y5|<(rjಪR]|0JylPZdz}4cb߇@=+GPE:jHNM.y1%2!4fH]AAI>0+N )40Z6\P,`WO*#SB:`A !dz xb{]qKe90+#+ c?uXqԹ%TI($UhjGZ~[ $ā*ɡ4վn8XUFb3L;8 qbvN 7u A\+i;0lĭmfAr$IyfX5C;2B~l[+˶fGo6U%B?akpHUv)i:>nGu~}u" x*'#Xɼ+79Oې:`" gJs_ۍr?F7VNpkB5 f}N;[Hi.&eHGb[՝~1ڣt]cbF792[夾6V5;{v)!;w8vv'.$$AfPXԜCޫr+ҕs%/.f `vj7\8Ѻ$B(P.}3*38DdOvcF#i얹BJH]OA4)m^MXz"YG" 0H4UFJtAS*~:cayq+A ~82, q!x+m>?VU5ǩj7H0I750MF4d+ZfOX)d+.*E_? HqN*ҹ? # OSkI'U+c#g0kQU5;W/h8{VR"dv IJm# ^Y2RR0Fht ӯ\~* [I POh; p"shM2oqM|*z܊TopG֣hbCS_22=z~5PZ>xSxKͽ]()zPkV's+#"~ѫf 3LV T)GJџՓt' q,lbaV E duǵR we~\StU+RkevzO3`3JJkn$YSS0Pw˥<Ǟ&絎󏹨x\VR3eouLuߠ2_q~ ^Z+C_QX!* OQSA)?Iilм66?m0P0os{B{" {R~X7pIƈ"OPZk]F<-Lq!ydoj0.XN/6ąu@͝\\s]nz<3"_(cruN (:C<1SDQLM/ UEPSŜ_wwIw4vO$ UE[._}qs$9{ֺ "A1%ovTF-R ZI&$#2uťgx]^ܒIaMR?D aBОxKCK(rEPY@*j)E9Kmi9Y!C jB. q˗3\ZRR GP6)Nxۂp=>M.Ši[@Mv Fփ:(S=,R4x_mX(?F 0#?,Pi]zu(1(p ץ1U 7 Hͳ'PA, |p7ic<-)P`$fA4-s rmY_~&DP>Ziu"G㻂Tż>=YpejfvfU;弶`k$B K' d֚3zTSM0(*ڇG?̮k{E?rYir?0/o"52S3@='?S"k^ Ϟ&iHc54| c%܏:TxMSERV`ŧ|e"έZſڻT;p^!Mce t̏} gZ1BH R\{u,0(H ߘ=/bF.VM:2n*nc tܣ?<߈%]o p>}`G"qїL S (3xK9.e=kiw/1h+MJ'|"4yIP0Z|FK ^:ıWb3'qE#`3>#ZTՂ!p A*8(iR5A?CF<ApWB jq:yЃA݀(N[N= dH,q? :~ӏ\Ȩ?ͦC\)fᚄc@wR pUkVqR‹@+SCL Z`5X«ZcxZ-?4jN0hs$= wp}Db kv7CzS˜( >C\ ]7] )BT~Š UPQ0PSe d|͑SwHzƣia} mCgi~cS$;f 'J)#ܸ-^#pԃX@pYs$7Vđ2C@EkJ}? v \Fy]RSĪ3KM1O\[o ",-n&B;%ԤLUkLt ."5rYHӠUZPƹ B'D7g o<}a!wS:pv* 9cQlPHun۵PtpU[1&h3}ʃ1h UNf9L.kPnQ :OnBµ4J QWc{h:S@d#PKfI4pwF0aYhOT OP3Nգֹ8,aUjJm2ʕW ZXrw @<ЃQ1mM|F62Ue\9n#`Mf2,$WWcSO#Te~<&AJ ǪӨ|q3/]5$p#$\r J+־݇ ;,Zyaܣp ljÐ }M OURX=*2f&+AQJi oQBq=i剧F]z\ӖAp@:.JE;L m.t܌7,ث;4h 8q#Ge㉹+xٞ*FӠ+bs*{DTG\m+O־XH ~ËȢw1n*k2Yڪe\T1'#kWa%iJ53ʔA]1HcePhYzy h=rQԎ`UA~0PR|(u5#~ޭnSR+2Sy0)1iNX;[At79 9 5ViM' J瞺პrlwO 4_Tiʑ0&CQ4Fu1BSu(5s <#ӯ}x.H9gi̓S\)#(|iQp 55coiZ ,V)]| U#])M|5Q Lt\#nUSqڔ5_8+ZSοE0 w|զBPmQゕZL M­l>4K\:,j S!\O0DAԦJMp8"*!2Qzw,c*) U*YiZWpc] dфhW Ȇq4`u]@R4lϺeA *L鯖# (nZjP:tk i76mQթ=P<U@+W,{fJmܠjb╪vɞghmrUIb!@7 u#ph2##ZԢxSLIyogܨ IČ*61e=+C*Xn>g<$ SeA ut>78oʆfD&5b2RʙO_>*YPTuϵ=jn;هȹ nBi5JrCM̔gVBMG4/`# T eQO ., +tUSFn> nP ݂MЂCUpVLk# JEO\BG @֙0w`! O᏾\:ٝN,~&֙jJsT6g_ 01|v=ፀrgO UhzyyZfxy* <)ʹOUjfExH=$R=rf;hi0LSRL0Byf)QM+\ ?~6(RAʣ4P }5qBH̏߀u)тc`ji IESIO(JtNd|*E+ZhIDCeP)4Rw@||<=@.I5%UFAÚî~Ht$(MѼu$èCR}οzZtOP){Fp'ޕV`z6yxM0`RVb,#,{A*C5MvƽGӅ0m A_L}"XHe^ 6'_ +QSR~pAΙx]O_Fk\)\ɥ0Wi*kB58j?F3$L.̎\&u9+_ jnz25$T-4XgZu4֘->4s u$7Hһh3 l+A]^WPҸ?ߍ]k^TL:_Lz :LOՀSۨu5X>Ԓ6|JeCO:4J`ۥk\hi#Ҥex 0DZ:k^x`Ntl6 7ѯ׆ ]<PAۧxj@Z?RԂ4Bi#uxA-2N P*s#=kgGS{#*h_í胣j+ 83tScz=+2;h'mП<۾LD.R_P#*ҽ0Y]$i j0j OU45A?Pȏ I$ BAZUy;I$ol(%MHZtmVLԂ}! =,{b:j@A%S@ \:3et9328@Y73V|s d|rץ 0 R TaҚnT)hsS\֘``R2į=X@EB3H'E= \vsB APҝH9jdT+O!:Mku)\δ fٻMujhhI fEC>+S$T̪ ʕ8d5P(֕:W)δU / ncmi`*FVkL}ڀ3֦XmHbQծSG*h\5+zg:,Vk C bZbk:E+ܥ@OZ&yfAm"9a@Z(U:L?{bp<:|2~8%Z Gǩ\:2al#ST|)g͍P=UHfz2JR:b%Z1v Gl  aW?NL iIk֤21됰1 F 5R4 W}HU۴.|483ٸV.Ơ-N,OQ՝)_ٖS!H&Ɵ@C r)\J-W)AQʸZ}Y!>cYkኮu ^`VR0Diצx,jgJhpVe̊y Δr4,"H0Uar>&?^=9 Χúk@gLV̆ȃWGBQ`3傀ӡ5y}8* 0P+fy7 + սYVс 4CZ4e)"Ph ሤFPh5k6ndy(kAMŘfrКR4{w31[ܡ`Ng]i<"1+'ݚ˦yp"jp7VZ%iBH1Nu'gۣ<=0aGd"&0mjTgSНI9%d`iP*x]GpC62VcXH Jҕ /0K% OS?u!53jiP>ZiL$`"В#-ZF#IBc5bE?44Am ՎxcɎ(_@ d$n<Ɣ8mfgPR?6 FFk#ϫ]-]u'@GӅE)0Qv3̻송UȏNX"Q($#-jN+@4Ė3MRC…at&D^ s牞X U{nF۴HKе,"TjQ@H=OJ ㅆ!"/](cVgSi^[ePi5YY{~?R 0wWZa$L>UCoB,TG!~9S!Ak8I_kĐ4Qk#J jCl%̶gq`Sv{Cz2':j?&bQ(Q0 S9 ?@2j)h3h.,Dn GNIfٷ}ةsax6܀}T,.q pʂ1^uu醊BZ9I_2<,ۄKdܩKu$뇳%`Y]V W"Aև\%LhP)MEJ3 VbR<< M?TP쬠z[rf>$ye7Im,Ɂ4tĴUfV ([x\\4w ]|uŀ*=DVU9OE19A\~2CE+yQYȔВ)8밊 Y'ۥzԎ4Lυ~9`@Ȃ)?MqTgZUg_Yy 5YAh5"GF((h\0 ##Jxa\'BO<{2la_OՁoԟREjAm@BI$͂VMw#91f*ٕzG\,>gAk<$M¦OCĞ*I0W0a}o,BCzӦ'XYqI_I f Nڞd"ZT@@M@ ), Վyh|>)\V58jڣ|0K _=2~C4dUD# $FBcH\BL$>tAjMs)Q֦˥5$%hkE'΃T"^ > e?$c(XԱA*s40L{j(V:~b3>8&ᔫg_b6`vцULQ@I>F3DzNĩj#{o [X#,Z)t.CI/wVI[Re"e2!Fyxae\U}kE=m\ϝHUiڤ 3*NG3jr`M}@WB<dz+ܺRE|<ѣ94h~#e>XeԄjSifZTƛpjhҾ4 ZSx#//*TȌUEɈnO `LjƵS׮eu9mop$U:d|E?Fc F!]C) тla GmehzWm.ФfqHcv)_~Ұb)^ AVB ukQBN9 z*?D:{ 3 tǻ FIgğ:e@w-pU2 ֪ h|.&"{acDVF[ighr ԀS\Y +->,E,L m*D4VO׍5fBYWʺ!v 3h]+S ֊eEsQZ`E *B&L *~݇+3* NΥj0e/ƞ9ᤍHfUNJerbHӨAǼk TV+S\r\ Jk˜-zB/IWVR̊,:éyH=CJLG1F s!0+Dx m!s%4z4@hSA1ng =:2gAֽGAܨ`7i=FxVDj0m J0\5XoeԎVC]DhQ<%ń>5J>SԟH$S8,rmOzZXI5TO׍hx󵚟(?K2:WZPBcj@Vucᆆu"/3xR _ ujh<1$jT+Tu\Fbb`52n=2kAB޺QOtDz Ip\ */쎾jMt1 2X9PG*K{"%ʚ(=c87㕷;=[2PiSA*W1pҺ҇5TJel.ۮeGx䙥T5+@$fTSO{'E;BMF=`0"E1I[+4:x1\V,d,C=NZ<4{RK]d(ondF%!NBe׮᥾nCIm$ B)Ҟxxh[wgr_̹gtz;UHZ0#!@VHUE2Χ_ Hd"Ydbɪ iS˯]q!(=eZsԓZ0Mi%kJ*" (9,z, d RIW 6rMvHiQ C=q rCo*37PWJ&i%'S!wjakob-nanobind-6c4457b/docs/images/perf.svg000066400000000000000000001564461474760012700210170ustar00rootroot00000000000000 2023-04-24T16:58:39.940540 image/svg+xml Matplotlib v3.5.1, https://matplotlib.org/ wjakob-nanobind-6c4457b/docs/images/sizes.svg000066400000000000000000001504451474760012700212110ustar00rootroot00000000000000 2023-04-24T16:53:14.348990 image/svg+xml Matplotlib v3.5.1, https://matplotlib.org/ wjakob-nanobind-6c4457b/docs/images/times.svg000066400000000000000000001466711474760012700212030ustar00rootroot00000000000000 2023-04-24T16:53:10.667274 image/svg+xml Matplotlib v3.5.1, https://matplotlib.org/ wjakob-nanobind-6c4457b/docs/images/wrapper-dark.svg000066400000000000000000000336151474760012700224520ustar00rootroot00000000000000 wjakob-nanobind-6c4457b/docs/images/wrapper-light.svg000066400000000000000000000331671474760012700226420ustar00rootroot00000000000000 wjakob-nanobind-6c4457b/docs/index.rst000066400000000000000000000066671474760012700177350ustar00rootroot00000000000000Introduction ============ .. only:: not latex .. image:: https://github.com/wjakob/nanobind/raw/master/docs/images/logo.jpg :width: 800 :align: center :alt: nanobind logo :class: only-light .. image:: https://rgl.s3.eu-central-1.amazonaws.com/media/uploads/wjakob/2023/03/28/nanobind_logo_dark.png :width: 800 :align: center :alt: nanobind logo :class: only-dark .. only:: latex .. image:: https://github.com/wjakob/nanobind/raw/master/docs/images/logo.jpg :width: 800 :align: center :alt: nanobind logo *nanobind* is a small binding library that exposes C++ types in Python and vice versa. It is reminiscent of `Boost.Python `_ and `pybind11 `_ and uses near-identical syntax. In contrast to these existing tools, nanobind is *more efficient*: bindings compile in a shorter amount of time, produce smaller binaries, and have better runtime performance. More concretely, :ref:`benchmarks ` show up to **~4× faster** compile time, **~5× smaller** binaries, and **~10× lower** runtime overheads compared to pybind11. nanobind also outperforms Cython in important metrics (**3-12×** binary size reduction, **1.6-4×** compilation time reduction, similar runtime performance). .. only:: not latex Documentation formats --------------------- You are reading the HTML version of the documentation. An alternative `PDF version `__ is also available. Dependencies ------------ .. only:: latex .. rubric:: Dependencies nanobinds depends on - **Python 3.8+** or **PyPy 7.3.10+** (the *3.8* and *3.9* PyPy flavors are supported, though there are :ref:`some limitations `). - **CMake 3.15+**. - **A C++17 compiler**: Clang 8+, GCC 8+, MSVC2019+, and the CUDA NVCC compiler are officially supported. Others (MinGW, Cygwin, Intel, ..) may work as well but will not receive support. .. only:: not latex How to cite this project? ------------------------- .. only:: latex .. rubric:: How to cite this project? Please use the following BibTeX template to cite nanobind in scientific discourse: .. code-block:: bibtex @misc{nanobind, author = {Wenzel Jakob}, year = {2022}, note = {https://github.com/wjakob/nanobind}, title = {nanobind: tiny and efficient C++/Python bindings} } The nanobind logo was designed by `AndoTwin Studio `__. High-resolution version are available `here `__ (light) and `here `__ (dark). .. only:: not latex Table of contents ----------------- .. toctree:: :maxdepth: 1 changelog why benchmark porting faq .. toctree:: :caption: Basics :maxdepth: 1 installing building basics bazel meson .. toctree:: :caption: Intermediate :maxdepth: 1 exchanging ownership functions classes exceptions ndarray_index packaging typing utilities .. toctree:: :caption: Advanced :maxdepth: 1 free_threaded ownership_adv lowlevel typeslots .. toctree:: :caption: API Reference :maxdepth: 1 api_core api_extra api_cmake api_bazel wjakob-nanobind-6c4457b/docs/installing.rst000066400000000000000000000030351474760012700207540ustar00rootroot00000000000000.. _installing: Installing the library ###################### The *nanobind* project is hosted at `wjakob/nanobind on GitHub `_. To use the library in your own projects, it is usually easiest to install it using one of the following three methods: Install via Pip (recommended) ============================== Run the following command in your terminal to install a package containing both C++ and CMake source code needed to compile extension modules. .. code-block:: bash python -m pip install nanobind Install via Conda ================= The following alternative installs an equivalent package through Conda. It is provided for users that develop Conda-based extensions with a build-time dependency on *nanobind*, in which case the PyPI package cannot be used. .. code-block:: bash conda install -c conda-forge nanobind Install as a Git submodule ========================== If you prefer not to involve external package managers, and if your project uses the Git control system, you may also directly reference *nanobind* as a `Git submodule `_. In the main directory of your repository, run the following commands: .. code-block:: bash git submodule add https://github.com/wjakob/nanobind ext/nanobind git submodule update --init --recursive This assumes you are placing your dependencies in ``ext/``. The :ref:`next section ` will explain how to set up a basic build system that you can use to build your first extension module. wjakob-nanobind-6c4457b/docs/lowlevel.rst000066400000000000000000000257001474760012700204440ustar00rootroot00000000000000.. _lowlevel: .. cpp:namespace:: nanobind Low-level interface =================== nanobind exposes a low-level interface to provide fine-grained control over the sequence of steps that instantiates a Python object wrapping a C++ instance. This is useful when writing generic binding code that manipulates nanobind-based objects of various types. Given a previous :cpp:class:`nb::class_\<...\> ` binding declaration, the :cpp:func:`nb::type\() ` template function can be used to look up the Python type object associated with a C++ class named ``MyClass``. .. code-block:: cpp nb::handle py_type = nb::type(); In the case of failure, this line will return a ``nullptr`` pointer, which can be checked via ``py_type.is_valid()``. We can verify that the type lookup succeeded, and that the returned instance indeed represents a nanobind-owned type (via :cpp:func:`nb::type_check() `, which is redundant in this case): .. code-block:: cpp assert(py_type.is_valid() && nb::type_check(py_type)); nanobind knows the size, alignment, and C++ RTTI ``std::type_info`` record of all bound types. They can be queried on the fly via :cpp:func:`nb::type_size() `, :cpp:func:`nb::type_align() `, and :cpp:func:`nb::type_info() ` in situations where this is useful. .. code-block:: cpp assert(nb::type_size(py_type) == sizeof(MyClass) && nb::type_align(py_type) == alignof(MyClass) && nb::type_info(py_type) == typeid(MyClass)); Given a type object representing a C++ type, we can create an uninitialized instance via :cpp:func:`nb::inst_alloc() `. This is an ordinary Python object that can, however, not (yet) be passed to bound C++ functions to prevent undefined behavior. It must first be initialized. .. code-block:: cpp nb::object py_inst = nb::inst_alloc(py_type); We can confirm via :cpp:func:`nb::inst_check() ` that this newly created instance is managed by nanobind, that it has the correct type in Python. Calling :cpp:func:`nb::inst_ready() ` reveals that the *ready* flag of the instance is set to ``false`` (i.e., it is still uninitialized). .. code-block:: cpp assert(nb::inst_check(py_inst) && py_inst.type().is(py_type) && !nb::inst_ready(py_inst)); For simple *plain old data* (POD) types, the :cpp:func:`nb::inst_zero() ` function can be used to *zero-initialize* the object and mark it as ready. .. code-block:: cpp nb::inst_zero(py_inst); assert(nb::inst_ready(py_inst)); We can destruct this default instance via :cpp:func:`nb::inst_destruct() ` and convert it back to non-ready status. This memory region can then be reinitialized once more. .. code-block:: cpp nb::inst_destruct(py_inst); assert(!nb::inst_ready(py_inst)); What follows is a more interesting example, where we use a lesser-known feature of C++ (the "`placement new `_" operator) to construct an instance *in-place* into the memory region allocated by nanobind. .. code-block:: cpp // Get a C++ pointer to the uninitialized instance data MyClass *ptr = nb::inst_ptr(py_inst); // Perform an in-place construction of the C++ object at address 'ptr' new (ptr) MyClass(/* constructor arguments go here */); Following this constructor call, we must inform nanobind that the instance object is now fully constructed via :cpp:func:`nb::inst_mark_ready() `. When its reference count reaches zero, nanobind will then automatically call the in-place destructor (``MyClass::~MyClass``). .. code-block:: cpp nb::inst_mark_ready(py_inst); assert(nb::inst_ready(py_inst)); Let’s destroy this instance once more manually (which will, again, call the C++ destructor and mark the Python object as non-ready). .. code-block:: cpp nb::inst_destruct(py_inst); Another useful feature is that nanobind can copy- or move-construct ``py_inst`` from another instance of the same type via :cpp:func:`nb::inst_copy() ` and :cpp:func:`nb::inst_move() `. These functions call the C++ copy or move constructor and transition ``py_inst`` back to ``ready`` status. This is equivalent to calling an in-place version of these constructors followed by a call to :cpp:func:`nb::inst_mark_ready() ` but compiles to more compact code (the :cpp:class:`nb::class_\ ` declaration had already created bindings for both constructors, and this simply calls those bindings). .. code-block:: cpp if (copy_instance) nb::inst_copy(/* dst = */ py_inst, /* src = */ some_other_instance); else nb::inst_move(/* dst = */ py_inst, /* src = */ some_other_instance); Both functions assume that the destination object is uninitialized. Two alternative versions :cpp:func:`nb::inst_replace_copy() ` and :cpp:func:`nb::inst_replace_move() ` destruct an initialized instance and replace it with the contents of another by either copying or moving. .. code-block:: cpp if (copy_instance) nb::inst_replace_copy(/* dst = */ py_inst, /* src = */ some_other_instance); else nb::inst_replace_move(/* dst = */ py_inst, /* src = */ some_other_instance); Note that these functions are all *unsafe* in the sense that they do not verify that their input arguments are valid. This is done for performance reasons, and such checks (if needed) are therefore the responsibility of the caller. Functions labeled ``nb::type_*`` should only be called with nanobind type objects, and functions labeled ``nb::inst_*`` should only be called with nanobind instance objects. The functions :cpp:func:`nb::type_check() ` and :cpp:func:`nb::inst_check() ` are exceptions to this rule: they accept any Python object and test whether something is a nanobind type or instance object. Two further functions :cpp:func:`nb::type_name() ` and :cpp:func:`nb::inst_name() ` determine the type name associated with a type or instance thereof. These also accept non-nanobind types and instances. Even lower-level interface -------------------------- Every nanobind object has two important flags that control its behavior: 1. ``ready``: is the object fully constructed? If set to ``false``, nanobind will raise an exception when the object is passed to a bound C++ function. 2. ``destruct``: Should nanobind call the C++ destructor when the instance is garbage collected? The functions :cpp:func:`nb::inst_zero() `, :cpp:func:`nb::inst_mark_ready() `, :cpp:func:`nb::inst_move() `, and :cpp:func:`nb::inst_copy() ` set both of these flags to ``true``, and :cpp:func:`nb::inst_destruct() ` sets both of them to ``false``. In rare situations, the destructor should *not* be invoked when the instance is garbage collected, for example when working with a nanobind instance representing a field of a parent instance created using the :cpp:enumerator:`nb::rv_policy::reference_internal ` return value policy. The library therefore exposes two more functions :cpp:func:`nb::inst_state() ` and :cpp:func:`nb::inst_set_state() ` that can be used to access them individually. Referencing existing instances ------------------------------ The above examples used the function :cpp:func:`nb::inst_alloc() ` to allocate a Python object along with space to hold a C++ instance associated with the binding ``py_type``. .. code-block:: cpp nb::object py_inst = nb::inst_alloc(py_type); // Next, perform a C++ in-place construction into the // address given by nb::inst_ptr(py_inst) ... omitted, see the previous examples ... What if the C++ instance already exists? nanobind also supports this case via the :cpp:func:`nb::inst_reference() ` and :cpp:func:`nb::inst_take_ownership() ` functions—in this case, the Python object references the existing memory region, which is potentially (slightly) less efficient due to the need for an extra indirection. .. code-block:: cpp MyClass *inst = new MyClass(); // Transfer ownership of 'inst' to Python (which will use a delete // expression to free it when the Python instance is garbage collected) nb::object py_inst = nb::inst_take_ownership(py_type, inst); // We can also wrap C++ instances that should not be destructed since // they represent offsets into another data structure. In this case, // the optional 'parent' parameter ensures that 'py_inst' remains alive // while 'py_subinst' exists to prevent undefined behavior. nb::object py_subinst = nb::inst_reference( py_field_type, &inst->field, /* parent = */ py_inst); .. _supplement: Supplemental type data ---------------------- nanobind can stash supplemental data *inside* the type object of bound types. This involves the :cpp:class:`nb::supplement\() ` class binding annotation to reserve space and :cpp:func:`nb::type_supplement\() ` to access the reserved memory region. An example use of this fairly advanced feature are libraries that register large numbers of different types (e.g. flavors of tensors). A single generically implemented function can then query the supplemental data block to handle each tensor type slightly differently. Here is what this might look like in an implementation: .. code-block:: cpp struct MyTensorMetadata { bool stored_on_gpu; // .. // should be a POD (plain old data) type }; // Register a new type MyTensor, and reserve space for sizeof(MyTensorMedadata) nb::class_ cls(m, "MyTensor", nb::supplement()) /// Mutable reference to 'MyTensorMedadata' portion in Python type object MyTensorMedadata &supplement = nb::type_supplement(cls); supplement.stored_on_gpu = true; The :cpp:class:`nb::supplement\() ` annotation implicitly also passes :cpp:class:`nb::is_final() ` to ensure that type objects with supplemental data cannot be subclassed in Python. nanobind requires that the specified type ``T`` be trivially default constructible. It zero-initializes the supplement when the type is first created but does not perform any further custom initialization or destruction. You can fill the supplement with different contents following the type creation, e.g., using the placement new operator. The contents of the supplemental data are not directly visible to Python's cyclic garbage collector, which creates challenges if you want to reference Python objects. The recommended workaround is to store the Python objects as attributes of the type object (in its ``__dict__``) and store a borrowed ``PyObject*`` reference in the supplemental data. If you use an attribute name that begins with the symbol ``@``, then nanobind will prevent Python code from rebinding or deleting the attribute after it has been set, making the borrowed reference reasonably safe. wjakob-nanobind-6c4457b/docs/meson.rst000066400000000000000000000052611474760012700177340ustar00rootroot00000000000000.. _meson: Building extensions using Meson =============================== If you prefer the Meson build system to CMake, you can build extensions using the `Meson WrapDB `__ package. .. note:: This package is a community contribution maintained by `Will Ayd `__, please report issues directly in the `Meson WrapDB `__ repository. .. _meson-setup: Adding nanobind to your Meson project ------------------------------------- To use Meson as the build generator in your Python project, you will want to install the `meson-python `__ project as a build dependency. To do so, simply add the following to your pyproject.toml file: .. code-block:: toml [project] name = "my_project_name" dynamic = ['version'] [build-system] requires = ['meson-python'] build-backend = 'mesonpy' In your project root, you will also want to create the subprojects folder that Meson can install into. Then you will need to install the wrap packages for both nanobind and robin-map: .. code-block:: sh mkdir -p subprojects meson wrap install robin-map meson wrap install nanobind The ``meson.build`` definition in your project root should look like: .. code-block:: python project( 'my_project_name', 'cpp', version: '0.0.1', ) py = import('python').find_installation() nanobind_dep = dependency('nanobind', static: true) py.extension_module( 'my_module_name', sources: ['path_to_module.cc'], dependencies: [nanobind_dep], install: true, ) With this configuration, you may then call: .. code-block:: sh meson setup builddir meson compile -C builddir To compile the extension in the ``builddir`` folder. Alternatively, if you don't care to have a local build folder, you can use the Python build frontend of your choosing to install the package as an editable install. With pip, this would look like: .. code-block:: sh python -m pip install -e . .. _meson-stable-abi: Building against the stable ABI ------------------------------- As in nanobind's CMake config, you can build bindings targeting Python's stable ABI, starting from version 3.12. To do this, specify the target version using the ``limited_api`` argument in your configuration. For example, to build extensions against the CPython 3.12 stable ABI, you would use: .. code-block:: python py.extension_module( 'my_module_name', sources: ['path_to_module.cc'], dependencies: [nanobind_dep], install: true, limited_api: '3.12', ) In your ``meson.build`` file. wjakob-nanobind-6c4457b/docs/microbenchmark.ipynb000066400000000000000000000412651474760012700221140ustar00rootroot00000000000000{ "cells": [ { "cell_type": "code", "execution_count": null, "id": "83b016f7-695a-43b7-8baf-4bd0d435a0c8", "metadata": { "tags": [] }, "outputs": [], "source": [ "import random\n", "import subprocess\n", "import itertools\n", "from collections import defaultdict\n", "import importlib.machinery\n", "import os\n", "import time\n", "import cython\n", "from matplotlib.patches import Rectangle\n", " \n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "\n", "import matplotlib as mpl\n", "mpl.rcParams['hatch.linewidth'] = 5.0 \n", "cycle = [x['color'] for x in mpl.rcParams['axes.prop_cycle']]" ] }, { "cell_type": "code", "execution_count": null, "id": "705868b4-c013-4fc2-a4c3-bdaca6c90d05", "metadata": { "tags": [] }, "outputs": [], "source": [ "experiment_labels = []\n", "sizes = defaultdict(lambda: [])\n", "times = defaultdict(lambda: [])\n", "\n", "from sysconfig import get_paths as gp\n", "suffix = importlib.machinery.EXTENSION_SUFFIXES[0]\n", "\n", "# Path to pybind11 git repository\n", "pybind11_path = '/home/wjakob/pybind11/include'\n", "\n", "# Path to pybind11 git repository (smartholder branch)\n", "pybind11_sh_path = '/home/wjakob/pybind11_sh/include'\n", "\n", "# Path to boost (in this case, assumed to be installed by the OS)\n", "boost_path = '/usr/include/boost'\n", "\n", "cmd_base = ['clang++', '-march=native', '-shared', '-rpath', '..', '-std=c++17', '-I', '../include', '-I', gp()['include'],\n", " '-Wno-deprecated-declarations', '-fPIC', f'-L{boost_path}/stage/lib', '-L..', '-fno-stack-protector',\n", " '-DPYBIND11_USE_SMART_HOLDER_AS_DEFAULT']\n", "\n", "def gen_file(name, func, libs=('cython', 'boost', 'pybind11', 'pybind11_sh', 'nanobind')):\n", " for i, lib in enumerate(libs): \n", " for opt_mode, opt_flags in {'debug' : ['-O0', '-g3'], 'opt' : ['-Os', '-g0']}.items():\n", " if lib != 'cython':\n", " fname = name + '_' + lib + '.cpp'\n", " else:\n", " fname = name + '_' + lib + '_' + opt_mode + '.pyx'\n", " \n", " with open(fname, 'w') as f:\n", " if lib == 'boost':\n", " f.write(f'#include \\n')\n", " f.write(f'namespace py = boost::python;\\n\\n')\n", " f.write(f'BOOST_PYTHON_MODULE({name}_{lib}_{opt_mode}) {{\\n')\n", " elif lib == 'nanobind':\n", " f.write(f'#include \\n\\n')\n", " f.write(f'namespace py = nanobind;\\n\\n')\n", " f.write(f'NB_MODULE({name}_{lib}_{opt_mode}, m) {{\\n')\n", " elif lib.startswith('pybind11'):\n", " f.write(f'#include \\n\\n')\n", " f.write(f'namespace py = pybind11;\\n\\n')\n", " f.write(f'PYBIND11_MODULE({name}_{lib}_{opt_mode}, m) {{\\n')\n", " elif lib == 'cython':\n", " f.write(f'from libc.stdint cimport uint16_t, int32_t, uint32_t, int64_t, uint64_t\\n')\n", "\n", " func(f, lib)\n", " if lib != 'cython':\n", " f.write(f'}}\\n')\n", "\n", " fname_out = name + '_' + lib + '_' + opt_mode + suffix\n", " cmd = cmd_base + opt_flags + [name + '_' + lib + '.cpp', '-o', fname_out]\n", " if lib == 'nanobind':\n", " cmd += ['-lnanobind']\n", " elif lib == 'boost':\n", " cmd += ['-I', boost_path, '-lboost_python310']\n", " elif lib == 'pybind11':\n", " cmd += ['-I', pybind11_path]\n", " elif lib == 'pybind11_sh':\n", " cmd += ['-I', pybind11_sh_path]\n", " \n", " print(' '.join(cmd))\n", " time_list = []\n", " for l in range(5):\n", " time_before = time.perf_counter()\n", " if lib == 'cython':\n", " subprocess.check_call(['cython3', '-3', '--cplus', fname, '-o', name + '_' + lib + '.cpp'])\n", " subprocess.check_call(cmd)\n", " time_after = time.perf_counter()\n", " time_list.append(time_after-time_before)\n", " time_list.sort()\n", " \n", " if opt_mode != 'debug':\n", " subprocess.check_call(['strip', fname_out])\n", " if i == 0:\n", " experiment_labels.append(name + ' [' + opt_mode + ']')\n", " sizes[lib].append(os.path.getsize(fname_out) / (1024 * 1024))\n", " times[lib].append(time_list[len(time_list)//2])\n", "\n", "\n", " \n", "def gen_func(f, lib):\n", " types = [ 'uint16_t', 'int32_t', 'uint32_t', 'int64_t', 'uint64_t', 'float' ]\n", " if lib == 'boost':\n", " prefix = 'py::'\n", " else:\n", " prefix = 'm.'\n", " for i, t in enumerate(itertools.permutations(types)):\n", " args = f'{t[0]} a, {t[1]} b, {t[2]} c, {t[3]} d, {t[4]} e, {t[5]} f'\n", " if lib != 'cython':\n", " f.write(' %sdef(\"test_%04i\", +[](%s) { return a+b+c+d+e+f; });\\n' % (prefix, i, args))\n", " else:\n", " f.write('cpdef float test_%04i(%s):\\n return a+b+c+d+e+f\\n\\n' % (i, args))\n", "\n", "\n", "def gen_class(f, lib):\n", " types = [ 'uint16_t', 'int32_t', 'uint32_t', 'int64_t', 'uint64_t', 'float' ]\n", "\n", " for i, t in enumerate(itertools.permutations(types)):\n", " if lib == 'boost':\n", " prefix = ''\n", " postfix = f', py::init<{t[0]}, {t[1]}, {t[2]}, {t[3]}, {t[4]}, {t[4]}>()'\n", " func_prefix = 'py::def'\n", "\n", " else:\n", " prefix = 'm, '\n", " postfix = ''\n", " func_prefix = 'm.def'\n", "\n", " if lib != 'cython':\n", " f.write(f' struct Struct{i} {{\\n')\n", " f.write(f' {t[0]} a; {t[1]} b; {t[2]} c; {t[3]} d; {t[4]} e; {t[5]} f;\\n')\n", " f.write(f' Struct{i}({t[0]} a, {t[1]} b, {t[2]} c, {t[3]} d, {t[4]} e, {t[5]} f) : a(a), b(b), c(c), d(d), e(e), f(f) {{ }}\\n')\n", " f.write(f' float sum() const {{ return a+b+c+d+e+f; }}\\n')\n", " f.write(f' }};\\n')\n", " else:\n", " f.write(f'cdef class Struct{i}:\\n')\n", " f.write(f' cdef {t[0]} a\\n')\n", " f.write(f' cdef {t[1]} b\\n')\n", " f.write(f' cdef {t[2]} c\\n')\n", " f.write(f' cdef {t[3]} d\\n')\n", " f.write(f' cdef {t[4]} e\\n')\n", " f.write(f' cdef {t[5]} f\\n\\n')\n", " f.write(f' def __cinit__(self, {t[0]} a, {t[1]} b, {t[2]} c, {t[3]} d, {t[4]} e, {t[5]} f):\\n')\n", " f.write(f' self.a = a\\n')\n", " f.write(f' self.b = b\\n')\n", " f.write(f' self.c = c\\n')\n", " f.write(f' self.d = d\\n')\n", " f.write(f' self.e = e\\n')\n", " f.write(f' self.f = f\\n\\n')\n", " f.write(f' cpdef float sum(self):\\n')\n", " f.write(f' return self.a+self.b+self.c+self.d+self.e+self.f\\n\\n')\n", " continue\n", "\n", " f.write(f' py::class_({prefix}\\\"Struct{i}\\\"{postfix})\\n')\n", " \n", " if lib != 'boost':\n", " f.write(f' .def(py::init<{t[0]}, {t[1]}, {t[2]}, {t[3]}, {t[4]}, {t[5]}>())\\n')\n", " f.write(f' .def(\"sum\", &Struct{i}::sum);\\n\\n')\n", " \n", " if i > 250:\n", " break;\n", " \n", " \n", "gen_file('func', gen_func)\n", "gen_file('class', gen_class)\n", "experiment_labels = ['func [debug]', 'func [opt]', 'class [debug]', 'class [opt]']\n", "\n", "print(experiment_labels)\n", "print(dict(sizes))\n", "print(dict(times))" ] }, { "cell_type": "code", "execution_count": null, "id": "c67eac20-ffb5-4c58-ba08-64e7404a54a9", "metadata": { "tags": [] }, "outputs": [], "source": [ "\n", "plot_colors = {\n", " 'boost': cycle[1],\n", " 'pybind11': cycle[3],\n", " 'pybind11_sh': cycle[5],\n", " 'cython' : cycle[4],\n", " 'nanobind': cycle[0]\n", "}\n", "plot_labels = {\n", " 'boost' : 'Boost.Python',\n", " 'pybind11' : 'pybind11',\n", " 'pybind11_sh' : 'pybind11 + smart_holder',\n", " 'cython' : 'Cython',\n", " 'nanobind' : 'nanobind'\n", "}\n", "\n", "def bars(data, ylim_scale = 1, figsize_scale = 1, width_scale=1.0, debug_shift=0.1):\n", " ylim = 0\n", " for n, d in data.items():\n", " if len(d) == 0:\n", " continue\n", " ylim = max(max(d), ylim)\n", " ylim *= ylim_scale * 1.3\n", "\n", " def adj(ann):\n", " for i, a in enumerate(ann):\n", " if a.xy[1] > ylim*.9:\n", " a.xy = (a.xy[0], ylim * 0.8)\n", " if i%2 == 1:\n", " a.set_color('white')\n", "\n", " fig, ax = plt.subplots(figsize=[11.25*figsize_scale, 3*figsize_scale])\n", " width = 1.0/(len(data) + 1)*width_scale\n", " x = np.arange(4)\n", "\n", " result = []\n", " for i, n in enumerate(plot_labels):\n", " d = data[n]\n", " if len(d) == 0:\n", " continue\n", "\n", " col = plot_colors[n]\n", " if col != 'None':\n", " kwargs = { 'edgecolor': 'black', 'color': col }\n", " else:\n", " kwargs = {'edgecolor': 'white', 'hatch' : '/', 'color':cycle[7]}\n", " \n", " bar = ax.bar(x+width*(i -(len(data)-1)/2), d, width, label=plot_labels[n], align='center', **kwargs)\n", " result.append(bar)\n", " \n", " ax.add_patch(Rectangle((-0.65+debug_shift, -1), 1, 28, facecolor='white', alpha=.8, edgecolor='None'))\n", " ax.add_patch(Rectangle((1.4+debug_shift, -1), 1, 25, facecolor='white', alpha=.8, edgecolor='None'))\n", "\n", " for i, n in enumerate(plot_labels):\n", " d = data[n]\n", " if len(d) == 0:\n", " continue\n", "\n", " bar = result[i]\n", " if n == 'nanobind':\n", " adj(ax.bar_label(bar, fmt='%.2f'))\n", " else:\n", " improvement = np.array(d) / np.array(data['nanobind'])\n", " improvement = ['%.2f\\n(x%.1f)' % (d[i], v) for i, v in enumerate(improvement)]\n", " adj(ax.bar_label(bar, labels=improvement, padding=3))\n", " \n", " ax.set_ylim(0, ylim)\n", " ax.set_xticks(x, experiment_labels)\n", " return fig, ax\n" ] }, { "cell_type": "code", "execution_count": null, "id": "60cb243a-e94d-4dd0-af67-91b7c5007571", "metadata": { "tags": [] }, "outputs": [], "source": [ "fig, ax = bars(times, ylim_scale=0.93, figsize_scale=1.1, width_scale=1)\n", "ax.set_ylabel('Time (seconds)')\n", "ax.set_title('Compilation time')\n", "ax.set_xlim(-0.45,3.45)\n", "\n", "ax.legend(loc='upper left')\n", "\n", "fig.tight_layout()\n", "plt.savefig('times.png', facecolor='white', dpi=200, bbox_inches='tight', pad_inches = 0)\n", "plt.savefig('times.svg', facecolor='white', bbox_inches='tight', pad_inches = 0)\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "id": "b23e02b4-6e98-49a3-a60f-14142757af71", "metadata": { "tags": [] }, "outputs": [], "source": [ "fig, ax = bars(sizes, ylim_scale=.085, figsize_scale=1.1)\n", "ax.set_ylabel('Size (MiB)')\n", "ax.set_title('Binary size')\n", "ax.set_xlim(-0.45,3.45)\n", "ax.legend(loc='lower left')\n", "\n", "fig.tight_layout()\n", "plt.savefig('sizes.png', facecolor='white', dpi=200, bbox_inches='tight', pad_inches = 0)\n", "plt.savefig('sizes.svg', facecolor='white', bbox_inches='tight', pad_inches = 0)\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "id": "d3f3b5d2-74d6-415c-ad3d-b8fb0f37eddb", "metadata": { "tags": [] }, "outputs": [], "source": [ "import cppyy\n", "if not hasattr(cppyy.gbl, 'test_0000'):\n", " cppyy.include('cppyy.h')\n", "\n", "plot_colors = {\n", " 'boost': cycle[1],\n", " 'cython': cycle[4],\n", " 'pybind11': cycle[3],\n", " 'cppyy' : cycle[8],\n", " 'python': 'None',\n", " 'nanobind': cycle[0]\n", "}\n", "\n", "plot_labels = {\n", " 'boost' : 'Boost.Python',\n", " 'pybind11' : 'pybind11', \n", " 'cppyy' : 'cppyy',\n", " 'cython' : 'Cython',\n", " 'nanobind' : 'nanobind',\n", " 'python' : 'Python'\n", "}\n", "\n", "class native_module:\n", " @staticmethod\n", " def test_0000(a, b, c, d, e, f):\n", " return a + b + c + d +e + f\n", "\n", " \n", " class Struct0:\n", " def __init__(self, a, b, c, d, e, f):\n", " self.a = a\n", " self.b = b\n", " self.c = c\n", " self.d = d\n", " self.e = e\n", " self.f = f\n", "\n", " def sum(self):\n", " return self.a + self.b + self.c + self.e + self.f\n", " \n", "\n", "rtimes = defaultdict(lambda: [])\n", "for name in ['func', 'class']:\n", " its = 10000000 if name == 'func' else 2500000\n", " for lib in plot_labels:\n", " for mode in ['debug', 'opt']:\n", " if lib == 'cppyy':\n", " m = cppyy.gbl\n", " elif lib == 'nanobind_sh':\n", " continue # Performance identical, not an interesting data point\n", " elif lib == 'python':\n", " m = native_module\n", " else:\n", " m = importlib.import_module(f'{name}_{lib}_{mode}')\n", " \n", " time_list = []\n", " for i in range(5):\n", " time_before = time.perf_counter()\n", " if name == 'func':\n", " func = m.test_0000\n", " for i in range(its):\n", " func(1,2,3,4,5,6)\n", " elif name == 'class':\n", " cls = m.Struct0\n", " sum_member = cls.sum\n", " for i in range(its):\n", " sum_member(cls(1,2,3,4,5,6))\n", "\n", " time_after = time.perf_counter()\n", " time_list.append(time_after-time_before)\n", " time_list.sort()\n", "\n", " rtimes[lib].append(time_list[len(time_list)//2])" ] }, { "cell_type": "code", "execution_count": null, "id": "5ad743ce-33c4-4dd1-8a0f-2ccbcf02aa1c", "metadata": { "tags": [] }, "outputs": [], "source": [ "fig, ax = bars(rtimes, ylim_scale=.188, figsize_scale=1.25, width_scale=1, debug_shift=.1)\n", "ax.set_ylabel('Time (seconds)')\n", "ax.set_title('Runtime performance')\n", "ax.set_xlim(-0.45,3.45)\n", "ax.legend()\n", "fig.tight_layout()\n", "plt.savefig('perf.png', facecolor='white', dpi=200, bbox_inches='tight', pad_inches = 0)\n", "plt.savefig('perf.svg', facecolor='white', bbox_inches='tight', pad_inches = 0)\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "id": "2f54fb73-d150-48c0-862f-57abdbce9875", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.6" } }, "nbformat": 4, "nbformat_minor": 5 } wjakob-nanobind-6c4457b/docs/ndarray.rst000066400000000000000000000701041474760012700202510ustar00rootroot00000000000000.. cpp:namespace:: nanobind .. _ndarray_class: The ``nb::ndarray<..>`` class ============================= nanobind can exchange n-dimensional arrays (henceforth "**nd-arrays**") with popular array programming frameworks including `NumPy `__, `PyTorch `__, `TensorFlow `__, `JAX `__, and `CuPy `_. It supports *zero-copy* exchange using two protocols: - The classic `buffer protocol `__. - `DLPack `__, a GPU-compatible generalization of the buffer protocol. nanobind knows how to talk to each framework and takes care of all the nitty-gritty details. To use this feature, you must add the include directive .. code-block:: cpp #include to your code. Following this, you can bind functions with :cpp:class:`nb::ndarray\<...\> `-typed parameters and return values. Array input arguments --------------------- A function that accepts an :cpp:class:`nb::ndarray\<\> `-typed parameter (i.e., *without* template parameters) can be called with *any* writable array from any framework regardless of the device on which it is stored. The following example binding declaration uses this functionality to inspect the properties of an arbitrary input array: .. code-block:: cpp m.def("inspect", [](const nb::ndarray<>& a) { printf("Array data pointer : %p\n", a.data()); printf("Array dimension : %zu\n", a.ndim()); for (size_t i = 0; i < a.ndim(); ++i) { printf("Array dimension [%zu] : %zu\n", i, a.shape(i)); printf("Array stride [%zu] : %zd\n", i, a.stride(i)); } printf("Device ID = %u (cpu=%i, cuda=%i)\n", a.device_id(), int(a.device_type() == nb::device::cpu::value), int(a.device_type() == nb::device::cuda::value) ); printf("Array dtype: int16=%i, uint32=%i, float32=%i\n", a.dtype() == nb::dtype(), a.dtype() == nb::dtype(), a.dtype() == nb::dtype() ); }); Below is an example of what this function does when called with a NumPy array: .. code-block:: pycon >>> my_module.inspect(np.array([[1,2,3], [3,4,5]], dtype=np.float32)) Array data pointer : 0x1c30f60 Array dimension : 2 Array dimension [0] : 2 Array stride [0] : 3 Array dimension [1] : 3 Array stride [1] : 1 Device ID = 0 (cpu=1, cuda=0) Array dtype: int16=0, uint32=0, float32=1 Array constraints ----------------- In practice, it can often be useful to *constrain* what kinds of arrays constitute valid inputs to a function. For example, a function expecting CPU storage would likely crash if given a pointer to GPU memory, and nanobind should therefore prevent such undefined behavior. The :cpp:class:`nb::ndarray\<...\> ` class accepts template arguments to specify such constraints. For example the binding below guarantees that the implementation can only be called with CPU-resident arrays with shape (·,·,3) containing 8-bit unsigned integers. .. code-block:: cpp using RGBImage = nb::ndarray, nb::device::cpu>; m.def("process", [](RGBImage data) { // Double brightness of the MxNx3 RGB image for (size_t y = 0; y < data.shape(0); ++y) for (size_t x = 0; x < data.shape(1); ++x) for (size_t ch = 0; ch < 3; ++ch) data(y, x, ch) = (uint8_t) std::min(255, data(y, x, ch) * 2); }); The above example also demonstrates the use of :cpp:func:`operator() `, which provides direct read/write access to the array contents assuming that they are reachable through the CPU's virtual address space. .. _ndarray-constraints-1: Overview ^^^^^^^^ Overall, the following kinds of constraints are available: - **Data type**: a type annotation like ``float``, ``uint8_t``, etc., constrain the numerical representation of the nd-array. Complex arrays (i.e., ``std::complex`` or ``std::complex``) are also supported. - **Constant arrays**: further annotating the data type with ``const`` makes it possible to call the function with constant arrays that do not permit write access. Without the annotation, calling the binding would fail with a ``TypeError``. You can alternatively accept constant arrays of *any type* by not specifying a data type at all and instead passing the :cpp:class:`nb::ro ` annotation. - **Shape**: The :cpp:class:`nb::shape ` annotation (as in ``nb::shape<-1, 3>``) simultaneously constrains the number of array dimensions and the size per dimension. A value of ``-1`` leaves the size of the associated dimension unconstrained. :cpp:class:`nb::ndim\ ` is shorter when only the dimension should be constrained. For example, ``nb::ndim<3>`` is equivalent to ``nb::shape<-1, -1, -1>``. - **Device tags**: annotations like :cpp:class:`nb::device::cpu ` or :cpp:class:`nb::device::cuda ` constrain the source device and address space. - **Memory order**: two ordering tags :cpp:class:`nb::c_contig ` and :cpp:class:`nb::f_contig ` enforce contiguous storage in either C or Fortran style. In the case of matrices, C-contiguous implies row-major and F-contiguous implies column-major storage. Without this tag, arbitrary non-contiguous representations (e.g. produced by slicing operations) and other unusual layouts are permitted. This tag is mainly useful when your code directly accesses the array contents via :cpp:func:`nb::ndarray\<...\>::data() `, while assuming a particular layout. A third order tag named :cpp:class:`nb::any_contig ` accepts *both* ``F``- and ``C``-contiguous arrays while rejecting non-contiguous ones. Type signatures ^^^^^^^^^^^^^^^ nanobind displays array constraints in docstrings and error messages. For example, suppose that we now call the ``process()`` function with an invalid input. This produces the following error message: .. code-block:: pycon >>> my_module.process(np.zeros(1)) TypeError: process(): incompatible function arguments. The following argument types are supported: 1. process(arg: ndarray[dtype=uint8, shape=(*, *, 3), device='cpu'], /) -> None Invoked with types: numpy.ndarray Note that these type annotations are intended for humans–they will not currently work with automatic type checking tools like `MyPy `__ (which at least for the time being don’t provide a portable or sufficiently flexible annotation of n-dimensional arrays). Overload resolution ^^^^^^^^^^^^^^^^^^^ A function binding can declare multiple overloads with different nd-array constraints (e.g., a CPU and a GPU implementation), in which case nanobind will call the first matching overload. When no perfect match can be found, nanobind will try each overload once more while performing basic implicit conversions: it will convert strided arrays into C- or F-contiguous arrays (if requested) and perform type conversion. This, e.g., makes it possible to call a function expecting a ``float32`` array with ``float64`` data. Implicit conversions create temporary nd-arrays containing a copy of the data, which can be undesirable. To suppress them, add an :cpp:func:`nb::arg("my_array_arg").noconvert() ` or :cpp:func:`"my_array_arg"_a.noconvert() ` argument annotation. Passing arrays within C++ code ------------------------------ You can think of the :cpp:class:`nb::ndarray ` class as a reference-counted pointer resembling ``std::shared_ptr`` that can be freely moved or copied. This means that there isn't a big difference between a function taking ``ndarray`` by value versus taking a constant reference ``const ndarray &`` (i.e., the former does not create an additional copy of the underlying data). Copies of the :cpp:class:`nb::ndarray ` wrapper will point to the same underlying buffer and increase the reference count until they go out of scope. You may call freely call :cpp:class:`nb::ndarray\<...\> ` methods from multithreaded code even when the `GIL `__ is not held, for example to examine the layout of an array and access the underlying storage. There are two exceptions to this: creating a *new* nd-array object from C++ (discussed :ref:`later `) and casting it to Python via the :cpp:func:`ndarray::cast` function both involve Python API calls that require that the GIL is held. .. _returning-ndarrays: Returning arrays from C++ to Python ----------------------------------- Passing an nd-array across the C++ → Python language barrier is a two-step process: 1. Creating an :cpp:class:`nb::ndarray\<...\> ` instance, which only stores *metadata*, e.g.: - Where is the data located in memory? (pointer address and device) - What is its type and shape? - Who owns this data? An actual Python object is not yet constructed at this stage. 2. Converting the :cpp:class:`nb::ndarray\<...\> ` into a Python object of the desired type (e.g. ``numpy.ndarray``). Normally, step 1 is your responsibility, while step 2 is taken care of by the binding layer. To understand this separation, let's look at an example. The ``.view()`` function binding below creates a 4×4 column-major NumPy array view into a ``Matrix4f`` instance. .. _matrix4f-example: .. code-block:: cpp struct Matrix4f { float m[4][4] { }; }; using Array = nb::ndarray, nb::f_contig>; nb::class_(m, "Matrix4f") .def(nb::init<>()) .def("view", [](Matrix4f &m){ return Array(data); }, nb::rv_policy::reference_internal); In this case: - step 1 is the ``Array(data)`` call in the lambda function. - step 2 occurs outside of the lambda function when the nd-array :cpp:class:`nb::ndarray\<...\> ` :ref:`type caster ` constructs a NumPy array from the metadata. Data *ownership* is an important aspect of this two-step process: because the NumPy array points directly into the storage of another object, nanobind must keep the ``Matrix4f`` instance alive as long as the NumPy array exists, which the :cpp:enumerator:`reference_internal ` return value policy signals to nanobind. More generally, wrapping an existing memory region without copying requires that that this memory region remains valid throughout the lifetime of the created array (more on this point :ref:`shortly `). Recall the discussion of the :ref:`nd-array constraint ` template parameters. For the return path, you will generally want to add a *framework* template parameter to the nd-array parameters that indicates the desired Python type. - :cpp:class:`nb::numpy `: create a ``numpy.ndarray``. - :cpp:class:`nb::pytorch `: create a ``torch.Tensor``. - :cpp:class:`nb::tensorflow `: create a ``tensorflow.python.framework.ops.EagerTensor``. - :cpp:class:`nb::jax `: create a ``jaxlib.xla_extension.DeviceArray``. - :cpp:class:`nb::cupy `: create a ``cupy.ndarray``. - No framework annotation. In this case, nanobind will create a raw Python ``dltensor`` `capsule `__ representing the `DLPack `__ metadata. This annotation also affects the auto-generated docstring of the function, which in this case becomes: .. code-block:: python view(self) -> numpy.ndarray[float32, shape=(4, 4), order='F'] Note that the framework annotation only plays a role when passing arrays from C++ to Python. It does not constrain the reverse direction (for example, a PyTorch array would still be accepted by a function taking the ``Array`` alias defined above as input. For this reason, you may want to add a :cpp:class:`nb::device::cpu ` device annotation). Dynamic array configurations ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The previous example was rather simple because all the array configuration was fully known at compile time and specified via the :cpp:class:`nb::ndarray\<...\> ` template parameters. In general, there are often dynamic aspects of the configuration that must be explicitly passed to the constructor. Its signature (with some simplifications) is given below. See the :ref:`ndarray::ndarray() ` documentation for a more detailed specification and another variant of the constructor. .. code-block:: cpp ndarray(void *data, std::initializer_list shape = { }, handle owner = { }, std::initializer_list strides = { }, dlpack::dtype dtype = ..., int device_type = ..., int device_id = 0, char order = ...) { .. } The parameters have the following role: - ``data``: CPU/GPU/.. memory address of the data. - ``shape``: number of dimensions and size along each axis. - ``owner``: a Python object owning the storage, which must be kept alive while the array object exists. - ``strides``: specifies the data layout in memory. You only need to specify this parameter if it has a non-standard ``order`` (e.g., if it is non-contiguous). Note that the ``strides`` count elements, not bytes. - ``dtype`` data type (floating point, signed/unsigned integer), bit depth. - ``device_type`` and ``device_id``: device type and number, e.g., for multi-GPU setups. - ``order``: coefficient memory order. Default: ``'C'`` (C-style) ordering, specify ``'F'`` for Fortran-style ordering. The parameters generally have inferred defaults based on the array's compile-time template parameters. Passing them explicitly overrides these defaults with information available at runtime. .. _ndarray-ownership: Data ownership ^^^^^^^^^^^^^^ Let's look at a fancier example that uses the constructor arguments explained above to return a dynamically sized 2D array. This example also shows another mechanism to express *data ownership*: .. code-block:: cpp m.def("create_2d", [](size_t rows, size_t cols) { // Allocate a memory region an initialize it float *data = new float[rows * cols]; for (size_t i = 0; i < rows * cols; ++i) data[i] = (float) i; // Delete 'data' when the 'owner' capsule expires nb::capsule owner(data, [](void *p) noexcept { delete[] (float *) p; }); return nb::ndarray>( /* data = */ data, /* shape = */ { rows, cols }, /* owner = */ owner ); }); The ``owner`` parameter should specify a Python object, whose continued existence keeps the underlying memory region alive. Nanobind will temporarily increase the ``owner`` reference count in the :cpp:func:`ndarray::ndarray()` constructor and then decrease it again when the created NumPy array expires. The above example binding returns a *new* memory region that should be deleted when it is no longer in use. This is done by creating a :cpp:class:`nb::capsule`, an opaque pointer with a destructor callback that runs at this point and takes care of cleaning things up. If there is already an existing Python object, whose existence guarantees that it is safe to access the provided storage region, then you may alternatively pass this object as the ``owner``---nanobind will make sure that this object isn't deleted as long as the created array exists. If the owner is a C++ object with an associated Python instance, you may use :cpp:func:`nb::find() ` to look up the associated Python object. When binding methods, you can use the :cpp:enumerator:`reference_internal ` return value policy to specify the implicit ``self`` argument as the ``owner`` upon return, which was done in the earlier ``Matrix4f`` :ref:`example `. .. warning:: If you do not specify an owner and use a return value policy like :cpp:enumerator:`rv_policy::reference` (see also the the section on :ref:`nd-array return value policies `), nanobind will assume that the array storage **remains valid forever**. This is one of the most frequent issues reported on the nanobind GitHub repository: users forget to think about data ownership and run into data corruption. If there isn't anything keeping the array storage alive, it will likely be released and reused at some point, while stale arrays still point to the associated memory region (i.e., a classic "use-after-free" bug). In more advanced situations, it may be helpful to have a capsule that manages the lifetime of data structures containing *multiple* storage regions. The same capsule can be referenced from different nd-arrays and will call the deleter when all of them have expired: .. code-block:: cpp m.def("return_multiple", []() { struct Temp { std::vector vec_1; std::vector vec_2; }; Temp *temp = new Temp(); temp->vec_1 = std::move(...); temp->vec_2 = std::move(...); nb::capsule deleter(temp, [](void *p) noexcept { delete (Temp *) p; }); size_t size_1 = temp->vec_1.size(); size_t size_2 = temp->vec_2.size(); return std::make_pair( nb::ndarray(temp->vec_1.data(), { size_1 }, deleter), nb::ndarray(temp->vec_2.data(), { size_2 }, deleter) ); }); .. _ndarray_rvp: Return value policies ^^^^^^^^^^^^^^^^^^^^^ Function bindings that return nd-arrays can specify return value policy annotations to determine whether or not a copy should be made. They are interpreted as follows: - The default :cpp:enumerator:`rv_policy::automatic` and :cpp:enumerator:`rv_policy::automatic_reference` policies cause the array to be copied when it has no owner and when it is not already associated with a Python object. - The policy :cpp:enumerator:`rv_policy::reference` references an existing memory region and never copies. - :cpp:enumerator:`rv_policy::copy` always copies. - :cpp:enumerator:`rv_policy::none` refuses the cast unless the array is already associated with an existing Python object (e.g. a NumPy array), in which case that object is returned. - :cpp:enumerator:`rv_policy::reference_internal` retroactively sets the nd-array's ``owner`` field to a method's ``self`` argument. It fails with an error if there is already a different owner. - :cpp:enumerator:`rv_policy::move` is unsupported and demoted to :cpp:enumerator:`rv_policy::copy`. .. _ndarray-temporaries: Returning temporaries ^^^^^^^^^^^^^^^^^^^^^ Returning nd-arrays from temporaries (e.g. stack-allocated memory) requires extra precautions. .. code-block:: cpp :emphasize-lines: 4,5 using Vector3f = nb::ndarray>; m.def("return_vec3", []{ float data[] { 1, 2, 3 }; // !!! BAD don't do this !!! return Vector3f(data); }); Recall the discussion at the :ref:`beginning ` of this subsection. The :cpp:class:`nb::ndarray\<...\> ` constructor only creates *metadata* describing this array, with the actual array creation happening *after* of the function call. That isn't safe in this case because ``data`` is a temporary on the stack that is no longer valid once the function has returned. To fix this, we could use the :cpp:func:`nb::cast() ` method to *force* the array creation in the body of the function: .. code-block:: cpp :emphasize-lines: 4,5 using Vector3f = nb::ndarray>; m.def("return_vec3", []{ float data[] { 1, 2, 3 }; // OK. return nb::cast(Vector3f(data)); }); While safe, one unfortunate aspect of this change is that the function now has a rather non-informative docstring ``return_vec3() -> object``, which is a consequence of :cpp:func:`nb::cast() ` returning a generic :cpp:class:`nb::object `. To fix this, you can use the nd-array :cpp:func:`.cast() ` method, which is like :cpp:func:`nb::cast() ` except that it preserves the type signature: .. code-block:: cpp :emphasize-lines: 4,5 using Vector3f = nb::ndarray>; m.def("return_vec3", []{ float data[] { 1, 2, 3 }; // Perfect. return Vector3f(data).cast(); }); .. _ndarray-nonstandard: Nonstandard arithmetic types ---------------------------- Low or extended-precision arithmetic types (e.g., ``int128``, ``float16``, ``bfloat16``) are sometimes used but don't have standardized C++ equivalents. If you wish to exchange arrays based on such types, you must register a partial overload of ``nanobind::detail::dtype_traits`` to inform nanobind about it. You are expressively allowed to create partial overloads of this class despite it being in the ``nanobind::detail`` namespace. For example, the following snippet makes ``__fp16`` (half-precision type on ``aarch64``) available by providing 1. ``value``, a DLPack ``nanobind::dlpack::dtype`` type descriptor, and 2. ``name``, a type name for use in docstrings and error messages. .. code-block:: cpp namespace nanobind::detail { template <> struct dtype_traits<__fp16> { static constexpr dlpack::dtype value { (uint8_t) dlpack::dtype_code::Float, // type code 16, // size in bits 1 // lanes (simd), usually set to 1 }; static constexpr auto name = const_name("float16"); }; } .. _ndarray-views: Fast array views ---------------- The following advice applies to performance-sensitive CPU code that reads and writes arrays using loops that invoke :cpp:func:`nb::ndarray\<...\>::operator() `. It does not apply to GPU arrays because they are usually not accessed in this way. Consider the following snippet, which fills a 2D array with data: .. code-block:: cpp void fill(nb::ndarray, nb::c_contig, nb::device::cpu> arg) { for (size_t i = 0; i < arg.shape(0); ++i) for (size_t j = 0; j < arg.shape(1); ++j) arg(i, j) = /* ... */; } While functional, this code is not perfect. The problem is that to compute the address of an entry, ``operator()`` accesses the DLPack array descriptor. This indirection can break certain compiler optimizations. nanobind provides the method :cpp:func:`ndarray\<...\>::view() ` to fix this. It creates a tiny data structure that provides all information needed to access the array contents, and which can be held within CPU registers. All relevant compile-time information (:cpp:class:`nb::ndim `, :cpp:class:`nb::shape `, :cpp:class:`nb::c_contig `, :cpp:class:`nb::f_contig `) is materialized in this view, which enables constant propagation, auto-vectorization, and loop unrolling. An improved version of the example using such a view is shown below: .. code-block:: cpp void fill(nb::ndarray, nb::c_contig, nb::device::cpu> arg) { auto v = arg.view(); // <-- new! for (size_t i = 0; i < v.shape(0); ++i) // Important; use 'v' instead of 'arg' everywhere in loop for (size_t j = 0; j < v.shape(1); ++j) v(i, j) = /* ... */; } Note that the view performs no reference counting. You may not store it in a way that exceeds the lifetime of the original array. When using OpenMP to parallelize expensive array operations, pass the ``firstprivate(view_1, view_2, ...)`` so that each worker thread can copy the view into its register file. .. code-block:: cpp auto v = arg.view(); #pragma omp parallel for schedule(static) firstprivate(v) for (...) { /* parallel loop */ } .. _ndarray-runtime-specialization: Specializing views at runtime ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ As mentioned earlier, element access via ``operator()`` only works when both the array's scalar type and its dimension are specified within the type (i.e., when they are known at compile time); the same is also true for array views. However, sometimes, it is useful that a function can be called with different array types. You may use the :cpp:func:`ndarray\<...\>::view() ` method to create *specialized* views if a run-time check determines that it is safe to do so. For example, the function below accepts contiguous CPU arrays and performs a loop over a specialized 2D ``float`` view when the array is of this type. .. code-block:: cpp void fill(nb::ndarray arg) { if (arg.dtype() == nb::dtype() && arg.ndim() == 2) { auto v = arg.view>(); // <-- new! for (size_t i = 0; i < v.shape(0); ++i) { for (size_t j = 0; j < v.shape(1); ++j) { v(i, j) = /* ... */; } } } else { /* ... */ } } Array libraries --------------- The Python `array API standard `__ defines a common interface and interchange protocol for nd-array libraries. In particular, to support inter-framework data exchange, custom array types should implement the - `__dlpack__ `__ and - `__dlpack_device__ `__ methods. This is easy thanks to the nd-array integration in nanobind. An example is shown below: .. code-block:: cpp nb::class_(m, "MyArray") // ... .def("__dlpack__", [](nb::kwargs kwargs) { return nb::ndarray<>( /* ... */); }) .def("__dlpack_device__", []() { return std::make_pair(nb::device::cpu::value, 0); }); Returning a raw :cpp:class:`nb::ndarray ` without framework annotation will produce a DLPack capsule, which is what the interface expects. The ``kwargs`` argument can be used to provide additional parameters (for example to request a copy), please see the DLPack documentation for details. Note that nanobind does not yet implement the versioned DLPack protocol. The version number should be ignored for now. Frequently asked questions -------------------------- Why does my returned nd-array contain corrupt data? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ If your nd-array bindings lead to undefined behavior (data corruption or crashes), then this is usually an ownership issue. Please review the section on :ref:`data ownership ` for details. Why does nanobind not accept my NumPy array? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ When binding a function that takes an ``nb::ndarray`` as input, nanobind will by default require that array to be writable. This means that the function cannot be called using NumPy arrays that are marked as constant. If you wish your function to be callable with constant input, either change the parameter to ``nb::ndarray`` (if the array is parameterized by type), or write ``nb::ndarray`` to accept a read-only array of any type. Limitations related to ``dtypes`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. _dtype_restrictions: Libraries like `NumPy `__ support arrays with flexible internal representations (*dtypes*), including - Floating point and integer arrays with various bit depths - Null-terminated strings - Arbitrary Python objects - Heterogeneous data structures composed of multiple fields nanobind's :cpp:class:`nb::ndarray\<...\> ` is based on the `DLPack `__ array exchange protocol, which causes it to be more restrictive. Presently supported dtypes include signed/unsigned integers, floating point values, complex numbers, and boolean values. Some :ref:`nonstandard arithmetic types ` can be supported as well. Nanobind can receive and return *read-only* arrays via the buffer protocol when exhanging data with NumPy. The DLPack interface currently ignores this annotation. wjakob-nanobind-6c4457b/docs/ndarray_index.rst000066400000000000000000000003111474760012700214310ustar00rootroot00000000000000.. _ndarrays: N-dimensional arrays ==================== nanobind provides two alternative interfaces to exchange array data between Python and C++. .. toctree:: :maxdepth: 1 ndarray eigen wjakob-nanobind-6c4457b/docs/ownership.rst000066400000000000000000000366061474760012700206400ustar00rootroot00000000000000.. _ownership: .. cpp:namespace:: nanobind Object ownership ================ Python and C++ don't manage the lifetime and storage of objects in the same way. Consequently, two questions arise whenever an object crosses the language barrier: - Who actually *owns* this object? C++? Python? Both?! - Can we safely determine when it is no longer needed? This is important: we *must* exclude the possibility that Python destroys an object that is still being used by C++ (or vice versa). The :ref:`previous section ` introduced three ways of exchanging information between C++ and Python: :ref:`type casters `, :ref:`bindings `, and :ref:`wrappers `. It is specifically :ref:`bindings ` for which these two questions must be answered. .. _ownership_problem: A problematic example --------------------- Consider the following problematic example to see what can go wrong: .. code-block:: cpp #include namespace nb = nanobind; struct Data { }; Data data; // Data global variable & function returning a pointer to it Data *get_data() { return &data; } NB_MODULE(my_ext, m) { nb::class_(m, "Data"); // KABOOM, calling this function will crash the Python interpreter m.def("get_data", &get_data); } The bound function ``my_ext.get_data()`` returns a Python object of type ``my_ext.Data`` that wraps the pointer ``&data`` and takes ownership of it. When Python eventually garbage collects the object, nanobind will try to free the (non-heap-allocated) C++ instance via ``operator delete``, causing a segmentation fault. To avoid this problem, we can 1. **Provide more information**: the problem was that nanobind *incorrectly* transferred ownership of a C++ instance to the Python side. To fix this, we can add add a :ref:`return value policy ` annotation that clarifies what to do with the return value. 2. **Make ownership transfer explicit**: C++ types passed via :ref:`unique pointers ` (``std::unique_ptr``) make the ownership transfer explicit in the type system, which would have revealed the problem in this example. 3. **Switch to shared ownership**: C++ types passed via :ref:`shared pointers ` (``std::shared_ptr``), or which use :ref:`intrusive reference counting ` can be shared by C++ and Python. The whole issue disappears because ownership transfer is no longer needed. The remainder of this section goes through each of these options. .. _rvp: Return value policies --------------------- nanobind provides several *return value policy* annotations that can be passed to :func:`module_::def`, :func:`class_::def`, and :func:`cpp_function`. The default policy is :cpp:enumerator:`rv_policy::automatic`, which is usually a reasonable default (but not in this case!). In the :ref:`problematic example `, the policy :cpp:enumerator:`rv_policy::reference` should have been specified explicitly so that the global instance is only *referenced* without any implied transfer of ownership, i.e.: .. code-block:: cpp m.def("get_data", &get_data, nb::rv_policy::reference); On the other hand, this is not the right policy for many other situations, where ignoring ownership could lead to resource leaks. As a developer using this library, it is important that you familiarize yourself with the different options below. In particular, the following policies are available: - :cpp:enumerator:`rv_policy::take_ownership`: Create a thin Python object wrapper around the returned C++ instance without making a copy and transfer ownership to Python. When the Python wrapper is eventually garbage collected, nanobind will call the C++ ``delete`` operator to free the C++ instance. In the example below, a function uses this policy to transfer ownership of a heap-allocated C++ instance to Python: .. code-block:: cpp m.def("make_data", []{ return new Data(); }, nb::rv_policy::take_ownership); The return value policy declaration could actually have been omitted here because :cpp:enumerator:`take_ownership ` is the default for *pointer return values* (see :cpp:enumerator:`automatic `). - :cpp:enumerator:`rv_policy::copy`: Copy-construct a new Python object from the C++ instance. The copy will be owned by Python, while C++ retains ownership of the original. In the example below, a function uses this policy to return a reference to a C++ instance. The owner and lifetime of such a reference may not be clear, so the safest route is to make a copy. .. code-block:: cpp struct A { B &b() { /* .. unknown code .. */ } }; nb::class_(m, "A") .def("b", &A::b, nb::rv_policy::copy); The return value policy declaration could actually have been omitted here because :cpp:enumerator:`copy ` is the default for *lvalue reference* return values (see :cpp:enumerator:`automatic `). - :cpp:enumerator:`rv_policy::move`: Move-construct a new Python object from the C++ instance. The new object will be owned by Python, while C++ retains ownership of the original (whose contents were likely invalidated by the move operation). In the example below, a function uses this policy to return a C++ instance by value. The :cpp:enumerator:`copy ` operation mentioned above would also be safe to use, but move construction has the potential of being significantly more efficient. .. code-block:: cpp struct A { B b() { return B(...); } }; nb::class_(m, "A") .def("b", &A::b, nb::rv_policy::move); The return value policy declaration could actually have been omitted here because :cpp:enumerator:`move ` is the default for *functions that return by value* (see :cpp:enumerator:`automatic `). - :cpp:enumerator:`rv_policy::reference`: Create a thin Python object wrapper around the returned C++ instance without making a copy, but *do not transfer ownership to Python*. nanobind will never call the C++ ``delete`` operator, even when the wrapper expires. The C++ side is responsible for destructing the C++ instance. This return value policy is *dangerous* and should be used cautiously. Undefined behavior will ensue when the C++ side deletes the instance while it is still being used by Python. If you need to use this policy, combine it with a :cpp:struct:`keep_alive` function binding annotation to manage the lifetime. Or use the simple and safe :cpp:enumerator:`reference_internal ` alternative described next. Below is an example use of this return value policy to reference a global variable that does not need ownership and lifetime management. .. code-block:: cpp Data data; // This is a global variable m.def("get_data", []{ return &data; }, nb::rv_policy::reference) - :cpp:enumerator:`rv_policy::reference_internal`: A policy for *methods* that expose an internal field. The lifetime of the field must match that of the parent object. The policy resembles :cpp:enumerator:`reference ` in that it creates creates a thin Python object wrapper around the returned C++ field without making a copy, and without transferring ownership to Python. Furthermore, it ensures that the instance owning the field (implicit ``this``/``self`` argument) cannot be garbage collected while an object representing the field is alive. The example below uses this policy to implement a *getter* that permits mutable access to an internal field. .. code-block:: cpp struct MyClass { public: MyField &field() { return m_field; } private: MyField m_field; }; nb::class_(m, "MyClass") .def("field", &MyClass::field, nb::rv_policy::reference_internal); More advanced variations of this scheme are also possible using combinations of :cpp:enumerator:`reference ` and the :cpp:struct:`keep_alive` function binding annotation. - :cpp:enumerator:`rv_policy::none`: This is the most conservative policy: it simply refuses the cast unless the C++ instance already has a corresponding Python object, in which case the question of ownership becomes moot. - :cpp:enumerator:`rv_policy::automatic`: This is the default return value policy, which falls back to :cpp:enumerator:`take_ownership ` when the return value is a pointer, :cpp:enumerator:`move ` when it is a rvalue reference, and :cpp:enumerator:`copy ` when it is a lvalue reference. - :cpp:enumerator:`rv_policy::automatic_reference`: This policy matches :cpp:enumerator:`automatic ` but falls back to :cpp:enumerator:`reference ` when the return value is a pointer. It is the default for function arguments when calling Python functions from C++ code via :cpp:func:`detail::api::operator()`. You probably won't need to use this policy in your own code. .. _unique_ptr: Unique pointers --------------- Passing a STL unique pointer embodies an ownership transfer---a return value policy annotation is therefore not needed. To bind functions that receive or return ``std::unique_ptr<..>``, add the extra include directive .. code-block:: cpp #include .. note:: While this this header file technically contains a :ref:`type caster `, it is *not* affected by their usual limitations (mandatory copy/conversion, inability to mutate function arguments). **Example**: The following example binds two functions that create and consume instances of a C++ type ``Data`` via unique pointers. .. code-block:: cpp #include namespace nb = nanobind; NB_MODULE(my_ext, m) { struct Data { }; nb::class_(m, "Data"); m.def("create", []() { return std::make_unique(); }); m.def("consume", [](std::unique_ptr x) { /* no-op */ }); } Calling a function taking a unique pointer from Python invalidates the passed Python object. nanobind will refuse further use of it: .. code-block:: pycon :emphasize-lines: 8,9 Python 3.11.1 (main, Dec 23 2022, 09:28:24) [Clang 14.0.0 (clang-1400.0.29.202)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import my_ext >>> x = my_ext.create() >>> my_ext.consume(x) >>> my_ext.consume(x) :1: RuntimeWarning: nanobind: attempted to access an uninitialized instance of type 'my_ext.Data'! TypeError: consume(): incompatible function arguments. The following argument types are supported: 1. consume(arg: my_ext.Data, /) -> None Invoked with types: my_ext.Data We strongly recommend that you replace all use of ``std::unique_ptr`` by ``std::unique_ptr>`` in your code. Without the latter type declaration, which references a custom nanobind-provided deleter :cpp:class:`nb::deleter\ `, nanobind cannot transfer ownership of objects constructed using :cpp:class:`nb::init\<...\> ` to C++ and will refuse to do so with an error message. Further detail on this special case can be found in the *advanced* :ref:`section ` on object ownership. .. _shared_ownership: Shared ownership ---------------- In a *shared ownership* model, an object can have multiple owners that each register their claim by holding a *reference*. The system keeps track of the total number of references and destroys the object once the count reaches zero. Passing such an object in a function call shares ownership between the caller and callee. nanobind makes this behavior seamless so that everything works regardless of whether caller/callee are written in C++ or Python. .. _shared_ptr: Shared pointers ^^^^^^^^^^^^^^^ STL shared pointers (``std::shared_ptr``) allocate a separate control block to keep track of the reference count, which makes them very general but also slightly less efficient than other alternatives. nanobind's support for shared pointers requires an extra include directive: .. code-block:: cpp #include .. note:: While this this header file technically contains a :ref:`type caster `, it is *not* affected by their usual limitations (mandatory copy/conversion, inability to mutate function arguments). You don't need to specify a return value policy annotation when a function returns a shared pointer. nanobind's implementation of ``std::shared_ptr`` support typically allocates a new ``shared_ptr`` control block each time a Python object must be converted to ``std::shared_ptr``. The new ``shared_ptr`` "owns" a reference to the Python object, and its deleter drops that reference. This has the advantage that the Python portion of the object will be kept alive by its C++-side references (which is important when implementing C++ virtual methods in Python), but it can be inefficient when passing the same object back and forth between Python and C++ many times, and it means that the ``use_count()`` method of ``std::shared_ptr`` will return a value that does not capture all uses. Some of these problems can be mitigated by modifying ``T`` so that it inherits from ``std::enable_shared_from_this``. See the :ref:`advanced section ` on object ownership for more details on the implementation. nanobind has limited support for objects that inherit from ``std::enable_shared_from_this`` to allow safe conversion of raw pointers to shared pointers. The safest way to deal with these objects is to always use ``std::make_shared(...)`` when constructing them in C++, and always pass them across the Python/C++ boundary wrapped in an explicit ``std::shared_ptr``. If you do this, then there shouldn't be any surprises. If you will be passing raw ``T*`` pointers around, then read the :ref:`advanced section on object ownership ` for additional caveats. .. _intrusive_intro: Intrusive reference counting ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Intrusive reference counting is the most flexible and efficient way of handling shared ownership. The main downside is that you must adapt the base class of your object hierarchy to the needs of nanobind. The core idea is to define base class (e.g. ``Object``) common to all bound types requiring shared ownership. That class contains a builtin atomic counter (e.g., ``m_ref_count``) and a Python object pointer (e.g., ``m_py_object``). .. code-block:: cpp class Object { ... private: mutable std::atomic m_ref_count { 0 }; PyObject *m_py_object = nullptr; }; The core idea is that such ``Object`` instances can either be managed by C++ or Python. In the former case, the ``m_ref_count`` field keeps track of the number of outstanding references. In the latter case, reference counting is handled by Python, and the ``m_ref_count`` field remains unused. This is actually little wasteful---nanobind therefore ships with a more efficient reference counter sample implementation that supports both use cases while requiring only ``sizeof(void*)`` bytes of storage: .. code-block:: cpp #include class Object { ... private: intrusive_counter m_ref_count; }; Please read the dedicated :ref:`section on intrusive reference counting ` for more details on how to set this up. wjakob-nanobind-6c4457b/docs/ownership_adv.rst000066400000000000000000000420671474760012700214700ustar00rootroot00000000000000.. _ownership_adv: .. cpp:namespace:: nanobind Object ownership, continued =========================== This section covers intrusive reference counting as an alternative to shared pointers, and it explains the nitty-gritty details of how shared and unique pointer conversion is implemented in nanobind. .. _intrusive: Intrusive reference counting ---------------------------- nanobind provides a custom intrusive reference counting solution that completely solves the issue of shared C++/Python object ownership, while avoiding the overheads and complexities of traditional C++ shared pointers (``std::shared_ptr``). The main limitation is that it requires adapting the base class of an object hierarchy according to the needs of nanobind, which may not always be possible. Motivation ^^^^^^^^^^ Consider the following simple class with intrusive reference counting: .. code-block:: cpp class Object { public: void inc_ref() const noexcept { ++m_ref_count; } void dec_ref() const noexcept { if (--m_ref_count == 0) delete this; } private: mutable std::atomic m_ref_count { 0 }; }; It contains an atomic counter that stores the number of references. When the counter reaches zero, the object deallocates itself. Easy and efficient. The advantage of over ``std::shared_ptr`` is that no separate control block must be allocated. Technical band-aids like ``std::enable_shared_from_this`` can also be avoided, since the reference count is always found in the object itself. However, one issue that tends to arise when a type like ``Object`` is wrapped using nanobind is that there are now *two* separate reference counts referring to the same object: one in Python’s ``PyObject``, and one in ``Object``. This can lead to a problematic reference cycle: - Python’s ``PyObject`` needs to keep the ``Object`` instance alive so that it can be safely passed to C++ functions. - The C++ ``Object`` may in turn need to keep the ``PyObject`` alive. This is the case when a subclass uses *trampolines* (:c:macro:`NB_TRAMPOLINE`, :c:macro:`NB_OVERRIDE`) to catch C++ virtual function calls and potentially dispatch them to an overridden implementation in Python. In this case, the C++ instance needs to be able to perform a function call on its own Python object identity, which requires a reference. The source of the problem is that there are *two* separate counters that try to reason about the reference count of *one* instance, which leads to an uncollectable inter-language reference cycle. The solution ^^^^^^^^^^^^ We can solve the problem by using just one counter: - if an instance lives purely on the C++ side, the ``m_ref_count`` field is used to reason about the number of references. - The first time that an instance is exposed to Python (by being created from Python, or by being returned from a bound C++ function), lifetime management switches over to Python. The file `nanobind/intrusive/counter.h `_ includes an official sample implementation of this functionality. It contains an extra optimization to pack *either* a reference counter or a pointer to a ``PyObject*`` into a single ``sizeof(void*)``-sized field. The most basic interface, :cpp:class:`intrusive_counter` represents an atomic counter that can be increased (via :cpp:func:`intrusive_counter::inc_ref()`) or decreased (via :cpp:func:`intrusive_counter::dec_ref()`). When the counter reaches zero, the object should be deleted, which ``dec_ref()`` indicates by returning ``true``. In addition to this simple counting mechanism, ownership of the object can also be transferred to Python (via :cpp:func:`intrusive_counter::set_self_py()`). In this case, subsequent calls to ``inc_ref()`` and ``dec_ref()`` modify the reference count of the underlying Python object. To incorporate intrusive reference counting into your own project, you would usually add an :cpp:class:`intrusive_counter`-typed member to the base class of an object hierarchy and expose it as follows: .. code-block:: cpp #include class Object { public: void inc_ref() noexcept { m_ref_count.inc_ref(); } bool dec_ref() noexcept { return m_ref_count.dec_ref(); } // Important: must declare virtual destructor virtual ~Object() = default; void set_self_py(PyObject *self) noexcept { m_ref_count.set_self_py(self); } private: nb::intrusive_counter m_ref_count; }; // Convenience function for increasing the reference count of an instance inline void inc_ref(Object *o) noexcept { if (o) o->inc_ref(); } // Convenience function for decreasing the reference count of an instance // and potentially deleting it when the count reaches zero inline void dec_ref(Object *o) noexcept { if (o && o->dec_ref()) delete o; } Alternatively, you could also inherit from :cpp:class:`intrusive_base`, which obviates the need for all of the above declarations: .. code-block:: cpp class Object : public nb::intrusive_base { public: // ... }; The main change in the bindings is that the base class must specify a :cpp:class:`nb::intrusive_ptr ` annotation to inform an instance that lifetime management has been taken over by Python. This annotation is automatically inherited by all subclasses. In the linked example, this is done via the ``Object::set_self_py()`` method that we can now call from the class binding annotation: .. code-block:: cpp nb::class_( m, "Object", nb::intrusive_ptr( [](Object *o, PyObject *po) noexcept { o->set_self_py(po); })); Also, somewhere in your binding initialization code, you must register Python reference counting hooks with the intrusive reference counter class. This allows its implementation of the code in ``nanobind/intrusive/counter.h`` to *not* depend on Python (this means that it can be used in projects where Python bindings are an optional component). .. code-block:: cpp nb::intrusive_init( [](PyObject *o) noexcept { nb::gil_scoped_acquire guard; Py_INCREF(o); }, [](PyObject *o) noexcept { nb::gil_scoped_acquire guard; Py_DECREF(o); }); These ``counter.h`` include file references several functions that must be compiled somewhere inside the project, which can be accomplished by including the following file from a single ``.cpp`` file. .. code-block:: cpp #include Having to call :cpp:func:`inc_ref()` and :cpp:func:`dec_ref()` many times to perform manual reference counting in project code can quickly become tedious. Nanobind also ships with a :cpp:class:`ref\ ` RAII helper class to help with this. .. code-block:: cpp #include void foo() { /// Assignment to ref automatically increases the object's reference count ref x = new MyObject(); // ref can be used like a normal pointer x->func(); } // <-- ref::~ref() calls dec_ref(), which deletes the now-unreferenced instance When the file ``nanobind/intrusive/ref.h`` is included following ``nanobind/nanobind.h``, it also exposes a custom type caster to bind functions taking or returning ``ref``-typed values. That's it. If you use this approach, any potential issues involving shared pointers, return value policies, reference leaks with trampolines, etc., can be avoided from the beginning. .. _shared_ptr_adv: Shared pointers, continued -------------------------- The following continues the :ref:`discussion of shared pointers ` in the introductory section on object ownership and provides detail on how shared pointer conversion is *implemented* by nanobind. When the user calls a C++ function taking an argument of type ``std::shared_ptr`` from Python, ownership of that object must be shared between C++ to Python. nanobind does this by increasing the reference count of the ``PyObject`` and then creating a ``std::shared_ptr`` with a new control block containing a custom deleter that will in turn reduce the Python reference count upon destruction of the shared pointer. When a C++ function returns a ``std::shared_ptr``, nanobind checks if the instance already has a ``PyObject`` counterpart (nothing needs to be done in this case). Otherwise, it indicates shared ownership by creating a temporary ``std::shared_ptr`` on the heap that will be destructed when the ``PyObject`` is garbage collected. The approach in nanobind was chosen following on discussions with `Ralf Grosse-Kunstleve `_; it is unusual in that multiple ``shared_ptr`` control blocks are potentially allocated for the same object, which means that ``std::shared_ptr::use_count()`` generally won’t show the true global reference count. .. _enable_shared_from_this: enable_shared_from_this ^^^^^^^^^^^^^^^^^^^^^^^ The C++ standard library class ``std::enable_shared_from_this`` allows an object that inherits from it to locate an existing ``std::shared_ptr`` that manages that object. nanobind supports types that inherit from ``enable_shared_from_this``, with some caveats described in this section. Background (not nanobind-specific): Suppose a type ``ST`` inherits from ``std::enable_shared_from_this``. When a raw pointer ``ST *obj`` or ``std::unique_ptr obj`` is wrapped in a shared pointer using a constructor of the form ``std::shared_ptr(obj, ...)``, a reference to the new ``shared_ptr``\'s control block is saved (as ``std::weak_ptr``) inside the object. This allows new ``shared_ptr``\s that share ownership with the existing one to be obtained for the same object using ``obj->shared_from_this()`` or ``obj->weak_from_this()``. nanobind's support for ``std::enable_shared_from_this`` consists of three behaviors: * If a raw pointer ``ST *obj`` is returned from C++ to Python, and there already exists an associated ``std::shared_ptr`` which ``obj->shared_from_this()`` can locate, then nanobind will produce a Python instance that shares ownership with it. The behavior is identical to what would happen if the C++ code did ``return obj->shared_from_this();`` (returning an explicit ``std::shared_ptr`` to Python) rather than ``return obj;``. The return value policy has limited effect in this case; you will get shared ownership on the Python side regardless of whether you used `rv_policy::take_ownership` or `rv_policy::reference`. (`rv_policy::copy` and `rv_policy::move` will still create a new object that has no ongoing relationship to the returned pointer.) * Note that this behavior occurs only if such a ``std::shared_ptr`` already exists! If not, then nanobind behaves as it would without ``enable_shared_from_this``: a raw pointer will transfer exclusive ownership to Python by default, or will create a non-owning reference if you use `rv_policy::reference`. * If a Python object is passed to C++ as ``std::shared_ptr obj``, and there already exists an associated ``std::shared_ptr`` which ``obj->shared_from_this()`` can locate, then nanobind will produce a ``std::shared_ptr`` that shares ownership with it: an additional reference to the same control block, rather than a new control block (as would occur without ``enable_shared_from_this``). This improves performance and makes the result of ``shared_ptr::use_count()`` more accurate. * If a Python object is passed to C++ as ``std::shared_ptr obj``, and there is no associated ``std::shared_ptr`` that ``obj->shared_from_this()`` can locate, then nanobind will produce a ``std::shared_ptr`` as usual (with a new control block whose deleter drops a Python object reference), *and* will do so in a way that enables future calls to ``obj->shared_from_this()`` to find it as long as any ``shared_ptr`` that shares this control block is still alive on the C++ side. (Once all of the ``std::shared_ptr``\s that share this control block have been destroyed, the underlying PyObject reference being managed by the ``shared_ptr`` deleter will be dropped, and ``shared_from_this()`` will stop working. It can be reenabled by passing the Python object back to C++ as ``std::shared_ptr`` once more, which will create another control block.) Bindings for a class that supports ``enable_shared_from_this`` will be slightly larger than bindings for a class that doesn't, as nanobind must produce type-specific code to implement the above behaviors. .. warning:: The ``shared_from_this()`` method will only work when there is actually a ``std::shared_ptr`` managing the object. A nanobind instance constructed from Python will not have an associated ``std::shared_ptr`` yet, so ``shared_from_this()`` will throw an exception if you pass such an instance to C++ using a reference or raw pointer. ``shared_from_this()`` will only work when there exists a corresponding live ``std::shared_ptr`` on the C++ side. The only situation where nanobind will create the first ``std::shared_ptr`` for an object (thus enabling ``shared_from_this()``), even with ``enable_shared_from_this``, is when a Python instance is passed to C++ as the explicit type ``std::shared_ptr``. If you don't do this, or if no such ``std::shared_ptr`` is still alive, then ``shared_from_this()`` will throw an exception. It also works to create the ``std::shared_ptr`` on the C++ side, such as by using a factory function which always uses ``std::make_shared(...)`` to construct the object, and returns the resulting ``std::shared_ptr`` to Python. If you need to enable ``shared_from_this`` immediately upon regular Python-side object construction (i.e., ``SomeType(*args)`` rather than ``SomeType.some_fn(*args)``), you can bind a C++ function that returns ``std::shared_ptr`` as your class's ``__new__`` method. See the documentation on :ref:`customizing object creation `. .. warning:: C++ code that receives a raw pointer ``T *obj`` *must not* assume that it has exclusive ownership of ``obj``, or even that ``obj`` is allocated on the C++ heap (via ``operator new``); ``obj`` might instead be a subobject of a nanobind instance allocated from Python. This applies even if ``T`` supports ``shared_from_this()`` and there is no associated ``std::shared_ptr``. Lack of a ``shared_ptr`` does *not* imply exclusive ownership; it just means there's no way to share ownership with whoever the current owner is. .. _unique_ptr_adv: Unique pointers --------------- The following continues the :ref:`discussion of unique pointers ` in the introductory section on object ownership and provides detail on how unique pointer conversion is *implemented* by nanobind. Whereas ``std::shared_ptr<..>`` could abstract over details concerning storage and the deletion mechanism, this is not possible in the simpler ``std::unique_ptr<..>``, which means that some of those details leak into the type signature. When the user calls a C++ function taking an argument of type ``std::unique_ptr`` from Python, ownership of that object must be transferred from C++ to Python. - When ``Deleter`` is ``std::default_delete`` (i.e., the default when no ``Deleter`` is specified), this ownership transfer is only possible when the instance was originally created by a *new expression* within C++ and nanobind has taken over ownership (i.e., it was created by a function returning a raw pointer ``T *value`` with :cpp:enumerator:`rv_policy::take_ownership`, or a function returning a ``std::unique_ptr``). This limitation exists because the ``Deleter`` will execute the statement ``delete value`` when the unique pointer expires, causing undefined behavior when the object was allocated within Python (the problem here is that nanobind uses the Python memory allocator and furthermore co-locates Python and C++ object storage. A *delete expression* cannot be used in such a case). nanobind detects this, refuses unsafe conversions with a ``TypeError`` and emits a separate warning. - To enable ownership transfer under all conditions, nanobind provides a custom ``Deleter`` named :cpp:class:`nb::deleter\ ` that uses reference counting to keep the underlying ``PyObject`` alive during the lifetime of the unique pointer. Following this route requires changing function signatures so that they use ``std::unique_ptr>`` instead of ``std::unique_ptr``. This custom deleter supports ownership by both C++ and Python and can be used in all situations. In both cases, a Python object may continue to exist after ownership was transferred to C++ side. nanobind marks this object as *invalid*: any operations involving it will fail with a ``TypeError``. Reverse ownership transfer at a later point will make it usable again. Binding functions that return a ``std::unique_ptr`` always works: nanobind will then acquire or reacquire ownership of the object. Deleters other than ``std::default_delete`` or ``nb::deleter`` are *not supported*. wjakob-nanobind-6c4457b/docs/packaging.rst000066400000000000000000000275421474760012700205450ustar00rootroot00000000000000.. _packaging: Packaging ========= A Python *wheel* is a self-contained binary file that bundles Python code and extension libraries along with metadata such as versioned package dependencies. Wheels are easy to download and install, and they are the recommended mechanism for distributing extensions created using nanobind. This section walks through the recommended sequence of steps to build wheels and optionally automate this process to simultaneously target many platforms (Linux, Windows, macOS) and processors (i386, x86_64, arm64) using the `GitHub Actions `__ CI service. Note that all of the recommended practices have already been implemented in the `nanobind_example repository `_, which is a minimal C++ project with nanobind-based bindings. You may therefore prefer to clone this repository and modify its contents. Step 1: Overview ---------------- The example project has a simple directory structure: .. code-block:: text ├── README.md ├── CMakeLists.txt ├── pyproject.toml └── src/ ├── my_ext.cpp └── my_ext/ └── __init__.py The file ``CMakeLists.txt`` contains the C++-specifics part of the build system, while ``pyproject.toml`` explains how to turn the example into a wheel. The file ``README.md`` should ideally explain how to use the project in more detail. Its contents are arbitrary, but the file must exist for the following build system to work. All source code is located in a ``src`` directory containing the Python package as a subdirectory. Compilation will turn ``my_ext.cpp`` into a shared library in the package directory, which has an underscored platform-dependent name (e.g., ``_my_ext_impl.cpython-311-darwin.so``) to indicate that it is an implementation detail. The ``src/my_ext/__init__.py`` imports the extension and exposes relevant functionality. In this small example project, it only contains a single line: .. code-block:: python from ._my_ext_impl import hello The file ``src/my_ext.cpp`` contains minimal bindings for an example function: .. code-block:: cpp #include NB_MODULE(_my_ext_impl, m) { m.def("hello", []() { return "Hello world!"; }); } The next two steps will set up the infrastructure needed for wheel generation. Step 2: Specify build dependencies and metadata ----------------------------------------------- In the root directory of the project, create a file named ``pyproject.toml`` listing *build-time dependencies*. Note that runtime dependencies *do not* need to be added here. The following core dependencies are required by nanobind: .. code-block:: toml [build-system] requires = ["scikit-build-core >=0.4.3", "nanobind >=1.3.2"] build-backend = "scikit_build_core.build" You may need to increase the minimum nanobind version in the above snippet if you are using features from versions newer than 1.3.2. Just below the list of build-time requirements, specify project metadata including: - The project's name (which must be a valid package name) - The version number - A brief (1-line) description of the project - The name of a more detailed README file - The list of authors with email addresses. - The software license - The project web page - Runtime dependencies, if applicable An example is shown below: .. code-block:: toml [project] name = "my_ext" version = "0.0.1" description = "A brief description of what this project does" readme = "README.md" requires-python = ">=3.8" authors = [ { name = "Your Name", email = "your.email@address.com" }, ] classifiers = [ "License :: BSD", ] # Optional: runtime dependency specification # dependencies = [ "cryptography >=41.0" ] [project.urls] Homepage = "https://github.com/your/project" We will use `scikit-build-core `__ to build wheels, and this tool also has its own configuration block in ``pyproject.toml``. The following defaults are recommended: .. code-block:: toml [tool.scikit-build] # Protect the configuration against future changes in scikit-build-core minimum-version = "0.4" # Setuptools-style build caching in a local directory build-dir = "build/{wheel_tag}" # Build stable ABI wheels for CPython 3.12+ wheel.py-api = "cp312" Step 3: Set up a CMake build system ----------------------------------- Next, we will set up a suitable ``CMakeLists.txt`` file in the root directory. Since this build system is designed to be invoked through ``scikit-build-core``, it does not make sense to perform a standalone CMake build. The message at the top warns users attempting to do this. .. code-block:: cmake # Set the minimum CMake version and policies for highest tested version cmake_minimum_required(VERSION 3.15...3.27) # Set up the project and ensure there is a working C++ compiler project(my_ext LANGUAGES CXX) # Warn if the user invokes CMake directly if (NOT SKBUILD) message(WARNING "\ This CMake file is meant to be executed using 'scikit-build-core'. Running it directly will almost certainly not produce the desired result. If you are a user trying to install this package, use the command below, which will install all necessary build dependencies, compile the package in an isolated environment, and then install it. ===================================================================== $ pip install . ===================================================================== If you are a software developer, and this is your own package, then it is usually much more efficient to install the build dependencies in your environment once and use the following command that avoids a costly creation of a new virtual environment at every compilation: ===================================================================== $ pip install nanobind scikit-build-core[pyproject] $ pip install --no-build-isolation -ve . ===================================================================== You may optionally add -Ceditable.rebuild=true to auto-rebuild when the package is imported. Otherwise, you need to rerun the above after editing C++ files.") endif() Next, import Python and nanobind including the ``Development.SABIModule`` component that can be used to create `stable ABI `__ builds. .. code-block:: cmake # Try to import all Python components potentially needed by nanobind find_package(Python 3.8 REQUIRED COMPONENTS Interpreter Development.Module OPTIONAL_COMPONENTS Development.SABIModule) # Import nanobind through CMake's find_package mechanism find_package(nanobind CONFIG REQUIRED) The last two steps build and install the actual extension .. code-block:: cmake # We are now ready to compile the actual extension module nanobind_add_module( # Name of the extension _my_ext_impl # Target the stable ABI for Python 3.12+, which reduces # the number of binary wheels that must be built. This # does nothing on older Python versions STABLE_ABI # Source code goes here src/my_ext.cpp ) # Install directive for scikit-build-core install(TARGETS _my_ext_impl LIBRARY DESTINATION my_ext) Step 4: Install the package locally ----------------------------------- To install the package, run .. code-block:: bash $ cd $ pip install . ``pip`` will parse the ``pyproject.toml`` file and create a fresh environment containing all needed dependencies. Following this, you should be able to install and access the extension. .. code-block:: python >>> import my_ext >>> my_ext.hello() 'Hello world!' Alternatively, you can use the following command to generate a ``.whl`` file instead of installing the package. .. code-block:: bash $ pip wheel . Step 5: Incremental rebuilds ---------------------------- The ``pip install`` and ``pip wheel`` commands are extremely conservative to ensure reproducible builds. They create a pristine virtual environment and install build-time dependencies before compiling the extension *from scratch*. It can be frustrating to wait for this lengthy sequence of steps after every small change to a source file during the active development phase of a project. To avoid this, first install the project's build dependencies, e.g.: .. code-block:: bash $ pip install nanobind scikit-build-core[pyproject] Next, install the project without build isolation to enable incremental builds: .. code-block:: bash $ pip install --no-build-isolation -ve . This command will need to be run after every change to reinstall the updated package. For an even more interactive experience, use .. code-block:: bash $ pip install --no-build-isolation -Ceditable.rebuild=true -ve . This will automatically rebuild any code (if needed) whenever the ``my_ext`` package is imported into a Python session. Step 6: Build wheels in the cloud --------------------------------- On my machine, the ``pip wheel`` command produces a file named ``my_ext-0.0.1-cp311-cp311-macosx_13_0_arm64.whl`` that is specific to Python 3.11 running on an arm64 macOS machine. Other Python versions and operating systems each require their own wheels, which leads to a dauntingly large build matrix (though nanobind's stable ABI support will help to significantly reduce the size of this matrix once Python 3.12 is more widespread). Rather than building these wheels manually on different machines, it is far more efficient to use GitHub actions along with the powerful `cibuildwheel `__ package to fully automate the process. To do so, create a file named ``.github/workflows/wheels.yml`` containing the contents of the `following file `__. You may want to remove the ``on: push:`` lines, otherwise, the action will run after every commit, which is perhaps a bit excessive. In this case, you can still trigger the action manually on the *Actions* tab of the GitHub project page. Furthermore, append the following ``cibuildwheel``-specific configuration to ``pyproject.toml``: .. code-block:: toml [tool.cibuildwheel] # Necessary to see build output from the actual compilation build-verbosity = 1 # Optional: run pytest to ensure that the package was correctly built # test-command = "pytest {project}/tests" # test-requires = "pytest" # Needed for full C++17 support on macOS [tool.cibuildwheel.macos.environment] MACOSX_DEPLOYMENT_TARGET = "10.14" Following each run, the action provides a downloadable *build artifact*, which is a ZIP file containing all the individual wheel files for each platform. By default, ``cibuildwheel`` will launch a very large build matrix, and it is possible that your extension is not compatible with every single configuration. For example, suppose that the project depends on Python 3.9+ and a 64 bit processor. In this case, add further entries to the ``[tool.cibuildwheel]`` block to remove incompatible configurations from the matrix: .. code-block:: toml skip = ["cp38-*", "pp38-*"] # Skip CPython and PyPy 3.8 archs = ["auto64"] # Only target 64 bit architectures The `cibuildwheel documentation `__ explains the possible options. If you set up a GitHub actions `secret `__ named ``pypi_password`` containing a PyPI authentication token, the action will automatically upload the generated wheels to the `Python Package Index (PyPI) `__ when the action is triggered by a `software release event `__. wjakob-nanobind-6c4457b/docs/porting.rst000066400000000000000000000342211474760012700202730ustar00rootroot00000000000000.. cpp:namespace:: nanobind .. _porting: Porting guide ============= The API of nanobind is *extremely* similar to that of `pybind11 `_, which makes porting existing projects easy. Parts of the nanobind documentation are almost verbatim copies pybind11's documentation. A number of noteworthy changes are documented below. Namespace --------- nanobind types and functions are located in the ``nanobind`` namespace. The following shorthand alias is recommended and used throughout the documentation: .. code-block:: cpp namespace nb = nanobind; Name changes ------------ The following macros, types, and functions were renamed: .. list-table:: :widths: 42 48 :header-rows: 1 * - pybind11 - nanobind * - ``PYBIND11_MODULE(..)`` - :c:macro:`NB_MODULE(..) ` * - ``PYBIND11_OVERRIDE_*(..)`` - :c:macro:`NB_OVERRIDE_*(..) ` * - ``error_already_set`` - :cpp:class:`python_error` * - ``type::of()`` - :cpp:func:`type\() ` * - ``type`` - :cpp:class:`type_object` * - ``reinterpret_borrow(x)`` - :cpp:func:`borrow\(x) ` * - ``reinterpret_steal(x)`` - :cpp:func:`steal\(x) ` * - ``.def_readwrite(..)`` - :cpp:func:`.def_rw(..) ` * - ``.def_readonly(..)`` - :cpp:func:`.def_ro(..) ` * - ``.def_property(..)`` - :cpp:func:`.def_prop_rw(..) ` * - ``.def_property_readonly(..)`` - :cpp:func:`.def_prop_ro(..) ` * - ``.def_readwrite_static(..)`` - :cpp:func:`.def_rw_static(..) ` * - ``.def_readonly_static(..)`` - :cpp:func:`.def_ro_static(..) ` * - ``.def_property_static(..)`` - :cpp:func:`.def_prop_rw_static(..) ` * - ``.def_property_readonly_static(..)`` - :cpp:func:`.def_prop_ro_static(..) ` * - ``register_exception`` - :cpp:class:`exception\ ` None/null arguments ------------------- In contrast to pybind11, nanobind does *not* permit ``None``-valued function arguments by default. You must enable them explicitly using the :cpp:func:`arg::none() ` argument annotation, e.g.: .. code-block:: cpp m.def("func", &func, "arg"_a.none()); It is also possible to set a ``None`` default value, in which case the :cpp:func:`.none() ` annotation can be omitted. .. code-block:: cpp m.def("func", &func, "arg"_a = nb::none()); ``None``-valued arguments are only supported by two of the three parameter passing styles described in the section on :ref:`information exchange `. In particular, they are supported by :ref:`bindings ` and :ref:`wrappers `, *but not* by :ref:`type casters `. Shared pointers and holders --------------------------- When nanobind instantiates a C++ type within Python, the resulting instance data is stored *within* the created Python object ("``PyObject``"). Alternatively, when an already existing C++ instance is transferred to Python via a function return value and :cpp:enumerator:`rv_policy::reference`, :cpp:enumerator:`rv_policy::reference_internal`, or :cpp:enumerator:`rv_policy::take_ownership`, nanobind creates a smaller wrapper ``PyObject`` that only stores a pointer to the instance data. This is *very different* from pybind11, where the instance ``PyObject`` contained a *holder type* (typically ``std::unique_ptr``) storing a pointer to the instance data. Dealing with holders caused inefficiencies and introduced complexity; they were therefore removed in nanobind. This has implications on object ownership, shared ownership, and interactions with C++ shared/unique pointers. The :ref:`intermediate ` and :ref:`advanced ` sections on object ownership provide further detail. The gist is that it is no longer necessary to specify holder types in the type declaration: *pybind11*: .. code-block:: cpp py::class_>(m, "MyType") *nanobind*: .. code-block:: cpp nb::class_(m, "MyType") To bind functions that exchange shared/unique pointers, you must add one or both of the following include directives to your code: .. code-block:: cpp #include #include Binding functions that take ``std::unique_ptr`` arguments involves some limitations that can be avoided by changing their signatures to ``std::unique_ptr>`` (:ref:`details `). Use of ``std::enable_shared_from_this`` is permitted, but since nanobind does not use holder types, an object constructed in Python will typically not have any associated ``std::shared_ptr`` until it is passed to a C++ function that accepts ``std::shared_ptr``. That means a C++ function that accepts a raw ``T*`` and calls ``shared_from_this()`` on it might stop working when ported from pybind11 to nanobind. You can solve this problem by always passing such objects across the Python/C++ boundary as ``std::shared_ptr`` rather than as ``T*``. See the :ref:`advanced section on object ownership ` for more details. Custom constructors ------------------- In pybind11, custom constructors (i.e. ones that do not already exist in the C++ class) could be specified as a lambda function returning an instance of the desired type. .. code-block:: cpp py::class_(m, "MyType") .def(py::init([](int) { return MyType(...); })); Unfortunately, the implementation of this feature was quite complex and often required further internal calls to the move or copy constructor. nanobind instead reverts to how pybind11 originally implemented this feature using in-place construction (`placement new `_): .. code-block:: cpp nb::class_(m, "MyType") .def("__init__", [](MyType *t) { new (t) MyType(...); }); The provided lambda function will be called with a pointer to uninitialized memory that has already been allocated (this memory region is co-located with the Python object for reasons of efficiency). The lambda function can then either run an in-place constructor and return normally (in which case the instance is assumed to be correctly constructed) or fail by raising an exception. To turn an existing factory function into a constructor, you will need to combine the above pattern with an invocation of the move/copy-constructor, e.g.: .. code-block:: cpp nb::class_(m, "MyType") .def("__init__", [](MyType *t) { new (t) MyType(MyType::create()); }); Implicit conversions -------------------- In pybind11, implicit conversions were specified using a follow-up function call. This also works in nanobind, but it is recommended that you already specify them within the constructor declaration: *pybind11*: .. code-block:: cpp py::class_(m, "MyType") .def(py::init()); py::implicitly_convertible(); *nanobind*: .. code-block:: cpp nb::class_(m, "MyType") .def(nb::init_implicit()); Trampoline classes ------------------ Trampolines, i.e., polymorphic class implementations that forward virtual function calls to Python, now require an extra :c:macro:`NB_TRAMPOLINE(parent, size) ` declaration, where ``parent`` refers to the parent class and ``size`` is at least as big as the number of :c:macro:`NB_OVERRIDE_*() ` calls. nanobind caches information to enable efficient function dispatch, for which it must know the number of trampoline "slots". The macro ``PYBIND11_OVERRIDE_*(..)`` required the base type and return value as the first two arguments. This information is no longer needed in nanobind, and the arguments should be removed in :c:macro:`NB_OVERRIDE_*() `: An example: .. code-block:: cpp struct PyAnimal : Animal { NB_TRAMPOLINE(Animal, 1); std::string name() const override { NB_OVERRIDE(name); } }; Trampoline declarations with an insufficient size may eventually trigger a Python ``RuntimeError`` exception with a descriptive label, e.g.: .. code-block:: text nanobind::detail::get_trampoline('PyAnimal::what()'): the trampoline ran out of slots (you will need to increase the value provided to the NB_TRAMPOLINE() macro) Iterator bindings ----------------- Use of the :cpp:func:`nb::make_iterator() `, :cpp:func:`nb::make_key_iterator() `, and :cpp:func:`nb::make_value_iterator() ` functions requires including the additional header file ``nanobind/make_iterator.h``. The interface of these functions has also slightly changed: all take a Python scope and a name as first and second arguments, which are used to permanently "install" the iterator type (which is created on demand). See the `test suite `_ for a worked out example. Type casters ------------ The API of custom type casters has changed *significantly*. The following changes are needed: - ``load()`` was renamed to ``from_python()``. The function now takes an extra ``uint8_t flags`` parameter (instead ``bool convert``, which is now represented by the flag ``nb::detail::cast_flags::convert``). A ``cleanup_list *`` pointer keeps track of Python temporaries that are created by the conversion, and which need to be deallocated after a function call has taken place. ``flags`` and ``cleanup`` should be passed to any recursive usage of ``type_caster::from_python()``. If casting fails due to a Python exception, the function should clear it (``PyErr_Clear()``) and return ``false``. If a severe error condition arises that should be reported, use Python warning API calls for this, e.g. ``PyErr_WarnFormat()``. - ``cast()`` was renamed to ``from_cpp()``. The function takes a return value policy (as before) and a ``cleanup_list *`` pointer. If casting fails due to a Python exception, the function should *leave the error set* (note the asymmetry compared to ``from_python()``) and return ``nullptr``. Note that the cleanup list is only available when ``from_python()`` or ``from_cpp()`` are called as part of function dispatch, while usage by :cpp:func:`nb::cast() ` may set ``cleanup`` to ``nullptr`` if implicit conversions are not enabled. This case should be handled gracefully by refusing the conversion if the cleanup list is absolutely required. Type casters may not raise C++ exceptions. Both ``from_python()`` and ``from_cpp()`` must be annotated with ``noexcept``. Exceptions or failure conditions caused by a conversion should instead be caught *within* the function body and handled as follows: - ``from_python()``: return ``false``. That's it. (Failed Python to C++ conversion occur all the time while dispatching calls, causing nanobind to simply move to the next function overload. Dedicated error reporting would add undesirable overheads). In case of a severe internal error, use the CPython warning API (e.g., ``PyErr_Warn()``) to notify the user. - ``from_cpp()``: a failure here is more serious, since a return value of a successfully evaluated cannot be converted, causing the call to fail. To provide further detail, use the CPython error API (e.g., ``PyErr_Format()``) and return an invalid handle (``return nb::handle();``). The ``std::pair`` type caster (`link `_) may be useful as a starting point of custom implementations. .. _removed: Removed features ---------------- A number of pybind11 features are unavailable in nanobind. The list below uses the following symbols: - ○: This removal is a design choice. Use pybind11 if you need this feature. - ●: Unclear, to be discussed. Removed features include: - ○ **Multiple inheritance**: this feature was a persistent source of complexity in pybind11 and it is one of the main casualties in creating nanobind. - ○ **Holders**: nanobind instances co-locate instance data with a Python object instead of accessing it via a holder type. This is a major difference compared to pybind11 and will require changes to binding code that used custom holders (e.g. unique or shared pointers). The :ref:`intermediate ` and :ref:`advanced ` sections on object ownership provide further detail. - ○ **Multi-intepreter, Embedding**: The ability to embed Python in an executable or run several independent Python interpreters in the same process is unsupported. Nanobind caters to bindings only. Multi-interpreter support would require TLS lookups for nanobind data structures, which is undesirable. - ○ **Function binding annotations**: The ``pos_only`` argument annotation was removed. However, the same behavior can be achieved by creating unnamed arguments; see the discussion in the section on :ref:`keyword-only arguments `. - ○ **Metaclasses**: creating types with custom metaclasses is unsupported. - ○ **Module-local bindings**: support was removed (both for types and exceptions). - ○ **Custom allocation**: C++ classes with an overloaded or deleted ``operator new`` / ``operator delete`` are not supported. - ○ **Compilation**: workarounds for buggy or non-standard-compliant compilers were removed and will not be reintroduced. - ○ The ``options`` class for customizing docstring generation was removed. - ○ The NumPy array class (``py::array``) was removed in exchange for a more powerful alternative (:cpp:class:`nb::ndarray\<..\> `) that additionally supports CPU/GPU tensors produced by various frameworks (NumPy, PyTorch, TensorFlow, JAX, etc.). Its API is not compatible with pybind11, however. - ● Buffer protocol binding (``.def_buffer()``) was removed in favor of :cpp:class:`nb::ndarray\<..\> `. - ● Support for evaluating Python files was removed. Bullet points marked with ● may be reintroduced eventually, but this will need to be done in a careful opt-in manner that does not affect code complexity, binary size, and compilation/runtime performance of basic bindings that don't depend on these features. wjakob-nanobind-6c4457b/docs/pypy.rst000066400000000000000000000017161474760012700176150ustar00rootroot00000000000000:orphan: .. cpp:namespace:: nanobind .. _pypy_issues: PyPy support ------------ PyPy 7.3.10 and newer versions are supported, though with some limitations: 1. When nanobind types occur in reference cycles, then those cycles are not collectable and will be leaked. This is a limitation of PyPy's ``cpyext`` layer that was reported in `PyPy issue #3849 `_. Note that this would only affects users that use the :cpp:class:`nb::type_slots() ` feature to implement a custom ``Py_tp_traverse`` or ``Py_tp_clear`` slot. 2. nanobind normally complains about any reference leaks involving instances, functions, and types when the interpreter shuts down. PyPy lacks the final garbage collection step that is needed to identify such leaks See `PyPy issue #3855 `_. Those those checks therefore had to be disabled when compiling for PyPy. wjakob-nanobind-6c4457b/docs/release.rst000066400000000000000000000021751474760012700202340ustar00rootroot00000000000000How to make a new release? -------------------------- 1. Ensure that the full version of nanobind is checked out (including the ``robin_map`` submodule) 2. Update version in ``src/__init__.py``, ``include/nanobind/nanobind.h``, and ``pyproject.toml``: Also: - Remove ``dev1`` suffix from ``X.Y.Zdev1`` in ``src/__init__.py`` and ``pyproject.toml``. - Set ``NB_VERSION_DEV`` to ``0`` in ``include/nanobind/nanobind.h``. 3. Add release date to ``docs/changelog.rst``. 4. Update ``setup.py`` if new directories were added (see ``package_data``). Update ``cmake/nanobind-config.cmake`` if new C++ source or header files were added. 5. Commit: ``git commit -am "vX.Y.Z release"`` 6. Tag: ``git tag -a vX.Y.Z -m "vX.Y.Z release"`` 7. Push: ``git push`` and ``git push --tags`` 8. Run ``pipx run build`` 9. Upload: ``twine upload --repository nanobind `` 10. Update version in ``src/__init__.py`` and ``include/nanobind/nanobind.h``: - Append ``dev1`` suffix from ``X.Y.Zdev1`` in ``src/__init__.py`` and ``pyproject.toml``. - Set ``NB_VERSION_DEV`` to ``1`` in ``include/nanobind/nanobind.h`` wjakob-nanobind-6c4457b/docs/requirements.txt000066400000000000000000000001721474760012700213410ustar00rootroot00000000000000furo sphinx==6.1.3 sphinx-copybutton==0.5.1 sphinxcontrib-moderncmakedomain==3.25.0 sphinxcontrib-svg2pdfconverter==1.2.2 wjakob-nanobind-6c4457b/docs/typeslots.rst000066400000000000000000000166601474760012700206660ustar00rootroot00000000000000.. _typeslots: .. cpp:namespace:: nanobind Customizing type creation ========================= nanobind exposes a low-level interface to install custom *type slots* (``PyType_Slot`` in the `CPython API `_) in newly constructed types. This provides an escape hatch to realize features that were not foreseen in the design of this library. To use this feature, specify the :cpp:class:`nb::type_slots() ` annotation when creating the type. .. code-block:: cpp nb::class_(m, "MyClass", nb::type_slots(slots)); Here, ``slots`` should refer to an array of function pointers that are tagged with a corresponding slot identifier. For example, here is an example function that overrides the addition operator so that it behaves like a multiplication. .. code-block:: cpp PyObject *myclass_tp_add(PyObject *a, PyObject *b) { return PyNumber_Multiply(a, b); } PyType_Slot slots[] = { { Py_nb_add, (void *) myclass_tp_add }, { 0, nullptr } }; The ``slots`` array specified in the previous :cpp:class:`nb::class_\() ` declaration references the function ``myclass_tp_add`` and is followed by a mandatory null terminator. Information on type slots can be found in the CPython documentation sections covering `type objects `_ and `type construction `_. This example is contrived because it could have been accomplished using builtin features: .. code-block:: cpp nb::class_(m, "MyClass") .def("__add__", [](const MyClass &a, const MyClass &b) { return a * b; }, nb::is_operator()) The next section introduces a more interesting use case. .. _cyclic_gc: Cyclic garbage collection ------------------------- Python tracks the lifetime of objects using an approach known as *reference counting*. An object can be safely deconstructed once it is no longer referenced from elsewhere, which happens when its reference count reaches zero. This mechanism is simple and efficient, but it breaks down when objects form *reference cycles*. For example, consider the following data structure .. code-block:: cpp struct Wrapper { std::shared_ptr value; }; with associated bindings .. code-block:: cpp nb::class_(m, "Wrapper") .def(nb::init<>()) .def_rw("value", &Wrapper::value); If we instantiate this class with a cycle, it can never be reclaimed (even when Python shuts down and is supposed to free up all memory): .. code-block:: pycon >>> a = my_ext.Wrapper() >>> a.value = a >>> del a nanobind will loudly complain about this when the Python interpreter shuts down: .. code-block:: pycon >>> exit() nanobind: leaked 1 instances! nanobind: leaked 1 types! - leaked type "my_ext.Wrapper" nanobind: leaked 3 functions! - leaked function "" - leaked function "__init__" - leaked function "" nanobind: this is likely caused by a reference counting issue in the binding code. The leaked ``Wrapper`` instance ``a`` references the ``Wrapper`` type, which in turn references function definitions, causing a longer sequence of warnings. Python provides a *cyclic garbage collector* that can in principle solve this problem. To operate correctly, it requires information about how objects are connected to each other. We can provide a ``tp_traverse`` type slot that walks through the object graph to inform the cyclic GC, and a ``tp_clear`` slot to break any detected reference cycles: .. code-block:: cpp int wrapper_tp_traverse(PyObject *self, visitproc visit, void *arg) { // Retrieve a pointer to the C++ instance associated with 'self' (never fails) Wrapper *w = nb::inst_ptr(self); // If w->value has an associated CPython object, return it. // If not, value.ptr() will equal NULL, which is also fine. nb::handle value = nb::find(w->value); // Inform the Python GC about the instance (if non-NULL) Py_VISIT(value.ptr()); return 0; } int wrapper_tp_clear(PyObject *self) { // Retrieve a pointer to the C++ instance associated with 'self' (never fails) Wrapper *w = nb::inst_ptr(self); // Clear the cycle! w->value.reset(); return 0; } // Slot data structure referencing the above two functions PyType_Slot slots[] = { { Py_tp_traverse, (void *) wrapper_tp_traverse }, { Py_tp_clear, (void *) wrapper_tp_clear }, { 0, nullptr } }; The type ``visitproc`` and macro ``Py_VISIT()`` are part of the Python C API. .. note:: When targeting free-threaded Python, it is important that the ``tp_traverse`` callback does not hold additional references to the objects being traversed. A previous version of this documentation page suggested the following .. code-block:: cpp nb::object value = nb::find(w->value); Py_VISIT(value.ptr()); However, these now have to change to .. code-block:: cpp nb::handle value = nb::find(w->value); Py_VISIT(value.ptr()); The expression :cpp:func:`nb::inst_ptr\(self) ` efficiently returns the C++ instance associated with a Python object and is explained in the documentation about nanobind's :cpp:ref:`low level interface `. Note the use of the :cpp:func:`nb::find() ` function, which behaves like :cpp:func:`nb::cast() ` by returning the Python object associated with a C++ instance. The main difference is that :cpp:func:`nb::cast() ` will create the Python object if it doesn't exist, while :cpp:func:`nb::find() ` returns a ``nullptr`` object in that case. To activate this machinery, the ``Wrapper`` type bindings must be made aware of these extra type slots: .. code-block:: cpp nb::class_(m, "Wrapper", nb::type_slots(slots)) With this change, the cycle can be garbage-collected, and the leak warnings disappear. Reference cycles involving functions ------------------------------------ What if our wrapper class from the previous example instead stored a function object? .. code-block:: cpp struct Wrapper { std::function value; }; It may not be immediately obvious, but functions are one of the main sources of reference cycles! For example, in Python we could write .. code-block:: pycon >>> a = my_ext.Wrapper() >>> a.value = lambda: print(a) This function is actually a `function closure `_ because it references external variable state (its body accesses ``a``). This creates an inter-language cycle ``Wrapper`` → ``function`` (itself wrapped in ``std::function``) → ``Wrapper``. Such cycles are extremely common when Python-based callbacks can be installed in C++ classes. An example would be a callback handler triggered by a button press in a GUI framework. It is important to detect and handle such cycles. When given a ``std::function<>`` instance, :cpp:func:`nb::find() ` retrieves the associated Python ``function`` object (if present), which means that the previous ``wrapper_tp_traverse()`` traversal function continues to work without changes. The ``tp_clear`` slot requires small touch-ups: .. code-block:: cpp int wrapper_tp_clear(PyObject *self) { Wrapper *w = nb::inst_ptr(self); w->value = nullptr; return 0; } That's it! wjakob-nanobind-6c4457b/docs/typing.rst000066400000000000000000000606251474760012700201320ustar00rootroot00000000000000.. cpp:namespace:: nanobind .. _typing: Typing ====== This section covers three broad typing-related topics: 1. How to create rich type annotation in C++ bindings so that projects using them can be effectively type-checked. 2. How to :ref:`automatically generate stub files ` that are needed to enable static type checking and autocompletion in Python IDEs. 3. How to write :ref:`pattern files ` to handle advanced use cases requiring significant stub customization. Signature customization ----------------------- In larger binding projects, some customization of function or class signatures is often needed so that static type checkers can effectively use the generated stubs. .. _typing_signature_functions: Functions ^^^^^^^^^ Nanobind generates typed function signatures automatically, but these are not always satisfactory. For example, the following function binding .. code-block:: cpp nb::class_(m, "Int") .def(nb::self == nb::self); is likely to be rejected because the default ``__eq__`` function signature .. code-block:: text __eq__(self, arg: Int, /) -> bool is more specific than that of the parent class ``object``: .. code-block:: text __eq__(self, arg: object, /) -> bool In this case, a static type checker like `MyPy `__ will report a failure: .. code-block:: text error: Argument 1 of "__eq__" is incompatible with supertype "object"; supertype defines the argument type as "object" [override] To handle such cases, you can use the :cpp:class:`nb::sig ` attribute to overrides the function signature with a custom string. .. code-block:: cpp nb::class_(m, "Int") .def(nb::self == nb::self, nb::sig("def __eq__(self, arg: object, /) -> bool")); The argument must be a valid Python function signature of the form ``def name(...) -> ...`` without trailing colon (``":"``) and newlines, where ``name`` must furthermore match the name given to the binding declaration. In this case, the name is implicitly given by the operator. It must match ``"name"`` in the case of ``.def("name", ...)``-style bindings with an explicit name. The signature can span multiple lines, e.g., to prefix one or more decorators. The modified signature is shown in generated stubs, docstrings, and error messages (e.g., when a function receives incompatible arguments). In cases where a custom signature is only needed to tweak how nanobind renders the signature of a default argument, the more targeted :cpp:func:`nb::arg("name").sig("signature") ` annotation is preferable to :cpp:class:`nb::sig `. .. _typing_signature_classes: Classes ^^^^^^^ Signature customization is also available for class bindings, though only stubs are affected in this case. Consider the example below, which defines an iterable vector type storing integers. Suppose that ``GeneralIterator`` iterates over arbitrary data and does not provide a useful ``int``-typed signature. .. code-block:: cpp using IntVec = std::vector; nb::class_(m, "IntVec") .def("__iter__", [](const IntVec &v) -> GeneralIterator { ... }) It may be useful to inherit from ``collections.abc.Iterable[int]`` to communicate more information to static type checkers, but such a Python → C++ inheritance chain is not permitted by nanobind. .. _typing_liberties: Stubs often take certain liberties in deviating somewhat from the precise type signature of the underlying implementation, which is fine as long as this improves the capabilities of the type checker (the stubs are only used by the static type checking phase, which never imports the actual extension). Here, we could specify .. code-block:: cpp nb::class_(m, "IntVec", nb::sig("class IntVec(collections.abc.Iterable[int])")); This is technically a lie. Such shenanigans are worthwhile because they can greatly improve the development experience (e.g. `VS Code `__ autocomplete) involving compiled extensions. The supplied signature string must be a valid Python class signature of the form ``class ClassName(...)`` excluding trailing colon (``":"``) and newline, where ``ClassName`` must furthermore match the name provided in the main class binding declaration. The signature can span multiple lines, e.g., to prefix one or more decorators. Generic types ------------- .. _typing_generics_parameterizing: Parameterizing generic types ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Various standard Python types are `generic `__ can be parameterized to improve the effectiveness of static type checkers such as `MyPy `__. In the presence of such a specialization, a type checker can, e.g., infer that the variable ``a`` below is of type ``int``. .. code-block:: python def f() -> list[int]: ... a = f()[0] This is even supported for *abstract types*---for example, ``collections.abc.Mapping[str, int]`` indicates an abstract mapping from strings to integers. nanobind provides the template class :cpp:class:`nb::typed\ ` to generate parameterized type annotations in C++ bindings. For example, the argument and return value of the following function binding reproduces the exact list and mapping types mentioned above. .. code-block:: cpp m.def("f", [](nb::typed arg) -> nb::typed { ... }); (Usually, :cpp:class:`nb::typed\ ` would be applied to :ref:`wrapper ` types, though this is not a strict limitation.) An important limitation of this feature is that it *only* affects function signatures. Nanobind will (as always) ensure that ``f`` can only be called with a ``nb::mapping``, but it will *not* insert additional runtime checks to verify that ``arg`` indeed maps strings to integers. It is the responsibility of the function to perform these checks and, if needed, to raise a :cpp:func:`nb::type_error `. The parameterized C++ type :cpp:class:`nb::typed\ ` subclasses the type ``T`` and can be used interchangeably with ``T``. The other arguments (``Ts...``) are used to generate a Python type signature but have no other effect (for example, parameterizing by ``str`` on the Python end can alternatively be achieved by passing ``nb::str``, ``std::string``, or ``const char*`` as part of the ``Ts...`` parameter pack). There are two special forms of ``nb::typed`` that will be rendered as something other than ``T[Ts...]``: * In some cases, a function may wish to accept or return an arbitrary Python object, but generate signatures that describe it as some more specific type ``T``. The types ``nb::typed`` and ``nb::typed`` will be rendered as ``T`` rather than as the nonsensical ``object[T]`` that they would be without this rule. (If you want nanobind to check that an argument is actually of type ``T``, while still giving you a generic Python object to work with, then use :cpp:class:`nb::handle_t\ ` instead.) * Type parameters for ``nb::callable`` can be provided using a C++ function signature, since there would otherwise be no way to express the nested brackets used in Python callable signatures. In order to express the Python type ``Callable[[str, float], int]``, which is a function taking two parameters (string and float) and returning an integer, you might write ``nb::typed``. For a callable type that accepts any arguments, like ``Callable[..., int]``, use a C-style variadic function signature: ``nb::typed``. (The latter could also be written without this special support, as ``nb::typed``.) .. _typing_generics_creating: Creating generic types ^^^^^^^^^^^^^^^^^^^^^^ Python types inheriting from `types.Generic `__ can be *parameterized* by other types including generic `type variables `__ that act as placeholders. Such constructions enable more effective static type checking. In the snippet below, tools like `MyPy `__ or `PyRight `__ can infer that ``x`` and ``y`` have types ``Wrapper[int]`` and ``int``, respectively. .. code-block:: python import typing # 1. Instantiate a placeholder type ("type variable") used below T = typing.TypeVar("T") # 2. Create a generic type by inheriting from typing.Generic class Wrapper(typing.Generic[T]): # The constructor references the placeholder type def __init__(self, value: T): self.value = value # .. this type is then preserved in the getter def get(self) -> T: return self.value # Based on the typed constructor, MyPy knows that 'x' has type 'Wrapper[int]' x = Wrapper(3) # Based on the typed 'Wrapped.get' method, 'y' is inferred to have type 'int' y = x.get() Note that parameterization of a generic type doesn't generate new code or modify its functionality. It is not to be confused with C++ template instantiation. The feature only exists to propagate fine-grained type information and thereby aid static type checking. Similar functionality can also be supported in nanobind-based binding projects. This looks as follows: .. code-block:: cpp #include // needed by nb::type_var below struct Wrapper { nb::object value; }; NB_MODULE(my_ext, m) { // 1. Instantiate a placeholder type ("type variable") used below m.attr("T") = nb::type_var("T"); // 2. Create a generic type, and indicate in generated stubs // that it derives from Generic[T] nb::class_ wrapper(m, "Wrapper", nb::is_generic(), nb::sig("class Wrapper(typing.Generic[T])")) .def(nb::init(), nb::sig("def __init__(self, arg: T, /) -> None")) .def("get", [](Wrapper &w) { return w.value; }, nb::sig("def get(self, /) -> T")); } This involves the following steps: - The :cpp:func:`nb::type_var ` constructor generates a type variable analogous to the previous Python snippet and assigns it to the name ``"T"`` within the module. - If we were to follow the previous Python example, the next step would require defining ``Wrapper`` as a subclass of ``typing.Generic[T]``. However, this isn't possible because nanobind-based classes cannot derive from Python types. - The solution to this problem takes the following :ref:`liberties `: - It passes the :cpp:class:`nb::is_generic ` annotation to the :cpp:class:`nb::class_\<...\> ` constructor, causing the addition of a ``__class_getattr__`` member that enables type parameterization. Following this step, an expression like ``Wrapper[int]`` becomes valid and returns a ``typing.TypeAlias`` (in other words, the behavior is *as if* we had derived from ``typing.Generic[T]``). However, `MyPy `__ and similar tools don't quite know what to do with custom types overriding ``__class_getattr__`` themselves, since the official parameterization mechanism is to subclass ``typing.Generic``. - Therefore, we *lie* about this in the stub and declare ``typing.Generic[T]`` as a base class. Only static type checkers will see this information, and it helps them to interpret how the type works. - That's it! You may also extend parameterized forms of such generic types: .. code-block:: cpp nb::class_(m, "Subclass", wrapper[nb::type()]); nanobind's stub generator will render this as ``class Subclass(Wrapper[Foo]):``. Any-typed return values ^^^^^^^^^^^^^^^^^^^^^^^ The return value of a function can sometimes be unclear (dynamic), in which case it can be helpful to declare ``typing.Any`` as a pragmatic return type (this effectively disables analysis of the return value in static type checkers). nanobind provides a :py:class:`nb::any ` wrapper type that is equivalent to :py:class:`nb::object ` except that its type signature renders as ``typing.Any`` to facilitate this. .. _stubs: Stub generation --------------- A *stub file* provides a *typed* and potentially documented summary of a module's class, function, and variable declarations. Stub files have the extension ``.pyi`` and are often shipped along with Python extensions. They are needed to enable autocompletion and static type checking in tools like `Visual Studio Code `__, `MyPy `__, `PyRight `__ and `PyType `__. Take for example the following function: .. code-block:: python def square(x: int) -> int: '''Return the square of the input''' return x*x The associated default stub removes the body, while retaining the docstring: .. code-block:: python def square(x: int) -> int: '''Return the square of the input''' An undocumented stub replaces the entire body with the Python ellipsis object (``...``). .. code-block:: python def square(x: int) -> int: ... Complex default arguments are often also abbreviated with ``...`` to improve the readability of signatures. You can read more about stub files in the `typing documentation `__ and the `MyPy documentation `__. nanobind's ``stubgen`` tool automates the process of stub generation to turn modules containing a mixture of ordinary Python code and C++ bindings into an associated ``.pyi`` file. The main challenge here is that C++ bindings are unlike ordinary Python objects, which causes standard mechanisms to extract their signature to fail. Existing tools like MyPy's `stubgen `__ and `pybind11-stubgen `__ must therefore parse docstrings to infer function signatures, which is brittle and does not always produce high-quality output. nanobind functions expose a ``__nb_signature__`` property, which provides structured information about typed function signatures, overload chains, and default arguments. nanobind's ``stubgen`` leverages this information to reliably generate high-quality stubs that are usable by static type checkers. There are three ways to interface with the stub generator described in the following subsections. CMake interface ^^^^^^^^^^^^^^^ nanobind's CMake interface provides the :cmake:command:`nanobind_add_stub` command for stub generation at build or install time. It generates a single stub at a time--more complex cases involving large numbers of stubs are easily handled using standard CMake constructs (e.g. a ``foreach()`` loop). The command requires a target name (e.g., ``my_ext_stub``) that must be unique but has no other significance. Once all dependencies (``DEPENDS`` parameter) are met, it will invoke ``stubgen`` to turn a single module (``MODULE`` parameter) into a stub file (``OUTPUT`` parameter). For this to work, the module must be importable. ``stubgen`` will add all paths specified as part of the ``PYTHON_PATH`` parameter and then execute ``import my_ext``, raising an error if this fails. .. code-block:: cmake nanobind_add_stub( my_ext_stub MODULE my_ext OUTPUT my_ext.pyi PYTHON_PATH $ DEPENDS my_ext ) Typed extensions normally identify themselves via the presence of an empty file named ``py.typed`` in each module directory. :cmake:command:`nanobind_add_stub` can optionally generate this file as well. .. code-block:: cmake nanobind_add_stub( ... MARKER_FILE py.typed ... ) CMake tracks the generated outputs in its dependency graph. The combination of compiled extension module, stub, and marker file can subsequently be installed by subsequent ``install()`` directives. .. code-block:: cmake install(TARGETS my_ext DESTINATION ".") install(FILES py.typed my_ext.pyi DESTINATION ".") In certain situations, it may be tricky to import an extension that is built but not yet installed to its final destination. To handle such cases, specify the ``INSTALL_TIME`` parameter to :cmake:command:`nanobind_add_stub` to delay stub generation to the installation phase. .. code-block:: cmake install(TARGETS my_ext DESTINATION ".") nanobind_add_stub( my_ext_stub INSTALL_TIME MODULE my_ext OUTPUT my_ext.pyi PYTHON_PATH "." ) This requires several changes: 1. ``PYTHON_PATH`` must be adjusted so that it references a location relative to ``CMAKE_INSTALL_PREFIX`` from which the installed module is importable. 2. The :cmake:command:`nanobind_add_stub` command should be preceded by ``install(TARGETS my_ext)`` and ``install(FILES`` commands that place all data (compiled extension files, plain Python code, etc.) needed to bring the module into an importable state. Place all relevant ``install()`` directives within the same ``CMakeLists.txt`` file to ensure that these steps are executed sequentially. 3. Dependencies (``DEPENDS``) no longer need to be listed. These are build-time constraints that do not apply in the installation phase. 4. The output file path (``OUTPUT``) is relative to ``CMAKE_INSTALL_PREFIX`` and may need adjustments as well. The :cmake:command:`nanobind_add_stub` command has a few other options, please refer to its documentation for details. Command line interface ^^^^^^^^^^^^^^^^^^^^^^ Alternatively, you can invoke ``stubgen`` on the command line. The nanobind package must be installed for this to work, e.g., via ``pip install nanobind``. The command line interface is also able to generate multiple stubs at once (simply specify ``-m MODULE`` several times). .. code-block:: bash $ python -m nanobind.stubgen -m my_ext -M py.typed Module "my_ext" .. - importing .. - analyzing .. - writing stub "my_ext.pyi" .. - writing marker file "py.typed" .. Unless an output file (``-o``) or output directory (``-O``) is specified, this places the ``.pyi`` files directly into the module. Existing stubs are overwritten without warning. The program has the following command line options: .. code-block:: text usage: python -m nanobind.stubgen [-h] [-o FILE] [-O PATH] [-i PATH] [-m MODULE] [-r] [-M FILE] [-P] [-D] [-q] Generate stubs for nanobind-based extensions. options: -h, --help show this help message and exit -o FILE, --output-file FILE write generated stubs to the specified file -O PATH, --output-dir PATH write generated stubs to the specified directory -i PATH, --import PATH add the directory to the Python import path (can specify multiple times) -m MODULE, --module MODULE generate a stub for the specified module (can specify multiple times) -r, --recursive recursively process submodules -M FILE, --marker-file FILE generate a marker file (usually named 'py.typed') -p FILE, --pattern-file FILE apply the given patterns to the generated stub (see the docs for syntax) -P, --include-private include private members (with single leading or trailing underscore) -D, --exclude-docstrings exclude docstrings from the generated stub -q, --quiet do not generate any output in the absence of failures Python interface ^^^^^^^^^^^^^^^^ Finally, you can import ``stubgen`` into your own Python programs and use it to programmatically generate stubs with a finer degree of control. To do so, construct an instance of the ``StubGen`` class and repeatedly call ``.put()`` to register modules or contents within the modules (specific methods, classes, etc.). Afterwards, the ``.get()`` method returns a string containing the stub declarations. .. code-block:: python from nanobind.stubgen import StubGen import my_module sg = StubGen() sg.put(my_module) print(sg.get()) Note that for now, the ``nanobind.stubgen.StubGen`` API is considered experimental and not subject to the semantic versioning policy used by the nanobind project. .. _pattern_files: Pattern files ------------- In complex binding projects requiring static type checking, the previously discussed mechanisms for controlling typed signatures (:cpp:class:`nb::sig `, :cpp:class:`nb::typed `) may be insufficient. Two common reasons are as follows: - the ``@typing.overload`` chain associated with a function may sometimes require significant deviations from the actual overloads present on the C++ side. - Some members of a module could be inherited from existing Python packages or extension libraries, in which case patching their signature via :cpp:class:`nb::sig ` is not even an option. ``stubgen`` supports *pattern files* as a last-resort solution to handle such advanced needs. These are files written in a *domain-specific language* (DSL) that specifies replacement patterns to dynamically rewrite stubs during generation. To use one, simply add it to the :cmake:command:`nanobind_add_stub` command. .. code-block:: cmake nanobind_add_stub( ... PATTERN_FILE ... ) A pattern file contains sequence of patterns. Each pattern consists of a query and an indented replacement block to be applied when the query matches. .. code-block:: text # This is the first pattern query 1: replacement 1 # And this is the second one query 2: replacement 2 Empty lines and lines beginning with ``#`` are ignored. The amount of indentation is arbitrary: ``stubgen`` will re-indent the replacement as needed based on where the query matched. When the stub generator traverses the module, it computes the *fully qualified name* of every type, function, property, etc. (for example: ``"my_ext.MyClass.my_function"``). The queries in a pattern file are checked against these qualified names one by one until the first one matches. For example, suppose that we had the following lackluster stub entry: .. code-block:: python class MyClass: def my_function(arg: object) -> object: ... The pattern below matches this function stub and inserts an alternative with two typed overloads. .. code-block:: text my_ext.MyClass.my_function: @overload def my_function(arg: int) -> int: """A helpful docstring""" @overload def my_function(arg: str) -> str: ... Patterns can also *remove* entries, by simply not specifying a replacement block. Also, queries don't have to match the entire qualified name. For example, the following pattern deletes all occurrences of anything containing the string ``secret`` somewhere in its name .. code-block:: text secret: In fact (you may have guessed it), the queries are *regular expressions*! The query supports all features of Python's builtin `re `__ library. When the query uses *groups*, the replacement block may access the contents of each numbered group using using the syntax ``\1``, ``\2``, etc. This permits writing generic patterns that can be applied to a number of stub entries at once: .. code-block:: text __(eq|ne)__: def __\1__(self, arg, /) -> bool: ... Named groups are also supported: .. code-block:: text __(?Peq|ne)__: def __\op__(self, arg, /) -> bool : ... Finally, sometimes, it is desirable to rewrite only the signature of a function in a stub but to keep its docstring so that it doesn't have to be copied into the pattern file. The special escape code ``\doc`` references the previously existing docstring. .. code-block:: text my_ext.lookup: def lookup(array: Array[T], index: int) -> T: \doc If your replacement rule requires additional types to work (e.g., from ``typing.*``), you may use the special ``\from`` escape code to import them: .. code-block:: text @overload my_ext.lookup: \from typing import Optional as _Opt, Literal def lookup(array: Array[T], index: Literal[0] = 0) -> _Opt[T]: \doc You may also add free-form text the beginning or the end of the generated stub. To do so, add an entry that matches on ``module_name.__prefix__`` or ``module_name.__suffix__``. wjakob-nanobind-6c4457b/docs/utilities.rst000066400000000000000000000032071474760012700206240ustar00rootroot00000000000000.. cpp:namespace:: nanobind .. _utilities: Utilities ========== .. _utilities_eval: Evaluating Python expressions from strings ------------------------------------------ nanobind provides the :cpp:func:`eval` and :cpp:func:`exec` functions to evaluate Python expressions and statements. The following example illustrates how they can be used. .. code-block:: cpp // At beginning of file #include ... // Evaluate in scope of main module nb::object scope = nb::module_::import_("__main__").attr("__dict__"); // Evaluate an isolated expression int result = nb::eval("my_variable + 10", scope).cast(); // Evaluate a sequence of statements nb::exec( "print('Hello')\n" "print('world!');", scope); C++11 raw string literals are also supported and quite handy for this purpose. The only requirement is that the first statement must be on a new line following the raw string delimiter ``R"(``, ensuring all lines have common leading indent: .. code-block:: cpp nb::exec(R"( x = get_answer() if x == 42: print('Hello World!') else: print('Bye!') )", scope ); .. note:: :cpp:func:`eval` accepts a template parameter that describes how the string/file should be interpreted. Possible choices include ``eval_expr`` (isolated expression), ``eval_single_statement`` (a single statement, return value is always ``none``), and ``eval_statements`` (sequence of statements, return value is always ``none``). `eval` defaults to ``eval_expr`` and `exec` is just a shortcut for ``eval``. wjakob-nanobind-6c4457b/docs/why.rst000066400000000000000000000316641474760012700174300ustar00rootroot00000000000000.. _why: .. cpp:namespace:: nanobind Why another binding library? ============================ I started the `pybind11 `__ project back in 2015 to generate better C++/Python bindings for a project I had been working on. Thanks to many amazing contributions by others, pybind11 has since become a core dependency of software used across the world including flagship projects like `PyTorch `__ and `Tensorflow `__. Every day, it is downloaded over 400'000 times. Hundreds of contributed extensions and generalizations address use cases of this diverse audience. However, all of this success also came with costs: the complexity of the library grew tremendously, which had a negative impact on efficiency. Curiously, the situation now is reminiscent of 2015: binding generation with existing tools (`Boost.Python `__, `pybind11 `__) is slow and produces enormous binaries with overheads on runtime performance. At the same time, key improvements in C++17 and Python 3.8 provide opportunities for drastic simplifications. Therefore, I am starting *another* binding project. This time, the scope is intentionally limited so that this doesn't turn into an endless cycle. So what is different? --------------------- nanobind is highly related to pybind11 and inherits most of its conventions and syntax. The main difference is a change in philosophy: pybind11 must deal with *all of C++* to bind legacy codebases, while nanobind targets a smaller C++ subset. *The codebase has to adapt to the binding tool and not the other way around*, which allows nanobind to be simpler and faster. Pull requests with extensions and generalizations to handle subtle fringe cases were welcomed in pybind11, but they will likely be rejected in this project. An overview of removed features is provided in a :ref:`separate section `. Besides feature removal, the rewrite was also an opportunity to address :ref:`long-standing performance issues ` and add a number of :ref:`major quality-of-life improvements ` and :ref:`smaller features `. .. _perf_improvements: Performance improvements ------------------------ The :ref:`benchmark section ` evaluates the impact of the following performance improvements: - **Compact objects**: C++ objects are now co-located with the Python object whenever possible (less pointer chasing compared to pybind11). The per-instance overhead for wrapping a C++ type into a Python object shrinks by a factor of 2.3x. (pybind11: 56 bytes, nanobind: 24 bytes.) - **Compact functions**: C++ function binding information is now co-located with the Python function object (less pointer chasing). - **Compact types**: C++ type binding information is now co-located with the Python type object (less pointer chasing, fewer hashtable lookups). - **Fast hash table**: nanobind upgrades several important internal associative data structures that previously used ``std::unordered_map`` to a more efficient alternative (`tsl::robin_map `__, which is included as a git submodule). - **Vector calls**: function calls from/to Python are realized using `PEP 590 vector calls `__, which gives a nice speed boost. The main function dispatch loop no longer allocates heap memory. - **Library component**: pybind11 was designed as a header-only library, which is generally a good thing because it simplifies the compilation workflow. However, one major downside of this is that a large amount of redundant code has to be compiled in each binding file (e.g., the function dispatch loop and all of the related internal data structures). nanobind compiles a separate shared or static support library ("*libnanobind*") and links it against the binding code to avoid redundant compilation. The CMake interface :cmake:command:`nanobind_add_module()` fully automates these extra steps. - **Smaller headers**: ``#include `` pulls in a large portion of the STL (about 2.1 MiB of headers with Clang and libc++). nanobind minimizes STL usage to avoid this problem. Type casters even for for basic types like ``std::string`` require an explicit opt-in by including an extra header file (e.g. ``#include ``). - **Simpler compilation**: pybind11 was dependent on *link time optimization* (LTO) to produce reasonably-sized bindings, which makes linking a build time bottleneck. With nanobind's split into a precompiled library and minimal metatemplating, LTO is no longer crucial and can be skipped. - **Free-threading**: Python 3.13+ supports a free-threaded mode that removes the *Global Interpreter Lock* (GIL). Both pybind11 and nanobind support free-threading as of recently. When comparing the two, nanobind provides better multi-core scaling using a localized locking scheme. In pybind11, lock contention on a central ``internals`` data structure used in every binding operation becomes a bottleneck in practice. - **Lifetime management**: nanobind maintains efficient internal data structures for lifetime management (needed for :cpp:class:`nb::keep_alive `, :cpp:enumerator:`nb::rv_policy::reference_internal `, the ``std::shared_ptr`` interface, etc.). With these changes, bound types no longer need to be weak-referenceable, which saves a pointer per instance. .. _major_additions: Major additions --------------- nanobind includes a number of quality-of-life improvements for developers: - **N-dimensional arrays**: nanobind can exchange data with modern array programming frameworks. It uses either `DLPack `__ or the `buffer protocol `__ to achieve *zero-copy* CPU/GPU array exchange with frameworks like `NumPy `__, `PyTorch `__, `TensorFlow `__, `JAX `__, etc. See the :ref:`section on n-dimensional arrays ` for details. - **Stable ABI**: nanobind can target Python's `stable ABI interface `__ starting with Python 3.12. This means that extension modules will be compatible with future version of Python without having to compile separate binaries per interpreter. That vision is still relatively far out, however: it will require Python 3.12+ to be widely deployed. - **Stub generation**: nanobind ships with a custom :ref:`stub generator ` and CMake integration to automatically create high quality stubs as part of the build process. `Stubs `__ make compiled extension code compatible with visual autocomplete in editors like `Visual Studio Code `__ and static type checkers like `MyPy `__, `PyRight `__ and `PyType `__. - **Smart pointers, ownership, etc.**: corner cases in pybind11 related to smart/unique pointers and callbacks could lead to undefined behavior. A later pybind11 redesign (``smart_holder``) was able to address these problems, but this came at the cost of further increased runtime overheads. The object ownership model of nanobind avoids this undefined behavior without penalizing runtime performance. - **Leak warnings**: When the Python interpreter shuts down, nanobind reports instance, type, and function leaks related to bindings, which is useful for tracking down reference counting issues. If these warnings are undesired, call :cpp:func:`nb::set_leak_warnings(false) `. nanobind also fully deletes its internal data structures when the Python interpreter terminates, which avoids memory leak reports in tools like *valgrind*. - **Better docstrings**: pybind11 pre-renders docstrings while the binding code runs. In other words, every call to ``.def(...)`` to bind a function immediately creates the underlying docstring. When a function takes a C++ type as parameter that is not yet registered in pybind11, the docstring will include a C++ type name (e.g. ``std::vector>``), which can look rather ugly. pybind11 binding declarations must be carefully arranged to work around this issue. nanobind avoids the issue altogether by not pre-rendering docstrings: they are created on the fly when queried. nanobind also has improved out-of-the-box compatibility with documentation generation tools like `Sphinx `__. - **Low-level API**: nanobind exposes an optional low-level API to provide fine-grained control over diverse aspects including :ref:`instance creation `, :ref:`type creation `, and it can store :ref:`supplemental data ` in types. The low-level API provides a useful escape hatch to pursue advanced projects that were not foreseen in the design of this library. .. _minor_additions: Minor additions --------------- The following lists minor-but-useful additions relative to pybind11. - **Finding Python objects associated with a C++ instance**: In addition to all of the return value policies supported by pybind11, nanobind provides one additional policy named :cpp:enumerator:`nb::rv_policy::none ` that *only* succeeds when the return value is already a known/registered Python object. In other words, this policy will never attempt to move, copy, or reference a C++ instance by constructing a new Python object. The new :cpp:func:`nb::find() ` function encapsulates this behavior. It resembles :cpp:func:`nb::cast() ` in the sense that it returns the Python object associated with a C++ instance. But while :cpp:func:`nb::cast() ` will create that Python object if it doesn't yet exist, :cpp:func:`nb::find() ` will return a ``nullptr`` object. This function is useful to interface with Python's :ref:`cyclic garbage collector `. - **Parameterized wrappers**: The :cpp:class:`nb::handle_t\ ` type behaves just like the :cpp:class:`nb::handle ` class and wraps a ``PyObject *`` pointer. However, when binding a function that takes such an argument, nanobind will only call the associated function overload when the underlying Python object wraps a C++ instance of type ``T``. Similarly, the :cpp:class:`nb::type_object_t\ ` type behaves just like the :cpp:class:`nb::type_object ` class and wraps a ``PyTypeObject *`` pointer. However, when binding a function that takes such an argument, nanobind will only call the associated function overload when the underlying Python type object is a subtype of the C++ type ``T``. Finally, the :cpp:class:`nb::typed\ ` annotation can parameterize any other type. The feature exists to improve the expressiveness of type signatures (e.g., to turn ``list`` into ``list[int]``). Note, however, that nanobind does not perform additional runtime checks in this case. Please see the section on :ref:`parameterizing generics ` for further details. - **Signature overrides**: it may sometimes be necessary to tweak the type signature of a class or function to provide richer type information to static type checkers like `MyPy `__ or `PyRight `__. In such cases, specify the :cpp:class:`nb::sig ` attribute to override the default nanobind-provided signature. For example, the following function signature annotation creates an overload that should only be called with an ``1``-valued integer literal. While the function also includes a runtime check, a static type checker can now ensure that this error condition cannot possibly be triggered by a given piece of code. .. code-block:: cpp m.def("f", [](int arg) { if (arg != 1) nb::raise("invalid input"); return arg; }, nb::sig("def f(arg: typing.Literal[1], /) -> int")); Please see the section on :ref:`customizing function signatures ` and :ref:`class signatures ` for further details. TLDR ---- My recommendation is that current pybind11 users look into migrating to nanobind. Fixing all the long-standing issues in pybind11 (see above list) would require a substantial redesign and years of careful work by a team of C++ metaprogramming experts. At the same time, changing anything in pybind11 is extremely hard because of the large number of downstream users and their requirements on API/ABI stability. I personally don't have the time and energy to fix pybind11 and have moved my focus to this project. wjakob-nanobind-6c4457b/ext/000077500000000000000000000000001474760012700157255ustar00rootroot00000000000000wjakob-nanobind-6c4457b/ext/robin_map/000077500000000000000000000000001474760012700176735ustar00rootroot00000000000000wjakob-nanobind-6c4457b/include/000077500000000000000000000000001474760012700165505ustar00rootroot00000000000000wjakob-nanobind-6c4457b/include/nanobind/000077500000000000000000000000001474760012700203405ustar00rootroot00000000000000wjakob-nanobind-6c4457b/include/nanobind/eigen/000077500000000000000000000000001474760012700214275ustar00rootroot00000000000000wjakob-nanobind-6c4457b/include/nanobind/eigen/dense.h000066400000000000000000000442741474760012700227110ustar00rootroot00000000000000/* nanobind/eigen/dense.h: type casters for dense Eigen vectors and matrices Copyright (c) 2023 Wenzel Jakob All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ #pragma once #include #include static_assert(EIGEN_VERSION_AT_LEAST(3, 3, 1), "Eigen matrix support in nanobind requires Eigen >= 3.3.1"); NAMESPACE_BEGIN(NB_NAMESPACE) /// Function argument types that are compatible with various array flavors using DStride = Eigen::Stride; template using DRef = Eigen::Ref; template using DMap = Eigen::Map; NAMESPACE_BEGIN(detail) /// Determine the number of dimensions of the given Eigen type template constexpr int ndim_v = bool(T::IsVectorAtCompileTime) ? 1 : 2; /// Extract the compile-time strides of the given Eigen type template struct stride { using type = Eigen::Stride<0, 0>; }; template struct stride> { using type = StrideType; }; template struct stride> { using type = StrideType; }; template using stride_t = typename stride::type; /** \brief Identify types with a contiguous memory representation. * * This includes all specializations of ``Eigen::Matrix``/``Eigen::Array`` and * certain specializations of ``Eigen::Map`` and ``Eigen::Ref``. Note: Eigen * interprets a compile-time stride of 0 as contiguous. */ template constexpr bool is_contiguous_v = (stride_t::InnerStrideAtCompileTime == 0 || stride_t::InnerStrideAtCompileTime == 1) && (ndim_v == 1 || stride_t::OuterStrideAtCompileTime == 0 || (stride_t::OuterStrideAtCompileTime != Eigen::Dynamic && int(stride_t::OuterStrideAtCompileTime) == int(T::InnerSizeAtCompileTime))); /// Identify types with a static or dynamic layout that support contiguous storage template constexpr bool can_map_contiguous_memory_v = (stride_t::InnerStrideAtCompileTime == 0 || stride_t::InnerStrideAtCompileTime == 1 || stride_t::InnerStrideAtCompileTime == Eigen::Dynamic) && (ndim_v == 1 || stride_t::OuterStrideAtCompileTime == 0 || stride_t::OuterStrideAtCompileTime == Eigen::Dynamic || int(stride_t::OuterStrideAtCompileTime) == int(T::InnerSizeAtCompileTime)); /* This type alias builds the most suitable 'ndarray' for the given Eigen type. In particular, it - matches the underlying scalar type - matches the number of dimensions (i.e. whether the type is a vector/matrix) - matches the shape (if the row/column count is known at compile time) - matches the in-memory ordering when the Eigen type is contiguous. This is helpful because type_caster> will then perform the necessary conversion steps (if given incompatible input) to enable data exchange with Eigen. A limitation of this approach is that ndarray does not support compile-time strides besides c_contig and f_contig. If an Eigen type requires non-contiguous strides (at compile-time) and we are given an ndarray with unsuitable strides (at run-time), type casting will fail. Note, however, that this is rather unusual, since the default stride type of Eigen::Map requires contiguous memory, and the one of Eigen::Ref requires a contiguous inner stride, while handling any outer stride. */ template using array_for_eigen_t = ndarray< Scalar, numpy, std::conditional_t< ndim_v == 1, shape, shape>, std::conditional_t< is_contiguous_v, std::conditional_t< ndim_v == 1 || T::IsRowMajor, c_contig, f_contig>, unused>>; /// Any kind of Eigen class template constexpr bool is_eigen_v = is_base_of_template_v; /// Detects Eigen::Array, Eigen::Matrix, etc. template constexpr bool is_eigen_plain_v = is_base_of_template_v; /// Detect Eigen::SparseMatrix template constexpr bool is_eigen_sparse_v = is_base_of_template_v; /// Detects expression templates template constexpr bool is_eigen_xpr_v = is_eigen_v && !is_eigen_plain_v && !is_eigen_sparse_v && !std::is_base_of_v, T>; template struct type_caster && is_ndarray_scalar_v>> { using Scalar = typename T::Scalar; using NDArray = array_for_eigen_t; using NDArrayCaster = make_caster; NB_TYPE_CASTER(T, NDArrayCaster::Name) bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept { // We're in any case making a copy, so non-writable inputs area also okay using NDArrayConst = array_for_eigen_t; make_caster caster; if (!caster.from_python(src, flags & ~(uint8_t)cast_flags::accepts_none, cleanup)) return false; const NDArrayConst &array = caster.value; if constexpr (ndim_v == 1) value.resize(array.shape(0)); else value.resize(array.shape(0), array.shape(1)); // The layout is contiguous & compatible thanks to array_for_eigen_t memcpy(value.data(), array.data(), array.size() * sizeof(Scalar)); return true; } static handle from_cpp(T &&v, rv_policy policy, cleanup_list *cleanup) noexcept { if (policy == rv_policy::automatic || policy == rv_policy::automatic_reference) policy = rv_policy::move; return from_cpp((const T &) v, policy, cleanup); } static handle from_cpp(const T &v, rv_policy policy, cleanup_list *cleanup) noexcept { size_t shape[ndim_v]; int64_t strides[ndim_v]; if constexpr (ndim_v == 1) { shape[0] = v.size(); strides[0] = v.innerStride(); } else { shape[0] = v.rows(); shape[1] = v.cols(); strides[0] = v.rowStride(); strides[1] = v.colStride(); } void *ptr = (void *) v.data(); switch (policy) { case rv_policy::automatic: policy = rv_policy::copy; break; case rv_policy::automatic_reference: policy = rv_policy::reference; break; case rv_policy::move: // Don't bother moving when the data is static or occupies <1KB if ((T::SizeAtCompileTime != Eigen::Dynamic || (size_t) v.size() < (1024 / sizeof(Scalar)))) policy = rv_policy::copy; break; default: // leave policy unchanged break; } object owner; if (policy == rv_policy::move) { T *temp = new T(std::move(v)); owner = capsule(temp, [](void *p) noexcept { delete (T *) p; }); ptr = temp->data(); policy = rv_policy::reference; } else if (policy == rv_policy::reference_internal && cleanup->self()) { owner = borrow(cleanup->self()); policy = rv_policy::reference; } object o = steal(NDArrayCaster::from_cpp( NDArray(ptr, ndim_v, shape, owner, strides), policy, cleanup)); return o.release(); } }; /// Caster for Eigen expression templates template struct type_caster && is_ndarray_scalar_v>> { using Array = Eigen::Array; using Caster = make_caster; static constexpr auto Name = Caster::Name; template using Cast = T; template static constexpr bool can_cast() { return true; } /// Generating an expression template from a Python object is, of course, not possible bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept = delete; template static handle from_cpp(T2 &&v, rv_policy policy, cleanup_list *cleanup) noexcept { return Caster::from_cpp(std::forward(v), policy, cleanup); } }; /** \brief Type caster for ``Eigen::Map`` The ``Eigen::Map<..>`` type exists to efficiently access memory provided by a caller. Given that, the nanobind type caster refuses to turn incompatible inputs into a ``Eigen::Map`` when this would require an implicit conversion. */ template struct type_caster, enable_if_t && is_ndarray_scalar_v>> { using Map = Eigen::Map; using NDArray = array_for_eigen_t, const typename Map::Scalar, typename Map::Scalar>>; using NDArrayCaster = type_caster; static constexpr auto Name = NDArrayCaster::Name; template using Cast = Map; template static constexpr bool can_cast() { return true; } NDArrayCaster caster; bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept { // Disable implicit conversions return from_python_(src, flags & ~(uint8_t)cast_flags::convert, cleanup); } bool from_python_(handle src, uint8_t flags, cleanup_list* cleanup) noexcept { if (!caster.from_python(src, flags & ~(uint8_t)cast_flags::accepts_none, cleanup)) return false; // Check for memory layout compatibility of non-contiguous 'Map' types if constexpr (!is_contiguous_v) { // Dynamic inner strides support any input, check the fixed case if constexpr (StrideType::InnerStrideAtCompileTime != Eigen::Dynamic) { // A compile-time stride of 0 implies "contiguous" .. int64_t is_expected = StrideType::InnerStrideAtCompileTime == 0 ? 1 /* .. and equals 1 for the inner stride */ : StrideType::InnerStrideAtCompileTime, is_actual = caster.value.stride( (ndim_v != 1 && T::IsRowMajor) ? 1 : 0); if (is_expected != is_actual) return false; } // Analogous check for the outer strides if constexpr (ndim_v == 2 && StrideType::OuterStrideAtCompileTime != Eigen::Dynamic) { int64_t os_expected = StrideType::OuterStrideAtCompileTime == 0 ? caster.value.shape(T::IsRowMajor ? 1 : 0) : StrideType::OuterStrideAtCompileTime, os_actual = caster.value.stride(T::IsRowMajor ? 0 : 1); if (os_expected != os_actual) return false; } } return true; } static handle from_cpp(const Map &v, rv_policy policy, cleanup_list *cleanup) noexcept { size_t shape[ndim_v]; int64_t strides[ndim_v]; if constexpr (ndim_v == 1) { shape[0] = v.size(); strides[0] = v.innerStride(); } else { shape[0] = v.rows(); shape[1] = v.cols(); strides[0] = v.rowStride(); strides[1] = v.colStride(); } return NDArrayCaster::from_cpp( NDArray((void *) v.data(), ndim_v, shape, handle(), strides), (policy == rv_policy::automatic || policy == rv_policy::automatic_reference) ? rv_policy::reference : policy, cleanup); } StrideType strides() const { constexpr int IS = StrideType::InnerStrideAtCompileTime, OS = StrideType::OuterStrideAtCompileTime; int64_t inner = caster.value.stride(0), outer; if constexpr (ndim_v == 1) outer = caster.value.shape(0); else outer = caster.value.stride(1); (void) inner; (void) outer; if constexpr (ndim_v == 2 && T::IsRowMajor) std::swap(inner, outer); // Eigen may expect a stride of 0 to avoid an assertion failure if constexpr (IS == 0) inner = 0; if constexpr (OS == 0) outer = 0; if constexpr (std::is_same_v>) return StrideType(inner); else if constexpr (std::is_same_v>) return StrideType(outer); else return StrideType(outer, inner); } operator Map() { NDArray &t = caster.value; if constexpr (ndim_v == 1) return Map(t.data(), t.shape(0), strides()); else return Map(t.data(), t.shape(0), t.shape(1), strides()); } }; /** \brief Caster for Eigen::Ref Compared to the ``Eigen::Map`` type caster above, the reference caster accepts a wider set of inputs when it is used in *constant reference* mode (i.e., ``Eigen::Ref``). In this case, it performs stride conversions (except for unusual non-contiguous strides) as well as conversions of the underlying scalar type (if implicit conversions are enabled). For non-constant references, the caster matches that of ``Eigen::Map`` and requires an input with the expected layout (so that changes can propagate to the caller). */ template struct type_caster, enable_if_t && is_ndarray_scalar_v>> { using Ref = Eigen::Ref; /// Potentially convert strides/dtype when casting constant references static constexpr bool MaybeConvert = std::is_const_v && // Restrict to contiguous 'T' (limitation in Eigen, see PR #215) can_map_contiguous_memory_v; using NDArray = array_for_eigen_t, const typename Ref::Scalar, typename Ref::Scalar>>; using NDArrayCaster = type_caster; /// Eigen::Map caster with fixed strides using Map = Eigen::Map; using MapCaster = make_caster; // Extended version taking arbitrary strides using DMap = Eigen::Map; using DMapCaster = make_caster; /** * The constructor of ``Ref`` uses one of two strategies * depending on the input. It may either * * 1. Create a copy ``Ref::m_object`` (owned by Ref), or * 2. Reference the existing input (non-owned). * * When the value below is ``true``, then it is guaranteed that * ``Ref()`` owns the underlying data. */ static constexpr bool DMapConstructorOwnsData = !Eigen::internal::traits::template match::type::value; static constexpr auto Name = const_name(DMapCaster::Name, MapCaster::Name); template using Cast = Ref; template static constexpr bool can_cast() { return true; } MapCaster caster; struct Empty { }; std::conditional_t dcaster; bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept { // Try a direct cast without implicit conversion first if (caster.from_python(src, flags, cleanup)) return true; // Potentially convert strides/dtype when casting constant references if constexpr (MaybeConvert) { /* Generating an implicit copy requires some object to assume ownership. During a function call, ``dcaster`` can serve that role (this case is detected by checking whether ``flags`` has the ``manual`` flag set). When used in other situations (e.g. ``nb::cast()``), the created ``Eigen::Ref<..>`` must take ownership of the copy. This is only guranteed to work if DMapConstructorOwnsData. If neither of these is possible, we disable implicit conversions. */ if ((flags & (uint8_t) cast_flags::manual) && !DMapConstructorOwnsData) flags &= ~(uint8_t) cast_flags::convert; if (dcaster.from_python_(src, flags, cleanup)) return true; } return false; } static handle from_cpp(const Ref &v, rv_policy policy, cleanup_list *cleanup) noexcept { // Copied from the Eigen::Map caster size_t shape[ndim_v]; int64_t strides[ndim_v]; if constexpr (ndim_v == 1) { shape[0] = v.size(); strides[0] = v.innerStride(); } else { shape[0] = v.rows(); shape[1] = v.cols(); strides[0] = v.rowStride(); strides[1] = v.colStride(); } return NDArrayCaster::from_cpp( NDArray((void *) v.data(), ndim_v, shape, handle(), strides), (policy == rv_policy::automatic || policy == rv_policy::automatic_reference) ? rv_policy::reference : policy, cleanup); } operator Ref() { if constexpr (MaybeConvert) { if (dcaster.caster.value.is_valid()) return Ref(dcaster.operator DMap()); } return Ref(caster.operator Map()); } }; NAMESPACE_END(detail) NAMESPACE_END(NB_NAMESPACE) wjakob-nanobind-6c4457b/include/nanobind/eigen/sparse.h000066400000000000000000000150011474760012700230720ustar00rootroot00000000000000/* nanobind/eigen/sparse.h: type casters for sparse Eigen matrices Copyright (c) 2023 Henri Menke and Wenzel Jakob All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ #pragma once #include #include #include #include #include #include NAMESPACE_BEGIN(NB_NAMESPACE) NAMESPACE_BEGIN(detail) /// Detect Eigen::SparseMatrix template constexpr bool is_eigen_sparse_matrix_v = is_eigen_sparse_v && !std::is_base_of_v, T>; /// Caster for Eigen::SparseMatrix template struct type_caster>> { using Scalar = typename T::Scalar; using StorageIndex = typename T::StorageIndex; using Index = typename T::Index; using SparseMap = Eigen::Map; static_assert(std::is_same_v>, "nanobind: Eigen sparse caster only implemented for matrices"); static constexpr bool RowMajor = T::IsRowMajor; using ScalarNDArray = ndarray>; using StorageIndexNDArray = ndarray>; using ScalarCaster = make_caster; using StorageIndexCaster = make_caster; NB_TYPE_CASTER(T, const_name("scipy.sparse.csr_matrix[", "scipy.sparse.csc_matrix[") + make_caster::Name + const_name("]")) ScalarCaster data_caster; StorageIndexCaster indices_caster, indptr_caster; bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept { object obj = borrow(src); try { object matrix_type = module_::import_("scipy.sparse").attr(RowMajor ? "csr_matrix" : "csc_matrix"); if (!obj.type().is(matrix_type)) obj = matrix_type(obj); } catch (const python_error &) { return false; } if (object data_o = obj.attr("data"); !data_caster.from_python(data_o, flags, cleanup)) return false; ScalarNDArray& values = data_caster.value; if (object indices_o = obj.attr("indices"); !indices_caster.from_python(indices_o, flags, cleanup)) return false; StorageIndexNDArray& inner_indices = indices_caster.value; if (object indptr_o = obj.attr("indptr"); !indptr_caster.from_python(indptr_o, flags, cleanup)) return false; StorageIndexNDArray& outer_indices = indptr_caster.value; object shape_o = obj.attr("shape"), nnz_o = obj.attr("nnz"); Index rows, cols, nnz; try { if (len(shape_o) != 2) return false; rows = cast(shape_o[0]); cols = cast(shape_o[1]); nnz = cast(nnz_o); } catch (const python_error &) { return false; } value = SparseMap(rows, cols, nnz, outer_indices.data(), inner_indices.data(), values.data()); return true; } static handle from_cpp(T &&v, rv_policy policy, cleanup_list *cleanup) noexcept { if (policy == rv_policy::automatic || policy == rv_policy::automatic_reference) policy = rv_policy::move; return from_cpp((const T &) v, policy, cleanup); } static handle from_cpp(const T &v, rv_policy policy, cleanup_list *) noexcept { if (!v.isCompressed()) { PyErr_SetString(PyExc_ValueError, "nanobind: unable to return an Eigen sparse matrix that is not in a compressed format. " "Please call `.makeCompressed()` before returning the value on the C++ end."); return handle(); } object matrix_type; try { matrix_type = module_::import_("scipy.sparse").attr(RowMajor ? "csr_matrix" : "csc_matrix"); } catch (python_error &e) { e.restore(); return handle(); } const Index rows = v.rows(), cols = v.cols(); const size_t data_shape[] = { (size_t) v.nonZeros() }; const size_t outer_indices_shape[] = { (size_t) ((RowMajor ? rows : cols) + 1) }; T *src = std::addressof(const_cast(v)); object owner; if (policy == rv_policy::move) { src = new T(std::move(v)); owner = capsule(src, [](void *p) noexcept { delete (T *) p; }); } ScalarNDArray data(src->valuePtr(), 1, data_shape, owner); StorageIndexNDArray outer_indices(src->outerIndexPtr(), 1, outer_indices_shape, owner); StorageIndexNDArray inner_indices(src->innerIndexPtr(), 1, data_shape, owner); try { return matrix_type(nanobind::make_tuple( std::move(data), std::move(inner_indices), std::move(outer_indices)), nanobind::make_tuple(rows, cols)) .release(); } catch (python_error &e) { e.restore(); return handle(); } } }; /// Caster for Eigen::Map, still needs to be implemented. template struct type_caster, enable_if_t>> { using Map = Eigen::Map; using SparseMatrixCaster = type_caster; static constexpr auto Name = SparseMatrixCaster::Name; template using Cast = Map; template static constexpr bool can_cast() { return true; } bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept = delete; static handle from_cpp(const Map &v, rv_policy policy, cleanup_list *cleanup) noexcept = delete; }; /// Caster for Eigen::Ref, still needs to be implemented template struct type_caster, enable_if_t>> { using Ref = Eigen::Ref; using Map = Eigen::Map; using MapCaster = make_caster; static constexpr auto Name = MapCaster::Name; template using Cast = Ref; template static constexpr bool can_cast() { return true; } bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept = delete; static handle from_cpp(const Ref &v, rv_policy policy, cleanup_list *cleanup) noexcept = delete; }; NAMESPACE_END(detail) NAMESPACE_END(NB_NAMESPACE) wjakob-nanobind-6c4457b/include/nanobind/eval.h000066400000000000000000000036231474760012700214440ustar00rootroot00000000000000/* nanobind/eval.h: Support for evaluating Python expressions and statements from strings Adapted by Nico Schlömer from pybind11's eval.h. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ #pragma once #include NAMESPACE_BEGIN(NB_NAMESPACE) enum eval_mode { // Evaluate a string containing an isolated expression eval_expr = Py_eval_input, // Evaluate a string containing a single statement. Returns \c none eval_single_statement = Py_single_input, // Evaluate a string containing a sequence of statement. Returns \c none eval_statements = Py_file_input }; template object eval(const str &expr, handle global = handle(), handle local = handle()) { if (!local.is_valid()) local = global; // This used to be PyRun_String, but that function isn't in the stable ABI. object codeobj = steal(Py_CompileString(expr.c_str(), "", start)); if (!codeobj.is_valid()) raise_python_error(); PyObject *result = PyEval_EvalCode(codeobj.ptr(), global.ptr(), local.ptr()); if (!result) raise_python_error(); return steal(result); } template object eval(const char (&s)[N], handle global = handle(), handle local = handle()) { // Support raw string literals by removing common leading whitespace str expr = (s[0] == '\n') ? str(module_::import_("textwrap").attr("dedent")(s)) : str(s); return eval(expr, global, local); } inline void exec(const str &expr, handle global = handle(), handle local = handle()) { eval(expr, global, local); } template void exec(const char (&s)[N], handle global = handle(), handle local = handle()) { eval(s, global, local); } NAMESPACE_END(NB_NAMESPACE) wjakob-nanobind-6c4457b/include/nanobind/intrusive/000077500000000000000000000000001474760012700223705ustar00rootroot00000000000000wjakob-nanobind-6c4457b/include/nanobind/intrusive/counter.h000066400000000000000000000212641474760012700242250ustar00rootroot00000000000000/* nanobind/intrusive/counter.h: Intrusive reference counting sample implementation. Intrusive reference counting is a simple solution for various lifetime and ownership-related issues that can arise in Python bindings of C++ code. The implementation here represents one of many ways in which intrusive reference counting can be realized and is included for convenience. The code in this file is designed to be truly minimal: it depends neither on Python, nanobind, nor the STL. This enables its use in small projects with a 100% optional Python interface. Two section of nanobind's documentation discuss intrusive reference counting in general: - https://nanobind.readthedocs.io/en/latest/ownership.html - https://nanobind.readthedocs.io/en/latest/ownership_adv.html Comments below are specific to this sample implementation. Copyright (c) 2023 Wenzel Jakob All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ #pragma once #include // Override this definition to specify DLL export/import declarations #if !defined(NB_INTRUSIVE_EXPORT) # define NB_INTRUSIVE_EXPORT #endif #if !defined(Py_PYTHON_H) /* While the implementation below does not directly depend on Python, the PyObject type occurs in a few function interfaces (in a fully opaque manner). The lines below forward-declare it. */ extern "C" { struct _object; typedef _object PyObject; }; #endif #if !defined(NAMESPACE_BEGIN) # define NAMESPACE_BEGIN(name) namespace name { #endif #if !defined(NAMESPACE_END) # define NAMESPACE_END(name) } #endif NAMESPACE_BEGIN(nanobind) /** \brief Simple intrusive reference counter. * * Intrusive reference counting is a simple solution for various lifetime and * ownership-related issues that can arise in Python bindings of C++ code. The * implementation here represents one of many ways in which intrusive reference * counting can be realized and is included for convenience. * * The ``intrusive_counter`` class represents an atomic counter that can be * increased (via ``inc_ref()``) or decreased (via ``dec_ref()``). When the * counter reaches zero, the object should be deleted, which ``dec_ref()`` * indicates by returning ``true``. * * In addition to this simple counting mechanism, ownership of the object can * also be transferred to Python (via ``set_self_py()``). In this case, * subsequent calls to ``inc_ref()`` and ``dec_ref()`` modify the reference * count of the underlying Python object. The ``intrusive_counter`` class * supports both cases using only ``sizeof(void*)`` bytes of storage. * * To incorporate intrusive reference counting into your own project, you would * usually add an ``intrusive_counter``-typed member to the base class of an * object hierarchy and expose it as follows: * * ```cpp * #include * * class Object { * public: * void inc_ref() noexcept { m_ref_count.inc_ref(); } * bool dec_ref() noexcept { return m_ref_count.dec_ref(); } * * // Important: must declare virtual destructor * virtual ~Object() = default; * * void set_self_py(PyObject *self) noexcept { * m_ref_count.set_self_py(self); * } * * private: * nb::intrusive_counter m_ref_count; * }; * * // Convenience function for increasing the reference count of an instance * inline void inc_ref(Object *o) noexcept { * if (o) * o->inc_ref(); * } * * // Convenience function for decreasing the reference count of an instance * // and potentially deleting it when the count reaches zero * inline void dec_ref(Object *o) noexcept { * if (o && o->dec_ref()) * delete o; * } * ``` * * Alternatively, you could also inherit from ``intrusive_base``, which obviates * the need for all of the above declarations: * * ```cpp * class Object : public intrusive_base { * public: * // ... * }; * ``` * * When binding the base class in Python, you must indicate to nanobind that * this type uses intrusive reference counting and expose the ``set_self_py`` * member. This must only be done once, as the attribute is automatically * inherited by subclasses. * * ```cpp * nb::class_( * m, "Object", * nb::intrusive_ptr( * [](Object *o, PyObject *po) noexcept { o->set_self_py(po); })); * ``` * * Also, somewhere in your binding initialization code, you must call * * ```cpp * nb::intrusive_init( * [](PyObject *o) noexcept { * nb::gil_scoped_acquire guard; * Py_INCREF(o); * }, * [](PyObject *o) noexcept { * nb::gil_scoped_acquire guard; * Py_DECREF(o); * }); * ``` * * For this all to compile, a single one of your .cpp files must include this * header file from somewhere as follows: * * ```cpp * #include * ``` * * Calling the ``inc_ref()`` and ``dec_ref()`` members many times throughout * the code can quickly become tedious. Nanobind also ships with a ``ref`` * RAII helper class to help with this. * * ```cpp * #include * * { * ref x = new MyObject(); // <-- assigment to ref<..> automatically calls inc_ref() * x->func(); // ref<..> can be used like a normal pointer * } // <-- Destruction of ref<..> calls dec_ref(), deleting the instance in this example. * ``` * * When the file ``nanobind/intrusive/ref.h`` is included following * ``nanobind/nanobind.h``, it also exposes a custom type caster to bind * functions taking or returning ``ref``-typed values. */ struct NB_INTRUSIVE_EXPORT intrusive_counter { public: intrusive_counter() noexcept = default; // The counter value is not affected by copy/move assignment/construction intrusive_counter(const intrusive_counter &) noexcept { } intrusive_counter(intrusive_counter &&) noexcept { } intrusive_counter &operator=(const intrusive_counter &) noexcept { return *this; } intrusive_counter &operator=(intrusive_counter &&) noexcept { return *this; } /// Increase the object's reference count void inc_ref() const noexcept; /// Decrease the object's reference count, return ``true`` if it should be deallocated bool dec_ref() const noexcept; /// Return the Python object associated with this instance (or NULL) PyObject *self_py() const noexcept; /// Set the Python object associated with this instance void set_self_py(PyObject *self) noexcept; protected: /** * \brief Mutable counter. Note that the value ``1`` actually encodes * a zero reference count (see the file ``counter.inl`` for details). */ mutable uintptr_t m_state = 1; }; static_assert( sizeof(intrusive_counter) == sizeof(void *), "The intrusive_counter class should always have the same size as a pointer."); /// Reference-counted base type of an object hierarchy class NB_INTRUSIVE_EXPORT intrusive_base { public: /// Increase the object's reference count void inc_ref() const noexcept { m_ref_count.inc_ref(); } /// Decrease the object's reference count, return ``true`` if it should be deallocated bool dec_ref() const noexcept { return m_ref_count.dec_ref(); } /// Set the Python object associated with this instance void set_self_py(PyObject *self) noexcept { m_ref_count.set_self_py(self); } /// Return the Python object associated with this instance (or NULL) PyObject *self_py() const noexcept { return m_ref_count.self_py(); } /// Virtual destructor virtual ~intrusive_base() = default; private: mutable intrusive_counter m_ref_count; }; /** * \brief Increase the reference count of an intrusively reference-counted * object ``o`` if ``o`` is non-NULL. */ inline void inc_ref(const intrusive_base *o) noexcept { if (o) o->inc_ref(); } /** * \brief Decrease the reference count and potentially delete an intrusively * reference-counted object ``o`` if ``o`` is non-NULL. */ inline void dec_ref(const intrusive_base *o) noexcept { if (o && o->dec_ref()) delete o; } /** * \brief Install Python reference counting handlers * * The ``intrusive_counter`` class is designed so that the dependency on Python is * *optional*: the code compiles in ordinary C++ projects, in which case the * Python reference counting functionality will simply not be used. * * Python binding code must invoke ``intrusive_init`` once to supply two * functions that increase and decrease the reference count of a Python object, * while ensuring that the GIL is held. */ extern NB_INTRUSIVE_EXPORT void intrusive_init(void (*intrusive_inc_ref_py)(PyObject *) noexcept, void (*intrusive_dec_ref_py)(PyObject *) noexcept); NAMESPACE_END(nanobind) wjakob-nanobind-6c4457b/include/nanobind/intrusive/counter.inl000066400000000000000000000114121474760012700245520ustar00rootroot00000000000000/* nanobind/intrusive/counter.inl: Intrusive reference counting sample implementation; see 'counter.h' for an explanation of the interface. Copyright (c) 2023 Wenzel Jakob All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ #include "counter.h" #include #include NAMESPACE_BEGIN(nanobind) // The code below uses intrinsics for atomic operations. This is not as nice // and portable as ``std::atomic`` but avoids pulling in large amounts of // STL header code #if !defined(_MSC_VER) #define NB_ATOMIC_LOAD(ptr) __atomic_load_n(ptr, 0) #define NB_ATOMIC_STORE(ptr, v) __atomic_store_n(ptr, v, 0) #define NB_ATOMIC_CMPXCHG(ptr, cmp, xchg) \ __atomic_compare_exchange_n(ptr, cmp, xchg, true, 0, 0) #else extern "C" void *_InterlockedCompareExchangePointer( void *volatile *Destination, void *Exchange, void *Comparand); #pragma intrinsic(_InterlockedCompareExchangePointer) #define NB_ATOMIC_LOAD(ptr) *((volatile const uintptr_t *) ptr) #define NB_ATOMIC_STORE(ptr, v) *((volatile uintptr_t *) ptr) = v; #define NB_ATOMIC_CMPXCHG(ptr, cmp, xchg) nb_cmpxchg(ptr, cmp, xchg) static bool nb_cmpxchg(uintptr_t *ptr, uintptr_t *cmp, uintptr_t xchg) { uintptr_t cmpv = *cmp; uintptr_t prev = (uintptr_t) _InterlockedCompareExchangePointer( (void * volatile *) ptr, (void *) xchg, (void *) cmpv); if (prev == cmpv) { return true; } else { *cmp = prev; return false; } } #endif static void (*intrusive_inc_ref_py)(PyObject *) noexcept = nullptr, (*intrusive_dec_ref_py)(PyObject *) noexcept = nullptr; void intrusive_init(void (*intrusive_inc_ref_py_)(PyObject *) noexcept, void (*intrusive_dec_ref_py_)(PyObject *) noexcept) { intrusive_inc_ref_py = intrusive_inc_ref_py_; intrusive_dec_ref_py = intrusive_dec_ref_py_; } /** A few implementation details: * * The ``intrusive_counter`` constructor sets the ``m_state`` field to ``1``, * which indicates that the instance is owned by C++. Bits 2..63 of this * field are used to store the actual reference count value. The * ``inc_ref()`` and ``dec_ref()`` functions increment or decrement this * number. When ``dec_ref()`` removes the last reference, the instance * returns ``true`` to indicate that it should be deallocated using a * *delete expression* that would typically be handled using a polymorphic * destructor. * * When an class with intrusive reference counting is returned from C++ to * Python, nanobind will invoke ``set_self_py()``, which hands ownership * over to Python/nanobind. Any remaining references will be moved from the * ``m_state`` field to the Python reference count. In this mode, * ``inc_ref()`` and ``dec_ref()`` wrap Python reference counting * primitives (``Py_INCREF()`` / ``Py_DECREF()``) which must be made * available by calling the function ``intrusive_init`` once during module * initialization. Note that the `m_state` field is also used to store a * pointer to the `PyObject *`. Python instance pointers are always aligned * (i.e. bit 1 is zero), which disambiguates between the two possible * configurations. */ void intrusive_counter::inc_ref() const noexcept { uintptr_t v = NB_ATOMIC_LOAD(&m_state); while (true) { if (v & 1) { if (!NB_ATOMIC_CMPXCHG(&m_state, &v, v + 2)) continue; } else { intrusive_inc_ref_py((PyObject *) v); } break; } } bool intrusive_counter::dec_ref() const noexcept { uintptr_t v = NB_ATOMIC_LOAD(&m_state); while (true) { if (v & 1) { if (v == 1) { fprintf(stderr, "intrusive_counter::dec_ref(%p): reference count " "underflow!", (void *) this); abort(); } if (!NB_ATOMIC_CMPXCHG(&m_state, &v, v - 2)) continue; if (v == 3) return true; } else { intrusive_dec_ref_py((PyObject *) v); } return false; } } void intrusive_counter::set_self_py(PyObject *o) noexcept { uintptr_t v = NB_ATOMIC_LOAD(&m_state); if (v & 1) { v >>= 1; for (uintptr_t i = 0; i < v; ++i) intrusive_inc_ref_py(o); NB_ATOMIC_STORE(&m_state, (uintptr_t) o); } else { fprintf(stderr, "intrusive_counter::set_self_py(%p): a Python object was " "already present!", (void *) this); abort(); } } PyObject *intrusive_counter::self_py() const noexcept { uintptr_t v = NB_ATOMIC_LOAD(&m_state); if (v & 1) return nullptr; else return (PyObject *) v; } NAMESPACE_END(nanobind) wjakob-nanobind-6c4457b/include/nanobind/intrusive/ref.h000066400000000000000000000113741474760012700233230ustar00rootroot00000000000000/* nanobind/intrusive/ref.h: This file defines the ``ref`` RAII scoped reference counting helper class. When included following ``nanobind/nanobind.h``, the code below also exposes a custom type caster to bind functions taking or returning ``ref``-typed values. Copyright (c) 2023 Wenzel Jakob All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ #pragma once #include "counter.h" NAMESPACE_BEGIN(nanobind) /** * \brief RAII scoped reference counting helper class * * ``ref`` is a simple RAII wrapper class that encapsulates a pointer to an * instance with intrusive reference counting. * * It takes care of increasing and decreasing the reference count as needed and * deleting the instance when the count reaches zero. * * For this to work, compatible functions ``inc_ref()`` and ``dec_ref()`` must * be defined before including this file. Default implementations for * subclasses of the type ``intrusive_base`` are already provided as part of the * file ``counter.h``. */ template class ref { public: /// Create a null reference ref() = default; /// Construct a reference from a pointer ref(T *ptr) : m_ptr(ptr) { inc_ref((intrusive_base *) m_ptr); } /// Copy a reference, increases the reference count ref(const ref &r) : m_ptr(r.m_ptr) { inc_ref((intrusive_base *) m_ptr); } /// Move a reference witout changing the reference count ref(ref &&r) noexcept : m_ptr(r.m_ptr) { r.m_ptr = nullptr; } /// Destroy this reference ~ref() { dec_ref((intrusive_base *) m_ptr); } /// Move-assign another reference into this one ref &operator=(ref &&r) noexcept { dec_ref((intrusive_base *) m_ptr); m_ptr = r.m_ptr; r.m_ptr = nullptr; return *this; } /// Copy-assign another reference into this one ref &operator=(const ref &r) { inc_ref((intrusive_base *) r.m_ptr); dec_ref((intrusive_base *) m_ptr); m_ptr = r.m_ptr; return *this; } /// Overwrite this reference with a pointer to another object ref &operator=(T *ptr) { inc_ref((intrusive_base *) ptr); dec_ref((intrusive_base *) m_ptr); m_ptr = ptr; return *this; } /// Clear the currently stored reference void reset() { dec_ref((intrusive_base *) m_ptr); m_ptr = nullptr; } /// Compare this reference with another reference bool operator==(const ref &r) const { return m_ptr == r.m_ptr; } /// Compare this reference with another reference bool operator!=(const ref &r) const { return m_ptr != r.m_ptr; } /// Compare this reference with a pointer bool operator==(const T *ptr) const { return m_ptr == ptr; } /// Compare this reference with a pointer bool operator!=(const T *ptr) const { return m_ptr != ptr; } /// Access the object referenced by this reference T *operator->() { return m_ptr; } /// Access the object referenced by this reference const T *operator->() const { return m_ptr; } /// Return a C++ reference to the referenced object T &operator*() { return *m_ptr; } /// Return a const C++ reference to the referenced object const T &operator*() const { return *m_ptr; } /// Return a pointer to the referenced object operator T *() { return m_ptr; } /// Return a const pointer to the referenced object operator const T *() const { return m_ptr; } /// Return a pointer to the referenced object T *get() { return m_ptr; } /// Return a const pointer to the referenced object const T *get() const { return m_ptr; } private: T *m_ptr = nullptr; }; // Registar a type caster for ``ref`` if nanobind was previously #included #if defined(NB_VERSION_MAJOR) NAMESPACE_BEGIN(detail) template struct type_caster> { using Caster = make_caster; static constexpr bool IsClass = true; NB_TYPE_CASTER(ref, Caster::Name) bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept { Caster caster; if (!caster.from_python(src, flags, cleanup)) return false; value = Value(caster.operator T *()); return true; } static handle from_cpp(const ref &value, rv_policy policy, cleanup_list *cleanup) noexcept { if constexpr (std::is_base_of_v) if (policy != rv_policy::copy && policy != rv_policy::move && value.get()) if (PyObject* obj = value->self_py()) return handle(obj).inc_ref(); return Caster::from_cpp(value.get(), policy, cleanup); } }; NAMESPACE_END(detail) #endif NAMESPACE_END(nanobind) wjakob-nanobind-6c4457b/include/nanobind/make_iterator.h000066400000000000000000000155331474760012700233460ustar00rootroot00000000000000/* nanobind/make_iterator.h: nb::make_[key,value_]iterator() This implementation is a port from pybind11 with minimal adjustments. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ #pragma once #include #include NAMESPACE_BEGIN(NB_NAMESPACE) NAMESPACE_BEGIN(detail) /* There are a large number of apparently unused template arguments because each combination requires a separate nb::class_ registration. */ template struct iterator_state { Iterator it; Sentinel end; bool first_or_done; }; template struct remove_rvalue_ref { using type = T; }; template struct remove_rvalue_ref { using type = T; }; // Note: these helpers take the iterator by non-const reference because some // iterators in the wild can't be dereferenced when const. template struct iterator_access { using result_type = decltype(*std::declval()); result_type operator()(Iterator &it) const { return *it; } }; template struct iterator_key_access { // Note double parens in decltype((...)) to capture the value category // as well. This will be lvalue if the iterator's operator* returned an // lvalue reference, and xvalue if the iterator's operator* returned an // object (or rvalue reference but that's unlikely). decltype of an xvalue // produces T&&, but we want to return a value T from operator() in that // case, in order to avoid creating a Python object that references a // C++ temporary. Thus, pass the result through remove_rvalue_ref. using result_type = typename remove_rvalue_ref< decltype(((*std::declval()).first))>::type; result_type operator()(Iterator &it) const { return (*it).first; } }; template struct iterator_value_access { using result_type = typename remove_rvalue_ref< decltype(((*std::declval()).second))>::type; result_type operator()(Iterator &it) const { return (*it).second; } }; template typed make_iterator_impl(handle scope, const char *name, Iterator first, Sentinel last, Extra &&...extra) { using State = iterator_state; static_assert( !detail::is_base_caster_v> || detail::is_copy_constructible_v || (Policy != rv_policy::automatic_reference && Policy != rv_policy::copy), "make_iterator_impl(): the generated __next__ would copy elements, so the " "element type must be copy-constructible"); { static ft_mutex mu; ft_lock_guard lock(mu); if (!type().is_valid()) { class_(scope, name) .def("__iter__", [](handle h) { return h; }) .def("__next__", [](State &s) -> ValueType { if (!s.first_or_done) ++s.it; else s.first_or_done = false; if (s.it == s.end) { s.first_or_done = true; throw stop_iteration(); } return Access()(s.it); }, std::forward(extra)..., Policy); } } return borrow>(cast(State{ std::forward(first), std::forward(last), true })); } NAMESPACE_END(detail) /// Makes a python iterator from a first and past-the-end C++ InputIterator. template ::result_type, typename... Extra, typename = decltype(std::declval() == std::declval())> auto make_iterator(handle scope, const char *name, Iterator first, Sentinel last, Extra &&...extra) { return detail::make_iterator_impl, Policy, Iterator, Sentinel, ValueType, Extra...>( scope, name, std::forward(first), std::forward(last), std::forward(extra)...); } /// Makes an iterator over the keys (`.first`) of a iterator over pairs from a /// first and past-the-end InputIterator. template ::result_type, typename... Extra> auto make_key_iterator(handle scope, const char *name, Iterator first, Sentinel last, Extra &&...extra) { return detail::make_iterator_impl, Policy, Iterator, Sentinel, KeyType, Extra...>( scope, name, std::forward(first), std::forward(last), std::forward(extra)...); } /// Makes an iterator over the values (`.second`) of a iterator over pairs from a /// first and past-the-end InputIterator. template ::result_type, typename... Extra> auto make_value_iterator(handle scope, const char *name, Iterator first, Sentinel last, Extra &&...extra) { return detail::make_iterator_impl, Policy, Iterator, Sentinel, ValueType, Extra...>( scope, name, std::forward(first), std::forward(last), std::forward(extra)...); } /// Makes an iterator over values of a container supporting `std::begin()`/`std::end()` template ()))> auto make_iterator(handle scope, const char *name, Type &value, Extra &&...extra) { return make_iterator(scope, name, std::begin(value), std::end(value), std::forward(extra)...); } NAMESPACE_END(NB_NAMESPACE) wjakob-nanobind-6c4457b/include/nanobind/nanobind.h000066400000000000000000000033631474760012700223060ustar00rootroot00000000000000/* nanobind/nanobind.h: Main include file for core nanobind components Copyright (c) 2022 Wenzel Jakob All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ #pragma once #if __cplusplus < 201703L && (!defined(_MSVC_LANG) || _MSVC_LANG < 201703L) # error The nanobind library requires C++17! #endif #if defined(_MSC_VER) # pragma warning(push) # pragma warning(disable: 4702) // unreachable code (e.g. when binding a noreturn function) // The next two lines disable warnings that are "just noise" according to Stephan T. Lavavej (a MSFT STL maintainer) # pragma warning(disable: 4275) // non dll-interface class 'std::exception' used as base for dll-interface class [..] # pragma warning(disable: 4251) // [..] needs to have a dll-interface to be used by clients of class [..] #endif #define NB_VERSION_MAJOR 2 #define NB_VERSION_MINOR 5 #define NB_VERSION_PATCH 0 #define NB_VERSION_DEV 0 // A value > 0 indicates a development release // Core C++ headers that nanobind depends on #include #include #include #include #include #include #include #include // Implementation. The nb_*.h files should only be included through nanobind.h // IWYU pragma: begin_exports #include "nb_python.h" #include "nb_defs.h" #include "nb_enums.h" #include "nb_traits.h" #include "nb_tuple.h" #include "nb_lib.h" #include "nb_descr.h" #include "nb_types.h" #include "nb_accessor.h" #include "nb_error.h" #include "nb_attr.h" #include "nb_cast.h" #include "nb_misc.h" #include "nb_call.h" #include "nb_func.h" #include "nb_class.h" // IWYU pragma: end_exports #if defined(_MSC_VER) # pragma warning(pop) #endif wjakob-nanobind-6c4457b/include/nanobind/nb_accessor.h000066400000000000000000000144631474760012700230020ustar00rootroot00000000000000/* nanobind/nb_accessor.h: Accessor helper class for .attr(), operator[] Copyright (c) 2022 Wenzel Jakob All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ NAMESPACE_BEGIN(NB_NAMESPACE) NAMESPACE_BEGIN(detail) template class accessor : public api> { template friend void nanobind::del(accessor &); template friend void nanobind::del(accessor &&); public: static constexpr auto Name = const_name("object"); template accessor(handle obj, Key &&key) : m_base(obj.ptr()), m_key(std::move(key)) { } accessor(const accessor &) = delete; accessor(accessor &&) = delete; ~accessor() { if constexpr (Impl::cache_dec_ref) Py_XDECREF(m_cache); } template accessor& operator=(T &&value); template > = 0> operator T() const { return borrow(ptr()); } NB_INLINE PyObject *ptr() const { Impl::get(m_base, m_key, &m_cache); return m_cache; } NB_INLINE handle base() const { return m_base; } NB_INLINE object key() const { return steal(Impl::key(m_key)); } private: NB_INLINE void del () { Impl::del(m_base, m_key); } private: PyObject *m_base; mutable PyObject *m_cache{nullptr}; typename Impl::key_type m_key; }; struct str_attr { static constexpr bool cache_dec_ref = true; using key_type = const char *; NB_INLINE static void get(PyObject *obj, const char *key, PyObject **cache) { detail::getattr_or_raise(obj, key, cache); } NB_INLINE static void set(PyObject *obj, const char *key, PyObject *v) { setattr(obj, key, v); } NB_INLINE static PyObject *key(const char *key) { return PyUnicode_InternFromString(key); } }; struct obj_attr { static constexpr bool cache_dec_ref = true; using key_type = handle; NB_INLINE static void get(PyObject *obj, handle key, PyObject **cache) { detail::getattr_or_raise(obj, key.ptr(), cache); } NB_INLINE static void set(PyObject *obj, handle key, PyObject *v) { setattr(obj, key.ptr(), v); } NB_INLINE static PyObject *key(handle key) { Py_INCREF(key.ptr()); return key.ptr(); } }; struct str_item { static constexpr bool cache_dec_ref = true; using key_type = const char *; NB_INLINE static void get(PyObject *obj, const char *key, PyObject **cache) { detail::getitem_or_raise(obj, key, cache); } NB_INLINE static void set(PyObject *obj, const char *key, PyObject *v) { setitem(obj, key, v); } NB_INLINE static void del(PyObject *obj, const char *key) { delitem(obj, key); } }; struct obj_item { static constexpr bool cache_dec_ref = true; using key_type = handle; NB_INLINE static void get(PyObject *obj, handle key, PyObject **cache) { detail::getitem_or_raise(obj, key.ptr(), cache); } NB_INLINE static void set(PyObject *obj, handle key, PyObject *v) { setitem(obj, key.ptr(), v); } NB_INLINE static void del(PyObject *obj, handle key) { delitem(obj, key.ptr()); } }; struct num_item { static constexpr bool cache_dec_ref = true; using key_type = Py_ssize_t; NB_INLINE static void get(PyObject *obj, Py_ssize_t index, PyObject **cache) { detail::getitem_or_raise(obj, index, cache); } NB_INLINE static void set(PyObject *obj, Py_ssize_t index, PyObject *v) { setitem(obj, index, v); } NB_INLINE static void del(PyObject *obj, Py_ssize_t index) { delitem(obj, index); } }; struct num_item_list { #if defined(Py_GIL_DISABLED) static constexpr bool cache_dec_ref = true; #else static constexpr bool cache_dec_ref = false; #endif using key_type = Py_ssize_t; NB_INLINE static void get(PyObject *obj, Py_ssize_t index, PyObject **cache) { #if defined(Py_GIL_DISABLED) *cache = PyList_GetItemRef(obj, index); #else *cache = NB_LIST_GET_ITEM(obj, index); #endif } NB_INLINE static void set(PyObject *obj, Py_ssize_t index, PyObject *v) { #if defined(Py_LIMITED_API) || defined(NB_FREE_THREADED) Py_INCREF(v); PyList_SetItem(obj, index, v); #else PyObject *old = NB_LIST_GET_ITEM(obj, index); Py_INCREF(v); NB_LIST_SET_ITEM(obj, index, v); Py_DECREF(old); #endif } NB_INLINE static void del(PyObject *obj, Py_ssize_t index) { delitem(obj, index); } }; struct num_item_tuple { static constexpr bool cache_dec_ref = false; using key_type = Py_ssize_t; NB_INLINE static void get(PyObject *obj, Py_ssize_t index, PyObject **cache) { *cache = NB_TUPLE_GET_ITEM(obj, index); } template static void set(Ts...) { static_assert(false_v, "tuples are immutable!"); } }; template accessor api::attr(handle key) const { return { derived(), borrow(key) }; } template accessor api::attr(const char *key) const { return { derived(), key }; } template accessor api::doc() const { return { derived(), "__doc__" }; } template accessor api::operator[](handle key) const { return { derived(), borrow(key) }; } template accessor api::operator[](const char *key) const { return { derived(), key }; } template template >> accessor api::operator[](T index) const { return { derived(), (Py_ssize_t) index }; } NAMESPACE_END(detail) template >> detail::accessor list::operator[](T index) const { return { derived(), (Py_ssize_t) index }; } template >> detail::accessor tuple::operator[](T index) const { return { derived(), (Py_ssize_t) index }; } template str str::format(Args&&... args) { return steal( derived().attr("format")((detail::forward_t) args...).release()); } NAMESPACE_END(NB_NAMESPACE) wjakob-nanobind-6c4457b/include/nanobind/nb_attr.h000066400000000000000000000366501474760012700221540ustar00rootroot00000000000000/* nanobind/nb_attr.h: Annotations for function and class declarations Copyright (c) 2022 Wenzel Jakob All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ NAMESPACE_BEGIN(NB_NAMESPACE) struct scope { PyObject *value; NB_INLINE scope(handle value) : value(value.ptr()) {} }; struct name { const char *value; NB_INLINE name(const char *value) : value(value) {} }; struct arg_v; struct arg_locked; struct arg_locked_v; // Basic function argument descriptor (no default value, not locked) struct arg { NB_INLINE constexpr explicit arg(const char *name = nullptr) : name_(name), signature_(nullptr) { } // operator= can be used to provide a default value template NB_INLINE arg_v operator=(T &&value) const; // Mutators that don't change default value or locked state NB_INLINE arg &noconvert(bool value = true) { convert_ = !value; return *this; } NB_INLINE arg &none(bool value = true) { none_ = value; return *this; } NB_INLINE arg &sig(const char *value) { signature_ = value; return *this; } // After lock(), this argument is locked NB_INLINE arg_locked lock(); const char *name_, *signature_; uint8_t convert_{ true }; bool none_{ false }; }; // Function argument descriptor with default value (not locked) struct arg_v : arg { object value; NB_INLINE arg_v(const arg &base, object &&value) : arg(base), value(std::move(value)) {} private: // Inherited mutators would slice off the default, and are not generally needed using arg::noconvert; using arg::none; using arg::sig; using arg::lock; }; // Function argument descriptor that is locked (no default value) struct arg_locked : arg { NB_INLINE constexpr explicit arg_locked(const char *name = nullptr) : arg(name) { } NB_INLINE constexpr explicit arg_locked(const arg &base) : arg(base) { } // operator= can be used to provide a default value template NB_INLINE arg_locked_v operator=(T &&value) const; // Mutators must be respecified in order to not slice off the locked status NB_INLINE arg_locked &noconvert(bool value = true) { convert_ = !value; return *this; } NB_INLINE arg_locked &none(bool value = true) { none_ = value; return *this; } NB_INLINE arg_locked &sig(const char *value) { signature_ = value; return *this; } // Redundant extra lock() is allowed NB_INLINE arg_locked &lock() { return *this; } }; // Function argument descriptor that is potentially locked and has a default value struct arg_locked_v : arg_locked { object value; NB_INLINE arg_locked_v(const arg_locked &base, object &&value) : arg_locked(base), value(std::move(value)) {} private: // Inherited mutators would slice off the default, and are not generally needed using arg_locked::noconvert; using arg_locked::none; using arg_locked::sig; using arg_locked::lock; }; NB_INLINE arg_locked arg::lock() { return arg_locked{*this}; } template struct call_guard { using type = detail::tuple; }; struct dynamic_attr {}; struct is_weak_referenceable {}; struct is_method {}; struct is_implicit {}; struct is_operator {}; struct is_arithmetic {}; struct is_flag {}; struct is_final {}; struct is_generic {}; struct kw_only {}; struct lock_self {}; template struct keep_alive {}; template struct supplement {}; template struct intrusive_ptr { intrusive_ptr(void (*set_self_py)(T *, PyObject *) noexcept) : set_self_py(set_self_py) { } void (*set_self_py)(T *, PyObject *) noexcept; }; struct type_slots { type_slots (const PyType_Slot *value) : value(value) { } const PyType_Slot *value; }; struct type_slots_callback { using cb_t = void (*)(const detail::type_init_data *t, PyType_Slot *&slots, size_t max_slots) noexcept; type_slots_callback(cb_t callback) : callback(callback) { } cb_t callback; }; struct sig { const char *value; sig(const char *value) : value(value) { } }; struct is_getter { }; template struct call_policy final {}; NAMESPACE_BEGIN(literals) constexpr arg operator"" _a(const char *name, size_t) { return arg(name); } NAMESPACE_END(literals) NAMESPACE_BEGIN(detail) enum class func_flags : uint32_t { /* Low 3 bits reserved for return value policy */ /// Did the user specify a name for this function, or is it anonymous? has_name = (1 << 4), /// Did the user specify a scope in which this function should be installed? has_scope = (1 << 5), /// Did the user specify a docstring? has_doc = (1 << 6), /// Did the user specify nb::arg/arg_v annotations for all arguments? has_args = (1 << 7), /// Does the function signature contain an *args-style argument? has_var_args = (1 << 8), /// Does the function signature contain an *kwargs-style argument? has_var_kwargs = (1 << 9), /// Is this function a method of a class? is_method = (1 << 10), /// Is this function a method called __init__? (automatically generated) is_constructor = (1 << 11), /// Can this constructor be used to perform an implicit conversion? is_implicit = (1 << 12), /// Is this function an arithmetic operator? is_operator = (1 << 13), /// When the function is GCed, do we need to call func_data_prelim::free_capture? has_free = (1 << 14), /// Should the func_new() call return a new reference? return_ref = (1 << 15), /// Does this overload specify a custom function signature (for docstrings, typing) has_signature = (1 << 16), /// Does this function potentially modify the elements of the PyObject*[] array /// representing its arguments? (nb::keep_alive() or call_policy annotations) can_mutate_args = (1 << 17) }; enum cast_flags : uint8_t { // Enable implicit conversions (code assumes this has value 1, don't reorder..) convert = (1 << 0), // Passed to the 'self' argument in a constructor call (__init__) construct = (1 << 1), // Indicates that the function dispatcher should accept 'None' arguments accepts_none = (1 << 2), // Indicates that this cast is performed by nb::cast or nb::try_cast. // This implies that objects added to the cleanup list may be // released immediately after the caster's final output value is // obtained, i.e., before it is used. manual = (1 << 3) }; struct arg_data { const char *name; const char *signature; PyObject *name_py; PyObject *value; uint8_t flag; }; template struct func_data_prelim { // A small amount of space to capture data used by the function/closure void *capture[3]; // Callback to clean up the 'capture' field void (*free_capture)(void *); /// Implementation of the function call PyObject *(*impl)(void *, PyObject **, uint8_t *, rv_policy, cleanup_list *); /// Function signature description const char *descr; /// C++ types referenced by 'descr' const std::type_info **descr_types; /// Supplementary flags uint32_t flags; /// Total number of parameters accepted by the C++ function; nb::args /// and nb::kwargs parameters are counted as one each. If the /// 'has_args' flag is set, then there is one arg_data structure /// for each of these. uint16_t nargs; /// Number of paramters to the C++ function that may be filled from /// Python positional arguments without additional ceremony. nb::args and /// nb::kwargs parameters are not counted in this total, nor are any /// parameters after nb::args or after a nb::kw_only annotation. /// The parameters counted here may be either named (nb::arg("name")) /// or unnamed (nb::arg()). If unnamed, they are effectively positional-only. /// nargs_pos is always <= nargs. uint16_t nargs_pos; // ------- Extra fields ------- const char *name; const char *doc; PyObject *scope; // *WARNING*: nanobind regularly receives requests from users who run it // through Clang-Tidy, or who compile with increased warnings levels, like // // -Wpedantic, -Wcast-qual, -Wsign-conversion, etc. // // (i.e., beyond -Wall -Wextra and /W4 that are currently already used) // // Their next step is to open a big pull request needed to silence all of // the resulting messages. This comment is strategically placed here // because the zero-length array construction below will almost certainly // be flagged in this process. // // My policy on this is as follows: I am always happy to fix issues in the // codebase. However, many of the resulting change requests are in the // "ritual purification" category: things that cause churn, decrease // readability, and which don't fix actual problems. It's a never-ending // cycle because each new revision of such tooling adds further warnings // and purification rites. // // So just to be clear: I do not wish to pepper this codebase with // "const_cast" and #pragmas/comments to avoid warnings in external // tooling just so those users can have a "silent" build. I don't think it // is reasonable for them to impose their own style on this project. // // As a workaround it is likely possible to restrict the scope of style // checks to particular C++ namespaces or source code locations. #if defined(_MSC_VER) // MSVC doesn't support zero-length arrays arg_data args[Size == 0 ? 1 : Size]; #else // GCC and Clang do. arg_data args[Size]; #endif }; template NB_INLINE void func_extra_apply(F &f, const name &name, size_t &) { f.name = name.value; f.flags |= (uint32_t) func_flags::has_name; } template NB_INLINE void func_extra_apply(F &f, const scope &scope, size_t &) { f.scope = scope.value; f.flags |= (uint32_t) func_flags::has_scope; } template NB_INLINE void func_extra_apply(F &f, const sig &s, size_t &) { f.flags |= (uint32_t) func_flags::has_signature; f.name = s.value; } template NB_INLINE void func_extra_apply(F &f, const char *doc, size_t &) { f.doc = doc; f.flags |= (uint32_t) func_flags::has_doc; } template NB_INLINE void func_extra_apply(F &f, is_method, size_t &) { f.flags |= (uint32_t) func_flags::is_method; } template NB_INLINE void func_extra_apply(F &, is_getter, size_t &) { } template NB_INLINE void func_extra_apply(F &f, is_implicit, size_t &) { f.flags |= (uint32_t) func_flags::is_implicit; } template NB_INLINE void func_extra_apply(F &f, is_operator, size_t &) { f.flags |= (uint32_t) func_flags::is_operator; } template NB_INLINE void func_extra_apply(F &f, rv_policy pol, size_t &) { f.flags = (f.flags & ~0b111) | (uint16_t) pol; } template NB_INLINE void func_extra_apply(F &, std::nullptr_t, size_t &) { } template NB_INLINE void func_extra_apply(F &f, const arg &a, size_t &index) { uint8_t flag = 0; if (a.none_) flag |= (uint8_t) cast_flags::accepts_none; if (a.convert_) flag |= (uint8_t) cast_flags::convert; arg_data &arg = f.args[index]; arg.flag = flag; arg.name = a.name_; arg.signature = a.signature_; arg.value = nullptr; index++; } // arg_locked will select the arg overload; the locking is added statically // in nb_func.h template NB_INLINE void func_extra_apply(F &f, const arg_v &a, size_t &index) { arg_data &ad = f.args[index]; func_extra_apply(f, (const arg &) a, index); ad.value = a.value.ptr(); } template NB_INLINE void func_extra_apply(F &f, const arg_locked_v &a, size_t &index) { arg_data &ad = f.args[index]; func_extra_apply(f, (const arg_locked &) a, index); ad.value = a.value.ptr(); } template NB_INLINE void func_extra_apply(F &, kw_only, size_t &) {} template NB_INLINE void func_extra_apply(F &, lock_self, size_t &) {} template NB_INLINE void func_extra_apply(F &, call_guard, size_t &) {} template NB_INLINE void func_extra_apply(F &f, nanobind::keep_alive, size_t &) { f.flags |= (uint32_t) func_flags::can_mutate_args; } template NB_INLINE void func_extra_apply(F &f, call_policy, size_t &) { f.flags |= (uint32_t) func_flags::can_mutate_args; } template struct func_extra_info { using call_guard = void; static constexpr bool pre_post_hooks = false; static constexpr size_t nargs_locked = 0; }; template struct func_extra_info : func_extra_info { }; template struct func_extra_info, Ts...> : func_extra_info { static_assert(std::is_same_v::call_guard, void>, "call_guard<> can only be specified once!"); using call_guard = nanobind::call_guard; }; template struct func_extra_info, Ts...> : func_extra_info { static constexpr bool pre_post_hooks = true; }; template struct func_extra_info, Ts...> : func_extra_info { static constexpr bool pre_post_hooks = true; }; template struct func_extra_info : func_extra_info { static constexpr size_t nargs_locked = 1 + func_extra_info::nargs_locked; }; template struct func_extra_info : func_extra_info { static constexpr size_t nargs_locked = 1 + func_extra_info::nargs_locked; }; NB_INLINE void process_precall(PyObject **, size_t, detail::cleanup_list *, void *) { } template NB_INLINE void process_precall(PyObject **args, std::integral_constant nargs, detail::cleanup_list *cleanup, call_policy *) { Policy::precall(args, nargs, cleanup); } NB_INLINE void process_postcall(PyObject **, size_t, PyObject *, void *) { } template NB_INLINE void process_postcall(PyObject **args, std::integral_constant, PyObject *result, nanobind::keep_alive *) { static_assert(Nurse != Patient, "keep_alive with the same argument as both nurse and patient " "doesn't make sense"); static_assert(Nurse <= NArgs && Patient <= NArgs, "keep_alive template parameters must be in the range " "[0, number of C++ function arguments]"); keep_alive(Nurse == 0 ? result : args[Nurse - 1], Patient == 0 ? result : args[Patient - 1]); } template NB_INLINE void process_postcall(PyObject **args, std::integral_constant nargs, PyObject *&result, call_policy *) { // result_guard avoids leaking a reference to the return object // if postcall throws an exception object result_guard = steal(result); Policy::postcall(args, nargs, result); result_guard.release(); } NAMESPACE_END(detail) NAMESPACE_END(NB_NAMESPACE) wjakob-nanobind-6c4457b/include/nanobind/nb_call.h000066400000000000000000000131331474760012700221040ustar00rootroot00000000000000/* nanobind/nb_call.h: Functionality for calling Python functions from C++ Copyright (c) 2022 Wenzel Jakob All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ NAMESPACE_BEGIN(NB_NAMESPACE) NAMESPACE_BEGIN(detail) #if defined(_MSC_VER) # pragma warning(push) # pragma warning(disable: 6255) // _alloca indicates failure by raising a stack overflow exception #endif class kwargs_proxy : public handle { public: explicit kwargs_proxy(handle h) : handle(h) { } }; class args_proxy : public handle { public: explicit args_proxy(handle h) : handle(h) { } kwargs_proxy operator*() const { return kwargs_proxy(*this); } }; template args_proxy api::operator*() const { return args_proxy(derived().ptr()); } /// Implementation detail of api::operator() (call operator) template NB_INLINE void call_analyze(size_t &nargs, size_t &nkwargs, const T &value) { using D = std::decay_t; static_assert(!std::is_base_of_v, "nb::arg().lock() may be used only when defining functions, " "not when calling them"); if constexpr (std::is_same_v) nkwargs++; else if constexpr (std::is_same_v) nargs += len(value); else if constexpr (std::is_same_v) nkwargs += len(value); else nargs += 1; (void) nargs; (void) nkwargs; (void) value; } /// Implementation detail of api::operator() (call operator) template NB_INLINE void call_init(PyObject **args, PyObject *kwnames, size_t &nargs, size_t &nkwargs, const size_t kwargs_offset, T &&value) { using D = std::decay_t; if constexpr (std::is_same_v) { args[kwargs_offset + nkwargs] = value.value.release().ptr(); NB_TUPLE_SET_ITEM(kwnames, nkwargs++, PyUnicode_InternFromString(value.name_)); } else if constexpr (std::is_same_v) { for (size_t i = 0, l = len(value); i < l; ++i) args[nargs++] = borrow(value[i]).release().ptr(); } else if constexpr (std::is_same_v) { PyObject *key, *entry; Py_ssize_t pos = 0; #if defined(NB_FREE_THREADED) ft_object_guard guard(value); #endif while (PyDict_Next(value.ptr(), &pos, &key, &entry)) { Py_INCREF(key); Py_INCREF(entry); args[kwargs_offset + nkwargs] = entry; NB_TUPLE_SET_ITEM(kwnames, nkwargs++, key); } } else { args[nargs++] = make_caster::from_cpp((forward_t) value, policy, nullptr).ptr(); } (void) args; (void) kwnames; (void) nargs; (void) nkwargs; (void) kwargs_offset; } #define NB_DO_VECTORCALL() \ PyObject *base, **args_p; \ if constexpr (method_call) { \ base = derived().key().release().ptr(); \ args[0] = derived().base().inc_ref().ptr(); \ args_p = args; \ nargs++; \ } else { \ base = derived().inc_ref().ptr(); \ args[0] = nullptr; \ args_p = args + 1; \ } \ nargs |= NB_VECTORCALL_ARGUMENTS_OFFSET; \ return steal(obj_vectorcall(base, args_p, nargs, kwnames, method_call)) template template object api::operator()(Args &&...args_) const { static constexpr bool method_call = std::is_same_v> || std::is_same_v>; if constexpr (((std::is_same_v || std::is_same_v || std::is_same_v) || ...)) { // Complex call with keyword arguments, *args/**kwargs expansion, etc. size_t nargs = 0, nkwargs = 0, nargs2 = 0, nkwargs2 = 0; // Determine storage requirements for positional and keyword args (call_analyze(nargs, nkwargs, (const Args &) args_), ...); // Allocate memory on the stack PyObject **args = (PyObject **) alloca((nargs + nkwargs + 1) * sizeof(PyObject *)); PyObject *kwnames = nkwargs ? PyTuple_New((Py_ssize_t) nkwargs) : nullptr; // Fill 'args' and 'kwnames' variables (call_init(args + 1, kwnames, nargs2, nkwargs2, nargs, (forward_t) args_), ...); NB_DO_VECTORCALL(); } else { // Simple version with only positional arguments PyObject *args[sizeof...(Args) + 1], *kwnames = nullptr; size_t nargs = 0; ((args[1 + nargs++] = detail::make_caster::from_cpp( (detail::forward_t) args_, policy, nullptr) .ptr()), ...); NB_DO_VECTORCALL(); } } #undef NB_DO_VECTORCALL #if defined(_MSC_VER) # pragma warning(pop) #endif NAMESPACE_END(detail) NAMESPACE_END(NB_NAMESPACE) wjakob-nanobind-6c4457b/include/nanobind/nb_cast.h000066400000000000000000000656061474760012700221370ustar00rootroot00000000000000/* nanobind/nb_cast.h: Type caster interface and essential type casters Copyright (c) 2022 Wenzel Jakob All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ #define NB_TYPE_CASTER(Value_, descr) \ using Value = Value_; \ static constexpr auto Name = descr; \ template using Cast = movable_cast_t; \ template static constexpr bool can_cast() { return true; } \ template , Value>> = 0> \ static handle from_cpp(T_ *p, rv_policy policy, cleanup_list *list) { \ if (!p) \ return none().release(); \ return from_cpp(*p, policy, list); \ } \ explicit operator Value*() { return &value; } \ explicit operator Value&() { return (Value &) value; } \ explicit operator Value&&() { return (Value &&) value; } \ Value value; #define NB_MAKE_OPAQUE(...) \ namespace nanobind::detail { \ template <> class type_caster<__VA_ARGS__> \ : public type_caster_base<__VA_ARGS__> { }; } NAMESPACE_BEGIN(NB_NAMESPACE) NAMESPACE_BEGIN(detail) /** * Type casters expose a member 'Cast' which users of a type caster must * query to determine what the caster actually can (and prefers) to produce. * The convenience alias ``cast_t`` defined below performs this query for a * given type ``T``. * * Often ``cast_t`` is simply equal to ``T`` or ``T&``. More significant * deviations are also possible, which could be due to one of the following * two reasons: * * 1. Efficiency: most STL type casters create a local copy (``value`` member) * of the value being cast. The caller should move this value to its * intended destination instead of making further copies along the way. * Consequently, ``cast_t>`` yields ``cast_t> * &&`` to enable such behavior. * * 2. STL pairs may contain references, and such pairs aren't * default-constructible. The STL pair caster therefore cannot create a local * copy and must construct the pair on the fly, which in turns means that it * cannot return references. Therefore, ``cast_t&>`` * yields ``std::pair``. */ /// Ask a type caster what flavors of a type it can actually produce -- may be different from 'T' template using cast_t = typename make_caster::template Cast; /// This is a default choice for the 'Cast' type alias described above. It /// prefers to return rvalue references to allow the caller to move the object. template using movable_cast_t = std::conditional_t, intrinsic_t *, std::conditional_t, intrinsic_t &, intrinsic_t &&>>; /// This version is more careful about what the caller actually requested and /// only moves when this was explicitly requested. It is the default for the /// base type caster (i.e., types bound via ``nanobind::class_<..>``) template using precise_cast_t = std::conditional_t, intrinsic_t *, std::conditional_t, intrinsic_t &&, intrinsic_t &>>; /// Many type casters delegate to another caster using the pattern: /// ~~~ .cc /// bool from_python(handle src, uint8_t flags, cleanup_list *cl) noexcept { /// SomeCaster c; /// if (!c.from_python(src, flags, cl)) return false; /// /* do something with */ c.operator T(); /// return true; /// } /// ~~~ /// This function adjusts the flags to avoid issues where the resulting T object /// refers into storage that will dangle after SomeCaster is destroyed, and /// causes a static assertion failure if that's not sufficient. Use it like: /// ~~~ .cc /// if (!c.from_python(src, flags_for_local_caster(flags), cl)) /// return false; /// ~~~ /// where the template argument T is the type you plan to extract. template NB_INLINE uint8_t flags_for_local_caster(uint8_t flags) noexcept { using Caster = make_caster; constexpr bool is_ref = std::is_pointer_v || std::is_reference_v; if constexpr (is_base_caster_v) { if constexpr (is_ref) { /* References/pointers to a type produced by implicit conversions refer to storage owned by the cleanup_list. In a nb::cast() call, that storage will be released before the reference can be used; to prevent dangling, don't allow implicit conversions there. */ if (flags & ((uint8_t) cast_flags::manual)) flags &= ~((uint8_t) cast_flags::convert); } } else { /* Any pointer produced by a non-base caster will generally point into storage owned by the caster, which won't live long enough. Exception: the 'char' caster produces a result that points to storage owned by the incoming Python 'str' object, so it's OK. */ static_assert(!is_ref || std::is_same_v || (std::is_pointer_v && std::is_constructible_v), "nanobind generally cannot produce objects that " "contain interior pointers T* (or references T&) if " "the pointee T is not handled by nanobind's regular " "class binding mechanism. For example, you can write " "a function that accepts int*, or std::vector, " "but not std::vector."); } return flags; } template struct type_caster && !is_std_char_v>> { NB_INLINE bool from_python(handle src, uint8_t flags, cleanup_list *) noexcept { if constexpr (std::is_floating_point_v) { if constexpr (std::is_same_v) { return detail::load_f64(src.ptr(), flags, &value); } else if constexpr (std::is_same_v) { return detail::load_f32(src.ptr(), flags, &value); } else { double d; if (!detail::load_f64(src.ptr(), flags, &d)) return false; T result = (T) d; if ((flags & (uint8_t) cast_flags::convert) || (double) result == d || (result != result && d != d)) { value = result; return true; } return false; } } else { if constexpr (std::is_signed_v) { if constexpr (sizeof(T) == 8) return detail::load_i64(src.ptr(), flags, (int64_t *) &value); else if constexpr (sizeof(T) == 4) return detail::load_i32(src.ptr(), flags, (int32_t *) &value); else if constexpr (sizeof(T) == 2) return detail::load_i16(src.ptr(), flags, (int16_t *) &value); else return detail::load_i8(src.ptr(), flags, (int8_t *) &value); } else { if constexpr (sizeof(T) == 8) return detail::load_u64(src.ptr(), flags, (uint64_t *) &value); else if constexpr (sizeof(T) == 4) return detail::load_u32(src.ptr(), flags, (uint32_t *) &value); else if constexpr (sizeof(T) == 2) return detail::load_u16(src.ptr(), flags, (uint16_t *) &value); else return detail::load_u8(src.ptr(), flags, (uint8_t *) &value); } } } NB_INLINE static handle from_cpp(T src, rv_policy, cleanup_list *) noexcept { if constexpr (std::is_floating_point_v) { return PyFloat_FromDouble((double) src); } else { if constexpr (std::is_signed_v) { if constexpr (sizeof(T) <= sizeof(long)) return PyLong_FromLong((long) src); else return PyLong_FromLongLong((long long) src); } else { if constexpr (sizeof(T) <= sizeof(unsigned long)) return PyLong_FromUnsignedLong((unsigned long) src); else return PyLong_FromUnsignedLongLong((unsigned long long) src); } } } NB_TYPE_CASTER(T, const_name>("int", "float")) }; template struct type_caster>> { NB_INLINE bool from_python(handle src, uint8_t flags, cleanup_list *) noexcept { int64_t result; bool rv = enum_from_python(&typeid(T), src.ptr(), &result, flags); value = (T) result; return rv; } NB_INLINE static handle from_cpp(T src, rv_policy, cleanup_list *) noexcept { return enum_from_cpp(&typeid(T), (int64_t) src); } NB_TYPE_CASTER(T, const_name()) }; template <> struct type_caster { static constexpr auto Name = const_name("None"); }; template <> struct type_caster { template using Cast = void *; template static constexpr bool can_cast() { return true; } using Value = void*; static constexpr auto Name = const_name("types.CapsuleType"); explicit operator void *() { return value; } Value value; bool from_python(handle src, uint8_t, cleanup_list *) noexcept { if (src.is_none()) { value = nullptr; return true; } else { value = PyCapsule_GetPointer(src.ptr(), "nb_handle"); if (!value) { PyErr_Clear(); return false; } return true; } } static handle from_cpp(void *ptr, rv_policy, cleanup_list *) noexcept { if (ptr) return PyCapsule_New(ptr, "nb_handle", nullptr); else return none().release(); } }; template struct none_caster { bool from_python(handle src, uint8_t, cleanup_list *) noexcept { if (src.is_none()) return true; return false; } static handle from_cpp(T, rv_policy, cleanup_list *) noexcept { return none().release(); } NB_TYPE_CASTER(T, const_name("None")) }; template <> struct type_caster : none_caster { }; template <> struct type_caster { bool from_python(handle src, uint8_t, cleanup_list *) noexcept { if (src.ptr() == Py_True) { value = true; return true; } else if (src.ptr() == Py_False) { value = false; return true; } else { return false; } } static handle from_cpp(bool src, rv_policy, cleanup_list *) noexcept { return handle(src ? Py_True : Py_False).inc_ref(); } NB_TYPE_CASTER(bool, const_name("bool")) }; template <> struct type_caster { using Value = const char *; Value value; Py_ssize_t size; static constexpr auto Name = const_name("str"); template using Cast = std::conditional_t, const char *, char>; bool from_python(handle src, uint8_t, cleanup_list *) noexcept { value = PyUnicode_AsUTF8AndSize(src.ptr(), &size); if (!value) { PyErr_Clear(); return false; } return true; } static handle from_cpp(const char *value, rv_policy, cleanup_list *) noexcept { if (value == nullptr) { PyObject* result = Py_None; Py_INCREF(result); return result; } return PyUnicode_FromString(value); } static handle from_cpp(char value, rv_policy, cleanup_list *) noexcept { return PyUnicode_FromStringAndSize(&value, 1); } template NB_INLINE bool can_cast() const noexcept { return std::is_pointer_v || (value && size == 1); } explicit operator const char *() { return value; } explicit operator char() { if (can_cast()) return value[0]; else throw next_overload(); } }; template struct type_caster> { using Caster = make_caster; using T2 = pointer_and_handle; NB_TYPE_CASTER(T2, Caster::Name) bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept { Caster c; if (!c.from_python(src, flags_for_local_caster(flags), cleanup) || !c.template can_cast()) return false; value.h = src; value.p = c.operator T*(); return true; } }; template struct typed_base_name { static constexpr auto Name = type_caster::Name; }; #if PY_VERSION_HEX < 0x03090000 #define NB_TYPED_NAME_PYTHON38(type, name) \ template <> struct typed_base_name { \ static constexpr auto Name = detail::const_name(name); \ }; NB_TYPED_NAME_PYTHON38(nanobind::tuple, NB_TYPING_TUPLE) NB_TYPED_NAME_PYTHON38(list, NB_TYPING_LIST) NB_TYPED_NAME_PYTHON38(set, NB_TYPING_SET) NB_TYPED_NAME_PYTHON38(dict, NB_TYPING_DICT) NB_TYPED_NAME_PYTHON38(type_object, NB_TYPING_TYPE) #endif // Base case: typed renders as T[Ts...], with some adjustments to // T for older versions of Python (typing.List instead of list, for example) template struct typed_name { static constexpr auto Name = typed_base_name>::Name + const_name("[") + concat(const_name>(const_name("..."), make_caster::Name)...) + const_name("]"); }; // typed or typed renders as T, rather than as // the nonsensical object[T] template struct typed_name { static constexpr auto Name = make_caster::Name; }; template struct typed_name { static constexpr auto Name = make_caster::Name; }; // typed renders as Callable[[Args...], R] template struct typed_name { using Ret = std::conditional_t, void_type, R>; static constexpr auto Name = const_name(NB_TYPING_CALLABLE "[[") + concat(make_caster::Name...) + const_name("], ") + make_caster::Name + const_name("]"); }; // typed renders as Callable[..., R] template struct typed_name { using Ret = std::conditional_t, void_type, R>; static constexpr auto Name = const_name(NB_TYPING_CALLABLE "[..., ") + make_caster::Name + const_name("]"); }; template struct type_caster> { using Caster = make_caster; using Typed = typed; NB_TYPE_CASTER(Typed, (typed_name::Name)) bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept { Caster caster; if (!caster.from_python(src, flags_for_local_caster(flags), cleanup) || !caster.template can_cast()) return false; value = caster.operator cast_t(); return true; } static handle from_cpp(const Value &src, rv_policy policy, cleanup_list *cleanup) noexcept { return Caster::from_cpp(src, policy, cleanup); } }; template struct type_caster && !T::nb_typed>> { public: NB_TYPE_CASTER(T, T::Name) type_caster() : value(nullptr, ::nanobind::detail::steal_t()) { } bool from_python(handle src, uint8_t, cleanup_list *) noexcept { if (!isinstance(src)) return false; if constexpr (std::is_base_of_v) value = borrow(src); else value = src; return true; } static handle from_cpp(T&& src, rv_policy, cleanup_list *) noexcept { if constexpr (std::is_base_of_v) return src.release(); else return src.inc_ref(); } static handle from_cpp(const T &src, rv_policy, cleanup_list *) noexcept { return src.inc_ref(); } }; template NB_INLINE rv_policy infer_policy(rv_policy policy) { if constexpr (is_pointer_v) { if (policy == rv_policy::automatic) policy = rv_policy::take_ownership; else if (policy == rv_policy::automatic_reference) policy = rv_policy::reference; } else if constexpr (std::is_lvalue_reference_v) { if (policy == rv_policy::automatic || policy == rv_policy::automatic_reference) policy = rv_policy::copy; } else { if (policy == rv_policy::automatic || policy == rv_policy::automatic_reference || policy == rv_policy::reference || policy == rv_policy::reference_internal) policy = rv_policy::move; } return policy; } template struct type_hook : std::false_type { }; template struct type_caster_base : type_caster_base_tag { using Type = Type_; static constexpr auto Name = const_name(); template using Cast = precise_cast_t; NB_INLINE bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept { return nb_type_get(&typeid(Type), src.ptr(), flags, cleanup, (void **) &value); } template NB_INLINE static handle from_cpp(T &&value, rv_policy policy, cleanup_list *cleanup) noexcept { Type *ptr; if constexpr (is_pointer_v) ptr = (Type *) value; else ptr = (Type *) &value; policy = infer_policy(policy); const std::type_info *type = &typeid(Type); constexpr bool has_type_hook = !std::is_base_of_v>; if constexpr (has_type_hook) type = type_hook::get(ptr); if constexpr (!std::is_polymorphic_v) { return nb_type_put(type, ptr, policy, cleanup); } else { const std::type_info *type_p = (!has_type_hook && ptr) ? &typeid(*ptr) : nullptr; return nb_type_put_p(type, type_p, ptr, policy, cleanup); } } template bool can_cast() const noexcept { return std::is_pointer_v || (value != nullptr); } operator Type*() { return value; } operator Type&() { raise_next_overload_if_null(value); return *value; } operator Type&&() { raise_next_overload_if_null(value); return (Type &&) *value; } private: Type *value; }; template struct type_caster : type_caster_base { }; template T cast_impl(handle h) { using Caster = detail::make_caster; // A returned reference/pointer would usually refer into the type_caster // object, which will be destroyed before the returned value can be used, // so we prohibit it by default, with two exceptions that we know are safe: // // - If we're casting to a bound object type, the returned pointer points // into storage owned by that object, not the type caster. Note this is // only safe if we don't allow implicit conversions, because the pointer // produced after an implicit conversion points into storage owned by // a temporary object in the cleanup list, and we have to release those // temporaries before we return. // // - If we're casting to const char*, the caster was provided by nanobind, // and we know it will only accept Python 'str' objects, producing // a pointer to storage owned by that object. constexpr bool is_ref = std::is_reference_v || std::is_pointer_v; static_assert( !is_ref || is_base_caster_v || std::is_same_v, "nanobind::cast(): cannot return a reference to a temporary."); Caster caster; bool rv; if constexpr (Convert && !is_ref) { // Release the values in the cleanup list only after we // initialize the return object, since the initialization // might access those temporaries. struct raii_cleanup { cleanup_list list{nullptr}; ~raii_cleanup() { list.release(); } } cleanup; rv = caster.from_python(h.ptr(), ((uint8_t) cast_flags::convert) | ((uint8_t) cast_flags::manual), &cleanup.list); if (!rv) detail::raise_cast_error(); return caster.operator cast_t(); } else { rv = caster.from_python(h.ptr(), (uint8_t) cast_flags::manual, nullptr); if (!rv) detail::raise_cast_error(); return caster.operator cast_t(); } } template bool try_cast_impl(handle h, T &out) noexcept { using Caster = detail::make_caster; // See comments in cast_impl above constexpr bool is_ref = std::is_reference_v || std::is_pointer_v; static_assert( !is_ref || is_base_caster_v || std::is_same_v, "nanobind::try_cast(): cannot return a reference to a temporary."); Caster caster; bool rv; if constexpr (Convert && !is_ref) { cleanup_list cleanup(nullptr); rv = caster.from_python(h.ptr(), ((uint8_t) cast_flags::convert) | ((uint8_t) cast_flags::manual), &cleanup) && caster.template can_cast(); if (rv) { out = caster.operator cast_t(); } cleanup.release(); // 'from_python' is 'noexcept', so this always runs } else { rv = caster.from_python(h.ptr(), (uint8_t) cast_flags::manual, nullptr) && caster.template can_cast(); if (rv) { out = caster.operator cast_t(); } } return rv; } NAMESPACE_END(detail) template NB_INLINE T cast(const detail::api &value, bool convert = true) { if constexpr (std::is_same_v) { (void) value; (void) convert; return; } else { if (convert) return detail::cast_impl(value); else return detail::cast_impl(value); } } template NB_INLINE bool try_cast(const detail::api &value, T &out, bool convert = true) noexcept { if (convert) return detail::try_cast_impl(value, out); else return detail::try_cast_impl(value, out); } template object cast(T &&value, rv_policy policy = rv_policy::automatic_reference) { handle h = detail::make_caster::from_cpp((detail::forward_t) value, policy, nullptr); if (!h.is_valid()) detail::raise_cast_error(); return steal(h); } template object cast(T &&value, rv_policy policy, handle parent) { detail::cleanup_list cleanup(parent.ptr()); handle h = detail::make_caster::from_cpp((detail::forward_t) value, policy, &cleanup); cleanup.release(); if (!h.is_valid()) detail::raise_cast_error(); return steal(h); } template object find(const T &value) noexcept { return steal(detail::make_caster::from_cpp(value, rv_policy::none, nullptr)); } template tuple make_tuple(Args &&...args) { tuple result = steal(PyTuple_New((Py_ssize_t) sizeof...(Args))); size_t nargs = 0; PyObject *o = result.ptr(); (NB_TUPLE_SET_ITEM(o, nargs++, detail::make_caster::from_cpp( (detail::forward_t) args, policy, nullptr) .ptr()), ...); detail::tuple_check(o, sizeof...(Args)); return result; } template arg_v arg::operator=(T &&value) const { return arg_v(*this, cast((detail::forward_t) value)); } template arg_locked_v arg_locked::operator=(T &&value) const { return arg_locked_v(*this, cast((detail::forward_t) value)); } template template detail::accessor& detail::accessor::operator=(T &&value) { object result = cast((detail::forward_t) value); Impl::set(m_base, m_key, result.ptr()); return *this; } template void list::append(T &&value) { object o = nanobind::cast((detail::forward_t) value); if (PyList_Append(m_ptr, o.ptr())) raise_python_error(); } template void list::insert(Py_ssize_t index, T &&value) { object o = nanobind::cast((detail::forward_t) value); if (PyList_Insert(m_ptr, index, o.ptr())) raise_python_error(); } template bool dict::contains(T&& key) const { object o = nanobind::cast((detail::forward_t) key); int rv = PyDict_Contains(m_ptr, o.ptr()); if (rv == -1) raise_python_error(); return rv == 1; } template bool set::contains(T&& key) const { object o = nanobind::cast((detail::forward_t) key); int rv = PySet_Contains(m_ptr, o.ptr()); if (rv == -1) raise_python_error(); return rv == 1; } template void set::add(T&& key) { object o = nanobind::cast((detail::forward_t) key); int rv = PySet_Add(m_ptr, o.ptr()); if (rv == -1) raise_python_error(); } template bool set::discard(T &&value) { object o = nanobind::cast((detail::forward_t) value); int rv = PySet_Discard(m_ptr, o.ptr()); if (rv < 0) raise_python_error(); return rv == 1; } template bool mapping::contains(T&& key) const { object o = nanobind::cast((detail::forward_t) key); int rv = PyMapping_HasKey(m_ptr, o.ptr()); if (rv == -1) raise_python_error(); return rv == 1; } NAMESPACE_END(NB_NAMESPACE) wjakob-nanobind-6c4457b/include/nanobind/nb_class.h000066400000000000000000001012031474760012700222720ustar00rootroot00000000000000/* nanobind/nb_class.h: Functionality for binding C++ classes/structs Copyright (c) 2022 Wenzel Jakob All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ NAMESPACE_BEGIN(NB_NAMESPACE) NAMESPACE_BEGIN(detail) /// Flags about a type that persist throughout its lifetime enum class type_flags : uint32_t { /// Does the type provide a C++ destructor? is_destructible = (1 << 0), /// Does the type provide a C++ copy constructor? is_copy_constructible = (1 << 1), /// Does the type provide a C++ move constructor? is_move_constructible = (1 << 2), /// Is the 'destruct' field of the type_data structure set? has_destruct = (1 << 4), /// Is the 'copy' field of the type_data structure set? has_copy = (1 << 5), /// Is the 'move' field of the type_data structure set? has_move = (1 << 6), /// Internal: does the type maintain a list of implicit conversions? has_implicit_conversions = (1 << 7), /// Is this a python type that extends a bound C++ type? is_python_type = (1 << 8), /// This type does not permit subclassing from Python is_final = (1 << 9), /// Instances of this type support dynamic attribute assignment has_dynamic_attr = (1 << 10), /// The class uses an intrusive reference counting approach intrusive_ptr = (1 << 11), /// Is this a class that inherits from enable_shared_from_this? /// If so, type_data::keep_shared_from_this_alive is also set. has_shared_from_this = (1 << 12), /// Instances of this type can be referenced by 'weakref' is_weak_referenceable = (1 << 13), /// A custom signature override was specified has_signature = (1 << 14), /// The class implements __class_getitem__ similar to typing.Generic is_generic = (1 << 15), /// Does the type implement a custom __new__ operator? has_new = (1 << 16), /// Does the type implement a custom __new__ operator that can take no args /// (except the type object)? has_nullary_new = (1 << 17) // One more bit available without needing a larger reorganization }; /// Flags about a type that are only relevant when it is being created. /// These are currently stored in type_data::flags alongside the type_flags /// for more efficient memory layout, but could move elsewhere if we run /// out of flags. enum class type_init_flags : uint32_t { /// Is the 'supplement' field of the type_init_data structure set? has_supplement = (1 << 19), /// Is the 'doc' field of the type_init_data structure set? has_doc = (1 << 20), /// Is the 'base' field of the type_init_data structure set? has_base = (1 << 21), /// Is the 'base_py' field of the type_init_data structure set? has_base_py = (1 << 22), /// This type provides extra PyType_Slot fields has_type_slots = (1 << 23), all_init_flags = (0x1f << 19) }; // See internals.h struct nb_alias_chain; /// Information about a type that persists throughout its lifetime struct type_data { uint32_t size; uint32_t align : 8; uint32_t flags : 24; const char *name; const std::type_info *type; PyTypeObject *type_py; nb_alias_chain *alias_chain; #if defined(Py_LIMITED_API) PyObject* (*vectorcall)(PyObject *, PyObject * const*, size_t, PyObject *); #endif void *init; // Constructor nb_func void (*destruct)(void *); void (*copy)(void *, const void *); void (*move)(void *, void *) noexcept; union { // Implicit conversions for C++ type bindings struct { const std::type_info **cpp; bool (**py)(PyTypeObject *, PyObject *, cleanup_list *) noexcept; } implicit; // Forward and reverse mappings for enumerations struct { void *fwd; void *rev; } enum_tbl; }; void (*set_self_py)(void *, PyObject *) noexcept; bool (*keep_shared_from_this_alive)(PyObject *) noexcept; #if defined(Py_LIMITED_API) uint32_t dictoffset; uint32_t weaklistoffset; #endif }; /// Information about a type that is only relevant when it is being created struct type_init_data : type_data { PyObject *scope; const std::type_info *base; PyTypeObject *base_py; const char *doc; const PyType_Slot *type_slots; size_t supplement; }; NB_INLINE void type_extra_apply(type_init_data &t, const handle &h) { t.flags |= (uint32_t) type_init_flags::has_base_py; t.base_py = (PyTypeObject *) h.ptr(); } NB_INLINE void type_extra_apply(type_init_data &t, const char *doc) { t.flags |= (uint32_t) type_init_flags::has_doc; t.doc = doc; } NB_INLINE void type_extra_apply(type_init_data &t, type_slots c) { t.flags |= (uint32_t) type_init_flags::has_type_slots; t.type_slots = c.value; } template NB_INLINE void type_extra_apply(type_init_data &t, intrusive_ptr ip) { t.flags |= (uint32_t) type_flags::intrusive_ptr; t.set_self_py = (void (*)(void *, PyObject *) noexcept) ip.set_self_py; } NB_INLINE void type_extra_apply(type_init_data &t, is_final) { t.flags |= (uint32_t) type_flags::is_final; } NB_INLINE void type_extra_apply(type_init_data &t, dynamic_attr) { t.flags |= (uint32_t) type_flags::has_dynamic_attr; } NB_INLINE void type_extra_apply(type_init_data & t, is_weak_referenceable) { t.flags |= (uint32_t) type_flags::is_weak_referenceable; } NB_INLINE void type_extra_apply(type_init_data & t, is_generic) { t.flags |= (uint32_t) type_flags::is_generic; } NB_INLINE void type_extra_apply(type_init_data & t, const sig &s) { t.flags |= (uint32_t) type_flags::has_signature; t.name = s.value; } template NB_INLINE void type_extra_apply(type_init_data &t, supplement) { static_assert(std::is_trivially_default_constructible_v, "The supplement must be a POD (plain old data) type"); static_assert(alignof(T) <= alignof(void *), "The alignment requirement of the supplement is too high."); t.flags |= (uint32_t) type_init_flags::has_supplement | (uint32_t) type_flags::is_final; t.supplement = sizeof(T); } enum class enum_flags : uint32_t { /// Is this an arithmetic enumeration? is_arithmetic = (1 << 1), /// Is the number type underlying the enumeration signed? is_signed = (1 << 2), /// Is the underlying enumeration type Flag? is_flag = (1 << 3) }; struct enum_init_data { const std::type_info *type; PyObject *scope; const char *name; const char *docstr; uint32_t flags; }; NB_INLINE void enum_extra_apply(enum_init_data &e, is_arithmetic) { e.flags |= (uint32_t) enum_flags::is_arithmetic; } NB_INLINE void enum_extra_apply(enum_init_data &e, is_flag) { e.flags |= (uint32_t) enum_flags::is_flag; } NB_INLINE void enum_extra_apply(enum_init_data &e, const char *doc) { e.docstr = doc; } template NB_INLINE void enum_extra_apply(enum_init_data &, T) { static_assert( std::is_void_v, "Invalid enum binding annotation. The implementation of " "enums changed nanobind 2.0.0: only nb::is_arithmetic and " "docstrings can be passed since this change."); } template void wrap_copy(void *dst, const void *src) { new ((T *) dst) T(*(const T *) src); } template void wrap_move(void *dst, void *src) noexcept { new ((T *) dst) T(std::move(*(T *) src)); } template void wrap_destruct(void *value) noexcept { ((T *) value)->~T(); } template typename, typename...> struct extract; template typename Pred> struct extract { using type = T; }; template typename Pred, typename Tv, typename... Ts> struct extract { using type = std::conditional_t< Pred::value, Tv, typename extract::type >; }; template using is_alias = std::is_base_of; template using is_base = std::is_base_of; enum op_id : int; enum op_type : int; struct undefined_t; template struct op_; // The header file include/nanobind/stl/detail/traits.h extends this type trait template struct is_copy_constructible : std::is_copy_constructible { }; template constexpr bool is_copy_constructible_v = is_copy_constructible::value; NAMESPACE_END(detail) // Low level access to nanobind type objects inline bool type_check(handle h) { return detail::nb_type_check(h.ptr()); } inline size_t type_size(handle h) { return detail::nb_type_size(h.ptr()); } inline size_t type_align(handle h) { return detail::nb_type_align(h.ptr()); } inline const std::type_info& type_info(handle h) { return *detail::nb_type_info(h.ptr()); } template inline T &type_supplement(handle h) { return *(T *) detail::nb_type_supplement(h.ptr()); } inline str type_name(handle h) { return steal(detail::nb_type_name(h.ptr())); } // Low level access to nanobind instance objects inline bool inst_check(handle h) { return type_check(h.type()); } inline str inst_name(handle h) { return steal(detail::nb_inst_name(h.ptr())); } inline object inst_alloc(handle h) { return steal(detail::nb_inst_alloc((PyTypeObject *) h.ptr())); } inline object inst_alloc_zero(handle h) { return steal(detail::nb_inst_alloc_zero((PyTypeObject *) h.ptr())); } inline object inst_take_ownership(handle h, void *p) { return steal(detail::nb_inst_take_ownership((PyTypeObject *) h.ptr(), p)); } inline object inst_reference(handle h, void *p, handle parent = handle()) { return steal(detail::nb_inst_reference((PyTypeObject *) h.ptr(), p, parent.ptr())); } inline void inst_zero(handle h) { detail::nb_inst_zero(h.ptr()); } inline void inst_set_state(handle h, bool ready, bool destruct) { detail::nb_inst_set_state(h.ptr(), ready, destruct); } inline std::pair inst_state(handle h) { return detail::nb_inst_state(h.ptr()); } inline void inst_mark_ready(handle h) { inst_set_state(h, true, true); } inline bool inst_ready(handle h) { return inst_state(h).first; } inline void inst_destruct(handle h) { detail::nb_inst_destruct(h.ptr()); } inline void inst_copy(handle dst, handle src) { detail::nb_inst_copy(dst.ptr(), src.ptr()); } inline void inst_move(handle dst, handle src) { detail::nb_inst_move(dst.ptr(), src.ptr()); } inline void inst_replace_copy(handle dst, handle src) { detail::nb_inst_replace_copy(dst.ptr(), src.ptr()); } inline void inst_replace_move(handle dst, handle src) { detail::nb_inst_replace_move(dst.ptr(), src.ptr()); } template T *inst_ptr(handle h) { return (T *) detail::nb_inst_ptr(h.ptr()); } inline void *type_get_slot(handle h, int slot_id) { #if NB_TYPE_GET_SLOT_IMPL return detail::type_get_slot((PyTypeObject *) h.ptr(), slot_id); #else return PyType_GetSlot((PyTypeObject *) h.ptr(), slot_id); #endif } template struct def_visitor { protected: // Ensure def_visitor can only be derived from, not constructed // directly def_visitor() { static_assert(std::is_base_of_v, "def_visitor uses CRTP: def_visitor should be " "a base of T"); } }; template struct init : def_visitor> { template friend class class_; NB_INLINE init() {} private: template NB_INLINE static void execute(Class &cl, const Extra&... extra) { using Type = typename Class::Type; using Alias = typename Class::Alias; cl.def( "__init__", [](pointer_and_handle v, Args... args) { if constexpr (!std::is_same_v && std::is_constructible_v) { if (!detail::nb_inst_python_derived(v.h.ptr())) { new (v.p) Type{ (detail::forward_t) args... }; return; } } new ((void *) v.p) Alias{ (detail::forward_t) args... }; }, extra...); } }; template struct init_implicit : def_visitor> { template friend class class_; NB_INLINE init_implicit() { } private: template NB_INLINE static void execute(Class &cl, const Extra&... extra) { using Type = typename Class::Type; using Alias = typename Class::Alias; cl.def( "__init__", [](pointer_and_handle v, Arg arg) { if constexpr (!std::is_same_v && std::is_constructible_v) { if (!detail::nb_inst_python_derived(v.h.ptr())) { new ((Type *) v.p) Type{ (detail::forward_t) arg }; return; } } new ((Alias *) v.p) Alias{ (detail::forward_t) arg }; }, is_implicit(), extra...); using Caster = detail::make_caster; if constexpr (!detail::is_class_caster_v) { detail::implicitly_convertible( [](PyTypeObject *, PyObject *src, detail::cleanup_list *cleanup) noexcept -> bool { return Caster().from_python( src, detail::cast_flags::convert, cleanup); }, &typeid(Type)); } } }; namespace detail { // This is 'inline' so we can define it in a header and not pay // for it if unused, and also 'noinline' so we don't generate // multiple copies and produce code bloat. NB_NOINLINE inline void wrap_base_new(handle cls, bool do_wrap) { if (PyCFunction_Check(cls.attr("__new__").ptr())) { if (do_wrap) { cpp_function_def( [](handle type) { if (!type_check(type)) detail::raise_cast_error(); return inst_alloc(type); }, scope(cls), name("__new__")); } } else { if (!do_wrap) { // We already defined the wrapper, so this zero-arg overload // would be unreachable. Raise an error rather than hiding it. raise("nanobind: %s must define its zero-argument __new__ " "before any other overloads", type_name(cls).c_str()); } } } // Call policy that ensures __new__ returns an instance of the correct // Python type, even when deriving from the C++ class in Python struct new_returntype_fixup_policy { static inline void precall(PyObject **, size_t, detail::cleanup_list *) {} NB_NOINLINE static inline void postcall(PyObject **args, size_t, PyObject *&ret) { handle type_requested = args[0]; if (ret == nullptr || !type_requested.is_type()) return; // somethign strange about this call; don't meddle handle type_created = Py_TYPE(ret); if (type_created.is(type_requested)) return; // already created the requested type so no fixup needed if (type_check(type_created) && PyType_IsSubtype((PyTypeObject *) type_requested.ptr(), (PyTypeObject *) type_created.ptr()) && type_info(type_created) == type_info(type_requested)) { // The new_ constructor returned an instance of a bound type T. // The user wanted an instance of some python subclass S of T. // Since both wrap the same C++ type, we can satisfy the request // by returning a pyobject of type S that wraps a C++ T*, and // handling the lifetimes by having that pyobject keep the // already-created T pyobject alive. object wrapper = inst_reference(type_requested, inst_ptr(ret), /* parent = */ ret); handle(ret).dec_ref(); ret = wrapper.release().ptr(); } } }; } template > struct new_; template struct new_ : def_visitor> { std::remove_reference_t func; new_(Func &&f) : func((detail::forward_t) f) {} template NB_INLINE void execute(Class &cl, const Extra&... extra) { // If this is the first __new__ overload we're defining, then wrap // nanobind's built-in __new__ so we overload with it instead of // replacing it; this is important for pickle support. // We can't do this if the user-provided __new__ takes no // arguments, because it would make an ambiguous overload set. constexpr size_t num_defaults = ((std::is_same_v || std::is_same_v) + ... + 0); constexpr size_t num_varargs = ((std::is_same_v, args> || std::is_same_v, kwargs>) + ... + 0); detail::wrap_base_new(cl, sizeof...(Args) > num_defaults + num_varargs); auto wrapper = [func_ = (detail::forward_t) func](handle, Args... args) { return func_((detail::forward_t) args...); }; auto policy = call_policy(); if constexpr ((std::is_base_of_v || ...)) { // If any argument annotations are specified, add another for the // extra class argument that we don't forward to Func, so visible // arg() annotations stay aligned with visible function arguments. cl.def_static("__new__", std::move(wrapper), arg("cls"), extra..., policy); } else { cl.def_static("__new__", std::move(wrapper), extra..., policy); } cl.def("__init__", [](handle, Args...) {}, extra...); } }; template new_(Func&& f) -> new_; template struct for_setter { T value; for_setter(const T &value) : value(value) { } }; template struct for_getter { T value; for_getter(const T &value) : value(value) { } }; template for_getter(T) -> for_getter>; template for_setter(T) -> for_setter>; namespace detail { template auto filter_getter(const T &v) { return v; } template auto filter_getter(const for_getter &v) { return v.value; } template std::nullptr_t filter_getter(const for_setter &) { return nullptr; } template auto filter_setter(const T &v) { return v; } template auto filter_setter(const for_setter &v) { return v.value; } template std::nullptr_t filter_setter(const for_getter &) { return nullptr; } } template class class_ : public object { public: NB_OBJECT_DEFAULT(class_, object, "type", PyType_Check) using Type = T; using Base = typename detail::extract::type; using Alias = typename detail::extract::type; static_assert(sizeof(Alias) < (((uint64_t) 1) << 32), "Instance size is too big!"); static_assert(alignof(Alias) < (1 << 8), "Instance alignment is too big!"); static_assert( sizeof...(Ts) == !std::is_same_v + !std::is_same_v, "nanobind::class_<> was invoked with extra arguments that could not be handled"); static_assert( detail::is_base_caster_v>, "You attempted to bind a type that is already intercepted by a type " "caster. Having both at the same time is not allowed. Are you perhaps " "binding an STL type, while at the same time including a matching " "type caster from ? Or did you perhaps forget to " "declare NB_MAKE_OPAQUE(..) to specifically disable the type caster " "catch-all for a specific type? Please review the documentation " "to learn about the difference between bindings and type casters."); template NB_INLINE class_(handle scope, const char *name, const Extra &... extra) { detail::type_init_data d; d.flags = 0; d.align = (uint8_t) alignof(Alias); d.size = (uint32_t) sizeof(Alias); d.name = name; d.scope = scope.ptr(); d.type = &typeid(T); if constexpr (!std::is_same_v) { d.base = &typeid(Base); d.flags |= (uint32_t) detail::type_init_flags::has_base; } if constexpr (detail::is_copy_constructible_v) { d.flags |= (uint32_t) detail::type_flags::is_copy_constructible; if constexpr (!std::is_trivially_copy_constructible_v) { d.flags |= (uint32_t) detail::type_flags::has_copy; d.copy = detail::wrap_copy; } } if constexpr (std::is_move_constructible::value) { d.flags |= (uint32_t) detail::type_flags::is_move_constructible; if constexpr (!std::is_trivially_move_constructible_v) { d.flags |= (uint32_t) detail::type_flags::has_move; d.move = detail::wrap_move; } } if constexpr (std::is_destructible_v) { d.flags |= (uint32_t) detail::type_flags::is_destructible; if constexpr (!std::is_trivially_destructible_v) { d.flags |= (uint32_t) detail::type_flags::has_destruct; d.destruct = detail::wrap_destruct; } } if constexpr (detail::has_shared_from_this_v) { d.flags |= (uint32_t) detail::type_flags::has_shared_from_this; d.keep_shared_from_this_alive = [](PyObject *self) noexcept { // weak_from_this().lock() is equivalent to shared_from_this(), // except that it returns an empty shared_ptr instead of // throwing an exception if there is no active shared_ptr // for this object. (Added in C++17.) if (auto sp = inst_ptr(self)->weak_from_this().lock()) { detail::keep_alive(self, new auto(std::move(sp)), [](void *p) noexcept { delete (decltype(sp) *) p; }); return true; } return false; }; } (detail::type_extra_apply(d, extra), ...); m_ptr = detail::nb_type_new(&d); } template NB_INLINE class_ &def(const char *name_, Func &&f, const Extra &... extra) { cpp_function_def((detail::forward_t) f, scope(*this), name(name_), is_method(), extra...); return *this; } template NB_INLINE class_ &def(def_visitor &&arg, const Extra &... extra) { static_cast(arg).execute(*this, extra...); return *this; } template NB_INLINE class_ &def_static(const char *name_, Func &&f, const Extra &... extra) { static_assert( !std::is_member_function_pointer_v, "def_static(...) called with a non-static member function pointer"); cpp_function_def((detail::forward_t) f, scope(*this), name(name_), extra...); return *this; } template NB_INLINE class_ &def_prop_rw(const char *name_, Getter &&getter, Setter &&setter, const Extra &...extra) { object get_p, set_p; if constexpr (!std::is_same_v) get_p = cpp_function((detail::forward_t) getter, is_method(), is_getter(), rv_policy::reference_internal, detail::filter_getter(extra)...); if constexpr (!std::is_same_v) set_p = cpp_function((detail::forward_t) setter, is_method(), detail::filter_setter(extra)...); detail::property_install(m_ptr, name_, get_p.ptr(), set_p.ptr()); return *this; } template NB_INLINE class_ &def_prop_rw_static(const char *name_, Getter &&getter, Setter &&setter, const Extra &...extra) { object get_p, set_p; if constexpr (!std::is_same_v) get_p = cpp_function((detail::forward_t) getter, is_getter(), rv_policy::reference, detail::filter_getter(extra)...); if constexpr (!std::is_same_v) set_p = cpp_function((detail::forward_t) setter, detail::filter_setter(extra)...); detail::property_install_static(m_ptr, name_, get_p.ptr(), set_p.ptr()); return *this; } template NB_INLINE class_ &def_prop_ro(const char *name_, Getter &&getter, const Extra &...extra) { return def_prop_rw(name_, getter, nullptr, extra...); } template NB_INLINE class_ &def_prop_ro_static(const char *name_, Getter &&getter, const Extra &...extra) { return def_prop_rw_static(name_, getter, nullptr, extra...); } template NB_INLINE class_ &def_rw(const char *name, D C::*p, const Extra &...extra) { // Unions never satisfy is_base_of, thus the is_same alternative static_assert(std::is_base_of_v || std::is_same_v, "def_rw() requires a (base) class member!"); using Q = std::conditional_t>, const D &, D &&>; def_prop_rw(name, [p](const T &c) -> const D & { return c.*p; }, [p](T &c, Q value) { c.*p = (Q) value; }, extra...); return *this; } template NB_INLINE class_ &def_rw_static(const char *name, D *p, const Extra &...extra) { using Q = std::conditional_t>, const D &, D &&>; def_prop_rw_static(name, [p](handle) -> const D & { return *p; }, [p](handle, Q value) { *p = (Q) value; }, extra...); return *this; } template NB_INLINE class_ &def_ro(const char *name, D C::*p, const Extra &...extra) { // Unions never satisfy is_base_of, thus the is_same alternative static_assert(std::is_base_of_v || std::is_same_v, "def_ro() requires a (base) class member!"); def_prop_ro(name, [p](const T &c) -> const D & { return c.*p; }, extra...); return *this; } template NB_INLINE class_ &def_ro_static(const char *name, D *p, const Extra &...extra) { def_prop_ro_static(name, [p](handle) -> const D & { return *p; }, extra...); return *this; } template class_ &def(const detail::op_ &op, const Extra&... extra) { op.execute(*this, extra...); return *this; } template class_ & def_cast(const detail::op_ &op, const Extra&... extra) { op.execute_cast(*this, extra...); return *this; } }; template class enum_ : public object { public: static_assert(std::is_enum_v, "nanobind::enum_<> requires an enumeration type!"); using Base = class_; using Underlying = std::underlying_type_t; template NB_INLINE enum_(handle scope, const char *name, const Extra &... extra) { detail::enum_init_data ed { }; ed.type = &typeid(T); ed.scope = scope.ptr(); ed.name = name; ed.flags = std::is_signed_v ? (uint32_t) detail::enum_flags::is_signed : 0; (detail::enum_extra_apply(ed, extra), ...); m_ptr = detail::enum_create(&ed); } NB_INLINE enum_ &value(const char *name, T value, const char *doc = nullptr) { detail::enum_append(m_ptr, name, (int64_t) value, doc); return *this; } NB_INLINE enum_ &export_values() { detail::enum_export(m_ptr); return *this; } template NB_INLINE enum_ &def(const char *name_, Func &&f, const Extra &... extra) { cpp_function_def((detail::forward_t) f, scope(*this), name(name_), is_method(), extra...); return *this; } template NB_INLINE enum_ &def_static(const char *name_, Func &&f, const Extra &... extra) { static_assert( !std::is_member_function_pointer_v, "def_static(...) called with a non-static member function pointer"); cpp_function_def((detail::forward_t) f, scope(*this), name(name_), extra...); return *this; } template NB_INLINE enum_ &def_prop_rw(const char *name_, Getter &&getter, Setter &&setter, const Extra &...extra) { object get_p, set_p; if constexpr (!std::is_same_v) get_p = cpp_function((detail::forward_t) getter, is_method(), is_getter(), rv_policy::reference_internal, detail::filter_getter(extra)...); if constexpr (!std::is_same_v) set_p = cpp_function((detail::forward_t) setter, is_method(), detail::filter_setter(extra)...); detail::property_install(m_ptr, name_, get_p.ptr(), set_p.ptr()); return *this; } template NB_INLINE enum_ &def_prop_ro(const char *name_, Getter &&getter, const Extra &...extra) { return def_prop_rw(name_, getter, nullptr, extra...); } }; template void implicitly_convertible() { using Caster = detail::make_caster; static_assert(!std::is_enum_v, "implicitly_convertible(): 'Target' cannot be an enumeration."); if constexpr (detail::is_base_caster_v) { detail::implicitly_convertible(&typeid(Source), &typeid(Target)); } else { detail::implicitly_convertible( [](PyTypeObject *, PyObject *src, detail::cleanup_list *cleanup) noexcept -> bool { return Caster().from_python(src, detail::cast_flags::convert, cleanup); }, &typeid(Target)); } } NAMESPACE_END(NB_NAMESPACE) wjakob-nanobind-6c4457b/include/nanobind/nb_defs.h000066400000000000000000000160441474760012700221160ustar00rootroot00000000000000/* nanobind/nb_defs.h: Preprocessor definitions used by the project Copyright (c) 2022 Wenzel Jakob All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ #pragma once #define NB_STRINGIFY(x) #x #define NB_TOSTRING(x) NB_STRINGIFY(x) #define NB_CONCAT(first, second) first##second #define NB_NEXT_OVERLOAD ((PyObject *) 1) // special failure return code #if !defined(NAMESPACE_BEGIN) # define NAMESPACE_BEGIN(name) namespace name { #endif #if !defined(NAMESPACE_END) # define NAMESPACE_END(name) } #endif #if defined(_WIN32) # define NB_EXPORT __declspec(dllexport) # define NB_IMPORT __declspec(dllimport) # define NB_INLINE __forceinline # define NB_NOINLINE __declspec(noinline) # define NB_INLINE_LAMBDA #else # define NB_EXPORT __attribute__ ((visibility("default"))) # define NB_IMPORT NB_EXPORT # define NB_INLINE inline __attribute__((always_inline)) # define NB_NOINLINE __attribute__((noinline)) # if defined(__clang__) # define NB_INLINE_LAMBDA __attribute__((always_inline)) # else # define NB_INLINE_LAMBDA # endif #endif #if defined(__GNUC__) && !defined(_WIN32) # define NB_NAMESPACE nanobind __attribute__((visibility("hidden"))) #else # define NB_NAMESPACE nanobind #endif #if defined(__GNUC__) # define NB_UNLIKELY(x) __builtin_expect(bool(x), 0) # define NB_LIKELY(x) __builtin_expect(bool(x), 1) #else # define NB_LIKELY(x) x # define NB_UNLIKELY(x) x #endif #if defined(NB_SHARED) # if defined(NB_BUILD) # define NB_CORE NB_EXPORT # else # define NB_CORE NB_IMPORT # endif #else # define NB_CORE #endif #if !defined(NB_SHARED) && defined(__GNUC__) && !defined(_WIN32) # define NB_EXPORT_SHARED __attribute__ ((visibility("hidden"))) #else # define NB_EXPORT_SHARED #endif #if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L # define NB_HAS_U8STRING #endif #if defined(Py_TPFLAGS_HAVE_VECTORCALL) # define NB_VECTORCALL PyObject_Vectorcall # define NB_HAVE_VECTORCALL Py_TPFLAGS_HAVE_VECTORCALL #elif defined(_Py_TPFLAGS_HAVE_VECTORCALL) # define NB_VECTORCALL _PyObject_Vectorcall # define NB_HAVE_VECTORCALL _Py_TPFLAGS_HAVE_VECTORCALL #else # define NB_HAVE_VECTORCALL (1UL << 11) #endif #if defined(PY_VECTORCALL_ARGUMENTS_OFFSET) # define NB_VECTORCALL_ARGUMENTS_OFFSET PY_VECTORCALL_ARGUMENTS_OFFSET # define NB_VECTORCALL_NARGS PyVectorcall_NARGS #else # define NB_VECTORCALL_ARGUMENTS_OFFSET ((size_t) 1 << (8 * sizeof(size_t) - 1)) # define NB_VECTORCALL_NARGS(n) ((n) & ~NB_VECTORCALL_ARGUMENTS_OFFSET) #endif #if PY_VERSION_HEX < 0x03090000 # define NB_TYPING_ABC "typing." # define NB_TYPING_TUPLE "typing.Tuple" # define NB_TYPING_LIST "typing.List" # define NB_TYPING_DICT "typing.Dict" # define NB_TYPING_SET "typing.Set" # define NB_TYPING_TYPE "typing.Type" #else # define NB_TYPING_ABC "collections.abc." # define NB_TYPING_TUPLE "tuple" # define NB_TYPING_LIST "list" # define NB_TYPING_DICT "dict" # define NB_TYPING_SET "set" # define NB_TYPING_TYPE "type" #endif #define NB_TYPING_SEQUENCE NB_TYPING_ABC "Sequence" #define NB_TYPING_MAPPING NB_TYPING_ABC "Mapping" #define NB_TYPING_CALLABLE NB_TYPING_ABC "Callable" #define NB_TYPING_ITERATOR NB_TYPING_ABC "Iterator" #define NB_TYPING_ITERABLE NB_TYPING_ABC "Iterable" #if PY_VERSION_HEX < 0x03090000 # define NB_TYPING_ABSTRACT_SET "typing.AbstractSet" #else # define NB_TYPING_ABSTRACT_SET "collections.abc.Set" #endif #if defined(Py_LIMITED_API) # if PY_VERSION_HEX < 0x030C0000 || defined(PYPY_VERSION) # error "nanobind can target Python's limited API, but this requires CPython >= 3.12" # endif # define NB_TUPLE_GET_SIZE PyTuple_Size # define NB_TUPLE_GET_ITEM PyTuple_GetItem # define NB_TUPLE_SET_ITEM PyTuple_SetItem # define NB_LIST_GET_SIZE PyList_Size # define NB_LIST_GET_ITEM PyList_GetItem # define NB_LIST_SET_ITEM PyList_SetItem # define NB_DICT_GET_SIZE PyDict_Size # define NB_SET_GET_SIZE PySet_Size #else # define NB_TUPLE_GET_SIZE PyTuple_GET_SIZE # define NB_TUPLE_GET_ITEM PyTuple_GET_ITEM # define NB_TUPLE_SET_ITEM PyTuple_SET_ITEM # define NB_LIST_GET_SIZE PyList_GET_SIZE # define NB_LIST_GET_ITEM PyList_GET_ITEM # define NB_LIST_SET_ITEM PyList_SET_ITEM # define NB_DICT_GET_SIZE PyDict_GET_SIZE # define NB_SET_GET_SIZE PySet_GET_SIZE #endif #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x07030a00 # error "nanobind requires a newer PyPy version (>= 7.3.10)" #endif #if defined(NB_FREE_THREADED) && !defined(Py_GIL_DISABLED) # error "Free-threaded extensions require a free-threaded version of Python" #endif #if defined(NB_DOMAIN) # define NB_DOMAIN_STR NB_TOSTRING(NB_DOMAIN) #else # define NB_DOMAIN_STR nullptr #endif #if !defined(PYPY_VERSION) # if PY_VERSION_HEX < 0x030A0000 # define NB_TYPE_GET_SLOT_IMPL 1 // Custom implementation of nb::type_get_slot # else # define NB_TYPE_GET_SLOT_IMPL 0 # endif # if PY_VERSION_HEX < 0x030C0000 # define NB_TYPE_FROM_METACLASS_IMPL 1 // Custom implementation of PyType_FromMetaclass # else # define NB_TYPE_FROM_METACLASS_IMPL 0 # endif #else # define NB_TYPE_FROM_METACLASS_IMPL 1 # define NB_TYPE_GET_SLOT_IMPL 1 #endif #define NB_NONCOPYABLE(X) \ X(const X &) = delete; \ X &operator=(const X &) = delete; #define NB_MODULE_IMPL(name) \ extern "C" [[maybe_unused]] NB_EXPORT PyObject *PyInit_##name(); \ extern "C" NB_EXPORT PyObject *PyInit_##name() #define NB_MODULE(name, variable) \ static PyModuleDef NB_CONCAT(nanobind_module_def_, name); \ [[maybe_unused]] static void NB_CONCAT(nanobind_init_, \ name)(::nanobind::module_ &); \ NB_MODULE_IMPL(name) { \ nanobind::detail::init(NB_DOMAIN_STR); \ nanobind::module_ m = \ nanobind::steal(nanobind::detail::module_new( \ NB_TOSTRING(name), &NB_CONCAT(nanobind_module_def_, name))); \ try { \ NB_CONCAT(nanobind_init_, name)(m); \ return m.release().ptr(); \ } catch (const std::exception &e) { \ PyErr_SetString(PyExc_ImportError, e.what()); \ return nullptr; \ } \ } \ void NB_CONCAT(nanobind_init_, name)(::nanobind::module_ & (variable)) wjakob-nanobind-6c4457b/include/nanobind/nb_descr.h000066400000000000000000000132201474760012700222660ustar00rootroot00000000000000/* nanobind/nb_descr.h: Constexpr string class for function signatures Copyright (c) 2022 Wenzel Jakob All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ NAMESPACE_BEGIN(NB_NAMESPACE) NAMESPACE_BEGIN(detail) /// Helper type for concatenating type signatures at compile time template struct descr { char text[N + 1]{'\0'}; constexpr descr() = default; constexpr descr(char const (&s)[N+1]) : descr(s, std::make_index_sequence()) { } template constexpr descr(char const (&s)[N+1], std::index_sequence) : text{s[Is]..., '\0'} { } template constexpr descr(char c, Cs... cs) : text{c, static_cast(cs)..., '\0'} { } constexpr size_t type_count() const { return sizeof...(Ts); } constexpr size_t size() const { return N; } NB_INLINE void put_types(const std::type_info **out) const { size_t ctr = 0; ((out[ctr++] = &typeid(Ts)), ...); out[ctr++] = nullptr; } }; template constexpr descr plus_impl(const descr &a, const descr &b, std::index_sequence, std::index_sequence) { return {a.text[Is1]..., b.text[Is2]...}; } template constexpr descr operator+(const descr &a, const descr &b) { return plus_impl(a, b, std::make_index_sequence(), std::make_index_sequence()); } template constexpr descr const_name(char const(&text)[N]) { return descr(text); } constexpr descr<0> const_name(char const(&)[1]) { return {}; } template struct int_to_str : int_to_str {}; template struct int_to_str<0, Digits...> { static constexpr auto digits = descr(('0' + Digits)...); }; constexpr auto const_name(char c) { return descr<1>(c); } // Ternary description (like std::conditional) template constexpr auto const_name(char const(&text1)[N1], char const(&text2)[N2]) { (void) text1; (void) text2; if constexpr(B) return const_name(text1); else return const_name(text2); } template constexpr auto const_name(const T1 &d1, const T2 &d2) { (void) d1; (void) d2; if constexpr (B) return d1; else return d2; } // Use a different name based on whether the parameter is used as input or output template constexpr auto io_name(char const (&text1)[N1], char const (&text2)[N2]) { return const_name('@') + const_name(text1) + const_name('@') + const_name(text2) + const_name('@'); } #if PY_VERSION_HEX < 0x030A0000 template constexpr auto optional_name(const T &v) { return const_name("typing.Optional[") + v + const_name("]"); } template constexpr auto union_name(const Ts&... vs) { return const_name("typing.Union[") + concat(vs...) + const_name("]"); } #else template constexpr auto optional_name(const T &v) { return v + const_name(" | None"); } template constexpr auto union_name(const T &v) { return v; } template constexpr auto union_name(const T1 &v1, const T2 &v2, const Ts &...vs) { return v1 + const_name(" | ") + union_name(v2, vs...); } #endif template auto constexpr const_name() -> std::remove_cv_t::digits)> { return int_to_str::digits; } template constexpr descr<1, Type> const_name() { return {'%'}; } constexpr descr<0> concat() { return {}; } constexpr descr<0> concat_maybe() { return {}; } template constexpr descr concat(const descr &descr) { return descr; } template constexpr descr concat_maybe(const descr &descr) { return descr; } template constexpr auto concat(const descr &d, const Args &...args) -> decltype(std::declval>() + concat(args...)) { return d + const_name(", ") + concat(args...); } template constexpr auto concat_maybe(const descr<0> &, const descr<0> &, const Args &...args) -> decltype(concat_maybe(args...)) { return concat_maybe(args...); } template constexpr auto concat_maybe(const descr<0> &, const descr &arg, const Args &...args) -> decltype(concat_maybe(arg, args...)) { return concat_maybe(arg, args...); } template constexpr auto concat_maybe(const descr &arg, const descr<0> &, const Args &...args) -> decltype(concat_maybe(arg, args...)) { return concat_maybe(arg, args...); } template = 0> constexpr auto concat_maybe(const descr &arg0, const descr &arg1, const Args &...args) -> decltype(concat(arg0, concat_maybe(arg1, args...))) { return concat(arg0, concat_maybe(arg1, args...)); } template constexpr descr type_descr(const descr &descr) { return const_name("{") + descr + const_name("}"); } NAMESPACE_END(detail) NAMESPACE_END(NB_NAMESPACE) wjakob-nanobind-6c4457b/include/nanobind/nb_enums.h000066400000000000000000000012321474760012700223150ustar00rootroot00000000000000/* nanobind/nb_enums.h: enumerations used in nanobind (just rv_policy atm.) Copyright (c) 2022 Wenzel Jakob All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ NAMESPACE_BEGIN(NB_NAMESPACE) // Approach used to cast a previously unknown C++ instance into a Python object enum class rv_policy { automatic, automatic_reference, take_ownership, copy, move, reference, reference_internal, none /* Note to self: nb_func.h assumes that this value fits into 3 bits, hence no further policies can be added. */ }; NAMESPACE_END(NB_NAMESPACE) wjakob-nanobind-6c4457b/include/nanobind/nb_error.h000066400000000000000000000121271474760012700223240ustar00rootroot00000000000000/* nanobind/nb_error.h: Python exception handling, binding of exceptions Copyright (c) 2022 Wenzel Jakob All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ NAMESPACE_BEGIN(NB_NAMESPACE) /// RAII wrapper that temporarily clears any Python error state #if PY_VERSION_HEX >= 0x030C0000 struct error_scope { error_scope() { value = PyErr_GetRaisedException(); } ~error_scope() { PyErr_SetRaisedException(value); } private: PyObject *value; }; #else struct error_scope { error_scope() { PyErr_Fetch(&type, &value, &trace); } ~error_scope() { PyErr_Restore(type, value, trace); } private: PyObject *type, *value, *trace; }; #endif /// Wraps a Python error state as a C++ exception class NB_EXPORT python_error : public std::exception { public: NB_EXPORT_SHARED python_error(); NB_EXPORT_SHARED python_error(const python_error &); NB_EXPORT_SHARED python_error(python_error &&) noexcept; NB_EXPORT_SHARED ~python_error() override; bool matches(handle exc) const noexcept { #if PY_VERSION_HEX < 0x030C0000 return PyErr_GivenExceptionMatches(m_type, exc.ptr()) != 0; #else return PyErr_GivenExceptionMatches(m_value, exc.ptr()) != 0; #endif } /// Move the error back into the Python domain. This may only be called /// once, and you should not reraise the exception in C++ afterward. NB_EXPORT_SHARED void restore() noexcept; /// Pass the error to Python's `sys.unraisablehook`, which prints /// a traceback to `sys.stderr` by default but may be overridden. /// The *context* should be some object whose repr() helps clarify where /// the error occurred. Like `.restore()`, this consumes the error and /// you should not reraise the exception in C++ afterward. void discard_as_unraisable(handle context) noexcept { restore(); PyErr_WriteUnraisable(context.ptr()); } void discard_as_unraisable(const char *context) noexcept { object context_s = steal(PyUnicode_FromString(context)); discard_as_unraisable(context_s); } handle value() const { return m_value; } #if PY_VERSION_HEX < 0x030C0000 handle type() const { return m_type; } object traceback() const { return borrow(m_traceback); } #else handle type() const { return value().type(); } object traceback() const { return steal(PyException_GetTraceback(m_value)); } #endif [[deprecated]] object trace() const { return traceback(); } NB_EXPORT_SHARED const char *what() const noexcept override; private: #if PY_VERSION_HEX < 0x030C0000 mutable PyObject *m_type = nullptr; mutable PyObject *m_value = nullptr; mutable PyObject *m_traceback = nullptr; #else mutable PyObject *m_value = nullptr; #endif mutable char *m_what = nullptr; }; /// Thrown by nanobind::cast when casting fails using cast_error = std::bad_cast; enum class exception_type { runtime_error, stop_iteration, index_error, key_error, value_error, type_error, buffer_error, import_error, attribute_error, next_overload }; // Base interface used to expose common Python exceptions in C++ class NB_EXPORT builtin_exception : public std::runtime_error { public: NB_EXPORT_SHARED builtin_exception(exception_type type, const char *what); NB_EXPORT_SHARED builtin_exception(builtin_exception &&) = default; NB_EXPORT_SHARED builtin_exception(const builtin_exception &) = default; NB_EXPORT_SHARED ~builtin_exception(); NB_EXPORT_SHARED exception_type type() const { return m_type; } private: exception_type m_type; }; #define NB_EXCEPTION(name) \ inline builtin_exception name(const char *what = nullptr) { \ return builtin_exception(exception_type::name, what); \ } NB_EXCEPTION(stop_iteration) NB_EXCEPTION(index_error) NB_EXCEPTION(key_error) NB_EXCEPTION(value_error) NB_EXCEPTION(type_error) NB_EXCEPTION(buffer_error) NB_EXCEPTION(import_error) NB_EXCEPTION(attribute_error) NB_EXCEPTION(next_overload) #undef NB_EXCEPTION inline void register_exception_translator(detail::exception_translator t, void *payload = nullptr) { detail::register_exception_translator(t, payload); } template class exception : public object { NB_OBJECT_DEFAULT(exception, object, "Exception", PyExceptionClass_Check) exception(handle scope, const char *name, handle base = PyExc_Exception) : object(detail::exception_new(scope.ptr(), name, base.ptr()), detail::steal_t()) { detail::register_exception_translator( [](const std::exception_ptr &p, void *payload) { try { std::rethrow_exception(p); } catch (T &e) { PyErr_SetString((PyObject *) payload, e.what()); } }, m_ptr); } }; NB_CORE void chain_error(handle type, const char *fmt, ...) noexcept; [[noreturn]] NB_CORE void raise_from(python_error &e, handle type, const char *fmt, ...); NAMESPACE_END(NB_NAMESPACE) wjakob-nanobind-6c4457b/include/nanobind/nb_func.h000066400000000000000000000423521474760012700221310ustar00rootroot00000000000000/* nanobind/nb_func.h: Functionality for binding C++ functions/methods Copyright (c) 2022 Wenzel Jakob All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ NAMESPACE_BEGIN(NB_NAMESPACE) NAMESPACE_BEGIN(detail) template bool from_python_remember_conv(Caster &c, PyObject **args, uint8_t *args_flags, cleanup_list *cleanup, size_t index) { size_t size_before = cleanup->size(); if (!c.from_python(args[index], args_flags[index], cleanup)) return false; // If an implicit conversion took place, update the 'args' array so that // any keep_alive annotation or postcall hook can be aware of this change size_t size_after = cleanup->size(); if (size_after != size_before) args[index] = (*cleanup)[size_after - 1]; return true; } // Return the number of nb::arg and nb::arg_v types in the first I types Ts. // Invoke with std::make_index_sequence() to provide // an index pack 'Is' that parallels the types pack Ts. template constexpr size_t count_args_before_index(std::index_sequence) { static_assert(sizeof...(Is) == sizeof...(Ts)); return ((Is < I && std::is_base_of_v) + ... + 0); } #if defined(NB_FREE_THREADED) struct ft_args_collector { PyObject **args; handle h1; handle h2; size_t index = 0; NB_INLINE explicit ft_args_collector(PyObject **a) : args(a) {} NB_INLINE void apply(arg_locked *) { if (h1.ptr() == nullptr) h1 = args[index]; h2 = args[index]; ++index; } NB_INLINE void apply(arg *) { ++index; } NB_INLINE void apply(...) {} }; struct ft_args_guard { NB_INLINE void lock(const ft_args_collector& info) { PyCriticalSection2_Begin(&cs, info.h1.ptr(), info.h2.ptr()); } ~ft_args_guard() { PyCriticalSection2_End(&cs); } PyCriticalSection2 cs; }; #endif struct no_guard {}; template NB_INLINE PyObject *func_create(Func &&func, Return (*)(Args...), std::index_sequence is, const Extra &...extra) { using Info = func_extra_info; if constexpr (CheckGuard && !std::is_same_v) { return func_create( [func = (forward_t) func](Args... args) NB_INLINE_LAMBDA { typename Info::call_guard::type g; (void) g; return func((forward_t) args...); }, (Return(*)(Args...)) nullptr, is, extra...); } (void) is; // Detect locations of nb::args / nb::kwargs (if they exist). // Find the first and last occurrence of each; we'll later make sure these // match, in order to guarantee there's only one instance. static constexpr size_t args_pos_1 = index_1_v, args>...>, args_pos_n = index_n_v, args>...>, kwargs_pos_1 = index_1_v, kwargs>...>, kwargs_pos_n = index_n_v, kwargs>...>, nargs = sizeof...(Args); // Determine the number of nb::arg/nb::arg_v annotations constexpr size_t nargs_provided = (std::is_base_of_v + ... + 0); constexpr bool is_method_det = (std::is_same_v + ... + 0) != 0; constexpr bool is_getter_det = (std::is_same_v + ... + 0) != 0; constexpr bool has_arg_annotations = nargs_provided > 0 && !is_getter_det; // Determine the number of potentially-locked function arguments constexpr bool lock_self_det = (std::is_same_v + ... + 0) != 0; static_assert(Info::nargs_locked <= 2, "At most two function arguments can be locked"); static_assert(!(lock_self_det && !is_method_det), "The nb::lock_self() annotation only applies to methods"); // Detect location of nb::kw_only annotation, if supplied. As with args/kwargs // we find the first and last location and later verify they match each other. // Note this is an index in Extra... while args/kwargs_pos_* are indices in // Args... . constexpr size_t kwonly_pos_1 = index_1_v...>, kwonly_pos_n = index_n_v...>; // Arguments after nb::args are implicitly keyword-only even if there is no // nb::kw_only annotation constexpr bool explicit_kw_only = kwonly_pos_1 != sizeof...(Extra); constexpr bool implicit_kw_only = args_pos_1 + 1 < kwargs_pos_1; // A few compile-time consistency checks static_assert(args_pos_1 == args_pos_n && kwargs_pos_1 == kwargs_pos_n, "Repeated use of nb::kwargs or nb::args in the function signature!"); static_assert(!has_arg_annotations || nargs_provided + is_method_det == nargs, "The number of nb::arg annotations must match the argument count!"); static_assert(kwargs_pos_1 == nargs || kwargs_pos_1 + 1 == nargs, "nb::kwargs must be the last element of the function signature!"); static_assert(args_pos_1 == nargs || args_pos_1 < kwargs_pos_1, "nb::args must precede nb::kwargs if both are present!"); static_assert(has_arg_annotations || (!implicit_kw_only && !explicit_kw_only), "Keyword-only arguments must have names!"); // Find the index in Args... of the first keyword-only parameter. Since // the 'self' parameter doesn't get a nb::arg annotation, we must adjust // by 1 for methods. Note that nargs_before_kw_only is only used if // a kw_only annotation exists (i.e., if explicit_kw_only is true); // the conditional is just to save the compiler some effort otherwise. constexpr size_t nargs_before_kw_only = explicit_kw_only ? is_method_det + count_args_before_index( std::make_index_sequence()) : nargs; (void) kwonly_pos_n; if constexpr (explicit_kw_only) { static_assert(kwonly_pos_1 == kwonly_pos_n, "Repeated use of nb::kw_only annotation!"); // If both kw_only and *args are specified, kw_only must be // immediately after the nb::arg for *args. static_assert(args_pos_1 == nargs || nargs_before_kw_only == args_pos_1 + 1, "Arguments after nb::args are implicitly keyword-only; any " "nb::kw_only() annotation must be positioned to reflect that!"); // If both kw_only and **kwargs are specified, kw_only must be // before the nb::arg for **kwargs. static_assert(nargs_before_kw_only < kwargs_pos_1, "Variadic nb::kwargs are implicitly keyword-only; any " "nb::kw_only() annotation must be positioned to reflect that!"); } // Collect function signature information for the docstring using cast_out = make_caster< std::conditional_t, void_type, Return>>; // Compile-time function signature static constexpr auto descr = const_name("(") + concat(type_descr( make_caster>>::Name)...) + const_name(") -> ") + cast_out::Name; // std::type_info for all function arguments const std::type_info* descr_types[descr.type_count() + 1]; descr.put_types(descr_types); // Auxiliary data structure to capture the provided function/closure struct capture { std::remove_reference_t func; }; // The following temporary record will describe the function in detail func_data_prelim f; f.flags = (args_pos_1 < nargs ? (uint32_t) func_flags::has_var_args : 0) | (kwargs_pos_1 < nargs ? (uint32_t) func_flags::has_var_kwargs : 0) | (ReturnRef ? (uint32_t) func_flags::return_ref : 0) | (has_arg_annotations ? (uint32_t) func_flags::has_args : 0); /* Store captured function inside 'func_data_prelim' if there is space. Issues with aliasing are resolved via separate compilation of libnanobind. */ if constexpr (sizeof(capture) <= sizeof(f.capture)) { capture *cap = (capture *) f.capture; new (cap) capture{ (forward_t) func }; if constexpr (!std::is_trivially_destructible_v) { f.flags |= (uint32_t) func_flags::has_free; f.free_capture = [](void *p) { ((capture *) p)->~capture(); }; } } else { void **cap = (void **) f.capture; cap[0] = new capture{ (forward_t) func }; f.flags |= (uint32_t) func_flags::has_free; f.free_capture = [](void *p) { delete (capture *) ((void **) p)[0]; }; } f.impl = [](void *p, PyObject **args, uint8_t *args_flags, rv_policy policy, cleanup_list *cleanup) NB_INLINE_LAMBDA -> PyObject * { (void) p; (void) args; (void) args_flags; (void) policy; (void) cleanup; const capture *cap; if constexpr (sizeof(capture) <= sizeof(f.capture)) cap = (capture *) p; else cap = (capture *) ((void **) p)[0]; tuple...> in; (void) in; #if defined(NB_FREE_THREADED) std::conditional_t guard; if constexpr (Info::nargs_locked) { ft_args_collector collector{args}; if constexpr (is_method_det) { if constexpr (lock_self_det) collector.apply((arg_locked *) nullptr); else collector.apply((arg *) nullptr); } (collector.apply((Extra *) nullptr), ...); guard.lock(collector); } #endif if constexpr (Info::pre_post_hooks) { std::integral_constant nargs_c; (process_precall(args, nargs_c, cleanup, (Extra *) nullptr), ...); if ((!from_python_remember_conv(in.template get(), args, args_flags, cleanup, Is) || ...)) return NB_NEXT_OVERLOAD; } else { if ((!in.template get().from_python(args[Is], args_flags[Is], cleanup) || ...)) return NB_NEXT_OVERLOAD; } PyObject *result; if constexpr (std::is_void_v) { #if defined(_WIN32) && !defined(__CUDACC__) // temporary workaround for an internal compiler error in MSVC cap->func(static_cast>(in.template get())...); #else cap->func(in.template get().operator cast_t()...); #endif result = Py_None; Py_INCREF(result); } else { #if defined(_WIN32) && !defined(__CUDACC__) // temporary workaround for an internal compiler error in MSVC result = cast_out::from_cpp( cap->func(static_cast>(in.template get())...), policy, cleanup).ptr(); #else result = cast_out::from_cpp( cap->func((in.template get()) .operator cast_t()...), policy, cleanup).ptr(); #endif } if constexpr (Info::pre_post_hooks) { std::integral_constant nargs_c; (process_postcall(args, nargs_c, result, (Extra *) nullptr), ...); } return result; }; f.descr = descr.text; f.descr_types = descr_types; f.nargs = nargs; // Set nargs_pos to the number of C++ function parameters (Args...) that // can be filled from Python positional arguments in a one-to-one fashion. // This ends at: // - the location of the variadic *args parameter, if present; otherwise // - the location of the first keyword-only parameter, if any; otherwise // - the location of the variadic **kwargs parameter, if present; otherwise // - the end of the parameter list // It's correct to give *args priority over kw_only because we verified // above that kw_only comes afterward if both are present. It's correct // to give kw_only priority over **kwargs because we verified above that // kw_only comes before if both are present. f.nargs_pos = args_pos_1 < nargs ? args_pos_1 : explicit_kw_only ? nargs_before_kw_only : kwargs_pos_1 < nargs ? kwargs_pos_1 : nargs; // Fill remaining fields of 'f' size_t arg_index = 0; (func_extra_apply(f, extra, arg_index), ...); (void) arg_index; return nb_func_new((const void *) &f); } NAMESPACE_END(detail) // The initial template parameter to cpp_function/cpp_function_def is // used by class_ to ensure that member pointers are treated as members // of the class being defined; other users can safely leave it at its // default of void. template NB_INLINE object cpp_function(Return (*f)(Args...), const Extra&... extra) { return steal(detail::func_create( f, f, std::make_index_sequence(), extra...)); } template NB_INLINE void cpp_function_def(Return (*f)(Args...), const Extra&... extra) { detail::func_create( f, f, std::make_index_sequence(), extra...); } /// Construct a cpp_function from a lambda function (pot. with internal state) template < typename = void, typename Func, typename... Extra, detail::enable_if_t>> = 0> NB_INLINE object cpp_function(Func &&f, const Extra &...extra) { using am = detail::analyze_method::operator())>; return steal(detail::func_create( (detail::forward_t) f, (typename am::func *) nullptr, std::make_index_sequence(), extra...)); } template < typename = void, typename Func, typename... Extra, detail::enable_if_t>> = 0> NB_INLINE void cpp_function_def(Func &&f, const Extra &...extra) { using am = detail::analyze_method::operator())>; detail::func_create( (detail::forward_t) f, (typename am::func *) nullptr, std::make_index_sequence(), extra...); } /// Construct a cpp_function from a class method (non-const) template NB_INLINE object cpp_function(Return (Class::*f)(Args...), const Extra &...extra) { using T = std::conditional_t, Class, Target>; return steal(detail::func_create( [f](T *c, Args... args) NB_INLINE_LAMBDA -> Return { return (c->*f)((detail::forward_t) args...); }, (Return(*)(T *, Args...)) nullptr, std::make_index_sequence(), extra...)); } template NB_INLINE void cpp_function_def(Return (Class::*f)(Args...), const Extra &...extra) { using T = std::conditional_t, Class, Target>; detail::func_create( [f](T *c, Args... args) NB_INLINE_LAMBDA -> Return { return (c->*f)((detail::forward_t) args...); }, (Return(*)(T *, Args...)) nullptr, std::make_index_sequence(), extra...); } /// Construct a cpp_function from a class method (const) template NB_INLINE object cpp_function(Return (Class::*f)(Args...) const, const Extra &...extra) { using T = std::conditional_t, Class, Target>; return steal(detail::func_create( [f](const T *c, Args... args) NB_INLINE_LAMBDA -> Return { return (c->*f)((detail::forward_t) args...); }, (Return(*)(const T *, Args...)) nullptr, std::make_index_sequence(), extra...)); } template NB_INLINE void cpp_function_def(Return (Class::*f)(Args...) const, const Extra &...extra) { using T = std::conditional_t, Class, Target>; detail::func_create( [f](const T *c, Args... args) NB_INLINE_LAMBDA -> Return { return (c->*f)((detail::forward_t) args...); }, (Return(*)(const T *, Args...)) nullptr, std::make_index_sequence(), extra...); } template module_ &module_::def(const char *name_, Func &&f, const Extra &...extra) { cpp_function_def((detail::forward_t) f, scope(*this), name(name_), extra...); return *this; } NAMESPACE_END(NB_NAMESPACE) wjakob-nanobind-6c4457b/include/nanobind/nb_lib.h000066400000000000000000000541671474760012700217530ustar00rootroot00000000000000/* nanobind/nb_lib.h: Interface to libnanobind.so Copyright (c) 2022 Wenzel Jakob All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ NAMESPACE_BEGIN(NB_NAMESPACE) // Forward declarations for types in ndarray.h (1) namespace dlpack { struct dltensor; struct dtype; } NAMESPACE_BEGIN(detail) // Forward declarations for types in ndarray.h (2) struct ndarray_handle; struct ndarray_config; /** * Helper class to clean temporaries created by function dispatch. * The first element serves a special role: it stores the 'self' * object of method calls (for rv_policy::reference_internal). */ struct NB_CORE cleanup_list { public: static constexpr uint32_t Small = 6; cleanup_list(PyObject *self) : m_size{1}, m_capacity{Small}, m_data{m_local} { m_local[0] = self; } ~cleanup_list() = default; /// Append a single PyObject to the cleanup stack NB_INLINE void append(PyObject *value) noexcept { if (m_size >= m_capacity) expand(); m_data[m_size++] = value; } NB_INLINE PyObject *self() const { return m_local[0]; } /// Decrease the reference count of all appended objects void release() noexcept; /// Does the list contain any entries? (besides the 'self' argument) bool used() { return m_size != 1; } /// Return the size of the cleanup stack size_t size() const { return m_size; } /// Subscript operator PyObject *operator[](size_t index) const { return m_data[index]; } protected: /// Out of memory, expand.. void expand() noexcept; protected: uint32_t m_size; uint32_t m_capacity; PyObject **m_data; PyObject *m_local[Small]; }; // ======================================================================== /// Raise a runtime error with the given message #if defined(__GNUC__) __attribute__((noreturn, __format__ (__printf__, 1, 2))) #else [[noreturn]] #endif NB_CORE void raise(const char *fmt, ...); /// Raise a type error with the given message #if defined(__GNUC__) __attribute__((noreturn, __format__ (__printf__, 1, 2))) #else [[noreturn]] #endif NB_CORE void raise_type_error(const char *fmt, ...); /// Abort the process with a fatal error #if defined(__GNUC__) __attribute__((noreturn, __format__ (__printf__, 1, 2))) #else [[noreturn]] #endif NB_CORE void fail(const char *fmt, ...) noexcept; /// Raise nanobind::python_error after an error condition was found [[noreturn]] NB_CORE void raise_python_error(); /// Raise nanobind::next_overload NB_CORE void raise_next_overload_if_null(void *p); /// Raise nanobind::cast_error [[noreturn]] NB_CORE void raise_cast_error(); // ======================================================================== NB_CORE void init(const char *domain); // ======================================================================== /// Convert a Python object into a Python unicode string NB_CORE PyObject *str_from_obj(PyObject *o); /// Convert an UTF8 null-terminated C string into a Python unicode string NB_CORE PyObject *str_from_cstr(const char *c); /// Convert an UTF8 C string + size into a Python unicode string NB_CORE PyObject *str_from_cstr_and_size(const char *c, size_t n); // ======================================================================== /// Convert a Python object into a Python byte string NB_CORE PyObject *bytes_from_obj(PyObject *o); /// Convert an UTF8 null-terminated C string into a Python byte string NB_CORE PyObject *bytes_from_cstr(const char *c); /// Convert a memory region into a Python byte string NB_CORE PyObject *bytes_from_cstr_and_size(const void *c, size_t n); // ======================================================================== /// Convert a Python object into a Python byte array NB_CORE PyObject *bytearray_from_obj(PyObject *o); /// Convert a memory region into a Python byte array NB_CORE PyObject *bytearray_from_cstr_and_size(const void *c, size_t n); // ======================================================================== /// Convert a Python object into a Python boolean object NB_CORE PyObject *bool_from_obj(PyObject *o); /// Convert a Python object into a Python integer object NB_CORE PyObject *int_from_obj(PyObject *o); /// Convert a Python object into a Python floating point object NB_CORE PyObject *float_from_obj(PyObject *o); // ======================================================================== /// Convert a Python object into a Python list NB_CORE PyObject *list_from_obj(PyObject *o); /// Convert a Python object into a Python tuple NB_CORE PyObject *tuple_from_obj(PyObject *o); /// Convert a Python object into a Python set NB_CORE PyObject *set_from_obj(PyObject *o); // ======================================================================== /// Get an object attribute or raise an exception NB_CORE PyObject *getattr(PyObject *obj, const char *key); NB_CORE PyObject *getattr(PyObject *obj, PyObject *key); /// Get an object attribute or return a default value (never raises) NB_CORE PyObject *getattr(PyObject *obj, const char *key, PyObject *def) noexcept; NB_CORE PyObject *getattr(PyObject *obj, PyObject *key, PyObject *def) noexcept; /// Get an object attribute or raise an exception. Skip if 'out' is non-null NB_CORE void getattr_or_raise(PyObject *obj, const char *key, PyObject **out); NB_CORE void getattr_or_raise(PyObject *obj, PyObject *key, PyObject **out); /// Set an object attribute or raise an exception NB_CORE void setattr(PyObject *obj, const char *key, PyObject *value); NB_CORE void setattr(PyObject *obj, PyObject *key, PyObject *value); /// Delete an object attribute or raise an exception NB_CORE void delattr(PyObject *obj, const char *key); NB_CORE void delattr(PyObject *obj, PyObject *key); // ======================================================================== /// Index into an object or raise an exception. Skip if 'out' is non-null NB_CORE void getitem_or_raise(PyObject *obj, Py_ssize_t, PyObject **out); NB_CORE void getitem_or_raise(PyObject *obj, const char *key, PyObject **out); NB_CORE void getitem_or_raise(PyObject *obj, PyObject *key, PyObject **out); /// Set an item or raise an exception NB_CORE void setitem(PyObject *obj, Py_ssize_t, PyObject *value); NB_CORE void setitem(PyObject *obj, const char *key, PyObject *value); NB_CORE void setitem(PyObject *obj, PyObject *key, PyObject *value); /// Delete an item or raise an exception NB_CORE void delitem(PyObject *obj, Py_ssize_t); NB_CORE void delitem(PyObject *obj, const char *key); NB_CORE void delitem(PyObject *obj, PyObject *key); // ======================================================================== /// Determine the length of a Python object NB_CORE size_t obj_len(PyObject *o); /// Try to roughly determine the length of a Python object NB_CORE size_t obj_len_hint(PyObject *o) noexcept; /// Obtain a string representation of a Python object NB_CORE PyObject* obj_repr(PyObject *o); /// Perform a comparison between Python objects and handle errors NB_CORE bool obj_comp(PyObject *a, PyObject *b, int value); /// Perform an unary operation on a Python object with error handling NB_CORE PyObject *obj_op_1(PyObject *a, PyObject* (*op)(PyObject*)); /// Perform an unary operation on a Python object with error handling NB_CORE PyObject *obj_op_2(PyObject *a, PyObject *b, PyObject *(*op)(PyObject *, PyObject *)); // Perform a vector function call NB_CORE PyObject *obj_vectorcall(PyObject *base, PyObject *const *args, size_t nargsf, PyObject *kwnames, bool method_call); /// Create an iterator from 'o', raise an exception in case of errors NB_CORE PyObject *obj_iter(PyObject *o); /// Advance the iterator 'o', raise an exception in case of errors NB_CORE PyObject *obj_iter_next(PyObject *o); // ======================================================================== // Conversion validity check done by nb::make_tuple NB_CORE void tuple_check(PyObject *tuple, size_t nargs); // ======================================================================== // Append a single argument to a function call NB_CORE void call_append_arg(PyObject *args, size_t &nargs, PyObject *value); // Append a variable-length sequence of arguments to a function call NB_CORE void call_append_args(PyObject *args, size_t &nargs, PyObject *value); // Append a single keyword argument to a function call NB_CORE void call_append_kwarg(PyObject *kwargs, const char *name, PyObject *value); // Append a variable-length dictionary of keyword arguments to a function call NB_CORE void call_append_kwargs(PyObject *kwargs, PyObject *value); // ======================================================================== // If the given sequence has the size 'size', return a pointer to its contents. // May produce a temporary. NB_CORE PyObject **seq_get_with_size(PyObject *seq, size_t size, PyObject **temp) noexcept; // Like the above, but return the size instead of checking it. NB_CORE PyObject **seq_get(PyObject *seq, size_t *size, PyObject **temp) noexcept; // ======================================================================== /// Create a new capsule object with a name NB_CORE PyObject *capsule_new(const void *ptr, const char *name, void (*cleanup)(void *) noexcept) noexcept; // ======================================================================== /// Create a Python function object for the given function record NB_CORE PyObject *nb_func_new(const void *data) noexcept; // ======================================================================== /// Create a Python type object for the given type record struct type_init_data; NB_CORE PyObject *nb_type_new(const type_init_data *c) noexcept; /// Extract a pointer to a C++ type underlying a Python object, if possible NB_CORE bool nb_type_get(const std::type_info *t, PyObject *o, uint8_t flags, cleanup_list *cleanup, void **out) noexcept; /// Cast a C++ type instance into a Python object NB_CORE PyObject *nb_type_put(const std::type_info *cpp_type, void *value, rv_policy rvp, cleanup_list *cleanup, bool *is_new = nullptr) noexcept; // Special version of nb_type_put for polymorphic classes NB_CORE PyObject *nb_type_put_p(const std::type_info *cpp_type, const std::type_info *cpp_type_p, void *value, rv_policy rvp, cleanup_list *cleanup, bool *is_new = nullptr) noexcept; // Special version of 'nb_type_put' for unique pointers and ownership transfer NB_CORE PyObject *nb_type_put_unique(const std::type_info *cpp_type, void *value, cleanup_list *cleanup, bool cpp_delete) noexcept; // Special version of 'nb_type_put_unique' for polymorphic classes NB_CORE PyObject *nb_type_put_unique_p(const std::type_info *cpp_type, const std::type_info *cpp_type_p, void *value, cleanup_list *cleanup, bool cpp_delete) noexcept; /// Try to relinquish ownership from Python object to a unique_ptr; /// return true if successful, false if not. (Failure is only /// possible if `cpp_delete` is true.) NB_CORE bool nb_type_relinquish_ownership(PyObject *o, bool cpp_delete) noexcept; /// Reverse the effects of nb_type_relinquish_ownership(). NB_CORE void nb_type_restore_ownership(PyObject *o, bool cpp_delete) noexcept; /// Get a pointer to a user-defined 'extra' value associated with the nb_type t. NB_CORE void *nb_type_supplement(PyObject *t) noexcept; /// Check if the given python object represents a nanobind type NB_CORE bool nb_type_check(PyObject *t) noexcept; /// Return the size of the type wrapped by the given nanobind type object NB_CORE size_t nb_type_size(PyObject *t) noexcept; /// Return the alignment of the type wrapped by the given nanobind type object NB_CORE size_t nb_type_align(PyObject *t) noexcept; /// Return a unicode string representing the long-form name of the given type NB_CORE PyObject *nb_type_name(PyObject *t) noexcept; /// Return a unicode string representing the long-form name of object's type NB_CORE PyObject *nb_inst_name(PyObject *o) noexcept; /// Return the C++ type_info wrapped by the given nanobind type object NB_CORE const std::type_info *nb_type_info(PyObject *t) noexcept; /// Get a pointer to the instance data of a nanobind instance (nb_inst) NB_CORE void *nb_inst_ptr(PyObject *o) noexcept; /// Check if a Python type object wraps an instance of a specific C++ type NB_CORE bool nb_type_isinstance(PyObject *obj, const std::type_info *t) noexcept; /// Search for the Python type object associated with a C++ type NB_CORE PyObject *nb_type_lookup(const std::type_info *t) noexcept; /// Allocate an instance of type 't' NB_CORE PyObject *nb_inst_alloc(PyTypeObject *t); /// Allocate an zero-initialized instance of type 't' NB_CORE PyObject *nb_inst_alloc_zero(PyTypeObject *t); /// Allocate an instance of type 't' referencing the existing 'ptr' NB_CORE PyObject *nb_inst_reference(PyTypeObject *t, void *ptr, PyObject *parent); /// Allocate an instance of type 't' taking ownership of the existing 'ptr' NB_CORE PyObject *nb_inst_take_ownership(PyTypeObject *t, void *ptr); /// Call the destructor of the given python object NB_CORE void nb_inst_destruct(PyObject *o) noexcept; /// Zero-initialize a POD type and mark it as ready + to be destructed upon GC NB_CORE void nb_inst_zero(PyObject *o) noexcept; /// Copy-construct 'dst' from 'src', mark it as ready and to be destructed (must have the same nb_type) NB_CORE void nb_inst_copy(PyObject *dst, const PyObject *src) noexcept; /// Move-construct 'dst' from 'src', mark it as ready and to be destructed (must have the same nb_type) NB_CORE void nb_inst_move(PyObject *dst, const PyObject *src) noexcept; /// Destruct 'dst', copy-construct 'dst' from 'src', mark ready and retain 'destruct' status (must have the same nb_type) NB_CORE void nb_inst_replace_copy(PyObject *dst, const PyObject *src) noexcept; /// Destruct 'dst', move-construct 'dst' from 'src', mark ready and retain 'destruct' status (must have the same nb_type) NB_CORE void nb_inst_replace_move(PyObject *dst, const PyObject *src) noexcept; /// Check if a particular instance uses a Python-derived type NB_CORE bool nb_inst_python_derived(PyObject *o) noexcept; /// Overwrite the instance's ready/destruct flags NB_CORE void nb_inst_set_state(PyObject *o, bool ready, bool destruct) noexcept; /// Query the 'ready' and 'destruct' flags of an instance NB_CORE std::pair nb_inst_state(PyObject *o) noexcept; // ======================================================================== // Create and install a Python property object NB_CORE void property_install(PyObject *scope, const char *name, PyObject *getter, PyObject *setter) noexcept; NB_CORE void property_install_static(PyObject *scope, const char *name, PyObject *getter, PyObject *setter) noexcept; // ======================================================================== NB_CORE PyObject *get_override(void *ptr, const std::type_info *type, const char *name, bool pure); // ======================================================================== // Ensure that 'patient' cannot be GCed while 'nurse' is alive NB_CORE void keep_alive(PyObject *nurse, PyObject *patient); // Keep 'payload' alive until 'nurse' is GCed NB_CORE void keep_alive(PyObject *nurse, void *payload, void (*deleter)(void *) noexcept) noexcept; // ======================================================================== /// Indicate to nanobind that an implicit constructor can convert 'src' -> 'dst' NB_CORE void implicitly_convertible(const std::type_info *src, const std::type_info *dst) noexcept; /// Register a callback to check if implicit conversion to 'dst' is possible NB_CORE void implicitly_convertible(bool (*predicate)(PyTypeObject *, PyObject *, cleanup_list *), const std::type_info *dst) noexcept; // ======================================================================== struct enum_init_data; /// Create a new enumeration type NB_CORE PyObject *enum_create(enum_init_data *) noexcept; /// Append an entry to an enumeration NB_CORE void enum_append(PyObject *tp, const char *name, int64_t value, const char *doc) noexcept; // Query an enumeration's Python object -> integer value map NB_CORE bool enum_from_python(const std::type_info *, PyObject *, int64_t *, uint8_t flags) noexcept; // Query an enumeration's integer value -> Python object map NB_CORE PyObject *enum_from_cpp(const std::type_info *, int64_t) noexcept; /// Export enum entries to the parent scope NB_CORE void enum_export(PyObject *tp); // ======================================================================== /// Try to import a Python extension module, raises an exception upon failure NB_CORE PyObject *module_import(const char *name); /// Try to import a Python extension module, raises an exception upon failure NB_CORE PyObject *module_import(PyObject *name); /// Create a new extension module with the given name NB_CORE PyObject *module_new(const char *name, PyModuleDef *def) noexcept; /// Create a submodule of an existing module NB_CORE PyObject *module_new_submodule(PyObject *base, const char *name, const char *doc) noexcept; // ======================================================================== // Try to import a reference-counted ndarray object via DLPack NB_CORE ndarray_handle *ndarray_import(PyObject *o, const ndarray_config *c, bool convert, cleanup_list *cleanup) noexcept; // Describe a local ndarray object using a DLPack capsule NB_CORE ndarray_handle *ndarray_create(void *value, size_t ndim, const size_t *shape, PyObject *owner, const int64_t *strides, dlpack::dtype dtype, bool ro, int device, int device_id, char order); /// Increase the reference count of the given ndarray object; returns a pointer /// to the underlying DLTensor NB_CORE dlpack::dltensor *ndarray_inc_ref(ndarray_handle *) noexcept; /// Decrease the reference count of the given ndarray object NB_CORE void ndarray_dec_ref(ndarray_handle *) noexcept; /// Wrap a ndarray_handle* into a PyCapsule NB_CORE PyObject *ndarray_export(ndarray_handle *, int framework, rv_policy policy, cleanup_list *cleanup) noexcept; /// Check if an object represents an ndarray NB_CORE bool ndarray_check(PyObject *o) noexcept; // ======================================================================== /// Print to stdout using Python NB_CORE void print(PyObject *file, PyObject *str, PyObject *end); // ======================================================================== typedef void (*exception_translator)(const std::exception_ptr &, void *); NB_CORE void register_exception_translator(exception_translator translator, void *payload); NB_CORE PyObject *exception_new(PyObject *mod, const char *name, PyObject *base); // ======================================================================== NB_CORE bool load_i8 (PyObject *o, uint8_t flags, int8_t *out) noexcept; NB_CORE bool load_u8 (PyObject *o, uint8_t flags, uint8_t *out) noexcept; NB_CORE bool load_i16(PyObject *o, uint8_t flags, int16_t *out) noexcept; NB_CORE bool load_u16(PyObject *o, uint8_t flags, uint16_t *out) noexcept; NB_CORE bool load_i32(PyObject *o, uint8_t flags, int32_t *out) noexcept; NB_CORE bool load_u32(PyObject *o, uint8_t flags, uint32_t *out) noexcept; NB_CORE bool load_i64(PyObject *o, uint8_t flags, int64_t *out) noexcept; NB_CORE bool load_u64(PyObject *o, uint8_t flags, uint64_t *out) noexcept; NB_CORE bool load_f32(PyObject *o, uint8_t flags, float *out) noexcept; NB_CORE bool load_f64(PyObject *o, uint8_t flags, double *out) noexcept; // ======================================================================== /// Increase the reference count of 'o', and check that the GIL is held NB_CORE void incref_checked(PyObject *o) noexcept; /// Decrease the reference count of 'o', and check that the GIL is held NB_CORE void decref_checked(PyObject *o) noexcept; // ======================================================================== NB_CORE bool leak_warnings() noexcept; NB_CORE bool implicit_cast_warnings() noexcept; NB_CORE void set_leak_warnings(bool value) noexcept; NB_CORE void set_implicit_cast_warnings(bool value) noexcept; // ======================================================================== NB_CORE bool iterable_check(PyObject *o) noexcept; // ======================================================================== NB_CORE void slice_compute(PyObject *slice, Py_ssize_t size, Py_ssize_t &start, Py_ssize_t &stop, Py_ssize_t &step, size_t &slice_length); // ======================================================================== NB_CORE bool issubclass(PyObject *a, PyObject *b); // ======================================================================== NB_CORE PyObject *repr_list(PyObject *o); NB_CORE PyObject *repr_map(PyObject *o); NB_CORE bool is_alive() noexcept; #if NB_TYPE_GET_SLOT_IMPL NB_CORE void *type_get_slot(PyTypeObject *t, int slot_id); #endif NB_CORE PyObject *dict_get_item_ref_or_fail(PyObject *d, PyObject *k); NAMESPACE_END(detail) using detail::raise; using detail::raise_type_error; using detail::raise_python_error; NAMESPACE_END(NB_NAMESPACE) wjakob-nanobind-6c4457b/include/nanobind/nb_misc.h000066400000000000000000000055231474760012700221300ustar00rootroot00000000000000/* nanobind/nb_misc.h: Miscellaneous bits (GIL, etc.) Copyright (c) 2022 Wenzel Jakob All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ NAMESPACE_BEGIN(NB_NAMESPACE) struct gil_scoped_acquire { public: NB_NONCOPYABLE(gil_scoped_acquire) gil_scoped_acquire() noexcept : state(PyGILState_Ensure()) { } ~gil_scoped_acquire() { PyGILState_Release(state); } private: const PyGILState_STATE state; }; struct gil_scoped_release { public: NB_NONCOPYABLE(gil_scoped_release) gil_scoped_release() noexcept : state(PyEval_SaveThread()) { } ~gil_scoped_release() { PyEval_RestoreThread(state); } private: PyThreadState *state; }; struct ft_mutex { public: NB_NONCOPYABLE(ft_mutex) ft_mutex() = default; #if !defined(NB_FREE_THREADED) void lock() { } void unlock() { } #else void lock() { PyMutex_Lock(&mutex); } void unlock() { PyMutex_Unlock(&mutex); } private: PyMutex mutex { 0 }; #endif }; struct ft_lock_guard { public: NB_NONCOPYABLE(ft_lock_guard) ft_lock_guard(ft_mutex &m) : m(m) { m.lock(); } ~ft_lock_guard() { m.unlock(); } private: ft_mutex &m; }; struct ft_object_guard { public: NB_NONCOPYABLE(ft_object_guard) #if !defined(NB_FREE_THREADED) ft_object_guard(handle) { } #else ft_object_guard(handle h) { PyCriticalSection_Begin(&cs, h.ptr()); } ~ft_object_guard() { PyCriticalSection_End(&cs); } private: PyCriticalSection cs; #endif }; struct ft_object2_guard { public: NB_NONCOPYABLE(ft_object2_guard) #if !defined(NB_FREE_THREADED) ft_object2_guard(handle, handle) { } #else ft_object2_guard(handle h1, handle h2) { PyCriticalSection2_Begin(&cs, h1.ptr(), h2.ptr()); } ~ft_object2_guard() { PyCriticalSection2_End(&cs); } private: PyCriticalSection2 cs; #endif }; inline bool leak_warnings() noexcept { return detail::leak_warnings(); } inline bool implicit_cast_warnings() noexcept { return detail::implicit_cast_warnings(); } inline void set_leak_warnings(bool value) noexcept { detail::set_leak_warnings(value); } inline void set_implicit_cast_warnings(bool value) noexcept { detail::set_implicit_cast_warnings(value); } inline dict globals() { PyObject *p = PyEval_GetGlobals(); if (!p) raise("nanobind::globals(): no frame is currently executing!"); return borrow(p); } inline Py_hash_t hash(handle h) { Py_hash_t rv = PyObject_Hash(h.ptr()); if (rv == -1 && PyErr_Occurred()) nanobind::raise_python_error(); return rv; } inline bool isinstance(handle inst, handle cls) { int ret = PyObject_IsInstance(inst.ptr(), cls.ptr()); if (ret == -1) nanobind::raise_python_error(); return ret; } inline bool is_alive() noexcept { return detail::is_alive(); } NAMESPACE_END(NB_NAMESPACE) wjakob-nanobind-6c4457b/include/nanobind/nb_python.h000066400000000000000000000025411474760012700225130ustar00rootroot00000000000000/* nanobind/nb_python.h: Include CPython headers while temporarily disabling certain warnings. Also, disable dangerous preprocessor definitions. Copyright (c) 2022 Wenzel Jakob All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ /// Include Python header, disable linking to pythonX_d.lib on Windows in debug mode #if defined(_MSC_VER) # pragma warning(push) # if defined(_DEBUG) && !defined(Py_DEBUG) # define NB_DEBUG_MARKER # undef _DEBUG # endif #endif #include #include #include #include /* Python #defines overrides on all sorts of core functions, which tends to weak havok in C++ codebases that expect these to work like regular functions (potentially with several overloads) */ #if defined(isalnum) # undef isalnum # undef isalpha # undef islower # undef isspace # undef isupper # undef tolower # undef toupper #endif #if defined(copysign) # undef copysign #endif #if defined(setter) # undef setter #endif #if defined(getter) # undef getter #endif #if defined(_MSC_VER) # if defined(NB_DEBUG_MARKER) # define _DEBUG # undef NB_DEBUG_MARKER # endif # pragma warning(pop) #endif #if PY_VERSION_HEX < 0x03080000 # error The nanobind library requires Python 3.8 (or newer) #endif wjakob-nanobind-6c4457b/include/nanobind/nb_traits.h000066400000000000000000000212531474760012700225010ustar00rootroot00000000000000/* nanobind/nb_traits.h: type traits for metaprogramming in nanobind Copyright (c) 2022 Wenzel Jakob All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ NAMESPACE_BEGIN(NB_NAMESPACE) using ssize_t = std::make_signed_t; NAMESPACE_BEGIN(detail) struct void_type { }; template struct index_1; template struct index_n; template <> struct index_1<> { constexpr static size_t value = 0; }; template <> struct index_n<> { constexpr static size_t value = 0; }; template struct index_1 { constexpr static size_t value_rec = index_1::value; constexpr static size_t value = B ? 0 : (value_rec + 1); }; template struct index_n { constexpr static size_t value_rec = index_n::value; constexpr static size_t value = (value_rec < sizeof...(Bs) || !B) ? (value_rec + 1) : 0; }; template constexpr size_t index_1_v = index_1::value; template constexpr size_t index_n_v = index_n::value; /// Helper template to strip away type modifiers template struct intrinsic_type { using type = T; }; template struct intrinsic_type { using type = typename intrinsic_type::type; }; template struct intrinsic_type { using type = typename intrinsic_type::type; }; template struct intrinsic_type { using type = typename intrinsic_type::type; }; template struct intrinsic_type { using type = typename intrinsic_type::type; }; template struct intrinsic_type { using type = typename intrinsic_type::type; }; template struct intrinsic_type { using type = typename intrinsic_type::type; }; template using intrinsic_t = typename intrinsic_type::type; // More relaxed pointer test template constexpr bool is_pointer_v = std::is_pointer_v>; template using forwarded_type = std::conditional_t, std::remove_reference_t &, std::remove_reference_t &&>; /// Forwards a value U as rvalue or lvalue according to whether T is rvalue or lvalue; typically /// used for forwarding a container's elements. template NB_INLINE forwarded_type forward_like_(U &&u) { return (forwarded_type) u; } template constexpr bool is_std_char_v = std::is_same_v #if defined(NB_HAS_U8STRING) || std::is_same_v /* std::u8string */ #endif || std::is_same_v || std::is_same_v || std::is_same_v; template using enable_if_t = std::enable_if_t; /// Check if a function is a lambda function template constexpr bool is_lambda_v = !std::is_function_v && !std::is_pointer_v && !std::is_member_pointer_v; /// Inspect the signature of a method call template struct analyze_method { }; template struct analyze_method { using func = Ret(Args...); static constexpr size_t argc = sizeof...(Args); }; template struct analyze_method { using func = Ret(Args...); static constexpr size_t argc = sizeof...(Args); }; template struct analyze_method { using func = Ret(Args...); static constexpr size_t argc = sizeof...(Args); }; template struct analyze_method { using func = Ret(Args...); static constexpr size_t argc = sizeof...(Args); }; template struct strip_function_object { using type = typename analyze_method::func; }; // Extracts the function signature from a function, function pointer or lambda. template > using function_signature_t = std::conditional_t< std::is_function_v, F, typename std::conditional_t< std::is_pointer_v || std::is_member_pointer_v, std::remove_pointer, strip_function_object>::type>; template using forward_t = std::conditional_t, T, T &&>; template inline constexpr bool false_v = false; template struct overload_cast_impl { template constexpr auto operator()(Return (*pf)(Args...)) const noexcept -> decltype(pf) { return pf; } template constexpr auto operator()(Return (Class::*pmf)(Args...), std::false_type = {}) const noexcept -> decltype(pmf) { return pmf; } template constexpr auto operator()(Return (Class::*pmf)(Args...) const, std::true_type) const noexcept -> decltype(pmf) { return pmf; } }; /// Detector pattern template typename Op, typename Arg> struct detector : std::false_type { }; template