webchanges 3.36.1__tar.gz → 3.38.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.
Files changed (68) hide show
  1. {webchanges-3.36.1/webchanges.egg-info → webchanges-3.38.0}/PKG-INFO +45 -35
  2. {webchanges-3.36.1 → webchanges-3.38.0}/README.rst +34 -27
  3. {webchanges-3.36.1 → webchanges-3.38.0}/pyproject.toml +22 -6
  4. {webchanges-3.36.1 → webchanges-3.38.0}/requirements.txt +0 -1
  5. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/__init__.py +2 -2
  6. webchanges-3.38.0/webchanges/__main__.py +11 -0
  7. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/_resources/config.schema.json +240 -59
  8. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/_resources/jobs.schema.json +368 -81
  9. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/_vendored/headers.py +4 -4
  10. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/_vendored/packaging_version.py +41 -21
  11. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/_vendored/typeguard.py +70 -54
  12. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/cli.py +245 -112
  13. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/command.py +216 -66
  14. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/config.py +11 -0
  15. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/differs.py +453 -209
  16. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/filters/__init__.py +2 -0
  17. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/filters/_base.py +31 -14
  18. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/filters/_document.py +121 -51
  19. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/filters/_encoding.py +2 -0
  20. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/filters/_html.py +86 -29
  21. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/filters/_shell.py +2 -0
  22. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/filters/_text.py +66 -18
  23. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/handler.py +72 -36
  24. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/jobs/__init__.py +2 -0
  25. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/jobs/_base.py +197 -71
  26. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/jobs/_browser.py +301 -127
  27. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/jobs/_exceptions.py +14 -1
  28. webchanges-3.38.0/webchanges/jobs/_shell.py +260 -0
  29. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/jobs/_url.py +271 -106
  30. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/mailer.py +69 -13
  31. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/main.py +15 -0
  32. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/reporters/__init__.py +10 -4
  33. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/reporters/_base.py +215 -73
  34. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/reporters/_browser.py +2 -0
  35. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/reporters/_chat.py +97 -72
  36. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/reporters/_stdout.py +41 -17
  37. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/reporters/_system.py +2 -0
  38. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/reporters/_web.py +13 -10
  39. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/storage/_base.py +62 -14
  40. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/storage/_config.py +82 -45
  41. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/storage/_minidb.py +3 -1
  42. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/storage/_redis.py +10 -7
  43. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/storage/_sqlite3.py +10 -5
  44. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/storage/_ssdb.py +12 -5
  45. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/storage/_yaml.py +169 -57
  46. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/util.py +187 -82
  47. webchanges-3.38.0/webchanges/worker.py +303 -0
  48. {webchanges-3.36.1 → webchanges-3.38.0/webchanges.egg-info}/PKG-INFO +45 -35
  49. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges.egg-info/SOURCES.txt +0 -1
  50. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges.egg-info/requires.txt +16 -6
  51. webchanges-3.36.1/webchanges/__main__.py +0 -10
  52. webchanges-3.36.1/webchanges/jobs/_shell.py +0 -91
  53. webchanges-3.36.1/webchanges/reporters/_filter.py +0 -59
  54. webchanges-3.36.1/webchanges/worker.py +0 -245
  55. {webchanges-3.36.1 → webchanges-3.38.0}/LICENSE.md +0 -0
  56. {webchanges-3.36.1 → webchanges-3.38.0}/MANIFEST.in +0 -0
  57. {webchanges-3.36.1 → webchanges-3.38.0}/setup.cfg +0 -0
  58. {webchanges-3.36.1 → webchanges-3.38.0}/setup.py +0 -0
  59. {webchanges-3.36.1 → webchanges-3.38.0}/tools/get_manpages_parser.py +0 -0
  60. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/_resources/__init__.py +0 -0
  61. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/_vendored/__init__.py +0 -0
  62. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/py.typed +0 -0
  63. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/reporters/_email.py +0 -0
  64. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/storage/__init__.py +0 -0
  65. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges/storage_minidb.py +0 -0
  66. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges.egg-info/dependency_links.txt +0 -0
  67. {webchanges-3.36.1 → webchanges-3.38.0}/webchanges.egg-info/entry_points.txt +0 -0
  68. {webchanges-3.36.1 → webchanges-3.38.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.36.1
3
+ Version: 3.38.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>
@@ -21,10 +21,10 @@ Classifier: Operating System :: OS Independent
21
21
  Classifier: Programming Language :: Python
22
22
  Classifier: Programming Language :: Python :: 3
23
23
  Classifier: Programming Language :: Python :: 3 :: Only
24
- Classifier: Programming Language :: Python :: 3.11
25
24
  Classifier: Programming Language :: Python :: 3.12
26
25
  Classifier: Programming Language :: Python :: 3.13
27
26
  Classifier: Programming Language :: Python :: 3.14
27
+ Classifier: Programming Language :: Python :: 3.15
28
28
  Classifier: Programming Language :: Python :: Free Threading
29
29
  Classifier: Programming Language :: Python :: Free Threading :: 4 - Resilient
30
30
  Classifier: Programming Language :: Python :: Implementation :: CPython
@@ -34,10 +34,9 @@ Classifier: Topic :: Internet :: WWW/HTTP :: Indexing/Search
34
34
  Classifier: Topic :: System :: Monitoring
35
35
  Classifier: Topic :: Utilities
36
36
  Classifier: Typing :: Typed
37
- Requires-Python: >=3.11
37
+ Requires-Python: >=3.12
38
38
  Description-Content-Type: text/x-rst
39
39
  License-File: LICENSE.md
40
- Requires-Dist: colorama; sys_platform == "win32"
41
40
  Requires-Dist: cssselect
42
41
  Requires-Dist: h2
43
42
  Requires-Dist: html2text
@@ -64,7 +63,7 @@ Requires-Dist: html5lib; extra == "html5lib"
64
63
  Provides-Extra: ical2text
65
64
  Requires-Dist: vobject; extra == "ical2text"
66
65
  Provides-Extra: jq
67
- Requires-Dist: jq; os_name != "nt" and extra == "jq"
66
+ Requires-Dist: jq; extra == "jq"
68
67
  Provides-Extra: ocr
69
68
  Requires-Dist: pytesseract; extra == "ocr"
70
69
  Requires-Dist: Pillow; extra == "ocr"
@@ -75,10 +74,14 @@ Requires-Dist: pypdf; extra == "pypdf"
75
74
  Provides-Extra: pypdf-crypto
76
75
  Requires-Dist: pypdf; extra == "pypdf-crypto"
77
76
  Requires-Dist: cryptography; extra == "pypdf-crypto"
77
+ Provides-Extra: xmltodict
78
+ Requires-Dist: xmltodict; extra == "xmltodict"
78
79
  Provides-Extra: deepdiff
79
- Requires-Dist: deepdiff; extra == "deepdiff"
80
+ Requires-Dist: deepdiff>=8.0; python_version < "3.15" and extra == "deepdiff"
81
+ Requires-Dist: deepdiff<9,>=8.0; python_version >= "3.15" and extra == "deepdiff"
80
82
  Provides-Extra: deepdiff-xml
81
- Requires-Dist: deepdiff; extra == "deepdiff-xml"
83
+ Requires-Dist: deepdiff>=8.0; python_version < "3.15" and extra == "deepdiff-xml"
84
+ Requires-Dist: deepdiff<9,>=8.0; python_version >= "3.15" and extra == "deepdiff-xml"
82
85
  Requires-Dist: xmltodict; extra == "deepdiff-xml"
83
86
  Provides-Extra: imagediff
84
87
  Requires-Dist: Pillow; extra == "imagediff"
@@ -99,7 +102,7 @@ Requires-Dist: requests; extra == "requests"
99
102
  Provides-Extra: safe-password
100
103
  Requires-Dist: keyring; extra == "safe-password"
101
104
  Provides-Extra: all
102
- Requires-Dist: webchanges[beautify,bs4,curl_cffi,deepdiff_xml,html5lib,ical2text,imagediff,jq,matrix,ocr,pdf2text,pushbullet,pushover,pypdf_crypto,redis,requests,safe_password,use_browser,xmpp]; extra == "all"
105
+ Requires-Dist: webchanges[beautify,bs4,curl_cffi,deepdiff_xml,html5lib,ical2text,imagediff,jq,matrix,ocr,pdf2text,pushbullet,pushover,pypdf_crypto,redis,requests,safe_password,use_browser,xmltodict,xmpp]; extra == "all"
103
106
  Dynamic: license-file
104
107
 
105
108
  .. role:: underline
@@ -118,26 +121,35 @@ notifications and AI-powered summaries to your favorite `platform
118
121
  <https://webchanges.readthedocs.io/en/stable/introduction.html#reporters>`__.
119
122
 
120
123
 
121
- Requirements
122
- ============
123
- **webchanges** requires |support|.
124
+ Highlights
125
+ ==========
126
+ - **AI-powered change summaries** via Gemini (`ai_google differ
127
+ <https://webchanges.readthedocs.io/en/stable/differs.html#ai-google-diff>`__, BETA).
128
+ - **Structural diffs for JSON and XML** via the `deepdiff differ
129
+ <https://webchanges.readthedocs.io/en/stable/differs.html#deepdiff-diff>`__.
130
+ - **Visual diffs for images** via the `image differ
131
+ <https://webchanges.readthedocs.io/en/stable/differs.html#image-diff>`__ (BETA).
132
+ - **Bypass TLS/JA3 fingerprinting** with the optional `curl_cffi
133
+ <https://webchanges.readthedocs.io/en/stable/jobs.html#http-client>`__ HTTP client.
134
+ - **JSON-Schema-validated** ``jobs.yaml`` and ``config.yaml`` for editor autocompletion and inline validation.
124
135
 
125
- For the best experience, use the current version of `Python <https://www.python.org/downloads/>`__. We also support
126
- 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
127
- bug and security fix release from that older version.
128
136
 
129
- While **webchanges** supports free-threated Python, certain optional dependencies may not.
137
+ Requirements
138
+ ============
139
+ **webchanges** requires |support|. For the best experience, use the current version of `Python
140
+ <https://www.python.org/downloads/>`__; older Python versions are supported for 3 years after they're replaced. Free-threaded Python is supported, though some
141
+ optional dependencies may not be.
130
142
 
131
143
  For Generative AI summaries (BETA), you need a free `API Key from Google Cloud AI Studio
132
144
  <https://aistudio.google.com/app/apikey>`__ (see `here
133
- <https://webchanges.readthedocs.io/en/stable/differs.html#ai-google>`__).
145
+ <https://webchanges.readthedocs.io/en/stable/differs.html#ai-google-diff>`__).
134
146
 
135
147
 
136
148
  Installation
137
149
  ============
138
150
  |pypi_version| |format| |status|
139
151
 
140
- Install **webchanges** with ``uv`` (recommended):
152
+ Install **webchanges** with `uv <https://docs.astral.sh/uv/>`__ (recommended):
141
153
 
142
154
  .. code-block:: bash
143
155
 
@@ -149,22 +161,22 @@ or with ``pip``:
149
161
 
150
162
  pip install webchanges
151
163
 
152
- Running in Docker
153
- -----------------
154
- **webchanges** can easily run in a `Docker <https://www.docker.com/>`__ container! You will find a minimal
155
- implementation (no browser) `here <https://github.com/yubiuser/webchanges-docker>`__, and one with a browser
156
- `here <https://github.com/jhedlund/webchanges-docker>`__.
164
+ On Windows with Python 3.15, first run ``set PYYAML_FORCE_LIBYAML=0`` (in PowerShell:
165
+ ``$env:PYYAML_FORCE_LIBYAML = "0"``), as explained `here
166
+ <https://webchanges.readthedocs.io/en/stable/introduction.html#install-windows>`__.
157
167
 
158
- As a GitHub Action
159
- ------------------
160
- **webchanges** can easily run as a `GitHub Action <https://www.docker.com/>`__! You will find an implementation
161
- `here <https://github.com/swimmwatch/webchanges-action>`__.
168
+ Other ways to run
169
+ -----------------
170
+ - In a `Docker <https://www.docker.com/>`__ container: a minimal implementation (no browser) is `here
171
+ <https://github.com/yubiuser/webchanges-docker>`__, and one with a browser is `here
172
+ <https://github.com/jhedlund/webchanges-docker>`__.
173
+ - As a `GitHub Action <https://docs.github.com/en/actions>`__: an implementation is `here
174
+ <https://github.com/swimmwatch/webchanges-action>`__.
162
175
 
163
176
 
164
177
  Documentation |readthedocs|
165
178
  ===========================
166
- The documentation is hosted on `Read the Docs <https://webchanges.readthedocs.io/>`__. A (very good) AI-generated
167
- high-level architectural overview is available on `DeepWiki <https://deepwiki.com/mborsetti/webchanges>`__.
179
+ The documentation is hosted on `Read the Docs <https://webchanges.readthedocs.io/>`__.
168
180
 
169
181
 
170
182
  Quick Start
@@ -238,13 +250,11 @@ licensed under a `BSD 3-Clause License
238
250
  <https://raw.githubusercontent.com/thp/urlwatch/346b25914b0418342ffe2fb0529bed702fddc01f/COPYING>`__).
239
251
 
240
252
 
241
- Compatibility with **urlwatch**
242
- ===============================
243
-
244
- This project is based on code from `urlwatch 2.21
245
- <https://github.com/thp/urlwatch/tree/346b25914b0418342ffe2fb0529bed702fddc01f>`__ dated 30 July 2020.
246
- For upgrading from **urlwatch** to **webchanges** (using the same job and
247
- configuration files), see `here <https://webchanges.readthedocs.io/en/stable/upgrading.html>`__.
253
+ Relationship with **urlwatch**
254
+ ==============================
255
+ This project is a fork of `urlwatch 2.21
256
+ <https://github.com/thp/urlwatch/tree/346b25914b0418342ffe2fb0529bed702fddc01f>`__ and has since added many features;
257
+ see the `comparison <https://webchanges.readthedocs.io/en/stable/upgrading.html>`__.
248
258
 
249
259
 
250
260
  .. |support| image:: https://img.shields.io/pypi/pyversions/webchanges.svg
@@ -14,26 +14,35 @@ notifications and AI-powered summaries to your favorite `platform
14
14
  <https://webchanges.readthedocs.io/en/stable/introduction.html#reporters>`__.
15
15
 
16
16
 
17
- Requirements
18
- ============
19
- **webchanges** requires |support|.
17
+ Highlights
18
+ ==========
19
+ - **AI-powered change summaries** via Gemini (`ai_google differ
20
+ <https://webchanges.readthedocs.io/en/stable/differs.html#ai-google-diff>`__, BETA).
21
+ - **Structural diffs for JSON and XML** via the `deepdiff differ
22
+ <https://webchanges.readthedocs.io/en/stable/differs.html#deepdiff-diff>`__.
23
+ - **Visual diffs for images** via the `image differ
24
+ <https://webchanges.readthedocs.io/en/stable/differs.html#image-diff>`__ (BETA).
25
+ - **Bypass TLS/JA3 fingerprinting** with the optional `curl_cffi
26
+ <https://webchanges.readthedocs.io/en/stable/jobs.html#http-client>`__ HTTP client.
27
+ - **JSON-Schema-validated** ``jobs.yaml`` and ``config.yaml`` for editor autocompletion and inline validation.
20
28
 
21
- For the best experience, use the current version of `Python <https://www.python.org/downloads/>`__. We also support
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
- bug and security fix release from that older version.
24
29
 
25
- While **webchanges** supports free-threated Python, certain optional dependencies may not.
30
+ Requirements
31
+ ============
32
+ **webchanges** requires |support|. For the best experience, use the current version of `Python
33
+ <https://www.python.org/downloads/>`__; older Python versions are supported for 3 years after they're replaced. Free-threaded Python is supported, though some
34
+ optional dependencies may not be.
26
35
 
27
36
  For Generative AI summaries (BETA), you need a free `API Key from Google Cloud AI Studio
28
37
  <https://aistudio.google.com/app/apikey>`__ (see `here
29
- <https://webchanges.readthedocs.io/en/stable/differs.html#ai-google>`__).
38
+ <https://webchanges.readthedocs.io/en/stable/differs.html#ai-google-diff>`__).
30
39
 
31
40
 
32
41
  Installation
33
42
  ============
34
43
  |pypi_version| |format| |status|
35
44
 
36
- Install **webchanges** with ``uv`` (recommended):
45
+ Install **webchanges** with `uv <https://docs.astral.sh/uv/>`__ (recommended):
37
46
 
38
47
  .. code-block:: bash
39
48
 
@@ -45,22 +54,22 @@ or with ``pip``:
45
54
 
46
55
  pip install webchanges
47
56
 
48
- Running in Docker
49
- -----------------
50
- **webchanges** can easily run in a `Docker <https://www.docker.com/>`__ container! You will find a minimal
51
- implementation (no browser) `here <https://github.com/yubiuser/webchanges-docker>`__, and one with a browser
52
- `here <https://github.com/jhedlund/webchanges-docker>`__.
57
+ On Windows with Python 3.15, first run ``set PYYAML_FORCE_LIBYAML=0`` (in PowerShell:
58
+ ``$env:PYYAML_FORCE_LIBYAML = "0"``), as explained `here
59
+ <https://webchanges.readthedocs.io/en/stable/introduction.html#install-windows>`__.
53
60
 
54
- As a GitHub Action
55
- ------------------
56
- **webchanges** can easily run as a `GitHub Action <https://www.docker.com/>`__! You will find an implementation
57
- `here <https://github.com/swimmwatch/webchanges-action>`__.
61
+ Other ways to run
62
+ -----------------
63
+ - In a `Docker <https://www.docker.com/>`__ container: a minimal implementation (no browser) is `here
64
+ <https://github.com/yubiuser/webchanges-docker>`__, and one with a browser is `here
65
+ <https://github.com/jhedlund/webchanges-docker>`__.
66
+ - As a `GitHub Action <https://docs.github.com/en/actions>`__: an implementation is `here
67
+ <https://github.com/swimmwatch/webchanges-action>`__.
58
68
 
59
69
 
60
70
  Documentation |readthedocs|
61
71
  ===========================
62
- The documentation is hosted on `Read the Docs <https://webchanges.readthedocs.io/>`__. A (very good) AI-generated
63
- high-level architectural overview is available on `DeepWiki <https://deepwiki.com/mborsetti/webchanges>`__.
72
+ The documentation is hosted on `Read the Docs <https://webchanges.readthedocs.io/>`__.
64
73
 
65
74
 
66
75
  Quick Start
@@ -134,13 +143,11 @@ licensed under a `BSD 3-Clause License
134
143
  <https://raw.githubusercontent.com/thp/urlwatch/346b25914b0418342ffe2fb0529bed702fddc01f/COPYING>`__).
135
144
 
136
145
 
137
- Compatibility with **urlwatch**
138
- ===============================
139
-
140
- This project is based on code from `urlwatch 2.21
141
- <https://github.com/thp/urlwatch/tree/346b25914b0418342ffe2fb0529bed702fddc01f>`__ dated 30 July 2020.
142
- For upgrading from **urlwatch** to **webchanges** (using the same job and
143
- configuration files), see `here <https://webchanges.readthedocs.io/en/stable/upgrading.html>`__.
146
+ Relationship with **urlwatch**
147
+ ==============================
148
+ This project is a fork of `urlwatch 2.21
149
+ <https://github.com/thp/urlwatch/tree/346b25914b0418342ffe2fb0529bed702fddc01f>`__ and has since added many features;
150
+ see the `comparison <https://webchanges.readthedocs.io/en/stable/upgrading.html>`__.
144
151
 
145
152
 
146
153
  .. |support| image:: https://img.shields.io/pypi/pyversions/webchanges.svg
@@ -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.11'
19
+ requires-python = '>=3.12'
20
20
  license = "MIT AND BSD-3-Clause"
21
21
  license-files = ['LICENSE.md']
22
22
  authors = [{ name = 'Mike Borsetti', email = 'mike+webchanges@borsetti.com' }]
@@ -35,10 +35,10 @@ classifiers = [
35
35
  'Programming Language :: Python',
36
36
  'Programming Language :: Python :: 3',
37
37
  'Programming Language :: Python :: 3 :: Only',
38
- 'Programming Language :: Python :: 3.11',
39
38
  'Programming Language :: Python :: 3.12',
40
39
  'Programming Language :: Python :: 3.13',
41
40
  'Programming Language :: Python :: 3.14',
41
+ 'Programming Language :: Python :: 3.15',
42
42
  'Programming Language :: Python :: Free Threading',
43
43
  'Programming Language :: Python :: Free Threading :: 4 - Resilient',
44
44
  'Programming Language :: Python :: Implementation :: CPython',
@@ -70,14 +70,22 @@ beautify = ['beautifulsoup4', 'jsbeautifier', 'cssbeautifier']
70
70
  bs4 = ['beautifulsoup4']
71
71
  html5lib = ['html5lib']
72
72
  ical2text = ['vobject']
73
- jq = ['jq; os_name != "nt"']
73
+ jq = ['jq']
74
74
  ocr = ['pytesseract', 'Pillow']
75
75
  pdf2text = ['pdftotext']
76
76
  pypdf = ['pypdf']
77
77
  pypdf_crypto = ['pypdf', 'cryptography']
78
+ xmltodict = ['xmltodict'] # xmltojson and xmltoyaml filters
78
79
  # differs
79
- deepdiff = ['deepdiff']
80
- deepdiff_xml = ['deepdiff', 'xmltodict']
80
+ # deepdiff >= 8.0 is required for threshold_to_diff_deeper
81
+ # deepdiff < 9 on Python >= 3.15: deepdiff 9 requires cachebox < 6, and cachebox 5.x has no 3.15 wheels and cannot be
82
+ # built for 3.15 (it uses PyO3 0.27, which supports Python only up to 3.14). Keep in sync with tests/requirements_*.txt
83
+ deepdiff = ['deepdiff >= 8.0; python_version < "3.15"', 'deepdiff >= 8.0, < 9; python_version >= "3.15"']
84
+ deepdiff_xml = [
85
+ 'deepdiff >= 8.0; python_version < "3.15"',
86
+ 'deepdiff >= 8.0, < 9; python_version >= "3.15"',
87
+ 'xmltodict',
88
+ ]
81
89
  imagediff = ['Pillow']
82
90
  # reporters
83
91
  matrix = ['matrix_client']
@@ -91,7 +99,7 @@ requests = ['requests']
91
99
  safe_password = ['keyring']
92
100
  # all
93
101
  all = [
94
- 'webchanges[use_browser,beautify,bs4,html5lib,ical2text,jq,ocr,pdf2text,pypdf_crypto,deepdiff_xml,imagediff,matrix,pushbullet,pushover,xmpp,curl_cffi,redis,requests,safe_password]',
102
+ 'webchanges[use_browser,beautify,bs4,html5lib,ical2text,jq,ocr,pdf2text,pypdf_crypto,xmltodict,deepdiff_xml,imagediff,matrix,pushbullet,pushover,xmpp,curl_cffi,redis,requests,safe_password]',
95
103
  ]
96
104
 
97
105
 
@@ -210,6 +218,14 @@ report_level = 'WARNING'
210
218
  # log_cli = true
211
219
  minversion = '9.0.2'
212
220
  testpaths = ['tests']
221
+ filterwarnings = [
222
+ # Fail tests that leak sqlite3 connections. Scoped by message so third-party ResourceWarnings (e.g.
223
+ # asyncio/playwright transports) don't destabilize the suite. The second entry is required because the warning
224
+ # is emitted during garbage collection: the error raised there is unraisable, and only surfaces as a test
225
+ # failure through pytest's unraisable-exception plugin (as a PytestUnraisableExceptionWarning).
226
+ 'error:unclosed database:ResourceWarning',
227
+ 'error:(?s).*unclosed database:pytest.PytestUnraisableExceptionWarning',
228
+ ]
213
229
 
214
230
  # pytest-playwright
215
231
  # addopts = ['--browser', 'chromium', '--browser-channel', 'chrome']
@@ -1,4 +1,3 @@
1
- colorama; sys_platform == 'win32'
2
1
  cssselect
3
2
  h2
4
3
  html2text
@@ -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, 11) # minimum version of Python required to run; 3.11 supported until fall 2026
15
+ __min_python_version__ = (3, 12) # minimum version of Python required to run; 3.12 supported until 7 October 2027
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.36.1'
25
+ __version__ = '3.38.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
  )
@@ -0,0 +1,11 @@
1
+ if __name__ == '__main__':
2
+ import sys
3
+ from pathlib import Path
4
+
5
+ cwd = str(Path.cwd())
6
+ if cwd not in sys.path:
7
+ sys.path.insert(0, cwd)
8
+
9
+ from webchanges.cli import main
10
+
11
+ main()