Utility Functions

String

The following two functions (py3_str() and py3_b()) are commonly used utility functions, and so they are exposed directly in the kaa namespace.

kaa.py3_str(value, encoding=None, desperate=True, coerce=False, fs=False)

Convert (if necessary) the given value to a (unicode) string.

Parameters:
  • value – the value to be converted to a unicode string
  • encoding (str) – the character set to first try to decode as; if None, will use the system default (from the locale).
  • desperate (bool) – if True and decoding to the given (or default) charset fails, will also try utf-8 and latin-1 (in that order), and if those fail, will decode as the preferred charset, replacing unknown characters with \uFFFD.
  • coerce (bool) – if True, will coerce numeric types to a unicode string; if False, such values will be returned untouched.
  • fs (bool) – indicates value is a file name or other environment string; if True, the encoding (if not explicitly specified) will be the encoding given by sys.getfilesystemencoding() and the error handler used will be surrogateescape if supported.
Returns:

the value as a (unicode) string, or the original value if coerce is False and the value was not a bytes or string.

Note

The naming of str is relative Python 3’s notion of a str object, hence the py3_ prefix. On Python 2, the returned value is a unicode object while on Python 3, the returned value is a str object.

kaa.py3_b(value, encoding=None, desperate=True, coerce=False, fs=False)

Convert (if necessary) the given value to a “string of bytes”, agnostic to any character encoding.

Parameters:
  • value – the value to be converted to a string of bytes
  • encoding (str) – the character set to first try to encode to; if None, will use the system default (from the locale).
  • desperate (bool) – if True and encoding to the given (or default) charset fails, will also try utf-8 and latin-1 (in that order), and if those fail, will encode to the preferred charset, replacing unknown characters with \uFFFD.
  • coerce (bool) – if True, will coerce numeric types to a bytes object; if False, such values will be returned untouched.
  • fs (bool) – indicates value is a file name or other environment string; if True, the encoding (if not explicitly specified) will be the encoding given by sys.getfilesystemencoding() and the error handler used will be surrogateescape if supported.
Returns:

the value as a string of bytes, or the original value if coerce is False and the value was not a bytes or string.

Note

The notion of “bytes” was introduced in Python 3 (and included in Python 2.6 as an alias to str), hence the py3_ prefix. On Python 2, the returned value is a str object while on Python 3, the returned value is a bytes object.

kaa.strutils.nativestr(s, encoding=None, desperate=True, coerce=False, fs=False)

Returns a string object native to the current Python version, converting between types if needed.

Parameters:s – bytes or unicode object to convert

This is useful for functions like __str__ which expects a native string type.

kaa.strutils.fsname(s)

Return an object appropriate to represent a filename for the current Python version.

Parameters:s – the filename to decode if needed (Python 3) or encode if needed (Python 2)

Python 2 returns a non-unicode string, while Python 3 returns a unicode string using the surrogateescape handler. See PEP 383.

Note

This is a convenience function, equivalent to:

nativestr(s, fs=True, desperate=False)
kaa.strutils.utf8(s)

Returns a UTF-8 string, converting from other character sets if necessary.

kaa.strutils.get_encoding()

Return the current encoding.

kaa.strutils.set_encoding(encoding)

Set default character encoding. This function also sets the global Python encoding.

kaa.strutils.format(s, *args)

Format a string and make sure all string or unicode arguments are converted to the correct type.

kaa.strutils.BYTES_TYPE
kaa.strutils.UNICODE_TYPE

Date and Time

TODO: utc, local

Miscellaneous

TODO: property

kaa.utils.tempfile(name, unique=False)

Return a filename in the secure kaa tmp directory with the given name. Name can also be a relative path in the temp directory, directories will be created if missing. If unique is set, it will return a unique name based on the given name.

kaa.utils.which(file, path=None)

Does what which(1) does: searches the PATH in order for a given file name and returns the full path to first match.

kaa.utils.fork()

Forks the process. May safely be called after the main loop has been started.

kaa.utils.daemonize(stdin='/dev/null', stdout='/dev/null', stderr=None, pidfile=None, exit=True, wait=False)

Does a double-fork to daemonize the current process using the technique described at http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16 .

If exit is True (default), parent exits immediately. If false, caller will receive the pid of the forked child.

kaa.utils.is_running(name)

Check if the program with the given name is running. The program must have called set_running itself. Returns the pid or 0.

kaa.utils.set_running(name, modify=True)

Set this program as running with the given name. If modify is True, the process name is updated as described in set_process_name().

kaa.utils.set_process_name(name)

On Linux systems later than 2.6.9, this function sets the process name as it appears in ps, and so that it can be found with killall(1) and pidof(8).

Note

name will be truncated to the cumulative length of the original process name and all its arguments; once updated, passed arguments will no longer be visible.

This function currently only works properly with Python 2. With Python 3, the process will be found with killall(1), but ps(1) and pidof(8) will not see the new name.

kaa.utils.get_num_cpus()

Returns the number of processors on the system, or raises RuntimeError if that value cannot be determined.

kaa.utils.get_machine_uuid()

Returns a unique (and hopefully persistent) identifier for the current machine.

This function will return the D-Bus UUID if it exists (which should be available on modern Linuxes), otherwise it will return the machine’s hostname.

kaa.utils.get_plugins(group=None, location=None, attr=None, filter=None, scope=None)

Flexible plugin loader, supporting Python eggs as well as on-disk trees. All modules at the specified location or entry point group (for eggs) are loaded and returned as a dict mapping plugin names to plugin objects.

Parameters:
  • group (str or None) – a setuptools entry point group name (more below)
  • location (str or None) – path within which to load plugins. If a filename is included, it will be stripped, which means you can conveniently pass __file__ here. Paths inside eggs are also supported. All modules at the given location will be imported except for __init__.
  • attr (str or None) – if specified, this attribute is fetched from all modules loaded from the specified location and used as the value in the plugin dict; if not specified, the module itself is used as the module.
  • filter (callable or None) – an optional callable to which all candidate module names found at location will be passed. If the filter returns a zero value that module will skipped, otherwise it will be imported; if the filter returns a string, it specifies the name of a module to be imported instead.
  • scope (dict) – the global scope to use when importing plugin modules. If this is not specified, the caller’s scope will be used (using stack inspection trickery). If get_plugins() is being called indirectly, you will need to pass through the value of globals().
Returns:

a dict mapping plugin names to plugin objects.

If a plugin raises an exception while it is being imported, the value in the returned dictionary for that plugin will be the Exception object that was raised.

Plugins can be loaded by one or both of the following methods:
  1. Loading modules from a specified directory location either on-disk or inside a zipped egg
  2. Entry point groups offered by setuptools

Method 1 is the more traditional approach to plugins in Python. For example, you might have a directory structure like:

module/
    plugins/
        __init__.py
        plugin1.py
        plugin2.py

There is typically logic inside plugins/__init__.py to import all other files in the same directory (os.path.dirname(__file__)). It can pass location=__file__ to kaa.utils.get_plugins() to do this:

>>> kaa.utils.get_plugins(location=__file__)
{'plugin1': <module 'module.plugins.plugin1' from '.../module/plugins/plugin1.py'>, 
 'plugin2': <module 'module.plugins.plugin2' from '.../module/plugins/plugin2.py'>}

Note

Plugins will be imported relative to the caller’s module name. So if the caller is module module.plugins, plugin1 will be imported as module.plugins.plugin1.

This also works when plugins/__init__.py is inside a zipped egg. However, if you reference __file__ as above, setuptools (assuming it’s available on the system), when it examines the source code during installation, will think it’s not safe to zip the tree into an egg file, and so it will install it as an on-disk directory tree instead. You can override this by passing zip_safe=True to setup() in the setup script for the application that loads plugins.

Method 2 is the approach to take when setuptools is available. Plugin modules register themselves with an entry point group name. For example, a plugin module’s setup.py may call setup() with:

setup(
    module='myplugin',
    # ...
    plugins = {'someapplication.plugins': 'src/submodule'},
    entry_points = {'someapplication.plugins': 'plugname = myplugin.submodule:SomeClass'},
)

When SomeApplication wants to load all registered modules, it can do:

>>> kaa.utils.get_plugins(group='someapplication.plugins')
{'plugname': <class myplugin.submodule.SomeClass at 0xdeadbeef>}

The entry_points kwarg specified in the plugin module can specify multiple plugin names, and SomeClass could be any python object, as long as it is exposed within myplugin.submodule. For more information on entry points, refer to setuptools documentation.

It is possible and in fact recommended to mix both methods. (If your project makes setuptools a mandatory dependency, then you can use entry point groups exclusively.) If group is not specified, then it becomes impossible for either the application or the plugin to be installed as eggs.

The attr kwarg makes it more convenient to combine both methods. Plugins loaded from entry points will be SomeClass objects. If (assuming now the application is not installed as a zipped egg but rather an on-disk source tree) some plugins were installed to the applications source tree, while others installed as eggs registered with the entry point group, you would want to pull SomeClass from those modules loaded from location. So:

>>> kaa.utils.get_plugins(group='someapplication.plugins', location=__file__, attr='SomeClass')
{'plugin1': <class module.plugins.plugin1.SomeClass at 0xdeadbeef>,
 'plugin2': <class module.plugins.plugin2.SomeClass at 0xcafebabe>,
 'plugname': <class myplugin.submodule.SomeClass at 0xbaadf00d>}
kaa.utils.wraps(origfunc, lshift=0)

Decorator factory: used to create a decorator that assumes the same attributes (name, docstring, signature) as its decorated function when sphinx has been imported. This is necessary because sphinx uses introspection to construct the documentation.

This logic is inspired from Michele Simionato’s decorator module.

>>> def decorator(func):
...     @wraps(func)
...     def newfunc(*args, **kwargs):
...             # custom logic here ...
...             return func(*args, **kwargs)
...     return newfunc
Parameters:
  • origfunc – the original function being decorated which is to be wrapped.
  • lshift – number of arguments to shift from the left of the original function’s call spec. Wrapped function will have this nubmer of arguments removed.
Returns:

a decorator which has the attributes of the decorated function.

class kaa.utils.DecoratorDataStore(func, newfunc=None, newfunc_args=None, identifier=None)

A utility class for decorators that sets or gets a value to/from a decorated function. Attributes of instances of this class can be get, set, or deleted, and those attributes are associated with the decorated function.

The object to which the data is attached is either the function itself for non-method, or the instance object for methods.

There are two possible perspectives of using the data store: from inside the decorator, and from outside the decorator. This allows, for example, a method to access data stored by one of its decorators.

kaa.utils.weakref(cls, object)

This class represents a weak reference based on the python module weakref. The difference between weakref.ref and this class is that you can access the ref without calling it first. E.g.: foo = weak(bar) and bar has the attribute x. With a normal weakref.ref you need to call foo().x to get, this class makes it possible to just use foo.x.

All functions are passed to the real object behind the weakref. To check if the weakref is alive or not, you can compare the object with None. Do not use a simple if, because an object still alive can also be False (e.g. an empty list).

IOCTL

The kaa.ioctl module provides functions for the C-level ioctl macros that are defined in /usr/include/asm-generic/ioctl.h used for creating and decoding ioctl numbers.

kaa.ioctl.IO(type, nr)
kaa.ioctl.IOR(type, nr, size)
kaa.ioctl.IOR(type, nr, size)
kaa.ioctl.IOWR(type, nr, size)
kaa.ioctl.IOC_DIR(nr)
kaa.ioctl.IOC_TYPE(nr)
kaa.ioctl.IOC_NR(nr)
kaa.ioctl.IOC_SIZE(nr)
kaa.ioctl.ioctl(fd, code, *args, **kargs)

Table Of Contents

Previous topic

INotify

Next topic

Input Plugins

This Page