ASN.1 standard has a built-in way of limiting the set of values a type can possibly have. Imposing value constraints on an ASN.1 type, together with tagging, is a way of creating a more specialized subtype of an ASN.1 type.

The pyasn1 implementation represents all flavors of constraints, as well as their combinations, as immutable Python objects. Ultimately, they get attached to ASN.1 type object at a .subtypeSpec attribute.

class Age(Integer):
    ASN.1 specification:

    Age ::= INTEGER (0..120)
    subtypeSpec = ValueRangeConstraint(0, 120)

Logic operations on constraints

Sometimes multiple constraints are applied on an ASN.1 type. To capture this situation, individual constraint objects can be glued together by the logic operator objects.

The logic operators are Python objects that exhibit similar behaviour as the constraint objects do with the only difference that logic operators are instantiated on the constraint and logic operator objects, not on the bare values.

class PhoneNumber(NumericString):
    ASN.1 specification:

    PhoneNumber ::=
        NumericString (FROM ("0".."9")) (SIZE (10))
    subtypeSpec = ConstraintsIntersection(
        ValueRangeConstraint('0', '9'), ValueSizeConstraint(10)