git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v5 09/15] git-p4: python 3 syntax changes

From
Ben Keene via GitGitGadget <gitgitgadget@gmail.com>
Date
Dec 7, 2019, 17:47 UTC
Message-ID
<a221eb8bb68975030966897a220ba2d328b000f5.1575740863.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.463.v5.git.1575740863.gitgitgadget@gmail.com>
From: Ben Keene <seraphire@gmail.com>

Python 3 handles strings differently than Python 2.7. Since Python 2 is reaching it's end of life, a series of changes are being submitted to enable python 3.5 and following support. The current code fails basic tests under python 3.5.

There are a number of translations suggested by modernize/futureize that should be taken to fix numerous non-string specific issues.

Change references to the X.next() iterator to the function next(X) which is compatible with both Python2 and Python3.

Change references to X.keys() to list(X.keys()) to return a list that can be iterated in both Python2 and Python3.

Add the literal text (object) to the end of class definitions to be consistent with Python3 class definition.

Change integer divison to use "//" instead of "/" Under Both Python 2 and Python 3 // will return a floor()ed result which matches existing functionality.

Change the format string for displaying decimal values from %d to %4.1f% when displaying a progress. This avoids displaying long repeating decimals in user displayed text.

Signed-off-by: Ben Keene <seraphire@gmail.com>
---
 git-p4.py | 55 +++++++++++++++++++++++++++++--------------------------
 1 file changed, 29 insertions(+), 26 deletions(-)
diff --git a/git-p4.py b/git-p4.py
index e6f7513384..fc6c9406c2 100755
--- a/git-p4.py
+++ b/git-p4.py
@@ -26,6 +26,9 @@
 import zlib
 import ctypes
 import errno
+import os.path
+import codecs
+import io
 
 # support basestring in Python 3
 try:
@@ -639,7 +642,7 @@ def parseDiffTreeEntry(entry):
 
     If the pattern is not matched, None is returned."""
 
-    match = diffTreePattern().next().match(entry)
+    match = next(diffTreePattern()).match(entry)
     if match:
         return {
             'src_mode': match.group(1),
@@ -980,7 +983,7 @@ def findUpstreamBranchPoint(head = "HEAD"):
     branches = p4BranchesInGit()
     # map from depot-path to branch name
     branchByDepotPath = {}
-    for branch in branches.keys():
+    for branch in list(branches.keys()):
         tip = branches[branch]
         log = extractLogMessageFromGitCommit(tip)
         settings = extractSettingsGitLog(log)
@@ -1174,7 +1177,7 @@ def getClientSpec():
     client_name = entry["Client"]
 
     # just the keys that start with "View"
-    view_keys = [ k for k in entry.keys() if k.startswith("View") ]
+    view_keys = [ k for k in list(entry.keys()) if k.startswith("View") ]
 
     # hold this new View
     view = View(client_name)
@@ -1416,7 +1419,7 @@ def processContent(self, git_mode, relPath, contents):
         else:
             return LargeFileSystem.processContent(self, git_mode, relPath, contents)
 
-class Command:
+class Command(object):
     delete_actions = ( "delete", "move/delete", "purge" )
     add_actions = ( "add", "branch", "move/add" )
 
@@ -1431,7 +1434,7 @@ def ensure_value(self, attr, value):
             setattr(self, attr, value)
         return getattr(self, attr)
 
-class P4UserMap:
+class P4UserMap(object):
     def __init__(self):
         self.userMapFromPerforceServer = False
         self.myP4UserId = None
@@ -1482,7 +1485,7 @@ def getUserMapFromPerforceServer(self):
                 self.emails[email] = user
 
         s = ''
-        for (key, val) in self.users.items():
+        for (key, val) in list(self.users.items()):
             s += "%s\t%s\n" % (key.expandtabs(1), val.expandtabs(1))
 
         open(self.getUserCacheFilename(), "wb").write(s)
@@ -1833,7 +1836,7 @@ def prepareSubmitTemplate(self, changelist=None):
                 break
         if not change_entry:
             die('Failed to decode output of p4 change -o')
-        for key, value in change_entry.iteritems():
+        for key, value in list(change_entry.items()):
             if key.startswith('File'):
                 if 'depot-paths' in settings:
                     if not [p for p in settings['depot-paths']
@@ -2077,7 +2080,7 @@ def applyCommit(self, id):
             p4_delete(f)
 
         # Set/clear executable bits
-        for f in filesToChangeExecBit.keys():
+        for f in list(filesToChangeExecBit.keys()):
             mode = filesToChangeExecBit[f]
             setP4ExecBit(f, mode)
 
@@ -2330,7 +2333,7 @@ def run(self, args):
             self.clientSpecDirs = getClientSpec()
 
         # Check for the existence of P4 branches
-        branchesDetected = (len(p4BranchesInGit().keys()) > 1)
+        branchesDetected = (len(list(p4BranchesInGit().keys())) > 1)
 
         if self.useClientSpec and not branchesDetected:
             # all files are relative to the client spec
@@ -2721,7 +2724,7 @@ def __init__(self):
         self.knownBranches = {}
         self.initialParents = {}
 
-        self.tz = "%+03d%02d" % (- time.timezone / 3600, ((- time.timezone % 3600) / 60))
+        self.tz = "%+03d%02d" % (- time.timezone // 3600, ((- time.timezone % 3600) // 60))
         self.labels = {}
 
     # Force a checkpoint in fast-import and wait for it to finish
@@ -2838,7 +2841,7 @@ def splitFilesIntoBranches(self, commit):
             else:
                 relPath = self.stripRepoPath(path, self.depotPaths)
 
-            for branch in self.knownBranches.keys():
+            for branch in list(self.knownBranches.keys()):
                 # add a trailing slash so that a commit into qt/4.2foo
                 # doesn't end up in qt/4.2, e.g.
                 if p4PathStartsWith(relPath, branch + "/"):
@@ -2867,7 +2870,7 @@ def streamOneP4File(self, file, contents):
                 size = int(self.stream_file['fileSize'])
             else:
                 size = 0 # deleted files don't get a fileSize apparently
-            sys.stdout.write('\r%s --> %s (%i MB)\n' % (file['depotFile'], relPath, size/1024/1024))
+            sys.stdout.write('\r%s --> %s (%i MB)\n' % (file['depotFile'], relPath, size//1024//1024))
             sys.stdout.flush()
 
         (type_base, type_mods) = split_p4_type(file["type"])
@@ -2967,7 +2970,7 @@ def streamP4FilesCb(self, marshalled):
             required_bytes = int((4 * int(self.stream_file["fileSize"])) - calcDiskFree())
             if required_bytes > 0:
                 err = 'Not enough space left on %s! Free at least %i MB.' % (
-                    os.getcwd(), required_bytes/1024/1024
+                    os.getcwd(), required_bytes//1024//1024
                 )
 
         if err:
@@ -2996,7 +2999,7 @@ def streamP4FilesCb(self, marshalled):
 
         # pick up the new file information... for the
         # 'data' field we need to append to our array
-        for k in marshalled.keys():
+        for k in list(marshalled.keys()):
             if k == 'data':
                 if 'streamContentSize' not in self.stream_file:
                     self.stream_file['streamContentSize'] = 0
@@ -3011,8 +3014,8 @@ def streamP4FilesCb(self, marshalled):
             'depotFile' in self.stream_file):
             size = int(self.stream_file["fileSize"])
             if size > 0:
-                progress = 100*self.stream_file['streamContentSize']/size
-                sys.stdout.write('\r%s %d%% (%i MB)' % (self.stream_file['depotFile'], progress, int(size/1024/1024)))
+                progress = 100.0*self.stream_file['streamContentSize']/size
+                sys.stdout.write('\r%s %4.1f%% (%i MB)' % (self.stream_file['depotFile'], progress, int(size//1024//1024)))
                 sys.stdout.flush()
 
         self.stream_have_file_info = True
@@ -3093,7 +3096,7 @@ def streamTag(self, gitStream, labelName, labelDetails, commit, epoch):
 
         gitStream.write("tagger %s\n" % tagger)
 
-        print("labelDetails=",labelDetails)
+        print(("labelDetails=",labelDetails))
         if 'Description' in labelDetails:
             description = labelDetails['Description']
         else:
@@ -3232,7 +3235,7 @@ def getLabels(self):
             self.labels[newestChange] = [output, revisions]
 
         if self.verbose:
-            print("Label changes: %s" % self.labels.keys())
+            print("Label changes: %s" % list(self.labels.keys()))
 
     # Import p4 labels as git tags. A direct mapping does not
     # exist, so assume that if all the files are at the same revision
@@ -3375,7 +3378,7 @@ def getBranchMapping(self):
 
     def getBranchMappingFromGitBranches(self):
         branches = p4BranchesInGit(self.importIntoRemotes)
-        for branch in branches.keys():
+        for branch in list(branches.keys()):
             if branch == "master":
                 branch = "main"
             else:
@@ -3487,14 +3490,14 @@ def importChanges(self, changes, origin_revision=0):
             self.updateOptionDict(description)
 
             if not self.silent:
-                sys.stdout.write("\rImporting revision %s (%s%%)" % (change, cnt * 100 / len(changes)))
+                sys.stdout.write("\rImporting revision %s (%4.1f%%)" % (change, cnt * 100 / len(changes)))
                 sys.stdout.flush()
             cnt = cnt + 1
 
             try:
                 if self.detectBranches:
                     branches = self.splitFilesIntoBranches(description)
-                    for branch in branches.keys():
+                    for branch in list(branches.keys()):
                         ## HACK  --hwn
                         branchPrefix = self.depotPaths[0] + branch + "/"
                         self.branchPrefixes = [ branchPrefix ]
@@ -3683,13 +3686,13 @@ def run(self, args):
                 if short in branches:
                     self.p4BranchesInGit = [ short ]
             else:
-                self.p4BranchesInGit = branches.keys()
+                self.p4BranchesInGit = list(branches.keys())
 
             if len(self.p4BranchesInGit) > 1:
                 if not self.silent:
                     print("Importing from/into multiple branches")
                 self.detectBranches = True
-                for branch in branches.keys():
+                for branch in list(branches.keys()):
                     self.initialParents[self.refPrefix + branch] = \
                         branches[branch]
 
@@ -4073,7 +4076,7 @@ def findLastP4Revision(self, starting_point):
             to find the P4 commit we are based on, and the depot-paths.
         """
 
-        for parent in (range(65535)):
+        for parent in (list(range(65535))):
             log = extractLogMessageFromGitCommit("{0}^{1}".format(starting_point, parent))
             settings = extractSettingsGitLog(log)
             if 'change' in settings:
@@ -4212,7 +4215,7 @@ def printUsage(commands):
 
 def main():
     if len(sys.argv[1:]) == 0:
-        printUsage(commands.keys())
+        printUsage(list(commands.keys()))
         sys.exit(2)
 
     cmdName = sys.argv[1]
@@ -4222,7 +4225,7 @@ def main():
     except KeyError:
         print("unknown command %s" % cmdName)
         print("")
-        printUsage(commands.keys())
+        printUsage(list(commands.keys()))
         sys.exit(2)
 
     options = cmd.options
-- 
gitgitgadget
Previous: Ben Keene via GitGitGadgetNext: Ben Keene via GitGitGadget
Message 60 of 77 in “git-p4.py: Cast byte strings to unicode strings in python3”
  1. 0/1 git-p4.py: Cast byte strings to unicode strings in python3Ben Keene via GitGitGadget, Nov 13, 2019
  2. 1/1 Cast byte strings to unicode strings in python3Ben Keene via GitGitGadget, Nov 13, 2019
  3. Junio C HamanoNov 14, 2019
  4. Luke DiamandNov 14, 2019
  5. 0/3 git-p4.py: Cast byte strings to unicode strings in python3Ben Keene via GitGitGadget, Nov 15, 2019
  6. 1/3 Cast byte strings to unicode strings in python3Ben Keene via GitGitGadget, Nov 15, 2019
  7. 2/3 FIX: cast as unicode fails when a value is already unicodeBen Keene via GitGitGadget, Nov 15, 2019
  8. 3/3 FIX: wrap return for read_pipe_lines in ustring() and wrap GitLFS read of the pointer file in ustring()Ben Keene via GitGitGadget, Nov 15, 2019
  9. 0/1 git-p4.py: Cast byte strings to unicode strings in python3Ben Keene via GitGitGadget, Dec 2, 2019
  10. 1/1 Python3 support for t9800 tests. Basic P4/Python3 supportBen Keene via GitGitGadget, Dec 2, 2019
  11. Denton LiuDec 3, 2019
  12. Ben KeeneDec 3, 2019
  13. Denton LiuDec 4, 2019
  14. 00/11 git-p4.py: Cast byte strings to unicode strings in python3Ben Keene via GitGitGadget, Dec 4, 2019
  15. 01/11 git-p4: select p4 binary by operating-systemBen Keene via GitGitGadget, Dec 4, 2019
  16. Denton LiuDec 5, 2019
  17. Ben KeeneDec 5, 2019
  18. 02/11 git-p4: change the expansion test from basestring to listBen Keene via GitGitGadget, Dec 4, 2019
  19. Denton LiuDec 5, 2019
  20. Ben KeeneDec 5, 2019
  21. 03/11 git-p4: add new helper functions for python3 conversionBen Keene via GitGitGadget, Dec 4, 2019
  22. Denton LiuDec 5, 2019
  23. Ben KeeneDec 5, 2019
  24. 05/11 git-p4: Add new functions in preparation of usageBen Keene via GitGitGadget, Dec 4, 2019
  25. Denton LiuDec 5, 2019
  26. Ben KeeneDec 5, 2019
  27. 04/11 git-p4: python3 syntax changesBen Keene via GitGitGadget, Dec 4, 2019
  28. Denton LiuDec 5, 2019
  29. 08/11 git-p4: p4CmdList - support Unicode encodingBen Keene via GitGitGadget, Dec 4, 2019
  30. Junio C HamanoDec 5, 2019
  31. Ben KeeneDec 5, 2019
  32. 07/11 git-p4: Add a helper class for stream writingBen Keene via GitGitGadget, Dec 4, 2019
  33. Junio C HamanoDec 5, 2019
  34. Ben KeeneDec 5, 2019
  35. 06/11 git-p4: Fix assumed path separators to be more Windows friendlyBen Keene via GitGitGadget, Dec 4, 2019
  36. Junio C HamanoDec 5, 2019
  37. Ben KeeneDec 5, 2019
  38. 09/11 git-p4: Add usability enhancementsBen Keene via GitGitGadget, Dec 4, 2019
  39. Junio C HamanoDec 5, 2019
  40. Ben KeeneDec 5, 2019
  41. 10/11 git-p4: Support python3 for basic P4 clone, sync, and submitBen Keene via GitGitGadget, Dec 4, 2019
  42. 11/11 git-p4: Added --encoding parameter to p4 cloneBen Keene via GitGitGadget, Dec 4, 2019
  43. Luke DiamandDec 5, 2019
  44. Ben KeeneDec 5, 2019
  45. Denton LiuDec 5, 2019
  46. Ben KeeneDec 5, 2019
  47. 00/15 git-p4.py: Cast byte strings to unicode strings in python3Ben Keene via GitGitGadget, Dec 7, 2019
  48. 01/15 t/gitweb-lib.sh: drop confusing quotesJeff King via GitGitGadget, Dec 7, 2019
  49. 02/15 t/gitweb-lib.sh: set $REQUEST_URIJeff King via GitGitGadget, Dec 7, 2019
  50. 03/15 git-p4: select P4 binary by operating-systemBen Keene via GitGitGadget, Dec 7, 2019
  51. Junio C HamanoDec 9, 2019
  52. 05/15 git-p4: promote encodeWithUTF8() to a global functionBen Keene via GitGitGadget, Dec 7, 2019
  53. Junio C HamanoDec 11, 2019
  54. 04/15 git-p4: change the expansion test from basestring to listBen Keene via GitGitGadget, Dec 7, 2019
  55. Junio C HamanoDec 9, 2019
  56. Ben KeeneDec 13, 2019
  57. 06/15 git-p4: remove p4_write_pipe() and write_pipe() return valuesBen Keene via GitGitGadget, Dec 7, 2019
  58. 11/15 git-p4: add Py23File() - helper class for stream writingBen Keene via GitGitGadget, Dec 7, 2019
  59. 08/15 git-p4: add casting helper functions for python 3 conversionBen Keene via GitGitGadget, Dec 7, 2019
  60. 09/15 git-p4: python 3 syntax changesBen Keene via GitGitGadget, Dec 7, 2019
  61. 10/15 git-p4: fix assumed path separators to be more Windows friendlyBen Keene via GitGitGadget, Dec 7, 2019
  62. 15/15 git-p4: Add depot manipulation functionsBen Keene via GitGitGadget, Dec 7, 2019
  63. 14/15 git-p4: added --encoding parameter to p4 cloneBen Keene via GitGitGadget, Dec 7, 2019
  64. 07/15 git-p4: add new support function gitConfigSet()Ben Keene via GitGitGadget, Dec 7, 2019
  65. Junio C HamanoDec 11, 2019
  66. 13/15 git-p4: support Python 3 for basic P4 clone, sync, and submit (t9800)Ben Keene via GitGitGadget, Dec 7, 2019
  67. 12/15 git-p4: p4CmdList - support Unicode encodingBen Keene via GitGitGadget, Dec 7, 2019
  68. Jeff KingDec 7, 2019
  69. Ben KeeneDec 7, 2019
  70. Junio C HamanoDec 11, 2019
  71. Denton LiuDec 11, 2019
  72. Junio C HamanoDec 11, 2019
  73. Luke DiamandDec 11, 2019
  74. Junio C HamanoDec 11, 2019
  75. Yang ZhaoDec 11, 2019
  76. Ben KeeneDec 12, 2019
  77. Ben KeeneDec 13, 2019

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.