chore: move TypedDict from typing_extensions to typing (#25121)

This commit is contained in:
Sebastian Liebscher 2023-08-30 18:49:45 +02:00 committed by GitHub
parent 46a0a6e08a
commit 067bfbf950
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 43 additions and 62 deletions

View File

@ -19,13 +19,12 @@ from __future__ import annotations
import copy import copy
import logging import logging
import re import re
from typing import Any, ClassVar, TYPE_CHECKING from typing import Any, ClassVar, TYPE_CHECKING, TypedDict
import numpy as np import numpy as np
import pandas as pd import pandas as pd
from flask_babel import gettext as _ from flask_babel import gettext as _
from pandas import DateOffset from pandas import DateOffset
from typing_extensions import TypedDict
from superset import app from superset import app
from superset.common.chart_data import ChartDataResultFormat from superset.common.chart_data import ChartDataResultFormat
@ -169,7 +168,7 @@ class QueryContextProcessor:
cache.error_message = str(ex) cache.error_message = str(ex)
cache.status = QueryStatus.FAILED cache.status = QueryStatus.FAILED
# the N-dimensional DataFrame has converteds into flat DataFrame # the N-dimensional DataFrame has converted into flat DataFrame
# by `flatten operator`, "comma" in the column is escaped by `escape_separator` # by `flatten operator`, "comma" in the column is escaped by `escape_separator`
# the result DataFrame columns should be unescaped # the result DataFrame columns should be unescaped
label_map = { label_map = {
@ -632,11 +631,6 @@ class QueryContextProcessor:
return generate_cache_key(cache_dict, key_prefix) return generate_cache_key(cache_dict, key_prefix)
def get_annotation_data(self, query_obj: QueryObject) -> dict[str, Any]: def get_annotation_data(self, query_obj: QueryObject) -> dict[str, Any]:
"""
:param query_context:
:param query_obj:
:return:
"""
annotation_data: dict[str, Any] = self.get_native_annotation_data(query_obj) annotation_data: dict[str, Any] = self.get_native_annotation_data(query_obj)
for annotation_layer in [ for annotation_layer in [
layer layer

View File

@ -23,7 +23,16 @@ import logging
import re import re
from datetime import datetime from datetime import datetime
from re import Match, Pattern from re import Match, Pattern
from typing import Any, Callable, cast, ContextManager, NamedTuple, TYPE_CHECKING, Union from typing import (
Any,
Callable,
cast,
ContextManager,
NamedTuple,
TYPE_CHECKING,
TypedDict,
Union,
)
import pandas as pd import pandas as pd
import sqlparse import sqlparse
@ -46,7 +55,6 @@ from sqlalchemy.sql import quoted_name, text
from sqlalchemy.sql.expression import ColumnClause, Select, TextAsFrom, TextClause from sqlalchemy.sql.expression import ColumnClause, Select, TextAsFrom, TextClause
from sqlalchemy.types import TypeEngine from sqlalchemy.types import TypeEngine
from sqlparse.tokens import CTE from sqlparse.tokens import CTE
from typing_extensions import TypedDict
from superset import security_manager, sql_parse from superset import security_manager, sql_parse
from superset.constants import TimeGrain as TimeGrainConstants from superset.constants import TimeGrain as TimeGrainConstants
@ -114,8 +122,8 @@ class TimestampExpression(
ColumnClause ColumnClause
): # pylint: disable=abstract-method, too-many-ancestors ): # pylint: disable=abstract-method, too-many-ancestors
def __init__(self, expr: str, col: ColumnClause, **kwargs: Any) -> None: def __init__(self, expr: str, col: ColumnClause, **kwargs: Any) -> None:
"""Sqlalchemy class that can be can be used to render native column elements """Sqlalchemy class that can be used to render native column elements respecting
respecting engine-specific quoting rules as part of a string-based expression. engine-specific quoting rules as part of a string-based expression.
:param expr: Sql expression with '{col}' denoting the locations where the col :param expr: Sql expression with '{col}' denoting the locations where the col
object will be rendered. object will be rendered.
@ -331,7 +339,7 @@ class BaseEngineSpec: # pylint: disable=too-many-public-methods
allows_alias_to_source_column = True allows_alias_to_source_column = True
# Whether ORDER BY clause must appear in SELECT # Whether ORDER BY clause must appear in SELECT
# if TRUE, then it doesn't have to. # if True, then it doesn't have to.
allows_hidden_orderby_agg = True allows_hidden_orderby_agg = True
# Whether ORDER BY clause can use sql calculated expression # Whether ORDER BY clause can use sql calculated expression
@ -1000,7 +1008,7 @@ class BaseEngineSpec: # pylint: disable=too-many-public-methods
to_sql_kwargs["name"] = table.table to_sql_kwargs["name"] = table.table
if table.schema: if table.schema:
# Only add schema when it is preset and non empty. # Only add schema when it is preset and non-empty.
to_sql_kwargs["schema"] = table.schema to_sql_kwargs["schema"] = table.schema
with cls.get_engine(database) as engine: with cls.get_engine(database) as engine:
@ -1049,8 +1057,7 @@ class BaseEngineSpec: # pylint: disable=too-many-public-methods
context = context or {} context = context or {}
for regex, (message, error_type, extra) in cls.custom_errors.items(): for regex, (message, error_type, extra) in cls.custom_errors.items():
match = regex.search(raw_message) if match := regex.search(raw_message):
if match:
params = {**context, **match.groupdict()} params = {**context, **match.groupdict()}
extra["engine_name"] = cls.engine_name extra["engine_name"] = cls.engine_name
return [ return [
@ -1832,7 +1839,7 @@ class BaseEngineSpec: # pylint: disable=too-many-public-methods
""" """
Construct an impersonation key, by default it's the given username. Construct an impersonation key, by default it's the given username.
:param user: logged in user :param user: logged-in user
:returns: username if given user is not null :returns: username if given user is not null
""" """

View File

@ -20,7 +20,7 @@ import re
import urllib import urllib
from datetime import datetime from datetime import datetime
from re import Pattern from re import Pattern
from typing import Any, Optional, TYPE_CHECKING from typing import Any, Optional, TYPE_CHECKING, TypedDict
import pandas as pd import pandas as pd
from apispec import APISpec from apispec import APISpec
@ -33,7 +33,6 @@ from sqlalchemy import column, types
from sqlalchemy.engine.base import Engine from sqlalchemy.engine.base import Engine
from sqlalchemy.engine.reflection import Inspector from sqlalchemy.engine.reflection import Inspector
from sqlalchemy.sql import sqltypes from sqlalchemy.sql import sqltypes
from typing_extensions import TypedDict
from superset import sql_parse from superset import sql_parse
from superset.constants import PASSWORD_MASK, TimeGrain from superset.constants import PASSWORD_MASK, TimeGrain
@ -66,7 +65,6 @@ except ModuleNotFoundError:
if TYPE_CHECKING: if TYPE_CHECKING:
from superset.models.core import Database # pragma: no cover from superset.models.core import Database # pragma: no cover
CONNECTION_DATABASE_PERMISSIONS_REGEX = re.compile( CONNECTION_DATABASE_PERMISSIONS_REGEX = re.compile(
"Access Denied: Project (?P<project_name>.+?): User does not have " "Access Denied: Project (?P<project_name>.+?): User does not have "
+ "bigquery.jobs.create permission in project (?P<project>.+?)" + "bigquery.jobs.create permission in project (?P<project>.+?)"

View File

@ -18,7 +18,7 @@ from __future__ import annotations
import json import json
from datetime import datetime from datetime import datetime
from typing import Any, TYPE_CHECKING from typing import Any, TYPE_CHECKING, TypedDict
from apispec import APISpec from apispec import APISpec
from apispec.ext.marshmallow import MarshmallowPlugin from apispec.ext.marshmallow import MarshmallowPlugin
@ -27,7 +27,6 @@ from marshmallow import fields, Schema
from marshmallow.validate import Range from marshmallow.validate import Range
from sqlalchemy.engine.reflection import Inspector from sqlalchemy.engine.reflection import Inspector
from sqlalchemy.engine.url import URL from sqlalchemy.engine.url import URL
from typing_extensions import TypedDict
from superset.constants import TimeGrain, USER_AGENT from superset.constants import TimeGrain, USER_AGENT
from superset.databases.utils import make_url_safe from superset.databases.utils import make_url_safe

View File

@ -22,7 +22,7 @@ import json
import logging import logging
import re import re
from re import Pattern from re import Pattern
from typing import Any, TYPE_CHECKING from typing import Any, TYPE_CHECKING, TypedDict
import pandas as pd import pandas as pd
from apispec import APISpec from apispec import APISpec
@ -34,7 +34,6 @@ from marshmallow.exceptions import ValidationError
from requests import Session from requests import Session
from sqlalchemy.engine import create_engine from sqlalchemy.engine import create_engine
from sqlalchemy.engine.url import URL from sqlalchemy.engine.url import URL
from typing_extensions import TypedDict
from superset import db, security_manager from superset import db, security_manager
from superset.constants import PASSWORD_MASK from superset.constants import PASSWORD_MASK

View File

@ -19,7 +19,7 @@ import logging
import re import re
from datetime import datetime from datetime import datetime
from re import Pattern from re import Pattern
from typing import Any, Optional, TYPE_CHECKING from typing import Any, Optional, TYPE_CHECKING, TypedDict
from urllib import parse from urllib import parse
from apispec import APISpec from apispec import APISpec
@ -32,7 +32,6 @@ from marshmallow import fields, Schema
from sqlalchemy import types from sqlalchemy import types
from sqlalchemy.engine.reflection import Inspector from sqlalchemy.engine.reflection import Inspector
from sqlalchemy.engine.url import URL from sqlalchemy.engine.url import URL
from typing_extensions import TypedDict
from superset.constants import TimeGrain, USER_AGENT from superset.constants import TimeGrain, USER_AGENT
from superset.databases.utils import make_url_safe from superset.databases.utils import make_url_safe

View File

@ -14,9 +14,7 @@
# KIND, either express or implied. See the License for the # KIND, either express or implied. See the License for the
# specific language governing permissions and limitations # specific language governing permissions and limitations
# under the License. # under the License.
from typing import Optional from typing import Optional, TypedDict
from typing_extensions import TypedDict
from superset.utils.core import DatasourceType from superset.utils.core import DatasourceType

View File

@ -18,7 +18,7 @@
import json import json
import re import re
from functools import lru_cache, partial from functools import lru_cache, partial
from typing import Any, Callable, cast, Optional, TYPE_CHECKING, Union from typing import Any, Callable, cast, Optional, TYPE_CHECKING, TypedDict, Union
from flask import current_app, g, has_request_context, request from flask import current_app, g, has_request_context, request
from flask_babel import gettext as _ from flask_babel import gettext as _
@ -26,7 +26,6 @@ from jinja2 import DebugUndefined
from jinja2.sandbox import SandboxedEnvironment from jinja2.sandbox import SandboxedEnvironment
from sqlalchemy.engine.interfaces import Dialect from sqlalchemy.engine.interfaces import Dialect
from sqlalchemy.types import String from sqlalchemy.types import String
from typing_extensions import TypedDict
from superset.constants import LRU_CACHE_MAX_SIZE from superset.constants import LRU_CACHE_MAX_SIZE
from superset.datasets.commands.exceptions import DatasetNotFoundError from superset.datasets.commands.exceptions import DatasetNotFoundError
@ -597,7 +596,7 @@ def get_template_processors() -> dict[str, Any]:
processors = current_app.config.get("CUSTOM_TEMPLATE_PROCESSORS", {}) processors = current_app.config.get("CUSTOM_TEMPLATE_PROCESSORS", {})
for engine, processor in DEFAULT_PROCESSORS.items(): for engine, processor in DEFAULT_PROCESSORS.items():
# do not overwrite engine-specific CUSTOM_TEMPLATE_PROCESSORS # do not overwrite engine-specific CUSTOM_TEMPLATE_PROCESSORS
if not engine in processors: if engine not in processors:
processors[engine] = processor processors[engine] = processor
return processors return processors

View File

@ -16,9 +16,9 @@
# under the License. # under the License.
from collections.abc import Sequence from collections.abc import Sequence
from datetime import datetime from datetime import datetime
from typing import Any, Literal, Optional, TYPE_CHECKING, Union from typing import Any, Literal, Optional, TYPE_CHECKING, TypedDict, Union
from typing_extensions import NotRequired, TypedDict from typing_extensions import NotRequired
from werkzeug.wrappers import Response from werkzeug.wrappers import Response
if TYPE_CHECKING: if TYPE_CHECKING:

View File

@ -14,9 +14,7 @@
# KIND, either express or implied. See the License for the # KIND, either express or implied. See the License for the
# specific language governing permissions and limitations # specific language governing permissions and limitations
# under the License. # under the License.
from typing import Optional from typing import Optional, TypedDict
from typing_extensions import TypedDict
class Entry(TypedDict): class Entry(TypedDict):

View File

@ -49,7 +49,7 @@ from enum import Enum, IntEnum
from io import BytesIO from io import BytesIO
from timeit import default_timer from timeit import default_timer
from types import TracebackType from types import TracebackType
from typing import Any, Callable, cast, NamedTuple, TYPE_CHECKING, TypeVar from typing import Any, Callable, cast, NamedTuple, TYPE_CHECKING, TypedDict, TypeVar
from urllib.parse import unquote_plus from urllib.parse import unquote_plus
from zipfile import ZipFile from zipfile import ZipFile
@ -73,7 +73,7 @@ from sqlalchemy.engine import Connection, Engine
from sqlalchemy.engine.reflection import Inspector from sqlalchemy.engine.reflection import Inspector
from sqlalchemy.sql.type_api import Variant from sqlalchemy.sql.type_api import Variant
from sqlalchemy.types import TEXT, TypeDecorator, TypeEngine from sqlalchemy.types import TEXT, TypeDecorator, TypeEngine
from typing_extensions import TypedDict, TypeGuard from typing_extensions import TypeGuard
from superset.constants import ( from superset.constants import (
EXTRA_FORM_DATA_APPEND_KEYS, EXTRA_FORM_DATA_APPEND_KEYS,
@ -368,9 +368,9 @@ def flasher(msg: str, severity: str = "message") -> None:
def parse_js_uri_path_item( def parse_js_uri_path_item(
item: str | None, unquote: bool = True, eval_undefined: bool = False item: str | None, unquote: bool = True, eval_undefined: bool = False
) -> str | None: ) -> str | None:
"""Parse a uri path item made with js. """Parse an uri path item made with js.
:param item: a uri path component :param item: an uri path component
:param unquote: Perform unquoting of string using urllib.parse.unquote_plus() :param unquote: Perform unquoting of string using urllib.parse.unquote_plus()
:param eval_undefined: When set to True and item is either 'null' or 'undefined', :param eval_undefined: When set to True and item is either 'null' or 'undefined',
assume item is undefined and return None. assume item is undefined and return None.
@ -1162,16 +1162,14 @@ def merge_extra_filters(form_data: dict[str, Any]) -> None:
filtr["isExtra"] = True filtr["isExtra"] = True
# Pull out time filters/options and merge into form data # Pull out time filters/options and merge into form data
filter_column = filtr["col"] filter_column = filtr["col"]
time_extra = date_options.get(filter_column) if time_extra := date_options.get(filter_column):
if time_extra:
time_extra_value = filtr.get("val") time_extra_value = filtr.get("val")
if time_extra_value and time_extra_value != NO_TIME_RANGE: if time_extra_value and time_extra_value != NO_TIME_RANGE:
form_data[time_extra] = time_extra_value form_data[time_extra] = time_extra_value
form_data["applied_time_extras"][filter_column] = time_extra_value form_data["applied_time_extras"][filter_column] = time_extra_value
elif filtr["val"]: elif filtr["val"]:
# Merge column filters # Merge column filters
filter_key = get_filter_key(filtr) if (filter_key := get_filter_key(filtr)) in existing_filters:
if filter_key in existing_filters:
# Check if the filter already exists # Check if the filter already exists
if isinstance(filtr["val"], list): if isinstance(filtr["val"], list):
if isinstance(existing_filters[filter_key], list): if isinstance(existing_filters[filter_key], list):
@ -1268,11 +1266,9 @@ def get_column_name(column: Column, verbose_map: dict[str, Any] | None = None) -
:raises ValueError: if metric object is invalid :raises ValueError: if metric object is invalid
""" """
if isinstance(column, dict): if isinstance(column, dict):
label = column.get("label") if label := column.get("label"):
if label:
return label return label
expr = column.get("sqlExpression") if expr := column.get("sqlExpression"):
if expr:
return expr return expr
if isinstance(column, str): if isinstance(column, str):
@ -1293,13 +1289,10 @@ def get_metric_name(metric: Metric, verbose_map: dict[str, Any] | None = None) -
:raises ValueError: if metric object is invalid :raises ValueError: if metric object is invalid
""" """
if is_adhoc_metric(metric): if is_adhoc_metric(metric):
label = metric.get("label") if label := metric.get("label"):
if label:
return label return label
expression_type = metric.get("expressionType") if (expression_type := metric.get("expressionType")) == "SQL":
if expression_type == "SQL": if sql_expression := metric.get("sqlExpression"):
sql_expression = metric.get("sqlExpression")
if sql_expression:
return sql_expression return sql_expression
if expression_type == "SIMPLE": if expression_type == "SIMPLE":
column: AdhocMetricColumn = metric.get("column") or {} column: AdhocMetricColumn = metric.get("column") or {}
@ -1753,9 +1746,8 @@ def get_time_filter_status(
} }
) )
time_range = applied_time_extras.get(ExtraFiltersTimeColumnType.TIME_RANGE) if applied_time_extras.get(ExtraFiltersTimeColumnType.TIME_RANGE):
if time_range: # are there any temporal columns to assign the time range to?
# are there any temporal columns to assign the time grain to?
if temporal_columns: if temporal_columns:
applied.append({"column": ExtraFiltersTimeColumnType.TIME_RANGE}) applied.append({"column": ExtraFiltersTimeColumnType.TIME_RANGE})
else: else:

View File

@ -23,7 +23,7 @@ import string
import sys import sys
from collections.abc import Iterator from collections.abc import Iterator
from datetime import date, datetime, time, timedelta from datetime import date, datetime, time, timedelta
from typing import Any, Callable, cast, Optional from typing import Any, Callable, cast, Optional, TypedDict
from uuid import uuid4 from uuid import uuid4
import sqlalchemy.sql.sqltypes import sqlalchemy.sql.sqltypes
@ -34,7 +34,6 @@ from sqlalchemy.dialects import postgresql
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlalchemy.sql import func from sqlalchemy.sql import func
from sqlalchemy.sql.visitors import VisitableType from sqlalchemy.sql.visitors import VisitableType
from typing_extensions import TypedDict
from superset import db from superset import db

View File

@ -14,10 +14,9 @@
# KIND, either express or implied. See the License for the # KIND, either express or implied. See the License for the
# specific language governing permissions and limitations # specific language governing permissions and limitations
# under the License. # under the License.
from typing import Any, Optional from typing import Any, Optional, TypedDict
from marshmallow import fields, post_load, pre_load, Schema, validate from marshmallow import fields, post_load, pre_load, Schema, validate
from typing_extensions import TypedDict
from superset import app from superset import app
from superset.charts.schemas import ChartDataExtrasSchema, ChartDataFilterSchema from superset.charts.schemas import ChartDataExtrasSchema, ChartDataFilterSchema