[PATCH 1 of 3] py3: add "b" prefix to string literals related to module policy

FUJIWARA Katsunori foozy at lares.dti.ne.jp
Sun Mar 12 06:47:58 UTC 2017


# HG changeset patch
# User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
# Date 1489300798 -32400
#      Sun Mar 12 15:39:58 2017 +0900
# Node ID 0f3cdc6061dc630d154c3fa45dfc8257d8ed9d09
# Parent  62939e0148f170b67ca8c7374f36c413b67fd387
py3: add "b" prefix to string literals related to module policy

String literals without explicit prefix in __init__.py and policy.py
are treated as unicode object on Python3, because these modules are
loaded before setup of ower specific code transformation (the later
module is imported at the beginning of __init__.py).

This causes issues below;

  - checking "policy" value in other modules causes unintentional result

    For example, "b'py' not in (u'c', u'py')" returns True
    unintentionaly on Python3.

  - writing "policy" out fails at conversion from unicode to bytes

    62939e0148f1, which fixed this issue, is partially backed out, for
    simplicity described below.

This patch adds "b" prefix to string literals, which are related to
module policy, in modules above.

Value of "policy" is fixed only after checking HGMODULEPOLICY
environment variable. But checking "supports_bytes_environ", switching
os.environ/os.environb, and so on (for portability between Python2 and
Python3) seem redundant in this case.

Therefore, for simplicity, this patch does:

  - not add "b" prefix to string literals below, which are used to be
    assigned into "policy", even though these are policy related string

    - 'c' in policy.py, initial value
    - modulepolicy in __modulepolicy__.py, which is generated by setup.py
    - 'cffi' in policy.py, for pypy

  - convert "policy" into bytes at the end of policy.py

BTW, "modulepolicy" in __init__ is initialized by "policy.policy".

diff --git a/mercurial/__init__.py b/mercurial/__init__.py
--- a/mercurial/__init__.py
+++ b/mercurial/__init__.py
@@ -68,7 +68,7 @@ class hgimporter(object):
                 # indicates the type of module. So just assume what we found
                 # is OK (even though it could be a pure Python module).
             except ImportError:
-                if modulepolicy == 'c':
+                if modulepolicy == b'c':
                     raise
                 zl = ziploader('mercurial', 'pure')
                 mod = zl.load_module(name)
@@ -106,7 +106,7 @@ class hgimporter(object):
                                   'version should exist' % name)
 
         except ImportError:
-            if modulepolicy == 'c':
+            if modulepolicy == b'c':
                 raise
 
             # Could not load the C extension and pure Python is allowed. So
diff --git a/mercurial/policy.py b/mercurial/policy.py
--- a/mercurial/policy.py
+++ b/mercurial/policy.py
@@ -20,8 +20,8 @@ import sys
 #
 # By default, require the C extensions for performance reasons.
 policy = 'c'
-policynoc = ('cffi', 'cffi-allow', 'py')
-policynocffi = ('c', 'py')
+policynoc = (b'cffi', b'cffi-allow', b'py')
+policynocffi = (b'c', b'py')
 
 try:
     from . import __modulepolicy__
@@ -39,7 +39,11 @@ if '__pypy__' in sys.builtin_module_name
 # Our C extensions aren't yet compatible with Python 3. So use pure Python
 # on Python 3 for now.
 if sys.version_info[0] >= 3:
-    policy = b'py'
+    policy = 'py'
 
 # Environment variable can always force settings.
 policy = os.environ.get('HGMODULEPOLICY', policy)
+
+if sys.version_info[0] >= 3:
+    # at this point, "policy" is still unicode
+    policy = policy.encode('utf-8')


More information about the Mercurial-devel mailing list