-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathpyproject.toml
More file actions
181 lines (165 loc) · 7.19 KB
/
Copy pathpyproject.toml
File metadata and controls
181 lines (165 loc) · 7.19 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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
[project]
name = "assertpy2"
version = "2.19.0"
description = "Fluent assertion library for Python with composable matchers, structural matching, and full type safety"
readme = "README.md"
license = "BSD-3-Clause"
requires-python = ">=3.10"
authors = [
{ name = "Justin Shacklette", email = "justin@saturnboy.com" },
]
maintainers = [
{ name = "Solganis", email = "solganis.dev@gmail.com" },
]
keywords = ["test", "testing", "assert", "assertion", "assertthat", "assert_that", "pytest", "unittest", "assertpy", "fluent", "matchers", "type-safe"]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"License :: OSI Approved :: BSD License",
"Natural Language :: English",
"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",
"Programming Language :: Python :: 3.14",
"Programming Language :: Python :: 3.15",
"Topic :: Software Development",
"Topic :: Software Development :: Testing",
]
dependencies = [
"typing_extensions>=4.0; python_version < '3.11'",
]
[project.urls]
Homepage = "https://github.com/Solganis/assertpy2"
Repository = "https://github.com/Solganis/assertpy2"
Issues = "https://github.com/Solganis/assertpy2/issues"
[project.entry-points."pytest11"]
assertpy2 = "assertpy2.pytest_plugin"
[project.optional-dependencies]
allure = ["allure-pytest>=2.13"]
behave = ["behave>=1.2.6"]
data = ["assertpy2[numpy,pandas,polars]"]
inline = ["executing>=2.2", "asttokens>=2.0"]
json = ["jsonpath-ng>=1.8", "jsonschema>=4.18", "referencing>=0.28.4"]
numpy = ["numpy>=1.26"]
pandas = ["pandas>=2.0"]
polars = ["polars>=1.0"]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[dependency-groups]
dev = [
"hypothesis>=6.165.0",
"pytest>=9.1.1",
"pytest-cov>=7.1.0",
"ruff>=0.16.1",
"ty>=0.0.69",
"typing_extensions>=4.0",
]
docs = [
"mkdocs-material>=9.7.6",
"mkdocstrings[python]>=1.0.4",
"mkdocs-redirects>=1.2.3",
]
# Real third-party libraries the duck-typed integration paths are verified against in CI (the suite
# otherwise skips these tests); pandas/polars/numpy come from the [data] extra instead.
integrations = [
"attrs>=25.0",
"pydantic>=2.0",
"requests>=2.32",
]
typecheck = [
"mypy>=2.3.0",
"pyright>=1.1.411",
]
mutation = [
"cosmic-ray>=8.4.6",
]
docs-examples = [
"pytest-examples>=0.0.18",
]
# Performance regression gate. Own group: pytest-codspeed is only needed by the CodSpeed CI job and a
# manual `pytest benchmarks/ --codspeed`, not by the suite every contributor runs.
benchmark = [
"pytest-codspeed>=5",
]
[tool.pytest.ini_options]
testpaths = ["tests"]
# --strict-markers: unknown @pytest.mark.* is an error, not a silent typo.
addopts = ["-p", "no:assertpy2", "--strict-markers"]
xfail_strict = true # an xfail that unexpectedly passes (xpass) fails the run
# Warnings are errors: a deprecation or runtime warning fails the run instead of
# scrolling past. The suite already passes clean under this; add targeted
# `"ignore::<Category>"` entries here only if a third-party warning forces it.
filterwarnings = ["error"]
[tool.coverage.run]
branch = true
source = ["assertpy2"]
[tool.coverage.report]
omit = ["tests/*", "assertpy2/__init__.py", "assertpy2/_typing.py", "assertpy2/_compat.py"]
[tool.ruff]
# 120 feeds both `ruff format` and the E501 lint. Unlike black-style configs we do
# NOT disable E501 (see the empty `ignore` below): line length is a hard rule, not
# just a formatter hint, so the formatter and the linter agree at 120.
line-length = 120
target-version = "py310" # lowest Python we support; UP rewrites target this floor
# Ruff 0.16 prints rule names instead of codes under preview. Keep the codes: they are what a
# `# noqa` needs, and looking one up from a name is a detour on every suppression.
output-prefer-rule-codes = true
[tool.ruff.format]
# Ruff 0.16 reformats python blocks inside Markdown. Docs code is hand-wrapped to 90 characters so
# it fits the theme's 0.8em code font without a horizontal scrollbar, and reflowing it at the 120
# above pushes eight pages past that. Snippets stay gated by tests/test_docs_examples.py.
exclude = ["*.md"]
[tool.ruff.lint]
# Enable preview rules, but ONLY the ones named explicitly in `select`
# (explicit-preview-rules), so we can opt into a single preview rule (E301) without
# pulling in every unstable rule ruff ships behind the preview flag.
preview = true
explicit-preview-rules = true
# Curated set, not "ALL": each prefix is here on purpose. Plugin name + why we keep it.
select = [
"E", # pycodestyle errors
"E301", # pycodestyle, preview-gated: require a blank line between methods (not in stable "E")
"F", # Pyflakes - unused imports/names, undefined names
"W", # pycodestyle warnings
"N", # pep8-naming - naming conventions
"I", # isort - import ordering
"UP", # pyupgrade - modernize syntax to our py310+ floor
"B", # flake8-bugbear - likely bugs and footguns
"A", # flake8-builtins - don't shadow builtins
"ASYNC", # flake8-async - async footguns (blocking calls, missing await) in async assertions/polling
"C4", # flake8-comprehensions - drop redundant list()/dict()/set() wrappers
"FA", # flake8-future-annotations - `X | Y` in a runtime-evaluated annotation needs the
# `from __future__ import annotations` our 3.10 floor depends on
"FURB", # refurb - idiom simplifications in the same family as SIM/PIE/C4
"PIE", # flake8-pie - small idiom simplifications
"RSE", # flake8-raise - no empty parens on a bare `raise SomeError()`
"PGH", # pygrep-hooks - forbid blanket `noqa`/`type: ignore` (must name a rule code)
"PLE", # Pylint errors - real-error subset (not style)
"SIM", # flake8-simplify - collapse redundant constructs
"T10", # flake8-debugger - no committed breakpoint()/pdb calls
"RUF", # Ruff-specific rules
"ERA", # eradicate - no commented-out code
"PERF", # Perflint - performance anti-patterns
"TC", # flake8-type-checking - keep typing-only imports under TYPE_CHECKING
]
# Intentionally empty: nothing is globally ignored. In particular E501 stays ON
# (see line-length note above). Per-file relaxations go in per-file-ignores, not here.
ignore = []
[tool.ruff.lint.per-file-ignores]
# Tests trade a few style rules for directness and literal fixtures:
"tests/*" = [
"E741", # ambiguous one-letter names (l/I/O) are fine in throwaway test locals
"SIM102", # keep nested `if`s when they read closer to the scenario under test
"SIM300", # allow Yoda-style literal-first comparisons in hand-written test data
"A002", # fixtures/helpers may take args named like builtins (id, type, filter, ...)
"ERA001", # example snippets deliberately left as comments in tests
]
[tool.ty.analysis]
# Suppressions must be ty-native `# ty: ignore[rule]`. Make ty disregard mypy's
# generic `# type: ignore` so a stray mypy-style comment can't silently mask a ty error.
respect-type-ignore-comments = false