Skip to content

Commit

Permalink
Merge pull request #332 from Carreau/mix-clean
Browse files Browse the repository at this point in the history
Cleanup and removal of unnecessary branches
  • Loading branch information
Carreau authored Apr 22, 2024
2 parents 0a76b6a + 3cdc373 commit e7188e9
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 27 deletions.
26 changes: 17 additions & 9 deletions lib/python/pyflyby/_importstmt.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,9 @@ class ImportStatement:
def __new__(cls, arg):
if isinstance(arg, cls):
return arg
if isinstance(arg, (PythonStatement, str)):
if isinstance(arg, str):
return cls._from_str(arg)
if isinstance(arg, PythonStatement):
return cls._from_statement(arg)
if isinstance(arg, (ast.ImportFrom, ast.Import)):
return cls._from_ast_node(arg)
Expand All @@ -397,32 +399,38 @@ def from_parts(cls, fromname:Optional[str], aliases:Tuple[Tuple[str, Optional[st
return self

@classmethod
def _from_statement(cls, statement):
def _from_str(cls, code:str, /):
"""
>>> ImportStatement._from_statement("from foo import bar, bar2, bar")
>>> ImportStatement._from_str("from foo import bar, bar2, bar")
ImportStatement('from foo import bar, bar2, bar')
>>> ImportStatement._from_statement("from foo import bar as bar")
>>> ImportStatement._from_str("from foo import bar as bar")
ImportStatement('from foo import bar as bar')
>>> ImportStatement._from_statement("from foo.bar import baz")
>>> ImportStatement._from_str("from foo.bar import baz")
ImportStatement('from foo.bar import baz')
>>> ImportStatement._from_statement("import foo.bar")
>>> ImportStatement._from_str("import foo.bar")
ImportStatement('import foo.bar')
>>> ImportStatement._from_statement("from .foo import bar")
>>> ImportStatement._from_str("from .foo import bar")
ImportStatement('from .foo import bar')
>>> ImportStatement._from_statement("from . import bar, bar2")
>>> ImportStatement._from_str("from . import bar, bar2")
ImportStatement('from . import bar, bar2')
:type statement:
`PythonStatement`
:rtype:
`ImportStatement`
"""
statement = PythonStatement(statement)

statement = PythonStatement(code)
return cls._from_ast_node(statement.ast_node)

@classmethod
def _from_statement(cls, statement):
statement = PythonStatement.from_statement(statement)
return cls._from_ast_node(statement.ast_node)

@classmethod
Expand Down
56 changes: 38 additions & 18 deletions lib/python/pyflyby/_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import sys
from textwrap import dedent
import types
from typing import Optional, Union, Tuple, List
from typing import Optional, Union, Tuple, List, Any
import warnings

from pyflyby._file import FilePos, FileText, Filename
Expand All @@ -27,7 +27,7 @@
_sentinel = object()


def _is_comment_or_blank(line):
def _is_comment_or_blank(line, /):
"""
Returns whether a line of python code contains only a comment is blank.
Expand Down Expand Up @@ -185,7 +185,7 @@ def _walk_ast_nodes_in_order(node):
todo.extend(reversed(list(_iter_child_nodes_in_order(node))))


def _flags_to_try(source, flags, auto_flags, mode):
def _flags_to_try(source:str, flags, auto_flags, mode):
"""
Flags to try for ``auto_flags``.
Expand All @@ -199,7 +199,7 @@ def _flags_to_try(source, flags, auto_flags, mode):
return


def _parse_ast_nodes(text, flags, auto_flags, mode):
def _parse_ast_nodes(text:FileText, flags:CompilerFlags, auto_flags:bool, mode:str):
"""
Parse a block of lines into an AST.
Expand All @@ -220,7 +220,7 @@ def _parse_ast_nodes(text, flags, auto_flags, mode):
:rtype:
``ast.Module``
"""
text = FileText(text)
assert isinstance(text, FileText)
filename = str(text.filename) if text.filename else "<unknown>"
source = text.joined
source = dedent(source)
Expand All @@ -233,7 +233,7 @@ def _parse_ast_nodes(text, flags, auto_flags, mode):
cflags = ast.PyCF_ONLY_AST | int(flags)
try:
result = compile(
source, filename, mode, flags=cflags, dont_inherit=1)
source, filename, mode, flags=cflags, dont_inherit=True)
except SyntaxError as e:
exp = e
pass
Expand All @@ -244,10 +244,13 @@ def _parse_ast_nodes(text, flags, auto_flags, mode):
result.flags = result.input_flags | result.source_flags
result.text = text
return result
raise exp # SyntaxError
# None, would be unraisable and Mypy would complains below
assert exp is not None
raise exp


def _test_parse_string_literal(text, flags):

def _test_parse_string_literal(text:str, flags:CompilerFlags):
r"""
Attempt to parse ``text``. If it parses cleanly to a single string
literal, return its value. Otherwise return ``None``.
Expand All @@ -256,9 +259,9 @@ def _test_parse_string_literal(text, flags):
'foo\n\\nbar'
"""
text = FileText(text)
filetext = FileText(text)
try:
module_node = _parse_ast_nodes(text, flags, False, "eval")
module_node = _parse_ast_nodes(filetext, flags, False, "eval")
except SyntaxError:
return None
body = module_node.body
Expand Down Expand Up @@ -759,11 +762,15 @@ class PythonStatement:

block: PythonBlock

def __new__(cls, arg:PythonStatement, filename=None, startpos=None, flags=None):
def __new__(cls, arg:Any, filename=None, startpos=None, flags=None):
arg_ : Union[PythonBlock, FileText, str, PythonStatement]
if isinstance(arg, cls):
if filename is startpos is flags is None:
return arg
# TODO: this seem unreachable
assert False, "does test suite reach here ?"
return cls.from_statement(arg)
# TODO: this seem unreachable as well
assert False, "does test suite reach there ?"
arg_ = arg.block
# Fall through
else:
Expand All @@ -780,21 +787,32 @@ def __new__(cls, arg:PythonStatement, filename=None, startpos=None, flags=None):
else:
raise TypeError("PythonStatement: unexpected %s" % type(arg_).__name__)

return cls.from_block(block)

@classmethod
def from_statement(cls, statement):
assert isinstance(statement, cls), (statement, cls)
return statement

@classmethod
def from_block(cls, block:PythonBlock) -> PythonStatement:
"""
Return a statement from a PythonBlock
This assume the PythonBlock is a single statement and check the comments
to not start with newlines.
"""
statements = block.statements
if len(statements) != 1:
raise ValueError(
"Code contains %d statements instead of exactly 1: %r"
% (len(statements), block)
)
(statement,) = statements
if statement.is_comment:
assert not statement.text.joined.startswith(("\n", " ")), (
statement.text.joined,
statement,
)
assert isinstance(statement, cls)
return statement


@classmethod
def _construct_from_block(cls, block:PythonBlock):
# Only to be used by PythonBlock.
Expand Down Expand Up @@ -961,7 +979,7 @@ class PythonBlock:
_auto_flags: bool
_input_flags: Union[int,CompilerFlags]

def __new__(cls, arg, filename=None, startpos=None, flags=None,
def __new__(cls, arg:Any, filename=None, startpos=None, flags=None,
auto_flags=None):
if isinstance(arg, PythonStatement):
arg = arg.block
Expand Down Expand Up @@ -1340,6 +1358,7 @@ def _get_docstring_nodes(self):
continue
# If the first body item is a literal string, then yield the node.
if (isinstance(node.body[0], ast.Expr) and
# TODO: sys.version_info >= (3,14)
isinstance(node.body[0].value, ast.Str)):
yield node.body[0].value
for i in range(1, len(node.body)-1):
Expand All @@ -1348,6 +1367,7 @@ def _get_docstring_nodes(self):
n1, n2 = node.body[i], node.body[i+1]
if (isinstance(n1, ast.Assign) and
isinstance(n2, ast.Expr) and
# TODO: sys.version_info >= (3,14)
isinstance(n2.value, ast.Str)):
yield n2.value

Expand Down

0 comments on commit e7188e9

Please sign in to comment.