From f335fbb8479f0bcc2ae5612bffc540f8dcbab2e0 Mon Sep 17 00:00:00 2001 From: Kazuya Takei Date: Sun, 18 Feb 2024 13:02:30 +0900 Subject: [PATCH] refactor: Project data is controlled as struct --- rst_pypi_ref/core.py | 27 +++++++++++++++++++++++++-- tests/test_it.py | 10 +++++----- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/rst_pypi_ref/core.py b/rst_pypi_ref/core.py index 5faf8b4..865cb78 100644 --- a/rst_pypi_ref/core.py +++ b/rst_pypi_ref/core.py @@ -1,5 +1,6 @@ """Core module.""" import re +from dataclasses import dataclass from typing import List, Optional from docutils import nodes @@ -7,6 +8,28 @@ from docutils.parsers.rst.states import Inliner +@dataclass +class Project: + """Project data struct on PyPI.""" + + name: str + version: Optional[str] = None + + @classmethod + def parse(cls, fullname: str) -> "Project": + spec = fullname.split("==") + if len(spec) == 1: + return cls(name=spec[0]) + return cls(name=spec[0], version=spec[1]) + + @property + def url(self) -> str: + url = f"https://pypi.org/project/{self.name}/" + if self.version: + url += f"{self.version}/" + return url + + def build_package_url(fullname: str) -> str: """Build ref URL for package fullname after parsed.""" spec = fullname.split("==") @@ -34,8 +57,8 @@ def pypi_reference_role( if matched: title = matched.group("title") target = matched.group("target") - url = build_package_url(target) - return [nodes.reference(rawtext, title, refuri=url, **options)], messages + project = Project.parse(target) + return [nodes.reference(rawtext, title, refuri=project.url, **options)], messages def bootstrap(): diff --git a/tests/test_it.py b/tests/test_it.py index 345b049..5d6b420 100644 --- a/tests/test_it.py +++ b/tests/test_it.py @@ -23,14 +23,14 @@ def test_title_and_target(self): assert node["refuri"] == "https://pypi.org/project/docutils/" -class TestForBuildPackageUrl: +class TestForProject: def test_name_only(self): - url = core.build_package_url("docutils") - assert url == "https://pypi.org/project/docutils/" + project = core.Project(name="docutils") + assert project.url == "https://pypi.org/project/docutils/" def test_with_version(self): - url = core.build_package_url("docutils==0.1.0") - assert url == "https://pypi.org/project/docutils/0.1.0/" + project = core.Project(name="docutils", version="0.1.0") + assert project.url == "https://pypi.org/project/docutils/0.1.0/" class TestForParse: