Skip to content

Commit 6a47325

Browse files
committed
🏷️ fix types
1 parent 1800d49 commit 6a47325

File tree

6 files changed

+38
-45
lines changed

6 files changed

+38
-45
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,5 +121,5 @@ warn_return_any = true
121121
warn_unused_configs = true
122122

123123
[[tool.mypy.overrides]]
124-
module = "pytimeparse2.*"
124+
module = "pytimeparse2.*,factory.*,docker.*"
125125
ignore_missing_imports = true

requirements_dev.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ simplejson>=3.19.1
1313
types-simplejson
1414
sqlalchemy
1515
sqlalchemy-utils
16+
types-sqlalchemy-utils
1617
tox
1718
tqdm>=4.65.0
1819
types-tqdm

tests/conftest.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
from docker.errors import NotFound
2020
from docker.models.containers import Container
2121
from faker import Faker
22-
from mysql.connector import MySQLConnection, errorcode
22+
from mysql.connector import CMySQLConnection, MySQLConnection, errorcode
23+
from mysql.connector.pooling import PooledMySQLConnection
2324
from requests import HTTPError
2425
from sqlalchemy import create_engine
2526
from sqlalchemy.engine import Engine
@@ -236,7 +237,7 @@ def mysql_credentials(pytestconfig: Config) -> MySQLCredentials:
236237
@pytest.fixture(scope="session")
237238
def mysql_instance(mysql_credentials: MySQLCredentials, pytestconfig: Config) -> t.Iterator[MySQLConnection]:
238239
container: t.Optional[Container] = None
239-
mysql_connection: t.Optional[MySQLConnection] = None
240+
mysql_connection: t.Optional[t.Union[PooledMySQLConnection, MySQLConnection, CMySQLConnection]] = None
240241
mysql_available: bool = False
241242
mysql_connection_retries: int = 15 # failsafe
242243

@@ -310,15 +311,15 @@ def mysql_instance(mysql_credentials: MySQLCredentials, pytestconfig: Config) ->
310311
if not mysql_available and mysql_connection_retries <= 0:
311312
raise ConnectionAbortedError("Maximum MySQL connection retries exhausted! Are you sure MySQL is running?")
312313

313-
yield
314+
yield # type: ignore[misc]
314315

315316
if use_docker and container is not None:
316317
container.kill()
317318

318319

319320
@pytest.fixture()
320321
def mysql_database(mysql_instance: t.Generator, mysql_credentials: MySQLCredentials) -> t.Iterator[Engine]:
321-
yield
322+
yield # type: ignore[misc]
322323

323324
engine: Engine = create_engine(
324325
"mysql+pymysql://{user}:{password}@{host}:{port}/{database}".format(

tests/func/sqlite3_to_mysql_test.py

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
from _pytest.capture import CaptureFixture
1414
from _pytest.logging import LogCaptureFixture
1515
from faker import Faker
16-
from mysql.connector import MySQLConnection, errorcode
16+
from mysql.connector import CMySQLConnection, MySQLConnection, errorcode
17+
from mysql.connector.pooling import PooledMySQLConnection
1718
from pytest_mock import MockFixture
1819
from sqlalchemy import MetaData, Table, create_engine, inspect, select, text
1920
from sqlalchemy.engine import Connection, CursorResult, Engine, Inspector, Row
@@ -31,21 +32,21 @@ class TestSQLite3toMySQL:
3132
@pytest.mark.parametrize("quiet", [False, True])
3233
def test_no_sqlite_file_raises_exception(self, quiet: bool) -> None:
3334
with pytest.raises(ValueError) as excinfo:
34-
SQLite3toMySQL(quiet=quiet)
35+
SQLite3toMySQL(quiet=quiet) # type: ignore
3536
assert "Please provide an SQLite file" in str(excinfo.value)
3637

3738
@pytest.mark.init
3839
@pytest.mark.parametrize("quiet", [False, True])
3940
def test_invalid_sqlite_file_raises_exception(self, faker: Faker, quiet: bool) -> None:
4041
with pytest.raises((FileNotFoundError, IOError)) as excinfo:
41-
SQLite3toMySQL(sqlite_file=faker.file_path(depth=1, extension=".sqlite3"), quiet=quiet)
42+
SQLite3toMySQL(sqlite_file=faker.file_path(depth=1, extension=".sqlite3"), quiet=quiet) # type: ignore
4243
assert "SQLite file does not exist" in str(excinfo.value)
4344

4445
@pytest.mark.init
4546
@pytest.mark.parametrize("quiet", [False, True])
4647
def test_missing_mysql_user_raises_exception(self, sqlite_database: str, quiet: bool) -> None:
4748
with pytest.raises(ValueError) as excinfo:
48-
SQLite3toMySQL(sqlite_file=sqlite_database, quiet=quiet)
49+
SQLite3toMySQL(sqlite_file=sqlite_database, quiet=quiet) # type: ignore
4950
assert "Please provide a MySQL user" in str(excinfo.value)
5051

5152
@pytest.mark.init
@@ -59,7 +60,7 @@ def test_valid_sqlite_file_and_valid_mysql_credentials(
5960
quiet: bool,
6061
):
6162
with helpers.not_raises(FileNotFoundError):
62-
SQLite3toMySQL(
63+
SQLite3toMySQL( # type: ignore
6364
sqlite_file=sqlite_database,
6465
mysql_user=mysql_credentials.user,
6566
mysql_password=mysql_credentials.password,
@@ -81,7 +82,7 @@ def test_valid_sqlite_file_and_invalid_mysql_credentials_raises_access_denied_ex
8182
quiet: bool,
8283
) -> None:
8384
with pytest.raises(mysql.connector.Error) as excinfo:
84-
SQLite3toMySQL(
85+
SQLite3toMySQL( # type: ignore[call-arg]
8586
sqlite_file=sqlite_database,
8687
mysql_user=faker.first_name().lower(),
8788
mysql_password=faker.password(length=16),
@@ -112,7 +113,7 @@ def test_unspecified_mysql_error(
112113
)
113114
caplog.set_level(logging.DEBUG)
114115
with pytest.raises(mysql.connector.Error) as excinfo:
115-
SQLite3toMySQL(
116+
SQLite3toMySQL( # type: ignore[call-arg]
116117
sqlite_file=sqlite_database,
117118
mysql_user=mysql_credentials.user,
118119
mysql_password=mysql_credentials.password,
@@ -163,7 +164,7 @@ def cursor(
163164
mocker.patch.object(mysql.connector, "connect", return_value=FakeMySQLConnection())
164165
with pytest.raises(mysql.connector.Error):
165166
caplog.set_level(logging.DEBUG)
166-
SQLite3toMySQL(
167+
SQLite3toMySQL( # type: ignore[call-arg]
167168
sqlite_file=sqlite_database,
168169
mysql_user=mysql_credentials.user,
169170
mysql_password=mysql_credentials.password,
@@ -186,7 +187,7 @@ def test_bad_mysql_connection(
186187
return_value=FakeConnector(is_connected=lambda: False),
187188
)
188189
with pytest.raises((ConnectionError, IOError)) as excinfo:
189-
SQLite3toMySQL(
190+
SQLite3toMySQL( # type: ignore[call-arg]
190191
sqlite_file=sqlite_database,
191192
mysql_user=mysql_credentials.user,
192193
mysql_password=mysql_credentials.password,
@@ -214,7 +215,7 @@ def test_log_to_file(
214215
log_file: LocalPath = tmpdir.join(Path("db.log"))
215216
with pytest.raises(mysql.connector.Error):
216217
caplog.set_level(logging.DEBUG)
217-
SQLite3toMySQL(
218+
SQLite3toMySQL( # type: ignore[call-arg]
218219
sqlite_file=sqlite_database,
219220
mysql_user=faker.first_name().lower(),
220221
mysql_password=faker.password(length=16),
@@ -276,7 +277,7 @@ def test_transfer_transfers_all_tables_in_sqlite_file(
276277
mysql_insert_method: str,
277278
ignore_duplicate_keys: bool,
278279
):
279-
proc: SQLite3toMySQL = SQLite3toMySQL(
280+
proc: SQLite3toMySQL = SQLite3toMySQL( # type: ignore[call-arg]
280281
sqlite_file=sqlite_database,
281282
mysql_user=mysql_credentials.user,
282283
mysql_password=mysql_credentials.password,
@@ -317,7 +318,9 @@ def test_transfer_transfers_all_tables_in_sqlite_file(
317318
mysql_inspect: Inspector = inspect(mysql_engine)
318319
mysql_tables: t.List[str] = mysql_inspect.get_table_names()
319320

320-
mysql_connector_connection: MySQLConnection = mysql.connector.connect(
321+
mysql_connector_connection: t.Union[
322+
PooledMySQLConnection, MySQLConnection, CMySQLConnection
323+
] = mysql.connector.connect(
321324
user=mysql_credentials.user,
322325
password=mysql_credentials.password,
323326
host=mysql_credentials.host,
@@ -339,7 +342,7 @@ def test_transfer_transfers_all_tables_in_sqlite_file(
339342
""" Test if all the tables have the same indices """
340343
index_keys: t.Tuple[str, ...] = ("name", "column_names", "unique")
341344
mysql_indices: t.Tuple[ReflectedIndex, ...] = tuple(
342-
t.cast(ReflectedIndex, {key: index[key] for key in index_keys})
345+
t.cast(ReflectedIndex, {key: index[key] for key in index_keys}) # type: ignore[literal-required]
343346
for index in (chain.from_iterable(mysql_inspect.get_indexes(table_name) for table_name in mysql_tables))
344347
)
345348

@@ -484,7 +487,7 @@ def test_transfer_specific_tables_transfers_only_specified_tables_from_sqlite_fi
484487
random_sqlite_tables: t.List[str] = sample(sqlite_tables, table_number)
485488
random_sqlite_tables.sort()
486489

487-
proc: SQLite3toMySQL = SQLite3toMySQL(
490+
proc: SQLite3toMySQL = SQLite3toMySQL( # type: ignore[call-arg]
488491
sqlite_file=sqlite_database,
489492
sqlite_tables=random_sqlite_tables,
490493
mysql_user=mysql_credentials.user,
@@ -531,7 +534,7 @@ def test_transfer_specific_tables_transfers_only_specified_tables_from_sqlite_fi
531534
""" Test if all the tables have the same indices """
532535
index_keys: t.Tuple[str, ...] = ("name", "column_names", "unique")
533536
mysql_indices: t.Tuple[ReflectedIndex, ...] = tuple(
534-
t.cast(ReflectedIndex, {key: index[key] for key in index_keys})
537+
t.cast(ReflectedIndex, {key: index[key] for key in index_keys}) # type: ignore[literal-required]
535538
for index in (chain.from_iterable(mysql_inspect.get_indexes(table_name) for table_name in mysql_tables))
536539
)
537540

tests/models.py

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from sqlalchemy import (
88
BLOB,
99
CHAR,
10+
DECIMAL,
1011
JSON,
1112
REAL,
1213
TIMESTAMP,
@@ -25,19 +26,6 @@
2526
from sqlalchemy.sql.functions import current_timestamp
2627

2728

28-
class SQLiteNumeric(types.TypeDecorator):
29-
impl: t.Type[String] = types.String
30-
31-
def load_dialect_impl(self, dialect: Dialect) -> t.Any:
32-
return dialect.type_descriptor(types.VARCHAR(100))
33-
34-
def process_bind_param(self, value: t.Any, dialect: Dialect) -> str:
35-
return str(value)
36-
37-
def process_result_value(self, value: t.Any, dialect: Dialect) -> Decimal:
38-
return Decimal(value)
39-
40-
4129
class MyCustomType(types.TypeDecorator):
4230
impl: t.Type[String] = types.String
4331

@@ -118,13 +106,13 @@ class Misc(Base):
118106
char_field: Mapped[str] = mapped_column(CHAR(255), nullable=True)
119107
date_field: Mapped[date] = mapped_column(nullable=True)
120108
date_time_field: Mapped[datetime] = mapped_column(nullable=True)
121-
decimal_field: Mapped[Decimal] = mapped_column(SQLiteNumeric(10, 2), nullable=True)
122-
float_field: Mapped[Decimal] = mapped_column(SQLiteNumeric(12, 4), default=0)
109+
decimal_field: Mapped[Decimal] = mapped_column(DECIMAL(10, 2), nullable=True)
110+
float_field: Mapped[Decimal] = mapped_column(DECIMAL(12, 4), default=0)
123111
integer_field: Mapped[int] = mapped_column(default=0)
124112
if environ.get("LEGACY_DB", "0") == "0":
125-
json_field: Mapped[t.Dict[str, t.Any]] = mapped_column(JSON, nullable=True)
126-
numeric_field: Mapped[Decimal] = mapped_column(SQLiteNumeric(12, 4), default=0)
127-
real_field: Mapped[float] = mapped_column(REAL(12, 4), default=0)
113+
json_field: Mapped[t.Mapping[str, t.Any]] = mapped_column(JSON, nullable=True)
114+
numeric_field: Mapped[Decimal] = mapped_column(DECIMAL(12, 4), default=0)
115+
real_field: Mapped[float] = mapped_column(REAL(12), default=0)
128116
small_integer_field: Mapped[int] = mapped_column(SmallInteger, default=0)
129117
string_field: Mapped[str] = mapped_column(String(255), nullable=True)
130118
text_field: Mapped[str] = mapped_column(Text, nullable=True)

tests/unit/sqlite3_to_mysql_test.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def test_translate_type_from_sqlite_to_mysql_invalid_column_type(
2727
mocker: MockerFixture,
2828
quiet: bool,
2929
) -> None:
30-
proc: SQLite3toMySQL = SQLite3toMySQL(
30+
proc: SQLite3toMySQL = SQLite3toMySQL( # type: ignore[call-arg]
3131
sqlite_file=sqlite_database,
3232
mysql_user=mysql_credentials.user,
3333
mysql_password=mysql_credentials.password,
@@ -60,7 +60,7 @@ def test_translate_type_from_sqlite_to_mysql_all_valid_columns(
6060
mysql_string_type: str,
6161
mysql_text_type: str,
6262
) -> None:
63-
proc: SQLite3toMySQL = SQLite3toMySQL(
63+
proc: SQLite3toMySQL = SQLite3toMySQL( # type: ignore
6464
sqlite_file=sqlite_database,
6565
mysql_user=mysql_credentials.user,
6666
mysql_password=mysql_credentials.password,
@@ -136,7 +136,7 @@ def test_create_database_connection_error(
136136
caplog: LogCaptureFixture,
137137
quiet: bool,
138138
) -> None:
139-
proc: SQLite3toMySQL = SQLite3toMySQL(
139+
proc: SQLite3toMySQL = SQLite3toMySQL( # type: ignore[call-arg]
140140
sqlite_file=sqlite_database,
141141
mysql_user=mysql_credentials.user,
142142
mysql_password=mysql_credentials.password,
@@ -169,7 +169,7 @@ def test_create_table_cursor_error(
169169
caplog: LogCaptureFixture,
170170
quiet: bool,
171171
) -> None:
172-
proc = SQLite3toMySQL(
172+
proc = SQLite3toMySQL( # type: ignore[call-arg]
173173
sqlite_file=sqlite_database,
174174
mysql_user=mysql_credentials.user,
175175
mysql_password=mysql_credentials.password,
@@ -208,7 +208,7 @@ def test_process_cursor_error(
208208
caplog: LogCaptureFixture,
209209
quiet: bool,
210210
) -> None:
211-
proc = SQLite3toMySQL(
211+
proc = SQLite3toMySQL( # type: ignore[call-arg]
212212
sqlite_file=sqlite_database,
213213
mysql_user=mysql_credentials.user,
214214
mysql_password=mysql_credentials.password,
@@ -240,7 +240,7 @@ def test_add_indices_error(
240240
caplog: LogCaptureFixture,
241241
quiet: bool,
242242
) -> None:
243-
proc = SQLite3toMySQL(
243+
proc = SQLite3toMySQL( # type: ignore[call-arg]
244244
sqlite_file=sqlite_database,
245245
mysql_user=mysql_credentials.user,
246246
mysql_password=mysql_credentials.password,
@@ -287,7 +287,7 @@ def test_add_foreign_keys_error(
287287
caplog: LogCaptureFixture,
288288
quiet: bool,
289289
) -> None:
290-
proc = SQLite3toMySQL(
290+
proc = SQLite3toMySQL( # type: ignore[call-arg]
291291
sqlite_file=sqlite_database,
292292
mysql_user=mysql_credentials.user,
293293
mysql_password=mysql_credentials.password,

0 commit comments

Comments
 (0)