Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-enable the typing github action #2445

Merged
merged 4 commits into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,12 @@ jobs:
strategy:
fail-fast: false
matrix:
# tox: ['docs', 'typing']
tox: ['docs'] # disable typing tests until we have typed the project correctly
tox: ['docs', 'typing']
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
with:
python-version: '3.x'
python-version: 3.11
cache: pip
cache-dependency-path: requirements*/*.txt
- name: cache mypy
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ If you\'re using Homebrew on MacOS, you might need this:
# install postgis and geos
> brew install postgis
> brew install geos
> export DYLD_LIBRARY_PATH=/opt/homebrew/opt/geos/lib/

# set up postgresql user
> createuser -s postgresql
Expand Down
2 changes: 1 addition & 1 deletion flask_admin/_backwards.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import warnings

try:
from wtforms.widgets import HTMLString as Markup
from wtforms.widgets import HTMLString as Markup # type: ignore[attr-defined]
except ImportError:
# WTForms 2.3.0
from markupsafe import Markup # noqa: F401
Expand Down
39 changes: 14 additions & 25 deletions flask_admin/_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,23 @@
:copyright: (c) 2013 by Armin Ronacher.
:license: BSD, see LICENSE for more details.
"""
from typing import Callable

text_type = str
string_types = (str,)

itervalues = lambda d: iter(d.values())
iteritems = lambda d: iter(d.items())
filter_list = lambda f, l: list(filter(f, l))

def itervalues(d: dict):
return iter(d.values())


def iteritems(d: dict):
return iter(d.items())


def filter_list(f: Callable, l: list):
return list(filter(f, l))


def as_unicode(s):
if isinstance(s, bytes):
Expand All @@ -29,29 +39,8 @@ def csv_encode(s):
return as_unicode(s)


def with_metaclass(meta, *bases):
# This requires a bit of explanation: the basic idea is to make a
# dummy metaclass for one level of class instantiation that replaces
# itself with the actual metaclass. Because of internal type checks
# we also need to make sure that we downgrade the custom metaclass
# for one level to something closer to type (that's why __call__ and
# __init__ comes back from type etc.).
#
# This has the advantage over six.with_metaclass in that it does not
# introduce dummy classes into the final MRO.
class metaclass(meta):
__call__ = type.__call__
__init__ = type.__init__

def __new__(cls, name, this_bases, d):
if this_bases is None:
return type.__new__(cls, name, (), d)
return meta(name, bases, d)
return metaclass('temporary_class', None, {})


try:
# jinja2 3.0.0
from jinja2 import pass_context
from jinja2 import pass_context # type: ignore[attr-defined]
except ImportError:
from jinja2 import contextfunction as pass_context
6 changes: 6 additions & 0 deletions flask_admin/_types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from typing import Union, Sequence, Dict, Callable

import sqlalchemy

T_COLUMN_LIST = Sequence[Union[str, sqlalchemy.Column]]
T_FORMATTERS = Dict[type, Callable] # todo: Make this tighter
2 changes: 1 addition & 1 deletion flask_admin/babel.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def get_translations_path(self, ctx):

wtforms_domain = Domain(messages_path(), domain='wtforms')

class Translations(object):
class Translations(object): # type: ignore[no-redef]
''' Fixes WTForms translation support and uses wtforms translations '''
def gettext(self, string):
t = wtforms_domain.get_translations()
Expand Down
4 changes: 2 additions & 2 deletions flask_admin/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from flask import Blueprint, current_app, render_template, abort, g, url_for
from flask_admin import babel
from flask_admin._compat import with_metaclass, as_unicode
from flask_admin._compat import as_unicode
from flask_admin import helpers as h

# For compatibility reasons import MenuLink
Expand Down Expand Up @@ -106,7 +106,7 @@ class BaseViewClass(object):
pass


class BaseView(with_metaclass(AdminViewMeta, BaseViewClass)):
class BaseView(BaseViewClass, metaclass=AdminViewMeta):
"""
Base administrative view.

Expand Down
2 changes: 1 addition & 1 deletion flask_admin/contrib/fileadmin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ class MyAdmin(FileAdmin):
allowed_extensions = ('swf', 'jpg', 'gif', 'png')
"""

editable_extensions = tuple()
editable_extensions: tuple = tuple()
"""
List of editable extensions, in lower case.

Expand Down
4 changes: 4 additions & 0 deletions flask_admin/contrib/fileadmin/s3.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import time
from types import ModuleType
from typing import Optional

s3: Optional[ModuleType]

try:
from boto import s3
Expand Down
2 changes: 1 addition & 1 deletion flask_admin/contrib/geoa/typefmt.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ def geom_formatter(view, value):


DEFAULT_FORMATTERS = BASE_FORMATTERS.copy()
DEFAULT_FORMATTERS[WKBElement] = geom_formatter
DEFAULT_FORMATTERS[WKBElement] = geom_formatter # type: ignore[assignment]
2 changes: 1 addition & 1 deletion flask_admin/contrib/mongoengine/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,4 @@ class MongoImageField(MongoFileField):
GridFS image field.
"""

widget = widgets.MongoImageInput()
widget = widgets.MongoImageInput() # type: ignore[assignment]
2 changes: 1 addition & 1 deletion flask_admin/contrib/peewee/form.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
PrimaryKeyField, ForeignKeyField)

try:
from peewee import BaseModel
from peewee import BaseModel # type: ignore[attr-defined]
except ImportError:
from peewee import ModelBase as BaseModel

Expand Down
2 changes: 1 addition & 1 deletion flask_admin/contrib/sqla/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ class MyView(ModelView):
'languages': CheckboxListField,
}
"""
widget = CheckboxListInput()
widget = CheckboxListInput() # type: ignore[assignment]


class HstoreForm(BaseForm):
Expand Down
2 changes: 1 addition & 1 deletion flask_admin/contrib/sqla/form.py
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,7 @@ def contribute(self, model, form_class, inline_model):


class InlineOneToOneModelConverter(InlineModelConverter):
inline_field_list_type = InlineModelOneToOneField
inline_field_list_type = InlineModelOneToOneField # type: ignore[assignment]

def _calculate_mapping_key_pair(self, model, info):

Expand Down
6 changes: 3 additions & 3 deletions flask_admin/contrib/sqla/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
from sqlalchemy.orm.clsregistry import _class_resolver
except ImportError:
# If 1.4/2.0 module import fails, fall back to <1.3.x architecture.
from sqlalchemy.ext.declarative.clsregistry import _class_resolver
from sqlalchemy.ext.declarative.clsregistry import _class_resolver # type: ignore[no-redef]
from sqlalchemy.ext.hybrid import hybrid_property
try:
# Attempt ASSOCATION_PROXY import from pre-2.0 release
from sqlalchemy.ext.associationproxy import ASSOCIATION_PROXY
except ImportError:
from sqlalchemy.ext.associationproxy import AssociationProxyExtensionType
from sqlalchemy.ext.associationproxy import AssociationProxyExtensionType # type: ignore[attr-defined]
ASSOCIATION_PROXY = AssociationProxyExtensionType.ASSOCIATION_PROXY
from sqlalchemy.sql.operators import eq
from sqlalchemy.sql.operators import eq # type: ignore[attr-defined]
from sqlalchemy.exc import DBAPIError
from sqlalchemy.orm.attributes import InstrumentedAttribute

Expand Down
6 changes: 3 additions & 3 deletions flask_admin/contrib/sqla/typefmt.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ def arrow_export_formatter(view, arrow_time):
})
try:
from sqlalchemy_utils import Choice
DEFAULT_FORMATTERS[Choice] = choice_formatter
DEFAULT_FORMATTERS[Choice] = choice_formatter # type: ignore[assignment]
except ImportError:
pass

try:
from arrow import Arrow
DEFAULT_FORMATTERS[Arrow] = arrow_formatter
EXPORT_FORMATTERS[Arrow] = arrow_export_formatter
DEFAULT_FORMATTERS[Arrow] = arrow_formatter # type: ignore[assignment]
EXPORT_FORMATTERS[Arrow] = arrow_export_formatter # type: ignore[assignment]
except ImportError:
pass
20 changes: 12 additions & 8 deletions flask_admin/contrib/sqla/view.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging
import warnings
import inspect
from typing import Optional, Dict, List, Tuple, cast as t_cast

from sqlalchemy.orm.attributes import InstrumentedAttribute
from sqlalchemy.orm.base import manager_of_class, instance_state
Expand Down Expand Up @@ -72,16 +73,19 @@ class PostAdmin(ModelView):
Please refer to the `subqueryload` on list of possible values.
"""

column_display_all_relations = ObsoleteAttr('column_display_all_relations',
'list_display_all_relations',
False)
column_display_all_relations = ObsoleteAttr(
'column_display_all_relations',
'list_display_all_relations',
False
)
"""
Controls if list view should display all relations, not only many-to-one.
"""

column_searchable_list = ObsoleteAttr('column_searchable_list',
'searchable_columns',
None)
column_searchable_list = t_cast(
None,
ObsoleteAttr('column_searchable_list', 'searchable_columns', None),
)
"""
Collection of the searchable columns.

Expand Down Expand Up @@ -264,9 +268,9 @@ class MyModelView(ModelView):
inline_models = (MyInlineModelForm(MyInlineModel),)
"""

column_type_formatters = DEFAULT_FORMATTERS
column_type_formatters = DEFAULT_FORMATTERS # type: ignore[assignment]

form_choices = None
form_choices: Optional[Dict[str, List[Tuple[str, str]]]] = None
"""
Map choices to form fields

Expand Down
2 changes: 1 addition & 1 deletion flask_admin/contrib/sqla/widgets.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from wtforms.widgets.core import escape
from wtforms.widgets.core import escape # type: ignore[attr-defined]

from flask_admin._backwards import Markup

Expand Down
9 changes: 7 additions & 2 deletions flask_admin/form/upload.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import os
import os.path as op
from types import ModuleType
from typing import Optional
from urllib.parse import urljoin

from werkzeug.utils import secure_filename
from werkzeug.datastructures import FileStorage

from wtforms import ValidationError, fields, __version__ as wtforms_version
from wtforms import ValidationError, fields, __version__ as wtforms_version # type: ignore[attr-defined]
from wtforms.utils import unset_value
from wtforms.widgets import html_params

Expand All @@ -15,6 +17,9 @@
from flask_admin._backwards import Markup
from flask_admin._compat import string_types

Image: Optional[ModuleType]
ImageOps: Optional[ModuleType]


try:
from PIL import Image, ImageOps
Expand Down Expand Up @@ -299,7 +304,7 @@ class ImageUploadField(FileUploadField):

Requires PIL (or Pillow) to be installed.
"""
widget = ImageUploadInput()
widget = ImageUploadInput() # type: ignore[assignment]

keep_image_formats = ('PNG',)
"""
Expand Down
Loading
Loading