Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-Flask-Admin for openSUSE:Factory checked in at 2026-02-17 18:14:18 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-Flask-Admin (Old) and /work/SRC/openSUSE:Factory/.python-Flask-Admin.new.1977 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-Flask-Admin" Tue Feb 17 18:14:18 2026 rev:19 rq:1333428 version:2.0.2 Changes: -------- --- /work/SRC/openSUSE:Factory/python-Flask-Admin/python-Flask-Admin.changes 2025-10-28 14:50:29.508844006 +0100 +++ /work/SRC/openSUSE:Factory/.python-Flask-Admin.new.1977/python-Flask-Admin.changes 2026-02-17 18:14:34.085985014 +0100 @@ -1,0 +2,10 @@ +Mon Feb 16 17:50:25 UTC 2026 - Dirk Müller <[email protected]> + +- update to 2.0.2: + * Add support for Python 3.14 + * Add a MenuDivider item for bootstrap themes + * Field errors are now shown in red text for bootstrap themes + * Fix documentation + * Update arabic translations + +------------------------------------------------------------------- Old: ---- flask_admin-2.0.0.tar.gz New: ---- flask_admin-2.0.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-Flask-Admin.spec ++++++ --- /var/tmp/diff_new_pack.3UM1CH/_old 2026-02-17 18:14:35.102027348 +0100 +++ /var/tmp/diff_new_pack.3UM1CH/_new 2026-02-17 18:14:35.106027514 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-Flask-Admin # -# Copyright (c) 2025 SUSE LLC and contributors +# Copyright (c) 2026 SUSE LLC and contributors # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,7 +18,7 @@ %{?sle15_python_module_pythons} Name: python-Flask-Admin -Version: 2.0.0 +Version: 2.0.2 Release: 0 Summary: Extensible admin interface framework for Flask License: BSD-3-Clause ++++++ flask_admin-2.0.0.tar.gz -> flask_admin-2.0.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/flask_admin-2.0.0/PKG-INFO new/flask_admin-2.0.2/PKG-INFO --- old/flask_admin-2.0.0/PKG-INFO 1970-01-01 01:00:00.000000000 +0100 +++ new/flask_admin-2.0.2/PKG-INFO 1970-01-01 01:00:00.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.4 Name: Flask-Admin -Version: 2.0.0 +Version: 2.0.2 Summary: Simple and extensible admin interface framework for Flask Maintainer-email: Pallets Ecosystem <[email protected]> Requires-Python: >=3.10 @@ -16,6 +16,7 @@ Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: 3.12 Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 License-File: LICENSE License-File: LICENSE.txt Requires-Dist: flask>=2.0 @@ -100,10 +101,14 @@ control over the look, feel, functionality and user experience of the resulting application. +<img width="1242" height="596" alt="image" src="https://github.com/user-attachments/assets/177c1ffd-1f55-4c0d-88a8-abce0d3371f6" /> + + Out-of-the-box, Flask-Admin plays nicely with various ORM\'s, including - [SQLAlchemy](https://www.sqlalchemy.org/) - [pymongo](https://pymongo.readthedocs.io/) +- [MongoEngine](https://mongoengine.org/) - and [Peewee](https://github.com/coleifer/peewee). It also boasts a simple file management interface and a [Redis client](https://redis.io/) console. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/flask_admin-2.0.0/README.md new/flask_admin-2.0.2/README.md --- old/flask_admin-2.0.0/README.md 2025-10-20 21:09:31.000000000 +0200 +++ new/flask_admin-2.0.2/README.md 2025-11-11 14:07:49.000000000 +0100 @@ -23,10 +23,14 @@ control over the look, feel, functionality and user experience of the resulting application. +<img width="1242" height="596" alt="image" src="https://github.com/user-attachments/assets/177c1ffd-1f55-4c0d-88a8-abce0d3371f6" /> + + Out-of-the-box, Flask-Admin plays nicely with various ORM\'s, including - [SQLAlchemy](https://www.sqlalchemy.org/) - [pymongo](https://pymongo.readthedocs.io/) +- [MongoEngine](https://mongoengine.org/) - and [Peewee](https://github.com/coleifer/peewee). It also boasts a simple file management interface and a [Redis client](https://redis.io/) console. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/flask_admin-2.0.0/flask_admin/__init__.py new/flask_admin-2.0.2/flask_admin/__init__.py --- old/flask_admin-2.0.0/flask_admin/__init__.py 2025-10-20 21:09:31.000000000 +0200 +++ new/flask_admin-2.0.2/flask_admin/__init__.py 2025-11-11 14:07:49.000000000 +0100 @@ -1,4 +1,4 @@ -__version__ = "2.0.0" +__version__ = "2.0.2" __author__ = "Flask-Admin team" __email__ = "[email protected]" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/flask_admin-2.0.0/flask_admin/menu.py new/flask_admin-2.0.2/flask_admin/menu.py --- old/flask_admin-2.0.0/flask_admin/menu.py 2025-10-20 21:09:31.000000000 +0200 +++ new/flask_admin-2.0.2/flask_admin/menu.py 2025-11-11 14:07:49.000000000 +0100 @@ -181,3 +181,23 @@ def __init__(self, *args: str, **kwargs: t.Any) -> None: super().__init__(*args, **kwargs) self.class_name += " dropdown-submenu dropright" + + +class MenuDivider(MenuLink): + """ + Bootstrap Menu divider item + Usage: + admin = Admin(app, ...) + admin.add_menu_item(MenuDivider(), target_category='Category1') + """ + + def __init__(self, class_name=""): + class_name = "dropdown-divider" + (" " + class_name if class_name else "") + super().__init__("divider", class_name=class_name) + + def get_url(self): + return None + + def is_visible(self): + # Return True/False depending on your use-case + return True diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/flask_admin-2.0.0/flask_admin/model/template.py new/flask_admin-2.0.2/flask_admin/model/template.py --- old/flask_admin-2.0.0/flask_admin/model/template.py 2025-10-20 21:09:31.000000000 +0200 +++ new/flask_admin-2.0.2/flask_admin/model/template.py 2025-11-11 14:07:49.000000000 +0100 @@ -31,7 +31,12 @@ class LinkRowAction(BaseListRowAction): - def __init__(self, icon_class: str, url: str, title: str | None = None) -> None: + def __init__( + self, + icon_class: str, + url: str | t.Callable[["LinkRowAction", str, t.Any], str], + title: str | None = None, + ) -> None: super().__init__(title=title) self.url = url diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/flask_admin-2.0.0/flask_admin/templates/bootstrap4/admin/layout.html new/flask_admin-2.0.2/flask_admin/templates/bootstrap4/admin/layout.html --- old/flask_admin-2.0.0/flask_admin/templates/bootstrap4/admin/layout.html 2025-10-20 21:09:31.000000000 +0200 +++ new/flask_admin-2.0.2/flask_admin/templates/bootstrap4/admin/layout.html 2025-11-11 14:07:49.000000000 +0100 @@ -22,42 +22,45 @@ {% set children = item.get_children() %} {%- if children %} {% set class_name = item.get_class_name() or '' %} - {%- if item.is_active(admin_view) %} - <li class="active dropdown"> - {% else -%} - <li class="dropdown"> - {%- endif %} - <a class="dropdown-toggle {% if is_main_nav %}nav-link{% else %}dropdown-item{% endif %}" data-toggle="dropdown" href="javascript:void(0)"> - <!-- show icon --> - {% if item.class_name %}<span class="{{ item.class_name }}"></span> {% endif %} - {{ menu_icon(item) }}{{ item.name }} - {%- if 'dropdown-submenu' in class_name -%} - <i class="glyphicon glyphicon-chevron-right small"></i> - {%- else -%} - <i class="glyphicon glyphicon-chevron-down small"></i> - {%- endif -%} - </a> - <ul class="dropdown-menu"> - {%- for child in children -%} - {%- if child.is_category() -%} - {{ menu(menu_root=[child]) }} - {% else %} - {% set class_name = child.get_class_name() %} - <li> - {%- if child.is_active(admin_view) %} - <a class="dropdown-item active {{ class_name }} " href="{{ child.get_url() }}"{% if child.target %} - target="{{ child.target }}"{% endif %}> - {{ menu_icon(child) }}{{ child.name }}</a> + + <!-- just enhance the readability --> + <li class="{% if item.is_active(admin_view) %}active {% endif %}dropdown"> + + <a class="dropdown-toggle {% if is_main_nav %}nav-link{% else %}dropdown-item{% endif %}" data-toggle="dropdown" href="javascript:void(0)"> + <!-- show icon --> + {% if item.class_name %}<span class="{{ item.class_name }}"></span> {% endif %} + {{ menu_icon(item) }}{{ item.name }} + {%- if 'dropdown-submenu' in class_name -%} + <i class="glyphicon glyphicon-chevron-right small"></i> + {%- else -%} + <i class="glyphicon glyphicon-chevron-down small"></i> + {%- endif -%} + </a> + <ul class="dropdown-menu"> + {%- for child in children -%} + {%- if child.is_category() -%} + {{ menu(menu_root=[child]) }} {% else %} - <a class="dropdown-item {{ class_name }}" href="{{ child.get_url() }}"{% if child.target %} - target="{{ child.target }}"{% endif %}> - {{ menu_icon(child) }}{{ child.name }}</a> + {% set class_name = child.get_class_name() %} + {% if 'dropdown-divider' in class_name %} + <li class="{{ class_name }}"></li> + {% else %} + <li> + {%- if child.is_active(admin_view) %} + <a class="dropdown-item active {{ class_name }} " href="{{ child.get_url() }}"{% if child.target %} + target="{{ child.target }}"{% endif %}> + {{ menu_icon(child) }}{{ child.name }}</a> + {% else %} + <a class="dropdown-item {{ class_name }}" href="{{ child.get_url() }}"{% if child.target %} + target="{{ child.target }}"{% endif %}> + {{ menu_icon(child) }}{{ child.name }}</a> + {%- endif %} + </li> + {%- endif %} {%- endif %} - </li> - {%- endif %} - {%- endfor %} - </ul> - </li> + {%- endfor %} + </ul> + </li> {% endif %} {%- else %} {%- if item.is_accessible() and item.is_visible() -%} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/flask_admin-2.0.0/flask_admin/templates/bootstrap4/admin/lib.html new/flask_admin-2.0.2/flask_admin/templates/bootstrap4/admin/lib.html --- old/flask_admin-2.0.0/flask_admin/templates/bootstrap4/admin/lib.html 2025-10-20 21:09:31.000000000 +0200 +++ new/flask_admin-2.0.2/flask_admin/templates/bootstrap4/admin/lib.html 2025-11-11 14:07:49.000000000 +0100 @@ -151,7 +151,7 @@ {%- endif -%} {% if direct_error %} <div class="invalid-feedback"> - <ul class="form-text text-muted {% if field.widget.input_type == 'checkbox' %}mt-0{% endif %}"> + <ul class="form-text text-danger {% if field.widget.input_type == 'checkbox' %}mt-0{% endif %}"> {% for e in field.errors if e is string %} <li>{{ e }}</li> {% endfor %} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/flask_admin-2.0.0/flask_admin/tests/geoa/conftest.py new/flask_admin-2.0.2/flask_admin/tests/geoa/conftest.py --- old/flask_admin-2.0.0/flask_admin/tests/geoa/conftest.py 2025-10-20 21:09:31.000000000 +0200 +++ new/flask_admin-2.0.2/flask_admin/tests/geoa/conftest.py 2025-11-11 14:07:49.000000000 +0100 @@ -7,9 +7,12 @@ @pytest.fixture -def db(): +def db(app): db = SQLAlchemy() yield db + with app.app_context(): + db.session.close() + db.engine.dispose() @pytest.fixture diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/flask_admin-2.0.0/flask_admin/tests/peeweemodel/conftest.py new/flask_admin-2.0.2/flask_admin/tests/peeweemodel/conftest.py --- old/flask_admin-2.0.0/flask_admin/tests/peeweemodel/conftest.py 2025-10-20 21:09:31.000000000 +0200 +++ new/flask_admin-2.0.2/flask_admin/tests/peeweemodel/conftest.py 2025-11-11 14:07:49.000000000 +0100 @@ -5,10 +5,11 @@ @pytest.fixture -def db(): +def db(app): db = peewee.SqliteDatabase(":memory:") yield db - db.close() + with app.app_context(): + db.close() @pytest.fixture diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/flask_admin-2.0.0/flask_admin/tests/sqla/conftest.py new/flask_admin-2.0.2/flask_admin/tests/sqla/conftest.py --- old/flask_admin-2.0.0/flask_admin/tests/sqla/conftest.py 2025-10-20 21:09:31.000000000 +0200 +++ new/flask_admin-2.0.2/flask_admin/tests/sqla/conftest.py 2025-11-11 14:07:49.000000000 +0100 @@ -27,6 +27,10 @@ db = SQLAlchemy(app) yield db + with app.app_context(): + db.session.close() + db.engine.dispose() + @pytest.fixture def postgres_db(app): @@ -40,6 +44,10 @@ db = SQLAlchemy(app) yield db + with app.app_context(): + db.session.close() + db.engine.dispose() + @pytest.fixture def admin(app, babel, db): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/flask_admin-2.0.0/flask_admin/tests/test_base.py new/flask_admin-2.0.2/flask_admin/tests/test_base.py --- old/flask_admin-2.0.0/flask_admin/tests/test_base.py 2025-10-20 21:09:31.000000000 +0200 +++ new/flask_admin-2.0.2/flask_admin/tests/test_base.py 2025-11-11 14:07:49.000000000 +0100 @@ -12,6 +12,8 @@ from flask_admin import base from flask_admin import BaseView from flask_admin import expose +from flask_admin.menu import MenuDivider +from flask_admin.menu import MenuLink @pytest.fixture @@ -245,6 +247,7 @@ assert len(admin.menu()) == 3 [email protected]("ignore:unclosed file:ResourceWarning") def test_add_category(admin): admin.add_category("Category1", "class-name", "icon-type", "icon-value") admin.add_view(MockView(name="Test 1", endpoint="test1", category="Category1")) @@ -354,6 +357,40 @@ assert children[0].is_accessible() +def test_menu_divider(app, admin): + # admin.add_view(MockView(name="Test 1", category="Test", endpoint="test1")) + # admin.add_view(MockView(name="Test 2", category="Test", endpoint="test2")) + admin.add_link( + MenuLink(name="link1", url="http://www.example.com/", category="Links") + ) + admin.add_link( + MenuLink(name="link2", url="http://www.example.com/", category="Links") + ) + admin.add_menu_item(MenuDivider(), target_category="Links") + admin.add_link( + MenuLink(name="link3", url="http://www.example.com/", category="Links") + ) + + assert admin.menu()[1].name == "Links" + assert len(admin._menu) == 2 + assert admin._menu[1].name == "Links" + assert len(admin._menu[1]._children) == 4 + + client = app.test_client() + + rv = client.get("/admin/") + assert rv.status_code == 200 + + data = rv.data.decode("utf-8") + pos1 = data.find("link1") + pos2 = data.find("link2") + pos3 = data.find('<li class="dropdown-divider"></li>') + pos4 = data.find("link3") + assert pos2 > pos1 + assert pos3 > pos2 + assert pos4 > pos3 + + def test_delayed_init(app, admin): admin.add_view(MockView()) Binary files old/flask_admin-2.0.0/flask_admin/translations/ar/LC_MESSAGES/admin.mo and new/flask_admin-2.0.2/flask_admin/translations/ar/LC_MESSAGES/admin.mo differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/flask_admin-2.0.0/flask_admin/translations/ar/LC_MESSAGES/admin.po new/flask_admin-2.0.2/flask_admin/translations/ar/LC_MESSAGES/admin.po --- old/flask_admin-2.0.0/flask_admin/translations/ar/LC_MESSAGES/admin.po 2025-10-20 21:09:31.000000000 +0200 +++ new/flask_admin-2.0.2/flask_admin/translations/ar/LC_MESSAGES/admin.po 2025-11-11 14:07:49.000000000 +0100 @@ -4,8 +4,8 @@ "Project-Id-Version: flask-admin\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2025-09-16 00:18+0200\n" -"PO-Revision-Date: 2025-07-07 20:12-0500\n" -"Last-Translator: ElLorans <[email protected]>\n" +"PO-Revision-Date: 2025-10-31 20:12-0500\n" +"Last-Translator: Sami Alfattany <[email protected]>\n" "Language: ar_SA\n" "Language-Team: Arabic\n" "Plural-Forms: nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : " @@ -17,7 +17,7 @@ #: ../flask_admin/base.py:518 msgid "Home" -msgstr "الصفحة الرئيسية" +msgstr "الرئيسية" #: ../flask_admin/contrib/rediscli.py:118 msgid "Cli: Invalid command." @@ -25,11 +25,11 @@ #: ../flask_admin/contrib/fileadmin/__init__.py:414 msgid "File to upload" -msgstr "ملف لتحميله" +msgstr "الملف المراد رفعه" #: ../flask_admin/contrib/fileadmin/__init__.py:422 msgid "File required." -msgstr "الملف المطلوب." +msgstr "الملف مطلوب." #: ../flask_admin/contrib/fileadmin/__init__.py:427 msgid "Invalid file type." @@ -37,7 +37,7 @@ #: ../flask_admin/contrib/fileadmin/__init__.py:440 msgid "Content" -msgstr "محتوى السكريبت" +msgstr "المحتوى" #: ../flask_admin/contrib/fileadmin/__init__.py:457 msgid "Invalid name" @@ -51,7 +51,7 @@ #: ../flask_admin/contrib/fileadmin/__init__.py:838 #, python-format msgid "File \"%(name)s\" already exists." -msgstr "ملف \"%(name)s\" موجود بالفعل." +msgstr "الملف \"%(name)s\" موجود بالفعل." #: ../flask_admin/contrib/fileadmin/__init__.py:885 #: ../flask_admin/contrib/fileadmin/__init__.py:994 @@ -65,12 +65,12 @@ #: ../flask_admin/contrib/fileadmin/__init__.py:990 msgid "File uploading is disabled." -msgstr "تحميل الملف معطل." +msgstr "خاصية رفع الملفات معطلة." #: ../flask_admin/contrib/fileadmin/__init__.py:1003 #, python-format msgid "Successfully saved file: %(name)s" -msgstr "ملف تم حفظه بنجاح: %(name)s" +msgstr "تم حفظ الملف بنجاح: %(name)s" #: ../flask_admin/contrib/fileadmin/__init__.py:1012 #, python-format @@ -81,27 +81,27 @@ #: ../flask_admin/templates/bootstrap4/admin/file/list.html:154 #: ../flask_admin/templates/bootstrap4/admin/file/list.html:156 msgid "Upload File" -msgstr "تحميل الملف" +msgstr "رفع الملف" #: ../flask_admin/contrib/fileadmin/__init__.py:1066 msgid "Directory creation is disabled." -msgstr "يتم تعطيل إنشاء الدليل." +msgstr "تم تعطيل إنشاء المجلد." #: ../flask_admin/contrib/fileadmin/__init__.py:1087 #, python-format msgid "Successfully created directory: %(directory)s" -msgstr "الدليل الذي تم إنشاؤه بنجاح: %(directory)s" +msgstr "المجلد الذي تم إنشاؤه بنجاح: %(directory)s" #: ../flask_admin/contrib/fileadmin/__init__.py:1096 #, python-format msgid "Failed to create directory: %(error)s" -msgstr "فشل إنشاء الدليل: %(error)s" +msgstr "فشل إنشاء المجلد: %(error)s" #: ../flask_admin/contrib/fileadmin/__init__.py:1113 #: ../flask_admin/templates/bootstrap4/admin/file/list.html:165 #: ../flask_admin/templates/bootstrap4/admin/file/list.html:167 msgid "Create Directory" -msgstr "إنشاء دليل" +msgstr "إنشاء مجلد" #: ../flask_admin/contrib/fileadmin/__init__.py:1140 msgid "Deletion is disabled." @@ -109,17 +109,17 @@ #: ../flask_admin/contrib/fileadmin/__init__.py:1149 msgid "Directory deletion is disabled." -msgstr "يتم تعطيل حذف الدليل." +msgstr "يتم تعطيل حذف المجلد." #: ../flask_admin/contrib/fileadmin/__init__.py:1157 #, python-format msgid "Directory \"%(path)s\" was successfully deleted." -msgstr "تم بنجاح حذف الدليل \"%(path)s\"." +msgstr "تم بنجاح حذف المجلد \"%(path)s\"." #: ../flask_admin/contrib/fileadmin/__init__.py:1164 #, python-format msgid "Failed to delete directory: %(error)s" -msgstr "فشل في حذف الدليل: %(error)s" +msgstr "فشل في حذف المجلد: %(error)s" #: ../flask_admin/contrib/fileadmin/__init__.py:1175 #: ../flask_admin/contrib/fileadmin/__init__.py:1378 @@ -135,7 +135,7 @@ #: ../flask_admin/contrib/fileadmin/__init__.py:1207 msgid "Renaming is disabled." -msgstr "إعادة تسمية معطل." +msgstr "خاصية إعادة التسمية معطلة." #: ../flask_admin/contrib/fileadmin/__init__.py:1215 msgid "Path does not exist." @@ -164,12 +164,12 @@ #: ../flask_admin/contrib/fileadmin/__init__.py:1304 #, python-format msgid "Changes to %(name)s saved successfully." -msgstr "التغييرات إلى %(name)s حفظه بنجاح." +msgstr "تم حفظ التعديلات على %(name)s بنجاح." #: ../flask_admin/contrib/fileadmin/__init__.py:1314 #, python-format msgid "Error reading %(name)s." -msgstr "خطأ القراءة %(name)s." +msgstr "خطأ في قراءة %(name)s." #: ../flask_admin/contrib/fileadmin/__init__.py:1318 #: ../flask_admin/contrib/fileadmin/__init__.py:1331 @@ -197,21 +197,21 @@ #: ../flask_admin/contrib/fileadmin/__init__.py:1364 msgid "Are you sure you want to delete these files?" -msgstr "هل تريد فعلا حذف %d من الملفات؟?" +msgstr "هل تريد فعلا حذف هذه الملفات؟?" #: ../flask_admin/contrib/fileadmin/__init__.py:1368 msgid "File deletion is disabled." -msgstr "يتم تعطيل حذف الملف." +msgstr "تم تعطيل حذف الملف." #: ../flask_admin/contrib/fileadmin/__init__.py:1390 #: ../flask_admin/templates/bootstrap4/admin/model/details.html:17 #: ../flask_admin/templates/bootstrap4/admin/model/edit.html:22 msgid "Edit" -msgstr "عدل" +msgstr "تعديل" #: ../flask_admin/contrib/fileadmin/s3.py:233 msgid "Cannot operate on non empty directories" -msgstr "لا يمكن العمل على الدلائل غير الفارغة" +msgstr "لا يمكن العمل على المجلدات غير الفارغة" #: ../flask_admin/contrib/mongoengine/filters.py:41 #: ../flask_admin/contrib/peewee/filters.py:47 @@ -225,7 +225,7 @@ #: ../flask_admin/contrib/pymongo/filters.py:58 #: ../flask_admin/contrib/sqla/filters.py:72 msgid "not equal" -msgstr "لا تساوي" +msgstr "لا يساوي" #: ../flask_admin/contrib/mongoengine/filters.py:60 #: ../flask_admin/contrib/peewee/filters.py:64 @@ -239,7 +239,7 @@ #: ../flask_admin/contrib/pymongo/filters.py:78 #: ../flask_admin/contrib/sqla/filters.py:94 msgid "not contains" -msgstr "لا تحتوي علي" +msgstr "لا يحتوي علي" #: ../flask_admin/contrib/mongoengine/filters.py:79 #: ../flask_admin/contrib/peewee/filters.py:81 @@ -285,7 +285,7 @@ #: ../flask_admin/contrib/mongoengine/filters.py:248 msgid "ObjectId equals" -msgstr "معرّف الكائن يساوي" +msgstr "ObjectId يساوي" #: ../flask_admin/contrib/mongoengine/form.py:121 #: ../flask_admin/contrib/sqla/fields.py:151 @@ -339,12 +339,12 @@ #, python-format msgid "Record was successfully deleted." msgid_plural "%(count)s records were successfully deleted." -msgstr[0] "تم بنجاح حذف السجلات %(count)s." +msgstr[0] "تم حذف %(count)s سجلات بنجاح ." msgstr[1] "تم حذف السجل بنجاح." -msgstr[2] "تم بنجاح حذف السجلات %(count)s." -msgstr[3] "تم بنجاح حذف السجلات %(count)s." -msgstr[4] "تم بنجاح حذف السجلات %(count)s." -msgstr[5] "تم بنجاح حذف السجلات %(count)s." +msgstr[2] "تم حذف السجلين بنجاح." +msgstr[3] "تم حذف %(count)s سجلات بنجاح ." +msgstr[4] "تم حذف %(count)s سجلات بنجاح ." +msgstr[5] "تم حذف %(count)s سجلات بنجاح ." #: ../flask_admin/contrib/mongoengine/view.py:749 #: ../flask_admin/contrib/peewee/view.py:642 @@ -379,20 +379,20 @@ #: ../flask_admin/contrib/sqla/validators.py:98 msgid "Not a valid ISO currency code (e.g. USD, EUR, CNY)." -msgstr "ليس رمز عملة ISO صالحًا (على سبيل المثال USD، EUR، CNY)." +msgstr "رمز عملة غير صالح، استخدم رمز مطابق للـISO (مثلا: USD، EUR، CNY)." #: ../flask_admin/contrib/sqla/validators.py:109 msgid "Not a valid color (e.g. \"red\", \"#f00\", \"#ff0000\")." -msgstr "ليس لونًا صالحًا (على سبيل المثال \"red\"، \"#f00\"، \"#ff0000\")." +msgstr "ليس لونًا صالحًا (مثلا \"red\"، \"#f00\"، \"#ff0000\")." #: ../flask_admin/contrib/sqla/view.py:1317 #, python-format msgid "Integrity error. %(message)s" -msgstr "خطأ سلامة. %(message)s" +msgstr "خطأ في توافق البيانات. %(message)s" #: ../flask_admin/form/fields.py:131 msgid "Invalid time format" -msgstr "تنسيق الوقت غير صالح" +msgstr "صيغة الوقت غير صالح" #: ../flask_admin/form/fields.py:202 msgid "Invalid Choice: could not coerce" @@ -400,11 +400,11 @@ #: ../flask_admin/form/fields.py:291 msgid "Invalid JSON" -msgstr "JSON غير صالح" +msgstr "صيغة JSON غير صالحة" #: ../flask_admin/form/upload.py:241 msgid "Invalid file extension" -msgstr "ملحق الملف غير صالح" +msgstr "امتداد الملف غير صالح" #: ../flask_admin/form/validators.py:18 msgid "This field requires at least one item." @@ -476,7 +476,7 @@ #: ../flask_admin/templates/bootstrap4/admin/lib.html:216 #: ../flask_admin/templates/bootstrap4/admin/lib.html:227 msgid "Save" -msgstr "احفظ" +msgstr "حفظ" #: ../flask_admin/templates/bootstrap4/admin/lib.html:221 #: ../flask_admin/templates/bootstrap4/admin/lib.html:232 @@ -545,7 +545,7 @@ #: ../flask_admin/templates/bootstrap4/admin/model/details.html:28 #: ../flask_admin/templates/bootstrap4/admin/model/modals/details.html:15 msgid "Filter" -msgstr "الذهاب »" +msgstr "بحث" #: ../flask_admin/templates/bootstrap4/admin/model/inline_list_base.html:14 msgid "Delete?" @@ -567,13 +567,13 @@ #: ../flask_admin/templates/bootstrap4/admin/model/layout.html:2 msgid "Add Filter" -msgstr "إضافة عامل تصفية" +msgstr "إضافة تصفية" #: ../flask_admin/templates/bootstrap4/admin/model/layout.html:14 #: ../flask_admin/templates/bootstrap4/admin/model/layout.html:19 #: ../flask_admin/templates/bootstrap4/admin/model/layout.html:26 msgid "Export" -msgstr "يصدّر" +msgstr "تصدير" #: ../flask_admin/templates/bootstrap4/admin/model/layout.html:49 msgid "Apply" @@ -581,7 +581,7 @@ #: ../flask_admin/templates/bootstrap4/admin/model/layout.html:51 msgid "Reset Filters" -msgstr "إعادة تعيين عوامل تصفية" +msgstr "حذف التصفية" #: ../flask_admin/templates/bootstrap4/admin/model/layout.html:80 #: ../flask_admin/templates/bootstrap4/admin/model/layout.html:93 @@ -592,17 +592,17 @@ #: ../flask_admin/templates/bootstrap4/admin/model/layout.html:88 #: ../flask_admin/templates/bootstrap4/admin/model/layout.html:94 msgid "Search" -msgstr "البحث" +msgstr "بحث" #: ../flask_admin/templates/bootstrap4/admin/model/layout.html:102 msgid "items" -msgstr "أغراض" +msgstr "عناصر" #: ../flask_admin/templates/bootstrap4/admin/model/list.html:23 #: ../flask_admin/templates/bootstrap4/admin/model/list.html:25 #: ../flask_admin/templates/bootstrap4/admin/model/modals/create.html:10 msgid "Create New Record" -msgstr "قم بإنشاء سجل جديد" +msgstr "إنشاء سجل جديد" #: ../flask_admin/templates/bootstrap4/admin/model/list.html:76 msgid "Select all records" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/flask_admin-2.0.0/pyproject.toml new/flask_admin-2.0.2/pyproject.toml --- old/flask_admin-2.0.0/pyproject.toml 2025-10-20 21:09:31.000000000 +0200 +++ new/flask_admin-2.0.2/pyproject.toml 2025-11-11 14:07:49.000000000 +0100 @@ -1,6 +1,6 @@ [project] name = "Flask-Admin" -version = "2.0.0" +version = "2.0.2" description = "Simple and extensible admin interface framework for Flask" readme = "README.md" license = { file = "LICENSE.txt" } @@ -18,6 +18,7 @@ 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12', 'Programming Language :: Python :: 3.13', + 'Programming Language :: Python :: 3.14', ] requires-python = ">=3.10" dependencies = [ @@ -164,8 +165,11 @@ # `flask.testing` accesses this attribute; remove when they have updated their code. "default:The '__version__' attribute is deprecated and will be removed in Werkzeug 3\\.1\\.:DeprecationWarning", - # raised by flask-sqlalchemy https://github.com/pallets-eco/flask-sqlalchemy/issues/137 + # raised by flask-sqlalchemy https://github.com/pallets-eco/flask-sqlalchemy/issues/1379 "ignore:Exception ignored in.*sqlite3.Connection:pytest.PytestUnraisableExceptionWarning", + + # raised by flask-sqlalchemy https://github.com/pallets-eco/flask-sqlalchemy/issues/1379 + "ignore:unclosed database in <sqlite3\\.Connection object at 0x[0-9a-f]+>:ResourceWarning", ] [tool.coverage.run] @@ -262,9 +266,9 @@ [tool.tox] env_list = [ - "py310", "py311", "py312", "py313", - "py310-sqlalchemy1", "py313-sqlalchemy1", - "py313-noflaskbabel", + "py310", "py311", "py312", "py313", "py314", + "py310-sqlalchemy1", "py314-sqlalchemy1", + "py314-noflaskbabel", "py310-min", "style", "typing", @@ -338,10 +342,10 @@ ], ] -[tool.tox.env.py313-sqlalchemy1] -description = "pytest with SQLAlchemy 1.x on Python 3.13" +[tool.tox.env.py314-sqlalchemy1] +description = "pytest with SQLAlchemy 1.x on Python 3.14" base = ["env_run_base"] -base_python = ["3.13"] +base_python = ["3.14"] commands = [ ["uv", "pip", "install", "sqlalchemy>=1.4,<2"], ["uv", "pip", "install", "flask-sqlalchemy<=3.0.5"], @@ -351,7 +355,7 @@ ], ] -[tool.tox.env.py313-noflaskbabel] +[tool.tox.env.py314-noflaskbabel] description = "pytest without flask-babel" base = ["env_run_base"] commands = [ @@ -374,8 +378,8 @@ dependency_groups = ["typing"] commands = [ ["mypy", "--python-version", "3.10"], - ["mypy", "--python-version", "3.13"], - ["mypy", "--python-version", "3.13", + ["mypy", "--python-version", "3.14"], + ["mypy", "--python-version", "3.14", "--ignore-missing-imports", "--disable-error-code", "name-defined", # allow flask_sqlalchemy's db.Model in examples "--no-warn-unused-ignores", # prevent conflict with mypy 1st run on src folder
