Author: Ronan Lamy <ronan.l...@gmail.com>
Branch: py3tests
Changeset: r94059:47c8f77a9d6f
Date: 2018-03-21 23:08 +0100
http://bitbucket.org/pypy/pypy/changeset/47c8f77a9d6f/

Log:    Move app-level AST rewriting to some unimportable location and
        remove more imports

diff --git a/pypy/tool/pytest/app_rewrite.py b/pypy/tool/pytest/app_rewrite.py
new file mode 100644
--- /dev/null
+++ b/pypy/tool/pytest/app_rewrite.py
@@ -0,0 +1,39 @@
+import re
+
+ASCII_IS_DEFAULT_ENCODING = False
+
+cookie_re = re.compile(r"^[ \t\f]*#.*coding[:=][ \t]*[-\w.]+")
+BOM_UTF8 = '\xef\xbb\xbf'
+
+def _prepare_source(fn):
+    """Read the source code for re-writing."""
+    try:
+        stat = fn.stat()
+        source = fn.read("rb")
+    except EnvironmentError:
+        return None, None
+    if ASCII_IS_DEFAULT_ENCODING:
+        # ASCII is the default encoding in Python 2. Without a coding
+        # declaration, Python 2 will complain about any bytes in the file
+        # outside the ASCII range. Sadly, this behavior does not extend to
+        # compile() or ast.parse(), which prefer to interpret the bytes as
+        # latin-1. (At least they properly handle explicit coding cookies.) To
+        # preserve this error behavior, we could force ast.parse() to use ASCII
+        # as the encoding by inserting a coding cookie. Unfortunately, that
+        # messes up line numbers. Thus, we have to check ourselves if anything
+        # is outside the ASCII range in the case no encoding is explicitly
+        # declared. For more context, see issue #269. Yay for Python 3 which
+        # gets this right.
+        end1 = source.find("\n")
+        end2 = source.find("\n", end1 + 1)
+        if (not source.startswith(BOM_UTF8) and
+            cookie_re.match(source[0:end1]) is None and
+            cookie_re.match(source[end1 + 1:end2]) is None):
+            try:
+                source.decode("ascii")
+            except UnicodeDecodeError:
+                # Let it fail in real import.
+                return None, None
+    # On Python versions which are not 2.7 and less than or equal to 3.1, the
+    # parser expects *nix newlines.
+    return stat, source
diff --git a/pypy/tool/pytest/apptest2.py b/pypy/tool/pytest/apptest2.py
--- a/pypy/tool/pytest/apptest2.py
+++ b/pypy/tool/pytest/apptest2.py
@@ -4,7 +4,7 @@
 import pytest
 from pypy import pypydir
 import pypy.interpreter.function
-import pypy.tool.pytest.rewrite
+from pypy.tool.pytest import app_rewrite
 from pypy.interpreter.error import OperationError
 from pypy.tool.pytest import objspace
 from pypy.tool.pytest import appsupport
@@ -13,19 +13,20 @@
 class AppTestModule(pytest.Module):
 
     def collect(self):
-        _, source = pypy.tool.pytest.rewrite._prepare_source(self.fspath)
+        _, source = app_rewrite._prepare_source(self.fspath)
         space = objspace.gettestobjspace()
-        w_rootdir = space.newtext(os.path.dirname(pypydir))
+        w_rootdir = space.newtext(
+            os.path.join(pypydir, 'tool', 'pytest', 'ast-rewriter'))
         w_source = space.newtext(source)
         w_fname = space.newtext(str(self.fspath))
         w_mod = space.appexec([w_rootdir, w_source, w_fname],
                               """(rootdir, source, fname):
         import sys
         sys.path.insert(0, rootdir)
-        from pypy.tool.pytest import rewrite
+        from ast_rewrite import rewrite_asserts, create_module
 
-        co = rewrite.rewrite_asserts(source, fname)
-        mod = rewrite.create_module(fname, co)
+        co = rewrite_asserts(source, fname)
+        mod = create_module(fname, co)
         return mod
         """)
         mod_dict = w_mod.getdict(space).unwrap(space)
diff --git a/pypy/tool/pytest/rewrite.py 
b/pypy/tool/pytest/ast-rewriter/ast_rewrite.py
rename from pypy/tool/pytest/rewrite.py
rename to pypy/tool/pytest/ast-rewriter/ast_rewrite.py
--- a/pypy/tool/pytest/rewrite.py
+++ b/pypy/tool/pytest/ast-rewriter/ast_rewrite.py
@@ -2,35 +2,19 @@
 from __future__ import absolute_import, division, print_function
 import ast
 import itertools
-import imp
 import marshal
-import os
-import re
 import struct
 import sys
-import types
 
-from . import util
+from ast_util import assertrepr_compare, format_explanation as 
_format_explanation
 
 
 # pytest caches rewritten pycs in __pycache__.
-if hasattr(imp, "get_tag"):
-    PYTEST_TAG = imp.get_tag() + "-PYTEST"
-else:
-    if hasattr(sys, "pypy_version_info"):
-        impl = "pypy"
-    elif sys.platform == "java":
-        impl = "jython"
-    else:
-        impl = "cpython"
-    ver = sys.version_info
-    PYTEST_TAG = "%s-%s%s-PYTEST" % (impl, ver[0], ver[1])
-    del ver, impl
+PYTEST_TAG = sys.implementation.cache_tag + "-PYTEST"
 
 PYC_EXT = ".py" + (__debug__ and "c" or "o")
 PYC_TAIL = "." + PYTEST_TAG + PYC_EXT
 
-ASCII_IS_DEFAULT_ENCODING = sys.version_info[0] < 3
 
 if sys.version_info >= (3, 5):
     ast_Call = ast.Call
@@ -65,60 +49,6 @@
     return True
 
 
-RN = "\r\n".encode("utf-8")
-N = "\n".encode("utf-8")
-
-cookie_re = re.compile(r"^[ \t\f]*#.*coding[:=][ \t]*[-\w.]+")
-BOM_UTF8 = '\xef\xbb\xbf'
-
-
-def _prepare_source(fn):
-    """Read the source code for re-writing."""
-    try:
-        stat = fn.stat()
-        source = fn.read("rb")
-    except EnvironmentError:
-        return None, None
-    if ASCII_IS_DEFAULT_ENCODING:
-        # ASCII is the default encoding in Python 2. Without a coding
-        # declaration, Python 2 will complain about any bytes in the file
-        # outside the ASCII range. Sadly, this behavior does not extend to
-        # compile() or ast.parse(), which prefer to interpret the bytes as
-        # latin-1. (At least they properly handle explicit coding cookies.) To
-        # preserve this error behavior, we could force ast.parse() to use ASCII
-        # as the encoding by inserting a coding cookie. Unfortunately, that
-        # messes up line numbers. Thus, we have to check ourselves if anything
-        # is outside the ASCII range in the case no encoding is explicitly
-        # declared. For more context, see issue #269. Yay for Python 3 which
-        # gets this right.
-        end1 = source.find("\n")
-        end2 = source.find("\n", end1 + 1)
-        if (not source.startswith(BOM_UTF8) and
-            cookie_re.match(source[0:end1]) is None and
-            cookie_re.match(source[end1 + 1:end2]) is None):
-            try:
-                source.decode("ascii")
-            except UnicodeDecodeError:
-                # Let it fail in real import.
-                return None, None
-    # On Python versions which are not 2.7 and less than or equal to 3.1, the
-    # parser expects *nix newlines.
-    return stat, source
-
-
-def _rewrite_test(config, fn):
-    """Try to read and rewrite *fn* and return the code object."""
-    state = config._assertstate
-    stat, source = _prepare_source(fn)
-    try:
-        co = rewrite_asserts(source, fn.strpath)
-    except SyntaxError:
-        # Let this pop up again in the real import.
-        state.trace("failed to parse/compile: %r" % (fn,))
-        return None, None
-    return stat, co
-
-
 def rewrite_asserts(source, filename):
     """Parse the source code and rewrite asserts statements
 
@@ -132,7 +62,7 @@
 
 def create_module(filename, co, pyc=None):
     """Create a module from a code object created by rewrite_asserts()"""
-    mod = imp.new_module(filename)
+    mod = type(sys)(filename)
     mod.__file__ = co.co_filename
     if pyc is not None:
         mod.__cached__ = pyc
@@ -143,6 +73,7 @@
 
 def _make_rewritten_pyc(state, source_stat, pyc, co):
     """Try to dump rewritten code to *pyc*."""
+    import os
     if sys.platform.startswith("win"):
         # Windows grants exclusive access to open files and doesn't have atomic
         # rename, so just write into the final file.
@@ -202,9 +133,6 @@
     return repr(obj).replace('\n', '\\n')
 
 
-from .util import format_explanation as _format_explanation  # noqa
-
-
 def _format_assertmsg(obj):
     """Format the custom assertion message given.
 
@@ -233,7 +161,7 @@
             done = True
         if done:
             break
-    custom = util.assertrepr_compare(ops[i], each_obj[i], each_obj[i + 1])
+    custom = assertrepr_compare(ops[i], each_obj[i], each_obj[i + 1])
     if custom is not None:
         return custom
     return expl
@@ -365,7 +293,7 @@
         else:
             builtin_name = '__builtin__'
         aliases = [ast.alias(builtin_name, "@py_builtins"),
-                   ast.alias("pypy.tool.pytest.rewrite", "@pytest_ar")]
+                   ast.alias("ast_rewrite", "@pytest_ar")]
         doc = getattr(mod, "docstring", None)
         expect_docstring = doc is None
         if doc is not None and self.is_rewrite_disabled(doc):
diff --git a/pypy/tool/pytest/util.py 
b/pypy/tool/pytest/ast-rewriter/ast_util.py
rename from pypy/tool/pytest/util.py
rename to pypy/tool/pytest/ast-rewriter/ast_util.py
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to