ipython / ipython

Official repository for IPython itself. Other repos in the IPython organization contain things like the website, documentation builds, etc.
https://ipython.readthedocs.org
BSD 3-Clause "New" or "Revised" License
16.31k stars 4.45k forks source link

%time unable to access functions in nested scope. #11240

Open napsternxg opened 6 years ago

napsternxg commented 6 years ago

I am trying to use %time with nested function. When I run the code normally, I am able to execute my functions. But when I add %time to each function call, the function fails with the message NameError: name 'f1' is not defined

Reproducing the bug: This code runs perfectly, producing the output below:

def f():
    def f1():
        print("f1")
    def f2():
        print("f2")
    def f3():
        print("f3")
        f1()
        f2()
    f3()
f()

Output:

f3
f1
f2

This code causes the error described below.

def f():
    def f1():
        print("f1")
    def f2():
        print("f2")
    def f3():
        print("f3")
        %time f1()
        %time f2()
    f3()
f()
Execution of f3 started at 03:05:54
.......................................
f3

NameErrorTraceback (most recent call last)
<ipython-input-24-c43e34e6d405> in <module>()
----> 1 f()

<ipython-input-23-399d74c82109> in f()
     11         get_ipython().magic(u'time f1()')
     12         get_ipython().magic(u'time f2()')
---> 13     f3()

<ipython-input-15-72dec894541f> in timed_execution(*args, **kwargs)
     13             ))
     14             print(".......................................")
---> 15             output = fn(*args, **kwargs)
     16             end_time = datetime.utcnow()
     17             print(".......................................")

<ipython-input-23-399d74c82109> in f3()
      9     def f3():
     10         print("f3")
---> 11         get_ipython().magic(u'time f1()')
     12         get_ipython().magic(u'time f2()')
     13     f3()

/ipython-5.7.0-py2-none-any.whl/IPython/core/interactiveshell.pyc in magic(self, arg_s)
   2158         magic_name, _, magic_arg_s = arg_s.partition(' ')
   2159         magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
-> 2160         return self.run_line_magic(magic_name, magic_arg_s)
   2161 
   2162     #-------------------------------------------------------------------------

/ipython-5.7.0-py2-none-any.whl/IPython/core/interactiveshell.pyc in run_line_magic(self, magic_name, line)
   2079                 kwargs['local_ns'] = sys._getframe(stack_depth).f_locals
   2080             with self.builtin_trap:
-> 2081                 result = fn(*args,**kwargs)
   2082             return result
   2083 

<decorator-gen-60> in time(self, line, cell, local_ns)

/ipython-5.7.0-py2-none-any.whl/IPython/core/magic.pyc in <lambda>(f, *a, **k)
    186     # but it's overkill for just that one bit of state.
    187     def magic_deco(arg):
--> 188         call = lambda f, *a, **k: f(*a, **k)
    189 
    190         if callable(arg):

/ipython-5.7.0-py2-none-any.whl/IPython/core/magics/execution.pyc in time(self, line, cell, local_ns)
   1187         if mode=='eval':
   1188             st = clock2()
-> 1189             out = eval(code, glob, local_ns)
   1190             end = clock2()
   1191         else:

<timed eval> in <module>()

NameError: name 'f1' is not defined
import IPython
print(IPython.sys_info())

# Output
{'commit_hash': u'a0d6ad545',
 'commit_source': 'installation',
 'default_encoding': 'ANSI_X3.4-1968',
 'ipython_path': '<some_path>',
 'ipython_version': '5.7.0',
 'os_name': 'posix',
 'platform': 'Linux-4.9.34-t7.el7.x86_64-x86_64-with-centos-7.4.1708-Core',
 'sys_executable': '/opt/ee/python/2.7/bin/python2.7',
 'sys_platform': 'linux2',
 'sys_version': '2.7.15 (default, Jun 21 2018, 21:10:58) \n[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)]'}
mezaugusto commented 6 years ago

It works if you declare them as global

def f():
    global f1, f2
    def f1():
        print("f1")
    def f2():
        print("f2")
    def f3():
        print("f3")
        %time f1()
        %time f2()
    f3()
f()

Output:

f3  
f1  
CPU times: user 85 µs, sys: 25 µs, total: 110 µs  
Wall time: 99.7 µs  
f2  
CPU times: user 10 µs, sys: 9 µs, total: 19 µs  
Wall time: 19.1 µs

I think this is related to #9892