Core utilities (pwkit)

A toolkit for science and astronomy in Python.

The toplevel pwkit module includes a few basic abstractions that show up throughout the rest of the codebase. These include:

The Holder namespace object

Holder is a “namespace object” that primarily exists so that you can fill it with named attributes however you want. It’s essentially like a plain dict, but you can write the convenient form myholder.xcoord instead of mydict['xcoord']. It has useful methods like set() and to_pretty() also.

class pwkit.Holder(_Holder__decorating=None, **kwargs)[source]

Create a new Holder. Any keyword arguments will be assigned as properties on the object itself, for instance, o = Holder(foo=1) yields an object such that o.foo is 1.

The __decorating keyword is used to implement the Holder decorator functionality, described below.

get(name[, defval])

Get an attribute on this Holder.

set(**kwargs)

For each keyword argument, sets an attribute on this Holder to its value.

set_one(name, value)

Set a single attribute on this object.

has(name)

Return whether the named attribute has been set on this object.

copy()

Return a shallow copy of this object.

to_dict()

Return a copy of this object converted to a dict.

to_pretty([format])

Return a string with a prettified version of this object’s contents.

Iterating over a Holder yields its contents in the form of a sequence of (name, value) tuples. The stringification of a Holder returns its representation in a dict-like format. Holder objects implement __contains__ so that boolean tests such as "myprop" in myholder act sensibly.

get(name, defval=None)[source]

Get an attribute on this Holder.

Equivalent to getattr(self, name, defval).

set(**kwargs)[source]

For each keyword argument, sets an attribute on this Holder to its value.

Equivalent to:

for key, value in kwargs.iteritems():
  setattr(self, key, value)

Returns self.

set_one(name, value)[source]

Set a single attribute on this object.

Equivalent to setattr(self, name, value). Returns self.

has(name)[source]

Return whether the named attribute has been set on this object.

This can more naturally be expressed by writing name in self.

copy()[source]

Return a shallow copy of this object.

to_dict()[source]

Return a copy of this object converted to a dict.

to_pretty(format='str')[source]

Return a string with a prettified version of this object’s contents.

The format is a multiline string where each line is of the form key = value. If the format argument is equal to "str", each value is the stringification of the value; if it is "repr", it is its repr().

Calling str() on a Holder returns a slightly different pretty stringification that uses a textual representation similar to a Python dict literal.

@pwkit.Holder[source]

The Holder class may also be used as a decorator on a class definition to transform its contents into a Holder instance. Writing:

@Holder
class mydata ():
    a = 1
    b = 'hello'

creates a Holder instance named mydata containing names a and b. This can be a convenient way to populate one-off data structures.

Utilities for exceptions

class pwkit.PKError(fmt, *args)[source]

A generic base class for exceptions.

All custom exceptions raised by pwkit modules should be subclasses of this class.

The constructor automatically applies old-fashioned printf-like (%-based) string formatting if more than one argument is given:

PKError('my format string says %r, %d', myobj, 12345)
# has text content equal to:
'my format string says %r, %d' % (myobj, 12345)

If only a single argument is given, the exception text is its stringification without applying printf-style formatting.

pwkit.reraise_context(fmt, *args)[source]

Reraise an exception with its message modified to specify additional context.

This function tries to help provide context when a piece of code encounters an exception while trying to get something done, and it wishes to propagate contextual information farther up the call stack. It only makes sense in Python 2, which does not provide Python 3’s exception chaining functionality. Instead of that more sophisticated infrastructure, this function just modifies the textual message associated with the exception being raised.

If only a single argument is supplied, the exception text prepended with the stringification of that argument. If multiple arguments are supplied, the first argument is treated as an old-fashioned printf-type (%-based) format string, and the remaining arguments are the formatted values.

Example usage:

from pwkit import reraise_context
from pwkit.io import Path

filename = 'my-filename.txt'

try:
  f = Path(filename).open('rt')
  for line in f.readlines():
    # do stuff ...
except Exception as e:
  reraise_context('while reading "%r"', filename)
  # The exception is reraised and so control leaves this function.

If an exception with text "bad value" were to be raised inside the try block in the above example, its text would be modified to read "while reading "my-filename.txt": bad value".

Abstractions between Python versions 2 and 3

The toplevel pwkit module defines the following variables as a holdover from the times when it was concerned with compatibility between Python 2 and Python 3:

  • binary_type

  • text_type

pwkit.unicode_to_str(s)

A function for implementing the __str__ method of classes, the meaning of which differs between Python versions 2 and 3. In all cases, you should implement __unicode__ on your classes. Setting the __str__ property of a class to unicode_to_str() will cause it to Do The Right Thing™, which means returning the UTF-8 encoded version of its Unicode expression in Python 2, or returning the Unicode expression directly in Python 3:

import pwkit

class MyClass (object):
    def __unicode__ (self):
        return u'my value'

    __str__ = pwkit.unicode_to_str