Refactor(Optimizer): improve typing coverage of optimizer modules#7446
Refactor(Optimizer): improve typing coverage of optimizer modules#7446OutSquareCapital wants to merge 21 commits intotobymao:mainfrom
Conversation
…alized`. the caller site is currently untypted anyway
… function body to avoid redundant/type unsafe double isinstance check
…y_integer_cast`. trying with overloads
sqlglot/optimizer/simplify.py
Outdated
|
|
||
| @annotate_types_on_change | ||
| def simplify_literals(self, expression, root=True): | ||
| def simplify_literals(self, expression, root: bool = True): |
There was a problem hiding this comment.
Should we type expression and include a return type as well here?
There was a problem hiding this comment.
It wasn't really possible with the code as it was, but then I remembered that TypeIs is perfectly usable with typing_extensions , so now yes, fully typed!
This also open the door for lots of improvements at other places.
FYI, TypeIs is what ppl often think TypeGuard do
sqlglot/optimizer/simplify.py
Outdated
| def absorb_and_eliminate(self, expression, root=True): | ||
| def absorb_and_eliminate(self, expression: object, root: bool = True): |
There was a problem hiding this comment.
Why object? Should we add a return type?
There was a problem hiding this comment.
My rule is to make the input as wide as possible and the output as narrow as possible. mypy won't let pass object as soon as we do something more specific than the likes of __eq__(), __str__(), or __dict__(), so it's permissive but strict at the same time (unlike Any for example). Narrowing the type would be incorrect as this would be an arbitrary decision. I added object as a return type tho.
sqlglot/optimizer/simplify.py
Outdated
| def uniq_sort(self, expression, root=True): | ||
| def uniq_sort(self, expression: object, root: bool = True): |
There was a problem hiding this comment.
Added object return type. Same logic as remove_complements
sqlglot/optimizer/simplify.py
Outdated
| def remove_complements(self, expression, root=True): | ||
| def remove_complements(self, expression: object, root: bool = True): |
There was a problem hiding this comment.
Added object return type. Since we can take any object and either return an Expr or the object itself.
sqlglot/optimizer/simplify.py
Outdated
| def _simplify_comparison(self, expression, left, right, or_=False): | ||
| def _simplify_comparison( | ||
| self, expression: exp.Expr, left: exp.Expr, right: exp.Expr, or_: bool = False | ||
| ): |
There was a problem hiding this comment.
Ditto, re: return type.
There was a problem hiding this comment.
My bad, this was a miss on my part. Fixed to exp.Expr | None.
sqlglot/optimizer/simplify.py
Outdated
| def simplify_connectors(self, expression: exp.Expr, root: bool = True): | ||
| def _simplify_connectors(expression: exp.Expr, left: exp.Expr, right: exp.Expr): |
There was a problem hiding this comment.
Could be narrowed to -> exp.Expr thanks to the _simplify_comparison fix
|
|
||
|
|
||
| def eval_boolean( | ||
| expression: object, a: SupportsComparison, b: SupportsComparison |
There was a problem hiding this comment.
here is a good example to explain why it's unecessary to use anything else than object:
each path will explicitely check the instance type, so it will always narrow from object to the specific check. Or else, we return None.
So really it can be any object as an input.
|
To clarify: the goal is to gradually add types, since
The latter will be revisited in the future, hopefully with the help of more context. |
Details
WIP
This is a work in progress. But since those files are very untyped ATM, it's better to split up in various passes. This is the first one, focusing on public level and simplify module.
datetime import
I changed the
import datetimetofrom datetime import x, y, z. It's more concise when thedatetimeobject are needed, but most importantly it's much less confusing.Fault is on Python for sure for the API design, but since
datetimeis both a module and an object, anddatetime.datecan represent both a method and an object, IMO it's preferrable.Partial typing
I skipped various methods/functions (or partially typed them like
simplify_literals).This is intentionnal. ATM there's various untypable behaviors, like "unsafe" non-none checks on
Exprproperties/args.This would require changing the actual runtime behavior, which is out-of-scope here.