Skip to content

Commit d880653

Browse files
pirapiraclaude
andcommitted
Replace declare -A with case function for macOS Bash 3.2 compatibility
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 8d4558b commit d880653

1 file changed

Lines changed: 115 additions & 117 deletions

File tree

test_leanspec_imports.sh

Lines changed: 115 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -20,122 +20,120 @@ FAIL=0
2020
XFAIL=0
2121
FAILURES=""
2222

23-
# Expected failures: module_pattern -> "issue_number reason"
24-
# Modules matching these patterns are XFAIL (expected to fail).
25-
declare -A XFAIL_MAP
26-
27-
# #5: lean_multisig_py (pending pure Python impl)
28-
XFAIL_MAP["lean_spec.subspecs.xmss.aggregation"]="#5 lean_multisig_py"
29-
# Transitive: everything importing xmss.aggregation
30-
XFAIL_MAP["lean_spec.subspecs.xmss.interface"]="#5 imports aggregation transitively"
31-
XFAIL_MAP["lean_spec.subspecs.containers.attestation.attestation"]="#5 imports xmss.aggregation"
32-
XFAIL_MAP["lean_spec.subspecs.containers.block.block"]="#5 imports xmss.aggregation"
33-
XFAIL_MAP["lean_spec.subspecs.containers.block.types"]="#4,#5 dict subclass + xmss.aggregation"
34-
XFAIL_MAP["lean_spec.subspecs.containers.state.state"]="#5 imports xmss.aggregation"
35-
XFAIL_MAP["lean_spec.subspecs.containers.validator"]="#5 imports xmss.containers->config"
36-
XFAIL_MAP["lean_spec.subspecs.containers.attestation.aggregation_bits"]="#5 imports validator->xmss"
37-
XFAIL_MAP["lean_spec.subspecs.containers.state.types"]="#5 imports validator->xmss"
38-
39-
# #5: XMSS modules that need lean_spec.config (get_args / PEP 695 __value__)
40-
XFAIL_MAP["lean_spec.config"]="#5 get_args + PEP695 __value__"
41-
XFAIL_MAP["lean_spec.subspecs.xmss.constants"]="#5 imports lean_spec.config"
42-
XFAIL_MAP["lean_spec.subspecs.xmss.types"]="#5 imports xmss.constants"
43-
XFAIL_MAP["lean_spec.subspecs.xmss.containers"]="#5 imports xmss.constants"
44-
XFAIL_MAP["lean_spec.subspecs.xmss._validation"]="#5 imports lean_spec.config"
45-
XFAIL_MAP["lean_spec.subspecs.xmss.hypercube"]="#5 imports xmss.constants"
46-
XFAIL_MAP["lean_spec.subspecs.xmss.message_hash"]="#5 imports xmss chain"
47-
XFAIL_MAP["lean_spec.subspecs.xmss.poseidon"]="#5 imports xmss chain"
48-
XFAIL_MAP["lean_spec.subspecs.xmss.prf"]="#5 imports xmss.constants"
49-
XFAIL_MAP["lean_spec.subspecs.xmss.rand"]="#5 imports xmss.constants"
50-
XFAIL_MAP["lean_spec.subspecs.xmss.subtree"]="#5 imports xmss.types"
51-
XFAIL_MAP["lean_spec.subspecs.xmss.target_sum"]="#5 imports xmss.constants"
52-
XFAIL_MAP["lean_spec.subspecs.xmss.tweak_hash"]="#5 imports xmss chain"
53-
XFAIL_MAP["lean_spec.subspecs.xmss.utils"]="#5 imports xmss chain"
54-
55-
# #6: numpy/numba (pending pure Python impl)
56-
XFAIL_MAP["lean_spec.subspecs.poseidon2.permutation"]="#6 numpy"
57-
XFAIL_MAP["lean_spec.subspecs.poseidon2.constants"]="#6 imports permutation transitively"
58-
59-
# #7: asyncio
60-
XFAIL_MAP["lean_spec.__main__"]="#7 asyncio"
61-
XFAIL_MAP["lean_spec.subspecs.chain.clock"]="#7 asyncio"
62-
XFAIL_MAP["lean_spec.subspecs.chain.service"]="#7 asyncio"
63-
XFAIL_MAP["lean_spec.subspecs.api.server"]="#7 asyncio"
64-
XFAIL_MAP["lean_spec.subspecs.api.routes"]="#7 imports api.server"
65-
XFAIL_MAP["lean_spec.subspecs.api.endpoints.checkpoints"]="#7 imports api chain"
66-
XFAIL_MAP["lean_spec.subspecs.api.endpoints.fork_choice"]="#7 imports api chain"
67-
XFAIL_MAP["lean_spec.subspecs.api.endpoints.health"]="#7 imports api chain"
68-
XFAIL_MAP["lean_spec.subspecs.api.endpoints.metrics"]="#7 imports api chain"
69-
XFAIL_MAP["lean_spec.subspecs.api.endpoints.states"]="#7 asyncio"
70-
XFAIL_MAP["lean_spec.subspecs.networking.client.event_source"]="#7 asyncio"
71-
XFAIL_MAP["lean_spec.subspecs.networking.client.reqresp_client"]="#7 asyncio"
72-
XFAIL_MAP["lean_spec.subspecs.networking.discovery.service"]="#7 asyncio"
73-
XFAIL_MAP["lean_spec.subspecs.networking.discovery.transport"]="#7 asyncio + cryptography"
74-
XFAIL_MAP["lean_spec.subspecs.networking.gossipsub.behavior"]="#7 asyncio"
75-
XFAIL_MAP["lean_spec.subspecs.networking.service.service"]="#7 asyncio"
76-
XFAIL_MAP["lean_spec.subspecs.networking.service.events"]="#7 imports service chain"
77-
XFAIL_MAP["lean_spec.subspecs.networking.transport.quic.connection"]="#7 asyncio + aioquic"
78-
XFAIL_MAP["lean_spec.subspecs.networking.transport.quic.stream_adapter"]="#7 asyncio"
79-
XFAIL_MAP["lean_spec.subspecs.node.node"]="#7 asyncio"
80-
XFAIL_MAP["lean_spec.subspecs.sync.service"]="#7 asyncio"
81-
XFAIL_MAP["lean_spec.subspecs.sync.backfill_sync"]="#7 imports sync chain"
82-
XFAIL_MAP["lean_spec.subspecs.sync.checkpoint_sync"]="#7 imports sync chain"
83-
XFAIL_MAP["lean_spec.subspecs.sync.head_sync"]="#7 imports sync chain"
84-
XFAIL_MAP["lean_spec.subspecs.validator.service"]="#7 asyncio"
85-
XFAIL_MAP["lean_spec.subspecs.validator.registry"]="#5,#7 imports xmss + chain"
86-
87-
# chain/__init__.py imports clock.py which uses asyncio, blocking all chain.* imports
88-
XFAIL_MAP["lean_spec.subspecs.chain.config"]="#7 chain/__init__.py imports clock->asyncio"
89-
XFAIL_MAP["lean_spec.subspecs.containers.checkpoint"]="#7 imports chain->clock->asyncio"
90-
XFAIL_MAP["lean_spec.subspecs.containers.config"]="#7 imports chain->clock->asyncio"
91-
XFAIL_MAP["lean_spec.subspecs.containers.slot"]="#7 imports chain->clock->asyncio"
92-
93-
# #9: prometheus_client
94-
XFAIL_MAP["lean_spec.subspecs.metrics.registry"]="#9 prometheus_client"
95-
XFAIL_MAP["lean_spec.subspecs.forkchoice.store"]="#5,#9 xmss + prometheus_client"
96-
97-
# Other external deps (cryptography, aioquic, sqlite3)
98-
XFAIL_MAP["lean_spec.subspecs.networking.discovery.crypto"]="cryptography lib"
99-
XFAIL_MAP["lean_spec.subspecs.networking.discovery.keys"]="cryptography lib"
100-
XFAIL_MAP["lean_spec.subspecs.networking.discovery.handshake"]="cryptography lib"
101-
XFAIL_MAP["lean_spec.subspecs.networking.discovery.codec"]="imports discovery chain"
102-
XFAIL_MAP["lean_spec.subspecs.networking.discovery.config"]="imports discovery chain"
103-
XFAIL_MAP["lean_spec.subspecs.networking.discovery.messages"]="imports discovery chain"
104-
XFAIL_MAP["lean_spec.subspecs.networking.discovery.packet"]="imports discovery chain"
105-
XFAIL_MAP["lean_spec.subspecs.networking.discovery.routing"]="imports discovery chain"
106-
XFAIL_MAP["lean_spec.subspecs.networking.discovery.session"]="imports discovery chain"
107-
XFAIL_MAP["lean_spec.subspecs.networking.enr.enr"]="cryptography lib"
108-
XFAIL_MAP["lean_spec.subspecs.networking.enr.eth2"]="imports enr chain"
109-
XFAIL_MAP["lean_spec.subspecs.networking.enr.keys"]="cryptography lib"
110-
XFAIL_MAP["lean_spec.subspecs.networking.transport.identity.keypair"]="cryptography lib"
111-
XFAIL_MAP["lean_spec.subspecs.networking.transport.identity.signature"]="cryptography lib"
112-
XFAIL_MAP["lean_spec.subspecs.networking.transport.peer_id"]="imports identity chain"
113-
XFAIL_MAP["lean_spec.subspecs.networking.transport.protocols"]="imports transport chain"
114-
XFAIL_MAP["lean_spec.subspecs.networking.transport.quic.tls"]="aioquic + cryptography"
115-
XFAIL_MAP["lean_spec.subspecs.networking.peer"]="imports networking chain"
116-
XFAIL_MAP["lean_spec.subspecs.networking.config"]="imports networking chain"
117-
XFAIL_MAP["lean_spec.subspecs.networking.types"]="imports networking chain"
118-
XFAIL_MAP["lean_spec.subspecs.networking.varint"]="imports networking chain"
119-
XFAIL_MAP["lean_spec.subspecs.networking.reqresp.codec"]="imports networking chain"
120-
XFAIL_MAP["lean_spec.subspecs.networking.reqresp.handler"]="imports networking chain"
121-
XFAIL_MAP["lean_spec.subspecs.networking.reqresp.message"]="imports networking chain"
122-
XFAIL_MAP["lean_spec.subspecs.networking.gossipsub.mcache"]="imports networking chain"
123-
XFAIL_MAP["lean_spec.subspecs.networking.gossipsub.mesh"]="imports networking chain"
124-
XFAIL_MAP["lean_spec.subspecs.networking.gossipsub.message"]="imports networking chain"
125-
XFAIL_MAP["lean_spec.subspecs.networking.gossipsub.parameters"]="imports networking chain"
126-
XFAIL_MAP["lean_spec.subspecs.networking.gossipsub.rpc"]="imports networking chain"
127-
XFAIL_MAP["lean_spec.subspecs.networking.gossipsub.topic"]="imports networking chain"
128-
XFAIL_MAP["lean_spec.subspecs.networking.gossipsub.types"]="imports networking chain"
129-
XFAIL_MAP["lean_spec.subspecs.storage.sqlite"]="sqlite3"
130-
XFAIL_MAP["lean_spec.subspecs.storage.database"]="imports storage chain"
131-
XFAIL_MAP["lean_spec.subspecs.storage.exceptions"]="imports storage chain"
132-
XFAIL_MAP["lean_spec.subspecs.storage.namespaces"]="imports storage chain"
133-
XFAIL_MAP["lean_spec.subspecs.sync.block_cache"]="imports sync chain"
134-
XFAIL_MAP["lean_spec.subspecs.sync.config"]="imports sync chain"
135-
XFAIL_MAP["lean_spec.subspecs.sync.peer_manager"]="imports sync chain"
136-
XFAIL_MAP["lean_spec.subspecs.sync.states"]="imports sync chain"
137-
XFAIL_MAP["lean_spec.subspecs.genesis.config"]="#5 imports xmss chain"
138-
XFAIL_MAP["lean_spec.subspecs.genesis.state"]="#5 imports genesis.config"
23+
# Expected failures: module -> "issue_number reason"
24+
# Modules matching these entries are XFAIL (expected to fail).
25+
# Uses a lookup function instead of `declare -A` for Bash 3.2 (macOS) compatibility.
26+
xfail_reason() {
27+
case "$1" in
28+
# #5: lean_multisig_py (pending pure Python impl)
29+
lean_spec.subspecs.xmss.aggregation) echo "#5 lean_multisig_py" ;;
30+
# Transitive: everything importing xmss.aggregation
31+
lean_spec.subspecs.xmss.interface) echo "#5 imports aggregation transitively" ;;
32+
lean_spec.subspecs.containers.attestation.attestation) echo "#5 imports xmss.aggregation" ;;
33+
lean_spec.subspecs.containers.block.block) echo "#5 imports xmss.aggregation" ;;
34+
lean_spec.subspecs.containers.block.types) echo "#4,#5 dict subclass + xmss.aggregation" ;;
35+
lean_spec.subspecs.containers.state.state) echo "#5 imports xmss.aggregation" ;;
36+
lean_spec.subspecs.containers.validator) echo "#5 imports xmss.containers->config" ;;
37+
lean_spec.subspecs.containers.attestation.aggregation_bits) echo "#5 imports validator->xmss" ;;
38+
lean_spec.subspecs.containers.state.types) echo "#5 imports validator->xmss" ;;
39+
# #5: XMSS modules that need lean_spec.config (get_args / PEP 695 __value__)
40+
lean_spec.config) echo "#5 get_args + PEP695 __value__" ;;
41+
lean_spec.subspecs.xmss.constants) echo "#5 imports lean_spec.config" ;;
42+
lean_spec.subspecs.xmss.types) echo "#5 imports xmss.constants" ;;
43+
lean_spec.subspecs.xmss.containers) echo "#5 imports xmss.constants" ;;
44+
lean_spec.subspecs.xmss._validation) echo "#5 imports lean_spec.config" ;;
45+
lean_spec.subspecs.xmss.hypercube) echo "#5 imports xmss.constants" ;;
46+
lean_spec.subspecs.xmss.message_hash) echo "#5 imports xmss chain" ;;
47+
lean_spec.subspecs.xmss.poseidon) echo "#5 imports xmss chain" ;;
48+
lean_spec.subspecs.xmss.prf) echo "#5 imports xmss.constants" ;;
49+
lean_spec.subspecs.xmss.rand) echo "#5 imports xmss.constants" ;;
50+
lean_spec.subspecs.xmss.subtree) echo "#5 imports xmss.types" ;;
51+
lean_spec.subspecs.xmss.target_sum) echo "#5 imports xmss.constants" ;;
52+
lean_spec.subspecs.xmss.tweak_hash) echo "#5 imports xmss chain" ;;
53+
lean_spec.subspecs.xmss.utils) echo "#5 imports xmss chain" ;;
54+
# #6: numpy/numba (pending pure Python impl)
55+
lean_spec.subspecs.poseidon2.permutation) echo "#6 numpy" ;;
56+
lean_spec.subspecs.poseidon2.constants) echo "#6 imports permutation transitively" ;;
57+
# #7: asyncio
58+
lean_spec.__main__) echo "#7 asyncio" ;;
59+
lean_spec.subspecs.chain.clock) echo "#7 asyncio" ;;
60+
lean_spec.subspecs.chain.service) echo "#7 asyncio" ;;
61+
lean_spec.subspecs.api.server) echo "#7 asyncio" ;;
62+
lean_spec.subspecs.api.routes) echo "#7 imports api.server" ;;
63+
lean_spec.subspecs.api.endpoints.checkpoints) echo "#7 imports api chain" ;;
64+
lean_spec.subspecs.api.endpoints.fork_choice) echo "#7 imports api chain" ;;
65+
lean_spec.subspecs.api.endpoints.health) echo "#7 imports api chain" ;;
66+
lean_spec.subspecs.api.endpoints.metrics) echo "#7 imports api chain" ;;
67+
lean_spec.subspecs.api.endpoints.states) echo "#7 asyncio" ;;
68+
lean_spec.subspecs.networking.client.event_source) echo "#7 asyncio" ;;
69+
lean_spec.subspecs.networking.client.reqresp_client) echo "#7 asyncio" ;;
70+
lean_spec.subspecs.networking.discovery.service) echo "#7 asyncio" ;;
71+
lean_spec.subspecs.networking.discovery.transport) echo "#7 asyncio + cryptography" ;;
72+
lean_spec.subspecs.networking.gossipsub.behavior) echo "#7 asyncio" ;;
73+
lean_spec.subspecs.networking.service.service) echo "#7 asyncio" ;;
74+
lean_spec.subspecs.networking.service.events) echo "#7 imports service chain" ;;
75+
lean_spec.subspecs.networking.transport.quic.connection) echo "#7 asyncio + aioquic" ;;
76+
lean_spec.subspecs.networking.transport.quic.stream_adapter) echo "#7 asyncio" ;;
77+
lean_spec.subspecs.node.node) echo "#7 asyncio" ;;
78+
lean_spec.subspecs.sync.service) echo "#7 asyncio" ;;
79+
lean_spec.subspecs.sync.backfill_sync) echo "#7 imports sync chain" ;;
80+
lean_spec.subspecs.sync.checkpoint_sync) echo "#7 imports sync chain" ;;
81+
lean_spec.subspecs.sync.head_sync) echo "#7 imports sync chain" ;;
82+
lean_spec.subspecs.validator.service) echo "#7 asyncio" ;;
83+
lean_spec.subspecs.validator.registry) echo "#5,#7 imports xmss + chain" ;;
84+
# chain/__init__.py imports clock.py which uses asyncio, blocking all chain.* imports
85+
lean_spec.subspecs.chain.config) echo "#7 chain/__init__.py imports clock->asyncio" ;;
86+
lean_spec.subspecs.containers.checkpoint) echo "#7 imports chain->clock->asyncio" ;;
87+
lean_spec.subspecs.containers.config) echo "#7 imports chain->clock->asyncio" ;;
88+
lean_spec.subspecs.containers.slot) echo "#7 imports chain->clock->asyncio" ;;
89+
# #9: prometheus_client
90+
lean_spec.subspecs.metrics.registry) echo "#9 prometheus_client" ;;
91+
lean_spec.subspecs.forkchoice.store) echo "#5,#9 xmss + prometheus_client" ;;
92+
# Other external deps (cryptography, aioquic, sqlite3)
93+
lean_spec.subspecs.networking.discovery.crypto) echo "cryptography lib" ;;
94+
lean_spec.subspecs.networking.discovery.keys) echo "cryptography lib" ;;
95+
lean_spec.subspecs.networking.discovery.handshake) echo "cryptography lib" ;;
96+
lean_spec.subspecs.networking.discovery.codec) echo "imports discovery chain" ;;
97+
lean_spec.subspecs.networking.discovery.config) echo "imports discovery chain" ;;
98+
lean_spec.subspecs.networking.discovery.messages) echo "imports discovery chain" ;;
99+
lean_spec.subspecs.networking.discovery.packet) echo "imports discovery chain" ;;
100+
lean_spec.subspecs.networking.discovery.routing) echo "imports discovery chain" ;;
101+
lean_spec.subspecs.networking.discovery.session) echo "imports discovery chain" ;;
102+
lean_spec.subspecs.networking.enr.enr) echo "cryptography lib" ;;
103+
lean_spec.subspecs.networking.enr.eth2) echo "imports enr chain" ;;
104+
lean_spec.subspecs.networking.enr.keys) echo "cryptography lib" ;;
105+
lean_spec.subspecs.networking.transport.identity.keypair) echo "cryptography lib" ;;
106+
lean_spec.subspecs.networking.transport.identity.signature) echo "cryptography lib" ;;
107+
lean_spec.subspecs.networking.transport.peer_id) echo "imports identity chain" ;;
108+
lean_spec.subspecs.networking.transport.protocols) echo "imports transport chain" ;;
109+
lean_spec.subspecs.networking.transport.quic.tls) echo "aioquic + cryptography" ;;
110+
lean_spec.subspecs.networking.peer) echo "imports networking chain" ;;
111+
lean_spec.subspecs.networking.config) echo "imports networking chain" ;;
112+
lean_spec.subspecs.networking.types) echo "imports networking chain" ;;
113+
lean_spec.subspecs.networking.varint) echo "imports networking chain" ;;
114+
lean_spec.subspecs.networking.reqresp.codec) echo "imports networking chain" ;;
115+
lean_spec.subspecs.networking.reqresp.handler) echo "imports networking chain" ;;
116+
lean_spec.subspecs.networking.reqresp.message) echo "imports networking chain" ;;
117+
lean_spec.subspecs.networking.gossipsub.mcache) echo "imports networking chain" ;;
118+
lean_spec.subspecs.networking.gossipsub.mesh) echo "imports networking chain" ;;
119+
lean_spec.subspecs.networking.gossipsub.message) echo "imports networking chain" ;;
120+
lean_spec.subspecs.networking.gossipsub.parameters) echo "imports networking chain" ;;
121+
lean_spec.subspecs.networking.gossipsub.rpc) echo "imports networking chain" ;;
122+
lean_spec.subspecs.networking.gossipsub.topic) echo "imports networking chain" ;;
123+
lean_spec.subspecs.networking.gossipsub.types) echo "imports networking chain" ;;
124+
lean_spec.subspecs.storage.sqlite) echo "sqlite3" ;;
125+
lean_spec.subspecs.storage.database) echo "imports storage chain" ;;
126+
lean_spec.subspecs.storage.exceptions) echo "imports storage chain" ;;
127+
lean_spec.subspecs.storage.namespaces) echo "imports storage chain" ;;
128+
lean_spec.subspecs.sync.block_cache) echo "imports sync chain" ;;
129+
lean_spec.subspecs.sync.config) echo "imports sync chain" ;;
130+
lean_spec.subspecs.sync.peer_manager) echo "imports sync chain" ;;
131+
lean_spec.subspecs.sync.states) echo "imports sync chain" ;;
132+
lean_spec.subspecs.genesis.config) echo "#5 imports xmss chain" ;;
133+
lean_spec.subspecs.genesis.state) echo "#5 imports genesis.config" ;;
134+
*) echo "" ;;
135+
esac
136+
}
139137

140138
# --- Test runner ---
141139

@@ -169,7 +167,7 @@ MODULES=$(find "$SRC/lean_spec" -name "*.py" -not -name "__init__.py" -not -path
169167
| sed "s|$SRC/||; s|/|.|g; s|\.py$||" | sort)
170168

171169
for mod in $MODULES; do
172-
xfail_reason="${XFAIL_MAP[$mod]:-}"
170+
xfail_reason="$(xfail_reason "$mod")"
173171

174172
output=$(try_import "$mod" 2>&1) && ok=true || ok=false
175173

0 commit comments

Comments
 (0)