ShlubluLib
v0.5
ShlubluLib is a lightweight, modular, general purpose, open-source C++ library for Linux and Windows.
|
Classes | |
class | BindingLogicError |
Python throws this exception when an issue expected to be detectable in the code happens at run time. More... | |
class | BindingRuntimeError |
Python throws this exception when an issue not detectable in the code happens at run time. More... | |
class | ObjectHandler |
Handler of CPython object pointers used by Python to handle references counts. More... | |
class | ObjectHandlersCollection |
Collection of ObjectHandler used internally by Python. More... | |
Typedefs | |
using | PathEntriesList = std::vector< std::string > |
Path, as a vector of strings. | |
using | ObjectHandlersList = std::vector< ObjectHandler > |
Parameters list to pass to call() or to functions that create collections. | |
using | ObjectPointer = PyObject * |
Pointer to scope objects (either imported modules or instances of a class) or callable objects (functions or methods). More... | |
using | RawCode = std::string |
Plain Python code. | |
using | Program = std::vector< RawCode > |
Complete program. More... | |
Functions | |
bool | isInitialized () |
Check whether Python is initialized. More... | |
void | init (std::string const &programName, PathEntriesList const &pythonSysPath=PathEntriesList()) |
Initializes Python. More... | |
void | shutdown () |
Shuts down Python. More... | |
void | execute (RawCode const &code) |
Executes raw code. More... | |
void | execute (Program const &program) |
Executes a program. More... | |
ObjectPointer | import (std::string const &moduleName) |
Imports a module by its name. More... | |
ObjectPointer | module (std::string const &moduleName) |
Retrieves a previously imported module. More... | |
ObjectHandler const & | object (ObjectPointer scope, std::string const &objectName) |
Retrieves an object by its name from a scope pointer. More... | |
ObjectHandler const & | object (std::string const &moduleName, std::string const &objectName) |
Retrieves an object by its name from a module name. More... | |
ObjectPointer | callable (ObjectPointer scope, std::string const &callableName, bool forceReload=false) |
Retrieves a callable object (function or method) by its name from a scope pointer. More... | |
ObjectPointer | callable (std::string const &moduleName, std::string const &callableName, bool forceReload=false) |
Retrieves a callable object (function) by its name from a module name. More... | |
ObjectHandler const & | call (ObjectPointer callableObject, ObjectHandlersList const &args={}, bool keepArguments=false) |
Calls a callable with the given arguments. More... | |
ObjectHandler | tuple (ObjectHandlersList const &args={}, bool keepArguments=false) |
Creates a tuple object initialized with the given arguments. More... | |
ObjectHandler | list (ObjectHandlersList const &args={}, bool keepArguments=false) |
Creates a list object initialized with the given arguments. More... | |
void | addList (ObjectHandler list, ObjectHandler item, bool keepArg=false) |
Adds an item to the end of a list. More... | |
ObjectHandler | fromAscii (std::string const &str) |
Converts a string to a UTF-8 CPython string object. More... | |
std::string | toAscii (ObjectHandler utfStr, bool keepArg=false) |
Converts a UTF-8 CPython string object to a std::string. More... | |
ObjectHandler const & | keepArgument (ObjectHandler const &object) |
Prevents an object reference from being stolen. More... | |
ObjectHandler const & | controlArgument (ObjectHandler object) |
Places an CPython object under control of Python. More... | |
void | forgetArgument (ObjectHandler const &object) |
Get rid of a reference of an object under control. More... | |
void | beginCriticalSection () |
Enters a critical section, preventing other threads from entering any Python critical section. More... | |
void | endCriticalSection () |
Exits a critical section, allowing other threads to enter a Python critical section. More... | |
bool | operator== (ObjectHandler const &lhs, ObjectHandler const &rhs) |
Equality operator. More... | |
bool | operator!= (ObjectHandler const &lhs, ObjectHandler const &rhs) |
Inequality operator. More... | |
Variables | |
const std::string | moduleMain |
Main module ("__main__"). More... | |
const std::string | moduleBuiltins |
Built-ins module ("builtins"). More... | |
Helper classes and functions wrapping the CPython standard API.
Not all functions of the CPython API are wrapped here. shlublu::Python is intended to make the most common operations simpler without preventing users from using advanced features from the CPython API when needed. In particular, this module focuses of making the references count handling simpler and less error-prone than doing it manually as CPython requires.
Requirements
This module uses the official Python3.x
library. Client programs need their include path, libraries path and linker input to be updated as follows:
<depends on your local installation>
<depends on your local installation>
libpython3.<x>m.a
python3<x>.dll
Typical examples of use
beginCriticalSection()
/ endCriticalSection()
to prevent other threads from calling the CPython interpreter while these transactions are executing. Such interruptions would not crash the program but could make the results inconsistents should these threads work on the same shared pieces of data. beginCriticalSection()
/ endCriticalSection()
as these functions do not support concurrency. For example, PyLong_FromLong(42)
, Py_XDECREF(object)
, or PyLong_AsLong(object)
fall in this category. PyGILState_*()
API. As shlublu::Python doesn't use this API there should not be any issue there.fork()
time. Testing shows the interpreter supports this very well, providing a full isolation, as long as the fork operation is conducted from a mono-thread process. Should you wish to fork a multi-threads process there are some cautions. using shlublu::Python::ObjectPointer = typedef PyObject* |
Pointer to scope objects (either imported modules or instances of a class) or callable objects (functions or methods).
Conversion from and to ObjectHandler is silent.
using shlublu::Python::Program = typedef std::vector<RawCode> |
Complete program.
Typical use is one line per element. Indentation is under the responsability of the programmer.
bool shlublu::Python::isInitialized | ( | ) |
Check whether Python is initialized.
Calling shutdown()
makes Python not to be initialized anymore.
void shlublu::Python::init | ( | std::string const & | programName, |
PathEntriesList const & | pythonSysPath = PathEntriesList() |
||
) |
Initializes Python.
Should pythonSysPath
differ between two calls not separated by a shutdown()
, elements of the second path that are not part of the first are appended.
This function can be called several times in a row with no issue.
programName | the name to give the interpreter. The argv[0] argument given to the main() function of your program is a preferred choice though not mandatory (see below) |
pythonSysPath | system path that will be appended to sys.path if not already part of it |
void shlublu::Python::shutdown | ( | ) |
Shuts down Python.
Cleans up all references to the various objects previously handled or created by using Python and calls Py_Finalize()
.
This function can be called several times in a row with no issue even if Python has not been initialized in the first place. It is called through atexit()
, which makes its explicit use optional.
void shlublu::Python::execute | ( | RawCode const & | code | ) |
Executes raw code.
code | piece of code to execute. Lines should be separated by \n . Intentation should be materialized by spaces or \t . |
BindingLogicError | if Python is not initialized or if the piece of code causes an error at interpretation time. |
Example
void shlublu::Python::execute | ( | Program const & | program | ) |
Executes a program.
The whole program is executed in a row and cannot be interrupted by other threads using the CPython interpreter.
program | code to execute, typically splitted by lines. Intentation should be materialized by spaces or \t . Empty lines are permitted. |
BindingLogicError | if Python is not initialized or if any line of code causes an error at interpretation time. |
Example
ObjectPointer shlublu::Python::import | ( | std::string const & | moduleName | ) |
Imports a module by its name.
Modules can be imported several times in a row with no issue, the same pointer being returned each time.
The returned pointer is under control of Python for garbage collection at shutdown()
time only.
moduleName | the name of the module, dot-delimited should it be part of a package |
BindingLogicError | if Python is not initialized or if the module cannot be found |
Example
ObjectPointer shlublu::Python::module | ( | std::string const & | moduleName | ) |
Retrieves a previously imported module.
Modules have to be imported by import()
to be retrieved that way. Modules imported by execute()
(as execute("import <name>")
) are not retrieved by this function.
The returned pointer is under control of Python for garbage collection at shutdown()
time only.
moduleName | the name of the module, dot-delimited should it be part of a package |
BindingLogicError | if Python is not initialized or if the module has not be previsouly imported by import() |
Example
ObjectHandler const& shlublu::Python::object | ( | ObjectPointer | scope, |
std::string const & | objectName | ||
) |
Retrieves an object by its name from a scope pointer.
The returned handler is under control of Python for garbage collection. Such a garbage collection is triggered by several functions. This is mentioned in their documentation.
scope | pointer to the module, namespace or object the object to retrieve belongs to |
objectName | the name of the object to retrieve |
BindingLogicError | if Python is not initialized or if the object cannot be found |
Example
ObjectHandler const& shlublu::Python::object | ( | std::string const & | moduleName, |
std::string const & | objectName | ||
) |
Retrieves an object by its name from a module name.
The returned handler is under control of Python for garbage collection. Such a garbage collection is triggered by several functions. This is mentioned in their documentation.
moduleName | the name of the module the object to retrieve belongs to |
objectName | the name of the object to retrieve |
BindingLogicError | if Python is not initialized, if the module has not been imported by import() , or if the object cannot be found |
Example
ObjectPointer shlublu::Python::callable | ( | ObjectPointer | scope, |
std::string const & | callableName, | ||
bool | forceReload = false |
||
) |
Retrieves a callable object (function or method) by its name from a scope pointer.
Callable objects are less likely to change than non-callable objects during the execution of the program. For this reason, pointers to callable are memorized. Multiple calls to this function with the same scope argument and callable name make the pointer retrieved in the first place to be returned, unless forceReload
is set to true.
The returned pointer is under control of Python for garbage collection at shutdown()
time only.
scope | pointer to the module, namespace or object the callable object to retrieve belongs to |
callableName | the name of the callable object to retrieve |
forceReload | if true, refresh the callable object pointer before returning it and dispose of any previous version |
BindingLogicError | if Python is not initialized, if the object cannot be found or if it is not callable |
Example
ObjectPointer shlublu::Python::callable | ( | std::string const & | moduleName, |
std::string const & | callableName, | ||
bool | forceReload = false |
||
) |
Retrieves a callable object (function) by its name from a module name.
Callable objects are less likely to change than non-callable objects during the execution of the program. For this reason, pointers to callable are memorized. Multiple calls to this function with the same scope argument and callable name make the pointer retrieved in the first place to be returned, unless forceReload
is set to true.
The returned pointer is under control of Python for garbage collection at shutdown()
time only.
moduleName | name of the module the callable object to retrieve belongs to |
callableName | the name of the callable object to retrieve |
forceReload | if true, refresh the callable object pointer before returning it and dispose of any previous version |
BindingLogicError | if Python is not initialized, if the module has not been imported by import() , if the object cannot be found or if it is not callable |
Example
ObjectHandler const& shlublu::Python::call | ( | ObjectPointer | callableObject, |
ObjectHandlersList const & | args = {} , |
||
bool | keepArguments = false |
||
) |
Calls a callable with the given arguments.
Once the callable returns, the references counts of the elements of args
are decreased unless keepArguments
is true in which case none are decreased. Should you wich to only keep some of the passed arguments, keepArguments
should be set to false
and controlArgument()
/keepArgument()
should be used with the arguments to preserve.
The returned handler is under control of Python for garbage collection. Such a garbage collection is triggered by several functions. This is mentioned in their documentation.
callableObject | pointer to the callable object to call, typically returned by callable() |
args | arguments of the call. They can either be obtained from previous Python calls or from CPython calls. Empty if no aregument is required. |
keepArguments | if true, the references counts of the elements of args will not be decreased so they can be reused later on |
None
if the callable returns no value. BindingLogicError | if Python is not initialized |
BindingRuntimeError | if any issue occurs during the call |
Example
ObjectHandler shlublu::Python::tuple | ( | ObjectHandlersList const & | args = {} , |
bool | keepArguments = false |
||
) |
Creates a tuple object initialized with the given arguments.
This function steals a reference from each element of args
unless keepArguments
is true in which case they are all preserved. Should you wich to only preserve some of the passed arguments, keepArguments
should be set to false
and controlArgument()
/keepArgument()
should be used with the arguments to preserve.
The returned handler is under control of Python for garbage collection. Such a garbage collection is triggered by several functions. This is mentioned in their documentation.
args | initializer of the tuple. These arguments can either be obtained from previous Python calls or from CPython calls. Empty to create an empty tuple. |
keepArguments | if true, no references will be stolen from args |
BindingLogicError | if Python is not initialized |
BindingRuntimeError | if any issue occurs during the creation of the tuple |
Example
ObjectHandler shlublu::Python::list | ( | ObjectHandlersList const & | args = {} , |
bool | keepArguments = false |
||
) |
Creates a list object initialized with the given arguments.
This function steals a reference from each element of args
unless keepArguments
is true in which case they are all preserved. Should you wich to only preserve some of the passed arguments, keepArguments
should be set to false
and controlArgument()
/keepArgument()
should be used with the arguments to preserve.
The returned handler is under control of Python for garbage collection. Such a garbage collection is triggered by several functions. This is mentioned in their documentation.
args | initializer of the list. These arguments can either be obtained from previous Python calls or from CPython calls. Empty to create an empty list. |
keepArguments | if true, no references will be stolen from args |
BindingLogicError | if Python is not initialized |
BindingRuntimeError | if any issue occurs during the creation of the list |
Example
void shlublu::Python::addList | ( | ObjectHandler | list, |
ObjectHandler | item, | ||
bool | keepArg = false |
||
) |
Adds an item to the end of a list.
This function steals a reference from item
unless keepArg
is true.
The returned handler is under control of Python for garbage collection. Such a garbage collection is triggered by several functions. This is mentioned in their documentation.
list | handler of the list object to add an item to. It can either be obtained from a previous Python call or implied by a PyObject * pointer obtained from a CPython call. |
item | handler of the item to add. It can either be obtained from a previous Python call or implied by a PyObject * pointer obtained from a CPython call. |
keepArg | if true, no reference will be stolen from item |
BindingLogicError | if Python is not initialized or if list is not a list |
Example
ObjectHandler shlublu::Python::fromAscii | ( | std::string const & | str | ) |
Converts a string to a UTF-8 CPython string object.
The returned handler is under control of Python for garbage collection. Such a garbage collection is triggered by several functions. This is mentioned in their documentation.
str | the string to convert |
str
BindingLogicError | if Python is not initialized |
Example
std::string shlublu::Python::toAscii | ( | ObjectHandler | utfStr, |
bool | keepArg = false |
||
) |
Converts a UTF-8 CPython string object to a std::string.
This function steals a reference from utfStr
unless keepArg
is true.
utfStr | the UTF-8 string object to convert |
keepArg | if true, no reference will be stolen from utfStr |
utfStr
BindingLogicError | if Python is not initialized or if utfStr is not a UTF-8 CPython string object |
Example
ObjectHandler const& shlublu::Python::keepArgument | ( | ObjectHandler const & | object | ) |
Prevents an object reference from being stolen.
This function increases the reference count of an object under control of Python. This prevents reference-stealing functions from disposing of a reference that is owned by the caller.
object | a handler of the object to preserve. It shoud be under control of Python. |
object
BindingLogicError | if Python is not initialized or if object is not under control of Python |
Example
ObjectHandler const& shlublu::Python::controlArgument | ( | ObjectHandler | object | ) |
Places an CPython object under control of Python.
This makes Python aware of this object to include it to its references count handling process.
object | a handler of the object to be controlled. Typical use it to have it implicitely created from a PyObject * pointer obtained from the CPython API |
object
BindingLogicError | if Python is not initialized or if object is already under control |
Example
void shlublu::Python::forgetArgument | ( | ObjectHandler const & | object | ) |
Get rid of a reference of an object under control.
This function allows saving memory by decreasing the reference count of an object that is no longer used without waiting for shutdown()
to do it.
object | a handler of the object to forget |
BindingLogicError | if Python is not initialized, if object is not under control, or if the references count of object is zero or less |
Example
void shlublu::Python::beginCriticalSection | ( | ) |
Enters a critical section, preventing other threads from entering any Python critical section.
This function is relevant in multi-threaded applications, either to guarantee data consistency or to prevent concurrent calls to native or CPython functions from causing a crash (see note regarding concurrency in the detailed description of this namespace).
Calls to this function should be followed in the same thread by as many calls to endCriticalSection()
. Not doing so is a cause of deadlocks.
BindingLogicError | if Python is not initialized. |
Example
void shlublu::Python::endCriticalSection | ( | ) |
Exits a critical section, allowing other threads to enter a Python critical section.
Calls to this function should match calls to beginCriticalSection()
performed in the same thread.
BindingLogicError | if this call doesn't match a previous call to beginCriticalSection() performed in the same thread. |
bool shlublu::Python::operator== | ( | ObjectHandler const & | lhs, |
ObjectHandler const & | rhs | ||
) |
Equality operator.
Compare use cases represented by two instances ObjectHandler. Refers to the ID to do so as two identical ID should come with two identical object pointers while the reverse is not true.
lhs | left operand |
rhs | right operand |
bool shlublu::Python::operator!= | ( | ObjectHandler const & | lhs, |
ObjectHandler const & | rhs | ||
) |
Inequality operator.
Compare use cases represented by two instances ObjectHandler. Refers to the ID to do so as two identical ID should come with two identical object pointers while the reverse is not true.
lhs | left operand |
rhs | right operand |
const std::string shlublu::Python::moduleMain |
Main module ("__main__").
Imported automatically at init()
time.
const std::string shlublu::Python::moduleBuiltins |
Built-ins module ("builtins").
Imported automatically at init()
time.