Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] update python 3.0 for vsc-base #258

Closed
wants to merge 25 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
6661251
also starting changes for vsc-base
vsoch May 9, 2018
84fd379
Merge branch 'update/python3' of github.com:vsoch/vsc-base into updat…
vsoch May 9, 2018
ec0b31b
bumping version and merging python3 changes into updated master
vsoch May 9, 2018
6e0638d
more tweaks for python3 compatibility - note that updates to vsc-inst…
vsoch May 10, 2018
36cd0f7
small round of changes for early easybuild testing
vsoch May 10, 2018
f0d7d53
changes to get python2 testing working, now python3 is probably broke…
vsoch May 10, 2018
3d28c90
stuck
vsoch May 11, 2018
90e2abc
not sure how to move forward
vsoch May 11, 2018
9d9be9f
Merge branch 'master' into update/python3
itkovian May 12, 2018
3aefc93
I cant do more without including LICENSE that needs to be found on pypi?
vsoch May 17, 2018
a8bd01f
Merge branch 'update/python3' of github.com:vsoch/vsc-base into updat…
vsoch May 17, 2018
ac6bc50
adding python versions 3 to travis
vsoch May 17, 2018
87aba51
tiny progress? the main bug with python3 is that running loops seems …
vsoch May 25, 2018
a3932a8
fixing up issues with rest.py. urllib2 is no longer!
vsoch May 25, 2018
34123cb
tests working for wrapper.py, needed to add check for python version …
vsoch May 25, 2018
9b47ca1
fixing affinity module import
vsoch May 25, 2018
be0316e
tests are running wouhou!
vsoch May 25, 2018
c77d2bf
travis needs future
vsoch May 25, 2018
04df6be
done for now, getting blocked/403 errors from rest.py
vsoch May 25, 2018
3cc6fa5
broke my testing environment, so I guess Im done. sorry.
vsoch May 26, 2018
161be5b
cannot compare (meaning do a sort) for subclasses that that are type …
vsoch May 27, 2018
5f8ad23
why are we trying to rewrite optparse/argpares???
vsoch May 27, 2018
2bc5387
back to forbidden http, used up testing for today!
vsoch May 27, 2018
1d68791
a little help would be nice, I have no idea wat some of these tests/f…
vsoch May 28, 2018
aee8e1d
Merge branch 'master' into update/python3
vsoch May 28, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions bin/logdaemon.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,9 @@ def start(self):

# get socket
self.socket_.bind((self.hostname, self.port))
print "FANCYLOG_SERVER_PID=%s" % self.pidfile
print "FANCYLOG_SERVER=%s:%d" % (socket.gethostname(), self.socket_.getsockname()[-1])
print "FANCYLOG_SERVER_LOGFILE=%s" % self.logfile
print("FANCYLOG_SERVER_PID=%s" % self.pidfile)
print("FANCYLOG_SERVER=%s:%d" % (socket.gethostname(), self.socket_.getsockname()[-1]))
print("FANCYLOG_SERVER_LOGFILE=%s" % self.logfile)
sys.stdout.flush()

# Start the daemon
Expand Down
22 changes: 11 additions & 11 deletions lib/vsc/utils/affinity.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,33 +294,33 @@ def setpriority(prio, which=None, who=None):
setLogLevelDebug()

cs = cpu_set_t()
print "__bits", cs.__bits
print "sizeof cpu_set_t", ctypes.sizeof(cs)
print("__bits", cs.__bits)
print("sizeof cpu_set_t", ctypes.sizeof(cs))
x = sched_getaffinity()
print "x", x
print("x", x)
hr_mask = "1-5,7,9,10-15"
print hr_mask, x.convert_hr_bits(hr_mask)
print x
print(hr_mask, x.convert_hr_bits(hr_mask))
print(x)
x.set_bits()
print x
print(x)

sched_setaffinity(x)
print sched_getaffinity()
print(sched_getaffinity())

x.convert_hr_bits("1")
x.set_bits()
sched_setaffinity(x)
y = sched_getaffinity()
print x, y
print(x, y)

print sched_getcpu()
print(sched_getcpu())

# resources
# nice -n 5 python affinity.py prints 5 here
currentprio = getpriority()
print "getpriority", currentprio
print("getpriority", currentprio)
newprio = 10
setpriority(newprio)
newcurrentprio = getpriority()
print "getpriority", newcurrentprio
print("getpriority", newcurrentprio)
assert newcurrentprio == newprio
2 changes: 1 addition & 1 deletion lib/vsc/utils/asyncprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def send(self, inp):

try:
written = os.write(self.stdin.fileno(), inp)
except OSError, why:
except OSError as why:
if why[0] == errno.EPIPE: # broken pipe
return self._close('stdin')
raise
Expand Down
8 changes: 4 additions & 4 deletions lib/vsc/utils/daemon.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def daemonize(self):
if pid > 0:
# exit first parent
sys.exit(0)
except OSError, e:
except OSError as e:
sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
sys.exit(1)

Expand All @@ -52,7 +52,7 @@ def daemonize(self):
if pid > 0:
# exit from second parent
sys.exit(0)
except OSError, e:
except OSError as e:
sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
sys.exit(1)

Expand Down Expand Up @@ -117,13 +117,13 @@ def stop(self):
while 1:
os.kill(pid, SIGTERM)
time.sleep(0.1)
except OSError, err:
except OSError as err:
err = str(err)
if err.find("No such process") > 0:
if os.path.exists(self.pidfile):
os.remove(self.pidfile)
else:
print str(err)
print(str(err))
sys.exit(1)

def restart(self):
Expand Down
2 changes: 1 addition & 1 deletion lib/vsc/utils/dateandtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def number(self, otherdate):
def get_other(self, shift=-1):
"""Return month that is shifted shift months: negative integer is in past, positive is in future"""
new = self.date.year * 12 + self.date.month - 1 + shift
return self.__class__(date(new // 12, new % 12 + 1, 01))
return self.__class__(date(new // 12, new % 12 + 1, 1))
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line, specifically the 01

return self.__class__(date(new // 12, new % 12 + 1, 01))

wasn't clear to me why it would be used instead of 1?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there's a good reason for the 01, it's exactly the same as 1...

Maybe because this refers to 1st day of the month? Dunno, but changing it to 1 seems fine to me.

We could double-check that this is covered by the tests to make sure changing it is OK, but I don't see how it could have any impact (famous last words!).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In python2 01 is the octal representation for 1, this is deprecated in python3 (should be 0o1)

If the 01 is needed for programatic reasons here, replace it with 0o1 instead of 1 (but I can't see a reason why it would make a difference)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh interesting! I didn't know this, but it looks like the 1 should be equivalent to 0o1 (see here https://bugs.python.org/issue1715302). And here is a confirmation (in Python 3) that the two produce the same result:

In [8]: datetime.date(2007, 5, 0o1)
Out[8]: datetime.date(2007, 5, 1)

In [9]: datetime.date(2007, 5, 1)
Out[9]: datetime.date(2007, 5, 1)


def interval(self, otherdate):
"""Return time ordered list of months between date and otherdate"""
Expand Down
2 changes: 1 addition & 1 deletion lib/vsc/utils/docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def mk_rst_table(titles, columns):
title_cnt, col_cnt = len(titles), len(columns)
if title_cnt != col_cnt:
msg = "Number of titles/columns should be equal, found %d titles and %d columns" % (title_cnt, col_cnt)
raise LengthNotEqualException, msg
raise LengthNotEqualException(msg)
table = []
tmpl = []
line= []
Expand Down
30 changes: 16 additions & 14 deletions lib/vsc/utils/fancylogger.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,12 @@ def _env_to_boolean(varname, default=False):
APOCALYPTIC = 'APOCALYPTIC'
# register new loglevelname
logging.addLevelName(logging.CRITICAL * 2 + 1, APOCALYPTIC)

# register QUIET, EXCEPTION and FATAL alias
logging._levelNames['EXCEPTION'] = logging.ERROR
logging._levelNames['FATAL'] = logging.CRITICAL
logging._levelNames['QUIET'] = logging.WARNING
if hasattr(logging,'_levelNames'):
logging._levelNames['EXCEPTION'] = logging.ERROR
logging._levelNames['FATAL'] = logging.CRITICAL
logging._levelNames['QUIET'] = logging.WARNING

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't find this in the logging 3.0 docs, so I'm guessing it is relevant only to some older version and we can just check and pass over if the data structure doesn't exist?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Python 2.7, there's this:

>>> import logging
>>> logging._levelNames
{0: 'NOTSET', 10: 'DEBUG', 'WARN': 30, 20: 'INFO', 'ERROR': 40, 'DEBUG': 10, 30: 'WARNING', 'INFO': 20, 'WARNING': 30, 40: 'ERROR', 50: 'CRITICAL', 'CRITICAL': 50, 'NOTSET': 0}

We are defining additional log levels here, which we are injecting in the _levelNames (hidden) dictionary.

I guess we'll need to figure out what the equivalent approach is in Python 3?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we want this https://docs.python.org/3/library/logging.html#logging.addLevelName and with the print you gave me above, I think all I need is that (the name and the level) for each of the new levels. Let me test it out.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Python 3 has levelToName as well:

import logging

In [2]: logging._levelToName
Out[2]: 
{0: 'NOTSET',
 10: 'DEBUG',
 20: 'INFO',
 30: 'WARNING',
 40: 'ERROR',
 50: 'CRITICAL'}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In [1]: import logging

In [2]: logging._levelToName
Out[2]: 
{0: 'NOTSET',
 10: 'DEBUG',
 20: 'INFO',
 30: 'WARNING',
 40: 'ERROR',
 50: 'CRITICAL'}

In [3]: logging.addLevelName(logging.CRITICAL,'PINKYANDTHEBRAIN')

In [4]: logging._levelToName
Out[4]: 
{0: 'NOTSET',
 10: 'DEBUG',
 20: 'INFO',
 30: 'WARNING',
 40: 'ERROR',
 50: 'PINKYANDTHEBRAIN'}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to replace it, which isn't what we want. I'm going to look into adding a custom level.


# mpi rank support
Expand Down Expand Up @@ -326,7 +328,7 @@ def raiseException(self, message, exception=None, catch=False):
exception = self.RAISE_EXCEPTION_CLASS

self.RAISE_EXCEPTION_LOG_METHOD(fullmessage)
raise exception, message, tb
raise exception(message)

# pylint: disable=unused-argument
def deprecated(self, msg, cur_ver, max_ver, depth=2, exception=None, log_callback=None, *args, **kwargs):
Expand Down Expand Up @@ -477,12 +479,12 @@ def getLogger(name=None, fname=False, clsname=False, fancyrecord=None):
l = logging.getLogger(fullname)
l.fancyrecord = fancyrecord
if _env_to_boolean('FANCYLOGGER_GETLOGGER_DEBUG'):
print 'FANCYLOGGER_GETLOGGER_DEBUG',
print 'name', name, 'fname', fname, 'fullname', fullname,
print "getRootLoggerName: ", getRootLoggerName()
print('FANCYLOGGER_GETLOGGER_DEBUG'),
print('name', name, 'fname', fname, 'fullname', fullname),
print("getRootLoggerName: ", getRootLoggerName())
if hasattr(l, 'get_parent_info'):
print 'parent_info verbose'
print "\n".join(l.get_parent_info("FANCYLOGGER_GETLOGGER_DEBUG"))
print('parent_info verbose')
print("\n".join(l.get_parent_info("FANCYLOGGER_GETLOGGER_DEBUG")))
sys.stdout.flush()
return l

Expand Down Expand Up @@ -585,7 +587,7 @@ def logToFile(filename, enable=True, filehandler=None, name=None, max_bytes=MAX_
os.makedirs(directory)
except Exception as ex:
exc, detail, tb = sys.exc_info()
raise exc, "Cannot create logdirectory %s: %s \n detail: %s" % (directory, ex, detail), tb
raise exc("Cannot create logdirectory %s: %s \n detail: %s" % (directory, ex, detail))

return _logToSomething(
logging.handlers.RotatingFileHandler,
Expand Down Expand Up @@ -745,8 +747,8 @@ def setLogLevel(level):

logger.setLevel(level)
if _env_to_boolean('FANCYLOGGER_LOGLEVEL_DEBUG'):
print "FANCYLOGGER_LOGLEVEL_DEBUG", level, logging.getLevelName(level)
print "\n".join(logger.get_parent_info("FANCYLOGGER_LOGLEVEL_DEBUG"))
print("FANCYLOGGER_LOGLEVEL_DEBUG", level, logging.getLevelName(level))
print("\n".join(logger.get_parent_info("FANCYLOGGER_LOGLEVEL_DEBUG")))
sys.stdout.flush()


Expand Down Expand Up @@ -865,8 +867,8 @@ class FancyRootLogger(FancyLogger, logging.RootLogger):
lgr[1].parent = root

if _env_to_boolean('FANCYLOGGER_LOGLEVEL_DEBUG'):
print "FANCYLOGGER_LOGLEVEL_DEBUG SETROOT ", lvl, logging.getLevelName(lvl)
print "\n".join(root.get_parent_info("FANCYLOGGER_LOGLEVEL_DEBUG SETROOT "))
print("FANCYLOGGER_LOGLEVEL_DEBUG SETROOT ", lvl, logging.getLevelName(lvl))
print("\n".join(root.get_parent_info("FANCYLOGGER_LOGLEVEL_DEBUG SETROOT ")))
sys.stdout.flush()

# silence the root logger
Expand Down
4 changes: 2 additions & 2 deletions lib/vsc/utils/generaloption.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ def _process_long_opt(self, rargs, values):
"""Extend optparse code with catch of unknown long options error"""
try:
OptionParser._process_long_opt(self, rargs, values)
except BadOptionError, err:
except BadOptionError as err:
self.largs.append(err.opt_str)

def _process_short_opts(self, rargs, values):
Expand Down Expand Up @@ -1252,7 +1252,7 @@ def parseoptions(self, options_list=None):

try:
(self.options, self.args) = self.parser.parse_args(options_list)
except SystemExit, err:
except SystemExit as err:
self.log.debug("parseoptions: parse_args err %s code %s" % (err, err.code))
if self.no_system_exit:
return
Expand Down
12 changes: 6 additions & 6 deletions lib/vsc/utils/mail.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,30 +96,30 @@ def _send(self,
s.connect()
try:
s.sendmail(mail_from, mail_to, msg.as_string())
except smtplib.SMTPHeloError, err:
except smtplib.SMTPHeloError as err:
self.log.error("Cannot get a proper response from the SMTP host" +
(self.mail_host and " %s" % (self.mail_host) or ""))
raise
except smtplib.SMTPRecipientsRefused, err:
except smtplib.SMTPRecipientsRefused as err:
self.log.error("All recipients were refused by SMTP host" +
(self.mail_host and " %s" % (self.mail_host) or "") +
" [%s]" % (mail_to))
raise
except smtplib.SMTPSenderRefused, err:
except smtplib.SMTPSenderRefused as err:
self.log.error("Sender was refused by SMTP host" +
(self.mail_host and " %s" % (self.mail_host) or "") +
"%s" % (mail_from))
raise
except smtplib.SMTPDataError, err:
except smtplib.SMTPDataError as err:
raise
except smtplib.SMTPConnectError, err:
except smtplib.SMTPConnectError as err:
self.log.exception("Cannot connect to the SMTP host" + (self.mail_host and " %s" % (self.mail_host) or ""))
raise VscMailError(mail_host=self.mail_host,
mail_to=mail_to,
mail_from=mail_from,
mail_subject=mail_subject,
err=err)
except Exception, err:
except Exception as err:
self.log.exception("Some unknown exception occurred in VscMail.sendTextMail. Raising a VscMailError.")
raise VscMailError(mail_host=self.mail_host,
mail_to=mail_to,
Expand Down
8 changes: 4 additions & 4 deletions lib/vsc/utils/missing.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ def __getitem__(self, key, *args, **kwargs):
"""Redefine __getitem__ to provide a better KeyError message."""
try:
return super(FrozenDictKnownKeys, self).__getitem__(key, *args, **kwargs)
except KeyError, err:
except KeyError as err:
if key in self.KNOWN_KEYS:
raise KeyError(err)
else:
Expand Down Expand Up @@ -293,12 +293,12 @@ def get_class_for(modulepath, class_name):
# try to import specified module path, reraise ImportError if it occurs
try:
module = __import__(modulepath, globals(), locals(), [''])
except ImportError, err:
except ImportError as err:
raise ImportError(err)
# try to import specified class name from specified module path, throw ImportError if this fails
try:
klass = getattr(module, class_name)
except AttributeError, err:
except AttributeError as err:
raise ImportError("Failed to import %s from %s: %s" % (class_name, modulepath, err))
return klass

Expand Down Expand Up @@ -335,7 +335,7 @@ def new_function(*args, **kwargs):
for i in xrange(0, self.n):
try:
return function(*args, **kwargs)
except self.exceptions, err:
except self.exceptions as err:
if i == self.n - 1:
raise
_log.exception("try_or_fail caught an exception - attempt %d: %s" % (i, err))
Expand Down
6 changes: 3 additions & 3 deletions lib/vsc/utils/optcomplete.py
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ def autocomplete(parser, arg_completer=None, opt_completer=None, subcmd_complete
if isinstance(completions, basestring):
# is a bash command, just run it
if SHELL in (BASH,): # TODO: zsh
print completions
print(completions)
else:
raise Exception("Commands are unsupported by this shell %s" % SHELL)
else:
Expand All @@ -555,9 +555,9 @@ def autocomplete(parser, arg_completer=None, opt_completer=None, subcmd_complete

# Save results
if SHELL == "bash":
print 'COMPREPLY=(' + completions + ')'
print('COMPREPLY=(' + completions + ')')
else:
print completions
print(completions)

# Print debug output (if needed). You can keep a shell with 'tail -f' to
# the log file to monitor what is happening.
Expand Down
5 changes: 5 additions & 0 deletions lib/vsc/utils/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@
@author: Stijn De Weirdt (Ghent University)
"""

try:
basestring
except:
basestring = str

import errno
import logging
import os
Expand Down
6 changes: 3 additions & 3 deletions test/dateandtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ def suite():
today = datetime.date.today()
endapril = datetime.date(today.year, 4, 10)
f = FancyMonth(endapril)
print f.nrdays, 30 # nr days in month
print(f.nrdays, 30) # nr days in month

may2nd = datetime.date(today.year, 5, 2)
print f.number(may2nd), 2 # spans 2 months
print [x.nrdays for x in f.interval(may2nd)], [30, 31] # interval returns FancyMonth instances
print(f.number(may2nd), 2) # spans 2 months
print([x.nrdays for x in f.interval(may2nd)], [30, 31]) # interval returns FancyMonth instances
2 changes: 1 addition & 1 deletion test/fancylogger.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ def somefunction(self):
handler = fancylogger.logToScreen()
logger = fancylogger.getLogger(fname=False, clsname=False)
logger.warn("blabla")
print stringfile.getvalue()
print(stringfile.getvalue())
# this will only hold in debug mode, so also disable the test
if __debug__:
self.assertTrue('FancyLoggerTest' in stringfile.getvalue())
Expand Down
2 changes: 1 addition & 1 deletion test/generaloption.py
Original file line number Diff line number Diff line change
Expand Up @@ -787,7 +787,7 @@ def test_error_env_options(self):
msg='no errors logged, got %s' % self.count_logcache('error'))

topt1 = TestOption1(go_args=['--level-level'], envvar_prefix='GENERALOPTIONTEST', error_env_options=True)
print self.LOGCACHE['error']
print(self.LOGCACHE['error'])
self.assertEqual(self.count_logcache('error'), 1,
msg='one error should be logged, got %s' % self.count_logcache('error'))

Expand Down
2 changes: 1 addition & 1 deletion test/missing.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def generate_random_dag():
"""
myseed = randint(0, sys.maxint)
seed(myseed)
print "testing with random seed", myseed
print("testing with random seed", myseed)
edge_probability = randint(10, 30)
ranks = randint(3, 10)
graph = {}
Expand Down
2 changes: 1 addition & 1 deletion test/optcomplete.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def _call(self, **kwargs):
# missing mandatory CALL_ARGS
try:
nc()
except Exception, e:
except Exception as e:
pass

self.assertEqual(e.__class__, CompleterMissingCallArgument)
Expand Down