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

Compatibility with Flask 3, WTForms 3, SQLAlchemy 2.0 and others #2467

Merged
merged 6 commits into from
Aug 6, 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
8 changes: 6 additions & 2 deletions flask_admin/contrib/sqla/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,13 @@ class CheckboxListInput:

def __call__(self, field, **kwargs):
items = []
for val, label, selected in field.iter_choices():
for field_choices in field.iter_choices():
if len(field_choices) == 3: # wtforms <3.1, >=3.1.1, <3.2
value, label, selected = field_choices
else:
value, label, selected, _ = field_choices
args = {
'id': val,
'id': value,
'name': field.name,
'label': escape(label),
'selected': ' checked' if selected else '',
Expand Down
6 changes: 5 additions & 1 deletion flask_admin/model/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,11 @@ def get_kwargs(self, field, kwargs):

choices = []
selected_ids = []
for value, label, selected in field.iter_choices():
for field_choices in field.iter_choices():
if len(field_choices) == 3: # wtforms <3.1, >=3.1.1, <3.2
value, label, selected = field_choices
else:
value, label, selected, _ = field_choices
try:
label = text_type(label)
except TypeError:
Expand Down
1 change: 0 additions & 1 deletion flask_admin/tests/geoa/test_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ def __unicode__(self):
return GeoModel


@pytest.mark.filterwarnings("ignore:Please update your type formatter:UserWarning")
def test_model(app, db, admin):
GeoModel = create_models(db)
with app.app_context():
Expand Down
1 change: 0 additions & 1 deletion flask_admin/tests/peeweemodel/test_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,6 @@ def test_model(app, db, admin):
assert Model1.select().count() == 0


# @pytest.mark.filterwarnings("ignore:Please update your type formatter:UserWarning")
def test_column_editable_list(app, db, admin):
Model1, Model2 = create_models(db)

Expand Down
15 changes: 9 additions & 6 deletions flask_admin/tests/sqla/test_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,9 @@ def fill_db(db, Model1, Model2):
db.session.commit()


@pytest.mark.filterwarnings("ignore:Please update your type formatter:UserWarning")
@pytest.mark.filterwarnings(
"ignore:'iter_groups' is expected to return 4 items tuple since wtforms 3.1, this will be mandatory in wtforms 3.2:DeprecationWarning",
)
def test_model(app, db, admin):
with app.app_context():
Model1, Model2 = create_models(db)
Expand Down Expand Up @@ -470,7 +472,6 @@ def test_extra_args_filter(app, db, admin):
assert '<input type="hidden" name="foo" value="bar">' in data


@pytest.mark.filterwarnings("ignore:Please update your type formatter:UserWarning")
def test_complex_searchable_list(app, db, admin):
with app.app_context():
Model1, Model2 = create_models(db)
Expand Down Expand Up @@ -505,7 +506,6 @@ def test_complex_searchable_list(app, db, admin):
assert 'model1-test2-val' not in data


@pytest.mark.filterwarnings("ignore:Please update your type formatter:UserWarning")
def test_complex_searchable_list_missing_children(app, db, admin):
with app.app_context():
Model1, Model2 = create_models(db)
Expand All @@ -525,7 +525,6 @@ def test_complex_searchable_list_missing_children(app, db, admin):
assert 'magic string' in data


@pytest.mark.filterwarnings("ignore:Please update your type formatter:UserWarning")
def test_column_editable_list(app, db, admin):
with app.app_context():
Model1, Model2 = create_models(db)
Expand Down Expand Up @@ -684,7 +683,6 @@ def __init__(self, id=None, val1=None):
assert 'change-success-1' in data


@pytest.mark.filterwarnings("ignore:Please update your type formatter:UserWarning")
def test_column_filters(app, db, admin):
with app.app_context():
Model1, Model2 = create_models(db)
Expand Down Expand Up @@ -1670,7 +1668,6 @@ class Model2(db.Model):
assert 'Jim Smith' in data


@pytest.mark.filterwarnings("ignore:Please update your type formatter:UserWarning")
def test_url_args(app, db, admin):
with app.app_context():
Model1, Model2 = create_models(db)
Expand Down Expand Up @@ -2118,6 +2115,9 @@ def test_default_complex_sort(app, db, admin):
assert data[1].model1.test1 == 'b'


@pytest.mark.filterwarnings(
"ignore:'iter_groups' is expected to return 4 items tuple since wtforms 3.1, this will be mandatory in wtforms 3.2:DeprecationWarning",
)
def test_extra_fields(app, db, admin):
with app.app_context():
Model1, _ = create_models(db)
Expand Down Expand Up @@ -2184,6 +2184,9 @@ def test_extra_field_order(app, db, admin):
('zh_TW', '首頁'),
)
)
@pytest.mark.filterwarnings(
"ignore:'iter_groups' is expected to return 4 items tuple since wtforms 3.1, this will be mandatory in wtforms 3.2:DeprecationWarning",
)
@flask_babel_test_decorator
def test_modelview_localization(request, app, locale, expect_text):
# We need to configure the default Babel locale _before_ the `babel` fixture is
Expand Down
8 changes: 7 additions & 1 deletion flask_admin/tests/sqla/test_form_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,10 @@ def test_rule_field_set(app, db, admin):
assert pos3 == -1


@pytest.mark.filterwarnings("ignore:Fields missing:UserWarning")
@pytest.mark.filterwarnings(
"ignore:'iter_groups' is expected to return 4 items tuple since wtforms 3.1, this will be mandatory in wtforms 3.2:DeprecationWarning",
"ignore:Fields missing from ruleset.*:UserWarning",
)
def test_rule_inlinefieldlist(app, db, admin):
with app.app_context():
Model1, Model2 = create_models(db)
Expand All @@ -140,6 +143,9 @@ def test_rule_inlinefieldlist(app, db, admin):
assert rv.status_code == 200


@pytest.mark.filterwarnings(
"ignore:'iter_groups' is expected to return 4 items tuple since wtforms 3.1, this will be mandatory in wtforms 3.2:DeprecationWarning",
)
def test_inline_model_rules(app, db, admin):
with app.app_context():
Model1, Model2 = create_models(db)
Expand Down
8 changes: 5 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ classifiers = [
]
requires-python = ">=3.8"
dependencies = [
"flask>=2.0,<3",
"wtforms>=2,<3",
"flask>=2.0",
"wtforms>=2",
]

[project.optional-dependencies]
Expand All @@ -47,7 +47,9 @@ geoalchemy = [
mongoengine = [ # TODO: seems out-of-date/unmaintained; replace or deprecate?
"Flask-Admin[sqlalchemy]",
"flask-mongoengine<1",
"Flask<2.3.0", # flask-mongoengine tries to access `flask.json`
"Flask<2.3.0", # flask-mongoengine tries to access `flask.json`,
"sqlalchemy>=1.4,<2",
Copy link
Contributor

@samuelhwilliams samuelhwilliams Aug 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to repeat the >=1.4 here, as we get this from the sqlalchemy optional group already. Ie this could maybe just be sqlalchemy<2

However it's all a bit moot, as I have a PR up to remove support for mongoengine altogether.

"wtforms>=2,<3",
]
pymongo = ["pymongo>=3.7.0"]
peewee = [
Expand Down