(root)/
Python-3.12.0/
Lib/
rlcompleter.py
       1  """Word completion for GNU readline.
       2  
       3  The completer completes keywords, built-ins and globals in a selectable
       4  namespace (which defaults to __main__); when completing NAME.NAME..., it
       5  evaluates (!) the expression up to the last dot and completes its attributes.
       6  
       7  It's very cool to do "import sys" type "sys.", hit the completion key (twice),
       8  and see the list of names defined by the sys module!
       9  
      10  Tip: to use the tab key as the completion key, call
      11  
      12      readline.parse_and_bind("tab: complete")
      13  
      14  Notes:
      15  
      16  - Exceptions raised by the completer function are *ignored* (and generally cause
      17    the completion to fail).  This is a feature -- since readline sets the tty
      18    device in raw (or cbreak) mode, printing a traceback wouldn't work well
      19    without some complicated hoopla to save, reset and restore the tty state.
      20  
      21  - The evaluation of the NAME.NAME... form may cause arbitrary application
      22    defined code to be executed if an object with a __getattr__ hook is found.
      23    Since it is the responsibility of the application (or the user) to enable this
      24    feature, I consider this an acceptable risk.  More complicated expressions
      25    (e.g. function calls or indexing operations) are *not* evaluated.
      26  
      27  - When the original stdin is not a tty device, GNU readline is never
      28    used, and this module (and the readline module) are silently inactive.
      29  
      30  """
      31  
      32  import atexit
      33  import builtins
      34  import inspect
      35  import keyword
      36  import re
      37  import __main__
      38  
      39  __all__ = ["Completer"]
      40  
      41  class ESC[4;38;5;81mCompleter:
      42      def __init__(self, namespace = None):
      43          """Create a new completer for the command line.
      44  
      45          Completer([namespace]) -> completer instance.
      46  
      47          If unspecified, the default namespace where completions are performed
      48          is __main__ (technically, __main__.__dict__). Namespaces should be
      49          given as dictionaries.
      50  
      51          Completer instances should be used as the completion mechanism of
      52          readline via the set_completer() call:
      53  
      54          readline.set_completer(Completer(my_namespace).complete)
      55          """
      56  
      57          if namespace and not isinstance(namespace, dict):
      58              raise TypeError('namespace must be a dictionary')
      59  
      60          # Don't bind to namespace quite yet, but flag whether the user wants a
      61          # specific namespace or to use __main__.__dict__. This will allow us
      62          # to bind to __main__.__dict__ at completion time, not now.
      63          if namespace is None:
      64              self.use_main_ns = 1
      65          else:
      66              self.use_main_ns = 0
      67              self.namespace = namespace
      68  
      69      def complete(self, text, state):
      70          """Return the next possible completion for 'text'.
      71  
      72          This is called successively with state == 0, 1, 2, ... until it
      73          returns None.  The completion should begin with 'text'.
      74  
      75          """
      76          if self.use_main_ns:
      77              self.namespace = __main__.__dict__
      78  
      79          if not text.strip():
      80              if state == 0:
      81                  if _readline_available:
      82                      readline.insert_text('\t')
      83                      readline.redisplay()
      84                      return ''
      85                  else:
      86                      return '\t'
      87              else:
      88                  return None
      89  
      90          if state == 0:
      91              if "." in text:
      92                  self.matches = self.attr_matches(text)
      93              else:
      94                  self.matches = self.global_matches(text)
      95          try:
      96              return self.matches[state]
      97          except IndexError:
      98              return None
      99  
     100      def _callable_postfix(self, val, word):
     101          if callable(val):
     102              word += "("
     103              try:
     104                  if not inspect.signature(val).parameters:
     105                      word += ")"
     106              except ValueError:
     107                  pass
     108  
     109          return word
     110  
     111      def global_matches(self, text):
     112          """Compute matches when text is a simple name.
     113  
     114          Return a list of all keywords, built-in functions and names currently
     115          defined in self.namespace that match.
     116  
     117          """
     118          matches = []
     119          seen = {"__builtins__"}
     120          n = len(text)
     121          for word in keyword.kwlist + keyword.softkwlist:
     122              if word[:n] == text:
     123                  seen.add(word)
     124                  if word in {'finally', 'try'}:
     125                      word = word + ':'
     126                  elif word not in {'False', 'None', 'True',
     127                                    'break', 'continue', 'pass',
     128                                    'else', '_'}:
     129                      word = word + ' '
     130                  matches.append(word)
     131          for nspace in [self.namespace, builtins.__dict__]:
     132              for word, val in nspace.items():
     133                  if word[:n] == text and word not in seen:
     134                      seen.add(word)
     135                      matches.append(self._callable_postfix(val, word))
     136          return matches
     137  
     138      def attr_matches(self, text):
     139          """Compute matches when text contains a dot.
     140  
     141          Assuming the text is of the form NAME.NAME....[NAME], and is
     142          evaluable in self.namespace, it will be evaluated and its attributes
     143          (as revealed by dir()) are used as possible completions.  (For class
     144          instances, class members are also considered.)
     145  
     146          WARNING: this can still invoke arbitrary C code, if an object
     147          with a __getattr__ hook is evaluated.
     148  
     149          """
     150          m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text)
     151          if not m:
     152              return []
     153          expr, attr = m.group(1, 3)
     154          try:
     155              thisobject = eval(expr, self.namespace)
     156          except Exception:
     157              return []
     158  
     159          # get the content of the object, except __builtins__
     160          words = set(dir(thisobject))
     161          words.discard("__builtins__")
     162  
     163          if hasattr(thisobject, '__class__'):
     164              words.add('__class__')
     165              words.update(get_class_members(thisobject.__class__))
     166          matches = []
     167          n = len(attr)
     168          if attr == '':
     169              noprefix = '_'
     170          elif attr == '_':
     171              noprefix = '__'
     172          else:
     173              noprefix = None
     174          while True:
     175              for word in words:
     176                  if (word[:n] == attr and
     177                      not (noprefix and word[:n+1] == noprefix)):
     178                      match = "%s.%s" % (expr, word)
     179                      if isinstance(getattr(type(thisobject), word, None),
     180                                    property):
     181                          # bpo-44752: thisobject.word is a method decorated by
     182                          # `@property`. What follows applies a postfix if
     183                          # thisobject.word is callable, but know we know that
     184                          # this is not callable (because it is a property).
     185                          # Also, getattr(thisobject, word) will evaluate the
     186                          # property method, which is not desirable.
     187                          matches.append(match)
     188                          continue
     189                      if (value := getattr(thisobject, word, None)) is not None:
     190                          matches.append(self._callable_postfix(value, match))
     191                      else:
     192                          matches.append(match)
     193              if matches or not noprefix:
     194                  break
     195              if noprefix == '_':
     196                  noprefix = '__'
     197              else:
     198                  noprefix = None
     199          matches.sort()
     200          return matches
     201  
     202  def get_class_members(klass):
     203      ret = dir(klass)
     204      if hasattr(klass,'__bases__'):
     205          for base in klass.__bases__:
     206              ret = ret + get_class_members(base)
     207      return ret
     208  
     209  try:
     210      import readline
     211  except ImportError:
     212      _readline_available = False
     213  else:
     214      readline.set_completer(Completer().complete)
     215      # Release references early at shutdown (the readline module's
     216      # contents are quasi-immortal, and the completer function holds a
     217      # reference to globals).
     218      atexit.register(lambda: readline.set_completer(None))
     219      _readline_available = True