forked from DOI-USGS/dataretrieval-python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpyproject.toml
More file actions
217 lines (200 loc) · 7.32 KB
/
Copy pathpyproject.toml
File metadata and controls
217 lines (200 loc) · 7.32 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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
[build-system]
requires = ["setuptools>=45", "setuptools_scm[toml]>=6.2"]
build-backend = "setuptools.build_meta"
[project]
name = "dataretrieval"
description = "Discover and retrieve water data from U.S. federal hydrologic web services."
readme = "README.md"
requires-python = ">=3.10"
keywords = ["USGS", "water data"]
license = "CC0-1.0"
license-files = ["LICENSE.md"]
authors = [
{name = "Timothy Hodson", email = "thodson@usgs.gov"},
]
maintainers = [
{name = "Elise Hinman", email = "ehinman@usgs.gov"},
]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Science/Research",
"Topic :: Scientific/Engineering :: Hydrology",
"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",
]
dependencies = [
"httpx",
"pandas>=2.0.0,<4.0.0",
# Directly imported by ``waterdata`` (``anyio.from_thread.start_blocking_portal``),
# so declared here rather than relied on transitively via httpx.
"anyio>=4.0",
# ``dataretrieval.config`` reads a TOML config file. ``tomllib`` is stdlib
# from 3.11, so this marker installs the backport only on 3.10 and drops
# itself when ``requires-python`` moves to >=3.11.
"tomli>=1.1.0; python_version < '3.11'",
]
dynamic = ["version"]
[tool.setuptools.packages.find]
include = ["dataretrieval*"]
[tool.setuptools.package-data]
dataretrieval = ["py.typed"]
[tool.complexipy]
max-complexity-allowed = 10
failed = true
[project.optional-dependencies]
# Minimal set the CI ``type-check`` job installs — just mypy + the package,
# not the whole test stack.
type-check = [
"mypy",
]
# Structural gates (complexity ratchets, dependency contracts) and the wily
# trend history. Kept out of ``test`` so the test job stays lean; see
# CONTRIBUTING.md for what each does.
metrics = [
"xenon==0.9.3",
"wily==1.25.0",
"complexipy==6.2.0",
"import-linter==2.13",
]
# Advisory weekly deep sweep -- see .github/workflows/code-health.yml. Pyscn has
# wheels only for macOS ARM64, Linux x86-64, and Windows x86-64, with no sdist,
# so keep it separate from the extra used by merge gates and contributors.
health = [
"pyscn==1.29.0",
]
test = [
"pytest > 5.0.0",
"pytest-cov[all]",
"pytest-rerunfailures",
"coverage",
"pytest-httpx",
"ruff==0.16.1",
"dataretrieval[type-check]", # mypy, pinned once in the type-check extra
]
doc = [
"docutils<0.22",
"sphinx",
"sphinx-rtd-theme",
"nbsphinx",
"nbsphinx_link",
"ipython",
"ipykernel",
"matplotlib",
"folium>=0.12",
# WaterData_demo.ipynb uses ``.set_crs().explore()`` on geometry-bearing
# frames; without geopandas the call raises ``AttributeError`` on plain
# pandas DataFrames. ``mapclassify`` is required by ``geopandas.explore()``
# (alongside ``folium`` + ``matplotlib`` above). Mirrors the same lower
# bound as the [nldi] extra.
"geopandas>=0.10",
"mapclassify",
]
nldi = [
'geopandas>=0.10'
]
[project.urls]
homepage = "https://github.com/DOI-USGS/dataretrieval-python"
documentation = "https://doi-usgs.github.io/dataretrieval-python/"
repository = "https://github.com/DOI-USGS/dataretrieval-python.git"
[tool.setuptools_scm]
write_to = "dataretrieval/_version.py"
[tool.ruff]
target-version = "py310"
extend-exclude = ["demos"]
[tool.ruff.lint]
preview = true
# Select rules: Pyflakes(F), pycodestyle(E,W), isort(I), pyupgrade(UP),
# flake8-bugbear(B), flake8-quotes(Q), flake8-simplify(SIM), flake8-tidy-imports(TID)
select = [
"F", "E", "W", "I", "UP", "B", "Q", "SIM", "TID",
"C90", # mccabe
"E501", # line-length
# A first-party import used only in annotations is not a runtime
# dependency, and the project already says so twice: ``.importlinter`` sets
# ``exclude_type_checking_imports = True`` ("Contracts describe what runs")
# and ``tests/architecture_test.py`` skips ``TYPE_CHECKING`` blocks when it
# asserts the module seams. TC001 makes the code agree with the policy
# instead of leaving it to reviewer memory. TC002/TC003 (third-party and
# stdlib) are a separate import-cost concern with no policy behind them
# here, so they stay unselected.
"TC001",
"TC006", # quoted first argument to ``typing.cast``
]
ignore = [
"SIM105", # Use `contextlib.suppress(...)` instead of `try-except-pass`
"SIM117", # Use a single `with` statement with multiple contexts
]
[tool.ruff.lint.mccabe]
max-complexity = 20
[tool.ruff.lint.per-file-ignores]
"tests/*" = ["SIM108"]
"**/__init__.py" = ["F403"]
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto"
docstring-code-format = true
docstring-code-line-length = 72
[tool.mypy]
# The package is fully annotated and passes ``mypy --strict``. The one
# remaining relaxation is ``ignore_missing_imports``: untyped third-party
# libraries (pandas, geopandas) are treated as ``Any`` instead of
# requiring stub packages. Dropping that — via pandas-stubs/types-requests and
# per-module overrides — can follow.
python_version = "3.10" # the project's minimum supported version
files = ["dataretrieval"]
strict = true
ignore_missing_imports = true
# anyio ships ``py.typed``, so mypy follows into its source — which uses
# ``match`` statements (3.10+). Under our ``python_version = "3.9"`` target that
# is a hard parse error, so don't follow anyio's source; treat it as ``Any``.
[[tool.mypy.overrides]]
module = ["anyio", "anyio.*"]
follow_imports = "skip"
[tool.pytest.ini_options]
# The suite is offline by default. Every HTTP call is mocked (see
# ``tests/conftest.py``), so a push neither depends on USGS uptime nor spends
# someone's rate limit. The exception is the handful of tests marked ``live``,
# which exist precisely to notice when an upstream API changes shape -- a thing
# a mock can never tell us, because the mock is what would need updating.
# Deselecting them here rather than in the CI command keeps a local
# ``pytest tests/`` doing what CI does; run them with ``-m live``.
addopts = "-m 'not live'"
markers = [
"live: hits real USGS services; deselected by default, run on a schedule",
]
[tool.coverage.run]
source = ["dataretrieval"]
# Most of what this package gets wrong is a branch rather than a line.
branch = true
omit = [
# Written by setuptools_scm at build time; absent from a source checkout.
"dataretrieval/_version.py",
]
[tool.coverage.report]
show_missing = true
skip_covered = true
# 98.97% displays as "99%", which would pass a ``fail_under = 99`` on rounding.
precision = 2
# A ratchet: raise it as coverage rises. Lower it only when a genuinely
# untestable path is added and excluding it would be dishonest.
fail_under = 98.9
# Anchored to the statement, so a pattern cannot match its own words in a
# comment or a string. Literal strings, because TOML rejects ``\s``.
exclude_also = [
# Type-checking-only imports never execute.
'^\s*if TYPE_CHECKING:',
'^\s*@overload',
# The suite installs the [test,nldi] extras, so an absent-dependency fallback
# is unreachable here by construction.
'^\s*except ImportError',
'^\s*except PackageNotFoundError',
# One arm is dead on every interpreter, which would otherwise make the total
# depend on which version measured it.
'^\s*if sys\.version_info',
]