Skip to content

Commit

Permalink
Remove implicit getattr partials
Browse files Browse the repository at this point in the history
Resolves   #730.
  • Loading branch information
evhub committed Apr 21, 2023
1 parent 4a448f5 commit 62db4b0
Show file tree
Hide file tree
Showing 8 changed files with 22 additions and 8 deletions.
1 change: 0 additions & 1 deletion DOCS.md
Original file line number Diff line number Diff line change
Expand Up @@ -1650,7 +1650,6 @@ Coconut supports a number of different syntactical aliases for common partial ap
```coconut
.attr => operator.attrgetter("attr")
.method(args) => operator.methodcaller("method", args)
obj. => getattr$(obj)
func$ => ($)$(func)
seq[] => operator.getitem$(seq)
iter$[] => # the equivalent of seq[] for iterators
Expand Down
7 changes: 4 additions & 3 deletions coconut/compiler/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -2290,7 +2290,7 @@ def pipe_handle(self, original, loc, tokens, **kwargs):
elif name == "right op partial":
return partial_op_item_handle(item)
elif name == "await":
raise CoconutDeferredSyntaxError("cannot pipe from await, only into await", loc)
raise CoconutDeferredSyntaxError("await in pipe must have something piped into it", loc)
else:
raise CoconutInternalException("invalid split pipe item", split_item)

Expand Down Expand Up @@ -2367,7 +2367,7 @@ def pipe_handle(self, original, loc, tokens, **kwargs):
else:
raise CoconutInternalException("invalid pipe operator direction", direction)

def item_handle(self, loc, tokens):
def item_handle(self, original, loc, tokens):
"""Process trailers."""
out = tokens.pop(0)
for i, trailer in enumerate(tokens):
Expand All @@ -2381,6 +2381,7 @@ def item_handle(self, loc, tokens):
elif trailer[0] == "[]":
out = "_coconut.functools.partial(_coconut.operator.getitem, " + out + ")"
elif trailer[0] == ".":
self.strict_err_or_warn("'obj.' as a shorthand for 'getattr$(obj)' is deprecated (just use the getattr partial)", original, loc)
out = "_coconut.functools.partial(_coconut.getattr, " + out + ")"
elif trailer[0] == "type:[]":
out = "_coconut.typing.Sequence[" + out + "]"
Expand All @@ -2395,7 +2396,7 @@ def item_handle(self, loc, tokens):
raise CoconutDeferredSyntaxError("None-coalescing '?' must have something after it", loc)
not_none_tokens = [none_coalesce_var]
not_none_tokens.extend(rest_of_trailers)
not_none_expr = self.item_handle(loc, not_none_tokens)
not_none_expr = self.item_handle(original, loc, not_none_tokens)
# := changes meaning inside lambdas, so we must disallow it when wrapping
# user expressions in lambdas (and naive string analysis is safe here)
if ":=" in not_none_expr:
Expand Down
2 changes: 1 addition & 1 deletion coconut/root.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
VERSION = "3.0.0"
VERSION_NAME = None
# False for release, int >= 1 for develop
DEVELOP = 24
DEVELOP = 25
ALPHA = True # for pre releases rather than post releases

# -----------------------------------------------------------------------------------------------------------------------
Expand Down
3 changes: 1 addition & 2 deletions coconut/tests/src/cocotest/agnostic/primary.coco
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ def primary_test() -> bool:
assert isinstance(one_line_class(), one_line_class)
assert (.join)("")(["1", "2", "3"]) == "123"
assert "" |> .join <| ["1","2","3"] == "123"
assert "". <| "join" <| ["1","2","3"] == "123"
assert 1 |> [1,2,3][] == 2 == 1 |> [1,2,3]$[]
assert 1 |> "123"[] == "2" == 1 |> "123"$[]
assert (| -1, 0, |) :: range(1, 5) |> list == [-1, 0, 1, 2, 3, 4]
Expand Down Expand Up @@ -448,7 +447,6 @@ def primary_test() -> bool:
assert None?[herp].derp is None # type: ignore
assert None?(derp)[herp] is None # type: ignore
assert None?$(herp)(derp) is None # type: ignore
assert "a b c" == (" ". ?? "not gonna happen")("join")("abc")
a: int[]? = None # type: ignore
assert a is None
assert range(5) |> iter |> reiterable |> .[1] == 1
Expand Down Expand Up @@ -1583,4 +1581,5 @@ def primary_test() -> bool:
assert (in)(1, [1, 2])
assert not (1 not in .)([1, 2])
assert not (in)([[]], [])
assert ("{a}" . .)("format")(a=1) == "1"
return True
2 changes: 1 addition & 1 deletion coconut/tests/src/cocotest/agnostic/suite.coco
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def suite_test() -> bool:
assert collatz(27)
assert preop(1, 2).add() == 3
assert vector(3, 4) |> abs == 5 == vector_with_id(3, 4, 1) |> abs
assert vector(1, 2) |> ((v) -> map(v., ("x", "y"))) |> tuple == (1, 2) # type: ignore
assert vector(1, 2) |> ((v) -> map(getattr$(v), ("x", "y"))) |> tuple == (1, 2) # type: ignore
assert vector(3, 1) |> vector(1, 2).transform |> ((v) -> map(v[], (0, 1))) |> tuple == (4, 3) # type: ignore
assert vector(1, 2) |> vector(1, 2).__eq__
assert not vector(1, 2) |> vector(3, 4).__eq__
Expand Down
2 changes: 2 additions & 0 deletions coconut/tests/src/cocotest/non_strict/non_strict_test.coco
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ def non_strict_test() -> bool:
assert weird_func()()(5) == 5
a_dict: TextMap[str, int] = {"a": 1}
assert a_dict["a"] == 1
assert "". <| "join" <| ["1","2","3"] == "123"
assert "a b c" == (" ". ?? "not gonna happen")("join")("abc")
return True

if __name__ == "__main__":
Expand Down
12 changes: 12 additions & 0 deletions coconut/tests/src/cocotest/target_36/py36_test.coco
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,18 @@ def py36_test() -> bool:
loop.run_until_complete(aiter_test())
assert l == list(range(10)) + list(range(10))

async def arec(x) = await arec(x-1) if x else x
async def atest():
assert (
10
|> arec
|> await
|> (.+10)
|> arec
|> await
) == 0
loop.run_until_complete(atest())

loop.close()

return True
1 change: 1 addition & 0 deletions coconut/tests/src/extras.coco
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ else:
assert_raises(-> parse("""case x:
match x:
pass"""), CoconutStyleError, err_has="case x:")
assert_raises(-> parse("obj."), CoconutStyleError, err_has="getattr")

setup(strict=True, target="sys")
assert_raises(-> parse("await f x"), CoconutParseError, err_has='invalid use of the keyword "await"')
Expand Down

0 comments on commit 62db4b0

Please sign in to comment.