v4.2.0b4
Pre-releaseWhat'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.