This is an automated email from the ASF dual-hosted git repository. sadpandajoe pushed a commit to branch ultraset-mh-dataset-scope-mypy-2 in repository https://gitbox.apache.org/repos/asf/superset.git
commit e46201682cea0146fe9c5c5f1da7da6333c3feb8 Author: Joe Li <[email protected]> AuthorDate: Thu Sep 24 14:17:52 2026 +0000 fix(mypy): resolve dataset-scope and datasource-perm mypy errors The nightly full-repo mypy scan flagged 6 new errors introduced by PR #44146 and PR #43848, surfaced only because per-PR CI lints changed files only: - superset/mcp_service/dataset_scope.py:127 and tests/unit_tests/mcp_service/dataset/tool/test_dataset_tools.py:2712 call .in_() on SqlaTable.uuid/.id. Both are plain Column() attributes with no Mapped[] annotation, so mypy resolves the class-level access as the raw nullable value type instead of an InstrumentedAttribute, which genuinely lacks .in_(). This is a static-only false positive (real query-buildable columns at runtime), already worked around the same way for SqlaTable.perm/.schema_perm/.catalog_perm at superset/connectors/sqla/models.py:2491. - tests/unit_tests/charts/semantic_view_chart_filter_test.py:402-404 assigned BaseDatasource's nullable perm/schema_perm/catalog_perm properties into str-annotated locals; narrow with the same assert-not-None idiom already used elsewhere in this codebase for nullable ORM reads. Co-Authored-By: Claude Sonnet 5 <[email protected]> --- superset/mcp_service/dataset_scope.py | 6 +++++- tests/unit_tests/charts/semantic_view_chart_filter_test.py | 9 ++++++--- tests/unit_tests/mcp_service/dataset/tool/test_dataset_tools.py | 4 +++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/superset/mcp_service/dataset_scope.py b/superset/mcp_service/dataset_scope.py index e0e1c320925..ba50dd37580 100644 --- a/superset/mcp_service/dataset_scope.py +++ b/superset/mcp_service/dataset_scope.py @@ -124,7 +124,11 @@ class DatasetScopeFilter(BaseFilter): # pylint: disable=too-few-public-methods def apply(self, query: "Query", value: frozenset[UUID]) -> "Query": from superset.connectors.sqla.models import SqlaTable - return query.filter(SqlaTable.uuid.in_(value)) + # SqlaTable.uuid is an unannotated Column, so mypy sees the raw + # nullable value type here instead of an InstrumentedAttribute; same + # false positive already ignored at + # superset/connectors/sqla/models.py:2491. + return query.filter(SqlaTable.uuid.in_(value)) # type: ignore[union-attr] def parse_dataset_role_allowlist(config: Any) -> dict[str, set[UUID]] | None: diff --git a/tests/unit_tests/charts/semantic_view_chart_filter_test.py b/tests/unit_tests/charts/semantic_view_chart_filter_test.py index 053dd0b02d6..1abd136fbd1 100644 --- a/tests/unit_tests/charts/semantic_view_chart_filter_test.py +++ b/tests/unit_tests/charts/semantic_view_chart_filter_test.py @@ -399,9 +399,12 @@ def test_hard_deleted_dataset_retains_only_schema_catalog_list_access( ) session.add(chart) session.flush() - dataset_perm: str = table.perm - schema_perm: str = table.schema_perm - catalog_perm: str = table.catalog_perm + dataset_perm: str | None = table.perm + schema_perm: str | None = table.schema_perm + catalog_perm: str | None = table.catalog_perm + assert dataset_perm is not None + assert schema_perm is not None + assert catalog_perm is not None grant_perm: str = { "datasource_access": dataset_perm, "schema_access": schema_perm, diff --git a/tests/unit_tests/mcp_service/dataset/tool/test_dataset_tools.py b/tests/unit_tests/mcp_service/dataset/tool/test_dataset_tools.py index 3fdce64819d..781231f26c9 100644 --- a/tests/unit_tests/mcp_service/dataset/tool/test_dataset_tools.py +++ b/tests/unit_tests/mcp_service/dataset/tool/test_dataset_tools.py @@ -2709,7 +2709,9 @@ async def test_description_discovery_uses_dao_search_and_exposes_alternatives( # UUID union (including an inaccessible dataset) is intersected by # the existing access filter before count and page boundaries. identifiers = ( - session.query(SqlaTable.uuid).filter(SqlaTable.id.in_([1, 3])).all() + session.query(SqlaTable.uuid) + .filter(SqlaTable.id.in_([1, 3])) # type: ignore[attr-defined] + .all() ) scoped_rows, scoped_count = DatasetDAO.list( search="Order",
