docs: def setdefaults(d, defaults):
      """
      If defaults is a str, updates a dict with None at an optionally dot-notated current:
          'a.b' --> {'a': {'b': None}}
      If defaults is a list, updates a dict with None at each optionally dot-notated current:
          ['a.b', 'a.c'] --> {'a': {'b': None, 'c': None}}
      If defaults is a dict, applies keys as fields and values as defaults:
          {'a.b': 'bbb', 'a.c': 'ccc'} --> {'a': {'b': 'bbb', 'c': 'ccc'}}
          {'a.b.c': 'ccc', 'a.c.d.e': 'eee'} --> {'a': {'b': {'c': 'ccc'}, 'c': {'d': {'e': 'eee'}}}}
      """
  
      if not isinstance(d, dict) or defaults is None:
          return d
      elif isinstance(defaults, _wrap_types):
          return setdefaults(d, [defaults])  # Wrap in list for consistent behavior
  
      use_none = not any(isinstance(s, dict) for s in defaults)
  
      # Accumulate (current, remaining) pairs to be applied to d
  
      accumulated = {}
      for current, remaining in _to_key_val_pairs(defaults):
          accumulated.setdefault(current, [])
          if remaining is not None:
              accumulated[current].append(remaining)
  
      # Update d with accumulated pairs, handling further nested dot-notated keys
  
      for current, remaining in iteritems(accumulated):
          if use_none:
  
              # Apply None value for what remains of the dot notated key
              defaults = setdefaults(d.get(current, {}), remaining) if remaining else None
              if defaults and isinstance(d.get(current), dict):
                  d[current].update(defaults)
              else:
                  d.setdefault(current, defaults)
  
          else:
              next_up = remaining[0] if remaining else None
  
              if '.' in current:
                  # Split on the dot and process next segment
                  k, s = current.split('.', 1)
                  d.setdefault(k, {})
                  setdefaults(d[k], [{s: next_up}])
              elif isinstance(next_up, STRING_TYPES):
                  # Set a string value directly
                  d.setdefault(current, next_up)
              else:
                  # Process a dict value or just set to the value in next_up
                  d.setdefault(current, setdefaults({}, remaining) or next_up)
  
      return d