Conversation
- Introduce packages/special/types.py with DBCursor Protocol - Add/ tighten type hints across special/, sqlcompleter, sqlexecute, clibuffer/toolbar/style, config, filepaths, lexer, completion_refresher, key_bindings - Remove remaining mypy ignore headers in special modules - Replace Any with concrete types where safe; improve TextIO handling - Fix utils.check_if_sqlitedotcommand to handle non-str inputs safely - Remove mycli references in comments and update docstrings - Minor refactors for clarity; ruff+mypy clean
…o implicit Optional, warn on Any). Note: run with --explicit-package-bases or via tox.
…py, and utils bug fix
…pline (Unreleased at top, succinct entries)
litecli/clistyle.py
Outdated
| from __future__ import annotations | ||
|
|
||
| import logging | ||
| from typing import Dict, List, Tuple |
There was a problem hiding this comment.
When using import annotations in Python 3.9, and for any later Python without the import, dict, list, and tuple can be used in their lowercased forms, without importing from typing.
| @@ -1,3 +1,6 @@ | |||
| # type: ignore | |||
There was a problem hiding this comment.
Why is this #type: ignore needed?
There was a problem hiding this comment.
I had added mypy: ignore-errors to all the files before I started. Looks like I left them in by mistake.
litecli/clitoolbar.py
Outdated
| @@ -1,17 +1,19 @@ | |||
| from __future__ import unicode_literals | |||
| # mypy: ignore-errors | |||
There was a problem hiding this comment.
What is mypy: ignore-errors doing for us?
There was a problem hiding this comment.
I had added mypy: ignore-errors to all the files before I started. Looks like I left them in by mistake.
litecli/config.py
Outdated
|
|
||
|
|
||
| def load_config(usr_cfg, def_cfg=None): | ||
| def load_config(usr_cfg: str, def_cfg: Optional[str] = None) -> ConfigObj: |
There was a problem hiding this comment.
str | None is preferred by most over Optional[str].
| @@ -1,24 +1,31 @@ | |||
| from __future__ import unicode_literals | |||
There was a problem hiding this comment.
There are a few changes here unrelated to type hinting.
litecli/packages/parseutils.py
Outdated
|
|
||
|
|
||
| def last_word(text, include="alphanum_underscore"): | ||
| def last_word(text: str, include: str = "alphanum_underscore") -> str: |
There was a problem hiding this comment.
The type of include could even be a Literal of the keys of cleanup_regex.
| case_sensitive=True, | ||
| ) | ||
| def status(cur, **_): | ||
| def status(cur: DBCursor, **_: Any) -> List[Tuple]: |
There was a problem hiding this comment.
As a matter of style, there isn't much purpose in typing **_: Any. But it does no harm.
|
|
||
| @export | ||
| def set_favorite_queries(config): | ||
| def set_favorite_queries(config: Any) -> None: |
There was a problem hiding this comment.
Is Any the best we can do for config?
There was a problem hiding this comment.
I was looking at mycli for this and it wasn't typed so I just went to Any.
rolandwalker
left a comment
There was a problem hiding this comment.
I would highly recommend replacing the capitalized versions of types with lowercased versions for builtins such as tuple. Python 3.9 will be EOL soon, and we even can remove from __future__ import annotations if support for 3.9 is removed.
Replace Dict, List, Tuple with dict, list, tuple. Replace Optional[str] with str | None.
|
I will take a look at this pr over the weekend. |
kracekumar
left a comment
There was a problem hiding this comment.
lgtm as a first step to introduce the type hints. We can improve over time 👍🏾
|
|
||
|
|
||
| def cli_is_multiline(cli): | ||
| def cli_is_multiline(cli: Any) -> Filter: |
There was a problem hiding this comment.
I understand sometimes types can be complicated to express so Any is preferred. Is it possible to add type here? If not documenting reason to use Any can be useful later to replace it with better type. I suspect cli by default is of the type, Any.
There was a problem hiding this comment.
I'll have to come back to the use of Any and fix them up.
litecli/completion_refresher.py
Outdated
| return [(None, None, None, "Auto-completion refresh restarted.")] | ||
| else: | ||
| if executor.dbname == ":memory:": | ||
| if executor.dbname == ":memory": |
There was a problem hiding this comment.
This one seems non-type change.
There was a problem hiding this comment.
Should we use something like executor.dbname.startswith(":memory")?
There was a problem hiding this comment.
Good catch. I'll fix it.
I don't think we could use startswith() here. I think it has to be an exact match.
litecli/packages/prompt_utils.py
Outdated
| * False if the query is destructive and the user doesn't want to proceed. | ||
| def convert(self, value: bool | str, param: click.Parameter | None, ctx: click.Context | None) -> bool: | ||
| if isinstance(value, bool): | ||
| return bool(value) |
There was a problem hiding this comment.
We can just return value right like return value right?
| @@ -1,3 +1,5 @@ | |||
| # mypy: ignore-errors | |||
There was a problem hiding this comment.
Is there a way to ignore all the errors in the directory rather than at each file in test directory?
Description
Add mypy based type checking.
Thanks to @rolandwalker for adding type hints to mycli. I've used that as inspiration and reference to do the same for litecli.
Checklist
CHANGELOG.mdfile.