77import itertools
88import os
99from collections import defaultdict
10+ from dataclasses import dataclass
1011from pathlib import Path
1112from typing import Any , Container , Dict , Iterable , Iterator , List , Mapping , Set , cast
1213
@@ -79,12 +80,17 @@ def _parse_when(data: dict[str, Any], table_path: str) -> Marker | None:
7980 )
8081
8182
83+ @dataclass (frozen = True )
84+ class DeactivatedCommand :
85+ name : str
86+
87+
8288def _parse_commands (
8389 commands : dict [str , Any ] | None ,
8490 required_steps : dict [str , list [tuple [Factor , ...]]],
8591 project_dir : Path ,
8692 marker_environment : dict [str , str ] | None ,
87- ) -> Iterator [Command ]:
93+ ) -> Iterator [Command | DeactivatedCommand ]:
8894 if not commands :
8995 raise InvalidModelError (
9096 "There must be at least one entry in the [tool.dev-cmd.commands] table to run "
@@ -280,8 +286,10 @@ def substitute(text: str) -> str:
280286 python = substituted_python ,
281287 )
282288
283- if not when or when .evaluate (marker_environment ):
284- final_name = f"{ name } { factors_suffix } "
289+ final_name = f"{ name } { factors_suffix } "
290+ if when and not when .evaluate (marker_environment ):
291+ yield DeactivatedCommand (final_name )
292+ else :
285293 previous_original_name = seen_commands .get (final_name )
286294 if previous_original_name and previous_original_name != original_name :
287295 raise InvalidModelError (
@@ -312,14 +320,17 @@ def _parse_group(
312320 group : list [Any ],
313321 all_task_names : Container [str ],
314322 tasks_defined_so_far : Mapping [str , Task ],
315- commands : Mapping [str , Command ],
323+ commands : Mapping [str , Command | DeactivatedCommand ],
316324) -> Group :
317325 members : list [Command | Task | Group ] = []
318326 for index , member in enumerate (group ):
319327 if isinstance (member , str ):
320328 for item in expand (member ):
329+ command = commands .get (item )
330+ if isinstance (command , DeactivatedCommand ):
331+ continue
321332 try :
322- members .append (commands . get ( item ) or tasks_defined_so_far [item ])
333+ members .append (command or tasks_defined_so_far [item ])
323334 except KeyError :
324335 if item in all_task_names :
325336 raise InvalidModelError (
@@ -362,7 +373,7 @@ def _parse_group(
362373
363374def _parse_tasks (
364375 tasks : dict [str , Any ] | None ,
365- commands : Mapping [str , Command ],
376+ commands : Mapping [str , Command | DeactivatedCommand ],
366377 marker_environment : dict [str , str ] | None ,
367378) -> Iterator [Task ]:
368379 if not tasks :
@@ -454,11 +465,13 @@ def _parse_tasks(
454465
455466
456467def _parse_default (
457- default : Any , commands : Mapping [str , Command ], tasks : Mapping [str , Task ]
468+ default : Any , commands : Mapping [str , Command | DeactivatedCommand ], tasks : Mapping [str , Task ]
458469) -> Command | Task | None :
459470 if default is None :
460471 if len (commands ) == 1 :
461- return next (iter (commands .values ()))
472+ only_command = next (iter (commands .values ()))
473+ if isinstance (only_command , Command ):
474+ return only_command
462475 return None
463476
464477 if not isinstance (default , str ):
@@ -467,8 +480,11 @@ def _parse_default(
467480 f"{ type (default )} ."
468481 )
469482
483+ if selected_task := tasks .get (default ):
484+ return selected_task
470485 try :
471- return tasks .get (default ) or commands [default ]
486+ selected_command = commands [default ]
487+ return selected_command if isinstance (selected_command , Command ) else None
472488 except KeyError :
473489 raise InvalidModelError (
474490 os .linesep .join (
@@ -875,7 +891,7 @@ def pop_dict(key: str, *, path: str) -> dict[str, Any] | None:
875891 )
876892 break
877893
878- commands = {
894+ commands : dict [ str , Command | DeactivatedCommand ] = {
879895 cmd .name : cmd
880896 for cmd in _parse_commands (
881897 commands_data ,
@@ -904,7 +920,7 @@ def pop_dict(key: str, *, path: str) -> dict[str, Any] | None:
904920 )
905921
906922 return Configuration (
907- commands = tuple (commands .values ()),
923+ commands = tuple (cmd for cmd in commands .values () if isinstance ( cmd , Command )),
908924 tasks = tuple (tasks .values ()),
909925 default = default ,
910926 exit_style = exit_style ,
0 commit comments