├── testproject
├── __init__.py
├── migrations
│ ├── __init__.py
│ └── 0001_initial.py
├── urls.py
├── constants.py
├── requirements.in
├── templates
│ ├── home.html
│ └── model_form.html
├── models.py
├── views.py
├── manage.py
├── forms.py
├── settings.py
└── requirements.txt
├── docs
├── _static
│ └── .do-not-delete
├── requirements.in
├── index.rst
├── setup.rst
├── requirements.txt
├── settings.rst
├── usage.rst
├── Makefile
└── conf.py
├── django_bleach
├── tests
│ ├── __init__.py
│ ├── test_templatetags.py
│ ├── test_settings.py
│ ├── test_modelformfield.py
│ ├── test_models.py
│ └── test_forms.py
├── templatetags
│ ├── __init__.py
│ └── bleach_tags.py
├── __init__.py
├── utils.py
├── forms.py
└── models.py
├── .pep8
├── requirements.in
├── requirements
├── requirements.in
├── compile.py
├── py311-django41.txt
├── py311-django42.txt
├── py312-django42.txt
├── py38-django32.txt
├── py38-django40.txt
├── py38-django41.txt
├── py38-django42.txt
├── py39-django32.txt
├── py39-django40.txt
├── py39-django41.txt
├── py39-django42.txt
├── py310-django32.txt
├── py310-django40.txt
├── py310-django41.txt
└── py310-django42.txt
├── MANIFEST.in
├── .editorconfig
├── .github
├── dependabot.yml
├── pull_request_template.md
├── workflows
│ ├── docs.yml
│ ├── publish-to-live-pypi.yml
│ ├── publish-to-test-pypi.yml
│ ├── lint.yml
│ ├── codeql-analysis.yml
│ └── test.yml
└── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── .readthedocs.yaml
├── tox.ini
├── setup.cfg
├── LICENSE
├── .pre-commit-config.yaml
├── requirements.txt
├── .gitignore
├── pyproject.toml
├── setup.py
├── CHANGELOG.md
└── README.rst
/testproject/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/_static/.do-not-delete:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/django_bleach/tests/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/django_bleach/templatetags/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/testproject/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.pep8:
--------------------------------------------------------------------------------
1 | [flake8]
2 | ignore = E501
3 | exclude = migrations,.venv_*,docs
--------------------------------------------------------------------------------
/requirements.in:
--------------------------------------------------------------------------------
1 | bump2version
2 | pip-tools
3 | pre-commit
4 | tox
5 | wheel
6 |
--------------------------------------------------------------------------------
/requirements/requirements.in:
--------------------------------------------------------------------------------
1 | bleach>=5,<6
2 | coverage[toml]
3 | mock
4 | tinycss2
5 |
--------------------------------------------------------------------------------
/django_bleach/__init__.py:
--------------------------------------------------------------------------------
1 | __version__ = "3.1.0"
2 |
3 | VERSION = __version__.split(".")
4 |
--------------------------------------------------------------------------------
/docs/requirements.in:
--------------------------------------------------------------------------------
1 | furo
2 | MarkupSafe
3 | sphinx
4 | sphinx-autobuild
5 | sphinxext-opengraph
6 | sphinxcontrib-spelling
7 | sphinx-autobuild
8 |
--------------------------------------------------------------------------------
/testproject/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from .views import home, model_form
4 |
5 |
6 | urlpatterns = [
7 | path("", home, name="home"),
8 | path("model_form/", model_form, name="model_form"),
9 | ]
10 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include LICENSE
2 | include README.rst
3 | include CHANGELOG.md
4 | include docs/*.rst
5 | prune docs/_build
6 | graft testproject
7 | global-exclude coverage.xml
8 | global-exclude .coverage
9 | recursive-exclude * *.pyc __pycache__ .DS_Store
10 |
--------------------------------------------------------------------------------
/testproject/constants.py:
--------------------------------------------------------------------------------
1 | ALLOWED_ATTRIBUTES = {"*": ["class", "style"], "a": ["href", "title"]}
2 |
3 | ALLOWED_CSS_PROPERTIES = ["color"]
4 |
5 | ALLOWED_PROTOCOLS = [
6 | "https",
7 | "data",
8 | ]
9 |
10 | ALLOWED_STYLES = ALLOWED_CSS_PROPERTIES
11 |
12 | ALLOWED_TAGS = ["a", "li", "ul"]
13 |
--------------------------------------------------------------------------------
/testproject/requirements.in:
--------------------------------------------------------------------------------
1 | bleach
2 | django
3 | coverage
4 | mock
5 | flake8
6 | flake8-broken-line
7 | flake8-bugbear
8 | flake8-builtins
9 | flake8-commas
10 | flake8-comprehensions
11 | flake8-eradicate
12 | flake8-quotes
13 | flake8-tidy-imports
14 | pep8-naming
15 | pip-tools
16 | sphinx
17 | sphinx-rtd-theme
18 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 |
3 | root = true
4 |
5 | [*]
6 | charset = utf-8
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 | indent_style = space
11 | indent_size = 4
12 |
13 | [*.py]
14 | max_line_length = 80
15 |
16 | [*.toml]
17 | indent_size = 2
18 |
19 | [*.yml]
20 | indent_size = 2
21 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: github-actions
4 | directory: "/"
5 | commit-message:
6 | prefix: "ci:"
7 | include: "scope"
8 | schedule:
9 | interval: weekly
10 | - package-ecosystem: pip
11 | directory: "/"
12 | schedule:
13 | interval: weekly
14 | groups:
15 | python-packages:
16 | patterns:
17 | - "*"
18 |
--------------------------------------------------------------------------------
/.readthedocs.yaml:
--------------------------------------------------------------------------------
1 | # Read the Docs configuration file
2 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
3 | version: 2
4 |
5 | build:
6 | os: ubuntu-22.04
7 | tools:
8 | python: "3.11"
9 |
10 | sphinx:
11 | configuration: docs/conf.py
12 | fail_on_warning: false
13 |
14 | formats:
15 | - epub
16 | - pdf
17 |
18 | python:
19 | install:
20 | - requirements: docs/requirements.txt
21 |
--------------------------------------------------------------------------------
/testproject/templates/home.html:
--------------------------------------------------------------------------------
1 |
2 | Form example
3 |
13 | Model form example(Note: you need to migrate database to use it)
14 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | # Description
2 |
3 | Describe:
4 |
5 | * Content of the pull request
6 | * Feature added / Problem fixed
7 |
8 | ## References
9 |
10 | Provide any github issue fixed (as in ``Fix #XYZ``)
11 |
12 | # Checklist
13 |
14 | * [ ] I have ran `tox` to ensure tests pass
15 | * [ ] Usage documentation added in case of new features
16 | * [ ] README & CHANGELOG updated
17 | * [ ] Tests added / I have not lowered coverage from 100%
18 |
--------------------------------------------------------------------------------
/tox.ini:
--------------------------------------------------------------------------------
1 | [tox]
2 | requires =
3 | tox>=4.2
4 | env_list =
5 | py312-django{42}
6 | py311-django{42, 41}
7 | py310-django{42, 41, 40, 32}
8 | py39-django{42, 41, 40, 32}
9 | py38-django{42, 41, 40, 32}
10 |
11 | [testenv]
12 | package = wheel
13 | deps =
14 | -r {toxinidir}/requirements/{envname}.txt
15 | set_env =
16 | PYTHONDEVMODE = 1
17 | PYTHONDONTWRITEBYTECODE=1
18 | commands =
19 | python \
20 | -W error::ResourceWarning \
21 | -W error::DeprecationWarning \
22 | -W error::PendingDeprecationWarning \
23 | -m coverage run testproject/manage.py test django_bleach
24 |
--------------------------------------------------------------------------------
/.github/workflows/docs.yml:
--------------------------------------------------------------------------------
1 | name: Docs
2 |
3 | on: [push, pull_request]
4 |
5 | concurrency:
6 | group: ${{ github.workflow }}-${{ github.ref }}
7 | cancel-in-progress: true
8 |
9 | jobs:
10 | docs:
11 | runs-on: ubuntu-latest
12 | name: docs
13 | steps:
14 | - name: Checkout
15 | uses: actions/checkout@v3
16 | - name: Set up Python
17 | uses: actions/setup-python@v5
18 | with:
19 | python-version: 3.11
20 | - run: python -m pip install sphinx
21 | - name: Build docs
22 | run: |
23 | cd docs
24 | sphinx-build -W -b html -d _build/doctrees . _build/html
25 |
--------------------------------------------------------------------------------
/testproject/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 |
3 | from bleach.css_sanitizer import CSSSanitizer
4 |
5 | from django_bleach.models import BleachField
6 |
7 |
8 | class Person(models.Model):
9 | name = models.CharField(max_length=20)
10 | biography = BleachField(
11 | max_length=100,
12 | verbose_name="Person biography",
13 | allowed_tags=["p", "a", "li", "ul", "strong"],
14 | allowed_attributes=["class", "href", "style"],
15 | allowed_protocols=["http", "https"],
16 | css_sanitizer=CSSSanitizer(
17 | allowed_css_properties=["color", "background-color"]
18 | ),
19 | )
20 |
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | .. django-bleach documentation master file, created by
2 | sphinx-quickstart on Tue Jun 19 10:24:12 2012.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | ``django-bleach``
7 | =======================
8 |
9 | ``bleach`` is a Python module that takes any HTML input, and returns valid,
10 | sanitised HTML that contains only an allowed subset of HTML tags, attributes
11 | and styles. ``django-bleach`` is a Django app that makes using bleach extremely
12 | easy.
13 |
14 | Contents:
15 |
16 | .. toctree::
17 | :maxdepth: 2
18 |
19 | setup
20 | usage
21 | settings
22 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Additional context**
27 | Add any other context about the problem here.
28 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/docs/setup.rst:
--------------------------------------------------------------------------------
1 | =====
2 | Setup
3 | =====
4 |
5 | .. _setup:
6 |
7 | 1. Get the source from the `Git repository`_ or install it from the Python
8 | Package Index by running ``pip install django-bleach``.
9 |
10 | 2. Add ``django_bleach`` to the ``INSTALLED_APPS`` setting::
11 |
12 | INSTALLED_APPS += (
13 | 'django_bleach',
14 | )
15 |
16 | 3. Configure ``django_bleach``. It comes with some sensible defaults, but you
17 | will probably want to tweak the settings for your application. See the
18 | :ref:`settings` page for more information
19 |
20 | 3. Add a ``django_bleach.models.BleachField`` to a model, a
21 | ``django_bleach.forms.BleachField`` to a form, or use the ``bleach``
22 | template filter in your templates.
23 |
24 | .. _Git repository: https://github.com/marksweb/django-bleach/
25 |
--------------------------------------------------------------------------------
/django_bleach/utils.py:
--------------------------------------------------------------------------------
1 | from bleach.css_sanitizer import CSSSanitizer
2 | from django.conf import settings
3 |
4 |
5 | def get_bleach_default_options():
6 | bleach_args = {}
7 | bleach_settings = {
8 | "BLEACH_ALLOWED_TAGS": "tags",
9 | "BLEACH_ALLOWED_ATTRIBUTES": "attributes",
10 | "BLEACH_ALLOWED_STYLES": "css_sanitizer",
11 | "BLEACH_STRIP_TAGS": "strip",
12 | "BLEACH_STRIP_COMMENTS": "strip_comments",
13 | "BLEACH_ALLOWED_PROTOCOLS": "protocols",
14 | }
15 |
16 | for setting, kwarg in bleach_settings.items():
17 | if hasattr(settings, setting):
18 | attr = getattr(settings, setting)
19 | if setting == "BLEACH_ALLOWED_STYLES":
20 | attr = CSSSanitizer(allowed_css_properties=attr)
21 | bleach_args[kwarg] = attr
22 |
23 | return bleach_args
24 |
--------------------------------------------------------------------------------
/.github/workflows/publish-to-live-pypi.yml:
--------------------------------------------------------------------------------
1 | name: Publish Python 🐍 distributions 📦 to pypi
2 |
3 | on:
4 | release:
5 | types:
6 | - published
7 |
8 | jobs:
9 | build-n-publish:
10 | name: Build and publish Python 🐍 distributions 📦 to pypi
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/checkout@v3
14 | - name: Set up Python 3.9
15 | uses: actions/setup-python@v5
16 | with:
17 | python-version: 3.9
18 |
19 | - name: Install pypa/build
20 | run: >-
21 | python -m
22 | pip install
23 | build
24 | --user
25 | - name: Build a binary wheel and a source tarball
26 | run: >-
27 | python -m
28 | build
29 | --sdist
30 | --wheel
31 | --outdir dist/
32 | .
33 |
34 | - name: Publish distribution 📦 to PyPI
35 | if: startsWith(github.ref, 'refs/tags')
36 | uses: pypa/gh-action-pypi-publish@master
37 | with:
38 | password: ${{ secrets.PYPI_API_TOKEN }}
39 |
--------------------------------------------------------------------------------
/testproject/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.4 on 2021-06-15 12:39
2 |
3 | from django.db import migrations, models
4 | import django_bleach.models
5 |
6 |
7 | class Migration(migrations.Migration):
8 | initial = True
9 |
10 | dependencies = []
11 |
12 | operations = [
13 | migrations.CreateModel(
14 | name="Person",
15 | fields=[
16 | (
17 | "id",
18 | models.AutoField(
19 | auto_created=True,
20 | primary_key=True,
21 | serialize=False,
22 | verbose_name="ID",
23 | ),
24 | ),
25 | ("name", models.CharField(max_length=20)),
26 | (
27 | "biography",
28 | django_bleach.models.BleachField(
29 | max_length=100, verbose_name="Person biography"
30 | ),
31 | ),
32 | ],
33 | ),
34 | ]
35 |
--------------------------------------------------------------------------------
/.github/workflows/publish-to-test-pypi.yml:
--------------------------------------------------------------------------------
1 | name: Publish Python 🐍 distributions 📦 to TestPyPI
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 |
8 | jobs:
9 | build-n-publish:
10 | name: Build and publish Python 🐍 distributions 📦 to TestPyPI
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/checkout@v3
14 | - name: Set up Python 3.9
15 | uses: actions/setup-python@v5
16 | with:
17 | python-version: 3.9
18 |
19 | - name: Install pypa/build
20 | run: >-
21 | python -m
22 | pip install
23 | build
24 | --user
25 | - name: Build a binary wheel and a source tarball
26 | run: >-
27 | python -m
28 | build
29 | --sdist
30 | --wheel
31 | --outdir dist/
32 | .
33 |
34 | - name: Publish distribution 📦 to Test PyPI
35 | uses: pypa/gh-action-pypi-publish@master
36 | with:
37 | password: ${{ secrets.TEST_PYPI_API_TOKEN }}
38 | repository_url: https://test.pypi.org/legacy/
39 | skip_existing: true
40 |
--------------------------------------------------------------------------------
/.github/workflows/lint.yml:
--------------------------------------------------------------------------------
1 | name: Lint
2 |
3 | on: [ push, pull_request ]
4 |
5 | concurrency:
6 | group: ${{ github.workflow }}-${{ github.ref }}
7 | cancel-in-progress: true
8 |
9 | jobs:
10 | ruff:
11 | name: ruff
12 | runs-on: ubuntu-latest
13 | steps:
14 | - name: Checkout
15 | uses: actions/checkout@v3
16 | - name: Set up Python
17 | uses: actions/setup-python@v5
18 | with:
19 | python-version: "3.11"
20 | cache: 'pip'
21 | - run: |
22 | python -m pip install --upgrade pip
23 | pip install ruff
24 | - name: Run Ruff
25 | run: ruff django_bleach
26 |
27 | codespell:
28 | runs-on: ubuntu-latest
29 | steps:
30 | - name: Checkout
31 | uses: actions/checkout@v3
32 | - name: Set up Python
33 | uses: actions/setup-python@v5
34 | with:
35 | python-version: 3.11
36 | cache: 'pip'
37 | - run: python -m pip install codespell
38 | - name: codespell
39 | uses: codespell-project/actions-codespell@master
40 |
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [bumpversion]
2 | current_version = 3.1.0
3 | commit = True
4 | tag = False
5 |
6 | [bumpversion:file:django_bleach/__init__.py]
7 | search = __version__ = "{current_version}"
8 | replace = __version__ = "{new_version}"
9 |
10 | [bumpversion:file:docs/conf.py]
11 | search = version = "{current_version}"
12 | replace = version = "{new_version}"
13 |
14 | [bumpversion:file:CHANGELOG.md]
15 | search =
16 | [unreleased](https://github.com/marksweb/django-bleach/compare/{current_version}...master) changes
17 | -------------------------------------------------------------------------------------
18 | replace =
19 | [unreleased](https://github.com/marksweb/django-bleach/compare/{new_version}...master) changes
20 | -------------------------------------------------------------------------------------
21 |
22 | Version {new_version}
23 | =============
24 | **{utcnow:%%d-%%m-%%Y}**
25 |
26 | [bdist_wheel]
27 | universal = 1
28 |
29 | [codespell]
30 | skip = ./.git,./.env,./.venv,./.tox,./.eggs,./django_bleach/tests,./docs/_build,./testproject,./htmlcov
31 | count =
32 | quiet-level = 3
33 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Mark Walker
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/testproject/views.py:
--------------------------------------------------------------------------------
1 | from django.db import OperationalError
2 | from django.http import HttpResponseRedirect
3 | from django.shortcuts import render
4 |
5 | from .forms import BleachForm, PersonForm
6 | from .models import Person
7 |
8 |
9 | def home(request):
10 | if request.POST:
11 | form = BleachForm(request.POST)
12 | if form.is_valid():
13 | return HttpResponseRedirect(request.path + "?ok")
14 | else:
15 | form = BleachForm()
16 |
17 | return render(request, "home.html", {"form": form})
18 |
19 |
20 | def model_form(request):
21 | if request.POST:
22 | form = PersonForm(request.POST)
23 | if form.is_valid():
24 | form.save()
25 | return HttpResponseRedirect("?ok")
26 | else:
27 | form = PersonForm()
28 | try:
29 | people = list(Person.objects.all())
30 | except OperationalError:
31 | people = []
32 |
33 | return render(
34 | request,
35 | "model_form.html",
36 | {
37 | "form": form,
38 | "people": people,
39 | },
40 | )
41 |
--------------------------------------------------------------------------------
/testproject/manage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import sys
3 | import os
4 |
5 | try:
6 | from django.core.management import execute_manager
7 |
8 | OLD_DJANGO = True
9 | except ImportError:
10 | from django.core.management import execute_from_command_line
11 |
12 | OLD_DJANGO = False
13 |
14 | if OLD_DJANGO:
15 | try:
16 | import settings # Assumed to be in the same directory.
17 | except ImportError:
18 | sys.stderr.write(
19 | "Error: Can't find the file 'settings.py' in the directory containing %r. "
20 | "It appears you've customized things.\nYou'll have to run django-admin.py, "
21 | "passing it your settings module.\n(If the file settings.py does indeed exist, "
22 | "it's causing an ImportError somehow.)\n" % __file__
23 | )
24 | sys.exit(1)
25 |
26 | BASEDIR = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
27 | sys.path.insert(0, BASEDIR)
28 |
29 | if __name__ == "__main__":
30 | os.environ["DJANGO_SETTINGS_MODULE"] = "testproject.settings"
31 | if OLD_DJANGO:
32 | execute_manager(settings)
33 | else:
34 | execute_from_command_line(sys.argv)
35 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | ci:
2 | autofix_commit_msg: |
3 | ci: auto fixes from pre-commit hooks
4 |
5 | for more information, see https://pre-commit.ci
6 | autofix_prs: true
7 | autoupdate_commit_msg: 'ci: pre-commit autoupdate'
8 | autoupdate_schedule: monthly
9 |
10 | repos:
11 | - repo: https://github.com/asottile/pyupgrade
12 | rev: v3.15.2
13 | hooks:
14 | - id: pyupgrade
15 | args: ["--py38-plus"]
16 |
17 | - repo: https://github.com/adamchainz/django-upgrade
18 | rev: '1.16.0'
19 | hooks:
20 | - id: django-upgrade
21 | args: [--target-version, "3.2"]
22 |
23 | - repo: https://github.com/astral-sh/ruff-pre-commit
24 | rev: "v0.4.3"
25 | hooks:
26 | - id: ruff
27 | args: [--fix, --exit-non-zero-on-fix]
28 |
29 | - repo: https://github.com/asottile/yesqa
30 | rev: v1.5.0
31 | hooks:
32 | - id: yesqa
33 |
34 | - repo: https://github.com/pre-commit/pre-commit-hooks
35 | rev: v4.6.0
36 | hooks:
37 | - id: check-merge-conflict
38 | - id: mixed-line-ending
39 |
40 | - repo: https://github.com/psf/black
41 | rev: 24.4.2
42 | hooks:
43 | - id: black
44 | name: Black
45 |
--------------------------------------------------------------------------------
/django_bleach/templatetags/bleach_tags.py:
--------------------------------------------------------------------------------
1 | import bleach
2 | from django import template
3 | from django.utils.safestring import mark_safe
4 |
5 | from django_bleach.utils import get_bleach_default_options
6 |
7 | register = template.Library()
8 |
9 |
10 | @register.filter(name="bleach")
11 | def bleach_value(value, tags=None):
12 | if value is None:
13 | return None
14 |
15 | bleach_args = get_bleach_default_options()
16 | if tags is not None:
17 | args = bleach_args.copy()
18 | args["tags"] = tags.split(",")
19 | else:
20 | args = bleach_args
21 | bleached_value = bleach.clean(value, **args)
22 | return mark_safe(bleached_value)
23 |
24 |
25 | @register.filter
26 | def bleach_linkify(value):
27 | """
28 | Convert URL-like strings in an HTML fragment to links
29 |
30 | This function converts strings that look like URLs, domain names and email
31 | addresses in text that may be an HTML fragment to links, while preserving:
32 |
33 | 1. links already in the string
34 | 2. urls found in attributes
35 | 3. email addresses
36 | """
37 | if value is None:
38 | return None
39 |
40 | return bleach.linkify(value, parse_email=True)
41 |
--------------------------------------------------------------------------------
/testproject/templates/model_form.html:
--------------------------------------------------------------------------------
1 | {% load bleach_tags %}
2 |
3 |
13 |
14 |
15 | Model form example
16 | Note: You must migrate project to add person!
17 |
18 |
28 |
29 |
30 |
People list
31 |
32 |
33 |
34 | Name
35 | Biography
36 |
37 | {% for person in people %}
38 |
39 | {{person.name}}
40 | {{person.biography|safe}}
41 |
42 | {% endfor %}
43 |
44 |
45 |
46 |
47 | Form example
48 |
49 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | #
2 | # This file is autogenerated by pip-compile with python 3.9
3 | # To update, run:
4 | #
5 | # pip-compile
6 | #
7 | bump2version==1.0.1
8 | # via -r requirements.in
9 | cfgv==3.3.1
10 | # via pre-commit
11 | click==8.0.3
12 | # via pip-tools
13 | distlib==0.3.4
14 | # via virtualenv
15 | filelock==3.4.2
16 | # via
17 | # tox
18 | # virtualenv
19 | identify==2.4.2
20 | # via pre-commit
21 | nodeenv==1.6.0
22 | # via pre-commit
23 | packaging==21.3
24 | # via tox
25 | pep517==0.12.0
26 | # via pip-tools
27 | pip-tools==6.4.0
28 | # via -r requirements.in
29 | platformdirs==2.4.1
30 | # via virtualenv
31 | pluggy==1.0.0
32 | # via tox
33 | pre-commit==2.16.0
34 | # via -r requirements.in
35 | py==1.11.0
36 | # via tox
37 | pyparsing==3.0.6
38 | # via packaging
39 | pyyaml==6.0
40 | # via pre-commit
41 | six==1.16.0
42 | # via
43 | # tox
44 | # virtualenv
45 | toml==0.10.2
46 | # via
47 | # pre-commit
48 | # tox
49 | tomli==2.0.0
50 | # via pep517
51 | tox==3.24.5
52 | # via -r requirements.in
53 | virtualenv==20.13.0
54 | # via
55 | # pre-commit
56 | # tox
57 | wheel==0.38.1
58 | # via
59 | # -r requirements.in
60 | # pip-tools
61 |
62 | # The following packages are considered to be unsafe in a requirements file:
63 | # pip
64 | # setuptools
65 |
--------------------------------------------------------------------------------
/testproject/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 |
3 | from bleach.css_sanitizer import CSSSanitizer
4 |
5 | from django_bleach.forms import BleachField
6 | from testproject.constants import (
7 | ALLOWED_ATTRIBUTES,
8 | ALLOWED_CSS_PROPERTIES,
9 | ALLOWED_PROTOCOLS,
10 | ALLOWED_STYLES,
11 | ALLOWED_TAGS,
12 | )
13 | from testproject.models import Person
14 |
15 |
16 | class CustomBleachWidget(forms.Textarea):
17 | def __init__(self, attrs=None):
18 | default_attrs = {"rows": 15, "cols": 60}
19 | default_attrs.update(attrs or {})
20 | super().__init__(attrs=default_attrs)
21 |
22 |
23 | class BleachForm(forms.Form):
24 | """Form for testing BleachField"""
25 |
26 | no_tags = BleachField(max_length=100, strip_tags=True, allowed_tags=[])
27 |
28 | no_strip = BleachField(
29 | max_length=100, allowed_tags=None, allowed_attributes=None
30 | )
31 |
32 | bleach_strip = BleachField(
33 | max_length=100,
34 | strip_comments=True,
35 | strip_tags=True,
36 | allowed_tags=ALLOWED_TAGS,
37 | )
38 | bleach_attrs = BleachField(
39 | max_length=100,
40 | strip_tags=False,
41 | allowed_tags=ALLOWED_TAGS,
42 | allowed_protocols=ALLOWED_PROTOCOLS,
43 | allowed_attributes=ALLOWED_ATTRIBUTES,
44 | )
45 | bleach_styles = BleachField(
46 | max_length=100,
47 | strip_tags=False,
48 | allowed_attributes=["style"],
49 | allowed_tags=ALLOWED_TAGS,
50 | allowed_styles=ALLOWED_STYLES,
51 | )
52 | bleach_css_sanitizer = BleachField(
53 | max_length=100,
54 | strip_tags=False,
55 | allowed_attributes=["style"],
56 | allowed_tags=ALLOWED_TAGS,
57 | css_sanitizer=CSSSanitizer(
58 | allowed_css_properties=ALLOWED_CSS_PROPERTIES
59 | ),
60 | )
61 |
62 |
63 | class PersonForm(forms.ModelForm):
64 | class Meta:
65 | model = Person
66 | fields = "__all__"
67 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | share/python-wheels/
24 | *.egg-info/
25 | .installed.cfg
26 | *.egg
27 | MANIFEST
28 |
29 | # PyInstaller
30 | # Usually these files are written by a python script from a template
31 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
32 | *.manifest
33 | *.spec
34 |
35 | # Installer logs
36 | pip-log.txt
37 | pip-delete-this-directory.txt
38 |
39 | # Unit test / coverage reports
40 | htmlcov/
41 | .tox/
42 | .nox/
43 | .coverage
44 | .coverage.*
45 | .cache
46 | nosetests.xml
47 | coverage.xml
48 | *.cover
49 | .hypothesis/
50 | .pytest_cache/
51 |
52 | # Translations
53 | *.mo
54 | *.pot
55 |
56 | # Django stuff:
57 | *.log
58 | local_settings.py
59 | db.sqlite3
60 | django-bleach.db
61 |
62 | # Flask stuff:
63 | instance/
64 | .webassets-cache
65 |
66 | # Scrapy stuff:
67 | .scrapy
68 |
69 | # Sphinx documentation
70 | docs/_build/
71 |
72 | # PyBuilder
73 | target/
74 |
75 | # Jupyter Notebook
76 | .ipynb_checkpoints
77 |
78 | # IPython
79 | profile_default/
80 | ipython_config.py
81 |
82 | # pyenv
83 | .python-version
84 |
85 | # celery beat schedule file
86 | celerybeat-schedule
87 |
88 | # SageMath parsed files
89 | *.sage.py
90 |
91 | # Environments
92 | .env
93 | .venv
94 | env/
95 | venv/
96 | ENV/
97 | env.bak/
98 | venv.bak/
99 |
100 | # Spyder project settings
101 | .spyderproject
102 | .spyproject
103 |
104 | # Rope project settings
105 | .ropeproject
106 |
107 | # mkdocs documentation
108 | /site
109 |
110 | # mypy
111 | .mypy_cache/
112 | .dmypy.json
113 | dmypy.json
114 |
115 | # Pyre type checker
116 | .pyre/
117 |
118 | # IDE
119 | .idea
120 |
121 | # OSX
122 | .DS_Store
--------------------------------------------------------------------------------
/testproject/settings.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sys
3 |
4 |
5 | SITE_ID = 1
6 |
7 | PROJECT_PATH = os.path.abspath(os.path.dirname(__file__))
8 |
9 | PYTHON_VERSION = "%s.%s" % sys.version_info[:2]
10 |
11 |
12 | DATABASES = {
13 | "default": {
14 | "ENGINE": "django.db.backends.sqlite3",
15 | "NAME": os.path.join(PROJECT_PATH, "django-bleach.db"),
16 | }
17 | }
18 | DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
19 | DATABASE_SUPPORTS_TRANSACTIONS = True
20 |
21 | INSTALLED_APPS = [
22 | "django.contrib.auth",
23 | "django.contrib.admin",
24 | "django.contrib.contenttypes",
25 | "django.contrib.sessions",
26 | "django.contrib.sites",
27 | "django.contrib.messages",
28 | "django_bleach",
29 | "testproject",
30 | ]
31 |
32 | LANGUAGE_CODE = "en"
33 |
34 | LANGUAGES = (("en", "English"),)
35 |
36 | ROOT_URLCONF = "testproject.urls"
37 |
38 | DEBUG = True
39 |
40 | TEMPLATES = [
41 | {
42 | "BACKEND": "django.template.backends.django.DjangoTemplates",
43 | "APP_DIRS": True,
44 | "OPTIONS": {
45 | "debug": False,
46 | "context_processors": (
47 | "django.contrib.auth.context_processors.auth",
48 | "django.template.context_processors.debug",
49 | "django.template.context_processors.i18n",
50 | "django.template.context_processors.media",
51 | "django.template.context_processors.request",
52 | "django.template.context_processors.static",
53 | "django.template.context_processors.tz",
54 | "django.contrib.messages.context_processors.messages",
55 | ),
56 | },
57 | "DIRS": ("templates",),
58 | },
59 | ]
60 |
61 | USE_TZ = True
62 | SECRET_KEY = "blah"
63 |
64 | MIDDLEWARE = (
65 | "django.contrib.sessions.middleware.SessionMiddleware",
66 | "django.contrib.auth.middleware.AuthenticationMiddleware",
67 | "django.contrib.messages.middleware.MessageMiddleware",
68 | )
69 |
70 | # BLEACH_DEFAULT_WIDGET = 'testproject.forms.CustomBleachWidget'
71 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | # Minimum requirements for the build system to execute.
3 | requires = ["setuptools", "wheel"] # PEP 508 specifications.
4 |
5 | [tool.black]
6 | line-length = 79
7 | target-version = ["py311"]
8 |
9 | [tool.coverage.run]
10 | branch = true
11 | parallel = true
12 | omit = [
13 | "testproject/**"
14 | ]
15 |
16 | [tool.coverage.paths]
17 | source = [
18 | "django_bleach",
19 | ".tox/**/site-packages"
20 | ]
21 |
22 | [tool.coverage.report]
23 | show_missing = true
24 |
25 | [tool.ruff]
26 | # https://beta.ruff.rs/docs/configuration/
27 | line-length = 79
28 | select = [
29 | "E", # pycodestyle errors
30 | "W", # pycodestyle warnings
31 | "F", # pyflakes
32 | "I", # isort
33 | "C", # flake8-comprehensions
34 | "B", # flake8-bugbear
35 | "Q", # flake8-quotes
36 | "PLE", # pylint error
37 | "PLR", # pylint refactor
38 | "PLW", # pylint warning
39 | "UP", # pyupgrade
40 | ]
41 |
42 | exclude = [
43 | ".eggs",
44 | ".git",
45 | ".mypy_cache",
46 | ".ruff_cache",
47 | ".env",
48 | ".venv",
49 | "**migrations/**",
50 | "docs/**",
51 | "node_modules",
52 | "requirements",
53 | "venv",
54 | "testproject",
55 | ]
56 |
57 | ignore = [
58 | "B006", # Do not use mutable data structures for argument defaults
59 | "B011", # tests use assert False
60 | "B019", # Use of `functools.lru_cache` or `functools.cache` on methods can lead to memory leaks
61 | "B905", # `zip()` without an explicit `strict=` parameter
62 | "C901", # too complex functions
63 | "E402", # module level import not at top of file
64 | "E731", # do not assign a lambda expression, use a def
65 | "PLR0911", # Too many return statements
66 | "PLR0912", # Too many branches
67 | "PLR0913", # Too many arguments to function call
68 | "PLR0915", # Too many statements
69 | "PLR2004", # Magic value used in comparison, consider replacing with a constant variable
70 | ]
71 |
72 | [tool.ruff.per-file-ignores]
73 | "__init__.py" = [
74 | "F401" # unused-import
75 | ]
76 |
77 | [tool.ruff.isort]
78 | combine-as-imports = true
79 | known-first-party = [
80 | "django_bleach",
81 | ]
82 | extra-standard-library = ["dataclasses"]
83 |
--------------------------------------------------------------------------------
/docs/requirements.txt:
--------------------------------------------------------------------------------
1 | #
2 | # This file is autogenerated by pip-compile with Python 3.11
3 | # by the following command:
4 | #
5 | # pip-compile
6 | #
7 | alabaster==0.7.13
8 | # via sphinx
9 | babel==2.13.1
10 | # via sphinx
11 | beautifulsoup4==4.12.2
12 | # via furo
13 | certifi==2023.11.17
14 | # via requests
15 | charset-normalizer==3.3.2
16 | # via requests
17 | colorama==0.4.6
18 | # via sphinx-autobuild
19 | docutils==0.20.1
20 | # via sphinx
21 | furo==2023.9.10
22 | # via -r requirements.in
23 | idna==3.6
24 | # via requests
25 | imagesize==1.4.1
26 | # via sphinx
27 | jinja2==3.1.2
28 | # via sphinx
29 | livereload==2.6.3
30 | # via sphinx-autobuild
31 | markupsafe==2.1.3
32 | # via
33 | # -r requirements.in
34 | # jinja2
35 | packaging==23.2
36 | # via sphinx
37 | pyenchant==3.2.2
38 | # via sphinxcontrib-spelling
39 | pygments==2.17.2
40 | # via
41 | # furo
42 | # sphinx
43 | requests==2.31.0
44 | # via sphinx
45 | six==1.16.0
46 | # via livereload
47 | snowballstemmer==2.2.0
48 | # via sphinx
49 | soupsieve==2.5
50 | # via beautifulsoup4
51 | sphinx==7.2.6
52 | # via
53 | # -r requirements.in
54 | # furo
55 | # sphinx-autobuild
56 | # sphinx-basic-ng
57 | # sphinxcontrib-applehelp
58 | # sphinxcontrib-devhelp
59 | # sphinxcontrib-htmlhelp
60 | # sphinxcontrib-qthelp
61 | # sphinxcontrib-serializinghtml
62 | # sphinxcontrib-spelling
63 | # sphinxext-opengraph
64 | sphinx-autobuild==2021.3.14
65 | # via -r requirements.in
66 | sphinx-basic-ng==1.0.0b2
67 | # via furo
68 | sphinxcontrib-applehelp==1.0.7
69 | # via sphinx
70 | sphinxcontrib-devhelp==1.0.5
71 | # via sphinx
72 | sphinxcontrib-htmlhelp==2.0.4
73 | # via sphinx
74 | sphinxcontrib-jsmath==1.0.1
75 | # via sphinx
76 | sphinxcontrib-qthelp==1.0.6
77 | # via sphinx
78 | sphinxcontrib-serializinghtml==1.1.9
79 | # via sphinx
80 | sphinxcontrib-spelling==8.0.0
81 | # via -r requirements.in
82 | sphinxext-opengraph==0.9.0
83 | # via -r requirements.in
84 | tornado==6.4
85 | # via livereload
86 | urllib3==2.2.2
87 | # via requests
88 |
--------------------------------------------------------------------------------
/django_bleach/tests/test_templatetags.py:
--------------------------------------------------------------------------------
1 | from django.template import Context, Template
2 | from django.test import TestCase
3 |
4 |
5 | class TestBleachTemplates(TestCase):
6 | """Test template tags"""
7 |
8 | def test_bleaching(self):
9 | """Test that unsafe tags are sanitised"""
10 | context = Context(
11 | {"some_unsafe_content": ''},
12 | )
13 | template_to_render = Template(
14 | "{% load bleach_tags %}" "{{ some_unsafe_content|bleach }}"
15 | )
16 | rendered_template = template_to_render.render(context)
17 | self.assertInHTML(
18 | '<script>alert("Hello World!")</script>',
19 | rendered_template,
20 | )
21 |
22 | def test_bleaching_none(self):
23 | """Test that None is handled properly as an input"""
24 | context = Context({"none_value": None})
25 | template_to_render = Template(
26 | "{% load bleach_tags %}" "{{ none_value|bleach }}"
27 | )
28 | rendered_template = template_to_render.render(context)
29 | self.assertEqual("None", rendered_template)
30 |
31 | def test_bleaching_tags(self):
32 | """Test provided tags are kept"""
33 | context = Context(
34 | {"some_unsafe_content": ''}
35 | )
36 | template_to_render = Template(
37 | "{% load bleach_tags %}"
38 | '{{ some_unsafe_content|bleach:"script" }}'
39 | )
40 | rendered_template = template_to_render.render(context)
41 | self.assertInHTML(
42 | '', rendered_template
43 | )
44 |
45 | def test_linkify(self):
46 | """Test bleach linkify"""
47 | url = "www.google.com"
48 | context = Context({"link_this": url})
49 | template_to_render = Template(
50 | "{% load bleach_tags %}" "{{ link_this|bleach_linkify|safe }}"
51 | )
52 | rendered_template = template_to_render.render(context)
53 | self.assertInHTML(
54 | f'{url} ',
55 | rendered_template,
56 | )
57 |
58 | def test_linkify_none(self):
59 | """Test bleach linkify with None as an input"""
60 | context = Context({"none_value": None})
61 | template_to_render = Template(
62 | "{% load bleach_tags %}" "{{ none_value|bleach_linkify }}"
63 | )
64 | rendered_template = template_to_render.render(context)
65 | self.assertEqual(
66 | "None",
67 | rendered_template,
68 | )
69 |
--------------------------------------------------------------------------------
/docs/settings.rst:
--------------------------------------------------------------------------------
1 | .. _settings:
2 |
3 | ========
4 | Settings
5 | ========
6 |
7 | Configuring ``bleach``
8 | ======================
9 |
10 | You can configure how ``bleach`` acts for your whole project using the
11 | following settings. These settings map directly to the ``bleach`` parameters of
12 | the same name, so see the ``bleach`` `documentation` for more information. Each
13 | of these have a sensible default set by ``bleach``, and each of these are
14 | completely optional::
15 |
16 | # Which HTML tags are allowed
17 | BLEACH_ALLOWED_TAGS = ['p', 'b', 'i', 'u', 'em', 'strong', 'a']
18 |
19 | # Which HTML attributes are allowed
20 | BLEACH_ALLOWED_ATTRIBUTES = ['href', 'title', 'style']
21 |
22 | # Which CSS properties are allowed in 'style' attributes (assuming style is
23 | # an allowed attribute)
24 | BLEACH_ALLOWED_STYLES = [
25 | 'font-family', 'font-weight', 'text-decoration', 'font-variant'
26 | ]
27 |
28 | # Which protocols (and pseudo-protocols) are allowed in 'src' attributes
29 | # (assuming src is an allowed attribute)
30 | BLEACH_ALLOWED_PROTOCOLS = [
31 | 'http', 'https', 'data'
32 | ]
33 |
34 | # Strip unknown tags if True, replace with HTML escaped characters if False
35 | BLEACH_STRIP_TAGS = True
36 |
37 | # Strip HTML comments, or leave them in.
38 | BLEACH_STRIP_COMMENTS = False
39 |
40 | You can override each of these for individual ``BleachField`` form and model
41 | fields if you need to. Simply pass in one of the following settings you want to
42 | override as a named parameter to the ``BleachField``:
43 |
44 | * ``allowed_tags``
45 | * ``allowed_attributes``
46 | * ``allowed_protocols``
47 | * ``strip_tags``
48 | * ``strip_comments``
49 | * ``css_sanitizer``
50 |
51 | The following argument will be deprecated in the near future:
52 |
53 | * ``allowed_styles``
54 |
55 | An example, where blog posts should be allowed to contain images and headings::
56 |
57 | # in app/models.py
58 |
59 | from django import models
60 | from django_bleach.models import BleachField
61 |
62 | class Post(models.Model):
63 |
64 | title = models.CharField()
65 | content = BleachField(allowed_tags=[
66 | 'p', 'b', 'i', 'u', 'em', 'strong', 'a',
67 | 'img', 'h3', 'h4', 'h5', 'h6'])
68 |
69 | Default form widget
70 | ===================
71 |
72 | By default, a ``BleachField`` will use a ``django.forms.Textarea`` widget. This
73 | is obviously not great for users. You can override this to use a custom widget
74 | in your project. You will probably want to use a WYSIWYG editor, or something
75 | similar::
76 |
77 | BLEACH_DEFAULT_WIDGET = 'wysiwyg.widgets.WysiwygWidget'
78 |
79 | I use ``django-ckeditor`` in my projects, but what you use is up to you.
80 |
81 |
82 | .. _documentation: http://bleach.readthedocs.org/en/latest/index.html
83 |
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | name: "CodeQL"
7 |
8 | on:
9 | push:
10 | branches: [master]
11 | pull_request:
12 | # The branches below must be a subset of the branches above
13 | branches: [master]
14 | schedule:
15 | - cron: '0 18 * * 2'
16 |
17 | jobs:
18 | analyze:
19 | name: Analyze
20 | runs-on: ubuntu-latest
21 |
22 | strategy:
23 | fail-fast: false
24 | matrix:
25 | # Override automatic language detection by changing the below list
26 | # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
27 | language: ['python']
28 | # Learn more...
29 | # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
30 |
31 | steps:
32 | - name: Checkout repository
33 | uses: actions/checkout@v3
34 | with:
35 | # We must fetch at least the immediate parents so that if this is
36 | # a pull request then we can checkout the head.
37 | fetch-depth: 2
38 |
39 | # If this run was triggered by a pull request event, then checkout
40 | # the head of the pull request instead of the merge commit.
41 | - run: git checkout HEAD^2
42 | if: ${{ github.event_name == 'pull_request' }}
43 |
44 | # Initializes the CodeQL tools for scanning.
45 | - name: Initialize CodeQL
46 | uses: github/codeql-action/init@v3
47 | with:
48 | languages: ${{ matrix.language }}
49 | # If you wish to specify custom queries, you can do so here or in a config file.
50 | # By default, queries listed here will override any specified in a config file.
51 | # Prefix the list here with "+" to use these queries and those in the config file.
52 | # queries: ./path/to/local/query, your-org/your-repo/queries@main
53 |
54 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
55 | # If this step fails, then you should remove it and run the build manually (see below)
56 | - name: Autobuild
57 | uses: github/codeql-action/autobuild@v3
58 |
59 | # ℹ️ Command-line programs to run using the OS shell.
60 | # 📚 https://git.io/JvXDl
61 |
62 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
63 | # and modify them (or add more) to build your code if your project
64 | # uses a compiled language
65 |
66 | #- run: |
67 | # make bootstrap
68 | # make release
69 |
70 | - name: Perform CodeQL Analysis
71 | uses: github/codeql-action/analyze@v3
72 |
--------------------------------------------------------------------------------
/django_bleach/forms.py:
--------------------------------------------------------------------------------
1 | from importlib import import_module
2 |
3 | import bleach
4 | from bleach.css_sanitizer import CSSSanitizer
5 | from django import forms
6 | from django.conf import settings
7 | from django.core.exceptions import ImproperlyConfigured
8 | from django.utils.safestring import mark_safe
9 |
10 | from django_bleach.utils import get_bleach_default_options
11 |
12 |
13 | def load_widget(path):
14 | """Load custom widget for the form field"""
15 | i = path.rfind(".")
16 | module, attr = path[:i], path[i + 1 :]
17 | try:
18 | mod = import_module(module)
19 | except (ImportError, ValueError) as e:
20 | error_message = "Error importing widget for BleachField %s: '%s'"
21 | raise ImproperlyConfigured(error_message % (path, e)) from e
22 |
23 | try:
24 | cls = getattr(mod, attr)
25 | except AttributeError as e:
26 | raise ImproperlyConfigured(
27 | f"Module '{module}' does not define a '{attr}' widget"
28 | ) from e
29 |
30 | return cls
31 |
32 |
33 | def get_default_widget():
34 | """Get the default widget or the widget defined in settings"""
35 | default_widget = forms.Textarea
36 | if hasattr(settings, "BLEACH_DEFAULT_WIDGET"):
37 | default_widget = load_widget(settings.BLEACH_DEFAULT_WIDGET)
38 | return default_widget
39 |
40 |
41 | class BleachField(forms.CharField):
42 | """Bleach form field"""
43 |
44 | empty_values = [None, "", [], (), {}]
45 |
46 | def __init__(
47 | self,
48 | allowed_tags=None,
49 | allowed_attributes=None,
50 | allowed_styles=None,
51 | allowed_protocols=None,
52 | strip_comments=None,
53 | strip_tags=None,
54 | css_sanitizer=None,
55 | *args,
56 | **kwargs,
57 | ):
58 | self.widget = get_default_widget()
59 |
60 | super().__init__(*args, **kwargs)
61 |
62 | self.bleach_options = get_bleach_default_options()
63 |
64 | if allowed_tags is not None:
65 | self.bleach_options["tags"] = allowed_tags
66 | if allowed_attributes is not None:
67 | self.bleach_options["attributes"] = allowed_attributes
68 | if allowed_styles:
69 | css_sanitizer = CSSSanitizer(allowed_css_properties=allowed_styles)
70 | if css_sanitizer is not None:
71 | self.bleach_options["css_sanitizer"] = css_sanitizer
72 | if allowed_protocols is not None:
73 | self.bleach_options["protocols"] = allowed_protocols
74 | if strip_tags is not None:
75 | self.bleach_options["strip"] = strip_tags
76 | if strip_comments is not None:
77 | self.bleach_options["strip_comments"] = strip_comments
78 |
79 | def to_python(self, value):
80 | """
81 | Strips any dodgy HTML tags from the input.
82 |
83 | Mark the return value as template safe.
84 | """
85 | if value in self.empty_values:
86 | return self.empty_value
87 | return mark_safe(bleach.clean(value, **self.bleach_options))
88 |
--------------------------------------------------------------------------------
/django_bleach/models.py:
--------------------------------------------------------------------------------
1 | from bleach import clean
2 | from bleach.css_sanitizer import CSSSanitizer
3 | from django.db import models
4 | from django.utils.safestring import mark_safe
5 |
6 | from . import forms
7 | from .utils import get_bleach_default_options
8 |
9 |
10 | class BleachField(models.TextField):
11 | def __init__(
12 | self,
13 | allowed_tags=None,
14 | allowed_attributes=None,
15 | allowed_styles=None,
16 | allowed_protocols=None,
17 | strip_tags=None,
18 | strip_comments=None,
19 | css_sanitizer=None,
20 | *args,
21 | **kwargs,
22 | ):
23 | super().__init__(*args, **kwargs)
24 |
25 | self.bleach_kwargs = get_bleach_default_options()
26 |
27 | if allowed_tags:
28 | self.bleach_kwargs["tags"] = allowed_tags
29 | if allowed_attributes:
30 | self.bleach_kwargs["attributes"] = allowed_attributes
31 | if allowed_styles:
32 | css_sanitizer = CSSSanitizer(allowed_css_properties=allowed_styles)
33 | if css_sanitizer:
34 | self.bleach_kwargs["css_sanitizer"] = css_sanitizer
35 | if allowed_protocols:
36 | self.bleach_kwargs["protocols"] = allowed_protocols
37 | if strip_tags:
38 | self.bleach_kwargs["strip"] = strip_tags
39 | if strip_comments:
40 | self.bleach_kwargs["strip_comments"] = strip_comments
41 |
42 | def formfield(self, form_class=forms.BleachField, **kwargs):
43 | """Makes the field for a ModelForm"""
44 |
45 | # If field doesn't have any choices add kwargs expected by BleachField.
46 | if not self.choices:
47 | kwargs.setdefault("widget", forms.get_default_widget())
48 | kwargs.update(
49 | {
50 | "max_length": self.max_length,
51 | "allowed_tags": self.bleach_kwargs.get("tags"),
52 | "allowed_attributes": self.bleach_kwargs.get("attributes"),
53 | "css_sanitizer": self.bleach_kwargs.get("css_sanitizer"),
54 | "allowed_protocols": self.bleach_kwargs.get("protocols"),
55 | "strip_tags": self.bleach_kwargs.get("strip"),
56 | "strip_comments": self.bleach_kwargs.get("strip_comments"),
57 | "required": not self.blank,
58 | }
59 | )
60 |
61 | return super().formfield(form_class=form_class, **kwargs)
62 |
63 | def pre_save(self, model_instance, add):
64 | data = getattr(model_instance, self.attname)
65 | if data is None:
66 | return data
67 | clean_value = clean(data, **self.bleach_kwargs) if data else ""
68 | setattr(model_instance, self.attname, mark_safe(clean_value))
69 | return clean_value
70 |
71 | def from_db_value(self, value, expression, connection):
72 | if value is None:
73 | return value
74 | # Values are sanitised before saving, so any value returned from the DB
75 | # is safe to render unescaped.
76 | return mark_safe(value)
77 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import codecs
3 | import os
4 | import re
5 |
6 | from setuptools import find_packages, setup
7 |
8 | try:
9 | from sphinx.setup_command import BuildDoc
10 | except ImportError:
11 | BuildDoc = None
12 |
13 |
14 | def read(*parts):
15 | file_path = os.path.join(os.path.dirname(__file__), *parts)
16 | return codecs.open(file_path, encoding="utf-8").read()
17 |
18 |
19 | def find_variable(variable, *parts):
20 | version_file = read(*parts)
21 | version_match = re.search(
22 | rf"^{variable} = ['\"]([^'\"]*)['\"]", version_file, re.M
23 | )
24 | if version_match:
25 | return str(version_match.group(1))
26 | raise RuntimeError("Unable to find version string.")
27 |
28 |
29 | name = "django-bleach"
30 | release = find_variable("__version__", "django_bleach", "__init__.py")
31 | version = release.rstrip(".")
32 |
33 | setup(
34 | name=name,
35 | version=version,
36 | description="Easily use bleach with Django models and templates",
37 | long_description=read("README.rst"),
38 | long_description_content_type="text/x-rst",
39 | author="Tim Heap",
40 | maintainer="Mark Walker",
41 | maintainer_email="theshow+django-bleach@gmail.com",
42 | url="https://github.com/marksweb/django-bleach",
43 | license="MIT",
44 | packages=find_packages(exclude=("testproject*",)),
45 | install_requires=[
46 | "bleach[css]>=5,<6",
47 | "Django>=3.2",
48 | ],
49 | python_requires=">=3.8",
50 | tests_require=["bleach[css]>=5,<6", "mock", "sphinx", "tox"],
51 | cmdclass={
52 | "build_sphinx": BuildDoc,
53 | },
54 | command_options={
55 | "build_sphinx": {
56 | "project": ("setup.py", name),
57 | "version": ("setup.py", version),
58 | "release": ("setup.py", release),
59 | "source_dir": ("setup.py", "docs"),
60 | "build_dir": ("setup.py", "./docs/_build"),
61 | }
62 | },
63 | package_data={},
64 | classifiers=[
65 | "Environment :: Web Environment",
66 | "Intended Audience :: Developers",
67 | "License :: OSI Approved :: MIT License",
68 | "Operating System :: OS Independent",
69 | "Programming Language :: Python",
70 | "Programming Language :: Python :: 3 :: Only",
71 | "Programming Language :: Python :: 3.8",
72 | "Programming Language :: Python :: 3.9",
73 | "Programming Language :: Python :: 3.10",
74 | "Programming Language :: Python :: 3.11",
75 | "Programming Language :: Python :: 3.12",
76 | "Framework :: Django :: 3.2",
77 | "Framework :: Django :: 4.0",
78 | "Framework :: Django :: 4.1",
79 | "Framework :: Django :: 4.2",
80 | "Development Status :: 5 - Production/Stable",
81 | ],
82 | project_urls={
83 | "Documentation": "https://django-bleach.readthedocs.io/",
84 | "Release notes": "https://github.com/marksweb/django-bleach/blob/main/CHANGELOG.md",
85 | "Issues": "https://github.com/marksweb/django-bleach/issues",
86 | "Source": "https://github.com/marksweb/django-bleach",
87 | },
88 | )
89 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Tests
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | pull_request:
8 |
9 | concurrency:
10 | group: ${{ github.head_ref || github.run_id }}
11 | cancel-in-progress: true
12 |
13 | jobs:
14 | unit-tests:
15 | name: Python ${{ matrix.python-version }}
16 | runs-on: ubuntu-22.04
17 |
18 | strategy:
19 | fail-fast: false
20 | matrix:
21 | python-version:
22 | - 3.8
23 | - 3.9
24 | - '3.10'
25 | - '3.11'
26 | - '3.12'
27 |
28 | steps:
29 | - uses: actions/checkout@v3
30 |
31 | - uses: actions/setup-python@v5
32 | with:
33 | python-version: ${{ matrix.python-version }}
34 | allow-prereleases: true
35 | cache: pip
36 | cache-dependency-path: 'requirements/*.txt'
37 |
38 | - name: Install dependencies
39 | run: |
40 | python -m pip install --upgrade pip setuptools wheel
41 | python -m pip install --upgrade 'tox>=4.0.0rc3'
42 |
43 | - name: Run tox targets for ${{ matrix.python-version }}
44 | run: tox run -f py$(echo ${{ matrix.python-version }} | tr -d .)
45 |
46 | - name: Upload coverage data
47 | uses: actions/upload-artifact@v3
48 | with:
49 | name: coverage-data
50 | path: '.coverage.*'
51 |
52 | coverage:
53 | name: Coverage
54 | runs-on: ubuntu-22.04
55 | needs: unit-tests
56 | steps:
57 | - uses: actions/checkout@v3
58 |
59 | - uses: actions/setup-python@v5
60 | with:
61 | python-version: '3.11'
62 |
63 | - name: Install dependencies
64 | run: python -m pip install --upgrade coverage[toml]
65 |
66 | - name: Download data
67 | uses: actions/download-artifact@v3
68 | with:
69 | name: coverage-data
70 |
71 | - name: Fail if coverage is <100%
72 | run: |
73 | python -m coverage combine
74 | python -m coverage html --skip-covered --skip-empty
75 | python -m coverage report --fail-under=100
76 |
77 | - name: Upload HTML report
78 | if: ${{ failure() }}
79 | uses: actions/upload-artifact@v3
80 | with:
81 | name: html-report
82 | path: htmlcov
83 |
84 | unit-tests-future-versions:
85 | # Runs for all Django/Python versions which are not yet supported
86 | runs-on: ubuntu-22.04
87 | strategy:
88 | fail-fast: false
89 | matrix:
90 | python-version: ['3.11', '3.12']
91 | django-version: [
92 | 'https://github.com/django/django/archive/main.tar.gz'
93 | ]
94 |
95 | steps:
96 | - uses: actions/checkout@v3
97 | - name: Set up Python ${{ matrix.python-version }}
98 | uses: actions/setup-python@v5
99 | with:
100 | allow-prereleases: true
101 | cache: pip
102 | cache-dependency-path: 'requirements/*.txt'
103 | python-version: ${{ matrix.python-version }}
104 | - name: Install dependencies
105 | run: |
106 | python -m pip install --upgrade pip setuptools wheel
107 | python -m pip install --upgrade 'tox>=4.0.0rc3'
108 |
109 | - name: Run tox targets for ${{ matrix.python-version }}
110 | run: tox run -f py$(echo ${{ matrix.python-version }} | tr -d .)
111 |
--------------------------------------------------------------------------------
/testproject/requirements.txt:
--------------------------------------------------------------------------------
1 | #
2 | # This file is autogenerated by pip-compile with python 3.9
3 | # To update, run:
4 | #
5 | # pip-compile
6 | #
7 | alabaster==0.7.12
8 | # via sphinx
9 | asgiref==3.6.0
10 | # via django
11 | attrs==21.4.0
12 | # via
13 | # flake8-bugbear
14 | # flake8-eradicate
15 | babel==2.9.1
16 | # via sphinx
17 | bleach==5.0.0
18 | # via -r requirements.in
19 | certifi==2022.12.7
20 | # via requests
21 | charset-normalizer==2.0.10
22 | # via requests
23 | click==8.0.3
24 | # via pip-tools
25 | coverage==6.2
26 | # via -r requirements.in
27 | django==4.1.9
28 | # via -r requirements.in
29 | docutils==0.17.1
30 | # via
31 | # sphinx
32 | # sphinx-rtd-theme
33 | eradicate==2.0.0
34 | # via flake8-eradicate
35 | flake8==4.0.1
36 | # via
37 | # -r requirements.in
38 | # flake8-broken-line
39 | # flake8-bugbear
40 | # flake8-builtins
41 | # flake8-commas
42 | # flake8-comprehensions
43 | # flake8-eradicate
44 | # flake8-polyfill
45 | # flake8-quotes
46 | # flake8-tidy-imports
47 | # pep8-naming
48 | flake8-broken-line==0.4.0
49 | # via -r requirements.in
50 | flake8-bugbear==21.11.29
51 | # via -r requirements.in
52 | flake8-builtins==1.5.3
53 | # via -r requirements.in
54 | flake8-commas==2.1.0
55 | # via -r requirements.in
56 | flake8-comprehensions==3.7.0
57 | # via -r requirements.in
58 | flake8-eradicate==1.2.0
59 | # via -r requirements.in
60 | flake8-polyfill==1.0.2
61 | # via pep8-naming
62 | flake8-quotes==3.3.1
63 | # via -r requirements.in
64 | flake8-tidy-imports==4.5.0
65 | # via -r requirements.in
66 | idna==3.3
67 | # via requests
68 | imagesize==1.3.0
69 | # via sphinx
70 | jinja2==3.0.3
71 | # via sphinx
72 | markupsafe==2.0.1
73 | # via jinja2
74 | mccabe==0.6.1
75 | # via flake8
76 | mock==4.0.3
77 | # via -r requirements.in
78 | packaging==21.3
79 | # via sphinx
80 | pep517==0.12.0
81 | # via pip-tools
82 | pep8-naming==0.12.1
83 | # via -r requirements.in
84 | pip-tools==6.4.0
85 | # via -r requirements.in
86 | pycodestyle==2.8.0
87 | # via flake8
88 | pyflakes==2.4.0
89 | # via flake8
90 | pygments==2.15.0
91 | # via sphinx
92 | pyparsing==3.0.6
93 | # via packaging
94 | pytz==2021.3
95 | # via babel
96 | requests==2.32.0
97 | # via sphinx
98 | six==1.16.0
99 | # via bleach
100 | snowballstemmer==2.2.0
101 | # via sphinx
102 | sphinx==4.3.2
103 | # via
104 | # -r requirements.in
105 | # sphinx-rtd-theme
106 | sphinx-rtd-theme==1.0.0
107 | # via -r requirements.in
108 | sphinxcontrib-applehelp==1.0.2
109 | # via sphinx
110 | sphinxcontrib-devhelp==1.0.2
111 | # via sphinx
112 | sphinxcontrib-htmlhelp==2.0.0
113 | # via sphinx
114 | sphinxcontrib-jsmath==1.0.1
115 | # via sphinx
116 | sphinxcontrib-qthelp==1.0.3
117 | # via sphinx
118 | sphinxcontrib-serializinghtml==1.1.5
119 | # via sphinx
120 | sqlparse==0.4.4
121 | # via django
122 | tomli==2.0.0
123 | # via pep517
124 | urllib3==1.26.7
125 | # via requests
126 | webencodings==0.5.1
127 | # via bleach
128 | wheel==0.38.1
129 | # via pip-tools
130 |
131 | # The following packages are considered to be unsafe in a requirements file:
132 | # pip
133 | # setuptools
134 |
--------------------------------------------------------------------------------
/docs/usage.rst:
--------------------------------------------------------------------------------
1 | .. _usage:
2 |
3 | =====
4 | Usage
5 | =====
6 |
7 | .. _models:
8 |
9 | In your models
10 | ==============
11 |
12 | ``django-bleach`` provides three ways of creating bleached output. The simplest
13 | way of including user-editable HTML content that is automatically sanitised is
14 | by using the BleachField model field::
15 |
16 | # in app/models.py
17 |
18 | from django import models
19 | from django_bleach.models import BleachField
20 |
21 | class Post(models.Model):
22 |
23 | title = models.CharField()
24 | content = BleachField()
25 |
26 | ``BleachField`` takes the following arguments, to customise the output of
27 | ``bleach``.
28 |
29 | See the bleach documentation for their use:
30 |
31 | * ``allowed_tags``
32 | * ``allowed_attributes``
33 | * ``allowed_protocols``
34 | * ``strip_tags``
35 | * ``strip_comments``
36 | * ``css_sanitizer``
37 |
38 | The following argument will be deprecated in the near future:
39 |
40 | * ``allowed_styles``
41 |
42 | In addition to the bleach-specific arguments, the ``BleachField`` model field
43 | accepts all of the normal field attributes. Behind the scenes, it is a
44 | ``TextField``, and accepts all the same arguments as ``TextField``.
45 |
46 | The ``BleachField`` model field sanitises its value before it is saved to the
47 | database and is marked safe so it can be immediately rendered in a template
48 | without further intervention.
49 |
50 | In model forms, ``BleachField`` model field are represented with the
51 | ``BleachField`` form field by default.
52 |
53 | .. _forms:
54 |
55 | In your forms
56 | =============
57 |
58 | A ``BleachField`` form field is provided. This field sanitises HTML input from
59 | the user, and presents safe, clean HTML to your Django application and the
60 | returned value is marked safe for immediate rendering.
61 |
62 | Usually you will want to use a ``BleachField`` model field, as opposed to the
63 | form field, but if you want, you can just use the form field. One possible use
64 | case for this set up is to force user input to be bleached, but allow
65 | administrators to add any content they like via another form (e.g. the admin
66 | site)::
67 |
68 | # in app/forms.py
69 |
70 | from django import forms
71 | from django_bleach.forms import BleachField
72 |
73 | from app.models import Post
74 |
75 | class PostForm(forms.ModelForm):
76 | class Meta:
77 | model = Post
78 |
79 | fields = ['title', 'content']
80 |
81 | content = BleachField()
82 |
83 | The ``BleachField`` form field takes exactly the same arguments as the
84 | ``BleachField`` model field above.
85 |
86 | .. _templates:
87 |
88 | In your templates
89 | =================
90 |
91 | If you have a piece of content from somewhere that needs to be printed in a
92 | template, you can use the ``bleach`` filter::
93 |
94 | {% load bleach_tags %}
95 |
96 | {{ some_unsafe_content|bleach }}
97 |
98 | It uses the ``ALLOWED_TAGS`` setting in your application, or optionally,
99 | ``bleach`` can pass tags::
100 |
101 | {% load bleach_tags %}
102 |
103 | {{ some_unsafe_content|bleach:"p,span" }}
104 |
105 | If you have content which doesn't contain HTML, but contains links or email
106 | addresses, you can also use the ``bleach_linkify`` filter to convert
107 | content to links::
108 |
109 |
110 | {% load bleach_tags %}
111 |
112 | {{ some_safe_content|bleach_linkify }}
113 |
114 |
--------------------------------------------------------------------------------
/django_bleach/tests/test_settings.py:
--------------------------------------------------------------------------------
1 | from unittest.mock import patch
2 |
3 | from bleach.css_sanitizer import CSSSanitizer
4 | from django.core.exceptions import ImproperlyConfigured
5 | from django.forms import Textarea
6 | from django.test import TestCase, override_settings
7 |
8 | from django_bleach.forms import get_default_widget
9 | from django_bleach.utils import get_bleach_default_options
10 | from testproject.constants import (
11 | ALLOWED_ATTRIBUTES,
12 | ALLOWED_CSS_PROPERTIES,
13 | ALLOWED_PROTOCOLS,
14 | ALLOWED_TAGS,
15 | )
16 | from testproject.forms import CustomBleachWidget
17 |
18 |
19 | class TestBleachOptions(TestCase):
20 | @patch(
21 | "django_bleach.utils.settings",
22 | BLEACH_ALLOWED_ATTRIBUTES=ALLOWED_ATTRIBUTES,
23 | )
24 | def test_custom_attrs(self, settings):
25 | bleach_args = get_bleach_default_options()
26 | self.assertEqual(bleach_args["attributes"], ALLOWED_ATTRIBUTES)
27 |
28 | @patch(
29 | "django_bleach.utils.settings",
30 | BLEACH_ALLOWED_PROTOCOLS=ALLOWED_PROTOCOLS,
31 | )
32 | def test_custom_proto(self, settings):
33 | bleach_args = get_bleach_default_options()
34 | self.assertEqual(bleach_args["protocols"], ALLOWED_PROTOCOLS)
35 |
36 | @patch(
37 | "django_bleach.utils.settings",
38 | BLEACH_ALLOWED_STYLES=ALLOWED_CSS_PROPERTIES,
39 | )
40 | def test_custom_styles(self, settings):
41 | bleach_args = get_bleach_default_options()
42 | self.assertIsInstance(bleach_args["css_sanitizer"], CSSSanitizer)
43 | self.assertEqual(
44 | bleach_args["css_sanitizer"].allowed_css_properties,
45 | ALLOWED_CSS_PROPERTIES,
46 | )
47 |
48 | @patch("django_bleach.utils.settings", BLEACH_ALLOWED_TAGS=ALLOWED_TAGS)
49 | def test_custom_tags(self, settings):
50 | bleach_args = get_bleach_default_options()
51 | self.assertEqual(bleach_args["tags"], ALLOWED_TAGS)
52 |
53 | @patch("django_bleach.utils.settings", BLEACH_STRIP_TAGS=True)
54 | def test_strip_tags(self, settings):
55 | bleach_args = get_bleach_default_options()
56 | self.assertEqual(bleach_args["strip"], True)
57 |
58 | @patch("django_bleach.utils.settings", BLEACH_STRIP_COMMENTS=True)
59 | def test_strip_comments(self, settings):
60 | bleach_args = get_bleach_default_options()
61 | self.assertEqual(bleach_args["strip_comments"], True)
62 |
63 |
64 | class TestDefaultWidget(TestCase):
65 | """Test form field widgets"""
66 |
67 | @override_settings(BLEACH_DEFAULT_WIDGET="django.forms.widgets.Textarea")
68 | def test_default_widget(self):
69 | self.assertEqual(get_default_widget(), Textarea)
70 |
71 | @patch(
72 | "django_bleach.forms.settings",
73 | BLEACH_DEFAULT_WIDGET="testproject.forms.CustomBleachWidget",
74 | )
75 | def test_custom_widget(self, settings):
76 | self.assertEqual(get_default_widget(), CustomBleachWidget)
77 |
78 | @patch(
79 | "django_bleach.forms.settings",
80 | BLEACH_DEFAULT_WIDGET="testproject.forms.NoneExistentWidget",
81 | )
82 | def test_attribute_err(self, settings):
83 | with self.assertRaises(ImproperlyConfigured):
84 | get_default_widget()
85 |
86 | @patch(
87 | "django_bleach.forms.settings",
88 | BLEACH_DEFAULT_WIDGET="testproject.forms2.CustomBleachWidget",
89 | )
90 | def test_import_err(self, settings):
91 | with self.assertRaises(ImproperlyConfigured):
92 | get_default_widget()
93 |
--------------------------------------------------------------------------------
/django_bleach/tests/test_modelformfield.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 | from django.test import TestCase, override_settings
3 |
4 | from django_bleach import forms as bleach_forms
5 | from testproject.forms import CustomBleachWidget
6 | from testproject.models import Person
7 |
8 | from .test_models import BleachContent
9 |
10 |
11 | class BleachContentModelForm(forms.ModelForm):
12 | class Meta:
13 | model = BleachContent
14 | fields = "__all__"
15 |
16 |
17 | class TestModelFormField(TestCase):
18 | def setUp(self):
19 | model_form = BleachContentModelForm()
20 | self.form_field = model_form.fields["content"]
21 | self.choice_form_field = model_form.fields["choice"]
22 | self.blank_field_form_field = model_form.fields["blank_field"]
23 | self.model_field = BleachContent()._meta.get_field("content")
24 |
25 | def test_formfield_type(self):
26 | """
27 | Check content's form field is instance of BleachField
28 | """
29 | self.assertIsInstance(self.form_field, bleach_forms.BleachField)
30 |
31 | def test_default_widget_type(self):
32 | """
33 | Widget class is Textarea when BLEACH_DEFAULT_WIDGET is not set.
34 | """
35 | form = forms.modelform_factory(Person, fields="__all__")()
36 | self.assertIsInstance(
37 | form.fields["biography"].widget,
38 | forms.Textarea,
39 | )
40 |
41 | @override_settings(
42 | BLEACH_DEFAULT_WIDGET="testproject.forms.CustomBleachWidget"
43 | )
44 | def test_custom_widget_type(self):
45 | """
46 | Widget class matches BLEACH_DEFAULT_WIDGET setting.
47 | """
48 | form = forms.modelform_factory(Person, fields="__all__")()
49 | self.assertIsInstance(
50 | form.fields["biography"].widget, CustomBleachWidget
51 | )
52 |
53 | @override_settings(
54 | BLEACH_DEFAULT_WIDGET="testproject.forms.CustomBleachWidget"
55 | )
56 | def test_widget_override(self):
57 | """
58 | Widget class matches widget class specified in overrides.
59 | """
60 | form = forms.modelform_factory(
61 | Person,
62 | fields="__all__",
63 | widgets={"biography": CustomBleachWidget},
64 | )()
65 | self.assertIsInstance(
66 | form.fields["biography"].widget, CustomBleachWidget
67 | )
68 |
69 | def test_same_allowed_args(self):
70 | """
71 | Check model and form's allowed arguments (tags, attributes, ...)
72 | are the same
73 | """
74 | form_allowed_args: dict = self.form_field.bleach_options
75 | model_allowed_args: dict = self.model_field.bleach_kwargs
76 |
77 | self.assertEqual(model_allowed_args, form_allowed_args)
78 |
79 | def test_with_choices(self):
80 | """
81 | Check if choices specified, use TextField's default widget (Select).
82 | """
83 | form_field_widget = self.choice_form_field.widget.__class__
84 | self.assertEqual(form_field_widget, forms.widgets.Select)
85 |
86 | def test_optional_field(self):
87 | """
88 | Check for the required flag on fields with `blank=True`
89 | """
90 | self.assertEqual(self.blank_field_form_field.required, False)
91 |
92 | def test_required_field(self):
93 | """
94 | Check for the required flag on fields
95 | """
96 | self.assertEqual(self.form_field.required, True)
97 |
98 |
99 | class CustomBleachedFormField(bleach_forms.BleachField): ...
100 |
101 |
102 | class OverriddenBleachContentModelForm(forms.ModelForm):
103 | class Meta:
104 | model = BleachContent
105 | fields = "__all__"
106 | field_classes = {
107 | "content": CustomBleachedFormField,
108 | }
109 |
110 |
111 | class TestModelFormFieldOverrides(TestCase):
112 | def setUp(self):
113 | model_form = OverriddenBleachContentModelForm()
114 | self.form_field = model_form.fields["content"]
115 |
116 | def test_formfield_type(self):
117 | """
118 | Check content's form field is instance of CustomBleachedFormField.
119 | """
120 | self.assertIsInstance(self.form_field, CustomBleachedFormField)
121 |
--------------------------------------------------------------------------------
/django_bleach/tests/test_models.py:
--------------------------------------------------------------------------------
1 | from bleach.css_sanitizer import CSSSanitizer
2 | from django.db import models
3 | from django.test import TestCase
4 | from django.utils.safestring import SafeString
5 |
6 | from django_bleach.models import BleachField
7 | from testproject.constants import (
8 | ALLOWED_ATTRIBUTES,
9 | ALLOWED_CSS_PROPERTIES,
10 | ALLOWED_PROTOCOLS,
11 | ALLOWED_TAGS,
12 | )
13 |
14 |
15 | class BleachContent(models.Model):
16 | """Bleach test model"""
17 |
18 | CHOICES = (("f", "first choice"), ("s", "second choice"))
19 | content = BleachField(
20 | allowed_attributes=ALLOWED_ATTRIBUTES,
21 | allowed_protocols=ALLOWED_PROTOCOLS,
22 | css_sanitizer=CSSSanitizer(
23 | allowed_css_properties=ALLOWED_CSS_PROPERTIES
24 | ),
25 | allowed_tags=ALLOWED_TAGS,
26 | allowed_styles=ALLOWED_CSS_PROPERTIES,
27 | strip_comments=True,
28 | strip_tags=True,
29 | )
30 | choice = BleachField(choices=CHOICES)
31 | blank_field = BleachField(blank=True)
32 | null_field = BleachField(blank=True, null=True)
33 |
34 |
35 | class TestBleachModelField(TestCase):
36 | """Test model field"""
37 |
38 | def test_bleaching(self):
39 | """Test values are bleached"""
40 | test_data = {
41 | "no_tags": "Heading ",
42 | "no_strip": "Heading ",
43 | "bleach_strip": """""",
44 | "bleach_attrs": 'google.com ',
46 | "bleach_css_sanitizer": 'item ',
47 | "bleach_comment": "",
48 | }
49 | expected_values = {
50 | "no_tags": "Heading",
51 | "no_strip": "Heading",
52 | "bleach_strip": """alert("Hello World")""",
53 | "bleach_attrs": "google.com ",
54 | "bleach_css_sanitizer": 'item ',
55 | "bleach_comment": "",
56 | }
57 |
58 | for key, value in test_data.items():
59 | obj = BleachContent.objects.create(content=value)
60 | self.assertEqual(obj.content, expected_values[key])
61 |
62 | def test_retrieved_values_are_template_safe(self):
63 | obj = BleachContent.objects.create(content="some content")
64 | obj.refresh_from_db()
65 | self.assertIsInstance(obj.content, SafeString)
66 | obj = BleachContent.objects.create(content="")
67 | obj.refresh_from_db()
68 | self.assertIsInstance(obj.content, SafeString)
69 |
70 | def test_saved_values_are_template_safe(self):
71 | obj = BleachContent(content="some content")
72 | obj.save()
73 | self.assertIsInstance(obj.content, SafeString)
74 | obj = BleachContent(content="")
75 | obj.save()
76 | self.assertIsInstance(obj.content, SafeString)
77 |
78 | def test_saved_none_values_are_none(self):
79 | obj = BleachContent(null_field=None)
80 | obj.save()
81 | self.assertIsNone(obj.null_field)
82 |
83 |
84 | class BleachNullableContent(models.Model):
85 | """Bleach test model"""
86 |
87 | content = BleachField(
88 | allowed_attributes=ALLOWED_ATTRIBUTES,
89 | allowed_protocols=ALLOWED_PROTOCOLS,
90 | css_sanitizer=CSSSanitizer(
91 | allowed_css_properties=ALLOWED_CSS_PROPERTIES
92 | ),
93 | allowed_tags=ALLOWED_TAGS,
94 | strip_comments=True,
95 | strip_tags=True,
96 | blank=True,
97 | null=True,
98 | )
99 |
100 |
101 | class TestBleachNullableModelField(TestCase):
102 | """Test model field"""
103 |
104 | def test_bleaching(self):
105 | """Test values are bleached"""
106 | test_data = {
107 | "none": None,
108 | "empty": "",
109 | "whitespaces": " ",
110 | "linebreak": "\n",
111 | }
112 | expected_values = {
113 | "none": None,
114 | "empty": "",
115 | "whitespaces": " ",
116 | "linebreak": "\n",
117 | }
118 |
119 | for key, value in test_data.items():
120 | obj = BleachNullableContent.objects.create(content=value)
121 | self.assertEqual(obj.content, expected_values[key])
122 |
--------------------------------------------------------------------------------
/requirements/compile.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | from __future__ import annotations
3 |
4 | import os
5 | import subprocess
6 | import sys
7 | from pathlib import Path
8 |
9 | if __name__ == "__main__":
10 | os.chdir(Path(__file__).parent)
11 | os.environ["CUSTOM_COMPILE_COMMAND"] = "requirements/compile.py"
12 | os.environ["PIP_REQUIRE_VIRTUALENV"] = "0"
13 | common_args = [
14 | "-m",
15 | "piptools",
16 | "compile",
17 | "--generate-hashes",
18 | "--allow-unsafe",
19 | ] + sys.argv[1:]
20 | # mysqlclient requirements found on each version's "Databases" documentation page:
21 | # https://docs.djangoproject.com/en/3.0/ref/databases/#mysql-db-api-drivers
22 | subprocess.run(
23 | [
24 | "python3.8",
25 | *common_args,
26 | "-P",
27 | "Django>=3.2a1,<3.3",
28 | "-o",
29 | "py38-django32.txt",
30 | ],
31 | check=True,
32 | capture_output=True,
33 | )
34 | subprocess.run(
35 | [
36 | "python3.8",
37 | *common_args,
38 | "-P",
39 | "Django>=4.0a1,<4.1",
40 | "-o",
41 | "py38-django40.txt",
42 | ],
43 | check=True,
44 | capture_output=True,
45 | )
46 | subprocess.run(
47 | [
48 | "python3.8",
49 | *common_args,
50 | "-P",
51 | "Django>=4.1a1,<4.2",
52 | "-o",
53 | "py38-django41.txt",
54 | ],
55 | check=True,
56 | capture_output=True,
57 | )
58 | subprocess.run(
59 | [
60 | "python3.8",
61 | *common_args,
62 | "-P",
63 | "Django>=4.2a1,<5.0",
64 | "-o",
65 | "py38-django42.txt",
66 | ],
67 | check=True,
68 | capture_output=True,
69 | )
70 | subprocess.run(
71 | [
72 | "python3.9",
73 | *common_args,
74 | "-P",
75 | "Django>=3.2a1,<3.3",
76 | "-o",
77 | "py39-django32.txt",
78 | ],
79 | check=True,
80 | capture_output=True,
81 | )
82 | subprocess.run(
83 | [
84 | "python3.9",
85 | *common_args,
86 | "-P",
87 | "Django>=4.0a1,<4.1",
88 | "-o",
89 | "py39-django40.txt",
90 | ],
91 | check=True,
92 | capture_output=True,
93 | )
94 | subprocess.run(
95 | [
96 | "python3.9",
97 | *common_args,
98 | "-P",
99 | "Django>=4.1a1,<4.2",
100 | "-o",
101 | "py39-django41.txt",
102 | ],
103 | check=True,
104 | capture_output=True,
105 | )
106 | subprocess.run(
107 | [
108 | "python3.9",
109 | *common_args,
110 | "-P",
111 | "Django>=4.2a1,<5.0",
112 | "-o",
113 | "py39-django42.txt",
114 | ],
115 | check=True,
116 | capture_output=True,
117 | )
118 | subprocess.run(
119 | [
120 | "python3.10",
121 | *common_args,
122 | "-P",
123 | "Django>=3.2a1,<3.3",
124 | "-o",
125 | "py310-django32.txt",
126 | ],
127 | check=True,
128 | capture_output=True,
129 | )
130 | subprocess.run(
131 | [
132 | "python3.10",
133 | *common_args,
134 | "-P",
135 | "Django>=4.0a1,<4.1",
136 | "-o",
137 | "py310-django40.txt",
138 | ],
139 | check=True,
140 | capture_output=True,
141 | )
142 | subprocess.run(
143 | [
144 | "python3.10",
145 | *common_args,
146 | "-P",
147 | "Django>=4.1a1,<4.2",
148 | "-o",
149 | "py310-django41.txt",
150 | ],
151 | check=True,
152 | capture_output=True,
153 | )
154 | subprocess.run(
155 | [
156 | "python3.10",
157 | *common_args,
158 | "-P",
159 | "Django>=4.2a1,<5.0",
160 | "-o",
161 | "py310-django42.txt",
162 | ],
163 | check=True,
164 | capture_output=True,
165 | )
166 | subprocess.run(
167 | [
168 | "python3.11",
169 | *common_args,
170 | "-P",
171 | "Django>=4.1a1,<4.2",
172 | "-o",
173 | "py311-django41.txt",
174 | ],
175 | check=True,
176 | capture_output=True,
177 | )
178 | subprocess.run(
179 | [
180 | "python3.11",
181 | *common_args,
182 | "-P",
183 | "Django>=4.2a1,<5.0",
184 | "-o",
185 | "py311-django42.txt",
186 | ],
187 | check=True,
188 | capture_output=True,
189 | )
190 | subprocess.run(
191 | [
192 | "python3.12",
193 | *common_args,
194 | "-P",
195 | "Django>=4.2a1,<5.0",
196 | "-o",
197 | "py312-django42.txt",
198 | ],
199 | check=True,
200 | capture_output=True,
201 | )
202 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | Change Log
2 | ==========
3 |
4 | This document records all notable changes to [django-bleach](https://github.com/marksweb/django-bleach).
5 | This project adheres to [Semantic Versioning](https://semver.org/).
6 |
7 | [unreleased](https://github.com/marksweb/django-bleach/compare/3.1.0...master) changes
8 | -------------------------------------------------------------------------------------
9 |
10 | Version 3.1.0
11 | =============
12 | **05-08-2023**
13 |
14 | * Added support for django 4.2
15 | * Added support for python 3.12
16 | * Revamp package for easier maintenance
17 |
18 |
19 | Version 3.0.1
20 | =============
21 | **11-10-2022**
22 |
23 | * Added support for django 4.1
24 |
25 | Version 3.0.0
26 | =============
27 | **19-05-2022**
28 |
29 | * Bleach dependency is now at ``>=5,<6`` [#55](https://github.com/marksweb/django-bleach/pull/55) (Thanks [Laityned](https://github.com/Laityned))
30 | * Deprecate bleach's `allowed_styles` kwarg
31 | * Added support for bleach's `css_sanitizer` kwarg
32 | * Add isort and codespell to ci
33 | * Dropped support for python 3.6 and 3.7 as well as django 3.0 and 3.1
34 | * Renamed default branch from `master` to `main`. If you have the project locally, you can update using:
35 |
36 | ```shell
37 | git branch -m master main
38 | git fetch origin
39 | git branch -u origin/main main
40 | git remote set-head origin -a
41 | ```
42 |
43 | Version 2.0.0
44 | =============
45 | ###### 08-04-2022
46 |
47 | * cap bleach version at ``<5`` [#51](https://github.com/marksweb/django-bleach/issues/51)
48 | * drop support for python 3.6
49 | * drop support for django 3.0 and 3.1
50 | * added support for django 4
51 |
52 | Version 1.0.0
53 | =============
54 | ###### 13-11-2021
55 | Going to 1.0 is long overdue, especially considering SemVer.
56 | * automated pypi releases via github actions
57 | * pre-commit hooks
58 | * python 3.10 support
59 | * docs syntax highlighting [#38](https://github.com/marksweb/django-bleach/pull/38)
60 |
61 | Version 0.9.0
62 | =============
63 | ###### 28-09-2021
64 | * Drop support for django <2.2
65 | * Added support for django 4.0
66 |
67 | Version 0.8.0
68 | =============
69 | ###### 18-09-2021
70 | Thank you to [Mark Gregson](https://github.com/MrkGrgsn) for providing the changes in this release!
71 | * Fix for [#28](https://github.com/marksweb/django-bleach/issues/28): Return ``empty_value`` for any empty input value
72 | * Fix for [#27](https://github.com/marksweb/django-bleach/issues/27): Mark cleaned data as template safe
73 | * Fix for [#25](https://github.com/marksweb/django-bleach/issues/25): Respect the ``form_class`` argument
74 | * Fix custom widget tests [#34](https://github.com/marksweb/django-bleach/pulls/34)
75 |
76 | Version 0.7.2
77 | =============
78 | ###### 27-07-2021
79 | * Fix for [#23](https://github.com/marksweb/django-bleach/issues/23): `kwargs` being lost in the default form field.
80 |
81 | Version 0.7.1
82 | =============
83 | ###### 23-07-2021
84 | * Fix for [#21](https://github.com/marksweb/django-bleach/issues/21): default form field not respecting required fields.
85 |
86 | Version 0.7.0
87 | =============
88 | ###### 09-07-2021
89 | * Default form field set to `forms.BleachField` for `models.BleachField` (Thanks [Alirezaja1384](https://github.com/Alirezaja1384))
90 | * Introduced testing against Python 3.9
91 |
92 | Version 0.6.1
93 | =============
94 | ###### 07-11-2019
95 | * Handle `None` as an input value of template tags (Thanks [pegler](https://github.com/pegler))
96 |
97 | Version 0.6.0
98 | =============
99 | ###### 18-10-2019
100 | * Introduced testing against Python 3.8
101 | * Drop support for Django <1.11
102 | * Test coverage at 100%
103 |
104 | Version 0.5.3
105 | =============
106 | ###### 16-04-2019
107 | * Fix for `BleachField` set to allow `blank` or `null`. (Thanks [denisroldan](https://github.com/denisroldan))
108 |
109 | Version 0.5.2
110 | =============
111 | ###### 15-03-2019
112 | * Fix for `BleachField` receiving a `None` value. (Thanks [MrkGrgsn](https://github.com/MrkGrgsn))
113 |
114 | Version 0.5.1
115 | =============
116 | ###### 12-02-2019
117 | * 100% coverage achieved
118 | * Changelog updated with `0.5.0` changes. (Thanks [dyve](https://github.com/dyve))
119 |
120 | Version 0.5.0
121 | =============
122 | ###### 02-02-2019
123 | * Added support for bleach's `allowed_protocols` kwarg. (Thanks [blag](https://github.com/blag))
124 | * Bleach dependency is now `>=1.5.0`
125 |
126 | Version 0.4.1
127 | =============
128 | ###### 24-01-2019
129 | * Option to pass *allowed tags* to the `bleach` template filter added by [Rafał Selewońko](https://github.com/seler).
130 | * Moved project to Github.
131 |
132 | Version 0.4.0
133 | =============
134 | ###### 18-12-2018
135 | * Added support for django>=1.9
136 | * Ensure that the `model_instance` field gets updated with the clean value
137 |
138 | Version 0.3.0
139 | =============
140 | ###### 20-09-2014
141 | * The `BleachField` model field now does its own sanitisation,
142 | and does *not* specify a default form field or widget.
143 | Developers are expected to provide their own widget as needed.
144 |
145 | Version 0.2.1
146 | =============
147 | ###### 02-09-2014
148 | * Make the package python3 compatible.
149 |
150 | Version 0.2.0
151 | =============
152 | ###### 14-02-2014
153 | * Add `bleach_linkify` template filter from [whitehat2k13](https://bitbucket.org/%7B66836148-7eee-4894-acec-e073b30499ee%7D/)
154 |
155 | Version 0.1.5
156 | =============
157 | ###### 25-09-2013
158 |
159 | Version 0.1.4
160 | =============
161 | ###### 03-06-2013
162 |
163 | Version 0.1.3
164 | =============
165 | ###### 22-08-2012
166 | * Add missing `templatetags` package, by using `find_packages()`
167 | * Correct templatetag name: ``bleach.py`` -> ``bleach_tags.py``
168 |
169 | Version 0.1.2
170 | =============
171 | ###### 13-08-2012
172 | * Fix south migration bug
173 |
174 | Version 0.1.1
175 | =============
176 | ###### 13-08-2012
177 | * add south_triple_field for south integration
178 | * clean up files to meet pep8 compliance
179 |
180 | Version 0.1.0
181 | =============
182 | ###### 13-08-2012
183 | * Initial release
184 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line.
5 | SPHINXOPTS =
6 | SPHINXBUILD = sphinx-build
7 | PAPER =
8 | BUILDDIR = _build
9 |
10 | # Internal variables.
11 | PAPEROPT_a4 = -D latex_paper_size=a4
12 | PAPEROPT_letter = -D latex_paper_size=letter
13 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
14 | # the i18n builder cannot share the environment and doctrees with the others
15 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
16 |
17 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
18 |
19 | help:
20 | @echo "Please use \`make ' where is one of"
21 | @echo " html to make standalone HTML files"
22 | @echo " dirhtml to make HTML files named index.html in directories"
23 | @echo " singlehtml to make a single large HTML file"
24 | @echo " pickle to make pickle files"
25 | @echo " json to make JSON files"
26 | @echo " htmlhelp to make HTML files and a HTML help project"
27 | @echo " qthelp to make HTML files and a qthelp project"
28 | @echo " devhelp to make HTML files and a Devhelp project"
29 | @echo " epub to make an epub"
30 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
31 | @echo " latexpdf to make LaTeX files and run them through pdflatex"
32 | @echo " text to make text files"
33 | @echo " man to make manual pages"
34 | @echo " texinfo to make Texinfo files"
35 | @echo " info to make Texinfo files and run them through makeinfo"
36 | @echo " gettext to make PO message catalogs"
37 | @echo " changes to make an overview of all changed/added/deprecated items"
38 | @echo " linkcheck to check all external links for integrity"
39 | @echo " doctest to run all doctests embedded in the documentation (if enabled)"
40 |
41 | clean:
42 | -rm -rf $(BUILDDIR)/*
43 |
44 | html:
45 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
46 | @echo
47 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
48 |
49 | dirhtml:
50 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
51 | @echo
52 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
53 |
54 | singlehtml:
55 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
56 | @echo
57 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
58 |
59 | pickle:
60 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
61 | @echo
62 | @echo "Build finished; now you can process the pickle files."
63 |
64 | json:
65 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
66 | @echo
67 | @echo "Build finished; now you can process the JSON files."
68 |
69 | htmlhelp:
70 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
71 | @echo
72 | @echo "Build finished; now you can run HTML Help Workshop with the" \
73 | ".hhp project file in $(BUILDDIR)/htmlhelp."
74 |
75 | qthelp:
76 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
77 | @echo
78 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \
79 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
80 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/django-bleach.qhcp"
81 | @echo "To view the help file:"
82 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/django-bleach.qhc"
83 |
84 | devhelp:
85 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
86 | @echo
87 | @echo "Build finished."
88 | @echo "To view the help file:"
89 | @echo "# mkdir -p $$HOME/.local/share/devhelp/django-bleach"
90 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/django-bleach"
91 | @echo "# devhelp"
92 |
93 | epub:
94 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
95 | @echo
96 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
97 |
98 | latex:
99 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
100 | @echo
101 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
102 | @echo "Run \`make' in that directory to run these through (pdf)latex" \
103 | "(use \`make latexpdf' here to do that automatically)."
104 |
105 | latexpdf:
106 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
107 | @echo "Running LaTeX files through pdflatex..."
108 | $(MAKE) -C $(BUILDDIR)/latex all-pdf
109 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
110 |
111 | text:
112 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
113 | @echo
114 | @echo "Build finished. The text files are in $(BUILDDIR)/text."
115 |
116 | man:
117 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
118 | @echo
119 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
120 |
121 | texinfo:
122 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
123 | @echo
124 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
125 | @echo "Run \`make' in that directory to run these through makeinfo" \
126 | "(use \`make info' here to do that automatically)."
127 |
128 | info:
129 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
130 | @echo "Running Texinfo files through makeinfo..."
131 | make -C $(BUILDDIR)/texinfo info
132 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
133 |
134 | gettext:
135 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
136 | @echo
137 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
138 |
139 | changes:
140 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
141 | @echo
142 | @echo "The overview file is in $(BUILDDIR)/changes."
143 |
144 | linkcheck:
145 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
146 | @echo
147 | @echo "Link check complete; look for any errors in the above output " \
148 | "or in $(BUILDDIR)/linkcheck/output.txt."
149 |
150 | doctest:
151 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
152 | @echo "Testing of doctests in the sources finished, look at the " \
153 | "results in $(BUILDDIR)/doctest/output.txt."
154 |
--------------------------------------------------------------------------------
/requirements/py311-django41.txt:
--------------------------------------------------------------------------------
1 | #
2 | # This file is autogenerated by pip-compile with Python 3.11
3 | # by the following command:
4 | #
5 | # requirements/compile.py
6 | #
7 | bleach==5.0.1 \
8 | --hash=sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a \
9 | --hash=sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c
10 | # via -r requirements.in
11 | coverage[toml]==7.2.7 \
12 | --hash=sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f \
13 | --hash=sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2 \
14 | --hash=sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a \
15 | --hash=sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a \
16 | --hash=sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01 \
17 | --hash=sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6 \
18 | --hash=sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7 \
19 | --hash=sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f \
20 | --hash=sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02 \
21 | --hash=sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c \
22 | --hash=sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063 \
23 | --hash=sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a \
24 | --hash=sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5 \
25 | --hash=sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959 \
26 | --hash=sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97 \
27 | --hash=sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6 \
28 | --hash=sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f \
29 | --hash=sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9 \
30 | --hash=sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5 \
31 | --hash=sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f \
32 | --hash=sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562 \
33 | --hash=sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe \
34 | --hash=sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9 \
35 | --hash=sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f \
36 | --hash=sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb \
37 | --hash=sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb \
38 | --hash=sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1 \
39 | --hash=sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb \
40 | --hash=sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250 \
41 | --hash=sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e \
42 | --hash=sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511 \
43 | --hash=sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5 \
44 | --hash=sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59 \
45 | --hash=sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2 \
46 | --hash=sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d \
47 | --hash=sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3 \
48 | --hash=sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4 \
49 | --hash=sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de \
50 | --hash=sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9 \
51 | --hash=sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833 \
52 | --hash=sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0 \
53 | --hash=sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9 \
54 | --hash=sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d \
55 | --hash=sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050 \
56 | --hash=sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d \
57 | --hash=sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6 \
58 | --hash=sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353 \
59 | --hash=sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb \
60 | --hash=sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e \
61 | --hash=sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8 \
62 | --hash=sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495 \
63 | --hash=sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2 \
64 | --hash=sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd \
65 | --hash=sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27 \
66 | --hash=sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1 \
67 | --hash=sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818 \
68 | --hash=sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4 \
69 | --hash=sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e \
70 | --hash=sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850 \
71 | --hash=sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3
72 | # via -r requirements.in
73 | mock==5.1.0 \
74 | --hash=sha256:18c694e5ae8a208cdb3d2c20a993ca1a7b0efa258c247a1e565150f477f83744 \
75 | --hash=sha256:5e96aad5ccda4718e0a229ed94b2024df75cc2d55575ba5762d31f5767b8767d
76 | # via -r requirements.in
77 | six==1.16.0 \
78 | --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
79 | --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
80 | # via bleach
81 | tinycss2==1.2.1 \
82 | --hash=sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847 \
83 | --hash=sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627
84 | # via -r requirements.in
85 | webencodings==0.5.1 \
86 | --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
87 | --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
88 | # via
89 | # bleach
90 | # tinycss2
91 |
--------------------------------------------------------------------------------
/requirements/py311-django42.txt:
--------------------------------------------------------------------------------
1 | #
2 | # This file is autogenerated by pip-compile with Python 3.11
3 | # by the following command:
4 | #
5 | # requirements/compile.py
6 | #
7 | bleach==5.0.1 \
8 | --hash=sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a \
9 | --hash=sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c
10 | # via -r requirements.in
11 | coverage[toml]==7.2.7 \
12 | --hash=sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f \
13 | --hash=sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2 \
14 | --hash=sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a \
15 | --hash=sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a \
16 | --hash=sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01 \
17 | --hash=sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6 \
18 | --hash=sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7 \
19 | --hash=sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f \
20 | --hash=sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02 \
21 | --hash=sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c \
22 | --hash=sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063 \
23 | --hash=sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a \
24 | --hash=sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5 \
25 | --hash=sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959 \
26 | --hash=sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97 \
27 | --hash=sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6 \
28 | --hash=sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f \
29 | --hash=sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9 \
30 | --hash=sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5 \
31 | --hash=sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f \
32 | --hash=sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562 \
33 | --hash=sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe \
34 | --hash=sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9 \
35 | --hash=sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f \
36 | --hash=sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb \
37 | --hash=sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb \
38 | --hash=sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1 \
39 | --hash=sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb \
40 | --hash=sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250 \
41 | --hash=sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e \
42 | --hash=sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511 \
43 | --hash=sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5 \
44 | --hash=sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59 \
45 | --hash=sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2 \
46 | --hash=sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d \
47 | --hash=sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3 \
48 | --hash=sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4 \
49 | --hash=sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de \
50 | --hash=sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9 \
51 | --hash=sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833 \
52 | --hash=sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0 \
53 | --hash=sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9 \
54 | --hash=sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d \
55 | --hash=sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050 \
56 | --hash=sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d \
57 | --hash=sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6 \
58 | --hash=sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353 \
59 | --hash=sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb \
60 | --hash=sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e \
61 | --hash=sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8 \
62 | --hash=sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495 \
63 | --hash=sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2 \
64 | --hash=sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd \
65 | --hash=sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27 \
66 | --hash=sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1 \
67 | --hash=sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818 \
68 | --hash=sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4 \
69 | --hash=sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e \
70 | --hash=sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850 \
71 | --hash=sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3
72 | # via -r requirements.in
73 | mock==5.1.0 \
74 | --hash=sha256:18c694e5ae8a208cdb3d2c20a993ca1a7b0efa258c247a1e565150f477f83744 \
75 | --hash=sha256:5e96aad5ccda4718e0a229ed94b2024df75cc2d55575ba5762d31f5767b8767d
76 | # via -r requirements.in
77 | six==1.16.0 \
78 | --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
79 | --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
80 | # via bleach
81 | tinycss2==1.2.1 \
82 | --hash=sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847 \
83 | --hash=sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627
84 | # via -r requirements.in
85 | webencodings==0.5.1 \
86 | --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
87 | --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
88 | # via
89 | # bleach
90 | # tinycss2
91 |
--------------------------------------------------------------------------------
/requirements/py312-django42.txt:
--------------------------------------------------------------------------------
1 | #
2 | # This file is autogenerated by pip-compile with Python 3.12
3 | # by the following command:
4 | #
5 | # requirements/compile.py
6 | #
7 | bleach==5.0.1 \
8 | --hash=sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a \
9 | --hash=sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c
10 | # via -r requirements.in
11 | coverage[toml]==7.2.7 \
12 | --hash=sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f \
13 | --hash=sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2 \
14 | --hash=sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a \
15 | --hash=sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a \
16 | --hash=sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01 \
17 | --hash=sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6 \
18 | --hash=sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7 \
19 | --hash=sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f \
20 | --hash=sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02 \
21 | --hash=sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c \
22 | --hash=sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063 \
23 | --hash=sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a \
24 | --hash=sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5 \
25 | --hash=sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959 \
26 | --hash=sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97 \
27 | --hash=sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6 \
28 | --hash=sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f \
29 | --hash=sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9 \
30 | --hash=sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5 \
31 | --hash=sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f \
32 | --hash=sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562 \
33 | --hash=sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe \
34 | --hash=sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9 \
35 | --hash=sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f \
36 | --hash=sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb \
37 | --hash=sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb \
38 | --hash=sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1 \
39 | --hash=sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb \
40 | --hash=sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250 \
41 | --hash=sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e \
42 | --hash=sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511 \
43 | --hash=sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5 \
44 | --hash=sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59 \
45 | --hash=sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2 \
46 | --hash=sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d \
47 | --hash=sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3 \
48 | --hash=sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4 \
49 | --hash=sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de \
50 | --hash=sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9 \
51 | --hash=sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833 \
52 | --hash=sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0 \
53 | --hash=sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9 \
54 | --hash=sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d \
55 | --hash=sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050 \
56 | --hash=sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d \
57 | --hash=sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6 \
58 | --hash=sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353 \
59 | --hash=sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb \
60 | --hash=sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e \
61 | --hash=sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8 \
62 | --hash=sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495 \
63 | --hash=sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2 \
64 | --hash=sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd \
65 | --hash=sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27 \
66 | --hash=sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1 \
67 | --hash=sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818 \
68 | --hash=sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4 \
69 | --hash=sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e \
70 | --hash=sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850 \
71 | --hash=sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3
72 | # via -r requirements.in
73 | mock==5.1.0 \
74 | --hash=sha256:18c694e5ae8a208cdb3d2c20a993ca1a7b0efa258c247a1e565150f477f83744 \
75 | --hash=sha256:5e96aad5ccda4718e0a229ed94b2024df75cc2d55575ba5762d31f5767b8767d
76 | # via -r requirements.in
77 | six==1.16.0 \
78 | --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
79 | --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
80 | # via bleach
81 | tinycss2==1.2.1 \
82 | --hash=sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847 \
83 | --hash=sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627
84 | # via -r requirements.in
85 | webencodings==0.5.1 \
86 | --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
87 | --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
88 | # via
89 | # bleach
90 | # tinycss2
91 |
--------------------------------------------------------------------------------
/requirements/py38-django32.txt:
--------------------------------------------------------------------------------
1 | #
2 | # This file is autogenerated by pip-compile with Python 3.8
3 | # by the following command:
4 | #
5 | # requirements/compile.py
6 | #
7 | bleach==5.0.1 \
8 | --hash=sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a \
9 | --hash=sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c
10 | # via -r requirements.in
11 | coverage[toml]==7.2.7 \
12 | --hash=sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f \
13 | --hash=sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2 \
14 | --hash=sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a \
15 | --hash=sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a \
16 | --hash=sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01 \
17 | --hash=sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6 \
18 | --hash=sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7 \
19 | --hash=sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f \
20 | --hash=sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02 \
21 | --hash=sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c \
22 | --hash=sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063 \
23 | --hash=sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a \
24 | --hash=sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5 \
25 | --hash=sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959 \
26 | --hash=sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97 \
27 | --hash=sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6 \
28 | --hash=sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f \
29 | --hash=sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9 \
30 | --hash=sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5 \
31 | --hash=sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f \
32 | --hash=sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562 \
33 | --hash=sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe \
34 | --hash=sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9 \
35 | --hash=sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f \
36 | --hash=sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb \
37 | --hash=sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb \
38 | --hash=sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1 \
39 | --hash=sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb \
40 | --hash=sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250 \
41 | --hash=sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e \
42 | --hash=sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511 \
43 | --hash=sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5 \
44 | --hash=sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59 \
45 | --hash=sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2 \
46 | --hash=sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d \
47 | --hash=sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3 \
48 | --hash=sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4 \
49 | --hash=sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de \
50 | --hash=sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9 \
51 | --hash=sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833 \
52 | --hash=sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0 \
53 | --hash=sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9 \
54 | --hash=sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d \
55 | --hash=sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050 \
56 | --hash=sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d \
57 | --hash=sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6 \
58 | --hash=sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353 \
59 | --hash=sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb \
60 | --hash=sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e \
61 | --hash=sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8 \
62 | --hash=sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495 \
63 | --hash=sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2 \
64 | --hash=sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd \
65 | --hash=sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27 \
66 | --hash=sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1 \
67 | --hash=sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818 \
68 | --hash=sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4 \
69 | --hash=sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e \
70 | --hash=sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850 \
71 | --hash=sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3
72 | # via -r requirements.in
73 | mock==5.1.0 \
74 | --hash=sha256:18c694e5ae8a208cdb3d2c20a993ca1a7b0efa258c247a1e565150f477f83744 \
75 | --hash=sha256:5e96aad5ccda4718e0a229ed94b2024df75cc2d55575ba5762d31f5767b8767d
76 | # via -r requirements.in
77 | six==1.16.0 \
78 | --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
79 | --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
80 | # via bleach
81 | tinycss2==1.2.1 \
82 | --hash=sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847 \
83 | --hash=sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627
84 | # via -r requirements.in
85 | tomli==2.0.1 \
86 | --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \
87 | --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f
88 | # via coverage
89 | webencodings==0.5.1 \
90 | --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
91 | --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
92 | # via
93 | # bleach
94 | # tinycss2
95 |
--------------------------------------------------------------------------------
/requirements/py38-django40.txt:
--------------------------------------------------------------------------------
1 | #
2 | # This file is autogenerated by pip-compile with Python 3.8
3 | # by the following command:
4 | #
5 | # requirements/compile.py
6 | #
7 | bleach==5.0.1 \
8 | --hash=sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a \
9 | --hash=sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c
10 | # via -r requirements.in
11 | coverage[toml]==7.2.7 \
12 | --hash=sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f \
13 | --hash=sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2 \
14 | --hash=sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a \
15 | --hash=sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a \
16 | --hash=sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01 \
17 | --hash=sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6 \
18 | --hash=sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7 \
19 | --hash=sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f \
20 | --hash=sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02 \
21 | --hash=sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c \
22 | --hash=sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063 \
23 | --hash=sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a \
24 | --hash=sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5 \
25 | --hash=sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959 \
26 | --hash=sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97 \
27 | --hash=sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6 \
28 | --hash=sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f \
29 | --hash=sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9 \
30 | --hash=sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5 \
31 | --hash=sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f \
32 | --hash=sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562 \
33 | --hash=sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe \
34 | --hash=sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9 \
35 | --hash=sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f \
36 | --hash=sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb \
37 | --hash=sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb \
38 | --hash=sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1 \
39 | --hash=sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb \
40 | --hash=sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250 \
41 | --hash=sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e \
42 | --hash=sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511 \
43 | --hash=sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5 \
44 | --hash=sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59 \
45 | --hash=sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2 \
46 | --hash=sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d \
47 | --hash=sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3 \
48 | --hash=sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4 \
49 | --hash=sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de \
50 | --hash=sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9 \
51 | --hash=sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833 \
52 | --hash=sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0 \
53 | --hash=sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9 \
54 | --hash=sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d \
55 | --hash=sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050 \
56 | --hash=sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d \
57 | --hash=sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6 \
58 | --hash=sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353 \
59 | --hash=sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb \
60 | --hash=sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e \
61 | --hash=sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8 \
62 | --hash=sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495 \
63 | --hash=sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2 \
64 | --hash=sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd \
65 | --hash=sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27 \
66 | --hash=sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1 \
67 | --hash=sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818 \
68 | --hash=sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4 \
69 | --hash=sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e \
70 | --hash=sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850 \
71 | --hash=sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3
72 | # via -r requirements.in
73 | mock==5.1.0 \
74 | --hash=sha256:18c694e5ae8a208cdb3d2c20a993ca1a7b0efa258c247a1e565150f477f83744 \
75 | --hash=sha256:5e96aad5ccda4718e0a229ed94b2024df75cc2d55575ba5762d31f5767b8767d
76 | # via -r requirements.in
77 | six==1.16.0 \
78 | --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
79 | --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
80 | # via bleach
81 | tinycss2==1.2.1 \
82 | --hash=sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847 \
83 | --hash=sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627
84 | # via -r requirements.in
85 | tomli==2.0.1 \
86 | --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \
87 | --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f
88 | # via coverage
89 | webencodings==0.5.1 \
90 | --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
91 | --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
92 | # via
93 | # bleach
94 | # tinycss2
95 |
--------------------------------------------------------------------------------
/requirements/py38-django41.txt:
--------------------------------------------------------------------------------
1 | #
2 | # This file is autogenerated by pip-compile with Python 3.8
3 | # by the following command:
4 | #
5 | # requirements/compile.py
6 | #
7 | bleach==5.0.1 \
8 | --hash=sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a \
9 | --hash=sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c
10 | # via -r requirements.in
11 | coverage[toml]==7.2.7 \
12 | --hash=sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f \
13 | --hash=sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2 \
14 | --hash=sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a \
15 | --hash=sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a \
16 | --hash=sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01 \
17 | --hash=sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6 \
18 | --hash=sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7 \
19 | --hash=sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f \
20 | --hash=sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02 \
21 | --hash=sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c \
22 | --hash=sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063 \
23 | --hash=sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a \
24 | --hash=sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5 \
25 | --hash=sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959 \
26 | --hash=sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97 \
27 | --hash=sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6 \
28 | --hash=sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f \
29 | --hash=sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9 \
30 | --hash=sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5 \
31 | --hash=sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f \
32 | --hash=sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562 \
33 | --hash=sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe \
34 | --hash=sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9 \
35 | --hash=sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f \
36 | --hash=sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb \
37 | --hash=sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb \
38 | --hash=sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1 \
39 | --hash=sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb \
40 | --hash=sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250 \
41 | --hash=sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e \
42 | --hash=sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511 \
43 | --hash=sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5 \
44 | --hash=sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59 \
45 | --hash=sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2 \
46 | --hash=sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d \
47 | --hash=sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3 \
48 | --hash=sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4 \
49 | --hash=sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de \
50 | --hash=sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9 \
51 | --hash=sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833 \
52 | --hash=sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0 \
53 | --hash=sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9 \
54 | --hash=sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d \
55 | --hash=sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050 \
56 | --hash=sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d \
57 | --hash=sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6 \
58 | --hash=sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353 \
59 | --hash=sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb \
60 | --hash=sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e \
61 | --hash=sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8 \
62 | --hash=sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495 \
63 | --hash=sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2 \
64 | --hash=sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd \
65 | --hash=sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27 \
66 | --hash=sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1 \
67 | --hash=sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818 \
68 | --hash=sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4 \
69 | --hash=sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e \
70 | --hash=sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850 \
71 | --hash=sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3
72 | # via -r requirements.in
73 | mock==5.1.0 \
74 | --hash=sha256:18c694e5ae8a208cdb3d2c20a993ca1a7b0efa258c247a1e565150f477f83744 \
75 | --hash=sha256:5e96aad5ccda4718e0a229ed94b2024df75cc2d55575ba5762d31f5767b8767d
76 | # via -r requirements.in
77 | six==1.16.0 \
78 | --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
79 | --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
80 | # via bleach
81 | tinycss2==1.2.1 \
82 | --hash=sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847 \
83 | --hash=sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627
84 | # via -r requirements.in
85 | tomli==2.0.1 \
86 | --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \
87 | --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f
88 | # via coverage
89 | webencodings==0.5.1 \
90 | --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
91 | --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
92 | # via
93 | # bleach
94 | # tinycss2
95 |
--------------------------------------------------------------------------------
/requirements/py38-django42.txt:
--------------------------------------------------------------------------------
1 | #
2 | # This file is autogenerated by pip-compile with Python 3.8
3 | # by the following command:
4 | #
5 | # requirements/compile.py
6 | #
7 | bleach==5.0.1 \
8 | --hash=sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a \
9 | --hash=sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c
10 | # via -r requirements.in
11 | coverage[toml]==7.2.7 \
12 | --hash=sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f \
13 | --hash=sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2 \
14 | --hash=sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a \
15 | --hash=sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a \
16 | --hash=sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01 \
17 | --hash=sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6 \
18 | --hash=sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7 \
19 | --hash=sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f \
20 | --hash=sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02 \
21 | --hash=sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c \
22 | --hash=sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063 \
23 | --hash=sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a \
24 | --hash=sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5 \
25 | --hash=sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959 \
26 | --hash=sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97 \
27 | --hash=sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6 \
28 | --hash=sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f \
29 | --hash=sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9 \
30 | --hash=sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5 \
31 | --hash=sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f \
32 | --hash=sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562 \
33 | --hash=sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe \
34 | --hash=sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9 \
35 | --hash=sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f \
36 | --hash=sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb \
37 | --hash=sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb \
38 | --hash=sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1 \
39 | --hash=sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb \
40 | --hash=sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250 \
41 | --hash=sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e \
42 | --hash=sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511 \
43 | --hash=sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5 \
44 | --hash=sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59 \
45 | --hash=sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2 \
46 | --hash=sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d \
47 | --hash=sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3 \
48 | --hash=sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4 \
49 | --hash=sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de \
50 | --hash=sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9 \
51 | --hash=sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833 \
52 | --hash=sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0 \
53 | --hash=sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9 \
54 | --hash=sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d \
55 | --hash=sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050 \
56 | --hash=sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d \
57 | --hash=sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6 \
58 | --hash=sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353 \
59 | --hash=sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb \
60 | --hash=sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e \
61 | --hash=sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8 \
62 | --hash=sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495 \
63 | --hash=sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2 \
64 | --hash=sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd \
65 | --hash=sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27 \
66 | --hash=sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1 \
67 | --hash=sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818 \
68 | --hash=sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4 \
69 | --hash=sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e \
70 | --hash=sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850 \
71 | --hash=sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3
72 | # via -r requirements.in
73 | mock==5.1.0 \
74 | --hash=sha256:18c694e5ae8a208cdb3d2c20a993ca1a7b0efa258c247a1e565150f477f83744 \
75 | --hash=sha256:5e96aad5ccda4718e0a229ed94b2024df75cc2d55575ba5762d31f5767b8767d
76 | # via -r requirements.in
77 | six==1.16.0 \
78 | --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
79 | --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
80 | # via bleach
81 | tinycss2==1.2.1 \
82 | --hash=sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847 \
83 | --hash=sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627
84 | # via -r requirements.in
85 | tomli==2.0.1 \
86 | --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \
87 | --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f
88 | # via coverage
89 | webencodings==0.5.1 \
90 | --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
91 | --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
92 | # via
93 | # bleach
94 | # tinycss2
95 |
--------------------------------------------------------------------------------
/requirements/py39-django32.txt:
--------------------------------------------------------------------------------
1 | #
2 | # This file is autogenerated by pip-compile with Python 3.9
3 | # by the following command:
4 | #
5 | # requirements/compile.py
6 | #
7 | bleach==5.0.1 \
8 | --hash=sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a \
9 | --hash=sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c
10 | # via -r requirements.in
11 | coverage[toml]==7.2.7 \
12 | --hash=sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f \
13 | --hash=sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2 \
14 | --hash=sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a \
15 | --hash=sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a \
16 | --hash=sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01 \
17 | --hash=sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6 \
18 | --hash=sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7 \
19 | --hash=sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f \
20 | --hash=sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02 \
21 | --hash=sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c \
22 | --hash=sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063 \
23 | --hash=sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a \
24 | --hash=sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5 \
25 | --hash=sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959 \
26 | --hash=sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97 \
27 | --hash=sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6 \
28 | --hash=sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f \
29 | --hash=sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9 \
30 | --hash=sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5 \
31 | --hash=sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f \
32 | --hash=sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562 \
33 | --hash=sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe \
34 | --hash=sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9 \
35 | --hash=sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f \
36 | --hash=sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb \
37 | --hash=sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb \
38 | --hash=sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1 \
39 | --hash=sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb \
40 | --hash=sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250 \
41 | --hash=sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e \
42 | --hash=sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511 \
43 | --hash=sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5 \
44 | --hash=sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59 \
45 | --hash=sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2 \
46 | --hash=sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d \
47 | --hash=sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3 \
48 | --hash=sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4 \
49 | --hash=sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de \
50 | --hash=sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9 \
51 | --hash=sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833 \
52 | --hash=sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0 \
53 | --hash=sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9 \
54 | --hash=sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d \
55 | --hash=sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050 \
56 | --hash=sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d \
57 | --hash=sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6 \
58 | --hash=sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353 \
59 | --hash=sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb \
60 | --hash=sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e \
61 | --hash=sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8 \
62 | --hash=sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495 \
63 | --hash=sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2 \
64 | --hash=sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd \
65 | --hash=sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27 \
66 | --hash=sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1 \
67 | --hash=sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818 \
68 | --hash=sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4 \
69 | --hash=sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e \
70 | --hash=sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850 \
71 | --hash=sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3
72 | # via -r requirements.in
73 | mock==5.1.0 \
74 | --hash=sha256:18c694e5ae8a208cdb3d2c20a993ca1a7b0efa258c247a1e565150f477f83744 \
75 | --hash=sha256:5e96aad5ccda4718e0a229ed94b2024df75cc2d55575ba5762d31f5767b8767d
76 | # via -r requirements.in
77 | six==1.16.0 \
78 | --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
79 | --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
80 | # via bleach
81 | tinycss2==1.2.1 \
82 | --hash=sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847 \
83 | --hash=sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627
84 | # via -r requirements.in
85 | tomli==2.0.1 \
86 | --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \
87 | --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f
88 | # via coverage
89 | webencodings==0.5.1 \
90 | --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
91 | --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
92 | # via
93 | # bleach
94 | # tinycss2
95 |
--------------------------------------------------------------------------------
/requirements/py39-django40.txt:
--------------------------------------------------------------------------------
1 | #
2 | # This file is autogenerated by pip-compile with Python 3.9
3 | # by the following command:
4 | #
5 | # requirements/compile.py
6 | #
7 | bleach==5.0.1 \
8 | --hash=sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a \
9 | --hash=sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c
10 | # via -r requirements.in
11 | coverage[toml]==7.2.7 \
12 | --hash=sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f \
13 | --hash=sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2 \
14 | --hash=sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a \
15 | --hash=sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a \
16 | --hash=sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01 \
17 | --hash=sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6 \
18 | --hash=sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7 \
19 | --hash=sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f \
20 | --hash=sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02 \
21 | --hash=sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c \
22 | --hash=sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063 \
23 | --hash=sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a \
24 | --hash=sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5 \
25 | --hash=sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959 \
26 | --hash=sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97 \
27 | --hash=sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6 \
28 | --hash=sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f \
29 | --hash=sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9 \
30 | --hash=sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5 \
31 | --hash=sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f \
32 | --hash=sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562 \
33 | --hash=sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe \
34 | --hash=sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9 \
35 | --hash=sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f \
36 | --hash=sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb \
37 | --hash=sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb \
38 | --hash=sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1 \
39 | --hash=sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb \
40 | --hash=sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250 \
41 | --hash=sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e \
42 | --hash=sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511 \
43 | --hash=sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5 \
44 | --hash=sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59 \
45 | --hash=sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2 \
46 | --hash=sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d \
47 | --hash=sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3 \
48 | --hash=sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4 \
49 | --hash=sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de \
50 | --hash=sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9 \
51 | --hash=sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833 \
52 | --hash=sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0 \
53 | --hash=sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9 \
54 | --hash=sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d \
55 | --hash=sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050 \
56 | --hash=sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d \
57 | --hash=sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6 \
58 | --hash=sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353 \
59 | --hash=sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb \
60 | --hash=sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e \
61 | --hash=sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8 \
62 | --hash=sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495 \
63 | --hash=sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2 \
64 | --hash=sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd \
65 | --hash=sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27 \
66 | --hash=sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1 \
67 | --hash=sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818 \
68 | --hash=sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4 \
69 | --hash=sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e \
70 | --hash=sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850 \
71 | --hash=sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3
72 | # via -r requirements.in
73 | mock==5.1.0 \
74 | --hash=sha256:18c694e5ae8a208cdb3d2c20a993ca1a7b0efa258c247a1e565150f477f83744 \
75 | --hash=sha256:5e96aad5ccda4718e0a229ed94b2024df75cc2d55575ba5762d31f5767b8767d
76 | # via -r requirements.in
77 | six==1.16.0 \
78 | --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
79 | --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
80 | # via bleach
81 | tinycss2==1.2.1 \
82 | --hash=sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847 \
83 | --hash=sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627
84 | # via -r requirements.in
85 | tomli==2.0.1 \
86 | --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \
87 | --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f
88 | # via coverage
89 | webencodings==0.5.1 \
90 | --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
91 | --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
92 | # via
93 | # bleach
94 | # tinycss2
95 |
--------------------------------------------------------------------------------
/requirements/py39-django41.txt:
--------------------------------------------------------------------------------
1 | #
2 | # This file is autogenerated by pip-compile with Python 3.9
3 | # by the following command:
4 | #
5 | # requirements/compile.py
6 | #
7 | bleach==5.0.1 \
8 | --hash=sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a \
9 | --hash=sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c
10 | # via -r requirements.in
11 | coverage[toml]==7.2.7 \
12 | --hash=sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f \
13 | --hash=sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2 \
14 | --hash=sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a \
15 | --hash=sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a \
16 | --hash=sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01 \
17 | --hash=sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6 \
18 | --hash=sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7 \
19 | --hash=sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f \
20 | --hash=sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02 \
21 | --hash=sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c \
22 | --hash=sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063 \
23 | --hash=sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a \
24 | --hash=sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5 \
25 | --hash=sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959 \
26 | --hash=sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97 \
27 | --hash=sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6 \
28 | --hash=sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f \
29 | --hash=sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9 \
30 | --hash=sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5 \
31 | --hash=sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f \
32 | --hash=sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562 \
33 | --hash=sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe \
34 | --hash=sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9 \
35 | --hash=sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f \
36 | --hash=sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb \
37 | --hash=sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb \
38 | --hash=sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1 \
39 | --hash=sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb \
40 | --hash=sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250 \
41 | --hash=sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e \
42 | --hash=sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511 \
43 | --hash=sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5 \
44 | --hash=sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59 \
45 | --hash=sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2 \
46 | --hash=sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d \
47 | --hash=sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3 \
48 | --hash=sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4 \
49 | --hash=sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de \
50 | --hash=sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9 \
51 | --hash=sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833 \
52 | --hash=sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0 \
53 | --hash=sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9 \
54 | --hash=sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d \
55 | --hash=sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050 \
56 | --hash=sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d \
57 | --hash=sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6 \
58 | --hash=sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353 \
59 | --hash=sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb \
60 | --hash=sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e \
61 | --hash=sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8 \
62 | --hash=sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495 \
63 | --hash=sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2 \
64 | --hash=sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd \
65 | --hash=sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27 \
66 | --hash=sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1 \
67 | --hash=sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818 \
68 | --hash=sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4 \
69 | --hash=sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e \
70 | --hash=sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850 \
71 | --hash=sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3
72 | # via -r requirements.in
73 | mock==5.1.0 \
74 | --hash=sha256:18c694e5ae8a208cdb3d2c20a993ca1a7b0efa258c247a1e565150f477f83744 \
75 | --hash=sha256:5e96aad5ccda4718e0a229ed94b2024df75cc2d55575ba5762d31f5767b8767d
76 | # via -r requirements.in
77 | six==1.16.0 \
78 | --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
79 | --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
80 | # via bleach
81 | tinycss2==1.2.1 \
82 | --hash=sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847 \
83 | --hash=sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627
84 | # via -r requirements.in
85 | tomli==2.0.1 \
86 | --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \
87 | --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f
88 | # via coverage
89 | webencodings==0.5.1 \
90 | --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
91 | --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
92 | # via
93 | # bleach
94 | # tinycss2
95 |
--------------------------------------------------------------------------------
/requirements/py39-django42.txt:
--------------------------------------------------------------------------------
1 | #
2 | # This file is autogenerated by pip-compile with Python 3.9
3 | # by the following command:
4 | #
5 | # requirements/compile.py
6 | #
7 | bleach==5.0.1 \
8 | --hash=sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a \
9 | --hash=sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c
10 | # via -r requirements.in
11 | coverage[toml]==7.2.7 \
12 | --hash=sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f \
13 | --hash=sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2 \
14 | --hash=sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a \
15 | --hash=sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a \
16 | --hash=sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01 \
17 | --hash=sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6 \
18 | --hash=sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7 \
19 | --hash=sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f \
20 | --hash=sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02 \
21 | --hash=sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c \
22 | --hash=sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063 \
23 | --hash=sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a \
24 | --hash=sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5 \
25 | --hash=sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959 \
26 | --hash=sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97 \
27 | --hash=sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6 \
28 | --hash=sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f \
29 | --hash=sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9 \
30 | --hash=sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5 \
31 | --hash=sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f \
32 | --hash=sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562 \
33 | --hash=sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe \
34 | --hash=sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9 \
35 | --hash=sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f \
36 | --hash=sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb \
37 | --hash=sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb \
38 | --hash=sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1 \
39 | --hash=sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb \
40 | --hash=sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250 \
41 | --hash=sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e \
42 | --hash=sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511 \
43 | --hash=sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5 \
44 | --hash=sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59 \
45 | --hash=sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2 \
46 | --hash=sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d \
47 | --hash=sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3 \
48 | --hash=sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4 \
49 | --hash=sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de \
50 | --hash=sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9 \
51 | --hash=sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833 \
52 | --hash=sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0 \
53 | --hash=sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9 \
54 | --hash=sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d \
55 | --hash=sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050 \
56 | --hash=sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d \
57 | --hash=sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6 \
58 | --hash=sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353 \
59 | --hash=sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb \
60 | --hash=sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e \
61 | --hash=sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8 \
62 | --hash=sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495 \
63 | --hash=sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2 \
64 | --hash=sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd \
65 | --hash=sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27 \
66 | --hash=sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1 \
67 | --hash=sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818 \
68 | --hash=sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4 \
69 | --hash=sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e \
70 | --hash=sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850 \
71 | --hash=sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3
72 | # via -r requirements.in
73 | mock==5.1.0 \
74 | --hash=sha256:18c694e5ae8a208cdb3d2c20a993ca1a7b0efa258c247a1e565150f477f83744 \
75 | --hash=sha256:5e96aad5ccda4718e0a229ed94b2024df75cc2d55575ba5762d31f5767b8767d
76 | # via -r requirements.in
77 | six==1.16.0 \
78 | --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
79 | --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
80 | # via bleach
81 | tinycss2==1.2.1 \
82 | --hash=sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847 \
83 | --hash=sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627
84 | # via -r requirements.in
85 | tomli==2.0.1 \
86 | --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \
87 | --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f
88 | # via coverage
89 | webencodings==0.5.1 \
90 | --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
91 | --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
92 | # via
93 | # bleach
94 | # tinycss2
95 |
--------------------------------------------------------------------------------
/requirements/py310-django32.txt:
--------------------------------------------------------------------------------
1 | #
2 | # This file is autogenerated by pip-compile with Python 3.10
3 | # by the following command:
4 | #
5 | # requirements/compile.py
6 | #
7 | bleach==5.0.1 \
8 | --hash=sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a \
9 | --hash=sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c
10 | # via -r requirements.in
11 | coverage[toml]==7.2.7 \
12 | --hash=sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f \
13 | --hash=sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2 \
14 | --hash=sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a \
15 | --hash=sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a \
16 | --hash=sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01 \
17 | --hash=sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6 \
18 | --hash=sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7 \
19 | --hash=sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f \
20 | --hash=sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02 \
21 | --hash=sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c \
22 | --hash=sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063 \
23 | --hash=sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a \
24 | --hash=sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5 \
25 | --hash=sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959 \
26 | --hash=sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97 \
27 | --hash=sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6 \
28 | --hash=sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f \
29 | --hash=sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9 \
30 | --hash=sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5 \
31 | --hash=sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f \
32 | --hash=sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562 \
33 | --hash=sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe \
34 | --hash=sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9 \
35 | --hash=sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f \
36 | --hash=sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb \
37 | --hash=sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb \
38 | --hash=sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1 \
39 | --hash=sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb \
40 | --hash=sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250 \
41 | --hash=sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e \
42 | --hash=sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511 \
43 | --hash=sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5 \
44 | --hash=sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59 \
45 | --hash=sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2 \
46 | --hash=sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d \
47 | --hash=sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3 \
48 | --hash=sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4 \
49 | --hash=sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de \
50 | --hash=sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9 \
51 | --hash=sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833 \
52 | --hash=sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0 \
53 | --hash=sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9 \
54 | --hash=sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d \
55 | --hash=sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050 \
56 | --hash=sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d \
57 | --hash=sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6 \
58 | --hash=sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353 \
59 | --hash=sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb \
60 | --hash=sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e \
61 | --hash=sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8 \
62 | --hash=sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495 \
63 | --hash=sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2 \
64 | --hash=sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd \
65 | --hash=sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27 \
66 | --hash=sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1 \
67 | --hash=sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818 \
68 | --hash=sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4 \
69 | --hash=sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e \
70 | --hash=sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850 \
71 | --hash=sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3
72 | # via -r requirements.in
73 | mock==5.1.0 \
74 | --hash=sha256:18c694e5ae8a208cdb3d2c20a993ca1a7b0efa258c247a1e565150f477f83744 \
75 | --hash=sha256:5e96aad5ccda4718e0a229ed94b2024df75cc2d55575ba5762d31f5767b8767d
76 | # via -r requirements.in
77 | six==1.16.0 \
78 | --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
79 | --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
80 | # via bleach
81 | tinycss2==1.2.1 \
82 | --hash=sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847 \
83 | --hash=sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627
84 | # via -r requirements.in
85 | tomli==2.0.1 \
86 | --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \
87 | --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f
88 | # via coverage
89 | webencodings==0.5.1 \
90 | --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
91 | --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
92 | # via
93 | # bleach
94 | # tinycss2
95 |
--------------------------------------------------------------------------------
/requirements/py310-django40.txt:
--------------------------------------------------------------------------------
1 | #
2 | # This file is autogenerated by pip-compile with Python 3.10
3 | # by the following command:
4 | #
5 | # requirements/compile.py
6 | #
7 | bleach==5.0.1 \
8 | --hash=sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a \
9 | --hash=sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c
10 | # via -r requirements.in
11 | coverage[toml]==7.2.7 \
12 | --hash=sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f \
13 | --hash=sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2 \
14 | --hash=sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a \
15 | --hash=sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a \
16 | --hash=sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01 \
17 | --hash=sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6 \
18 | --hash=sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7 \
19 | --hash=sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f \
20 | --hash=sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02 \
21 | --hash=sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c \
22 | --hash=sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063 \
23 | --hash=sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a \
24 | --hash=sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5 \
25 | --hash=sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959 \
26 | --hash=sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97 \
27 | --hash=sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6 \
28 | --hash=sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f \
29 | --hash=sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9 \
30 | --hash=sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5 \
31 | --hash=sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f \
32 | --hash=sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562 \
33 | --hash=sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe \
34 | --hash=sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9 \
35 | --hash=sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f \
36 | --hash=sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb \
37 | --hash=sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb \
38 | --hash=sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1 \
39 | --hash=sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb \
40 | --hash=sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250 \
41 | --hash=sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e \
42 | --hash=sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511 \
43 | --hash=sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5 \
44 | --hash=sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59 \
45 | --hash=sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2 \
46 | --hash=sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d \
47 | --hash=sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3 \
48 | --hash=sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4 \
49 | --hash=sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de \
50 | --hash=sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9 \
51 | --hash=sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833 \
52 | --hash=sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0 \
53 | --hash=sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9 \
54 | --hash=sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d \
55 | --hash=sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050 \
56 | --hash=sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d \
57 | --hash=sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6 \
58 | --hash=sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353 \
59 | --hash=sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb \
60 | --hash=sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e \
61 | --hash=sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8 \
62 | --hash=sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495 \
63 | --hash=sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2 \
64 | --hash=sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd \
65 | --hash=sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27 \
66 | --hash=sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1 \
67 | --hash=sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818 \
68 | --hash=sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4 \
69 | --hash=sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e \
70 | --hash=sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850 \
71 | --hash=sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3
72 | # via -r requirements.in
73 | mock==5.1.0 \
74 | --hash=sha256:18c694e5ae8a208cdb3d2c20a993ca1a7b0efa258c247a1e565150f477f83744 \
75 | --hash=sha256:5e96aad5ccda4718e0a229ed94b2024df75cc2d55575ba5762d31f5767b8767d
76 | # via -r requirements.in
77 | six==1.16.0 \
78 | --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
79 | --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
80 | # via bleach
81 | tinycss2==1.2.1 \
82 | --hash=sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847 \
83 | --hash=sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627
84 | # via -r requirements.in
85 | tomli==2.0.1 \
86 | --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \
87 | --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f
88 | # via coverage
89 | webencodings==0.5.1 \
90 | --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
91 | --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
92 | # via
93 | # bleach
94 | # tinycss2
95 |
--------------------------------------------------------------------------------
/requirements/py310-django41.txt:
--------------------------------------------------------------------------------
1 | #
2 | # This file is autogenerated by pip-compile with Python 3.10
3 | # by the following command:
4 | #
5 | # requirements/compile.py
6 | #
7 | bleach==5.0.1 \
8 | --hash=sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a \
9 | --hash=sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c
10 | # via -r requirements.in
11 | coverage[toml]==7.2.7 \
12 | --hash=sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f \
13 | --hash=sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2 \
14 | --hash=sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a \
15 | --hash=sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a \
16 | --hash=sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01 \
17 | --hash=sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6 \
18 | --hash=sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7 \
19 | --hash=sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f \
20 | --hash=sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02 \
21 | --hash=sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c \
22 | --hash=sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063 \
23 | --hash=sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a \
24 | --hash=sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5 \
25 | --hash=sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959 \
26 | --hash=sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97 \
27 | --hash=sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6 \
28 | --hash=sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f \
29 | --hash=sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9 \
30 | --hash=sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5 \
31 | --hash=sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f \
32 | --hash=sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562 \
33 | --hash=sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe \
34 | --hash=sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9 \
35 | --hash=sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f \
36 | --hash=sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb \
37 | --hash=sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb \
38 | --hash=sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1 \
39 | --hash=sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb \
40 | --hash=sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250 \
41 | --hash=sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e \
42 | --hash=sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511 \
43 | --hash=sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5 \
44 | --hash=sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59 \
45 | --hash=sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2 \
46 | --hash=sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d \
47 | --hash=sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3 \
48 | --hash=sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4 \
49 | --hash=sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de \
50 | --hash=sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9 \
51 | --hash=sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833 \
52 | --hash=sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0 \
53 | --hash=sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9 \
54 | --hash=sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d \
55 | --hash=sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050 \
56 | --hash=sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d \
57 | --hash=sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6 \
58 | --hash=sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353 \
59 | --hash=sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb \
60 | --hash=sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e \
61 | --hash=sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8 \
62 | --hash=sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495 \
63 | --hash=sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2 \
64 | --hash=sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd \
65 | --hash=sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27 \
66 | --hash=sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1 \
67 | --hash=sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818 \
68 | --hash=sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4 \
69 | --hash=sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e \
70 | --hash=sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850 \
71 | --hash=sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3
72 | # via -r requirements.in
73 | mock==5.1.0 \
74 | --hash=sha256:18c694e5ae8a208cdb3d2c20a993ca1a7b0efa258c247a1e565150f477f83744 \
75 | --hash=sha256:5e96aad5ccda4718e0a229ed94b2024df75cc2d55575ba5762d31f5767b8767d
76 | # via -r requirements.in
77 | six==1.16.0 \
78 | --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
79 | --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
80 | # via bleach
81 | tinycss2==1.2.1 \
82 | --hash=sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847 \
83 | --hash=sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627
84 | # via -r requirements.in
85 | tomli==2.0.1 \
86 | --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \
87 | --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f
88 | # via coverage
89 | webencodings==0.5.1 \
90 | --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
91 | --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
92 | # via
93 | # bleach
94 | # tinycss2
95 |
--------------------------------------------------------------------------------
/requirements/py310-django42.txt:
--------------------------------------------------------------------------------
1 | #
2 | # This file is autogenerated by pip-compile with Python 3.10
3 | # by the following command:
4 | #
5 | # requirements/compile.py
6 | #
7 | bleach==5.0.1 \
8 | --hash=sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a \
9 | --hash=sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c
10 | # via -r requirements.in
11 | coverage[toml]==7.2.7 \
12 | --hash=sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f \
13 | --hash=sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2 \
14 | --hash=sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a \
15 | --hash=sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a \
16 | --hash=sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01 \
17 | --hash=sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6 \
18 | --hash=sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7 \
19 | --hash=sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f \
20 | --hash=sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02 \
21 | --hash=sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c \
22 | --hash=sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063 \
23 | --hash=sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a \
24 | --hash=sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5 \
25 | --hash=sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959 \
26 | --hash=sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97 \
27 | --hash=sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6 \
28 | --hash=sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f \
29 | --hash=sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9 \
30 | --hash=sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5 \
31 | --hash=sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f \
32 | --hash=sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562 \
33 | --hash=sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe \
34 | --hash=sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9 \
35 | --hash=sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f \
36 | --hash=sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb \
37 | --hash=sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb \
38 | --hash=sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1 \
39 | --hash=sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb \
40 | --hash=sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250 \
41 | --hash=sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e \
42 | --hash=sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511 \
43 | --hash=sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5 \
44 | --hash=sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59 \
45 | --hash=sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2 \
46 | --hash=sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d \
47 | --hash=sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3 \
48 | --hash=sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4 \
49 | --hash=sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de \
50 | --hash=sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9 \
51 | --hash=sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833 \
52 | --hash=sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0 \
53 | --hash=sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9 \
54 | --hash=sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d \
55 | --hash=sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050 \
56 | --hash=sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d \
57 | --hash=sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6 \
58 | --hash=sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353 \
59 | --hash=sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb \
60 | --hash=sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e \
61 | --hash=sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8 \
62 | --hash=sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495 \
63 | --hash=sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2 \
64 | --hash=sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd \
65 | --hash=sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27 \
66 | --hash=sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1 \
67 | --hash=sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818 \
68 | --hash=sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4 \
69 | --hash=sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e \
70 | --hash=sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850 \
71 | --hash=sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3
72 | # via -r requirements.in
73 | mock==5.1.0 \
74 | --hash=sha256:18c694e5ae8a208cdb3d2c20a993ca1a7b0efa258c247a1e565150f477f83744 \
75 | --hash=sha256:5e96aad5ccda4718e0a229ed94b2024df75cc2d55575ba5762d31f5767b8767d
76 | # via -r requirements.in
77 | six==1.16.0 \
78 | --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
79 | --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
80 | # via bleach
81 | tinycss2==1.2.1 \
82 | --hash=sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847 \
83 | --hash=sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627
84 | # via -r requirements.in
85 | tomli==2.0.1 \
86 | --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \
87 | --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f
88 | # via coverage
89 | webencodings==0.5.1 \
90 | --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
91 | --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
92 | # via
93 | # bleach
94 | # tinycss2
95 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | django-bleach - Bleach and sanitise user HTML
2 | =============================================
3 |
4 | .. image:: https://readthedocs.org/projects/django-bleach/badge/?version=latest
5 | :target: https://django-bleach.readthedocs.io/en/latest/?badge=latest
6 | :alt: Documentation Status
7 |
8 | .. image:: http://img.shields.io/pypi/v/django-bleach.svg?style=flat-square
9 | :target: https://pypi.python.org/pypi/django-bleach/
10 | :alt: Latest Version
11 |
12 | .. image:: http://img.shields.io/pypi/l/django-bleach.svg?style=flat-square
13 | :target: https://pypi.python.org/pypi/django-bleach/
14 | :alt: License
15 |
16 | .. image:: http://img.shields.io/pypi/dm/django-bleach.svg?style=flat-square
17 | :target: https://pypi.python.org/pypi/django-bleach/
18 | :alt: Downloads
19 |
20 | |
21 |
22 | .. image:: https://codecov.io/gh/marksweb/django-bleach/branch/master/graph/badge.svg
23 | :target: https://codecov.io/gh/marksweb/django-bleach
24 |
25 | .. image:: https://api.codacy.com/project/badge/Grade/c34f923ab0a84a6f96728866c749d511
26 | :alt: Codacy Badge
27 | :target: https://app.codacy.com/app/marksweb/django-bleach?utm_source=github.com&utm_medium=referral&utm_content=marksweb/django-bleach&utm_campaign=Badge_Grade_Dashboard
28 |
29 | .. image:: https://results.pre-commit.ci/badge/github/marksweb/django-bleach/master.svg
30 | :target: https://results.pre-commit.ci/latest/github/marksweb/django-bleach/master
31 | :alt: pre-commit.ci status
32 |
33 | .. image:: https://img.shields.io/lgtm/grade/python/g/marksweb/django-bleach.svg?logo=lgtm&logoWidth=18
34 | :target: https://lgtm.com/projects/g/marksweb/django-bleach/context:python
35 | :alt: Language grade: Python
36 |
37 | .. image:: https://img.shields.io/lgtm/alerts/g/marksweb/django-bleach.svg?logo=lgtm&logoWidth=18
38 | :target: https://lgtm.com/projects/g/marksweb/django-bleach/alerts/
39 | :alt: Total alerts
40 |
41 | |
42 |
43 | Archived
44 | ========
45 |
46 | This project has been archived because bleach is no longer supported. The supported means of sanitizing input data is the nh3 library and there's a similar package to this available:
47 |
48 | https://github.com/marksweb/django-nh3
49 |
50 | ------------
51 |
52 | Bleach_ is a Python module that takes any HTML input, and returns
53 | valid, sanitised HTML that contains only an allowed subset of HTML tags,
54 | attributes and styles. ``django-bleach`` is a Django app that makes using
55 | ``bleach`` extremely easy.
56 |
57 | `Read the documentation here`_.
58 |
59 | Setup
60 | -----
61 |
62 | 1. Install ``django-bleach`` via ``pip``::
63 |
64 | pip install django-bleach
65 |
66 | 2. Add ``django-bleach`` to your ``INSTALLED_APPS``:
67 |
68 | .. code-block:: python
69 |
70 | INSTALLED_APPS = [
71 | # ...
72 | 'django_bleach',
73 | # ...
74 | ]
75 |
76 | 3. Select some sensible defaults for the allowed tags, attributes and styles;
77 | and the behaviour when unknown tags are encountered. Each of these are
78 | optional, and default to using the ``bleach`` defaults. See the
79 | `bleach documentation`_:
80 |
81 | .. code-block:: python
82 |
83 | # Which HTML tags are allowed
84 | BLEACH_ALLOWED_TAGS = ['p', 'b', 'i', 'u', 'em', 'strong', 'a']
85 |
86 | # Which HTML attributes are allowed
87 | BLEACH_ALLOWED_ATTRIBUTES = ['href', 'title', 'style']
88 |
89 | # Which CSS properties are allowed in 'style' attributes (assuming
90 | # style is an allowed attribute)
91 | BLEACH_ALLOWED_STYLES = [
92 | 'font-family', 'font-weight', 'text-decoration', 'font-variant']
93 |
94 | # Strip unknown tags if True, replace with HTML escaped characters if
95 | # False
96 | BLEACH_STRIP_TAGS = True
97 |
98 | # Strip comments, or leave them in.
99 | BLEACH_STRIP_COMMENTS = False
100 |
101 | 4. Select the default widget for bleach fields. This defaults to
102 | ``django.forms.Textarea``, but you will probably want to replace it with a
103 | WYSIWYG editor, or something similar:
104 |
105 | .. code-block:: python
106 |
107 | # Use the CKEditorWidget for bleached HTML fields
108 | BLEACH_DEFAULT_WIDGET = 'wysiwyg.widgets.WysiwygWidget'
109 |
110 | I use `django-ckeditor`_ in my projects, but what you use is up to you.
111 |
112 | Usage
113 | -----
114 |
115 | In your models
116 | **************
117 |
118 | ``django-bleach`` provides three ways of creating bleached output. The simplest
119 | way of including user-editable HTML content that is automatically sanitised is
120 | by using the ``BleachField`` model field:
121 |
122 | .. code-block:: python
123 |
124 | # in app/models.py
125 |
126 | from django import models
127 | from django_bleach.models import BleachField
128 |
129 | class Post(models.Model):
130 |
131 | title = models.CharField()
132 | content = BleachField()
133 |
134 | # ...
135 |
136 | ``BleachField`` takes the following arguments, to customise the output of
137 | ``bleach``. See the `bleach documentation`_ for their use:
138 |
139 | * ``allowed_tags``
140 | * ``allowed_attributes``
141 | * ``strip_tags``
142 | * ``strip_comments``
143 | * ``css_sanitizer``
144 |
145 | The following argument will be deprecated in the near future:
146 |
147 | * ``allowed_styles``
148 |
149 | In addition to the ``bleach``-specific arguments, the ``BleachField`` model field
150 | accepts all of the normal field attributes. Behind the scenes, it is a
151 | ``TextField``, and accepts all the same arguments as the default ``TextField`` does.
152 |
153 | The ``BleachField`` model field sanitises its value before it is saved to the
154 | database and is marked safe so it can be immediately rendered in a template
155 | without further intervention.
156 |
157 | In model forms, ``BleachField`` model field are represented with the
158 | ``BleachField`` form field by default.
159 |
160 | In your forms
161 | *************
162 |
163 | A ``BleachField`` form field is provided. This field sanitises HTML input from
164 | the user, and presents safe, clean HTML to your Django application and the
165 | returned value is marked safe for immediate rendering.
166 |
167 | In your templates
168 | *****************
169 |
170 | If you have a piece of content from somewhere that needs to be printed in a
171 | template, you can use the ``bleach`` filter:
172 |
173 | .. code-block:: django
174 |
175 | {% load bleach_tags %}
176 |
177 | {{ some_unsafe_content|bleach }}
178 |
179 | If filter has no arguments it uses default settings defined in your
180 | application settings. You can override allowed tags by specifying them
181 | as a parameter to the filter:
182 |
183 | .. code-block:: django
184 |
185 | {{ some_unsafe_content|bleach:"p,span" }}
186 |
187 | There is also ``bleach_linkify`` which uses the linkify_ function of bleach
188 | which converts URL-like strings in an HTML fragment to links
189 |
190 | This function converts strings that look like URLs, domain names and email
191 | addresses in text that may be an HTML fragment to links, while preserving:
192 |
193 | 1. links already in the string
194 | 2. urls found in attributes
195 | 3. email addresses
196 |
197 |
198 | .. _bleach: https://github.com/mozilla/bleach
199 | .. _Read the documentation here: https://django-bleach.readthedocs.io/
200 | .. _bleach documentation: https://bleach.readthedocs.io/en/latest/clean.html
201 | .. _django-ckeditor: https://github.com/shaunsephton/django-ckeditor
202 | .. _linkify: https://bleach.readthedocs.io/en/latest/linkify.html?highlight=linkify#bleach.linkify "linkify"
203 |
--------------------------------------------------------------------------------
/django_bleach/tests/test_forms.py:
--------------------------------------------------------------------------------
1 | from bleach.css_sanitizer import CSSSanitizer
2 | from django import forms
3 | from django.test import TestCase, override_settings
4 | from django.utils.safestring import SafeString
5 |
6 | from django_bleach.forms import BleachField
7 | from testproject.constants import (
8 | ALLOWED_ATTRIBUTES,
9 | ALLOWED_CSS_PROPERTIES,
10 | ALLOWED_PROTOCOLS,
11 | ALLOWED_STYLES,
12 | ALLOWED_TAGS,
13 | )
14 | from testproject.forms import BleachForm, CustomBleachWidget
15 |
16 |
17 | class TestBleachField(TestCase):
18 | def test_empty(self):
19 | """
20 | Test that the empty_value arg is returned for any input empty value
21 | """
22 | for requested_empty_value in ("", None):
23 | field = BleachField(empty_value=requested_empty_value)
24 | for empty_value in field.empty_values:
25 | self.assertEqual(
26 | field.to_python(empty_value), requested_empty_value
27 | )
28 |
29 | def test_return_type(self):
30 | """Test bleached values are SafeString objects"""
31 | field = BleachField()
32 | self.assertIsInstance(field.to_python("some text"), SafeString)
33 |
34 | def test_bleaching(self):
35 | """Test values are bleached"""
36 | test_data = {
37 | "no_tags": "Heading ",
38 | "no_strip": "Heading ",
39 | "bleach_strip": ""
40 | '',
41 | "bleach_attrs": 'google.com ',
43 | "bleach_css_sanitizer": 'item ',
44 | }
45 | form = BleachForm(data=test_data)
46 | form.is_valid()
47 | self.assertEqual(form.cleaned_data["no_tags"], "Heading")
48 | self.assertEqual(
49 | form.cleaned_data["no_strip"], "<h1>Heading</h1>"
50 | )
51 | self.assertEqual(
52 | form.cleaned_data["bleach_strip"], 'alert("Hello World")'
53 | )
54 | self.assertEqual(
55 | form.cleaned_data["bleach_attrs"],
56 | 'google.com ',
57 | )
58 | self.assertNotEqual(
59 | form.cleaned_data["bleach_css_sanitizer"],
60 | test_data["bleach_css_sanitizer"],
61 | )
62 |
63 | def test_tags(self):
64 | """Test allowed tags are rendered"""
65 | test_data = {
66 | "no_tags": "No tags here
",
67 | "no_strip": "No tags here",
68 | "bleach_strip": "",
69 | "bleach_attrs": 'google.com ',
71 | "bleach_css_sanitizer": 'item ',
72 | }
73 | form = BleachForm(data=test_data)
74 | form.is_valid()
75 | self.assertEqual(form.cleaned_data["no_tags"], "No tags here")
76 | self.assertEqual(form.cleaned_data["no_strip"], "No tags here")
77 |
78 | self.assertEqual(
79 | form.cleaned_data["bleach_strip"], test_data["bleach_strip"]
80 | )
81 | self.assertEqual(
82 | form.cleaned_data["bleach_attrs"], test_data["bleach_attrs"]
83 | )
84 | self.assertEqual(
85 | form.cleaned_data["bleach_css_sanitizer"],
86 | test_data["bleach_css_sanitizer"],
87 | )
88 |
89 | def test_attrs(self):
90 | """Test allowed attributes are rendered"""
91 | list_html = (
92 | ''
93 | 'one '
94 | "two "
95 | " "
96 | )
97 | test_data = {
98 | "no_strip": "",
99 | "no_tags": list_html,
100 | "bleach_strip": list_html,
101 | "bleach_attrs": list_html,
102 | "bleach_css_sanitizer": list_html,
103 | }
104 | form = BleachForm(data=test_data)
105 | form.is_valid()
106 | self.assertEqual(form.cleaned_data["no_tags"], "\none\ntwo")
107 |
108 | self.assertEqual(
109 | form.cleaned_data["bleach_strip"],
110 | "",
111 | )
112 | self.assertEqual(
113 | form.cleaned_data["bleach_attrs"], test_data["bleach_strip"]
114 | )
115 | self.assertEqual(
116 | form.cleaned_data["bleach_css_sanitizer"],
117 | "",
118 | )
119 |
120 |
121 | @override_settings(
122 | BLEACH_DEFAULT_WIDGET="testproject.forms.CustomBleachWidget"
123 | )
124 | class TestCustomWidget(TestCase):
125 | def setUp(self):
126 | class CustomForm(forms.Form):
127 | # Define form inside function with overridden settings so
128 | # get_default_widget() sees the modified setting.
129 | no_tags = BleachField(
130 | max_length=100, strip_tags=True, allowed_tags=[]
131 | )
132 | no_strip = BleachField(
133 | max_length=100, allowed_tags=None, allowed_attributes=None
134 | )
135 | bleach_strip = BleachField(
136 | max_length=100,
137 | strip_comments=True,
138 | strip_tags=True,
139 | allowed_tags=ALLOWED_TAGS,
140 | )
141 | bleach_attrs = BleachField(
142 | max_length=100,
143 | strip_tags=False,
144 | allowed_tags=ALLOWED_TAGS,
145 | allowed_protocols=ALLOWED_PROTOCOLS,
146 | allowed_attributes=ALLOWED_ATTRIBUTES,
147 | )
148 | bleach_styles = BleachField(
149 | max_length=100,
150 | strip_tags=False,
151 | allowed_attributes=["style"],
152 | allowed_tags=ALLOWED_TAGS,
153 | allowed_styles=ALLOWED_STYLES,
154 | )
155 | bleach_css_sanitizer = BleachField(
156 | max_length=100,
157 | strip_tags=False,
158 | allowed_attributes=["style"],
159 | allowed_tags=ALLOWED_TAGS,
160 | css_sanitizer=CSSSanitizer(
161 | allowed_css_properties=ALLOWED_CSS_PROPERTIES
162 | ),
163 | )
164 |
165 | self.CustomForm = CustomForm
166 |
167 | def test_custom_widget_type(self):
168 | """Test widget class matches BLEACH_DEFAULT_WIDGET"""
169 | for field in self.CustomForm().fields.values():
170 | self.assertIsInstance(field.widget, CustomBleachWidget)
171 |
172 | def test_custom_widget_bleaches_content(self):
173 | """
174 | Test input is bleached according to config while using a custom
175 | widget
176 | """
177 | test_data = {
178 | "no_tags": "Heading ",
179 | "no_strip": "Heading ",
180 | "bleach_strip": ""
181 | '',
182 | "bleach_attrs": (
183 | 'google.com '
185 | 'google.com '
186 | ),
187 | "bleach_styles": 'item ',
188 | "bleach_css_sanitizer": 'item ',
189 | }
190 | form = self.CustomForm(data=test_data)
191 | form.is_valid()
192 | self.assertEqual(form.cleaned_data["no_tags"], "Heading")
193 | self.assertEqual(
194 | form.cleaned_data["no_strip"], "<h1>Heading</h1>"
195 | )
196 | self.assertEqual(
197 | form.cleaned_data["bleach_strip"], 'alert("Hello World")'
198 | )
199 | self.assertEqual(
200 | form.cleaned_data["bleach_attrs"],
201 | 'google.com google.com ',
202 | )
203 | self.assertNotEqual(
204 | form.cleaned_data["bleach_styles"], test_data["bleach_styles"]
205 | )
206 | self.assertNotEqual(
207 | form.cleaned_data["bleach_css_sanitizer"],
208 | test_data["bleach_css_sanitizer"],
209 | )
210 |
--------------------------------------------------------------------------------
/docs/conf.py:
--------------------------------------------------------------------------------
1 | #
2 | # django-bleach documentation build configuration file, created by
3 | # sphinx-quickstart on Tue Jun 19 10:24:12 2012.
4 | #
5 | # This file is execfile()d with the current directory set to its containing dir.
6 | #
7 | # Note that not all possible configuration values are present in this
8 | # autogenerated file.
9 | #
10 | # All configuration values have a default; values that are commented out
11 | # serve to show the default.
12 |
13 |
14 | # If extensions (or modules to document with autodoc) are in another directory,
15 | # add these directories to sys.path here. If the directory is relative to the
16 | # documentation root, use os.path.abspath to make it absolute, like shown here.
17 | # sys.path.insert(0, os.path.abspath('.'))
18 |
19 | # -- General configuration -----------------------------------------------------
20 |
21 | # If your documentation needs a minimal Sphinx version, state it here.
22 | # needs_sphinx = '1.0'
23 |
24 | # Add any Sphinx extension module names here, as strings. They can be extensions
25 | # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
26 | import datetime
27 |
28 | extensions = ["sphinx.ext.autodoc"]
29 |
30 | # Add any paths that contain templates here, relative to this directory.
31 | templates_path = ["_templates"]
32 |
33 | # The suffix of source filenames.
34 | source_suffix = ".rst"
35 |
36 | # The encoding of source files.
37 | # source_encoding = 'utf-8-sig'
38 |
39 | # The master toctree document.
40 | master_doc = "index"
41 |
42 | # General information about the project.
43 | project = "django-bleach"
44 | copyright = f"{datetime.date.today().year}, Tim Heap, Mark Walker"
45 | # The version info for the project you're documenting, acts as replacement for
46 | # |version| and |release|, also used in various other places throughout the
47 | # built documents.
48 | #
49 | # The short X.Y version.
50 | version = "3.1.0"
51 | # The full version, including alpha/beta/rc tags.
52 | # release = '1.0.0'
53 |
54 | # The language for content autogenerated by Sphinx. Refer to documentation
55 | # for a list of supported languages.
56 | # language = None
57 |
58 | # There are two options for replacing |today|: either, you set today to some
59 | # non-false value, then it is used:
60 | # today = ''
61 | # Else, today_fmt is used as the format for a strftime call.
62 | # today_fmt = '%B %d, %Y'
63 |
64 | # List of patterns, relative to source directory, that match files and
65 | # directories to ignore when looking for source files.
66 | exclude_patterns = ["_build"]
67 |
68 | # The reST default role (used for this markup: `text`) to use for all documents.
69 | # default_role = None
70 |
71 | # If true, '()' will be appended to :func: etc. cross-reference text.
72 | # add_function_parentheses = True
73 |
74 | # If true, the current module name will be prepended to all description
75 | # unit titles (such as .. function::).
76 | # add_module_names = True
77 |
78 | # If true, sectionauthor and moduleauthor directives will be shown in the
79 | # output. They are ignored by default.
80 | # show_authors = False
81 |
82 | # The name of the Pygments (syntax highlighting) style to use.
83 | pygments_style = "sphinx"
84 |
85 | # A list of ignored prefixes for module index sorting.
86 | # modindex_common_prefix = []
87 |
88 |
89 | # -- Options for HTML output ---------------------------------------------------
90 |
91 | # The theme to use for HTML and HTML Help pages. See the documentation for
92 | # a list of builtin themes.
93 | try:
94 | import furo
95 |
96 | html_theme = "furo"
97 | html_theme_options = {
98 | "navigation_with_keys": True,
99 | }
100 | except ImportError:
101 | html_theme = "default"
102 |
103 | # Theme options are theme-specific and customize the look and feel of a theme
104 | # further. For a list of options available for each theme, see the
105 | # documentation.
106 | # html_theme_options = {}
107 |
108 | # Add any paths that contain custom themes here, relative to this directory.
109 | # html_theme_path = []
110 |
111 | # The name for this set of Sphinx documents. If None, it defaults to
112 | # " v documentation".
113 | # html_title = None
114 |
115 | # A shorter title for the navigation bar. Default is the same as html_title.
116 | # html_short_title = None
117 |
118 | # The name of an image file (relative to this directory) to place at the top
119 | # of the sidebar.
120 | # html_logo = None
121 |
122 | # The name of an image file (within the static path) to use as favicon of the
123 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
124 | # pixels large.
125 | # html_favicon = None
126 |
127 | # Add any paths that contain custom static files (such as style sheets) here,
128 | # relative to this directory. They are copied after the builtin static files,
129 | # so a file named "default.css" will overwrite the builtin "default.css".
130 | html_static_path = ["_static"]
131 |
132 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
133 | # using the given strftime format.
134 | # html_last_updated_fmt = '%b %d, %Y'
135 |
136 | # If true, SmartyPants will be used to convert quotes and dashes to
137 | # typographically correct entities.
138 | # html_use_smartypants = True
139 |
140 | # Custom sidebar templates, maps document names to template names.
141 | # html_sidebars = {}
142 |
143 | # Additional templates that should be rendered to pages, maps page names to
144 | # template names.
145 | # html_additional_pages = {}
146 |
147 | # If false, no module index is generated.
148 | # html_domain_indices = True
149 |
150 | # If false, no index is generated.
151 | # html_use_index = True
152 |
153 | # If true, the index is split into individual pages for each letter.
154 | # html_split_index = False
155 |
156 | # If true, links to the reST sources are added to the pages.
157 | # html_show_sourcelink = True
158 |
159 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
160 | # html_show_sphinx = True
161 |
162 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
163 | # html_show_copyright = True
164 |
165 | # If true, an OpenSearch description file will be output, and all pages will
166 | # contain a tag referring to it. The value of this option must be the
167 | # base URL from which the finished HTML is served.
168 | # html_use_opensearch = ''
169 |
170 | # This is the file name suffix for HTML files (e.g. ".xhtml").
171 | # html_file_suffix = None
172 |
173 | # Output file base name for HTML help builder.
174 | htmlhelp_basename = "django-bleach"
175 |
176 |
177 | # -- Options for LaTeX output --------------------------------------------------
178 |
179 | # latex_elements = {
180 | # The paper size ('letterpaper' or 'a4paper').
181 | # 'papersize': 'letterpaper',
182 |
183 | # The font size ('10pt', '11pt' or '12pt').
184 | # 'pointsize': '10pt',
185 |
186 | # Additional stuff for the LaTeX preamble.
187 | # 'preamble': '',
188 | # }
189 |
190 | # Grouping the document tree into LaTeX files. List of tuples
191 | # (source start file, target name, title, author, documentclass [howto/manual]).
192 | latex_documents = [
193 | (
194 | "index",
195 | "django-bleach.tex",
196 | "django-bleach Documentation",
197 | "Mark Walker",
198 | "manual",
199 | ),
200 | ]
201 |
202 | # The name of an image file (relative to this directory) to place at the top of
203 | # the title page.
204 | # latex_logo = None
205 |
206 | # For "manual" documents, if this is true, then toplevel headings are parts,
207 | # not chapters.
208 | # latex_use_parts = False
209 |
210 | # If true, show page references after internal links.
211 | # latex_show_pagerefs = False
212 |
213 | # If true, show URL addresses after external links.
214 | # latex_show_urls = False
215 |
216 | # Documents to append as an appendix to all manuals.
217 | # latex_appendices = []
218 |
219 | # If false, no module index is generated.
220 | # latex_domain_indices = True
221 |
222 |
223 | # -- Options for manual page output --------------------------------------------
224 |
225 | # One entry per manual page. List of tuples
226 | # (source start file, name, description, authors, manual section).
227 | man_pages = [
228 | (
229 | "index",
230 | "django-bleach",
231 | "django-bleach Documentation",
232 | ["Mark Walker"],
233 | 1,
234 | )
235 | ]
236 |
237 | # If true, show URL addresses after external links.
238 | # man_show_urls = False
239 |
240 |
241 | # -- Options for Texinfo output ------------------------------------------------
242 |
243 | # Grouping the document tree into Texinfo files. List of tuples
244 | # (source start file, target name, title, author,
245 | # dir menu entry, description, category)
246 | texinfo_documents = [
247 | (
248 | "index",
249 | "django-bleach",
250 | "django-bleach Documentation",
251 | "Mark Walker",
252 | "django-bleach",
253 | "One line description of project.",
254 | "Miscellaneous",
255 | ),
256 | ]
257 |
258 | # Documents to append as an appendix to all manuals.
259 | # texinfo_appendices = []
260 |
261 | # If false, no module index is generated.
262 | # texinfo_domain_indices = True
263 |
264 | # How to display URL addresses: 'footnote', 'no', or 'inline'.
265 | # texinfo_show_urls = 'footnote'
266 |
--------------------------------------------------------------------------------