Skip to content

Conversation

@Carreau
Copy link
Member

@Carreau Carreau commented May 24, 2017

Allow to display the result of the last assignment of it has a unique
target.

meh, I should write tests for that.

@Carreau
Copy link
Member Author

Carreau commented May 24, 2017

@rgbkrk though on that ? I though about that because display() is long to type and I often do

df = some_operation(df)
df 

Just to display it.

@Carreau Carreau force-pushed the ast-interactivity branch from cc82cfc to 2e8d986 Compare May 24, 2017 19:24
Up until 6.0 the following code wouldn't show the value of the assigned
variable:

>>> var = "something"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My brain almost broke because it was in JS mode while reading this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can change for let if you want ?

@rgbkrk
Copy link
Member

rgbkrk commented May 24, 2017

If this behavior exists, out of old Matlab habit I will append ; in hopes that it will not show the result by default.

I too do the operation then display it pretty often. I'd hate to have to figure out how to suppress output though.

@rgbkrk
Copy link
Member

rgbkrk commented May 24, 2017

Oh I see, this isn't the default setting, just a configurable. 🆒

@Carreau
Copy link
Member Author

Carreau commented May 24, 2017

yeah, of course it's not the default :-)

$ ipython --InteractiveShell.ast_node_interactivity='last_expr_or_assign'
Python 3.6.0 |Continuum Analytics, Inc.| (default, Dec 23 2016, 13:19:00)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.1.0.dev -- An enhanced Interactive Python. Type '?' for help.

In [1]: a = 1;

In [2]: a = 1
Out[2]: 1

In [3]:

; works, you can also do a newline / pass or newline / None

@Carreau Carreau requested review from ivanov and takluyver May 24, 2017 20:55
if isinstance(nodelist[-1], ast.Assign):
asg = nodelist[-1]
if len(asg.targets) == 1:
nnode = ast.Expr(ast.Name(asg.targets[0].id, ast.Load()))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will crash if you try to do a multiple assignment. When I parse something like (a, b) = (1, 2), I get an assignment with a length-1 list of targets whose only entry is an instance of ast.Tuple, which has no id:

In [5]: sys.version_info
Out[5]: sys.version_info(major=3, minor=5, micro=2, releaselevel='final', serial=0)

In [6]: %%ast
   ...: (a, b) = (1, 2)
   ...:
Module(
  body=[
    Assign(
      targets=[
        Tuple(
          elts=[
            Name(id='a', ctx=Store()),
            Name(id='b', ctx=Store()),
          ],
          ctx=Store(),
        ),
      ],
      value=Tuple(
        elts=[
          Num(1),
          Num(2),
        ],
        ctx=Load(),
      ),
    ),
  ],
)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(That %%ast magic comes from https://github.com/llllllllll/codetransformer/blob/master/codetransformer/__init__.py#L23-L35, btw. That might be relevant to your interests if you're working on ast stuff.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, sweet. Thanks. Does it also define a pretty formatter for ast objects that are returned ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't at the moment, but that could be added pretty easily. The logic that does the actual formatting lives here: https://github.com/llllllllll/codetransformer/blob/master/codetransformer/utils/pretty.py#L31.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey ! ... it's not in the released version ! It's been merged a year ago, why no release?
1pns0e

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, TIL. @llllllllll we should probably do a codetransformer release...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Carreau Carreau force-pushed the ast-interactivity branch 2 times, most recently from 1f5d398 to 5260f5a Compare May 24, 2017 23:35
@Carreau
Copy link
Member Author

Carreau commented May 24, 2017

codetransformer 0.7.0 has been released

Thanks ! Though I'm on 3.6, so can't import it :-(

Pushed new commits that test the various behavior.

Copy link
Member

@takluyver takluyver left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work 👍

With the option ``InteractiveShell.ast_node_interactivity='last_expr_or_assign'``
you can now do::

>>> df = pandas.load_csv(...)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this example match the others above? And use IPython prompts instead of >>>?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

return

if interactivity == 'last_expr_or_assign':
if isinstance(nodelist[-1], ast.Assign):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is fine for getting this feature in and letting people experiment with it, but be aware that it won't catch a += 1 (which is an AugAssign node), or a : int = 1 (new in Python 3.6, AnnAssign node).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call. Fixed. It should work on all of these.

@Carreau Carreau force-pushed the ast-interactivity branch 2 times, most recently from 435916a to faaa345 Compare May 25, 2017 18:06
ip.run_cell('(u,v) = (41+1, 43-1)')

finally:
ip.run_cell('a = 1+1', store_history=True)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this in the finally block?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No reasons, bad copy past likely. Fixed.

@Carreau Carreau modified the milestone: 6.2 May 29, 2017
@Carreau Carreau force-pushed the ast-interactivity branch from faaa345 to 81a07e3 Compare May 29, 2017 21:28
@Carreau
Copy link
Member Author

Carreau commented May 29, 2017

@fperez would prefer for this to not assign to Out[] and _.
I'm unsure about that. So I can rewrite the Ast to actually do display(ast_name).
I'll see what I can do.

@Carreau
Copy link
Member Author

Carreau commented May 29, 2017

Hum inject something at the end like that:

In [10]: %%ast
    ...: __import__('IPython').display.display(whatever)
Module(
  body=[
    Expr(
      value=Call(
        func=Attribute(
          value=Attribute(
            value=Call(
              func=Name(id='__import__', ctx=Load()),
              args=[
                Str(
                  s='IPython',
                ),
              ],
              keywords=[],
            ),
            attr='display',
            ctx=Load(),
          ),
          attr='display',
          ctx=Load(),
        ),
        args=[
          Name(id='whatever', ctx=Load()),
        ],
        keywords=[],
      ),
    ),
  ],
)

At the same time when the expression of a of a cell display something there is always an Out[], so I"m unsure.

@takluyver
Copy link
Member

If we're injecting display() into the builtins, that could be simpler. Although then I guess it would be susceptible to someone overriding display =.

Maybe there's a nicer way to do this - instead of modifying the AST, inspect it to find the target of the final assignment, and then record some information which says 'if this code completes successfully, print the value of foo'.

@Carreau
Copy link
Member Author

Carreau commented May 30, 2017

Maybe there's a nicer way to do this - instead of modifying the AST, inspect it to find the target of the final assignment, and then record some information which says 'if this code completes successfully, print the value of foo'

Well that's almost exactly what the above do. it calls display on the last assignment target.

Here is my argument against having it displayed and not triggerd as part of display hook.

One the the two below methods are doing

def load_something():
    display(...)

The other

def load_somethingelse():
    return ...
$ ipython
Python 3.6.0 |Continuum Analytics, Inc.| (default, Dec 23 2016, 13:19:00)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.1.0.dev -- An enhanced Interactive Python. Type '?' for help.

In [1]: %config TerminalInteractiveShell.ast_node_interactivity='display_last_expr_or_assign'
In [2]: from dummymod import load_cars, load_iris

In [3]: a = load_iris()

=================
 Id    |  types
=================
1      |    A
2      |    B
3      |    A
None

In [4]: b = load_cars()

=================
 Id    |  types
=================
I      |    E
II     |    F
III    |    G

With the current implementation that would be disambiguated by having (or not) an Out:

In [6]: a = load_iris()

=================
 Id    |  types
=================
1      |    A
2      |    B
3      |    A

In [7]: b = load_cars()
Out[7]:

=================
 Id    |  types
=================
I      |    E
II     |    F
III    |    G

Well now both are implemented so I can push 2 options.

@rgbkrk
Copy link
Member

rgbkrk commented May 30, 2017

Ok I'm totally going to set this in my personal defaults.

@Carreau
Copy link
Member Author

Carreau commented May 30, 2017

Note, the current code will also not work if the LHS is an arbitrary assignment like a.b = 1

@Carreau
Copy link
Member Author

Carreau commented May 30, 2017

So @fperez agree with the original proposal. I'm going to revert ca387c8

@Carreau Carreau force-pushed the ast-interactivity branch from ca387c8 to 81a07e3 Compare May 30, 2017 23:12
you can now do::

In[2]: xyz = "something else"
"something else"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example (and the second one above) should have an Out[2]: prompt, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes ! I s/>>>/In[1] stupidly.

@Carreau Carreau force-pushed the ast-interactivity branch from 81a07e3 to 2a668e5 Compare May 31, 2017 17:53
Allow to display the result of the last assignment of it has a unique
target.
@Carreau Carreau force-pushed the ast-interactivity branch from 2a668e5 to a137755 Compare May 31, 2017 17:53
@Carreau
Copy link
Member Author

Carreau commented Jun 1, 2017

Now that 6.1 is released, I'm getting this in to play with it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants