Skip to content

Commit 3c4b677

Browse files
committed
Add the version to get ty working
1 parent f4c3052 commit 3c4b677

File tree

9 files changed

+69
-40
lines changed

9 files changed

+69
-40
lines changed

litecli/clistyle.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
from __future__ import annotations
22

33
import logging
4-
4+
from typing import cast
55

66
import pygments.styles
7-
from pygments.token import string_to_tokentype, Token
8-
from pygments.style import Style as PygmentsStyle
9-
from pygments.util import ClassNotFound
7+
from prompt_toolkit.styles import Style, merge_styles
108
from prompt_toolkit.styles.pygments import style_from_pygments_cls
11-
from prompt_toolkit.styles import merge_styles, Style
129
from prompt_toolkit.styles.style import _MergedStyle
10+
from pygments.style import Style as PygmentsStyle
11+
from pygments.token import Token, _TokenType, string_to_tokentype
12+
from pygments.util import ClassNotFound
1313

1414
logger = logging.getLogger(__name__)
1515

1616
# map Pygments tokens (ptk 1.0) to class names (ptk 2.0).
17-
TOKEN_TO_PROMPT_STYLE: dict[Token, str] = {
17+
TOKEN_TO_PROMPT_STYLE: dict[_TokenType, str] = {
1818
Token.Menu.Completions.Completion.Current: "completion-menu.completion.current",
1919
Token.Menu.Completions.Completion: "completion-menu.completion",
2020
Token.Menu.Completions.Meta.Current: "completion-menu.meta.completion.current",
@@ -43,10 +43,10 @@
4343
}
4444

4545
# reverse dict for cli_helpers, because they still expect Pygments tokens.
46-
PROMPT_STYLE_TO_TOKEN: dict[str, Token] = {v: k for k, v in TOKEN_TO_PROMPT_STYLE.items()}
46+
PROMPT_STYLE_TO_TOKEN: dict[str, _TokenType] = {v: k for k, v in TOKEN_TO_PROMPT_STYLE.items()}
4747

4848

49-
def parse_pygments_style(token_name: str, style_object: PygmentsStyle | dict, style_dict: dict[str, str]) -> tuple[Token, str]:
49+
def parse_pygments_style(token_name: str, style_object: PygmentsStyle | dict, style_dict: dict[str, str]) -> tuple[_TokenType, str]:
5050
"""Parse token type and style string.
5151
5252
:param token_name: str name of Pygments token. Example: "Token.String"
@@ -111,4 +111,5 @@ class OutputStyle(PygmentsStyle):
111111
default_style = ""
112112
styles = style
113113

114-
return OutputStyle
114+
# mypy does not complain only ty complains: error[invalid-return-type]: Return type does not match returned value. Hence added cast.
115+
return cast(OutputStyle, PygmentsStyle)

litecli/completion_refresher.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
from __future__ import annotations
22

33
import threading
4+
from collections import OrderedDict
45
from typing import Callable
56

67
from .packages.special.main import COMMANDS
7-
from collections import OrderedDict
8-
98
from .sqlcompleter import SQLCompleter
109
from .sqlexecute import SQLExecute
1110

@@ -94,7 +93,7 @@ def _bg_refresh(
9493
# break statement.
9594
continue
9695

97-
for callback in callbacks:
96+
for callback in callbacks: # ty: ignore[not-iterable]
9897
callback(completer)
9998

10099

litecli/main.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,20 @@
1212
from datetime import datetime
1313
from io import open
1414

15+
from litecli import sqlexecute
16+
1517
try:
1618
from sqlean import OperationalError, sqlite_version
1719
except ImportError:
1820
from sqlite3 import OperationalError, sqlite_version
1921
from time import time
20-
from typing import Any, Iterable
22+
from typing import Any, Iterable, cast
2123

2224
import click
2325
import sqlparse
2426
from cli_helpers.tabular_output import TabularOutputFormatter, preprocessors
2527
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
26-
from prompt_toolkit.completion import DynamicCompleter
28+
from prompt_toolkit.completion import Completion, DynamicCompleter
2729
from prompt_toolkit.document import Document
2830
from prompt_toolkit.enums import DEFAULT_BUFFER, EditingMode
2931
from prompt_toolkit.filters import HasFocus, IsDone
@@ -35,8 +37,6 @@
3537
)
3638
from prompt_toolkit.lexers import PygmentsLexer
3739
from prompt_toolkit.shortcuts import CompleteStyle, PromptSession
38-
from typing import cast
39-
from prompt_toolkit.completion import Completion
4040

4141
from .__init__ import __version__
4242
from .clibuffer import cli_is_multiline
@@ -53,8 +53,6 @@
5353
from .sqlcompleter import SQLCompleter
5454
from .sqlexecute import SQLExecute
5555

56-
click.disable_unicode_literals_warning = True
57-
5856
# Query tuples are used for maintaining history
5957
Query = namedtuple("Query", ["query", "successful", "mutating"])
6058

@@ -84,7 +82,7 @@ def __init__(
8482
self.key_bindings = c["main"]["key_bindings"]
8583
special.set_favorite_queries(self.config)
8684
self.formatter = TabularOutputFormatter(format_name=c["main"]["table_format"])
87-
self.formatter.litecli = self
85+
self.formatter.litecli = self # ty: ignore[unresolved-attribute]
8886
self.syntax_style = c["main"]["syntax_style"]
8987
self.less_chatty = c["main"].as_bool("less_chatty")
9088
self.show_bottom_toolbar = c["main"].as_bool("show_bottom_toolbar")
@@ -200,11 +198,14 @@ def change_db(self, arg: str | None, **_: Any) -> Iterable[tuple]:
200198
self.sqlexecute.connect(database=arg)
201199

202200
self.refresh_completions()
201+
# guard so that ty doesn't complain
202+
dbname = self.sqlexecute.dbname if self.sqlexecute is not None else ""
203+
203204
yield (
204205
None,
205206
None,
206207
None,
207-
'You are now connected to database "%s"' % (self.sqlexecute.dbname),
208+
'You are now connected to database "%s"' % (dbname),
208209
)
209210

210211
def execute_from_file(self, arg: str | None, **_: Any) -> Iterable[tuple[Any, ...]]:

litecli/packages/special/__init__.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# ruff: noqa
22

33
from __future__ import annotations
4+
from types import FunctionType
45

56
from typing import Callable, Any
67

@@ -9,8 +10,9 @@
910

1011
def export(defn: Callable[..., Any]) -> Callable[..., Any]:
1112
"""Decorator to explicitly mark functions that are exposed in a lib."""
12-
globals()[defn.__name__] = defn
13-
__all__.append(defn.__name__)
13+
if isinstance(defn, FunctionType):
14+
globals()[defn.__name__] = defn
15+
__all__.append(defn.__name__)
1416
return defn
1517

1618

litecli/packages/special/favoritequeries.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# -*- coding: utf-8 -*-
22
from __future__ import annotations
33

4+
import builtins
45
from typing import Any, cast
56

67

@@ -39,7 +40,7 @@ class FavoriteQueries(object):
3940
def __init__(self, config: Any) -> None:
4041
self.config = config
4142

42-
def list(self) -> list[str]:
43+
def list(self) -> builtins.list[str]:
4344
section = cast(dict[str, str], self.config.get(self.section_name, {}))
4445
return list(section.keys())
4546

litecli/sqlexecute.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
from __future__ import annotations
22

33
import logging
4-
from typing import Any, Generator, Iterable
5-
64
from contextlib import closing
5+
from typing import Any, Generator, Iterable
76

87
try:
98
import sqlean as sqlite3
@@ -13,12 +12,13 @@
1312
except ImportError:
1413
import sqlite3
1514
from sqlite3 import OperationalError
16-
from litecli.packages.special.utils import check_if_sqlitedotcommand
17-
18-
import sqlparse
1915
import os.path
2016
from urllib.parse import urlparse
2117

18+
import sqlparse
19+
20+
from litecli.packages.special.utils import check_if_sqlitedotcommand
21+
2222
from .packages import special
2323

2424
_logger = logging.getLogger(__name__)
@@ -88,7 +88,8 @@ def connect(self, database: str | None = None) -> None:
8888
if not os.path.exists(db_dir_name):
8989
raise Exception("Path does not exist: {}".format(db_dir_name))
9090

91-
conn = sqlite3.connect(database=db_name, isolation_level=None, uri=uri)
91+
# sqlean exposes the connect method during run-time
92+
conn = sqlite3.connect(database=db_name, isolation_level=None, uri=uri) # ty: ignore[possibly-missing-attribute]
9293
conn.text_factory = lambda x: x.decode("utf-8", "backslashreplace")
9394
if self.conn:
9495
self.conn.close()

pyproject.toml

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@ dependencies = [
1515
"prompt-toolkit>=3.0.3,<4.0.0",
1616
"pygments>=1.6",
1717
"sqlparse>=0.4.4",
18-
"setuptools", # Required by llm commands to install models
18+
"setuptools", # Required by llm commands to install models
1919
"pip",
2020
"llm>=0.25.0",
21+
"ty>=0.0.2",
2122
]
2223

2324
[build-system]
@@ -87,3 +88,23 @@ exclude = [
8788
'^\.pytest_cache/',
8889
'^\.ruff_cache/',
8990
]
91+
92+
93+
[tool.ty.environment]
94+
python-version = "3.9"
95+
root = ["litecli"]
96+
97+
[tool.ty.rules]
98+
unresolved-import = "ignore"
99+
100+
[tool.ty.src]
101+
exclude = [
102+
'**/build/',
103+
'**/dist/',
104+
'**/.tox/',
105+
'**/.venv/',
106+
'**/.mypy_cache/',
107+
'**/.pytest_cache/',
108+
'**/.ruff_cache/',
109+
'tests/**'
110+
]

tests/test_main.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,28 @@
11
# mypy: ignore-errors
22

33
import os
4-
from collections import namedtuple
5-
from textwrap import dedent
64
import shutil
5+
from collections import namedtuple
76
from datetime import datetime
7+
from textwrap import dedent
88
from unittest.mock import patch
99

1010
import click
1111
import pytest
1212
from click.testing import CliRunner
13+
from utils import create_db, db_connection, dbtest, run
1314

14-
from litecli.main import cli, LiteCli
15+
from litecli.main import LiteCli, cli
1516
from litecli.packages.special.main import COMMANDS as SPECIAL_COMMANDS
16-
from utils import dbtest, run, create_db, db_connection
1717

1818
test_dir = os.path.abspath(os.path.dirname(__file__))
1919
project_dir = os.path.dirname(test_dir)
2020
default_config_file = os.path.join(project_dir, "tests", "liteclirc")
2121

2222
CLI_ARGS = ["--liteclirc", default_config_file, "_test_db"]
2323

24+
clickoutput: str
25+
2426

2527
@dbtest
2628
def test_execute_arg(executor):
@@ -237,7 +239,7 @@ def stub_terminal_size():
237239

238240
old_func = shutil.get_terminal_size
239241

240-
shutil.get_terminal_size = stub_terminal_size
242+
shutil.get_terminal_size = stub_terminal_size # ty: ignore[invalid-assignment]
241243
lc = LiteCli()
242244
assert isinstance(lc.get_reserved_space(), int)
243245
shutil.get_terminal_size = old_func

tests/utils.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
# -*- coding: utf-8 -*-
22
# mypy: ignore-errors
33

4+
import multiprocessing
45
import os
5-
import time
66
import signal
7-
import platform
8-
import multiprocessing
7+
import sys
8+
import time
99
from contextlib import closing
10+
1011
import pytest
1112

1213
try:
@@ -75,8 +76,8 @@ def send_ctrl_c_to_pid(pid, wait_seconds):
7576
"""Sends a Ctrl-C like signal to the given `pid` after `wait_seconds`
7677
seconds."""
7778
time.sleep(wait_seconds)
78-
system_name = platform.system()
79-
if system_name == "Windows":
79+
# ty, is aware of sys.platform and not platform.system. See: https://github.com/astral-sh/ty/issues/2033
80+
if sys.platform == "win32":
8081
os.kill(pid, signal.CTRL_C_EVENT)
8182
else:
8283
os.kill(pid, signal.SIGINT)

0 commit comments

Comments
 (0)