Skip to content

Commit 8a052aa

Browse files
authored
feat(doc): replace index with __init__.py (#2779)
1 parent bf9dbb4 commit 8a052aa

4 files changed

Lines changed: 128 additions & 29 deletions

File tree

pyproject.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ actionlint = [
225225
"shellcheck-py>=0.10",
226226
]
227227
doc = [
228-
"docc>=0.5.1,<0.6.0",
228+
"docc>=0.6.0,<0.7.0",
229229
"fladrif>=0.2.0,<0.3.0",
230230
"mistletoe>=1.5.0,<2",
231231
]
@@ -273,6 +273,7 @@ whitelist = "ethereum_spec_tools.whitelist:main"
273273
[project.entry-points."docc.plugins"]
274274
"ethereum_spec_tools.docc.listing" = "ethereum_spec_tools.docc:EthereumListingDiscover"
275275
"ethereum_spec_tools.docc.discover" = "ethereum_spec_tools.docc:EthereumDiscover"
276+
"ethereum_spec_tools.docc.python" = "ethereum_spec_tools.docc:EthereumPythonDiscover"
276277
"ethereum_spec_tools.docc.build" = "ethereum_spec_tools.docc:EthereumBuilder"
277278
"ethereum_spec_tools.docc.fix-indexes" = "ethereum_spec_tools.docc:FixIndexTransform"
278279
"ethereum_spec_tools.docc.minimize-diffs" = "ethereum_spec_tools.docc:MinimizeDiffsTransform"
@@ -311,7 +312,7 @@ context = [
311312
discovery = [
312313
"docc.search.discover",
313314
"docc.html.discover",
314-
"docc.python.discover",
315+
"ethereum_spec_tools.docc.python",
315316
"ethereum_spec_tools.docc.discover",
316317
"ethereum_spec_tools.docc.listing",
317318
"docc.files.discover",
@@ -341,7 +342,7 @@ excluded_references = [
341342
"ethereum_spec_tools.lint.lints", # This is a namespace package.
342343
]
343344

344-
[tool.docc.plugins."docc.python.discover"]
345+
[tool.docc.plugins."ethereum_spec_tools.docc.python"]
345346
paths = [
346347
"src",
347348
]

src/ethereum_spec_tools/docc.py

Lines changed: 118 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import logging
2222
import os
2323
from collections import defaultdict
24+
from functools import total_ordering
2425
from itertools import tee, zip_longest
2526
from pathlib import PurePath
2627
from typing import (
@@ -51,7 +52,8 @@
5152
ListingNode,
5253
ListingSource,
5354
)
54-
from docc.plugins.python import PythonBuilder
55+
from docc.plugins.python import PythonBuilder, PythonDiscover
56+
from docc.plugins.python.cst import PythonSource
5557
from docc.plugins.references import Definition, Reference
5658
from docc.settings import PluginSettings
5759
from docc.source import Source
@@ -76,24 +78,65 @@ def pairwise(iterable: Iterable[G]) -> Iterable[Tuple[G, G]]:
7678
return zip(a, b, strict=False)
7779

7880

81+
@total_ordering
82+
@dataclasses.dataclass(frozen=True)
83+
class _EthereumSortKey:
84+
sort: int
85+
path: PurePath
86+
87+
def __lt__(self, other: object) -> bool:
88+
if isinstance(other, _EthereumSortKey):
89+
return (self.sort, self.path) < (other.sort, other.path)
90+
elif isinstance(other, PurePath):
91+
return self.path < other
92+
return NotImplemented
93+
94+
95+
class _EthereumPythonSource(PythonSource):
96+
_sort: Final[int]
97+
98+
def __init__(
99+
self,
100+
root_path: PurePath,
101+
relative_path: PurePath,
102+
absolute_path: PurePath,
103+
sort: int,
104+
) -> None:
105+
super().__init__(root_path, relative_path, absolute_path)
106+
self._sort = sort
107+
108+
@override
109+
def listing_order_key(
110+
self,
111+
) -> Tuple[bool, _EthereumSortKey, None]:
112+
return (
113+
self.index_dir is None,
114+
_EthereumSortKey(self._sort, self.output_path),
115+
None,
116+
)
117+
118+
79119
class _EthereumListingSource(ListingSource):
80120
_sort: Final[int]
81121

82122
def __init__(
83123
self,
84124
relative_path: PurePath,
85125
output_path: PurePath,
86-
sources: Set[Source],
87126
sort: int,
88127
) -> None:
89-
super().__init__(relative_path, output_path, sources)
128+
super().__init__(relative_path, output_path)
90129
self._sort = sort
91130

92131
@override
93132
def listing_order_key(
94133
self,
95-
) -> Tuple[bool, Tuple[int, PurePath], None]:
96-
return (self.is_leaf, (self._sort, self.output_path), None)
134+
) -> Tuple[bool, _EthereumSortKey, None]:
135+
return (
136+
self.index_dir is None,
137+
_EthereumSortKey(self._sort, self.output_path),
138+
None,
139+
)
97140

98141

99142
def _find_forks(config: PluginSettings) -> List[Hardfork]:
@@ -105,47 +148,85 @@ def _diff_path(before: Hardfork, after: Hardfork) -> PurePath:
105148
return PurePath("diffs") / before.short_name / after.short_name
106149

107150

108-
class EthereumListingDiscover(ListingDiscover):
109-
"""
110-
Changes the sort order of directory listings so they render in hard fork
111-
chronological order.
112-
"""
113-
114-
fork_order: List[PurePath]
115-
diff_order: List[PurePath]
151+
class _ForkOrder:
152+
forks: List[PurePath]
153+
diffs: List[PurePath]
116154

117155
def __init__(self, config: PluginSettings) -> None:
118-
super().__init__(config)
119156
forks = _find_forks(config)
120-
self.fork_order = [
157+
self.forks = [
121158
config.unresolve_path(PurePath(f.path))
122159
for f in forks
123160
if f.path is not None
124161
]
125-
self.diff_order = [_diff_path(b, a).parent for b, a in pairwise(forks)]
162+
self.diffs = [_diff_path(b, a).parent for b, a in pairwise(forks)]
126163

127-
def _fork_index(self, parent: PurePath) -> Optional[int]:
128-
for idx, fork in enumerate(self.fork_order):
164+
def index(self, parent: PurePath) -> Optional[int]:
165+
for idx, fork in enumerate(self.forks):
129166
if parent.is_relative_to(fork):
130167
return idx
131168

132-
for idx, diff in enumerate(self.diff_order):
169+
for idx, diff in enumerate(self.diffs):
133170
if parent.is_relative_to(diff):
134171
return idx
135172

136173
return None
137174

175+
176+
class EthereumListingDiscover(ListingDiscover):
177+
"""
178+
Changes the sort order of directory listings so they render in hard fork
179+
chronological order.
180+
"""
181+
182+
_fork_order: _ForkOrder
183+
184+
def __init__(self, config: PluginSettings) -> None:
185+
super().__init__(config)
186+
self._fork_order = _ForkOrder(config)
187+
138188
@override
139189
def _listing_source(
140190
self, source: Source, parent: PurePath
141191
) -> ListingSource:
142-
index = self._fork_index(parent)
192+
index = self._fork_order.index(parent)
143193
if index is None:
144194
return super()._listing_source(source, parent)
145195
return _EthereumListingSource(
146196
parent,
147197
parent / "index",
148-
set(),
198+
-index, # Reverse chronological order
199+
)
200+
201+
202+
class EthereumPythonDiscover(PythonDiscover):
203+
"""
204+
Changes the sort order of python files so they render in hard fork
205+
chronological order.
206+
"""
207+
208+
_fork_order: _ForkOrder
209+
210+
def __init__(self, config: PluginSettings) -> None:
211+
super().__init__(config)
212+
self._fork_order = _ForkOrder(config)
213+
214+
@override
215+
def _python_source(
216+
self,
217+
root_path: PurePath,
218+
relative_path: PurePath,
219+
absolute_path: PurePath,
220+
) -> PythonSource:
221+
index = self._fork_order.index(relative_path)
222+
if index is None:
223+
return super()._python_source(
224+
root_path, relative_path, absolute_path
225+
)
226+
return _EthereumPythonSource(
227+
root_path,
228+
relative_path,
229+
absolute_path,
149230
-index, # Reverse chronological order
150231
)
151232

@@ -214,6 +295,9 @@ def discover(self, known: FrozenSet[T]) -> Iterator[Source]:
214295

215296
assert before_source or after_source
216297

298+
if path.name == "__init__.py":
299+
path = path.with_name("index")
300+
217301
output_path = _diff_path(before, after) / path
218302

219303
yield DiffSource(
@@ -282,6 +366,19 @@ def output_path(self) -> PurePath:
282366
"""
283367
return self._output_path
284368

369+
@property
370+
def index_dir(self) -> Optional[PurePath]:
371+
"""
372+
For index sources, the directory the source indexes. For other sources,
373+
`None`.
374+
375+
For example, for an output path of `./foo/index`, this should return
376+
`./foo`.
377+
"""
378+
if self.output_path.name == "index":
379+
return self.output_path.parent
380+
return None
381+
285382

286383
class AfterNode(Node):
287384
"""

uv.lock

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vulture_whitelist.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
# src/ethereum_spec_tools/docc.py
5757
docc.EthereumDiscover
5858
docc.EthereumBuilder
59+
docc.EthereumPythonDiscover
5960
docc.EthereumListingDiscover
6061
docc.DiffSource.show_in_listing
6162
docc.FixIndexTransform

0 commit comments

Comments
 (0)