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.
_FlagMeta
[source]¶ Bases:
type
Metaclass for defining new Flag classes.
This attempts to do the minimum required to make the Flag class and its subclasses function properly. It mostly digests the class attributes, resolves automatic values and creates instances of the class as it’s own class attributes for each field. The rest of the functionality lives in the base
Flag
class as plain-old code.Tip
Because individual flags are defined as class attributes (as opposed to instance attributes), we have to customize the way a Flag subclass itself is built, which requires a metaclass.
-
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 forenum.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. In such circumstances, the
from_bytes()
andto_bytes()
methods are available to represent a Flag’s values in smaller chunks.-
_autoAt
= 1¶
-
_nameToValue
= {}¶
-
_valuesTaken
= {}¶
-
_width
= 0¶
-
classmethod
_registerField
(name, value)[source]¶ Plug a new field into the Flags.
This makes sure everything is consistent and does error/collision checks. Mostly useful for extending an existing class with more fields.
-
classmethod
_resolveAutos
(fields: Sequence[str]) → List[Tuple[str, int]][source]¶ Assign values to autos, based on the current state of the class.
-
classmethod
width
()[source]¶ Return the number of bytes needed to store all of the flags on this class.
-
classmethod
fields
()[source]¶ Return a dictionary containing a mapping from field name to integer value.
-
classmethod
sortedFields
()[source]¶ Return a list of all field names, sorted by increasing integer value.
-
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>
-
to_bytes
(byteorder='little')[source]¶ Return a byte stream representing the flag.
This is useful when storing Flags in a data type of limited size. Python ints can be of arbitrary size, while most other systems can only represent integers of 32 or 64 bits. For compatibiliy, this function allows to convert the flags to a sequence of single-byte elements.
Note that this uses snake_case to mimic the method on the Python-native int type.
-
classmethod
from_bytes
(bytes, byteorder='little')[source]¶ Return a Flags instance given a byte stream.
-
__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, likef1 &= ~f2
. Iff2
is narrower thanf1
the field of ones that you need to keepf1
bits on might not cover the width off1
, 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.
-