ethspecify 0.1.0__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.0
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
@@ -33,81 +33,50 @@ When that happens, they can update the implementations appropriately.
33
33
 
34
34
  ## Getting Started
35
35
 
36
- ### Adding Spec Tags
37
-
38
- In your client, add an HTML tag like this:
39
-
40
- ```
41
- /*
42
- * <spec fn="is_fully_withdrawable_validator" fork="deneb">
43
- */
44
- ```
45
-
46
- This supports all languages and comment styles. It preserves indentation, so something like this
47
- would also work:
48
-
49
- ```
50
- /// <spec fn="is_fully_withdrawable_validator" fork="deneb">
51
- ```
52
-
53
- After the script is finished executing, a new `hash` field will exist in the tag. This tag is used
54
- to tell if the specification changed, without having to include the specification content.
55
-
56
- ```
57
- /// <spec fn="is_fully_withdrawable_validator" fork="deneb" hash="e936da25" />
58
- ```
59
-
60
- > [!NOTE]
61
- > Closing tags will be added automatically. For `style="hash"` tags, a self-closing tag is used for
62
- > conciseness. For `style="full"` and `style="diff"` tags, a paired closing tag must be used.
63
-
64
36
  ### Installation
65
37
 
66
- #### Install with Pip
67
-
68
38
  ```
69
39
  python3 -mpip install ethspecify
70
40
  ```
71
41
 
72
- #### Manual Install
42
+ ### Adding Spec Tags
73
43
 
74
- First, clone the repository. You only need the latest commit.
44
+ In your client, add HTML tags like this:
75
45
 
76
46
  ```
77
- git clone https://github.com/jtraglia/ethspecify.git --depth=1
78
- cd ethspecify
47
+ /*
48
+ * <spec fn="is_fully_withdrawable_validator" fork="deneb">
49
+ */
79
50
  ```
80
51
 
81
- Next, build and install the utility.
82
-
83
52
  ```
84
- python3 -mpip install .
53
+ /*
54
+ * <spec ssz_object="BeaconState" fork="electra" style="diff">
55
+ */
85
56
  ```
86
57
 
87
- Then, change directory to the source source directory and run `ethspecify`.
58
+ ### Populating Spec Tags
59
+
60
+ Then, navigate to your codebase and run `ethspecify`:
88
61
 
89
62
  ```
90
- Projects/client$ ethspecify
91
- Processing file: /Users/user/Projects/client/src/file.ext
92
- spec tag: {'custom_type': 'Blob', 'fork': 'electra'}
93
- spec tag: {'dataclass': 'PayloadAttributes', 'fork': 'electra'}
94
- spec tag: {'ssz_object': 'ConsolidationRequest', 'fork': 'electra'}
63
+ ethspecify
95
64
  ```
96
65
 
97
- ### Specification Options
66
+ ## Specification Options
98
67
 
99
- #### Fork
68
+ ### Fork
100
69
 
101
70
  This attribute can be any of the [executable
102
71
  specifications](https://github.com/ethereum/consensus-specs/blob/e6bddd966214a19d2b97199bbe3c02577a22a8b4/Makefile#L3-L15)
103
72
  in the consensus-specs. At the time of writing, these are: phase0, altair, bellatrix, capella,
104
73
  deneb, electra, fulu, whisk, eip6800, and eip7732.
105
74
 
106
- #### Style
75
+ ### Style
107
76
 
108
77
  This attribute can be used to change how the specification content is shown.
109
78
 
110
- ##### `hash` (default)
79
+ #### `hash` (default)
111
80
 
112
81
  This style adds a hash of the specification content to the spec tag, without showing the content.
113
82
 
@@ -120,7 +89,7 @@ This style adds a hash of the specification content to the spec tag, without sho
120
89
  > [!NOTE]
121
90
  > The hash is the first 8 characters of the specification content's SHA256 digest.
122
91
 
123
- ##### `full`
92
+ #### `full`
124
93
 
125
94
  This style displays the whole content of this specification item, including comments.
126
95
 
@@ -140,10 +109,7 @@ This style displays the whole content of this specification item, including comm
140
109
  */
141
110
  ```
142
111
 
143
- ##### `link`
144
-
145
- > [!WARNING]
146
- > This feature is a work-in-progress.
112
+ #### `link`
147
113
 
148
114
  This style displays a GitHub link to the specification item.
149
115
 
@@ -155,7 +121,7 @@ This style displays a GitHub link to the specification item.
155
121
  */
156
122
  ```
157
123
 
158
- ##### `diff`
124
+ #### `diff`
159
125
 
160
126
  This style displays a diff with the previous fork's version of the specification.
161
127
 
@@ -203,9 +169,9 @@ This can be used with any specification item, like functions too:
203
169
  */
204
170
  ```
205
171
 
206
- ### Supported Specification Items
172
+ ## Supported Specification Items
207
173
 
208
- #### Constants
174
+ ### Constants
209
175
 
210
176
  These are items found in the `Constants` section of the specifications.
211
177
 
@@ -217,7 +183,7 @@ These are items found in the `Constants` section of the specifications.
217
183
  */
218
184
  ```
219
185
 
220
- #### Custom Types
186
+ ### Custom Types
221
187
 
222
188
  These are items found in the `Custom types` section of the specifications.
223
189
 
@@ -229,7 +195,7 @@ These are items found in the `Custom types` section of the specifications.
229
195
  */
230
196
  ```
231
197
 
232
- #### Preset Variables
198
+ ### Preset Variables
233
199
 
234
200
  These are items found in the
235
201
  [`presets`](https://github.com/ethereum/consensus-specs/tree/dev/presets) directory.
@@ -259,7 +225,7 @@ It's not strictly necessary to specify the preset attribute. The default preset
259
225
  */
260
226
  ```
261
227
 
262
- #### Config Variables
228
+ ### Config Variables
263
229
 
264
230
  These are items found in the
265
231
  [`configs`](https://github.com/ethereum/consensus-specs/tree/dev/presets) directory.
@@ -272,7 +238,7 @@ These are items found in the
272
238
  */
273
239
  ```
274
240
 
275
- #### SSZ Objects
241
+ ### SSZ Objects
276
242
 
277
243
  These are items found in the `Containers` section of the specifications.
278
244
 
@@ -287,7 +253,7 @@ These are items found in the `Containers` section of the specifications.
287
253
  */
288
254
  ```
289
255
 
290
- #### Dataclasses
256
+ ### Dataclasses
291
257
 
292
258
  These are classes with the `@dataclass` decorator.
293
259
 
@@ -304,7 +270,7 @@ These are classes with the `@dataclass` decorator.
304
270
  */
305
271
  ```
306
272
 
307
- #### Functions
273
+ ### Functions
308
274
 
309
275
  These are all the functions found in the specifications.
310
276
 
@@ -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.0.dist-info/LICENSE,sha256=Awxsr73mm9YMBVhBYnzeI7bNdRd-bH6RDtO5ItG0DaM,1071
5
- ethspecify-0.1.0.dist-info/METADATA,sha256=-ot8oXPC7HfNHVD6_ZCcwn7oZJ6EHN5bJeQL9ERByDg,9965
6
- ethspecify-0.1.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
7
- ethspecify-0.1.0.dist-info/entry_points.txt,sha256=09viGkCg9J3h0c9BFRN-BKaJUEaIc4JyULNgBP5EL_g,51
8
- ethspecify-0.1.0.dist-info/top_level.txt,sha256=0klaMvlVyOkXW09fwZTijJpdybITEp2c9zQKV5v30VM,11
9
- ethspecify-0.1.0.dist-info/RECORD,,