armi.utils.flags module

A Flag class, similar to enum.Flag.

This is an alternate implementation of the standard-library enum.Flag class. We use this to implement armi.reactor.flags.Flags. We used to use the standard-library implementation, but that became limiting when we wanted to make it possible for plugins to define their own flags; the standard implementation does not support extension. We also considered the aenum package, which permits extension of Enum classes, but unfortunately does not support extension of Flags. So, we had to make our own. This is a much simplified version of what comes with aenum, but still provides most of the safety and functionality.

There is an issue on the aenum bitbucket site to track Flag extension.

class armi.utils.flags.auto[source]

Bases: object

Empty class for requesting a lazily-evaluated automatic field value.

This can be used to automatically provision a value for a field, when the specific value does not matter.

In the future, it would be nice to support some arithmetic for these so that automatically-derived combinations of other automatically defined fields can be specified as well.

class armi.utils.flags.Flag(init=0)[source]

Bases: object

A collection of bitwise flags.

This is intended to emulate enum.Flag, except with the possibility of extension after the class has been defined. Most docs for enum.Flag should be relevant here, but there are sure to be occasional differences.

Warning

Python features arbitrary-width integers, allowing one to represent an practically unlimited number of fields. However, including more flags than can be represented in the system-native integer types may lead to strange behavior when interfacing with non-pure Python code. For instance, exceeding 64 fields makes the underlying value not trivially-storable in an HDF5 file. If we ever want to store flags in an HDF5 file, we will need to develop some method of encoding these when they are too wide.

classmethod extend(fields: Dict[str, Union[int, armi.utils.flags.auto]])[source]

Extend the Flags object with new fields.

Warning

This alters the class that it is called upon! Existing instances should see the new data, since classes are mutable.

Parameters

fields (dict) – A dictionary containing field names as keys, and their desired values, or an instance of auto as values.

Example

>>> class MyFlags(Flags):
...     FOO = auto()
...     BAR = 1
...     BAZ = auto()
>>> MyFlags.extend({
...     "SUPER": auto()
... })
>>> print(MyFlags.SUPER)
<MyFlags.SUPER: 8>
__invert__()[source]

Implement unary ~.

Note

This is avoiding just ~ on the _value because it might not be safe. Using the int directly is slightly dangerous in that python ints are not of fixed width, so the result of inverting one Flag might not be as wide as the result of inverting another Flag. Typically, one would want to invert a Flag to create a mask for unsetting a bit on another Flag, like f1 &= ~f2. If f2 is narrower than f1 the field of ones that you need to keep f1 bits on might not cover the width of f1, erroneously turning off its upper bits. Not sure if this was an issue before or not. Once things are working, might make sense to play with this more.