Skip to content

Commit

Permalink
Potential dead code removal.
Browse files Browse the repository at this point in the history
It looks to me that all this is unreachable, and can go toward
simplification to go toward and __init__ instead of a __new__.
  • Loading branch information
Carreau committed May 6, 2024
1 parent 4d11be4 commit ddb98d4
Showing 1 changed file with 34 additions and 152 deletions.
186 changes: 34 additions & 152 deletions lib/python/pyflyby/_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -461,133 +461,9 @@ def _annotate_ast_startpos(
aast_node.startpos = leftstr_node.startpos
return True

# It should now be the case that we are looking at a multi-line string
# literal.
# TODO: everything below here is either untested or unreachable
# this maybe laftstr_node is always reached ?

if isinstance(aast_node, ast.FormattedValue):
aast_node.startpos = aast_node.value.startpos
aast_node.endpos = aast_node.value.startpos

return True
if not _is_ast_str_or_byte(aast_node):
raise ValueError("got a non-string col_offset=-1: %s" % (ast.dump(aast_node)))
# The ``lineno`` attribute gives the ending line number of the multiline
# string ... unless it's multiple multiline strings that are concatenated
# by adjacency, in which case it's merely the end of the first one of
# them. At least we know that the start lineno is definitely not later
# than the ``lineno`` attribute.
first_end_lineno = text.startpos.lineno + aast_node.lineno - 1
# Compute possible start positions.
# The starting line number of this string could be anywhere between the
# end of the previous expression and ``first_end_lineno``.
startpos_candidates = []
assert minpos.lineno <= first_end_lineno
for start_lineno in range(minpos.lineno, first_end_lineno + 1):
start_line = text[start_lineno]
start_line_colno = (text.startpos.colno
if start_lineno==text.startpos.lineno else 1)
startpos_candidates.extend([
(_m.group()[-1], FilePos(start_lineno, _m.start()+start_line_colno))
for _m in re.finditer("[bBrRuU]*[\"\']", start_line)])
target_str = aast_node.s

# Loop over possible end_linenos. The first one we've identified is the
# by far most likely one, but in theory it could be anywhere later in the
# file. This could be because of a dastardly concatenated string like
# this:
# """ # L1
# two # L2
# """ """ # L3
# four # L4
# five # L5
# six # L6
# """ # L7
# There are two substrings on L1:L3 and L3:L7. The parser gives us a
# single concatenated string, but sets lineno to 3 instead of 7. We don't
# have much to go on to figure out that the real end_lineno is 7. If we
# don't find the string ending on L3, then search forward looking for the
# real end of the string. Yuck!
#
# This is now complicated by fstrings that do interpolate variable on 3.7 fixed on 3.8+)
# where we'll try to guess based on prefix
f_string_candidate_prefixes = []
for end_lineno in range(first_end_lineno, text.endpos.lineno+1):
# Compute possible end positions. We're given the line we're ending
# on, but not the column position. Note that the ending line could
# contain more than just the string we're looking for -- including
# possibly other strings or comments.
end_line = text[end_lineno]
end_line_startcol = (
text.startpos.colno if end_lineno==text.startpos.lineno else 1)
endpos_candidates = [
(_m.group(), FilePos(end_lineno,_m.start()+end_line_startcol+1))
for _m in re.finditer("[\"\']", end_line)]
if not endpos_candidates:
# We found no endpos_candidates. This should not happen for
# first_end_lineno because there should be _some_ string that ends
# there.
if end_lineno == first_end_lineno:
raise AssertionError(
"No quote char found on line with supposed string")
continue
# Filter and sort the possible startpos candidates given this endpos
# candidate. It's possible for the starting quotechar and ending
# quotechar to be different in case of adjacent string concatenation,
# e.g. "foo"'''bar'''. That said, it's an unlikely case, so
# deprioritize checking them.
likely_candidates: List[Tuple[FilePos, FilePos]] = []
unlikely_candidates: List[Tuple[FilePos, FilePos]] = []
for end_quotechar, endpos in reversed(endpos_candidates):
for start_quotechar, startpos in startpos_candidates:
assert isinstance(startpos, FilePos)
assert isinstance(endpos, FilePos)
if not startpos < endpos:
continue
if start_quotechar == end_quotechar:
candidate_list = likely_candidates
else:
candidate_list = unlikely_candidates
candidate_list.append((startpos,endpos))
# Loop over sorted candidates.
matched_prefix = set()
for (startpos, endpos) in likely_candidates + unlikely_candidates:
# Try to parse the given range and see if it matches the target
# string literal.

# TODO: this seem impossible as startpos and endpos are not int,
# but this might be unreachable see comment earlier.
subtext = text[startpos:endpos] # type: ignore
candidate_str = _test_parse_string_literal(subtext, flags)
if candidate_str is None:
continue

maybe_fstring = False

if target_str == candidate_str and target_str:
# Success!
aast_node.startpos = startpos
aast_node.endpos = endpos
# This node is a multiline string; and, it's a leaf, so by
# definition it is the leftmost node.
return True # all done
elif candidate_str and target_str.startswith(candidate_str):
matched_prefix.add(startpos)
elif maybe_fstring:
candidate_prefix = candidate_str.split("{")[0]
if candidate_prefix and target_str.startswith(candidate_prefix):
f_string_candidate_prefixes.append((startpos, endpos))
# We didn't find a string given the current end_lineno candidate.
# Only continue checking the startpos candidates that so far produced
# prefixes of the string we're looking for.
if not matched_prefix:
break
startpos_candidates = [
(sq, sp)
for (sq, sp) in startpos_candidates
if sp in matched_prefix
]
# a large chunk of what look like unreachable code has been removed from here
# as the type annotation say many things were impossible (slices indexed by FilePos
# instead of integers.
raise ValueError("Couldn't find exact position of %s" % (ast.dump(ast_node)))


Expand Down Expand Up @@ -991,32 +867,10 @@ class PythonBlock:
text: FileText
_auto_flags: bool
_input_flags: Union[int,CompilerFlags]
source:str

def __new__(cls, arg:Any, 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)):
return cls.from_text(
arg, filename=filename, startpos=startpos,
flags=flags, auto_flags=auto_flags)
raise TypeError("%r: unexpected %r"
% (cls.__name__, type(arg).__name__,))

@classmethod
def from_filename(cls, filename):
return cls.from_text(Filename(filename))

@classmethod
def from_text(cls, text, filename=None, startpos=None, flags=None,
auto_flags=False):
"""
:type text:
`FileText` or convertible
Expand All @@ -1037,13 +891,41 @@ def from_text(cls, text, filename=None, startpos=None, flags=None,
:rtype:
`PythonBlock`
"""
text = FileText(text, filename=filename, startpos=startpos)
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 not isinstance(arg, (FileText, Filename, str)):
raise TypeError("%r: unexpected %r"
% (cls.__name__, type(arg).__name__,))
return cls._from_text(
arg, filename=filename, startpos=startpos,
flags=flags, auto_flags=bool(auto_flags))

@classmethod
def _from_text(cls, text:Union[str, Filename, FileText], filename=None, startpos=None, flags=None,
auto_flags=False):
ftext = FileText(text, filename=filename, startpos=startpos)
self = object.__new__(cls)
self.text = text
self.text = ftext
self._input_flags = CompilerFlags(flags)
self._auto_flags = auto_flags
return self

@classmethod
def from_statement(cls, statement:PythonStatement) -> PythonBlock:
return statement.block

@classmethod
def from_filename(cls, filename):
return cls._from_text(Filename(filename))


@classmethod
def __construct_from_annotated_ast(cls, annotated_ast_nodes, text:FileText, flags):
# Constructor for internal use by _split_by_statement() or
Expand Down

0 comments on commit ddb98d4

Please sign in to comment.