Integer and enumeration types - rhjdjong/xdrlib2 GitHub Wiki
Integer, UnsignedInteger, Hyper, and UnsignedHyper are subclasses of the abstract XdrInteger class.
Each of these subclasses has two explicit parameters that are supplied with the subclass creation:
-
bits: the number of bits required for values of this subclass; -
signed: a boolean flag indicating if the subclass supports signed values.
These parameters are stored as attributes in the subclass.
If T is one of these subclasses with value b for T.bits, and t is an instance of T, then
- If
T.signedisTrue, then −2b−1 ≤ t < 2b−1; - If
T.signedisFalse, then 0 ≤ t < 2b.
Instantiation of these subclasses is delegated to the Python int class.
The constraint on the value of the instance is checked after the instance has been created.
If the constraint is not satisfied then a ValueError exception is raised.
Any other exceptions on instantiation are raised by the Python int class.
When no arguments are provided when one of these subclasses is instantiated,
the resulting value is 0, just as it is for Python ints.
Enumeration is an abstract subclass of Integer.
It must be subclassed with a series of enumeration-identifiers with their corresponding Integer values,
as in:
>>> class Colors(Enumeration):
... RED = 2
... YELLOW = 3
... BLUE = 5
The XDR standard implicitly states that the enumeration identifiers live
in the specification's name space.
In other words, an enum declaration does not create a separate namespace.
To achieve this effect in Python code, global names must be defined for each of
the enumeration identifiers:
>>> RED = Colors.RED
>>> YELLOW = Colors.YELLOW
>>> BLUE = Colors.BLUE
The instances of an enumeration are singletons, i.e. both Colors.RED and Colors(2) result in the same object.
This allows for identity comparison between enumeration values:
>>> RED is Colors(2)
True
To allow programmatic access to enumeration values (e.g. when the name of the enumeration identifier is provided dynamically), the enumeration values can also be retrieved via indexing:
>>> name = 'RED'
>>> Colors[name] is Colors.RED
True
Note that because Enumeration is a subclass of Integer,
each Enumeration subclass also has the signed, and bits attributes.
These are normal integer values, not singletons like Colors.RED.
Also note that an Enumeration subclass can define enumeration-identifiers that shadow
these attributes inherited from Integer:
class Shadow(Enumeration):
bits = 1
signed = -5
Shadow.bits and Shadow.signed are singleton Shadow instances with the values 1 and -5 respectively,
and they are not related to the superclass Integer.bits and Integer.signed attributes.
Because the range of enumeration values does not necessarily include the value 0, instantiation without arguments is not allowed:
>>> Colors()
Traceback (most recent call last):
...
TypeError: Colors.__init__() missing 1 required positional argument...
The XDR standard allows identifiers that match Python keywords. By convention, such identifiers are converted to attribute names by appending trailing underscore(s) to achieve a unique identifier. So, the following XDR specification
enum { def = 3, if = 4, break = 5 } keywords
corresponds to the following Python class definition:
class keywords(Enumeration):
def_ = 3
if_ = 4
break_ = 5