flask
Advanced tools
Sorry, the diff of this file is too big to display
+4
-0
@@ -29,2 +29,3 @@ import packaging.version | ||
| "pr": ("https://github.com/pallets/flask/pull/%s", "#%s"), | ||
| "ghsa": ("https://github.com/pallets/flask/security/advisories/GHSA-%s", "GHSA-%s"), | ||
| } | ||
@@ -66,2 +67,5 @@ intersphinx_mapping = { | ||
| gettext_uuid = True | ||
| gettext_compact = False | ||
| # Local Extensions ----------------------------------------------------- | ||
@@ -68,0 +72,0 @@ |
+6
-3
@@ -130,5 +130,5 @@ Configuration Handling | ||
| A list of old secret keys that can still be used for unsigning, most recent | ||
| first. This allows a project to implement key rotation without invalidating | ||
| active sessions or other recently-signed secrets. | ||
| A list of old secret keys that can still be used for unsigning. This allows | ||
| a project to implement key rotation without invalidating active sessions or | ||
| other recently-signed secrets. | ||
@@ -138,2 +138,5 @@ Keys should be removed after an appropriate period of time, as checking each | ||
| Order should not matter, but the default implementation will test the last | ||
| key in the list first, so it might make sense to order oldest to newest. | ||
| Flask's built-in secure cookie session supports this. Extensions that use | ||
@@ -140,0 +143,0 @@ :data:`SECRET_KEY` may not support this yet. |
@@ -1,1 +0,8 @@ | ||
| .. include:: ../CONTRIBUTING.rst | ||
| Contributing | ||
| ============ | ||
| See the Pallets `detailed contributing documentation <_contrib>`_ for many ways | ||
| to contribute, including reporting issues, requesting features, asking or | ||
| answering questions, and making PRs. | ||
| .. _contrib: https://palletsprojects.com/contributing/ |
@@ -102,5 +102,5 @@ Application Factories | ||
| $ flask --app hello:create_app(local_auth=True) run | ||
| $ flask --app 'hello:create_app(local_auth=True)' run | ||
| Then the ``create_app`` factory in ``myapp`` is called with the keyword | ||
| Then the ``create_app`` factory in ``hello`` is called with the keyword | ||
| argument ``local_auth=True``. See :doc:`/cli` for more detail. | ||
@@ -107,0 +107,0 @@ |
@@ -27,4 +27,7 @@ Adding a favicon | ||
| app.add_url_rule('/favicon.ico', | ||
| redirect_to=url_for('static', filename='favicon.ico')) | ||
| app.add_url_rule( | ||
| "/favicon.ico", | ||
| endpoint="favicon", | ||
| redirect_to=url_for("static", filename="favicon.ico"), | ||
| ) | ||
@@ -31,0 +34,0 @@ If you want to save the extra redirect request you can also write a view |
@@ -83,3 +83,3 @@ MongoDB with MongoEngine | ||
| bttf = Movies.objects(title="Back To The Future").get_or_404() | ||
| bttf = Movie.objects(title="Back To The Future").get_or_404() | ||
@@ -86,0 +86,0 @@ Query operators may be used by concatenating them with the field name |
@@ -272,15 +272,2 @@ Security Considerations | ||
| HTTP Public Key Pinning (HPKP) | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| This tells the browser to authenticate with the server using only the specific | ||
| certificate key to prevent MITM attacks. | ||
| .. warning:: | ||
| Be careful when enabling this, as it is very difficult to undo if you set up | ||
| or upgrade your key incorrectly. | ||
| - https://developer.mozilla.org/en-US/docs/Web/HTTP/Public_Key_Pinning | ||
| Copy/Paste to Terminal | ||
@@ -287,0 +274,0 @@ ---------------------- |
+23
-15
@@ -1,4 +0,4 @@ | ||
| Metadata-Version: 2.3 | ||
| Metadata-Version: 2.4 | ||
| Name: Flask | ||
| Version: 3.1.0 | ||
| Version: 3.1.1 | ||
| Summary: A simple framework for building complex web applications. | ||
@@ -8,2 +8,3 @@ Maintainer-email: Pallets <contact@palletsprojects.com> | ||
| Description-Content-Type: text/markdown | ||
| License-Expression: BSD-3-Clause | ||
| Classifier: Development Status :: 5 - Production/Stable | ||
@@ -13,3 +14,2 @@ Classifier: Environment :: Web Environment | ||
| Classifier: Intended Audience :: Developers | ||
| Classifier: License :: OSI Approved :: BSD License | ||
| Classifier: Operating System :: OS Independent | ||
@@ -22,11 +22,13 @@ Classifier: Programming Language :: Python | ||
| Classifier: Typing :: Typed | ||
| Requires-Dist: Werkzeug>=3.1 | ||
| Requires-Dist: Jinja2>=3.1.2 | ||
| Requires-Dist: itsdangerous>=2.2 | ||
| License-File: LICENSE.txt | ||
| Requires-Dist: blinker>=1.9.0 | ||
| Requires-Dist: click>=8.1.3 | ||
| Requires-Dist: blinker>=1.9 | ||
| Requires-Dist: importlib-metadata>=3.6; python_version < '3.10' | ||
| Requires-Dist: importlib-metadata>=3.6.0; python_version < '3.10' | ||
| Requires-Dist: itsdangerous>=2.2.0 | ||
| Requires-Dist: jinja2>=3.1.2 | ||
| Requires-Dist: markupsafe>=2.1.1 | ||
| Requires-Dist: werkzeug>=3.1.0 | ||
| Requires-Dist: asgiref>=3.2 ; extra == "async" | ||
| Requires-Dist: python-dotenv ; extra == "dotenv" | ||
| Project-URL: Changes, https://flask.palletsprojects.com/changes/ | ||
| Project-URL: Changes, https://flask.palletsprojects.com/page/changes/ | ||
| Project-URL: Chat, https://discord.gg/pallets | ||
@@ -41,6 +43,6 @@ Project-URL: Documentation, https://flask.palletsprojects.com/ | ||
| Flask is a lightweight [WSGI][] web application framework. It is designed | ||
| Flask is a lightweight [WSGI] web application framework. It is designed | ||
| to make getting started quick and easy, with the ability to scale up to | ||
| complex applications. It began as a simple wrapper around [Werkzeug][] | ||
| and [Jinja][], and has become one of the most popular Python web | ||
| complex applications. It began as a simple wrapper around [Werkzeug] | ||
| and [Jinja], and has become one of the most popular Python web | ||
| application frameworks. | ||
@@ -57,3 +59,2 @@ | ||
| ## A Simple Example | ||
@@ -77,3 +78,2 @@ | ||
| ## Donate | ||
@@ -84,5 +84,13 @@ | ||
| allow the maintainers to devote more time to the projects, [please | ||
| donate today][]. | ||
| donate today]. | ||
| [please donate today]: https://palletsprojects.com/donate | ||
| ## Contributing | ||
| See our [detailed contributing documentation][contrib] for many ways to | ||
| contribute, including reporting issues, requesting features, asking or answering | ||
| questions, and making PRs. | ||
| [contrib]: https://palletsprojects.com/contributing/ | ||
+174
-18
| [project] | ||
| name = "Flask" | ||
| version = "3.1.0" | ||
| version = "3.1.1" | ||
| description = "A simple framework for building complex web applications." | ||
| readme = "README.md" | ||
| license = {file = "LICENSE.txt"} | ||
| license = "BSD-3-Clause" | ||
| license-files = ["LICENSE.txt"] | ||
| maintainers = [{name = "Pallets", email = "contact@palletsprojects.com"}] | ||
@@ -13,3 +14,2 @@ classifiers = [ | ||
| "Intended Audience :: Developers", | ||
| "License :: OSI Approved :: BSD License", | ||
| "Operating System :: OS Independent", | ||
@@ -25,21 +25,61 @@ "Programming Language :: Python", | ||
| dependencies = [ | ||
| "Werkzeug>=3.1", | ||
| "Jinja2>=3.1.2", | ||
| "itsdangerous>=2.2", | ||
| "blinker>=1.9.0", | ||
| "click>=8.1.3", | ||
| "blinker>=1.9", | ||
| "importlib-metadata>=3.6; python_version < '3.10'", | ||
| "importlib-metadata>=3.6.0; python_version < '3.10'", | ||
| "itsdangerous>=2.2.0", | ||
| "jinja2>=3.1.2", | ||
| "markupsafe>=2.1.1", | ||
| "werkzeug>=3.1.0", | ||
| ] | ||
| [project.optional-dependencies] | ||
| async = ["asgiref>=3.2"] | ||
| dotenv = ["python-dotenv"] | ||
| [dependency-groups] | ||
| dev = [ | ||
| "ruff", | ||
| "tox", | ||
| "tox-uv", | ||
| ] | ||
| docs = [ | ||
| "pallets-sphinx-themes", | ||
| "sphinx", | ||
| "sphinx-tabs", | ||
| "sphinxcontrib-log-cabinet", | ||
| ] | ||
| docs-auto = [ | ||
| "sphinx-autobuild", | ||
| ] | ||
| gha-update = [ | ||
| "gha-update ; python_full_version >= '3.12'", | ||
| ] | ||
| pre-commit = [ | ||
| "pre-commit", | ||
| "pre-commit-uv", | ||
| ] | ||
| tests = [ | ||
| "asgiref", | ||
| "greenlet ; python_version < '3.11'", | ||
| "pytest", | ||
| "python-dotenv", | ||
| ] | ||
| typing = [ | ||
| "asgiref", | ||
| "cryptography", | ||
| "mypy", | ||
| "pyright", | ||
| "pytest", | ||
| "python-dotenv", | ||
| "types-contextvars", | ||
| "types-dataclasses", | ||
| ] | ||
| [project.urls] | ||
| Donate = "https://palletsprojects.com/donate" | ||
| Documentation = "https://flask.palletsprojects.com/" | ||
| Changes = "https://flask.palletsprojects.com/changes/" | ||
| Changes = "https://flask.palletsprojects.com/page/changes/" | ||
| Source = "https://github.com/pallets/flask/" | ||
| Chat = "https://discord.gg/pallets" | ||
| [project.optional-dependencies] | ||
| async = ["asgiref>=3.2"] | ||
| dotenv = ["python-dotenv"] | ||
| [project.scripts] | ||
@@ -59,7 +99,5 @@ flask = "flask.cli:main" | ||
| "examples/", | ||
| "requirements/", | ||
| "tests/", | ||
| "CHANGES.rst", | ||
| "CONTRIBUTING.rst", | ||
| "tox.ini", | ||
| "uv.lock" | ||
| ] | ||
@@ -70,2 +108,5 @@ exclude = [ | ||
| [tool.uv] | ||
| default-groups = ["dev", "pre-commit", "tests", "typing"] | ||
| [tool.pytest.ini_options] | ||
@@ -84,5 +125,12 @@ testpaths = ["tests"] | ||
| [tool.coverage.report] | ||
| exclude_also = [ | ||
| "if t.TYPE_CHECKING", | ||
| "raise NotImplementedError", | ||
| ": \\.{3}", | ||
| ] | ||
| [tool.mypy] | ||
| python_version = "3.9" | ||
| files = ["src/flask", "tests/type_check"] | ||
| files = ["src", "tests/type_check"] | ||
| show_error_codes = true | ||
@@ -103,3 +151,3 @@ pretty = true | ||
| pythonVersion = "3.9" | ||
| include = ["src/flask", "tests/type_check"] | ||
| include = ["src", "tests/type_check"] | ||
| typeCheckingMode = "basic" | ||
@@ -131,1 +179,109 @@ | ||
| ] | ||
| [tool.tox] | ||
| env_list = [ | ||
| "py3.13", "py3.12", "py3.11", "py3.10", "py3.9", | ||
| "pypy3.11", | ||
| "tests-min", "tests-dev", | ||
| "style", | ||
| "typing", | ||
| "docs", | ||
| ] | ||
| [tool.tox.env_run_base] | ||
| description = "pytest on latest dependency versions" | ||
| runner = "uv-venv-lock-runner" | ||
| package = "wheel" | ||
| wheel_build_env = ".pkg" | ||
| constrain_package_deps = true | ||
| use_frozen_constraints = true | ||
| dependency_groups = ["tests"] | ||
| env_tmp_dir = "{toxworkdir}/tmp/{envname}" | ||
| commands = [[ | ||
| "pytest", "-v", "--tb=short", "--basetemp={env_tmp_dir}", | ||
| {replace = "posargs", default = [], extend = true}, | ||
| ]] | ||
| [tool.tox.env.tests-min] | ||
| description = "pytest on minimum dependency versions" | ||
| base_python = ["3.13"] | ||
| commands = [ | ||
| [ | ||
| "uv", "pip", "install", | ||
| "blinker==1.9.0", | ||
| "click==8.1.3", | ||
| "itsdangerous==2.2.0", | ||
| "jinja2==3.1.2", | ||
| "markupsafe==2.1.1", | ||
| "werkzeug==3.1.0", | ||
| ], | ||
| [ | ||
| "pytest", "-v", "--tb=short", "--basetemp={env_tmp_dir}", | ||
| {replace = "posargs", default = [], extend = true}, | ||
| ], | ||
| ] | ||
| [tool.tox.env.tests-dev] | ||
| description = "pytest on development dependency versions (git main branch)" | ||
| base_python = ["3.10"] | ||
| commands = [ | ||
| [ | ||
| "uv", "pip", "install", | ||
| "https://github.com/pallets-eco/blinker/archive/refs/heads/main.tar.gz", | ||
| "https://github.com/pallets/click/archive/refs/heads/main.tar.gz", | ||
| "https://github.com/pallets/itsdangerous/archive/refs/heads/main.tar.gz", | ||
| "https://github.com/pallets/jinja/archive/refs/heads/main.tar.gz", | ||
| "https://github.com/pallets/markupsafe/archive/refs/heads/main.tar.gz", | ||
| "https://github.com/pallets/werkzeug/archive/refs/heads/main.tar.gz", | ||
| ], | ||
| [ | ||
| "pytest", "-v", "--tb=short", "--basetemp={env_tmp_dir}", | ||
| {replace = "posargs", default = [], extend = true}, | ||
| ], | ||
| ] | ||
| [tool.tox.env.style] | ||
| description = "run all pre-commit hooks on all files" | ||
| dependency_groups = ["pre-commit"] | ||
| skip_install = true | ||
| commands = [["pre-commit", "run", "--all-files"]] | ||
| [tool.tox.env.typing] | ||
| description = "run static type checkers" | ||
| dependency_groups = ["typing"] | ||
| commands = [ | ||
| ["mypy"], | ||
| ["pyright"], | ||
| ] | ||
| [tool.tox.env.docs] | ||
| description = "build docs" | ||
| dependency_groups = ["docs"] | ||
| commands = [["sphinx-build", "-E", "-W", "-b", "dirhtml", "docs", "docs/_build/dirhtml"]] | ||
| [tool.tox.env.docs-auto] | ||
| description = "continuously rebuild docs and start a local server" | ||
| dependency_groups = ["docs", "docs-auto"] | ||
| commands = [["sphinx-autobuild", "-W", "-b", "dirhtml", "--watch", "src", "docs", "docs/_build/dirhtml"]] | ||
| [tool.tox.env.update-actions] | ||
| description = "update GitHub Actions pins" | ||
| labels = ["update"] | ||
| dependency_groups = ["gha-update"] | ||
| skip_install = true | ||
| commands = [["gha-update"]] | ||
| [tool.tox.env.update-pre_commit] | ||
| description = "update pre-commit pins" | ||
| labels = ["update"] | ||
| dependency_groups = ["pre-commit"] | ||
| skip_install = true | ||
| commands = [["pre-commit", "autoupdate", "--freeze", "-j4"]] | ||
| [tool.tox.env.update-requirements] | ||
| description = "update uv lock" | ||
| labels = ["update"] | ||
| dependency_groups = [] | ||
| no_default_groups = true | ||
| skip_install = true | ||
| commands = [["uv", "lock", {replace = "posargs", default = ["-U"], extend = true}]] |
+12
-6
| # Flask | ||
| Flask is a lightweight [WSGI][] web application framework. It is designed | ||
| Flask is a lightweight [WSGI] web application framework. It is designed | ||
| to make getting started quick and easy, with the ability to scale up to | ||
| complex applications. It began as a simple wrapper around [Werkzeug][] | ||
| and [Jinja][], and has become one of the most popular Python web | ||
| complex applications. It began as a simple wrapper around [Werkzeug] | ||
| and [Jinja], and has become one of the most popular Python web | ||
| application frameworks. | ||
@@ -18,3 +18,2 @@ | ||
| ## A Simple Example | ||
@@ -38,3 +37,2 @@ | ||
| ## Donate | ||
@@ -45,4 +43,12 @@ | ||
| allow the maintainers to devote more time to the projects, [please | ||
| donate today][]. | ||
| donate today]. | ||
| [please donate today]: https://palletsprojects.com/donate | ||
| ## Contributing | ||
| See our [detailed contributing documentation][contrib] for many ways to | ||
| contribute, including reporting issues, requesting features, asking or answering | ||
| questions, and making PRs. | ||
| [contrib]: https://palletsprojects.com/contributing/ |
+14
-13
@@ -45,17 +45,18 @@ from __future__ import annotations | ||
| if not t.TYPE_CHECKING: | ||
| def __getattr__(name: str) -> t.Any: | ||
| if name == "__version__": | ||
| import importlib.metadata | ||
| import warnings | ||
| def __getattr__(name: str) -> t.Any: | ||
| if name == "__version__": | ||
| import importlib.metadata | ||
| import warnings | ||
| warnings.warn( | ||
| "The '__version__' attribute is deprecated and will be removed in" | ||
| " Flask 3.1. Use feature detection or" | ||
| " 'importlib.metadata.version(\"flask\")' instead.", | ||
| DeprecationWarning, | ||
| stacklevel=2, | ||
| ) | ||
| return importlib.metadata.version("flask") | ||
| warnings.warn( | ||
| "The '__version__' attribute is deprecated and will be removed in" | ||
| " Flask 3.2. Use feature detection or" | ||
| " 'importlib.metadata.version(\"flask\")' instead.", | ||
| DeprecationWarning, | ||
| stacklevel=2, | ||
| ) | ||
| return importlib.metadata.version("flask") | ||
| raise AttributeError(name) | ||
| raise AttributeError(name) |
+4
-4
@@ -268,5 +268,5 @@ from __future__ import annotations | ||
| if self.has_static_folder: | ||
| assert ( | ||
| bool(static_host) == host_matching | ||
| ), "Invalid static_host/host_matching combination" | ||
| assert bool(static_host) == host_matching, ( | ||
| "Invalid static_host/host_matching combination" | ||
| ) | ||
| # Use a weakref to avoid creating a reference cycle between the app | ||
@@ -1226,3 +1226,3 @@ # and the view function (see #3761). | ||
| rv = self.response_class( | ||
| rv, | ||
| rv, # pyright: ignore | ||
| status=status, | ||
@@ -1229,0 +1229,0 @@ headers=headers, # type: ignore[arg-type] |
+3
-1
@@ -687,3 +687,5 @@ from __future__ import annotations | ||
| def parse_args(self, ctx: click.Context, args: list[str]) -> list[str]: | ||
| if not args and self.no_args_is_help: | ||
| if (not args and self.no_args_is_help) or ( | ||
| len(args) == 1 and args[0] in self.get_help_option_names(ctx) | ||
| ): | ||
| # Attempt to load --env-file and --app early in case they | ||
@@ -690,0 +692,0 @@ # were given as env vars. Otherwise no_args_is_help will not |
@@ -321,3 +321,3 @@ from __future__ import annotations | ||
| keys: list[str | bytes] = [app.secret_key] | ||
| keys: list[str | bytes] = [] | ||
@@ -327,2 +327,3 @@ if fallbacks := app.config["SECRET_KEY_FALLBACKS"]: | ||
| keys.append(app.secret_key) # itsdangerous expects current key at top | ||
| return URLSafeTimedSerializer( | ||
@@ -329,0 +330,0 @@ keys, # type: ignore[arg-type] |
@@ -13,2 +13,3 @@ from __future__ import annotations | ||
| from click.testing import CliRunner | ||
| from click.testing import Result | ||
| from werkzeug.test import Client | ||
@@ -61,5 +62,5 @@ from werkzeug.wrappers import Request as BaseRequest | ||
| base_url is not None | ||
| ) != bool( | ||
| subdomain or url_scheme | ||
| ), 'Cannot pass "subdomain" or "url_scheme" with "base_url".' | ||
| ) != bool(subdomain or url_scheme), ( | ||
| 'Cannot pass "subdomain" or "url_scheme" with "base_url".' | ||
| ) | ||
@@ -278,3 +279,3 @@ if base_url is None: | ||
| self, cli: t.Any = None, args: t.Any = None, **kwargs: t.Any | ||
| ) -> t.Any: | ||
| ) -> Result: | ||
| """Invokes a CLI command in an isolated environment. See | ||
@@ -281,0 +282,0 @@ :meth:`CliRunner.invoke <click.testing.CliRunner.invoke>` for |
| from __future__ import annotations | ||
| import collections.abc as cabc | ||
| import typing as t | ||
@@ -20,2 +21,4 @@ | ||
| t.Iterator[bytes], | ||
| cabc.AsyncIterable[str], # for Quart, until App is generic. | ||
| cabc.AsyncIterable[bytes], | ||
| ] | ||
@@ -22,0 +25,0 @@ |
+0
-32
| import os | ||
| import pkgutil | ||
| import sys | ||
@@ -99,33 +98,2 @@ | ||
| @pytest.fixture(params=(True, False)) | ||
| def limit_loader(request, monkeypatch): | ||
| """Patch pkgutil.get_loader to give loader without get_filename or archive. | ||
| This provides for tests where a system has custom loaders, e.g. Google App | ||
| Engine's HardenedModulesHook, which have neither the `get_filename` method | ||
| nor the `archive` attribute. | ||
| This fixture will run the testcase twice, once with and once without the | ||
| limitation/mock. | ||
| """ | ||
| if not request.param: | ||
| return | ||
| class LimitedLoader: | ||
| def __init__(self, loader): | ||
| self.loader = loader | ||
| def __getattr__(self, name): | ||
| if name in {"archive", "get_filename"}: | ||
| raise AttributeError(f"Mocking a loader which does not have {name!r}.") | ||
| return getattr(self.loader, name) | ||
| old_get_loader = pkgutil.get_loader | ||
| def get_loader(*args, **kwargs): | ||
| return LimitedLoader(old_get_loader(*args, **kwargs)) | ||
| monkeypatch.setattr(pkgutil, "get_loader", get_loader) | ||
| @pytest.fixture | ||
@@ -132,0 +100,0 @@ def modules_tmp_path(tmp_path, monkeypatch): |
+11
-4
@@ -384,10 +384,17 @@ import gc | ||
| # Set session with initial secret key | ||
| # Set session with initial secret key, and two valid expiring keys | ||
| app.secret_key, app.config["SECRET_KEY_FALLBACKS"] = ( | ||
| "0 key", | ||
| ["-1 key", "-2 key"], | ||
| ) | ||
| client.post() | ||
| assert client.get().json == {"a": 1} | ||
| # Change secret key, session can't be loaded and appears empty | ||
| app.secret_key = "new test key" | ||
| app.secret_key = "? key" | ||
| assert client.get().json == {} | ||
| # Add initial secret key as fallback, session can be loaded | ||
| app.config["SECRET_KEY_FALLBACKS"] = ["test key"] | ||
| # Rotate the valid keys, session can be loaded | ||
| app.secret_key, app.config["SECRET_KEY_FALLBACKS"] = ( | ||
| "+1 key", | ||
| ["0 key", "-1 key"], | ||
| ) | ||
| assert client.get().json == {"a": 1} | ||
@@ -394,0 +401,0 @@ |
@@ -66,3 +66,3 @@ import os | ||
| def test_installed_module_paths( | ||
| modules_tmp_path, modules_tmp_path_prefix, purge_module, site_packages, limit_loader | ||
| modules_tmp_path, modules_tmp_path_prefix, purge_module, site_packages | ||
| ): | ||
@@ -82,3 +82,3 @@ (site_packages / "site_app.py").write_text( | ||
| def test_installed_package_paths( | ||
| limit_loader, modules_tmp_path, modules_tmp_path_prefix, purge_module, monkeypatch | ||
| modules_tmp_path, modules_tmp_path_prefix, purge_module, monkeypatch | ||
| ): | ||
@@ -102,3 +102,3 @@ installed_path = modules_tmp_path / "path" | ||
| def test_prefix_package_paths( | ||
| limit_loader, modules_tmp_path, modules_tmp_path_prefix, purge_module, site_packages | ||
| modules_tmp_path, modules_tmp_path_prefix, purge_module, site_packages | ||
| ): | ||
@@ -105,0 +105,0 @@ app = site_packages / "site_package" |
-238
| How to contribute to Flask | ||
| ========================== | ||
| Thank you for considering contributing to Flask! | ||
| Support questions | ||
| ----------------- | ||
| Please don't use the issue tracker for this. The issue tracker is a tool | ||
| to address bugs and feature requests in Flask itself. Use one of the | ||
| following resources for questions about using Flask or issues with your | ||
| own code: | ||
| - The ``#questions`` channel on our Discord chat: | ||
| https://discord.gg/pallets | ||
| - Ask on `Stack Overflow`_. Search with Google first using: | ||
| ``site:stackoverflow.com flask {search term, exception message, etc.}`` | ||
| - Ask on our `GitHub Discussions`_ for long term discussion or larger | ||
| questions. | ||
| .. _Stack Overflow: https://stackoverflow.com/questions/tagged/flask?tab=Frequent | ||
| .. _GitHub Discussions: https://github.com/pallets/flask/discussions | ||
| Reporting issues | ||
| ---------------- | ||
| Include the following information in your post: | ||
| - Describe what you expected to happen. | ||
| - If possible, include a `minimal reproducible example`_ to help us | ||
| identify the issue. This also helps check that the issue is not with | ||
| your own code. | ||
| - Describe what actually happened. Include the full traceback if there | ||
| was an exception. | ||
| - List your Python and Flask versions. If possible, check if this | ||
| issue is already fixed in the latest releases or the latest code in | ||
| the repository. | ||
| .. _minimal reproducible example: https://stackoverflow.com/help/minimal-reproducible-example | ||
| Submitting patches | ||
| ------------------ | ||
| If there is not an open issue for what you want to submit, prefer | ||
| opening one for discussion before working on a PR. You can work on any | ||
| issue that doesn't have an open PR linked to it or a maintainer assigned | ||
| to it. These show up in the sidebar. No need to ask if you can work on | ||
| an issue that interests you. | ||
| Include the following in your patch: | ||
| - Use `Black`_ to format your code. This and other tools will run | ||
| automatically if you install `pre-commit`_ using the instructions | ||
| below. | ||
| - Include tests if your patch adds or changes code. Make sure the test | ||
| fails without your patch. | ||
| - Update any relevant docs pages and docstrings. Docs pages and | ||
| docstrings should be wrapped at 72 characters. | ||
| - Add an entry in ``CHANGES.rst``. Use the same style as other | ||
| entries. Also include ``.. versionchanged::`` inline changelogs in | ||
| relevant docstrings. | ||
| .. _Black: https://black.readthedocs.io | ||
| .. _pre-commit: https://pre-commit.com | ||
| First time setup using GitHub Codespaces | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| `GitHub Codespaces`_ creates a development environment that is already set up for the | ||
| project. By default it opens in Visual Studio Code for the Web, but this can | ||
| be changed in your GitHub profile settings to use Visual Studio Code or JetBrains | ||
| PyCharm on your local computer. | ||
| - Make sure you have a `GitHub account`_. | ||
| - From the project's repository page, click the green "Code" button and then "Create | ||
| codespace on main". | ||
| - The codespace will be set up, then Visual Studio Code will open. However, you'll | ||
| need to wait a bit longer for the Python extension to be installed. You'll know it's | ||
| ready when the terminal at the bottom shows that the virtualenv was activated. | ||
| - Check out a branch and `start coding`_. | ||
| .. _GitHub Codespaces: https://docs.github.com/en/codespaces | ||
| .. _devcontainer: https://docs.github.com/en/codespaces/setting-up-your-project-for-codespaces/adding-a-dev-container-configuration/introduction-to-dev-containers | ||
| First time setup in your local environment | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| - Make sure you have a `GitHub account`_. | ||
| - Download and install the `latest version of git`_. | ||
| - Configure git with your `username`_ and `email`_. | ||
| .. code-block:: text | ||
| $ git config --global user.name 'your name' | ||
| $ git config --global user.email 'your email' | ||
| - Fork Flask to your GitHub account by clicking the `Fork`_ button. | ||
| - `Clone`_ your fork locally, replacing ``your-username`` in the command below with | ||
| your actual username. | ||
| .. code-block:: text | ||
| $ git clone https://github.com/your-username/flask | ||
| $ cd flask | ||
| - Create a virtualenv. Use the latest version of Python. | ||
| - Linux/macOS | ||
| .. code-block:: text | ||
| $ python3 -m venv .venv | ||
| $ . .venv/bin/activate | ||
| - Windows | ||
| .. code-block:: text | ||
| > py -3 -m venv .venv | ||
| > .venv\Scripts\activate | ||
| - Install the development dependencies, then install Flask in editable mode. | ||
| .. code-block:: text | ||
| $ python -m pip install -U pip | ||
| $ pip install -r requirements/dev.txt && pip install -e . | ||
| - Install the pre-commit hooks. | ||
| .. code-block:: text | ||
| $ pre-commit install --install-hooks | ||
| .. _GitHub account: https://github.com/join | ||
| .. _latest version of git: https://git-scm.com/downloads | ||
| .. _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 | ||
| .. _Fork: https://github.com/pallets/flask/fork | ||
| .. _Clone: https://docs.github.com/en/github/getting-started-with-github/fork-a-repo#step-2-create-a-local-clone-of-your-fork | ||
| .. _start coding: | ||
| Start coding | ||
| ~~~~~~~~~~~~ | ||
| - Create a branch to identify the issue you would like to work on. If you're | ||
| submitting a bug or documentation fix, branch off of the latest ".x" branch. | ||
| .. code-block:: text | ||
| $ git fetch origin | ||
| $ git checkout -b your-branch-name origin/2.0.x | ||
| If you're submitting a feature addition or change, branch off of the "main" branch. | ||
| .. code-block:: text | ||
| $ git fetch origin | ||
| $ git checkout -b your-branch-name origin/main | ||
| - Using your favorite editor, make your changes, `committing as you go`_. | ||
| - If you are in a codespace, you will be prompted to `create a fork`_ the first | ||
| time you make a commit. Enter ``Y`` to continue. | ||
| - Include tests that cover any code changes you make. Make sure the test fails without | ||
| your patch. Run the tests as described below. | ||
| - Push your commits to your fork on GitHub and `create a pull request`_. Link to the | ||
| issue being addressed with ``fixes #123`` in the pull request description. | ||
| .. code-block:: text | ||
| $ git push --set-upstream origin your-branch-name | ||
| .. _committing as you go: https://afraid-to-commit.readthedocs.io/en/latest/git/commandlinegit.html#commit-your-changes | ||
| .. _create a fork: https://docs.github.com/en/codespaces/developing-in-codespaces/using-source-control-in-your-codespace#about-automatic-forking | ||
| .. _create a pull request: https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request | ||
| .. _Running the tests: | ||
| Running the tests | ||
| ~~~~~~~~~~~~~~~~~ | ||
| Run the basic test suite with pytest. | ||
| .. code-block:: text | ||
| $ pytest | ||
| This runs the tests for the current environment, which is usually | ||
| sufficient. CI will run the full suite when you submit your pull | ||
| request. You can run the full test suite with tox if you don't want to | ||
| wait. | ||
| .. code-block:: text | ||
| $ tox | ||
| Running test coverage | ||
| ~~~~~~~~~~~~~~~~~~~~~ | ||
| Generating a report of lines that do not have test coverage can indicate | ||
| where to start contributing. Run ``pytest`` using ``coverage`` and | ||
| generate a report. | ||
| If you are using GitHub Codespaces, ``coverage`` is already installed | ||
| so you can skip the installation command. | ||
| .. code-block:: text | ||
| $ pip install coverage | ||
| $ coverage run -m pytest | ||
| $ coverage html | ||
| Open ``htmlcov/index.html`` in your browser to explore the report. | ||
| Read more about `coverage <https://coverage.readthedocs.io>`__. | ||
| Building the docs | ||
| ~~~~~~~~~~~~~~~~~ | ||
| Build the docs in the ``docs`` directory using Sphinx. | ||
| .. code-block:: text | ||
| $ cd docs | ||
| $ make html | ||
| Open ``_build/html/index.html`` in your browser to view the docs. | ||
| Read more about `Sphinx <https://www.sphinx-doc.org/en/stable/>`__. |
| build |
| # | ||
| # This file is autogenerated by pip-compile with Python 3.13 | ||
| # by the following command: | ||
| # | ||
| # pip-compile build.in | ||
| # | ||
| build==1.2.2.post1 | ||
| # via -r build.in | ||
| packaging==24.2 | ||
| # via build | ||
| pyproject-hooks==1.2.0 | ||
| # via build |
| -r docs.txt | ||
| -r tests.txt | ||
| -r typing.txt | ||
| pre-commit | ||
| tox |
| # | ||
| # This file is autogenerated by pip-compile with Python 3.13 | ||
| # by the following command: | ||
| # | ||
| # pip-compile dev.in | ||
| # | ||
| alabaster==1.0.0 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/docs.txt | ||
| # sphinx | ||
| asgiref==3.8.1 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/tests.txt | ||
| # -r /Users/david/Projects/flask/requirements/typing.txt | ||
| babel==2.16.0 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/docs.txt | ||
| # sphinx | ||
| cachetools==5.5.0 | ||
| # via tox | ||
| certifi==2024.8.30 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/docs.txt | ||
| # requests | ||
| cffi==1.17.1 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/typing.txt | ||
| # cryptography | ||
| cfgv==3.4.0 | ||
| # via pre-commit | ||
| chardet==5.2.0 | ||
| # via tox | ||
| charset-normalizer==3.4.0 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/docs.txt | ||
| # requests | ||
| colorama==0.4.6 | ||
| # via tox | ||
| cryptography==43.0.3 | ||
| # via -r /Users/david/Projects/flask/requirements/typing.txt | ||
| distlib==0.3.9 | ||
| # via virtualenv | ||
| docutils==0.21.2 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/docs.txt | ||
| # sphinx | ||
| # sphinx-tabs | ||
| filelock==3.16.1 | ||
| # via | ||
| # tox | ||
| # virtualenv | ||
| identify==2.6.2 | ||
| # via pre-commit | ||
| idna==3.10 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/docs.txt | ||
| # requests | ||
| imagesize==1.4.1 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/docs.txt | ||
| # sphinx | ||
| iniconfig==2.0.0 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/tests.txt | ||
| # -r /Users/david/Projects/flask/requirements/typing.txt | ||
| # pytest | ||
| jinja2==3.1.4 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/docs.txt | ||
| # sphinx | ||
| markupsafe==3.0.2 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/docs.txt | ||
| # jinja2 | ||
| mypy==1.13.0 | ||
| # via -r /Users/david/Projects/flask/requirements/typing.txt | ||
| mypy-extensions==1.0.0 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/typing.txt | ||
| # mypy | ||
| nodeenv==1.9.1 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/typing.txt | ||
| # pre-commit | ||
| # pyright | ||
| packaging==24.2 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/docs.txt | ||
| # -r /Users/david/Projects/flask/requirements/tests.txt | ||
| # -r /Users/david/Projects/flask/requirements/typing.txt | ||
| # pallets-sphinx-themes | ||
| # pyproject-api | ||
| # pytest | ||
| # sphinx | ||
| # tox | ||
| pallets-sphinx-themes==2.3.0 | ||
| # via -r /Users/david/Projects/flask/requirements/docs.txt | ||
| platformdirs==4.3.6 | ||
| # via | ||
| # tox | ||
| # virtualenv | ||
| pluggy==1.5.0 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/tests.txt | ||
| # -r /Users/david/Projects/flask/requirements/typing.txt | ||
| # pytest | ||
| # tox | ||
| pre-commit==4.0.1 | ||
| # via -r dev.in | ||
| pycparser==2.22 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/typing.txt | ||
| # cffi | ||
| pygments==2.18.0 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/docs.txt | ||
| # sphinx | ||
| # sphinx-tabs | ||
| pyproject-api==1.8.0 | ||
| # via tox | ||
| pyright==1.1.389 | ||
| # via -r /Users/david/Projects/flask/requirements/typing.txt | ||
| pytest==8.3.3 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/tests.txt | ||
| # -r /Users/david/Projects/flask/requirements/typing.txt | ||
| python-dotenv==1.0.1 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/tests.txt | ||
| # -r /Users/david/Projects/flask/requirements/typing.txt | ||
| pyyaml==6.0.2 | ||
| # via pre-commit | ||
| requests==2.32.3 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/docs.txt | ||
| # sphinx | ||
| snowballstemmer==2.2.0 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/docs.txt | ||
| # sphinx | ||
| sphinx==8.1.3 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/docs.txt | ||
| # pallets-sphinx-themes | ||
| # sphinx-notfound-page | ||
| # sphinx-tabs | ||
| # sphinxcontrib-log-cabinet | ||
| sphinx-notfound-page==1.0.4 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/docs.txt | ||
| # pallets-sphinx-themes | ||
| sphinx-tabs==3.4.7 | ||
| # via -r /Users/david/Projects/flask/requirements/docs.txt | ||
| sphinxcontrib-applehelp==2.0.0 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/docs.txt | ||
| # sphinx | ||
| sphinxcontrib-devhelp==2.0.0 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/docs.txt | ||
| # sphinx | ||
| sphinxcontrib-htmlhelp==2.1.0 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/docs.txt | ||
| # sphinx | ||
| sphinxcontrib-jsmath==1.0.1 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/docs.txt | ||
| # sphinx | ||
| sphinxcontrib-log-cabinet==1.0.1 | ||
| # via -r /Users/david/Projects/flask/requirements/docs.txt | ||
| sphinxcontrib-qthelp==2.0.0 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/docs.txt | ||
| # sphinx | ||
| sphinxcontrib-serializinghtml==2.0.0 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/docs.txt | ||
| # sphinx | ||
| tox==4.23.2 | ||
| # via -r dev.in | ||
| types-contextvars==2.4.7.3 | ||
| # via -r /Users/david/Projects/flask/requirements/typing.txt | ||
| types-dataclasses==0.6.6 | ||
| # via -r /Users/david/Projects/flask/requirements/typing.txt | ||
| typing-extensions==4.12.2 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/typing.txt | ||
| # mypy | ||
| # pyright | ||
| urllib3==2.2.3 | ||
| # via | ||
| # -r /Users/david/Projects/flask/requirements/docs.txt | ||
| # requests | ||
| virtualenv==20.27.1 | ||
| # via | ||
| # pre-commit | ||
| # tox |
| pallets-sphinx-themes | ||
| sphinx | ||
| sphinxcontrib-log-cabinet | ||
| sphinx-tabs |
| # | ||
| # This file is autogenerated by pip-compile with Python 3.13 | ||
| # by the following command: | ||
| # | ||
| # pip-compile docs.in | ||
| # | ||
| alabaster==1.0.0 | ||
| # via sphinx | ||
| babel==2.16.0 | ||
| # via sphinx | ||
| certifi==2024.8.30 | ||
| # via requests | ||
| charset-normalizer==3.4.0 | ||
| # via requests | ||
| docutils==0.21.2 | ||
| # via | ||
| # sphinx | ||
| # sphinx-tabs | ||
| idna==3.10 | ||
| # via requests | ||
| imagesize==1.4.1 | ||
| # via sphinx | ||
| jinja2==3.1.4 | ||
| # via sphinx | ||
| markupsafe==3.0.2 | ||
| # via jinja2 | ||
| packaging==24.2 | ||
| # via | ||
| # pallets-sphinx-themes | ||
| # sphinx | ||
| pallets-sphinx-themes==2.3.0 | ||
| # via -r docs.in | ||
| pygments==2.18.0 | ||
| # via | ||
| # sphinx | ||
| # sphinx-tabs | ||
| requests==2.32.3 | ||
| # via sphinx | ||
| snowballstemmer==2.2.0 | ||
| # via sphinx | ||
| sphinx==8.1.3 | ||
| # via | ||
| # -r docs.in | ||
| # pallets-sphinx-themes | ||
| # sphinx-notfound-page | ||
| # sphinx-tabs | ||
| # sphinxcontrib-log-cabinet | ||
| sphinx-notfound-page==1.0.4 | ||
| # via pallets-sphinx-themes | ||
| sphinx-tabs==3.4.7 | ||
| # via -r docs.in | ||
| sphinxcontrib-applehelp==2.0.0 | ||
| # via sphinx | ||
| sphinxcontrib-devhelp==2.0.0 | ||
| # via sphinx | ||
| 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==2.0.0 | ||
| # via sphinx | ||
| sphinxcontrib-serializinghtml==2.0.0 | ||
| # via sphinx | ||
| urllib3==2.2.3 | ||
| # via requests |
| https://github.com/pallets/werkzeug/archive/refs/heads/main.tar.gz | ||
| https://github.com/pallets/jinja/archive/refs/heads/main.tar.gz | ||
| https://github.com/pallets/markupsafe/archive/refs/heads/main.tar.gz | ||
| https://github.com/pallets/itsdangerous/archive/refs/heads/main.tar.gz | ||
| https://github.com/pallets/click/archive/refs/heads/main.tar.gz | ||
| https://github.com/pallets-eco/blinker/archive/refs/heads/main.tar.gz |
| werkzeug==3.1.0 | ||
| jinja2==3.1.2 | ||
| markupsafe==2.1.1 | ||
| itsdangerous==2.2.0 | ||
| click==8.1.3 | ||
| blinker==1.9.0 |
| # | ||
| # This file is autogenerated by pip-compile with Python 3.13 | ||
| # by the following command: | ||
| # | ||
| # pip-compile tests-min.in | ||
| # | ||
| blinker==1.9.0 | ||
| # via -r tests-min.in | ||
| click==8.1.3 | ||
| # via -r tests-min.in | ||
| itsdangerous==2.2.0 | ||
| # via -r tests-min.in | ||
| jinja2==3.1.2 | ||
| # via -r tests-min.in | ||
| markupsafe==2.1.1 | ||
| # via | ||
| # -r tests-min.in | ||
| # jinja2 | ||
| # werkzeug | ||
| werkzeug==3.1.0 | ||
| # via -r tests-min.in |
| pytest | ||
| asgiref | ||
| greenlet ; python_version < "3.11" | ||
| python-dotenv |
| # | ||
| # This file is autogenerated by pip-compile with Python 3.13 | ||
| # by the following command: | ||
| # | ||
| # pip-compile tests.in | ||
| # | ||
| asgiref==3.8.1 | ||
| # via -r tests.in | ||
| iniconfig==2.0.0 | ||
| # via pytest | ||
| packaging==24.2 | ||
| # via pytest | ||
| pluggy==1.5.0 | ||
| # via pytest | ||
| pytest==8.3.3 | ||
| # via -r tests.in | ||
| python-dotenv==1.0.1 | ||
| # via -r tests.in |
| mypy | ||
| pyright | ||
| pytest | ||
| types-contextvars | ||
| types-dataclasses | ||
| asgiref | ||
| cryptography | ||
| python-dotenv |
| # | ||
| # This file is autogenerated by pip-compile with Python 3.13 | ||
| # by the following command: | ||
| # | ||
| # pip-compile typing.in | ||
| # | ||
| asgiref==3.8.1 | ||
| # via -r typing.in | ||
| cffi==1.17.1 | ||
| # via cryptography | ||
| cryptography==43.0.3 | ||
| # via -r typing.in | ||
| iniconfig==2.0.0 | ||
| # via pytest | ||
| mypy==1.13.0 | ||
| # via -r typing.in | ||
| mypy-extensions==1.0.0 | ||
| # via mypy | ||
| nodeenv==1.9.1 | ||
| # via pyright | ||
| packaging==24.2 | ||
| # via pytest | ||
| pluggy==1.5.0 | ||
| # via pytest | ||
| pycparser==2.22 | ||
| # via cffi | ||
| pyright==1.1.389 | ||
| # via -r typing.in | ||
| pytest==8.3.3 | ||
| # via -r typing.in | ||
| python-dotenv==1.0.1 | ||
| # via -r typing.in | ||
| types-contextvars==2.4.7.3 | ||
| # via -r typing.in | ||
| types-dataclasses==0.6.6 | ||
| # via -r typing.in | ||
| typing-extensions==4.12.2 | ||
| # via | ||
| # mypy | ||
| # pyright |
-62
| [tox] | ||
| envlist = | ||
| py3{13,12,11,10,9} | ||
| pypy310 | ||
| py313-min | ||
| py39-dev | ||
| style | ||
| typing | ||
| docs | ||
| skip_missing_interpreters = true | ||
| [testenv] | ||
| package = wheel | ||
| wheel_build_env = .pkg | ||
| envtmpdir = {toxworkdir}/tmp/{envname} | ||
| constrain_package_deps = true | ||
| use_frozen_constraints = true | ||
| deps = | ||
| -r requirements/tests.txt | ||
| min: -r requirements/tests-min.txt | ||
| dev: -r requirements/tests-dev.txt | ||
| commands = pytest -v --tb=short --basetemp={envtmpdir} {posargs} | ||
| [testenv:style] | ||
| deps = pre-commit | ||
| skip_install = true | ||
| commands = pre-commit run --all-files | ||
| [testenv:typing] | ||
| deps = -r requirements/typing.txt | ||
| commands = | ||
| mypy | ||
| pyright | ||
| [testenv:docs] | ||
| deps = -r requirements/docs.txt | ||
| commands = sphinx-build -E -W -b dirhtml docs docs/_build/dirhtml | ||
| [testenv:update-actions] | ||
| labels = update | ||
| deps = gha-update | ||
| skip_install = true | ||
| commands = gha-update | ||
| [testenv:update-pre_commit] | ||
| labels = update | ||
| deps = pre-commit | ||
| skip_install = true | ||
| commands = pre-commit autoupdate -j4 | ||
| [testenv:update-requirements] | ||
| labels = update | ||
| deps = pip-tools | ||
| skip_install = true | ||
| change_dir = requirements | ||
| commands = | ||
| pip-compile build.in -q {posargs:-U} | ||
| pip-compile docs.in -q {posargs:-U} | ||
| pip-compile tests.in -q {posargs:-U} | ||
| pip-compile tests-min.in -q | ||
| pip-compile typing.in -q {posargs:-U} | ||
| pip-compile dev.in -q {posargs:-U} |
Sorry, the diff of this file is too big to display
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
1767277
15.29%221
-5.96%13865
-0.04%