-
Notifications
You must be signed in to change notification settings - Fork 78
Expand file tree
/
Copy pathpyproject.toml
More file actions
139 lines (129 loc) · 5.43 KB
/
Copy pathpyproject.toml
File metadata and controls
139 lines (129 loc) · 5.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "django-mfa"
version = "4.6.0"
description = "Second-factor authentication for Django: authenticator apps (TOTP), security keys and passkeys (WebAuthn), and recovery codes."
readme = "README.md"
requires-python = ">=3.10"
license = "MIT"
license-files = ["LICENSE"]
authors = [{ name = "Micropyramid", email = "hello@micropyramid.com" }]
keywords = ["django", "mfa", "2fa", "totp", "webauthn", "passkey", "fido2"]
dependencies = [
"Django>=4.2",
"fido2>=1.1.2,<3",
"qrcode>=7.0.0,<9",
]
# No "License ::" classifier: PyPI rejects a license classifier alongside the
# SPDX `license` expression above (PEP 639). The expression is the source of
# truth.
classifiers = [
"Development Status :: 5 - Production/Stable",
"Environment :: Web Environment",
"Framework :: Django",
"Framework :: Django :: 4.2",
"Framework :: Django :: 5.2",
"Framework :: Django :: 6.1",
"Intended Audience :: Developers",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Internet :: WWW/HTTP :: Dynamic Content",
"Topic :: Security",
]
[project.urls]
Homepage = "https://github.com/MicroPyramid/django-mfa"
Documentation = "http://django-mfa.readthedocs.io/en/latest/"
Source = "https://github.com/MicroPyramid/django-mfa"
Issues = "https://github.com/MicroPyramid/django-mfa/issues"
# PEP 735 dependency groups. These are DEVELOPMENT-ONLY and are never seen by
# a project that installs django-mfa -- unlike `dependencies` above, they are
# not published in the wheel's metadata. `uv sync` installs them by default;
# pip needs `pip install --group dev`.
[dependency-groups]
dev = [
"coverage>=7",
"ruff>=0.14",
# Required by django_mfa/tests/test_packaging.py, which builds a real
# wheel and asserts every package on disk ships in it. Without this the
# packaging tests skip -- and skipping is exactly how the missing
# adapters/ and views/ packages went unnoticed in the first place.
"build>=1.2",
# Source packages for the mfa_import_django_otp / mfa_import_django_mfa2
# management commands' tests (tasks 11-12). These are test-only fixtures,
# never runtime dependencies -- the importer commands resolve the foreign
# models through apps.get_model() inside try/except LookupError so the
# package never imports either at runtime (see
# django_mfa/tests/test_packaging.py, which asserts [project.dependencies]
# stays Django/fido2/qrcode only). Kept in `dev` rather than a separate
# opt-in group for the same reason `build` above is in `dev`: an opt-in
# group is exactly how the missing adapters/ and views/ packages went
# unnoticed, because `uv run python test_runner.py` alone would silently
# skip the importer tests instead of running them against real models.
# django-mfa2 pulls in python-u2flib-server transitively (its own U2F
# support) -- that's expected, not a regression: this package removed
# U2F entirely (see test_u2f_removal.py, docs/upgrading.md) and never
# imports python-u2flib-server itself; it only rides along in uv.lock
# as django-mfa2's dependency.
"django-otp>=1.5",
"django-mfa2>=2.9",
]
# The docs are Markdown; myst-parser is what lets Sphinx read them at all.
# Kept as its own group so a test run doesn't pull the whole Sphinx stack.
docs = [
"sphinx>=7",
"sphinx-rtd-theme>=2",
"myst-parser>=3",
]
# ---------------------------------------------------------------------------
# Build configuration
#
# `packages` names the ROOT package only. Hatchling then ships every module
# under it -- django_mfa.adapters, django_mfa.views, and anything added later
# -- with nothing to enumerate and therefore nothing to forget. The setup.py
# this replaced hardcoded a three-entry `packages=[...]` list that predated
# django_mfa/adapters/ and django_mfa/views/, so the built wheel omitted both
# and `pip install django-mfa` raised ImportError on startup. See
# django_mfa/tests/test_packaging.py, which builds a wheel and asserts every
# package present on disk is actually in it.
#
# Templates and static files live inside the package directory, so they are
# included automatically -- the MANIFEST.in that used to declare them is gone.
# ---------------------------------------------------------------------------
[tool.hatch.build.targets.wheel]
packages = ["django_mfa"]
[tool.hatch.build.targets.sdist]
# Ship what a consumer or packager might need to build and verify the project,
# and nothing else. The sandbox is a demo host project, not part of the
# distribution.
include = [
"/django_mfa",
"/docs",
"/test_runner.py",
"/README.md",
"/LICENSE",
]
[tool.ruff]
line-length = 88
target-version = "py310"
# migrations are generated; docs/conf.py is Sphinx boilerplate; sandbox is a
# throwaway demo host project, not part of the distribution.
extend-exclude = ["django_mfa/migrations", "sandbox", "docs/conf.py"]
[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"F", # pyflakes
"I", # isort
"UP", # pyupgrade
"B", # flake8-bugbear
"DJ", # flake8-django
]
[tool.ruff.lint.isort]
known-first-party = ["django_mfa"]