Type Casting

Here we describe the types that can be passed as the first argument to cast() and their conversion rules. In principle, all types must accept values of the same type as themselves. Therefore, this is not described repeatedly. In the description, val means the value passed as the second argument to cast().

If a type that is not directly supported is passed as the first argument of cast(), the rules of the nearest base class are applied. For example, a user-defined class that does not define a base class follows the rule of object, and a class that inherits from int follows the rule of int. So when we say we call int(val) in the description of int, you should interpret int as being replaced by a user-defined type. If the user-defined type does not follow the rules of the base class, it should be specialized with cast.register().

The same rules apply to val. For example, when we say enum.IntEnum accepts int in this description, it means accepts when isinstance(val, int) is true. If the user-defined type instance passed to val doesn’t follow this rule, it can also be specialized with cast.register().

Builtin Types

bool

Converted to and from int and str.

When bool is converted to str, it is converted to "True" or "False". When converting str to bool, convert it to lowercase first and then look up the bool_strings dictionary. It raises TypeError if this dictionary is empty, and ValueError if it is not empty but there is no key for that string.

If bool_is_int is False, conversion to and from int is not allowed.

If lossy_conversion is False, int other than 0 and 1 is not converted to bool.

One-way conversion from bool to float is allowed. If lossy_conversion is False, values other than 0 and 1 are not converted. Even this is forbidden if bool_is_int is False.

bytearray

bytes

complex

Converted to and from tuple[float,float] and str.

One-way conversion from int or float to complex is allowed.

If accept_nan is False, only values for which cmath.isfinite() returns true are accepted.

dict

float

frozenset

int

Converted to and from int, bool, float, and str.

For other types, calls int(val). This means that it accepts all user-defined types that support the int conversion. In this case, the conversion in the opposite direction is up to the implementation of the user-defined type.

If bool_is_int is False then bool is not accepted.

If lossy_conversion is False, it does not accept float which has non-zero fractional part, and integers other than 0 and 1 are not converted to bool.

list

None

object

set

str

tuple

type

Converted to and from str.

When converting a type object to str, it is converted to fully qualified name. For builtin types, the builtins module is used as the module name.

When converting from str to a type object, it accepts fully qualified name. However, for builtin types, you can omit builtins.

If val is a type, only type checking is performed and val is returned as it is.

Given a generic type parameter, it is interpreted as covariant. In other words, it accepts all subclasses of the type parameter.

In addition to TypeError, ImportError or AttributeError can also be raised.

Standard Types

enum

enum.Enum

Converted to and from str using name of enum member.

Calls enum.Enum(val) for all other types, including enum.Enum. Because of this, enum.Enum that have None as their value will also accept None. In this case, the reverse direction conversion is not provided.

enum.Flag

Converted to and from int using value of enum member.

Unlike enum.Enum, conversion to and from str is not supported.

enum.IntEnum

Converting to and from str works like enum.Enum.

In addition to this, converting to and from int is supported using value of enum member.

enum.IntFlag

Converted to and from int using value of enum member.

Unlike enum.IntEnum, conversion to and from str is not supported.

typing

typing.Annotated

A type T can be annotated with metadata x via the typehint Annotated[T, x].

If x is an instance of Constraint, then cast() checks if the value after casting meets the constraint defined by x. Also, this constraint is reflected in JsonSchema.

If multiple metadata is provided, all constraints must be satisfied.

Ignored if x is not an instance of Constraint.

Since typing.Annotated was added in Python 3.9, the typeable.typing module provides backport.

Currently Typeable provides the following Constraint subclasses:

AllOf, AnyOf, NoneOf, IsFinite, IsGreaterThan, IsGreaterThanOrEqual, IsLessThan, IsLessThanOrEqual, IsLongerThanOrEqual, IsMatched, IsMultipleOf, and IsShorterThanOrEqual.

typing.Any

Pass val as it is without conversion or checking.

typing.Dict

typing.ForwardRef

typing.ForwardRef that appears in the type parameter of a generic type is automatically evaluated by Typeable.

typing.ForwardRef does not express a type by itself, it is just an intermediary passing a string forward reference to delay evaluation of a type. Usually (though not impossible) you don’t create an instance of typing.ForwardRef yourself, it is created automatically when you pass a string to the type parameter when using a generic type. The support provided by the typing module is limited to the annotation area.

Typeable provides a declare() context manager so that forward references can be used outside of the annotation.

typing.FrozenSet

typing.List

typing.Literal

If there is a literal that matches val, it returns the literal, otherwise ValueError is raised.

Since typing.Literal was added in Python 3.8, the typeable.typing module provides backport.

typing.Optional

typing.Optional is automatically converted to typing.Union.

typing.Set

typing.Tuple

typing.Type

Same as the conversion rule for type.

typing.Union

Typeable Types

JsonSchema

A subclass of Object representing JSON Schema.

JsonValue

This is a type that represents a JSON value recursively.

It converts the value to one of types float, bool, int, str, None, dict[str, JsonValue], list[JsonValue] and tuple[JsonValue, ...].

Object

Converted to and from dict.

When dict is converted to Object, undefined keys are ignored. It raises TypeError if a field with required specified as True is missing. If the field specifying default_factory is missing, it creates a value and assigns it to the instance attribute.

When Object is converted to dict, only Object instance attributes are provided. Fields not assigned to instance attributes are not included. Although default is defined so the attribute can be read, it will not be included if it has not been assigned as an instance attribute.