From 6d6d986fc502c2c24fe3db0ec0dbb062d053e068 Mon Sep 17 00:00:00 2001 From: David Lord Date: Wed, 18 Jan 2023 09:50:41 -0800 Subject: [PATCH 1/3] switch to pyproject.toml --- .flake8 | 26 ++++++++ .github/workflows/tests.yaml | 2 +- CHANGES.rst | 2 + pyproject.toml | 94 ++++++++++++++++++++++++++ setup.cfg | 123 ----------------------------------- setup.py | 17 ----- 6 files changed, 123 insertions(+), 141 deletions(-) create mode 100644 .flake8 create mode 100644 pyproject.toml delete mode 100644 setup.cfg delete mode 100644 setup.py diff --git a/.flake8 b/.flake8 new file mode 100644 index 00000000..09809616 --- /dev/null +++ b/.flake8 @@ -0,0 +1,26 @@ +[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 + # import at top, too many circular import fixes + E402 + # line length, handled by bugbear B950 + E501 + # bare except, handled by bugbear B001 + E722 + # bin op line break, invalid + W503 + # requires Python 3.10 + B905 +# up to 88 allowed by bugbear B950 +max-line-length = 80 +per-file-ignores = + # __init__ exports names + src/flask/__init__.py: F401 diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 89e548db..a00c5355 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -52,7 +52,7 @@ jobs: uses: actions/cache@v3.2.2 with: path: ./.mypy_cache - key: mypy|${{ matrix.python }}|${{ hashFiles('setup.cfg') }} + key: mypy|${{ matrix.python }}|${{ hashFiles('pyproject.toml') }} if: matrix.tox == 'typing' - run: pip install tox - run: tox run -e ${{ matrix.tox }} diff --git a/CHANGES.rst b/CHANGES.rst index bcec74a7..94c16a34 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -3,6 +3,8 @@ Version 2.3.0 Unreleased +- Use modern packaging metadata with ``pyproject.toml`` instead of ``setup.cfg``. + :pr:`4947` - Ensure subdomains are applied with nested blueprints. :issue:`4834` diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..95a6e100 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,94 @@ +[project] +name = "Flask" +description = "A simple framework for building complex web applications." +readme = "README.rst" +license = {text = "BSD-3-Clause"} +maintainers = [{name = "Pallets", email = "contact@palletsprojects.com"}] +authors = [{name = "Armin Ronacher", email = "armin.ronacher@active-4.com"}] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Environment :: Web Environment", + "Framework :: Flask", + "Intended Audience :: Developers", + "License :: OSI Approved :: BSD License", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Topic :: Internet :: WWW/HTTP :: Dynamic Content", + "Topic :: Internet :: WWW/HTTP :: WSGI", + "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", + "Topic :: Software Development :: Libraries :: Application Frameworks", +] +requires-python = ">=3.7" +dependencies = [ + "Werkzeug>=2.2.2", + "Jinja2>=3.0", + "itsdangerous>=2.0", + "click>=8.0", + "importlib-metadata>=3.6.0; python_version < '3.10'", +] +dynamic = ["version"] + +[project.urls] +Donate = "https://palletsprojects.com/donate" +Documentation = "https://flask.palletsprojects.com/" +Changes = "https://flask.palletsprojects.com/changes/" +"Source Code" = "https://github.com/pallets/flask/" +"Issue Tracker" = "https://github.com/pallets/flask/issues/" +Twitter = "https://twitter.com/PalletsTeam" +Chat = "https://discord.gg/pallets" + +[project.optional-dependencies] +async = ["asgiref>=3.2"] +dotenv = ["python-dotenv"] + +[project.scripts] +flask = "flask.cli:main" + +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[tool.setuptools.dynamic] +version = {attr = "flask.__version__"} + +[tool.pytest.ini_options] +testpaths = ["tests"] +filterwarnings = ["error"] + +[tool.coverage.run] +branch = true +source = ["flask", "tests"] + +[tool.coverage.paths] +source = ["src", "*/site-packages"] + +[tool.mypy] +python_version = "3.7" +files = ["src/flask"] +show_error_codes = true +pretty = true +#strict = true +allow_redefinition = true +disallow_subclassing_any = true +#disallow_untyped_calls = true +#disallow_untyped_defs = true +#disallow_incomplete_defs = true +no_implicit_optional = true +local_partial_types = true +#no_implicit_reexport = true +strict_equality = true +warn_redundant_casts = true +warn_unused_configs = true +warn_unused_ignores = true +#warn_return_any = true +#warn_unreachable = true + +[[tool.mypy.overrides]] +module = [ + "asgiref.*", + "blinker.*", + "dotenv.*", + "cryptography.*", + "importlib_metadata", +] +ignore_missing_imports = true diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index ea7f66e2..00000000 --- a/setup.cfg +++ /dev/null @@ -1,123 +0,0 @@ -[metadata] -name = Flask -version = attr: flask.__version__ -url = https://palletsprojects.com/p/flask -project_urls = - Donate = https://palletsprojects.com/donate - Documentation = https://flask.palletsprojects.com/ - Changes = https://flask.palletsprojects.com/changes/ - Source Code = https://github.com/pallets/flask/ - Issue Tracker = https://github.com/pallets/flask/issues/ - Twitter = https://twitter.com/PalletsTeam - Chat = https://discord.gg/pallets -license = BSD-3-Clause -author = Armin Ronacher -author_email = armin.ronacher@active-4.com -maintainer = Pallets -maintainer_email = contact@palletsprojects.com -description = A simple framework for building complex web applications. -long_description = file: README.rst -long_description_content_type = text/x-rst -classifiers = - Development Status :: 5 - Production/Stable - Environment :: Web Environment - Framework :: Flask - Intended Audience :: Developers - License :: OSI Approved :: BSD License - Operating System :: OS Independent - Programming Language :: Python - Topic :: Internet :: WWW/HTTP :: Dynamic Content - Topic :: Internet :: WWW/HTTP :: WSGI - Topic :: Internet :: WWW/HTTP :: WSGI :: Application - Topic :: Software Development :: Libraries :: Application Frameworks - -[options] -packages = find: -package_dir = = src -include_package_data = True -python_requires = >= 3.7 -# Dependencies are in setup.py for GitHub's dependency graph. - -[options.packages.find] -where = src - -[options.entry_points] -console_scripts = - flask = flask.cli:main - -[tool:pytest] -testpaths = tests -filterwarnings = - error - -[coverage:run] -branch = True -source = - flask - tests - -[coverage:paths] -source = - src - */site-packages - -[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 - # import at top, too many circular import fixes - E402 - # line length, handled by bugbear B950 - E501 - # bare except, handled by bugbear B001 - E722 - # bin op line break, invalid - W503 - # requires Python 3.10 - B905 -# up to 88 allowed by bugbear B950 -max-line-length = 80 -per-file-ignores = - # __init__ exports names - src/flask/__init__.py: F401 - -[mypy] -files = src/flask, tests/typing -python_version = 3.7 -show_error_codes = True -allow_redefinition = True -disallow_subclassing_any = True -# disallow_untyped_calls = True -# disallow_untyped_defs = True -# disallow_incomplete_defs = True -no_implicit_optional = True -local_partial_types = True -# no_implicit_reexport = True -strict_equality = True -warn_redundant_casts = True -warn_unused_configs = True -warn_unused_ignores = True -# warn_return_any = True -# warn_unreachable = True - -[mypy-asgiref.*] -ignore_missing_imports = True - -[mypy-blinker.*] -ignore_missing_imports = True - -[mypy-dotenv.*] -ignore_missing_imports = True - -[mypy-cryptography.*] -ignore_missing_imports = True - -[mypy-importlib_metadata] -ignore_missing_imports = True diff --git a/setup.py b/setup.py deleted file mode 100644 index 67175467..00000000 --- a/setup.py +++ /dev/null @@ -1,17 +0,0 @@ -from setuptools import setup - -# Metadata goes in setup.cfg. These are here for GitHub's dependency graph. -setup( - name="Flask", - install_requires=[ - "Werkzeug >= 2.2.2", - "Jinja2 >= 3.0", - "itsdangerous >= 2.0", - "click >= 8.0", - "importlib-metadata >= 3.6.0; python_version < '3.10'", - ], - extras_require={ - "async": ["asgiref >= 3.2"], - "dotenv": ["python-dotenv"], - }, -) From 8f13f5b6d672f1ba434f9c8ebe2c1b1dd385962e Mon Sep 17 00:00:00 2001 From: David Lord Date: Wed, 18 Jan 2023 10:21:37 -0800 Subject: [PATCH 2/3] update docs and examples for pyproject setup.py -> pyproject.toml venv -> .venv --- CONTRIBUTING.rst | 6 ++-- docs/cli.rst | 41 +++++++--------------- docs/deploying/eventlet.rst | 4 +-- docs/deploying/gevent.rst | 4 +-- docs/deploying/gunicorn.rst | 4 +-- docs/deploying/mod_wsgi.rst | 6 ++-- docs/deploying/uwsgi.rst | 4 +-- docs/deploying/waitress.rst | 4 +-- docs/installation.rst | 10 +++--- docs/patterns/packages.rst | 25 ++++++------- docs/tutorial/deploy.rst | 21 ++++------- docs/tutorial/install.rst | 56 +++++++++++++----------------- docs/tutorial/layout.rst | 8 ++--- docs/tutorial/tests.rst | 22 ++++++------ examples/javascript/.gitignore | 2 +- examples/javascript/README.rst | 4 +-- examples/javascript/pyproject.toml | 26 ++++++++++++++ examples/javascript/setup.cfg | 29 ---------------- examples/javascript/setup.py | 3 -- examples/tutorial/.gitignore | 2 +- examples/tutorial/README.rst | 8 ++--- examples/tutorial/pyproject.toml | 28 +++++++++++++++ examples/tutorial/setup.cfg | 28 --------------- examples/tutorial/setup.py | 3 -- 24 files changed, 153 insertions(+), 195 deletions(-) create mode 100644 examples/javascript/pyproject.toml delete mode 100644 examples/javascript/setup.cfg delete mode 100644 examples/javascript/setup.py create mode 100644 examples/tutorial/pyproject.toml delete mode 100644 examples/tutorial/setup.cfg delete mode 100644 examples/tutorial/setup.py diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 8d209048..8962490f 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -102,14 +102,14 @@ First time setup .. code-block:: text - $ python3 -m venv env - $ . env/bin/activate + $ python3 -m venv .venv + $ . .venv/bin/activate - Windows .. code-block:: text - > py -3 -m venv env + > py -3 -m venv .venv > env\Scripts\activate - Upgrade pip and setuptools. diff --git a/docs/cli.rst b/docs/cli.rst index a3ea268e..ec2ea22d 100644 --- a/docs/cli.rst +++ b/docs/cli.rst @@ -280,25 +280,25 @@ script. Activating the virtualenv will set the variables. .. group-tab:: Bash - Unix Bash, :file:`venv/bin/activate`:: + Unix Bash, :file:`.venv/bin/activate`:: $ export FLASK_APP=hello .. group-tab:: Fish - Fish, :file:`venv/bin/activate.fish`:: + Fish, :file:`.venv/bin/activate.fish`:: $ set -x FLASK_APP hello .. group-tab:: CMD - Windows CMD, :file:`venv\\Scripts\\activate.bat`:: + Windows CMD, :file:`.venv\\Scripts\\activate.bat`:: > set FLASK_APP=hello .. group-tab:: Powershell - Windows Powershell, :file:`venv\\Scripts\\activate.ps1`:: + Windows Powershell, :file:`.venv\\Scripts\\activate.ps1`:: > $env:FLASK_APP = "hello" @@ -438,24 +438,16 @@ Plugins Flask will automatically load commands specified in the ``flask.commands`` `entry point`_. This is useful for extensions that want to add commands when -they are installed. Entry points are specified in :file:`setup.py` :: +they are installed. Entry points are specified in :file:`pyproject.toml`: - from setuptools import setup - - setup( - name='flask-my-extension', - ..., - entry_points={ - 'flask.commands': [ - 'my-command=flask_my_extension.commands:cli' - ], - }, - ) +.. code-block:: toml + [project.entry-points."flask.commands"] + my-command = "my_extension.commands:cli" .. _entry point: https://packaging.python.org/tutorials/packaging-projects/#entry-points -Inside :file:`flask_my_extension/commands.py` you can then export a Click +Inside :file:`my_extension/commands.py` you can then export a Click object:: import click @@ -493,19 +485,12 @@ Create an instance of :class:`~cli.FlaskGroup` and pass it the factory:: def cli(): """Management script for the Wiki application.""" -Define the entry point in :file:`setup.py`:: +Define the entry point in :file:`pyproject.toml`: - from setuptools import setup +.. code-block:: toml - setup( - name='flask-my-extension', - ..., - entry_points={ - 'console_scripts': [ - 'wiki=wiki:cli' - ], - }, - ) + [project.scripts] + wiki = "wiki:cli" Install the application in the virtualenv in editable mode and the custom script is available. Note that you don't need to set ``--app``. :: diff --git a/docs/deploying/eventlet.rst b/docs/deploying/eventlet.rst index 243be5eb..3653c01e 100644 --- a/docs/deploying/eventlet.rst +++ b/docs/deploying/eventlet.rst @@ -34,8 +34,8 @@ Create a virtualenv, install your application, then install .. code-block:: text $ cd hello-app - $ python -m venv venv - $ . venv/bin/activate + $ python -m venv .venv + $ . .venv/bin/activate $ pip install . # install your application $ pip install eventlet diff --git a/docs/deploying/gevent.rst b/docs/deploying/gevent.rst index aae63e89..448b93e7 100644 --- a/docs/deploying/gevent.rst +++ b/docs/deploying/gevent.rst @@ -33,8 +33,8 @@ Create a virtualenv, install your application, then install ``gevent``. .. code-block:: text $ cd hello-app - $ python -m venv venv - $ . venv/bin/activate + $ python -m venv .venv + $ . .venv/bin/activate $ pip install . # install your application $ pip install gevent diff --git a/docs/deploying/gunicorn.rst b/docs/deploying/gunicorn.rst index 93d11d39..c50edc23 100644 --- a/docs/deploying/gunicorn.rst +++ b/docs/deploying/gunicorn.rst @@ -30,8 +30,8 @@ Create a virtualenv, install your application, then install .. code-block:: text $ cd hello-app - $ python -m venv venv - $ . venv/bin/activate + $ python -m venv .venv + $ . .venv/bin/activate $ pip install . # install your application $ pip install gunicorn diff --git a/docs/deploying/mod_wsgi.rst b/docs/deploying/mod_wsgi.rst index eae973de..23e82279 100644 --- a/docs/deploying/mod_wsgi.rst +++ b/docs/deploying/mod_wsgi.rst @@ -33,8 +33,8 @@ Create a virtualenv, install your application, then install .. code-block:: text $ cd hello-app - $ python -m venv venv - $ . venv/bin/activate + $ python -m venv .venv + $ . .venv/bin/activate $ pip install . # install your application $ pip install mod_wsgi @@ -89,6 +89,6 @@ mod_wsgi to drop to that user after starting. .. code-block:: text - $ sudo /home/hello/venv/bin/mod_wsgi-express start-server \ + $ sudo /home/hello/.venv/bin/mod_wsgi-express start-server \ /home/hello/wsgi.py \ --user hello --group hello --port 80 --processes 4 diff --git a/docs/deploying/uwsgi.rst b/docs/deploying/uwsgi.rst index 2da5efe2..1f9d5eca 100644 --- a/docs/deploying/uwsgi.rst +++ b/docs/deploying/uwsgi.rst @@ -29,8 +29,8 @@ Create a virtualenv, install your application, then install ``pyuwsgi``. .. code-block:: text $ cd hello-app - $ python -m venv venv - $ . venv/bin/activate + $ python -m venv .venv + $ . .venv/bin/activate $ pip install . # install your application $ pip install pyuwsgi diff --git a/docs/deploying/waitress.rst b/docs/deploying/waitress.rst index eb70e058..aeafb9f7 100644 --- a/docs/deploying/waitress.rst +++ b/docs/deploying/waitress.rst @@ -27,8 +27,8 @@ Create a virtualenv, install your application, then install .. code-block:: text $ cd hello-app - $ python -m venv venv - $ . venv/bin/activate + $ python -m venv .venv + $ . .venv/bin/activate $ pip install . # install your application $ pip install waitress diff --git a/docs/installation.rst b/docs/installation.rst index 8a338e18..276fdc3d 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -85,7 +85,7 @@ environments. Create an environment ~~~~~~~~~~~~~~~~~~~~~ -Create a project folder and a :file:`venv` folder within: +Create a project folder and a :file:`.venv` folder within: .. tabs:: @@ -95,7 +95,7 @@ Create a project folder and a :file:`venv` folder within: $ mkdir myproject $ cd myproject - $ python3 -m venv venv + $ python3 -m venv .venv .. group-tab:: Windows @@ -103,7 +103,7 @@ Create a project folder and a :file:`venv` folder within: > mkdir myproject > cd myproject - > py -3 -m venv venv + > py -3 -m venv .venv .. _install-activate-env: @@ -119,13 +119,13 @@ Before you work on your project, activate the corresponding environment: .. code-block:: text - $ . venv/bin/activate + $ . .venv/bin/activate .. group-tab:: Windows .. code-block:: text - > venv\Scripts\activate + > .venv\Scripts\activate Your shell prompt will change to show the name of the activated environment. diff --git a/docs/patterns/packages.rst b/docs/patterns/packages.rst index 13f8270e..12c46083 100644 --- a/docs/patterns/packages.rst +++ b/docs/patterns/packages.rst @@ -42,19 +42,20 @@ You should then end up with something like that:: But how do you run your application now? The naive ``python yourapplication/__init__.py`` will not work. Let's just say that Python does not want modules in packages to be the startup file. But that is not -a big problem, just add a new file called :file:`setup.py` next to the inner -:file:`yourapplication` folder with the following contents:: +a big problem, just add a new file called :file:`pyproject.toml` next to the inner +:file:`yourapplication` folder with the following contents: - from setuptools import setup +.. code-block:: toml - setup( - name='yourapplication', - packages=['yourapplication'], - include_package_data=True, - install_requires=[ - 'flask', - ], - ) + [project] + name = "yourapplication" + dependencies = [ + "flask", + ] + + [build-system] + requires = ["setuptools"] + build-backend = "setuptools.build_meta" Install your application so it is importable: @@ -98,7 +99,7 @@ And this is what :file:`views.py` would look like:: You should then end up with something like that:: /yourapplication - setup.py + pyproject.toml /yourapplication __init__.py views.py diff --git a/docs/tutorial/deploy.rst b/docs/tutorial/deploy.rst index 436ed5e8..eb3a53ac 100644 --- a/docs/tutorial/deploy.rst +++ b/docs/tutorial/deploy.rst @@ -14,22 +14,13 @@ application. Build and Install ----------------- -When you want to deploy your application elsewhere, you build a -distribution file. The current standard for Python distribution is the -*wheel* format, with the ``.whl`` extension. Make sure the wheel library -is installed first: +When you want to deploy your application elsewhere, you build a *wheel* +(``.whl``) file. Install and use the ``build`` tool to do this. .. code-block:: none - $ pip install wheel - -Running ``setup.py`` with Python gives you a command line tool to issue -build-related commands. The ``bdist_wheel`` command will build a wheel -distribution file. - -.. code-block:: none - - $ python setup.py bdist_wheel + $ pip install build + $ python -m build --wheel You can find the file in ``dist/flaskr-1.0.0-py3-none-any.whl``. The file name is in the format of {project name}-{version}-{python tag} @@ -54,7 +45,7 @@ create the database in the instance folder. When Flask detects that it's installed (not in editable mode), it uses a different directory for the instance folder. You can find it at -``venv/var/flaskr-instance`` instead. +``.venv/var/flaskr-instance`` instead. Configure the Secret Key @@ -77,7 +68,7 @@ Create the ``config.py`` file in the instance folder, which the factory will read from if it exists. Copy the generated value into it. .. code-block:: python - :caption: ``venv/var/flaskr-instance/config.py`` + :caption: ``.venv/var/flaskr-instance/config.py`` SECRET_KEY = '192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf' diff --git a/docs/tutorial/install.rst b/docs/tutorial/install.rst index f6820ebd..9bb1234e 100644 --- a/docs/tutorial/install.rst +++ b/docs/tutorial/install.rst @@ -1,11 +1,10 @@ Make the Project Installable ============================ -Making your project installable means that you can build a -*distribution* file and install that in another environment, just like -you installed Flask in your project's environment. This makes deploying -your project the same as installing any other library, so you're using -all the standard Python tools to manage everything. +Making your project installable means that you can build a *wheel* file and install that +in another environment, just like you installed Flask in your project's environment. +This makes deploying your project the same as installing any other library, so you're +using all the standard Python tools to manage everything. Installing also comes with other benefits that might not be obvious from the tutorial or as a new Python user, including: @@ -28,31 +27,25 @@ the tutorial or as a new Python user, including: Describe the Project -------------------- -The ``setup.py`` file describes your project and the files that belong -to it. +The ``pyproject.toml`` file describes your project and how to build it. -.. code-block:: python - :caption: ``setup.py`` +.. code-block:: toml + :caption: ``pyproject.toml`` - from setuptools import find_packages, setup + [project] + name = "flaskr" + version = "1.0.0" + dependencies = [ + "flask", + ] - setup( - name='flaskr', - version='1.0.0', - packages=find_packages(), - include_package_data=True, - install_requires=[ - 'flask', - ], - ) + [build-system] + requires = ["setuptools"] + build-backend = "setuptools.build_meta" -``packages`` tells Python what package directories (and the Python files -they contain) to include. ``find_packages()`` finds these directories -automatically so you don't have to type them out. To include other -files, such as the static and templates directories, -``include_package_data`` is set. Python needs another file named -``MANIFEST.in`` to tell what this other data is. +The setuptools build backend needs another file named ``MANIFEST.in`` to tell it about +non-Python files to include. .. code-block:: none :caption: ``MANIFEST.in`` @@ -62,9 +55,8 @@ files, such as the static and templates directories, graft flaskr/templates global-exclude *.pyc -This tells Python to copy everything in the ``static`` and ``templates`` -directories, and the ``schema.sql`` file, but to exclude all bytecode -files. +This tells the build to copy everything in the ``static`` and ``templates`` directories, +and the ``schema.sql`` file, but to exclude all bytecode files. See the official `Packaging tutorial `_ and `detailed guide `_ for more explanation of the files @@ -83,10 +75,10 @@ Use ``pip`` to install your project in the virtual environment. $ pip install -e . -This tells pip to find ``setup.py`` in the current directory and install -it in *editable* or *development* mode. Editable mode means that as you -make changes to your local code, you'll only need to re-install if you -change the metadata about the project, such as its dependencies. +This tells pip to find ``pyproject.toml`` in the current directory and install the +project in *editable* or *development* mode. Editable mode means that as you make +changes to your local code, you'll only need to re-install if you change the metadata +about the project, such as its dependencies. You can observe that the project is now installed with ``pip list``. diff --git a/docs/tutorial/layout.rst b/docs/tutorial/layout.rst index b6a09f03..6f8e59f4 100644 --- a/docs/tutorial/layout.rst +++ b/docs/tutorial/layout.rst @@ -41,7 +41,7 @@ The project directory will contain: * ``flaskr/``, a Python package containing your application code and files. * ``tests/``, a directory containing test modules. -* ``venv/``, a Python virtual environment where Flask and other +* ``.venv/``, a Python virtual environment where Flask and other dependencies are installed. * Installation files telling Python how to install your project. * Version control config, such as `git`_. You should make a habit of @@ -80,8 +80,8 @@ By the end, your project layout will look like this: │ ├── test_db.py │ ├── test_auth.py │ └── test_blog.py - ├── venv/ - ├── setup.py + ├── .venv/ + ├── pyproject.toml └── MANIFEST.in If you're using version control, the following files that are generated @@ -92,7 +92,7 @@ write. For example, with git: .. code-block:: none :caption: ``.gitignore`` - venv/ + .venv/ *.pyc __pycache__/ diff --git a/docs/tutorial/tests.rst b/docs/tutorial/tests.rst index cb60790c..f4744cda 100644 --- a/docs/tutorial/tests.rst +++ b/docs/tutorial/tests.rst @@ -490,20 +490,18 @@ no longer exist in the database. Running the Tests ----------------- -Some extra configuration, which is not required but makes running -tests with coverage less verbose, can be added to the project's -``setup.cfg`` file. +Some extra configuration, which is not required but makes running tests with coverage +less verbose, can be added to the project's ``pyproject.toml`` file. -.. code-block:: none - :caption: ``setup.cfg`` +.. code-block:: toml + :caption: ``pyproject.toml`` - [tool:pytest] - testpaths = tests + [tool.pytest.ini_options] + testpaths = ["tests"] - [coverage:run] - branch = True - source = - flaskr + [tool.coverage.run] + branch = true + source = ["flaskr"] To run the tests, use the ``pytest`` command. It will find and run all the test functions you've written. @@ -514,7 +512,7 @@ the test functions you've written. ========================= test session starts ========================== platform linux -- Python 3.6.4, pytest-3.5.0, py-1.5.3, pluggy-0.6.0 - rootdir: /home/user/Projects/flask-tutorial, inifile: setup.cfg + rootdir: /home/user/Projects/flask-tutorial collected 23 items tests/test_auth.py ........ [ 34%] diff --git a/examples/javascript/.gitignore b/examples/javascript/.gitignore index 85a35845..a306afbc 100644 --- a/examples/javascript/.gitignore +++ b/examples/javascript/.gitignore @@ -1,4 +1,4 @@ -venv/ +.venv/ *.pyc __pycache__/ instance/ diff --git a/examples/javascript/README.rst b/examples/javascript/README.rst index 23c7ce43..697bb217 100644 --- a/examples/javascript/README.rst +++ b/examples/javascript/README.rst @@ -23,8 +23,8 @@ Install .. code-block:: text - $ python3 -m venv venv - $ . venv/bin/activate + $ python3 -m venv .venv + $ . .venv/bin/activate $ pip install -e . diff --git a/examples/javascript/pyproject.toml b/examples/javascript/pyproject.toml new file mode 100644 index 00000000..ce326ea7 --- /dev/null +++ b/examples/javascript/pyproject.toml @@ -0,0 +1,26 @@ +[project] +name = "js_example" +version = "1.1.0" +description = "Demonstrates making AJAX requests to Flask." +readme = "README.rst" +license = {text = "BSD-3-Clause"} +maintainers = [{name = "Pallets", email = "contact@palletsprojects.com"}] +dependencies = ["flask"] + +[project.urls] +Documentation = "https://flask.palletsprojects.com/patterns/jquery/" + +[project.optional-dependencies] +test = ["pytest", "blinker"] + +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[tool.pytest.ini_options] +testpaths = ["tests"] +filterwarnings = ["error"] + +[tool.coverage.run] +branch = true +source = ["js_example", "tests"] diff --git a/examples/javascript/setup.cfg b/examples/javascript/setup.cfg deleted file mode 100644 index f509ddfe..00000000 --- a/examples/javascript/setup.cfg +++ /dev/null @@ -1,29 +0,0 @@ -[metadata] -name = js_example -version = 1.1.0 -url = https://flask.palletsprojects.com/patterns/jquery/ -license = BSD-3-Clause -maintainer = Pallets -maintainer_email = contact@palletsprojects.com -description = Demonstrates making AJAX requests to Flask. -long_description = file: README.rst -long_description_content_type = text/x-rst - -[options] -packages = find: -include_package_data = true -install_requires = - Flask - -[options.extras_require] -test = - pytest - blinker - -[tool:pytest] -testpaths = tests - -[coverage:run] -branch = True -source = - js_example diff --git a/examples/javascript/setup.py b/examples/javascript/setup.py deleted file mode 100644 index 60684932..00000000 --- a/examples/javascript/setup.py +++ /dev/null @@ -1,3 +0,0 @@ -from setuptools import setup - -setup() diff --git a/examples/tutorial/.gitignore b/examples/tutorial/.gitignore index 85a35845..a306afbc 100644 --- a/examples/tutorial/.gitignore +++ b/examples/tutorial/.gitignore @@ -1,4 +1,4 @@ -venv/ +.venv/ *.pyc __pycache__/ instance/ diff --git a/examples/tutorial/README.rst b/examples/tutorial/README.rst index 1c745078..653c2167 100644 --- a/examples/tutorial/README.rst +++ b/examples/tutorial/README.rst @@ -23,13 +23,13 @@ default Git version is the main branch. :: Create a virtualenv and activate it:: - $ python3 -m venv venv - $ . venv/bin/activate + $ python3 -m venv .venv + $ . .venv/bin/activate Or on Windows cmd:: - $ py -3 -m venv venv - $ venv\Scripts\activate.bat + $ py -3 -m venv .venv + $ .venv\Scripts\activate.bat Install Flaskr:: diff --git a/examples/tutorial/pyproject.toml b/examples/tutorial/pyproject.toml new file mode 100644 index 00000000..c86eb61f --- /dev/null +++ b/examples/tutorial/pyproject.toml @@ -0,0 +1,28 @@ +[project] +name = "flaskr" +version = "1.0.0" +description = "The basic blog app built in the Flask tutorial." +readme = "README.rst" +license = {text = "BSD-3-Clause"} +maintainers = [{name = "Pallets", email = "contact@palletsprojects.com"}] +dependencies = [ + "flask", +] + +[project.urls] +Documentation = "https://flask.palletsprojects.com/tutorial/" + +[project.optional-dependencies] +test = ["pytest"] + +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[tool.pytest.ini_options] +testpaths = ["tests"] +filterwarnings = ["error"] + +[tool.coverage.run] +branch = true +source = ["flaskr", "tests"] diff --git a/examples/tutorial/setup.cfg b/examples/tutorial/setup.cfg deleted file mode 100644 index d001093b..00000000 --- a/examples/tutorial/setup.cfg +++ /dev/null @@ -1,28 +0,0 @@ -[metadata] -name = flaskr -version = 1.0.0 -url = https://flask.palletsprojects.com/tutorial/ -license = BSD-3-Clause -maintainer = Pallets -maintainer_email = contact@palletsprojects.com -description = The basic blog app built in the Flask tutorial. -long_description = file: README.rst -long_description_content_type = text/x-rst - -[options] -packages = find: -include_package_data = true -install_requires = - Flask - -[options.extras_require] -test = - pytest - -[tool:pytest] -testpaths = tests - -[coverage:run] -branch = True -source = - flaskr diff --git a/examples/tutorial/setup.py b/examples/tutorial/setup.py deleted file mode 100644 index 60684932..00000000 --- a/examples/tutorial/setup.py +++ /dev/null @@ -1,3 +0,0 @@ -from setuptools import setup - -setup() From 261e4a6cf287180b69c4db407791e43ce90e50ad Mon Sep 17 00:00:00 2001 From: David Lord Date: Wed, 18 Jan 2023 10:31:08 -0800 Subject: [PATCH 3/3] fix flake8 bugbear errors --- .flake8 | 23 ++++++++++++----------- tests/test_appctx.py | 6 +++--- tests/test_basic.py | 4 ++-- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/.flake8 b/.flake8 index 09809616..a5ce8844 100644 --- a/.flake8 +++ b/.flake8 @@ -1,12 +1,12 @@ [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 = +extend-select = + # bugbear + B + # bugbear opinions + B9 + # implicit str concat + ISC +extend-ignore = # slice notation whitespace, invalid E203 # import at top, too many circular import fixes @@ -15,10 +15,11 @@ ignore = E501 # bare except, handled by bugbear B001 E722 - # bin op line break, invalid - W503 - # requires Python 3.10 + # zip with strict=, requires python >= 3.10 B905 + # string formatting opinion, B028 renamed to B907 + B028 + B907 # up to 88 allowed by bugbear B950 max-line-length = 80 per-file-ignores = diff --git a/tests/test_appctx.py b/tests/test_appctx.py index f5ca0bde..aa3a8b4e 100644 --- a/tests/test_appctx.py +++ b/tests/test_appctx.py @@ -120,14 +120,14 @@ def test_app_tearing_down_with_unhandled_exception(app, client): @app.route("/") def index(): - raise Exception("dummy") + raise ValueError("dummy") - with pytest.raises(Exception, match="dummy"): + with pytest.raises(ValueError, match="dummy"): with app.app_context(): client.get("/") assert len(cleanup_stuff) == 1 - assert isinstance(cleanup_stuff[0], Exception) + assert isinstance(cleanup_stuff[0], ValueError) assert str(cleanup_stuff[0]) == "dummy" diff --git a/tests/test_basic.py b/tests/test_basic.py index d547012a..9aca6679 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -1472,11 +1472,11 @@ def test_static_route_with_host_matching(): rv = flask.url_for("static", filename="index.html", _external=True) assert rv == "http://example.com/static/index.html" # Providing static_host without host_matching=True should error. - with pytest.raises(Exception): + with pytest.raises(AssertionError): flask.Flask(__name__, static_host="example.com") # Providing host_matching=True with static_folder # but without static_host should error. - with pytest.raises(Exception): + with pytest.raises(AssertionError): flask.Flask(__name__, host_matching=True) # Providing host_matching=True without static_host # but with static_folder=None should not error.