prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  add linter to CI
  Add a new job to CI that uses `flake8` or something similar to lint the the pyspec after the python code is dumped to `spec.py`.
  
  This will likely need a bit of configuration (`maxline=120`, etc) and some cleaning up.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `scripts/phase0/function_puller.py`
  Content:
  ```
  1 import sys
  2 from typing import List
  3 
  4 
  5 def get_spec(file_name: str) -> List[str]:
  6     code_lines = []
  7     pulling_from = None
  8     current_name = None
  9     current_typedef = None
  10     type_defs = []
  11     for linenum, line in enumerate(open(sys.argv[1]).readlines()):
  12         line = line.rstrip()
  13         if pulling_from is None and len(line) > 0 and line[0] == '#' and line[-1] == '`':
  14             current_name = line[line[:-1].rfind('`') + 1: -1]
  15         if line[:9] == '```python':
  16             assert pulling_from is None
  17             pulling_from = linenum + 1
  18         elif line[:3] == '```':
  19             if pulling_from is None:
  20                 pulling_from = linenum
  21             else:
  22                 if current_typedef is not None:
  23                     assert code_lines[-1] == '}'
  24                     code_lines[-1] = '})'
  25                     current_typedef[-1] = '})'
  26                     type_defs.append((current_name, current_typedef))
  27                 pulling_from = None
  28                 current_typedef = None
  29         else:
  30             if pulling_from == linenum and line == '{':
  31                 code_lines.append('%s = SSZType({' % current_name)
  32                 current_typedef = ['global_vars["%s"] = SSZType({' % current_name]
  33             elif pulling_from is not None:
  34                 # Add some whitespace between functions
  35                 if line[:3] == 'def':
  36                     code_lines.append('')
  37                     code_lines.append('')
  38                 code_lines.append(line)
  39                 # Remember type def lines
  40                 if current_typedef is not None:
  41                     current_typedef.append(line)
  42             elif pulling_from is None and len(line) > 0 and line[0] == '|':
  43                 row = line[1:].split('|')
  44                 if len(row) >= 2:
  45                     for i in range(2):
  46                         row[i] = row[i].strip().strip('`')
  47                         if '`' in row[i]:
  48                             row[i] = row[i][:row[i].find('`')]
  49                     eligible = True
  50                     if row[0][0] not in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_':
  51                         eligible = False
  52                     for c in row[0]:
  53                         if c not in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789':
  54                             eligible = False
  55                     if eligible:
  56                         code_lines.append(row[0] + ' = ' + (row[1].replace('**TBD**', '0x1234567890123456789012345678901234567890')))
  57     # Build type-def re-initialization
  58     code_lines.append('')
  59     code_lines.append('def init_SSZ_types():')
  60     code_lines.append('    global_vars = globals()')
  61     for ssz_type_name, ssz_type in type_defs:
  62         code_lines.append('')
  63         for type_line in ssz_type:
  64             code_lines.append('    ' + type_line)
  65     code_lines.append('\n')
  66     code_lines.append('ssz_types = [' + ', '.join([f'\'{ssz_type_name}\'' for (ssz_type_name, _) in type_defs]) + ']')
  67     code_lines.append('\n')
  68     code_lines.append('def get_ssz_type_by_name(name: str) -> SSZType:')
  69     code_lines.append('    return globals()[name]')
  70     code_lines.append('')
  71     return code_lines
  72
  ```
  
  Path: `scripts/phase0/build_spec.py`
  Content:
  ```
  1 import sys
  2 import function_puller
  3 
  4 
  5 def build_phase0_spec(sourcefile, outfile):
  6     code_lines = []
  7     code_lines.append("""
  8 from typing import (
  9     Any,
  10     Dict,
  11     List,
  12     NewType,
  13     Tuple,
  14 )
  15 from eth2spec.utils.minimal_ssz import *
  16 from eth2spec.utils.bls_stub import *
  17 
  18 # stub, will get overwritten by real var
  19 SLOTS_PER_EPOCH = 64
  20 
  21 Slot = NewType('Slot', int)  # uint64
  22 Epoch = NewType('Epoch', int)  # uint64
  23 Shard = NewType('Shard', int)  # uint64
  24 ValidatorIndex = NewType('ValidatorIndex', int)  # uint64
  25 Gwei = NewType('Gwei', int)  # uint64
  26 Bytes32 = NewType('Bytes32', bytes)  # bytes32
  27 BLSPubkey = NewType('BLSPubkey', bytes)  # bytes48
  28 BLSSignature = NewType('BLSSignature', bytes)  # bytes96
  29 Store = None
  30 """)
  31 
  32     code_lines += function_puller.get_spec(sourcefile)
  33 
  34     code_lines.append("""
  35 # Monkey patch validator compute committee code
  36 _compute_committee = compute_committee
  37 committee_cache = {}
  38 
  39 
  40 def compute_committee(indices: List[ValidatorIndex], seed: Bytes32, index: int, count: int) -> List[ValidatorIndex]:
  41     param_hash = (hash_tree_root(indices), seed, index, count)
  42 
  43     if param_hash in committee_cache:
  44         return committee_cache[param_hash]
  45     else:
  46         ret = _compute_committee(indices, seed, index, count)
  47         committee_cache[param_hash] = ret
  48         return ret
  49 
  50 
  51 # Monkey patch hash cache
  52 _hash = hash
  53 hash_cache = {}
  54 
  55 
  56 def hash(x):
  57     if x in hash_cache:
  58         return hash_cache[x]
  59     else:
  60         ret = _hash(x)
  61         hash_cache[x] = ret
  62         return ret
  63 
  64 # Access to overwrite spec constants based on configuration
  65 def apply_constants_preset(preset: Dict[str, Any]):
  66     global_vars = globals()
  67     for k, v in preset.items():
  68         global_vars[k] = v
  69 
  70     # Deal with derived constants
  71     global_vars['GENESIS_EPOCH'] = slot_to_epoch(GENESIS_SLOT)
  72 
  73     # Initialize SSZ types again, to account for changed lengths
  74     init_SSZ_types()
  75 """)
  76 
  77     with open(outfile, 'w') as out:
  78         out.write("\n".join(code_lines))
  79 
  80 
  81 if __name__ == '__main__':
  82     if len(sys.argv) < 3:
  83         print("Usage: <source phase0> <output phase0 pyspec>")
  84     build_phase0_spec(sys.argv[1], sys.argv[2])
  85 
  86
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/scripts/phase0/build_spec.py b/scripts/phase0/build_spec.py
  --- a/scripts/phase0/build_spec.py
  +++ b/scripts/phase0/build_spec.py
  @@ -12,8 +12,18 @@
       NewType,
       Tuple,
   )
  -from eth2spec.utils.minimal_ssz import *
  -from eth2spec.utils.bls_stub import *
  +from eth2spec.utils.minimal_ssz import (
  +    SSZType,
  +    hash_tree_root,
  +    signing_root,
  +)
  +from eth2spec.utils.bls_stub import (
  +    bls_aggregate_pubkeys,
  +    bls_verify,
  +    bls_verify_multiple,
  +)
  +from eth2spec.utils.hash_function import hash
  +
   
   # stub, will get overwritten by real var
   SLOTS_PER_EPOCH = 64
  @@ -61,6 +71,7 @@
           hash_cache[x] = ret
           return ret
   
  +
   # Access to overwrite spec constants based on configuration
   def apply_constants_preset(preset: Dict[str, Any]):
       global_vars = globals()
  diff --git a/scripts/phase0/function_puller.py b/scripts/phase0/function_puller.py
  --- a/scripts/phase0/function_puller.py
  +++ b/scripts/phase0/function_puller.py
  @@ -55,15 +55,19 @@
                       if eligible:
                           code_lines.append(row[0] + ' = ' + (row[1].replace('**TBD**', '0x1234567890123456789012345678901234567890')))
       # Build type-def re-initialization
  -    code_lines.append('')
  +    code_lines.append('\n')
       code_lines.append('def init_SSZ_types():')
       code_lines.append('    global_vars = globals()')
       for ssz_type_name, ssz_type in type_defs:
           code_lines.append('')
           for type_line in ssz_type:
  -            code_lines.append('    ' + type_line)
  +            if len(type_line) > 0:
  +                code_lines.append('    ' + type_line)
       code_lines.append('\n')
  -    code_lines.append('ssz_types = [' + ', '.join([f'\'{ssz_type_name}\'' for (ssz_type_name, _) in type_defs]) + ']')
  +    code_lines.append('ssz_types = [\n')
  +    for (ssz_type_name, _) in type_defs:
  +        code_lines.append(f'    {ssz_type_name},\n')
  +    code_lines.append(']')
       code_lines.append('\n')
       code_lines.append('def get_ssz_type_by_name(name: str) -> SSZType:')
       code_lines.append('    return globals()[name]')
  
verification_info: {"golden_diff": "diff --git a/scripts/phase0/build_spec.py b/scripts/phase0/build_spec.py\n--- a/scripts/phase0/build_spec.py\n+++ b/scripts/phase0/build_spec.py\n@@ -12,8 +12,18 @@\n     NewType,\n     Tuple,\n )\n-from eth2spec.utils.minimal_ssz import *\n-from eth2spec.utils.bls_stub import *\n+from eth2spec.utils.minimal_ssz import (\n+    SSZType,\n+    hash_tree_root,\n+    signing_root,\n+)\n+from eth2spec.utils.bls_stub import (\n+    bls_aggregate_pubkeys,\n+    bls_verify,\n+    bls_verify_multiple,\n+)\n+from eth2spec.utils.hash_function import hash\n+\n \n # stub, will get overwritten by real var\n SLOTS_PER_EPOCH = 64\n@@ -61,6 +71,7 @@\n         hash_cache[x] = ret\n         return ret\n \n+\n # Access to overwrite spec constants based on configuration\n def apply_constants_preset(preset: Dict[str, Any]):\n     global_vars = globals()\ndiff --git a/scripts/phase0/function_puller.py b/scripts/phase0/function_puller.py\n--- a/scripts/phase0/function_puller.py\n+++ b/scripts/phase0/function_puller.py\n@@ -55,15 +55,19 @@\n                     if eligible:\n                         code_lines.append(row[0] + ' = ' + (row[1].replace('**TBD**', '0x1234567890123456789012345678901234567890')))\n     # Build type-def re-initialization\n-    code_lines.append('')\n+    code_lines.append('\\n')\n     code_lines.append('def init_SSZ_types():')\n     code_lines.append('    global_vars = globals()')\n     for ssz_type_name, ssz_type in type_defs:\n         code_lines.append('')\n         for type_line in ssz_type:\n-            code_lines.append('    ' + type_line)\n+            if len(type_line) > 0:\n+                code_lines.append('    ' + type_line)\n     code_lines.append('\\n')\n-    code_lines.append('ssz_types = [' + ', '.join([f'\\'{ssz_type_name}\\'' for (ssz_type_name, _) in type_defs]) + ']')\n+    code_lines.append('ssz_types = [\\n')\n+    for (ssz_type_name, _) in type_defs:\n+        code_lines.append(f'    {ssz_type_name},\\n')\n+    code_lines.append(']')\n     code_lines.append('\\n')\n     code_lines.append('def get_ssz_type_by_name(name: str) -> SSZType:')\n     code_lines.append('    return globals()[name]')\n", "issue": "add linter to CI\nAdd a new job to CI that uses `flake8` or something similar to lint the the pyspec after the python code is dumped to `spec.py`.\r\n\r\nThis will likely need a bit of configuration (`maxline=120`, etc) and some cleaning up.\n", "before_files": [{"content": "import sys\nfrom typing import List\n\n\ndef get_spec(file_name: str) -> List[str]:\n    code_lines = []\n    pulling_from = None\n    current_name = None\n    current_typedef = None\n    type_defs = []\n    for linenum, line in enumerate(open(sys.argv[1]).readlines()):\n        line = line.rstrip()\n        if pulling_from is None and len(line) > 0 and line[0] == '#' and line[-1] == '`':\n            current_name = line[line[:-1].rfind('`') + 1: -1]\n        if line[:9] == '```python':\n            assert pulling_from is None\n            pulling_from = linenum + 1\n        elif line[:3] == '```':\n            if pulling_from is None:\n                pulling_from = linenum\n            else:\n                if current_typedef is not None:\n                    assert code_lines[-1] == '}'\n                    code_lines[-1] = '})'\n                    current_typedef[-1] = '})'\n                    type_defs.append((current_name, current_typedef))\n                pulling_from = None\n                current_typedef = None\n        else:\n            if pulling_from == linenum and line == '{':\n                code_lines.append('%s = SSZType({' % current_name)\n                current_typedef = ['global_vars[\"%s\"] = SSZType({' % current_name]\n            elif pulling_from is not None:\n                # Add some whitespace between functions\n                if line[:3] == 'def':\n                    code_lines.append('')\n                    code_lines.append('')\n                code_lines.append(line)\n                # Remember type def lines\n                if current_typedef is not None:\n                    current_typedef.append(line)\n            elif pulling_from is None and len(line) > 0 and line[0] == '|':\n                row = line[1:].split('|')\n                if len(row) >= 2:\n                    for i in range(2):\n                        row[i] = row[i].strip().strip('`')\n                        if '`' in row[i]:\n                            row[i] = row[i][:row[i].find('`')]\n                    eligible = True\n                    if row[0][0] not in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_':\n                        eligible = False\n                    for c in row[0]:\n                        if c not in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789':\n                            eligible = False\n                    if eligible:\n                        code_lines.append(row[0] + ' = ' + (row[1].replace('**TBD**', '0x1234567890123456789012345678901234567890')))\n    # Build type-def re-initialization\n    code_lines.append('')\n    code_lines.append('def init_SSZ_types():')\n    code_lines.append('    global_vars = globals()')\n    for ssz_type_name, ssz_type in type_defs:\n        code_lines.append('')\n        for type_line in ssz_type:\n            code_lines.append('    ' + type_line)\n    code_lines.append('\\n')\n    code_lines.append('ssz_types = [' + ', '.join([f'\\'{ssz_type_name}\\'' for (ssz_type_name, _) in type_defs]) + ']')\n    code_lines.append('\\n')\n    code_lines.append('def get_ssz_type_by_name(name: str) -> SSZType:')\n    code_lines.append('    return globals()[name]')\n    code_lines.append('')\n    return code_lines\n", "path": "scripts/phase0/function_puller.py"}, {"content": "import sys\nimport function_puller\n\n\ndef build_phase0_spec(sourcefile, outfile):\n    code_lines = []\n    code_lines.append(\"\"\"\nfrom typing import (\n    Any,\n    Dict,\n    List,\n    NewType,\n    Tuple,\n)\nfrom eth2spec.utils.minimal_ssz import *\nfrom eth2spec.utils.bls_stub import *\n\n# stub, will get overwritten by real var\nSLOTS_PER_EPOCH = 64\n\nSlot = NewType('Slot', int)  # uint64\nEpoch = NewType('Epoch', int)  # uint64\nShard = NewType('Shard', int)  # uint64\nValidatorIndex = NewType('ValidatorIndex', int)  # uint64\nGwei = NewType('Gwei', int)  # uint64\nBytes32 = NewType('Bytes32', bytes)  # bytes32\nBLSPubkey = NewType('BLSPubkey', bytes)  # bytes48\nBLSSignature = NewType('BLSSignature', bytes)  # bytes96\nStore = None\n\"\"\")\n\n    code_lines += function_puller.get_spec(sourcefile)\n\n    code_lines.append(\"\"\"\n# Monkey patch validator compute committee code\n_compute_committee = compute_committee\ncommittee_cache = {}\n\n\ndef compute_committee(indices: List[ValidatorIndex], seed: Bytes32, index: int, count: int) -> List[ValidatorIndex]:\n    param_hash = (hash_tree_root(indices), seed, index, count)\n\n    if param_hash in committee_cache:\n        return committee_cache[param_hash]\n    else:\n        ret = _compute_committee(indices, seed, index, count)\n        committee_cache[param_hash] = ret\n        return ret\n\n\n# Monkey patch hash cache\n_hash = hash\nhash_cache = {}\n\n\ndef hash(x):\n    if x in hash_cache:\n        return hash_cache[x]\n    else:\n        ret = _hash(x)\n        hash_cache[x] = ret\n        return ret\n\n# Access to overwrite spec constants based on configuration\ndef apply_constants_preset(preset: Dict[str, Any]):\n    global_vars = globals()\n    for k, v in preset.items():\n        global_vars[k] = v\n\n    # Deal with derived constants\n    global_vars['GENESIS_EPOCH'] = slot_to_epoch(GENESIS_SLOT)\n\n    # Initialize SSZ types again, to account for changed lengths\n    init_SSZ_types()\n\"\"\")\n\n    with open(outfile, 'w') as out:\n        out.write(\"\\n\".join(code_lines))\n\n\nif __name__ == '__main__':\n    if len(sys.argv) < 3:\n        print(\"Usage: <source phase0> <output phase0 pyspec>\")\n    build_phase0_spec(sys.argv[1], sys.argv[2])\n\n", "path": "scripts/phase0/build_spec.py"}], "after_files": [{"content": "import sys\nfrom typing import List\n\n\ndef get_spec(file_name: str) -> List[str]:\n    code_lines = []\n    pulling_from = None\n    current_name = None\n    current_typedef = None\n    type_defs = []\n    for linenum, line in enumerate(open(sys.argv[1]).readlines()):\n        line = line.rstrip()\n        if pulling_from is None and len(line) > 0 and line[0] == '#' and line[-1] == '`':\n            current_name = line[line[:-1].rfind('`') + 1: -1]\n        if line[:9] == '```python':\n            assert pulling_from is None\n            pulling_from = linenum + 1\n        elif line[:3] == '```':\n            if pulling_from is None:\n                pulling_from = linenum\n            else:\n                if current_typedef is not None:\n                    assert code_lines[-1] == '}'\n                    code_lines[-1] = '})'\n                    current_typedef[-1] = '})'\n                    type_defs.append((current_name, current_typedef))\n                pulling_from = None\n                current_typedef = None\n        else:\n            if pulling_from == linenum and line == '{':\n                code_lines.append('%s = SSZType({' % current_name)\n                current_typedef = ['global_vars[\"%s\"] = SSZType({' % current_name]\n            elif pulling_from is not None:\n                # Add some whitespace between functions\n                if line[:3] == 'def':\n                    code_lines.append('')\n                    code_lines.append('')\n                code_lines.append(line)\n                # Remember type def lines\n                if current_typedef is not None:\n                    current_typedef.append(line)\n            elif pulling_from is None and len(line) > 0 and line[0] == '|':\n                row = line[1:].split('|')\n                if len(row) >= 2:\n                    for i in range(2):\n                        row[i] = row[i].strip().strip('`')\n                        if '`' in row[i]:\n                            row[i] = row[i][:row[i].find('`')]\n                    eligible = True\n                    if row[0][0] not in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_':\n                        eligible = False\n                    for c in row[0]:\n                        if c not in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789':\n                            eligible = False\n                    if eligible:\n                        code_lines.append(row[0] + ' = ' + (row[1].replace('**TBD**', '0x1234567890123456789012345678901234567890')))\n    # Build type-def re-initialization\n    code_lines.append('\\n')\n    code_lines.append('def init_SSZ_types():')\n    code_lines.append('    global_vars = globals()')\n    for ssz_type_name, ssz_type in type_defs:\n        code_lines.append('')\n        for type_line in ssz_type:\n            if len(type_line) > 0:\n                code_lines.append('    ' + type_line)\n    code_lines.append('\\n')\n    code_lines.append('ssz_types = [\\n')\n    for (ssz_type_name, _) in type_defs:\n        code_lines.append(f'    {ssz_type_name},\\n')\n    code_lines.append(']')\n    code_lines.append('\\n')\n    code_lines.append('def get_ssz_type_by_name(name: str) -> SSZType:')\n    code_lines.append('    return globals()[name]')\n    code_lines.append('')\n    return code_lines\n", "path": "scripts/phase0/function_puller.py"}, {"content": "import sys\nimport function_puller\n\n\ndef build_phase0_spec(sourcefile, outfile):\n    code_lines = []\n    code_lines.append(\"\"\"\nfrom typing import (\n    Any,\n    Dict,\n    List,\n    NewType,\n    Tuple,\n)\nfrom eth2spec.utils.minimal_ssz import (\n    SSZType,\n    hash_tree_root,\n    signing_root,\n)\nfrom eth2spec.utils.bls_stub import (\n    bls_aggregate_pubkeys,\n    bls_verify,\n    bls_verify_multiple,\n)\nfrom eth2spec.utils.hash_function import hash\n\n\n# stub, will get overwritten by real var\nSLOTS_PER_EPOCH = 64\n\nSlot = NewType('Slot', int)  # uint64\nEpoch = NewType('Epoch', int)  # uint64\nShard = NewType('Shard', int)  # uint64\nValidatorIndex = NewType('ValidatorIndex', int)  # uint64\nGwei = NewType('Gwei', int)  # uint64\nBytes32 = NewType('Bytes32', bytes)  # bytes32\nBLSPubkey = NewType('BLSPubkey', bytes)  # bytes48\nBLSSignature = NewType('BLSSignature', bytes)  # bytes96\nStore = None\n\"\"\")\n\n    code_lines += function_puller.get_spec(sourcefile)\n\n    code_lines.append(\"\"\"\n# Monkey patch validator compute committee code\n_compute_committee = compute_committee\ncommittee_cache = {}\n\n\ndef compute_committee(indices: List[ValidatorIndex], seed: Bytes32, index: int, count: int) -> List[ValidatorIndex]:\n    param_hash = (hash_tree_root(indices), seed, index, count)\n\n    if param_hash in committee_cache:\n        return committee_cache[param_hash]\n    else:\n        ret = _compute_committee(indices, seed, index, count)\n        committee_cache[param_hash] = ret\n        return ret\n\n\n# Monkey patch hash cache\n_hash = hash\nhash_cache = {}\n\n\ndef hash(x):\n    if x in hash_cache:\n        return hash_cache[x]\n    else:\n        ret = _hash(x)\n        hash_cache[x] = ret\n        return ret\n\n\n# Access to overwrite spec constants based on configuration\ndef apply_constants_preset(preset: Dict[str, Any]):\n    global_vars = globals()\n    for k, v in preset.items():\n        global_vars[k] = v\n\n    # Deal with derived constants\n    global_vars['GENESIS_EPOCH'] = slot_to_epoch(GENESIS_SLOT)\n\n    # Initialize SSZ types again, to account for changed lengths\n    init_SSZ_types()\n\"\"\")\n\n    with open(outfile, 'w') as out:\n        out.write(\"\\n\".join(code_lines))\n\n\nif __name__ == '__main__':\n    if len(sys.argv) < 3:\n        print(\"Usage: <source phase0> <output phase0 pyspec>\")\n    build_phase0_spec(sys.argv[1], sys.argv[2])\n\n", "path": "scripts/phase0/build_spec.py"}]}