ADR Suggestion Type hinting
#124
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
General
Since Python is a dynamic language, types are not declared before assignment, which makes it easy to accidentally pass objects of wrong types to arguments. Python is attempting to remedy this issue with type hints, which allow coders to hint at what type any object will be. Type hints does not change functionality of code, but is merely a tool which allows type-checkers to find errors and advanced IDE´s to more easily suggest code.
Current Implementation
Currently we are using type-hinting very loosely, writing type-hints in arguments and return types in most places, but often using the wrong types. Since type-hinting does not change functionality, this is not a critical issue, but it does mean that using a type-checker provides little-to-no help in finding errors in written code. We also use
TypeVarsandNewTypewrong in many places in our code.Proposed Implementation
I here propose that we add type-checking with
mypyas a requirement before accepting new PR's. In other words, I propose that we properly type hint all our code so that we may benefit from error-finding with type-checkers.if TYPE_CHECKINGWhen importing classes and functions merely for type-hinting code, one should put those import statements withing an
if TYPE_CHECKINGblock to avoid too many imports, and in particular, to avoid cyclic imports:type variables
TypeVarTypeVarsare generic "wildcard" types which doesn't reflect any specific type. They are used when you want to type-hint that a certain argument type is also the one returned (or used elsewhere), no matter what type that might actually be, but just simply that they are the same:Here
Interfaceis theTypeVarand the above is the preferred method to denyTypeVars. TheTypeVarassumes the first type it is passed and then checks for that when used elsewhere in the same context.TypeVarscan also be constrained to only accept specific types:AnyStrhere is a type variable constrained to only accept the typesTextorbytes, and only 1 of them within a given context (i.e.AnyStrcan't be used for bothTextandbyteswithin a single method).TypeVarscan also be bound to an upper type:The type variable
Descriptorshere will acceptDescriptorNumberand any of its subclasses, but again, only 1 specific type within a given context.A type variable can't be both bound and constrained.
Since
TypeVarsare local and context-dependent, they should be defined withinSince
TypeVarsare generic types, I believe they should be avoided in favour of explicit types whenever possible. But in cases where explicit types are impossible, theTypeVarshould have a self-explanatory name, to ease reading of the type. I.e. noTypeVarswith names like:_Uor similar, like what currently exists in our codebase.Type aliases
Python allows type aliases such as:
In this type alias,
Vectoris a synonym forlist[float]. I propose to discourage/disallow type aliases, as it often makes types harder to read when reading code, unless the alias is well-known. Each new type alias should be proposed in anADR Suggestionbefore being implemented due to potentially making the code harder to read.NewTypeIt is possible to create new types which are subclasses of existing types (or other
NewTypes), with the use ofNewType. For example, we could have a subtype of int:This new type "
Iterator" is still anintand anyintfunction call will work on it, returning aninttype, butintsare notIteratorswhen type-checking, allowing for more complex type-checking. Like with type aliases, I propose discouraging/disallowing this for the same reason as with type-aliases, as it easily makes code more difficult to read, unless all the new types are well-known. Again, exceptions to this rule can be made but should require andADR Suggestion.Beta Was this translation helpful? Give feedback.
All reactions