Skip to content

Commit c4ca2db

Browse files
authored
Merge pull request #42 from jwodder/pep792
Support PEP 792
2 parents 3e7b94d + 54c1288 commit c4ca2db

File tree

13 files changed

+110
-15
lines changed

13 files changed

+110
-15
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ v1.7.0 (in development)
33
- Support Python 3.13
44
- **Bugfix**: Fix parsing of PEP 708 `alternate-locations` fields in JSON
55
project pages (Previous versions looked for the field in the wrong location)
6+
- Support PEP 792
7+
- `status` and `status_reason` attributes added to `ProjectPage` and `RepositoryPage`
8+
- `ProjectStatus` enum added
9+
- `SUPPORTED_REPOSITORY_VERSION` increased to `"1.4"`
610

711
v1.6.1 (2024-10-23)
812
-------------------

README.rst

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@
2727
2828
``pypi-simple`` is a client library for the Python Simple Repository API as
2929
specified in :pep:`503` and updated by :pep:`592`, :pep:`629`, :pep:`658`,
30-
:pep:`691`, :pep:`700`, :pep:`708`, :pep:`714`, and :pep:`740`. With it, you
31-
can query `the Python Package Index (PyPI) <https://pypi.org>`_ and other `pip
32-
<https://pip.pypa.io>`_-compatible repositories for a list of their available
33-
projects and lists of each project's available package files. The library also
34-
allows you to download package files and query them for their project version,
35-
package type, file digests, ``requires_python`` string, PGP signature URL, and
36-
metadata URL.
30+
:pep:`691`, :pep:`700`, :pep:`708`, :pep:`714`, :pep:`740`, and :pep:`792`.
31+
With it, you can query `the Python Package Index (PyPI) <https://pypi.org>`_
32+
and other `pip <https://pip.pypa.io>`_-compatible repositories for a list of
33+
their available projects and lists of each project's available package files.
34+
The library also allows you to download package files and query them for their
35+
project version, package type, file digests, ``requires_python`` string, PGP
36+
signature URL, and metadata URL.
3737

3838
See `the documentation <https://pypi-simple.readthedocs.io>`_ for more
3939
information.

docs/api.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Core Classes
1212
.. autoclass:: IndexPage()
1313
.. autoclass:: ProjectPage()
1414
.. autoclass:: DistributionPackage()
15+
.. autoclass:: ProjectStatus()
1516

1617
Progress Trackers
1718
-----------------

docs/changelog.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,16 @@ Changelog
66
v1.7.0 (in development)
77
-----------------------
88
- Support Python 3.13
9+
910
- **Bugfix**: Fix parsing of :pep:`708` ``alternate-locations`` fields in JSON
1011
project pages (Previous versions looked for the field in the wrong location)
1112

13+
- Support :pep:`792`
14+
15+
- ``status`` and ``status_reason`` attributes added to `ProjectPage` and `RepositoryPage`
16+
- `ProjectStatus` enum added
17+
- `SUPPORTED_REPOSITORY_VERSION` increased to `"1.4"`
18+
1219

1320
v1.6.1 (2024-10-23)
1421
-------------------

docs/index.rst

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ pypi-simple — PyPI Simple Repository API client library
1919

2020
``pypi-simple`` is a client library for the Python Simple Repository API as
2121
specified in :pep:`503` and updated by :pep:`592`, :pep:`629`, :pep:`658`,
22-
:pep:`691`, :pep:`700`, :pep:`708`, :pep:`714`, and :pep:`740`. With it, you
23-
can query `the Python Package Index (PyPI) <https://pypi.org>`_ and other `pip
24-
<https://pip.pypa.io>`_-compatible repositories for a list of their available
25-
projects and lists of each project's available package files. The library also
26-
allows you to download package files and query them for their project version,
27-
package type, file digests, ``requires_python`` string, PGP signature URL, and
28-
metadata URL.
22+
:pep:`691`, :pep:`700`, :pep:`708`, :pep:`714`, :pep:`740`, and :pep:`792`.
23+
With it, you can query `the Python Package Index (PyPI) <https://pypi.org>`_
24+
and other `pip <https://pip.pypa.io>`_-compatible repositories for a list of
25+
their available projects and lists of each project's available package files.
26+
The library also allows you to download package files and query them for their
27+
project version, package type, file digests, ``requires_python`` string, PGP
28+
signature URL, and metadata URL.
2929

3030
Installation
3131
============

src/pypi_simple/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
PYPI_SIMPLE_ENDPOINT: str = "https://pypi.org/simple/"
2525

2626
#: The maximum supported simple repository version (See :pep:`629`)
27-
SUPPORTED_REPOSITORY_VERSION: str = "1.3"
27+
SUPPORTED_REPOSITORY_VERSION: str = "1.4"
2828

2929
#: :mailheader:`Accept` header value for accepting either the HTML or JSON
3030
#: serialization without a preference
@@ -69,6 +69,7 @@
6969

7070
from .classes import DistributionPackage, IndexPage, ProjectPage
7171
from .client import PyPISimple
72+
from .enums import ProjectStatus
7273
from .errors import (
7374
DigestMismatchError,
7475
NoDigestsError,
@@ -97,6 +98,7 @@
9798
"PYPI_SIMPLE_ENDPOINT",
9899
"ProgressTracker",
99100
"ProjectPage",
101+
"ProjectStatus",
100102
"PyPISimple",
101103
"RepositoryPage",
102104
"SUPPORTED_REPOSITORY_VERSION",

src/pypi_simple/classes.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from urllib.parse import urlparse, urlunparse
77
from mailbits import ContentType
88
import requests
9+
from .enums import ProjectStatus
910
from .errors import UnparsableFilenameError, UnsupportedContentTypeError
1011
from .filenames import parse_filename
1112
from .html import Link, RepositoryPage
@@ -277,6 +278,16 @@ class ProjectPage:
277278
#: __ https://peps.python.org/pep-0708/#alternate-locations-metadata
278279
alternate_locations: list[str] = field(default_factory=list)
279280

281+
#: .. versionadded:: 1.7.0
282+
#:
283+
#: Project status marker, or `None` if not specified. See :pep:`792`.
284+
status: ProjectStatus | None = None
285+
286+
#: .. versionadded:: 1.7.0
287+
#:
288+
#: Freeform text contextualizing `status`, or `None` if not specified
289+
status_reason: str | None = None
290+
280291
@classmethod
281292
def from_html(
282293
cls,
@@ -317,6 +328,8 @@ def from_html(
317328
versions=None,
318329
tracks=page.tracks,
319330
alternate_locations=page.alternate_locations,
331+
status=page.status,
332+
status_reason=page.status_reason,
320333
)
321334

322335
@classmethod
@@ -352,6 +365,8 @@ def from_json_data(cls, data: Any, base_url: Optional[str] = None) -> ProjectPag
352365
versions=project.versions,
353366
tracks=project.meta.tracks,
354367
alternate_locations=project.alternate_locations,
368+
status=project.project_status.status,
369+
status_reason=project.project_status.reason,
355370
)
356371

357372
@classmethod

src/pypi_simple/enums.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from enum import Enum
2+
3+
4+
class ProjectStatus(str, Enum):
5+
"""
6+
.. versionadded:: 1.7.0
7+
8+
Enum of project status markers as defined by :pep:`792`
9+
"""
10+
11+
#: The project is active. This is the default status for a project.
12+
ACTIVE = "active"
13+
14+
#: The project does not expect to be updated in the future.
15+
ARCHIVED = "archived"
16+
17+
#: The project is considered generally unsafe for use, e.g. due to malware.
18+
QUARANTINED = "quarantined"
19+
20+
#: The project is considered obsolete, and may have been superseded by
21+
#: another project.
22+
DEPRECATED = "deprecated"
23+
24+
def __str__(self) -> str:
25+
return self.value

src/pypi_simple/html.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from typing import Optional
55
from urllib.parse import urljoin
66
from bs4 import BeautifulSoup, Tag
7+
from .enums import ProjectStatus
78
from .util import basejoin, check_repo_version
89

910

@@ -52,6 +53,28 @@ def alternate_locations(self) -> list[str]:
5253
"""
5354
return self.pypi_meta.get("alternate-locations", [])
5455

56+
@property
57+
def status(self) -> ProjectStatus | None:
58+
"""
59+
.. versionadded:: 1.7.0
60+
61+
Project status marker, or `None` if not specified. See :pep:`792`.
62+
"""
63+
if st := self.pypi_meta.get("project-status"):
64+
return ProjectStatus(st[0])
65+
else:
66+
return None
67+
68+
@property
69+
def status_reason(self) -> str | None:
70+
"""
71+
.. versionadded:: 1.7.0
72+
73+
Freeform text contextualizing `status`, or `None` if not specified.
74+
See :pep:`792` for more information.
75+
"""
76+
return self.pypi_meta.get("project-status-reason", [None])[0]
77+
5578
@classmethod
5679
def from_html(
5780
cls,

src/pypi_simple/pep691.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from datetime import datetime
33
from typing import Any, Dict, List, Optional, Union
44
from pydantic import BaseModel, Field, StrictBool, field_validator
5+
from .enums import ProjectStatus
56

67

78
def shishkebab(s: str) -> str:
@@ -25,6 +26,11 @@ class ProjectMeta(Meta):
2526
tracks: List[str] = Field(default_factory=list)
2627

2728

29+
class StatusData(BaseModel):
30+
status: Optional[ProjectStatus] = None
31+
reason: Optional[str] = None
32+
33+
2834
class File(BaseModel, alias_generator=shishkebab, populate_by_name=True):
2935
filename: str
3036
url: str
@@ -73,6 +79,7 @@ class Project(BaseModel, alias_generator=shishkebab, populate_by_name=True):
7379
files: List[File]
7480
meta: ProjectMeta
7581
alternate_locations: List[str] = Field(default_factory=list)
82+
project_status: StatusData = Field(default_factory=StatusData)
7683
versions: Optional[List[str]] = None
7784

7885

0 commit comments

Comments
 (0)