webchanges 3.31.4__tar.gz → 3.33.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {webchanges-3.31.4/webchanges.egg-info → webchanges-3.33.0}/PKG-INFO +6 -3
- {webchanges-3.31.4 → webchanges-3.33.0}/README.rst +2 -0
- {webchanges-3.31.4 → webchanges-3.33.0}/pyproject.toml +88 -123
- {webchanges-3.31.4 → webchanges-3.33.0}/webchanges/__init__.py +2 -2
- {webchanges-3.31.4 → webchanges-3.33.0}/webchanges/_vendored/headers.py +5 -5
- {webchanges-3.31.4 → webchanges-3.33.0}/webchanges/cli.py +10 -7
- {webchanges-3.31.4 → webchanges-3.33.0}/webchanges/command.py +71 -38
- {webchanges-3.31.4 → webchanges-3.33.0}/webchanges/config.py +1 -2
- {webchanges-3.31.4 → webchanges-3.33.0}/webchanges/differs.py +53 -32
- {webchanges-3.31.4 → webchanges-3.33.0}/webchanges/filters.py +21 -31
- {webchanges-3.31.4 → webchanges-3.33.0}/webchanges/handler.py +57 -78
- {webchanges-3.31.4 → webchanges-3.33.0}/webchanges/jobs.py +397 -277
- {webchanges-3.31.4 → webchanges-3.33.0}/webchanges/reporters.py +27 -28
- {webchanges-3.31.4 → webchanges-3.33.0}/webchanges/storage.py +55 -30
- {webchanges-3.31.4 → webchanges-3.33.0}/webchanges/util.py +16 -7
- {webchanges-3.31.4 → webchanges-3.33.0}/webchanges/worker.py +21 -12
- {webchanges-3.31.4 → webchanges-3.33.0/webchanges.egg-info}/PKG-INFO +6 -3
- {webchanges-3.31.4 → webchanges-3.33.0}/LICENSE.md +0 -0
- {webchanges-3.31.4 → webchanges-3.33.0}/MANIFEST.in +0 -0
- {webchanges-3.31.4 → webchanges-3.33.0}/requirements.txt +0 -0
- {webchanges-3.31.4 → webchanges-3.33.0}/setup.cfg +0 -0
- {webchanges-3.31.4 → webchanges-3.33.0}/webchanges/__main__.py +0 -0
- {webchanges-3.31.4 → webchanges-3.33.0}/webchanges/_vendored/__init__.py +0 -0
- {webchanges-3.31.4 → webchanges-3.33.0}/webchanges/_vendored/packaging_version.py +0 -0
- {webchanges-3.31.4 → webchanges-3.33.0}/webchanges/mailer.py +0 -0
- {webchanges-3.31.4 → webchanges-3.33.0}/webchanges/main.py +0 -0
- {webchanges-3.31.4 → webchanges-3.33.0}/webchanges/py.typed +0 -0
- {webchanges-3.31.4 → webchanges-3.33.0}/webchanges/storage_minidb.py +0 -0
- {webchanges-3.31.4 → webchanges-3.33.0}/webchanges.egg-info/SOURCES.txt +0 -0
- {webchanges-3.31.4 → webchanges-3.33.0}/webchanges.egg-info/dependency_links.txt +0 -0
- {webchanges-3.31.4 → webchanges-3.33.0}/webchanges.egg-info/entry_points.txt +0 -0
- {webchanges-3.31.4 → webchanges-3.33.0}/webchanges.egg-info/requires.txt +0 -0
- {webchanges-3.31.4 → webchanges-3.33.0}/webchanges.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: webchanges
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.33.0
|
|
4
4
|
Summary: Web Changes Delivered. AI-Summarized. Totally Anonymous.
|
|
5
5
|
Author-email: Mike Borsetti <mike+webchanges@borsetti.com>
|
|
6
6
|
Maintainer-email: Mike Borsetti <mike+webchanges@borsetti.com>
|
|
@@ -88,11 +88,12 @@ Classifier: Operating System :: OS Independent
|
|
|
88
88
|
Classifier: Programming Language :: Python
|
|
89
89
|
Classifier: Programming Language :: Python :: 3
|
|
90
90
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
91
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
92
91
|
Classifier: Programming Language :: Python :: 3.11
|
|
93
92
|
Classifier: Programming Language :: Python :: 3.12
|
|
94
93
|
Classifier: Programming Language :: Python :: 3.13
|
|
95
94
|
Classifier: Programming Language :: Python :: 3.14
|
|
95
|
+
Classifier: Programming Language :: Python :: Free Threading
|
|
96
|
+
Classifier: Programming Language :: Python :: Free Threading :: 4 - Resilient
|
|
96
97
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
97
98
|
Classifier: Topic :: Internet
|
|
98
99
|
Classifier: Topic :: Internet :: WWW/HTTP
|
|
@@ -100,7 +101,7 @@ Classifier: Topic :: Internet :: WWW/HTTP :: Indexing/Search
|
|
|
100
101
|
Classifier: Topic :: System :: Monitoring
|
|
101
102
|
Classifier: Topic :: Utilities
|
|
102
103
|
Classifier: Typing :: Typed
|
|
103
|
-
Requires-Python: >=3.
|
|
104
|
+
Requires-Python: >=3.11
|
|
104
105
|
Description-Content-Type: text/x-rst
|
|
105
106
|
License-File: LICENSE.md
|
|
106
107
|
Requires-Dist: colorama; sys_platform == "win32"
|
|
@@ -189,6 +190,8 @@ For the best experience, use the current version of `Python <https://www.python.
|
|
|
189
190
|
older Python versions for 3 years after they're replaced by a newer one; we just ask that you use the most up-to-date
|
|
190
191
|
bug and security fix release from that older version.
|
|
191
192
|
|
|
193
|
+
While **webchanges** supports free-threated Python, certain optional dependencies may not.
|
|
194
|
+
|
|
192
195
|
For Generative AI summaries (BETA), you need a free `API Key from Google Cloud AI Studio
|
|
193
196
|
<https://aistudio.google.com/app/apikey>`__ (see `here
|
|
194
197
|
<https://webchanges.readthedocs.io/en/stable/differs.html#ai-google>`__).
|
|
@@ -22,6 +22,8 @@ For the best experience, use the current version of `Python <https://www.python.
|
|
|
22
22
|
older Python versions for 3 years after they're replaced by a newer one; we just ask that you use the most up-to-date
|
|
23
23
|
bug and security fix release from that older version.
|
|
24
24
|
|
|
25
|
+
While **webchanges** supports free-threated Python, certain optional dependencies may not.
|
|
26
|
+
|
|
25
27
|
For Generative AI summaries (BETA), you need a free `API Key from Google Cloud AI Studio
|
|
26
28
|
<https://aistudio.google.com/app/apikey>`__ (see `here
|
|
27
29
|
<https://webchanges.readthedocs.io/en/stable/differs.html#ai-google>`__).
|
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
|
|
7
7
|
[build-system]
|
|
8
8
|
# Minimum requirements for the build system to execute.
|
|
9
|
-
requires = ['setuptools'] # PEP 508 specifications.
|
|
9
|
+
requires = ['argparse-manpage[setuptools]'] # PEP 508 specifications.
|
|
10
10
|
# Setuptools specification
|
|
11
|
-
build-backend =
|
|
11
|
+
build-backend = 'setuptools.build_meta'
|
|
12
12
|
|
|
13
13
|
[project]
|
|
14
14
|
# See https://packaging.python.org/en/latest/specifications/declaring-project-metadata/
|
|
@@ -16,7 +16,7 @@ dynamic = ['version', 'dependencies']
|
|
|
16
16
|
name = 'webchanges'
|
|
17
17
|
description = 'Web Changes Delivered. AI-Summarized. Totally Anonymous.'
|
|
18
18
|
readme = { file = 'README.rst', content-type = 'text/x-rst' }
|
|
19
|
-
requires-python = '>=3.
|
|
19
|
+
requires-python = '>=3.11'
|
|
20
20
|
license = { file = 'LICENSE.md' }
|
|
21
21
|
authors = [{ name = 'Mike Borsetti', email = 'mike+webchanges@borsetti.com' }]
|
|
22
22
|
maintainers = [
|
|
@@ -36,11 +36,12 @@ classifiers = [
|
|
|
36
36
|
'Programming Language :: Python',
|
|
37
37
|
'Programming Language :: Python :: 3',
|
|
38
38
|
'Programming Language :: Python :: 3 :: Only',
|
|
39
|
-
'Programming Language :: Python :: 3.10',
|
|
40
39
|
'Programming Language :: Python :: 3.11',
|
|
41
40
|
'Programming Language :: Python :: 3.12',
|
|
42
41
|
'Programming Language :: Python :: 3.13',
|
|
43
42
|
'Programming Language :: Python :: 3.14',
|
|
43
|
+
'Programming Language :: Python :: Free Threading',
|
|
44
|
+
'Programming Language :: Python :: Free Threading :: 4 - Resilient',
|
|
44
45
|
'Programming Language :: Python :: Implementation :: CPython',
|
|
45
46
|
'Topic :: Internet',
|
|
46
47
|
'Topic :: Internet :: WWW/HTTP',
|
|
@@ -88,6 +89,7 @@ xmpp = ['aioxmpp']
|
|
|
88
89
|
redis = ['redis']
|
|
89
90
|
requests = ['requests']
|
|
90
91
|
safe_password = ['keyring']
|
|
92
|
+
# all
|
|
91
93
|
all = [
|
|
92
94
|
'webchanges[use_browser,beautify,bs4,html5lib,ical2text,jq,ocr,pdf2text,pypdf_crypto,deepdiff_xml,imagediff,matrix,pushbullet,pushover,xmpp,redis,requests,safe_password]',
|
|
93
95
|
]
|
|
@@ -109,6 +111,10 @@ dependencies = { file = 'requirements.txt' }
|
|
|
109
111
|
[tool.setuptools.package-data]
|
|
110
112
|
'webchanges' = ['py.typed']
|
|
111
113
|
|
|
114
|
+
# -------------------------- manpages --------------------------
|
|
115
|
+
# https://github.com/praiskup/argparse-manpage/blob/main/README.md
|
|
116
|
+
[tool.build_manpages]
|
|
117
|
+
manpages = ['man/webchanges.1:function=get_parser:pyfile=get_parser']
|
|
112
118
|
|
|
113
119
|
# -------------------------- coverage --------------------------
|
|
114
120
|
[tool.coverage.run]
|
|
@@ -170,60 +176,6 @@ exclude_lines = [
|
|
|
170
176
|
# ignore_errors = true
|
|
171
177
|
|
|
172
178
|
|
|
173
|
-
# -------------------------- mypy --------------------------
|
|
174
|
-
[tool.mypy]
|
|
175
|
-
# Static Typing for Python
|
|
176
|
-
# Runs as part of pre-commit
|
|
177
|
-
# Config file documentation at https://mypy.readthedocs.io/en/stable/config_file.html
|
|
178
|
-
|
|
179
|
-
# Disables import discovery of namespace packages (see PEP 420)
|
|
180
|
-
namespace_packages = true
|
|
181
|
-
|
|
182
|
-
# Specifies the Python version used to parse and check the target program.
|
|
183
|
-
# python_version = 3.12
|
|
184
|
-
|
|
185
|
-
# Suppresses error messages about imports that cannot be resolved.
|
|
186
|
-
ignore_missing_imports = true
|
|
187
|
-
|
|
188
|
-
# Disallows calling functions without type annotations from functions with type annotations.
|
|
189
|
-
disallow_untyped_calls = false
|
|
190
|
-
|
|
191
|
-
# Disallows defining functions without type annotations or with incomplete type annotations.
|
|
192
|
-
disallow_untyped_defs = true
|
|
193
|
-
|
|
194
|
-
# Reports an error whenever a function with type annotations is decorated with a decorator without annotations.
|
|
195
|
-
disallow_untyped_decorators = true
|
|
196
|
-
|
|
197
|
-
# Warns about casting an expression to its inferred type.
|
|
198
|
-
warn_redundant_casts = true
|
|
199
|
-
|
|
200
|
-
# Warns about unneeded # type: ignore comments.
|
|
201
|
-
# May behave differently in GitHub Actions than it does on Windows.
|
|
202
|
-
# warn_unused_ignores = true
|
|
203
|
-
|
|
204
|
-
# Shows a warning when returning a value with type Any from a function declared with a non-Any return type.
|
|
205
|
-
warn_return_any = true
|
|
206
|
-
|
|
207
|
-
# Shows a warning when encountering any code inferred to be unreachable or redundant after performing type analysis.
|
|
208
|
-
warn_unreachable = false
|
|
209
|
-
|
|
210
|
-
# Enables additional checks that are technically correct but may be impractical in real code.
|
|
211
|
-
extra_checks = true
|
|
212
|
-
|
|
213
|
-
# Shows documentation link to corresponding error code.
|
|
214
|
-
show_error_code_links = true
|
|
215
|
-
|
|
216
|
-
# Use visually nicer output in error messages: use soft word wrap, show source code snippets, and show error location
|
|
217
|
-
# markers.
|
|
218
|
-
pretty = true
|
|
219
|
-
|
|
220
|
-
# Use an SQLite database to store the cache.
|
|
221
|
-
sqlite_cache = true
|
|
222
|
-
|
|
223
|
-
# Warns about per-module sections in the config file that do not match any files processed when invoking mypy.
|
|
224
|
-
warn_unused_configs = true
|
|
225
|
-
|
|
226
|
-
|
|
227
179
|
# -------------------------- rstcheck --------------------------
|
|
228
180
|
[tool.rstcheck]
|
|
229
181
|
# Checks syntax of reStructuredText and code blocks nested within it.
|
|
@@ -240,12 +192,15 @@ report_level = 'WARNING'
|
|
|
240
192
|
# Testing framework
|
|
241
193
|
# Config file documentation at https://docs.pytest.org/en/stable/reference/reference.html#ini-options-ref
|
|
242
194
|
|
|
243
|
-
log_auto_indent =
|
|
195
|
+
# log_auto_indent = 2
|
|
244
196
|
# Enable log display during test run (aka "live logging" https://docs.pytest.org/en/stable/logging.html#live-logs)
|
|
245
|
-
log_cli = true
|
|
246
|
-
minversion = '
|
|
197
|
+
# log_cli = true
|
|
198
|
+
minversion = '9.0.2'
|
|
247
199
|
testpaths = ['tests']
|
|
248
200
|
|
|
201
|
+
# pytest-playwright
|
|
202
|
+
# addopts = ['--browser', 'chromium', '--browser-channel', 'chrome']
|
|
203
|
+
|
|
249
204
|
# Adds pytest-cov functionality (see https://pytest-cov.readthedocs.io/en/latest/config.html)
|
|
250
205
|
# Note: --cov moved to .github/workflows/ci-cd.yaml and tox.ini due to interference with PyCharm breakpoints (see
|
|
251
206
|
# https://github.com/pytest-dev/pytest-cov/issues/131) and to enable running tox --parallel
|
|
@@ -258,10 +213,7 @@ testpaths = ['tests']
|
|
|
258
213
|
# Config file documentation at https://docs.astral.sh/ruff/configuration/ and https://docs.astral.sh/ruff/settings/
|
|
259
214
|
|
|
260
215
|
# File patterns to omit from formatting and linting, in addition to those specified by exclude.
|
|
261
|
-
extend-exclude = [
|
|
262
|
-
"webchanges/storage_minidb.py",
|
|
263
|
-
"webchanges/_vendored",
|
|
264
|
-
]
|
|
216
|
+
extend-exclude = ['webchanges/storage_minidb.py', 'webchanges/_vendored']
|
|
265
217
|
|
|
266
218
|
# By default, Ruff will discover files matching *.py, *.pyi, *.ipynb, or pyproject.toml.
|
|
267
219
|
# Include additional files
|
|
@@ -271,83 +223,87 @@ extend-exclude = [
|
|
|
271
223
|
line-length = 120
|
|
272
224
|
|
|
273
225
|
# Target Python version
|
|
274
|
-
# target-version =
|
|
226
|
+
# target-version = 'py311' # Commented out to infer from [project] requires-python
|
|
275
227
|
|
|
276
228
|
[tool.ruff.lint]
|
|
277
229
|
# By default, Ruff enables Flake8's F rules, along with a subset of the E rules
|
|
278
230
|
# Enable rules not enabled by default, and ignore specific rules.
|
|
279
231
|
select = [
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
#
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
#
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
#
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
#
|
|
313
|
-
#
|
|
314
|
-
|
|
315
|
-
#
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
#
|
|
232
|
+
'ANN', # flake8-annotations
|
|
233
|
+
'S', # flake8-bandit
|
|
234
|
+
'BLE', # flake8-blind-except
|
|
235
|
+
'B', # flake8-bugbear
|
|
236
|
+
'A', # flake8-builtin
|
|
237
|
+
'C4', # flake8-comprehensions
|
|
238
|
+
'DTZ', # flake8-datetimez
|
|
239
|
+
# 'EM', # flake8-errmsg # TODO
|
|
240
|
+
'FA', # flake8-future-annotations
|
|
241
|
+
'INT', # flake8-gettext
|
|
242
|
+
'ISC', # flake8-implicit-str-concat
|
|
243
|
+
'LOG', # flake8-logging
|
|
244
|
+
# 'G', # flake8-logging-format # Prefer f-string to lazy `%` formatting and OK with '+'
|
|
245
|
+
'PIE', # flake8-pie
|
|
246
|
+
'PYI', # flake8-pyi
|
|
247
|
+
'PT', # flake8-pytest-style
|
|
248
|
+
'Q', # flake8-quotes
|
|
249
|
+
'RSE', # flake8-raise
|
|
250
|
+
'RET', # flake8-return
|
|
251
|
+
'SIM', # flake8-simplify
|
|
252
|
+
'TID', # flake8-tidy-imports
|
|
253
|
+
'TD', # flake8-todos
|
|
254
|
+
'TC', # flake8-type-checking
|
|
255
|
+
# 'ARG', # flake8-unused-arguments # Code loses clarity
|
|
256
|
+
'PTH', # flake8-use-pathlib
|
|
257
|
+
'FLY', # flynt
|
|
258
|
+
'I', # isort
|
|
259
|
+
'C90', # mccabe
|
|
260
|
+
'N', # pep8-naming
|
|
261
|
+
'PERF', # Perflint
|
|
262
|
+
'E', # pycodestyle errors
|
|
263
|
+
'W', # pycodestyle warnings
|
|
264
|
+
# 'DOC', # pydoclint # TODO
|
|
265
|
+
# 'D', # pydocstyle # TODO
|
|
266
|
+
'F', # Pyflakes
|
|
267
|
+
# 'PL', # Pylint # TODO
|
|
268
|
+
'FURB', # refurb
|
|
269
|
+
'RUF', # Ruff-specific rules
|
|
270
|
+
# 'TRY', # tryceratops # TODO
|
|
319
271
|
]
|
|
320
272
|
|
|
321
273
|
ignore = [
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
274
|
+
'FLY002', # Consider f-string instead of string join
|
|
275
|
+
# 'G003', # Logging statement uses `+`'
|
|
276
|
+
# 'G004', # Logging statement uses f-string (Prefer f-string to lazy `%` formatting)
|
|
277
|
+
'PLC0415', # `import` should be at the top-level of a file
|
|
278
|
+
'PT011', # pytest.raises({exception}) is too broad, set the match parameter or use a more specific exception
|
|
279
|
+
'PT030', # pytest.warns({warning}) is too broad, set the match parameter or use a more specific warning
|
|
280
|
+
'RUF012', # Mutable class attributes should be annotated with `typing.ClassVar`
|
|
281
|
+
'SIM105', # Use contextlib.suppress({exception}) instead of try-except-pass
|
|
282
|
+
'SIM115', # Use a context manager for opening files
|
|
283
|
+
'TD002', # Missing author in TODO
|
|
284
|
+
'TD003', # Missing issue link for this TODO
|
|
329
285
|
]
|
|
330
286
|
|
|
331
287
|
# Allow fix for all enabled rules (when `--fix`) is provided.
|
|
332
|
-
fixable = [
|
|
288
|
+
fixable = ['ALL']
|
|
333
289
|
unfixable = []
|
|
334
290
|
|
|
335
291
|
# Allow unused variables when underscore-prefixed.
|
|
336
|
-
dummy-variable-rgx =
|
|
292
|
+
dummy-variable-rgx = '^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$'
|
|
337
293
|
|
|
338
294
|
[tool.ruff.lint.flake8-annotations]
|
|
339
|
-
allow-star-arg-any = true
|
|
295
|
+
allow-star-arg-any = true # TODO
|
|
340
296
|
|
|
341
297
|
[tool.ruff.lint.flake8-quotes]
|
|
342
|
-
inline-quotes =
|
|
298
|
+
inline-quotes = 'single'
|
|
343
299
|
|
|
344
300
|
[tool.ruff.lint.mccabe]
|
|
345
301
|
# Flag errors (`C901`) whenever the complexity level exceeds below.
|
|
346
302
|
max-complexity = 30
|
|
347
303
|
|
|
348
304
|
[tool.ruff.lint.per-file-ignores]
|
|
349
|
-
|
|
350
|
-
|
|
305
|
+
'tests/*' = [
|
|
306
|
+
'S101', # Use of `assert` detected
|
|
351
307
|
]
|
|
352
308
|
|
|
353
309
|
[tool.ruff.lint.pydoclint]
|
|
@@ -355,7 +311,7 @@ max-complexity = 30
|
|
|
355
311
|
ignore-one-line-docstrings = true
|
|
356
312
|
|
|
357
313
|
[tool.ruff.lint.pydocstyle]
|
|
358
|
-
convention =
|
|
314
|
+
convention = 'google'
|
|
359
315
|
|
|
360
316
|
[tool.ruff.format]
|
|
361
317
|
# Enable the formatter, which is a drop-in replacement for Black.
|
|
@@ -365,16 +321,16 @@ convention = "google"
|
|
|
365
321
|
exclude = []
|
|
366
322
|
|
|
367
323
|
# Use single quotes for strings.
|
|
368
|
-
quote-style =
|
|
324
|
+
quote-style = 'single'
|
|
369
325
|
|
|
370
326
|
# Like Black, indent with spaces, rather than tabs.
|
|
371
|
-
indent-style =
|
|
327
|
+
indent-style = 'space'
|
|
372
328
|
|
|
373
329
|
# Like Black, respect magic trailing commas.
|
|
374
330
|
skip-magic-trailing-comma = false
|
|
375
331
|
|
|
376
332
|
# Like Black, automatically detect the appropriate line ending.
|
|
377
|
-
line-ending =
|
|
333
|
+
line-ending = 'auto'
|
|
378
334
|
|
|
379
335
|
# Enable auto-formatting of code examples in docstrings. Markdown,
|
|
380
336
|
# reStructuredText code/literal blocks and doctests are all supported.
|
|
@@ -388,4 +344,13 @@ docstring-code-format = true
|
|
|
388
344
|
#
|
|
389
345
|
# This only has an effect when the `docstring-code-format` setting is
|
|
390
346
|
# enabled.
|
|
391
|
-
docstring-code-line-length =
|
|
347
|
+
docstring-code-line-length = 'dynamic'
|
|
348
|
+
|
|
349
|
+
# -------------------------- ty --------------------------
|
|
350
|
+
# Config file documentation at https://docs.astral.sh/ty/reference/configuration/
|
|
351
|
+
|
|
352
|
+
[tool.ty.environment]
|
|
353
|
+
extra-paths = ['./webchanges']
|
|
354
|
+
|
|
355
|
+
[tool.ty.src]
|
|
356
|
+
exclude = ['./webchanges/storage_minidb.py']
|
|
@@ -12,7 +12,7 @@ supported services. Can check the output of local commands as well.
|
|
|
12
12
|
|
|
13
13
|
from __future__ import annotations
|
|
14
14
|
|
|
15
|
-
__min_python_version__ = (3,
|
|
15
|
+
__min_python_version__ = (3, 11) # minimum version of Python required to run; 3.11 supported until fall 2026
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
__project_name__ = str(__package__)
|
|
@@ -22,7 +22,7 @@ __project_name__ = str(__package__)
|
|
|
22
22
|
# * MINOR version when you add functionality in a backwards compatible manner, and
|
|
23
23
|
# * MICRO or PATCH version when you make backwards compatible bug fixes. We no longer use '0'
|
|
24
24
|
# If unsure on increments, use pkg_resources.parse_version to parse
|
|
25
|
-
__version__ = '3.
|
|
25
|
+
__version__ = '3.33.0'
|
|
26
26
|
__description__ = (
|
|
27
27
|
'Check web (or command output) for changes since last run and notify.\n\nAnonymously alerts you of web changes.'
|
|
28
28
|
)
|
|
@@ -50,7 +50,7 @@ def to_str(value: str | bytes, encoding: str = 'utf-8') -> str:
|
|
|
50
50
|
|
|
51
51
|
|
|
52
52
|
def to_bytes_or_str(value: str, match_type_of: typing.AnyStr) -> typing.AnyStr:
|
|
53
|
-
return value if isinstance(match_type_of, str) else value.encode()
|
|
53
|
+
return value if isinstance(match_type_of, str) else value.encode() # ty:ignore[invalid-return-type]
|
|
54
54
|
|
|
55
55
|
|
|
56
56
|
# from https://github.com/encode/httpx/blob/master/httpx/_models.py
|
|
@@ -81,8 +81,8 @@ def _obfuscate_sensitive_headers(
|
|
|
81
81
|
items: typing.Iterable[tuple[typing.AnyStr, typing.AnyStr]],
|
|
82
82
|
) -> typing.Iterator[tuple[typing.AnyStr, typing.AnyStr]]:
|
|
83
83
|
for k, v in items:
|
|
84
|
-
if to_str(k.lower()) in SENSITIVE_HEADERS:
|
|
85
|
-
v = to_bytes_or_str('[secure]', match_type_of=v)
|
|
84
|
+
if to_str(k.lower()) in SENSITIVE_HEADERS: # ty:ignore[no-matching-overload, invalid-argument-type]
|
|
85
|
+
v = to_bytes_or_str('[secure]', match_type_of=v) # ty:ignore[invalid-argument-type]
|
|
86
86
|
yield k, v
|
|
87
87
|
|
|
88
88
|
|
|
@@ -102,8 +102,8 @@ class Headers(typing.MutableMapping[str, str]):
|
|
|
102
102
|
self._list = list(headers._list)
|
|
103
103
|
elif isinstance(headers, Mapping):
|
|
104
104
|
for k, v in headers.items():
|
|
105
|
-
bytes_key = _normalize_header_key(k, encoding)
|
|
106
|
-
bytes_value = _normalize_header_value(v, encoding)
|
|
105
|
+
bytes_key = _normalize_header_key(k, encoding) # ty:ignore[invalid-argument-type]
|
|
106
|
+
bytes_value = _normalize_header_value(v, encoding) # ty:ignore[invalid-argument-type]
|
|
107
107
|
self._list.append((bytes_key, bytes_key.lower(), bytes_value))
|
|
108
108
|
elif headers is not None:
|
|
109
109
|
for k, v in headers:
|
|
@@ -24,9 +24,14 @@ from webchanges import __copyright__, __docs_url__, __min_python_version__, __pr
|
|
|
24
24
|
from webchanges.config import CommandConfig
|
|
25
25
|
from webchanges.util import file_ownership_checks, get_new_version_number, import_module_from_source
|
|
26
26
|
|
|
27
|
-
#
|
|
28
|
-
|
|
27
|
+
# Restore the default system behavior for the SIGPIPE signal, which is ignored by Python by default.
|
|
28
|
+
# This prevents a BrokenPipeError when piping output to a command like `less` that may close the pipe before reading all
|
|
29
|
+
# of the output.
|
|
30
|
+
try:
|
|
29
31
|
signal.signal(signal.SIGPIPE, signal.SIG_DFL) # type: ignore[attr-defined] # not defined in Windows
|
|
32
|
+
except AttributeError:
|
|
33
|
+
pass
|
|
34
|
+
|
|
30
35
|
|
|
31
36
|
logger = logging.getLogger(__name__)
|
|
32
37
|
|
|
@@ -376,7 +381,7 @@ def main() -> None: # pragma: no cover
|
|
|
376
381
|
python_version_warning()
|
|
377
382
|
|
|
378
383
|
# Path where the config, jobs and hooks files are located
|
|
379
|
-
if
|
|
384
|
+
if sys.platform != 'win32':
|
|
380
385
|
config_path = platformdirs.user_config_path(__project_name__) # typically ~/.config/{__project_name__}
|
|
381
386
|
else:
|
|
382
387
|
config_path = platformdirs.user_documents_path().joinpath(__project_name__)
|
|
@@ -471,10 +476,8 @@ def main() -> None: # pragma: no cover
|
|
|
471
476
|
config_storage.load()
|
|
472
477
|
|
|
473
478
|
# Setup database API
|
|
474
|
-
database_engine = (
|
|
475
|
-
|
|
476
|
-
) # "or 'sqlite3'" is not needed except for a mypy bug; same for the "or 4" below
|
|
477
|
-
max_snapshots = command_config.max_snapshots or config_storage.config.get('database', {}).get('max_snapshots') or 4
|
|
479
|
+
database_engine = command_config.database_engine or config_storage.config.get('database', {}).get('engine')
|
|
480
|
+
max_snapshots = command_config.max_snapshots or config_storage.config.get('database', {}).get('max_snapshots')
|
|
478
481
|
if database_engine == 'sqlite3':
|
|
479
482
|
ssdb_storage: SsdbStorage = SsdbSQLite3Storage(command_config.ssdb_file, max_snapshots) # storage.py
|
|
480
483
|
elif any(str(command_config.ssdb_file).startswith(prefix) for prefix in ('redis://', 'rediss://')):
|