code: def _attach_decorators_to_step(step, decospecs):
      """
      Attach decorators to a step during runtime. This has the same
      effect as if you defined the decorators statically in the source for
      the step.
      """
      from .plugins import STEP_DECORATORS
  
      decos = {decotype.name: decotype for decotype in STEP_DECORATORS}
  
      for decospec in decospecs:
          splits = decospec.split(":", 1)
          deconame = splits[0]
          if deconame not in decos:
              raise UnknownStepDecoratorException(deconame)
          # Attach the decorator to step if it doesn't have the decorator
          # already. This means that statically defined decorators are always
          # preferred over runtime decorators.
          if (
              deconame not in [deco.name for deco in step.decorators]
              or decos[deconame].allow_multiple
          ):
              # if the decorator is present in a step and is of type allow_multiple
              # then add the decorator to the step
              deco = decos[deconame]._parse_decorator_spec(
                  splits[1] if len(splits) > 1 else ""
              )
              step.decorators.append(deco)
  
imports: from functools import partial
  import json
  import re
  import os
  import sys
  from .flowspec import FlowSpec
  from .exception import MetaflowInternalError, MetaflowException, InvalidDecoratorAttribute
  from metaflow._vendor import click
label_desc: Use image node_id 6 for calling a global function with example usage: _attach_decorators_to_step(step, decospecs) without return types