From b4eb707af0f668b2aefee91fad3e9066bceeeefc Mon Sep 17 00:00:00 2001 From: Carsten Schoenert <c.schoenert@t-online.de> Date: Thu, 19 Dec 2024 16:16:41 +0200 Subject: [PATCH] New upstream version 1.2.2 --- .github/workflows/lock.yaml | 2 +- .github/workflows/pre-commit.yaml | 16 ++++ .github/workflows/publish.yaml | 73 +++++++++++++++ .github/workflows/tests.yaml | 38 ++++---- .gitignore | 1 + .pre-commit-config.yaml | 36 ++------ .readthedocs.yaml | 8 +- CONTRIBUTING.rst | 4 +- README.rst | 4 +- docs/changes.rst | 8 ++ docs/conf.py | 8 +- docs/config.rst | 3 + docs/csrf.rst | 7 ++ docs/form.rst | 2 +- docs/install.rst | 8 +- examples/recaptcha/app.py | 1 - pyproject.toml | 50 +++++----- requirements/dev.txt | 138 +++++++--------------------- requirements/docs.txt | 57 ++++++------ requirements/style.txt | 22 ++--- requirements/tests.txt | 16 +--- src/flask_wtf/__init__.py | 10 +- src/flask_wtf/file.py | 5 +- src/flask_wtf/recaptcha/__init__.py | 2 + tests/test_file.py | 26 +++--- tox.ini | 2 +- 26 files changed, 273 insertions(+), 274 deletions(-) create mode 100644 .github/workflows/pre-commit.yaml create mode 100644 .github/workflows/publish.yaml diff --git a/.github/workflows/lock.yaml b/.github/workflows/lock.yaml index c771673..9ea3038 100644 --- a/.github/workflows/lock.yaml +++ b/.github/workflows/lock.yaml @@ -8,7 +8,7 @@ jobs: lock: runs-on: ubuntu-latest steps: - - uses: dessant/lock-threads@v4 + - uses: dessant/lock-threads@v5 with: github-token: ${{ github.token }} issue-inactive-days: 14 diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml new file mode 100644 index 0000000..683c85b --- /dev/null +++ b/.github/workflows/pre-commit.yaml @@ -0,0 +1,16 @@ +name: pre-commit +on: + pull_request: + push: + branches: [main, '*.x'] +jobs: + main: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + with: + python-version: 3.x + - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1 + - uses: pre-commit-ci/lite-action@9d882e7a565f7008d4faf128f27d1cb6503d4ebf # v1.0.2 + if: ${{ !cancelled() }} diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml new file mode 100644 index 0000000..41e0810 --- /dev/null +++ b/.github/workflows/publish.yaml @@ -0,0 +1,73 @@ +name: Publish +on: + push: + tags: + - '*' +jobs: + build: + runs-on: ubuntu-latest + outputs: + hash: ${{ steps.hash.outputs.hash }} + steps: + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 + with: + python-version: '3.x' + cache: pip + - run: pip install -e . + - run: pip install build + # Use the commit date instead of the current date during the build. + - run: echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> $GITHUB_ENV + - run: python -m build + # Generate hashes used for provenance. + - name: generate hash + id: hash + run: cd dist && echo "hash=$(sha256sum * | base64 -w0)" >> $GITHUB_OUTPUT + - uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 + with: + path: ./dist + provenance: + needs: [build] + permissions: + actions: read + id-token: write + contents: write + # Can't pin with hash due to how this workflow works. + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0 + with: + base64-subjects: ${{ needs.build.outputs.hash }} + create-release: + # Upload the sdist, wheels, and provenance to a GitHub release. They remain + # available as build artifacts for a while as well. + needs: [provenance] + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 + - name: create release + run: > + gh release create --draft --repo ${{ github.repository }} + ${{ github.ref_name }} + *.intoto.jsonl/* artifact/* + env: + GH_TOKEN: ${{ github.token }} + publish-pypi: + needs: [provenance] + # Wait for approval before attempting to upload to PyPI. This allows reviewing the + # files in the draft release. + environment: + name: publish + url: https://pypi.org/project/flask-wtf/${{ github.ref_name }} + runs-on: ubuntu-latest + permissions: + id-token: write + steps: + - uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 + - uses: pypa/gh-action-pypi-publish@ec4db0b4ddc65acdf4bff5fa45ac92d78b56bdf0 # v1.9.0 + with: + repository-url: https://test.pypi.org/legacy/ + packages-dir: artifact/ + - uses: pypa/gh-action-pypi-publish@ec4db0b4ddc65acdf4bff5fa45ac92d78b56bdf0 # v1.9.0 + with: + packages-dir: artifact/ diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index b37e564..b1f9216 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -4,38 +4,34 @@ on: branches: - main - '*.x' + paths-ignore: + - 'docs/**' + - '*.md' + - '*.rst' pull_request: - branches: - - main - - '*.x' paths-ignore: - 'docs/**' + - '*.md' - '*.rst' jobs: tests: - name: ${{ matrix.name }} - runs-on: ubuntu-latest + name: ${{ matrix.name || matrix.python }} + runs-on: ${{ matrix.os || 'ubuntu-latest' }} strategy: fail-fast: false matrix: include: - - {name: '3.11', python: '3.11', tox: 'py311,py-no-babel'} - - {name: '3.10', python: '3.10', tox: py310} - - {name: '3.9', python: '3.9', tox: py39} - - {name: '3.8', python: '3.8', tox: py38} - - {name: 'PyPy310', python: 'pypy-3.10', tox: pypy310} - - {name: 'PyPy39', python: 'pypy-3.9', tox: pypy39} + - {python: '3.13'} + - {python: '3.12'} + - {python: '3.11'} + - {python: '3.10'} + - {python: '3.9'} steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 with: python-version: ${{ matrix.python }} - cache: 'pip' - cache-dependency-path: 'requirements/*.txt' - - name: update pip - run: | - pip install -U wheel - pip install -U setuptools - python -m pip install -U pip + allow-prereleases: true + cache: pip - run: pip install tox - - run: tox -e ${{ matrix.tox }} + - run: tox run -e ${{ matrix.tox || format('py{0}', matrix.python) }} diff --git a/.gitignore b/.gitignore index 00d8dd2..9ba3a8a 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ __pycache__/ /docs/_build/ .coverage .coverage.* +/htmlcov/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5574264..856b490 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,36 +1,14 @@ -ci: - autoupdate_schedule: monthly repos: - - repo: https://github.com/asottile/pyupgrade - rev: v3.10.1 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.7.0 hooks: - - id: pyupgrade - args: ["--py37-plus"] - - repo: https://github.com/asottile/reorder-python-imports - rev: v3.10.0 - hooks: - - id: reorder-python-imports - args: ["--application-directories", "src"] - additional_dependencies: ["setuptools>60.9"] - - repo: https://github.com/psf/black - rev: 23.7.0 - hooks: - - id: black - - repo: https://github.com/PyCQA/flake8 - rev: 6.1.0 - hooks: - - id: flake8 - additional_dependencies: - - flake8-bugbear - - flake8-implicit-str-concat - - flake8-pyproject - - repo: https://github.com/peterdemin/pip-compile-multi - rev: v2.6.3 - hooks: - - id: pip-compile-multi-verify + - id: ruff + - id: ruff-format - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v5.0.0 hooks: + - id: check-merge-conflict + - id: debug-statements - id: fix-byte-order-marker - id: trailing-whitespace - id: end-of-file-fixer diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 44df8af..865c685 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -1,4 +1,8 @@ version: 2 +build: + os: ubuntu-22.04 + tools: + python: '3.12' python: install: - requirements: requirements/docs.txt @@ -7,7 +11,3 @@ python: sphinx: builder: dirhtml fail_on_warning: true -build: - os: "ubuntu-22.04" - tools: - python: "3.11" diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 41523a3..b93ddcb 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -83,7 +83,7 @@ First time setup .. code-block:: text - $ git clone https://github.com/wtforms/flask-wtf + $ git clone https://github.com/pallets-eco/flask-wtf $ cd flask-wtf - Add your fork as a remote to push your work to. Replace @@ -130,7 +130,7 @@ First time setup .. _username: https://docs.github.com/en/github/using-git/setting-your-username-in-git .. _email: https://docs.github.com/en/github/setting-up-and-managing-your-github-user-account/setting-your-commit-email-address .. _GitHub account: https://github.com/join -.. _Fork: https://github.com/wtforms/flask-wtf/fork +.. _Fork: https://github.com/pallets-eco/flask-wtf/fork .. _Clone: https://docs.github.com/en/github/getting-started-with-github/fork-a-repo#step-2-create-a-local-clone-of-your-fork diff --git a/README.rst b/README.rst index 5f69eb4..fbbd923 100644 --- a/README.rst +++ b/README.rst @@ -10,6 +10,6 @@ Links - Documentation: https://flask-wtf.readthedocs.io/ - Changes: https://flask-wtf.readthedocs.io/changes/ - PyPI Releases: https://pypi.org/project/Flask-WTF/ -- Source Code: https://github.com/wtforms/flask-wtf/ -- Issue Tracker: https://github.com/wtforms/flask-wtf/issues/ +- Source Code: https://github.com/pallets-eco/flask-wtf/ +- Issue Tracker: https://github.com/pallets-eco/flask-wtf/issues/ - Chat: https://discord.gg/pallets diff --git a/docs/changes.rst b/docs/changes.rst index db77082..16d5c0a 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -1,6 +1,14 @@ Changes ======= +Version 1.2.2 +------------- + +Released 2024-10-20 + +- Move the project to the pallets-eco organization. :pr:`602` +- Stop support for Python 3.8. Start support for Python 3.13. :pr:`603` + Version 1.2.1 ------------- diff --git a/docs/conf.py b/docs/conf.py index bd37efa..51e97a5 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -23,7 +23,7 @@ intersphinx_mapping = { "flask": ("https://flask.palletsprojects.com/", None), "wtforms": ("https://wtforms.readthedocs.io/", None), } -issues_github_path = "wtforms/flask-wtf" +issues_github_path = "pallets-eco/flask-wtf" # HTML ----------------------------------------------------------------- @@ -32,8 +32,10 @@ html_theme_options = {"index_sidebar_logo": False} html_context = { "project_links": [ ProjectLink("PyPI Releases", "https://pypi.org/project/Flask-WTF/"), - ProjectLink("Source Code", "https://github.com/wtforms/flask-wtf/"), - ProjectLink("Issue Tracker", "https://github.com/wtforms/flask-wtf/issues/"), + ProjectLink("Source Code", "https://github.com/pallets-eco/flask-wtf/"), + ProjectLink( + "Issue Tracker", "https://github.com/pallets-eco/flask-wtf/issues/" + ), ProjectLink("Chat", "https://discord.gg/pallets"), ] } diff --git a/docs/config.rst b/docs/config.rst index b4decae..fba26c9 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -19,6 +19,9 @@ Configuration ``WTF_CSRF_TIME_LIMIT`` Max age in seconds for CSRF tokens. Default is ``3600``. If set to ``None``, the CSRF token is valid for the life of the session. + If your webserver has a cache policy, make sure it is + configured with at maximum this value, so user browsers + won't display pages with expired CSRF tokens. ``WTF_CSRF_SSL_STRICT`` Whether to enforce the same origin policy by checking that the referrer matches the host. Only applies to HTTPS requests. Default is ``True``. diff --git a/docs/csrf.rst b/docs/csrf.rst index d9a8ff6..b8d0fa1 100644 --- a/docs/csrf.rst +++ b/docs/csrf.rst @@ -34,6 +34,13 @@ Like other Flask extensions, you can apply it lazily:: this will use the Flask app's ``SECRET_KEY``. If you'd like to use a separate token you can set ``WTF_CSRF_SECRET_KEY``. +.. warning:: + + Make sure your webserver cache policy wont't interfere with the CSRF protection. + If pages are cached longer than the ``WTF_CSRF_TIME_LIMIT`` value, then user browsers + may serve cached page including expired CSRF token, resulting in random *Invalid* + or *Expired* CSRF errors. + HTML Forms ---------- diff --git a/docs/form.rst b/docs/form.rst index b7edfe1..9a6dfac 100644 --- a/docs/form.rst +++ b/docs/form.rst @@ -182,4 +182,4 @@ And it can be easily setup in the templates: We have an example for you: `recaptcha@github`_. -.. _`recaptcha@github`: https://github.com/wtforms/flask-wtf/tree/main/examples/recaptcha +.. _`recaptcha@github`: https://github.com/pallets-eco/flask-wtf/tree/main/examples/recaptcha diff --git a/docs/install.rst b/docs/install.rst index 40fdaf5..f2c547d 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -19,12 +19,12 @@ Development The latest code is available from `GitHub`_. Clone the repository then install using pip. :: - git clone https://github.com/wtforms/flask-wtf + git clone https://github.com/pallets-eco/flask-wtf pip install -e ./flask-wtf Or install the latest build from an `archive`_. :: - pip install -U https://github.com/wtforms/flask-wtf/archive/main.tar.gz + pip install -U https://github.com/pallets-eco/flask-wtf/archive/main.tar.gz -.. _GitHub: https://github.com/wtforms/flask-wtf -.. _archive: https://github.com/wtforms/flask-wtf/archive/main.tar.gz +.. _GitHub: https://github.com/pallets-eco/flask-wtf +.. _archive: https://github.com/pallets-eco/flask-wtf/archive/main.tar.gz diff --git a/examples/recaptcha/app.py b/examples/recaptcha/app.py index 150cc51..fa34d87 100644 --- a/examples/recaptcha/app.py +++ b/examples/recaptcha/app.py @@ -10,7 +10,6 @@ from wtforms.validators import DataRequired from flask_wtf import FlaskForm from flask_wtf.recaptcha import RecaptchaField - DEBUG = True SECRET_KEY = "secret" diff --git a/pyproject.toml b/pyproject.toml index ba5d915..154a6ef 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,7 +16,7 @@ classifiers = [ "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", "Topic :: Software Development :: Libraries :: Application Frameworks", ] -requires-python = ">=3.8" +requires-python = ">=3.9" dependencies = [ "Flask", "WTForms", @@ -27,8 +27,8 @@ dynamic = ["version"] [project.urls] Documentation = "https://flask-wtf.readthedocs.io/" Changes = "https://flask-wtf.readthedocs.io/changes/" -"Source Code" = "https://github.com/wtforms/flask-wtf/" -"Issue Tracker" = "https://github.com/wtforms/flask-wtf/issues/" +"Source Code" = "https://github.com/pallets-eco/flask-wtf/" +"Issue Tracker" = "https://github.com/pallets-eco/flask-wtf/issues/" Chat = "https://discord.gg/pallets" [project.optional-dependencies] @@ -75,30 +75,22 @@ exclude_lines = [ "except ImportError:", ] -[tool.flake8] -# B = bugbear -# E = pycodestyle errors -# F = flake8 pyflakes -# W = pycodestyle warnings -# B9 = bugbear opinions -# ISC = implicit-str-concat -select = ["B", "E", "F", "W", "B9", "ISC"] -ignore = [ - # slice notation whitespace, invalid - "E203", - # line length, handled by bugbear B950 - "E501", - # bare except, handled by bugbear B001 - "E722", - # bin op line break, invalid - "W503", - # requires 'strict' argument for 'zip' - # that needs python >= 3.10 - "B905", -] -# up to 88 allowed by bugbear B950 -max-line-length = 80 -per-file-ignores = [ - # __init__ modules export names - "**/__init__.py: F401, F403", +[tool.ruff] +src = ["src"] +fix = true +show-fixes = true +output-format = "full" + +[tool.ruff.lint] +select = [ + "B", # flake8-bugbear + "E", # pycodestyle error + "F", # pyflakes + "I", # isort + "UP", # pyupgrade + "W", # pycodestyle warning ] + +[tool.ruff.lint.isort] +force-single-line = true +order-by-type = false diff --git a/requirements/dev.txt b/requirements/dev.txt index 3be5b3c..4ea15a4 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -5,129 +5,59 @@ # # pip-compile-multi # -alabaster==0.7.12 - # via sphinx -attrs==21.4.0 - # via pytest -babel==2.9.1 - # via sphinx -certifi==2023.7.22 - # via requests -cfgv==3.3.1 +-r docs.txt +-r tests.txt +build==1.2.2.post1 + # via pip-tools +cachetools==5.5.0 + # via tox +cfgv==3.4.0 # via pre-commit -charset-normalizer==2.0.12 - # via requests -click==8.1.1 +chardet==5.2.0 + # via tox +click==8.1.7 # via # pip-compile-multi # pip-tools -distlib==0.3.4 +colorama==0.4.6 + # via tox +distlib==0.3.9 # via virtualenv -docutils==0.17.1 - # via sphinx -filelock==3.6.0 +filelock==3.16.1 # via # tox # virtualenv -identify==2.4.12 +identify==2.6.1 # via pre-commit -idna==3.3 - # via requests -imagesize==1.3.0 - # via sphinx -iniconfig==1.1.1 - # via pytest -jinja2==3.1.1 - # via sphinx -markupsafe==2.1.1 - # via jinja2 -nodeenv==1.6.0 +nodeenv==1.9.1 # via pre-commit -packaging==21.3 - # via - # pallets-sphinx-themes - # pytest - # sphinx - # tox -pallets-sphinx-themes==2.0.2 - # via -r docs.in -pep517==0.12.0 - # via pip-tools -pip-compile-multi==2.4.4 - # via -r dev.in -pip-tools==6.5.1 +pip-compile-multi==2.6.4 + # via -r requirements/dev.in +pip-tools==7.4.1 # via pip-compile-multi -platformdirs==2.5.1 - # via virtualenv -pluggy==1.0.0 - # via - # pytest - # tox -pre-commit==2.17.0 - # via -r dev.in -py==1.11.0 - # via - # pytest - # tox -pygments==2.15.0 - # via sphinx -pyparsing==3.0.7 - # via packaging -pytest==7.1.1 - # via -r tests.in -pytz==2022.1 - # via babel -pyyaml==6.0 - # via pre-commit -requests==2.31.0 - # via sphinx -six==1.16.0 +platformdirs==4.3.6 # via # tox # virtualenv -snowballstemmer==2.2.0 - # via sphinx -sphinx==4.5.0 - # via - # -r docs.in - # pallets-sphinx-themes - # sphinx-issues - # sphinxcontrib-log-cabinet -sphinx-issues==3.0.1 - # via -r docs.in -sphinxcontrib-applehelp==1.0.2 - # via sphinx -sphinxcontrib-devhelp==1.0.2 - # via sphinx -sphinxcontrib-htmlhelp==2.0.0 - # via sphinx -sphinxcontrib-jsmath==1.0.1 - # via sphinx -sphinxcontrib-log-cabinet==1.0.1 - # via -r docs.in -sphinxcontrib-qthelp==1.0.3 - # via sphinx -sphinxcontrib-serializinghtml==1.1.5 - # via sphinx -toml==0.10.2 - # via - # pre-commit - # tox -tomli==2.0.1 +pre-commit==4.0.1 + # via -r requirements/dev.in +pyproject-api==1.8.0 + # via tox +pyproject-hooks==1.2.0 # via - # pep517 - # pytest -toposort==1.7 + # build + # pip-tools +pyyaml==6.0.2 + # via pre-commit +toposort==1.10 # via pip-compile-multi -tox==3.24.5 - # via -r dev.in -urllib3==1.26.9 - # via requests -virtualenv==20.14.0 +tox==4.23.0 + # via -r requirements/dev.in +virtualenv==20.27.0 # via # pre-commit # tox -wheel==0.38.1 +wheel==0.44.0 # via pip-tools # The following packages are considered to be unsafe in a requirements file: diff --git a/requirements/docs.txt b/requirements/docs.txt index 1900670..edfe85d 100644 --- a/requirements/docs.txt +++ b/requirements/docs.txt @@ -5,61 +5,60 @@ # # pip-compile-multi # -alabaster==0.7.12 +alabaster==1.0.0 # via sphinx -babel==2.9.1 +babel==2.16.0 # via sphinx -certifi==2023.7.22 +certifi==2024.8.30 # via requests -charset-normalizer==2.0.12 +charset-normalizer==3.4.0 # via requests -docutils==0.17.1 +docutils==0.21.2 # via sphinx -idna==3.3 +idna==3.10 # via requests -imagesize==1.3.0 +imagesize==1.4.1 # via sphinx -jinja2==3.1.1 +jinja2==3.1.4 # via sphinx -markupsafe==2.1.1 +markupsafe==3.0.1 # via jinja2 -packaging==21.3 +packaging==24.1 # via # pallets-sphinx-themes # sphinx -pallets-sphinx-themes==2.0.2 - # via -r docs.in -pygments==2.15.0 +pallets-sphinx-themes==2.2.0 + # via -r requirements/docs.in +pygments==2.18.0 # via sphinx -pyparsing==3.0.7 - # via packaging -pytz==2022.1 - # via babel -requests==2.31.0 +requests==2.32.3 # via sphinx snowballstemmer==2.2.0 # via sphinx -sphinx==4.5.0 +sphinx==8.1.3 # via - # -r docs.in + # -r requirements/docs.in # pallets-sphinx-themes # sphinx-issues + # sphinx-notfound-page # sphinxcontrib-log-cabinet -sphinx-issues==3.0.1 - # via -r docs.in -sphinxcontrib-applehelp==1.0.2 +sphinx-issues==5.0.0 + # via -r requirements/docs.in +sphinx-notfound-page==1.0.4 + # via pallets-sphinx-themes +sphinxcontrib-applehelp==2.0.0 # via sphinx -sphinxcontrib-devhelp==1.0.2 +sphinxcontrib-devhelp==2.0.0 # via sphinx -sphinxcontrib-htmlhelp==2.0.0 +sphinxcontrib-htmlhelp==2.1.0 # via sphinx sphinxcontrib-jsmath==1.0.1 # via sphinx sphinxcontrib-log-cabinet==1.0.1 - # via -r docs.in -sphinxcontrib-qthelp==1.0.3 + # via -r requirements/docs.in +sphinxcontrib-qthelp==2.0.0 # via sphinx -sphinxcontrib-serializinghtml==1.1.5 +sphinxcontrib-serializinghtml==2.0.0 # via sphinx -urllib3==1.26.9 +urllib3==2.2.3 # via requests diff --git a/requirements/style.txt b/requirements/style.txt index 428dbe1..d23aa80 100644 --- a/requirements/style.txt +++ b/requirements/style.txt @@ -5,25 +5,21 @@ # # pip-compile-multi # -cfgv==3.3.1 +cfgv==3.4.0 # via pre-commit -distlib==0.3.4 +distlib==0.3.9 # via virtualenv -filelock==3.6.0 +filelock==3.16.1 # via virtualenv -identify==2.4.12 +identify==2.6.1 # via pre-commit -nodeenv==1.6.0 +nodeenv==1.9.1 # via pre-commit -platformdirs==2.5.1 +platformdirs==4.3.6 # via virtualenv -pre-commit==2.17.0 +pre-commit==4.0.1 # via -r requirements/style.in -pyyaml==6.0 +pyyaml==6.0.2 # via pre-commit -six==1.16.0 - # via virtualenv -toml==0.10.2 - # via pre-commit -virtualenv==20.14.0 +virtualenv==20.27.0 # via pre-commit diff --git a/requirements/tests.txt b/requirements/tests.txt index ad11afe..ddec200 100644 --- a/requirements/tests.txt +++ b/requirements/tests.txt @@ -5,19 +5,11 @@ # # pip-compile-multi # -attrs==21.4.0 +iniconfig==2.0.0 # via pytest -iniconfig==1.1.1 +packaging==24.1 # via pytest -packaging==21.3 +pluggy==1.5.0 # via pytest -pluggy==1.0.0 - # via pytest -py==1.11.0 - # via pytest -pyparsing==3.0.7 - # via packaging -pytest==7.1.1 +pytest==8.3.3 # via -r requirements/tests.in -tomli==2.0.1 - # via pytest diff --git a/src/flask_wtf/__init__.py b/src/flask_wtf/__init__.py index be2649e..c152a76 100644 --- a/src/flask_wtf/__init__.py +++ b/src/flask_wtf/__init__.py @@ -5,4 +5,12 @@ from .recaptcha import Recaptcha from .recaptcha import RecaptchaField from .recaptcha import RecaptchaWidget -__version__ = "1.2.1" +__version__ = "1.2.2" +__all__ = [ + "CSRFProtect", + "FlaskForm", + "Form", + "Recaptcha", + "RecaptchaField", + "RecaptchaWidget", +] diff --git a/src/flask_wtf/file.py b/src/flask_wtf/file.py index a720dff..98c4577 100644 --- a/src/flask_wtf/file.py +++ b/src/flask_wtf/file.py @@ -137,9 +137,8 @@ class FileSize: raise ValidationError( self.message or field.gettext( - "File must be between {min_size} and {max_size} bytes.".format( - min_size=self.min_size, max_size=self.max_size - ) + f"File must be between {self.min_size}" + f" and {self.max_size} bytes." ) ) diff --git a/src/flask_wtf/recaptcha/__init__.py b/src/flask_wtf/recaptcha/__init__.py index 3100d37..c414a9f 100644 --- a/src/flask_wtf/recaptcha/__init__.py +++ b/src/flask_wtf/recaptcha/__init__.py @@ -1,3 +1,5 @@ from .fields import RecaptchaField from .validators import Recaptcha from .widgets import RecaptchaWidget + +__all__ = ["RecaptchaField", "RecaptchaWidget", "Recaptcha"] diff --git a/tests/test_file.py b/tests/test_file.py index 66d261b..87654d4 100644 --- a/tests/test_file.py +++ b/tests/test_file.py @@ -67,7 +67,8 @@ def test_file_allowed(form): def test_file_allowed_uploadset(app, form): pytest.importorskip("flask_uploads") - from flask_uploads import UploadSet, configure_uploads + from flask_uploads import configure_uploads + from flask_uploads import UploadSet app.config["UPLOADS_DEFAULT_DEST"] = "uploads" txt = UploadSet("txt", extensions=("txt",)) @@ -114,10 +115,8 @@ def test_file_size_invalid_file_size_fails_validation( with path.open("rb") as file: f = form(file=FileStorage(file)) assert not f.validate() - assert f.file.errors[ - 0 - ] == "File must be between {min_size} and {max_size} bytes.".format( - min_size=min_size, max_size=max_size + assert ( + f.file.errors[0] == f"File must be between {min_size} and {max_size} bytes." ) @@ -190,7 +189,8 @@ def test_files_allowed(form): def test_files_allowed_uploadset(app, form): pytest.importorskip("flask_uploads") - from flask_uploads import UploadSet, configure_uploads + from flask_uploads import configure_uploads + from flask_uploads import UploadSet app.config["UPLOADS_DEFAULT_DEST"] = "uploads" txt = UploadSet("txt", extensions=("txt",)) @@ -245,10 +245,9 @@ def test_file_size_invalid_file_sizes_fails_validation( with path.open("rb") as file: f = form(files=[FileStorage(file)]) assert not f.validate() - assert f.files.errors[ - 0 - ] == "File must be between {min_size} and {max_size} bytes.".format( - min_size=min_size, max_size=max_size + assert ( + f.files.errors[0] + == f"File must be between {min_size} and {max_size} bytes." ) @@ -257,10 +256,9 @@ def test_files_length(form, min_num=2, max_num=3): f = form(files=[FileStorage("1")]) assert not f.validate() - assert f.files.errors[ - 0 - ] == "Field must be between {min_num} and {max_num} characters long.".format( - min_num=min_num, max_num=max_num + assert ( + f.files.errors[0] + == f"Field must be between {min_num} and {max_num} characters long." ) f = form( diff --git a/tox.ini b/tox.ini index 019c548..a04654e 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - py3{11,10,9,8},pypy3{10,9} + py3{13,12,11,10,9},pypy3{10,9} py-{no-babel} style docs -- GitLab