API references

Subpackages

Submodules

pyclibrary.c_library module

Proxy to library object, allowing automatic type conversion and function calling based on C header definitions.

pyclibrary.c_library.make_mess(mess)[source]
class pyclibrary.c_library.CLibraryMeta(name, bases, dct)[source]

Bases: type

Meta class responsible for determining the backend and ensuring no duplicates libraries exists.

backends = {'ctypes': <class 'pyclibrary.backends.ctypes.CTypesCLibrary'>}
libs = <WeakValueDictionary>
class pyclibrary.c_library.CLibrary(lib, *args, **kwargs)[source]

Bases: object

The CLibrary class is intended to automate much of the work in using ctypes by integrating header file definitions from CParser. This class serves as a proxy to a backend, adding a few features:

  • allows easy access to values defined via CParser.

  • automatic type conversions for function calls using CParser function signatures.

  • creates ctype classes based on type definitions from CParser.

Initialize using a ctypes shared object and a CParser: >>> headers = CParser.winDefs() >>> lib = CLibrary(windll.User32, headers)

There are 3 ways to access library elements:

  • lib(type, name):

    type can be one of ‘values’, ‘functions’, ‘types’, ‘structs’, ‘unions’, or ‘enums’. Returns an object matching name. For values, the value from the headers is returned. For functions, a callable object is returned that handles automatic type conversion for arguments and return values. For structs, types, and enums, a ctypes class is returned matching the type specified.

  • lib.name:

    searches in order through values, functions, types, structs, unions, and enums from header definitions and returns an object for the first match found. The object returned is the same as returned by lib(type, name). This is the preferred way to access elements from CLibrary, but may not work in some situations (for example, if a struct and variable share the same name).

  • lib[type]:

    Accesses the header definitions directly, returns definition dictionaries based on the type requested. This is equivalent to headers.defs[type].

Parameters
  • lib – Library object.

  • headers (unicode or CParser) – Path to the header files or CParser holding all the definitions.

  • prefix (unicode, optional) – Prefix to remove from all definitions.

  • lock_calls (bool, optional) – Whether or not to lock the calls to the underlying library. This should be used only if the underlying library is not thread safe.

  • convention ({'cdll', 'windll', 'oledll'}) – Calling convention to use. Not all backends supports all calling conventions.

  • backend (unicode, optional) – Name of the backend to use. This is ignored if an already initialised library object is passed. NB : this kwarg is used by the metaclass.

  • kwargs – Additional keywords argument which are passed to the CParser if one is created.

Null = <object object>

Balise to use when a NULL pointer is needed

class pyclibrary.c_library.CFunction(lib, func, sig, name, lock_call)[source]

Bases: object

Wrapper object for a function from the library.

arg_c_type(arg)[source]

Return the type required for the specified argument.

Parameters

arg (int or unicode) – Name or index of the argument whose type should be returned.

pretty_signature()[source]
class pyclibrary.c_library.CallResult(lib, rval, args, sig, guessed)[source]

Bases: object

Class for bundling results from C function calls.

Allows access to the function value as well as all of the arguments, since the function call will often return extra values via these arguments:

  • Original ctype objects can be accessed via result.rval or result.args

  • Python values carried by these objects can be accessed using ()

To access values:

  • The return value: ()

  • The nth argument passed: [n]

  • The argument by name: [‘name’]

  • All values that were auto-generated: .auto()

The class can also be used as an iterator, so that tuple unpacking is possible:

>>> ret, (arg1, arg2) = lib.run_some_function(...)
lib

Reference to the CLibrary to which the function that created this object balongs.

Type

CLibrary

rval

Value returned by the C function.

args

Arguments passed to the C function.

Type

tuple

sig

Signature of the function which created this object.

guessed

Pointers that were created on the fly.

Type

tuple

find_arg(arg)[source]

Find argument based on name.

auto()[source]

Return a list of all the auto-generated values.

Pointers are dereferenced.

pyclibrary.c_library.cast_to(lib, obj, typ)[source]

Cast obj to a new type.

Parameters
  • lib (CLibrary) – Reference to the library to which the object ‘belongs’. This is needed as the way to get the address depends on the backend.

  • obj

    Object whose address should be returned.

    typetype or string

    Type object or string which will be used to determine the type of the array elements.

pyclibrary.c_library.build_array(lib, typ, size, vals=None)[source]

Build an array of the specified type and the specified size.

Parameters
  • lib (CLibrary) – Reference to the library with which this object will be used. This is needed as the way to build the array depends on the backend.

  • type (type or string) – Type object or string which will be used to determine the type of the array elements.

  • size (int or tuple) – Dimensions of the array to create.

  • vals (list, optional) – Initial values with which to fill the array.

pyclibrary.c_parser module

Used for extracting data such as macro definitions, variables, typedefs, and function signatures from C header files.

pyclibrary.c_parser.win_defs(version='1500')[source]

Loads selection of windows headers included with PyCLibrary.

These definitions can either be accessed directly or included before parsing another file like this: >>> windefs = c_parser.win_defs() >>> p = c_parser.CParser(“headerFile.h”, copy_from=windefs)

Definitions are pulled from a selection of header files included in Visual Studio (possibly not legal to distribute? Who knows.), some of which have been abridged because they take so long to parse.

Parameters

version (unicode) – Version of the MSVC to consider when parsing.

Returns

parser – CParser containing all the infos from te windows headers.

Return type

CParser

class pyclibrary.c_parser.CParser(files=None, copy_from=None, replace=None, process_all=True, cache=None, check_cache_validity=True, **kwargs)[source]

Bases: object

Class for parsing C code to extract variable, struct, enum, and function declarations as well as preprocessor macros.

This is not a complete C parser; instead, it is meant to simplify the process of extracting definitions from header files in the absence of a complete build system. Many files will require some amount of manual intervention to parse properly (see ‘replace’ and extra arguments)

Parameters
  • files (str or iterable, optional) – File or files which should be parsed.

  • copy_from (CParser or iterable of CParser, optional) – CParser whose definitions should be included.

  • replace (dict, optional) – Specify som string replacements to perform before parsing. Format is {‘searchStr’: ‘replaceStr’, …}

  • process_all (bool, optional) – Flag indicating whether files should be parsed immediatly. True by default.

  • cache (unicode, optional) – Path of the cache file from which to load definitions/to which save definitions as parsing is an expensive operation.

  • check_cache_validity (bool, optional) – Flag indicating whether to perform validity checking when using a cache file. This is useful in a scenario where the python wrapper needs to be used without access to the headers

  • kwargs – Extra parameters may be used to specify the starting state of the parser. For example, one could provide a set of missing type declarations by types={‘UINT’: (‘unsigned int’), ‘STRING’: (‘char’, 1)} Similarly, preprocessor macros can be specified: macros={‘WINAPI’: ‘’}

Example

Create parser object, load two files

>>> p = CParser(['header1.h', 'header2.h'])

Remove comments, preprocess, and search for declarations

>>> p.process_ all()

Just to see what was successfully parsed from the files

>>> p.print_all()

Access parsed declarations

>>> all_values = p.defs['values']
>>> functionSignatures = p.defs['functions']

To see what was not successfully parsed

>>> unp = p.process_all(return_unparsed=True)
>>> for s in unp:
        print s
cache_version = 2
process_all(cache=None, return_unparsed=False, print_after_preprocess=False, check_cache_validity=True)[source]

Remove comments, preprocess, and parse declarations from all files.

This operates in memory, and thus does not alter the original files.

Parameters
  • cache (unicode, optional) – File path where cached results are be stored or retrieved. The cache is automatically invalidated if any of the arguments to __init__ are changed, or if the C files are newer than the cache.

  • return_unparsed (bool, optional) – Passed directly to parse_defs.

  • print_after_preprocess (bool, optional) – If true prints the result of preprocessing each file.

Returns

results – List of the results from parse_defs.

Return type

list

load_cache(cache_file, check_validity=False)[source]

Load a cache file.

Used internally if cache is specified in process_all().

Parameters
  • cache_file (unicode) – Path of the file from which the cache should be loaded.

  • check_validity (bool, optional) –

    If True, then run several checks before loading the cache:
    • cache file must not be older than any source files

    • cache file must not be older than this library file

    • options recorded in cache must match options used to initialize CParser

Returns

result – Did the loading succeeded.

Return type

bool

import_dict(data)[source]

Import definitions from a dictionary.

The dict format should be the same as CParser.file_defs. Used internally; does not need to be called manually.

write_cache(cache_file)[source]

Store all parsed declarations to cache. Used internally.

find_headers(headers)[source]

Try to find the specified headers.

load_file(path, replace=None)[source]

Read a file, make replacements if requested.

Called by __init__, should not be called manually.

Parameters
  • path (unicode) – Path of the file to load.

  • replace (dict, optional) – Dictionary containing strings to replace by the associated value when loading the file.

print_all(filename=None)[source]

Print everything parsed from files. Useful for debugging.

Parameters

filename (unicode, optional) – Name of the file whose definition should be printed.

remove_comments(path)[source]

Remove all comments from file.

Operates in memory, does not alter the original files.

preprocess(path)[source]

Scan named file for preprocessor directives, removing them while expanding macros.

Operates in memory, does not alter the original files.

Currently support : - conditionals : ifdef, ifndef, if, elif, else (defined can be used in a if statement). - definition : define, undef - pragmas : pragma

eval_preprocessor_expr(expr)[source]
process_macro_defn(t)[source]

Parse a #define macro and register the definition.

compile_fn_macro(text, args)[source]

Turn a function macro spec into a compiled description.

expand_macros(line)[source]

Expand all the macro expressions in a string.

Faulty calls to macro function are left untouched.

expand_fn_macro(name, text)[source]

Replace a function macro.

parse_defs(path, return_unparsed=False)[source]

Scan through the named file for variable, struct, enum, and function declarations.

Parameters
  • path (unicode) – Path of the file to parse for definitions.

  • return_unparsed (bool, optional) – If true, return a string of all lines that failed to match (for debugging purposes).

Returns

tokens – Entire tree of successfully parsed tokens.

Return type

list

build_parser()[source]

Builds the entire tree of parser elements for the C language (the bits we support, anyway).

process_declarator(decl)[source]

Process a declarator (without base type) and return a tuple (name, [modifiers])

See process_type(…) for more information.

process_type(typ, decl)[source]

Take a declarator + base type and return a serialized name/type description.

The description will be a list of elements (name, [basetype, modifier, modifier, …]):

  • name is the string name of the declarator or None for an abstract declarator

  • basetype is the string representing the base type

  • modifiers can be:

    • * : pointer (multiple pointers *** allowed)

    • & : reference

    • __X : calling convention (windows only). X can be cdecl or stdcall

    • list : array. Value(s) indicate the length of each array, -1 for incomplete type.

    • tuple : function, items are the output of processType for each function argument.

Examples

  • int x[10] => (‘x’, [‘int’, [10], ‘’])

  • char fn(int x) => (‘fn’, [‘char’, [(‘x’, [‘int’])]])

  • struct s (*)(int, int*) => (None, [“struct s”, ((None, [‘int’]), (None, [‘int’, ‘*’])), ‘*’])

process_enum(s, l, t)[source]
process_function(s, l, t)[source]

Build a function definition from the parsing tokens.

packing_at(line)[source]

Return the structure packing value at the given line number.

process_struct(s, l, t)[source]
process_variable(s, l, t)[source]
process_typedef(s, l, t)[source]
eval_expr(toks)[source]

Evaluates expressions.

Currently only works for expressions that also happen to be valid python expressions.

eval(expr, *args)[source]

Just eval with a little extra robustness.

add_def(typ, name, val)[source]

Add a definition of a specific type to both the definition set for the current file and the global definition set.

rem_def(typ, name)[source]

Remove a definition of a specific type to both the definition set for the current file and the global definition set.

is_fund_type(typ)[source]

Return True if this type is a fundamental C type, struct, or union.

ATTENTION: This function is legacy and should be replaced by Type.is_fund_type()

eval_type(typ)[source]

Evaluate a named type into its fundamental type.

ATTENTION: This function is legacy and should be replaced by Type.eval()

find(name)[source]

Search all definitions for the given name.

find_text(text)[source]

Search all file strings for text, return matching lines.

pyclibrary.errors module

Errors that can happen during parsing or binding.

exception pyclibrary.errors.PyCLibError[source]

Bases: Exception

Base exception for all PyCLibrary exceptions.

exception pyclibrary.errors.DefinitionError[source]

Bases: PyCLibError

Excepion signaling that one definition found in the header is malformed or meaningless.

pyclibrary.init module

Initialisation routines.

Those should be run before creating a CParser and can be run only once. They are used to declare additional types and modifiers for the parser.

pyclibrary.init.init(extra_types=None, extra_modifiers=None)[source]

Init CParser and CLibrary classes.

Parameters
  • extra_types (dict, optional) – typeName->c_type pairs to extend typespace.

  • extra_modifiers (list, optional) – List of modifiers, such as ‘__stdcall’.

pyclibrary.init.auto_init(extra_types=None, extra_modifiers=None, os=None)[source]

Init CParser and CLibrary classes based on the targeted OS.

Parameters
  • extra_types (dict, optional) – Extra typeName->c_type pairs to extend typespace.

  • extra_modifiers (list, optional) – List of extra modifiers, such as ‘__stdcall’.

  • os ({'win32', 'linux2', 'darwin'}, optional) – OS for which to prepare the system. If not specified sys is used to identify the OS.

pyclibrary.utils module

Utility functions to retrieve headers or library path and architecture.

Most of those function have been taken or adapted from the ones found in PyVISA.

Functions

find_header : Find the path to a header file. find_library : Find the path to a shared library from its name.

pyclibrary.utils.add_header_locations(dir_list)[source]

Add directories in which to look for header files.

pyclibrary.utils.find_header(h_name, dirs=None)[source]

Look for a header file.

Headers are looked for in the directories specified by the user using the add_header_locations function, in the headers directory of PyCLibrary, and in the standards locations according to the operation system.

Parameters
  • h_name (unicode) – Name of the header to retrieve (should include the “.h”)

  • dirs (list, optional) – List of directory which should be searched for the header in addition to the default ones.

Returns

path – Path to the header file.

Return type

unicode

:raises OSError : if no matching file can be found.:

pyclibrary.utils.add_library_locations(dir_list)[source]

Add directories in which to look for libraries.

pyclibrary.utils.find_library(name, dirs=None)[source]

Look for a library file.

Libraries are looked for in the directories specified by the user using the add_library_locations function, and using the find_library function found the thirdparty package.

Parameters
  • name (unicode) – Name of the library to retrieve (should include the extension)

  • dirs (list, optional) – List of directory which should be searched for the library before ressorting to using thirdparty.find_library.

Returns

path – Path to the library file.

Return type

unicode

:raises OSError : if no matching file can be found.:

class pyclibrary.utils.LibraryPath(path, found_by='auto')[source]

Bases: str

property arch
property is_32bit
property is_64bit
property bitness
pyclibrary.utils.get_arch(filename)[source]
pyclibrary.utils.get_shared_library_arch(filename)[source]
pyclibrary.utils.check_output(*popenargs, **kwargs)[source]

Run command with arguments and return its output as a byte string.

Backported from Python 2.7 as it’s implemented as pure python on stdlib.

>>> check_output(['/usr/bin/python', '--version'])
Python 2.6.2