From 287f71d5614dc091fb8a810854f82ceaafd73752 Mon Sep 17 00:00:00 2001
From: Alex Willmer <alex@moreati.org.uk>
Date: Fri, 10 May 2019 21:28:35 +0100
Subject: [PATCH] Fix uses of retired builtins and builtin methods

In Python 3.x

- int and long types are unified. The unified type is called int.
- the text string type (unicode) is renamed to str.
- the byte string type (str) is renamed to bytes.
- chr returns a text string (i.e. str)
- xrange is renamed to range.
- dict.has_key() is removed
-
---
 examples/base64_sem1.py    |  6 +++---
 examples/base64_sem2.py    |  2 +-
 src/bindings/swig/hammer.i | 29 +++++++++++++++++++++--------
 tools/csharp/csharp.py     | 16 ++++++++--------
 4 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/examples/base64_sem1.py b/examples/base64_sem1.py
index 2c4d6e04..1665ccbe 100644
--- a/examples/base64_sem1.py
+++ b/examples/base64_sem1.py
@@ -26,7 +26,7 @@ import hammer as h
 
 def act_bsfdig(p, user_data=None):
     # FIXME See the note in init_parser()
-    c = p if isinstance(p, (int, long)) else ord(p)
+    c = p if isinstance(p, h.INTEGER_TYPES) else ord(p)
 
     if 0x41 <= c <= 0x5A: # A-Z
         return c - 0x41
@@ -65,14 +65,14 @@ def act_base64_n(n, p, user_data=None):
 
     x = 0
     bits = 0
-    for i in xrange(0, n+1):
+    for i in range(0, n+1):
         x <<= 6
         x |= p[i] or 0
         bits += 6
 
     x >>= bits % 8 # align, i.e. cut off extra bits
 
-    for i in xrange(n):
+    for i in range(n):
         item = x & 0xFF
 
         res[n-1-i] = item   # output the last byte and
diff --git a/examples/base64_sem2.py b/examples/base64_sem2.py
index 3b023dd3..99158895 100644
--- a/examples/base64_sem2.py
+++ b/examples/base64_sem2.py
@@ -28,7 +28,7 @@ import hammer as h
 def bsfdig_value(p):
     """Return the numeric value of a parsed base64 digit.
     """
-    c = p if isinstance(p, (int, long)) else ord(p)
+    c = p if isinstance(p, h.INTEGER_TYPES) else ord(p)
     if c:
         if 0x41 <= c <= 0x5A: # A-Z
             return  c - 0x41
diff --git a/src/bindings/swig/hammer.i b/src/bindings/swig/hammer.i
index 122ffe40..7ba7be22 100644
--- a/src/bindings/swig/hammer.i
+++ b/src/bindings/swig/hammer.i
@@ -25,6 +25,20 @@
  }
 
 %pythoncode %{
+  try:
+      INTEGER_TYPES = (int, long)
+  except NameError:
+      INTEGER_TYPES = (int,)
+
+  try:
+      TEXT_TYPE = unicode
+      def bchr(i):
+          return chr(i)
+  except NameError:
+      TEXT_TYPE = str
+      def bchr(i):
+          return bytes([i])
+
   class Placeholder(object):
       """The python equivalent of TT_NONE"""
       def __str__(self):
@@ -250,36 +264,35 @@
 }
 
 %pythoncode %{
-
 def action(p, act):
     return _h_action(p, act)
 def attr_bool(p, pred):
     return _h_attr_bool(p, pred)
 
 def ch(ch):
-    if isinstance(ch, str) or isinstance(ch, unicode):
+    if isinstance(ch, (bytes, TEXT_TYPE)):
         return token(ch)
     else:
         return  _h_ch(ch)
 
 def ch_range(c1, c2):
-    dostr = isinstance(c1, str)
-    dostr2 = isinstance(c2, str)
-    if isinstance(c1, unicode) or isinstance(c2, unicode):
+    dostr = isinstance(c1, bytes)
+    dostr2 = isinstance(c2, bytes)
+    if isinstance(c1, TEXT_TYPE) or isinstance(c2, TEXT_TYPE):
         raise TypeError("ch_range only works on bytes")
     if dostr != dostr2:
         raise TypeError("Both arguments to ch_range must be the same type")
     if dostr:
-        return action(_h_ch_range(c1, c2), chr)
+        return action(_h_ch_range(c1, c2), bchr)
     else:
         return _h_ch_range(c1, c2)
 def epsilon_p(): return _h_epsilon_p()
 def end_p():
     return _h_end_p()
 def in_(charset):
-    return action(_h_in(charset), chr)
+    return action(_h_in(charset), bchr)
 def not_in(charset):
-    return action(_h_not_in(charset), chr)
+    return action(_h_not_in(charset), bchr)
 def not_(p): return _h_not(p)
 def int_range(p, i1, i2):
     return _h_int_range(p, i1, i2)
diff --git a/tools/csharp/csharp.py b/tools/csharp/csharp.py
index f10fc71f..101d3f6b 100644
--- a/tools/csharp/csharp.py
+++ b/tools/csharp/csharp.py
@@ -205,7 +205,7 @@ def AddToModPaths(env, files, **kw):
 
 def cscFlags(target, source, env, for_signature):
     listCmd = []
-    if (env.has_key('WINEXE')):
+    if ('WINEXE' in env):
         if (env['WINEXE'] == 1):
             listCmd.append('-t:winexe')
     return listCmd
@@ -245,7 +245,7 @@ def cscSourcesNoResources(target, source, env, for_signature):
 def cscRefs(target, source, env, for_signature):
     listCmd = []
 
-    if (env.has_key('ASSEMBLYREFS')):
+    if ('ASSEMBLYREFS' in env):
         refs = SCons.Util.flatten(env['ASSEMBLYREFS'])
         for ref in refs:
             if SCons.Util.is_String(ref):
@@ -258,7 +258,7 @@ def cscRefs(target, source, env, for_signature):
 def cscMods(target, source, env, for_signature):
     listCmd = []
 
-    if (env.has_key('NETMODULES')):
+    if ('NETMODULES' in env):
         mods = SCons.Util.flatten(env['NETMODULES'])
         for mod in mods:
             listCmd.append('-addmodule:%s' % mod)
@@ -276,7 +276,7 @@ def alLinkSources(target, source, env, for_signature):
             # just treat this as a generic unidentified source file
             listCmd.append('-link:%s' % s.get_string(for_signature))
 
-    if env.has_key('VERSION'):
+    if 'VERSION' in env:
         version = parseVersion(env)
         listCmd.append('-version:%d.%d.%d.%d' % version)
 
@@ -298,7 +298,7 @@ def cliLinkSources(target, source, env, for_signature):
     return listCmd
 
 def add_version(target, source, env):
-    if env.has_key('VERSION'):
+    if 'VERSION' in env:
         if SCons.Util.is_String(target[0]):
             versionfile = target[0] + '_VersionInfo.cs'
         else:
@@ -321,14 +321,14 @@ def lib_emitter(target, source, env):
 def add_depends(target, source, env):
     """Add dependency information before the build order is established"""
 
-    if (env.has_key('NETMODULES')):
+    if ('NETMODULES' in env):
         mods = SCons.Util.flatten(env['NETMODULES'])
         for mod in mods:
             # add as dependency
             for t in target:
                 env.Depends(t, mod)
 
-    if (env.has_key('ASSEMBLYREFS')):
+    if ('ASSEMBLYREFS' in env):
         refs = SCons.Util.flatten(env['ASSEMBLYREFS'])
         for ref in refs:
             # add as dependency
@@ -419,7 +419,7 @@ res_action = SCons.Action.Action('$CLIRCCOM', '$CLIRCCOMSTR')
 
 def res_emitter(target, source, env):
     # prepend NAMESPACE if provided
-    if (env.has_key('NAMESPACE')):
+    if ('NAMESPACE' in env):
         newtargets = []
         for t in target:
             tname = t.name
-- 
GitLab