From c58183d3cc0aa504454ebbe8d261d74965aaa365 Mon Sep 17 00:00:00 2001 From: object-Object Date: Sun, 11 Jun 2023 16:25:52 -0400 Subject: [PATCH] Move most ABCs into common/abstract.py --- doc/src/common/abstract.py | 80 +++++++++++++++++++++++++++++++++++ doc/src/common/composition.py | 38 ----------------- doc/src/common/utils.py | 18 +------- doc/src/minecraft/resource.py | 30 ------------- doc/src/patchouli/category.py | 5 +-- doc/src/patchouli/entry.py | 5 +-- doc/src/patchouli/page.py | 2 +- 7 files changed, 87 insertions(+), 91 deletions(-) create mode 100644 doc/src/common/abstract.py delete mode 100644 doc/src/common/composition.py diff --git a/doc/src/common/abstract.py b/doc/src/common/abstract.py new file mode 100644 index 00000000..c59ae2fd --- /dev/null +++ b/doc/src/common/abstract.py @@ -0,0 +1,80 @@ +from __future__ import annotations + +from abc import ABC, abstractmethod +from dataclasses import dataclass +from pathlib import Path +from typing import TYPE_CHECKING, Any + +from minecraft.resource import ResourceLocation + +# circular imports are gross +if TYPE_CHECKING: + from patchouli.book import Book + from patchouli.category import Category + from patchouli.entry import Entry +else: + Book, Category, Entry = Any, Any, Any + + +class WithBook(ABC): + """ABC for composition with Book.""" + + @property + @abstractmethod + def book(self) -> Book: + ... + + @property + def resource_dir(self): + """book.resource_dir""" + return self.book.resource_dir + + @property + def modid(self): + """book.modid""" + return self.book.modid + + @property + def i18n(self): + """book.i18n""" + return self.book.i18n + + +class Sortable(ABC): + """ABC for classes which can be sorted.""" + + @property + @abstractmethod + def cmp_key(self) -> Any: + ... + + def __lt__(self, other: Any) -> bool: + if isinstance(other, Sortable): + return self.cmp_key < other.cmp_key + return NotImplemented + + +@dataclass +class WithPathId(ABC): + """ABC for classes with a ResourceLocation id.""" + + path: Path + + @property + @abstractmethod + def base_dir(self) -> Path: + """Base directory. Combine with self.id.path to find this file.""" + + @property + @abstractmethod + def modid(self) -> str: + ... + + @property + def id(self) -> ResourceLocation: + resource_path = self.path.relative_to(self.base_dir).with_suffix("").as_posix() + return ResourceLocation(self.modid, resource_path) + + @property + def href(self) -> str: + return f"#{self.id.path}" diff --git a/doc/src/common/composition.py b/doc/src/common/composition.py deleted file mode 100644 index 659c6f3e..00000000 --- a/doc/src/common/composition.py +++ /dev/null @@ -1,38 +0,0 @@ -from __future__ import annotations - -from abc import ABC, abstractmethod -from typing import TYPE_CHECKING, Any - -# circular imports are gross -if TYPE_CHECKING: - from patchouli.book import Book - from patchouli.category import Category - from patchouli.entry import Entry -else: - Book, Category, Entry = Any, Any, Any - -# TODO: consolidate ABCs here - - -class WithBook(ABC): - """ABC for composition with Book.""" - - @property - @abstractmethod - def book(self) -> Book: - ... - - @property - def resource_dir(self): - """book.resource_dir""" - return self.book.resource_dir - - @property - def modid(self): - """book.modid""" - return self.book.modid - - @property - def i18n(self): - """book.i18n""" - return self.book.i18n diff --git a/doc/src/common/utils.py b/doc/src/common/utils.py index 882983ab..91fbdd47 100644 --- a/doc/src/common/utils.py +++ b/doc/src/common/utils.py @@ -1,20 +1,6 @@ -from abc import ABC, abstractmethod -from typing import Any, Mapping, TypeVar - - -class Sortable(ABC): - """ABC for classes which can be sorted.""" - - @property - @abstractmethod - def cmp_key(self) -> Any: - ... - - def __lt__(self, other: Any) -> bool: - if isinstance(other, Sortable): - return self.cmp_key < other.cmp_key - return NotImplemented +from typing import Mapping, TypeVar +from common.abstract import Sortable _T = TypeVar("_T") _T_Sortable = TypeVar("_T_Sortable", bound=Sortable) diff --git a/doc/src/minecraft/resource.py b/doc/src/minecraft/resource.py index f0deeb3f..342998d2 100644 --- a/doc/src/minecraft/resource.py +++ b/doc/src/minecraft/resource.py @@ -1,9 +1,7 @@ from __future__ import annotations import re -from abc import ABC, abstractmethod from dataclasses import dataclass -from pathlib import Path from typing import Self from common.deserialize import FromStr @@ -12,8 +10,6 @@ _RESOURCE_LOCATION_RE = re.compile(r"(?:([0-9a-z_\-.]+):)?([0-9a-z_\-./]+)") _ITEM_STACK_SUFFIX_RE = re.compile(r"(?:#([0-9]+))?({.*})?") -# TODO: instead of the dataclass field thing, make this subclass str -# _namespace and _method, access via properties @dataclass(repr=False, frozen=True) class ResourceLocation(FromStr): """Represents a Minecraft resource location / namespaced ID.""" @@ -69,29 +65,3 @@ class ItemStack(ResourceLocation): if self.nbt is not None: s += self.nbt return s - - -@dataclass -class WithPathId(ABC): - """ABC for classes with a ResourceLocation id.""" - - path: Path - - @property - @abstractmethod - def base_dir(self) -> Path: - """Base directory. Combine with self.id.path to find this file.""" - - @property - @abstractmethod - def modid(self) -> str: - ... - - @property - def id(self) -> ResourceLocation: - resource_path = self.path.relative_to(self.base_dir).with_suffix("").as_posix() - return ResourceLocation(self.modid, resource_path) - - @property - def href(self) -> str: - return f"#{self.id.path}" diff --git a/doc/src/patchouli/category.py b/doc/src/patchouli/category.py index 807f8913..8485ca45 100644 --- a/doc/src/patchouli/category.py +++ b/doc/src/patchouli/category.py @@ -3,12 +3,11 @@ from __future__ import annotations from dataclasses import dataclass from pathlib import Path -from common.composition import Book, WithBook +from common.abstract import Book, Sortable, WithBook, WithPathId from common.deserialize import FromJson from common.formatting import FormatTree -from common.utils import Sortable from minecraft.i18n import LocalizedStr -from minecraft.resource import ItemStack, ResourceLocation, WithPathId +from minecraft.resource import ItemStack, ResourceLocation from patchouli.entry import Entry from serde import deserialize diff --git a/doc/src/patchouli/entry.py b/doc/src/patchouli/entry.py index cae39f24..f5de5677 100644 --- a/doc/src/patchouli/entry.py +++ b/doc/src/patchouli/entry.py @@ -4,11 +4,10 @@ from dataclasses import dataclass from pathlib import Path from typing import Any -from common.composition import Book, Category, WithBook +from common.abstract import Book, Category, Sortable, WithBook, WithPathId from common.deserialize import FromJson -from common.utils import Sortable from minecraft.i18n import LocalizedStr -from minecraft.resource import ItemStack, ResourceLocation, WithPathId +from minecraft.resource import ItemStack, ResourceLocation from patchouli.page import Page, Page_patchouli_text, page_transformers from serde import deserialize diff --git a/doc/src/patchouli/page.py b/doc/src/patchouli/page.py index 0596ea47..68b7cad6 100644 --- a/doc/src/patchouli/page.py +++ b/doc/src/patchouli/page.py @@ -12,7 +12,7 @@ from typing import ( TypeVar, ) -from common.composition import Book, Entry +from common.abstract import Book, Entry from common.formatting import FormatTree from common.pattern_info import PatternInfo, RawPatternInfo