Skip to content
Browse files

Simultaneous Python 2/3 compatibility.

  • Loading branch information...
1 parent b32b4e5 commit 605d9e1c2ec223c506b954eb6ae6b819d0aa5599 @bfroehle bfroehle committed
Showing with 92 additions and 43 deletions.
  1. +3 −3 debug_me.py
  2. +5 −4 pudb/__init__.py
  3. +19 −10 pudb/debugger.py
  4. +2 −2 pudb/ipython.py
  5. +8 −1 pudb/lowlevel.py
  6. +16 −0 pudb/py3compat.py
  7. +1 −1 pudb/run.py
  8. +11 −5 pudb/settings.py
  9. +3 −2 pudb/source_view.py
  10. +3 −4 pudb/theme.py
  11. +6 −4 pudb/ui_tools.py
  12. +15 −7 pudb/var_view.py
View
6 debug_me.py
@@ -35,9 +35,9 @@ def fermat(n):
if x**n + y**n == z**n:
yield x, y, z
-print "SF", simple_func(10)
+print("SF %s" % simple_func(10))
for i in fermat(2):
- print i
+ print(i)
-print "FINISHED"
+print("FINISHED")
View
9 pudb/__init__.py
@@ -1,7 +1,7 @@
NUM_VERSION = (2012, 2, 1)
VERSION = ".".join(str(nv) for nv in NUM_VERSION)
-
+from pudb.py3compat import raw_input
CURRENT_DEBUGGER = []
@@ -46,14 +46,15 @@ def runscript(mainpyfile, args=None, pre_run="", steal_output=False):
from subprocess import call
retcode = call(pre_run, close_fds=True, shell=True)
if retcode:
- print "*** WARNING: pre-run process exited with code %d." % retcode
+ print("*** WARNING: pre-run process exited with code %d." % retcode)
raw_input("[Hit Enter]")
status_msg = ""
try:
dbg._runscript(mainpyfile)
- except SystemExit, se:
+ except SystemExit:
+ se = sys.exc_info()[1]
status_msg = "The debuggee exited normally with status code %s.\n\n" % se.code
except:
dbg.post_mortem = True
@@ -149,4 +150,4 @@ def pm():
if __name__ == "__main__":
- print "You now need to type 'python -m pudb.run'. Sorry."
+ print("You now need to type 'python -m pudb.run'. Sorry.")
View
29 pudb/debugger.py
@@ -4,14 +4,17 @@
from __future__ import division
import urwid
import bdb
+import sys
from pudb.settings import load_config, save_config
CONFIG = load_config()
save_config(CONFIG)
-
-
-
+from pudb.py3compat import PY3
+if PY3:
+ _next = "__next__"
+else:
+ _next = "next"
HELP_TEXT = """\
@@ -124,7 +127,10 @@ def __init__(self, steal_output=False):
if steal_output:
raise NotImplementedError("output stealing")
import sys
- from cStringIO import StringIO
+ if PY3:
+ from io import StringIO
+ else:
+ from cStringIO import StringIO
self.stolen_output = sys.stderr = sys.stdout = StringIO()
sys.stdin = StringIO("") # avoid spurious hangs
@@ -132,7 +138,7 @@ def save_breakpoints(self):
from pudb.settings import save_breakpoints
save_breakpoints([
bp
- for fn, bp_lst in self.get_all_breaks().iteritems()
+ for fn, bp_lst in self.get_all_breaks().items()
for lineno in bp_lst
for bp in self.get_breaks(fn, lineno)
if not bp.temporary])
@@ -280,7 +286,10 @@ def _runscript(self, filename):
# user_call for details).
self._wait_for_mainpyfile = 1
self.mainpyfile = self.canonic(filename)
- statement = 'execfile( "%s")' % filename
+ if PY3:
+ statement = 'exec(compile(open("%s").read(), "%s", "exec"))' % (filename, filename)
+ else:
+ statement = 'execfile( "%s")' % filename
self.run(statement, globals=globals_, locals=locals_)
# }}}
@@ -834,7 +843,7 @@ def toggle_breakpoint(w, size, key):
self.update_breakpoints()
else:
- raise RuntimeError, "no valid current file"
+ raise RuntimeError("no valid current file")
def pick_module(w, size, key):
from os.path import splitext
@@ -1344,7 +1353,7 @@ def interaction(self, exc_tuple):
from pudb import VERSION
caption = [(None,
- u"PuDB %s - ?:help n:next s:step into b:breakpoint o:output "
+ "PuDB %s - ?:help n:next s:step into b:breakpoint o:output "
"t:run to cursor !:python shell"
% VERSION)]
@@ -1386,7 +1395,7 @@ def set_current_file(self, fname):
lines = getlines(fname)
from pudb.lowlevel import detect_encoding
- source_enc, _ = detect_encoding(iter(lines).next)
+ source_enc, _ = detect_encoding(getattr(iter(lines), _next))
decoded_lines = []
for l in lines:
@@ -1446,7 +1455,7 @@ def update_var_view(self, locals=None, globals=None):
def _get_bp_list(self):
return [bp
- for fn, bp_lst in self.debugger.get_all_breaks().iteritems()
+ for fn, bp_lst in self.debugger.get_all_breaks().items()
for lineno in bp_lst
for bp in self.debugger.get_breaks(fn, lineno)
if not bp.temporary]
View
4 pudb/ipython.py
@@ -24,7 +24,7 @@ def pudb_f_v10(self, arg):
"""
if not arg.strip():
- print __doc__
+ print(__doc__)
return
from IPython.genutils import arg_split
@@ -52,7 +52,7 @@ def pudb_f_v11(self, arg):
# Get the running instance
if not arg.strip():
- print __doc__
+ print(__doc__)
return
from IPython.utils.process import arg_split
View
9 pudb/lowlevel.py
@@ -1,3 +1,5 @@
+from pudb.py3compat import PY3
+
# breakpoint validity ---------------------------------------------------------
def generate_executable_lines_for_code(code):
l = code.co_firstlineno
@@ -80,6 +82,8 @@ def lookup_module(filename):
import re
cookie_re = re.compile("^\s*#.*coding[:=]\s*([-\w.]+)")
from codecs import lookup, BOM_UTF8
+if PY3:
+ BOM_UTF8 = BOM_UTF8.decode()
def detect_encoding(readline):
"""
@@ -108,7 +112,10 @@ def read_or_stop():
def find_cookie(line):
try:
- line_string = line.decode('ascii')
+ if PY3:
+ line_string = line
+ else:
+ line_string = line.decode('ascii')
except UnicodeDecodeError:
return None
View
16 pudb/py3compat.py
@@ -0,0 +1,16 @@
+import sys
+
+PY3 = sys.version_info[0] >= 3
+if PY3:
+ raw_input = input
+ xrange = range
+ integer_types = (int,)
+ string_types = (str,)
+ def execfile(fname, globs, locs=None):
+ exec(compile(open(fname).read(), fname, 'exec'), globs, locs or globs)
+else:
+ raw_input = raw_input
+ xrange = xrange
+ integer_types = (int, long)
+ string_types = (basestring,)
+ execfile = execfile
View
2 pudb/run.py
@@ -19,7 +19,7 @@ def main():
mainpyfile = args[0]
from os.path import exists, dirname
if not exists(mainpyfile):
- print 'Error:', mainpyfile, 'does not exist'
+ print('Error: %s does not exist' % mainpyfile)
sys.exit(1)
sys.argv = args
View
16 pudb/settings.py
@@ -1,5 +1,11 @@
import os
-from ConfigParser import ConfigParser
+import sys
+
+from pudb.py3compat import PY3
+if PY3:
+ from configparser import ConfigParser
+else:
+ from ConfigParser import ConfigParser
# minor LGPL violation: stolen from python-xdg
@@ -20,7 +26,7 @@ def get_save_config_path(*resource):
assert not resource.startswith('/')
path = os.path.join(xdg_config_home, resource)
if not os.path.isdir(path):
- os.makedirs(path, 0700)
+ os.makedirs(path, 448) # 0o700
return path
# end LGPL violation
@@ -90,8 +96,8 @@ def save_config(conf_dict):
cparser = ConfigParser()
cparser.add_section(CONF_SECTION)
- for key, val in conf_dict.iteritems():
- cparser.set(CONF_SECTION, key, val)
+ for key, val in conf_dict.items():
+ cparser.set(CONF_SECTION, key, str(val))
try:
outf = open(join(get_save_config_path(),
@@ -353,7 +359,7 @@ def parse_breakpoints(lines):
arg = arg[colon+1:].lstrip()
try:
lineno = int(arg)
- except ValueError, msg:
+ except ValueError:
continue
else:
continue
View
5 pudb/source_view.py
@@ -28,13 +28,14 @@ def set_breakpoint(self, has_breakpoint):
self.has_breakpoint = has_breakpoint
self._invalidate()
- def rows(self, (maxcol,), focus=False):
+ def rows(self, size, focus=False):
return 1
- def render(self, (maxcol,), focus=False):
+ def render(self, size, focus=False):
from pudb.debugger import CONFIG
render_line_nr = CONFIG["line_numbers"]
+ maxcol = size[0]
hscroll = self.dbg_ui.source_hscroll_start
attrs = []
if self.is_current:
View
7 pudb/theme.py
@@ -1,7 +1,6 @@
THEMES = ["classic", "vim", "dark vim", "midnight"]
-
-
+from pudb.py3compat import execfile, raw_input
def get_palette(may_use_fancy_formats, theme="classic"):
if may_use_fancy_formats:
@@ -288,10 +287,10 @@ def add_setting(color, setting):
from os.path import expanduser
execfile(expanduser(theme), symbols)
except:
- print "Error when importing theme:"
+ print("Error when importing theme:")
from traceback import print_exc
print_exc()
raw_input("Hit enter:")
- return [(key,)+value for key, value in palette_dict.iteritems()]
+ return [(key,)+value for key, value in palette_dict.items()]
View
10 pudb/ui_tools.py
@@ -103,10 +103,11 @@ def __init__(self, is_current, name, class_name, filename, line):
def selectable(self):
return True
- def rows(self, (maxcol,), focus=False):
+ def rows(self, size, focus=False):
return 1
- def render(self, (maxcol,), focus=False):
+ def render(self, size, focus=False):
+ maxcol = size[0]
if focus:
apfx = "focused "
else:
@@ -143,10 +144,11 @@ def __init__(self, is_current, filename, line):
def selectable(self):
return True
- def rows(self, (maxcol,), focus=False):
+ def rows(self, size, focus=False):
return 1
- def render(self, (maxcol,), focus=False):
+ def render(self, size, focus=False):
+ maxcol = size[0]
if focus:
apfx = "focused "
else:
View
22 pudb/var_view.py
@@ -2,6 +2,7 @@
# constants and imports -------------------------------------------------------
import urwid
+import sys
try:
import numpy
@@ -9,6 +10,13 @@
except ImportError:
HAVE_NUMPY = 0
+from pudb.py3compat import PY3, execfile, raw_input, xrange, \
+ integer_types, string_types
+if PY3:
+ ELLIPSIS = ''
+else:
+ ELLIPSIS = unicode('', 'utf-8')
+
from pudb.debugger import CONFIG
# data ------------------------------------------------------------------------
@@ -179,7 +187,7 @@ def render(self, size, focus=False):
for i in xrange(len(text)):
if len(text[i]) > maxcol:
text[i] = (unicode(text[i][:maxcol-1])
- + unicode(u'') + unicode(text[i][maxcol:]))
+ + ELLIPSIS + unicode(text[i][maxcol:]))
# XXX: This doesn't work. It just gives a ?
# Strangely, the following does work (it gives the …
# three characters from the right):
@@ -219,15 +227,15 @@ def get_stringifier(iinfo):
from os.path import expanduser
execfile(expanduser(iinfo.display_type), custom_stringifier_dict)
except:
- print "Error when importing custom stringifier:"
+ print("Error when importing custom stringifier:")
from traceback import print_exc
print_exc()
raw_input("Hit enter:")
return lambda value: "ERROR: Invalid custom stringifier file."
else:
if "pudb_stringifier" not in custom_stringifier_dict:
- print "%s does not contain " % iinfo.display_type
- "a function named pudb_stringifier at the module level."
+ print("%s does not contain a function named pudb_stringifier at"
+ "the module level." % iinfo.display_type)
raw_input("Hit enter:")
return lambda value: ("ERROR: Invalid custom stringifier file: "
"pudb_stringifer not defined.")
@@ -250,9 +258,9 @@ def walk_value(self, prefix, label, value, id_path=None, attr_prefix=None):
iinfo = self.frame_var_info.get_inspect_info(id_path, read_only=True)
- if isinstance(value, (int, float, long, complex)):
+ if isinstance(value, integer_types + (float, complex)):
self.add_item(prefix, label, repr(value), id_path, attr_prefix)
- elif isinstance(value, (str, unicode)):
+ elif isinstance(value, string_types):
self.add_item(prefix, label, repr(value), id_path, attr_prefix)
else:
try:
@@ -444,7 +452,7 @@ def add_item(self, prefix, var_label, value_str, id_path=None, attr_prefix=None)
SEPARATOR = urwid.AttrMap(urwid.Text(""), "variable separator")
def make_var_view(frame_var_info, locals, globals):
- vars = locals.keys()
+ vars = list(locals.keys())
vars.sort(key=lambda n: n.lower())
tmv_walker = TopAndMainVariableWalker(frame_var_info)

0 comments on commit 605d9e1

Please sign in to comment.
Something went wrong with that request. Please try again.