Skip to content

Commit

Permalink
Merge pull request #40 from Cheukting/flatten_union_literal
Browse files Browse the repository at this point in the history
  • Loading branch information
Zac-HD authored May 12, 2022
2 parents 044b201 + 551b94f commit 0999644
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 9 deletions.
55 changes: 46 additions & 9 deletions src/shed/_codemods.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,7 @@ def convert_optional_literal_to_literal_none(self, _, updated_node):
expr = updated_node.slice[0].slice.value
args = list(expr.slice)
args[-1] = args[-1].with_changes(comma=cst.Comma())
args.append(
cst.SubscriptElement(
slice=cst.Index(value=cst.Name(value="None")),
comma=cst.MaybeSentinel.DEFAULT,
)
)
args.append(cst.SubscriptElement(slice=cst.Index(value=cst.Name(value="None"))))
expr = expr.with_changes(slice=tuple(args))
return expr

Expand Down Expand Up @@ -305,9 +300,6 @@ def replace_unnecessary_listcomp_or_setcomp(self, _, updated_node):
def reorder_union_literal_contents_none_last(self, _, updated_node):
subscript_slice = list(updated_node.slice)
subscript_slice.sort(key=lambda elt: elt.slice.value.value == "None")
subscript_slice[-1] = subscript_slice[-1].with_changes(
comma=cst.MaybeSentinel.DEFAULT
)
return updated_node.with_changes(slice=subscript_slice)

@m.call_if_inside(m.Annotation(annotation=m.BinaryOperation()))
Expand All @@ -332,3 +324,48 @@ def _has_none(node):
return updated_node.with_changes(left=updated_node.right, right=node_left)
else:
return updated_node

@m.call_if_inside(m.Annotation(annotation=m.BinaryOperation()))
@m.leave(
m.BinaryOperation(
left=m.Subscript(value=m.Name(value="Literal")),
operator=m.BitOr(),
right=m.Name("None"),
)
)
def flatten_literal_op(self, _, updated_node):
literal = updated_node.left
args = list(literal.slice)
for item in args:
if m.matches(item, m.SubscriptElement(m.Index(m.Name("None")))):
return literal # Already has "None"
args.append(
cst.SubscriptElement(
slice=cst.Index(value=cst.Name(value="None")),
)
)
return literal.with_changes(slice=tuple(args))

@m.leave(m.Subscript(value=m.Name(value="Union") | m.Name(value="Literal")))
def flatten_union_literal_subscript(self, _, updated_node):
new_slice = []
has_none = False
for item in updated_node.slice:
if m.matches(item.slice.value, m.Subscript(m.Name("Optional"))):
new_slice += item.slice.value.slice # peel off "Optional"
has_none = True
elif m.matches(
item.slice.value, m.Subscript(m.Name("Union") | m.Name("Literal"))
) and m.matches(updated_node.value, item.slice.value.value):
new_slice += item.slice.value.slice # peel off "Union" or "Literal"
elif m.matches(item.slice.value, m.Name("None")):
has_none = True
else:
new_slice.append(item)
if has_none:
new_slice.append(
cst.SubscriptElement(
slice=cst.Index(value=cst.Name(value="None")),
)
)
return updated_node.with_changes(slice=new_slice)
15 changes: 15 additions & 0 deletions tests/recorded/flatten_literal.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Literal[1, 2] | None # this should not change
var: Literal[1, 2] | None
var2: Literal[1, Literal[2, 3]]
var3: Literal[None, 1, 2] | None
Literal[1, 2, Union[bool, str]] # this should not change
Literal[1, 2, Union[bool, str], Optional[int]]

================================================================================

Literal[1, 2] | None # this should not change
var: Literal[1, 2, None]
var2: Literal[1, 2, 3]
var3: Literal[1, 2, None]
Literal[1, 2, Union[bool, str]] # this should not change
Literal[1, 2, Union[bool, str], int, None]
13 changes: 13 additions & 0 deletions tests/recorded/flatten_union.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Union[int, Optional[str], bool]
Union[None, int, Optional[str]]
Union[Union[int, float], str]
Union[int, Literal[1, 2]] # this should not change
Union[int, Literal[1, 2], Optional[str]]

================================================================================

Union[int, str, bool, None]
Union[int, str, None]
Union[int, float, str]
Union[int, Literal[1, 2]] # this should not change
Union[int, Literal[1, 2], str, None]

0 comments on commit 0999644

Please sign in to comment.