示例#1
0
def test_PythonStatement_flags_1():
    block = PythonBlock("from __future__ import unicode_literals\nx\n",
                        flags="division")
    s0, s1 = block.statements
    assert s0.block.source_flags == CompilerFlags("unicode_literals")
    assert s1.block.source_flags == CompilerFlags(0)
    assert s0.block.flags == CompilerFlags("unicode_literals", "division")
    assert s1.block.flags == CompilerFlags("unicode_literals", "division")
示例#2
0
 def flags(self):
     """
     If this is a __future__ import, then the compiler_flag associated with
     it.  Otherwise, 0.
     """
     if self.split.module_name == "__future__":
         return CompilerFlags(self.split.member_name)
     else:
         return CompilerFlags(0)
示例#3
0
def test_PythonBlock_flags_type_comment_1():
    block = PythonBlock(dedent('''
    a = 1 # type: int
    ''').lstrip())
    if sys.version_info >= (3, 8):
        # Includes the type_comments flag
        assert block.flags == CompilerFlags(0x01000)
    else:
        assert block.flags == CompilerFlags(0x0000)
示例#4
0
def test_PythonStatement_auto_flags_1():
    block = PythonBlock(
        "from __future__ import unicode_literals\nprint(1,file=x)\n",
        flags="division",
        auto_flags=True)
    s0, s1 = block.statements
    assert s0.block.source_flags == CompilerFlags("unicode_literals")
    assert s1.block.source_flags == CompilerFlags(0)
    expected = CompilerFlags("unicode_literals", "division", "print_function")
    assert s0.block.flags == expected
    assert s1.block.flags == expected
示例#5
0
def _parse_ast_nodes(text, flags, auto_flags, mode):
    """
    Parse a block of lines into an AST.

    Also annotate ``input_flags``, ``source_flags``, and ``flags`` on the
    resulting ast node.

    :type text:
      ``FileText``
    :type flags:
      ``CompilerFlags``
    :type auto_flags:
      ``bool``
    :param auto_flags:
      Whether to guess different flags if ``text`` can't be parsed with
      ``flags``.
    :param mode:
      Compilation mode: "exec", "single", or "eval".
    :rtype:
      ``ast.Module``
    """
    text = FileText(text)
    flags = CompilerFlags(flags)
    filename = str(text.filename) if text.filename else "<unknown>"
    source = text.joined
    source = dedent(source)
    if PY2 and isinstance(source, unicode):
        source = source.encode('utf-8')
    if not source.endswith("\n"):
        # Ensure that the last line ends with a newline (``ast`` barfs
        # otherwise).
        source += "\n"
    exp = None
    for flags in _flags_to_try(source, flags, auto_flags, mode):
        cflags = ast.PyCF_ONLY_AST | int(flags)
        try:
            result = compile(source,
                             filename,
                             mode,
                             flags=cflags,
                             dont_inherit=1)
        except SyntaxError as e:
            exp = e
            pass
        else:
            # Attach flags to the result.
            result.input_flags = flags
            result.source_flags = CompilerFlags.from_ast(result)
            result.flags = result.input_flags | result.source_flags
            result.text = text
            return result
    raise exp  # SyntaxError
示例#6
0
def test_PythonBlock_flags_type_comment_1():
    block = PythonBlock(dedent("""
    a = 1 # type: int
    """).lstrip())
    if sys.version_info >= (3, 8):
        # Includes the type_comments flag
        with warnings.catch_warnings():
            warnings.simplefilter("ignore", DeprecationWarning)
            assert block.flags == CompilerFlags(0x01000)
    else:
        with warnings.catch_warnings():
            warnings.simplefilter("ignore", DeprecationWarning)
            assert block.flags == CompilerFlags(0x0000)
示例#7
0
def _parse_ast_nodes(text, flags, auto_flags, mode):
    """
    Parse a block of lines into an AST.

    Also annotate C{input_flags}, C{source_flags}, and C{flags} on the
    resulting ast node.

    @type text:
      C{FileText}
    @type flags:
      C{CompilerFlags}
    @type auto_flags:
      C{bool}
    @param auto_flags:
      Whether to guess different flags if C{text} can't be parsed with
      C{flags}.
    @param mode:
      Compilation mode: "exec", "single", or "eval".
    @rtype:
      C{ast.Module}
    """
    text = FileText(text)
    flags = CompilerFlags(flags)
    filename = str(text.filename) if text.filename else "<unknown>"
    source = text.joined
    source = dedent(source)
    if not source.endswith("\n"):
        # Ensure that the last line ends with a newline (C{ast} barfs
        # otherwise).
        source += "\n"
    exp = None
    for flags in _flags_to_try(source, flags, auto_flags, mode):
        cflags = ast.PyCF_ONLY_AST | int(flags)
        try:
            result = compile(source,
                             filename,
                             mode,
                             flags=cflags,
                             dont_inherit=1)
        except SyntaxError as e:
            exp = e
            pass
        else:
            # Attach flags to the result.
            result.input_flags = flags
            result.source_flags = CompilerFlags.from_ast(result)
            result.flags = result.input_flags | result.source_flags
            result.text = text
            return result
    raise exp  # SyntaxError
示例#8
0
def test_PythonBlock_flags_deduce_1():
    block = PythonBlock(dedent('''
        from __future__ import print_function
        print("x",
              file=None)
    ''').lstrip())
    assert block.flags == CompilerFlags(0x10000)
示例#9
0
 def from_text(cls,
               text,
               filename=None,
               startpos=None,
               flags=None,
               auto_flags=False):
     """
     :type text:
       `FileText` or convertible
     :type filename:
       ``Filename``
     :param filename:
       Filename, if not already given by ``text``.
     :type startpos:
       ``FilePos``
     :param startpos:
       Starting position, if not already given by ``text``.
     :type flags:
       ``CompilerFlags``
     :param flags:
       Input compiler flags.
     :param auto_flags:
       Whether to try other flags if ``flags`` fails.
     :rtype:
       `PythonBlock`
     """
     text = FileText(text, filename=filename, startpos=startpos)
     self = object.__new__(cls)
     self.text = text
     self._input_flags = CompilerFlags(flags)
     self._auto_flags = auto_flags
     return self
示例#10
0
 def __new__(cls,
             arg,
             filename=None,
             startpos=None,
             flags=None,
             auto_flags=None):
     if isinstance(arg, PythonStatement):
         arg = arg.block
         # Fall through
     if isinstance(arg, cls):
         if filename is startpos is flags is None:
             return arg
         flags = CompilerFlags(flags, arg.flags)
         arg = arg.text
         # Fall through
     if isinstance(arg, (FileText, Filename, str, six.text_type)):
         return cls.from_text(arg,
                              filename=filename,
                              startpos=startpos,
                              flags=flags,
                              auto_flags=auto_flags)
     raise TypeError("%s: unexpected %s" % (
         cls.__name__,
         type(arg).__name__,
     ))
示例#11
0
 def from_text(cls,
               text,
               filename=None,
               startpos=None,
               flags=None,
               auto_flags=False):
     """
     @type text:
       L{FileText} or convertible
     @type filename:
       C{Filename}
     @param filename:
       Filename, if not already given by C{text}.
     @type startpos:
       C{FilePos}
     @param startpos:
       Starting position, if not already given by C{text}.
     @type flags:
       C{CompilerFlags}
     @param flags:
       Input compiler flags.
     @param auto_flags:
       Whether to try other flags if C{flags} fails.
     @rtype:
       L{PythonBlock}
     """
     text = FileText(text, filename=filename, startpos=startpos)
     self = object.__new__(cls)
     self.text = text
     self._input_flags = CompilerFlags(flags)
     self._auto_flags = auto_flags
     return self
示例#12
0
def test_PythonStatement_auto_flags_1():
    block = PythonBlock(
        "from __future__ import unicode_literals\nprint(1,file=x)\n",
        flags="division", auto_flags=True)
    s0, s1 = block.statements
    assert s0.block.source_flags == CompilerFlags("unicode_literals")
    with warnings.catch_warnings():
        warnings.simplefilter("ignore", DeprecationWarning)
        assert s1.block.source_flags == CompilerFlags(0)
    if PY2:
        expected = CompilerFlags("unicode_literals", "division",
                                 "print_function")
    else:
        expected = CompilerFlags("unicode_literals", "division")
    assert s0.block.flags        == expected
    assert s1.block.flags        == expected
示例#13
0
 def flags(self):
     """
     If this contains __future__ imports, then the bitwise-ORed of the
     compiler_flag values associated with the features.  Otherwise, 0.
     """
     imports = self._by_module_name[0].get("__future__", [])
     return CompilerFlags(*[imp.flags for imp in imports])
示例#14
0
def test_CompilerFlags_eqne_1():
    with warnings.catch_warnings():
        warnings.simplefilter("ignore", DeprecationWarning)
        assert CompilerFlags(0x18000) == CompilerFlags(0x18000)
        assert not (CompilerFlags(0x18000) != CompilerFlags(0x18000))
        assert CompilerFlags(0x18000) != CompilerFlags.type_comments
        assert not (CompilerFlags(0x18000) == CompilerFlags(0x10000))
示例#15
0
def test_CompilerFlags_compile_1():
    # Should raise SyntaxError:
    with pytest.raises(SyntaxError):
        compile("print('x', file=None)", "?", "exec", flags=0, dont_inherit=1)
    # Shouldn't raise SyntaxError:
    compile("print('x', file=None)",
            "?",
            "exec",
            flags=CompilerFlags("print_function"),
            dont_inherit=1)
示例#16
0
def _flags_to_try(source, flags, auto_flags, mode):
    """
    Flags to try for ``auto_flags``.

    If ``auto_flags`` is False, then only yield ``flags``.
    If ``auto_flags`` is True, then yield ``flags`` and ``flags ^ print_function``.
    """
    flags = CompilerFlags(flags)
    if not auto_flags:
        yield flags
        return
    if PY3:
        yield flags
        return
    if mode == "eval":
        if re.search(r"\bprint\b", source):
            flags = flags | CompilerFlags("print_function")
        yield flags
        return
    yield flags
    if re.search(r"\bprint\b", source):
        yield flags ^ CompilerFlags("print_function")
示例#17
0
def _flags_to_try(source, flags, auto_flags, mode):
    """
    Flags to try for C{auto_flags}.

    If C{auto_flags} is False, then only yield C{flags}.
    If C{auto_flags} is True, then yield C{flags} and C{flags ^ print_function}.
    """
    flags = CompilerFlags(flags)
    if not auto_flags:
        yield flags
        return
    if sys.version_info[0] != 2:
        yield flags
        return
    if mode == "eval":
        if re.search(r"\bprint\b", source):
            flags = flags | CompilerFlags("print_function")
        yield flags
        return
    yield flags
    if re.search(r"\bprint\b", source):
        yield flags ^ CompilerFlags("print_function")
示例#18
0
def ImportPathForRelativeImportsCtx(codeblock):
    """
    Context manager that temporarily modifies C{sys.path} so that relative
    imports for the given C{codeblock} work as expected.

    @type codeblock:
      L{PythonBlock}
    """
    codeblock = PythonBlock(codeblock)
    if not codeblock.filename:
        return NullCtx()
    if codeblock.flags & CompilerFlags("absolute_import"):
        return NullCtx()
    return ImportPathCtx(str(codeblock.filename.dir))
示例#19
0
 def __construct_from_annotated_ast(cls, annotated_ast_nodes, text, flags):
     # Constructor for internal use by _split_by_statement() or
     # concatenate().
     ast_node = ast.Module(annotated_ast_nodes)
     ast_node.text = text
     ast_node.flags = flags
     if not hasattr(ast_node, "source_flags"):
         ast_node.source_flags = CompilerFlags.from_ast(annotated_ast_nodes)
     self = object.__new__(cls)
     self._ast_node_or_parse_exception = ast_node
     self.ast_node = ast_node
     self.annotated_ast_node = ast_node
     self.text = text
     self.flags = self._input_flags = flags
     self._auto_flags = False
     return self
示例#20
0
def test_PythonStatement_flags_1():
    block = PythonBlock("from __future__ import unicode_literals\nx\n",
                        flags="division")
    s0, s1 = block.statements
    assert s0.block.source_flags == CompilerFlags("unicode_literals")
    with warnings.catch_warnings():
        warnings.simplefilter("ignore", DeprecationWarning)
        assert s1.block.source_flags == CompilerFlags(0)
    if sys.version_info >= (3, 8):
        assert s0.block.flags == CompilerFlags("unicode_literals", "division",)
        assert s1.block.flags == CompilerFlags("unicode_literals", "division",)
    else:
        assert s0.block.flags == CompilerFlags("unicode_literals", "division")
        assert s1.block.flags == CompilerFlags("unicode_literals", "division")
示例#21
0
def test_PythonBlock_flags_1():
    block = PythonBlock('print("x",\n file=None)\n', flags="print_function")
    assert block.flags == CompilerFlags(0x10000)
示例#22
0
def test_CompilerFlags_from_names_single_1():
    result = CompilerFlags("with_statement")
    assert result == CompilerFlags(0x8000)
示例#23
0
def test_CompilerFlags_from_CompilerFlags_1():
    result = CompilerFlags(CompilerFlags(0x10000), CompilerFlags(0x8000))
    assert result == CompilerFlags(0x18000)
示例#24
0
def test_CompilerFlags_from_mixed_multi_1():
    result = CompilerFlags("print_function", 0x8000, CompilerFlags("division"))
    assert result == CompilerFlags(0x1a000)
示例#25
0
def test_CompilerFlags_from_names_list_1():
    result = CompilerFlags(["with_statement", "print_function"])
    assert result == CompilerFlags(0x18000)
示例#26
0
def test_CompilerFlags_from_ast_1():
    node = ast.parse("from __future__ import with_statement, print_function")
    result = CompilerFlags(node)
    assert result == CompilerFlags(0x18000)
示例#27
0
def test_CompilerFlags_bad_name_1():
    with pytest.raises(ValueError):
        CompilerFlags("print_statement")
示例#28
0
def test_CompilerFlags_bad_int_1():
    with pytest.raises(ValueError):
        CompilerFlags(1)
示例#29
0
import pytest
import sys
from   textwrap                 import dedent
import warnings

from   six                      import PY2, PY3

from   pyflyby._file            import FilePos, FileText, Filename
from   pyflyby._flags           import CompilerFlags
from   pyflyby._parse           import PythonBlock, PythonStatement
from   pyflyby._imports2s       import SourceToSourceFileImportsTransformation


if sys.version_info < (3, 8, 3):
    print_function_flag = CompilerFlags.from_int(0x10000)
else:
    print_function_flag = CompilerFlags.from_int(0x100000)


def test_PythonBlock_FileText_1():
    text = FileText(
        dedent(
            """
        foo()
        bar()
    """
        ).lstrip(),
        filename="/foo/test_PythonBlock_1.py",
        startpos=(101, 55),
    )
示例#30
0
 def flags(self):
     """
     If this is a __future__ import, then the bitwise-ORed of the
     compiler_flag values associated with the features.  Otherwise, 0.
     """
     return CompilerFlags(*[imp.flags for imp in self.imports])