4

Today I by mistake inputted just a comma on an interactive session
Input:

,

and I noticed strangely that it did not return an error but instead:
Output

''

So I explored a bit this behaviour and tried some random stuff, and it seems like it creates tuples of strings, but it seems like these objects cannot be interacted with:

, 'foo' bar 1 x 

returns:

("'foo'", 'bar', '1', 'x')

Trying to assign those tuples or making some == checks doesn't really work but return errors.
I couldn't find any answer or documentation about this behaviour. Anyone know what's happening here?

EDIT: I am using Python 3.9.8 and running in VSCode interactive window with IPython. As someone pointed out in the comments this is not the behaviour when running from the terminal

bad_coder
  • 11,289
  • 20
  • 44
  • 72

2 Answers2

2

This is an input transformation performed by the EscapedCommand class, specifically here. It's not part of autocall (details see below) which is handled by prefilter.AutoHandler. I couldn't find any public documentation on "escaped commands" and the class' docstring just mentions that it is a "transformer for escaped commands like %foo, !foo, or /foo". So I get the impression that the transformation for input like , a b is an (unintended) side effect of some other feature, as it's not publicly documented and doesn't seem to be of any use.

We can request the current IPython shell by importing the corresponding module and then check what component modifies the input:

In [1]: import IPython

In [2]: shell = IPython.get_ipython()

In [3]: %autocall
Automatic calling is: Smart

In [4]: shell.prefilter(',f a b')  # autocall (note the function name 'f'), not applied since there is no callable `f` in the global namespace
Out[4]: ',f a b'

In [5]: f = lambda x,y: x+y

In [6]: shell.prefilter(',f a b')  # autocall (note the function name 'f'), now it works
------> f("a", "b")
Out[6]: 'f("a", "b")'

In [7]: shell.prefilter(', a b')  # not identified as autocall --> remains unchanged
Out[7]: ', a b'

In [8]: shell.transform_cell(', a b')  # however, it gets transformed by `EscapedCommand`
Out[8]: '("a", "b")\n'

For autocall to work, we first have to activate it via the "magic" command %autocall. Also the indicated function name (f) must be present in the namespace and be callable. %quickref provides a brief overview of the autocall feature (scroll down to "Autocall"):

Autocall:

f 1,2            : f(1,2)  # Off by default, enable with %autocall magic.
/f 1,2           : f(1,2) (forced autoparen)
,f 1 2           : f("1","2")
;f 1 2           : f("1 2")
a_guest
  • 34,165
  • 12
  • 64
  • 118
  • @FreeTheOtter It turns out, this behavior is not part of "autocall"; it's handled by a separate transformer and I get the impression that the fact that it works for input like `, a b` is a side effect of some other syntax feature. I updated my answer accordingly. – a_guest Mar 31 '22 at 08:39
0

I have python 3.9.0 and observe the same behaviour.

I also try the same in a juptyer notebook and it returns the same.

enter image description here

However, this has no context because when i try to assign this "tuple" to a variable, it correctly throws an error.

enter image description here

So it looks like this "pseudo" tuple has no meaning, or at least an invalid syntax, in python...

I also note the answer from @a_guest which was just posted which adds additional clarity.

D.L
  • 4,339
  • 5
  • 22
  • 45