Repository: ipython/ipython

Issue:
Using the IPython debugger in a unittest fails to continue
The new tab completion with IPython 5 is great! My congratulations, I really do not want to miss that again. Not even in the debugger --- where I discovered the following behaviour:

To my understanding IPython 5.1.0 allows debugging with tab completion by inserting the following line `from IPython.terminal.debugger import TerminalPdb ;TerminalPdb().set_trace()` (see also #9940). However, when doing so in the script below and simply hitting `c` for continue, it will exit with an attribute error:

```
Traceback (most recent call last):
  File "../snippets/test_ipython_debugger_in_unittest.py", line 21, in <module>
    if __name__ == '__main__':
  File "/usr/lib/python3.4/unittest/main.py", line 92, in __init__
    self.parseArgs(argv)
  File "/usr/lib/python3.4/unittest/main.py", line 139, in parseArgs
    self.createTests()
  File "/usr/lib/python3.4/unittest/main.py", line 146, in createTests
    self.module)
  File "/usr/lib/python3.4/unittest/loader.py", line 146, in loadTestsFromNames
    suites = [self.loadTestsFromName(name, module) for name in names]
  File "/usr/lib/python3.4/unittest/loader.py", line 146, in <listcomp>
    suites = [self.loadTestsFromName(name, module) for name in names]
  File "/usr/lib/python3.4/unittest/loader.py", line 114, in loadTestsFromName
    parent, obj = obj, getattr(obj, part)
AttributeError: 'module' object has no attribute 'suite'
```

Using `import pdb; pdb.set_trace()` (commented line in code below) in contrast continues as expected (without exception).

---

``` python
import unittest

class ATest(unittest.TestCase):
    def test_true(self):
        self.assertTrue(True)

def suite():
    return unittest.makeSuite(ATest, 'test_')

from IPython.terminal.debugger import TerminalPdb; TerminalPdb().set_trace()
#import pdb; pdb.set_trace()

if __name__ == '__main__':
    unittest.main(defaultTest='suite')
```



Discussion:
Update: I looked into this again (and also slightly updated the description).

The problem is triggered by line 62 of /usr/lib/python3.4/unittest/main.py: `self.module = __import__(module)`, with module = `"__main__"`.

Now running the example (of the issue description) with pdb set_trace() I get at the debugger prompt:

```
(Pdb) __import__("__main__")
<module '__main__' from '../snippets/test_ipython_debugger_in_unittest.py'>
(Pdb) dir(__import__("__main__"))
['ATest', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'pdb', 'suite', 'unittest']
```

This is actually what I would expect.

Doing the same with the IPython set_trace, I get at the debugger prompt:

```
ipdb> __import__("__main__")
<module '__main__'>
ipdb> dir(__import__("__main__"))
['In', 'Out', '_', '__', '___', '__builtin__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', '_dh', '_ih', '_oh', '_sh', 'exit', 'get_ipython', 'quit']
```

That's interesting all imports the test class and suite is missing. That means `"__main__"` is something IPython specific. This is not rolled back, and so unittest will fail as described above.

Actually I can locally workaround / fix this issue by the following command from the command prompt.

```
ipdb> import sys, os; sys.modules["__main__"] = __import__(os.path.basename(__file__.replace(".py","")))
```

That is: For me it looks like, that the IPython `"__main__"` logic needs to be closed / rolled back / finished / teardowned as soon as the ipdb command prompt is hit.

Does it work if you restore `__main__` like this after starting the debugger?

``` python
save_main = sys.modules['__main__']
TerminalPdb().set_trace()
sys.modules['__main__'] = save_main
```

Thank you for taking your time and looking into this issue!

I tried your solution and yes, this works also.

I did the same experiment with `IPython.core.debugger.Pdb` and it shows exactly the same behaviour and it is also resolved by this solution.

Does it make sense to do save_main at the very beginning of the `IPython.core.debugger.Pdb` class and restore it just before `Pdb.set_trace`?

Possibly [this branch](https://github.com/ipython/ipython/blob/3ad65eb369cd8aa05c17a85e761fe8ab54558295/IPython/core/debugger.py#L229), which it takes when IPython is not running, should save `__main__` and restore it just after creating the TerminalInteractiveShell instance.

It would be better if it could initialise as much of IPython as it needs without IPython modifying `sys.modules`, but I suspect that making that work cleanly would take a bit more time and effort.


Resolving patch:
diff --git a/IPython/core/debugger.py b/IPython/core/debugger.py
--- a/IPython/core/debugger.py
+++ b/IPython/core/debugger.py
@@ -227,10 +227,14 @@ def __init__(self, color_scheme=None, completekey=None,
         self.shell = get_ipython()
 
         if self.shell is None:
+            save_main = sys.modules['__main__']
             # No IPython instance running, we must create one
             from IPython.terminal.interactiveshell import \
                 TerminalInteractiveShell
             self.shell = TerminalInteractiveShell.instance()
+            # needed by any code which calls __import__("__main__") after
+            # the debugger was entered. See also #9941.
+            sys.modules['__main__'] = save_main 
 
         if color_scheme is not None:
             warnings.warn(


Test patch: