{"thread":{"id":"48737","subject":"[PATCH 0/6] git-p4: small step towards Python3 support","startedAt":"2018-06-19T08:04:31Z","lastAt":"2018-06-19T08:15:27Z","messageCount":8,"participants":["Luke Diamand","Eric Sunshine"],"isPatch":true,"patchVersion":1,"patchTotal":6},"messages":[{"id":"350454","messageId":"20180619080411.6554-1-luke@diamand.org","threadId":"48737","inReplyTo":null,"subject":"[PATCH 0/6] git-p4: small step towards Python3 support","fromName":"Luke Diamand","fromEmail":"luke@diamand.org","sentAt":"2018-06-19T08:04:05Z","receivedAt":"2018-06-19T08:04:31Z","isPatch":true,"sender":{"key":"luke@diamand.org","avatar":"https://avatars.githubusercontent.com/u/5330967?v=4"},"body":"This patchset is a first small step towards Python3 support for\ngit-p4.py.\n\nThese are all the nice easy changes which can almost be done\nautomatically using 2to3.\n\nAfter these changes, it compiles using Python3, but fails to run.\nThat's because of the bytes vs string change in Python3. Fixing that is\nquite a bit harder (but not impossible).\n\nI have some further changes to address this, but they are quite a bit\nmore invasive, and not actually working yet. It's based very loosely on the\n\"polystr()\" suggestion from Eric on this list.\n\nIt still works fine with Python2.7 and Python2.6.\n\nLuke Diamand (6):\n  git-p4: python3: replace <> with !=\n  git-p4: python3: replace dict.has_key(k) with \"k in dict\"\n  git-p4: python3: remove backticks\n  git-p4: python3: basestring workaround\n  git-p4: python3: use print() function\n  git-p4: python3: fix octal constants\n\n git-p4.py | 348 ++++++++++++++++++++++++++++--------------------------\n 1 file changed, 182 insertions(+), 166 deletions(-)\n\n-- \n2.18.0.rc1.242.g61856ae69a\n\n"},{"id":"350455","messageId":"20180619080411.6554-2-luke@diamand.org","threadId":"48737","inReplyTo":"20180619080411.6554-1-luke@diamand.org","subject":"[PATCH 1/6] git-p4: python3: replace <> with !=","fromName":"Luke Diamand","fromEmail":"luke@diamand.org","sentAt":"2018-06-19T08:04:06Z","receivedAt":"2018-06-19T08:04:42Z","isPatch":true,"sender":{"key":"luke@diamand.org","avatar":"https://avatars.githubusercontent.com/u/5330967?v=4"},"body":"The <> string inequality operator (which doesn't seem to be even\ndocumented) no longer exists in python3. Replace with !=.\n\nThis still works with python2.\n\nSigned-off-by: Luke Diamand <luke@diamand.org>\n---\n git-p4.py | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/git-p4.py b/git-p4.py\nindex 0354d4df5c..51e9e64a73 100755\n--- a/git-p4.py\n+++ b/git-p4.py\n@@ -3590,7 +3590,7 @@ def run(self, args):\n                             prev_list = prev.split(\"/\")\n                             cur_list = cur.split(\"/\")\n                             for i in range(0, min(len(cur_list), len(prev_list))):\n-                                if cur_list[i] <> prev_list[i]:\n+                                if cur_list[i] != prev_list[i]:\n                                     i = i - 1\n                                     break\n \n-- \n2.18.0.rc1.242.g61856ae69a\n\n"},{"id":"350456","messageId":"20180619080411.6554-3-luke@diamand.org","threadId":"48737","inReplyTo":"20180619080411.6554-2-luke@diamand.org","subject":"[PATCH 2/6] git-p4: python3: replace dict.has_key(k) with \"k in dict\"","fromName":"Luke Diamand","fromEmail":"luke@diamand.org","sentAt":"2018-06-19T08:04:07Z","receivedAt":"2018-06-19T08:04:42Z","isPatch":true,"sender":{"key":"luke@diamand.org","avatar":"https://avatars.githubusercontent.com/u/5330967?v=4"},"body":"Python3 does not have the dict.has_key() function, so replace all\nsuch calls with \"k in dict\". This will still work with python2.6\nand python2.7.\n\nConverted using 2to3 (plus some hand-editing)\n\nSigned-off-by: Luke Diamand <luke@diamand.org>\n---\n git-p4.py | 78 +++++++++++++++++++++++++++----------------------------\n 1 file changed, 39 insertions(+), 39 deletions(-)\n\ndiff --git a/git-p4.py b/git-p4.py\nindex 51e9e64a73..6fcad35104 100755\n--- a/git-p4.py\n+++ b/git-p4.py\n@@ -767,7 +767,7 @@ def gitDeleteRef(ref):\n _gitConfig = {}\n \n def gitConfig(key, typeSpecifier=None):\n-    if not _gitConfig.has_key(key):\n+    if key not in _gitConfig:\n         cmd = [ \"git\", \"config\" ]\n         if typeSpecifier:\n             cmd += [ typeSpecifier ]\n@@ -781,12 +781,12 @@ def gitConfigBool(key):\n        variable is set to true, and False if set to false or not present\n        in the config.\"\"\"\n \n-    if not _gitConfig.has_key(key):\n+    if key not in _gitConfig:\n         _gitConfig[key] = gitConfig(key, '--bool') == \"true\"\n     return _gitConfig[key]\n \n def gitConfigInt(key):\n-    if not _gitConfig.has_key(key):\n+    if key not in _gitConfig:\n         cmd = [ \"git\", \"config\", \"--int\", key ]\n         s = read_pipe(cmd, ignore_error=True)\n         v = s.strip()\n@@ -797,7 +797,7 @@ def gitConfigInt(key):\n     return _gitConfig[key]\n \n def gitConfigList(key):\n-    if not _gitConfig.has_key(key):\n+    if key not in _gitConfig:\n         s = read_pipe([\"git\", \"config\", \"--get-all\", key], ignore_error=True)\n         _gitConfig[key] = s.strip().splitlines()\n         if _gitConfig[key] == ['']:\n@@ -855,7 +855,7 @@ def findUpstreamBranchPoint(head = \"HEAD\"):\n         tip = branches[branch]\n         log = extractLogMessageFromGitCommit(tip)\n         settings = extractSettingsGitLog(log)\n-        if settings.has_key(\"depot-paths\"):\n+        if \"depot-paths\" in settings:\n             paths = \",\".join(settings[\"depot-paths\"])\n             branchByDepotPath[paths] = \"remotes/p4/\" + branch\n \n@@ -865,9 +865,9 @@ def findUpstreamBranchPoint(head = \"HEAD\"):\n         commit = head + \"~%s\" % parent\n         log = extractLogMessageFromGitCommit(commit)\n         settings = extractSettingsGitLog(log)\n-        if settings.has_key(\"depot-paths\"):\n+        if \"depot-paths\" in settings:\n             paths = \",\".join(settings[\"depot-paths\"])\n-            if branchByDepotPath.has_key(paths):\n+            if paths in branchByDepotPath:\n                 return [branchByDepotPath[paths], settings]\n \n         parent = parent + 1\n@@ -891,8 +891,8 @@ def createOrUpdateBranchesFromOrigin(localRefPrefix = \"refs/remotes/p4/\", silent\n         originHead = line\n \n         original = extractSettingsGitLog(extractLogMessageFromGitCommit(originHead))\n-        if (not original.has_key('depot-paths')\n-            or not original.has_key('change')):\n+        if ('depot-paths' not in original\n+            or 'change' not in original):\n             continue\n \n         update = False\n@@ -902,7 +902,7 @@ def createOrUpdateBranchesFromOrigin(localRefPrefix = \"refs/remotes/p4/\", silent\n             update = True\n         else:\n             settings = extractSettingsGitLog(extractLogMessageFromGitCommit(remoteHead))\n-            if settings.has_key('change') > 0:\n+            if 'change' in settings:\n                 if settings['depot-paths'] == original['depot-paths']:\n                     originP4Change = int(original['change'])\n                     p4Change = int(settings['change'])\n@@ -1002,7 +1002,7 @@ def p4ChangesForPaths(depotPaths, changeRange, requestedBlockSize):\n \n         # Insert changes in chronological order\n         for entry in reversed(result):\n-            if not entry.has_key('change'):\n+            if 'change' not in entry:\n                 continue\n             changes.add(int(entry['change']))\n \n@@ -1312,7 +1312,7 @@ def p4UserId(self):\n \n         results = p4CmdList(\"user -o\")\n         for r in results:\n-            if r.has_key('User'):\n+            if 'User' in r:\n                 self.myP4UserId = r['User']\n                 return r['User']\n         die(\"Could not find your p4 user id\")\n@@ -1336,7 +1336,7 @@ def getUserMapFromPerforceServer(self):\n         self.emails = {}\n \n         for output in p4CmdList(\"users\"):\n-            if not output.has_key(\"User\"):\n+            if \"User\" not in output:\n                 continue\n             self.users[output[\"User\"]] = output[\"FullName\"] + \" <\" + output[\"Email\"] + \">\"\n             self.emails[output[\"Email\"]] = output[\"User\"]\n@@ -1588,7 +1588,7 @@ def p4UserForCommit(self,id):\n         gitEmail = read_pipe([\"git\", \"log\", \"--max-count=1\",\n                               \"--format=%ae\", id])\n         gitEmail = gitEmail.strip()\n-        if not self.emails.has_key(gitEmail):\n+        if gitEmail not in self.emails:\n             return (None,gitEmail)\n         else:\n             return (self.emails[gitEmail],gitEmail)\n@@ -1612,14 +1612,14 @@ def lastP4Changelist(self):\n         results = p4CmdList(\"client -o\")        # find the current client\n         client = None\n         for r in results:\n-            if r.has_key('Client'):\n+            if 'Client' in r:\n                 client = r['Client']\n                 break\n         if not client:\n             die(\"could not get client spec\")\n         results = p4CmdList([\"changes\", \"-c\", client, \"-m\", \"1\"])\n         for r in results:\n-            if r.has_key('change'):\n+            if 'change' in r:\n                 return r['change']\n         die(\"Could not get changelist number for last submit - cannot patch up user details\")\n \n@@ -1637,10 +1637,10 @@ def modifyChangelistUser(self, changelist, newUser):\n \n         result = p4CmdList(\"change -f -i\", stdin=input)\n         for r in result:\n-            if r.has_key('code'):\n+            if 'code' in r:\n                 if r['code'] == 'error':\n                     die(\"Could not modify user field of changelist %s to %s:%s\" % (changelist, newUser, r['data']))\n-            if r.has_key('data'):\n+            if 'data' in r:\n                 print(\"Updated user field for changelist %s to %s\" % (changelist, newUser))\n                 return\n         die(\"Could not modify user field of changelist %s to %s\" % (changelist, newUser))\n@@ -1650,7 +1650,7 @@ def canChangeChangelists(self):\n         # which are required to modify changelists.\n         results = p4CmdList([\"protects\", self.depotPath])\n         for r in results:\n-            if r.has_key('perm'):\n+            if 'perm' in r:\n                 if r['perm'] == 'admin':\n                     return 1\n                 if r['perm'] == 'super':\n@@ -1690,7 +1690,7 @@ def prepareSubmitTemplate(self, changelist=None):\n         if changelist:\n             args.append(str(changelist))\n         for entry in p4CmdList(args):\n-            if not entry.has_key('code'):\n+            if 'code' not in entry:\n                 continue\n             if entry['code'] == 'stat':\n                 change_entry = entry\n@@ -1699,7 +1699,7 @@ def prepareSubmitTemplate(self, changelist=None):\n             die('Failed to decode output of p4 change -o')\n         for key, value in change_entry.iteritems():\n             if key.startswith('File'):\n-                if settings.has_key('depot-paths'):\n+                if 'depot-paths' in settings:\n                     if not [p for p in settings['depot-paths']\n                             if p4PathStartsWith(value, p)]:\n                         continue\n@@ -1710,7 +1710,7 @@ def prepareSubmitTemplate(self, changelist=None):\n                 continue\n         # Output in the order expected by prepareLogMessage\n         for key in ['Change', 'Client', 'User', 'Status', 'Description', 'Jobs']:\n-            if not change_entry.has_key(key):\n+            if key not in change_entry:\n                 continue\n             template += '\\n'\n             template += key + ':'\n@@ -1738,7 +1738,7 @@ def edit_template(self, template_file):\n         mtime = os.stat(template_file).st_mtime\n \n         # invoke the editor\n-        if os.environ.has_key(\"P4EDITOR\") and (os.environ.get(\"P4EDITOR\") != \"\"):\n+        if \"P4EDITOR\" in os.environ and (os.environ.get(\"P4EDITOR\") != \"\"):\n             editor = os.environ.get(\"P4EDITOR\")\n         else:\n             editor = read_pipe(\"git var GIT_EDITOR\").strip()\n@@ -1762,7 +1762,7 @@ def edit_template(self, template_file):\n \n     def get_diff_description(self, editedFiles, filesToAdd, symlinks):\n         # diff\n-        if os.environ.has_key(\"P4DIFF\"):\n+        if \"P4DIFF\" in os.environ:\n             del(os.environ[\"P4DIFF\"])\n         diff = \"\"\n         for editedFile in editedFiles:\n@@ -2085,7 +2085,7 @@ def exportGitTags(self, gitTags):\n             logMessage = extractLogMessageFromGitCommit(name)\n             values = extractSettingsGitLog(logMessage)\n \n-            if not values.has_key('change'):\n+            if 'change' not in values:\n                 # a tag pointing to something not sent to p4; ignore\n                 if verbose:\n                     print \"git tag %s does not give a p4 commit\" % name\n@@ -2600,7 +2600,7 @@ def extractFilesFromCommit(self, commit, shelved=False, shelved_cl = 0, origin_r\n                              for path in self.cloneExclude]\n         files = []\n         fnum = 0\n-        while commit.has_key(\"depotFile%s\" % fnum):\n+        while \"depotFile%s\" % fnum in commit:\n             path =  commit[\"depotFile%s\" % fnum]\n \n             if [p for p in self.cloneExclude\n@@ -2638,7 +2638,7 @@ def extractFilesFromCommit(self, commit, shelved=False, shelved_cl = 0, origin_r\n     def extractJobsFromCommit(self, commit):\n         jobs = []\n         jnum = 0\n-        while commit.has_key(\"job%s\" % jnum):\n+        while \"job%s\" % jnum in commit:\n             job = commit[\"job%s\" % jnum]\n             jobs.append(job)\n             jnum = jnum + 1\n@@ -2686,7 +2686,7 @@ def splitFilesIntoBranches(self, commit):\n \n         branches = {}\n         fnum = 0\n-        while commit.has_key(\"depotFile%s\" % fnum):\n+        while \"depotFile%s\" % fnum in commit:\n             path =  commit[\"depotFile%s\" % fnum]\n             found = [p for p in self.depotPaths\n                      if p4PathStartsWith(path, p)]\n@@ -2866,7 +2866,7 @@ def streamP4FilesCb(self, marshalled):\n             else:\n                 die(\"Error from p4 print: %s\" % err)\n \n-        if marshalled.has_key('depotFile') and self.stream_have_file_info:\n+        if 'depotFile' in marshalled and self.stream_have_file_info:\n             # start of a new file - output the old one first\n             self.streamOneP4File(self.stream_file, self.stream_contents)\n             self.stream_file = {}\n@@ -2938,7 +2938,7 @@ def streamP4FilesCbSelf(entry):\n                       cb=streamP4FilesCbSelf)\n \n             # do the last chunk\n-            if self.stream_file.has_key('depotFile'):\n+            if 'depotFile' in self.stream_file:\n                 self.streamOneP4File(self.stream_file, self.stream_contents)\n \n     def make_email(self, userid):\n@@ -2957,7 +2957,7 @@ def streamTag(self, gitStream, labelName, labelDetails, commit, epoch):\n         gitStream.write(\"tag %s\\n\" % labelName)\n         gitStream.write(\"from %s\\n\" % commit)\n \n-        if labelDetails.has_key('Owner'):\n+        if 'Owner' in labelDetails:\n             owner = labelDetails[\"Owner\"]\n         else:\n             owner = None\n@@ -2973,7 +2973,7 @@ def streamTag(self, gitStream, labelName, labelDetails, commit, epoch):\n         gitStream.write(\"tagger %s\\n\" % tagger)\n \n         print \"labelDetails=\",labelDetails\n-        if labelDetails.has_key('Description'):\n+        if 'Description' in labelDetails:\n             description = labelDetails['Description']\n         else:\n             description = 'Label from git p4'\n@@ -3052,7 +3052,7 @@ def commit(self, details, files, branch, parent = \"\"):\n \n         change = int(details[\"change\"])\n \n-        if self.labels.has_key(change):\n+        if change in self.labels:\n             label = self.labels[change]\n             labelDetails = label[0]\n             labelRevisions = label[1]\n@@ -3141,7 +3141,7 @@ def importP4Labels(self, stream, p4Labels):\n             change = p4Cmd([\"changes\", \"-m\", \"1\"] + [\"%s...@%s\" % (p, name)\n                                 for p in self.depotPaths])\n \n-            if change.has_key('change'):\n+            if 'change' in change:\n                 # find the corresponding git commit; take the oldest commit\n                 changelist = int(change['change'])\n                 if changelist in self.committedChanges:\n@@ -3200,7 +3200,7 @@ def getBranchMapping(self):\n         for info in p4CmdList(command):\n             details = p4Cmd([\"branch\", \"-o\", info[\"branch\"]])\n             viewIdx = 0\n-            while details.has_key(\"View%s\" % viewIdx):\n+            while \"View%s\" % viewIdx in details:\n                 paths = details[\"View%s\" % viewIdx].split(\" \")\n                 viewIdx = viewIdx + 1\n                 # require standard //depot/foo/... //depot/bar/... mapping\n@@ -3266,7 +3266,7 @@ def updateOptionDict(self, d):\n         d[\"options\"] = ' '.join(sorted(option_keys.keys()))\n \n     def readOptions(self, d):\n-        self.keepRepoPath = (d.has_key('options')\n+        self.keepRepoPath = ('options' in d\n                              and ('keepRepoPath' in d['options']))\n \n     def gitRefForBranch(self, branch):\n@@ -3576,8 +3576,8 @@ def run(self, args):\n                 settings = extractSettingsGitLog(logMsg)\n \n                 self.readOptions(settings)\n-                if (settings.has_key('depot-paths')\n-                    and settings.has_key ('change')):\n+                if ('depot-paths' in settings\n+                    and 'change' in settings):\n                     change = int(settings['change']) + 1\n                     p4Change = max(p4Change, change)\n \n@@ -3950,7 +3950,7 @@ def findLastP4Revision(self, starting_point):\n         for parent in (range(65535)):\n             log = extractLogMessageFromGitCommit(\"{0}^{1}\".format(starting_point, parent))\n             settings = extractSettingsGitLog(log)\n-            if settings.has_key('change'):\n+            if 'change' in settings:\n                 return settings\n \n         sys.exit(\"could not find git-p4 commits in {0}\".format(self.origin))\n-- \n2.18.0.rc1.242.g61856ae69a\n\n"},{"id":"350457","messageId":"20180619080411.6554-7-luke@diamand.org","threadId":"48737","inReplyTo":"20180619080411.6554-6-luke@diamand.org","subject":"[PATCH 6/6] git-p4: python3: fix octal constants","fromName":"Luke Diamand","fromEmail":"luke@diamand.org","sentAt":"2018-06-19T08:04:11Z","receivedAt":"2018-06-19T08:04:59Z","isPatch":true,"sender":{"key":"luke@diamand.org","avatar":"https://avatars.githubusercontent.com/u/5330967?v=4"},"body":"See PEP3127. Works fine with python2 as well.\n\nSigned-off-by: Luke Diamand <luke@diamand.org>\n---\n git-p4.py | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/git-p4.py b/git-p4.py\nindex 714e442d7c..b449db1cc9 100755\n--- a/git-p4.py\n+++ b/git-p4.py\n@@ -1841,7 +1841,7 @@ def applyCommit(self, id):\n                     filesToDelete.remove(path)\n \n                 dst_mode = int(diff['dst_mode'], 8)\n-                if dst_mode == 0120000:\n+                if dst_mode == 0o120000:\n                     symlinks.add(path)\n \n             elif modifier == \"D\":\n-- \n2.18.0.rc1.242.g61856ae69a\n\n"},{"id":"350458","messageId":"20180619080411.6554-4-luke@diamand.org","threadId":"48737","inReplyTo":"20180619080411.6554-3-luke@diamand.org","subject":"[PATCH 3/6] git-p4: python3: remove backticks","fromName":"Luke Diamand","fromEmail":"luke@diamand.org","sentAt":"2018-06-19T08:04:08Z","receivedAt":"2018-06-19T08:05:02Z","isPatch":true,"sender":{"key":"luke@diamand.org","avatar":"https://avatars.githubusercontent.com/u/5330967?v=4"},"body":"Backticks around a variable are a deprecated alias for repr().\nThis has been removed in python3, so just use the string\nrepresentation instead, which is equivalent.\n\nSigned-off-by: Luke Diamand <luke@diamand.org>\n---\n git-p4.py | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/git-p4.py b/git-p4.py\nindex 6fcad35104..67865d14aa 100755\n--- a/git-p4.py\n+++ b/git-p4.py\n@@ -3089,7 +3089,7 @@ def getLabels(self):\n \n         l = p4CmdList([\"labels\"] + [\"%s...\" % p for p in self.depotPaths])\n         if len(l) > 0 and not self.silent:\n-            print \"Finding files belonging to labels in %s\" % `self.depotPaths`\n+            print(\"Finding files belonging to labels in %s\" % self.depotPaths)\n \n         for output in l:\n             label = output[\"label\"]\n-- \n2.18.0.rc1.242.g61856ae69a\n\n"},{"id":"350459","messageId":"20180619080411.6554-5-luke@diamand.org","threadId":"48737","inReplyTo":"20180619080411.6554-4-luke@diamand.org","subject":"[PATCH 4/6] git-p4: python3: basestring workaround","fromName":"Luke Diamand","fromEmail":"luke@diamand.org","sentAt":"2018-06-19T08:04:09Z","receivedAt":"2018-06-19T08:05:05Z","isPatch":true,"sender":{"key":"luke@diamand.org","avatar":"https://avatars.githubusercontent.com/u/5330967?v=4"},"body":"In Python3, basestring no longer exists, so use this workaround.\n\nSigned-off-by: Luke Diamand <luke@diamand.org>\n---\n git-p4.py | 16 ++++++++++++++++\n 1 file changed, 16 insertions(+)\n\ndiff --git a/git-p4.py b/git-p4.py\nindex 67865d14aa..f127ebce27 100755\n--- a/git-p4.py\n+++ b/git-p4.py\n@@ -27,6 +27,22 @@\n import ctypes\n import errno\n \n+# support basestring in python3\n+try:\n+    unicode = unicode\n+except NameError:\n+    # 'unicode' is undefined, must be Python 3\n+    str = str\n+    unicode = str\n+    bytes = bytes\n+    basestring = (str,bytes)\n+else:\n+    # 'unicode' exists, must be Python 2\n+    str = str\n+    unicode = unicode\n+    bytes = str\n+    basestring = basestring\n+\n try:\n     from subprocess import CalledProcessError\n except ImportError:\n-- \n2.18.0.rc1.242.g61856ae69a\n\n"},{"id":"350460","messageId":"20180619080411.6554-6-luke@diamand.org","threadId":"48737","inReplyTo":"20180619080411.6554-5-luke@diamand.org","subject":"[PATCH 5/6] git-p4: python3: use print() function","fromName":"Luke Diamand","fromEmail":"luke@diamand.org","sentAt":"2018-06-19T08:04:10Z","receivedAt":"2018-06-19T08:05:11Z","isPatch":true,"sender":{"key":"luke@diamand.org","avatar":"https://avatars.githubusercontent.com/u/5330967?v=4"},"body":"Replace calls to print ... with the function form, print(...), to\nallow use with python3 as well as python2.x.\n\nConverted using 2to3 (and some hand-editing).\n\nSigned-off-by: Luke Diamand <luke@diamand.org>\n---\n git-p4.py | 248 +++++++++++++++++++++++++++---------------------------\n 1 file changed, 124 insertions(+), 124 deletions(-)\n\ndiff --git a/git-p4.py b/git-p4.py\nindex f127ebce27..714e442d7c 100755\n--- a/git-p4.py\n+++ b/git-p4.py\n@@ -892,7 +892,7 @@ def findUpstreamBranchPoint(head = \"HEAD\"):\n \n def createOrUpdateBranchesFromOrigin(localRefPrefix = \"refs/remotes/p4/\", silent=True):\n     if not silent:\n-        print (\"Creating/updating branch(es) in %s based on origin branch(es)\"\n+        print(\"Creating/updating branch(es) in %s based on origin branch(es)\"\n                % localRefPrefix)\n \n     originPrefix = \"origin/p4/\"\n@@ -914,7 +914,7 @@ def createOrUpdateBranchesFromOrigin(localRefPrefix = \"refs/remotes/p4/\", silent\n         update = False\n         if not gitBranchExists(remoteHead):\n             if verbose:\n-                print \"creating %s\" % remoteHead\n+                print(\"creating %s\" % remoteHead)\n             update = True\n         else:\n             settings = extractSettingsGitLog(extractLogMessageFromGitCommit(remoteHead))\n@@ -923,13 +923,13 @@ def createOrUpdateBranchesFromOrigin(localRefPrefix = \"refs/remotes/p4/\", silent\n                     originP4Change = int(original['change'])\n                     p4Change = int(settings['change'])\n                     if originP4Change > p4Change:\n-                        print (\"%s (%s) is newer than %s (%s). \"\n+                        print(\"%s (%s) is newer than %s (%s). \"\n                                \"Updating p4 branch from origin.\"\n                                % (originHead, originP4Change,\n                                   remoteHead, p4Change))\n                         update = True\n                 else:\n-                    print (\"Ignoring: %s was imported from %s while \"\n+                    print(\"Ignoring: %s was imported from %s while \"\n                            \"%s was imported from %s\"\n                            % (originHead, ','.join(original['depot-paths']),\n                               remoteHead, ','.join(settings['depot-paths'])))\n@@ -1397,9 +1397,9 @@ def __init__(self):\n     def run(self, args):\n         j = 0\n         for output in p4CmdList(args):\n-            print 'Element: %d' % j\n+            print('Element: %d' % j)\n             j += 1\n-            print output\n+            print(output)\n         return True\n \n class P4RollBack(Command):\n@@ -1440,14 +1440,14 @@ def run(self, args):\n \n                 if len(p4Cmd(\"changes -m 1 \"  + ' '.join (['%s...@%s' % (p, maxChange)\n                                                            for p in depotPaths]))) == 0:\n-                    print \"Branch %s did not exist at change %s, deleting.\" % (ref, maxChange)\n+                    print(\"Branch %s did not exist at change %s, deleting.\" % (ref, maxChange))\n                     system(\"git update-ref -d %s `git rev-parse %s`\" % (ref, ref))\n                     continue\n \n                 while change and int(change) > maxChange:\n                     changed = True\n                     if self.verbose:\n-                        print \"%s is at %s ; rewinding towards %s\" % (ref, change, maxChange)\n+                        print(\"%s is at %s ; rewinding towards %s\" % (ref, change, maxChange))\n                     system(\"git update-ref %s \\\"%s^\\\"\" % (ref, ref))\n                     log = extractLogMessageFromGitCommit(ref)\n                     settings =  extractSettingsGitLog(log)\n@@ -1457,7 +1457,7 @@ def run(self, args):\n                     change = settings['change']\n \n                 if changed:\n-                    print \"%s rewound to %s\" % (ref, change)\n+                    print(\"%s rewound to %s\" % (ref, change))\n \n         return True\n \n@@ -1593,10 +1593,10 @@ def patchRCSKeywords(self, file, pattern):\n         except:\n             # cleanup our temporary file\n             os.unlink(outFileName)\n-            print \"Failed to strip RCS keywords in %s\" % file\n+            print(\"Failed to strip RCS keywords in %s\" % file)\n             raise\n \n-        print \"Patched up RCS keywords in %s\" % file\n+        print(\"Patched up RCS keywords in %s\" % file)\n \n     def p4UserForCommit(self,id):\n         # Return the tuple (perforce user,git email) for a given git commit id\n@@ -1616,7 +1616,7 @@ def checkValidP4Users(self,commits):\n             if not user:\n                 msg = \"Cannot find p4 user for email %s in commit %s.\" % (email, id)\n                 if gitConfigBool(\"git-p4.allowMissingP4Users\"):\n-                    print \"%s\" % msg\n+                    print(\"%s\" % msg)\n                 else:\n                     die(\"Error: %s\\nSet git-p4.allowMissingP4Users to true to allow this.\" % msg)\n \n@@ -1808,8 +1808,8 @@ def get_diff_description(self, editedFiles, filesToAdd, symlinks):\n     def applyCommit(self, id):\n         \"\"\"Apply one commit, return True if it succeeded.\"\"\"\n \n-        print \"Applying\", read_pipe([\"git\", \"show\", \"-s\",\n-                                     \"--format=format:%h %s\", id])\n+        print(\"Applying\", read_pipe([\"git\", \"show\", \"-s\",\n+                                     \"--format=format:%h %s\", id]))\n \n         (p4User, gitEmail) = self.p4UserForCommit(id)\n \n@@ -1899,7 +1899,7 @@ def applyCommit(self, id):\n         if os.system(tryPatchCmd) != 0:\n             fixed_rcs_keywords = False\n             patch_succeeded = False\n-            print \"Unfortunately applying the change failed!\"\n+            print(\"Unfortunately applying the change failed!\")\n \n             # Patch failed, maybe it's just RCS keyword woes. Look through\n             # the patch to see if that's possible.\n@@ -1917,13 +1917,13 @@ def applyCommit(self, id):\n                         for line in read_pipe_lines([\"git\", \"diff\", \"%s^..%s\" % (id, id), file]):\n                             if regexp.search(line):\n                                 if verbose:\n-                                    print \"got keyword match on %s in %s in %s\" % (pattern, line, file)\n+                                    print(\"got keyword match on %s in %s in %s\" % (pattern, line, file))\n                                 kwfiles[file] = pattern\n                                 break\n \n                 for file in kwfiles:\n                     if verbose:\n-                        print \"zapping %s with %s\" % (line,pattern)\n+                        print(\"zapping %s with %s\" % (line,pattern))\n                     # File is being deleted, so not open in p4.  Must\n                     # disable the read-only bit on windows.\n                     if self.isWindows and file not in editedFiles:\n@@ -1932,7 +1932,7 @@ def applyCommit(self, id):\n                     fixed_rcs_keywords = True\n \n             if fixed_rcs_keywords:\n-                print \"Retrying the patch with RCS keywords cleaned up\"\n+                print(\"Retrying the patch with RCS keywords cleaned up\")\n                 if os.system(tryPatchCmd) == 0:\n                     patch_succeeded = True\n \n@@ -2000,34 +2000,34 @@ def applyCommit(self, id):\n             # Leave the p4 tree prepared, and the submit template around\n             # and let the user decide what to do next\n             #\n-            print\n-            print \"P4 workspace prepared for submission.\"\n-            print \"To submit or revert, go to client workspace\"\n-            print \"  \" + self.clientPath\n-            print\n-            print \"To submit, use \\\"p4 submit\\\" to write a new description,\"\n-            print \"or \\\"p4 submit -i <%s\\\" to use the one prepared by\" \\\n-                  \" \\\"git p4\\\".\" % fileName\n-            print \"You can delete the file \\\"%s\\\" when finished.\" % fileName\n+            print()\n+            print(\"P4 workspace prepared for submission.\")\n+            print(\"To submit or revert, go to client workspace\")\n+            print(\"  \" + self.clientPath)\n+            print()\n+            print(\"To submit, use \\\"p4 submit\\\" to write a new description,\")\n+            print(\"or \\\"p4 submit -i <%s\\\" to use the one prepared by\" \\\n+                  \" \\\"git p4\\\".\" % fileName)\n+            print(\"You can delete the file \\\"%s\\\" when finished.\" % fileName)\n \n             if self.preserveUser and p4User and not self.p4UserIsMe(p4User):\n-                print \"To preserve change ownership by user %s, you must\\n\" \\\n+                print(\"To preserve change ownership by user %s, you must\\n\" \\\n                       \"do \\\"p4 change -f <change>\\\" after submitting and\\n\" \\\n-                      \"edit the User field.\"\n+                      \"edit the User field.\")\n             if pureRenameCopy:\n-                print \"After submitting, renamed files must be re-synced.\"\n-                print \"Invoke \\\"p4 sync -f\\\" on each of these files:\"\n+                print(\"After submitting, renamed files must be re-synced.\")\n+                print(\"Invoke \\\"p4 sync -f\\\" on each of these files:\")\n                 for f in pureRenameCopy:\n-                    print \"  \" + f\n+                    print(\"  \" + f)\n \n-            print\n-            print \"To revert the changes, use \\\"p4 revert ...\\\", and delete\"\n-            print \"the submit template file \\\"%s\\\"\" % fileName\n+            print()\n+            print(\"To revert the changes, use \\\"p4 revert ...\\\", and delete\")\n+            print(\"the submit template file \\\"%s\\\"\" % fileName)\n             if filesToAdd:\n-                print \"Since the commit adds new files, they must be deleted:\"\n+                print(\"Since the commit adds new files, they must be deleted:\")\n                 for f in filesToAdd:\n-                    print \"  \" + f\n-            print\n+                    print(\"  \" + f)\n+            print()\n             return True\n \n         #\n@@ -2094,7 +2094,7 @@ def exportGitTags(self, gitTags):\n \n             if not m.match(name):\n                 if verbose:\n-                    print \"tag %s does not match regexp %s\" % (name, validLabelRegexp)\n+                    print(\"tag %s does not match regexp %s\" % (name, validLabelRegexp))\n                 continue\n \n             # Get the p4 commit this corresponds to\n@@ -2104,7 +2104,7 @@ def exportGitTags(self, gitTags):\n             if 'change' not in values:\n                 # a tag pointing to something not sent to p4; ignore\n                 if verbose:\n-                    print \"git tag %s does not give a p4 commit\" % name\n+                    print(\"git tag %s does not give a p4 commit\" % name)\n                 continue\n             else:\n                 changelist = values['change']\n@@ -2139,10 +2139,10 @@ def exportGitTags(self, gitTags):\n                 labelTemplate += \"\\t%s\\n\" % depot_side\n \n             if self.dry_run:\n-                print \"Would create p4 label %s for tag\" % name\n+                print(\"Would create p4 label %s for tag\" % name)\n             elif self.prepare_p4_only:\n-                print \"Not creating p4 label %s for tag due to option\" \\\n-                      \" --prepare-p4-only\" % name\n+                print(\"Not creating p4 label %s for tag due to option\" \\\n+                      \" --prepare-p4-only\" % name)\n             else:\n                 p4_write_pipe([\"label\", \"-i\"], labelTemplate)\n \n@@ -2151,7 +2151,7 @@ def exportGitTags(self, gitTags):\n                           [\"%s@%s\" % (depot_side, changelist) for depot_side in clientSpec.mappings])\n \n                 if verbose:\n-                    print \"created p4 label for tag %s\" % name\n+                    print(\"created p4 label for tag %s\" % name)\n \n     def run(self, args):\n         if len(args) == 0:\n@@ -2195,10 +2195,10 @@ def run(self, args):\n             self.conflict_behavior = val\n \n         if self.verbose:\n-            print \"Origin branch is \" + self.origin\n+            print(\"Origin branch is \" + self.origin)\n \n         if len(self.depotPath) == 0:\n-            print \"Internal error: cannot locate perforce depot path from existing branches\"\n+            print(\"Internal error: cannot locate perforce depot path from existing branches\")\n             sys.exit(128)\n \n         self.useClientSpec = False\n@@ -2219,7 +2219,7 @@ def run(self, args):\n         if self.clientPath == \"\":\n             die(\"Error: Cannot locate perforce checkout of %s in client view\" % self.depotPath)\n \n-        print \"Perforce checkout for depot path %s located at %s\" % (self.depotPath, self.clientPath)\n+        print(\"Perforce checkout for depot path %s located at %s\" % (self.depotPath, self.clientPath))\n         self.oldWorkingDirectory = os.getcwd()\n \n         # ensure the clientPath exists\n@@ -2230,9 +2230,9 @@ def run(self, args):\n \n         chdir(self.clientPath, is_client_path=True)\n         if self.dry_run:\n-            print \"Would synchronize p4 checkout in %s\" % self.clientPath\n+            print(\"Would synchronize p4 checkout in %s\" % self.clientPath)\n         else:\n-            print \"Synchronizing p4 checkout...\"\n+            print(\"Synchronizing p4 checkout...\")\n             if new_client_dir:\n                 # old one was destroyed, and maybe nobody told p4\n                 p4_sync(\"...\", \"-f\")\n@@ -2308,13 +2308,13 @@ def run(self, args):\n         # continue to try the rest of the patches, or quit.\n         #\n         if self.dry_run:\n-            print \"Would apply\"\n+            print(\"Would apply\")\n         applied = []\n         last = len(commits) - 1\n         for i, commit in enumerate(commits):\n             if self.dry_run:\n-                print \" \", read_pipe([\"git\", \"show\", \"-s\",\n-                                      \"--format=format:%h %s\", commit])\n+                print(\" \", read_pipe([\"git\", \"show\", \"-s\",\n+                                      \"--format=format:%h %s\", commit]))\n                 ok = True\n             else:\n                 ok = self.applyCommit(commit)\n@@ -2322,15 +2322,15 @@ def run(self, args):\n                 applied.append(commit)\n             else:\n                 if self.prepare_p4_only and i < last:\n-                    print \"Processing only the first commit due to option\" \\\n-                          \" --prepare-p4-only\"\n+                    print(\"Processing only the first commit due to option\" \\\n+                          \" --prepare-p4-only\")\n                     break\n                 if i < last:\n                     quit = False\n                     while True:\n                         # prompt for what to do, or use the option/variable\n                         if self.conflict_behavior == \"ask\":\n-                            print \"What do you want to do?\"\n+                            print(\"What do you want to do?\")\n                             response = raw_input(\"[s]kip this commit but apply\"\n                                                  \" the rest, or [q]uit? \")\n                             if not response:\n@@ -2344,10 +2344,10 @@ def run(self, args):\n                                 self.conflict_behavior)\n \n                         if response[0] == \"s\":\n-                            print \"Skipping this commit, but applying the rest\"\n+                            print(\"Skipping this commit, but applying the rest\")\n                             break\n                         if response[0] == \"q\":\n-                            print \"Quitting\"\n+                            print(\"Quitting\")\n                             quit = True\n                             break\n                     if quit:\n@@ -2360,7 +2360,7 @@ def run(self, args):\n         elif self.prepare_p4_only:\n             pass\n         elif len(commits) == len(applied):\n-            print (\"All commits {0}!\".format(shelved_applied))\n+            print(\"All commits {0}!\".format(shelved_applied))\n \n             sync = P4Sync()\n             if self.branch:\n@@ -2376,17 +2376,17 @@ def run(self, args):\n \n         else:\n             if len(applied) == 0:\n-                print (\"No commits {0}.\".format(shelved_applied))\n+                print(\"No commits {0}.\".format(shelved_applied))\n             else:\n-                print (\"{0} only the commits marked with '*':\".format(shelved_applied.capitalize()))\n+                print(\"{0} only the commits marked with '*':\".format(shelved_applied.capitalize()))\n                 for c in commits:\n                     if c in applied:\n                         star = \"*\"\n                     else:\n                         star = \" \"\n-                    print star, read_pipe([\"git\", \"show\", \"-s\",\n-                                           \"--format=format:%h %s\",  c])\n-                print \"You will have to do 'git p4 sync' and rebase.\"\n+                    print(star, read_pipe([\"git\", \"show\", \"-s\",\n+                                           \"--format=format:%h %s\",  c]))\n+                print(\"You will have to do 'git p4 sync' and rebase.\")\n \n         if gitConfigBool(\"git-p4.exportLabels\"):\n             self.exportLabels = True\n@@ -2596,7 +2596,7 @@ def checkpoint(self):\n         self.gitStream.write(\"progress checkpoint\\n\\n\")\n         out = self.gitOutput.readline()\n         if self.verbose:\n-            print \"checkpoint finished: \" + out\n+            print(\"checkpoint finished: \" + out)\n \n     def cmp_shelved(self, path, filerev, revision):\n         \"\"\" Determine if a path at revision #filerev is the same as the file\n@@ -2751,7 +2751,7 @@ def encodeWithUTF8(self, path):\n                 encoding = gitConfig('git-p4.pathEncoding')\n             path = path.decode(encoding, 'replace').encode('utf8', 'replace')\n             if self.verbose:\n-                print 'Path with non-ASCII characters detected. Used %s to encode: %s ' % (encoding, path)\n+                print('Path with non-ASCII characters detected. Used %s to encode: %s ' % (encoding, path))\n         return path\n \n     # output one file from the P4 stream\n@@ -2780,7 +2780,7 @@ def streamOneP4File(self, file, contents):\n                 # to nothing.  This causes p4 errors when checking out such\n                 # a change, and errors here too.  Work around it by ignoring\n                 # the bad symlink; hopefully a future change fixes it.\n-                print \"\\nIgnoring empty symlink in %s\" % file['depotFile']\n+                print(\"\\nIgnoring empty symlink in %s\" % file['depotFile'])\n                 return\n             elif data[-1] == '\\n':\n                 contents = [data[:-1]]\n@@ -2820,7 +2820,7 @@ def streamOneP4File(self, file, contents):\n             # Ideally, someday, this script can learn how to generate\n             # appledouble files directly and import those to git, but\n             # non-mac machines can never find a use for apple filetype.\n-            print \"\\nIgnoring apple filetype file %s\" % file['depotFile']\n+            print(\"\\nIgnoring apple filetype file %s\" % file['depotFile'])\n             return\n \n         # Note that we do not try to de-mangle keywords on utf16 files,\n@@ -2969,7 +2969,7 @@ def streamTag(self, gitStream, labelName, labelDetails, commit, epoch):\n         \"\"\"\n \n         if verbose:\n-            print \"writing tag %s for commit %s\" % (labelName, commit)\n+            print(\"writing tag %s for commit %s\" % (labelName, commit))\n         gitStream.write(\"tag %s\\n\" % labelName)\n         gitStream.write(\"from %s\\n\" % commit)\n \n@@ -2988,7 +2988,7 @@ def streamTag(self, gitStream, labelName, labelDetails, commit, epoch):\n \n         gitStream.write(\"tagger %s\\n\" % tagger)\n \n-        print \"labelDetails=\",labelDetails\n+        print(\"labelDetails=\",labelDetails)\n         if 'Description' in labelDetails:\n             description = labelDetails['Description']\n         else:\n@@ -3060,7 +3060,7 @@ def commit(self, details, files, branch, parent = \"\"):\n \n         if len(parent) > 0:\n             if self.verbose:\n-                print \"parent %s\" % parent\n+                print(\"parent %s\" % parent)\n             self.gitStream.write(\"from %s\\n\" % parent)\n \n         self.streamP4Files(files)\n@@ -3073,7 +3073,7 @@ def commit(self, details, files, branch, parent = \"\"):\n             labelDetails = label[0]\n             labelRevisions = label[1]\n             if self.verbose:\n-                print \"Change %s is labelled %s\" % (change, labelDetails)\n+                print(\"Change %s is labelled %s\" % (change, labelDetails))\n \n             files = p4CmdList([\"files\"] + [\"%s...@%s\" % (p, change)\n                                                 for p in self.branchPrefixes])\n@@ -3091,12 +3091,12 @@ def commit(self, details, files, branch, parent = \"\"):\n \n                 else:\n                     if not self.silent:\n-                        print (\"Tag %s does not match with change %s: files do not match.\"\n+                        print(\"Tag %s does not match with change %s: files do not match.\"\n                                % (labelDetails[\"label\"], change))\n \n             else:\n                 if not self.silent:\n-                    print (\"Tag %s does not match with change %s: file count is different.\"\n+                    print(\"Tag %s does not match with change %s: file count is different.\"\n                            % (labelDetails[\"label\"], change))\n \n     # Build a dictionary of changelists and labels, for \"detect-labels\" option.\n@@ -3112,7 +3112,7 @@ def getLabels(self):\n             revisions = {}\n             newestChange = 0\n             if self.verbose:\n-                print \"Querying files for label %s\" % label\n+                print(\"Querying files for label %s\" % label)\n             for file in p4CmdList([\"files\"] +\n                                       [\"%s...@%s\" % (p, label)\n                                           for p in self.depotPaths]):\n@@ -3124,7 +3124,7 @@ def getLabels(self):\n             self.labels[newestChange] = [output, revisions]\n \n         if self.verbose:\n-            print \"Label changes: %s\" % self.labels.keys()\n+            print(\"Label changes: %s\" % self.labels.keys())\n \n     # Import p4 labels as git tags. A direct mapping does not\n     # exist, so assume that if all the files are at the same revision\n@@ -3132,7 +3132,7 @@ def getLabels(self):\n     # just ignore.\n     def importP4Labels(self, stream, p4Labels):\n         if verbose:\n-            print \"import p4 labels: \" + ' '.join(p4Labels)\n+            print(\"import p4 labels: \" + ' '.join(p4Labels))\n \n         ignoredP4Labels = gitConfigList(\"git-p4.ignoredP4Labels\")\n         validLabelRegexp = gitConfig(\"git-p4.labelImportRegexp\")\n@@ -3145,7 +3145,7 @@ def importP4Labels(self, stream, p4Labels):\n \n             if not m.match(name):\n                 if verbose:\n-                    print \"label %s does not match regexp %s\" % (name,validLabelRegexp)\n+                    print(\"label %s does not match regexp %s\" % (name,validLabelRegexp))\n                 continue\n \n             if name in ignoredP4Labels:\n@@ -3167,7 +3167,7 @@ def importP4Labels(self, stream, p4Labels):\n                     gitCommit = read_pipe([\"git\", \"rev-list\", \"--max-count=1\",\n                         \"--reverse\", \":/\\[git-p4:.*change = %d\\]\" % changelist], ignore_error=True)\n                     if len(gitCommit) == 0:\n-                        print \"importing label %s: could not find git commit for changelist %d\" % (name, changelist)\n+                        print(\"importing label %s: could not find git commit for changelist %d\" % (name, changelist))\n                     else:\n                         commitFound = True\n                         gitCommit = gitCommit.strip()\n@@ -3177,16 +3177,16 @@ def importP4Labels(self, stream, p4Labels):\n                     try:\n                         tmwhen = time.strptime(labelDetails['Update'], \"%Y/%m/%d %H:%M:%S\")\n                     except ValueError:\n-                        print \"Could not convert label time %s\" % labelDetails['Update']\n+                        print(\"Could not convert label time %s\" % labelDetails['Update'])\n                         tmwhen = 1\n \n                     when = int(time.mktime(tmwhen))\n                     self.streamTag(stream, name, labelDetails, gitCommit, when)\n                     if verbose:\n-                        print \"p4 label %s mapped to git commit %s\" % (name, gitCommit)\n+                        print(\"p4 label %s mapped to git commit %s\" % (name, gitCommit))\n             else:\n                 if verbose:\n-                    print \"Label %s has no changelists - possibly deleted?\" % name\n+                    print(\"Label %s has no changelists - possibly deleted?\" % name)\n \n             if not commitFound:\n                 # We can't import this label; don't try again as it will get very\n@@ -3231,8 +3231,8 @@ def getBranchMapping(self):\n \n                     if destination in self.knownBranches:\n                         if not self.silent:\n-                            print \"p4 branch %s defines a mapping from %s to %s\" % (info[\"branch\"], source, destination)\n-                            print \"but there exists another mapping from %s to %s already!\" % (self.knownBranches[destination], destination)\n+                            print(\"p4 branch %s defines a mapping from %s to %s\" % (info[\"branch\"], source, destination))\n+                            print(\"but there exists another mapping from %s to %s already!\" % (self.knownBranches[destination], destination))\n                         continue\n \n                     self.knownBranches[destination] = source\n@@ -3296,28 +3296,28 @@ def gitRefForBranch(self, branch):\n \n     def gitCommitByP4Change(self, ref, change):\n         if self.verbose:\n-            print \"looking in ref \" + ref + \" for change %s using bisect...\" % change\n+            print(\"looking in ref \" + ref + \" for change %s using bisect...\" % change)\n \n         earliestCommit = \"\"\n         latestCommit = parseRevision(ref)\n \n         while True:\n             if self.verbose:\n-                print \"trying: earliest %s latest %s\" % (earliestCommit, latestCommit)\n+                print(\"trying: earliest %s latest %s\" % (earliestCommit, latestCommit))\n             next = read_pipe(\"git rev-list --bisect %s %s\" % (latestCommit, earliestCommit)).strip()\n             if len(next) == 0:\n                 if self.verbose:\n-                    print \"argh\"\n+                    print(\"argh\")\n                 return \"\"\n             log = extractLogMessageFromGitCommit(next)\n             settings = extractSettingsGitLog(log)\n             currentChange = int(settings['change'])\n             if self.verbose:\n-                print \"current change %s\" % currentChange\n+                print(\"current change %s\" % currentChange)\n \n             if currentChange == change:\n                 if self.verbose:\n-                    print \"found %s\" % next\n+                    print(\"found %s\" % next)\n                 return next\n \n             if currentChange < change:\n@@ -3363,7 +3363,7 @@ def searchParent(self, parent, branch, target):\n             if len(read_pipe([\"git\", \"diff-tree\", blob, target])) == 0:\n                 parentFound = True\n                 if self.verbose:\n-                    print \"Found parent of %s in commit %s\" % (branch, blob)\n+                    print(\"Found parent of %s in commit %s\" % (branch, blob))\n                 break\n         if parentFound:\n             return blob\n@@ -3394,7 +3394,7 @@ def importChanges(self, changes, shelved=False, origin_revision=0):\n                         filesForCommit = branches[branch]\n \n                         if self.verbose:\n-                            print \"branch is %s\" % branch\n+                            print(\"branch is %s\" % branch)\n \n                         self.updatedBranches.add(branch)\n \n@@ -3415,13 +3415,13 @@ def importChanges(self, changes, shelved=False, origin_revision=0):\n                                         print(\"\\n    Resuming with change %s\" % change);\n \n                                 if self.verbose:\n-                                    print \"parent determined through known branches: %s\" % parent\n+                                    print(\"parent determined through known branches: %s\" % parent)\n \n                         branch = self.gitRefForBranch(branch)\n                         parent = self.gitRefForBranch(parent)\n \n                         if self.verbose:\n-                            print \"looking for initial parent for %s; current parent is %s\" % (branch, parent)\n+                            print(\"looking for initial parent for %s; current parent is %s\" % (branch, parent))\n \n                         if len(parent) == 0 and branch in self.initialParents:\n                             parent = self.initialParents[branch]\n@@ -3431,7 +3431,7 @@ def importChanges(self, changes, shelved=False, origin_revision=0):\n                         if len(parent) > 0:\n                             tempBranch = \"%s/%d\" % (self.tempBranchLocation, change)\n                             if self.verbose:\n-                                print \"Creating temporary branch: \" + tempBranch\n+                                print(\"Creating temporary branch: \" + tempBranch)\n                             self.commit(description, filesForCommit, tempBranch)\n                             self.tempBranches.append(tempBranch)\n                             self.checkpoint()\n@@ -3440,7 +3440,7 @@ def importChanges(self, changes, shelved=False, origin_revision=0):\n                             self.commit(description, filesForCommit, branch, blob)\n                         else:\n                             if self.verbose:\n-                                print \"Parent of %s not found. Committing into head of %s\" % (branch, parent)\n+                                print(\"Parent of %s not found. Committing into head of %s\" % (branch, parent))\n                             self.commit(description, filesForCommit, branch, parent)\n                 else:\n                     files = self.extractFilesFromCommit(description, shelved, change, origin_revision)\n@@ -3449,7 +3449,7 @@ def importChanges(self, changes, shelved=False, origin_revision=0):\n                     # only needed once, to connect to the previous commit\n                     self.initialParent = \"\"\n             except IOError:\n-                print self.gitError.read()\n+                print(self.gitError.read())\n                 sys.exit(1)\n \n     def sync_origin_only(self):\n@@ -3457,11 +3457,11 @@ def sync_origin_only(self):\n             self.hasOrigin = originP4BranchesExist()\n             if self.hasOrigin:\n                 if not self.silent:\n-                    print 'Syncing with origin first, using \"git fetch origin\"'\n+                    print('Syncing with origin first, using \"git fetch origin\"')\n                 system(\"git fetch origin\")\n \n     def importHeadRevision(self, revision):\n-        print \"Doing initial import of %s from revision %s into %s\" % (' '.join(self.depotPaths), revision, self.branch)\n+        print(\"Doing initial import of %s from revision %s into %s\" % (' '.join(self.depotPaths), revision, self.branch))\n \n         details = {}\n         details[\"user\"] = \"git perforce import user\"\n@@ -3513,8 +3513,8 @@ def importHeadRevision(self, revision):\n         try:\n             self.commit(details, self.extractFilesFromCommit(details), self.branch)\n         except IOError:\n-            print \"IO error with git fast-import. Is your git version recent enough?\"\n-            print self.gitError.read()\n+            print(\"IO error with git fast-import. Is your git version recent enough?\")\n+            print(self.gitError.read())\n \n     def openStreams(self):\n         self.importProcess = subprocess.Popen([\"git\", \"fast-import\"],\n@@ -3576,14 +3576,14 @@ def run(self, args):\n \n             if len(self.p4BranchesInGit) > 1:\n                 if not self.silent:\n-                    print \"Importing from/into multiple branches\"\n+                    print(\"Importing from/into multiple branches\")\n                 self.detectBranches = True\n                 for branch in branches.keys():\n                     self.initialParents[self.refPrefix + branch] = \\\n                         branches[branch]\n \n             if self.verbose:\n-                print \"branches: %s\" % self.p4BranchesInGit\n+                print(\"branches: %s\" % self.p4BranchesInGit)\n \n             p4Change = 0\n             for branch in self.p4BranchesInGit:\n@@ -3618,7 +3618,7 @@ def run(self, args):\n                 self.depotPaths = sorted(self.previousDepotPaths)\n                 self.changeRange = \"@%s,#head\" % p4Change\n                 if not self.silent and not self.detectBranches:\n-                    print \"Performing incremental import into %s git branch\" % self.branch\n+                    print(\"Performing incremental import into %s git branch\" % self.branch)\n \n         # accept multiple ref name abbreviations:\n         #    refs/foo/bar/branch -> use it exactly\n@@ -3635,10 +3635,10 @@ def run(self, args):\n \n         if len(args) == 0 and self.depotPaths:\n             if not self.silent:\n-                print \"Depot paths: %s\" % ' '.join(self.depotPaths)\n+                print(\"Depot paths: %s\" % ' '.join(self.depotPaths))\n         else:\n             if self.depotPaths and self.depotPaths != args:\n-                print (\"previous import used depot path %s and now %s was specified. \"\n+                print(\"previous import used depot path %s and now %s was specified. \"\n                        \"This doesn't work!\" % (' '.join (self.depotPaths),\n                                                ' '.join (args)))\n                 sys.exit(1)\n@@ -3705,8 +3705,8 @@ def run(self, args):\n             else:\n                 self.getBranchMapping()\n             if self.verbose:\n-                print \"p4-git branches: %s\" % self.p4BranchesInGit\n-                print \"initial parents: %s\" % self.initialParents\n+                print(\"p4-git branches: %s\" % self.p4BranchesInGit)\n+                print(\"initial parents: %s\" % self.initialParents)\n             for b in self.p4BranchesInGit:\n                 if b != \"master\":\n \n@@ -3750,8 +3750,8 @@ def run(self, args):\n                                     self.branch)\n \n                 if self.verbose:\n-                    print \"Getting p4 changes for %s...%s\" % (', '.join(self.depotPaths),\n-                                                              self.changeRange)\n+                    print(\"Getting p4 changes for %s...%s\" % (', '.join(self.depotPaths),\n+                                                              self.changeRange))\n                 changes = p4ChangesForPaths(self.depotPaths, self.changeRange, self.changes_block_size)\n \n                 if len(self.maxChanges) > 0:\n@@ -3759,10 +3759,10 @@ def run(self, args):\n \n             if len(changes) == 0:\n                 if not self.silent:\n-                    print \"No changes to import!\"\n+                    print(\"No changes to import!\")\n             else:\n                 if not self.silent and not self.detectBranches:\n-                    print \"Import destination: %s\" % self.branch\n+                    print(\"Import destination: %s\" % self.branch)\n \n                 self.updatedBranches = set()\n \n@@ -3777,7 +3777,7 @@ def run(self, args):\n                 self.importChanges(changes)\n \n                 if not self.silent:\n-                    print \"\"\n+                    print(\"\")\n                     if len(self.updatedBranches) > 0:\n                         sys.stdout.write(\"Updated branches: \")\n                         for b in self.updatedBranches:\n@@ -3841,7 +3841,7 @@ def rebase(self):\n         # the branchpoint may be p4/foo~3, so strip off the parent\n         upstream = re.sub(\"~[0-9]+$\", \"\", upstream)\n \n-        print \"Rebasing the current branch onto %s\" % upstream\n+        print(\"Rebasing the current branch onto %s\" % upstream)\n         oldHead = read_pipe(\"git rev-parse HEAD\").strip()\n         system(\"git rebase %s\" % upstream)\n         system(\"git diff-tree --stat --summary -M %s HEAD --\" % oldHead)\n@@ -3895,7 +3895,7 @@ def run(self, args):\n         if not self.cloneDestination:\n             self.cloneDestination = self.defaultDestination(args)\n \n-        print \"Importing from %s into %s\" % (', '.join(depotPaths), self.cloneDestination)\n+        print(\"Importing from %s into %s\" % (', '.join(depotPaths), self.cloneDestination))\n \n         if not os.path.exists(self.cloneDestination):\n             os.makedirs(self.cloneDestination)\n@@ -3917,8 +3917,8 @@ def run(self, args):\n             if not self.cloneBare:\n                 system([ \"git\", \"checkout\", \"-f\" ])\n         else:\n-            print 'Not checking out any branch, use ' \\\n-                  '\"git checkout -q -b master <branch>\"'\n+            print('Not checking out any branch, use ' \\\n+                  '\"git checkout -q -b master <branch>\"')\n \n         # auto-set this variable if invoked with --use-client-spec\n         if self.useClientSpec_from_options:\n@@ -4034,7 +4034,7 @@ def run(self, args):\n             log = extractLogMessageFromGitCommit(\"refs/remotes/%s\" % branch)\n             settings = extractSettingsGitLog(log)\n \n-            print \"%s <= %s (%s)\" % (branch, \",\".join(settings[\"depot-paths\"]), settings[\"change\"])\n+            print(\"%s <= %s (%s)\" % (branch, \",\".join(settings[\"depot-paths\"]), settings[\"change\"]))\n         return True\n \n class HelpFormatter(optparse.IndentedHelpFormatter):\n@@ -4048,12 +4048,12 @@ def format_description(self, description):\n             return \"\"\n \n def printUsage(commands):\n-    print \"usage: %s <command> [options]\" % sys.argv[0]\n-    print \"\"\n-    print \"valid commands: %s\" % \", \".join(commands)\n-    print \"\"\n-    print \"Try %s <command> --help for command specific help.\" % sys.argv[0]\n-    print \"\"\n+    print(\"usage: %s <command> [options]\" % sys.argv[0])\n+    print(\"\")\n+    print(\"valid commands: %s\" % \", \".join(commands))\n+    print(\"\")\n+    print(\"Try %s <command> --help for command specific help.\" % sys.argv[0])\n+    print(\"\")\n \n commands = {\n     \"debug\" : P4Debug,\n@@ -4078,8 +4078,8 @@ def main():\n         klass = commands[cmdName]\n         cmd = klass()\n     except KeyError:\n-        print \"unknown command %s\" % cmdName\n-        print \"\"\n+        print(\"unknown command %s\" % cmdName)\n+        print(\"\")\n         printUsage(commands.keys())\n         sys.exit(2)\n \n-- \n2.18.0.rc1.242.g61856ae69a\n\n"},{"id":"350461","messageId":"CAPig+cRE5_kqhXwFzWhi1xKgTfxcbMJNoisOuNvHCiGOMARunw@mail.gmail.com","threadId":"48737","inReplyTo":"20180619080411.6554-3-luke@diamand.org","subject":"Re: [PATCH 2/6] git-p4: python3: replace dict.has_key(k) with \"k in dict\"","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2018-06-19T08:15:11Z","receivedAt":"2018-06-19T08:15:27Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Tue, Jun 19, 2018 at 4:04 AM Luke Diamand <luke@diamand.org> wrote:\n> Python3 does not have the dict.has_key() function, so replace all\n> such calls with \"k in dict\". This will still work with python2.6\n> and python2.7.\n>\n> Converted using 2to3 (plus some hand-editing)\n>\n> Signed-off-by: Luke Diamand <luke@diamand.org>\n> ---\n> diff --git a/git-p4.py b/git-p4.py\n> @@ -3141,7 +3141,7 @@ def importP4Labels(self, stream, p4Labels):\n> -            if change.has_key('change'):\n> +            if 'change' in change:\n\nVery existential.\n\nAll these changes look sensible (as one might expect from automated conversion).\n"}]}