You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by mi...@apache.org on 2023/08/04 17:13:39 UTC
[superset] 06/16: fix: Python3.11 (str, Enum) issue (#24803)
This is an automated email from the ASF dual-hosted git repository.
michaelsmolina pushed a commit to branch 3.0
in repository https://gitbox.apache.org/repos/asf/superset.git
commit 161e05445c2c02853be50c18d00fa22c3ceddeb4
Author: EugeneTorap <ev...@gmail.com>
AuthorDate: Mon Jul 31 19:04:09 2023 +0300
fix: Python3.11 (str, Enum) issue (#24803)
---
.pylintrc | 1 +
superset/common/chart_data.py | 6 ++---
superset/common/db_query_status.py | 4 +--
superset/connectors/base/models.py | 4 +--
superset/constants.py | 8 +++---
superset/errors.py | 7 +++---
superset/key_value/types.py | 6 ++---
superset/models/core.py | 6 ++---
superset/reports/models.py | 17 ++++++-------
superset/sql_parse.py | 6 ++---
superset/sqllab/limiting_factor.py | 4 +--
superset/tasks/types.py | 5 ++--
.../limiting_factor.py => utils/backports.py} | 15 +++++------
superset/utils/core.py | 29 +++++++++++-----------
tests/unit_tests/utils/test_decorators.py | 4 +--
15 files changed, 63 insertions(+), 59 deletions(-)
diff --git a/.pylintrc b/.pylintrc
index b39335c56b..08e44d3fae 100644
--- a/.pylintrc
+++ b/.pylintrc
@@ -83,6 +83,7 @@ enable=
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
disable=
+ no-member, # re-enable once this no longer raises false positives. This will become redundant after the min required version is 3.11
missing-docstring,
duplicate-code,
unspecified-encoding,
diff --git a/superset/common/chart_data.py b/superset/common/chart_data.py
index 65c0c43c11..e03f51eee2 100644
--- a/superset/common/chart_data.py
+++ b/superset/common/chart_data.py
@@ -14,10 +14,10 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-from enum import Enum
+from superset.utils.backports import StrEnum
-class ChartDataResultFormat(str, Enum):
+class ChartDataResultFormat(StrEnum):
"""
Chart data response format
"""
@@ -31,7 +31,7 @@ class ChartDataResultFormat(str, Enum):
return {cls.CSV} | {cls.XLSX}
-class ChartDataResultType(str, Enum):
+class ChartDataResultType(StrEnum):
"""
Chart data response type
"""
diff --git a/superset/common/db_query_status.py b/superset/common/db_query_status.py
index 82bb437f65..fa893a1717 100644
--- a/superset/common/db_query_status.py
+++ b/superset/common/db_query_status.py
@@ -14,10 +14,10 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-from enum import Enum
+from superset.utils.backports import StrEnum
-class QueryStatus(str, Enum):
+class QueryStatus(StrEnum):
"""Enum-type class for query statuses"""
STOPPED: str = "stopped"
diff --git a/superset/connectors/base/models.py b/superset/connectors/base/models.py
index 56e5ef18ad..706c82635c 100644
--- a/superset/connectors/base/models.py
+++ b/superset/connectors/base/models.py
@@ -21,7 +21,6 @@ import json
import logging
from collections.abc import Hashable
from datetime import datetime
-from enum import Enum
from json.decoder import JSONDecodeError
from typing import Any, TYPE_CHECKING
@@ -44,6 +43,7 @@ from superset.superset_typing import (
ResultSetColumnType,
)
from superset.utils import core as utils
+from superset.utils.backports import StrEnum
from superset.utils.core import GenericDataType, MediumText
if TYPE_CHECKING:
@@ -75,7 +75,7 @@ COLUMN_FORM_DATA_PARAMS = [
]
-class DatasourceKind(str, Enum):
+class DatasourceKind(StrEnum):
VIRTUAL = "virtual"
PHYSICAL = "physical"
diff --git a/superset/constants.py b/superset/constants.py
index 48b08506ca..4f01674bd4 100644
--- a/superset/constants.py
+++ b/superset/constants.py
@@ -20,6 +20,8 @@
# string to use when None values *need* to be converted to/from strings
from enum import Enum
+from superset.utils.backports import StrEnum
+
USER_AGENT = "Apache Superset"
NULL_STRING = "<NULL>"
@@ -185,7 +187,7 @@ EXTRA_FORM_DATA_OVERRIDE_KEYS = (
)
-class TimeGrain(str, Enum):
+class TimeGrain(StrEnum):
SECOND = "PT1S"
FIVE_SECONDS = "PT5S"
THIRTY_SECONDS = "PT30S"
@@ -214,13 +216,13 @@ class PandasAxis(int, Enum):
COLUMN = 1
-class PandasPostprocessingCompare(str, Enum):
+class PandasPostprocessingCompare(StrEnum):
DIFF = "difference"
PCT = "percentage"
RAT = "ratio"
-class CacheRegion(str, Enum):
+class CacheRegion(StrEnum):
DEFAULT = "default"
DATA = "data"
THUMBNAIL = "thumbnail"
diff --git a/superset/errors.py b/superset/errors.py
index 6f68f2466c..6661e98183 100644
--- a/superset/errors.py
+++ b/superset/errors.py
@@ -15,13 +15,14 @@
# specific language governing permissions and limitations
# under the License.
from dataclasses import dataclass
-from enum import Enum
from typing import Any, Optional
from flask_babel import lazy_gettext as _
+from superset.utils.backports import StrEnum
-class SupersetErrorType(str, Enum):
+
+class SupersetErrorType(StrEnum):
"""
Types of errors that can exist within Superset.
@@ -183,7 +184,7 @@ ERROR_TYPES_TO_ISSUE_CODES_MAPPING = {
}
-class ErrorLevel(str, Enum):
+class ErrorLevel(StrEnum):
"""
Levels of errors that can exist within Superset.
diff --git a/superset/key_value/types.py b/superset/key_value/types.py
index b2a47336c3..f5865de323 100644
--- a/superset/key_value/types.py
+++ b/superset/key_value/types.py
@@ -20,7 +20,6 @@ import json
import pickle
from abc import ABC, abstractmethod
from dataclasses import dataclass
-from enum import Enum
from typing import Any, TypedDict
from uuid import UUID
@@ -30,6 +29,7 @@ from superset.key_value.exceptions import (
KeyValueCodecDecodeException,
KeyValueCodecEncodeException,
)
+from superset.utils.backports import StrEnum
@dataclass
@@ -44,14 +44,14 @@ class KeyValueFilter(TypedDict, total=False):
uuid: UUID | None
-class KeyValueResource(str, Enum):
+class KeyValueResource(StrEnum):
APP = "app"
DASHBOARD_PERMALINK = "dashboard_permalink"
EXPLORE_PERMALINK = "explore_permalink"
METASTORE_CACHE = "superset_metastore_cache"
-class SharedKey(str, Enum):
+class SharedKey(StrEnum):
DASHBOARD_PERMALINK_SALT = "dashboard_permalink_salt"
EXPLORE_PERMALINK_SALT = "explore_permalink_salt"
diff --git a/superset/models/core.py b/superset/models/core.py
index a8fe8b5411..21f8eddba4 100755
--- a/superset/models/core.py
+++ b/superset/models/core.py
@@ -20,7 +20,6 @@
from __future__ import annotations
import builtins
-import enum
import json
import logging
import textwrap
@@ -74,6 +73,7 @@ from superset.models.helpers import AuditMixinNullable, ImportExportMixin
from superset.result_set import SupersetResultSet
from superset.superset_typing import ResultSetColumnType
from superset.utils import cache as cache_util, core as utils
+from superset.utils.backports import StrEnum
from superset.utils.core import get_username
config = app.config
@@ -116,7 +116,7 @@ class CssTemplate(Model, AuditMixinNullable):
css = Column(Text, default="")
-class ConfigurationMethod(str, enum.Enum):
+class ConfigurationMethod(StrEnum):
SQLALCHEMY_FORM = "sqlalchemy_form"
DYNAMIC_FORM = "dynamic_form"
@@ -1007,7 +1007,7 @@ class Log(Model): # pylint: disable=too-few-public-methods
referrer = Column(String(1024))
-class FavStarClassName(str, enum.Enum):
+class FavStarClassName(StrEnum):
CHART = "slice"
DASHBOARD = "Dashboard"
diff --git a/superset/reports/models.py b/superset/reports/models.py
index a13ded6223..5c47f41456 100644
--- a/superset/reports/models.py
+++ b/superset/reports/models.py
@@ -15,8 +15,6 @@
# specific language governing permissions and limitations
# under the License.
"""A collection of ORM sqlalchemy models for Superset"""
-import enum
-
from cron_descriptor import get_description
from flask_appbuilder import Model
from flask_appbuilder.models.decorators import renders
@@ -41,28 +39,29 @@ from superset.models.dashboard import Dashboard
from superset.models.helpers import AuditMixinNullable, ExtraJSONMixin
from superset.models.slice import Slice
from superset.reports.types import ReportScheduleExtra
+from superset.utils.backports import StrEnum
metadata = Model.metadata # pylint: disable=no-member
-class ReportScheduleType(str, enum.Enum):
+class ReportScheduleType(StrEnum):
ALERT = "Alert"
REPORT = "Report"
-class ReportScheduleValidatorType(str, enum.Enum):
+class ReportScheduleValidatorType(StrEnum):
"""Validator types for alerts"""
NOT_NULL = "not null"
OPERATOR = "operator"
-class ReportRecipientType(str, enum.Enum):
+class ReportRecipientType(StrEnum):
EMAIL = "Email"
SLACK = "Slack"
-class ReportState(str, enum.Enum):
+class ReportState(StrEnum):
SUCCESS = "Success"
WORKING = "Working"
ERROR = "Error"
@@ -70,19 +69,19 @@ class ReportState(str, enum.Enum):
GRACE = "On Grace"
-class ReportDataFormat(str, enum.Enum):
+class ReportDataFormat(StrEnum):
VISUALIZATION = "PNG"
DATA = "CSV"
TEXT = "TEXT"
-class ReportCreationMethod(str, enum.Enum):
+class ReportCreationMethod(StrEnum):
CHARTS = "charts"
DASHBOARDS = "dashboards"
ALERTS_REPORTS = "alerts_reports"
-class ReportSourceFormat(str, enum.Enum):
+class ReportSourceFormat(StrEnum):
CHART = "chart"
DASHBOARD = "dashboard"
diff --git a/superset/sql_parse.py b/superset/sql_parse.py
index 974d7eacd4..a6d4806707 100644
--- a/superset/sql_parse.py
+++ b/superset/sql_parse.py
@@ -18,7 +18,6 @@ import logging
import re
from collections.abc import Iterator
from dataclasses import dataclass
-from enum import Enum
from typing import Any, cast, Optional
from urllib import parse
@@ -49,6 +48,7 @@ from sqlparse.tokens import (
from sqlparse.utils import imt
from superset.exceptions import QueryClauseValidationException
+from superset.utils.backports import StrEnum
try:
from sqloxide import parse_sql as sqloxide_parse
@@ -71,7 +71,7 @@ sqlparser_sql_regex.insert(25, (r"'(''|\\\\|\\|[^'])*'", sqlparse.tokens.String.
lex.set_SQL_REGEX(sqlparser_sql_regex)
-class CtasMethod(str, Enum):
+class CtasMethod(StrEnum):
TABLE = "TABLE"
VIEW = "VIEW"
@@ -483,7 +483,7 @@ def sanitize_clause(clause: str) -> str:
return clause
-class InsertRLSState(str, Enum):
+class InsertRLSState(StrEnum):
"""
State machine that scans for WHERE and ON clauses referencing tables.
"""
diff --git a/superset/sqllab/limiting_factor.py b/superset/sqllab/limiting_factor.py
index 46cbc9bd81..638f9e347a 100644
--- a/superset/sqllab/limiting_factor.py
+++ b/superset/sqllab/limiting_factor.py
@@ -14,10 +14,10 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-import enum
+from superset.utils.backports import StrEnum
-class LimitingFactor(str, enum.Enum):
+class LimitingFactor(StrEnum):
QUERY = "QUERY"
DROPDOWN = "DROPDOWN"
QUERY_AND_DROPDOWN = "QUERY_AND_DROPDOWN"
diff --git a/superset/tasks/types.py b/superset/tasks/types.py
index cc337a81ed..84a3e7b01f 100644
--- a/superset/tasks/types.py
+++ b/superset/tasks/types.py
@@ -14,11 +14,10 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
+from superset.utils.backports import StrEnum
-from enum import Enum
-
-class ExecutorType(str, Enum):
+class ExecutorType(StrEnum):
"""
Which user should scheduled tasks be executed as. Used as follows:
For Alerts & Reports: the "model" refers to the AlertSchedule object
diff --git a/superset/sqllab/limiting_factor.py b/superset/utils/backports.py
similarity index 79%
copy from superset/sqllab/limiting_factor.py
copy to superset/utils/backports.py
index 46cbc9bd81..b48f76d235 100644
--- a/superset/sqllab/limiting_factor.py
+++ b/superset/utils/backports.py
@@ -14,12 +14,13 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-import enum
+import sys
+from enum import Enum
+if sys.version_info >= (3, 11):
+ # pylint: disable=unused-import
+ from enum import StrEnum # nopycln: import
+else:
-class LimitingFactor(str, enum.Enum):
- QUERY = "QUERY"
- DROPDOWN = "DROPDOWN"
- QUERY_AND_DROPDOWN = "QUERY_AND_DROPDOWN"
- NOT_LIMITED = "NOT_LIMITED"
- UNKNOWN = "UNKNOWN"
+ class StrEnum(str, Enum):
+ pass
diff --git a/superset/utils/core.py b/superset/utils/core.py
index ca3b9ae7b7..f40ccb63a2 100644
--- a/superset/utils/core.py
+++ b/superset/utils/core.py
@@ -98,6 +98,7 @@ from superset.superset_typing import (
FormData,
Metric,
)
+from superset.utils.backports import StrEnum
from superset.utils.database import get_example_database
from superset.utils.date_parser import parse_human_timedelta
from superset.utils.dates import datetime_to_epoch, EPOCH
@@ -133,12 +134,12 @@ class LenientEnum(Enum):
return None
-class AdhocMetricExpressionType(str, Enum):
+class AdhocMetricExpressionType(StrEnum):
SIMPLE = "SIMPLE"
SQL = "SQL"
-class AnnotationType(str, Enum):
+class AnnotationType(StrEnum):
FORMULA = "FORMULA"
INTERVAL = "INTERVAL"
EVENT = "EVENT"
@@ -160,7 +161,7 @@ class GenericDataType(IntEnum):
# ROW = 7
-class DatasourceType(str, Enum):
+class DatasourceType(StrEnum):
SLTABLE = "sl_table"
TABLE = "table"
DATASET = "dataset"
@@ -169,7 +170,7 @@ class DatasourceType(str, Enum):
VIEW = "view"
-class LoggerLevel(str, Enum):
+class LoggerLevel(StrEnum):
INFO = "info"
WARNING = "warning"
EXCEPTION = "exception"
@@ -208,19 +209,19 @@ class QueryObjectFilterClause(TypedDict, total=False):
isExtra: bool | None
-class ExtraFiltersTimeColumnType(str, Enum):
+class ExtraFiltersTimeColumnType(StrEnum):
TIME_COL = "__time_col"
TIME_GRAIN = "__time_grain"
TIME_ORIGIN = "__time_origin"
TIME_RANGE = "__time_range"
-class ExtraFiltersReasonType(str, Enum):
+class ExtraFiltersReasonType(StrEnum):
NO_TEMPORAL_COLUMN = "no_temporal_column"
COL_NOT_IN_DATASOURCE = "not_in_datasource"
-class FilterOperator(str, Enum):
+class FilterOperator(StrEnum):
"""
Operators used filter controls
"""
@@ -242,7 +243,7 @@ class FilterOperator(str, Enum):
TEMPORAL_RANGE = "TEMPORAL_RANGE"
-class FilterStringOperators(str, Enum):
+class FilterStringOperators(StrEnum):
EQUALS = ("EQUALS",)
NOT_EQUALS = ("NOT_EQUALS",)
LESS_THAN = ("LESS_THAN",)
@@ -260,7 +261,7 @@ class FilterStringOperators(str, Enum):
IS_FALSE = ("IS_FALSE",)
-class PostProcessingBoxplotWhiskerType(str, Enum):
+class PostProcessingBoxplotWhiskerType(StrEnum):
"""
Calculate cell contribution to row/column total
"""
@@ -270,7 +271,7 @@ class PostProcessingBoxplotWhiskerType(str, Enum):
PERCENTILE = "percentile"
-class PostProcessingContributionOrientation(str, Enum):
+class PostProcessingContributionOrientation(StrEnum):
"""
Calculate cell contribution to row/column total
"""
@@ -298,7 +299,7 @@ class QuerySource(Enum):
SQL_LAB = 2
-class QueryStatus(str, Enum):
+class QueryStatus(StrEnum):
"""Enum-type class for query statuses"""
STOPPED: str = "stopped"
@@ -311,14 +312,14 @@ class QueryStatus(str, Enum):
TIMED_OUT: str = "timed_out"
-class DashboardStatus(str, Enum):
+class DashboardStatus(StrEnum):
"""Dashboard status used for frontend filters"""
PUBLISHED = "published"
DRAFT = "draft"
-class ReservedUrlParameters(str, Enum):
+class ReservedUrlParameters(StrEnum):
"""
Reserved URL parameters that are used internally by Superset. These will not be
passed to chart queries, as they control the behavior of the UI.
@@ -336,7 +337,7 @@ class ReservedUrlParameters(str, Enum):
return standalone
-class RowLevelSecurityFilterType(str, Enum):
+class RowLevelSecurityFilterType(StrEnum):
REGULAR = "Regular"
BASE = "Base"
diff --git a/tests/unit_tests/utils/test_decorators.py b/tests/unit_tests/utils/test_decorators.py
index 3aafc7a91d..f600334414 100644
--- a/tests/unit_tests/utils/test_decorators.py
+++ b/tests/unit_tests/utils/test_decorators.py
@@ -17,7 +17,6 @@
from contextlib import nullcontext
-from enum import Enum
from inspect import isclass
from typing import Any, Optional
from unittest.mock import call, Mock, patch
@@ -26,9 +25,10 @@ import pytest
from superset import app
from superset.utils import decorators
+from superset.utils.backports import StrEnum
-class ResponseValues(str, Enum):
+class ResponseValues(StrEnum):
FAIL = "fail"
WARN = "warn"
OK = "ok"