python 3 compatibility

This commit is contained in:
Dirk Thomas 2013-12-04 19:20:03 -08:00
parent 55e0339aa0
commit d1d3cc5514
22 changed files with 146 additions and 90 deletions

View File

@ -35,7 +35,7 @@
import sys
import os
PKG = os.path.split(os.getcwd())[1]
print "Creating pydev project for package '%s'"%PKG
print("Creating pydev project for package '%s'" % PKG)
import roslib; roslib.load_manifest(PKG)
pathlist = "\n".join(["<path>%s</path>"%path for path in sys.path if os.path.exists(path)])
@ -52,7 +52,7 @@ pydev_project= '''<?xml version="1.0" encoding="UTF-8" standalone="no"?>
</pydev_project>
'''%pathlist
print "Writing .pydevproject, adding %d modules"%len(sys.path)
print("Writing .pydevproject, adding %d modules" % len(sys.path))
f = open(".pydevproject","w")
f.write(pydev_project)
f.close()

View File

@ -8,14 +8,14 @@ import os.path
USAGE = "USAGE: rosgcov_summarize <package_dir> <rosgcov_file>"
if len(sys.argv) != 3:
print USAGE
print(USAGE)
sys.exit(-1)
pkg = sys.argv[1]
fname = sys.argv[2]
if not os.path.exists(fname):
print '[rosgcov] %s : %.2f%% (no coverage results)' % (os.path.split(pkg)[1],0.0)
print('[rosgcov] %s : %.2f%% (no coverage results)' % (os.path.split(pkg)[1],0.0))
sys.exit(0)
re_hit = re.compile('^ *[0-9]*:.*')
@ -38,18 +38,18 @@ misses = 0
branch_total = 0
branch_hits = 0
branch_misses = 0
print '-------------------------------------------------------'
print 'Coverage summary: '
print '-------------------------------------------------------'
print('-------------------------------------------------------')
print('Coverage summary: ')
print('-------------------------------------------------------')
for f in files:
prefix = os.path.commonprefix([pkg, f])
display_name = f[len(prefix):]
if display_name[0] == '/':
display_name = display_name[1:]
print ' ' + display_name + ': '
print(' ' + display_name + ': ')
gcov_fname = f + '.gcov'
if not os.path.exists(gcov_fname):
print 'WARNING: no coverage results for %s' % (display_name)
print('WARNING: no coverage results for %s' % (display_name))
continue
gcovf = fileinput.input(gcov_fname)
local_total = 0
@ -72,17 +72,17 @@ for f in files:
local_branch_misses += 1
local_branch_total += 1
print ' line: %.2f%% (%d / %d)' % ((100.0 * local_hits / max(local_total,1)), local_hits, local_total)
print(' line: %.2f%% (%d / %d)' % ((100.0 * local_hits / max(local_total,1)), local_hits, local_total))
hits += local_hits
misses += local_misses
total += local_total
print ' branch: %.2f%% (%d / %d)' % ((100.0 * local_branch_hits / max(local_branch_total,1)), local_branch_hits, local_branch_total)
print(' branch: %.2f%% (%d / %d)' % ((100.0 * local_branch_hits / max(local_branch_total,1)), local_branch_hits, local_branch_total))
branch_hits += local_branch_hits
branch_misses += local_branch_misses
branch_total += local_branch_total
print '-------------------------------------------------------'
print '[rosgcov] %s : %.2f%% (%d / %d)' % (os.path.split(pkg)[1],(100.0 * hits / max(total,1)), hits, total)
print '[rosgcov] %s : branch %.2f%% (%d / %d)' % (os.path.split(pkg)[1],(100.0 * branch_hits / max(branch_total,1)), branch_hits, branch_total)
print '-------------------------------------------------------'
print('-------------------------------------------------------')
print('[rosgcov] %s : %.2f%% (%d / %d)' % (os.path.split(pkg)[1],(100.0 * hits / max(total,1)), hits, total))
print('[rosgcov] %s : branch %.2f%% (%d / %d)' % (os.path.split(pkg)[1],(100.0 * branch_hits / max(branch_total,1)), branch_hits, branch_total))
print('-------------------------------------------------------')

View File

@ -66,11 +66,11 @@ def main():
m = hashlib.md5(open(dest).read())
d = m.hexdigest()
print '[rosbuild] Checking md5sum on %s'%(dest)
print('[rosbuild] Checking md5sum on %s'%(dest))
if d != md5sum:
if not fresh:
print '[rosbuild] WARNING: md5sum mismatch (%s != %s); re-downloading file %s'%(d, md5sum, dest)
print('[rosbuild] WARNING: md5sum mismatch (%s != %s); re-downloading file %s' % (d, md5sum, dest))
os.remove(dest)
# Try one more time
@ -79,7 +79,7 @@ def main():
d = m.hexdigest()
if d != md5sum:
print '[rosbuild] ERROR: md5sum mismatch (%s != %s) on %s; aborting'%(d, md5sum, dest)
print('[rosbuild] ERROR: md5sum mismatch (%s != %s) on %s; aborting' % (d, md5sum, dest))
return 1
return 0

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
import os
print os.sysconf(os.sysconf_names['SC_NPROCESSORS_ONLN'])
print(os.sysconf(os.sysconf_names['SC_NPROCESSORS_ONLN']))

View File

@ -38,6 +38,8 @@
## depends on. This is important for determining messages file that
## need to be rebuilt.
from __future__ import print_function
import sys
import roslib.msgs
@ -49,7 +51,7 @@ import rospkg
NAME='gendeps'
def usage(progname, stdout=sys.stdout):
print >> stdout, "%(progname)s msg-or-srv-file"%vars()
print("%(progname)s msg-or-srv-file" % vars(), file=stdout)
## main method for gendeps command
## @param argv [str]: sys args
@ -90,21 +92,21 @@ def gendeps_main(argv, stdout, stderr):
retval = roslib.gentools.get_file_dependencies(f, stdout=stdout, stderr=stderr, rospack=rospack)
if options.md5:
print >> stdout, roslib.gentools.compute_md5(retval, rospack=rospack)
print(roslib.gentools.compute_md5(retval, rospack=rospack), file=stdout)
elif options.sha1:
print >> stdout, roslib.gentools.compute_sha1(retval, rospack=rospack)
print(roslib.gentools.compute_sha1(retval, rospack=rospack), file=stdout)
elif options.cat_files:
# this option is used for the message definition that is
# stored in exchanged in ROS handshakes and then stored in bag
# files
print >> stdout, roslib.gentools.compute_full_text(retval)
print(roslib.gentools.compute_full_text(retval), file=stdout)
else:
print >> stdout, ' '.join(retval['files'].itervalues())
print(' '.join(retval['files'].values()), file=stdout)
if __name__ == "__main__":
try:
gendeps_main(sys.argv, sys.stdout, sys.stderr)
except Exception, e:
print >> sys.stderr, e
except Exception as e:
print(e, file=sys.stderr)
sys.exit(1)

View File

@ -171,10 +171,10 @@ def _compute_hash(get_deps_dict, hash, rospack=None):
from roslib.srvs import SrvSpec
spec = get_deps_dict['spec']
if isinstance(spec, MsgSpec):
hash.update(compute_md5_text(get_deps_dict, spec, rospack=rospack))
hash.update(compute_md5_text(get_deps_dict, spec, rospack=rospack).encode())
elif isinstance(spec, SrvSpec):
hash.update(compute_md5_text(get_deps_dict, spec.request, rospack=rospack))
hash.update(compute_md5_text(get_deps_dict, spec.response, rospack=rospack))
hash.update(compute_md5_text(get_deps_dict, spec.request, rospack=rospack).encode())
hash.update(compute_md5_text(get_deps_dict, spec.response, rospack=rospack).encode())
else:
raise Exception("[%s] is not a message or service"%spec)
return hash.hexdigest()
@ -321,7 +321,7 @@ def get_dependencies(spec, package, compute_files=True, stdout=sys.stdout, stder
_add_msgs_depends(rospack, spec.response, deps, package)
else:
raise MsgSpecException("spec does not appear to be a message or service")
except KeyError, e:
except KeyError as e:
raise MsgSpecException("Cannot load type %s. Perhaps the package is missing a dependency."%(str(e)))
# convert from type names to file names

View File

@ -383,9 +383,15 @@ class VersionControl(object):
@param url: URL associated with version control. must be non empty
@type url: str
"""
if not type_ or not isinstance(type_, basestring):
def is_string_type(obj):
try:
return isinstance(obj, basestring)
except NameError:
return isinstance(obj, str)
if not type_ or not is_string_type(type_):
raise ValueError("bad 'type' attribute")
if not url is None and not isinstance(url, basestring):
if not url is None and not is_string_type(url):
raise ValueError("bad 'url' attribute")
self.type = type_
self.url = url

View File

@ -172,7 +172,7 @@ def is_valid_msg_type(x):
state = 0 #closed
else:
try:
string.atoi(c)
int(c)
except:
return False
return state == 0

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
# this node only exists to test find_node functionality
print "hello"
print("hello")

View File

@ -143,8 +143,8 @@ class RoslibManifestTest(unittest.TestCase):
try:
parse_file(p)
self.fail("parse should have failed on bad manifest")
except ManifestException, e:
print str(e)
except ManifestException as e:
print(str(e))
self.assert_(b in str(e), "file name should be in error message: %s"%(str(e)))
EXAMPLE1 = """<package>

View File

@ -239,8 +239,8 @@ class RoslibManifestlibTest(unittest.TestCase):
try:
parse_file(m, p)
self.fail("parse should have failed on bad manifest")
except ManifestException, e:
print str(e)
except ManifestException as e:
print(str(e))
self.assert_(b in str(e), "file name should be in error message [%s]"%(str(e)))
EXAMPLE1 = """<package>

View File

@ -116,11 +116,11 @@ class RoslibStacksTest(unittest.TestCase):
d = os.path.join(d, 'test', 'stack_tests')
# - s1/s2/s3
print "s1/s2/s3"
print("s1/s2/s3")
paths = [os.path.join(d, p) for p in ['s1', 's2', 's3']]
os.environ[rospkg.environment.ROS_PACKAGE_PATH] = os.pathsep.join(paths)
# - run multiple times to test caching
for i in xrange(2):
for i in range(2):
stacks = roslib.stacks.list_stacks()
self.assert_('foo' in stacks)
self.assert_('bar' in stacks)
@ -131,7 +131,7 @@ class RoslibStacksTest(unittest.TestCase):
self.assertEquals(bar_p, roslib.stacks.get_stack_dir('bar'))
# - s2/s3/s1
print "s2/s3/s1"
print("s2/s3/s1")
paths = [os.path.join(d, p) for p in ['s2', 's3', 's1']]
os.environ[rospkg.environment.ROS_PACKAGE_PATH] = os.pathsep.join(paths)

View File

@ -62,8 +62,10 @@ def author_name():
except:
#pwd failed
pass
if type(name) == str:
try:
name = name.decode('utf-8')
except AttributeError:
pass
return name
def read_template(tmplf):
@ -80,8 +82,10 @@ def read_template(tmplf):
r = rospkg.RosPack()
with open(os.path.join(r.get_path('roscreate'), 'templates', tmplf)) as f:
t = f.read()
if type(t) == str:
try:
t = t.decode('utf-8')
except AttributeError:
pass
return t

View File

@ -87,7 +87,7 @@ def create_package(package, author, depends, uses_roscpp=False, uses_rospy=False
pass
templates = get_templates()
for filename, template in templates.iteritems():
for filename, template in templates.items():
contents = instantiate_template(template, package, package, package, author, depends)
p = os.path.abspath(os.path.join(package, filename))
with open(p, 'w') as f:

View File

@ -54,7 +54,7 @@ from . import parallel_build
from . import package_stats
from optparse import OptionParser
from gcc_output_parse import Warnings
from .gcc_output_parse import Warnings
# #3883
_popen_lock = threading.Lock()
@ -391,7 +391,7 @@ class RosMakeAll:
with _popen_lock:
command_line = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=local_env, preexec_fn=self._subprocess_setup)
(pstd_out, pstd_err) = command_line.communicate() # pstd_err should be None due to pipe above
return (command_line.returncode, pstd_out)
return (command_line.returncode, pstd_out.decode())
def build(self, p, argument = None, robust_build=False):
"""
@ -428,7 +428,7 @@ class RosMakeAll:
if num_warnings > 0:
return_string = "[PASS] [ %.2f seconds ] [ %d warnings "%(self.profile[argument][p], num_warnings)
warning_dict = warnings.analyze();
for warntype,warnlines in warning_dict.iteritems():
for warntype,warnlines in warning_dict.items():
if len( warnlines ) > 0:
return_string = return_string + '[ {0:d} {1} ] '.format(len(warnlines),warntype)
return_string = return_string + ' ]'

View File

@ -37,4 +37,4 @@ class Warnings:
@return A dictionary of lists of warning messages indexed by the warning type
@rtype {str:[str]}
"""
return dict( [ (t,self.byType(t)) for t,p in self._warning_pattern_map.iteritems() ] )
return dict( [ (t,self.byType(t)) for t,p in self._warning_pattern_map.items() ] )

View File

@ -43,7 +43,7 @@ import roslib
try:
import coverage
except ImportError, e:
except ImportError as e:
sys.stderr.write("ERROR: cannot import python-coverage, coverage report will not run.\nTo install coverage, run 'easy_install coverage'\n")
sys.exit(1)

View File

@ -42,13 +42,16 @@ from __future__ import print_function
import os
import sys
import cStringIO
try:
from cStringIO import StringIO
except ImportError:
from io import StringIO
import rospkg
import rosunit.junitxml as junitxml
def create_summary(result, packages):
buff = cStringIO.StringIO()
buff = StringIO()
buff.write('-'*80+'\n')
buff.write('\033[1m[AGGREGATED TEST RESULTS SUMMARY]\033[0m\n\n')

View File

@ -40,7 +40,10 @@ executables. These do not run in a ROS environment.
from __future__ import print_function
import os
import cStringIO
try:
from cStringIO import StringIO
except ImportError:
from io import StringIO
import unittest
import time
import signal
@ -149,7 +152,7 @@ class BareTestCase(unittest.TestCase):
raise TestTimeoutException("test max time allotted")
time.sleep(0.1)
except TestTimeoutException, e:
except TestTimeoutException as e:
if self.retry:
timeout_failure = True
else:
@ -252,11 +255,11 @@ class LocalProcess(pmon.Process):
if not os.path.exists(log_dir):
try:
os.makedirs(log_dir)
except OSError, (errno, msg):
if errno == 13:
except OSError as e:
if e.errno == 13:
raise RLException("unable to create directory for log file [%s].\nPlease check permissions."%log_dir)
else:
raise RLException("unable to create directory for log file [%s]: %s"%(log_dir, msg))
raise RLException("unable to create directory for log file [%s]: %s"%(log_dir, e.msg))
# #973: save log dir for error messages
self.log_dir = log_dir
@ -320,11 +323,11 @@ class LocalProcess(pmon.Process):
try:
self.popen = subprocess.Popen(self.args, cwd=cwd, stdout=logfileout, stderr=logfileerr, env=full_env, close_fds=True, preexec_fn=os.setsid)
except OSError, (errno, msg):
except OSError as e:
self.started = True # must set so is_alive state is correct
if errno == 8: #Exec format error
if e.errno == 8: #Exec format error
raise pmon.FatalProcessLaunch("Unable to launch [%s]. \nIf it is a script, you may be missing a '#!' declaration at the top."%self.name)
elif errno == 2: #no such file or directory
elif e.errno == 2: #no such file or directory
raise pmon.FatalProcessLaunch("""Roslaunch got a '%s' error while attempting to run:
%s
@ -470,7 +473,7 @@ def print_runner_summary(runner_results, junit_results, runner_name='ROSUNIT'):
# (i.e. doesn't check for actual test success). The 'r' result
# object contains results of the actual tests.
buff = cStringIO.StringIO()
buff = StringIO()
buff.write("[%s]"%(runner_name)+'-'*71+'\n\n')
for tc_result in junit_results.test_case_results:
@ -523,7 +526,7 @@ def print_unittest_summary(result):
Print summary of python unittest result to stdout
@param result: test results
"""
buff = cStringIO.StringIO()
buff = StringIO()
buff.write("-------------------------------------------------------------\nSUMMARY:\n")
if result.wasSuccessful():
buff.write("\033[32m * RESULT: SUCCESS\033[0m\n")

View File

@ -41,7 +41,10 @@ from __future__ import print_function
import os
import sys
import cStringIO
try:
from cStringIO import StringIO
except ImportError:
from io import StringIO
import string
import codecs
import re
@ -49,6 +52,7 @@ import re
from xml.dom.minidom import parse, parseString
from xml.dom import Node as DomNode
from functools import reduce
import rospkg
class TestInfo(object):
@ -71,14 +75,24 @@ class TestError(TestInfo):
'error' result container
"""
def xml(self):
return u'<error type="%s"><![CDATA[%s]]></error>'%(self.type, self.text)
data = '<error type="%s"><![CDATA[%s]]></error>' % (self.type, self.text)
try:
data = unicode(data)
except NameError:
pass
return data
class TestFailure(TestInfo):
"""
'failure' result container
"""
def xml(self):
return u'<failure type="%s"><![CDATA[%s]]></failure>'%(self.type, self.text)
data = '<failure type="%s"><![CDATA[%s]]></failure>' % (self.type, self.text)
try:
data = unicode(data)
except NameError:
pass
return data
class TestCaseResult(object):
@ -155,10 +169,15 @@ class TestCaseResult(object):
self.errors.append(error)
def xml(self):
return u' <testcase classname="%s" name="%s" time="%s">\n'%(self.classname, self.name, self.time)+\
'\n '.join([f.xml() for f in self.failures])+\
'\n '.join([e.xml() for e in self.errors])+\
data = ' <testcase classname="%s" name="%s" time="%s">\n' % (self.classname, self.name, self.time) + \
'\n '.join([f.xml() for f in self.failures]) + \
'\n '.join([e.xml() for e in self.errors]) + \
' </testcase>'
try:
data = unicode(data)
except NameError:
pass
return data
class Result(object):
__slots__ = ['name', 'num_errors', 'num_failures', 'num_tests', \
@ -201,13 +220,18 @@ class Result(object):
"""
@return: document as unicode (UTF-8 declared) XML according to Ant JUnit spec
"""
return u'<?xml version="1.0" encoding="utf-8"?>'+\
'<testsuite name="%s" tests="%s" errors="%s" failures="%s" time="%s">'%\
(self.name, self.num_tests, self.num_errors, self.num_failures, self.time)+\
'\n'.join([tc.xml() for tc in self.test_case_results])+\
' <system-out><![CDATA[%s]]></system-out>'%self.system_out+\
' <system-err><![CDATA[%s]]></system-err>'%self.system_err+\
data = '<?xml version="1.0" encoding="utf-8"?>' + \
'<testsuite name="%s" tests="%s" errors="%s" failures="%s" time="%s">' % \
(self.name, self.num_tests, self.num_errors, self.num_failures, self.time) + \
'\n'.join([tc.xml() for tc in self.test_case_results]) + \
' <system-out><![CDATA[%s]]></system-out>' % self.system_out + \
' <system-err><![CDATA[%s]]></system-err>' % self.system_err + \
'</testsuite>'
try:
data = unicode(data)
except NameError:
pass
return data
def _text(tag):
return reduce(lambda x, y: x + y, [c.data for c in tag.childNodes if c.nodeType in [DomNode.TEXT_NODE, DomNode.CDATA_SECTION_NODE]], "").strip()
@ -266,12 +290,23 @@ def _load_suite_results(test_suite_name, test_suite, result):
## #603: unit test suites are not good about screening out illegal
## unicode characters. This little recipe I from http://boodebr.org/main/python/all-about-python-and-unicode#UNI_XML
## screens these out
RE_XML_ILLEGAL = u'([\u0000-\u0008\u000b-\u000c\u000e-\u001f\ufffe-\uffff])' + \
u'|' + \
u'([%s-%s][^%s-%s])|([^%s-%s][%s-%s])|([%s-%s]$)|(^[%s-%s])' % \
(unichr(0xd800),unichr(0xdbff),unichr(0xdc00),unichr(0xdfff),
unichr(0xd800),unichr(0xdbff),unichr(0xdc00),unichr(0xdfff),
unichr(0xd800),unichr(0xdbff),unichr(0xdc00),unichr(0xdfff))
try:
char = unichr
except NameError:
char = chr
RE_XML_ILLEGAL = '([%s-%s%s-%s%s-%s%s-%s])' + \
'|' + \
'([%s-%s][^%s-%s])|([^%s-%s][%s-%s])|([%s-%s]$)|(^[%s-%s])'
try:
RE_XML_ILLEGAL = unicode(RE_XML_ILLEGAL)
except NameError:
pass
RE_XML_ILLEGAL = RE_XML_ILLEGAL % \
(char(0x0000),char(0x0008),char(0x000b),char(0x000c),
char(0x000e),char(0x001f),char(0xfffe),char(0xffff),
char(0xd800),char(0xdbff),char(0xdc00),char(0xdfff),
char(0xd800),char(0xdbff),char(0xdc00),char(0xdfff),
char(0xd800),char(0xdbff),char(0xdc00),char(0xdfff))
_safe_xml_regex = re.compile(RE_XML_ILLEGAL)
def _read_file_safe_xml(test_file, write_back_sanitized=True):
@ -297,7 +332,7 @@ def _read_file_safe_xml(test_file, write_back_sanitized=True):
x = x[:match.start()] + "?" + x[match.end():]
x = x.encode("utf-8")
if write_back_sanitized:
with open(test_file, 'w') as h:
with open(test_file, 'wb') as h:
h.write(x)
return x
finally:
@ -336,7 +371,7 @@ def read(test_file, test_name):
#test_suite = test_suite[0]
vals = [test_suite.getAttribute(attr) for attr in ['errors', 'failures', 'tests']]
vals = [v or 0 for v in vals]
err, fail, tests = [string.atoi(val) for val in vals]
err, fail, tests = [int(val) for val in vals]
result = Result(test_name, err, fail, tests)
result.time = 0.0 if not len(test_suite.getAttribute('time')) else float(test_suite.getAttribute('time'))
@ -431,7 +466,7 @@ def print_summary(junit_results, runner_name='ROSUNIT'):
# (i.e. doesn't check for actual test success). The 'r' result
# object contains results of the actual tests.
buff = cStringIO.StringIO()
buff = StringIO()
buff.write("[%s]"%runner_name+'-'*71+'\n\n')
for tc_result in junit_results.test_case_results:
buff.write(tc_result.description)

View File

@ -42,7 +42,10 @@ import os
import sys
import time
import traceback
import Queue
try:
from queue import Empty, Queue
except ImportError:
from Queue import Empty, Queue
import atexit
from threading import Thread, RLock, Lock
@ -98,7 +101,7 @@ def shutdown_process_monitor(process_monitor):
return False
else:
return True
except Exception, e:
except Exception as e:
return False
_shutdown_lock = Lock()
@ -409,7 +412,7 @@ class ProcessMonitor(Thread):
for l in self.listeners:
l.process_died(p.name, p.exit_code)
except Exception, e:
except Exception as e:
traceback.print_exc()
#don't respawn as this is an internal error
dead.append(p)
@ -453,7 +456,7 @@ class ProcessMonitor(Thread):
self.is_shutdown = True
# killall processes on run exit
q = Queue.Queue()
q = Queue()
q.join()
with self.plock:
@ -526,7 +529,7 @@ class _ProcessKiller(Thread):
p = q.get(False)
_kill_process(p, self.errors)
q.task_done()
except Queue.Empty:
except Empty:
pass

View File

@ -113,7 +113,7 @@ def start_coverage(packages):
_cov.start()
except coverage.CoverageException:
print("WARNING: you have an older version of python-coverage that is not support. Please update to the version provided by 'easy_install coverage'", file=sys.stderr)
except ImportError, e:
except ImportError as e:
print("""WARNING: cannot import python-coverage, coverage tests will not run.
To install coverage, run 'easy_install coverage'""", file=sys.stderr)
@ -164,9 +164,9 @@ def stop_coverage(packages, html=None):
print("="*80+"\ngenerating html coverage report to %s\n"%html+"="*80)
_cov.html_report(all_mods, directory=html)
except ImportError, e:
except ImportError as e:
print("WARNING: cannot import '%s', will not generate coverage report"%package, file=sys.stderr)
except ImportError, e:
except ImportError as e:
print("""WARNING: cannot import python-coverage, coverage tests will not run.
To install coverage, run 'easy_install coverage'""", file=sys.stderr)