{"thread":{"id":"32676","subject":"[PATCH v3 0/8] Python 3 support for git_remote_helpers","startedAt":"2013-01-20T13:15:30Z","lastAt":"2013-02-05T16:07:06Z","messageCount":38,"participants":["John Keeping","Sverre Rabbelier","Junio C Hamano","Brandon Casey","Michael Haggerty","Erik Faye-Lund"],"isPatch":true,"patchVersion":3,"patchTotal":8},"messages":[{"id":"207295","messageId":"cover.1358686905.git.john@keeping.me.uk","threadId":"32676","inReplyTo":null,"subject":"[PATCH v3 0/8] Python 3 support for git_remote_helpers","fromName":"John Keeping","fromEmail":"john@keeping.me.uk","sentAt":"2013-01-20T13:15:30Z","receivedAt":"2013-01-20T13:15:30Z","isPatch":true,"sender":{"key":"john@keeping.me.uk","avatar":"https://avatars.githubusercontent.com/u/1702081?v=4"},"body":"This series does enough so that everything except git-p4 runs under\nPython 3.\n                                                                                 \nAs discussed with Pete, it may not make sense to change git-p4 to\nsupport Python 3 until Perforce's Python output mode is changed.  So\ndoes it make sense to merge this now and say \"use Python 2 if you want\ngit-p4\"?\n                                                                                 \nChanges since v2:\n\n - Change reference URL in commit message of patch 4\n   (git_remote_helpers: Use 2to3 if building with Python 3) to point at\n   Python documentation instead of the Python wiki.\n\n - Add a comment in patch 7 (git-remote-testpy: don't do unbuffered text\n   I/O), as suggested by Sverre.\n\n\nJohn Keeping (8):\n  git_remote_helpers: Allow building with Python 3\n  git_remote_helpers: fix input when running under Python 3\n  git_remote_helpers: Force rebuild if python version changes\n  git_remote_helpers: Use 2to3 if building with Python 3\n  svn-fe: allow svnrdump_sim.py to run with Python 3\n  git-remote-testpy: hash bytes explicitly\n  git-remote-testpy: don't do unbuffered text I/O\n  git-remote-testpy: call print as a function\n\n contrib/svn-fe/svnrdump_sim.py     |  4 ++--\n git-remote-testpy.py               | 46 +++++++++++++++++++++-----------------\n git_remote_helpers/.gitignore      |  1 +\n git_remote_helpers/Makefile        | 10 +++++++--\n git_remote_helpers/git/importer.py |  9 +++++---\n git_remote_helpers/setup.py        | 10 +++++++++\n 6 files changed, 52 insertions(+), 28 deletions(-)\n\n-- \n1.8.1.353.gc992d5a.dirty\n"},{"id":"207296","messageId":"72abc4652432c35ebb81404b41c2149d0400347a.1358686905.git.john@keeping.me.uk","threadId":"32676","inReplyTo":"cover.1358686905.git.john@keeping.me.uk","subject":"[PATCH v3 1/8] git_remote_helpers: Allow building with Python 3","fromName":"John Keeping","fromEmail":"john@keeping.me.uk","sentAt":"2013-01-20T13:15:31Z","receivedAt":"2013-01-20T13:15:31Z","isPatch":true,"sender":{"key":"john@keeping.me.uk","avatar":"https://avatars.githubusercontent.com/u/1702081?v=4"},"body":"Change inline Python to call \"print\" as a function not a statement.\n\nThis is harmless because Python 2 will see the parentheses as redundant\ngrouping but they are necessary to run this code with Python 3.\n\nSigned-off-by: John Keeping <john@keeping.me.uk>\n---\n git_remote_helpers/Makefile | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/git_remote_helpers/Makefile b/git_remote_helpers/Makefile\nindex 74b05dc..f65f064 100644\n--- a/git_remote_helpers/Makefile\n+++ b/git_remote_helpers/Makefile\n@@ -23,7 +23,7 @@ endif\n \n PYLIBDIR=$(shell $(PYTHON_PATH) -c \\\n \t \"import sys; \\\n-\t print 'lib/python%i.%i/site-packages' % sys.version_info[:2]\")\n+\t print('lib/python%i.%i/site-packages' % sys.version_info[:2])\")\n \n all: $(pysetupfile)\n \t$(QUIET)$(PYTHON_PATH) $(pysetupfile) $(QUIETSETUP) build\n-- \n1.8.1.353.gc992d5a.dirty\n"},{"id":"207297","messageId":"7cd489e5b1b2578b1509232196cd6b21fd684843.1358686905.git.john@keeping.me.uk","threadId":"32676","inReplyTo":"cover.1358686905.git.john@keeping.me.uk","subject":"[PATCH v3 2/8] git_remote_helpers: fix input when running under Python 3","fromName":"John Keeping","fromEmail":"john@keeping.me.uk","sentAt":"2013-01-20T13:15:32Z","receivedAt":"2013-01-20T13:15:32Z","isPatch":true,"sender":{"key":"john@keeping.me.uk","avatar":"https://avatars.githubusercontent.com/u/1702081?v=4"},"body":"Although 2to3 will fix most issues in Python 2 code to make it run under\nPython 3, it does not handle the new strict separation between byte\nstrings and unicode strings.  There is one instance in\ngit_remote_helpers where we are caught by this, which is when reading\nrefs from \"git for-each-ref\".\n\nFix this by operating on the returned string as a byte string rather\nthan a unicode string.  As this method is currently only used internally\nby the class this does not affect code anywhere else.\n\nNote that we cannot use byte strings in the source as the 'b' prefix is\nnot supported before Python 2.7 so in order to maintain compatibility\nwith the maximum range of Python versions we use an explicit call to\nencode().\n\nSigned-off-by: John Keeping <john@keeping.me.uk>\n---\n git_remote_helpers/git/importer.py | 9 ++++++---\n 1 file changed, 6 insertions(+), 3 deletions(-)\n\ndiff --git a/git_remote_helpers/git/importer.py b/git_remote_helpers/git/importer.py\nindex e28cc8f..d3f90e1 100644\n--- a/git_remote_helpers/git/importer.py\n+++ b/git_remote_helpers/git/importer.py\n@@ -18,13 +18,16 @@ class GitImporter(object):\n \n     def get_refs(self, gitdir):\n         \"\"\"Returns a dictionary with refs.\n+\n+        Note that the keys in the returned dictionary are byte strings as\n+        read from git.\n         \"\"\"\n         args = [\"git\", \"--git-dir=\" + gitdir, \"for-each-ref\", \"refs/heads\"]\n-        lines = check_output(args).strip().split('\\n')\n+        lines = check_output(args).strip().split('\\n'.encode('ascii'))\n         refs = {}\n         for line in lines:\n-            value, name = line.split(' ')\n-            name = name.strip('commit\\t')\n+            value, name = line.split(' '.encode('ascii'))\n+            name = name.strip('commit\\t'.encode('ascii'))\n             refs[name] = value\n         return refs\n \n-- \n1.8.1.353.gc992d5a.dirty\n"},{"id":"207298","messageId":"9a8644116bebf81cc15c0e63056bb2054dd17ebc.1358686905.git.john@keeping.me.uk","threadId":"32676","inReplyTo":"cover.1358686905.git.john@keeping.me.uk","subject":"[PATCH v3 3/8] git_remote_helpers: Force rebuild if python version changes","fromName":"John Keeping","fromEmail":"john@keeping.me.uk","sentAt":"2013-01-20T13:15:33Z","receivedAt":"2013-01-20T13:15:33Z","isPatch":true,"sender":{"key":"john@keeping.me.uk","avatar":"https://avatars.githubusercontent.com/u/1702081?v=4"},"body":"When different version of python are used to build via distutils, the\nbehaviour can change.  Detect changes in version and pass --force in\nthis case.\n\nSigned-off-by: John Keeping <john@keeping.me.uk>\n---\n git_remote_helpers/.gitignore | 1 +\n git_remote_helpers/Makefile   | 8 +++++++-\n 2 files changed, 8 insertions(+), 1 deletion(-)\n\ndiff --git a/git_remote_helpers/.gitignore b/git_remote_helpers/.gitignore\nindex 2247d5f..06c664f 100644\n--- a/git_remote_helpers/.gitignore\n+++ b/git_remote_helpers/.gitignore\n@@ -1,2 +1,3 @@\n+/GIT-PYTHON_VERSION\n /build\n /dist\ndiff --git a/git_remote_helpers/Makefile b/git_remote_helpers/Makefile\nindex f65f064..91f458f 100644\n--- a/git_remote_helpers/Makefile\n+++ b/git_remote_helpers/Makefile\n@@ -25,8 +25,14 @@ PYLIBDIR=$(shell $(PYTHON_PATH) -c \\\n \t \"import sys; \\\n \t print('lib/python%i.%i/site-packages' % sys.version_info[:2])\")\n \n+py_version=$(shell $(PYTHON_PATH) -c \\\n+\t'import sys; print(\"%i.%i\" % sys.version_info[:2])')\n+\n all: $(pysetupfile)\n-\t$(QUIET)$(PYTHON_PATH) $(pysetupfile) $(QUIETSETUP) build\n+\t$(QUIET)test \"$$(cat GIT-PYTHON_VERSION 2>/dev/null)\" = \"$(py_version)\" || \\\n+\tflags=--force; \\\n+\t$(PYTHON_PATH) $(pysetupfile) $(QUIETSETUP) build $$flags\n+\t$(QUIET)echo \"$(py_version)\" >GIT-PYTHON_VERSION\n \n install: $(pysetupfile)\n \t$(PYTHON_PATH) $(pysetupfile) install --prefix $(DESTDIR_SQ)$(prefix)\n-- \n1.8.1.353.gc992d5a.dirty\n"},{"id":"207299","messageId":"821f662a13db72ef96a9026133e8cb763c0a9be2.1358686905.git.john@keeping.me.uk","threadId":"32676","inReplyTo":"cover.1358686905.git.john@keeping.me.uk","subject":"[PATCH v3 4/8] git_remote_helpers: Use 2to3 if building with Python 3","fromName":"John Keeping","fromEmail":"john@keeping.me.uk","sentAt":"2013-01-20T13:15:34Z","receivedAt":"2013-01-20T13:15:34Z","isPatch":true,"sender":{"key":"john@keeping.me.uk","avatar":"https://avatars.githubusercontent.com/u/1702081?v=4"},"body":"Using the approach detailed in the Python documentation[1], run 2to3 on\nthe code as part of the build if building with Python 3.\n\nThe code itself requires no changes to convert cleanly.\n\n[1] http://docs.python.org/3.3/howto/pyporting.html#during-installation\n\nSigned-off-by: John Keeping <john@keeping.me.uk>\nAcked-by: Sverre Rabbelier <srabbelier@gmail.com>\n---\n\nOn Fri, 18 Jan 2013 23:52:16 -0800, Sverre Rabbelier wrote:\n> Assuming you tried this out on both 2.x and 3.x:\n>\n> Acked-by: Sverre Rabbelier <srabbelier@gmail.com>\n\nI ran the test suite with Python 2.7.3 and 3.2.3.\n\n git_remote_helpers/setup.py | 10 ++++++++++\n 1 file changed, 10 insertions(+)\n\ndiff --git a/git_remote_helpers/setup.py b/git_remote_helpers/setup.py\nindex 4d434b6..6de41de 100644\n--- a/git_remote_helpers/setup.py\n+++ b/git_remote_helpers/setup.py\n@@ -4,6 +4,15 @@\n \n from distutils.core import setup\n \n+# If building under Python3 we need to run 2to3 on the code, do this by\n+# trying to import distutils' 2to3 builder, which is only available in\n+# Python3.\n+try:\n+    from distutils.command.build_py import build_py_2to3 as build_py\n+except ImportError:\n+    # 2.x\n+    from distutils.command.build_py import build_py\n+\n setup(\n     name = 'git_remote_helpers',\n     version = '0.1.0',\n@@ -14,4 +23,5 @@ setup(\n     url = 'http://www.git-scm.com/',\n     package_dir = {'git_remote_helpers': ''},\n     packages = ['git_remote_helpers', 'git_remote_helpers.git'],\n+    cmdclass = {'build_py': build_py},\n )\n-- \n1.8.1.353.gc992d5a.dirty\n"},{"id":"207300","messageId":"939a445ab113e0beb41e6882b1ec6089de86fac9.1358686905.git.john@keeping.me.uk","threadId":"32676","inReplyTo":"cover.1358686905.git.john@keeping.me.uk","subject":"[PATCH v3 5/8] svn-fe: allow svnrdump_sim.py to run with Python 3","fromName":"John Keeping","fromEmail":"john@keeping.me.uk","sentAt":"2013-01-20T13:15:35Z","receivedAt":"2013-01-20T13:15:35Z","isPatch":true,"sender":{"key":"john@keeping.me.uk","avatar":"https://avatars.githubusercontent.com/u/1702081?v=4"},"body":"The changes to allow this script to run with Python 3 are minimal and do\nnot affect its functionality on the versions of Python 2 that are\nalready supported (2.4 onwards).\n\nSigned-off-by: John Keeping <john@keeping.me.uk>\n---\n contrib/svn-fe/svnrdump_sim.py | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/contrib/svn-fe/svnrdump_sim.py b/contrib/svn-fe/svnrdump_sim.py\nindex 17cf6f9..4e78a1c 100755\n--- a/contrib/svn-fe/svnrdump_sim.py\n+++ b/contrib/svn-fe/svnrdump_sim.py\n@@ -14,7 +14,7 @@ if sys.hexversion < 0x02040000:\n \n def getrevlimit():\n         var = 'SVNRMAX'\n-        if os.environ.has_key(var):\n+        if var in os.environ:\n                 return os.environ[var]\n         return None\n \n@@ -44,7 +44,7 @@ def writedump(url, lower, upper):\n \n if __name__ == \"__main__\":\n         if not (len(sys.argv) in (3, 4, 5)):\n-                print \"usage: %s dump URL -rLOWER:UPPER\"\n+                print(\"usage: %s dump URL -rLOWER:UPPER\")\n                 sys.exit(1)\n         if not sys.argv[1] == 'dump': raise NotImplementedError('only \"dump\" is suppported.')\n         url = sys.argv[2]\n-- \n1.8.1.353.gc992d5a.dirty\n"},{"id":"207301","messageId":"611a44568bdc969bcfa3d7d870560855e00baf1e.1358686905.git.john@keeping.me.uk","threadId":"32676","inReplyTo":"cover.1358686905.git.john@keeping.me.uk","subject":"[PATCH v3 6/8] git-remote-testpy: hash bytes explicitly","fromName":"John Keeping","fromEmail":"john@keeping.me.uk","sentAt":"2013-01-20T13:15:36Z","receivedAt":"2013-01-20T13:15:36Z","isPatch":true,"sender":{"key":"john@keeping.me.uk","avatar":"https://avatars.githubusercontent.com/u/1702081?v=4"},"body":"Under Python 3 'hasher.update(...)' must take a byte string and not a\nunicode string.  Explicitly encode the argument to this method to hex\nbytes so that we don't need to worry about failures to encode that might\noccur if we chose a textual encoding.\n\nThis changes the directory used by git-remote-testpy for its git mirror\nof the remote repository, but this tool should not have any serious\nusers as it is used primarily to test the Python remote helper\nframework.\n\nThe use of encode() moves the required Python version forward to 2.0.\n\nSigned-off-by: John Keeping <john@keeping.me.uk>\n---\n git-remote-testpy.py | 8 ++++----\n 1 file changed, 4 insertions(+), 4 deletions(-)\n\ndiff --git a/git-remote-testpy.py b/git-remote-testpy.py\nindex d94a66a..197b7be 100644\n--- a/git-remote-testpy.py\n+++ b/git-remote-testpy.py\n@@ -31,9 +31,9 @@ from git_remote_helpers.git.exporter import GitExporter\n from git_remote_helpers.git.importer import GitImporter\n from git_remote_helpers.git.non_local import NonLocalGit\n \n-if sys.hexversion < 0x01050200:\n-    # os.makedirs() is the limiter\n-    sys.stderr.write(\"git-remote-testgit: requires Python 1.5.2 or later.\\n\")\n+if sys.hexversion < 0x02000000:\n+    # string.encode() is the limiter\n+    sys.stderr.write(\"git-remote-testgit: requires Python 2.0 or later.\\n\")\n     sys.exit(1)\n \n def get_repo(alias, url):\n@@ -45,7 +45,7 @@ def get_repo(alias, url):\n     repo.get_head()\n \n     hasher = _digest()\n-    hasher.update(repo.path)\n+    hasher.update(repo.path.encode('hex'))\n     repo.hash = hasher.hexdigest()\n \n     repo.get_base_path = lambda base: os.path.join(\n-- \n1.8.1.353.gc992d5a.dirty\n"},{"id":"207302","messageId":"c73b8e6e762bbf19e840994e4ff6e99de465051c.1358686905.git.john@keeping.me.uk","threadId":"32676","inReplyTo":"cover.1358686905.git.john@keeping.me.uk","subject":"[PATCH v3 7/8] git-remote-testpy: don't do unbuffered text I/O","fromName":"John Keeping","fromEmail":"john@keeping.me.uk","sentAt":"2013-01-20T13:15:37Z","receivedAt":"2013-01-20T13:15:37Z","isPatch":true,"sender":{"key":"john@keeping.me.uk","avatar":"https://avatars.githubusercontent.com/u/1702081?v=4"},"body":"Python 3 forbids unbuffered I/O in text mode.  Change the reading of\nstdin in git-remote-testpy so that we read the lines as bytes and then\ndecode them a line at a time.\n\nThis allows us to keep the I/O unbuffered in order to avoid\nreintroducing the bug fixed by commit 7fb8e16 (git-remote-testgit: fix\nrace when spawning fast-import).\n\nSigned-off-by: John Keeping <john@keeping.me.uk>\n---\n git-remote-testpy.py | 10 +++++++---\n 1 file changed, 7 insertions(+), 3 deletions(-)\n\ndiff --git a/git-remote-testpy.py b/git-remote-testpy.py\nindex 197b7be..5dbf1cc 100644\n--- a/git-remote-testpy.py\n+++ b/git-remote-testpy.py\n@@ -154,7 +154,7 @@ def do_import(repo, args):\n     refs = [ref]\n \n     while True:\n-        line = sys.stdin.readline()\n+        line = sys.stdin.readline().decode()\n         if line == '\\n':\n             break\n         if not line.startswith('import '):\n@@ -225,7 +225,7 @@ def read_one_line(repo):\n \n     line = sys.stdin.readline()\n \n-    cmdline = line\n+    cmdline = line.decode()\n \n     if not cmdline:\n         warn(\"Unexpected EOF\")\n@@ -277,7 +277,11 @@ def main(args):\n \n     more = True\n \n-    sys.stdin = os.fdopen(sys.stdin.fileno(), 'r', 0)\n+    # Use binary mode since Python 3 does not permit unbuffered I/O in text\n+    # mode.  Unbuffered I/O is required to avoid data that should be going\n+    # to git-fast-import after an \"export\" command getting caught in our\n+    # stdin buffer instead.\n+    sys.stdin = os.fdopen(sys.stdin.fileno(), 'rb', 0)\n     while (more):\n         more = read_one_line(repo)\n \n-- \n1.8.1.353.gc992d5a.dirty\n"},{"id":"207303","messageId":"ef4637c02dcfb306a2f209c7387ecfb2f66d4e7a.1358686905.git.john@keeping.me.uk","threadId":"32676","inReplyTo":"cover.1358686905.git.john@keeping.me.uk","subject":"[PATCH v3 8/8] git-remote-testpy: call print as a function","fromName":"John Keeping","fromEmail":"john@keeping.me.uk","sentAt":"2013-01-20T13:15:38Z","receivedAt":"2013-01-20T13:15:38Z","isPatch":true,"sender":{"key":"john@keeping.me.uk","avatar":"https://avatars.githubusercontent.com/u/1702081?v=4"},"body":"This is harmless in Python 2, which sees the parentheses as redundant\ngrouping, but is required for Python 3.  Since this is the only change\nrequired to make this script just run under Python 3 without needing\n2to3 it seems worthwhile.\n\nThe case of an empty print must be handled specially because in that\ncase Python 2 will interpret '()' as an empty tuple and print it as\n'()'; inserting an empty string fixes this.\n\nSigned-off-by: John Keeping <john@keeping.me.uk>\nAcked-by: Sverre Rabbelier <srabbelier@gmail.com>\n---\n git-remote-testpy.py | 28 ++++++++++++++--------------\n 1 file changed, 14 insertions(+), 14 deletions(-)\n\ndiff --git a/git-remote-testpy.py b/git-remote-testpy.py\nindex 5dbf1cc..c7a04ec 100644\n--- a/git-remote-testpy.py\n+++ b/git-remote-testpy.py\n@@ -87,9 +87,9 @@ def do_capabilities(repo, args):\n     \"\"\"Prints the supported capabilities.\n     \"\"\"\n \n-    print \"import\"\n-    print \"export\"\n-    print \"refspec refs/heads/*:%s*\" % repo.prefix\n+    print(\"import\")\n+    print(\"export\")\n+    print(\"refspec refs/heads/*:%s*\" % repo.prefix)\n \n     dirname = repo.get_base_path(repo.gitdir)\n \n@@ -98,11 +98,11 @@ def do_capabilities(repo, args):\n \n     path = os.path.join(dirname, 'git.marks')\n \n-    print \"*export-marks %s\" % path\n+    print(\"*export-marks %s\" % path)\n     if os.path.exists(path):\n-        print \"*import-marks %s\" % path\n+        print(\"*import-marks %s\" % path)\n \n-    print # end capabilities\n+    print('') # end capabilities\n \n \n def do_list(repo, args):\n@@ -115,16 +115,16 @@ def do_list(repo, args):\n \n     for ref in repo.revs:\n         debug(\"? refs/heads/%s\", ref)\n-        print \"? refs/heads/%s\" % ref\n+        print(\"? refs/heads/%s\" % ref)\n \n     if repo.head:\n         debug(\"@refs/heads/%s HEAD\" % repo.head)\n-        print \"@refs/heads/%s HEAD\" % repo.head\n+        print(\"@refs/heads/%s HEAD\" % repo.head)\n     else:\n         debug(\"@refs/heads/master HEAD\")\n-        print \"@refs/heads/master HEAD\"\n+        print(\"@refs/heads/master HEAD\")\n \n-    print # end list\n+    print('') # end list\n \n \n def update_local_repo(repo):\n@@ -164,7 +164,7 @@ def do_import(repo, args):\n         ref = line[7:].strip()\n         refs.append(ref)\n \n-    print \"feature done\"\n+    print(\"feature done\")\n \n     if os.environ.get(\"GIT_REMOTE_TESTGIT_FAILURE\"):\n         die('Told to fail')\n@@ -172,7 +172,7 @@ def do_import(repo, args):\n     repo = update_local_repo(repo)\n     repo.exporter.export_repo(repo.gitdir, refs)\n \n-    print \"done\"\n+    print(\"done\")\n \n \n def do_export(repo, args):\n@@ -192,8 +192,8 @@ def do_export(repo, args):\n         repo.non_local.push(repo.gitdir)\n \n     for ref in changed:\n-        print \"ok %s\" % ref\n-    print\n+        print(\"ok %s\" % ref)\n+    print('')\n \n \n COMMANDS = {\n-- \n1.8.1.353.gc992d5a.dirty\n"},{"id":"207616","messageId":"CAGdFq_hs+mP6JbLW65h1_U0JAetHyJ=HsA4sN_WCcRAs96LLew@mail.gmail.com","threadId":"32676","inReplyTo":"72abc4652432c35ebb81404b41c2149d0400347a.1358686905.git.john@keeping.me.uk","subject":"Re: [PATCH v3 1/8] git_remote_helpers: Allow building with Python 3","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2013-01-23T18:49:12Z","receivedAt":"2013-01-23T18:49:12Z","isPatch":true,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"On Sun, Jan 20, 2013 at 5:15 AM, John Keeping <john@keeping.me.uk> wrote:\n> Change inline Python to call \"print\" as a function not a statement.\n>\n> This is harmless because Python 2 will see the parentheses as redundant\n> grouping but they are necessary to run this code with Python 3.\n>\n> Signed-off-by: John Keeping <john@keeping.me.uk>\n\nAcked-by: Sverre Rabbelier <srabbelier@gmail.com>\n\n--\nCheers,\n\nSverre Rabbelier\n"},{"id":"207617","messageId":"CAGdFq_jfoN7FbbNXwudzOo7=E3Z11=sL0VGW3_QgRyCSQWw8aA@mail.gmail.com","threadId":"32676","inReplyTo":"9a8644116bebf81cc15c0e63056bb2054dd17ebc.1358686905.git.john@keeping.me.uk","subject":"Re: [PATCH v3 3/8] git_remote_helpers: Force rebuild if python version changes","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2013-01-23T18:51:24Z","receivedAt":"2013-01-23T18:51:24Z","isPatch":true,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"On Sun, Jan 20, 2013 at 5:15 AM, John Keeping <john@keeping.me.uk> wrote:\n> When different version of python are used to build via distutils, the\n> behaviour can change.  Detect changes in version and pass --force in\n> this case.\n>\n> Signed-off-by: John Keeping <john@keeping.me.uk>\n\nSomeone else's review on this would be appreciated, the idea sounds\nsane but I can't really comment on the implementation.\n\n--\nCheers,\n\nSverre Rabbelier\n"},{"id":"207619","messageId":"CAGdFq_jp3BrS0zgDpmiXGduwu_m4E2CCL+X32P-7T=z9Qk-wuQ@mail.gmail.com","threadId":"32676","inReplyTo":"7cd489e5b1b2578b1509232196cd6b21fd684843.1358686905.git.john@keeping.me.uk","subject":"Re: [PATCH v3 2/8] git_remote_helpers: fix input when running under Python 3","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2013-01-23T19:20:39Z","receivedAt":"2013-01-23T19:20:39Z","isPatch":true,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"On Sun, Jan 20, 2013 at 5:15 AM, John Keeping <john@keeping.me.uk> wrote:\n> Although 2to3 will fix most issues in Python 2 code to make it run under\n> Python 3, it does not handle the new strict separation between byte\n> strings and unicode strings.  There is one instance in\n> git_remote_helpers where we are caught by this, which is when reading\n> refs from \"git for-each-ref\".\n>\n> Fix this by operating on the returned string as a byte string rather\n> than a unicode string.  As this method is currently only used internally\n> by the class this does not affect code anywhere else.\n>\n> Note that we cannot use byte strings in the source as the 'b' prefix is\n> not supported before Python 2.7 so in order to maintain compatibility\n> with the maximum range of Python versions we use an explicit call to\n> encode().\n\nThe three patches that deal with .encode() stuff (2, 7, 8) make me a\nbit uncomfortable, as they add some significant complexity to our\npython code. Is this the recommended way to deal with this (similar to\nthe other patch where you linked to the python wiki explaining)?\n\nAs one datapoint, it seems that it's actually Python 2.6 that\nintroduces the b prefix.\n\nhttp://www.python.org/dev/peps/pep-3112/\n\nWhen did we last revisit what minimal python version we are ok with requiring?\n\n--\nCheers,\n\nSverre Rabbelier\n"},{"id":"207621","messageId":"20130123194757.GQ7498@serenity.lan","threadId":"32676","inReplyTo":"CAGdFq_jp3BrS0zgDpmiXGduwu_m4E2CCL+X32P-7T=z9Qk-wuQ@mail.gmail.com","subject":"Re: [PATCH v3 2/8] git_remote_helpers: fix input when running under Python 3","fromName":"John Keeping","fromEmail":"john@keeping.me.uk","sentAt":"2013-01-23T19:47:57Z","receivedAt":"2013-01-23T19:47:57Z","isPatch":true,"sender":{"key":"john@keeping.me.uk","avatar":"https://avatars.githubusercontent.com/u/1702081?v=4"},"body":"On Wed, Jan 23, 2013 at 11:20:39AM -0800, Sverre Rabbelier wrote:\n> On Sun, Jan 20, 2013 at 5:15 AM, John Keeping <john@keeping.me.uk> wrote:\n> > Although 2to3 will fix most issues in Python 2 code to make it run under\n> > Python 3, it does not handle the new strict separation between byte\n> > strings and unicode strings.  There is one instance in\n> > git_remote_helpers where we are caught by this, which is when reading\n> > refs from \"git for-each-ref\".\n> >\n> > Fix this by operating on the returned string as a byte string rather\n> > than a unicode string.  As this method is currently only used internally\n> > by the class this does not affect code anywhere else.\n> >\n> > Note that we cannot use byte strings in the source as the 'b' prefix is\n> > not supported before Python 2.7 so in order to maintain compatibility\n> > with the maximum range of Python versions we use an explicit call to\n> > encode().\n> \n> The three patches that deal with .encode() stuff (2, 7, 8) make me a\n> bit uncomfortable, as they add some significant complexity to our\n> python code. Is this the recommended way to deal with this (similar to\n> the other patch where you linked to the python wiki explaining)?\n\nThe best I can offer is this:\n\nhttp://docs.python.org/3/howto/pyporting.html#deal-with-the-bytes-string-dichotomy\n\nTheir recommendation is to use the b() function from the six project,\nbut given that we don't need it in too many places I prefer the approach\nI took here to adding a thirdparty dependency.\n\n> As one datapoint, it seems that it's actually Python 2.6 that\n> introduces the b prefix.\n> \n> http://www.python.org/dev/peps/pep-3112/\n> \n> When did we last revisit what minimal python version we are ok with requiring?\n\nI was wondering if people would weigh in discussing that in response to\n[1] but no one has commented on that part of it.  As another datapoint,\nBrandon Casey was suggesting patching git-p4.py to support Python 2.4\n[2].\n\n[1] http://article.gmane.org/gmane.comp.version-control.git/213920\n[2] http://article.gmane.org/gmane.comp.version-control.git/214048\n\n\nJohn\n"},{"id":"207629","messageId":"CAGdFq_jZDUxg7oTL7Z4v5ezYFPfJ8kZR6iHpESw6WnoDCeAy8w@mail.gmail.com","threadId":"32676","inReplyTo":"20130123194757.GQ7498@serenity.lan","subject":"Re: [PATCH v3 2/8] git_remote_helpers: fix input when running under Python 3","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2013-01-23T20:14:46Z","receivedAt":"2013-01-23T20:14:46Z","isPatch":true,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"On Wed, Jan 23, 2013 at 11:47 AM, John Keeping <john@keeping.me.uk> wrote:\n>> When did we last revisit what minimal python version we are ok with requiring?\n>\n> I was wondering if people would weigh in discussing that in response to\n> [1] but no one has commented on that part of it.  As another datapoint,\n> Brandon Casey was suggesting patching git-p4.py to support Python 2.4\n> [2].\n>\n> [1] http://article.gmane.org/gmane.comp.version-control.git/213920\n> [2] http://article.gmane.org/gmane.comp.version-control.git/214048\n\nI for one would be happy to kill off support for anything older than\n2.6 (which had it's latest release on October 1st, 2008).\n\nJunio, how have we decided in the past which version of x to support?\n\n--\nCheers,\n\nSverre Rabbelier\n"},{"id":"207632","messageId":"7v622nhc0u.fsf@alter.siamese.dyndns.org","threadId":"32676","inReplyTo":"CAGdFq_jZDUxg7oTL7Z4v5ezYFPfJ8kZR6iHpESw6WnoDCeAy8w@mail.gmail.com","subject":"Re: [PATCH v3 2/8] git_remote_helpers: fix input when running under Python 3","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-01-23T20:36:49Z","receivedAt":"2013-01-23T20:36:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Sverre Rabbelier <srabbelier@gmail.com> writes:\n\n> On Wed, Jan 23, 2013 at 11:47 AM, John Keeping <john@keeping.me.uk> wrote:\n>>> When did we last revisit what minimal python version we are ok with requiring?\n>>\n>> I was wondering if people would weigh in discussing that in response to\n>> [1] but no one has commented on that part of it.  As another datapoint,\n>> Brandon Casey was suggesting patching git-p4.py to support Python 2.4\n>> [2].\n>>\n>> [1] http://article.gmane.org/gmane.comp.version-control.git/213920\n>> [2] http://article.gmane.org/gmane.comp.version-control.git/214048\n>\n> I for one would be happy to kill off support for anything older than\n> 2.6 (which had it's latest release on October 1st, 2008).\n>\n> Junio, how have we decided in the past which version of x to support?\n\nI do not think there was any conclusion.  $gmane/212215 claiming 2.4\nsupport matters for RHEL 5.x users was the last on the topic as far\nas I can tell, so it boils down to another question: do users on\nRHEL 5.x matter?\n\nI can read from $gmane/212215 that users of the said platform can\nsafely keep using Python 2.4 under their vendor support contract\nuntil 2017.  But let's focus on what do these users expect of their\nsystem and software they run on it a bit.\n\nWhen they want to run a piece software that is not shipped with\nRHEL, either by writing their own or by importing from elsewhere,\nthat needs 2.6 features, what are their options?\n\n (a) The platform vendor optionally supplies 2.6 with or without\n     support;\n\n (b) The users can and do install 2.6 as /usr/local/bin/python2.6,\n     which may even be community-supported, but the vendor does not\n     support it; or\n\n (c) The vendor terminates the support contract for users who choose\n     to go (b).\n\nI think we can safely discard (c); if that is the case, the users on\nthe said platform will not choose to update Git either, so it does\nnot matter where the future versions of Git sets the lower bound of\nPython version at.\n\nIf we are not talking about the situation (c), then the users can\nchoose to use 2.6, and more importantly, Python being a popular\nsoftware, I would imagine that there are reputable sources of\nprepackaged RPMs for them to do so without going too much hassle of\nconfiguring, compiling and installing.\n\nNow how does the decision we make today for releases of Git that\nhaven't yet happened will affect these users?  As these versions of\nnewer Git were not shipped with RHEL 5.x, and also I am assuming\nthat Git is a more niche product than Python is, I would imagine\nthat it is very unlikely that the vendor gives it the users as an\noptional package.  The users will have to do the same thing to be\nable to use such versions of Git as whatever they do in order to use\nPython 2.6.\n\nGiven that, what the vendor originally shipped and officially\nsupports does not affect the choices we would make today for newer\nversions of Git.  The users in a shop where additional third-party\nsoftware in /usr/local/bin is strictly forbidden, they are stuck\nwith the version of Git that the vendor shipped anyway, because they\nwon't be able to install an updated Git in /usr/local/bin, either.\n\nThat is, unless installing 2.6 as /usr/local/bin/python2.6 (or if\nyou are really paranoid, /usr/local/only-for-git/bin/python2.6 where\nnobody's $PATH points at) is impossible.\n\nSo personally I do not think dropping 2.4 is a huge problem for\nfuture versions of Git, but I'd like to hear from those working in\nIT support for large and slow-moving organizations (aka RHEL 5\ncustomers).\n"},{"id":"207833","messageId":"CA+sFfMf2R6+qzrLR9rwhtcM=ABZ8aWUJw-3riF98B3XWVGm54w@mail.gmail.com","threadId":"32676","inReplyTo":"7v622nhc0u.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v3 2/8] git_remote_helpers: fix input when running under Python 3","fromName":"Brandon Casey","fromEmail":"drafnel@gmail.com","sentAt":"2013-01-25T20:23:56Z","receivedAt":"2013-01-25T20:23:56Z","isPatch":true,"sender":{"key":"drafnel@gmail.com","avatar":"https://avatars.githubusercontent.com/u/921167?v=4"},"body":"On Wed, Jan 23, 2013 at 12:36 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Sverre Rabbelier <srabbelier@gmail.com> writes:\n>\n>> On Wed, Jan 23, 2013 at 11:47 AM, John Keeping <john@keeping.me.uk> wrote:\n>>>> When did we last revisit what minimal python version we are ok with requiring?\n>>>\n>>> I was wondering if people would weigh in discussing that in response to\n>>> [1] but no one has commented on that part of it.  As another datapoint,\n>>> Brandon Casey was suggesting patching git-p4.py to support Python 2.4\n>>> [2].\n>>>\n>>> [1] http://article.gmane.org/gmane.comp.version-control.git/213920\n>>> [2] http://article.gmane.org/gmane.comp.version-control.git/214048\n>>\n>> I for one would be happy to kill off support for anything older than\n>> 2.6 (which had it's latest release on October 1st, 2008).\n>>\n>> Junio, how have we decided in the past which version of x to support?\n>\n> I do not think there was any conclusion.  $gmane/212215 claiming 2.4\n> support matters for RHEL 5.x users was the last on the topic as far\n> as I can tell, so it boils down to another question: do users on\n> RHEL 5.x matter?\n>\n> I can read from $gmane/212215 that users of the said platform can\n> safely keep using Python 2.4 under their vendor support contract\n> until 2017.  But let's focus on what do these users expect of their\n> system and software they run on it a bit.\n>\n> When they want to run a piece software that is not shipped with\n> RHEL, either by writing their own or by importing from elsewhere,\n> that needs 2.6 features, what are their options?\n>\n>  (a) The platform vendor optionally supplies 2.6 with or without\n>      support;\n>\n>  (b) The users can and do install 2.6 as /usr/local/bin/python2.6,\n>      which may even be community-supported, but the vendor does not\n>      support it; or\n>\n>  (c) The vendor terminates the support contract for users who choose\n>      to go (b).\n>\n> I think we can safely discard (c); if that is the case, the users on\n> the said platform will not choose to update Git either, so it does\n> not matter where the future versions of Git sets the lower bound of\n> Python version at.\n>\n> If we are not talking about the situation (c), then the users can\n> choose to use 2.6, and more importantly, Python being a popular\n> software, I would imagine that there are reputable sources of\n> prepackaged RPMs for them to do so without going too much hassle of\n> configuring, compiling and installing.\n>\n> Now how does the decision we make today for releases of Git that\n> haven't yet happened will affect these users?  As these versions of\n> newer Git were not shipped with RHEL 5.x, and also I am assuming\n> that Git is a more niche product than Python is, I would imagine\n> that it is very unlikely that the vendor gives it the users as an\n> optional package.  The users will have to do the same thing to be\n> able to use such versions of Git as whatever they do in order to use\n> Python 2.6.\n>\n> Given that, what the vendor originally shipped and officially\n> supports does not affect the choices we would make today for newer\n> versions of Git.  The users in a shop where additional third-party\n> software in /usr/local/bin is strictly forbidden, they are stuck\n> with the version of Git that the vendor shipped anyway, because they\n> won't be able to install an updated Git in /usr/local/bin, either.\n>\n> That is, unless installing 2.6 as /usr/local/bin/python2.6 (or if\n> you are really paranoid, /usr/local/only-for-git/bin/python2.6 where\n> nobody's $PATH points at) is impossible.\n>\n> So personally I do not think dropping 2.4 is a huge problem for\n> future versions of Git, but I'd like to hear from those working in\n> IT support for large and slow-moving organizations (aka RHEL 5\n> customers).\n\nI'm not really in the demographic that you asked to hear from, but\nI'll give my 2 cents anyway. :)\n\nFirstly, I defer to those with more knowledge and experience with\npython to decide which version should be the minimum version\nsupported.  Python 2.6 seems to be the consensus and that's fine with\nme.\n\nWith respect to older platforms like RHEL 5.X that don't ship with\nPython 2.6 or later, I suspect most people who work in an organization\nwith a dedicated IT staff can request that a more recent version of\npython be installed.  So, I don't think a python 2.6 requirement (if\nthere was one) would be a blocker for them, and I don't think it would\nbe a major pain for the sysadmin to install.\n\nMy only opinion is that if we can avoid breaking older platforms\nfairly easily, we should do so.  If there is someone out there\nbuilding git packages (e.g. EPEL) for RHEL 5.X or anything else, I\nimagine that one less dependency makes installing and supporting the\npackage that much easier.\n\nSo, my comments shouldn't be taken to suggest that git should support\nany particular version of python.  That decision should be made by\nthose who are willing to support whatever version they feel strongly\nabout.\n\n-Brandon\n"},{"id":"207883","messageId":"20130126175158.GK7498@serenity.lan","threadId":"32676","inReplyTo":"611a44568bdc969bcfa3d7d870560855e00baf1e.1358686905.git.john@keeping.me.uk","subject":"Re: [PATCH v3 6/8] git-remote-testpy: hash bytes explicitly","fromName":"John Keeping","fromEmail":"john@keeping.me.uk","sentAt":"2013-01-26T17:51:58Z","receivedAt":"2013-01-26T17:51:58Z","isPatch":true,"sender":{"key":"john@keeping.me.uk","avatar":"https://avatars.githubusercontent.com/u/1702081?v=4"},"body":"Under Python 3 'hasher.update(...)' must take a byte string and not a\nunicode string.  Explicitly encode the argument to this method as UTF-8\nbytes.  This is safe since we are encoding a Python Unicode string to a\nUnicode encoding.\n\nThis changes the directory used by git-remote-testpy for its git mirror\nof the remote repository, but this tool should not have any serious\nusers as it is used primarily to test the Python remote helper\nframework.\n\nThe use of encode() moves the required Python version forward to 2.0.\n\nSigned-off-by: John Keeping <john@keeping.me.uk>\n---\nJunio, can you replace the queued 0846b0c (git-remote-testpy: hash bytes\nexplicitly) with this?\n\nI hadn't realised that the \"hex\" encoding we chose before is a \"bytes to\nbytes\" encoding so it just fails with an error on Python 3 in the same\nway as the original code.\n\nSince we want to convert a Unicode string to bytes I think UTF-8 really\nis the best option here.\n\n git-remote-testpy.py | 8 ++++----\n 1 file changed, 4 insertions(+), 4 deletions(-)\n\ndiff --git a/git-remote-testpy.py b/git-remote-testpy.py\nindex d94a66a..f8dc196 100644\n--- a/git-remote-testpy.py\n+++ b/git-remote-testpy.py\n@@ -31,9 +31,9 @@ from git_remote_helpers.git.exporter import GitExporter\n from git_remote_helpers.git.importer import GitImporter\n from git_remote_helpers.git.non_local import NonLocalGit\n \n-if sys.hexversion < 0x01050200:\n-    # os.makedirs() is the limiter\n-    sys.stderr.write(\"git-remote-testgit: requires Python 1.5.2 or later.\\n\")\n+if sys.hexversion < 0x02000000:\n+    # string.encode() is the limiter\n+    sys.stderr.write(\"git-remote-testgit: requires Python 2.0 or later.\\n\")\n     sys.exit(1)\n \n def get_repo(alias, url):\n@@ -45,7 +45,7 @@ def get_repo(alias, url):\n     repo.get_head()\n \n     hasher = _digest()\n-    hasher.update(repo.path)\n+    hasher.update(repo.path.encode('utf-8'))\n     repo.hash = hasher.hexdigest()\n \n     repo.get_base_path = lambda base: os.path.join(\n-- \n1.8.1.1\n"},{"id":"207893","messageId":"7vwquzzkiw.fsf@alter.siamese.dyndns.org","threadId":"32676","inReplyTo":"20130126175158.GK7498@serenity.lan","subject":"Re: [PATCH v3 6/8] git-remote-testpy: hash bytes explicitly","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-01-26T21:44:55Z","receivedAt":"2013-01-26T21:44:55Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"John Keeping <john@keeping.me.uk> writes:\n\n> Junio, can you replace the queued 0846b0c (git-remote-testpy: hash bytes\n> explicitly) with this?\n>\n> I hadn't realised that the \"hex\" encoding we chose before is a \"bytes to\n> bytes\" encoding so it just fails with an error on Python 3 in the same\n> way as the original code.\n>\n> Since we want to convert a Unicode string to bytes I think UTF-8 really\n> is the best option here.\n\nAhh.  I think it is already in \"next\", so this needs to be turned\ninto an incremental to flip 'hex' to 'utf-8', with the justification\nbeing these five lines above.\n\nThanks for catching.\n\n>\n>  git-remote-testpy.py | 8 ++++----\n>  1 file changed, 4 insertions(+), 4 deletions(-)\n>\n> diff --git a/git-remote-testpy.py b/git-remote-testpy.py\n> index d94a66a..f8dc196 100644\n> --- a/git-remote-testpy.py\n> +++ b/git-remote-testpy.py\n> @@ -31,9 +31,9 @@ from git_remote_helpers.git.exporter import GitExporter\n>  from git_remote_helpers.git.importer import GitImporter\n>  from git_remote_helpers.git.non_local import NonLocalGit\n>  \n> -if sys.hexversion < 0x01050200:\n> -    # os.makedirs() is the limiter\n> -    sys.stderr.write(\"git-remote-testgit: requires Python 1.5.2 or later.\\n\")\n> +if sys.hexversion < 0x02000000:\n> +    # string.encode() is the limiter\n> +    sys.stderr.write(\"git-remote-testgit: requires Python 2.0 or later.\\n\")\n>      sys.exit(1)\n>  \n>  def get_repo(alias, url):\n> @@ -45,7 +45,7 @@ def get_repo(alias, url):\n>      repo.get_head()\n>  \n>      hasher = _digest()\n> -    hasher.update(repo.path)\n> +    hasher.update(repo.path.encode('utf-8'))\n>      repo.hash = hasher.hexdigest()\n>  \n>      repo.get_base_path = lambda base: os.path.join(\n"},{"id":"207898","messageId":"20130126233242.GM7498@serenity.lan","threadId":"32676","inReplyTo":"7vwquzzkiw.fsf@alter.siamese.dyndns.org","subject":"[PATCH] git-remote-testpy: fix patch hashing on Python 3","fromName":"John Keeping","fromEmail":"john@keeping.me.uk","sentAt":"2013-01-26T23:32:42Z","receivedAt":"2013-01-26T23:32:42Z","isPatch":true,"sender":{"key":"john@keeping.me.uk","avatar":"https://avatars.githubusercontent.com/u/1702081?v=4"},"body":"When this change was originally made (0846b0c - git-remote-testpy: hash bytes\nexplicitly , I didn't realised that the \"hex\" encoding we chose is a \"bytes to\nbytes\" encoding so it just fails with an error on Python 3 in the same way as\nthe original code.\n\nSince we want to convert a Unicode string to bytes, UTF-8 really is the best\noption here.\n\nSigned-off-by: John Keeping <john@keeping.me.uk>\n---\nOn Sat, Jan 26, 2013 at 01:44:55PM -0800, Junio C Hamano wrote:\n> Ahh.  I think it is already in \"next\", so this needs to be turned\n> into an incremental to flip 'hex' to 'utf-8', with the justification\n> being these five lines above.\n\nHere it is, based on next obviously.\n\n git-remote-testpy.py | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/git-remote-testpy.py b/git-remote-testpy.py\nindex c7a04ec..4713363 100644\n--- a/git-remote-testpy.py\n+++ b/git-remote-testpy.py\n@@ -45,7 +45,7 @@ def get_repo(alias, url):\n     repo.get_head()\n \n     hasher = _digest()\n-    hasher.update(repo.path.encode('hex'))\n+    hasher.update(repo.path.encode('utf-8'))\n     repo.hash = hasher.hexdigest()\n \n     repo.get_base_path = lambda base: os.path.join(\n-- \n1.8.1.1\n"},{"id":"207929","messageId":"5104B0B5.1030501@alum.mit.edu","threadId":"32676","inReplyTo":"7vwquzzkiw.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v3 6/8] git-remote-testpy: hash bytes explicitly","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2013-01-27T04:44:37Z","receivedAt":"2013-01-27T04:44:37Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 01/26/2013 10:44 PM, Junio C Hamano wrote:\n> John Keeping <john@keeping.me.uk> writes:\n> \n>> Junio, can you replace the queued 0846b0c (git-remote-testpy: hash bytes\n>> explicitly) with this?\n>>\n>> I hadn't realised that the \"hex\" encoding we chose before is a \"bytes to\n>> bytes\" encoding so it just fails with an error on Python 3 in the same\n>> way as the original code.\n>>\n>> Since we want to convert a Unicode string to bytes I think UTF-8 really\n>> is the best option here.\n> \n> Ahh.  I think it is already in \"next\", so this needs to be turned\n> into an incremental to flip 'hex' to 'utf-8', with the justification\n> being these five lines above.\n> \n> Thanks for catching.\n> \n>>\n>>  git-remote-testpy.py | 8 ++++----\n>>  1 file changed, 4 insertions(+), 4 deletions(-)\n>>\n>> diff --git a/git-remote-testpy.py b/git-remote-testpy.py\n>> index d94a66a..f8dc196 100644\n>> --- a/git-remote-testpy.py\n>> +++ b/git-remote-testpy.py\n>> @@ -31,9 +31,9 @@ from git_remote_helpers.git.exporter import GitExporter\n>>  from git_remote_helpers.git.importer import GitImporter\n>>  from git_remote_helpers.git.non_local import NonLocalGit\n>>  \n>> -if sys.hexversion < 0x01050200:\n>> -    # os.makedirs() is the limiter\n>> -    sys.stderr.write(\"git-remote-testgit: requires Python 1.5.2 or later.\\n\")\n>> +if sys.hexversion < 0x02000000:\n>> +    # string.encode() is the limiter\n>> +    sys.stderr.write(\"git-remote-testgit: requires Python 2.0 or later.\\n\")\n>>      sys.exit(1)\n>>  \n>>  def get_repo(alias, url):\n>> @@ -45,7 +45,7 @@ def get_repo(alias, url):\n>>      repo.get_head()\n>>  \n>>      hasher = _digest()\n>> -    hasher.update(repo.path)\n>> +    hasher.update(repo.path.encode('utf-8'))\n>>      repo.hash = hasher.hexdigest()\n>>  \n>>      repo.get_base_path = lambda base: os.path.join(\n\nThis will still fail under Python 2.x if repo.path is a byte string that\ncontains non-ASCII characters.  And it will fail under Python 3.1 and\nlater if repo.path contains characters using the surrogateescape\nencoding option [1], as it will if the original command-line argument\ncontained bytes that cannot be decoded into Unicode using the user's\ndefault encoding:\n\n    $ python3 --version\n    Python 3.2.3\n    $ python3 -c \"\n    import sys\n    print(repr(sys.argv[1]))\n    print(repr(sys.argv[1].encode('utf-8')))\n    \" $(echo français|iconv -t latin1)\n    'fran\\udce7ais'\n    Traceback (most recent call last):\n      File \"<string>\", line 4, in <module>\n    UnicodeEncodeError: 'utf-8' codec can't encode character '\\udce7' in\nposition 4: surrogates not allowed\n\nI'm not sure what happens in Python 3.0.\n\nI think the \"modern\" way to handle this situation in Python 3.1+ is via\nPEP 383's surrogateescape encoding option [1]:\n\n    repo.path.encode('utf-8', 'surrogateescape')\n\nBasically, byte strings that come from the OS are automatically decoded\ninto Unicode strings using\n\n    s = b.decode(sys.getfilesystemencoding(), 'surrogateescape')\n\nIf the string needs to be passed back to the filesystem as a byte string\nit is via\n\n    b = s.encode(sys.getfilesystemencoding(), 'surrogateescape')\n\nMy understanding is that the surrogateescape mechanism guarantees that\nthe round-trip bytestring -> string -> bytestring gives back the\noriginal byte string, which is what you want for things like filenames.\n But a Unicode string that contains surrogate escape characters *cannot*\nbe encoded without the 'surrogateescape' option.\n\n'surrogateescape' is not supported in Python 3.0, but I think it would\nbe quite acceptable only to support Python 3.x for x >= 1.\n\nBut 'surrogateescape' doesn't seem to be supported at all in Python 2.x\n(I tested 2.7.3 and it's not there).\n\nHere you don't really need byte-for-byte correctness; it would be enough\nto get *some* byte string that is unique for a given input (ideally,\nconsistent with ASCII or UTF-8 for backwards compatibility).  So you\ncould use\n\n    b = s.encode('utf-8', 'backslashreplace')\n\nUnfortunately, this doesn't work under Python 2.x:\n\n    $ python2 -c \"\n    import sys\n    print(repr(sys.argv[1]))\n    print(repr(sys.argv[1].encode('utf-8', 'backslashreplace')))\n    \" $(echo français|iconv -t latin1)\n    'fran\\xe7ais'\n    Traceback (most recent call last):\n      File \"<string>\", line 4, in <module>\n    UnicodeDecodeError: 'ascii' codec can't decode byte 0xe7 in position\n4: ordinal not in range(128)\n\nApparently when you call bytestring.encode(), Python first tries to\ndecode the string to Unicode using the 'ascii' encoding.\n\nSo to handle all of the cases across Python versions as closely as\npossible to the old 2.x code, it might be necessary to make the code\nexplicitly depend on the Python version number, like:\n\n    hasher = _digest()\n    if sys.hexversion < 0x03000000:\n        pathbytes = repo.path\n    elif sys.hexversion < 0x03010000:\n        # If support for Python 3.0.x is desired (note: result can\n        # be different in this case than under 2.x or 3.1+):\n        pathbytes = repo.path.encode(sys.getfilesystemencoding(),\n'backslashreplace')\n    else\n        pathbytes = repo.path.encode(sys.getfilesystemencoding(),\n'surrogateescape')\n    hasher.update(pathbytes)\n    repo.hash = hasher.hexdigest()\n\nMichael\n\n[1] http://www.python.org/dev/peps/pep-0383/\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"207932","messageId":"7vy5ffxkfb.fsf@alter.siamese.dyndns.org","threadId":"32676","inReplyTo":"5104B0B5.1030501@alum.mit.edu","subject":"Re: [PATCH v3 6/8] git-remote-testpy: hash bytes explicitly","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-01-27T05:30:00Z","receivedAt":"2013-01-27T05:30:00Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael Haggerty <mhagger@alum.mit.edu> writes:\n\n> This will still fail under Python 2.x if repo.path is a byte string that\n> contains non-ASCII characters.  And it will fail under Python 3.1 and\n> later if repo.path contains characters using the surrogateescape\n> encoding option [1],...\n> Here you don't really need byte-for-byte correctness; it would be enough\n> to get *some* byte string that is unique for a given input ...\n\nYeek.\n\nAs we do not care about the actual value at all, how about doing\nsomething like this instead?\n\n git-remote-testgit.py | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/git-remote-testgit.py b/git-remote-testgit.py\nindex 5f3ebd2..705750d 100644\n--- a/git-remote-testgit.py\n+++ b/git-remote-testgit.py\n@@ -40,7 +40,7 @@ def get_repo(alias, url):\n     repo.get_head()\n \n     hasher = _digest()\n-    hasher.update(repo.path)\n+    hasher.update(\".\".join([str(ord(c)) for c in repo.path]))\n     repo.hash = hasher.hexdigest()\n \n     repo.get_base_path = lambda base: os.path.join(\n"},{"id":"207933","messageId":"CAGdFq_icLDEdJJKHZsht8bXpZzSNProLt3F_u=0en2rFBvxLKw@mail.gmail.com","threadId":"32676","inReplyTo":"5104B0B5.1030501@alum.mit.edu","subject":"Re: [PATCH v3 6/8] git-remote-testpy: hash bytes explicitly","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2013-01-27T05:30:16Z","receivedAt":"2013-01-27T05:30:16Z","isPatch":true,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"On Sat, Jan 26, 2013 at 8:44 PM, Michael Haggerty <mhagger@alum.mit.edu> wrote:\n> So to handle all of the cases across Python versions as closely as\n> possible to the old 2.x code, it might be necessary to make the code\n> explicitly depend on the Python version number, like:\n\nDoes this all go away if we restrict ourselves to python 2.6 and just\nuse the b prefix?\n\n--\nCheers,\n\nSverre Rabbelier\n"},{"id":"207941","messageId":"5104E827.2040906@alum.mit.edu","threadId":"32676","inReplyTo":"CAGdFq_icLDEdJJKHZsht8bXpZzSNProLt3F_u=0en2rFBvxLKw@mail.gmail.com","subject":"Re: [PATCH v3 6/8] git-remote-testpy: hash bytes explicitly","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2013-01-27T08:41:11Z","receivedAt":"2013-01-27T08:41:11Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 01/27/2013 06:30 AM, Sverre Rabbelier wrote:\n> On Sat, Jan 26, 2013 at 8:44 PM, Michael Haggerty <mhagger@alum.mit.edu> wrote:\n>> So to handle all of the cases across Python versions as closely as\n>> possible to the old 2.x code, it might be necessary to make the code\n>> explicitly depend on the Python version number, like:\n> \n> Does this all go away if we restrict ourselves to python 2.6 and just\n> use the b prefix?\n\nrepo.path ultimately comes from the command line, which means that it is\na bytestring under Python 2.x and a Unicode string under Python 3.x.  It\ndoes not come from a literal that could be changed to b\"value\".  (Nor is\na six.b()-like function helpful, if that is what you meant; that is also\nintended to wrap literal strings.)\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"207954","messageId":"20130127141329.GN7498@serenity.lan","threadId":"32676","inReplyTo":"5104B0B5.1030501@alum.mit.edu","subject":"Re: [PATCH v3 6/8] git-remote-testpy: hash bytes explicitly","fromName":"John Keeping","fromEmail":"john@keeping.me.uk","sentAt":"2013-01-27T14:13:29Z","receivedAt":"2013-01-27T14:13:29Z","isPatch":true,"sender":{"key":"john@keeping.me.uk","avatar":"https://avatars.githubusercontent.com/u/1702081?v=4"},"body":"On Sun, Jan 27, 2013 at 05:44:37AM +0100, Michael Haggerty wrote:\n> On 01/26/2013 10:44 PM, Junio C Hamano wrote:\n> > John Keeping <john@keeping.me.uk> writes:\n> >> @@ -45,7 +45,7 @@ def get_repo(alias, url):\n> >>      repo.get_head()\n> >>  \n> >>      hasher = _digest()\n> >> -    hasher.update(repo.path)\n> >> +    hasher.update(repo.path.encode('utf-8'))\n> >>      repo.hash = hasher.hexdigest()\n> >>  \n> >>      repo.get_base_path = lambda base: os.path.join(\n> \n> This will still fail under Python 2.x if repo.path is a byte string that\n> contains non-ASCII characters.\n\nI had forgotten about Python 2 while doing this.\n\n>                                 And it will fail under Python 3.1 and\n> later if repo.path contains characters using the surrogateescape\n> encoding option [1], as it will if the original command-line argument\n> contained bytes that cannot be decoded into Unicode using the user's\n> default encoding:\n\nInteresting.  I wasn't aware of the \"surrogateescape\" error handler.\n\n> 'surrogateescape' is not supported in Python 3.0, but I think it would\n> be quite acceptable only to support Python 3.x for x >= 1.\n\nI agree.\n\n> But 'surrogateescape' doesn't seem to be supported at all in Python 2.x\n> (I tested 2.7.3 and it's not there).\n> \n> Here you don't really need byte-for-byte correctness; it would be enough\n> to get *some* byte string that is unique for a given input (ideally,\n> consistent with ASCII or UTF-8 for backwards compatibility).  So you\n> could use\n> \n>     b = s.encode('utf-8', 'backslashreplace')\n> \n> Unfortunately, this doesn't work under Python 2.x:\n> \n>     $ python2 -c \"\n>     import sys\n>     print(repr(sys.argv[1]))\n>     print(repr(sys.argv[1].encode('utf-8', 'backslashreplace')))\n>     \" $(echo français|iconv -t latin1)\n>     'fran\\xe7ais'\n>     Traceback (most recent call last):\n>       File \"<string>\", line 4, in <module>\n>     UnicodeDecodeError: 'ascii' codec can't decode byte 0xe7 in position\n> 4: ordinal not in range(128)\n> \n> Apparently when you call bytestring.encode(), Python first tries to\n> decode the string to Unicode using the 'ascii' encoding.\n\nActually it appears to use sys.getdefaultencoding() to do this initial\ndecode.  Not that it makes much difference here since the failure is the\nsame.\n\n> So to handle all of the cases across Python versions as closely as\n> possible to the old 2.x code, it might be necessary to make the code\n> explicitly depend on the Python version number, like:\n> \n>     hasher = _digest()\n>     if sys.hexversion < 0x03000000:\n>         pathbytes = repo.path\n>     elif sys.hexversion < 0x03010000:\n>         # If support for Python 3.0.x is desired (note: result can\n>         # be different in this case than under 2.x or 3.1+):\n>         pathbytes = repo.path.encode(sys.getfilesystemencoding(),\n> 'backslashreplace')\n>     else\n>         pathbytes = repo.path.encode(sys.getfilesystemencoding(),\n> 'surrogateescape')\n>     hasher.update(pathbytes)\n>     repo.hash = hasher.hexdigest()\n\nIf we don't want to put a version check in it probably wants to look\nlike this (ignoring Python 3.0 since I don't think we need to support\nit):\n\n    hasher = _digest()\n    try:\n        codecs.lookup_error('surrogateescape')\n    except LookupError:\n        pathbytes = repo.path\n    else:\n        pathbytes = repo.path.encode(sys.getfilesystemencoding(),\n                                     'surrogateescape')\n    hasher.update(pathbytes)\n    repo.hash = hasher.hexdigest()\n\nThe version with a version check seems better to me, although this\nshould probably be a utility function.\n\n\nJohn\n"},{"id":"207955","messageId":"20130127142154.GO7498@serenity.lan","threadId":"32676","inReplyTo":"7vy5ffxkfb.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v3 6/8] git-remote-testpy: hash bytes explicitly","fromName":"John Keeping","fromEmail":"john@keeping.me.uk","sentAt":"2013-01-27T14:21:54Z","receivedAt":"2013-01-27T14:21:54Z","isPatch":true,"sender":{"key":"john@keeping.me.uk","avatar":"https://avatars.githubusercontent.com/u/1702081?v=4"},"body":"On Sat, Jan 26, 2013 at 09:30:00PM -0800, Junio C Hamano wrote:\n> Michael Haggerty <mhagger@alum.mit.edu> writes:\n> \n> > This will still fail under Python 2.x if repo.path is a byte string that\n> > contains non-ASCII characters.  And it will fail under Python 3.1 and\n> > later if repo.path contains characters using the surrogateescape\n> > encoding option [1],...\n> > Here you don't really need byte-for-byte correctness; it would be enough\n> > to get *some* byte string that is unique for a given input ...\n> \n> Yeek.\n> \n> As we do not care about the actual value at all, how about doing\n> something like this instead?\n> \n> +    hasher.update(\".\".join([str(ord(c)) for c in repo.path]))\n\nThis doesn't solve the original problem since we're still ending up with\na Unicode string.  If we wanted something like this it would need to be:\n\n    hasher.update(b'.'.join([b'%X' % ord(c) for c in repo.path]))\n\nwhich limits us to Python 2.6 and later and seems to me to be less clear\nthan introducing an \"encode_filepath\" helper function using Michael's\nsuggestion.\n\n\nJohn\n"},{"id":"207957","messageId":"20130127145056.GP7498@serenity.lan","threadId":"32676","inReplyTo":"20130127141329.GN7498@serenity.lan","subject":"[PATCH] git-remote-testpy: fix patch hashing on Python 3","fromName":"John Keeping","fromEmail":"john@keeping.me.uk","sentAt":"2013-01-27T14:50:56Z","receivedAt":"2013-01-27T14:50:56Z","isPatch":true,"sender":{"key":"john@keeping.me.uk","avatar":"https://avatars.githubusercontent.com/u/1702081?v=4"},"body":"When this change was originally made (0846b0c - git-remote-testpy: hash\nbytes explicitly , I didn't realised that the \"hex\" encoding we chose is\na \"bytes to bytes\" encoding so it just fails with an error on Python 3\nin the same way as the original code.\n\nIt is not possible to provide a single code path that works on Python 2\nand Python 3 since Python 2.x will attempt to decode the string before\nencoding it, which fails for strings that are not valid in the default\nencoding.  Python 3.1 introduced the \"surrogateescape\" error handler\nwhich handles this correctly and permits a bytes -> unicode -> bytes\nround-trip to be lossless.\n\nAt this point Python 3.0 is unsupported so we don't go out of our way to\ntry to support it.\n\nHelped-by: Michael Haggerty <mhagger@alum.mit.edu>\nSigned-off-by: John Keeping <john@keeping.me.uk>\n---\nOn Sun, Jan 27, 2013 at 02:13:29PM +0000, John Keeping wrote:\n> On Sun, Jan 27, 2013 at 05:44:37AM +0100, Michael Haggerty wrote:\n> > So to handle all of the cases across Python versions as closely as\n> > possible to the old 2.x code, it might be necessary to make the code\n> > explicitly depend on the Python version number, like:\n> > \n> >     hasher = _digest()\n> >     if sys.hexversion < 0x03000000:\n> >         pathbytes = repo.path\n> >     elif sys.hexversion < 0x03010000:\n> >         # If support for Python 3.0.x is desired (note: result can\n> >         # be different in this case than under 2.x or 3.1+):\n> >         pathbytes = repo.path.encode(sys.getfilesystemencoding(),\n> > 'backslashreplace')\n> >     else\n> >         pathbytes = repo.path.encode(sys.getfilesystemencoding(),\n> > 'surrogateescape')\n> >     hasher.update(pathbytes)\n> >     repo.hash = hasher.hexdigest()\n\nHow about this?\n\n git-remote-testpy.py | 18 +++++++++++++++++-\n 1 file changed, 17 insertions(+), 1 deletion(-)\n\ndiff --git a/git-remote-testpy.py b/git-remote-testpy.py\nindex c7a04ec..16b0c52 100644\n--- a/git-remote-testpy.py\n+++ b/git-remote-testpy.py\n@@ -36,6 +36,22 @@ if sys.hexversion < 0x02000000:\n     sys.stderr.write(\"git-remote-testgit: requires Python 2.0 or later.\\n\")\n     sys.exit(1)\n \n+\n+def _encode_filepath(path):\n+    \"\"\"Encodes a Unicode file path to a byte string.\n+\n+    On Python 2 this is a no-op; on Python 3 we encode the string as\n+    suggested by [1] which allows an exact round-trip from the command line\n+    to the filesystem.\n+\n+    [1] http://docs.python.org/3/c-api/unicode.html#file-system-encoding\n+\n+    \"\"\"\n+    if sys.hexversion < 0x03000000:\n+        return path\n+    return path.encode('utf-8', 'surrogateescape')\n+\n+\n def get_repo(alias, url):\n     \"\"\"Returns a git repository object initialized for usage.\n     \"\"\"\n@@ -45,7 +61,7 @@ def get_repo(alias, url):\n     repo.get_head()\n \n     hasher = _digest()\n-    hasher.update(repo.path.encode('hex'))\n+    hasher.update(_encode_filepath(repo.path))\n     repo.hash = hasher.hexdigest()\n \n     repo.get_base_path = lambda base: os.path.join(\n-- \n1.8.1.1\n"},{"id":"207973","messageId":"7vzjzuv224.fsf@alter.siamese.dyndns.org","threadId":"32676","inReplyTo":"20130127145056.GP7498@serenity.lan","subject":"Re: [PATCH] git-remote-testpy: fix patch hashing on Python 3","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-01-27T19:49:39Z","receivedAt":"2013-01-27T19:49:39Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"John Keeping <john@keeping.me.uk> writes:\n\n> When this change was originally made (0846b0c - git-remote-testpy: hash\n> bytes explicitly , I didn't realised that the \"hex\" encoding we chose is\n> a \"bytes to bytes\" encoding so it just fails with an error on Python 3\n> in the same way as the original code.\n>\n> It is not possible to provide a single code path that works on Python 2\n> and Python 3 since Python 2.x will attempt to decode the string before\n> encoding it, which fails for strings that are not valid in the default\n> encoding.  Python 3.1 introduced the \"surrogateescape\" error handler\n> which handles this correctly and permits a bytes -> unicode -> bytes\n> round-trip to be lossless.\n>\n> At this point Python 3.0 is unsupported so we don't go out of our way to\n> try to support it.\n>\n> Helped-by: Michael Haggerty <mhagger@alum.mit.edu>\n> Signed-off-by: John Keeping <john@keeping.me.uk>\n> ---\n\nThanks; will queue and wait for an Ack from Michael.\n\nDoes the helper function need to be named with leading underscore,\nthough?\n\n> On Sun, Jan 27, 2013 at 02:13:29PM +0000, John Keeping wrote:\n>> On Sun, Jan 27, 2013 at 05:44:37AM +0100, Michael Haggerty wrote:\n>> > So to handle all of the cases across Python versions as closely as\n>> > possible to the old 2.x code, it might be necessary to make the code\n>> > explicitly depend on the Python version number, like:\n>> > \n>> >     hasher = _digest()\n>> >     if sys.hexversion < 0x03000000:\n>> >         pathbytes = repo.path\n>> >     elif sys.hexversion < 0x03010000:\n>> >         # If support for Python 3.0.x is desired (note: result can\n>> >         # be different in this case than under 2.x or 3.1+):\n>> >         pathbytes = repo.path.encode(sys.getfilesystemencoding(),\n>> > 'backslashreplace')\n>> >     else\n>> >         pathbytes = repo.path.encode(sys.getfilesystemencoding(),\n>> > 'surrogateescape')\n>> >     hasher.update(pathbytes)\n>> >     repo.hash = hasher.hexdigest()\n>\n> How about this?\n>\n>  git-remote-testpy.py | 18 +++++++++++++++++-\n>  1 file changed, 17 insertions(+), 1 deletion(-)\n>\n> diff --git a/git-remote-testpy.py b/git-remote-testpy.py\n> index c7a04ec..16b0c52 100644\n> --- a/git-remote-testpy.py\n> +++ b/git-remote-testpy.py\n> @@ -36,6 +36,22 @@ if sys.hexversion < 0x02000000:\n>      sys.stderr.write(\"git-remote-testgit: requires Python 2.0 or later.\\n\")\n>      sys.exit(1)\n>  \n> +\n> +def _encode_filepath(path):\n> +    \"\"\"Encodes a Unicode file path to a byte string.\n> +\n> +    On Python 2 this is a no-op; on Python 3 we encode the string as\n> +    suggested by [1] which allows an exact round-trip from the command line\n> +    to the filesystem.\n> +\n> +    [1] http://docs.python.org/3/c-api/unicode.html#file-system-encoding\n> +\n> +    \"\"\"\n> +    if sys.hexversion < 0x03000000:\n> +        return path\n> +    return path.encode('utf-8', 'surrogateescape')\n> +\n> +\n>  def get_repo(alias, url):\n>      \"\"\"Returns a git repository object initialized for usage.\n>      \"\"\"\n> @@ -45,7 +61,7 @@ def get_repo(alias, url):\n>      repo.get_head()\n>  \n>      hasher = _digest()\n> -    hasher.update(repo.path.encode('hex'))\n> +    hasher.update(_encode_filepath(repo.path))\n>      repo.hash = hasher.hexdigest()\n>  \n>      repo.get_base_path = lambda base: os.path.join(\n"},{"id":"207976","messageId":"20130127200401.GT7498@serenity.lan","threadId":"32676","inReplyTo":"7vzjzuv224.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] git-remote-testpy: fix patch hashing on Python 3","fromName":"John Keeping","fromEmail":"john@keeping.me.uk","sentAt":"2013-01-27T20:04:01Z","receivedAt":"2013-01-27T20:04:01Z","isPatch":true,"sender":{"key":"john@keeping.me.uk","avatar":"https://avatars.githubusercontent.com/u/1702081?v=4"},"body":"On Sun, Jan 27, 2013 at 11:49:39AM -0800, Junio C Hamano wrote:\n> John Keeping <john@keeping.me.uk> writes:\n> \n> > When this change was originally made (0846b0c - git-remote-testpy: hash\n> > bytes explicitly , I didn't realised that the \"hex\" encoding we chose is\n> > a \"bytes to bytes\" encoding so it just fails with an error on Python 3\n> > in the same way as the original code.\n> >\n> > It is not possible to provide a single code path that works on Python 2\n> > and Python 3 since Python 2.x will attempt to decode the string before\n> > encoding it, which fails for strings that are not valid in the default\n> > encoding.  Python 3.1 introduced the \"surrogateescape\" error handler\n> > which handles this correctly and permits a bytes -> unicode -> bytes\n> > round-trip to be lossless.\n> >\n> > At this point Python 3.0 is unsupported so we don't go out of our way to\n> > try to support it.\n> >\n> > Helped-by: Michael Haggerty <mhagger@alum.mit.edu>\n> > Signed-off-by: John Keeping <john@keeping.me.uk>\n> > ---\n> \n> Thanks; will queue and wait for an Ack from Michael.\n> \n> Does the helper function need to be named with leading underscore,\n> though?\n\nIt's a Python convention for internal functions.  Since this is a script\nnot a library module I don't feel strongly about it in this case.\n\n\nJohn\n"},{"id":"207978","messageId":"7vr4l6v11z.fsf@alter.siamese.dyndns.org","threadId":"32676","inReplyTo":"20130127200401.GT7498@serenity.lan","subject":"Re: [PATCH] git-remote-testpy: fix patch hashing on Python 3","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-01-27T20:11:20Z","receivedAt":"2013-01-27T20:11:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"John Keeping <john@keeping.me.uk> writes:\n\n>> Thanks; will queue and wait for an Ack from Michael.\n>> \n>> Does the helper function need to be named with leading underscore,\n>> though?\n>\n> ...  Since this is a script\n> not a library module I don't feel strongly about it in this case.\n\nThat is exactly why I asked.\n"},{"id":"207980","messageId":"20130127202106.GU7498@serenity.lan","threadId":"32676","inReplyTo":"7vr4l6v11z.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] git-remote-testpy: fix patch hashing on Python 3","fromName":"John Keeping","fromEmail":"john@keeping.me.uk","sentAt":"2013-01-27T20:21:06Z","receivedAt":"2013-01-27T20:21:06Z","isPatch":true,"sender":{"key":"john@keeping.me.uk","avatar":"https://avatars.githubusercontent.com/u/1702081?v=4"},"body":"On Sun, Jan 27, 2013 at 12:11:20PM -0800, Junio C Hamano wrote:\n> John Keeping <john@keeping.me.uk> writes:\n> \n> >> Thanks; will queue and wait for an Ack from Michael.\n> >> \n> >> Does the helper function need to be named with leading underscore,\n> >> though?\n> >\n> > ...  Since this is a script\n> > not a library module I don't feel strongly about it in this case.\n> \n> That is exactly why I asked.\n\nSo I think the answer is \"habit, but I probably shouldn't have put it\nin in this case\".\n\n\nJohn\n"},{"id":"207983","messageId":"7va9ruuzsf.fsf@alter.siamese.dyndns.org","threadId":"32676","inReplyTo":"20130127202106.GU7498@serenity.lan","subject":"Re: [PATCH] git-remote-testpy: fix patch hashing on Python 3","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-01-27T20:38:40Z","receivedAt":"2013-01-27T20:38:40Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"John Keeping <john@keeping.me.uk> writes:\n\n> On Sun, Jan 27, 2013 at 12:11:20PM -0800, Junio C Hamano wrote:\n>> John Keeping <john@keeping.me.uk> writes:\n>> \n>> >> Thanks; will queue and wait for an Ack from Michael.\n>> >> \n>> >> Does the helper function need to be named with leading underscore,\n>> >> though?\n>> >\n>> > ...  Since this is a script\n>> > not a library module I don't feel strongly about it in this case.\n>> \n>> That is exactly why I asked.\n>\n> So I think the answer is \"habit, but I probably shouldn't have put it\n> in in this case\".\n\nOK, then I'll queue with a local amend to drop the leading\nunderscore.\n\nThanks.\n"},{"id":"207984","messageId":"7v622iuzea.fsf@alter.siamese.dyndns.org","threadId":"32676","inReplyTo":"7va9ruuzsf.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] git-remote-testpy: fix patch hashing on Python 3","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-01-27T20:47:09Z","receivedAt":"2013-01-27T20:47:09Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> John Keeping <john@keeping.me.uk> writes:\n>\n>> So I think the answer is \"habit, but I probably shouldn't have put it\n>> in in this case\".\n>\n> OK, then I'll queue with a local amend to drop the leading\n> underscore.\n\nSo this is what I will be queuing (I'd appreciate the second set of\neyes, though), with the leading-underscore removal and log message\ntypofixes.\n\nI remember that I earlier asked somewhere if we want to say \"Python\n3.x that is older than 3.y is unsupported\"\n\n    http://thread.gmane.org/gmane.comp.version-control.git/213920/focus=213926\n\nbut I was told that we will support all versions in 3.x series, IIRC.\n\nDoes this patch contradict with that?  If so I think we would need\nto revisit the update to CodingGuidelines in that thread.\n\nI am perfectly fine with discarding early 3.x as \"0.x releases of\nPython3\", but I would want to see our document say so if that is\nwhat we do.\n\n-- >8 --\nFrom: John Keeping <john@keeping.me.uk>\nDate: Sun, 27 Jan 2013 14:50:56 +0000\nSubject: [PATCH] git-remote-testpy: fix path hashing on Python 3\n\nWhen this change was originally made (0846b0c - git-remote-testpy:\nhash bytes explicitly , I didn't realise that the \"hex\" encoding we\nchose is a \"bytes to bytes\" encoding so it just fails with an error\non Python 3 in the same way as the original code.\n\nIt is not possible to provide a single code path that works on\nPython 2 and Python 3 since Python 2.x will attempt to decode the\nstring before encoding it, which fails for strings that are not\nvalid in the default encoding.  Python 3.1 introduced the\n\"surrogateescape\" error handler which handles this correctly and\npermits a bytes -> unicode -> bytes round-trip to be lossless.\n\nAt this point Python 3.0 is unsupported so we don't go out of our\nway to try to support it.\n\nHelped-by: Michael Haggerty <mhagger@alum.mit.edu>\nSigned-off-by: John Keeping <john@keeping.me.uk>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n git-remote-testpy.py | 18 +++++++++++++++++-\n 1 file changed, 17 insertions(+), 1 deletion(-)\n\ndiff --git a/git-remote-testpy.py b/git-remote-testpy.py\nindex c7a04ec..6098bdd 100644\n--- a/git-remote-testpy.py\n+++ b/git-remote-testpy.py\n@@ -36,6 +36,22 @@ if sys.hexversion < 0x02000000:\n     sys.stderr.write(\"git-remote-testgit: requires Python 2.0 or later.\\n\")\n     sys.exit(1)\n \n+\n+def encode_filepath(path):\n+    \"\"\"Encodes a Unicode file path to a byte string.\n+\n+    On Python 2 this is a no-op; on Python 3 we encode the string as\n+    suggested by [1] which allows an exact round-trip from the command line\n+    to the filesystem.\n+\n+    [1] http://docs.python.org/3/c-api/unicode.html#file-system-encoding\n+\n+    \"\"\"\n+    if sys.hexversion < 0x03000000:\n+        return path\n+    return path.encode('utf-8', 'surrogateescape')\n+\n+\n def get_repo(alias, url):\n     \"\"\"Returns a git repository object initialized for usage.\n     \"\"\"\n@@ -45,7 +61,7 @@ def get_repo(alias, url):\n     repo.get_head()\n \n     hasher = _digest()\n-    hasher.update(repo.path.encode('hex'))\n+    hasher.update(encode_filepath(repo.path))\n     repo.hash = hasher.hexdigest()\n \n     repo.get_base_path = lambda base: os.path.join(\n-- \n1.8.1.1.550.g40037fd\n"},{"id":"207998","messageId":"20130127224208.GV7498@serenity.lan","threadId":"32676","inReplyTo":"7v622iuzea.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] git-remote-testpy: fix patch hashing on Python 3","fromName":"John Keeping","fromEmail":"john@keeping.me.uk","sentAt":"2013-01-27T22:42:08Z","receivedAt":"2013-01-27T22:42:08Z","isPatch":true,"sender":{"key":"john@keeping.me.uk","avatar":"https://avatars.githubusercontent.com/u/1702081?v=4"},"body":"On Sun, Jan 27, 2013 at 12:47:09PM -0800, Junio C Hamano wrote:\n> I remember that I earlier asked somewhere if we want to say \"Python\n> 3.x that is older than 3.y is unsupported\"\n> \n>     http://thread.gmane.org/gmane.comp.version-control.git/213920/focus=213926\n> \n> but I was told that we will support all versions in 3.x series, IIRC.\n> \n> Does this patch contradict with that?  If so I think we would need\n> to revisit the update to CodingGuidelines in that thread.\n\nYes.  I'll send an update to that over the next couple of days.\n\nI think 3.1 and later is fine, when I said \"Python 3.0 is unsupported\"\nin the commit message below, I meant \"unsupported by the Python\ndevelopers\".  Support ended at least 3 months ago:\n\n    http://hg.python.org/peps/rev/6d2e9d41dfaa\n\n\nJohn\n"},{"id":"208003","messageId":"7vip6icj06.fsf@alter.siamese.dyndns.org","threadId":"32676","inReplyTo":"20130127224208.GV7498@serenity.lan","subject":"Re: [PATCH] git-remote-testpy: fix patch hashing on Python 3","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-01-27T23:18:33Z","receivedAt":"2013-01-27T23:18:33Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"John Keeping <john@keeping.me.uk> writes:\n\n> On Sun, Jan 27, 2013 at 12:47:09PM -0800, Junio C Hamano wrote:\n>> I remember that I earlier asked somewhere if we want to say \"Python\n>> 3.x that is older than 3.y is unsupported\"\n>> \n>>     http://thread.gmane.org/gmane.comp.version-control.git/213920/focus=213926\n>> \n>> but I was told that we will support all versions in 3.x series, IIRC.\n>> \n>> Does this patch contradict with that?  If so I think we would need\n>> to revisit the update to CodingGuidelines in that thread.\n>\n> Yes.  I'll send an update to that over the next couple of days.\n>\n> I think 3.1 and later is fine, when I said \"Python 3.0 is unsupported\"\n> in the commit message below, I meant \"unsupported by the Python\n> developers\".\n\nYeah, I knew what you meant.  I do not think it is so wrong to write\n3.0 off as an early 0.x release of Python3 that was not yet usable\nfor that exact reason.\n"},{"id":"208078","messageId":"51065692.9000708@alum.mit.edu","threadId":"32676","inReplyTo":"20130127145056.GP7498@serenity.lan","subject":"Re: [PATCH] git-remote-testpy: fix patch hashing on Python 3","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2013-01-28T10:44:34Z","receivedAt":"2013-01-28T10:44:34Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 01/27/2013 03:50 PM, John Keeping wrote:\n> When this change was originally made (0846b0c - git-remote-testpy: hash\n> bytes explicitly , I didn't realised that the \"hex\" encoding we chose is\n> a \"bytes to bytes\" encoding so it just fails with an error on Python 3\n> in the same way as the original code.\n> \n> It is not possible to provide a single code path that works on Python 2\n> and Python 3 since Python 2.x will attempt to decode the string before\n> encoding it, which fails for strings that are not valid in the default\n> encoding.  Python 3.1 introduced the \"surrogateescape\" error handler\n> which handles this correctly and permits a bytes -> unicode -> bytes\n> round-trip to be lossless.\n> \n> At this point Python 3.0 is unsupported so we don't go out of our way to\n> try to support it.\n> \n> Helped-by: Michael Haggerty <mhagger@alum.mit.edu>\n> Signed-off-by: John Keeping <john@keeping.me.uk>\n> ---\n> On Sun, Jan 27, 2013 at 02:13:29PM +0000, John Keeping wrote:\n>> On Sun, Jan 27, 2013 at 05:44:37AM +0100, Michael Haggerty wrote:\n>>> So to handle all of the cases across Python versions as closely as\n>>> possible to the old 2.x code, it might be necessary to make the code\n>>> explicitly depend on the Python version number, like:\n>>>\n>>>     hasher = _digest()\n>>>     if sys.hexversion < 0x03000000:\n>>>         pathbytes = repo.path\n>>>     elif sys.hexversion < 0x03010000:\n>>>         # If support for Python 3.0.x is desired (note: result can\n>>>         # be different in this case than under 2.x or 3.1+):\n>>>         pathbytes = repo.path.encode(sys.getfilesystemencoding(),\n>>> 'backslashreplace')\n>>>     else\n>>>         pathbytes = repo.path.encode(sys.getfilesystemencoding(),\n>>> 'surrogateescape')\n>>>     hasher.update(pathbytes)\n>>>     repo.hash = hasher.hexdigest()\n> \n> How about this?\n> \n>  git-remote-testpy.py | 18 +++++++++++++++++-\n>  1 file changed, 17 insertions(+), 1 deletion(-)\n> \n> diff --git a/git-remote-testpy.py b/git-remote-testpy.py\n> index c7a04ec..16b0c52 100644\n> --- a/git-remote-testpy.py\n> +++ b/git-remote-testpy.py\n> @@ -36,6 +36,22 @@ if sys.hexversion < 0x02000000:\n>      sys.stderr.write(\"git-remote-testgit: requires Python 2.0 or later.\\n\")\n>      sys.exit(1)\n>  \n> +\n> +def _encode_filepath(path):\n> +    \"\"\"Encodes a Unicode file path to a byte string.\n> +\n> +    On Python 2 this is a no-op; on Python 3 we encode the string as\n> +    suggested by [1] which allows an exact round-trip from the command line\n> +    to the filesystem.\n> +\n> +    [1] http://docs.python.org/3/c-api/unicode.html#file-system-encoding\n> +\n> +    \"\"\"\n> +    if sys.hexversion < 0x03000000:\n> +        return path\n> +    return path.encode('utf-8', 'surrogateescape')\n> +\n> +\n>  def get_repo(alias, url):\n>      \"\"\"Returns a git repository object initialized for usage.\n>      \"\"\"\n> @@ -45,7 +61,7 @@ def get_repo(alias, url):\n>      repo.get_head()\n>  \n>      hasher = _digest()\n> -    hasher.update(repo.path.encode('hex'))\n> +    hasher.update(_encode_filepath(repo.path))\n>      repo.hash = hasher.hexdigest()\n>  \n>      repo.get_base_path = lambda base: os.path.join(\n> \n\nNAK.  It is still not right.  If the locale is not utf-8 based, then it\nis incorrect to re-encode the string using utf-8.  I think you really\nhave to use sys.getfilesystemencoding() as I suggested.\n\nThe attached program demonstrates the problem: the output of re-encoding\nusing UTF-8 depends on the locale, whereas that of re-encoding using the\nfilesystemencoding is independent of locale (as we want).  The output,\nusing Python 3.2.3:\n\n# This is 0xb6 0xc3:\n$ ARG=\"ö\"\n$ LANG='C' /usr/bin/python3 chaos3.py \"$ARG\"\nLANG = 'C'\nfse = 'ascii'\nsys.argv[1] = u\"U+DCC3 U+DCB6\"\nre-encoded using UTF-8: b\"C3 B6\"\nre-encoded using fse: b\"C3 B6\"\n\n$ LANG='C.UTF-8' /usr/bin/python3 chaos3.py \"$ARG\"\nLANG = 'C.UTF-8'\nfse = 'utf-8'\nsys.argv[1] = u\"U+00F6\"\nre-encoded using UTF-8: b\"C3 B6\"\nre-encoded using fse: b\"C3 B6\"\n\n$ LANG='en_US.iso88591' /usr/bin/python3 chaos3.py \"$ARG\"\nLANG = 'en_US.iso88591'\nfse = 'iso8859-1'\nsys.argv[1] = u\"U+00C3 U+00B6\"\nre-encoded using UTF-8: b\"C3 83 C2 B6\"\nre-encoded using fse: b\"C3 B6\"\n\nEven though the Unicode intermediate representation is different for\nUTF-8 and ASCII, re-encoding using the correct encoding gives back the\noriginal bytes (which is what we want).  But when using the ios8859-1\nlocale, the original bytes look like a valid latin1 string so they are\nnot surrogated going in, giving the incorrect Unicode string u\"U+00C3\nU+00B6\".  When this is re-encoded using UTF-8, the code points U+00C3\nand U+00B6 are each encoded as two bytes.\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n\n\n#! /usr/bin/python3\n\nimport sys\nimport os\n\n\ndef explicit(s):\n    \"\"\"Convert a string or bytestring into an unambiguous human-readable string.\"\"\"\n\n    if isinstance(s, str):\n        return 'u\"%s\"' % (' '.join('U+%04X' % (ord(c),) for c in s))\n    else:\n        return 'b\"%s\"' % (' '.join('%02X' % (c,) for c in s))\n\n\nfse = sys.getfilesystemencoding()\n\nprint('LANG = %r' % (os.getenv('LANG'),))\nprint('fse = %r' % (fse,))\nprint('sys.argv[1] = %s' % explicit(sys.argv[1]))\nprint('re-encoded using UTF-8: %s' % explicit(sys.argv[1].encode('utf-8', 'surrogateescape')))\nprint('re-encoded using fse: %s' % explicit(sys.argv[1].encode(fse, 'surrogateescape')))\nprint()\n\n\n"},{"id":"208084","messageId":"20130128112043.GZ7498@serenity.lan","threadId":"32676","inReplyTo":"51065692.9000708@alum.mit.edu","subject":"[PATCH] fixup! git-remote-testpy: fix path hashing on Python 3","fromName":"John Keeping","fromEmail":"john@keeping.me.uk","sentAt":"2013-01-28T11:20:43Z","receivedAt":"2013-01-28T11:20:43Z","isPatch":true,"sender":{"key":"john@keeping.me.uk","avatar":"https://avatars.githubusercontent.com/u/1702081?v=4"},"body":"---\nOn Mon, Jan 28, 2013 at 11:44:34AM +0100, Michael Haggerty wrote:\n> NAK.  It is still not right.  If the locale is not utf-8 based, then it\n> is incorrect to re-encode the string using utf-8.  I think you really\n> have to use sys.getfilesystemencoding() as I suggested.\n\nIf you'd asked me what the patch contained I would have said it did use\ngetfilesystemencoding(), but I can't disbelieve my own eyes :-(\n\nJunio, please can you squash this in?\n\n git-remote-testpy.py | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/git-remote-testpy.py b/git-remote-testpy.py\nindex 6098bdd..ca67899 100644\n--- a/git-remote-testpy.py\n+++ b/git-remote-testpy.py\n@@ -49,7 +49,7 @@ def encode_filepath(path):\n     \"\"\"\n     if sys.hexversion < 0x03000000:\n         return path\n-    return path.encode('utf-8', 'surrogateescape')\n+    return path.encode(sys.getfilesystemencoding(), 'surrogateescape')\n \n \n def get_repo(alias, url):\n-- \n1.8.1.1\n"},{"id":"208094","messageId":"7v8v7dxkgl.fsf@alter.siamese.dyndns.org","threadId":"32676","inReplyTo":"20130128112043.GZ7498@serenity.lan","subject":"Re: [PATCH] fixup! git-remote-testpy: fix path hashing on Python 3","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-01-28T17:53:46Z","receivedAt":"2013-01-28T17:53:46Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"John Keeping <john@keeping.me.uk> writes:\n\n> ---\n> On Mon, Jan 28, 2013 at 11:44:34AM +0100, Michael Haggerty wrote:\n>> NAK.  It is still not right.  If the locale is not utf-8 based, then it\n>> is incorrect to re-encode the string using utf-8.  I think you really\n>> have to use sys.getfilesystemencoding() as I suggested.\n>\n> If you'd asked me what the patch contained I would have said it did use\n> getfilesystemencoding(), but I can't disbelieve my own eyes :-(\n>\n> Junio, please can you squash this in?\n\nSure.  Thanks for double-checking, Michael.  I knew there was\nsomething missing but I didn't spot the difference myself.\n\n>  git-remote-testpy.py | 2 +-\n>  1 file changed, 1 insertion(+), 1 deletion(-)\n>\n> diff --git a/git-remote-testpy.py b/git-remote-testpy.py\n> index 6098bdd..ca67899 100644\n> --- a/git-remote-testpy.py\n> +++ b/git-remote-testpy.py\n> @@ -49,7 +49,7 @@ def encode_filepath(path):\n>      \"\"\"\n>      if sys.hexversion < 0x03000000:\n>          return path\n> -    return path.encode('utf-8', 'surrogateescape')\n> +    return path.encode(sys.getfilesystemencoding(), 'surrogateescape')\n>  \n>  \n>  def get_repo(alias, url):\n"},{"id":"208736","messageId":"CABPQNSbF8XTp8Biij6KPorq3-tSjLCbroU+G6skKWnngHRt8nQ@mail.gmail.com","threadId":"32676","inReplyTo":"CA+sFfMf2R6+qzrLR9rwhtcM=ABZ8aWUJw-3riF98B3XWVGm54w@mail.gmail.com","subject":"Re: [PATCH v3 2/8] git_remote_helpers: fix input when running under Python 3","fromName":"Erik Faye-Lund","fromEmail":"kusmabite@gmail.com","sentAt":"2013-02-05T16:07:06Z","receivedAt":"2013-02-05T16:07:06Z","isPatch":true,"sender":{"key":"kusmabite@gmail.com","avatar":"https://avatars.githubusercontent.com/u/47073?v=4"},"body":"On Fri, Jan 25, 2013 at 9:23 PM, Brandon Casey <drafnel@gmail.com> wrote:\n> On Wed, Jan 23, 2013 at 12:36 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>> Sverre Rabbelier <srabbelier@gmail.com> writes:\n>>\n>>> On Wed, Jan 23, 2013 at 11:47 AM, John Keeping <john@keeping.me.uk> wrote:\n>>>>> When did we last revisit what minimal python version we are ok with requiring?\n>>>>\n>>>> I was wondering if people would weigh in discussing that in response to\n>>>> [1] but no one has commented on that part of it.  As another datapoint,\n>>>> Brandon Casey was suggesting patching git-p4.py to support Python 2.4\n>>>> [2].\n>>>>\n>>>> [1] http://article.gmane.org/gmane.comp.version-control.git/213920\n>>>> [2] http://article.gmane.org/gmane.comp.version-control.git/214048\n>>>\n>>> I for one would be happy to kill off support for anything older than\n>>> 2.6 (which had it's latest release on October 1st, 2008).\n>>>\n>>> Junio, how have we decided in the past which version of x to support?\n>>\n>> I do not think there was any conclusion.  $gmane/212215 claiming 2.4\n>> support matters for RHEL 5.x users was the last on the topic as far\n>> as I can tell, so it boils down to another question: do users on\n>> RHEL 5.x matter?\n>>\n>> I can read from $gmane/212215 that users of the said platform can\n>> safely keep using Python 2.4 under their vendor support contract\n>> until 2017.  But let's focus on what do these users expect of their\n>> system and software they run on it a bit.\n>>\n>> When they want to run a piece software that is not shipped with\n>> RHEL, either by writing their own or by importing from elsewhere,\n>> that needs 2.6 features, what are their options?\n>>\n>>  (a) The platform vendor optionally supplies 2.6 with or without\n>>      support;\n>>\n>>  (b) The users can and do install 2.6 as /usr/local/bin/python2.6,\n>>      which may even be community-supported, but the vendor does not\n>>      support it; or\n>>\n>>  (c) The vendor terminates the support contract for users who choose\n>>      to go (b).\n>>\n>> I think we can safely discard (c); if that is the case, the users on\n>> the said platform will not choose to update Git either, so it does\n>> not matter where the future versions of Git sets the lower bound of\n>> Python version at.\n>>\n>> If we are not talking about the situation (c), then the users can\n>> choose to use 2.6, and more importantly, Python being a popular\n>> software, I would imagine that there are reputable sources of\n>> prepackaged RPMs for them to do so without going too much hassle of\n>> configuring, compiling and installing.\n>>\n>> Now how does the decision we make today for releases of Git that\n>> haven't yet happened will affect these users?  As these versions of\n>> newer Git were not shipped with RHEL 5.x, and also I am assuming\n>> that Git is a more niche product than Python is, I would imagine\n>> that it is very unlikely that the vendor gives it the users as an\n>> optional package.  The users will have to do the same thing to be\n>> able to use such versions of Git as whatever they do in order to use\n>> Python 2.6.\n>>\n>> Given that, what the vendor originally shipped and officially\n>> supports does not affect the choices we would make today for newer\n>> versions of Git.  The users in a shop where additional third-party\n>> software in /usr/local/bin is strictly forbidden, they are stuck\n>> with the version of Git that the vendor shipped anyway, because they\n>> won't be able to install an updated Git in /usr/local/bin, either.\n>>\n>> That is, unless installing 2.6 as /usr/local/bin/python2.6 (or if\n>> you are really paranoid, /usr/local/only-for-git/bin/python2.6 where\n>> nobody's $PATH points at) is impossible.\n>>\n>> So personally I do not think dropping 2.4 is a huge problem for\n>> future versions of Git, but I'd like to hear from those working in\n>> IT support for large and slow-moving organizations (aka RHEL 5\n>> customers).\n>\n> I'm not really in the demographic that you asked to hear from, but\n> I'll give my 2 cents anyway. :)\n>\n> Firstly, I defer to those with more knowledge and experience with\n> python to decide which version should be the minimum version\n> supported.  Python 2.6 seems to be the consensus and that's fine with\n> me.\n>\n> With respect to older platforms like RHEL 5.X that don't ship with\n> Python 2.6 or later, I suspect most people who work in an organization\n> with a dedicated IT staff can request that a more recent version of\n> python be installed.  So, I don't think a python 2.6 requirement (if\n> there was one) would be a blocker for them, and I don't think it would\n> be a major pain for the sysadmin to install.\n>\n\nJust a datapoint: I'm working with customers on RHEL 5.X that\nunfortunately has an extremely lengthy (>3 months) process of\napproving non-standard packages for install. Yeah, it's horrible, but\nsome times that's reality.\n\nWe are currently not using Git with that client, but we are in the\nprocess of changing that. Said customer already have an exception for\nall versions of Git.\n\nI doubt this will end up being a problem in reality or not, but if it\nwill be, I'm sure it can be worked around out. I'm just pointing out\nthat the above suspicion might not be accurate.\n"}]}