Format: text/x-python
⬇ Download File (2.9 KB)
   1  """Tests for input handlers.
   2  """
   3  #-----------------------------------------------------------------------------
   4  # Module imports
   5  #-----------------------------------------------------------------------------
   6  
   7  # our own packages
   8  from IPython.core import autocall
   9  from IPython.testing import tools as tt
  10  import pytest
  11  from collections.abc import Callable
  12  
  13  #-----------------------------------------------------------------------------
  14  # Globals
  15  #-----------------------------------------------------------------------------
  16  
  17  # Test functions
  18  #-----------------------------------------------------------------------------
  19  
  20  class CallableIndexable(object):
  21      def __getitem__(self, idx): return True
  22      def __call__(self, *args, **kws): return True
  23  
  24  
  25  class Autocallable(autocall.IPyAutocall):
  26      def __call__(self):
  27          return "called"
  28  
  29  
  30  @pytest.mark.parametrize(
  31      "autocall, input, output",
  32      [
  33          # For many of the below, we're also checking that leading whitespace
  34          # turns off the esc char, which it should unless there is a continuation
  35          # line.
  36          ("1", '"no change"', '"no change"'),  # normal
  37          ("1", "lsmagic", "get_ipython().run_line_magic('lsmagic', '')"),  # magic
  38          # Only explicit escapes or instances of IPyAutocallable should get
  39          # expanded
  40          ("0", 'len "abc"', 'len "abc"'),
  41          ("0", "autocallable", "autocallable()"),
  42          # Don't add extra brackets (gh-1117)
  43          ("0", "autocallable()", "autocallable()"),
  44          ("1", 'len "abc"', 'len("abc")'),
  45          ("1", 'len "abc";', 'len("abc");'),  # ; is special -- moves out of parens
  46          # Autocall is turned off if first arg is [] and the object
  47          # is both callable and indexable.  Like so:
  48          ("1", "len [1,2]", "len([1,2])"),  # len doesn't support __getitem__...
  49          ("1", "call_idx [1]", "call_idx [1]"),  # call_idx *does*..
  50          ("1", "call_idx 1", "call_idx(1)"),
  51          ("1", "len", "len"),  # only at 2 does it auto-call on single args
  52          ("2", 'len "abc"', 'len("abc")'),
  53          ("2", 'len "abc";', 'len("abc");'),
  54          ("2", "len [1,2]", "len([1,2])"),
  55          ("2", "call_idx [1]", "call_idx [1]"),
  56          ("2", "call_idx 1", "call_idx(1)"),
  57          # T his is what's different:
  58          ("2", "len", "len()"),  # only at 2 does it auto-call on single args
  59          ("0", "Callable[[int], None]", "Callable[[int], None]"),
  60          ("1", "Callable[[int], None]", "Callable[[int], None]"),
  61          ("1", "Callable[[int], None]", "Callable[[int], None]"),
  62      ],
  63  )
  64  def test_handlers_I(autocall, input, output):
  65      autocallable = Autocallable()
  66      ip.user_ns["autocallable"] = autocallable
  67  
  68      call_idx = CallableIndexable()
  69      ip.user_ns["call_idx"] = call_idx
  70  
  71      ip.user_ns["Callable"] = Callable
  72  
  73      ip.run_line_magic("autocall", autocall)
  74      assert ip.prefilter_manager.prefilter_lines(input) == output
  75      ip.run_line_magic("autocall", "1")
  76