arxiv 2.3.2.dev15__tar.gz → 2.4.1__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 (27) hide show
  1. {arxiv-2.3.2.dev15 → arxiv-2.4.1}/.github/workflows/static-analysis.yaml +3 -15
  2. {arxiv-2.3.2.dev15 → arxiv-2.4.1}/Makefile +1 -14
  3. {arxiv-2.3.2.dev15 → arxiv-2.4.1}/PKG-INFO +8 -48
  4. {arxiv-2.3.2.dev15 → arxiv-2.4.1}/README.md +7 -47
  5. {arxiv-2.3.2.dev15 → arxiv-2.4.1}/arxiv/__init__.py +25 -8
  6. {arxiv-2.3.2.dev15 → arxiv-2.4.1}/release.sh +1 -2
  7. arxiv-2.4.1/tests/test_errors.py +46 -0
  8. {arxiv-2.3.2.dev15 → arxiv-2.4.1}/uv.lock +10 -10
  9. {arxiv-2.3.2.dev15 → arxiv-2.4.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  10. {arxiv-2.3.2.dev15 → arxiv-2.4.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  11. {arxiv-2.3.2.dev15 → arxiv-2.4.1}/.github/ISSUE_TEMPLATE/question.md +0 -0
  12. {arxiv-2.3.2.dev15 → arxiv-2.4.1}/.github/pull_request_template.md +0 -0
  13. {arxiv-2.3.2.dev15 → arxiv-2.4.1}/.github/workflows/docs.yml +0 -0
  14. /arxiv-2.3.2.dev15/.github/workflows/python-package.yml → /arxiv-2.4.1/.github/workflows/python-test.yml +0 -0
  15. {arxiv-2.3.2.dev15 → arxiv-2.4.1}/.gitignore +0 -0
  16. {arxiv-2.3.2.dev15 → arxiv-2.4.1}/.python-version +0 -0
  17. {arxiv-2.3.2.dev15 → arxiv-2.4.1}/LICENSE.txt +0 -0
  18. {arxiv-2.3.2.dev15 → arxiv-2.4.1}/arxiv/arxiv.py +0 -0
  19. {arxiv-2.3.2.dev15 → arxiv-2.4.1}/pyproject.toml +0 -0
  20. {arxiv-2.3.2.dev15 → arxiv-2.4.1}/requirements.txt +0 -0
  21. {arxiv-2.3.2.dev15 → arxiv-2.4.1}/tests/.gitignore +0 -0
  22. {arxiv-2.3.2.dev15 → arxiv-2.4.1}/tests/__init__.py +0 -0
  23. {arxiv-2.3.2.dev15 → arxiv-2.4.1}/tests/test_api_bugs.py +0 -0
  24. {arxiv-2.3.2.dev15 → arxiv-2.4.1}/tests/test_client.py +0 -0
  25. {arxiv-2.3.2.dev15 → arxiv-2.4.1}/tests/test_download.py +0 -0
  26. {arxiv-2.3.2.dev15 → arxiv-2.4.1}/tests/test_package.py +0 -0
  27. {arxiv-2.3.2.dev15 → arxiv-2.4.1}/tests/test_result.py +0 -0
@@ -7,7 +7,7 @@ on:
7
7
  workflow_dispatch:
8
8
 
9
9
  jobs:
10
- quality-checks:
10
+ static-analysis:
11
11
  runs-on: ubuntu-latest
12
12
  steps:
13
13
  - uses: actions/checkout@v4
@@ -22,19 +22,7 @@ jobs:
22
22
  run: uv run make lint
23
23
  - name: Format check
24
24
  run: uv run ruff format --check .
25
- - name: Type check (allow failures for now)
26
- run: uv run make type-check || echo "Type checking has known issues - skipping for CI"
27
-
28
- security-audit:
29
- runs-on: ubuntu-latest
30
- steps:
31
- - uses: actions/checkout@v4
32
- - name: Install UV
33
- uses: astral-sh/setup-uv@v4
34
- with:
35
- enable-cache: true
36
- cache-dependency-glob: "uv.lock"
37
- - name: Install dependencies
38
- run: uv sync --group dev
25
+ - name: Type check
26
+ run: uv run make type-check
39
27
  - name: Security audit
40
28
  run: uv run make audit
@@ -1,8 +1,7 @@
1
1
  source := ${wildcard ./arxiv/*.py}
2
2
  tests := ${wildcard tests/*.py}
3
3
 
4
- # UV-based development workflow (assumes UV is installed)
5
- .PHONY: all install install-dev lint format test audit docs clean sync lock help
4
+ .PHONY: all install install-dev lint format test audit docs clean
6
5
 
7
6
  # Default target
8
7
  all: lint test docs
@@ -14,12 +13,6 @@ install:
14
13
  install-dev:
15
14
  uv sync --group dev
16
15
 
17
- sync:
18
- uv sync --group dev
19
-
20
- lock:
21
- uv lock
22
-
23
16
  # Development tasks
24
17
  format: $(source) $(tests)
25
18
  uv run ruff format .
@@ -50,9 +43,3 @@ clean:
50
43
  # Convenience commands
51
44
  check: lint type-check test
52
45
 
53
- # Release and distribution
54
- build:
55
- uv build
56
-
57
- release:
58
- ./release.sh
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: arxiv
3
- Version: 2.3.2.dev15
3
+ Version: 2.4.1
4
4
  Summary: Python wrapper for the arXiv API
5
5
  Project-URL: Homepage, https://github.com/lukasschwab/arxiv.py
6
6
  Project-URL: Repository, https://github.com/lukasschwab/arxiv.py
@@ -37,7 +37,7 @@ Requires-Dist: pytest>=6.2.2; extra == 'test'
37
37
  Description-Content-Type: text/markdown
38
38
 
39
39
  # arxiv.py
40
- [![PyPI](https://img.shields.io/pypi/v/arxiv)](https://pypi.org/project/arxiv/) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/arxiv) [![GitHub Workflow Status (branch)](https://img.shields.io/github/actions/workflow/status/lukasschwab/arxiv.py/python-package.yml?branch=master)](https://github.com/lukasschwab/arxiv.py/actions?query=branch%3Amaster) [![Full package documentation](https://img.shields.io/badge/docs-hosted-brightgreen)](https://lukasschwab.me/arxiv.py/index.html)
40
+ [![PyPI](https://img.shields.io/pypi/v/arxiv)](https://pypi.org/project/arxiv/) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/arxiv) [![GitHub Workflow Status (branch)](https://img.shields.io/github/actions/workflow/status/lukasschwab/arxiv.py/python-test.yml?branch=master)](https://github.com/lukasschwab/arxiv.py/actions?query=branch%3Amaster) [![Full package documentation](https://img.shields.io/badge/docs-hosted-brightgreen)](https://lukasschwab.me/arxiv.py/index.html)
41
41
 
42
42
  Python wrapper for [the arXiv API](https://arxiv.org/help/api/index).
43
43
 
@@ -45,28 +45,13 @@ Python wrapper for [the arXiv API](https://arxiv.org/help/api/index).
45
45
 
46
46
  ## Usage
47
47
 
48
- ### Installation
49
-
50
- #### For End Users (Recommended)
48
+ Install the package:
51
49
 
52
50
  ```bash
53
- $ pip install arxiv
51
+ $ pip install arxiv # Or `uv add arxiv` or similar.
54
52
  ```
55
53
 
56
- #### For Modern Python Development (with UV)
57
-
58
- ```bash
59
- $ uv add arxiv
60
- ```
61
-
62
- Or for a one-off script:
63
- ```bash
64
- $ uvx --from arxiv python -c "import arxiv; print('Working!')"
65
- ```
66
-
67
- #### Usage
68
-
69
- In your Python script, include the line:
54
+ In your Python code, include the line:
70
55
 
71
56
  ```python
72
57
  import arxiv
@@ -74,6 +59,9 @@ import arxiv
74
59
 
75
60
  ### Examples
76
61
 
62
+ > [!TIP]
63
+ > [`arxivql`](https://pypi.org/project/arxivql/) may simplify constructing complex query strings.
64
+
77
65
  #### Fetching results
78
66
 
79
67
  ```python
@@ -179,31 +167,3 @@ This project uses [UV](https://astral.sh/uv) for development, while maintaining
179
167
  cd arxiv.py
180
168
  make dev-setup
181
169
  ```
182
-
183
- 3. **Available commands**:
184
- ```bash
185
- make test # Run tests
186
- make lint # Run linting
187
- make format # Format code
188
- make docs # Generate docs
189
- make check # Run lint + test
190
- make audit # Security audit
191
- ```
192
-
193
- ### For End Users
194
-
195
- Even though development uses UV, **end users can continue using pip** as always:
196
-
197
- ```bash
198
- pip install arxiv # Still works perfectly!
199
- ```
200
-
201
- Both installation methods provide the same functionality - UV just offers a faster development experience.
202
-
203
- ### Modern Python Packaging
204
-
205
- This project uses current Python packaging standards:
206
- - **`pyproject.toml`** for all configuration (no setup.py)
207
- - **`uv.lock`** for reproducible development environments
208
- - **Hatchling** build backend for fast, reliable builds
209
- - **UV** for lightning-fast dependency management
@@ -1,5 +1,5 @@
1
1
  # arxiv.py
2
- [![PyPI](https://img.shields.io/pypi/v/arxiv)](https://pypi.org/project/arxiv/) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/arxiv) [![GitHub Workflow Status (branch)](https://img.shields.io/github/actions/workflow/status/lukasschwab/arxiv.py/python-package.yml?branch=master)](https://github.com/lukasschwab/arxiv.py/actions?query=branch%3Amaster) [![Full package documentation](https://img.shields.io/badge/docs-hosted-brightgreen)](https://lukasschwab.me/arxiv.py/index.html)
2
+ [![PyPI](https://img.shields.io/pypi/v/arxiv)](https://pypi.org/project/arxiv/) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/arxiv) [![GitHub Workflow Status (branch)](https://img.shields.io/github/actions/workflow/status/lukasschwab/arxiv.py/python-test.yml?branch=master)](https://github.com/lukasschwab/arxiv.py/actions?query=branch%3Amaster) [![Full package documentation](https://img.shields.io/badge/docs-hosted-brightgreen)](https://lukasschwab.me/arxiv.py/index.html)
3
3
 
4
4
  Python wrapper for [the arXiv API](https://arxiv.org/help/api/index).
5
5
 
@@ -7,28 +7,13 @@ Python wrapper for [the arXiv API](https://arxiv.org/help/api/index).
7
7
 
8
8
  ## Usage
9
9
 
10
- ### Installation
11
-
12
- #### For End Users (Recommended)
10
+ Install the package:
13
11
 
14
12
  ```bash
15
- $ pip install arxiv
13
+ $ pip install arxiv # Or `uv add arxiv` or similar.
16
14
  ```
17
15
 
18
- #### For Modern Python Development (with UV)
19
-
20
- ```bash
21
- $ uv add arxiv
22
- ```
23
-
24
- Or for a one-off script:
25
- ```bash
26
- $ uvx --from arxiv python -c "import arxiv; print('Working!')"
27
- ```
28
-
29
- #### Usage
30
-
31
- In your Python script, include the line:
16
+ In your Python code, include the line:
32
17
 
33
18
  ```python
34
19
  import arxiv
@@ -36,6 +21,9 @@ import arxiv
36
21
 
37
22
  ### Examples
38
23
 
24
+ > [!TIP]
25
+ > [`arxivql`](https://pypi.org/project/arxivql/) may simplify constructing complex query strings.
26
+
39
27
  #### Fetching results
40
28
 
41
29
  ```python
@@ -141,31 +129,3 @@ This project uses [UV](https://astral.sh/uv) for development, while maintaining
141
129
  cd arxiv.py
142
130
  make dev-setup
143
131
  ```
144
-
145
- 3. **Available commands**:
146
- ```bash
147
- make test # Run tests
148
- make lint # Run linting
149
- make format # Format code
150
- make docs # Generate docs
151
- make check # Run lint + test
152
- make audit # Security audit
153
- ```
154
-
155
- ### For End Users
156
-
157
- Even though development uses UV, **end users can continue using pip** as always:
158
-
159
- ```bash
160
- pip install arxiv # Still works perfectly!
161
- ```
162
-
163
- Both installation methods provide the same functionality - UV just offers a faster development experience.
164
-
165
- ### Modern Python Packaging
166
-
167
- This project uses current Python packaging standards:
168
- - **`pyproject.toml`** for all configuration (no setup.py)
169
- - **`uv.lock`** for reproducible development environments
170
- - **Hatchling** build backend for fast, reliable builds
171
- - **UV** for lightning-fast dependency management
@@ -38,6 +38,7 @@ if TYPE_CHECKING:
38
38
  arxiv_doi: str
39
39
  arxiv_primary_category: dict[str, str]
40
40
 
41
+
41
42
  logger = logging.getLogger(__name__)
42
43
 
43
44
  _DEFAULT_TIME = datetime.min
@@ -237,6 +238,8 @@ class Result:
237
238
  if not filename:
238
239
  filename = self._get_default_filename()
239
240
  path = os.path.join(dirpath, filename)
241
+ if self.pdf_url is None:
242
+ raise ValueError("No PDF URL available for this result")
240
243
  pdf_url = Result._substitute_domain(self.pdf_url, download_domain)
241
244
  written_path, _ = urlretrieve(pdf_url, path)
242
245
  return written_path
@@ -259,14 +262,19 @@ class Result:
259
262
  if not filename:
260
263
  filename = self._get_default_filename("tar.gz")
261
264
  path = os.path.join(dirpath, filename)
262
- source_url = Result._substitute_domain(self.source_url(), download_domain)
265
+ source_url_str = self.source_url()
266
+ if source_url_str is None:
267
+ raise ValueError("No source URL available for this result")
268
+ source_url = Result._substitute_domain(source_url_str, download_domain)
263
269
  written_path, _ = urlretrieve(source_url, path)
264
270
  return written_path
265
271
 
266
- def source_url(self) -> str:
272
+ def source_url(self) -> str | None:
267
273
  """
268
274
  Derives a URL for the source tarfile for this result.
269
275
  """
276
+ if self.pdf_url is None:
277
+ return None
270
278
  return self.pdf_url.replace("/pdf/", "/src/")
271
279
 
272
280
  @staticmethod
@@ -337,7 +345,7 @@ class Result:
337
345
  def __repr__(self) -> str:
338
346
  return "{}({})".format(_classname(self), repr(self.name))
339
347
 
340
- def __eq__(self, other) -> bool:
348
+ def __eq__(self, other: object) -> bool:
341
349
  if isinstance(other, Result.Author):
342
350
  return self.name == other.name
343
351
  return False
@@ -353,14 +361,14 @@ class Result:
353
361
  """The link's title."""
354
362
  rel: str
355
363
  """The link's relationship to the `Result`."""
356
- content_type: str
364
+ content_type: str | None
357
365
  """The link's HTTP content type."""
358
366
 
359
367
  def __init__(
360
368
  self,
361
369
  href: str,
362
370
  title: str | None = None,
363
- rel: str | None = None,
371
+ rel: str = "",
364
372
  content_type: str | None = None,
365
373
  ):
366
374
  """
@@ -385,7 +393,7 @@ class Result:
385
393
  return Result.Link(
386
394
  href=feed_link.href,
387
395
  title=feed_link.get("title"),
388
- rel=feed_link.get("rel"),
396
+ rel=feed_link.get("rel") or "",
389
397
  content_type=feed_link.get("content_type"),
390
398
  )
391
399
 
@@ -401,7 +409,7 @@ class Result:
401
409
  repr(self.content_type),
402
410
  )
403
411
 
404
- def __eq__(self, other) -> bool:
412
+ def __eq__(self, other: object) -> bool:
405
413
  if isinstance(other, Result.Link):
406
414
  return self.href == other.href
407
415
  return False
@@ -417,7 +425,7 @@ class Result:
417
425
  message: str
418
426
  """Message describing what caused this error."""
419
427
 
420
- def __init__(self, missing_field):
428
+ def __init__(self, missing_field: str):
421
429
  self.missing_field = missing_field
422
430
  self.message = "Entry from arXiv missing required info"
423
431
 
@@ -758,6 +766,9 @@ class ArxivError(Exception):
758
766
  self.message = message
759
767
  super().__init__(self.message)
760
768
 
769
+ def __reduce__(self) -> tuple:
770
+ return (self.__class__, (self.url, self.retry, self.message))
771
+
761
772
  def __str__(self) -> str:
762
773
  return "{} ({})".format(self.message, self.url)
763
774
 
@@ -787,6 +798,9 @@ class UnexpectedEmptyPageError(ArxivError):
787
798
  self.raw_feed = raw_feed
788
799
  super().__init__(url, retry, "Page of results was unexpectedly empty")
789
800
 
801
+ def __reduce__(self) -> tuple:
802
+ return (self.__class__, (self.url, self.retry, self.raw_feed))
803
+
790
804
  def __repr__(self) -> str:
791
805
  return "{}({}, {}, {})".format(
792
806
  _classname(self), repr(self.url), repr(self.retry), repr(self.raw_feed)
@@ -816,6 +830,9 @@ class HTTPError(ArxivError):
816
830
  "Page request resulted in HTTP {}".format(self.status),
817
831
  )
818
832
 
833
+ def __reduce__(self) -> tuple:
834
+ return (self.__class__, (self.url, self.retry, self.status))
835
+
819
836
  def __repr__(self) -> str:
820
837
  return "{}({}, {}, {})".format(
821
838
  _classname(self), repr(self.url), repr(self.retry), repr(self.status)
@@ -74,8 +74,7 @@ echo ""
74
74
 
75
75
  # Run tests
76
76
  echo "🧪 Running tests..."
77
- make lint
78
- make test
77
+ make check
79
78
  echo "✅ Tests passed"
80
79
 
81
80
  # Clean previous builds
@@ -0,0 +1,46 @@
1
+ import pickle
2
+ import unittest
3
+
4
+ import arxiv
5
+
6
+
7
+ class TestErrorPickle(unittest.TestCase):
8
+ """Regression tests for https://github.com/lukasschwab/arxiv.py/issues/191."""
9
+
10
+ def test_arxiv_error_pickle_roundtrip(self):
11
+ err = arxiv.ArxivError(url="http://example.com", retry=1, message="test")
12
+ restored = pickle.loads(pickle.dumps(err))
13
+ self.assertEqual(restored.url, err.url)
14
+ self.assertEqual(restored.retry, err.retry)
15
+ self.assertEqual(restored.message, err.message)
16
+ self.assertEqual(str(restored), str(err))
17
+
18
+ def test_http_error_pickle_roundtrip(self):
19
+ err = arxiv.HTTPError(url="http://export.arxiv.org/api/query", retry=3, status=503)
20
+ restored = pickle.loads(pickle.dumps(err))
21
+ self.assertEqual(restored.url, err.url)
22
+ self.assertEqual(restored.retry, err.retry)
23
+ self.assertEqual(restored.status, err.status)
24
+ self.assertIsInstance(restored.status, int)
25
+ self.assertEqual(str(restored), str(err))
26
+ self.assertEqual(repr(restored), repr(err))
27
+
28
+ def test_unexpected_empty_page_error_pickle_roundtrip(self):
29
+ err = arxiv.UnexpectedEmptyPageError(
30
+ url="http://export.arxiv.org/api/query", retry=2, raw_feed="<xml/>"
31
+ )
32
+ restored = pickle.loads(pickle.dumps(err))
33
+ self.assertEqual(restored.url, err.url)
34
+ self.assertEqual(restored.retry, err.retry)
35
+ self.assertEqual(restored.raw_feed, err.raw_feed)
36
+ self.assertEqual(str(restored), str(err))
37
+ self.assertEqual(repr(restored), repr(err))
38
+
39
+ def test_http_error_double_roundtrip(self):
40
+ """Ensure repeated pickle round-trips don't degrade the object."""
41
+ err = arxiv.HTTPError(url="http://export.arxiv.org/api/query", retry=3, status=503)
42
+ restored = pickle.loads(pickle.dumps(err))
43
+ restored2 = pickle.loads(pickle.dumps(restored))
44
+ self.assertEqual(restored2.status, 503)
45
+ self.assertEqual(restored2.args, err.args)
46
+ self.assertEqual(str(restored2), str(err))
@@ -117,7 +117,7 @@ wheels = [
117
117
 
118
118
  [package.optional-dependencies]
119
119
  filecache = [
120
- { name = "filelock", version = "3.20.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
120
+ { name = "filelock", version = "3.25.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
121
121
  ]
122
122
 
123
123
  [[package]]
@@ -327,14 +327,14 @@ wheels = [
327
327
 
328
328
  [[package]]
329
329
  name = "filelock"
330
- version = "3.20.2"
330
+ version = "3.25.0"
331
331
  source = { registry = "https://pypi.org/simple" }
332
332
  resolution-markers = [
333
333
  "python_full_version >= '3.10'",
334
334
  ]
335
- sdist = { url = "https://files.pythonhosted.org/packages/c1/e0/a75dbe4bca1e7d41307323dad5ea2efdd95408f74ab2de8bd7dba9b51a1a/filelock-3.20.2.tar.gz", hash = "sha256:a2241ff4ddde2a7cebddf78e39832509cb045d18ec1a09d7248d6bfc6bfbbe64", size = 19510, upload-time = "2026-01-02T15:33:32.582Z" }
335
+ sdist = { url = "https://files.pythonhosted.org/packages/77/18/a1fd2231c679dcb9726204645721b12498aeac28e1ad0601038f94b42556/filelock-3.25.0.tar.gz", hash = "sha256:8f00faf3abf9dc730a1ffe9c354ae5c04e079ab7d3a683b7c32da5dd05f26af3", size = 40158, upload-time = "2026-03-01T15:08:45.916Z" }
336
336
  wheels = [
337
- { url = "https://files.pythonhosted.org/packages/9a/30/ab407e2ec752aa541704ed8f93c11e2a5d92c168b8a755d818b74a3c5c2d/filelock-3.20.2-py3-none-any.whl", hash = "sha256:fbba7237d6ea277175a32c54bb71ef814a8546d8601269e1bfc388de333974e8", size = 16697, upload-time = "2026-01-02T15:33:31.133Z" },
337
+ { url = "https://files.pythonhosted.org/packages/f9/0b/de6f54d4a8bedfe8645c41497f3c18d749f0bd3218170c667bf4b81d0cdd/filelock-3.25.0-py3-none-any.whl", hash = "sha256:5ccf8069f7948f494968fc0713c10e5c182a9c9d9eef3a636307a20c2490f047", size = 26427, upload-time = "2026-03-01T15:08:44.593Z" },
338
338
  ]
339
339
 
340
340
  [[package]]
@@ -785,11 +785,11 @@ wheels = [
785
785
 
786
786
  [[package]]
787
787
  name = "pip"
788
- version = "25.3"
788
+ version = "26.0.1"
789
789
  source = { registry = "https://pypi.org/simple" }
790
- sdist = { url = "https://files.pythonhosted.org/packages/fe/6e/74a3f0179a4a73a53d66ce57fdb4de0080a8baa1de0063de206d6167acc2/pip-25.3.tar.gz", hash = "sha256:8d0538dbbd7babbd207f261ed969c65de439f6bc9e5dbd3b3b9a77f25d95f343", size = 1803014, upload-time = "2025-10-25T00:55:41.394Z" }
790
+ sdist = { url = "https://files.pythonhosted.org/packages/48/83/0d7d4e9efe3344b8e2fe25d93be44f64b65364d3c8d7bc6dc90198d5422e/pip-26.0.1.tar.gz", hash = "sha256:c4037d8a277c89b320abe636d59f91e6d0922d08a05b60e85e53b296613346d8", size = 1812747, upload-time = "2026-02-05T02:20:18.702Z" }
791
791
  wheels = [
792
- { url = "https://files.pythonhosted.org/packages/44/3c/d717024885424591d5376220b5e836c2d5293ce2011523c9de23ff7bf068/pip-25.3-py3-none-any.whl", hash = "sha256:9655943313a94722b7774661c21049070f6bbb0a1516bf02f7c8d5d9201514cd", size = 1778622, upload-time = "2025-10-25T00:55:39.247Z" },
792
+ { url = "https://files.pythonhosted.org/packages/de/f0/c81e05b613866b76d2d1066490adf1a3dbc4ee9d9c839961c3fc8a6997af/pip-26.0.1-py3-none-any.whl", hash = "sha256:bdb1b08f4274833d62c1aa29e20907365a2ceb950410df15fc9521bad440122b", size = 1787723, upload-time = "2026-02-05T02:20:16.416Z" },
793
793
  ]
794
794
 
795
795
  [[package]]
@@ -1129,9 +1129,9 @@ wheels = [
1129
1129
 
1130
1130
  [[package]]
1131
1131
  name = "urllib3"
1132
- version = "2.6.2"
1132
+ version = "2.6.3"
1133
1133
  source = { registry = "https://pypi.org/simple" }
1134
- sdist = { url = "https://files.pythonhosted.org/packages/1e/24/a2a2ed9addd907787d7aa0355ba36a6cadf1768b934c652ea78acbd59dcd/urllib3-2.6.2.tar.gz", hash = "sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797", size = 432930, upload-time = "2025-12-11T15:56:40.252Z" }
1134
+ sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", size = 435556, upload-time = "2026-01-07T16:24:43.925Z" }
1135
1135
  wheels = [
1136
- { url = "https://files.pythonhosted.org/packages/6d/b9/4095b668ea3678bf6a0af005527f39de12fb026516fb3df17495a733b7f8/urllib3-2.6.2-py3-none-any.whl", hash = "sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd", size = 131182, upload-time = "2025-12-11T15:56:38.584Z" },
1136
+ { url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584, upload-time = "2026-01-07T16:24:42.685Z" },
1137
1137
  ]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes