Format: text/x-python
⬇ Download File (4.7 KB)
   1  """Implementation of magic functions that control various automatic behaviors.
   2  """
   3  #-----------------------------------------------------------------------------
   4  #  Copyright (c) 2012 The IPython Development Team.
   5  #
   6  #  Distributed under the terms of the Modified BSD License.
   7  #
   8  #  The full license is in the file COPYING.txt, distributed with this software.
   9  #-----------------------------------------------------------------------------
  10  
  11  #-----------------------------------------------------------------------------
  12  # Imports
  13  #-----------------------------------------------------------------------------
  14  
  15  # Our own packages
  16  from IPython.core.magic import Bunch, Magics, magics_class, line_magic
  17  from IPython.testing.skipdoctest import skip_doctest
  18  from logging import error
  19  
  20  #-----------------------------------------------------------------------------
  21  # Magic implementation classes
  22  #-----------------------------------------------------------------------------
  23  
  24  @magics_class
  25  class AutoMagics(Magics):
  26      """Magics that control various autoX behaviors."""
  27  
  28      def __init__(self, shell):
  29          super(AutoMagics, self).__init__(shell)
  30          # namespace for holding state we may need
  31          self._magic_state = Bunch()
  32  
  33      @line_magic
  34      def automagic(self, parameter_s=''):
  35          """Make magic functions callable without having to type the initial %.
  36  
  37          Without arguments toggles on/off (when off, you must call it as
  38          %automagic, of course).  With arguments it sets the value, and you can
  39          use any of (case insensitive):
  40  
  41           - on, 1, True: to activate
  42  
  43           - off, 0, False: to deactivate.
  44  
  45          Note that magic functions have lowest priority, so if there's a
  46          variable whose name collides with that of a magic fn, automagic won't
  47          work for that function (you get the variable instead). However, if you
  48          delete the variable (del var), the previously shadowed magic function
  49          becomes visible to automagic again."""
  50  
  51          arg = parameter_s.lower()
  52          mman = self.shell.magics_manager
  53          if arg in ('on', '1', 'true'):
  54              val = True
  55          elif arg in ('off', '0', 'false'):
  56              val = False
  57          else:
  58              val = not mman.auto_magic
  59          mman.auto_magic = val
  60          print('\n' + self.shell.magics_manager.auto_status())
  61  
  62      @skip_doctest
  63      @line_magic
  64      def autocall(self, parameter_s=''):
  65          """Make functions callable without having to type parentheses.
  66  
  67          Usage:
  68  
  69             %autocall [mode]
  70  
  71          The mode can be one of: 0->Off, 1->Smart, 2->Full.  If not given, the
  72          value is toggled on and off (remembering the previous state).
  73  
  74          In more detail, these values mean:
  75  
  76          0 -> fully disabled
  77  
  78          1 -> active, but do not apply if there are no arguments on the line.
  79  
  80          In this mode, you get::
  81  
  82            In [1]: callable
  83            Out[1]: <built-in function callable>
  84  
  85            In [2]: callable 'hello'
  86            ------> callable('hello')
  87            Out[2]: False
  88  
  89          2 -> Active always.  Even if no arguments are present, the callable
  90          object is called::
  91  
  92            In [2]: float
  93            ------> float()
  94            Out[2]: 0.0
  95  
  96          Note that even with autocall off, you can still use '/' at the start of
  97          a line to treat the first argument on the command line as a function
  98          and add parentheses to it::
  99  
 100            In [8]: /str 43
 101            ------> str(43)
 102            Out[8]: '43'
 103  
 104          # all-random (note for auto-testing)
 105          """
 106  
 107          valid_modes = {
 108              0: "Off",
 109              1: "Smart",
 110              2: "Full",
 111          }
 112  
 113          def errorMessage() -> str:
 114              error = "Valid modes: "
 115              for k, v in valid_modes.items():
 116                  error += str(k) + "->" + v + ", "
 117              error = error[:-2]  # remove tailing `, ` after last element
 118              return error
 119  
 120          if parameter_s:
 121              if not parameter_s in map(str, valid_modes.keys()):
 122                  error(errorMessage())
 123                  return
 124              arg = int(parameter_s)
 125          else:
 126              arg = 'toggle'
 127  
 128          if not arg in (*list(valid_modes.keys()), "toggle"):
 129              error(errorMessage())
 130              return
 131  
 132          if arg in (valid_modes.keys()):
 133              self.shell.autocall = arg
 134          else: # toggle
 135              if self.shell.autocall:
 136                  self._magic_state.autocall_save = self.shell.autocall
 137                  self.shell.autocall = 0
 138              else:
 139                  try:
 140                      self.shell.autocall = self._magic_state.autocall_save
 141                  except AttributeError:
 142                      self.shell.autocall = self._magic_state.autocall_save = 1
 143  
 144          print("Automatic calling is:", list(valid_modes.values())[self.shell.autocall])
 145