ethspecify 0.3.9__tar.gz → 0.3.10__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.
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ethspecify
3
- Version: 0.3.9
3
+ Version: 0.3.10
4
4
  Summary: A utility for processing Ethereum specification tags.
5
- Home-page: https://github.com/jtraglia/ethspecify
5
+ Home-page: https://github.com/ethereum/ethspecify
6
6
  Author: Justin Traglia
7
7
  Author-email: jtraglia@pm.me
8
8
  Classifier: Programming Language :: Python :: 3
@@ -278,12 +278,20 @@ def is_fully_withdrawable_validator(validator: Validator, balance: Gwei, epoch:
278
278
 
279
279
  ### `link`
280
280
 
281
- This style displays an ethspec.tools link to the specification
282
- item.
281
+ This style displays a link to the specification item's source on
282
+ GitHub. For a tagged `version`, the link uses the tag as the ref:
283
283
 
284
284
  ```
285
- <spec fn="apply_pending_deposit" fork="electra" style="link" hash="83ee9126">
286
- https://ethspec.tools/#specs/v1.7.0-alpha.1/functions-apply_pending_deposit-electra
285
+ <spec ssz_object="BeaconState" fork="gloas" version="v1.7.0-alpha.11" style="link">
286
+ https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.11/specs/gloas/beacon-chain.md?plain=1#L411-L468
287
+ </spec>
288
+ ```
289
+
290
+ For `nightly`, the link uses a commit permalink instead of the tag:
291
+
292
+ ```
293
+ <spec fn="apply_pending_deposit" fork="electra" style="link">
294
+ https://github.com/ethereum/consensus-specs/blob/99cc40f9317a15ea185690cee6095297fc571dda/specs/electra/beacon-chain.md?plain=1#L960-L975
287
295
  </spec>
288
296
  ```
289
297
 
@@ -252,12 +252,20 @@ def is_fully_withdrawable_validator(validator: Validator, balance: Gwei, epoch:
252
252
 
253
253
  ### `link`
254
254
 
255
- This style displays an ethspec.tools link to the specification
256
- item.
255
+ This style displays a link to the specification item's source on
256
+ GitHub. For a tagged `version`, the link uses the tag as the ref:
257
257
 
258
258
  ```
259
- <spec fn="apply_pending_deposit" fork="electra" style="link" hash="83ee9126">
260
- https://ethspec.tools/#specs/v1.7.0-alpha.1/functions-apply_pending_deposit-electra
259
+ <spec ssz_object="BeaconState" fork="gloas" version="v1.7.0-alpha.11" style="link">
260
+ https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.11/specs/gloas/beacon-chain.md?plain=1#L411-L468
261
+ </spec>
262
+ ```
263
+
264
+ For `nightly`, the link uses a commit permalink instead of the tag:
265
+
266
+ ```
267
+ <spec fn="apply_pending_deposit" fork="electra" style="link">
268
+ https://github.com/ethereum/consensus-specs/blob/99cc40f9317a15ea185690cee6095297fc571dda/specs/electra/beacon-chain.md?plain=1#L960-L975
261
269
  </spec>
262
270
  ```
263
271
 
@@ -237,12 +237,30 @@ def diff(a_name, a_content, b_name, b_content):
237
237
 
238
238
  @functools.lru_cache()
239
239
  def get_pyspec(version="nightly"):
240
- url = f"https://raw.githubusercontent.com/jtraglia/ethspecify/main/pyspec/{version}/pyspec.json"
240
+ url = f"https://raw.githubusercontent.com/ethereum/ethspecify/main/pyspec/{version}/pyspec.json"
241
241
  response = requests.get(url)
242
242
  response.raise_for_status()
243
243
  return response.json()
244
244
 
245
245
 
246
+ @functools.lru_cache()
247
+ def get_links(version="nightly"):
248
+ """
249
+ Fetch the source location map (links.json) for a given version.
250
+
251
+ Returns a dict of the form {"commit": <sha>, "items": {name: {fork: {...}}}}
252
+ or None if no links.json is available for this version (e.g. older tags that
253
+ predate link support).
254
+ """
255
+ url = f"https://raw.githubusercontent.com/ethereum/ethspecify/main/pyspec/{version}/links.json"
256
+ try:
257
+ response = requests.get(url)
258
+ response.raise_for_status()
259
+ return response.json()
260
+ except (requests.RequestException, ValueError):
261
+ return None
262
+
263
+
246
264
  def get_previous_forks(fork, version="nightly"):
247
265
  pyspec = get_pyspec(version)
248
266
  config_vars = pyspec["mainnet"][fork]["config_vars"]
@@ -563,31 +581,117 @@ def get_spec_item(attributes, config=None):
563
581
  raise Exception("invalid style type")
564
582
 
565
583
 
566
- def build_spec_link(attributes, fork, version):
567
- base = f"https://ethspec.tools/#specs/{version}"
584
+ GITHUB_SPEC_REPO = "https://github.com/ethereum/consensus-specs"
585
+
586
+
587
+ def _get_link_item_name(attributes):
588
+ """
589
+ Return the spec item name referenced by a tag, or None if the tag does not
590
+ reference a linkable item.
591
+ """
592
+ if "function" in attributes and "fn" in attributes:
593
+ raise Exception("cannot contain 'function' and 'fn'")
568
594
  if "function" in attributes or "fn" in attributes:
569
- if "function" in attributes and "fn" in attributes:
570
- raise Exception(f"cannot contain 'function' and 'fn'")
571
- function_name = attributes.get("function", attributes.get("fn"))
572
- return f"{base}/functions-{function_name}-{fork}"
595
+ return attributes.get("function", attributes.get("fn"))
573
596
  if "constant_var" in attributes:
574
- return f"{base}/constant_vars-{attributes['constant_var']}-{fork}"
597
+ return attributes["constant_var"]
575
598
  if "preset_var" in attributes:
576
- return f"{base}/preset_vars-{attributes['preset_var']}-{fork}"
599
+ return attributes["preset_var"]
577
600
  if "config_var" in attributes:
578
- return f"{base}/config_vars-{attributes['config_var']}-{fork}"
601
+ return attributes["config_var"]
579
602
  if "custom_type" in attributes:
580
- return f"{base}/custom_types-{attributes['custom_type']}-{fork}"
603
+ return attributes["custom_type"]
604
+ if "ssz_object" in attributes and "container" in attributes:
605
+ raise Exception("cannot contain 'ssz_object' and 'container'")
581
606
  if "ssz_object" in attributes or "container" in attributes:
582
- if "ssz_object" in attributes and "container" in attributes:
583
- raise Exception(f"cannot contain 'ssz_object' and 'container'")
584
- object_name = attributes.get("ssz_object", attributes.get("container"))
585
- return f"{base}/ssz_objects-{object_name}-{fork}"
607
+ return attributes.get("ssz_object", attributes.get("container"))
586
608
  if "dataclass" in attributes:
587
- return f"{base}/dataclasses-{attributes['dataclass']}-{fork}"
609
+ return attributes["dataclass"]
588
610
  return None
589
611
 
590
612
 
613
+ def build_spec_link(attributes, fork, version):
614
+ """
615
+ Build a GitHub link to the source of the referenced spec item, or None if it
616
+ can't be resolved (unknown item, or no links.json for this version).
617
+ Tagged versions link to the tag; nightly links to a commit permalink.
618
+ """
619
+ item_name = _get_link_item_name(attributes)
620
+ if item_name is None:
621
+ return None
622
+
623
+ links = get_links(version)
624
+ if not links:
625
+ return None
626
+
627
+ item_forks = links.get("items", {}).get(item_name)
628
+ if not item_forks:
629
+ return None
630
+
631
+ location = _resolve_location(item_forks, fork, version)
632
+ if location is None:
633
+ return None
634
+
635
+ ref = version if version != "nightly" else links.get("commit")
636
+ if not ref:
637
+ return None
638
+
639
+ start = location["start"]
640
+ end = location["end"]
641
+
642
+ # For function line selections, narrow the anchor to the requested lines.
643
+ if ("function" in attributes or "fn" in attributes) and "lines" in attributes:
644
+ sub = _apply_line_subrange(start, end, attributes["lines"])
645
+ if sub is not None:
646
+ start, end = sub
647
+
648
+ anchor = f"L{start}" if start == end else f"L{start}-L{end}"
649
+ return f"{GITHUB_SPEC_REPO}/blob/{ref}/{location['file']}?plain=1#{anchor}"
650
+
651
+
652
+ def _resolve_location(item_forks, fork, version):
653
+ """
654
+ Find the source location for an item at the given fork. If the item is not
655
+ (re)defined in that fork, walk back through previous forks to the most recent
656
+ one that defines it (matching how the spec inherits unchanged items).
657
+ """
658
+ if fork in item_forks:
659
+ return item_forks[fork]
660
+ try:
661
+ previous_forks = get_previous_forks(fork, version)
662
+ except Exception:
663
+ return None
664
+ for prev in previous_forks:
665
+ if prev in item_forks:
666
+ return item_forks[prev]
667
+ return None
668
+
669
+
670
+ def _apply_line_subrange(start, end, lines_attr):
671
+ """
672
+ Narrow a [start, end] line range using a tag's `lines` attribute (1-indexed,
673
+ relative to the item). Returns (new_start, new_end) or None if invalid.
674
+ """
675
+ try:
676
+ parts = lines_attr.split("-")
677
+ if len(parts) == 1:
678
+ s = e = int(parts[0])
679
+ elif len(parts) == 2:
680
+ s = int(parts[0])
681
+ e = int(parts[1])
682
+ else:
683
+ return None
684
+ except ValueError:
685
+ return None
686
+
687
+ total = end - start + 1
688
+ s = max(1, min(s, total))
689
+ e = max(1, min(e, total))
690
+ if s > e:
691
+ return None
692
+ return start + s - 1, start + e - 1
693
+
694
+
591
695
  def extract_attributes(tag):
592
696
  attr_pattern = re.compile(r'(\w+)="(.*?)"')
593
697
  return dict(attr_pattern.findall(tag))
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ethspecify
3
- Version: 0.3.9
3
+ Version: 0.3.10
4
4
  Summary: A utility for processing Ethereum specification tags.
5
- Home-page: https://github.com/jtraglia/ethspecify
5
+ Home-page: https://github.com/ethereum/ethspecify
6
6
  Author: Justin Traglia
7
7
  Author-email: jtraglia@pm.me
8
8
  Classifier: Programming Language :: Python :: 3
@@ -278,12 +278,20 @@ def is_fully_withdrawable_validator(validator: Validator, balance: Gwei, epoch:
278
278
 
279
279
  ### `link`
280
280
 
281
- This style displays an ethspec.tools link to the specification
282
- item.
281
+ This style displays a link to the specification item's source on
282
+ GitHub. For a tagged `version`, the link uses the tag as the ref:
283
283
 
284
284
  ```
285
- <spec fn="apply_pending_deposit" fork="electra" style="link" hash="83ee9126">
286
- https://ethspec.tools/#specs/v1.7.0-alpha.1/functions-apply_pending_deposit-electra
285
+ <spec ssz_object="BeaconState" fork="gloas" version="v1.7.0-alpha.11" style="link">
286
+ https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.11/specs/gloas/beacon-chain.md?plain=1#L411-L468
287
+ </spec>
288
+ ```
289
+
290
+ For `nightly`, the link uses a commit permalink instead of the tag:
291
+
292
+ ```
293
+ <spec fn="apply_pending_deposit" fork="electra" style="link">
294
+ https://github.com/ethereum/consensus-specs/blob/99cc40f9317a15ea185690cee6095297fc571dda/specs/electra/beacon-chain.md?plain=1#L960-L975
287
295
  </spec>
288
296
  ```
289
297
 
@@ -8,13 +8,13 @@ long_description = (this_directory / "README.md").read_text(encoding="utf-8")
8
8
 
9
9
  setup(
10
10
  name="ethspecify",
11
- version="0.3.9",
11
+ version="0.3.10",
12
12
  description="A utility for processing Ethereum specification tags.",
13
13
  long_description=long_description,
14
14
  long_description_content_type="text/markdown",
15
15
  author="Justin Traglia",
16
16
  author_email="jtraglia@pm.me",
17
- url="https://github.com/jtraglia/ethspecify",
17
+ url="https://github.com/ethereum/ethspecify",
18
18
  packages=find_packages(),
19
19
  entry_points={
20
20
  "console_scripts": [
File without changes
File without changes