mirror of https://github.com/apache/superset.git
Add type anno (#7342)
* Updated local dev instructions to include missing step * First pass at type annotations
This commit is contained in:
parent
621cef7048
commit
48b2af471c
|
@ -14,8 +14,6 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
cache:
|
|
||||||
pip: true
|
|
||||||
jobs:
|
jobs:
|
||||||
include:
|
include:
|
||||||
- language: python
|
- language: python
|
||||||
|
|
|
@ -20,7 +20,7 @@ from flask import request
|
||||||
from superset import tables_cache
|
from superset import tables_cache
|
||||||
|
|
||||||
|
|
||||||
def view_cache_key(*unused_args, **unused_kwargs):
|
def view_cache_key(*unused_args, **unused_kwargs) -> str:
|
||||||
args_hash = hash(frozenset(request.args.items()))
|
args_hash = hash(frozenset(request.args.items()))
|
||||||
return 'view/{}/{}'.format(request.path, args_hash)
|
return 'view/{}/{}'.format(request.path, args_hash)
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,8 @@ import os
|
||||||
import signal
|
import signal
|
||||||
import smtplib
|
import smtplib
|
||||||
import sys
|
import sys
|
||||||
from typing import Optional, Tuple
|
from time import struct_time
|
||||||
|
from typing import List, Optional, Tuple
|
||||||
import uuid
|
import uuid
|
||||||
import zlib
|
import zlib
|
||||||
|
|
||||||
|
@ -39,7 +40,8 @@ import bleach
|
||||||
import celery
|
import celery
|
||||||
from dateutil.parser import parse
|
from dateutil.parser import parse
|
||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
from flask import flash, g, Markup, render_template
|
from flask import flash, Flask, g, Markup, render_template
|
||||||
|
from flask_appbuilder.security.sqla.models import User
|
||||||
from flask_babel import gettext as __
|
from flask_babel import gettext as __
|
||||||
from flask_babel import lazy_gettext as _
|
from flask_babel import lazy_gettext as _
|
||||||
from flask_caching import Cache
|
from flask_caching import Cache
|
||||||
|
@ -51,6 +53,7 @@ from pydruid.utils.having import Having
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
from sqlalchemy import event, exc, select, Text
|
from sqlalchemy import event, exc, select, Text
|
||||||
from sqlalchemy.dialects.mysql import MEDIUMTEXT
|
from sqlalchemy.dialects.mysql import MEDIUMTEXT
|
||||||
|
from sqlalchemy.sql.type_api import Variant
|
||||||
from sqlalchemy.types import TEXT, TypeDecorator
|
from sqlalchemy.types import TEXT, TypeDecorator
|
||||||
|
|
||||||
from superset.exceptions import SupersetException, SupersetTimeoutException
|
from superset.exceptions import SupersetException, SupersetTimeoutException
|
||||||
|
@ -138,11 +141,11 @@ def memoized(func=None, watch=None):
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
def js_string_to_python(item):
|
def js_string_to_python(item: str) -> Optional[str]:
|
||||||
return None if item in ('null', 'undefined') else item
|
return None if item in ('null', 'undefined') else item
|
||||||
|
|
||||||
|
|
||||||
def string_to_num(s):
|
def string_to_num(s: str):
|
||||||
"""Converts a string to an int/float
|
"""Converts a string to an int/float
|
||||||
|
|
||||||
Returns ``None`` if it can't be converted
|
Returns ``None`` if it can't be converted
|
||||||
|
@ -182,7 +185,7 @@ class DimSelector(Having):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def list_minus(l, minus):
|
def list_minus(l: List, minus: List) -> List:
|
||||||
"""Returns l without what is in minus
|
"""Returns l without what is in minus
|
||||||
|
|
||||||
>>> list_minus([1, 2, 3], [2])
|
>>> list_minus([1, 2, 3], [2])
|
||||||
|
@ -230,7 +233,7 @@ def parse_human_datetime(s):
|
||||||
return dttm
|
return dttm
|
||||||
|
|
||||||
|
|
||||||
def dttm_from_timtuple(d):
|
def dttm_from_timtuple(d: struct_time) -> datetime:
|
||||||
return datetime(
|
return datetime(
|
||||||
d.tm_year, d.tm_mon, d.tm_mday, d.tm_hour, d.tm_min, d.tm_sec)
|
d.tm_year, d.tm_mon, d.tm_mday, d.tm_hour, d.tm_min, d.tm_sec)
|
||||||
|
|
||||||
|
@ -284,7 +287,7 @@ class DashboardEncoder(json.JSONEncoder):
|
||||||
return json.JSONEncoder.default(self, o)
|
return json.JSONEncoder.default(self, o)
|
||||||
|
|
||||||
|
|
||||||
def parse_human_timedelta(s):
|
def parse_human_timedelta(s: str):
|
||||||
"""
|
"""
|
||||||
Returns ``datetime.datetime`` from natural language time deltas
|
Returns ``datetime.datetime`` from natural language time deltas
|
||||||
|
|
||||||
|
@ -349,7 +352,7 @@ def base_json_conv(obj):
|
||||||
return '[bytes]'
|
return '[bytes]'
|
||||||
|
|
||||||
|
|
||||||
def json_iso_dttm_ser(obj, pessimistic=False):
|
def json_iso_dttm_ser(obj, pessimistic: Optional[bool] = False):
|
||||||
"""
|
"""
|
||||||
json serializer that deals with dates
|
json serializer that deals with dates
|
||||||
|
|
||||||
|
@ -420,7 +423,7 @@ def error_msg_from_exception(e):
|
||||||
return msg or '{}'.format(e)
|
return msg or '{}'.format(e)
|
||||||
|
|
||||||
|
|
||||||
def markdown(s, markup_wrap=False):
|
def markdown(s: str, markup_wrap: Optional[bool] = False) -> str:
|
||||||
safe_markdown_tags = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'b', 'i',
|
safe_markdown_tags = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'b', 'i',
|
||||||
'strong', 'em', 'tt', 'p', 'br', 'span',
|
'strong', 'em', 'tt', 'p', 'br', 'span',
|
||||||
'div', 'blockquote', 'code', 'hr', 'ul', 'ol',
|
'div', 'blockquote', 'code', 'hr', 'ul', 'ol',
|
||||||
|
@ -438,7 +441,7 @@ def markdown(s, markup_wrap=False):
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
def readfile(file_path):
|
def readfile(file_path: str) -> Optional[str]:
|
||||||
with open(file_path) as f:
|
with open(file_path) as f:
|
||||||
content = f.read()
|
content = f.read()
|
||||||
return content
|
return content
|
||||||
|
@ -677,17 +680,18 @@ def send_MIME_email(e_from, e_to, mime_msg, config, dryrun=False):
|
||||||
logging.info(mime_msg.as_string())
|
logging.info(mime_msg.as_string())
|
||||||
|
|
||||||
|
|
||||||
def get_email_address_list(address_string):
|
def get_email_address_list(address_string: str) -> List[str]:
|
||||||
|
address_string_list: List[str] = []
|
||||||
if isinstance(address_string, str):
|
if isinstance(address_string, str):
|
||||||
if ',' in address_string:
|
if ',' in address_string:
|
||||||
address_string = address_string.split(',')
|
address_string_list = address_string.split(',')
|
||||||
elif '\n' in address_string:
|
elif '\n' in address_string:
|
||||||
address_string = address_string.split('\n')
|
address_string_list = address_string.split('\n')
|
||||||
elif ';' in address_string:
|
elif ';' in address_string:
|
||||||
address_string = address_string.split(';')
|
address_string_list = address_string.split(';')
|
||||||
else:
|
else:
|
||||||
address_string = [address_string]
|
address_string_list = [address_string]
|
||||||
return [x.strip() for x in address_string if x.strip()]
|
return [x.strip() for x in address_string_list if x.strip()]
|
||||||
|
|
||||||
|
|
||||||
def choicify(values):
|
def choicify(values):
|
||||||
|
@ -695,11 +699,13 @@ def choicify(values):
|
||||||
return [(v, v) for v in values]
|
return [(v, v) for v in values]
|
||||||
|
|
||||||
|
|
||||||
def setup_cache(app, cache_config):
|
def setup_cache(app: Flask, cache_config) -> Optional[Cache]:
|
||||||
"""Setup the flask-cache on a flask app"""
|
"""Setup the flask-cache on a flask app"""
|
||||||
if cache_config and cache_config.get('CACHE_TYPE') != 'null':
|
if cache_config and cache_config.get('CACHE_TYPE') != 'null':
|
||||||
return Cache(app, config=cache_config)
|
return Cache(app, config=cache_config)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def zlib_compress(data):
|
def zlib_compress(data):
|
||||||
"""
|
"""
|
||||||
|
@ -766,7 +772,7 @@ def to_adhoc(filt, expressionType='SIMPLE', clause='where'):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def merge_extra_filters(form_data):
|
def merge_extra_filters(form_data: dict):
|
||||||
# extra_filters are temporary/contextual filters (using the legacy constructs)
|
# extra_filters are temporary/contextual filters (using the legacy constructs)
|
||||||
# that are external to the slice definition. We use those for dynamic
|
# that are external to the slice definition. We use those for dynamic
|
||||||
# interactive filters like the ones emitted by the "Filter Box" visualization.
|
# interactive filters like the ones emitted by the "Filter Box" visualization.
|
||||||
|
@ -837,7 +843,7 @@ def merge_extra_filters(form_data):
|
||||||
del form_data['extra_filters']
|
del form_data['extra_filters']
|
||||||
|
|
||||||
|
|
||||||
def merge_request_params(form_data, params):
|
def merge_request_params(form_data: dict, params: dict):
|
||||||
url_params = {}
|
url_params = {}
|
||||||
for key, value in params.items():
|
for key, value in params.items():
|
||||||
if key in ('form_data', 'r'):
|
if key in ('form_data', 'r'):
|
||||||
|
@ -846,12 +852,12 @@ def merge_request_params(form_data, params):
|
||||||
form_data['url_params'] = url_params
|
form_data['url_params'] = url_params
|
||||||
|
|
||||||
|
|
||||||
def get_update_perms_flag():
|
def get_update_perms_flag() -> bool:
|
||||||
val = os.environ.get('SUPERSET_UPDATE_PERMS')
|
val = os.environ.get('SUPERSET_UPDATE_PERMS')
|
||||||
return val.lower() not in ('0', 'false', 'no') if val else True
|
return val.lower() not in ('0', 'false', 'no') if val else True
|
||||||
|
|
||||||
|
|
||||||
def user_label(user):
|
def user_label(user: User) -> Optional[str]:
|
||||||
"""Given a user ORM FAB object, returns a label"""
|
"""Given a user ORM FAB object, returns a label"""
|
||||||
if user:
|
if user:
|
||||||
if user.first_name and user.last_name:
|
if user.first_name and user.last_name:
|
||||||
|
@ -859,6 +865,8 @@ def user_label(user):
|
||||||
else:
|
else:
|
||||||
return user.username
|
return user.username
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def get_or_create_main_db():
|
def get_or_create_main_db():
|
||||||
from superset import conf, db
|
from superset import conf, db
|
||||||
|
@ -887,7 +895,7 @@ def get_main_database(session):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def is_adhoc_metric(metric):
|
def is_adhoc_metric(metric) -> bool:
|
||||||
return (
|
return (
|
||||||
isinstance(metric, dict) and
|
isinstance(metric, dict) and
|
||||||
(
|
(
|
||||||
|
@ -913,7 +921,7 @@ def get_metric_names(metrics):
|
||||||
return [get_metric_name(metric) for metric in metrics]
|
return [get_metric_name(metric) for metric in metrics]
|
||||||
|
|
||||||
|
|
||||||
def ensure_path_exists(path):
|
def ensure_path_exists(path: str):
|
||||||
try:
|
try:
|
||||||
os.makedirs(path)
|
os.makedirs(path)
|
||||||
except OSError as exc:
|
except OSError as exc:
|
||||||
|
@ -997,7 +1005,7 @@ def get_since_until(time_range: Optional[str] = None,
|
||||||
return since, until # noqa: T400
|
return since, until # noqa: T400
|
||||||
|
|
||||||
|
|
||||||
def add_ago_to_since(since):
|
def add_ago_to_since(since: str) -> str:
|
||||||
"""
|
"""
|
||||||
Backwards compatibility hack. Without this slices with since: 7 days will
|
Backwards compatibility hack. Without this slices with since: 7 days will
|
||||||
be treated as 7 days in the future.
|
be treated as 7 days in the future.
|
||||||
|
@ -1072,17 +1080,17 @@ def split_adhoc_filters_into_base_filters(fd):
|
||||||
fd['filters'] = simple_where_filters
|
fd['filters'] = simple_where_filters
|
||||||
|
|
||||||
|
|
||||||
def get_username():
|
def get_username() -> Optional[str]:
|
||||||
"""Get username if within the flask context, otherwise return noffin'"""
|
"""Get username if within the flask context, otherwise return noffin'"""
|
||||||
try:
|
try:
|
||||||
return g.user.username
|
return g.user.username
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
return None
|
||||||
|
|
||||||
|
|
||||||
def MediumText():
|
def MediumText() -> Variant:
|
||||||
return Text().with_variant(MEDIUMTEXT(), 'mysql')
|
return Text().with_variant(MEDIUMTEXT(), 'mysql')
|
||||||
|
|
||||||
|
|
||||||
def shortid():
|
def shortid() -> str:
|
||||||
return '{}'.format(uuid.uuid4())[-12:]
|
return '{}'.format(uuid.uuid4())[-12:]
|
||||||
|
|
Loading…
Reference in New Issue