Handle the dependencies order of dataclass objects
This commit is contained in:
parent
7b43a3d772
commit
bb3c360734
54
setup.py
54
setup.py
|
@ -1,3 +1,4 @@
|
||||||
|
from enum import Enum, auto
|
||||||
from setuptools import setup, find_packages, Command
|
from setuptools import setup, find_packages, Command
|
||||||
from setuptools.command.build_py import build_py
|
from setuptools.command.build_py import build_py
|
||||||
from distutils import dir_util
|
from distutils import dir_util
|
||||||
|
@ -14,6 +15,13 @@ class SpecObject(NamedTuple):
|
||||||
custom_types: Dict[str, str]
|
custom_types: Dict[str, str]
|
||||||
constants: Dict[str, str]
|
constants: Dict[str, str]
|
||||||
ssz_objects: Dict[str, str]
|
ssz_objects: Dict[str, str]
|
||||||
|
dataclasses: Dict[str, str]
|
||||||
|
|
||||||
|
|
||||||
|
class CodeBlockType(Enum):
|
||||||
|
SSZ = auto()
|
||||||
|
DATACLASS = auto()
|
||||||
|
FUNCTION = auto()
|
||||||
|
|
||||||
|
|
||||||
def get_spec(file_name: str) -> SpecObject:
|
def get_spec(file_name: str) -> SpecObject:
|
||||||
|
@ -28,8 +36,9 @@ def get_spec(file_name: str) -> SpecObject:
|
||||||
functions: Dict[str, str] = {}
|
functions: Dict[str, str] = {}
|
||||||
constants: Dict[str, str] = {}
|
constants: Dict[str, str] = {}
|
||||||
ssz_objects: Dict[str, str] = {}
|
ssz_objects: Dict[str, str] = {}
|
||||||
|
dataclasses: Dict[str, str] = {}
|
||||||
function_matcher = re.compile(FUNCTION_REGEX)
|
function_matcher = re.compile(FUNCTION_REGEX)
|
||||||
is_ssz = False
|
block_type = CodeBlockType.FUNCTION
|
||||||
custom_types: Dict[str, str] = {}
|
custom_types: Dict[str, str] = {}
|
||||||
for linenum, line in enumerate(open(file_name).readlines()):
|
for linenum, line in enumerate(open(file_name).readlines()):
|
||||||
line = line.rstrip()
|
line = line.rstrip()
|
||||||
|
@ -43,20 +52,26 @@ def get_spec(file_name: str) -> SpecObject:
|
||||||
else:
|
else:
|
||||||
# Handle function definitions & ssz_objects
|
# Handle function definitions & ssz_objects
|
||||||
if pulling_from is not None:
|
if pulling_from is not None:
|
||||||
# SSZ Object
|
|
||||||
if len(line) > 18 and line[:6] == 'class ' and line[-12:] == '(Container):':
|
if len(line) > 18 and line[:6] == 'class ' and line[-12:] == '(Container):':
|
||||||
name = line[6:-12]
|
name = line[6:-12]
|
||||||
# Check consistency with markdown header
|
# Check consistency with markdown header
|
||||||
assert name == current_name
|
assert name == current_name
|
||||||
is_ssz = True
|
block_type = CodeBlockType.SSZ
|
||||||
# function definition
|
elif line[:10] == '@dataclass':
|
||||||
|
block_type = CodeBlockType.DATACLASS
|
||||||
elif function_matcher.match(line) is not None:
|
elif function_matcher.match(line) is not None:
|
||||||
current_name = function_matcher.match(line).group(0)
|
current_name = function_matcher.match(line).group(0)
|
||||||
is_ssz = False
|
block_type = CodeBlockType.FUNCTION
|
||||||
if is_ssz:
|
|
||||||
|
if block_type == CodeBlockType.SSZ:
|
||||||
ssz_objects[current_name] = ssz_objects.get(current_name, '') + line + '\n'
|
ssz_objects[current_name] = ssz_objects.get(current_name, '') + line + '\n'
|
||||||
else:
|
elif block_type == CodeBlockType.DATACLASS:
|
||||||
|
dataclasses[current_name] = dataclasses.get(current_name, '') + line + '\n'
|
||||||
|
elif block_type == CodeBlockType.FUNCTION:
|
||||||
functions[current_name] = functions.get(current_name, '') + line + '\n'
|
functions[current_name] = functions.get(current_name, '') + line + '\n'
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
# Handle constant and custom types table entries
|
# Handle constant and custom types table entries
|
||||||
elif pulling_from is None and len(line) > 0 and line[0] == '|':
|
elif pulling_from is None and len(line) > 0 and line[0] == '|':
|
||||||
row = line[1:].split('|')
|
row = line[1:].split('|')
|
||||||
|
@ -75,7 +90,7 @@ def get_spec(file_name: str) -> SpecObject:
|
||||||
constants[row[0]] = row[1].replace('**TBD**', '2**32')
|
constants[row[0]] = row[1].replace('**TBD**', '2**32')
|
||||||
elif row[1].startswith('uint') or row[1].startswith('Bytes'):
|
elif row[1].startswith('uint') or row[1].startswith('Bytes'):
|
||||||
custom_types[row[0]] = row[1]
|
custom_types[row[0]] = row[1]
|
||||||
return SpecObject(functions, custom_types, constants, ssz_objects)
|
return SpecObject(functions, custom_types, constants, ssz_objects, dataclasses)
|
||||||
|
|
||||||
|
|
||||||
CONFIG_LOADER = '''
|
CONFIG_LOADER = '''
|
||||||
|
@ -237,7 +252,7 @@ get_start_shard = cache_this(
|
||||||
_get_start_shard, lru_size=SLOTS_PER_EPOCH * 3)'''
|
_get_start_shard, lru_size=SLOTS_PER_EPOCH * 3)'''
|
||||||
|
|
||||||
|
|
||||||
def objects_to_spec(spec_object: SpecObject, imports: str, fork: str) -> str:
|
def objects_to_spec(spec_object: SpecObject, imports: str, fork: str, ordered_class_objects: Dict[str, str]) -> str:
|
||||||
"""
|
"""
|
||||||
Given all the objects that constitute a spec, combine them into a single pyfile.
|
Given all the objects that constitute a spec, combine them into a single pyfile.
|
||||||
"""
|
"""
|
||||||
|
@ -257,7 +272,7 @@ def objects_to_spec(spec_object: SpecObject, imports: str, fork: str) -> str:
|
||||||
if k == "BLS12_381_Q":
|
if k == "BLS12_381_Q":
|
||||||
spec_object.constants[k] += " # noqa: E501"
|
spec_object.constants[k] += " # noqa: E501"
|
||||||
constants_spec = '\n'.join(map(lambda x: '%s = %s' % (x, spec_object.constants[x]), spec_object.constants))
|
constants_spec = '\n'.join(map(lambda x: '%s = %s' % (x, spec_object.constants[x]), spec_object.constants))
|
||||||
ssz_objects_instantiation_spec = '\n\n'.join(spec_object.ssz_objects.values())
|
ordered_class_objects_spec = '\n\n'.join(ordered_class_objects.values())
|
||||||
spec = (
|
spec = (
|
||||||
imports
|
imports
|
||||||
+ '\n\n' + f"fork = \'{fork}\'\n"
|
+ '\n\n' + f"fork = \'{fork}\'\n"
|
||||||
|
@ -265,7 +280,7 @@ def objects_to_spec(spec_object: SpecObject, imports: str, fork: str) -> str:
|
||||||
+ '\n' + SUNDRY_CONSTANTS_FUNCTIONS
|
+ '\n' + SUNDRY_CONSTANTS_FUNCTIONS
|
||||||
+ '\n\n' + constants_spec
|
+ '\n\n' + constants_spec
|
||||||
+ '\n\n' + CONFIG_LOADER
|
+ '\n\n' + CONFIG_LOADER
|
||||||
+ '\n\n' + ssz_objects_instantiation_spec
|
+ '\n\n' + ordered_class_objects_spec
|
||||||
+ '\n\n' + functions_spec
|
+ '\n\n' + functions_spec
|
||||||
+ '\n' + PHASE0_SUNDRY_FUNCTIONS
|
+ '\n' + PHASE0_SUNDRY_FUNCTIONS
|
||||||
)
|
)
|
||||||
|
@ -291,11 +306,12 @@ ignored_dependencies = [
|
||||||
'bit', 'boolean', 'Vector', 'List', 'Container', 'BLSPubkey', 'BLSSignature',
|
'bit', 'boolean', 'Vector', 'List', 'Container', 'BLSPubkey', 'BLSSignature',
|
||||||
'Bytes1', 'Bytes4', 'Bytes32', 'Bytes48', 'Bytes96', 'Bitlist', 'Bitvector',
|
'Bytes1', 'Bytes4', 'Bytes32', 'Bytes48', 'Bytes96', 'Bitlist', 'Bitvector',
|
||||||
'uint8', 'uint16', 'uint32', 'uint64', 'uint128', 'uint256',
|
'uint8', 'uint16', 'uint32', 'uint64', 'uint128', 'uint256',
|
||||||
'bytes', 'byte', 'ByteList', 'ByteVector'
|
'bytes', 'byte', 'ByteList', 'ByteVector',
|
||||||
|
'Dict', 'dict', 'field',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def dependency_order_ssz_objects(objects: Dict[str, str], custom_types: Dict[str, str]) -> None:
|
def dependency_order_class_objects(objects: Dict[str, str], custom_types: Dict[str, str]) -> None:
|
||||||
"""
|
"""
|
||||||
Determines which SSZ Object is dependent on which other and orders them appropriately
|
Determines which SSZ Object is dependent on which other and orders them appropriately
|
||||||
"""
|
"""
|
||||||
|
@ -332,13 +348,14 @@ def combine_spec_objects(spec0: SpecObject, spec1: SpecObject) -> SpecObject:
|
||||||
"""
|
"""
|
||||||
Takes in two spec variants (as tuples of their objects) and combines them using the appropriate combiner function.
|
Takes in two spec variants (as tuples of their objects) and combines them using the appropriate combiner function.
|
||||||
"""
|
"""
|
||||||
functions0, custom_types0, constants0, ssz_objects0 = spec0
|
functions0, custom_types0, constants0, ssz_objects0, dataclasses0 = spec0
|
||||||
functions1, custom_types1, constants1, ssz_objects1 = spec1
|
functions1, custom_types1, constants1, ssz_objects1, dataclasses1 = spec1
|
||||||
functions = combine_functions(functions0, functions1)
|
functions = combine_functions(functions0, functions1)
|
||||||
custom_types = combine_constants(custom_types0, custom_types1)
|
custom_types = combine_constants(custom_types0, custom_types1)
|
||||||
constants = combine_constants(constants0, constants1)
|
constants = combine_constants(constants0, constants1)
|
||||||
ssz_objects = combine_ssz_objects(ssz_objects0, ssz_objects1, custom_types)
|
ssz_objects = combine_ssz_objects(ssz_objects0, ssz_objects1, custom_types)
|
||||||
return SpecObject(functions, custom_types, constants, ssz_objects)
|
dataclasses = combine_functions(dataclasses0, dataclasses1)
|
||||||
|
return SpecObject(functions, custom_types, constants, ssz_objects, dataclasses)
|
||||||
|
|
||||||
|
|
||||||
fork_imports = {
|
fork_imports = {
|
||||||
|
@ -354,9 +371,10 @@ def build_spec(fork: str, source_files: List[str]) -> str:
|
||||||
for value in all_specs[1:]:
|
for value in all_specs[1:]:
|
||||||
spec_object = combine_spec_objects(spec_object, value)
|
spec_object = combine_spec_objects(spec_object, value)
|
||||||
|
|
||||||
dependency_order_ssz_objects(spec_object.ssz_objects, spec_object.custom_types)
|
class_objects = {**spec_object.ssz_objects, **spec_object.dataclasses}
|
||||||
|
dependency_order_class_objects(class_objects, spec_object.custom_types)
|
||||||
|
|
||||||
return objects_to_spec(spec_object, fork_imports[fork], fork)
|
return objects_to_spec(spec_object, fork_imports[fork], fork, class_objects)
|
||||||
|
|
||||||
|
|
||||||
class PySpecCommand(Command):
|
class PySpecCommand(Command):
|
||||||
|
|
Loading…
Reference in New Issue