coconut icon indicating copy to clipboard operation
coconut copied to clipboard

Addpattern with mypy - name already defined

Open EmilRehnberg opened this issue 5 years ago • 5 comments

I was going throught the case studies for coconut tutorial and tried using addpattern

def factorial(0) = 1

addpattern def factorial(n is int if n > 0) =
    """Compute n! where n is an integer >= 0."""
    n * factorial(n - 1)

# Test cases:
-1 |> factorial |> print  # MatchError
0.5 |> factorial |> print  # MatchError
0 |> factorial |> print  # 1
3 |> factorial |> print  # 6

Now compiling with coconut fact.coco --mypy yielded

CoconutWarning: missing __init__.coco in package: '...'
Compiling         fact.coco ...
Compiled to       fact.py .
fact.py:39: error: Name 'factorial' already defined on line 23
Found 1 error in 1 file (checked 1 source file)
Exiting due to MyPy error.

The code runs and all but I want to know if this is expected and desired output from mypy?

EmilRehnberg avatar Dec 10 '19 13:12 EmilRehnberg

Oh I guess this is related to #510

EmilRehnberg avatar Dec 10 '19 13:12 EmilRehnberg

@EmilRehnberg This is intended behavior—MyPy is correctly warning you that you're redefining factorial, since you first define it as def factorial(0) = 1 and then later redefine it by adding the more general pattern. In Coconut, redefining functions via addpattern is standard practice, but MyPy doesn't like it. If you want, you can pass --allow-redefinition to MyPy (i.e. run coconut <args> --mypy --allow-redefinition) to suppress the error, or just do something like:

if TYPE_CHECKING:
    def factorial(n: int) -> int: ...
else:
    <your code>

(see TYPE_CHECKING)

Possibly Coconut should pass --allow-redefinition by default to alleviate this issue? Not sure about that.

evhub avatar Dec 10 '19 19:12 evhub

Or if I understand #510 correctly, add_pattern could define a unique name and this mypy check makes sense all of a sudden.

Thanks for the suggested flag!

EmilRehnberg avatar Dec 11 '19 07:12 EmilRehnberg

@EmilRehnberg #510 would not resolve this issue, as even after you give the function a unique name you still need to reassign it if you want it to override the old name. So I think it still makes sense to consider whether Coconut should pass --allow-redefinition by default. I'm going to leave this issue open for that reason.

evhub avatar Dec 12 '19 09:12 evhub

Related to #520, Coconut could add # type: ignore[no-redef] when addpattern is used. For me, ideally, it could be added only when addpattern is used before the function is called, but I guess this is very hard to implement. Maybe include # type: ignore[no-redef] when addpattern is used right on the same file where function was declared.

FelipeSharkao avatar Sep 16 '21 12:09 FelipeSharkao