Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misc updates and types annotations + unused parameter deprecation #319

Merged
merged 5 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions lib/python/pyflyby/_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@



from functools import total_ordering
from functools import total_ordering, cached_property
import io
import os
import re
import sys

from pyflyby._util import cached_attribute, cmp, memoize
from pyflyby._util import cmp, memoize


class UnsafeFilenameError(ValueError):
Expand All @@ -28,6 +28,8 @@ class Filename(object):
Filename('/etc/passwd')

"""
_filename: str

def __new__(cls, arg):
if isinstance(arg, cls):
return arg
Expand Down Expand Up @@ -85,7 +87,7 @@ def __cmp__(self, o):
return NotImplemented
return cmp(self._filename, o._filename)

@cached_attribute
@cached_property
def ext(self):
"""
Returns the extension of this filename, including the dot.
Expand All @@ -99,15 +101,15 @@ def ext(self):
return None
return dot + rhs

@cached_attribute
@cached_property
def base(self):
return os.path.basename(self._filename)

@cached_attribute
@cached_property
def dir(self):
return type(self)(os.path.dirname(self._filename))

@cached_attribute
@cached_property
def real(self):
return type(self)(os.path.realpath(self._filename))

Expand Down Expand Up @@ -338,6 +340,8 @@ class FileText:
Represents a contiguous sequence of lines from a file.
"""

filename: Filename

def __new__(cls, arg, filename=None, startpos=None):
"""
Return a new ``FileText`` instance.
Expand Down Expand Up @@ -394,7 +398,7 @@ def _from_lines(cls, lines, filename, startpos):
self.startpos = startpos
return self

@cached_attribute
@cached_property
def lines(self):
r"""
Lines that have been split by newline.
Expand All @@ -414,7 +418,7 @@ def lines(self):
# (or requires extra work to process if we use splitlines(True)).
return tuple(self.joined.split('\n'))

@cached_attribute
@cached_property
def joined(self): # used if only initialized with 'lines'
return '\n'.join(self.lines)

Expand All @@ -441,7 +445,7 @@ def alter(self, filename=None, startpos=None):
result.startpos = startpos
return result

@cached_attribute
@cached_property
def endpos(self):
"""
The position after the last character in the text.
Expand Down
6 changes: 2 additions & 4 deletions lib/python/pyflyby/_imports2s.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,12 +200,10 @@ def insert_new_blocks_after_comments(self, blocks):
# insert in the middle.
self.blocks[:1] = (
[SourceToSourceTransformation(
PythonBlock.concatenate(statements[:idx],
assume_contiguous=True))] +
PythonBlock.concatenate(statements[:idx]))] +
blocks +
[SourceToSourceTransformation(
PythonBlock.concatenate(statements[idx:],
assume_contiguous=True))])
PythonBlock.concatenate(statements[idx:]))])
break
else:
# First block is entirely comments, so just insert after it.
Expand Down
39 changes: 29 additions & 10 deletions lib/python/pyflyby/_parse.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# pyflyby/_parse.py.
# Copyright (C) 2011, 2012, 2013, 2014, 2015, 2018 Karl Chen.
# License: MIT http://opensource.org/licenses/MIT

from __future__ import annotations


import ast
Expand All @@ -13,6 +13,8 @@
import sys
from textwrap import dedent
import types
from typing import Optional
import warnings

from pyflyby._file import FilePos, FileText, Filename
from pyflyby._flags import CompilerFlags
Expand All @@ -22,6 +24,8 @@

from ast import TypeIgnore, AsyncFunctionDef

_sentinel = object()


def _is_comment_or_blank(line):
"""
Expand Down Expand Up @@ -741,7 +745,7 @@ class _DummyAst_Node(object):
pass


class PythonStatement(object):
class PythonStatement:
r"""
Representation of a top-level Python statement or consecutive
comments/blank lines.
Expand All @@ -753,7 +757,9 @@ class PythonStatement(object):
top-level AST node.
"""

def __new__(cls, arg, filename=None, startpos=None, flags=None):
block: PythonBlock

def __new__(cls, arg:PythonStatement, filename=None, startpos=None, flags=None):
if isinstance(arg, cls):
if filename is startpos is flags is None:
return arg
Expand All @@ -773,23 +779,24 @@ def __new__(cls, arg, filename=None, startpos=None, flags=None):
raise TypeError("PythonStatement: unexpected %s" % (type(arg).__name__,))

@classmethod
def _construct_from_block(cls, block):
def _construct_from_block(cls, block:PythonBlock):
assert isinstance(block, PythonBlock), repr(block)
# Only to be used by PythonBlock.
assert isinstance(block, PythonBlock)
self = object.__new__(cls)
self.block = block
return self

@property
def text(self):
def text(self) -> FileText:
"""
:rtype:
`FileText`
"""
return self.block.text

@property
def filename(self):
def filename(self) -> Optional[str]:
"""
:rtype:
`Filename`
Expand Down Expand Up @@ -828,9 +835,17 @@ def ast_node(self):
return ast_nodes[0]
raise AssertionError("More than one AST node in block")

@property
def is_blank(self):
return self.ast_node is None and self.text.joined.strip() == ''

@property
def is_comment(self):
return self.ast_node is None and self.text.joined.strip() != ''

@property
def is_comment_or_blank(self):
return self.ast_node is None
return self.is_comment or self.is_blank

@property
def is_comment_or_blank_or_string_literal(self):
Expand Down Expand Up @@ -898,7 +913,7 @@ def __hash__(self):


@total_ordering
class PythonBlock(object):
class PythonBlock:
r"""
Representation of a sequence of consecutive top-level
`PythonStatement` (s).
Expand Down Expand Up @@ -993,17 +1008,21 @@ def __construct_from_annotated_ast(cls, annotated_ast_nodes, text, flags):
return self

@classmethod
def concatenate(cls, blocks, assume_contiguous=False):
def concatenate(cls, blocks, assume_contiguous=_sentinel):
"""
Concatenate a bunch of blocks into one block.

:type blocks:
sequence of `PythonBlock` s and/or `PythonStatement` s
:param assume_contiguous:
Deprecated, always True
Whether to assume, without checking, that the input blocks were
originally all contiguous. This must be set to True to indicate the
caller understands the assumption; False is not implemented.
"""
if assume_contiguous is not _sentinel:
warnings.warn('`assume_continuous` is deprecated and considered always `True`')
assume_contiguous = True
if not assume_contiguous:
raise NotImplementedError
blocks = [PythonBlock(b) for b in blocks]
Expand Down Expand Up @@ -1248,7 +1267,7 @@ def groupby(self, predicate):
cls = type(self)
for pred, stmts in groupby(self.statements, predicate):
blocks = [s.block for s in stmts]
yield pred, cls.concatenate(blocks, assume_contiguous=True)
yield pred, cls.concatenate(blocks)

def string_literals(self):
r"""
Expand Down
Loading