Closed JacobHayes closed 3 years ago
:exclamation: No coverage uploaded for pull request base (
main@23589d3
). Click here to learn what that means. The diff coverage is100.00%
.
@@ Coverage Diff @@
## main #37 +/- ##
=======================================
Coverage ? 99.12%
=======================================
Files ? 1
Lines ? 229
Branches ? 37
=======================================
Hits ? 227
Misses ? 2
Partials ? 0
Impacted Files | Coverage Δ | |
---|---|---|
multimethod/__init__.py | 99.12% <100.00%> (ø) |
Continue to review full report at Codecov.
Legend - Click here to learn more
Δ = absolute <relative> (impact)
,ø = not affected
,? = missing data
Powered by Codecov. Last update 23589d3...b7588e3. Read the comment docs.
Thanks, looks good. Regarding potential mypy breakage, what do you think of adding this to only multidispatch
? Since that requires a initial definition.
Sounds good, just pushed that - I kept the @X.register
improvement in multimethod
since that maintains the original signature (as the func is returned unchanged).
After re-reading the @multimethod
docs, I realized it is already somewhat incompatible with mypy
since mypy doesn't support redefinition. @multidispatch
only for the RETURN
is definitely the safer choice, but I wonder how much it would affect @multimethod
. I think it'd only be users w/ # type: ignore
comments (to avoid the redefinition error) but the added RETURN
would change __call__
. Probably more food for thought... there's definitely some trickiness statically typing a lib made to expand dynamic typing. 😁
Currently, the mypy return type of a
multimethod
call isAny
, but a stricter return is possible by makingmultimethod
aGeneric
. This will take the return of the first registered function. This should be fine as long as the initial function has-> Any
(implicit default with no return annotation) or uses a base type (eg:object
or another base class) matching subsequent function returns ("covariant" if I understand the terms correctly). Using the test suite as a baseline, these seem like "safe" assumptions.For example, running
mypy
on this module:before and after this PR shows:
.
The
register
ed funcs look great, but it's unfortunate the mypy signature for themultimethod
is*args, **kwargs
(and hence, should but does not error on line 23). I don't think it's possible to parametrize the input arguments in any sane way (mypy forces them to be contravariant).This PR shouldn't break any runtime usage, but may break users' mypy if the initial function has a return type and it isn't covariant/base class of the other functions. In these cases, the function definitions themselves will be ok, but the type hint for the
multimethod
return value will now be that first function's return, rather thanAny
, so mypy will scrutinize a bit further. I'm not sure how common that case is, but suggesting the initial func be explicitly annotated with-> Any
may be an easy work around.