(root)/
Python-3.12.0/
Lib/
importlib/
metadata/
_itertools.py
       1  from itertools import filterfalse
       2  
       3  
       4  def unique_everseen(iterable, key=None):
       5      "List unique elements, preserving order. Remember all elements ever seen."
       6      # unique_everseen('AAAABBBCCDAABBB') --> A B C D
       7      # unique_everseen('ABBCcAD', str.lower) --> A B C D
       8      seen = set()
       9      seen_add = seen.add
      10      if key is None:
      11          for element in filterfalse(seen.__contains__, iterable):
      12              seen_add(element)
      13              yield element
      14      else:
      15          for element in iterable:
      16              k = key(element)
      17              if k not in seen:
      18                  seen_add(k)
      19                  yield element
      20  
      21  
      22  # copied from more_itertools 8.8
      23  def always_iterable(obj, base_type=(str, bytes)):
      24      """If *obj* is iterable, return an iterator over its items::
      25  
      26          >>> obj = (1, 2, 3)
      27          >>> list(always_iterable(obj))
      28          [1, 2, 3]
      29  
      30      If *obj* is not iterable, return a one-item iterable containing *obj*::
      31  
      32          >>> obj = 1
      33          >>> list(always_iterable(obj))
      34          [1]
      35  
      36      If *obj* is ``None``, return an empty iterable:
      37  
      38          >>> obj = None
      39          >>> list(always_iterable(None))
      40          []
      41  
      42      By default, binary and text strings are not considered iterable::
      43  
      44          >>> obj = 'foo'
      45          >>> list(always_iterable(obj))
      46          ['foo']
      47  
      48      If *base_type* is set, objects for which ``isinstance(obj, base_type)``
      49      returns ``True`` won't be considered iterable.
      50  
      51          >>> obj = {'a': 1}
      52          >>> list(always_iterable(obj))  # Iterate over the dict's keys
      53          ['a']
      54          >>> list(always_iterable(obj, base_type=dict))  # Treat dicts as a unit
      55          [{'a': 1}]
      56  
      57      Set *base_type* to ``None`` to avoid any special handling and treat objects
      58      Python considers iterable as iterable:
      59  
      60          >>> obj = 'foo'
      61          >>> list(always_iterable(obj, base_type=None))
      62          ['f', 'o', 'o']
      63      """
      64      if obj is None:
      65          return iter(())
      66  
      67      if (base_type is not None) and isinstance(obj, base_type):
      68          return iter((obj,))
      69  
      70      try:
      71          return iter(obj)
      72      except TypeError:
      73          return iter((obj,))