-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Switch from attrs to dataclasses #1116
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,7 +39,7 @@ | |
) | ||
|
||
from appdirs import user_cache_dir | ||
from attr import dataclass, evolve, Factory | ||
from dataclasses import dataclass, field | ||
import click | ||
import toml | ||
from typed_ast import ast3, ast27 | ||
|
@@ -185,7 +185,7 @@ class Feature(Enum): | |
|
||
@dataclass | ||
class FileMode: | ||
target_versions: Set[TargetVersion] = Factory(set) | ||
target_versions: Set[TargetVersion] = field(default_factory=set) | ||
line_length: int = DEFAULT_LINE_LENGTH | ||
string_normalization: bool = True | ||
is_pyi: bool = False | ||
|
@@ -629,7 +629,7 @@ def format_file_in_place( | |
`mode` and `fast` options are passed to :func:`format_file_contents`. | ||
""" | ||
if src.suffix == ".pyi": | ||
mode = evolve(mode, is_pyi=True) | ||
mode = mode.replace(is_pyi=True) | ||
|
||
then = datetime.utcfromtimestamp(src.stat().st_mtime) | ||
with open(src, "rb") as buf: | ||
|
@@ -1028,11 +1028,11 @@ class BracketTracker: | |
"""Keeps track of brackets on a line.""" | ||
|
||
depth: int = 0 | ||
bracket_match: Dict[Tuple[Depth, NodeType], Leaf] = Factory(dict) | ||
delimiters: Dict[LeafID, Priority] = Factory(dict) | ||
bracket_match: Dict[Tuple[Depth, NodeType], Leaf] = field(default_factory=dict) | ||
delimiters: Dict[LeafID, Priority] = field(default_factory=dict) | ||
previous: Optional[Leaf] = None | ||
_for_loop_depths: List[int] = Factory(list) | ||
_lambda_argument_depths: List[int] = Factory(list) | ||
_for_loop_depths: List[int] = field(default_factory=list) | ||
_lambda_argument_depths: List[int] = field(default_factory=list) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe it makes sense to define a helper: def Factory(fn):
return field(default_factory=fn) to minimize the size of the diff? Not sure however what looks better. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this code is fine. I'd rather use dataclasses idiomatically than minimize diff size. |
||
|
||
def mark(self, leaf: Leaf) -> None: | ||
"""Mark `leaf` with bracket-related metadata. Keep track of delimiters. | ||
|
@@ -1160,9 +1160,11 @@ class Line: | |
"""Holds leaves and comments. Can be printed with `str(line)`.""" | ||
|
||
depth: int = 0 | ||
leaves: List[Leaf] = Factory(list) | ||
comments: Dict[LeafID, List[Leaf]] = Factory(dict) # keys ordered like `leaves` | ||
bracket_tracker: BracketTracker = Factory(BracketTracker) | ||
leaves: List[Leaf] = field(default_factory=list) | ||
comments: Dict[LeafID, List[Leaf]] = field( | ||
default_factory=dict | ||
) # keys ordered like `leaves` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you put this comment on the previous line by itself instead? (I'd personally prefer if Black did that automatically in this case.) |
||
bracket_tracker: BracketTracker = field(default_factory=BracketTracker) | ||
inside_brackets: bool = False | ||
should_explode: bool = False | ||
|
||
|
@@ -1565,7 +1567,7 @@ class EmptyLineTracker: | |
is_pyi: bool = False | ||
previous_line: Optional[Line] = None | ||
previous_after: int = 0 | ||
previous_defs: List[int] = Factory(list) | ||
previous_defs: List[int] = field(default_factory=list) | ||
|
||
def maybe_empty_lines(self, current_line: Line) -> Tuple[int, int]: | ||
"""Return the number of extra empty lines before and after the `current_line`. | ||
|
@@ -1679,7 +1681,7 @@ class LineGenerator(Visitor[Line]): | |
|
||
is_pyi: bool = False | ||
normalize_strings: bool = True | ||
current_line: Line = Factory(Line) | ||
current_line: Line = field(default_factory=Line) | ||
remove_u_prefix: bool = False | ||
|
||
def line(self, indent: int = 0) -> Iterator[Line]: | ||
|
@@ -1844,7 +1846,7 @@ def visit_factor(self, node: Node) -> Iterator[Line]: | |
node.insert_child(index, Node(syms.atom, [lpar, operand, rpar])) | ||
yield from self.visit_default(node) | ||
|
||
def __attrs_post_init__(self) -> None: | ||
def __post_init__(self) -> None: | ||
"""You are in a twisty little maze of passages.""" | ||
v = self.visit_stmt | ||
Ø: Set[str] = set() | ||
|
@@ -3712,7 +3714,7 @@ def _v(node: Union[ast.AST, ast3.AST, ast27.AST], depth: int = 0) -> Iterator[st | |
|
||
yield f"{' ' * depth}{node.__class__.__name__}(" | ||
|
||
for field in sorted(node._fields): | ||
for field in sorted(node._fields): # noqa: F402 | ||
# TypeIgnore has only one field 'lineno' which breaks this comparison | ||
type_ignore_classes = (ast3.TypeIgnore, ast27.TypeIgnore) | ||
if sys.version_info >= (3, 8): | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,7 +42,8 @@ def get_long_description() -> str: | |
"typed-ast>=1.4.0", | ||
"regex", | ||
"pathspec>=0.6, <1", | ||
], | ||
] | ||
+ (["dataclasses>=0.6"] if sys.version_info < (3, 7) else []), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prefer to do it like in python/typing@f254d69 |
||
extras_require={"d": ["aiohttp>=3.3.2", "aiohttp-cors"]}, | ||
test_suite="tests.test_black", | ||
classifiers=[ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's actually
dataclasses.replace
, a global function (presumably so dataclasses don't inject a.replace
method everywhere)