pyanalyze.value¶
Value classes represent the value of an expression in a Python program. Values are the key data type used in pyanalyze’s internals.
Values are instances of a subclass of Value
. This module defines
these subclasses and some related utilities.
dump_value()
can be used to show inferred values during type checking. Examples:
from typing import Any
from pyanalyze import dump_value
def function(x: int, y: list[int], z: Any):
dump_value(1) # Literal[1]
dump_value(x) # int
dump_value(y) # list[int]
dump_value(z) # Any
- class pyanalyze.value.Value¶
Base class for all values.
- can_assign(other: Value, ctx: CanAssignContext) CanAssignError ¶
Whether other can be assigned to self.
If yes, return a (possibly empty) map with the TypeVar values dictated by the assignment. If not, return a
CanAssignError
explaining why the types are not compatible.For example, calling
a.can_assign(b, ctx)
where a isIterable[T]
and b isList[int]
will return{T: TypedValue(int)}
.This is the primary mechanism used for checking type compatibility.
- is_assignable(other: Value, ctx: CanAssignContext) bool ¶
Similar to
can_assign()
but returns a bool for simplicity.
- substitute_typevars(typevars: Value')]) Value ¶
Substitute the typevars in the map to produce a new Value.
This is used to specialize a generic. For example, substituting
{T: int}
onList[T]
will produceList[int]
.
- is_type(typ: type) bool ¶
Returns whether this value is an instance of the given type.
This method should be avoided. Use
can_assign()
instead for checking compatibility.
- get_type() type | None ¶
Returns the type of this value, or None if it is not known.
This method should be avoided.
- class pyanalyze.value.CanAssignContext(*args, **kwargs)¶
A context passed to the
Value.can_assign()
method.Provides access to various functionality used for type checking.
- make_type_object(typ: type | super | str) TypeObject ¶
Return a
pyanalyze.type_object.TypeObject
for this concrete type.
- get_generic_bases(typ: type | str, generic_args: Sequence[Value] = ()) Value')]] ¶
Return the base classes for typ with their generic arguments.
For example, calling
ctx.get_generic_bases(dict, [TypedValue(int), TypedValue(str)])
may produce a map containing the following:{ dict: [TypedValue(int), TypedValue(str)], Mapping: [TypedValue(int), TypedValue(str)], Iterable: [TypedValue(int)], Sized: [], }
- get_signature(obj: object) Signature | OverloadedSignature | None ¶
Return a
pyanalyze.signature.Signature
for this object.Return None if the object is not callable.
- signature_from_value(value: Value) None | Signature | BoundMethodSignature | OverloadedSignature ¶
Return a
pyanalyze.signature.Signature
for aValue
.Return None if the object is not callable.
- has_used_any_match() bool ¶
Whether Any was used to secure a match.
- record_any_used() None ¶
Record that Any was used to secure a match.
- reset_any_used() ContextManager[None] ¶
Context that resets the value used by
has_used_any_match()
andrecord_any_match()
.
- set_exclude_any() ContextManager[None] ¶
Within this context, Any is compatible only with itself.
- should_exclude_any() bool ¶
Whether Any should be compatible only with itself.
- class pyanalyze.value.CanAssignError(message: str = '', children: ~typing.List[~pyanalyze.value.CanAssignError] = <factory>, error_code: ~pyanalyze.error_code.Error | None = None)¶
A type checking error message with nested details.
This exists in order to produce more useful error messages when there is a mismatch between complex types.
- display(depth: int = 2) str ¶
Display all errors in a human-readable format.
- pyanalyze.value.assert_is_value(obj: object, value: Value, *, skip_annotated: bool = False) None ¶
Used to test pyanalyze’s value inference.
Takes two arguments: a Python object and a
Value
object. At runtime this does nothing, but pyanalyze throws an error if the object is not inferred to be the same as theValue
.Example usage:
assert_is_value(1, KnownValue(1)) # passes assert_is_value(1, TypedValue(int)) # shows an error
If skip_annotated is True, unwraps any
AnnotatedValue
in the input.
- pyanalyze.value.dump_value(value: T) T ¶
Print out the
Value
representation of its argument.Calling it will make pyanalyze print out an internal representation of the argument’s inferred value. Use
pyanalyze.extensions.reveal_type()
for a more user-friendly representation.At runtime this returns the argument unchanged.
- class pyanalyze.value.AnySource(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)¶
Sources of Any values.
- default = 1¶
Any that has not been categorized.
- explicit = 2¶
The user wrote ‘Any’ in an annotation.
- error = 3¶
An error occurred.
- unreachable = 4¶
Value that is inferred to be unreachable.
- inference = 5¶
Insufficiently powerful type inference.
- unannotated = 6¶
Unannotated code.
- variable_name = 7¶
- from_another = 8¶
An Any derived from another Any, for example as an attribute.
- generic_argument = 9¶
Missing type argument to a generic class.
- marker = 10¶
Marker object used internally.
- incomplete_annotation = 11¶
A special form like ClassVar without a type argument.
- multiple_overload_matches = 12¶
Multiple matching overloads.
- ellipsis_callable = 13¶
Callable using an ellipsis.
- unresolved_import = 14¶
An unresolved import.
- pyanalyze.value.UNRESOLVED_VALUE = AnyValue(source=<AnySource.default: 1>)¶
The default instance of
AnyValue
.In the future, this should be replaced with instances of AnyValue with a specific source.
- class pyanalyze.value.VoidValue¶
Dummy Value used as the inferred type of AST nodes that do not represent expressions.
This is useful so that we can infer a Value for every AST node, but notice if we unexpectedly use it like an actual value.
- class pyanalyze.value.TypeAlias(evaluator: Callable[[], pyanalyze.value.Value], evaluate_type_params: Callable[[], Sequence[Union[ExternalType(type_path='TypeVar'), ExternalType(type_path='typing_extensions.TypeVar'), ExternalType(type_path='ParamSpec'), ExternalType(type_path='typing_extensions.ParamSpec'), ExternalType(type_path='TypeVarTuple'), ExternalType(type_path='typing_extensions.TypeVarTuple')]]], evaluated_value: pyanalyze.value.Value | None = None, type_params: Optional[Sequence[Union[ExternalType(type_path='TypeVar'), ExternalType(type_path='typing_extensions.TypeVar'), ExternalType(type_path='ParamSpec'), ExternalType(type_path='typing_extensions.ParamSpec'), ExternalType(type_path='TypeVarTuple'), ExternalType(type_path='typing_extensions.TypeVarTuple')]]] = None)¶
-
- evaluate_type_params: TypeVarTuple')]]¶
Callable that evaluates the type parameters.
- type_params: TypeVarTuple')] | None = None¶
Type parameters of the type alias.
- class pyanalyze.value.TypeAliasValue(name: str, module: str, alias: TypeAlias, type_arguments: Sequence[Value] = ())¶
Value representing a type alias.
- name: str¶
Name of the type alias.
- module: str¶
Module where the type alias is defined.
- class pyanalyze.value.UninitializedValue¶
Value for variables that have not been initialized.
Usage of variables with this value should be an error.
- pyanalyze.value.UNINITIALIZED_VALUE = UninitializedValue()¶
The only instance of
UninitializedValue
.
- class pyanalyze.value.KnownValue(val: Any)¶
Equivalent to
typing.Literal
. Represents a specific value.This is inferred for constants and for references to objects like modules, classes, and functions.
- val: Any¶
The Python object that this
KnownValue
represents.
- class pyanalyze.value.KnownValueWithTypeVars(val: Any, typevars: Value')])¶
Subclass of KnownValue that records a TypeVar substitution.
- typevars: Value')]¶
TypeVars substituted on this value.
- class pyanalyze.value.SyntheticModuleValue(module_path: Sequence[str])¶
Represents a module that exists only in stub files.
- class pyanalyze.value.UnboundMethodValue(attr_name: str, composite: Composite, secondary_attr_name: str | None = None, typevars: Value')] | None = None)¶
Value that represents a method on an underlying
Value
.Despite the name this really represents a method bound to a value. For example, given
s: str
,s.strip
will be inferred asUnboundMethodValue("strip", Composite(TypedValue(str), "s"))
.- attr_name: str¶
Name of the method.
- secondary_attr_name: str | None = None¶
Used when an attribute is accessed on an existing
UnboundMethodValue
.This is mostly useful in conjunction with asynq, where we might use
object.method.asynq
. In that case, we would infer anUnboundMethodValue
with secondary_attr_name set to"asynq"
.
- typevars: Value')] | None = None¶
Extra TypeVars applied to this method.
- get_method() Any | None ¶
Return the runtime callable for this
UnboundMethodValue
, or None if it cannot be found.
- class pyanalyze.value.TypedValue(typ: type | str, literal_only: bool = False)¶
Value for which we know the type. This is equivalent to simple type annotations: an annotation of
int
will yieldTypedValue(int)
during type inference.- typ: type | str¶
The underlying type, or a fully qualified reference to one.
- literal_only: bool = False¶
True if this is LiteralString (PEP 675).
- class pyanalyze.value.NewTypeValue(newtype: Any)¶
A wrapper around an underlying type.
Corresponds to
typing.NewType
.This is a subclass of
TypedValue
. Currently only NewTypes over simple, non-generic types are supported.- name: str¶
Name of the
NewType
.
- newtype: Any¶
Underlying
NewType
object.
- class pyanalyze.value.GenericValue(typ: type | str, args: Iterable[Value])¶
Subclass of
TypedValue
that can represent generics.For example,
List[int]
is represented asGenericValue(list, [TypedValue(int)])
.
- class pyanalyze.value.SequenceValue(typ: type | str, members: Sequence[Tuple[bool, Value]])¶
A
TypedValue
subclass representing a sequence of known type.This is represented as a sequence, but each entry in the sequence may consist of multiple values. For example, the expression
[int(self.foo)]
may be typed asSequenceValue(list, [(False, TypedValue(int))])
. The expression["x", *some_str.split()]
would be represented asSequenceValue(list, [(False, KnownValue("x")), (True, TypedValue(str))])
.This is only used for
set
,list
, andtuple
.
- class pyanalyze.value.KVPair(key: Value, value: Value, is_many: bool = False, is_required: bool = True)¶
Represents a single entry in a
DictIncompleteValue
.- is_many: bool = False¶
Whether this key-value pair represents possibly multiple keys.
- is_required: bool = True¶
Whether this key-value pair is definitely present.
- class pyanalyze.value.DictIncompleteValue(typ: type | str, kv_pairs: Sequence[KVPair])¶
A
TypedValue
representing a dictionary of known size.For example, the expression
{'foo': int(self.bar)}
may be typed asDictIncompleteValue(dict, [KVPair(KnownValue('foo'), TypedValue(int))])
.- kv_pairs: Tuple[KVPair, ...]¶
Sequence of
KVPair
objects representing the keys and values of the dict.
- property items: Sequence[Tuple[Value, Value]]¶
Sequence of pairs representing the keys and values of the dict.
- get_value(key: Value, ctx: CanAssignContext) Value ¶
Return the
Value
for a specific key.
- class pyanalyze.value.TypedDictEntry(typ: pyanalyze.value.Value, required: bool = True, readonly: bool = False)¶
- class pyanalyze.value.TypedDictValue(items: Dict[str, TypedDictEntry], extra_keys: Value | None = None, extra_keys_readonly: bool = False)¶
Equivalent to
typing.TypedDict
; a dictionary with a known set of string keys.- items: Dict[str, TypedDictEntry]¶
The items of the
TypedDict
. Required items are represented as (True, value) and optional ones as (False, value).
- extra_keys_readonly: bool = False¶
Whether the extra keys are readonly.
- class pyanalyze.value.AsyncTaskIncompleteValue(typ: type | str, value: Value)¶
A
GenericValue
representing an async task.This should probably just be replaced with
GenericValue
.
- class pyanalyze.value.CallableValue(signature: ~pyanalyze.signature.Signature | ~pyanalyze.signature.OverloadedSignature, fallback: type | str = <class 'collections.abc.Callable'>)¶
Equivalent to the
Callable
type.This is a thin wrapper around
pyanalyze.signature.Signature
.
- class pyanalyze.value.SubclassValue(typ: TypedValue | TypeVarValue, exactly: bool = False)¶
Equivalent of
Type[]
.The typ attribute can be either a
TypedValue
or aTypeVarValue
. The former is equivalent toType[int]
and represents theint
class or a subclass. The latter is equivalent toType[T]
whereT
is a type variable. The third legal argument toType[]
isAny
, butType[Any]
is represented asTypedValue(type)
.- typ: TypedValue | TypeVarValue¶
The underlying type.
- exactly: bool = False¶
If True, represents exactly this class and not a subclass.
- class pyanalyze.value.MultiValuedValue(raw_vals: dataclasses.InitVar[Iterable[pyanalyze.value.Value]])¶
Equivalent of
typing.Union
. Represents the union of multiple values.
- pyanalyze.value.NO_RETURN_VALUE = MultiValuedValue(vals=())¶
The empty union, equivalent to
typing.Never
.
- class pyanalyze.value.ReferencingValue(scope: Any, name: str)¶
Value that is a reference to another value (used to implement globals).
- class pyanalyze.value.Bound¶
- class pyanalyze.value.LowerBound(typevar: ExternalType(type_path='typing.TypeVar') | ExternalType(type_path='typing_extensions.TypeVar') | ExternalType(type_path='typing.ParamSpec') | ExternalType(type_path='typing_extensions.ParamSpec') | ExternalType(type_path='typing.TypeVarTuple') | ExternalType(type_path='typing_extensions.TypeVarTuple'), value: Value)¶
LowerBound(T, V) means V must be assignable to the value of T.
- class pyanalyze.value.UpperBound(typevar: ExternalType(type_path='typing.TypeVar') | ExternalType(type_path='typing_extensions.TypeVar') | ExternalType(type_path='typing.ParamSpec') | ExternalType(type_path='typing_extensions.ParamSpec') | ExternalType(type_path='typing.TypeVarTuple') | ExternalType(type_path='typing_extensions.TypeVarTuple'), value: Value)¶
UpperBound(T, V) means the value of T must be assignable to V.
- class pyanalyze.value.OrBound(bounds: Sequence[Sequence[Bound]])¶
At least one of the specified bounds must be true.
- class pyanalyze.value.IsOneOf(typevar: Union[ExternalType(type_path='TypeVar'), ExternalType(type_path='typing_extensions.TypeVar'), ExternalType(type_path='ParamSpec'), ExternalType(type_path='typing_extensions.ParamSpec'), ExternalType(type_path='TypeVarTuple'), ExternalType(type_path='typing_extensions.TypeVarTuple')], constraints: Sequence[pyanalyze.value.Value])¶
- class pyanalyze.value.TypeVarValue(typevar: ExternalType(type_path='typing.TypeVar') | ExternalType(type_path='typing_extensions.TypeVar') | ExternalType(type_path='typing.ParamSpec') | ExternalType(type_path='typing_extensions.ParamSpec') | ExternalType(type_path='typing.TypeVarTuple') | ExternalType(type_path='typing_extensions.TypeVarTuple'), bound: Value | None = None, constraints: Sequence[Value] = (), is_paramspec: bool = False, is_typevartuple: bool = False)¶
Value representing a
typing.TypeVar
ortyping.ParamSpec
.Currently, variance is ignored.
- class pyanalyze.value.ParamSpecArgsValue(param_spec: typing_extensions.ParamSpec)¶
- class pyanalyze.value.ParamSpecKwargsValue(param_spec: typing_extensions.ParamSpec)¶
- class pyanalyze.value.Extension¶
An extra piece of information about a type that can be stored in an
AnnotatedValue
.
- class pyanalyze.value.CustomCheckExtension(custom_check: pyanalyze.extensions.CustomCheck)¶
- class pyanalyze.value.ParameterTypeGuardExtension(varname: str, guarded_type: Value)¶
An
Extension
used in a function return type. Used to indicate that the parameter named varname is of type guarded_type.Corresponds to
pyanalyze.extensions.ParameterTypeGuard
.
- class pyanalyze.value.NoReturnGuardExtension(varname: str, guarded_type: Value)¶
An
Extension
used in a function return type. Used to indicate that unless the parameter named varname is of type guarded_type, the function does not return.Corresponds to
pyanalyze.extensions.NoReturnGuard
.
- class pyanalyze.value.TypeGuardExtension(guarded_type: Value)¶
An
Extension
used in a function return type. Used to indicate that the first function argument is of type guarded_type.Corresponds to
pyanalyze.extensions.TypeGuard
, ortyping.TypeGuard
.
- class pyanalyze.value.TypeIsExtension(guarded_type: Value)¶
An
Extension
used in a function return type. Used to indicate that the first function argument may be narrowed to type guarded_type.Corresponds to
typing_extensions.TypeIs
(see PEP 742).
- class pyanalyze.value.HasAttrGuardExtension(varname: str, attribute_name: Value, attribute_type: Value)¶
An
Extension
used in a function return type. Used to indicate that the function argument named varname has an attribute named attribute_name of type attribute_type.Corresponds to
pyanalyze.extensions.HasAttrGuard
.
- class pyanalyze.value.HasAttrExtension(attribute_name: Value, attribute_type: Value)¶
Attached to an object to indicate that it has the given attribute.
These cannot be created directly from user code, only through the
pyanalyze.extension.HasAttrGuard
mechanism. This is because of potential code like this:def f(x: Annotated[object, HasAttr["y", int]]) -> None: return x.y
Here, we would correctly type check the function body, but we currently have no way to enforce that the function is only called with arguments that obey the constraint.
- class pyanalyze.value.ConstraintExtension(constraint: AbstractConstraint)¶
Encapsulates a Constraint. If the value is evaluated and is truthy, the constraint must be True.
- class pyanalyze.value.NoReturnConstraintExtension(constraint: AbstractConstraint)¶
Encapsulates a Constraint. If the value is evaluated and completes, the constraint must be True.
- class pyanalyze.value.AlwaysPresentExtension¶
Extension that indicates that an iterable value is nonempty.
Currently cannot be used from user code.
- class pyanalyze.value.AssertErrorExtension¶
Used for the implementation of
pyanalyze.extensions.assert_error()
.
- class pyanalyze.value.SkipDeprecatedExtension¶
Indicates that use of this value should not trigger deprecation errors.
- class pyanalyze.value.DeprecatedExtension(deprecation_message: str)¶
Indicates that use of this value should trigger a deprecation error.
- class pyanalyze.value.SysPlatformExtension¶
Used for sys.platform.
- class pyanalyze.value.SysVersionInfoExtension¶
Used for sys.version_info.
- class pyanalyze.value.DefiniteValueExtension(value: bool)¶
Used if a comparison has a definite value that should be used to skip type checking.
- class pyanalyze.value.AnnotatedValue(value: Value, metadata: Sequence[Value | Extension])¶
Value representing a PEP 593 Annotated object.
Pyanalyze uses
Annotated
types to represent types with some extra information added to them in the form ofExtension
objects.- get_metadata_of_type(typ: Type[T]) Iterable[T] ¶
Return any metadata of the given type.
- get_custom_check_of_type(typ: Type[T]) Iterable[T] ¶
Return any CustomChecks of the given type in the metadata.
- class pyanalyze.value.UnpackedValue(value: Value)¶
Represents the result of PEP 646’s Unpack operator.
- class pyanalyze.value.VariableNameValue(varnames: Iterable[str])¶
Value that is stored in a variable associated with a particular kind of value.
For example, any variable named uid will get resolved into a
VariableNameValue
of type uid, and if it gets passed into a function that takes an argument called aid, the call will be rejected.This was created for a legacy codebase without type annotations. If possible, prefer using NewTypes or other more explicit types.
There should only be a limited set of
VariableNameValue
objects, created through the pyanalyze configuration.- classmethod from_varname(varname: str, varname_map: Dict[str, VariableNameValue]) VariableNameValue | None ¶
Returns the VariableNameValue corresponding to a variable name.
If there is no VariableNameValue that corresponds to the variable name, returns None.
- pyanalyze.value.flatten_values(val: Value, *, unwrap_annotated: bool = False) Iterable[Value] ¶
Flatten a
MultiValuedValue
into its constituent values.We don’t need to do this recursively because the
MultiValuedValue
constructor applies this to its arguments.if unwrap_annotated is true, produces the underlying values for
AnnotatedValue
objects.
- pyanalyze.value.unite_values(*values: Value) Value ¶
Unite multiple values into a single
Value
.This collapses equal values and returns a
MultiValuedValue
if multiple remain.
- pyanalyze.value.concrete_values_from_iterable(value: Value, ctx: CanAssignContext) CanAssignError | Value | Sequence[Value] ¶
Return the exact values that can be extracted from an iterable.
Three possible return types:
CanAssignError
if the argument is not iterableA sequence of
Value
if we know the exact types in the iterableA single
Value
if we just know that the iterable contains this value, but not the precise number of them.
Examples:
int
->CanAssignError
tuple[int, str]
->(int, str)
tuple[int, ...]
->int
- pyanalyze.value.kv_pairs_from_mapping(value_val: Value, ctx: CanAssignContext) Sequence[KVPair] | CanAssignError ¶
Return the
KVPair
objects that can be extracted from this value, or aCanAssignError
on error.
- pyanalyze.value.check_hashability(value: Value, ctx: CanAssignContext) CanAssignError | None ¶
Check whether a value is hashable.
Return None if it is hashable, otherwise a CanAssignError.
- pyanalyze.value.unpack_values(value: Value, ctx: CanAssignContext, target_length: int, post_starred_length: int | None = None) Sequence[Value] | CanAssignError ¶
Implement iterable unpacking.
If post_starred_length is None, return a list of target_length values, or
CanAssignError
if value is not an iterable of the expected length. If post_starred_length is not None, return a list of target_length + 1 + post_starred_length values. This implements unpacking likea, b, *c, d = ...
.
- pyanalyze.value.is_iterable(value: Value, ctx: CanAssignContext) CanAssignError | Value ¶
Check whether a value is iterable.
- pyanalyze.value.is_async_iterable(value: Value, ctx: CanAssignContext) CanAssignError | Value ¶
Check whether a value is an async iterable.
- pyanalyze.value.replace_known_sequence_value(value: Value) Value ¶
Simplify a Value in a way that is easier to handle for most typechecking use cases.
Does the following:
Replace AnnotatedValue with its inner type
Replace TypeVarValue with its fallback type
Replace KnownValues representing list, tuples, sets, or dicts with SequenceValue or DictIncompleteValue.