Skip to content

[ty] Add support for types.new_class#23144

Merged
charliermarsh merged 9 commits intomainfrom
charlie/new
Apr 5, 2026
Merged

[ty] Add support for types.new_class#23144
charliermarsh merged 9 commits intomainfrom
charlie/new

Conversation

@charliermarsh
Copy link
Copy Markdown
Member

@charliermarsh charliermarsh commented Feb 8, 2026

Summary

Generally straightforward given that we support type(...); however, I think the base class validation can be a bit looser, since types.new_class does proper metaclass resolution.

Closes astral-sh/ty#2399.

@charliermarsh charliermarsh added the ty Multi-file analysis & type inference label Feb 8, 2026
@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot bot commented Feb 8, 2026

Typing conformance results

No changes detected ✅

Current numbers
The percentage of diagnostics emitted that were expected errors held steady at 87.72%. The percentage of expected errors that received a diagnostic held steady at 82.85%. The number of fully passing files held steady at 74/132.

@charliermarsh charliermarsh force-pushed the charlie/new branch 2 times, most recently from 4f5f14c to 876eead Compare February 8, 2026 20:18
@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot bot commented Feb 8, 2026

mypy_primer results

Changes were detected when running on open source projects
attrs (https://github.com/python-attrs/attrs)
- src/attr/_cmp.py:98:9: error[unresolved-attribute] Object of type `type` has no attribute `_requirements`
- tests/test_make.py:1514:61: error[not-subscriptable] Cannot subscript object of type `type` with no `__class_getitem__` method
+ tests/test_make.py:1514:61: error[not-subscriptable] Cannot subscript object of type `<class 'MyParent'>` with no `__getitem__` method
- Found 671 diagnostics
+ Found 670 diagnostics

spack (https://github.com/spack/spack)
- lib/spack/spack/vendor/attr/_cmp.py:88:9: error[unresolved-attribute] Object of type `type` has no attribute `_requirements`
+ lib/spack/spack/vendor/jinja2/runtime.py:985:36: warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive

pip (https://github.com/pypa/pip)
- src/pip/_vendor/urllib3/request.py:178:25: warning[unsupported-base] Unsupported class base with type `type[ModuleType]`
- Found 700 diagnostics
+ Found 699 diagnostics

jinja (https://github.com/pallets/jinja)
+ src/jinja2/runtime.py:943:36: warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- Found 203 diagnostics
+ Found 204 diagnostics

werkzeug (https://github.com/pallets/werkzeug)
- src/werkzeug/test.py:819:32: warning[unsupported-dynamic-base] Unsupported class base: Has type `type[Response] & ~type[TestResponse]`
- Found 386 diagnostics
+ Found 385 diagnostics

scrapy (https://github.com/scrapy/scrapy)
+ scrapy/utils/deprecate.py:63:50: warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- tests/test_utils_datatypes.py:152:22: warning[unsupported-base] Unsupported class base with type `type[MutableMapping[Unknown, Unknown]]`
- tests/test_utils_datatypes.py:163:22: warning[unsupported-base] Unsupported class base with type `type[MutableMapping[Unknown, Unknown]]`
- Found 1795 diagnostics
+ Found 1794 diagnostics

nox (https://github.com/wntrblm/nox)
+ nox/logger.py:84:62: warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- Found 27 diagnostics
+ Found 28 diagnostics

schemathesis (https://github.com/schemathesis/schemathesis)
+ src/schemathesis/engine/run/stateful/_executor.py:90:54: warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- Found 343 diagnostics
+ Found 344 diagnostics

pandera (https://github.com/pandera-dev/pandera)
- pandera/api/dataframe/model.py:306:55: warning[unsupported-dynamic-base] Unsupported class base: Has type `type[Self@__class_getitem__] & <Protocol with members '__parameters__'>`
- pandera/api/pyspark/model.py:211:55: warning[unsupported-dynamic-base] Unsupported class base: Has type `type[Self@__class_getitem__] & <Protocol with members '__parameters__'>`
- Found 1644 diagnostics
+ Found 1642 diagnostics

artigraph (https://github.com/artigraph/artigraph)
- tests/arti/views/test_views.py:23:15: warning[unsupported-base] Unsupported class base with type `type[View]`
- tests/arti/views/test_views.py:32:15: warning[unsupported-base] Unsupported class base with type `type[View]`
- tests/arti/views/test_views.py:35:16: warning[unsupported-base] Unsupported class base with type `type[View]`
- tests/arti/views/test_views.py:39:15: warning[unsupported-base] Unsupported class base with type `type[View]`
- tests/arti/views/test_views.py:49:16: warning[unsupported-base] Unsupported class base with type `type[View]`
- tests/arti/views/test_views.py:60:16: warning[unsupported-base] Unsupported class base with type `type[View]`
- Found 156 diagnostics
+ Found 150 diagnostics

operator (https://github.com/canonical/operator)
- ops/_private/harness.py:431:25: warning[unsupported-base] Unsupported class base with type `Unknown | type[CharmType@Harness]`
- Found 124 diagnostics
+ Found 123 diagnostics

speedrun.com_global_scoreboard_webapp (https://github.com/Avasam/speedrun.com_global_scoreboard_webapp)
- backend/models/game_search_models.py:9:18: warning[unsupported-base] Unsupported class base with type `type[Model]`
- backend/models/tournament_scheduler_models.py:16:16: warning[unsupported-base] Unsupported class base with type `type[Model]`
- backend/models/tournament_scheduler_models.py:83:21: warning[unsupported-base] Unsupported class base with type `type[Model]`
- backend/models/tournament_scheduler_models.py:120:16: warning[unsupported-base] Unsupported class base with type `type[Model]`
- backend/models/tournament_scheduler_models.py:198:20: warning[unsupported-base] Unsupported class base with type `type[Model]`
- backend/models/tournament_scheduler_models.py:228:19: warning[unsupported-base] Unsupported class base with type `type[Model]`
- Found 20 diagnostics
+ Found 14 diagnostics

trio (https://github.com/python-trio/trio)
+ src/trio/_tests/test_exports.py:86:44: warning[unsupported-dynamic-base] Unsupported class base: Has type `type`
- Found 469 diagnostics
+ Found 470 diagnostics

meson (https://github.com/mesonbuild/meson)
- mesonbuild/_pathlib.py:42:16: warning[unsupported-base] Unsupported class base with type `type[Path]`
- Found 2356 diagnostics
+ Found 2355 diagnostics

strawberry (https://github.com/strawberry-graphql/strawberry)
- strawberry/tools/create_type.py:71:12: error[invalid-return-type] Return type does not match returned value: expected `type`, found `<decorator produced by dataclass-like function>`
- Found 342 diagnostics
+ Found 341 diagnostics

sphinx (https://github.com/sphinx-doc/sphinx)
+ sphinx/domains/__init__.py:194:49: warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- Found 407 diagnostics
+ Found 408 diagnostics

setuptools (https://github.com/pypa/setuptools)
- setuptools/_vendor/wheel/macosx_libfile.py:300:29: warning[unsupported-base] Unsupported class base with type `type[Structure]`
- setuptools/_vendor/wheel/macosx_libfile.py:306:31: warning[unsupported-base] Unsupported class base with type `type[Structure]`
- setuptools/_vendor/wheel/macosx_libfile.py:311:31: warning[unsupported-base] Unsupported class base with type `type[Structure]`
- setuptools/_vendor/wheel/macosx_libfile.py:363:23: warning[unsupported-base] Unsupported class base with type `type[Structure]`
- setuptools/_vendor/wheel/macosx_libfile.py:368:26: warning[unsupported-base] Unsupported class base with type `type[Structure]`
- setuptools/_vendor/wheel/macosx_libfile.py:373:26: warning[unsupported-base] Unsupported class base with type `type[Structure]`
- setuptools/_vendor/wheel/macosx_libfile.py:383:37: warning[unsupported-base] Unsupported class base with type `type[Structure]`
- setuptools/_vendor/wheel/macosx_libfile.py:390:32: warning[unsupported-base] Unsupported class base with type `type[Structure]`
- Found 1177 diagnostics
+ Found 1169 diagnostics

scikit-build-core (https://github.com/scikit-build/scikit-build-core)
+ src/scikit_build_core/build/wheel.py:99:20: error[no-matching-overload] No overload of bound method `__init__` matches arguments
- Found 59 diagnostics
+ Found 60 diagnostics

pandas (https://github.com/pandas-dev/pandas)
+ pandas/io/formats/style.py:4050:31: warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- Found 4583 diagnostics
+ Found 4584 diagnostics

@charliermarsh charliermarsh force-pushed the charlie/new branch 2 times, most recently from d90ba3d to 171e68c Compare February 9, 2026 02:01
@charliermarsh charliermarsh marked this pull request as ready for review February 9, 2026 02:01
@charliermarsh charliermarsh marked this pull request as draft February 9, 2026 02:15
@charliermarsh charliermarsh marked this pull request as ready for review February 9, 2026 02:27
@charliermarsh charliermarsh marked this pull request as draft February 11, 2026 15:23
@charliermarsh
Copy link
Copy Markdown
Member Author

I'll mark as draft pending #22792.

@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot bot commented Feb 14, 2026

Memory usage report

Memory usage unchanged ✅

@charliermarsh charliermarsh force-pushed the charlie/new branch 3 times, most recently from ac8a81b to db7116d Compare February 15, 2026 19:23
@charliermarsh charliermarsh marked this pull request as ready for review February 15, 2026 19:23
@charliermarsh charliermarsh force-pushed the charlie/new branch 2 times, most recently from fdac492 to 15d3318 Compare February 18, 2026 16:21
@carljm
Copy link
Copy Markdown
Contributor

carljm commented Feb 24, 2026

Closing and reopening this to test the PR auto-assignment workflow.

@carljm carljm closed this Feb 24, 2026
@carljm carljm reopened this Feb 24, 2026
@charliermarsh charliermarsh force-pushed the charlie/new branch 2 times, most recently from 580f562 to fe529c8 Compare March 4, 2026 14:05
@carljm
Copy link
Copy Markdown
Contributor

carljm commented Mar 11, 2026

Sorry I haven't got to this yet, it is on the list...

@charliermarsh
Copy link
Copy Markdown
Member Author

Don't worry, it's not urgent, I'm just trying to rebase all my stuff semi-regularly.

@carljm
Copy link
Copy Markdown
Contributor

carljm commented Apr 3, 2026

This looks reasonable -- if it's rebased (again) I'll properly review it.

@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot bot commented Apr 3, 2026

ecosystem-analyzer results

Lint rule Added Removed Changed
invalid-await 40 0 0
invalid-return-type 1 1 0
unresolved-attribute 0 2 0
invalid-base 1 0 0
not-subscriptable 0 0 1
unsupported-dynamic-base 1 0 0
Total 43 3 1

Changes in flaky projects detected. Raw diff output excludes flaky projects; see the HTML report for details.

Raw diff:

attrs (https://github.com/python-attrs/attrs)
- src/attr/_cmp.py:98:9 error[unresolved-attribute] Object of type `type` has no attribute `_requirements`
+ tests/test_make.py:1512:43 error[invalid-base] Invalid base for class created via `types.new_class()`: Has type `<special-form 'typing.Generic[MyTypeVar]'>`
- tests/test_make.py:1514:61 error[not-subscriptable] Cannot subscript object of type `type` with no `__class_getitem__` method
+ tests/test_make.py:1514:61 error[not-subscriptable] Cannot subscript object of type `<class 'MyParent'>` with no `__getitem__` method

spack (https://github.com/spack/spack)
- lib/spack/spack/vendor/attr/_cmp.py:88:9 error[unresolved-attribute] Object of type `type` has no attribute `_requirements`

strawberry (https://github.com/strawberry-graphql/strawberry)
- strawberry/tools/create_type.py:71:12 error[invalid-return-type] Return type does not match returned value: expected `type`, found `<decorator produced by dataclass-like function>`

trio (https://github.com/python-trio/trio)
+ src/trio/_tests/test_exports.py:86:44 warning[unsupported-dynamic-base] Unsupported class base: Has type `type`

Full report with detailed diff (timing results)

Copy link
Copy Markdown
Contributor

@carljm carljm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good overall! I think the regression around SubclassOf types is the only blocking issue.

@charliermarsh charliermarsh marked this pull request as draft April 4, 2026 01:15
@charliermarsh charliermarsh force-pushed the charlie/new branch 2 times, most recently from 4925377 to 5568da1 Compare April 4, 2026 02:04
@charliermarsh charliermarsh marked this pull request as ready for review April 4, 2026 02:08
@astral-sh-bot astral-sh-bot bot requested a review from carljm April 4, 2026 02:08
// deferred along with bases inference.
if let Some(explicit_bases) = &explicit_bases {
// Validate bases and collect disjoint bases for diagnostics.
let mut disjoint_bases = self.validate_dynamic_type_bases(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: there are still methods like this that are only used/shared by type-call and types-new-class, but still live in the main infer/builder.rs. Almost feels like we should have infer/builder/dynamic_class.rs and then infer/builder/dynamic_class/type_call.rs and infer/builder/dynamic_class/new_class.rs

@charliermarsh charliermarsh merged commit 62bb077 into main Apr 5, 2026
52 checks passed
@charliermarsh charliermarsh deleted the charlie/new branch April 5, 2026 01:14
charliermarsh added a commit that referenced this pull request Apr 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

imprecise inference for types.new_class() with bases

2 participants