Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new interactivity mode for ast. #10598

Merged
merged 1 commit into from Jun 1, 2017
Merged

Conversation

@Carreau
Copy link
Member

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 Carreau:ast-interactivity branch from cc82cfc to 2e8d986 May 24, 2017
Up until 6.0 the following code wouldn't show the value of the assigned
variable:

>>> var = "something"

This comment has been minimized.

@rgbkrk

rgbkrk May 24, 2017 Member

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

This comment has been minimized.

@Carreau

Carreau May 24, 2017 Author Member

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
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()))

This comment has been minimized.

@ssanderson

ssanderson May 24, 2017 Member

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(),
      ),
    ),
  ],
)

This comment has been minimized.

@ssanderson

ssanderson May 24, 2017 Member

(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.)

This comment has been minimized.

@Carreau

Carreau May 24, 2017 Author Member

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

This comment has been minimized.

@ssanderson

ssanderson May 24, 2017 Member

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.

This comment has been minimized.

@Carreau

Carreau May 24, 2017 Author Member

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

This comment has been minimized.

@ssanderson

ssanderson May 24, 2017 Member

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

@Carreau Carreau force-pushed the Carreau:ast-interactivity branch 2 times, most recently from 1f5d398 to 5260f5a May 24, 2017
@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 left a comment

Nice work 👍

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

>>> df = pandas.load_csv(...)

This comment has been minimized.

@takluyver

takluyver May 25, 2017 Member

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

This comment has been minimized.

@Carreau

Carreau May 25, 2017 Author Member

done.

@@ -2781,6 +2787,15 @@ def run_ast_nodes(self, nodelist, cell_name, interactivity='last_expr',
if not nodelist:
return

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

This comment has been minimized.

@takluyver

takluyver May 25, 2017 Member

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).

This comment has been minimized.

@Carreau

Carreau May 25, 2017 Author Member

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

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

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

This comment has been minimized.

@takluyver

takluyver May 26, 2017 Member

Why is this in the finally block?

This comment has been minimized.

@Carreau

Carreau May 29, 2017 Author Member

No reasons, bad copy past likely. Fixed.

@Carreau Carreau modified the milestone: 6.2 May 29, 2017
@Carreau Carreau force-pushed the Carreau:ast-interactivity branch from faaa345 to 81a07e3 May 29, 2017
@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

takluyver commented May 30, 2017

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 Carreau:ast-interactivity branch from ca387c8 to 81a07e3 May 30, 2017
you can now do::

In[2]: xyz = "something else"
"something else"

This comment has been minimized.

@takluyver

takluyver May 31, 2017 Member

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

This comment has been minimized.

@Carreau

Carreau May 31, 2017 Author Member

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

@Carreau Carreau force-pushed the Carreau:ast-interactivity branch from 81a07e3 to 2a668e5 May 31, 2017
Allow to display the result of the last assignment of it has a unique
target.
@Carreau Carreau force-pushed the Carreau:ast-interactivity branch from 2a668e5 to a137755 May 31, 2017
@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.

@Carreau Carreau merged commit beb08ba into ipython:master Jun 1, 2017
4 checks passed
4 checks passed
codecov/patch 97.91% of diff hit (target 0%)
Details
codecov/project 66.89% (+0.06%) compared to be46bc7
Details
continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
@Carreau Carreau deleted the Carreau:ast-interactivity branch Jul 20, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

4 participants
You can’t perform that action at this time.