pypi / astroid
astroid
What changed in astroid 4, from its official release notes, upgrade guides and advisories. Sources checked 2026-10-25.
1 breaking16 fixes and other
See which of these apply to your code, ranked, in your agent:
npx @unstale/cli initastroid 417 changes
Breaking changes 1
A function whose body is only ... is inferred to return Uninferable instead of None, matching a function whose body is only pass.
Fixes and other changes 16
No longer raises IndexError when a keyword-only argument repeats the name of *args or **kwargs.
ValueError during comparison inference is caught and returns Uninferable instead of raising an uncaught exception.
Introspecting a live class that exposes itself or a sibling class as one of its own attributes no longer loops infinitely.
Building a module from a live object that holds a container containing itself no longer raises RecursionError.
Inferring random.sample() on a sequence whose elements are inferred as Instance no longer crashes with TypeError.
Fixes a TypeError when __class_getitem__ is uninferable.
Inferred concatenations preserve their length when an element has multiple possible values; ambiguous or uninferable elements are represented as unknown instead of expanded into multiple items.
Fixes an AssertionError when inferring Class.__bases__, which previously returned a parentless Tuple.
An exception instance's args attribute is inferred as a tuple instance of unknown contents rather than a known empty tuple, so unpacking no longer looks unbalanced.
Returns None instead of raising AttributeError for a class whose PEP 695 type parameter is literally named __slots__.
Inference falls back to its default instead of crashing when a type name or field name contains str.format markup.
Inference of an f-string or str.format call with an out-of-range c format-spec code point now yields Uninferable instead of crashing.
Inference falls back to its default instead of crashing when a type name or field name contains str.format markup.
Functional NewType names that are not identifiers are assigned verbatim to the synthesized class, rather than spliced into its source.
Raises InferenceError instead of crashing with IndexError when called without a positional metaclass argument, during module building and call inference.
Functional TypeVar names that are not identifiers are assigned verbatim to the synthesized class, rather than spliced into its source.