2

I've tracked down a bug in which io.open() should have been passed 'utf-8' instead of 'utf8'. Minimal executable code below. Why doesn't the IPython traceback indicate a line number, and why does pdb neither report that the error was with the io.open function call nor report anything from within the the io.open code? What could I have done with pdb or the IPython debugger or the Canopy debugger layered on top of it to have had an easier time debugging this one?

Checking my IPython version is also confusing. The Canopy package manager reports that both ipython 4.0.0-3 and ipython4 4.0.0-9 are installed, but import IPython followed by IPython.version_info evaluates to (2, 4, 1, '').

my_module.py in Canopy code editor:

import io def my_function(filename): with io.open(my_other_function(filename), u'r', u'utf8') def my_other_function(text): return u'modified' + text 

In the IPython session:

In []: import pdb In []: import my_module In []: my_module.my_function(filename) ------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-5-4c50d9f6cb5c> in <module>() ----> 1 my_module.my_function(filename) C:\my_module in my_function(filename) TypeError: an integer is required In []: pdb.pm() > c:\users\bbrown\documents\github\canvasapi-python\capi\my_module.py(3)my_function() -> with io.open(my_other_function(filename), u'w', u'utf8') as filehandle: (Pdb) up > <ipython-input-14-f6d6cc2c1670>(1)<module>() -> my_module.my_function('testjunk') (Pdb) down > c:\users\bbrown\documents\github\canvasapi-python\capi\my_module.py(3)my_function() -> with io.open(my_other_function(filename), u'w', u'utf8') as filehandle: (Pdb) args filename = testjunk (Pdb) down *** Newest frame 

Given that 'utf-8' works fine as an argument, the TypeError is surprising unless originating from within the code of open, yet the call to open was not placed on the stack, at least not as navigable from pdb. Thank you for helping me and others learn how to debug more efficiently!

2
  • Edited to show my_other_function. I had removed it from the question when initially writing because I knew the error to be with io.open, but my question is ultimately about how to debug, and the embedded call is what made it opaque for a moment to me. Commented Jan 1, 2016 at 22:02
  • 2
    Regarding your IPython versions... Canopy GUI's IPython shell uses IPython 2.4.1, which is separate from the IPython installed into your User venv by Package Manager. The IPython installed by Package Manager can be accessed in a Canopy Terminal/ Command Prompt. The "ipython4" package is what is imported with import IPython outside of the Canopy GUI and is a dependency of the "ipython" package. This scheme was created to maintain the naming convention for users needing ipython < v4. The "ipython" package installs all dependencies of ipython/jupyter and is what should typically be installed. Commented Jan 1, 2016 at 22:37

1 Answer 1

5

io.open is a builtin function:

In [8]: import io In [9]: type(io.open) Out[9]: builtin_function_or_method 

It's not written in Python, so there's nothing for the debugger to debug. Your error is caused by improper arguments being passed into io.open:

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) -> file object 

You passed 'utf-8' as the third argument, but since buffering is supposed to be an integer, the function raised a descriptive TypeError. You can fix it by making encoding a keyword argument:

io.open(filename, mode='r', encoding='utf8') 

Also, you don't need to import the io module explicitly. The open builtin is exactly the same function:

In [15]: open Out[15]: <function io.open> 
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, that was the error, and your explanation about why no code from within open is shown in the traceback makes sense. I'm running Python 2.7, and open is <function open> while io.open is <function _io.open>. The encoding keyword produces an error with open but not with io.open.
I'm still wondering why the call to io.open isn't placed on the stack (I suppose because the call was never made because the arguments did not match the Type declared in the C function? And wondering about the IPython version numbers. And wondering if there are debugging techniques that would have made it easier for me to see that problem was with io.open rather than my_other_function (i.e. a way to know what that function returned without writing it on a separate line of code?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.