MeshLib
 
Loading...
Searching...
No Matches
MRPython.h File Reference
#include "MRMeshFwd.h"
#include <pybind11/pybind11.h>
#include <pybind11/operators.h>
#include <pybind11/stl_bind.h>
#include <pybind11/numpy.h>
#include "MRExpected.h"
#include <functional>
#include <filesystem>
#include <unordered_map>

Go to the source code of this file.

Classes

class  PythonStreamRedirector< T >
 
class  MR::PythonExport
 
struct  MR::PythonExport::ModuleData
 
struct  MR::PythonFunctionAdder
 

Namespaces

namespace  MR
 

Macros

#define MR_INIT_PYTHON_MODULE(moduleName)   MR_INIT_PYTHON_MODULE_PRECALL( moduleName, [](){} )
 
#define MR_INIT_PYTHON_MODULE_PRECALL(moduleName, precall)
 
#define MR_ADD_PYTHON_FUNCTION(moduleName, name, func, description)    static MR::PythonFunctionAdder name##_adder_( #moduleName, [](pybind11::module_& m){ m.def(#name, func, description);} );
 
#define MR_ADD_PYTHON_CUSTOM_DEF(moduleName, name, ...)
 
#define _MR_PYTHON_CUSTOM_CLASS_HOLDER_NAME(name)   name##_class_
 Python class wrapper name; for internal use only.
 
#define MR_PYTHON_CUSTOM_CLASS(name)   ( *_MR_PYTHON_CUSTOM_CLASS_HOLDER_NAME( name ) )
 
#define MR_ADD_PYTHON_CUSTOM_CLASS_DECL(moduleName, name, ...)   static std::optional<pybind11::class_<__VA_ARGS__>> _MR_PYTHON_CUSTOM_CLASS_HOLDER_NAME( name );
 
#define MR_ADD_PYTHON_CUSTOM_CLASS_INST(moduleName, name)
 
#define MR_ADD_PYTHON_CUSTOM_CLASS_INST_FUNC(moduleName, name, ...)
 
#define MR_ADD_PYTHON_CUSTOM_CLASS(moduleName, name, ...)
 
#define MR_ADD_PYTHON_VEC(moduleName, name, type)
 
#define MR_ADD_PYTHON_MAP(moduleName, name, mapType)
 
#define MR_ADD_PYTHON_EXPECTED(moduleName, name, type, errorType)
 

Typedefs

using StdoutPyRedirector = PythonStreamRedirector<Stdout>
 
using StderrPyRedirector = PythonStreamRedirector<Stderr>
 

Enumerations

enum  StreamType { Stdout , Stderr }
 

Functions

template<typename E >
void MR::throwExceptionFromExpected (const E &err)
 
template<typename R , typename E , typename... Args>
auto MR::decorateExpected (std::function< Expected< R, E >(Args...)> &&f) -> std::function< R(Args...)>
 
template<typename F >
auto MR::decorateExpected (F &&f)
 
template<typename R , typename T , typename... Args>
auto MR::decorateExpected (R(T::*memFunction)(Args...))
 

Macro Definition Documentation

◆ _MR_PYTHON_CUSTOM_CLASS_HOLDER_NAME

#define _MR_PYTHON_CUSTOM_CLASS_HOLDER_NAME ( name)    name##_class_

Python class wrapper name; for internal use only.

◆ MR_ADD_PYTHON_CUSTOM_CLASS

#define MR_ADD_PYTHON_CUSTOM_CLASS ( moduleName,
name,
... )
Value:
MR_ADD_PYTHON_CUSTOM_CLASS_DECL( moduleName, name, __VA_ARGS__ ) \
MR_ADD_PYTHON_CUSTOM_CLASS_INST( moduleName, name )
#define MR_ADD_PYTHON_CUSTOM_CLASS_DECL(moduleName, name,...)
Definition MRPython.h:54

For the proper stub file generation, a class must be defined prior to its depending methods. To achieve it, declare the class before the MR_ADD_PYTHON_CUSTOM_DEF block:

◆ MR_ADD_PYTHON_CUSTOM_CLASS_DECL

#define MR_ADD_PYTHON_CUSTOM_CLASS_DECL ( moduleName,
name,
... )   static std::optional<pybind11::class_<__VA_ARGS__>> _MR_PYTHON_CUSTOM_CLASS_HOLDER_NAME( name );

Explicitly declare the Python class wrapper

See also
MR_ADD_PYTHON_CUSTOM_CLASS

◆ MR_ADD_PYTHON_CUSTOM_CLASS_INST

#define MR_ADD_PYTHON_CUSTOM_CLASS_INST ( moduleName,
name )
Value:
MR_ADD_PYTHON_CUSTOM_DEF( moduleName, name##_inst_, [] ( pybind11::module_& module ) \
{ \
_MR_PYTHON_CUSTOM_CLASS_HOLDER_NAME( name ).emplace( module, #name ); \

Explicitly instantiate the Python class wrapper

See also
MR_ADD_PYTHON_CUSTOM_CLASS

◆ MR_ADD_PYTHON_CUSTOM_CLASS_INST_FUNC

#define MR_ADD_PYTHON_CUSTOM_CLASS_INST_FUNC ( moduleName,
name,
... )
Value:
MR_ADD_PYTHON_CUSTOM_DEF( moduleName, name##_inst_, [] ( pybind11::module_& module ) \
{ \
_MR_PYTHON_CUSTOM_CLASS_HOLDER_NAME( name ) = __VA_ARGS__ ( module ); \

Explicitly instantiate the Python class wrapper with a custom function (pybind11::bind_vector, pybind11::bind_map, etc.)

See also
MR_ADD_PYTHON_CUSTOM_CLASS
MR_ADD_PYTHON_VEC
MR_ADD_PYTHON_MAP

◆ MR_ADD_PYTHON_CUSTOM_DEF

#define MR_ADD_PYTHON_CUSTOM_DEF ( moduleName,
name,
... )
Value:
_Pragma("warning(push)") \
_Pragma("warning(disable:4459)") \
static MR::PythonFunctionAdder name##_adder_( #moduleName, __VA_ARGS__ ); \
_Pragma("warning(pop)")
Definition MRPython.h:222

◆ MR_ADD_PYTHON_EXPECTED

#define MR_ADD_PYTHON_EXPECTED ( moduleName,
name,
type,
errorType )
Value:
using name##_expected_type_ = MR::Expected<type, errorType>; \
MR_ADD_PYTHON_CUSTOM_CLASS( moduleName, name, name##_expected_type_ ) \
MR_ADD_PYTHON_CUSTOM_DEF( moduleName, name, [] ( pybind11::module_& ) \
{\
using expectedType = Expected<type,errorType>;\
MR_PYTHON_CUSTOM_CLASS( name ).\
def( "has_value", []() \
{ PyErr_WarnEx(PyExc_DeprecationWarning, ".has_value is deprecated. Please use 'try - except ValueError'", 1); \
return &expectedType::has_value; \
}).\
def( "value", []() \
{ \
PyErr_WarnEx(PyExc_DeprecationWarning, ".value is deprecated. Please use 'try - except ValueError'", 1); \
return ( type& ( expectedType::* )( )& )& expectedType::value; \
}, pybind11::return_value_policy::reference_internal ).\
def( "error", []() \
{ \
PyErr_WarnEx(PyExc_DeprecationWarning, ".error is deprecated. Please use 'try - except ValueError'", 1); \
return ( const errorType& ( expectedType::* )( )const& )& expectedType::error; \
} );\
} )
tl::expected< T, E > Expected
Definition MRExpected.h:49

◆ MR_ADD_PYTHON_FUNCTION

#define MR_ADD_PYTHON_FUNCTION ( moduleName,
name,
func,
description )    static MR::PythonFunctionAdder name##_adder_( #moduleName, [](pybind11::module_& m){ m.def(#name, func, description);} );

◆ MR_ADD_PYTHON_MAP

#define MR_ADD_PYTHON_MAP ( moduleName,
name,
mapType )
Value:
PYBIND11_MAKE_OPAQUE( mapType ) \
MR_ADD_PYTHON_CUSTOM_CLASS_DECL( moduleName, name, mapType, std::unique_ptr<mapType> ) \
MR_ADD_PYTHON_CUSTOM_CLASS_INST_FUNC( moduleName, name, [] ( pybind11::module_& module ) { return pybind11::bind_map<mapType>( module, #name, pybind11::module_local(false) ); } ) \
MR_ADD_PYTHON_CUSTOM_DEF( moduleName, name, [] ( pybind11::module_& ) \
{\
MR_PYTHON_CUSTOM_CLASS( name ).\
def( pybind11::init<>() ).\
def( "size", &mapType::size );\
} )

◆ MR_ADD_PYTHON_VEC

#define MR_ADD_PYTHON_VEC ( moduleName,
name,
type )
Value:
PYBIND11_MAKE_OPAQUE( std::vector<type> ) \
MR_ADD_PYTHON_CUSTOM_CLASS_DECL( moduleName, name, std::vector<type>, std::unique_ptr<std::vector<type>> ) \
MR_ADD_PYTHON_CUSTOM_CLASS_INST_FUNC( moduleName, name, [] ( pybind11::module_& module ) { return pybind11::bind_vector<std::vector<type>>( module, #name, pybind11::module_local(false) ); } ) \
MR_ADD_PYTHON_CUSTOM_DEF( moduleName, name, [] ( pybind11::module_& ) \
{\
using vecType = std::vector<type>;\
MR_PYTHON_CUSTOM_CLASS( name ).\
def( pybind11::init<>() ).\
def( pybind11::init<size_t>(), pybind11::arg( "size" ) ).\
def( "empty", &vecType::empty ).\
def( "size", &vecType::size ).\
def( "resize", ( void ( vecType::* )( const vecType::size_type ) )& vecType::resize ).\
def( "clear", &vecType::clear ); \
} )

◆ MR_INIT_PYTHON_MODULE

#define MR_INIT_PYTHON_MODULE ( moduleName)    MR_INIT_PYTHON_MODULE_PRECALL( moduleName, [](){} )

◆ MR_INIT_PYTHON_MODULE_PRECALL

#define MR_INIT_PYTHON_MODULE_PRECALL ( moduleName,
precall )
Value:
PYBIND11_MODULE( moduleName, m )\
{\
precall();\
auto& adders = MR::PythonExport::instance().functions( #moduleName );\
for ( auto& fs : adders )\
for ( auto& f : fs )\
f( m );\
}\
static MR::PythonFunctionAdder moduleName##_init_( #moduleName, &PyInit_##moduleName );
const std::array< std::vector< PythonRegisterFuncton >, size_t(Priority::Count)> & functions(const std::string &moduleName) const
Definition MRPython.h:201
static MRMESH_API PythonExport & instance()

◆ MR_PYTHON_CUSTOM_CLASS

#define MR_PYTHON_CUSTOM_CLASS ( name)    ( *_MR_PYTHON_CUSTOM_CLASS_HOLDER_NAME( name ) )

Python class wrapper accessor

See also
MR_ADD_PYTHON_CUSTOM_CLASS

Typedef Documentation

◆ StderrPyRedirector

◆ StdoutPyRedirector

Enumeration Type Documentation

◆ StreamType

enum StreamType
Enumerator
Stdout 
Stderr