ethspecify 0.1.1__py3-none-any.whl → 0.1.2__py3-none-any.whl

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.

Potentially problematic release.


This version of ethspecify might be problematic. Click here for more details.

ethspecify/cli.py CHANGED
@@ -1,7 +1,7 @@
1
1
  import argparse
2
2
  import os
3
3
 
4
- from .core import grep, replace_spec_tags # if you split functionality into core.py
4
+ from .core import grep, replace_spec_tags
5
5
 
6
6
  def main():
7
7
  parser = argparse.ArgumentParser(
ethspecify/core.py CHANGED
@@ -272,50 +272,66 @@ def replace_spec_tags(file_path):
272
272
  with open(file_path, 'r') as file:
273
273
  content = file.read()
274
274
 
275
- # Define regex to match both long and self-closing <spec> tags
276
- pattern = re.compile(r'(<spec\b[^>]*)(/?>)(?:([\s\S]*?)(</spec>))?', re.DOTALL)
275
+ # Define regex to match self-closing tags and long (paired) tags separately
276
+ pattern = re.compile(
277
+ r'(?P<self><spec\b[^>]*\/>)|(?P<long><spec\b[^>]*>[\s\S]*?</spec>)',
278
+ re.DOTALL
279
+ )
277
280
 
278
281
  def replacer(match):
279
- # Extract the tag parts:
280
- opening_tag_base = match.group(1)
281
- tag_end = match.group(2) # either ">" or "/>"
282
-
283
- # Reconstruct the full opening tag for attribute extraction
284
- opening_tag_full = opening_tag_base + tag_end
285
-
286
- # Extract attributes from the full opening tag
287
- attributes = extract_attributes(opening_tag_full)
288
- print(f"spec tag: {attributes}")
289
-
290
- # Parse common attributes to get preset, fork, style, etc.
291
- preset, fork, style = parse_common_attributes(attributes)
292
- spec = get_spec(attributes, preset, fork)
293
-
294
- # Compute the first 8 characters of the SHA256 hash of the spec content.
295
- hash_value = hashlib.sha256(spec.encode('utf-8')).hexdigest()[:8]
296
-
297
- # Update the full opening tag (opening_tag_full) to include the hash attribute.
298
- if 'hash="' in opening_tag_full:
299
- updated_opening = re.sub(
300
- r'(hash=")[^"]*(")',
301
- lambda m: f'{m.group(1)}{hash_value}{m.group(2)}',
302
- opening_tag_full
303
- )
282
+ if match.group("self") is not None:
283
+ # Process self-closing tag
284
+ tag_text = match.group("self")
285
+ attributes = extract_attributes(tag_text)
286
+ print(f"spec tag: {attributes}")
287
+ preset, fork, style = parse_common_attributes(attributes)
288
+ spec = get_spec(attributes, preset, fork)
289
+ hash_value = hashlib.sha256(spec.encode('utf-8')).hexdigest()[:8]
290
+ if 'hash="' in tag_text:
291
+ updated_tag = re.sub(
292
+ r'(hash=")[^"]*(")',
293
+ lambda m: f'{m.group(1)}{hash_value}{m.group(2)}',
294
+ tag_text
295
+ )
296
+ else:
297
+ # Insert hash attribute before the trailing '/>'
298
+ updated_tag = tag_text[:-2] + f' hash="{hash_value}"' + tag_text[-2:]
299
+ return updated_tag
304
300
  else:
305
- updated_opening = opening_tag_full[:-1] + f' hash="{hash_value}">'
301
+ # Process long (paired) tag
302
+ tag_text = match.group("long")
303
+ # Extract the opening tag from the long tag (everything up to the first '>')
304
+ opening_match = re.match(r'(<spec\b[^>]*>)([\s\S]*)(</spec>)', tag_text, re.DOTALL)
305
+ if not opening_match:
306
+ return tag_text
307
+ opening_tag_full = opening_match.group(1)
308
+ attributes = extract_attributes(opening_tag_full)
309
+ print(f"spec tag: {attributes}")
310
+ preset, fork, style = parse_common_attributes(attributes)
311
+ spec = get_spec(attributes, preset, fork)
312
+ hash_value = hashlib.sha256(spec.encode('utf-8')).hexdigest()[:8]
313
+ if 'hash="' in opening_tag_full:
314
+ updated_opening = re.sub(
315
+ r'(hash=")[^"]*(")',
316
+ lambda m: f'{m.group(1)}{hash_value}{m.group(2)}',
317
+ opening_tag_full
318
+ )
319
+ else:
320
+ updated_opening = opening_tag_full[:-1] + f' hash="{hash_value}">'
321
+ if style == "hash":
322
+ updated_tag = re.sub(r'\s*</spec>\s*$', '', updated_opening)
323
+ updated_tag = re.sub(r'\s*>$', '', updated_tag) + " />"
324
+ else:
325
+ spec_content = get_spec_item(attributes)
326
+ prefix = content[:match.start()].splitlines()[-1]
327
+ prefixed_spec = "\n".join(
328
+ f"{prefix}{line}" if line.rstrip() else prefix.rstrip()
329
+ for line in spec_content.rstrip().split("\n")
330
+ )
331
+ long_opening = updated_opening.rstrip(">/") + ">"
332
+ updated_tag = f"{long_opening}\n{prefixed_spec}\n{prefix}</spec>"
333
+ return updated_tag
306
334
 
307
- if style == "hash":
308
- # For hash style, output a short self-closing tag with normalized spacing.
309
- updated_tag = re.sub(r'\s*/?>\s*$', '', updated_opening) + " />"
310
- else:
311
- # For full/diff styles, output the long form with content.
312
- spec_content = get_spec_item(attributes)
313
- prefix = content[:match.start()].splitlines()[-1]
314
- prefixed_spec = "\n".join(f"{prefix}{line}" if line.rstrip() else prefix.rstrip() for line in spec_content.rstrip().split("\n"))
315
- long_opening = updated_opening.rstrip(">/") + ">"
316
- updated_tag = f"{long_opening}\n{prefixed_spec}\n{prefix}</spec>"
317
-
318
- return updated_tag
319
335
 
320
336
  # Replace all matches in the content
321
337
  updated_content = pattern.sub(replacer, content)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: ethspecify
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: A utility for processing Ethereum specification tags.
5
5
  Home-page: https://github.com/jtraglia/ethspecify
6
6
  Author: Justin Traglia
@@ -49,7 +49,13 @@ In your client, add HTML tags like this:
49
49
  */
50
50
  ```
51
51
 
52
- ### Populate Spec Tags
52
+ ```
53
+ /*
54
+ * <spec ssz_object="BeaconState" fork="electra" style="diff">
55
+ */
56
+ ```
57
+
58
+ ### Populating Spec Tags
53
59
 
54
60
  Then, navigate to your codebase and run `ethspecify`:
55
61
 
@@ -0,0 +1,9 @@
1
+ ethspecify/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ ethspecify/cli.py,sha256=TTKmSGUkuRdYlYS6t-cpVXpdpSKsYCWvmRDy8DcC10E,882
3
+ ethspecify/core.py,sha256=GHVBP4OjKAy5Rf3z5PIjee9WNhr5-_u7JG3Rt-Zd-4I,12890
4
+ ethspecify-0.1.2.dist-info/LICENSE,sha256=Awxsr73mm9YMBVhBYnzeI7bNdRd-bH6RDtO5ItG0DaM,1071
5
+ ethspecify-0.1.2.dist-info/METADATA,sha256=H1qF9pQTnFTKmnNnEL1oJjUk-GjGwoHv5slOp9qQ5-g,8786
6
+ ethspecify-0.1.2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
7
+ ethspecify-0.1.2.dist-info/entry_points.txt,sha256=09viGkCg9J3h0c9BFRN-BKaJUEaIc4JyULNgBP5EL_g,51
8
+ ethspecify-0.1.2.dist-info/top_level.txt,sha256=0klaMvlVyOkXW09fwZTijJpdybITEp2c9zQKV5v30VM,11
9
+ ethspecify-0.1.2.dist-info/RECORD,,
@@ -1,9 +0,0 @@
1
- ethspecify/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- ethspecify/cli.py,sha256=EFjH1ioHibDG1U-6XiozQ2aT2j-GyaWhUJJ-QMALrLc,925
3
- ethspecify/core.py,sha256=sxmTdXCQIpaAjebMG0NE-7mTf4m0NG_J9IjgGlmOTVk,12064
4
- ethspecify-0.1.1.dist-info/LICENSE,sha256=Awxsr73mm9YMBVhBYnzeI7bNdRd-bH6RDtO5ItG0DaM,1071
5
- ethspecify-0.1.1.dist-info/METADATA,sha256=WfBBcZ6NDCt_z0JKDGp66mFvGmjv7UiMB3fhmE_5XYA,8705
6
- ethspecify-0.1.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
7
- ethspecify-0.1.1.dist-info/entry_points.txt,sha256=09viGkCg9J3h0c9BFRN-BKaJUEaIc4JyULNgBP5EL_g,51
8
- ethspecify-0.1.1.dist-info/top_level.txt,sha256=0klaMvlVyOkXW09fwZTijJpdybITEp2c9zQKV5v30VM,11
9
- ethspecify-0.1.1.dist-info/RECORD,,