diff options
author | Fred Wright <fw@fwright.net> | 2016-04-09 19:57:14 -0700 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 2016-04-10 04:58:50 -0400 |
commit | 7a98971bd84ee294cb233887243d32bdb1d29520 (patch) | |
tree | bef431d85b95fd4e5d271d29797155d3ad13950a /leapsecond.py | |
parent | c1fc8432489e10ab08e2fc9c66312343e9245032 (diff) | |
download | gpsd-7a98971bd84ee294cb233887243d32bdb1d29520.tar.gz |
Fixes leapseconds.py for Python 3.
This fixes two Python 3 issues with leapsecond.py:
1) The urllib module is subdivided in Python 3. Only the 'request'
submodule is needed here. Either that or the Python 2 urllib is now
imported as 'urlrequest'.
2) The data returned by urlopen() is 'bytes' in Python 3, requiring
the polystr transformation to be usable as a string.
Also, the (duplicate) isotime() definition here has been updated to
match the version in gps/misc.py. It is still duplicated to avoid a
dependency on the latter, as is the needed portion of the polystr
code.
TESTED:
Ran "scons build-all check". Also ran "leapsecond.py -f" with all six
supported Python versions, and verified that the result matches the
existing leapseconds.cache. Did *not* test the updated retrieve()
function, but it's not used anywhere.
Diffstat (limited to 'leapsecond.py')
-rwxr-xr-x | leapsecond.py | 88 |
1 files changed, 61 insertions, 27 deletions
diff --git a/leapsecond.py b/leapsecond.py index 3bd13e25..e43f353d 100755 --- a/leapsecond.py +++ b/leapsecond.py @@ -46,13 +46,69 @@ BSD terms apply: see the file COPYING in the distribution root for details. # This code runs under both Python 2 and Python 3. Preserve this property! from __future__ import print_function, division -import os, urllib, re, random, time, calendar, math, sys, signal +import os, re, random, time, calendar, math, sys, signal + +try: + import urllib.request as urlrequest # Python 3 +except ImportError: + import urllib as urlrequest # Python 2 # Set a socket timeout for slow servers import socket socket.setdefaulttimeout(30) del socket +# *** Duplicate some code from gps.misc to avoid a dependency *** + +# Determine a single class for testing "stringness" +try: + STR_CLASS = basestring # Base class for 'str' and 'unicode' in Python 2 +except NameError: + STR_CLASS = str # In Python 3, 'str' is the base class + +# Polymorphic str/bytes handling + +BINARY_ENCODING = 'latin-1' + +if bytes is str: # In Python 2 these functions can be null transformations + + polystr = str + +else: # Otherwise we do something real + + def polystr(o): + "Convert bytes or str to str with proper encoding." + if isinstance(o, str): + return o + if isinstance(o, bytes): + return str(o, encoding=BINARY_ENCODING) + raise ValueError + + +def isotime(s): + "Convert timestamps in ISO8661 format to and from Unix time including optional fractional seconds." + if isinstance(s, int): + return time.strftime("%Y-%m-%dT%H:%M:%S", time.gmtime(s)) + elif isinstance(s, float): + date = int(s) + msec = s - date + date = time.strftime("%Y-%m-%dT%H:%M:%S", time.gmtime(s)) + return date + "." + repr(msec)[3:] + elif isinstance(s, STR_CLASS): + if s[-1] == "Z": + s = s[:-1] + if "." in s: + (date, msec) = s.split(".") + else: + date = s + msec = "0" + # Note: no leap-second correction! + return calendar.timegm(time.strptime(date, "%Y-%m-%dT%H:%M:%S")) + float("0." + msec) + else: + raise TypeError + +# *** End of duplicated code *** + verbose = 0 __locations = [ @@ -87,29 +143,6 @@ def gps_rollovers(t): return (t - GPS_EPOCH) // SECS_PER_WEEK // ROLLOVER -def isotime(s): - "Convert timestamps in ISO8661 format to and from Unix time including optional fractional seconds." - if type(s) == type(1): - return time.strftime("%Y-%m-%dT%H:%M:%S", time.gmtime(s)) - elif type(s) == type(1.0): - date = int(s) - msec = s - date - date = time.strftime("%Y-%m-%dT%H:%M:%S", time.gmtime(s)) - return date + "." + repr(msec)[3:] - elif type(s) == type("") or type(s) == type(""): - if s[-1] == "Z": - s = s[:-1] - if "." in s: - (date, msec) = s.split(".") - else: - date = s - msec = "0" - # Note: no leap-second correction! - return calendar.timegm(time.strptime(date, "%Y-%m-%dT%H:%M:%S")) + float("0." + msec) - else: - raise TypeError - - def retrieve(): "Retrieve current leap-second from Web sources." random.shuffle(__locations) # To spread the load @@ -118,8 +151,8 @@ def retrieve(): if os.path.exists(url): ifp = open(url) else: - ifp = urllib.urlopen(url) - txt = ifp.read() + ifp = urlrequest.urlopen(url) + txt = polystr(ifp.read()) ifp.close() if verbose: sys.stderr.write("%s\n" % txt) @@ -163,7 +196,7 @@ def save_leapseconds(outfile): for (_, _, _, _, url) in __locations: skip = True try: - fetchobj = urllib.urlopen(url) + fetchobj = urlrequest.urlopen(url) except IOError: sys.stderr.write("Fetch from %s failed.\n" % url) continue @@ -171,6 +204,7 @@ def save_leapseconds(outfile): # always integrally one second and every increment is listed here fp = open(outfile, "w") for line in fetchobj: + line = polystr(line) if verbose: sys.stderr.write("%s\n" % line[:-1]) if line.startswith(" 1980"): |