Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ endif

lint: deps build
ifneq ($(shell which black),)
black --check $(checkfiles) || (echo "Please run 'make style' to auto-fix style issues" && false)
black $(checkfiles)
endif
ruff check $(checkfiles)
ruff check --fix $(checkfiles)
mypy $(checkfiles)
#pylint $(checkfiles)
bandit -c pyproject.toml -r $(checkfiles)
Expand Down
5 changes: 3 additions & 2 deletions examples/blacksheep/server.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# pylint: disable=E0401,E0611
from typing import Union
from __future__ import annotations

from uuid import UUID

from blacksheep import Response
Expand All @@ -25,7 +26,7 @@


@app.router.get("/")
async def users_list() -> Union[UserPydanticOut]:
async def users_list() -> UserPydanticOut:
return ok(await UserPydanticOut.from_queryset(Users.all()))


Expand Down
2 changes: 2 additions & 0 deletions examples/fastapi/schemas.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

from typing import TYPE_CHECKING

from models import Users
Expand Down
14 changes: 6 additions & 8 deletions examples/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
This example demonstrates model signals usage
"""

from typing import Optional
from __future__ import annotations

from tortoise import BaseDBAsyncClient, Tortoise, fields, run_async
from tortoise.models import Model
Expand All @@ -21,33 +21,31 @@ def __str__(self):


@pre_save(Signal)
async def signal_pre_save(
sender: "type[Signal]", instance: Signal, using_db, update_fields
) -> None:
async def signal_pre_save(sender: type[Signal], instance: Signal, using_db, update_fields) -> None:
print(sender, instance, using_db, update_fields)


@post_save(Signal)
async def signal_post_save(
sender: "type[Signal]",
sender: type[Signal],
instance: Signal,
created: bool,
using_db: "Optional[BaseDBAsyncClient]",
using_db: BaseDBAsyncClient | None,
update_fields: list[str],
) -> None:
print(sender, instance, using_db, created, update_fields)


@pre_delete(Signal)
async def signal_pre_delete(
sender: "type[Signal]", instance: Signal, using_db: "Optional[BaseDBAsyncClient]"
sender: type[Signal], instance: Signal, using_db: BaseDBAsyncClient | None
) -> None:
print(sender, instance, using_db)


@post_delete(Signal)
async def signal_post_delete(
sender: "type[Signal]", instance: Signal, using_db: "Optional[BaseDBAsyncClient]"
sender: type[Signal], instance: Signal, using_db: BaseDBAsyncClient | None
) -> None:
print(sender, instance, using_db)

Expand Down
5 changes: 5 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,11 @@ show_missing = true
line-length = 100
[tool.ruff.lint]
ignore = ["E501"]
extend-select = [
"FA", # https://docs.astral.sh/ruff/rules/#flake8-future-annotations-fa
"UP", # https://docs.astral.sh/ruff/rules/#pyupgrade-up
"RUF100", # https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf
]

[tool.bandit]
exclude_dirs = ["tests", 'examples/*/_tests.py', "conftest.py"]
2 changes: 1 addition & 1 deletion tests/backends/test_capabilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class TestCapabilities(test.TestCase):
# pylint: disable=E1101

async def asyncSetUp(self) -> None:
await super(TestCapabilities, self).asyncSetUp()
await super().asyncSetUp()
self.db = connections.get("models")
self.caps = self.db.capabilities

Expand Down
3 changes: 2 additions & 1 deletion tests/benchmarks/test_bulk_create.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ def test_bulk_create_few_fields(benchmark):

data = [
BenchmarkFewFields(
level=random.choice([10, 20, 30, 40, 50]), text=f"Insert from C, item {i}" # nosec
level=random.choice([10, 20, 30, 40, 50]), # nosec
text=f"Insert from C, item {i}",
)
for i in range(100)
]
Expand Down
6 changes: 3 additions & 3 deletions tests/contrib/test_pydantic.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

class TestPydantic(test.TestCase):
async def asyncSetUp(self) -> None:
await super(TestPydantic, self).asyncSetUp()
await super().asyncSetUp()
self.Event_Pydantic = pydantic_model_creator(Event)
self.Event_Pydantic_List = pydantic_queryset_creator(Event)
self.Tournament_Pydantic = pydantic_model_creator(Tournament)
Expand Down Expand Up @@ -1392,7 +1392,7 @@ def test_exclude_readonly(self):

class TestPydanticCycle(test.TestCase):
async def asyncSetUp(self) -> None:
await super(TestPydanticCycle, self).asyncSetUp()
await super().asyncSetUp()
self.Employee_Pydantic = pydantic_model_creator(Employee)

self.root = await Employee.create(name="Root")
Expand Down Expand Up @@ -1599,7 +1599,7 @@ async def test_serialisation(self):

class TestPydanticComputed(test.TestCase):
async def asyncSetUp(self) -> None:
await super(TestPydanticComputed, self).asyncSetUp()
await super().asyncSetUp()
self.Employee_Pydantic = pydantic_model_creator(Employee)
self.employee = await Employee.create(name="Some Employee")
self.maxDiff = None
Expand Down
2 changes: 2 additions & 0 deletions tests/fields/subclass_fields.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

from enum import Enum, IntEnum
from typing import Any

Expand Down
4 changes: 3 additions & 1 deletion tests/fields/test_db_index.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

from typing import Any

from pypika_tortoise.terms import Field
Expand Down Expand Up @@ -45,7 +47,7 @@ def test_index_repr(self):
assert repr(Index(fields=("id",))) == "Index(fields=['id'])"
assert repr(Index(fields=("id", "name"))) == "Index(fields=['id', 'name'])"
assert repr(Index(fields=("id",), name="MyIndex")) == "Index(fields=['id'], name='MyIndex')"
assert repr(Index(Field("id"))) == f'Index({str(Field("id"))})'
assert repr(Index(Field("id"))) == f"Index({str(Field('id'))})"
assert repr(Index(Field("a"), name="Id")) == f"Index({str(Field('a'))}, name='Id')"
with self.assertRaises(ConfigurationError):
Index(Field("id"), fields=("name",))
Expand Down
24 changes: 15 additions & 9 deletions tests/fields/test_decimal.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class TestDecimalFields(test.TestCase):
def test_max_digits_empty(self):
with self.assertRaisesRegex(
TypeError,
"missing 2 required positional arguments: 'max_digits' and" " 'decimal_places'",
"missing 2 required positional arguments: 'max_digits' and 'decimal_places'",
):
fields.DecimalField() # pylint: disable=E1120

Expand Down Expand Up @@ -169,25 +169,31 @@ async def test_aggregate_sum_no_exist_field_with_f_expression(self):
FieldError,
"There is no non-virtual field not_exist on Model DecimalFields",
):
await testmodels.DecimalFields.all().annotate(sum_decimal=Sum(F("not_exist"))).values(
"sum_decimal"
await (
testmodels.DecimalFields.all()
.annotate(sum_decimal=Sum(F("not_exist")))
.values("sum_decimal")
)

async def test_aggregate_sum_different_field_type_at_right_with_f_expression(self):
with self.assertRaisesRegex(
FieldError, "Cannot use arithmetic expression between different field type"
):
await testmodels.DecimalFields.all().annotate(
sum_decimal=Sum(F("decimal") + F("id"))
).values("sum_decimal")
await (
testmodels.DecimalFields.all()
.annotate(sum_decimal=Sum(F("decimal") + F("id")))
.values("sum_decimal")
)

async def test_aggregate_sum_different_field_type_at_left_with_f_expression(self):
with self.assertRaisesRegex(
FieldError, "Cannot use arithmetic expression between different field type"
):
await testmodels.DecimalFields.all().annotate(
sum_decimal=Sum(F("id") + F("decimal"))
).values("sum_decimal")
await (
testmodels.DecimalFields.all()
.annotate(sum_decimal=Sum(F("id") + F("decimal")))
.values("sum_decimal")
)

async def test_aggregate_avg(self):
await testmodels.DecimalFields.create(decimal=Decimal("0"), decimal_nodec=1)
Expand Down
10 changes: 5 additions & 5 deletions tests/fields/test_fk.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,15 +120,15 @@ async def test_minimal__unfetched_contains(self):
tour = await testmodels.Tournament.create(name="Team1")
with self.assertRaisesRegex(
NoValuesFetched,
"No values were fetched for this relation," " first use .fetch_related()",
"No values were fetched for this relation, first use .fetch_related()",
):
"a" in tour.minrelations # pylint: disable=W0104

async def test_minimal__unfetched_iter(self):
tour = await testmodels.Tournament.create(name="Team1")
with self.assertRaisesRegex(
NoValuesFetched,
"No values were fetched for this relation," " first use .fetch_related()",
"No values were fetched for this relation, first use .fetch_related()",
):
for _ in tour.minrelations:
pass
Expand All @@ -137,23 +137,23 @@ async def test_minimal__unfetched_len(self):
tour = await testmodels.Tournament.create(name="Team1")
with self.assertRaisesRegex(
NoValuesFetched,
"No values were fetched for this relation," " first use .fetch_related()",
"No values were fetched for this relation, first use .fetch_related()",
):
len(tour.minrelations)

async def test_minimal__unfetched_bool(self):
tour = await testmodels.Tournament.create(name="Team1")
with self.assertRaisesRegex(
NoValuesFetched,
"No values were fetched for this relation," " first use .fetch_related()",
"No values were fetched for this relation, first use .fetch_related()",
):
bool(tour.minrelations)

async def test_minimal__unfetched_getitem(self):
tour = await testmodels.Tournament.create(name="Team1")
with self.assertRaisesRegex(
NoValuesFetched,
"No values were fetched for this relation," " first use .fetch_related()",
"No values were fetched for this relation, first use .fetch_related()",
):
tour.minrelations[0] # pylint: disable=W0104

Expand Down
10 changes: 5 additions & 5 deletions tests/fields/test_fk_uuid.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,15 @@ async def test_unfetched_contains(self):
tour = await self.UUIDPkModel.create()
with self.assertRaisesRegex(
NoValuesFetched,
"No values were fetched for this relation," " first use .fetch_related()",
"No values were fetched for this relation, first use .fetch_related()",
):
"a" in tour.children # pylint: disable=W0104

async def test_unfetched_iter(self):
tour = await self.UUIDPkModel.create()
with self.assertRaisesRegex(
NoValuesFetched,
"No values were fetched for this relation," " first use .fetch_related()",
"No values were fetched for this relation, first use .fetch_related()",
):
for _ in tour.children:
pass
Expand All @@ -129,23 +129,23 @@ async def test_unfetched_len(self):
tour = await self.UUIDPkModel.create()
with self.assertRaisesRegex(
NoValuesFetched,
"No values were fetched for this relation," " first use .fetch_related()",
"No values were fetched for this relation, first use .fetch_related()",
):
len(tour.children)

async def test_unfetched_bool(self):
tour = await self.UUIDPkModel.create()
with self.assertRaisesRegex(
NoValuesFetched,
"No values were fetched for this relation," " first use .fetch_related()",
"No values were fetched for this relation, first use .fetch_related()",
):
bool(tour.children)

async def test_unfetched_getitem(self):
tour = await self.UUIDPkModel.create()
with self.assertRaisesRegex(
NoValuesFetched,
"No values were fetched for this relation," " first use .fetch_related()",
"No values were fetched for this relation, first use .fetch_related()",
):
tour.children[0] # pylint: disable=W0104

Expand Down
10 changes: 5 additions & 5 deletions tests/fields/test_fk_with_unique.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,15 @@ async def test_student__unfetched_contains(self):
school = await testmodels.School.create(id=1024, name="School1")
with self.assertRaisesRegex(
NoValuesFetched,
"No values were fetched for this relation," " first use .fetch_related()",
"No values were fetched for this relation, first use .fetch_related()",
):
"a" in school.students # pylint: disable=W0104

async def test_stduent__unfetched_iter(self):
school = await testmodels.School.create(id=1024, name="School1")
with self.assertRaisesRegex(
NoValuesFetched,
"No values were fetched for this relation," " first use .fetch_related()",
"No values were fetched for this relation, first use .fetch_related()",
):
for _ in school.students:
pass
Expand All @@ -121,23 +121,23 @@ async def test_student__unfetched_len(self):
school = await testmodels.School.create(id=1024, name="School1")
with self.assertRaisesRegex(
NoValuesFetched,
"No values were fetched for this relation," " first use .fetch_related()",
"No values were fetched for this relation, first use .fetch_related()",
):
len(school.students)

async def test_student__unfetched_bool(self):
school = await testmodels.School.create(id=1024, name="School1")
with self.assertRaisesRegex(
NoValuesFetched,
"No values were fetched for this relation," " first use .fetch_related()",
"No values were fetched for this relation, first use .fetch_related()",
):
bool(school.students)

async def test_student__unfetched_getitem(self):
school = await testmodels.School.create(id=1024, name="School1")
with self.assertRaisesRegex(
NoValuesFetched,
"No values were fetched for this relation," " first use .fetch_related()",
"No values were fetched for this relation, first use .fetch_related()",
):
school.students[0] # pylint: disable=W0104

Expand Down
4 changes: 3 additions & 1 deletion tests/model_setup/model_bad_rel2.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
The model 'Tour' does not exist
"""

from __future__ import annotations

from typing import Any

from tortoise import fields
Expand All @@ -14,6 +16,6 @@ class Tournament(Model):


class Event(Model):
tournament: fields.ForeignKeyRelation["Any"] = fields.ForeignKeyField(
tournament: fields.ForeignKeyRelation[Any] = fields.ForeignKeyField(
"models.Tour", related_name="events"
)
2 changes: 1 addition & 1 deletion tests/model_setup/test_bad_relation_reference.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ async def asyncSetUp(self):

async def asyncTearDown(self) -> None:
await Tortoise._reset_apps()
await super(TestBadRelationReferenceErrors, self).asyncTearDown()
await super().asyncTearDown()

async def test_wrong_app_init(self):
with self.assertRaisesRegex(ConfigurationError, "No app with name 'app' registered."):
Expand Down
2 changes: 2 additions & 0 deletions tests/schema/models_fk_1.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
This is the testing Models — FK bad model name
"""

from __future__ import annotations

from typing import Any

from tortoise import fields
Expand Down
3 changes: 2 additions & 1 deletion tests/schema/models_fk_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@

class One(Model):
tournament: fields.ForeignKeyRelation[Two] = fields.ForeignKeyField(
"models.Two", on_delete="WABOOM" # type:ignore
"models.Two",
on_delete="WABOOM", # type:ignore
)
3 changes: 2 additions & 1 deletion tests/schema/models_o2o_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@

class One(Model):
tournament: fields.OneToOneRelation[Two] = fields.OneToOneField(
"models.Two", on_delete="WABOOM" # type:ignore
"models.Two",
on_delete="WABOOM", # type:ignore
)
Loading