Switch to pyproject.toml
This commit is contained in:
commit
ffb4293fca
21 changed files with 200 additions and 132 deletions
3
.flake8
3
.flake8
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
[flake8]
|
||||
extend-select =
|
||||
# bugbear
|
||||
|
|
@ -22,4 +23,4 @@ extend-ignore =
|
|||
max-line-length = 80
|
||||
per-file-ignores =
|
||||
# __init__ exports names
|
||||
src/flask/__init__.py: F401
|
||||
src/flask/__init__.py: F401
|
||||
2
.github/workflows/lock.yaml
vendored
2
.github/workflows/lock.yaml
vendored
|
|
@ -22,4 +22,4 @@ jobs:
|
|||
- uses: dessant/lock-threads@c1b35aecc5cdb1a34539d14196df55838bb2f836
|
||||
with:
|
||||
issue-inactive-days: 14
|
||||
pr-inactive-days: 14
|
||||
pr-inactive-days: 14
|
||||
2
.github/workflows/tests.yaml
vendored
2
.github/workflows/tests.yaml
vendored
|
|
@ -52,7 +52,7 @@ jobs:
|
|||
uses: actions/cache@58c146cc91c5b9e778e71775dfe9bf1442ad9a12
|
||||
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 }}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
ci:
|
||||
autoupdate_branch: "2.1.x"
|
||||
autoupdate_branch: "2.2.x"
|
||||
autoupdate_schedule: monthly
|
||||
repos:
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
|
|
|
|||
10
CHANGES.rst
10
CHANGES.rst
|
|
@ -1,3 +1,13 @@
|
|||
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`
|
||||
|
||||
|
||||
Version 2.2.3
|
||||
-------------
|
||||
|
||||
|
|
|
|||
|
|
@ -140,6 +140,19 @@ name, and child URLs will be prefixed with the parent's URL prefix.
|
|||
url_for('parent.child.create')
|
||||
/parent/child/create
|
||||
|
||||
In addition a child blueprint's will gain their parent's subdomain,
|
||||
with their subdomain as prefix if present i.e.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
parent = Blueprint('parent', __name__, subdomain='parent')
|
||||
child = Blueprint('child', __name__, subdomain='child')
|
||||
parent.register_blueprint(child)
|
||||
app.register_blueprint(parent)
|
||||
|
||||
url_for('parent.child.create', _external=True)
|
||||
"child.parent.domain.tld"
|
||||
|
||||
Blueprint-specific before request functions, etc. registered with the
|
||||
parent will trigger for the child. If a child does not have an error
|
||||
handler that can handle a given exception, the parent's will be tried.
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ the ``--debug`` option.
|
|||
|
||||
.. code-block:: console
|
||||
|
||||
$ flask --app hello --debug run
|
||||
$ flask --app hello run --debug
|
||||
* Serving Flask app "hello"
|
||||
* Debug mode: on
|
||||
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
|
||||
|
|
@ -550,7 +550,7 @@ a name such as "flask run".
|
|||
Click the *Script path* dropdown and change it to *Module name*, then input ``flask``.
|
||||
|
||||
The *Parameters* field is set to the CLI command to execute along with any arguments.
|
||||
This example uses ``--app hello --debug run``, which will run the development server in
|
||||
This example uses ``--app hello run --debug``, which will run the development server in
|
||||
debug mode. ``--app hello`` should be the import or file with your Flask app.
|
||||
|
||||
If you installed your project as a package in your virtualenv, you may uncheck the
|
||||
|
|
|
|||
|
|
@ -47,12 +47,12 @@ Debug Mode
|
|||
|
||||
The :data:`DEBUG` config value is special because it may behave inconsistently if
|
||||
changed after the app has begun setting up. In order to set debug mode reliably, use the
|
||||
``--debug`` option on the ``flask`` command. ``flask run`` will use the interactive
|
||||
``--debug`` option on the ``flask run`` command. ``flask run`` will use the interactive
|
||||
debugger and reloader by default in debug mode.
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ flask --app hello --debug run
|
||||
$ flask --app hello run --debug
|
||||
|
||||
Using the option is recommended. While it is possible to set :data:`DEBUG` in your
|
||||
config or code, this is strongly discouraged. It can't be read early by the ``flask run``
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ The debugger is enabled by default when the development server is run in debug m
|
|||
|
||||
.. code-block:: text
|
||||
|
||||
$ flask --app hello --debug run
|
||||
$ flask --app hello run --debug
|
||||
|
||||
When running from Python code, passing ``debug=True`` enables debug mode, which is
|
||||
mostly equivalent.
|
||||
|
|
@ -72,7 +72,7 @@ which can interfere.
|
|||
|
||||
.. code-block:: text
|
||||
|
||||
$ flask --app hello --debug run --no-debugger --no-reload
|
||||
$ flask --app hello run --debug --no-debugger --no-reload
|
||||
|
||||
When running from Python:
|
||||
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ To enable debug mode, use the ``--debug`` option.
|
|||
|
||||
.. code-block:: text
|
||||
|
||||
$ flask --app hello --debug run
|
||||
$ flask --app hello run --debug
|
||||
* Serving Flask app 'hello'
|
||||
* Debug mode: on
|
||||
* Running on http://127.0.0.1:5000 (Press CTRL+C to quit)
|
||||
|
|
@ -359,7 +359,7 @@ the application secure. Because of that Flask configures the `Jinja2
|
|||
|
||||
Templates can be used to generate any type of text file. For web applications, you'll
|
||||
primarily be generating HTML pages, but you can also generate markdown, plain text for
|
||||
emails, any anything else.
|
||||
emails, and anything else.
|
||||
|
||||
For a reference to HTML, CSS, and other web APIs, use the `MDN Web Docs`_.
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ debug mode.
|
|||
|
||||
.. code-block:: text
|
||||
|
||||
$ flask --app hello --debug run
|
||||
$ flask --app hello run --debug
|
||||
|
||||
This enables debug mode, including the interactive debugger and reloader, and then
|
||||
starts the server on http://localhost:5000/. Use ``flask run --help`` to see the
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ follow the tutorial.
|
|||
|
||||
.. code-block:: text
|
||||
|
||||
$ flask --app flaskr --debug run
|
||||
$ flask --app flaskr run --debug
|
||||
|
||||
You'll see output similar to this:
|
||||
|
||||
|
|
|
|||
|
|
@ -249,7 +249,7 @@ provide get (list) and post (create) methods.
|
|||
init_every_request = False
|
||||
|
||||
def __init__(self, model):
|
||||
self.model
|
||||
self.model = model
|
||||
self.validator = generate_validator(model)
|
||||
|
||||
def _get_item(self, id):
|
||||
|
|
@ -297,7 +297,7 @@ provide get (list) and post (create) methods.
|
|||
db.session.commit()
|
||||
return jsonify(item.to_json())
|
||||
|
||||
def register_api(app, model, url):
|
||||
def register_api(app, model, name):
|
||||
item = ItemAPI.as_view(f"{name}-item", model)
|
||||
group = GroupAPI.as_view(f"{name}-group", model)
|
||||
app.add_url_rule(f"/{name}/<int:id>", view_func=item)
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ Run
|
|||
.. code-block:: text
|
||||
|
||||
$ flask --app flaskr init-db
|
||||
$ flask --app flaskr --debug run
|
||||
$ flask --app flaskr run --debug
|
||||
|
||||
Open http://127.0.0.1:5000 in a browser.
|
||||
|
||||
|
|
|
|||
94
pyproject.toml
Normal file
94
pyproject.toml
Normal file
|
|
@ -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
|
||||
96
setup.cfg
96
setup.cfg
|
|
@ -1,96 +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
|
||||
|
||||
[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
|
||||
17
setup.py
17
setup.py
|
|
@ -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"],
|
||||
},
|
||||
)
|
||||
|
|
@ -42,7 +42,7 @@ from .templating import render_template_string as render_template_string
|
|||
from .templating import stream_template as stream_template
|
||||
from .templating import stream_template_string as stream_template_string
|
||||
|
||||
__version__ = "2.2.3.dev"
|
||||
__version__ = "2.3.0.dev"
|
||||
|
||||
|
||||
def __getattr__(name):
|
||||
|
|
|
|||
|
|
@ -2451,7 +2451,7 @@ class Flask(Scaffold):
|
|||
:data:`request` point at the request for the created
|
||||
environment. ::
|
||||
|
||||
with test_request_context(...):
|
||||
with app.test_request_context(...):
|
||||
generate_report()
|
||||
|
||||
When using the shell, it may be easier to push and pop the
|
||||
|
|
|
|||
|
|
@ -358,6 +358,9 @@ class Blueprint(Scaffold):
|
|||
:param options: Keyword arguments forwarded from
|
||||
:meth:`~Flask.register_blueprint`.
|
||||
|
||||
.. versionchanged:: 2.3
|
||||
Nested blueprints now correctly apply subdomains.
|
||||
|
||||
.. versionchanged:: 2.0.1
|
||||
Nested blueprints are registered with their dotted name.
|
||||
This allows different blueprints with the same name to be
|
||||
|
|
@ -453,6 +456,17 @@ class Blueprint(Scaffold):
|
|||
for blueprint, bp_options in self._blueprints:
|
||||
bp_options = bp_options.copy()
|
||||
bp_url_prefix = bp_options.get("url_prefix")
|
||||
bp_subdomain = bp_options.get("subdomain")
|
||||
|
||||
if bp_subdomain is None:
|
||||
bp_subdomain = blueprint.subdomain
|
||||
|
||||
if state.subdomain is not None and bp_subdomain is not None:
|
||||
bp_options["subdomain"] = bp_subdomain + "." + state.subdomain
|
||||
elif bp_subdomain is not None:
|
||||
bp_options["subdomain"] = bp_subdomain
|
||||
elif state.subdomain is not None:
|
||||
bp_options["subdomain"] = state.subdomain
|
||||
|
||||
if bp_url_prefix is None:
|
||||
bp_url_prefix = blueprint.url_prefix
|
||||
|
|
|
|||
|
|
@ -950,6 +950,55 @@ def test_nesting_url_prefixes(
|
|||
assert response.status_code == 200
|
||||
|
||||
|
||||
def test_nesting_subdomains(app, client) -> None:
|
||||
subdomain = "api"
|
||||
parent = flask.Blueprint("parent", __name__)
|
||||
child = flask.Blueprint("child", __name__)
|
||||
|
||||
@child.route("/child/")
|
||||
def index():
|
||||
return "child"
|
||||
|
||||
parent.register_blueprint(child)
|
||||
app.register_blueprint(parent, subdomain=subdomain)
|
||||
|
||||
client.allow_subdomain_redirects = True
|
||||
|
||||
domain_name = "domain.tld"
|
||||
app.config["SERVER_NAME"] = domain_name
|
||||
response = client.get("/child/", base_url="http://api." + domain_name)
|
||||
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
def test_child_and_parent_subdomain(app, client) -> None:
|
||||
child_subdomain = "api"
|
||||
parent_subdomain = "parent"
|
||||
parent = flask.Blueprint("parent", __name__)
|
||||
child = flask.Blueprint("child", __name__, subdomain=child_subdomain)
|
||||
|
||||
@child.route("/")
|
||||
def index():
|
||||
return "child"
|
||||
|
||||
parent.register_blueprint(child)
|
||||
app.register_blueprint(parent, subdomain=parent_subdomain)
|
||||
|
||||
client.allow_subdomain_redirects = True
|
||||
|
||||
domain_name = "domain.tld"
|
||||
app.config["SERVER_NAME"] = domain_name
|
||||
response = client.get(
|
||||
"/", base_url=f"http://{child_subdomain}.{parent_subdomain}.{domain_name}"
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
|
||||
response = client.get("/", base_url=f"http://{parent_subdomain}.{domain_name}")
|
||||
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
def test_unique_blueprint_names(app, client) -> None:
|
||||
bp = flask.Blueprint("bp", __name__)
|
||||
bp2 = flask.Blueprint("bp", __name__)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue