-
Notifications
You must be signed in to change notification settings - Fork 275
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
🐛 Fix Mypy plugin crash on variadic arguments #525
🐛 Fix Mypy plugin crash on variadic arguments #525
Conversation
These changes add comments to the `get_reducers_type` function annotating the purpose and meaning of various sections of the function. This will help future newcomers understand the logic used to compute more specific types for model-combining functions.
These changes add a regression test checking whether or not type-checking succeeds when applied to a file with variadic arguments passed to a Thinc API function.
These changes fix a crash that would occur in the Thinc Mypy plugin whenever a Thinc API function was called with variadic arguments. Previously the Thinc Mypy plugin would treat any argument with a generic type as a `Model` instance and attempt to infer a more specific type for the return type of the function call. However, the Thinc Mypy plugin was intended to only be used on functions that exclusively accept and return `Model` instances. Since the plugin accepted overly broad input, it would sometimes end up trying to access the second generic type argument for a generic type instance with only a single argument. This resulted in the plugin crashing. This specifically manifested itself whenever variadic arguments were passed to a Thinc API function. Mypy passes the type of variadic arguments as `List[Model[InT, OutT]]`. The Thinc Mypy plugin would look at this type and attempt to treat it as an unwrapped `Model` type since the plugin would allow any generic type as an argument type annotation. Later on the plugin would attempt to retrieve the output type of the "Model". Since `List` accepts only a single generic argument, attempting to access `type.args[1]` would cause the crash. These changes fix this by restricting the input on which the Thinc Mypy plugin operates. Specifically each argument and the return type must: * Be a generic type `Instance`, * Refer to the `thinc.model.Model` type and * Have two generic type arguments Notably these restrictions prevent the Thinc Mypy plugin from working on subclasses of `thinc.model.Model`. While this plugin previously had some support for `Model` subclasses, this behavior was not documented and unintentional. `Model` subclasses were only properly handled if their first two generic type arguments had the same meaning as `Model`'s generic type arguments. Support for `Model` subclasses may be restored in the future through the use of Mypy's `map_instance_to_supertype` function. I just haven't figured out how to use it yet 😅 Fixes explosion#519
Thanks for the PR! I'll go ahead and try to fix the python version compat issues from our end. |
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.
Hi @connorbrinton,
This all looks pretty good, I particularly appreciate the detailed explanations, code comments and additional unit test :-) I made a few small nitpicking suggestions for some of the comments, as it makes sense to avoid statements with "I/my" in the code base, as you don't know later on who wrote what (and it shouldn't really matter either).
Co-authored-by: Sofie Van Landeghem <svlandeg@users.noreply.github.com>
@svlandeg Thanks for those suggestions, they've been committed 🙂 |
We'll get this released as part of 8.0.9 so we can continue with explosion/spaCy#8773! |
These changes fix a crash that would occur in the Thinc Mypy plugin whenever a Thinc API function was called with variadic arguments.
Previously the Thinc Mypy plugin would treat any argument with a generic type as a
Model
instance and attempt to infer a more specific type for the return type of the function call. However, the Thinc Mypy plugin was intended to only be used on functions that exclusively accept and returnModel
instances. Since the plugin accepted overly broad input, it would sometimes end up trying to access the second generic type argument for a generic type instance with only a single argument. This resulted in the plugin crashing.This specifically manifested itself whenever variadic arguments were passed to a Thinc API function. Mypy passes the type of variadic arguments as
List[Model[InT, OutT]]
. The Thinc Mypy plugin would look at this type and attempt to treat it as an unwrappedModel
type since the plugin would allow any generic type as an argument type annotation. Later on the plugin would attempt to retrieve the output type of the "Model". SinceList
accepts only a single generic argument, attempting to accesstype.args[1]
would cause the crash.These changes fix this by restricting the input on which the Thinc Mypy plugin operates. Specifically each argument and the return type must:
Instance
,thinc.model.Model
type andNotably these restrictions prevent the Thinc Mypy plugin from working on subclasses of
thinc.model.Model
. While this plugin previously had some support forModel
subclasses, this behavior was not documented and unintentional.Model
subclasses were only properly handled if their first two generic type arguments had the same meaning asModel
's generic type arguments.Support for
Model
subclasses may be restored in the future through the use of Mypy'smap_instance_to_supertype
function. I just haven't figured out how to use it yet 😅Fixes #519