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",

Reply via email to