webchanges 3.31.3__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.3/webchanges.egg-info → webchanges-3.33.0}/PKG-INFO +14 -7
- {webchanges-3.31.3 → webchanges-3.33.0}/README.rst +7 -2
- {webchanges-3.31.3 → webchanges-3.33.0}/pyproject.toml +118 -208
- {webchanges-3.31.3 → webchanges-3.33.0}/requirements.txt +1 -1
- {webchanges-3.31.3 → webchanges-3.33.0}/webchanges/__init__.py +4 -4
- {webchanges-3.31.3 → webchanges-3.33.0}/webchanges/_vendored/headers.py +5 -5
- {webchanges-3.31.3 → webchanges-3.33.0}/webchanges/cli.py +26 -24
- {webchanges-3.31.3 → webchanges-3.33.0}/webchanges/command.py +115 -102
- {webchanges-3.31.3 → webchanges-3.33.0}/webchanges/config.py +2 -3
- {webchanges-3.31.3 → webchanges-3.33.0}/webchanges/differs.py +255 -211
- {webchanges-3.31.3 → webchanges-3.33.0}/webchanges/filters.py +83 -130
- {webchanges-3.31.3 → webchanges-3.33.0}/webchanges/handler.py +71 -98
- {webchanges-3.31.3 → webchanges-3.33.0}/webchanges/jobs.py +482 -387
- {webchanges-3.31.3 → webchanges-3.33.0}/webchanges/mailer.py +7 -4
- {webchanges-3.31.3 → webchanges-3.33.0}/webchanges/main.py +11 -9
- {webchanges-3.31.3 → webchanges-3.33.0}/webchanges/reporters.py +125 -149
- {webchanges-3.31.3 → webchanges-3.33.0}/webchanges/storage.py +115 -126
- {webchanges-3.31.3 → webchanges-3.33.0}/webchanges/storage_minidb.py +1 -1
- {webchanges-3.31.3 → webchanges-3.33.0}/webchanges/util.py +26 -25
- {webchanges-3.31.3 → webchanges-3.33.0}/webchanges/worker.py +26 -21
- {webchanges-3.31.3 → webchanges-3.33.0/webchanges.egg-info}/PKG-INFO +14 -7
- {webchanges-3.31.3 → webchanges-3.33.0}/webchanges.egg-info/SOURCES.txt +1 -1
- {webchanges-3.31.3 → webchanges-3.33.0}/webchanges.egg-info/requires.txt +2 -0
- /webchanges-3.31.3/LICENSE → /webchanges-3.33.0/LICENSE.md +0 -0
- {webchanges-3.31.3 → webchanges-3.33.0}/MANIFEST.in +0 -0
- {webchanges-3.31.3 → webchanges-3.33.0}/setup.cfg +0 -0
- {webchanges-3.31.3 → webchanges-3.33.0}/webchanges/__main__.py +0 -0
- {webchanges-3.31.3 → webchanges-3.33.0}/webchanges/_vendored/__init__.py +0 -0
- {webchanges-3.31.3 → webchanges-3.33.0}/webchanges/_vendored/packaging_version.py +0 -0
- {webchanges-3.31.3 → webchanges-3.33.0}/webchanges/py.typed +0 -0
- {webchanges-3.31.3 → webchanges-3.33.0}/webchanges.egg-info/dependency_links.txt +0 -0
- {webchanges-3.31.3 → webchanges-3.33.0}/webchanges.egg-info/entry_points.txt +0 -0
- {webchanges-3.31.3 → 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,10 +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
|
|
94
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
95
|
+
Classifier: Programming Language :: Python :: Free Threading
|
|
96
|
+
Classifier: Programming Language :: Python :: Free Threading :: 4 - Resilient
|
|
95
97
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
96
98
|
Classifier: Topic :: Internet
|
|
97
99
|
Classifier: Topic :: Internet :: WWW/HTTP
|
|
@@ -99,9 +101,9 @@ Classifier: Topic :: Internet :: WWW/HTTP :: Indexing/Search
|
|
|
99
101
|
Classifier: Topic :: System :: Monitoring
|
|
100
102
|
Classifier: Topic :: Utilities
|
|
101
103
|
Classifier: Typing :: Typed
|
|
102
|
-
Requires-Python: >=3.
|
|
104
|
+
Requires-Python: >=3.11
|
|
103
105
|
Description-Content-Type: text/x-rst
|
|
104
|
-
License-File: LICENSE
|
|
106
|
+
License-File: LICENSE.md
|
|
105
107
|
Requires-Dist: colorama; sys_platform == "win32"
|
|
106
108
|
Requires-Dist: cssselect
|
|
107
109
|
Requires-Dist: h2
|
|
@@ -113,7 +115,7 @@ Requires-Dist: msgpack
|
|
|
113
115
|
Requires-Dist: platformdirs
|
|
114
116
|
Requires-Dist: pyyaml
|
|
115
117
|
Requires-Dist: tzdata; sys_platform == "win32"
|
|
116
|
-
Requires-Dist: zstandard
|
|
118
|
+
Requires-Dist: zstandard; python_version < "3.14"
|
|
117
119
|
Provides-Extra: use-browser
|
|
118
120
|
Requires-Dist: playwright; extra == "use-browser"
|
|
119
121
|
Requires-Dist: psutil; extra == "use-browser"
|
|
@@ -188,6 +190,8 @@ For the best experience, use the current version of `Python <https://www.python.
|
|
|
188
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
|
|
189
191
|
bug and security fix release from that older version.
|
|
190
192
|
|
|
193
|
+
While **webchanges** supports free-threated Python, certain optional dependencies may not.
|
|
194
|
+
|
|
191
195
|
For Generative AI summaries (BETA), you need a free `API Key from Google Cloud AI Studio
|
|
192
196
|
<https://aistudio.google.com/app/apikey>`__ (see `here
|
|
193
197
|
<https://webchanges.readthedocs.io/en/stable/differs.html#ai-google>`__).
|
|
@@ -266,7 +270,7 @@ Schedule
|
|
|
266
270
|
|
|
267
271
|
Code
|
|
268
272
|
====
|
|
269
|
-
|coveralls| |snyk| |issues| |code_style|
|
|
273
|
+
|coveralls| |snyk| |issues| |code_style| |OpenSSF_Scorecard|
|
|
270
274
|
|
|
271
275
|
The code, issues tracker, and discussions are hosted on `GitHub <https://github.com/mborsetti/webchanges>`__.
|
|
272
276
|
|
|
@@ -285,7 +289,7 @@ License
|
|
|
285
289
|
=======
|
|
286
290
|
|license|
|
|
287
291
|
|
|
288
|
-
See the `complete licenses <https://raw.githubusercontent.com/mborsetti/webchanges/refs/heads/main/LICENSE>`__ (released
|
|
292
|
+
See the `complete licenses <https://raw.githubusercontent.com/mborsetti/webchanges/refs/heads/main/LICENSE.md>`__ (released
|
|
289
293
|
under the `MIT License <https://opensource.org/licenses/MIT>`__ but redistributing modified source code, dated 30
|
|
290
294
|
July 2020, from `urlwatch 2.21 <https://github.com/thp/urlwatch/tree/346b25914b0418342ffe2fb0529bed702fddc01f>`__
|
|
291
295
|
licensed under a `BSD 3-Clause License
|
|
@@ -346,3 +350,6 @@ configuration files), see `here <https://webchanges.readthedocs.io/en/stable/upg
|
|
|
346
350
|
.. |snyk| image:: https://snyk.io/advisor/python/holidays/badge.svg
|
|
347
351
|
:target: https://snyk.io/advisor/python/holidays
|
|
348
352
|
:alt: Snyk Package Health Score
|
|
353
|
+
.. |OpenSSF_Scorecard| image:: https://api.scorecard.dev/projects/github.com/mborsetti/webchanges/badge
|
|
354
|
+
:target: https://scorecard.dev/viewer/?uri=github.com/mborsetti/webchanges
|
|
355
|
+
:alt: OpenSSF Scoreard
|
|
@@ -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>`__).
|
|
@@ -100,7 +102,7 @@ Schedule
|
|
|
100
102
|
|
|
101
103
|
Code
|
|
102
104
|
====
|
|
103
|
-
|coveralls| |snyk| |issues| |code_style|
|
|
105
|
+
|coveralls| |snyk| |issues| |code_style| |OpenSSF_Scorecard|
|
|
104
106
|
|
|
105
107
|
The code, issues tracker, and discussions are hosted on `GitHub <https://github.com/mborsetti/webchanges>`__.
|
|
106
108
|
|
|
@@ -119,7 +121,7 @@ License
|
|
|
119
121
|
=======
|
|
120
122
|
|license|
|
|
121
123
|
|
|
122
|
-
See the `complete licenses <https://raw.githubusercontent.com/mborsetti/webchanges/refs/heads/main/LICENSE>`__ (released
|
|
124
|
+
See the `complete licenses <https://raw.githubusercontent.com/mborsetti/webchanges/refs/heads/main/LICENSE.md>`__ (released
|
|
123
125
|
under the `MIT License <https://opensource.org/licenses/MIT>`__ but redistributing modified source code, dated 30
|
|
124
126
|
July 2020, from `urlwatch 2.21 <https://github.com/thp/urlwatch/tree/346b25914b0418342ffe2fb0529bed702fddc01f>`__
|
|
125
127
|
licensed under a `BSD 3-Clause License
|
|
@@ -180,3 +182,6 @@ configuration files), see `here <https://webchanges.readthedocs.io/en/stable/upg
|
|
|
180
182
|
.. |snyk| image:: https://snyk.io/advisor/python/holidays/badge.svg
|
|
181
183
|
:target: https://snyk.io/advisor/python/holidays
|
|
182
184
|
:alt: Snyk Package Health Score
|
|
185
|
+
.. |OpenSSF_Scorecard| image:: https://api.scorecard.dev/projects/github.com/mborsetti/webchanges/badge
|
|
186
|
+
:target: https://scorecard.dev/viewer/?uri=github.com/mborsetti/webchanges
|
|
187
|
+
:alt: OpenSSF Scoreard
|
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
|
|
7
7
|
[build-system]
|
|
8
8
|
# Minimum requirements for the build system to execute.
|
|
9
|
-
requires = ['setuptools']
|
|
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,13 +16,11 @@ 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.
|
|
20
|
-
license = {file = 'LICENSE'}
|
|
21
|
-
authors = [
|
|
22
|
-
{name = 'Mike Borsetti', email = 'mike+webchanges@borsetti.com'},
|
|
23
|
-
]
|
|
19
|
+
requires-python = '>=3.11'
|
|
20
|
+
license = { file = 'LICENSE.md' }
|
|
21
|
+
authors = [{ name = 'Mike Borsetti', email = 'mike+webchanges@borsetti.com' }]
|
|
24
22
|
maintainers = [
|
|
25
|
-
{name = 'Mike Borsetti', email = 'mike+webchanges@borsetti.com'},
|
|
23
|
+
{ name = 'Mike Borsetti', email = 'mike+webchanges@borsetti.com' },
|
|
26
24
|
]
|
|
27
25
|
keywords = ['webmonitoring', 'monitoring']
|
|
28
26
|
classifiers = [
|
|
@@ -38,10 +36,12 @@ classifiers = [
|
|
|
38
36
|
'Programming Language :: Python',
|
|
39
37
|
'Programming Language :: Python :: 3',
|
|
40
38
|
'Programming Language :: Python :: 3 :: Only',
|
|
41
|
-
'Programming Language :: Python :: 3.10',
|
|
42
39
|
'Programming Language :: Python :: 3.11',
|
|
43
40
|
'Programming Language :: Python :: 3.12',
|
|
44
41
|
'Programming Language :: Python :: 3.13',
|
|
42
|
+
'Programming Language :: Python :: 3.14',
|
|
43
|
+
'Programming Language :: Python :: Free Threading',
|
|
44
|
+
'Programming Language :: Python :: Free Threading :: 4 - Resilient',
|
|
45
45
|
'Programming Language :: Python :: Implementation :: CPython',
|
|
46
46
|
'Topic :: Internet',
|
|
47
47
|
'Topic :: Internet :: WWW/HTTP',
|
|
@@ -89,56 +89,32 @@ xmpp = ['aioxmpp']
|
|
|
89
89
|
redis = ['redis']
|
|
90
90
|
requests = ['requests']
|
|
91
91
|
safe_password = ['keyring']
|
|
92
|
+
# all
|
|
92
93
|
all = [
|
|
93
|
-
'webchanges[use_browser,beautify,bs4,html5lib,ical2text,jq,ocr,pdf2text,pypdf_crypto,deepdiff_xml,imagediff,matrix,pushbullet,pushover,xmpp,redis,requests,safe_password]'
|
|
94
|
+
'webchanges[use_browser,beautify,bs4,html5lib,ical2text,jq,ocr,pdf2text,pypdf_crypto,deepdiff_xml,imagediff,matrix,pushbullet,pushover,xmpp,redis,requests,safe_password]',
|
|
94
95
|
]
|
|
95
96
|
|
|
96
97
|
|
|
97
98
|
# -------------------------- setuptools --------------------------
|
|
99
|
+
[tool.setuptools]
|
|
98
100
|
# Called by build
|
|
99
101
|
# See https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html
|
|
100
|
-
|
|
101
|
-
#
|
|
102
|
+
|
|
103
|
+
# Explicit package listing is required for building in tox -e new-install
|
|
102
104
|
# https://setuptools.pypa.io/en/latest/userguide/package_discovery.html
|
|
103
105
|
packages = ['webchanges', 'webchanges._vendored']
|
|
104
106
|
|
|
105
107
|
[tool.setuptools.dynamic]
|
|
106
|
-
version = {attr = 'webchanges.__version__'}
|
|
107
|
-
dependencies = {file = 'requirements.txt'}
|
|
108
|
+
version = { attr = 'webchanges.__version__' }
|
|
109
|
+
dependencies = { file = 'requirements.txt' }
|
|
108
110
|
|
|
109
111
|
[tool.setuptools.package-data]
|
|
110
112
|
'webchanges' = ['py.typed']
|
|
111
113
|
|
|
112
|
-
|
|
113
|
-
#
|
|
114
|
-
[tool.
|
|
115
|
-
|
|
116
|
-
# Runs as part of pre-commit.
|
|
117
|
-
# Config file documentation at https://bandit.readthedocs.io/en/latest/config.html
|
|
118
|
-
|
|
119
|
-
targets = ['webchanges', 'tests']
|
|
120
|
-
skips = [
|
|
121
|
-
'B101', # Use of assert detected.
|
|
122
|
-
'B404', # Consider possible security implications associated with subprocess module.
|
|
123
|
-
'B602', # subprocess call with shell=True identified, security issue.
|
|
124
|
-
'B603' # subprocess call - check for execution of untrusted input.
|
|
125
|
-
]
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
# -------------------------- black --------------------------
|
|
129
|
-
[tool.black]
|
|
130
|
-
# Uncompromising code formatting
|
|
131
|
-
# Runs as part of pre-commit
|
|
132
|
-
# Config file documentation
|
|
133
|
-
# https://black.readthedocs.io/en/stable/usage_and_configuration/the_basics.html#configuration-via-a-file
|
|
134
|
-
|
|
135
|
-
# What's in here overrides the command-line options shown by running $ black --help.
|
|
136
|
-
line-length = 120
|
|
137
|
-
target-version = ['py310']
|
|
138
|
-
skip-string-normalization = true
|
|
139
|
-
extend-exclude = '/(\.idea|\.pytest_cache|\__pycache__|\venv.*|\webchanges.egg-info)/'
|
|
140
|
-
color = true
|
|
141
|
-
|
|
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']
|
|
142
118
|
|
|
143
119
|
# -------------------------- coverage --------------------------
|
|
144
120
|
[tool.coverage.run]
|
|
@@ -193,104 +169,13 @@ exclude_lines = [
|
|
|
193
169
|
'except ImportError:',
|
|
194
170
|
|
|
195
171
|
# Don't cover IDE code:
|
|
196
|
-
'if TYPE_CHECKING:'
|
|
172
|
+
'if TYPE_CHECKING:',
|
|
197
173
|
]
|
|
198
174
|
# Exclude entire files if they have a custom # pragma: exclude file remark
|
|
199
175
|
# exclude_also = '(?s)\A.*# pragma: exclude file.*\Z'
|
|
200
176
|
# ignore_errors = true
|
|
201
177
|
|
|
202
178
|
|
|
203
|
-
# -------------------------- isort --------------------------
|
|
204
|
-
[tool.isort]
|
|
205
|
-
# isort your imports, so you don't have to.
|
|
206
|
-
# Runs as part of pre-commit.
|
|
207
|
-
# Config file documentation https://pycqa.github.io/isort/docs/configuration/options.html
|
|
208
|
-
|
|
209
|
-
profile = 'black'
|
|
210
|
-
# multi_line_output = 3
|
|
211
|
-
# use_parentheses = True
|
|
212
|
-
# include_trailing_comma = True
|
|
213
|
-
# force_grid_wrap = 0
|
|
214
|
-
# ensure_newline_before_comments = True
|
|
215
|
-
line_length = 120
|
|
216
|
-
|
|
217
|
-
# Treat project as a git repository and ignore files listed in .gitignore.
|
|
218
|
-
skip_gitignore = true
|
|
219
|
-
|
|
220
|
-
# Force isort to recognize a module as being part of the current python project.
|
|
221
|
-
known_first_party = 'webchanges'
|
|
222
|
-
|
|
223
|
-
# Force isort to recognize a module as being a local folder.
|
|
224
|
-
# Generally, this is reserved for relative imports (from . import module).
|
|
225
|
-
known_local_folder = 'webchanges'
|
|
226
|
-
|
|
227
|
-
# Force all imports to be sorted alphabetically within a section.
|
|
228
|
-
force_alphabetical_sort_within_sections = true
|
|
229
|
-
|
|
230
|
-
# Automatically create section groups by the top-level package they come from.
|
|
231
|
-
group_by_package = true
|
|
232
|
-
|
|
233
|
-
# Remove redundant aliases from imports, such as import os as os.
|
|
234
|
-
remove_redundant_aliases = true
|
|
235
|
-
|
|
236
|
-
# Use color in terminal output.
|
|
237
|
-
color_output = true
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
# -------------------------- mypy --------------------------
|
|
241
|
-
[tool.mypy]
|
|
242
|
-
# Static Typing for Python
|
|
243
|
-
# Runs as part of pre-commit
|
|
244
|
-
# Config file documentation at https://mypy.readthedocs.io/en/stable/config_file.html
|
|
245
|
-
|
|
246
|
-
# Disables import discovery of namespace packages (see PEP 420)
|
|
247
|
-
namespace_packages = false
|
|
248
|
-
|
|
249
|
-
# Specifies the Python version used to parse and check the target program.
|
|
250
|
-
# python_version = 3.12
|
|
251
|
-
|
|
252
|
-
# Suppresses error messages about imports that cannot be resolved.
|
|
253
|
-
ignore_missing_imports = true
|
|
254
|
-
|
|
255
|
-
# Disallows calling functions without type annotations from functions with type annotations.
|
|
256
|
-
disallow_untyped_calls = true
|
|
257
|
-
|
|
258
|
-
# Disallows defining functions without type annotations or with incomplete type annotations.
|
|
259
|
-
disallow_untyped_defs = true
|
|
260
|
-
|
|
261
|
-
# Reports an error whenever a function with type annotations is decorated with a decorator without annotations.
|
|
262
|
-
disallow_untyped_decorators = true
|
|
263
|
-
|
|
264
|
-
# Warns about casting an expression to its inferred type.
|
|
265
|
-
warn_redundant_casts = true
|
|
266
|
-
|
|
267
|
-
# Warns about unneeded # type: ignore comments.
|
|
268
|
-
# May behave differently in GitHub Actions than it does on Windows.
|
|
269
|
-
# warn_unused_ignores = true
|
|
270
|
-
|
|
271
|
-
# Shows a warning when returning a value with type Any from a function declared with a non-Any return type.
|
|
272
|
-
warn_return_any = true
|
|
273
|
-
|
|
274
|
-
# Shows a warning when encountering any code inferred to be unreachable or redundant after performing type analysis.
|
|
275
|
-
warn_unreachable = false
|
|
276
|
-
|
|
277
|
-
# Enables additional checks that are technically correct but may be impractical in real code.
|
|
278
|
-
extra_checks = true
|
|
279
|
-
|
|
280
|
-
# Shows documentation link to corresponding error code.
|
|
281
|
-
show_error_code_links = true
|
|
282
|
-
|
|
283
|
-
# Use visually nicer output in error messages: use soft word wrap, show source code snippets, and show error location
|
|
284
|
-
# markers.
|
|
285
|
-
pretty = true
|
|
286
|
-
|
|
287
|
-
# Use an SQLite database to store the cache.
|
|
288
|
-
sqlite_cache = true
|
|
289
|
-
|
|
290
|
-
# Warns about per-module sections in the config file that do not match any files processed when invoking mypy.
|
|
291
|
-
warn_unused_configs = true
|
|
292
|
-
|
|
293
|
-
|
|
294
179
|
# -------------------------- rstcheck --------------------------
|
|
295
180
|
[tool.rstcheck]
|
|
296
181
|
# Checks syntax of reStructuredText and code blocks nested within it.
|
|
@@ -307,15 +192,14 @@ report_level = 'WARNING'
|
|
|
307
192
|
# Testing framework
|
|
308
193
|
# Config file documentation at https://docs.pytest.org/en/stable/reference/reference.html#ini-options-ref
|
|
309
194
|
|
|
310
|
-
log_auto_indent =
|
|
195
|
+
# log_auto_indent = 2
|
|
311
196
|
# Enable log display during test run (aka "live logging" https://docs.pytest.org/en/stable/logging.html#live-logs)
|
|
312
|
-
log_cli = true
|
|
313
|
-
minversion = '
|
|
197
|
+
# log_cli = true
|
|
198
|
+
minversion = '9.0.2'
|
|
314
199
|
testpaths = ['tests']
|
|
315
200
|
|
|
316
|
-
#
|
|
317
|
-
#
|
|
318
|
-
# asyncio_default_fixture_loop_scope = 'function'
|
|
201
|
+
# pytest-playwright
|
|
202
|
+
# addopts = ['--browser', 'chromium', '--browser-channel', 'chrome']
|
|
319
203
|
|
|
320
204
|
# Adds pytest-cov functionality (see https://pytest-cov.readthedocs.io/en/latest/config.html)
|
|
321
205
|
# Note: --cov moved to .github/workflows/ci-cd.yaml and tox.ini due to interference with PyCharm breakpoints (see
|
|
@@ -326,40 +210,10 @@ testpaths = ['tests']
|
|
|
326
210
|
|
|
327
211
|
# -------------------------- ruff --------------------------
|
|
328
212
|
[tool.ruff]
|
|
329
|
-
# Config file documentation at https://docs.astral.sh/ruff/configuration/
|
|
330
|
-
|
|
331
|
-
#
|
|
332
|
-
exclude = [
|
|
333
|
-
".bzr",
|
|
334
|
-
".direnv",
|
|
335
|
-
".eggs",
|
|
336
|
-
".git",
|
|
337
|
-
".git-rewrite",
|
|
338
|
-
".hg",
|
|
339
|
-
".ipynb_checkpoints",
|
|
340
|
-
".mypy_cache",
|
|
341
|
-
".nox",
|
|
342
|
-
".pants.d",
|
|
343
|
-
".pyenv",
|
|
344
|
-
".pytest_cache",
|
|
345
|
-
".pytype",
|
|
346
|
-
".ruff_cache",
|
|
347
|
-
".svn",
|
|
348
|
-
".tox",
|
|
349
|
-
".venv",
|
|
350
|
-
".vscode",
|
|
351
|
-
"__pypackages__",
|
|
352
|
-
"_build",
|
|
353
|
-
"buck-out",
|
|
354
|
-
"build",
|
|
355
|
-
"dist",
|
|
356
|
-
"node_modules",
|
|
357
|
-
"site-packages",
|
|
358
|
-
"venv",
|
|
359
|
-
|
|
360
|
-
"webchanges/storage_minidb.py",
|
|
361
|
-
"webchanges/_vendored",
|
|
362
|
-
]
|
|
213
|
+
# Config file documentation at https://docs.astral.sh/ruff/configuration/ and https://docs.astral.sh/ruff/settings/
|
|
214
|
+
|
|
215
|
+
# File patterns to omit from formatting and linting, in addition to those specified by exclude.
|
|
216
|
+
extend-exclude = ['webchanges/storage_minidb.py', 'webchanges/_vendored']
|
|
363
217
|
|
|
364
218
|
# By default, Ruff will discover files matching *.py, *.pyi, *.ipynb, or pyproject.toml.
|
|
365
219
|
# Include additional files
|
|
@@ -367,44 +221,97 @@ exclude = [
|
|
|
367
221
|
|
|
368
222
|
# Set the maximum line length.
|
|
369
223
|
line-length = 120
|
|
370
|
-
indent-width = 4
|
|
371
224
|
|
|
372
225
|
# Target Python version
|
|
373
|
-
# target-version =
|
|
226
|
+
# target-version = 'py311' # Commented out to infer from [project] requires-python
|
|
374
227
|
|
|
375
228
|
[tool.ruff.lint]
|
|
376
229
|
# By default, Ruff enables Flake8's F rules, along with a subset of the E rules
|
|
377
230
|
# Enable rules not enabled by default, and ignore specific rules.
|
|
378
231
|
select = [
|
|
379
|
-
# flake8-
|
|
380
|
-
|
|
381
|
-
# flake8-
|
|
382
|
-
|
|
383
|
-
# flake8-
|
|
384
|
-
|
|
385
|
-
#
|
|
386
|
-
|
|
387
|
-
#
|
|
388
|
-
#
|
|
389
|
-
#
|
|
390
|
-
|
|
391
|
-
#
|
|
392
|
-
|
|
393
|
-
#
|
|
394
|
-
|
|
395
|
-
#
|
|
396
|
-
|
|
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
|
|
397
271
|
]
|
|
272
|
+
|
|
398
273
|
ignore = [
|
|
399
|
-
|
|
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
|
|
400
285
|
]
|
|
401
286
|
|
|
402
287
|
# Allow fix for all enabled rules (when `--fix`) is provided.
|
|
403
|
-
fixable = [
|
|
288
|
+
fixable = ['ALL']
|
|
404
289
|
unfixable = []
|
|
405
290
|
|
|
406
291
|
# Allow unused variables when underscore-prefixed.
|
|
407
|
-
dummy-variable-rgx =
|
|
292
|
+
dummy-variable-rgx = '^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$'
|
|
293
|
+
|
|
294
|
+
[tool.ruff.lint.flake8-annotations]
|
|
295
|
+
allow-star-arg-any = true # TODO
|
|
296
|
+
|
|
297
|
+
[tool.ruff.lint.flake8-quotes]
|
|
298
|
+
inline-quotes = 'single'
|
|
299
|
+
|
|
300
|
+
[tool.ruff.lint.mccabe]
|
|
301
|
+
# Flag errors (`C901`) whenever the complexity level exceeds below.
|
|
302
|
+
max-complexity = 30
|
|
303
|
+
|
|
304
|
+
[tool.ruff.lint.per-file-ignores]
|
|
305
|
+
'tests/*' = [
|
|
306
|
+
'S101', # Use of `assert` detected
|
|
307
|
+
]
|
|
308
|
+
|
|
309
|
+
[tool.ruff.lint.pydoclint]
|
|
310
|
+
# Skip docstrings which fit on a single line.
|
|
311
|
+
ignore-one-line-docstrings = true
|
|
312
|
+
|
|
313
|
+
[tool.ruff.lint.pydocstyle]
|
|
314
|
+
convention = 'google'
|
|
408
315
|
|
|
409
316
|
[tool.ruff.format]
|
|
410
317
|
# Enable the formatter, which is a drop-in replacement for Black.
|
|
@@ -414,16 +321,16 @@ dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
|
|
|
414
321
|
exclude = []
|
|
415
322
|
|
|
416
323
|
# Use single quotes for strings.
|
|
417
|
-
quote-style =
|
|
324
|
+
quote-style = 'single'
|
|
418
325
|
|
|
419
326
|
# Like Black, indent with spaces, rather than tabs.
|
|
420
|
-
indent-style =
|
|
327
|
+
indent-style = 'space'
|
|
421
328
|
|
|
422
329
|
# Like Black, respect magic trailing commas.
|
|
423
330
|
skip-magic-trailing-comma = false
|
|
424
331
|
|
|
425
332
|
# Like Black, automatically detect the appropriate line ending.
|
|
426
|
-
line-ending =
|
|
333
|
+
line-ending = 'auto'
|
|
427
334
|
|
|
428
335
|
# Enable auto-formatting of code examples in docstrings. Markdown,
|
|
429
336
|
# reStructuredText code/literal blocks and doctests are all supported.
|
|
@@ -437,10 +344,13 @@ docstring-code-format = true
|
|
|
437
344
|
#
|
|
438
345
|
# This only has an effect when the `docstring-code-format` setting is
|
|
439
346
|
# enabled.
|
|
440
|
-
docstring-code-line-length =
|
|
347
|
+
docstring-code-line-length = 'dynamic'
|
|
441
348
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
]
|
|
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']
|
|
@@ -3,7 +3,7 @@ it summarizes (including with Gen AI) what changed ('diff') and displays it and/
|
|
|
3
3
|
supported services. Can check the output of local commands as well.
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
-
# The code below is subject to the license contained in the LICENSE file, which is part of the source code.
|
|
6
|
+
# The code below is subject to the license contained in the LICENSE.md file, which is part of the source code.
|
|
7
7
|
|
|
8
8
|
# The docstring above (__doc__) and the variables below are used in the program and for builds, including in building
|
|
9
9
|
# documentation with Sphinx.
|
|
@@ -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
|
)
|
|
@@ -40,7 +40,7 @@ def init_data() -> dict[str, str | tuple]:
|
|
|
40
40
|
|
|
41
41
|
:returns: dict of globals()
|
|
42
42
|
"""
|
|
43
|
-
return
|
|
43
|
+
return dict(globals().items())
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
if __name__ == '__main__':
|
|
@@ -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:
|