-
-
Notifications
You must be signed in to change notification settings - Fork 10
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
Static Typing & Type Checking Support #100
Conversation
- Add: Type annotations where explicitly needed. - Add: Type annotations for response RE patterns and `bytes` versions of control sequences. - Change: Define `Pm()` as a `def` function, instead of a lambda. - Change: Refactor `x_parse_color()`. - Change: Use `tuple` instead of `typing.Tuple`. - Change: Re-organize some control sequences. - Change: Make definition grouping comments more visible.
- Add: Ignore type checking errors where necessary. - Change: Use `-1` as default value of `_tty_fd` i.e to indicate "no TTY", instead of `None`. - Change: Remove type annotations where not explicitly required. - Change: Correct and update type annotations. - Change: Refactor some decorators where necessary. - Change: Include `None` in the return type of all functions decorated with `@unix_tty_only`, for documentation purposes.
- Change: Correct and update type annotations. - Change: Use `None` as default value of *fg* and *bg* parameters, instead of an empty tuple.
- Add: Variable annotations. - Change: Improve readablility and logic. - Change: Reduce re-use of variables. - Change: Rename some variables for clarity.
- Add: `HEX_RGB_FMT` and `ColorType` in `.utils`. - Add: Overload signatures for type-checking. - Change: Simplify HEX string conversion. - Change: Simplify return type annotation using a type alias. - Change: Include overload signatures in the docstring.
- Add: Complete type annotations. - Change: Specialize type checking error ignore comment.
- Add: Ignore type checking error for implicit `__class__` reference. - Change: Refactor `AlignedPadding.get_padded_size()` for performance and remove the no-longer-needed type checking error ignore comment. - Change: Specialize type checking error ignore comments.
- Change: Update type annotations. - Change: Use `getattr()` instead of the attribute reference operator for abitrary function attributes.
- Change: Remove the no-longer-neccessary instance checks for arguments of: - set_cell_ratio() - set_query_timeout() - Change: Update the functions' docstrings.
- Change: Update test for `set_cell_ratio()` and `get_cell_ratio()`.
Starting work on the Renderable API ( Work on this PR will be on hold pending the redesign of the API in a separate PR. I've thought and planned out most, if not all aspects of the new design but the implementation and particularly, rewriting the tests will still take a while. |
- Change: Update typing in `RenderableMeta`. - Change: Update typing in `Renderable`. - Properly type-hint attributes. - Properly type-hint `frame_count`. - Properly type-hint `_init_render_(); define overload signatures. - Properly type-hint `_get_frame_count_()`. - Correct typing for retrieval of render data/args in `draw()`. - Change: Correct `Renderable` and `RenderableMeta` types in `._types`. - Change: Use actual class name instead of `__class__`.
- Add: Export `OptionalPaddingT` from `.renderable`. - Add: `OptionalPaddingT` to `.renderable`'s docs. - Add: `sphinx_toolbox.more_autodoc.typevars` sphinx extension.
- Add: `._associated` to indicate the association state of a namespace class. - Change: Make `._RENDER_CLS` compatible with static typing. - Remove `None` as possible value. - No longer has a default value; simply undefined for unassociated namespace classes. - Change: Update affected tests.
- Add: Type hints for attributes. - Change: Update typing in: - `ArgsDataNamespaceMeta` - `ArgsDataNamespace` - `ArgsNamespaceMeta` - `ArgsNamespace` - `DataNamespaceMeta` - `DataNamespace` - Change: Update existing attribute type hints. - Change: Properly type-hint methods. - Change: Update signatures of `__{get,set,del}attr__` methods: - Use complete signatures. - Rename parameter *attr* -> *name*. - Add parameter and return type hints. - Change: Use actual class names instead of `__class__`. - Change: `typing.Type` -> `type`.
- Add: Type hints for attributes. - Change: Update typing in: - `RenderArgsData` - `RenderArgs` - `RenderData` - Change: Update existing attribute type hints. - Change: Properly type-hint methods. - Change: Use actual class names instead of `__class__`. - Change: `typing.Type` -> `type`. - Change: Update render data subscription across `Renderable`.
- Change: Return instances of `RenderArgs` instead of `type(self)` in `.convert()` and `.update()`.
- Add: Note about `__getitem__()` return type.
- Change: `typing.NamedTuple` -> `typing_extensions.NamedTuple`. - Chaneg: Use actual class name instead of `__class__`.
- Add: Mark `ArgsNamespace` as providing dataclass-like behavior. - Constructor arguments are checked against field definitions. - Fields are marked as read-only. - ... (maybe) - Change: Mark `__setattr__()` as not to be called. Also results in an indirect type checking error for assignment to abitrary instance attributes.
- Add: Overload signatures for `RenderArgs.update()`. - Add: Document *namespace* pseudo parameter. - Change: Make the first argument of `.update()` positional-only. - Already dropped Python 3.7 support.
- Add: Type hints for private attributes. - Change: Refactor cached frame retrieval and validation. - Significantly better performance. - More static typing friendly. - Change: Properly type-hint methods.
- Add: `._renderable_data`. - Add: Specify type of render data subscription result. - Change: Use `._renderable_data` instead of subscripting `._render_data` all the time.
- Change: Call special method on the class, not instance. - Change: Disable `type-abstract` mypy error for all subpackages that use `RenderArgs` and `RenderData`. - Change: Remove some "type: ignore" comments.
- Change: Remove instance checks on arguments of functions, class contructors and methods, along with the corresponding `TypeError`s raised when invalid. - Instance checks are costly, especially when they fail (i.e evaluate to `False`). - Static typing is being incorporated. I took a look across a number of stdlib modules written in pure Python and most actually don't validate argument types. They just assume the arguments are of the expected type and use as-is. Only the interfaces implemented in C perform argument type validation.
- Change: Remove argument type validation tests. - Change: Remove instance and shape checks for return values. These are now achieved via static type checking.
- Change: Optimize `{RenderArgs,RenderData}.__getitem__()` for unashable argument types. - Change: Import required functions directly from `.utils` at package top level. - Change: Use `type(x) is bool` instead of `isinstance(x, bool)` since `bool` cannot be subclassed. - Change: Optimize compatibility validation of argument namespaces in `RenderArgs` initialization. - Change: Update the description of `TypeError`s raised by `{RenderArgs,RenderData}.__getitem__()`.
- Change: Update the generic description of `ValueError`s (raised by the `Renderable` and `RenderIterator` constructors).
- Add: "py.typed" file at package source top level and include as package data.
- Change: Update the guidelines for type annotations.
- Add: Make target for pre-commit checks. - Add: GH workflow.
image
andwidget
sub-packages as those should go through massive changes real soon, which should come along with static typing.typing_extensions
dependency.mypy
dev dependency.mypy
.Background
I've always been quite on the opposing side concerning this - thus far, annotations have only for documentation purposes - but I've come to realize the potential benefits of proper static type checking, both to the project itself and to its users.
That said, I'm still quite reserved about this as I've also realized this area is quite a slippery slope. It's just a thin line between adequate type hinting for type checking and spending valuable time writing unreadable or non-concise code just to satisfy a static type checker... and I'm not and will never be willing to cross that line (at least, not within this project).
One must understand and always keep in mind that Python is not a statically-typed language and really wasn't designed from the ground to be used that way but I'm willing to employ static typing to the extent that it doesn't result in poorer design, implementation or performance than dynamic typing.
Personally, I tend to play to the strengths of whatever language I use, which in the case of Python (IMHO) is majorly the fact that it's highly dynamic (in most cases) and fosters design and implementation of that kind. I tend to use quite a lot of these aspects of Python where reasonably applicable but will now try to find compromises where and when feasible.