Repository navigation
Releases
v4.3.4
What's new in astroid 4.3.4?
Release date: 2026-10-08
Bug Fixes
-
Fix a
RecursionErrorwhen building a module from a live object that holds a
container containing itself.Closes #2974
Closes pylint-dev/pylint#10459 -
Arguments.default_value()no longer raisesIndexErrorwhen a keyword-only
argument repeats the name of*argsor**kwargs, as indef f(x, *y, y).Closes #3259
-
Fix an infinite loop when introspecting a live class that exposes itself, or a
sibling class, as one of its own attributes.Closes #3284
-
Fix a
TypeErrorcrash when inferringrandom.sample()on a sequence whose
elements are inferred asInstance.Closes #3310
-
Catch
ValueErrorduring comparison inference (such as invalid byte values in bytes membership checks) and returnUninferableinstead of raising an uncaught exception.Closes #3333
-
A function whose body is only
...is now inferred to returnUninferable
instead ofNone, the same as a function whose body is onlypass. This
is the astroid part of the fix for a false positivenot-callablein pylint
when calling a...property stub, such as thesqlalchemy.funchelpers.Refs #3347
Refs pylint-dev/pylint#8138
v4.3.3
What's new in astroid 4.3.3?
Release date: 2026-09-30
Bug Fixes
-
Preserve the length of inferred list and tuple concatenations when an element
has multiple possible values. An ambiguous or uninferable element is now
represented as unknown instead of being expanded into multiple sequence items.Refs #3221
Closes pylint-dev/pylint#2621 -
Fix
TypeErrorinClassDef.getitemwhen__class_getitem__is uninferable.Closes #3312
-
Fix
AssertionErrorinNodeNG.root()when inferringClass.__bases__, which previously returned a parentlessTuple.Closes pylint-dev/pylint#11491
v4.3.2
What's new in astroid 4.3.2?
Release date: 2026-09-25
Bug Fixes
-
Fix a crash when a
namedtupleorEnumtype name or field name
containsstr.formatmarkup, as innamedtuple("{0}", "abc"). The name
is interpolated into an error message that astroid then reformats, so
building the message raisedIndexError. Inference now falls back to its
default.Closes #3199
-
Infer a functional
TypeVarorNewTypewhose name is not an identifier
without splicing that name into the synthesized class source. A crafted value
such asTypeVar("T(Base): #")no longer breaks out of the identifier
position to inject bases or a body; the name is assigned to the class verbatim.Refs #3217
-
Raise
InferenceErrorinstead of crashing withIndexErrorwhen a class
usessix.with_metaclass()with no positional metaclass argument, both while
building the module and when the call is inferred.Refs #3248
-
ClassDef.slots()no longer crashes on a class that declares a PEP 695
type parameter literally named__slots__(e.g.class C[__slots__]:).
The type parameter'sTypeVarnode was mistaken for the class's actual
__slots__value;slots()now returnsNonefor such classes
instead of raisingAttributeError.Refs #3258
-
Fix a crash when inferring an f-string or
str.format()call whosecformat
spec gets an out-of-range code point, such asf"{-1:c}". These now infer to
Uninferable, like the%ccase fixed in #3254.Closes #3301
-
The
argsattribute of an exception instance is now inferred as atuple
instance of unknown contents instead of a known empty tuple, so unpacking
exc.argsno longer looks unbalanced.Closes pylint-dev/pylint#11312
v4.3.1
What's New in astroid 4.3.1?
Release date: 2026-08-17
-
Fix inference of the attributes of a
namedtuplecreated with
rename=True. The renamed fields were applied to_fieldsand to the
class body, but the instance kept the field names as written, so an instance
ofnamedtuple("Tuple", "abc def", rename=True)was inferred as having a
defattribute instead of_1, and duplicate field names collapsed into
a single attribute instead of being renamed.Closes #242
v4.3.0
What's New in astroid 4.3.0?
Release date: 2026-08-07
Version 4.2.0 was skipped: a v4.2.0 tag was created by mistake during an
aborted release attempt, so the changes from the 4.2.0 betas are released
as 4.3.0.
-
Fix a crash on a functional
namedtuplewhose field name changes under NFKC
normalization, such asnamedtuple("mu", ["µ"]). Python normalizes
identifiers, so the parsed class stores the field under"μ"while the
brain looked it up as written, raisingKeyErroron a definition that
namedtupleitself accepts.Closes pylint-dev/pylint#8746
-
Fix inference of a method's first argument (
selforcls) when the
method's return value is stored on an unrelated object. This avoids inferring
clsas the caller's class when indexing a tuple returned by a
classmethod such asA.c()[0].Closes pylint-dev/pylint#11101
-
super()with no argument now resolves against the class of the object the
method was called on, instead of the class the method is written in. One consequence
is that atyping.Selfreturn value survives a chain ofsuper()calls.Closes #2852
Closes pylint-dev/pylint#10807 -
typing.overloadstubs no longer shadow the implementation when a special
method is looked up in the MRO.Closes #2448
-
Fix a crash when the field names of a functional
Enumornamedtuple
call are bytes, as inEnum("", b""). Such a definition is invalid, so
inference now falls back to its default instead of raisingTypeError.Closes #3189
-
Fix a crash when the body of a
typing.NamedTuplesubclass contains an
assignment whose target is not a single name, such ascat.color = "black",
basket[0] = "apple"orapple, banana = "red", "yellow". The names bound
by unpacking are now copied to the inferred class as well.Closes #3190
-
Fix a crash when a binary operation involves a class whose metaclass is not a
class, as inclass C(metaclass=sum)followed byC | None. The type of
such a class is a function, which has no bases, sohas_known_bases()now
returnsFalsefor anything that is not a class.Closes #3191
-
Fix a crash when a dataclass inherits from a dataclass that annotates
__init__as a field, as in__init__: int. Such a base binds
__init__to a name instead of a function, so it no longer contributes
arguments to the generated__init__.Closes #3200
-
The documentation build now fails on any Sphinx warning, so a cross-reference
that does not resolve is caught by CI instead of quietly rendering as plain
text.Uninferable,Positionand theBadOperationMessageclasses
are documented as part of the public API, and a number of docstrings that
Sphinx could not parse were repaired. -
The
>>>examples in the documentation are run when the documentation is
built, so one that stops being true is noticed. Most of them could not run
before: they printed node addresses recorded in 2018, and the multi-line ones
were missing the...continuation prompt. The example forDecorators
reported the wrong line numbers. -
Fix the example in the docstring of
BoolOp, which showed the node it was
copied from:astroid.extract_node("a and b")gives aBoolOp, not a
BinOp. -
Names written between single backticks in the ChangeLog render as code again,
rather than as italics. -
Prevent crashes while processing extension-module classes whose bases cannot
be resolved when applying enum inference transformations.Closes pylint-dev/pylint#11179
-
The API documentation now covers the proxies, the objects with no node of
their own, the inference context, the manager, the object models and the
extension call signatures. TheEvaluatedObject,Interpolation,
NamedExprandTemplateStrnodes were missing from the list of nodes
and are listed now. -
Add
__required_keys__and__optional_keys__to the inferred
TypedDictbase class, so subclasses no longer raise ano-member
false positive in pylint when accessing those attributes at runtime.Closes pylint-dev/pylint#10158
-
Comprehension conditions now constrain the inference of names used in the
comprehension, likeifstatement conditions already did:
[x for x in lst if x is not None]no longer infersNoneforx
in the element expression.Refs #3094
-
Fix
isinstance()constraints only filtering the first inferred value of
a variable: checking a value made theisinstanceclassinfo uninferable
for the checks of the following values. -
Remove Python 2 era dead code and outdated comments.
Notably: the internalTreeRebuilderconstructor no longer takes a
parser_moduleargument.Refs #3154
-
Fix inference of a starred target that is not last in a
forloop, such as
for a, *b, c in .... The elements following the starred one were counted
from the target's own arity rather than from the end of the iterable, so
bwas truncated whenever the iterable was longer than the target. -
Add
qname()method to theSlicenode class, returning
"builtins.slice", so that the node can be used in contexts
that require a qualified name (e.g. pylint'sbasic_checker).Closes #3115
-
Add brain tip for
numpy.fromfileso that calls to
np.fromfile(...)are correctly inferred as returning
numpy.ndarrayinstead ofUninferable.Closes #600
-
Add brain for
decimalthat gets applied if_decimalisn't available. -
Removed the
**kwargsargument from allinferfunctions.
Users upgrading theirastroidversions should ensure they do no pass values other than
contexttoinfer. -
Deduplicate keys when inferring
dict.fromkeys.dict.fromkeys("aab")
now infers a dict with keys"a","b"instead of"a","a",
"b", matching the runtime. This also stopsdict.fromkeysfrom
materializing oneConstnode per character for a repeated string such as
dict.fromkeys("x" * 10 ** 8), which is a single-key dict. -
Bound str/bytes and list/tuple concatenation (
a + b) during inference. -
Bound oversized old-style (
%) string/bytes formatting during inference.
A tiny literal such as"%1000000000d" % 1made
_infer_old_style_string_formattingeagerly build a multi-gigabyte
Constwhile inferring otherwise untrusted source. The width and
precision are now read out of the conversion specifiers (including*
fields) and the interpolation infers asUninferablepast1e8,
mirroring the repetition, concatenation andstr.formatcaps. Bytes
%formatting is routed through the same handler so it is bounded too;
small format strings keep inferring their exact value. -
Fix crash (
TypeError: 'UninferableBase' object is not iterable) in the
multiprocessingbrain when a local package shadows the stdlib
multiprocessingmodule.Closes pylint-dev/pylint#10014
-
Bound the number of nodes built when inferring
list/set/tuple/
frozensetanddict.fromkeysfrom astr/bytesconstant. These
built oneConstnode per character with no cap, so ``list(("a" * 10 ** 8)- "b")
(concatenation is not size-bounded) materialized hundreds of millions of nodes. They now fall back to the default inference past1e8`` characters,
matching the sequence-repetition guard.
- "b")
Refs #3127
-
Bound string/bytes multiplication (
"x" * n) and integer left shifts
(1 << n) inconst_infer_binary_opthe same way list/tuple
multiplication and**already are. Inferring a constant such as
"A" * 10 ** 10previously materialized the multi-gigabyte result
eagerly; these operations now infer asUninferablewhen the result
would be oversized.Refs #3107
-
Bound the field width and precision when inferring
str.formatcalls.
A template such as"{:>2000000000}".format("x")(or a width/precision
supplied through a nested{}field) previously built the padded
multi-gigabyte string eagerly during inference; such calls now infer as
Uninferablewhen the field size would be oversized.Refs #3131
-
Remove the
asnamekeyword argument fromImport._inferand
ImportFrom._infer. The alias-to-real-name translation that
asname=Trueperformed is now hoisted intoImportNode._infer_name,
which runs in_infer_stmtsbefore_inferis dispatched. Direct
callers ofImport.infer/ImportFrom.infer(previously the
asname=Falsepath) now consistently resolve the lookup name as-is.The two flows used to collapse into a single inference cache entry
because theasnamekwarg was not part of the cache key, so the
second call returned the cached result of the first regardless of
which one ran. With the translation hoisted upstream, the two flows
set differentlookupnamevalues and therefore land on distinct
cache keys, eliminating the collision.Refs pylint-dev/pylint#10193
Closes #3007 -
Avoid materializing a multi-gigabyte string while inferring a small literal
such as"{:>2000000000}".format("x")orf"{1.5:.2000000000f}".
_infer_str_format_callandFormattedValue._infernow yield
Uninferablewhen a format spec asks for a width or precision over 1e8,
mirroring the sequence/repetition caps inastroid.protocols.
Refs #3108
- Fix uncaught
IndentationErrorwhen parsing code whose lines end in
\r: the slice of source tokenized to compute a class or function
positionis split on\nonly and could be misaligned with the AST
line numbers. ...
v4.2.0b5
What's New in astroid 4.2.0b5?
Release date: 2026-07-27
-
Comprehension conditions now constrain the inference of names used in the
comprehension, likeifstatement conditions already did:
[x for x in lst if x is not None]no longer infersNoneforx
in the element expression.Refs #3094
-
Fix
isinstance()constraints only filtering the first inferred value of
a variable: checking a value made theisinstanceclassinfo uninferable
for the checks of the following values. -
Fix inference of a starred target that is not last in a
forloop, such as
for a, *b, c in .... The elements following the starred one were counted
from the target's own arity rather than from the end of the iterable, so
bwas truncated whenever the iterable was longer than the target. -
Add
qname()method to theSlicenode class, returning
"builtins.slice", so that the node can be used in contexts
that require a qualified name (e.g. pylint'sbasic_checker).Closes #3115
-
Add brain tip for
numpy.fromfileso that calls to
np.fromfile(...)are correctly inferred as returning
numpy.ndarrayinstead ofUninferable.Closes #600
-
Add brain for
decimalthat gets applied if_decimalisn't available. -
Removed the
**kwargsargument from allinferfunctions.
Users upgrading theirastroidversions should ensure they do no pass values other than
contexttoinfer. -
Deduplicate keys when inferring
dict.fromkeys.dict.fromkeys("aab")
now infers a dict with keys"a","b"instead of"a","a",
"b", matching the runtime. This also stopsdict.fromkeysfrom
materializing oneConstnode per character for a repeated string such as
dict.fromkeys("x" * 10 ** 8), which is a single-key dict. -
Fix crash (
TypeError: 'UninferableBase' object is not iterable) in the
multiprocessingbrain when a local package shadows the stdlib
multiprocessingmodule.Closes pylint-dev/pylint#10014
-
Bound string/bytes multiplication (
"x" * n) and integer left shifts
(1 << n) inconst_infer_binary_opthe same way list/tuple
multiplication and**already are. Inferring a constant such as
"A" * 10 ** 10previously materialized the multi-gigabyte result
eagerly; these operations now infer asUninferablewhen the result
would be oversized.Refs #3107
-
Remove the
asnamekeyword argument fromImport._inferand
ImportFrom._infer. The alias-to-real-name translation that
asname=Trueperformed is now hoisted intoImportNode._infer_name,
which runs in_infer_stmtsbefore_inferis dispatched. Direct
callers ofImport.infer/ImportFrom.infer(previously the
asname=Falsepath) now consistently resolve the lookup name as-is.The two flows used to collapse into a single inference cache entry
because theasnamekwarg was not part of the cache key, so the
second call returned the cached result of the first regardless of
which one ran. With the translation hoisted upstream, the two flows
set differentlookupnamevalues and therefore land on distinct
cache keys, eliminating the collision.Refs pylint-dev/pylint#10193
Closes #3007 -
Fix uncaught
IndentationErrorwhen parsing code whose lines end in
\r: the slice of source tokenized to compute a class or function
positionis split on\nonly and could be misaligned with the AST
line numbers. Such nodes now simply have no position information, as
already done whentokenizeraisesTokenError.Closes #3091
-
Support PEP 810 lazy imports (new in Python 3.15).
Importand
ImportFromnodes gain alazyboolean attribute. -
Support PEP 798 comprehension unpacking (
{**d for d in dicts},
new in Python 3.15). -
Fix astroid bootstrap crash on PyPy 7.3.22 (
TypeError: expected str, got getset_descriptor object) by also catchingTypeErrorfrom
getattr(obj, alias)inInspectBuilder.object_build. PyPy 7.3.22
raisesTypeErrorinstead ofAttributeErrorfor unset getset
descriptors liketypes.FunctionType.__text_signature__, which made
_astroid_bootstrapping()blow up on any call into astroid. -
Shorten
import astroidby deferring imports only needed on cold paths.
logging(used bymodutilsandraw_buildingsolely to report
stderr/stdout captured while importing a module) andpprint(used only
to format debug__repr__/repr_treeoutput) are now imported
lazily, andastroid.exceptionsimportsastroid.typingunder
TYPE_CHECKING. -
Fix
AttributeErrorcrash instarred_assigned_stmtswhen a starred
unpacking target is an attribute (e.g.for *o.attr, x in ...) rather
than a simple name.Closes #2646
-
Fix
AttributeErrorcrash in theArgumentsassigned_stmts
protocol when called without an inference context (the public
assigned_stmtsAPI defaultscontexttoNone). Resolving a
function's first parameter dereferencedcontext.boundnodewhile the
matchingcontext and ...guard a few lines below was missing; it now
degrades to Uninferable. -
Fix
AttributeErrorcrash inClassDef.infer_call_resultwhen called
through the public API without a context (it defaults toNone) for a
class whose metaclass defines__call__: the callee was assigned to
context.callcontext.calleewithout checking that a call context exists.
It is now guarded, matching the surrounding code. -
Wrap assignment expressions (
:=) in parentheses when emitting
as_stringoutput so the rendered code remains syntactically valid in
contexts such as comparisons, where Python requires the walrus expression
to be parenthesized.Closes #2668
-
Catch
MemoryError/RecursionError(andValueError) when validating
type comments withast.parse. Pathological type comments produced by
fuzzers (e.g.# type: i{{{{{{{...) previously crashed parsing with a
MemoryErrororRecursionErrordepending on the runtime; astroid now
treats them as invalid type comments and skips them, mirroring the f-string
fix from #2762.Closes #2993
-
Fix
TypeErrorinbrain_randomwhenrandom.sampleis called with a
sequence containing nodes whose__init__does not acceptlineno
(e.g.Module). The clone helper now filters init params to those the
class actually accepts.Closes #3043
-
Fix
RecursionErrorin_compute_mro()when circular class hierarchies
are created through runtime name rebinding. Circular bases are now resolved
to the original class instead of recursing.Closes #3023
Closes pylint-dev/pylint#10821 -
Changed
block_rangeto considerelseits own block, allowingpylintto apply
disables to just the block.References pylint-dev/pylint#872
-
Fix uncaught
TokenErrorwhen building a class or function whose source
slice is malformed.tokenize.generate_tokensmay raise (e.g. on an
unterminated bracket on Python < 3.12); position computation now treats such
a node as having no position information instead of crashing.Closes #2527
-
str()of a constant argument now infers the actual string value instead
of always inferring"". When every inference path of the argument
resolves toConstvalues that stringify to the same string,infer_str
returns that string; otherwise it keeps falling back toConst("").Closes #2994
-
Fix
AttributeErrorcrash when looking up a special method on a class
whose explicit metaclass infers to a non-class node (e.g. a function). Such
a metaclass has no MRO, so the dunder lookup now raises
AttributeInferenceErrorinstead of crashing.Closes #3063
-
Fix
AttributeErrorcrash inClassDef.getitemwhen__class_getitem__
resolves to a non-callable node (e.g. anAssignName).getitemnow
raisesAstroidTypeErrorin that case, consistent with its documented
behaviour.Closes #3064
-
Fix
DuplicateBasesErrorcrash in the enum brain when inferring an enum
class with duplicate bases (e.g.class C(enum.Enum, enum.Enum)).
infer_enum_classnow catchesMroErrorand leaves such a malformed
class untransformed.Closes #3065
-
Fix
InferenceErrorcrash inClassDef.slots()when__slots__is
declared as an annotation without a value (e.g.__slots__: None). Such a
__slots__cannot be inferred, soslots()now returnsNone.Closes #3067
-
Fix
TypeErrorcrash in the enum brain when a functionalEnumcall
has a non-string member name (e.g.Enum("e", (1,))). Such a definition
is invalid, so inference now falls back to the default instead of crashing.Closes #3068
-
Fix detecting static/class methods and inspecting IntFlag types in
GObject-based libraries (GLib, Gtk etc)
Note that this changelog also includes changes from previous betas.
v4.2.0b4
What's New in astroid 4.2.0b4?
Release date: 2026-07-04
-
Removed the
**kwargsargument from allinferfunctions.
Users upgrading theirastroidversions should ensure they do no pass values other than
contexttoinfer. -
Fix crash (
TypeError: 'UninferableBase' object is not iterable) in the
multiprocessingbrain when a local package shadows the stdlib
multiprocessingmodule.Closes pylint-dev/pylint#10014
-
Bound string/bytes multiplication (
"x" * n) and integer left shifts
(1 << n) inconst_infer_binary_opthe same way list/tuple
multiplication and**already are. Inferring a constant such as
"A" * 10 ** 10previously materialized the multi-gigabyte result
eagerly; these operations now infer asUninferablewhen the result
would be oversized.Refs #3107
-
Remove the
asnamekeyword argument fromImport._inferand
ImportFrom._infer. The alias-to-real-name translation that
asname=Trueperformed is now hoisted intoImportNode._infer_name,
which runs in_infer_stmtsbefore_inferis dispatched. Direct
callers ofImport.infer/ImportFrom.infer(previously the
asname=Falsepath) now consistently resolve the lookup name as-is.The two flows used to collapse into a single inference cache entry
because theasnamekwarg was not part of the cache key, so the
second call returned the cached result of the first regardless of
which one ran. With the translation hoisted upstream, the two flows
set differentlookupnamevalues and therefore land on distinct
cache keys, eliminating the collision.Refs pylint-dev/pylint#10193
Closes #3007 -
Fix uncaught
IndentationErrorwhen parsing code whose lines end in
\r: the slice of source tokenized to compute a class or function
positionis split on\nonly and could be misaligned with the AST
line numbers. Such nodes now simply have no position information, as
already done whentokenizeraisesTokenError.Closes #3091
-
Fix astroid bootstrap crash on PyPy 7.3.22 (
TypeError: expected str, got getset_descriptor object) by also catchingTypeErrorfrom
getattr(obj, alias)inInspectBuilder.object_build. PyPy 7.3.22
raisesTypeErrorinstead ofAttributeErrorfor unset getset
descriptors liketypes.FunctionType.__text_signature__, which made
_astroid_bootstrapping()blow up on any call into astroid. -
Shorten
import astroidby deferring imports only needed on cold paths.
logging(used bymodutilsandraw_buildingsolely to report
stderr/stdout captured while importing a module) andpprint(used only
to format debug__repr__/repr_treeoutput) are now imported
lazily, andastroid.exceptionsimportsastroid.typingunder
TYPE_CHECKING. -
Fix
AttributeErrorcrash instarred_assigned_stmtswhen a starred
unpacking target is an attribute (e.g.for *o.attr, x in ...) rather
than a simple name.Closes #2646
-
Fix
AttributeErrorcrash in theArgumentsassigned_stmts
protocol when called without an inference context (the public
assigned_stmtsAPI defaultscontexttoNone). Resolving a
function's first parameter dereferencedcontext.boundnodewhile the
matchingcontext and ...guard a few lines below was missing; it now
degrades to Uninferable. -
Fix
AttributeErrorcrash inClassDef.infer_call_resultwhen called
through the public API without a context (it defaults toNone) for a
class whose metaclass defines__call__: the callee was assigned to
context.callcontext.calleewithout checking that a call context exists.
It is now guarded, matching the surrounding code. -
Wrap assignment expressions (
:=) in parentheses when emitting
as_stringoutput so the rendered code remains syntactically valid in
contexts such as comparisons, where Python requires the walrus expression
to be parenthesized.Closes #2668
-
Catch
MemoryError/RecursionError(andValueError) when validating
type comments withast.parse. Pathological type comments produced by
fuzzers (e.g.# type: i{{{{{{{...) previously crashed parsing with a
MemoryErrororRecursionErrordepending on the runtime; astroid now
treats them as invalid type comments and skips them, mirroring the f-string
fix from #2762.Closes #2993
-
Fix
TypeErrorinbrain_randomwhenrandom.sampleis called with a
sequence containing nodes whose__init__does not acceptlineno
(e.g.Module). The clone helper now filters init params to those the
class actually accepts.Closes #3043
-
Fix
RecursionErrorin_compute_mro()when circular class hierarchies
are created through runtime name rebinding. Circular bases are now resolved
to the original class instead of recursing.Closes #3023
Closes pylint-dev/pylint#10821 -
Changed
block_rangeto considerelseits own block, allowingpylintto apply
disables to just the block.References pylint-dev/pylint#872
-
Fix uncaught
TokenErrorwhen building a class or function whose source
slice is malformed.tokenize.generate_tokensmay raise (e.g. on an
unterminated bracket on Python < 3.12); position computation now treats such
a node as having no position information instead of crashing.Closes #2527
-
str()of a constant argument now infers the actual string value instead
of always inferring"". When every inference path of the argument
resolves toConstvalues that stringify to the same string,infer_str
returns that string; otherwise it keeps falling back toConst("").Closes #2994
-
Fix
AttributeErrorcrash when looking up a special method on a class
whose explicit metaclass infers to a non-class node (e.g. a function). Such
a metaclass has no MRO, so the dunder lookup now raises
AttributeInferenceErrorinstead of crashing.Closes #3063
-
Fix
AttributeErrorcrash inClassDef.getitemwhen__class_getitem__
resolves to a non-callable node (e.g. anAssignName).getitemnow
raisesAstroidTypeErrorin that case, consistent with its documented
behaviour.Closes #3064
-
Fix
DuplicateBasesErrorcrash in the enum brain when inferring an enum
class with duplicate bases (e.g.class C(enum.Enum, enum.Enum)).
infer_enum_classnow catchesMroErrorand leaves such a malformed
class untransformed.Closes #3065
-
Fix
InferenceErrorcrash inClassDef.slots()when__slots__is
declared as an annotation without a value (e.g.__slots__: None). Such a
__slots__cannot be inferred, soslots()now returnsNone.Closes #3067
-
Fix
TypeErrorcrash in the enum brain when a functionalEnumcall
has a non-string member name (e.g.Enum("e", (1,))). Such a definition
is invalid, so inference now falls back to the default instead of crashing.Closes #3068
Note that this changelog also includes changes from previous betas.
v4.2.0b3
What's New in astroid 4.2.0b3?
Release date: 2026-04-24
-
Fix
RecursionErrorin_compute_mro()when circular class hierarchies
are created through runtime name rebinding. Circular bases are now resolved
to the original class instead of recursing.Closes #3023
Closes pylint-dev/pylint#10821 -
Changed
block_rangeto considerelseits own block, allowingpylintto apply
disables to just the block.References pylint-dev/pylint#872
Note that this changelog also includes changes from previous betas.
v4.2.0b2
What's New in astroid 4.2.0b2?
Release date: 2026-04-23
-
Fix
RecursionErrorin_compute_mro()when circular class hierarchies
are created through runtime name rebinding. Circular bases are now resolved
to the original class instead of recursing.Closes #3023
Closes pylint-dev/pylint#10821 -
Changed
block_rangeto considerelseits own block, allowingpylintto apply
disables to just the block.References pylint-dev/pylint#872
Note that this changelog also includes changes from previous betas.
v4.2.0b1
What's New in astroid 4.2.0b1?
Release date: Release date: 2026-03-23
-
Changed
block_rangeto considerelseits own block, allowingpylintto apply
disables to just the block.References pylint-dev/pylint#872