-
Notifications
You must be signed in to change notification settings - Fork 195
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
Some type annotations (1) #1846
Conversation
…o type_annotations
That exception is only ever constructed with a string. I think the use of |
parsl/app/errors.py
Outdated
@@ -128,9 +136,12 @@ def reraise(self): | |||
reraise(t, v, tb) | |||
|
|||
|
|||
def wrap_error(func): | |||
# TODO: [typing] I don't think this is correct. We need to constrain the type of the | |||
# wrapper to that of the wrapped function, whereas this specification makes the wrapper |
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.
I added a stub in mypy-stubs for @typeguard.typechecked annotations a while ago, because I wanted a typeguard decorated function to have the same type signature as the original pre-decorated function.
That code lives in mypy-stubs/typeguard.pyi
That feels to me similar-ish to what wrap_error is trying to do (but not in decorator form).
It looks like this:
from typing import TypeVar
Func = TypeVar('Func')
def typechecked(f: Func) -> Func: ...
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.
I had a bit of a play with this. One problem is that the wrapped function can return more than the original function - it might return a RemoteExceptionWrapper, rather than a value of the original returned type (so if the original return type was T, the new return type is Union[T, RemoteExceptionWrapper].
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.
I was thinking that the typevar trick won't work since the wrapper returned by the decorator should have a proper signature. Bu then it looks like it's possible to simply not typecheck that part:
T = TypeVar('T')
def decorator(f: T) -> T:
def w(*args, **kwargs):
return f(*args, **kwargs)
return w # type: ignore
So I guess that and Union[T, ...] should work here.
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.
i went down a rathole reading about this and playing yesterday and the short answer seems to be no, the longer answer being "no, but the typed python community is slowly working towards it; you can write a hacky mypy plugin in the meantime".
This seems to be the big relevant issue on mypy:
so if you don't figure out a pleasing solution, I guess add that issue into the TODO comment.
I was a bit concerned in my testing yesterday about how hard it was to get a type error to occur when I had got the types wrong in particular ways, so grr.
I merged this into benc-mypy to see how well they played together - in principle they wouldn't have any typing conflicts aside from superficial ones, or ones arising from where I've made invasive changes to the code. And yeah, I'm happy with how they merged. |
… decorated with this decorator are typechecked
Seems rather deliberate to me. If you look at repr(), it is not a copy from MissingOutputExceptions, but, unlike that class, it indicates that _outputs is meant to contain a list. Yadu? |
… list of files as main argument
…o type_annotations
I dug into the history of BadStdStreamFile. When it was initially implemented, it did indeed take a list of files, like this:
but commit 376d798 in early 2018 changed that to invoke it like this, taking a single filename:
So the multi-file invocation went away at least 2 years ago, without renaming _outputs to singular form in the exception implementation (although changing the printed exception text). |
The codebase has conflicting invocations in that _outputs field though still - sometimes a human message and sometimes a filepath. |
In both cases, it's a string. And repr is ambiguous enough to produce a reasonable result in either case. |
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.
This is all fine except I'm not happy with the wrap_error typing still and thing given the complexity surrounding that, the typing for that should be removed from this PR.
Ah, I actually missed that. It's the wrapper that changes the signature of the wrapped function, so yeah, my initial comment about this not being quite right stands and I got carried away by wishful thinking. Callable[..., R] -> Callable[..., Union[R, ?Exception]] can at least provide some type information without seemingly causing problems. Thoughts? |
If you can get something like that working, sure. I struggled for the short time I played with it. |
It works to the extent that the return type is correctly matched, including the Union[] part, but the args are treated as Any. So I think that's better than no typing at all. I'll commit shortly. |
Description
This PR is a small part of an effort to systematically add type annotations to Parsl.
In its initial form, this triggers one type error, related to parsl/utils.py:112. Please see the comment before that and let's discuss what the solution should be.
Type of change