docs: def _numeric_handler_factory(charset, transition, assertion, illegal_before_underscore, parse_func,
                               illegal_at_end=(None,), ion_type=None, append_first_if_not=None, first_char=None):
      """Generates a handler co-routine which tokenizes a numeric component (a token or sub-token).
  
      Args:
          charset (sequence): Set of ordinals of legal characters for this numeric component.
          transition (callable): Called upon termination of this component (i.e. when a character not in ``charset`` is
              found). Accepts the previous character ordinal, the current character ordinal, the current context, and the
              previous transition. Returns a Transition if the component ends legally; otherwise, raises an error.
          assertion (callable): Accepts the first character's ordinal and the current context. Returns True if this is
              a legal start to the component.
          illegal_before_underscore (sequence): Set of ordinals of illegal characters to precede an underscore for this
              component.
          parse_func (callable): Called upon ending the numeric value. Accepts the current token value and returns a
              thunk that lazily parses the token.
          illegal_at_end (Optional[sequence]): Set of ordinals of characters that may not legally end the value.
          ion_type (Optional[IonType]): The type of the value if it were to end on this component.
          append_first_if_not (Optional[int]): The ordinal of a character that should not be appended to the token if
              it occurs first in this component (e.g. an underscore in many cases).
          first_char (Optional[int]): The ordinal of the character that should be appended instead of the character that
              occurs first in this component. This is useful for preparing the token for parsing in the case where a
              particular character is peculiar to the Ion format (e.g. 'd' to denote the exponent of a decimal value
              should be replaced with 'e' for compatibility with python's Decimal type).
      """
      @coroutine
      def numeric_handler(c, ctx):
          assert assertion(c, ctx)
          if ion_type is not None:
              ctx.set_ion_type(ion_type)
          val = ctx.value
          if c != append_first_if_not:
              first = c if first_char is None else first_char
              val.append(first)
          prev = c
          c, self = yield
          trans = ctx.immediate_transition(self)
          while True:
              if _ends_value(c):
                  if prev == _UNDERSCORE or prev in illegal_at_end:
                      _illegal_character(c, ctx, '%s at end of number.' % (_chr(prev),))
                  trans = ctx.event_transition(IonThunkEvent, IonEventType.SCALAR, ctx.ion_type, parse_func(ctx.value))
                  if c == _SLASH:
                      trans = ctx.immediate_transition(_number_slash_end_handler(c, ctx, trans))
              else:
                  if c == _UNDERSCORE:
                      if prev == _UNDERSCORE or prev in illegal_before_underscore:
                          _illegal_character(c, ctx, 'Underscore after %s.' % (_chr(prev),))
                  else:
                      if c not in charset:
                          trans = transition(prev, c, ctx, trans)
                      else:
                          val.append(c)
              prev = c
              c, _ = yield trans
      return numeric_handler