chore: remove deprecated distutils (#24001)

This commit is contained in:
Sebastian Liebscher 2023-05-11 18:00:04 +02:00 committed by GitHub
parent c9a0694116
commit c963416c09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 72 additions and 20 deletions

View File

@ -300,7 +300,7 @@ ignore-mixin-members=yes
# (useful for modules/projects where namespaces are manipulated during runtime # (useful for modules/projects where namespaces are manipulated during runtime
# and thus existing member attributes cannot be deduced by static analysis. It # and thus existing member attributes cannot be deduced by static analysis. It
# supports qualified module names, as well as Unix pattern matching. # supports qualified module names, as well as Unix pattern matching.
ignored-modules=numpy,pandas,alembic.op,sqlalchemy,alembic.context,flask_appbuilder.security.sqla.PermissionView.role,flask_appbuilder.Model.metadata,flask_appbuilder.Base.metadata,distutils ignored-modules=numpy,pandas,alembic.op,sqlalchemy,alembic.context,flask_appbuilder.security.sqla.PermissionView.role,flask_appbuilder.Model.metadata,flask_appbuilder.Base.metadata
# List of class names for which member attributes should not be checked (useful # List of class names for which member attributes should not be checked (useful
# for classes with dynamically set attributes). This supports the use of # for classes with dynamically set attributes). This supports the use of

View File

@ -193,6 +193,7 @@ ordered-set==4.1.0
# via flask-limiter # via flask-limiter
packaging==23.1 packaging==23.1
# via # via
# apache-superset
# deprecation # deprecation
# limits # limits
pandas==1.5.3 pandas==1.5.3

View File

@ -101,6 +101,7 @@ setup(
"msgpack>=1.0.0, <1.1", "msgpack>=1.0.0, <1.1",
"nh3>=0.2.11, <0.3", "nh3>=0.2.11, <0.3",
"numpy==1.23.5", "numpy==1.23.5",
"packaging",
"pandas>=1.5.3, <1.6", "pandas>=1.5.3, <1.6",
"parsedatetime", "parsedatetime",
"pgsanity", "pgsanity",

View File

@ -16,9 +16,9 @@
# under the License. # under the License.
import logging import logging
from datetime import datetime from datetime import datetime
from distutils.version import StrictVersion
from typing import Any, Dict, Optional, Type from typing import Any, Dict, Optional, Type
from packaging.version import Version
from sqlalchemy import types from sqlalchemy import types
from superset.db_engine_specs.base import BaseEngineSpec from superset.db_engine_specs.base import BaseEngineSpec
@ -79,9 +79,7 @@ class ElasticSearchEngineSpec(BaseEngineSpec): # pylint: disable=abstract-metho
supports_dttm_parse = False supports_dttm_parse = False
try: try:
if es_version: if es_version:
supports_dttm_parse = StrictVersion(es_version) >= StrictVersion( supports_dttm_parse = Version(es_version) >= Version("7.8")
"7.8"
)
except Exception as ex: # pylint: disable=broad-except except Exception as ex: # pylint: disable=broad-except
logger.error("Unexpected error while convert es_version", exc_info=True) logger.error("Unexpected error while convert es_version", exc_info=True)
logger.exception(ex) logger.exception(ex)

View File

@ -23,7 +23,6 @@ import time
from abc import ABCMeta from abc import ABCMeta
from collections import defaultdict, deque from collections import defaultdict, deque
from datetime import datetime from datetime import datetime
from distutils.version import StrictVersion
from textwrap import dedent from textwrap import dedent
from typing import ( from typing import (
Any, Any,
@ -43,6 +42,7 @@ import pandas as pd
import simplejson as json import simplejson as json
from flask import current_app from flask import current_app
from flask_babel import gettext as __, lazy_gettext as _ from flask_babel import gettext as __, lazy_gettext as _
from packaging.version import Version
from sqlalchemy import Column, literal_column, types from sqlalchemy import Column, literal_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
@ -470,8 +470,7 @@ class PrestoBaseEngineSpec(BaseEngineSpec, metaclass=ABCMeta):
# Default to the new syntax if version is unset. # Default to the new syntax if version is unset.
partition_select_clause = ( partition_select_clause = (
f'SELECT * FROM "{table_name}$partitions"' f'SELECT * FROM "{table_name}$partitions"'
if not presto_version if not presto_version or Version(presto_version) >= Version("0.199")
or StrictVersion(presto_version) >= StrictVersion("0.199")
else f"SHOW PARTITIONS FROM {table_name}" else f"SHOW PARTITIONS FROM {table_name}"
) )
@ -705,7 +704,7 @@ class PrestoEngineSpec(PrestoBaseEngineSpec):
@classmethod @classmethod
def get_allow_cost_estimate(cls, extra: Dict[str, Any]) -> bool: def get_allow_cost_estimate(cls, extra: Dict[str, Any]) -> bool:
version = extra.get("version") version = extra.get("version")
return version is not None and StrictVersion(version) >= StrictVersion("0.319") return version is not None and Version(version) >= Version("0.319")
@classmethod @classmethod
def update_impersonation_config( def update_impersonation_config(

View File

@ -38,7 +38,6 @@ import zlib
from contextlib import contextmanager from contextlib import contextmanager
from dataclasses import dataclass from dataclasses import dataclass
from datetime import date, datetime, time, timedelta from datetime import date, datetime, time, timedelta
from distutils.util import strtobool
from email.mime.application import MIMEApplication from email.mime.application import MIMEApplication
from email.mime.image import MIMEImage from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart from email.mime.multipart import MIMEMultipart
@ -1191,6 +1190,7 @@ def merge_extra_filters(form_data: Dict[str, Any]) -> None:
"__time_grain": "time_grain_sqla", "__time_grain": "time_grain_sqla",
"__granularity": "granularity", "__granularity": "granularity",
} }
# Grab list of existing filters 'keyed' on the column and operator # Grab list of existing filters 'keyed' on the column and operator
def get_filter_key(f: Dict[str, Any]) -> str: def get_filter_key(f: Dict[str, Any]) -> str:
@ -1788,7 +1788,7 @@ def indexed(
def is_test() -> bool: def is_test() -> bool:
return strtobool(os.environ.get("SUPERSET_TESTENV", "false")) # type: ignore return parse_boolean_string(os.environ.get("SUPERSET_TESTENV", "false"))
def get_time_filter_status( def get_time_filter_status(
@ -1952,10 +1952,7 @@ def parse_boolean_string(bool_str: Optional[str]) -> bool:
""" """
if bool_str is None: if bool_str is None:
return False return False
try: return bool_str.lower() in ("y", "Y", "yes", "True", "t", "true", "On", "on", "1")
return bool(strtobool(bool_str.lower()))
except ValueError:
return False
def apply_max_row_limit( def apply_max_row_limit(

View File

@ -15,10 +15,10 @@
# specific language governing permissions and limitations # specific language governing permissions and limitations
# under the License. # under the License.
from typing import Sequence, Union from collections.abc import Iterable
from typing import Any, Sequence, Union
import pandas as pd import pandas as pd
from numpy.distutils.misc_util import is_sequence
from superset.utils.pandas_postprocessing.utils import ( from superset.utils.pandas_postprocessing.utils import (
_is_multi_index_on_columns, _is_multi_index_on_columns,
@ -27,6 +27,13 @@ from superset.utils.pandas_postprocessing.utils import (
) )
def is_sequence(seq: Any) -> bool:
if isinstance(seq, str):
return False
return isinstance(seq, Iterable)
def flatten( def flatten(
df: pd.DataFrame, df: pd.DataFrame,
reset_index: bool = True, reset_index: bool = True,
@ -85,7 +92,7 @@ def flatten(
_columns = [] _columns = []
for series in df.columns.to_flat_index(): for series in df.columns.to_flat_index():
_cells = [] _cells = []
for cell in series if is_sequence(series) else [series]: # type: ignore for cell in series if is_sequence(series) else [series]:
if pd.notnull(cell): if pd.notnull(cell):
# every cell should be converted to string and escape comma # every cell should be converted to string and escape comma
_cells.append(escape_separator(str(cell))) _cells.append(escape_separator(str(cell)))

View File

@ -15,11 +15,17 @@
# 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, Dict import os
from typing import Any, Dict, Optional
import pytest import pytest
from superset.utils.core import QueryObjectFilterClause, remove_extra_adhoc_filters from superset.utils.core import (
is_test,
parse_boolean_string,
QueryObjectFilterClause,
remove_extra_adhoc_filters,
)
ADHOC_FILTER: QueryObjectFilterClause = { ADHOC_FILTER: QueryObjectFilterClause = {
"col": "foo", "col": "foo",
@ -84,3 +90,46 @@ def test_remove_extra_adhoc_filters(
) -> None: ) -> None:
remove_extra_adhoc_filters(original) remove_extra_adhoc_filters(original)
assert expected == original assert expected == original
def test_is_test():
orig_value = os.getenv("SUPERSET_TESTENV")
os.environ["SUPERSET_TESTENV"] = "true"
assert is_test()
os.environ["SUPERSET_TESTENV"] = "false"
assert not is_test()
os.environ["SUPERSET_TESTENV"] = ""
assert not is_test()
if orig_value is not None:
os.environ["SUPERSET_TESTENV"] = orig_value
@pytest.mark.parametrize(
"test_input,expected",
[
("y", True),
("Y", True),
("yes", True),
("True", True),
("t", True),
("true", True),
("On", True),
("on", True),
("1", True),
("n", False),
("N", False),
("no", False),
("False", False),
("f", False),
("false", False),
("Off", False),
("off", False),
("0", False),
("foo", False),
(None, False),
],
)
def test_parse_boolean_string(test_input: Optional[str], expected: bool):
assert parse_boolean_string(test_input) == expected