CSlug API Reference
Module contents
- class cslug.CSlug(path, *sources, headers=(), links=(), flags=())[source]
Compiles and loads C code in a relatively safe and streamlined manner.
- __init__(path, *sources, headers=(), links=(), flags=())[source]
- Parameters:
path (str or os.PathLike or list)
*sources (str or os.PathLike or io.TextIOBase) – C source code files. May also be lists of files.
headers (cslug.Header or list[cslug.Header]) – cslug generated headers - not just
*.hfiles (which cslug doesn't need to see anywhere).links (str or list[str]) – Other C libraries to link to via the
-lcompiler switch. Should not contain the-lprefix or platform suffix.flags (str or list[str]) – Additional flags to be passed directly to the C compiler. Can also be configured using the
CFLAGSorCC_FLAGSenvironment variable. Inspect usingcompile_command.
Changed in version 0.3.0: Add flags parameter and the
CC_FLAGSvariable.Changed in version 1.0.0: Add
CFLAGSalias forCC_FLAGS.
- close(all=True)[source]
Close the library stored in
CSlug.dll.- Parameters:
all (bool) – Close any other existing handles to the same file.
Closing is required before a recompile to avoid permission errors or dangling pointers. If the library is already closed, this function silently does nothing.
- compile()[source]
Recompile C code only.
- Returns:
True if the compile succeeded. However this is redundant because an error is raised if it didn't.
- Return type:
- Raises:
exceptions.BuildError – Any compiler errors are propagated as Python exceptions.
- Warns:
exceptions.BuildWarning – Any build warnings from the compiler are propagated as Python warnings.
- compile_command(_cc=None, _cc_version=None)[source]
Get the compile command invoked by
compile.I hope to eventually make this function configurable.
- property dll
The open C library.
- Return type:
This attribute is lazily loaded. On first access, this
propertywill:Check the library has been compiled and invoke a full compile with
makeif it hasn't.Open the library.
Initialise type information for all known symbols (functions).
Use
closeto reset.
- make()[source]
Invoke a full recompile and refresh of everything.
- Returns:
True if the build succeeded.
- Return type:
Everything here is defined as the following sequence in the following order:
closeany open handles.Rebuild each
HeaderinheadersusingHeader.make.Recompile the shared library using :meth`compile`.
Rescan C source code for type information and write it to a json file.
The C library is loaded back into Python on next access of
dll.
- cslug.anchor(*paths)[source]
Replace relative paths with frozen paths relative to
__file__'s parent.- Parameters:
paths (str or os.PathLike or io.IOBase) – Path(s) to freeze or pseudo files.
- Returns:
List of modified paths.
- Return type:
Pseudo files (
io.IOBase) and absolute paths are left unchanged. Use this function to make your code working-dir independent.
- class cslug.Header(path, *sources, includes=(), defines=())[source]
Automatically generate a header file.
For every function in every source file, generate a prototype for it. Use to automate the unfortunate copy/pasting required for multiple source files to interact with each other.
Using a header like this globalises every function. Whilst this type of namespace collapsing would normally be discouraged, a shared library does not allow naming collisions anyway so there is little to no advantage in keeping namespaces separate.
- class cslug.Types(path, *sources, headers=(), compact=True)[source]
Manages type information which is not found in a shared libraryAn executable file containing definitions (function/variables/...) but no main method..
Scans source code for:
The name, argument and return types of each function.
The name, field names, types and bit-field sizes of structures.
Stores the above in a portable and quickly deserializable json file.
Sets the types for the contents of a
ctypes.CDLL.
- __init__(path, *sources, headers=(), compact=True)[source]
- Parameters:
path (str or os.PathLike or io.TextIOBase) – A filename to read or write serialised type information to.
*sources (str or os.PathLike or io.TextIOBase) – C sources to extract function definitions from.
headers (str or os.PathLike or io.TextIOBase or list) – C sources to extract function prototypes from.
compact (bool) – If true, serialise minimising file size. Otherwise, pretty format for human readability.
Note the distinction between sources and headers. A function prototype such as
int foo();will be ignored if found in sources but included if it were in headers. A true function definition such asint foo() {}, as well as structure definitions would be collected in either case.
- apply(dll, strict=False)[source]
Set the type information for the contents of dll.
- Parameters:
dll (ctypes.CDLL) – The opened shared libraryAn executable file containing definitions (function/variables/...) but no main method. to apply type information to.
strict (bool) – Raise an
AttributeErrorif a symbol wasn't found.
For every structure in
self.structs, turn it into actypes.Structureand set it as an attribute of dll. For every function inself.functions, get it from dll then set itsargtypesandrestypeattributes.Note
Structures don't normally go in shared librariesAn executable file containing definitions (function/variables/...) but no main method. but cslug lobs them in there for simplicity.
- property functions: dict
All functions (from true definitions of prototypes).
The format is:
function_name: [return_type, [arg_type, arg_type, ...]]
All types are strings - either names of structures or attribute names of
ctypes.
- json_path: TextIOBase | Path
File to read or write the json.
- property structs: dict
All structures defined using
typedef struct {...} name.The format is:
name: [(field_name, field_type), ...]
Or for bit-field structs:
name: [(field_name, field_type, bit_length), ...]
- types: dict
All type information collected. This is broken out into
functionsandstructs.Note that this attribute is not set automatically. You must explicitly call either
init_from_sourceorinit_from_jsonbefore accessing.
- write(path=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>)[source]
Serialise contents to path.
- Parameters:
path (str or os.PathLike or io.TextIOBase) – A filename or stream to write to. Defaults to
sys.stdout.
- cslug.ptr(bytes_like)[source]
Get the raw address of any Python object supporting the C buffer protocol.
A bytes-like object is anything for which calling
memoryview(obj)doesn't raise aTypeError. This includesbytes,bytearray,memoryview,array.arrayandnumpy.array. The output is a subclass ofint.>>> from cslug import ptr >>> ptr(bytearray([10, 12, 20, 45])) <Void Pointer 140533125025616>
Pass the output of this function to a C function which expects a pointer.
On calling this function on a buffer, the buffer's reference count is incremented to prevent it from being deleted whilst you're still using it. This reference count is decremented on deletion of the pointer returned by this function. With this in place, you generally shouldn't need to worry about holding onto or releasing memory. There is one exception to this: If you use pointer arithmetic, preducts of that arithmetic are just regular integers and do not carry the reference.
If you are using
numpythen you should be aware that this method only accepts C-contiguous buffers. If you understand how contiguity works and have explicitly supported non-contiguous buffers in your C code then you may usenc_ptrinstead. Otherwise convert your arrays to contiguous ones using either:array = np.ascontiguousarray(array)
or:
array = np.asarray(array, order="C")
- cslug.nc_ptr(bytes_like)[source]
Retrieve a pointer to a non-contiguous buffer.
Use with caution. If your function assumes a contiguous array but gets a non-contiguous one then you will either get garbage results or memory errors.
- class cslug.PointerType(bytes_like, flags)[source]
Bases:
intA raw pointer which inc-refs the buffer it points to.
Please no not instantiate this class directly. Instead use the
ptr()function.
- cslug.cc(CC=None)[source]
Get the full path of the C compiler.
- Parameters:
CC – Value to override the CC environment variable.
- Returns:
Full path of the C compiler.
- Return type:
- Raises:
exceptions.NoGccError – If CC is unset and gcc was not found in
PATH.exceptions.CCNotFoundError – If CC is set but couldn't be found.
exceptions.BuildBlockedError – If CC is set to
!block.
The C compiler is chosen by the CC environment variable.
If CC is unset then it defaults to
gcc.If CC is a name, such as
gccorclang, then it is searched for inPATH(respectingPATHEXTon Windows).If CC is a relative path, such as
./gcc, then it is made absolute.If CC is an absolute path then it is returned as is.
If CC is
!blockthen an error is raised. This can be used to test your pre-built package works without a compiler.
Note
The value of CC should never be wrapped in quotes.
- cslug.cc_version(CC=None)[source]
Get C compiler's name and version.
The
nameis determined by parsing the output of$CC -v(or%CC% -von Windows). It can be:'gcc'for gcc (both 32 and 64 bit).'tcc'for TinyCC including the 32-biti386-win32-tccversion.'clang'for clang.'pcc'for Portable C Compiler.'PGCC'for pgcc.
The
version_infois in the standard(major, minor, micro)version format.