# Changelog ## Unreleased - Implement call checking for callable intersection types. - Treat definitely missing attributes on intersection members as an error instead of ignoring them, while still allowing indeterminate members to be ignored when another member provides the attribute. - Normalize pycroscope extension annotations with PEP 604 union operands, such as `Intersection[A, B | C]`, `A | Intersection[B, C]`, and `int | Not[str]`, instead of producing an internal error. - Improve recursive gradual type compatibility for aliases, protocols, and TypedDicts, so recursive `Any` tails no longer hide incompatible nested types and mutually recursive TypedDicts no longer produce internal recursion errors. - Infer and validate class type-parameter variance from the collected class API in both importable and static fallback analysis, including generic bases and callable member annotations. - Treat plain subclasses of frozen dataclasses as mutable for their own annotated attributes, while keeping inherited frozen dataclass fields read-only. - Add basic support for `pycroscope.extensions.Not[T]` negation types, including assignability and intersection simplification. - Simplify unions containing an exact fully static `Not[T]` complement pair, such as `Literal[1] | Not[Literal[1]]`, to `object`. - Deduplicate unions containing equivalent intersections written in different orders, such as `Any & int` and `int & Any`. - Preserve `Not[T]` intersections in negative `TypeIs[T]` narrowing, while keeping other narrowing paths pragmatic. ## Version 0.4.0 (May 2, 2026) This release aims to strengthen robustness and quality, fixing many issues found in real-world code. - Add precise type inference for the result of `operator.getitem`. - Add a disabled-by-default `private_import` error code that flags imports and module attribute reads of single-underscore module members; pycroscope's self check now enforces it. - Recognize `warnings.deprecated` as a deprecation decorator in static fallback analysis, fixing missed deprecated diagnostics with newer `typing_extensions` backports. - Fix false positive `unsafe_comparison` errors when comparing a value narrowed by a length predicate against its original type. - Preserve precise dictionary entries for `dict.fromkeys()`, so known literal keys with a shared value can satisfy broader `dict[...]` return annotations. - Fix false positive `undefined_attribute` errors for `@staticmethod` methods accessed through dataclass instances. - Fix overload-only callable protocol methods so protocol compatibility checks use the declared overload set instead of the runtime overload placeholder. - Fix callable signature compatibility for syntactic `*args: Any, **kwargs: Any` tails and `ParamSpec[...]`, so callable protocols interoperate with fixed signatures more consistently. - Drop restrictions against redefined and function-local `type` statements. - Support `typing_extensions.Sentinel` and (on Python 3.15+) `builtins.sentinel`, as specified by PEP 661. - Clean up treatment of attributes to be more consistent and reliable. The `TreatClassAttributesAsAny` configuration is no longer supported. - Fix bug where the constructors of two classes with the same name were mixed up. - Respect class-level runtime constructor signatures for some metaclass-driven and extension-backed classes, so keyword-only constructors like `repoguess.Params(...)` no longer fall back to a bogus `object.__init__` call shape. - Make the command-line runner inject `typing.reveal_type` into `builtins` before importing user modules, with a compatible fallback on older Python versions, so top-level runtime use of `reveal_type()` no longer fails during CLI analysis. - Weaken inferred constructor-return generics, so fresh values like `Box(1)` and nested `defaultdict(...)` calls can satisfy broader annotated generic targets without forcing explicit specialization. - Avoid internal errors for some constructor-style generic patterns like `type[T] | T`, and stop showing a misleading `None.` module prefix in messages for generated callables. - Make `type()` results more consistent for imprecise values like `str`, `type[T]`, and `super()`, so pycroscope preserves subclass-aware class objects where appropriate and stops relying on implicit fallback behavior for internal type values. - Simplify `type()` lookups through narrowed intersections, so `hasattr()`-guarded class-object calls preserve the real constructor signature instead of picking up confusing fallback overloads like `object.__init__`. - Fix assignability involving weak list literals in nested invariant containers, so values like `defaultdict(lambda: ([], []))` can satisfy annotated tuple-valued `dict` entries instead of failing on the inner empty-list literals. - Improve nested tuple mismatch diagnostics so assignments involving tuple-valued generics now report which tuple element failed instead of the vague message `tuple is not assignable to tuple`. - Add an opt-in `--find-unused-call-patterns` check, plus `enforce_no_unused_call_patterns`, to report parameters whose accepted call shapes are only partially exercised, including always-omitted defaults, one-sided boolean flags, and unused union members. - Fix bare generic-class annotations so user-defined generics like `Capybara` now report `missing_generic_parameters`, and partially specialized forms like `Capybara[int]` report `invalid_specialization`. - Fix `hasattr()`-driven narrowing bookkeeping so synthetic attributes no longer show up as fake unused members, and looped identity checks like `value.param_spec is ps_args.param_spec` no longer poison nearby temporary-variable reads. - Fix `hasattr()`-based intersection lookup so class-object attributes like `cls.__name__` remain available after narrowing through unrelated `HasAttr[...]` predicates. - Fix class-object narrowing for unconstrained generic values, so combined checks like `isinstance(x, type) and issubclass(x, Base)` now preserve the refined `type[Base]` information inside the resulting intersection instead of getting stuck at `Any & type`. - Fix local attribute tracking for descriptor-backed optional attributes, so guarded writes like `if self.field is None: return; self.field = value` keep `self.field` narrowed within the current method instead of widening later reads back to the optional type. - Fix fallback-mode `TypeVarTuple` callable inference so conformance-style checks like `Process(target=..., args=...)` now match fixed-arity callables more consistently. - Make transformed instance attributes keep their declared types on writes, so bad assignments like `self.name = maybe_none` are reported and no longer widen later `self.name` reads across a method or class. - Fix false positive `incompatible_argument` errors for numeric `sum()` calls, so ordinary iterables like `list[int]`, generator expressions, and `dict.values()` type-check cleanly again. - Add an opt-in `unreachable` check that reports dead code after guaranteed termination and in impossible control-flow paths such as always-false branches and short-circuited boolean operands. - Support PEP 800 `@disjoint_base` classes in intersection-based narrowing, so incompatible `TypeIs[...]` checks on different disjoint bases now narrow to `Never`. - Improve class-symbol decorator metadata so final, abstractmethod, and deprecation checks now reuse stored symbol information more consistently, including deprecated class/static methods and property accessors. - Fix cache-order-dependent protocol lookup for importable runtime types, so string-backed types like `contextlib.AbstractContextManager[T]` no longer need a prior runtime lookup before context-manager protocol checks and self-checks succeed. - Fix runtime method binding for Cython-backed descriptor methods, so chained calls like `self.method.asynq()` no longer produce false positive call-arity errors or depend on fallback lookup. - Improve `TypeVar` inference for overloaded constructor callables, so patterns like `model_field(converter=dict, default=())` no longer fail by committing to the wrong `dict` overload too early. - Fix `Self`-aware descriptor lookup so instance access keeps `Self` through classmethod helper chains like `self.getter().get_one()`, and class-level descriptor comparisons like `Model.parent == self` can return custom query objects instead of collapsing to `bool`. - Fix `__init_subclass__` class-attribute initialization so projects can declare a class-level attribute contract on a base class and initialize it via `cls.attr = ...` without spurious instance-attribute errors. - Make class-object attribute lookup prefer real runtime members before synthetic overlays, so descriptor-backed class attributes keep working even when method bodies assign through `self.attr` or transformed instance access is enabled. - Fix runtime generic descriptor specialization so instances like `Field[int]()` and `Field[Other | None]()` keep their concrete payload types during attribute lookup instead of falling back to unspecialized `~T`. - Fix `Self`-typed iterator and query methods during fallback analysis, so classmethod patterns like `for i, obj in enumerate(cls.select()): ...` and `query = cls.select()` preserve `Self` instead of misbinding nested receiver types. - Fix a method-binding regression in fallback analysis so inherited instance methods are bound exactly once, which removes false positive call-arity errors in projects that use transformed class attributes. - Fix a `Self` regression for generic receiver methods, so calls like `Query[Self].filter() -> Query[Self]` and `Getter[Self].get_one() -> Self | None` no longer get widened to nested receiver types during fallback analysis. - Fix a user-visible regression in large project analysis so pycroscope no longer prints stray internal `__getitem__` debug lines, and avoids internal errors when stub lookup touches runtime objects whose `__getattr__` methods can raise project-specific exceptions. - Split overloaded annotation diagnostics into narrower ones: pycroscope now uses `invalid_self_usage`, `invalid_paramspec_usage`, and `invalid_qualifier` for those specific mistakes, keeps other bad annotation forms under `invalid_annotation`, uses declaration-specific codes like `invalid_typeddict`/`invalid_namedtuple`/`invalid_overload`/`invalid_final`/`invalid_type_alias`/`invalid_protocol`/`invalid_type_parameter`, reports duplicate type-alias statements as `already_declared`, and reports calling `Annotated` aliases as `not_callable`. - Fix fallback-mode generic class-object assignability so synthetic classes now honor declared type-parameter defaults when compared against annotations like `type[Bar[str]]`. - Fix several `Self` edge cases so generic classmethods preserve class arguments like `Box[int].make() -> Box[int]`, `Self | None` stays stable inside method bodies, and `cls` attribute writes using `Self` no longer produce false positives. - Fix generic `NamedTuple` subclasses in import-failure analysis so inherited tuple fields and synthetic methods now keep specialized type arguments, which restores checks like tuple-style indexing and constructor argument validation for classes such as `class Child(Base[int]): ...`. - Fix importable-mode runtime `NamedTuple` constructor inference so runtime classes preserve their concrete return types and tuple behavior without relying on fallback-analysis side effects. - Fix `Self` handling in class-body descriptor expressions so pycroscope now preserves owner-bound `Self` types in both importable and fallback analysis, instead of relying on syntax-specific workarounds. - Fix several internal-error crashes and false positives when analyzing large projects: pycroscope now degrades ParamSpec input-signature placeholders safely in suggested-type generation, avoids treating ordinary container literals with unsupported elements as crashing implicit type aliases, snapshots `from module import *` exports before lazy annotation work can mutate the source module dictionary, and no longer reports callable intersections as `not_callable`. - Fix two false positives around runtime analysis: subscripting ordinary values annotated with a type alias no longer looks like type-alias specialization, and unresolved `match` value patterns now fall back cleanly instead of reporting internal errors. - Improve `TypeObject` attribute lookup for stub-backed members so runtime classes now merge direct stub symbols with runtime descriptors, preserving runtime descriptor shape while using stub type information for properties and other attributes. - Fix class-object metaclass lookup so `TypeObject.get_attribute()` now follows Python's class-access rules, including bound metaclass members and metaclass properties overriding same-named class attributes. - Improve `TypeObject.get_attribute()` descriptor handling so instance-like access now resolves custom `__get__` descriptors more consistently, and class-object lookup correctly lets metaclass data descriptors win precedence over same-named class attributes. - Route more synthetic attribute inference through `TypeObject.get_attribute()`, preserving generic substitution, protocol matching, and `Self`-aware synthetic classmethod behavior in import-failure and stub-only analysis. - Fix dataclass definition diagnostics so invalid field ordering, conflicting `__slots__`, and `KW_ONLY` defaults now use a dedicated `invalid_dataclass` error, and subclasses reject required fields that follow inherited defaulted fields. - Fix `NamedTuple` subclass handling so overriding inherited fields is reported consistently in both module modes, and `pycroscope.get_mro()` preserves the specialized tuple base in import-failure analysis. - Improve deprecated-member diagnostics for inherited properties and `__call__`, so subclasses now inherit those deprecation errors consistently instead of sometimes losing them. - Allow subclasses to add `__slots__` entries without triggering `incompatible_override`, while still rejecting writes to attributes that are not declared in inherited slots. - Improve `match` fallthrough narrowing for irrefutable class and sequence patterns, so later cases and wildcard fallbacks now exclude values already guaranteed to match earlier branches. - Fix attribute-assignment checks on unions and intersections so pycroscope now preserves special-case errors like `Final`/`ClassVar` writes and still validates declared attribute types across each possible receiver branch. - Improve `super()` modeling so pycroscope now tracks `super` calls with a dedicated internal value, resolves `super()` attribute lookup more consistently, and accepts staticmethod access like `super().label()`. - Run Python 3.14 CI tests with coverage reporting, and keep a pinned set of fully covered modules at 100% coverage so regressions in files like `annotated_types.py`, `regex_check.py`, and `type_evaluation.py` fail CI. - Make the pytest suite fail on unexpected `DeprecationWarning`s by default, so newly escaped deprecated APIs are caught unless a test intentionally filters them. - Add `pycroscope.get_mro()` and record value-level class MROs on type objects, so generic, tuple-subclass, namedtuple, and synthetic-class inheritance can now be inspected with preserved specialization. - Improve type-parameter scoping for nested classes, class-body aliases, and PEP 695 generic declarations, so out-of-scope or legacy type parameters are rejected more consistently without changing existing variance checks. - Improve tuple-subclass modeling so `NamedTuple` handling relies more on recorded class information, readonly-field enforcement stays consistent, and exact `tuple[...]` subclasses preserve tuple-style behavior more accurately. - Speed up self-checks and other constraint-heavy analysis by caching repeated composite-constraint inversion and application work in scope narrowing. - Fix `Self`-annotated receiver attribute writes so attributes assigned through `self: Self` or `setattr(self, ...)` are recognized on instances instead of later being reported as undefined. - Speed up repeated declared-symbol lookups for synthetic and runtime-backed classes, reducing checker overhead on large modules and self-check runs. - Improve `--find-unused-attributes` so it now reports unused non-method attributes too, handles inheritance and overrides more accurately for polymorphic attribute access, treats concrete classes proven compatible with protocols as implementations of those protocols, skips `TypedDict` fields and framework-generated members, and supports config hooks to ignore patterns like `visit_*` methods on AST visitors and helper classes in test-only modules. - Reduce `--find-unused-attributes` false positives by ignoring `dataclasses.InitVar` pseudo-fields and `generic_visit()` methods on AST visitor classes. - Add an `ignored_unused_attribute_paths` option so individual unused-attribute findings can be suppressed by fully-qualified path, for example `pycroscope.analysis_lib.Sentinel.name`. - Restore the self-check's unused-object enforcement so repo-wide self-checks once again fail on genuinely unused module-level objects. - Add an `enforce_no_unused_attributes` option so repo and self-check runs can fail on unused class attributes without needing `--find-unused-attributes`. - Add PEP 767 `ReadOnly` attribute support for classes and protocols, including assignment/deletion errors for readonly members, protocol matching for readonly attributes, and `Final`-attribute deletion errors. - Fix a crash when resolving inherited string annotations for instance attributes accessed through `cls` in methods, so these attributes now infer their annotated types instead of raising an internal error. - Improve `isinstance()` narrowing for local class objects, including `NamedTuple` classes, so branches now narrow correctly even when the class object comes from pycroscope's synthetic local-class representation. - Improve `isinstance()` narrowing for generic class objects, so checks like `if isinstance(x, typ):` with `typ: type[T]` now narrow `x` using the type parameter instead of falling back to an imprecise type. - Improve `TypeVar` handling by distinguishing declared type parameters from call-site inference variables, so pycroscope no longer solves rigid `TypeVar`s during ordinary assignability checks and now preserves more accurate generic-call and recursive type-alias behavior. - Fix context-manager inference for cases like `contextlib.nullcontext()` and unions of different context manager implementations, so `with` bindings and exit-type checks now keep the right types instead of falling back to imprecise results or spurious errors. - Improve several inference edge cases: `iter(d.values())` now produces an `Iterator` with the right value type, tuple-valued attributes stay narrowed after truthiness and `len()` checks, and bitwise operations on `enum.Flag`/`re.RegexFlag` preserve the enum type. - Restore concise generic-parameter names in invalid type-alias diagnostics, so errors mention forms like `~T: str`, `~P`, and `Ts` instead of full internal parameter object reprs. - Fix `Generic[...]` and `Protocol[...]` base validation parity between importable and import-failure analysis, including PEP 695 class declarations like `class C[T](Generic[T])` that should be rejected consistently. - Fix `@dataclass_transform` parity between importable and import-failure analysis: pycroscope now reuses synthetic dataclass metadata for runtime-backed classes when checking attributes like `__hash__` and `__match_args__`, so hashability and class-pattern matching behave consistently in both modes. - Reject more invalid `Self` usages: pycroscope now reports errors for module-level `Self`, `Self` in type aliases or base-class expressions, and method signatures that use `Self` from staticmethods, metaclasses, or mismatched explicit receiver annotations. - Fix constructor result specialization for `float` arguments and overloaded `__init__` methods, so `assert_type()` now agrees with pycroscope's implicit `float | int` semantics in cases like `Box(1.0)` and `Box[float](1)`. - Fix `@dataclass_transform` field specifier checking for unimportable modules so converter-based defaults and constructor inputs work consistently for callables like `dict`. - Fix generic scoping checks so pycroscope now rejects out-of-scope type parameters in local and class-body annotations, nested class definitions, class-body type aliases, and runtime type expressions like `list[T]()` at module scope. - Reclassify invalid inheritance diagnostics: pycroscope now reports `invalid_base` instead of `invalid_annotation` for class-base errors such as bad `Generic[...]`/`Protocol[...]` bases, inheriting from `@final` classes, and incompatible multiple `TypedDict` bases. - Fix type-alias attribute handling in fallback mode: `Alias: TypeAlias = int` now uses runtime `int` attributes, while `type Alias = int` continues to expose alias-object attributes like `__value__`. - Improve `NamedTuple` compatibility for tuple-style indexing, unpacking, and item mutation checks. - Enforce function-parameter annotations on later reassignments, so pycroscope now reports incompatible writes like reassigning `x: int` to `str` or widening `Literal[...]` parameters with `+=`. - Fix variadic type-alias specialization in static fallback mode: pycroscope now solves `TypeVarTuple` arguments through aliases like `tuple[*Ts, T1, T2]` and preserves explicit empty-pack specializations such as `Array[()]` even when a module cannot be imported. - Improve `Self` handling in fallback mode for unimportable modules: pycroscope now resolves `@property` getters, inherited `Self`-annotated attributes, and `cls`/`self` receivers more accurately in advanced generic cases. - Restore simple `assert_type()` equivalence checking: pycroscope now compares the inferred type against the type form of the second argument directly, without special-case exact-type reconstruction for recent constructor and annotation patterns. - Preserve empty `TypeVarTuple` specializations when converting runtime generic aliases back into types, so checks like `assert_type(x, tuple[str, Array[()]])` continue to understand `Array[()]` instead of collapsing it to bare `Array`. - Stop exposing enum instance-only descriptors like `.name` as class attributes on enum types; pycroscope now reports these as undefined on enum classes, matching Python runtime behavior. - Fix several composite-type edge cases so pycroscope now preserves union/intersection handling when detecting missing async yields, deliteralizing enum attributes, and widening inferred `TypeVarTuple` arguments. - Treat `typing.TYPE_CHECKING` and `typing_extensions.TYPE_CHECKING` as statically true in control flow, so `if TYPE_CHECKING:` blocks are analyzed while runtime-only branches are skipped. - Improve deprecated-diagnostic coverage in static fallback mode for unimportable modules: pycroscope now reports deprecations for `__call__`, protocol methods, property getters/setters, and inplace-operation fallbacks (for example `x += y`) more consistently. - Improve generic default specialization behavior for both type aliases and classes: unsubscripted aliases/classes now use declared type-parameter defaults (rather than `Any`), overspecialization is reported consistently, and static fallback mode now preserves these semantics after import-time runtime failures. - Fix deprecated-overload inference when overload definitions are wrapped (for example by `typing_extensions.deprecated`): pycroscope now follows `__wrapped__` for overload signatures while preserving deprecation diagnostics on the selected overload. - Add a global `typeshed_path` option to override the typeshed root pycroscope uses for typeshed-client resolution, accepting either a directory with `VERSIONS` or one with `stdlib/VERSIONS`, and now reporting a clear error if neither exists. - Add a new `pycroscope.extensions.Overlapping[T]` type primitive: assignments to `Overlapping[T]` now accept values whose types overlap with `T` (that is, `T & U` is not `Never`). - Fix `Self` return checking for methods and classmethods: pycroscope now rejects returning concrete base-class instances from `-> Self` methods (for example `return Shape()`), which previously slipped through as valid. - Improve PEP 695 scoping checks by rejecting type-parameter bounds/constraints that depend on other type parameters, and preserve module execution order in import-failure fallback mode so top-level uses before assignment now report `undefined_name`. - Improve variance and generic-call checking in static fallback mode for unimportable modules: legacy `TypeVar(..., infer_variance=True)` now infers class variance from member usage, legacy `Generic[T]` classes preserve their type parameters more reliably, and generic `@dataclass` constructor calls retain explicit type arguments. - Improve type-inference handling of `|` type expressions in value position: pycroscope now preserves and resolves type-form unions (including metaclass types) without relying solely on runtime `__or__`/`__ror__`, fixing `assert_type(...)` checks like `constructors_call_metaclass.py`. - Fix constructor-call checking with generic metaclass passthrough methods: when a metaclass `__call__` is just `*args/**kwargs -> T`, pycroscope now falls back to class `__new__`/`__init__` signatures instead of incorrectly accepting missing constructor arguments. - Fix `TypeVarTuple` type-alias specialization for explicit empty and unpacked forms: aliases like `IntTuple[()]` and `TA9[*tuple[int, ...], str]` now preserve variadic bindings instead of defaulting to `Any` or nesting tuple arguments incorrectly. - Improve generic base handling in static-fallback analysis: pycroscope now preserves `Generic[...]` type-parameter order when imports fail, validates `Generic[...]`/`Protocol[...]` base arguments and coverage, rejects generic metaclass specialization, and preserves constrained `TypeVar` correlations in binary operations like `AnyStr` concatenation. - Improve generator annotation checking: pycroscope now reports missing returns based on a generator's declared return component (`Generator[..., ReturnT]`) and accepts protocol-based generator return annotations (for example protocols defining `__next__`/`__anext__`). - Conformance CI runs now disable the `must_use` error code so typing-conformance comparisons ignore intentionally discarded generator-expression values (such as `assert_type(...)` checks). - Improve `@dataclass_transform` converter support: synthesized constructor argument types and dataclass field assignment checks now use converter input types, and `default_factory` checks now validate against converter inputs instead of converted field types. - Fix `TypeVarTuple` concatenation in generic-class specialization so annotations like `Array[Batch, *Shape]` now infer as `Array[Batch, ...]` rather than collapsing to a single tuple type argument. - Improve callback-protocol compatibility for callable metadata members: pycroscope now treats function `__name__`/`__module__`/`__qualname__` as `str`, avoids false protocol override/assignment errors for these members, and reports unknown attribute writes on protocol-typed callables. - Fix `TypeVarTuple` unpack handling in generic class annotations: pycroscope now correctly type-checks patterns like `Array[Batch, *tuple[Any, ...], Channels]` and `Array[*tuple[Any, ...]]` in both normal and static-fallback analysis. - Fix protocol constructor-call handling for abstract class objects: pycroscope no longer reports spurious `Cannot instantiate protocol class ...` errors when calling through values typed as `type[Proto]` that may refer to concrete implementers. - Improve explicit-protocol checks in import-failure fallback mode: pycroscope now rejects abstract `super()` protocol calls without defaults, enforces protocol-declared member assignment types, and correctly flags instantiation of explicit protocol implementers that still have abstract members. - Improve explicit `TypeAlias` handling: pycroscope now preserves generic alias metadata (including `ParamSpec`) for `Alias: TypeAlias = ...`, reports invalid alias specializations more consistently, and treats unsubscripted `Callable[P, T]` aliases as `Callable[..., T]`. - Improve recursive type-alias checks: pycroscope now specializes recursive implicit generic aliases correctly, rejects circular `TypeAlias` unions more consistently, and reports runtime calls to union alias values as invalid. - Reduce runtime-import side effect leakage in module-scope inference for local class instances, improving `assert_type(...)` stability for dataclass `Final` fields even when later assignments mutate runtime objects. - Fix override checking for class and dataclass attributes so pycroscope now reports `incompatible_override` when `ClassVar` and instance variables override each other across inheritance. - Fix generic type-erasure class attribute checks: pycroscope now rejects class-object reads/writes of instance-only annotated attributes (including specialized generic aliases like `Node[int].label`), instead of allowing runtime import side effects to mask these errors. - Improve `LiteralString` inference for f-strings: pycroscope now preserves `LiteralString` for f-strings whose formatted expressions are all `LiteralString`-compatible, and falls back to `str` when any expression is not `LiteralString`. - Improve `Value` dispatch handling in name-check helper paths so enum `_ignore_` parsing, dataclass default detection, type-parameter identity extraction, and runtime-literal index checks process unions/intersections consistently. - Fix `@dataclass_transform` marker recognition to use inferred decorator values, so unrelated decorators named `dataclass_transform` are no longer treated as PEP 681 markers. Also improve support for other dynamic variations on dataclass_transform and dataclass decorators. - Improve `annotated_types` length-check metadata handling for unions/intersections by normalizing through fallback values and computing `MinLen`/`MaxLen` bounds more consistently. - Apply intersection-based narrowing for positive `isinstance(...)`, `issubclass(...)`, `TypeIs[...]`, and `is_of_type(...)` checks in more paths, aligning these checks with other intersection constraint handling. - Improve recursive protocol matching with `@classmethod` members: pycroscope now preserves classmethod parameter constraints and `Self` specialization in synthetic static-fallback analysis, fixing false protocol incompatibilities and downstream `Any` inference. - Improve generic-base-class analysis in static fallback mode for unimportable modules: pycroscope now preserves generic base mappings and type-parameter ordering more accurately, reports duplicate/conflicting generic base type-variable declarations, and rejects `Generic`/`Generic[...]` used as type annotations outside base-class lists. - Improve PEP 695 generic declaration checks: pycroscope now rejects `Generic[...]`/`Protocol[...]` specialization in `class C[T]` bases, handles forward references in type-parameter bounds/constraints without spurious `undefined_name` errors, and reports invalid type-parameter constraint tuples with fewer than two types. - Preserve literal type arguments when inferring generic class-syntax `NamedTuple` constructor return types (for example, `Box(1)` now infers `Box[Literal[1]]`). - Improve `TypeVarTuple` handling for generic classes in static-fallback analysis: pycroscope now preserves variadic argument lengths and `NewType` members during inference, and correctly reports incompatible tuple lengths across repeated uses. - Fix static-fallback generic-class specialization with `TypeVarTuple` bases so annotations like `Array[Height, Width]` no longer spuriously report wrong type-argument arity after an import-time runtime failure in the same module. - Generalize repeated `TypeVarTuple` inference so same-length element mismatches merge to per-position unions across call contexts (including `*args: tuple[*Ts]` and callable packs), while still rejecting mismatched tuple lengths. ## Version 0.3.0 (March 1, 2026) This release includes a large number of changes aimed at improving compliance with the [Python typing spec](https://typing.python.org/en/latest/spec/index.html). While many features are still missing or incomplete, there is now some degree of support of all major type system features. - Improve `TypeVarTuple` solving for repeated tuple-parameter uses (for example `def f(*args: tuple[*Ts])`): incompatible tuple shapes across arguments are now rejected, and same-length element mismatches are inferred as per-position unions. - Remove additional name-based receiver checks in protocol and call-signature handling, so nonstandard receiver names no longer affect protocol-member binding or TypedDict-backed dict-method checks. - Reduce name-based method heuristics by checking receiver parameters structurally in more places, which improves consistency for methods that don't use literal `self`/`cls` names. - Improve generic protocol checking by honoring `Protocol[...]` type-parameter order and rejecting protocol matches with unsatisfiable cross-member type-variable constraints. - Improve method-receiver handling by using inferred receiver semantics instead of hard-coded `self`/`cls` names, so checks for `Final` instance attributes, protocol-member synthesis, enum `_value_` assignments, and receiver attribute writes now behave correctly with nonstandard receiver names. - Improve protocol/class-object conformance for class-object assignments: pycroscope now enforces method/property/class-variable compatibility more accurately (including static-fallback analysis for unimportable modules). - Fix `@dataclass_transform` metadata tracking to live on inferred values instead of scope-name side tables, which avoids internal errors in cases like `ParamSpec` declarations and `global`/`nonlocal` references. - Improve `ParamSpec` component checking and forwarding: pycroscope now rejects more invalid `P.args`/`P.kwargs` annotation and call forms, accepts valid `Concatenate` forwarding patterns like `foo(1, *args, **kwargs)`, and no longer reports `generics_paramspec_components` as a known conformance failure. - Improve ParamSpec handling in static-fallback analysis for unimportable modules: generic classes like `Y(Generic[U, P])` now preserve ParamSpec type parameters from `Generic[...]` bases, list-form specializations like `Y[int, [int]]` are interpreted correctly, and callable attributes like `y.f` specialize to concrete signatures. - Improve descriptor handling for dataclass-like classes (`@dataclass` and `@dataclass_transform`): constructor parameters now use descriptor `__set__` value types for data descriptors, and class/instance attribute reads now follow descriptor `__get__` return types. - Tighten ParamSpec specialization checks for generic classes: pycroscope now reports `invalid_annotation` for invalid mixed-generic forms like `C[int, int]` when the second parameter is a `ParamSpec`, while still accepting valid forms like `C[int, [int]]`, `C[int, P]`, `C[int, Concatenate[str, P]]`, and `C[int, ...]`. - Improve `Value` dispatch consistency in suggested-type and class-key inference helpers by normalizing through fallback values and handling unions/intersections more consistently. - Improve `Value` dispatch robustness in name checking so enum assignment analysis, protocol-base detection, and type-parameter extraction handle unions/intersections consistently and avoid internal errors on non-gradual values. - Improve intersection-type attribute checks so pycroscope now enforces slot restrictions, frozen-dataclass immutability, and NamedTuple field immutability for `Intersection[...]` instance values. - Improve class-object resolution for annotated and generic values in core name checking, reducing false negatives in protocol-instantiation, enum-base, and attribute-target checks. - Improve protocol/class-object compatibility checks by handling more class-value forms consistently (including `SubclassValue` generic wrappers and `type`-typed values). - Improve `@contextmanager`/`@asynccontextmanager` inference: decorated callables now keep context-manager return types, and `with ... as x` now infers the yielded value type more precisely. - Improve constraint narrowing consistency by routing `isinstance(...)` and `is ...` checks through relation-based subtype logic, reducing edge-case mismatches across complex value kinds. - Apply NamedTuple runtime-call suppression consistently by removing the special-case exemption for classes in `pycroscope.*` modules. - Update internal `@contextmanager` return annotations to use `Generator[...]`, improving compatibility with newer typing/typeshed behavior. - Improve protocol compatibility in static fallback mode for unimportable modules: pycroscope now enforces ClassVar-vs-instance member distinctions, writable data-member/property rules (including setter requirements), and supports plain writable attributes for read-only protocol properties. - Fix tuple-literal equivalence checks so `Literal[("x",)]` is treated as equivalent to `tuple[Literal["x"]]` in subtype/equivalence relations. - Improve dataclass constructor/pattern semantics in static fallback mode: pycroscope now honors class-level `init`/`match_args` settings for `@dataclass` and `@dataclass_transform`, and recognizes `factory=` field specifier defaults when checking generated constructors and `default_factory` return types. - Improve dataclass conformance in static fallback mode for unimportable modules: pycroscope now validates default-before-non-default field ordering, checks `default_factory` return types against field annotations, preserves callable dataclass fields as values (not bound methods), exposes dataclass metadata (`__dataclass_fields__`), and resolves inherited dataclass constructors more accurately. - Tighten `TypeVarTuple` validation: pycroscope now reports `invalid_annotation` for unpacking mistakes like `tuple[Ts]`, `*args: Ts`, `Generic[Ts]`, and `Generic[*Ts1, *Ts2]`, and no longer emits spurious `Unrecognized annotation typing.Unpack[...]` errors for annotations like `Array[*Shape]`. - Improve `TypeVar` default validation: pycroscope now reports `invalid_annotation` when defaults conflict with bounds or constraints, enforces `Generic[...]` default-order rules (including import-failure fallback mode), and treats unspecialized synthetic class objects as compatible with specialized `type[...]` forms. - Improve constructor checking when modules fail at import time: pycroscope now enforces explicit `__init__` self-annotation compatibility for specialized generic class calls (for example rejecting `Class4[str]()` when `__init__` requires `Class4[int]`), and avoids false positives from synthetic class-subscripting fallback on generic instances. - Improve `TypeAliasType(...)` handling: variadic alias specialization now supports `TypeVarTuple`, runtime `type_params` scope/literal-tuple and circular-definition checks are enforced, and recursive alias evaluation no longer triggers internal recursion errors. - Fix variance checks in static fallback mode for unimportable modules by recovering generic type parameters from base annotations, which removes false `invalid_annotation` errors and restores expected nested-alias variance errors (for example `generics_variance.py`). - Fix a crash in type relation checks when comparing generic arguments that mix ParamSpec call-signature values with non-ParamSpec values; pycroscope now reports a regular type mismatch instead of `internal_error`. - Accept ParamSpec list specialization syntax in generic classes (for example `C[[int]]` for `class C[**P]`), matching the typing spec’s allowed form. - Improve static fallback analysis for unimportable modules by pre-registering synthetic methods and persisting `self`/`cls` attribute assignments, reducing false `undefined_attribute` errors in class methods. - Tighten typing-construct arity validation in annotations (including `ClassVar`/`Final`/`Required` qualifiers and runtime `Callable[...]` parsing), so malformed argument lists are reported more consistently. - Improve `@dataclass_transform` field specifier default handling: pycroscope now infers implicit `init` values from field-specifier signatures (including overload defaults like `Literal[False]`), fixing constructor checks for cases like `dataclasses_transform_field.py`. - Improve dataclass `slots` checking (including `@dataclass_transform` classes): pycroscope now surfaces `__slots__` for slotted dataclasses, rejects `slots=True` classes that also define `__slots__`, and reports invalid assignments to attributes not declared in slots (including static fallback mode for unimportable modules). - Fix callable protocol compatibility for `__call__` signatures in import-failure fallback mode (including `*args: Any, **kwargs: Any` ellipsis-style tails and `Concatenate[..., ...]` interop), improving conformance for `callables_annotation.py`. - Improve generic alias constructor checking in static fallback mode: calls like `Node[int](...)` now preserve explicit type arguments for inference and enforce constructor argument types. - Improve protocol conformance by rejecting protocol instantiation and fixing generic/variance protocol subtyping checks, including static fallback handling for protocol generic bases when runtime import metadata is incomplete. - Improve static fallback analysis for unimportable modules by resolving synthetic class instance methods from synthetic bases in expression contexts, reducing false `undefined_attribute`/`inference_failure` cascades for cases like `Self`-typed methods. - Improve static fallback analysis for unimportable modules by making synthetic `@classmethod` attributes callable and preserving `Self` return specialization (for example inferring `Circle` from `Circle.from_config(...)`). - Improve `ClassVar` conformance checks: pycroscope now rejects `ClassVar` outside class-body attribute declarations (including type aliases), reports errors for assignments to class variables through instances, and adds a new `classvar_type_parameters` error code (disabled by default) for rejecting `ClassVar` type parameters (`TypeVar`/`ParamSpec`); conformance CI now enables this stricter check. - Improve static fallback analysis for unimportable modules by resolving synthetic class instance methods from synthetic bases in expression contexts, reducing false `undefined_attribute`/`inference_failure` cascades for cases like `Self`-typed methods. - Fix dataclass hashability inference (including `@dataclass_transform` classes): mutable `eq=True` classes are now treated as unhashable unless `unsafe_hash=True` or an explicit `__hash__` is provided, in both normal analysis and import-failure fallback mode. - Improve dataclass `InitVar` handling: `__post_init__` signatures are now validated against `InitVar` fields (including inherited fields), and `InitVar` members are now correctly rejected as instance attributes, fixing conformance for `dataclasses_postinit.py`. - Align `@dataclass_transform` metaclass inheritance with the typing spec: classes that directly specify a transform-decorated metaclass are now treated as neither frozen nor non-frozen, which fixes conformance behavior for `dataclasses_transform_meta.py`. - Replace internal starred-expression handling with `PartialValue` `UNPACK` operations, removing `_StarredValue` and making partial unpack evaluation consistent across annotations and runtime expression analysis. - Enforce type-variable variance compatibility in class inheritance through generic aliases, so invalid bases like `Base[T_co]` and aliased equivalents now report `invalid_annotation`. - Tighten `Callable[...]` annotation validation to match the typing spec: pycroscope now correctly rejects invalid forms like `Callable[int]`, `Callable[int, int]`, `Callable[int, int, int]`, and `Callable[[...], T]`. - Improve dataclass and `@dataclass_transform` constructor/comparison checking: synthetic dataclass constructors no longer inherit non-dataclass base `__init__` parameters, generic transform bases now propagate correctly (including `Base[T]` forms), and `<`/`<=`/`>`/`>=` comparisons now enforce dataclass ordering rules. - Add initial PEP 681 `@dataclass_transform` support: classes transformed by marked decorators, base classes, or metaclasses now get dataclass-like constructor/frozen semantics in both normal analysis and static fallback mode when imports fail. - Honor standard `# type: ignore` comments (including top-of-file file-level ignores), so pycroscope now suppresses errors in the same places users expect from typing-spec directives. - Reduce false-positive `incompatible_override` errors for protocol-style method overrides by comparing callable signatures more consistently in override checks. - Improve `ParamSpec` handling by rejecting invalid annotation locations more consistently (including bare `ParamSpec` type aliases, `list[P]`, and `Callable[..., P]` return positions), and enforce assignment-target name matching for `TypeVar`, `TypeVarTuple`, `ParamSpec`, `NewType`, and functional `NamedTuple`/`TypedDict` declarations. - Improve `TypeVarTuple` callable checking by preserving unpacked tuple parameters in callable argument lists, improving inference for variadic `*args` patterns, and keeping constructor-call checking precise for synthetic classes in static fallback analysis. - Improve protocol runtime-check checks: `issubclass()` now rejects `@runtime_checkable` data protocols, and `isinstance()`/`issubclass()` now report `incompatible_argument` for unsafe-overlap runtime-checkable protocol checks that could succeed at runtime despite incompatible member types. - Improve synthetic constructor-to-callable inference: pycroscope now synthesizes more accurate callable signatures for overloaded `__init__`/`__new__`, honors custom metaclass `__call__`, preserves local `namedtuple` constructor behavior, and handles dataclass constructor fallback (including class vars and import-failure subclasses) more accurately. - Improve static fallback analysis for dataclasses with keyword-only fields: `KW_ONLY` pseudo-fields no longer raise `invalid_annotation`, and kw-only constructor arguments are now checked correctly even when modules fail at import time. - Allow `@override` methods in subclasses of `Any`-derived base classes (for example `class Parent(Any): ...`) instead of incorrectly reporting `override_does_not_override`. - Enforce PEP 695 generic-syntax compatibility rules for classes and generic functions/methods: pycroscope now reports `invalid_annotation` when old-style `TypeVar`/`ParamSpec`/`TypeVarTuple` declarations are mixed into new `class C[T]` or `def f[T](...)` annotation contexts. - Add protocol variance validation for both legacy `Protocol[T]` and PEP 695 generic syntax: pycroscope now reports `invalid_annotation` when declared protocol type-variable variance does not match inferred usage (including unused protocol type variables, which default to covariant). - Add a new `invalid_literal` error code (disabled by default) to flag `Literal[...]` arguments that are outside the typing-spec allowed set, and enable this check in conformance CI runs. - Tighten `type`-statement alias semantics: type aliases are no longer accepted as class bases or `isinstance`/`issubclass` classinfo arguments, alias metadata attributes like `__value__`/`__type_params__` are handled consistently, `type` statements are rejected inside function scope, and pycroscope now reports alias redeclarations/invalid unguarded alias cycles plus bound/constraint violations when specializing `TypeAliasType` aliases (including ParamSpec list-form arguments); `isinstance`/`issubclass` now also reject TypedDicts, non-`@runtime_checkable` protocols, and parameterized generics in classinfo arguments. - Improve constructor-call checking through `type[T]`: pycroscope now validates constructor arguments for both unbounded and bounded `TypeVar` class objects, and rejects extra arguments for classes that use the default no-argument object constructor. - Improve `typing.NewType` handling in static fallback mode (when modules fail at import): pycroscope now preserves NewType constructor results, validates NewType base-type restrictions (for example `Any`, protocols, `TypedDict`, literals, and generic forms), and reports `NewType` assignment-target name mismatches. - Add frozen-dataclass enforcement in both normal and import-failure fallback analysis: assigning to frozen dataclass instance attributes is now rejected, and mixing frozen/non-frozen dataclass inheritance now reports errors. - Preserve generic type arguments more consistently: unsubscripted generic aliases now default their parameters to `Any`, and constructor calls through generic aliases (for example `ListAlias[int]()`) keep static type arguments instead of erasing them to bare runtime container types. - Improve `TypeVar` bound handling by accepting forward-reference string bounds that refer to names defined later in the file, and by reporting `invalid_annotation` when a bound is parameterized by type variables (for example `bound=list[T]`). - Improve `Final` handling for dataclasses by allowing `ClassVar[Final[T]]` in dataclass bodies and by not requiring default-less `Final` dataclass fields to be explicitly assigned in `__init__`. - Unify synthetic class handling by storing synthetic generic/protocol metadata on each synthetic class object, and fix nested local-class intersections so annotation-only members (for example `x: int`) are recognized in attribute checks. - Improve static fallback analysis for unimportable modules: `TypeVar(...)` results are now preserved in annotations, `type[A | B]` unions are analyzed without runtime `|`, `type[...]` now enforces single-argument arity, and `typing.Type` alias values now report undefined attributes correctly. - Replace the internal `_SubscriptedValue` with a public `PartialValue` type that records partial expression evaluation details (including operation kind and runtime fallback value), improving extensibility for partially evaluated type expressions. - Improve protocol checking in import-failure fallback mode by preserving synthetic protocol members and restoring protocol-merging checks (including invalid protocol bases and abstract-class instantiation diagnostics), which fixes conformance coverage for `protocols_merging.py`. - Infer variance for PEP 695 class type parameters from class member usage and generic base classes, improving assignment checks for covariant and contravariant generics. - Accept union arguments for constrained `TypeVar` parameters when each union member matches at least one constraint, including calls like `re.compile(pattern)` where `pattern` is `str | bytes`. - Generalize class-call signature inference to use Python-level metaclass `__call__` methods (not just enum classes), improving call checking for custom metaclasses. - Allow setting `output_format` in `pyproject.toml` so users can choose concise or detailed error output from config files. - Improve enum analysis in import-failure fallback mode by preserving enum-member semantics for synthetic classes, validating declared enum `_value_` types, and avoiding false `unsafe_comparison` errors for enum identity checks. - Improve overload checks in import-failure fallback mode by preserving synthetic base-class relationships for override/final validation, fixing false `override_does_not_override` reports and missed final-method override errors. - Fix internal errors in static fallback analysis for unimportable modules involving zero-argument `super()` and property setters in synthetic classes. - Improve qualifier checking by rejecting calls to `Annotated` aliases, enforcing `Final` rules more consistently (including decorator semantics and class-member initialization), and preserving these checks when modules cannot be imported. - Fix an internal error on bare `ParamSpec` return annotations, and now report bare `ParamSpec` annotations as invalid in direct return/parameter/variable contexts instead of crashing. - Fix a crash in import-failure fallback mode when checking protocols that inherit generic bases (for example `Iterable[T]`), by resolving inherited protocol members statically instead of treating them as missing. - Annotate `match` pattern AST nodes in annotate mode, so `annotate_code()` and self-check no longer leave `Match*` nodes without `inferred_value`. - Fix an internal error when checking equality comparisons between dataclass instances in modules that fail at import time. - Preserve `@overload` behavior in static fallback mode when a module cannot be imported, including overload-aware inference for synthetic class dunder methods like `__getitem__` and consistency checks against overload implementations. - Preserve generic base information for synthetic classes in static fallback mode, so subclasses like `class D(dict[str, int])` are assignable to `dict[str, int]`. - Improve tuple typing behavior by validating invalid `tuple[..., ...]`/multi-unbounded-unpack forms, preserving `tuple[T, ...]` semantics when runtime imports fail, and improving tuple narrowing in sequence-pattern `match` cases. - Improve NamedTuple analysis in both normal and import-failure fallback modes: class-syntax NamedTuple definitions now enforce field/base-class rules, constructor/type inference is more precise (including generics), and tuple indexing/unpacking/type-compat checks now use NamedTuple field types instead of falling back to `Any`. - Tighten attribute-store checks: assigning to or deleting `NamedTuple` fields through attribute syntax now reports errors, and assignments to existing annotated attributes now report `incompatible_assignment` when types do not match. - Replace internal `**kwargs` TypedDict special-casing with dictionary-entry modeling, so TypedDict dict/Mapping assignability rules stay consistent while dict-method calls on TypedDict values still type-check correctly. - Tighten TypedDict conformance by enforcing class-syntax and inheritance checks in importable modules (not only fallback analysis), and by ignoring uninhabitable `NotRequired[Never]` keys in `TypedDict.update()`. - Respect declared `TypeVar` variance in generic assignability and subtyping checks, so covariant, contravariant, and invariant type parameters are enforced correctly. - Fix callable subtyping checks for `**kwargs` so callable protocols compare keyword value types correctly even with invariant generic relation checking. - Tighten `**kwargs: Unpack[...]` callable handling: pycroscope now requires a concrete `TypedDict` inside `Unpack` for `**kwargs`, rejects overlapping named parameters, and disallows assigning plain keyword-only callables to protocols that require unpacked `TypedDict` kwargs. - Remove the unused `requirements.txt` contributor setup file; local development setup now uses `uv sync` and `uv run`. - Improve inference for function-local `collections.namedtuple(...)` definitions by modeling the generated class as a synthetic local class object with a stable qualified name. - Tighten TypedDict operation checking: declared TypedDict variables now keep TypedDict semantics after reassignment, dict literals with unknown or non-literal keys are rejected when assigning to TypedDicts, and `TypedDict.clear()`/`TypedDict.popitem()` now report errors for non-closed TypedDicts or when required/readonly keys are possible. - Improve fallback analysis for unimportable modules so synthetically analyzed `TypedDict` declarations keep `extra_items`/`closed` semantics (including functional `TypedDict(...)` forms), which greatly improves conformance coverage for `typeddicts_extra_items.py`. - Fix functional `TypedDict(...)` field parsing for `Required[]` and `ReadOnly[]`, and restore assignment compatibility between `Protocol[P]` callables and `Callable[P, ...]` aliases in conformance checks. - Preserve static typing-helper inference for module-scope assignments in importable modules when import-time runtime values would otherwise erase that typing information. - Avoid runtime deprecation warnings during analysis by using non-deprecated coroutine detection and suppressing speculative-call deprecation warnings, which speeds up large runs like self-check. - Add a Python 3.12 CI workflow for typing conformance that runs unit tests for the conformance tooling and then fails if pycroscope's conformance outcomes diverge from the known-failing case list. - Speed up repeated analysis runs (including the test suite) by reusing typeshed resolvers across checker instances when stub search paths are the same. - Speed up checker setup by loading regex-related default argspecs only when regex functions are analyzed. - Speed up large analysis runs by memoizing repeated type-relation checks in assignability/subtyping logic. - Make implicit `TypeForm` checks side-effect-free so relation memoization stays safe and suppresses redundant work. - Suppress annotation errors while evaluating runtime forward references, so diagnostics are not misattributed to the current module. - Improve string forward-reference diagnostics by reporting errors on the original annotation lines rather than line 1, avoiding duplicate reports from the collect/check passes, and supporting multiline triple-quoted string annotations (parsed as implicitly parenthesized expressions). - Validate that overloaded implementations are compatible with their `@overload` signatures (including async/decorator-transformed signatures), and report overload/implementation mismatches with the new `inconsistent_overload` error code. - Fix callable protocol subtyping when `__call__` is overloaded, so pycroscope uses the declared overload signatures instead of a generic `*args, **kwargs` fallback. - Fix `assert_type(..., Callable[..., Any])` equivalence checks. - Fix `type[None]` annotations so `type(None)` is accepted and `None` values are rejected in type-checked calls. - Fix handling of historical positional-only parameters (`__x`) in source code: keyword calls to these parameters now error correctly, and invalid definitions like `def f(x, __y): ...` are now reported under a dedicated `invalid_positional_only` error code. - Allow constructor calls to TypedDict classes that are analyzed syntactically (for example when runtime class objects are unavailable), so `MyTypedDict(...)` is type-checked normally in those cases. - Report an error for `isinstance(obj, SomeTypedDict)` to match TypedDict runtime semantics. - Report an error when `TypedDict` is used as a `TypeVar` bound. - Report `invalid_annotation` for nested duplicate qualifiers (for example `Final[Final[int]]`) and for invalid `TypedDict` item qualifier combinations, including conflicting `Required[]`/`NotRequired[]`, nested `ReadOnly[]`, and unsupported qualifiers like `ClassVar[]`. - Improve TypedDict checking when runtime class objects are unavailable (for example after import-time failures or for function-local class definitions) by falling back to syntactic TypedDict analysis, so `ReadOnly`/`Required`/`NotRequired` annotations and inheritance conflicts are still reported. - Validate functional `TypedDict(...)` declarations more strictly by reporting errors for non-literal field mappings, non-string field names, and mismatched type names in assignments. - Preserve functional `TypedDict(...)` type information even when runtime keyword-form construction is unavailable (for example on Python 3.13+), avoiding spurious call errors and follow-on annotation failures. - Report `invalid_base` for synthetic TypedDict classes that mix `TypedDict` with non-`TypedDict` base classes or bare `Generic` (only `Generic[...]` is allowed). - Improve handling of class objects that come from stubs or unimportable modules by tracking them as singleton class values, which improves compatibility checks for TypedDict class objects and type-expression evaluation. - Create synthetic class objects for non-TypedDict classes when runtime class objects are unavailable (for example after import-time failures), so class self-references continue to resolve and nominal class values are preserved. - Treat synthetic class objects as class objects in assignability checks, so APIs expecting `type` (for example `TypedValue(...)`) accept synthetic classes. - Preserve dynamic `Any`-base behavior for synthetic classes while keeping declared methods precise, so checks like `ClassA(Any).method1()` retain annotated return types and unknown members still behave as `Any`. - Fix `Self` inference for classmethods on class objects loaded from stubs (including unimportable modules), so calls like `X.from_config()` now infer instance results correctly. - Treat `with` blocks as non-suppressing when `__exit__`/`__aexit__` return types include non-`bool` members like `None | bool`, which improves narrowing after the block. - Report `unused_variable` and `unused_assignment` for annotated assignments like `x: int = value` when the assigned value is never read. - Narrow tuple types after `len()` checks when bounds imply a more specific shape, including exact-length refinements and lower-bound refinements for tuples with fixed and variadic parts, which simplifies `reveal_type()` output. - Extend `len()`-based narrowing to use intersection predicates, which also improves narrowing for non-tuple cases such as literal strings and impossible `TypedDict` length branches. - Fix false-positive errors in some `len()`-narrowed branches involving `Any & Predicate[...]` intersections (including `assert_type(..., Any)` and some sequence indexing operations). - Fix a crash when accessing attributes on `len()` predicate constraints by treating `PredicateValue` attributes like attributes on `object`. - Fix dunder method handling on intersection types so operations like indexing `list[...] & Predicate[...]` values no longer produce spurious errors and `Any[error]` inference. - Keep unexpected keyword argument names in call errors in source order, so repeated runs produce stable output. - Make protocol member lists in type incompatibility messages deterministic by using definition order when available and sorted order otherwise. - Fix an internal error on Python 3.12+ when parsing PEP 695 generics that include `**P` (`ParamSpec`) type parameters. - Fix crash if accessing a module's `__annotations__` raises an error. - Implement PEP 747 `TypeForm` support, including implicit and explicit `TypeForm` evaluation, assignability checks, and conformance tests. - Require `typing_extensions>=4.13.0`. - Drop support for Python 3.9 and add official support for Python 3.14. - Narrow attribute and subscript expressions in nested scopes based on narrowing checks in the outer scope. - Apply the `class_attribute_transformers` plugin also for values that have a `__get__` method. - Fix internal error in certain cases involving custom `__getattr__` methods that raise an error. - Reduce the set of dependencies (`ast_decompiler` is no longer used; `tomli` is only used before Python 3.11; `codemod` is an extra). - Package a `py.typed` file for pycroscope itself. - Ignore presence of `__slots__` in protocols defined in stubs. - Change implementation of implicit int/float and float/complex promotion in accordance with https://github.com/python/typing/pull/1748. Now, annotations of `float` implicitly mean `float | int`. - Fix assignability for certain combinations of unions, `Annotated`, and `NewType`. - Reduce more uninhabited intersections to `Never` - Keep checking files when module import fails, and report `import_failed` on the line that triggered the import-time error (so it can be ignored with `# static analysis: ignore[import_failed]`). - Fix crashes on unsupported syntax in string forward references by reporting regular `invalid_annotation` errors instead. - Fix a crash in callable assignability involving `Concatenate[...,]` signatures represented as `AnySig`. - Fix crash when checking certain `TypeAliasType` specializations that include unhashable runtime arguments (e.g. ParamSpec argument lists). - Fix a crash when checking overloaded `@staticmethod` definitions that involve `ParamSpec`-based callable signatures. - Preserve overload-based return inference for `@staticmethod` and `@classmethod` definitions. - Avoid errors in generic-base extraction when runtime annotations include `TypeVarTuple` parameters, including `typing_extensions.TypeVarTuple` on Python 3.10. - Suppress `missing_return` for known abstract stub bodies (protocol methods and `@abstractmethod` methods) when the body is just `...` or `pass` (including optional docstrings), while still reporting `missing_return` for `@abstractmethod` methods with nontrivial bodies. - Fix a crash when checking classes that inherit from `typing.Any`. - Narrow variables correctly when calling `TypeGuard` or `TypeIs` functions defined as `@staticmethod`, including calls through either instances or classes. - Fix a crash when handling `typing.Annotated` on Python 3.14, where stubs expose it as an annotated assignment (`Annotated: _SpecialForm`). ## Version 0.2.0 (June 26, 2025) - Fix crash on class definition keyword args when the `no_implicit_any` error is enabled. - Fix incorrect treatment of `ParamSpec` in certain contexts. - Add basic support for intersection types with `pycroscope.extensions.Intersection`. - Fix crash on checking the boolability of certain complex types. - Support subtyping between more kinds of heterogeneous tuples. - Treat `bool` and enum classes as equivalent to the union of all their members. - Add support for unpacked tuple types using native unpack syntax (e.g., `tuple[int, *tuple[int, ...]]`; the alternative syntax with `Unpack` was already supported). - `assert_type()` now checks for type equivalence, not equality of the internal representation of the type. - Improve parsing of annotation expressions as distinct from type expressions. Fixes crash on certain combinations of type qualifiers. - Improve support for recursive type aliases - Correctly handle type aliases and other types with fallbacks in more places - Fix edge case in `TypeIs` type narrowing with tuple types - Rewrite the implementation of assignability to be more in line with the typing specification - Fix handling of `ClassVar` annotations in stubs - Fix operations on `ParamSpecArgs` and `ParamSpecKwargs` values - Fix incorrect assignability relation between `TypedDict` types and `dict[Any, Any]`; the spec requires that these be considered incompatible - Fix bug where certain binary operations were incorrectly inferred as Any - Fix bug with generic self types on overloaded methods in stubs - Add support for NewTypes over any type, instead of just simple types - Add support for a concise output format (`--output-format concise`) - Fix treatment of aliases created through the `type` statement in union assignability and in iteration - Make `asynq` and `qcore` optional dependencies - Fix use of aliases created through the `type` statement in boolean conditions ## Version 0.1.0 (May 3, 2025) First release under the pycroscope name. See [the pyanalyze docs](https://github.com/quora/pyanalyze/blob/master/docs/changelog.md) for the previous changelog. Changes relative to pyanalyze 0.13.1: - Update PEP 728 support to the latest version, using the `extra_items=` class argument instead of an `__extra_items__` key in the dict. - Add support for Python 3.13 - Drop support for Python 3.8 - Flag invalid regexes in arguments to functions like `re.search`.