ethspecify 0.2.3__tar.gz → 0.2.5__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.

Potentially problematic release.


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

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ethspecify
3
- Version: 0.2.3
3
+ Version: 0.2.5
4
4
  Summary: A utility for processing Ethereum specification tags.
5
5
  Home-page: https://github.com/jtraglia/ethspecify
6
6
  Author: Justin Traglia
@@ -745,14 +745,21 @@ def check_source_files(yaml_file, project_root, exceptions=None):
745
745
  return valid_count, total_count, errors
746
746
 
747
747
 
748
- def extract_spec_tags_from_yaml(yaml_file, tag_type):
748
+ def extract_spec_tags_from_yaml(yaml_file, tag_type=None):
749
749
  """
750
- Extract spec tags from a YAML file and return item#fork pairs.
750
+ Extract spec tags from a YAML file and return (tag_types_found, item#fork pairs).
751
+ If tag_type is provided, only extract tags of that type.
751
752
  """
752
753
  if not os.path.exists(yaml_file):
753
- return set()
754
+ return set(), set()
754
755
 
755
756
  pairs = set()
757
+ tag_types_found = set()
758
+
759
+ # Known tag type attributes
760
+ tag_attributes = ['fn', 'function', 'constant_var', 'config_var', 'preset_var',
761
+ 'ssz_object', 'dataclass', 'custom_type']
762
+
756
763
  try:
757
764
  with open(yaml_file, 'r') as f:
758
765
  content_str = f.read()
@@ -768,7 +775,7 @@ def extract_spec_tags_from_yaml(yaml_file, tag_type):
768
775
  content = yaml.load(content_str, Loader=yaml.FullLoader)
769
776
 
770
777
  if not content:
771
- return set()
778
+ return tag_types_found, pairs
772
779
 
773
780
  # Handle both array of objects and single object formats
774
781
  items = content if isinstance(content, list) else [content]
@@ -781,20 +788,41 @@ def extract_spec_tags_from_yaml(yaml_file, tag_type):
781
788
  if not isinstance(spec_content, str):
782
789
  continue
783
790
 
784
- # Find spec tags using regex in the spec field
785
- pattern = rf'<spec\s+{tag_type}="([^"]+)"[^>]*fork="([^"]+)"'
786
- matches = re.findall(pattern, spec_content)
791
+ # Find all spec tags in the content
792
+ spec_tag_pattern = r'<spec\s+([^>]+)>'
793
+ spec_matches = re.findall(spec_tag_pattern, spec_content)
794
+
795
+ for tag_attrs_str in spec_matches:
796
+ # Extract all attributes from the tag
797
+ attrs = dict(re.findall(r'(\w+)="([^"]+)"', tag_attrs_str))
798
+
799
+ # Find which tag type this is
800
+ found_tag_type = None
801
+ item_name = None
802
+
803
+ for attr in tag_attributes:
804
+ if attr in attrs:
805
+ found_tag_type = attr
806
+ item_name = attrs[attr]
807
+ # Normalize function to fn
808
+ if found_tag_type == 'function':
809
+ found_tag_type = 'fn'
810
+ break
811
+
812
+ if found_tag_type and 'fork' in attrs:
813
+ tag_types_found.add(found_tag_type)
787
814
 
788
- for match_item, fork in matches:
789
- pairs.add(f"{match_item}#{fork}")
815
+ # If tag_type filter is specified, only add matching types
816
+ if tag_type is None or tag_type == found_tag_type:
817
+ pairs.add(f"{item_name}#{attrs['fork']}")
790
818
 
791
819
  except (IOError, UnicodeDecodeError, yaml.YAMLError):
792
820
  pass
793
821
 
794
- return pairs
822
+ return tag_types_found, pairs
795
823
 
796
824
 
797
- def check_coverage(yaml_file, tag_type, exceptions, preset="mainnet"):
825
+ def check_coverage(yaml_file, tag_type, exceptions, preset="mainnet", version="nightly"):
798
826
  """
799
827
  Check that all spec items from ethspecify have corresponding tags in the YAML file.
800
828
  Returns (found_count, total_count, missing_items)
@@ -811,7 +839,7 @@ def check_coverage(yaml_file, tag_type, exceptions, preset="mainnet"):
811
839
  }
812
840
 
813
841
  # Get expected items from ethspecify
814
- history = get_spec_item_history(preset)
842
+ history = get_spec_item_history(preset, version)
815
843
  expected_pairs = set()
816
844
 
817
845
  history_key = history_key_map.get(tag_type, tag_type)
@@ -821,7 +849,7 @@ def check_coverage(yaml_file, tag_type, exceptions, preset="mainnet"):
821
849
  expected_pairs.add(f"{item_name}#{fork}")
822
850
 
823
851
  # Get actual pairs from YAML file
824
- actual_pairs = extract_spec_tags_from_yaml(yaml_file, tag_type)
852
+ _, actual_pairs = extract_spec_tags_from_yaml(yaml_file, tag_type)
825
853
 
826
854
  # Find missing items (excluding exceptions)
827
855
  missing_items = []
@@ -848,6 +876,9 @@ def run_checks(project_dir, config):
848
876
  results = {}
849
877
  overall_success = True
850
878
 
879
+ # Get version from config
880
+ version = config.get('version', 'nightly')
881
+
851
882
  # Get specrefs config
852
883
  specrefs_config = config.get('specrefs', {})
853
884
 
@@ -866,14 +897,15 @@ def run_checks(project_dir, config):
866
897
  print("Please add a 'specrefs:' section with 'files:' listing the files to check")
867
898
  return False, {}
868
899
 
869
- # File type mapping for coverage checking
870
- file_type_mapping = {
871
- 'ssz-objects': 'ssz_object',
872
- 'config-variables': 'config_var',
873
- 'preset-variables': 'preset_var',
874
- 'dataclasses': 'dataclass',
875
- 'functions': 'fn',
876
- 'constants': 'constant_var',
900
+ # Map tag types to exception keys (support both singular and plural)
901
+ exception_key_map = {
902
+ 'ssz_object': ['ssz_objects', 'ssz_object'],
903
+ 'config_var': ['configs', 'config_variables', 'config_var'],
904
+ 'preset_var': ['presets', 'preset_variables', 'preset_var'],
905
+ 'dataclass': ['dataclasses', 'dataclass'],
906
+ 'fn': ['functions', 'fn'],
907
+ 'constant_var': ['constants', 'constant_variables', 'constant_var'],
908
+ 'custom_type': ['custom_types', 'custom_type']
877
909
  }
878
910
 
879
911
  # Use explicit file list only
@@ -885,67 +917,91 @@ def run_checks(project_dir, config):
885
917
  overall_success = False
886
918
  continue
887
919
 
888
- # Determine the tag type from filename for coverage checking
889
- tag_type = None
890
- preset = "mainnet" # default preset
920
+ # Detect tag types in the file
921
+ tag_types_found, _ = extract_spec_tags_from_yaml(yaml_path)
891
922
 
892
- for pattern, file_tag_type in file_type_mapping.items():
893
- if pattern in filename:
894
- tag_type = file_tag_type
895
- # Check for preset indicators
896
- if 'minimal' in filename.lower():
897
- preset = "minimal"
898
- break
899
-
900
- # Get the appropriate exceptions for this file type
901
- section_exceptions = []
902
- if tag_type:
903
- # Map tag types to exception keys (support both singular and plural)
904
- exception_key_map = {
905
- 'ssz_object': ['ssz_objects', 'ssz_object'],
906
- 'config_var': ['configs', 'config_variables', 'config_var'],
907
- 'preset_var': ['presets', 'preset_variables', 'preset_var'],
908
- 'dataclass': ['dataclasses', 'dataclass'],
909
- 'fn': ['functions', 'fn'],
910
- 'constant_var': ['constants', 'constant_variables', 'constant_var'],
911
- 'custom_type': ['custom_types', 'custom_type']
923
+ # Check for preset indicators in filename
924
+ preset = "mainnet" # default preset
925
+ if 'minimal' in filename.lower():
926
+ preset = "minimal"
927
+
928
+ # Process each tag type found in the file
929
+ if not tag_types_found:
930
+ # No spec tags found, still check source files
931
+ valid_count, total_count, source_errors = check_source_files(yaml_path, os.path.dirname(project_dir), [])
932
+
933
+ # Store results using filename as section name
934
+ section_name = filename.replace('.yml', '').replace('-', ' ').title()
935
+ if preset != "mainnet":
936
+ section_name += f" ({preset.title()})"
937
+
938
+ results[section_name] = {
939
+ 'source_files': {
940
+ 'valid': valid_count,
941
+ 'total': total_count,
942
+ 'errors': source_errors
943
+ },
944
+ 'coverage': {
945
+ 'found': 0,
946
+ 'expected': 0,
947
+ 'missing': []
948
+ }
912
949
  }
913
950
 
914
- # Try plural first, then singular for backward compatibility
915
- if tag_type in exception_key_map:
916
- for key in exception_key_map[tag_type]:
917
- if key in exceptions:
918
- section_exceptions = exceptions[key]
919
- break
951
+ if source_errors:
952
+ overall_success = False
953
+ else:
954
+ # Process each tag type separately for better reporting
955
+ all_missing_items = []
956
+ total_found = 0
957
+ total_expected = 0
958
+
959
+ for tag_type in tag_types_found:
960
+ # Get the appropriate exceptions for this tag type
961
+ section_exceptions = []
962
+ if tag_type in exception_key_map:
963
+ for key in exception_key_map[tag_type]:
964
+ if key in exceptions:
965
+ section_exceptions = exceptions[key]
966
+ break
920
967
 
921
- # Check source files
922
- valid_count, total_count, source_errors = check_source_files(yaml_path, os.path.dirname(project_dir), section_exceptions)
923
-
924
- # Check coverage if we can determine the type
925
- found_count, expected_count, missing_items = 0, 0, []
926
- if tag_type:
927
- found_count, expected_count, missing_items = check_coverage(yaml_path, tag_type, section_exceptions, preset)
928
-
929
- # Store results using filename as section name
930
- section_name = filename.replace('.yml', '').replace('-', ' ').title()
931
- if preset != "mainnet":
932
- section_name += f" ({preset.title()})"
933
-
934
- results[section_name] = {
935
- 'source_files': {
936
- 'valid': valid_count,
937
- 'total': total_count,
938
- 'errors': source_errors
939
- },
940
- 'coverage': {
941
- 'found': found_count,
942
- 'expected': expected_count,
943
- 'missing': missing_items
968
+ # Check coverage for this specific tag type
969
+ found_count, expected_count, missing_items = check_coverage(yaml_path, tag_type, section_exceptions, preset, version)
970
+ total_found += found_count
971
+ total_expected += expected_count
972
+ all_missing_items.extend(missing_items)
973
+
974
+ # Check source files (only once per file, not per tag type)
975
+ # Use the union of all exceptions for source file checking
976
+ all_exceptions = []
977
+ for tag_type in tag_types_found:
978
+ if tag_type in exception_key_map:
979
+ for key in exception_key_map[tag_type]:
980
+ if key in exceptions:
981
+ all_exceptions.extend(exceptions[key])
982
+
983
+ valid_count, total_count, source_errors = check_source_files(yaml_path, os.path.dirname(project_dir), all_exceptions)
984
+
985
+ # Store results using filename as section name
986
+ section_name = filename.replace('.yml', '').replace('-', ' ').title()
987
+ if preset != "mainnet":
988
+ section_name += f" ({preset.title()})"
989
+
990
+ results[section_name] = {
991
+ 'source_files': {
992
+ 'valid': valid_count,
993
+ 'total': total_count,
994
+ 'errors': source_errors
995
+ },
996
+ 'coverage': {
997
+ 'found': total_found,
998
+ 'expected': total_expected,
999
+ 'missing': all_missing_items
1000
+ }
944
1001
  }
945
- }
946
1002
 
947
- # Update overall success
948
- if source_errors or missing_items:
949
- overall_success = False
1003
+ # Update overall success
1004
+ if source_errors or all_missing_items:
1005
+ overall_success = False
950
1006
 
951
1007
  return overall_success, results
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ethspecify
3
- Version: 0.2.3
3
+ Version: 0.2.5
4
4
  Summary: A utility for processing Ethereum specification tags.
5
5
  Home-page: https://github.com/jtraglia/ethspecify
6
6
  Author: Justin Traglia
@@ -8,7 +8,7 @@ long_description = (this_directory / "README.md").read_text(encoding="utf-8")
8
8
 
9
9
  setup(
10
10
  name="ethspecify",
11
- version="0.2.3",
11
+ version="0.2.5",
12
12
  description="A utility for processing Ethereum specification tags.",
13
13
  long_description=long_description,
14
14
  long_description_content_type="text/markdown",
File without changes
File without changes
File without changes
File without changes