Skip to content

Commit e0961d4

Browse files
authored
fix: fully qualify all datetime module references (#341)
To prevent any namespace collisions with signature resolution, all examples and code using the `datetime` module now use their fully qualified path (i.e. `datetime.datetime.now()`)
1 parent 3d95640 commit e0961d4

File tree

22 files changed

+152
-144
lines changed

22 files changed

+152
-144
lines changed

advanced_alchemy/_listeners.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from __future__ import annotations
44

5-
from datetime import datetime, timezone
5+
import datetime
66
from typing import TYPE_CHECKING, Any
77

88
if TYPE_CHECKING:
@@ -22,4 +22,4 @@ def touch_updated_timestamp(session: Session, *_: Any) -> None:
2222
"""
2323
for instance in session.dirty:
2424
if hasattr(instance, "updated_at"):
25-
instance.updated_at = datetime.now(timezone.utc)
25+
instance.updated_at = datetime.datetime.now(datetime.timezone.utc)

advanced_alchemy/base.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
from __future__ import annotations
55

66
import contextlib
7+
import datetime
78
import re
8-
from datetime import date, datetime
99
from typing import TYPE_CHECKING, Any, Iterator, Optional, Protocol, cast, runtime_checkable
1010
from uuid import UUID
1111

@@ -286,8 +286,8 @@ def create_registry(
286286
type_annotation_map: dict[Any, type[TypeEngine[Any]] | TypeEngine[Any]] = {
287287
UUID: GUID,
288288
core_uuid.UUID: GUID,
289-
datetime: DateTimeUTC,
290-
date: Date,
289+
datetime.datetime: DateTimeUTC,
290+
datetime.date: Date,
291291
dict: JsonB,
292292
DataclassProtocol: JsonB,
293293
}

advanced_alchemy/filters.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@
1111
Example:
1212
Basic usage with a datetime filter::
1313
14-
from datetime import datetime
14+
import datetime
1515
from advanced_alchemy.filters import BeforeAfter
1616
1717
filter = BeforeAfter(
1818
field_name="created_at",
19-
before=datetime.now(),
20-
after=datetime(2023, 1, 1),
19+
before=datetime.datetime.now(),
20+
after=datetime.datetime(2023, 1, 1),
2121
)
2222
statement = filter.append_to_statement(select(Model), Model)
2323
@@ -34,10 +34,10 @@
3434

3535
from __future__ import annotations
3636

37+
import datetime # noqa: TC003
3738
from abc import ABC, abstractmethod
3839
from collections import abc # noqa: TC003
3940
from dataclasses import dataclass
40-
from datetime import datetime # noqa: TC003
4141
from operator import attrgetter
4242
from typing import TYPE_CHECKING, Any, Generic, Literal, cast
4343

@@ -153,9 +153,9 @@ class BeforeAfter(StatementFilter):
153153

154154
field_name: str
155155
"""Name of the model attribute to filter on."""
156-
before: datetime | None
156+
before: datetime.datetime | None
157157
"""Filter results where field is earlier than this value."""
158-
after: datetime | None
158+
after: datetime.datetime | None
159159
"""Filter results where field is later than this value."""
160160

161161
def append_to_statement(self, statement: StatementTypeT, model: type[ModelT]) -> StatementTypeT:
@@ -199,9 +199,9 @@ class OnBeforeAfter(StatementFilter):
199199

200200
field_name: str
201201
"""Name of the model attribute to filter on."""
202-
on_or_before: datetime | None
202+
on_or_before: datetime.datetime | None
203203
"""Filter results where field is on or earlier than this value."""
204-
on_or_after: datetime | None
204+
on_or_after: datetime.datetime | None
205205
"""Filter results where field is on or later than this value."""
206206

207207
def append_to_statement(self, statement: StatementTypeT, model: type[ModelT]) -> StatementTypeT:

advanced_alchemy/mixins/audit.py

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

3-
from datetime import datetime, timezone
3+
import datetime
44

55
from sqlalchemy.orm import Mapped, declarative_mixin, mapped_column, validates
66

@@ -11,20 +11,20 @@
1111
class AuditColumns:
1212
"""Created/Updated At Fields Mixin."""
1313

14-
created_at: Mapped[datetime] = mapped_column(
14+
created_at: Mapped[datetime.datetime] = mapped_column(
1515
DateTimeUTC(timezone=True),
16-
default=lambda: datetime.now(timezone.utc),
16+
default=lambda: datetime.datetime.now(datetime.timezone.utc),
1717
)
1818
"""Date/time of instance creation."""
19-
updated_at: Mapped[datetime] = mapped_column(
19+
updated_at: Mapped[datetime.datetime] = mapped_column(
2020
DateTimeUTC(timezone=True),
21-
default=lambda: datetime.now(timezone.utc),
22-
onupdate=lambda: datetime.now(timezone.utc),
21+
default=lambda: datetime.datetime.now(datetime.timezone.utc),
22+
onupdate=lambda: datetime.datetime.now(datetime.timezone.utc),
2323
)
2424
"""Date/time of instance last update."""
2525

2626
@validates("created_at", "updated_at")
27-
def validate_tz_info(self, _: str, value: datetime) -> datetime:
27+
def validate_tz_info(self, _: str, value: datetime.datetime) -> datetime.datetime:
2828
if value.tzinfo is None:
29-
value = value.replace(tzinfo=timezone.utc)
29+
value = value.replace(tzinfo=datetime.timezone.utc)
3030
return value

advanced_alchemy/repository/memory/_async.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@
4040
from advanced_alchemy.utils.text import slugify
4141

4242
if TYPE_CHECKING:
43+
import datetime
4344
from collections import abc
4445
from collections.abc import Iterable
45-
from datetime import datetime
4646

4747
from sqlalchemy.ext.asyncio import AsyncSession
4848
from sqlalchemy.ext.asyncio.scoping import async_scoped_session
@@ -231,14 +231,14 @@ def _filter_on_datetime_field(
231231
self,
232232
result: list[ModelT],
233233
field_name: str,
234-
before: datetime | None = None,
235-
after: datetime | None = None,
236-
on_or_before: datetime | None = None,
237-
on_or_after: datetime | None = None,
234+
before: datetime.datetime | None = None,
235+
after: datetime.datetime | None = None,
236+
on_or_before: datetime.datetime | None = None,
237+
on_or_after: datetime.datetime | None = None,
238238
) -> list[ModelT]:
239239
result_: list[ModelT] = []
240240
for item in result:
241-
attr: datetime = getattr(item, field_name)
241+
attr: datetime.datetime = getattr(item, field_name)
242242
if before is not None and attr < before:
243243
result_.append(item)
244244
if after is not None and attr > after:

advanced_alchemy/repository/memory/_sync.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@
4242
from advanced_alchemy.utils.text import slugify
4343

4444
if TYPE_CHECKING:
45+
import datetime
4546
from collections import abc
4647
from collections.abc import Iterable
47-
from datetime import datetime
4848

4949
from sqlalchemy.orm.scoping import scoped_session
5050
from sqlalchemy.orm.strategy_options import _AbstractLoad # pyright: ignore[reportPrivateUsage]
@@ -232,14 +232,14 @@ def _filter_on_datetime_field(
232232
self,
233233
result: list[ModelT],
234234
field_name: str,
235-
before: datetime | None = None,
236-
after: datetime | None = None,
237-
on_or_before: datetime | None = None,
238-
on_or_after: datetime | None = None,
235+
before: datetime.datetime | None = None,
236+
after: datetime.datetime | None = None,
237+
on_or_before: datetime.datetime | None = None,
238+
on_or_after: datetime.datetime | None = None,
239239
) -> list[ModelT]:
240240
result_: list[ModelT] = []
241241
for item in result:
242-
attr: datetime = getattr(item, field_name)
242+
attr: datetime.datetime = getattr(item, field_name)
243243
if before is not None and attr < before:
244244
result_.append(item)
245245
if after is not None and attr > after:

docs/conf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
# ruff: noqa: FIX002 PLR0911 ARG001 ERA001
33
from __future__ import annotations
44

5+
import datetime
56
import os
67
import warnings
7-
from datetime import datetime
88
from functools import partial
99
from typing import TYPE_CHECKING, Any
1010

@@ -22,7 +22,7 @@
2222
warnings.filterwarnings("ignore", category=SAWarning)
2323

2424
# -- Project information -----------------------------------------------------
25-
current_year = datetime.now().year # noqa: DTZ005
25+
current_year = datetime.datetime.now().year # noqa: DTZ005
2626
project = __project__
2727
copyright = f"{current_year}, Litestar Organization" # noqa: A001
2828
release = os.getenv("_ADVANCED-ALCHEMY_DOCS_BUILD_VERSION", __version__.rsplit(".")[0])

docs/usage/frameworks/fastapi.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ Define your SQLAlchemy models and Pydantic schemas:
4545

4646
.. code-block:: python
4747
48-
from datetime import date
48+
import datetime
4949
from uuid import UUID
5050
from sqlalchemy import ForeignKey
5151
from sqlalchemy.orm import Mapped, mapped_column, relationship
@@ -71,15 +71,15 @@ Define your SQLAlchemy models and Pydantic schemas:
7171
class Author(BaseModel):
7272
id: UUID | None
7373
name: str
74-
dob: date | None = None
74+
dob: datetime.date | None = None
7575
7676
class AuthorCreate(BaseModel):
7777
name: str
78-
dob: date | None = None
78+
dob: datetime.date | None = None
7979
8080
class AuthorUpdate(BaseModel):
8181
name: str | None = None
82-
dob: date | None = None
82+
dob: datetime.date | None = None
8383
8484
Repository and Service
8585
----------------------

docs/usage/frameworks/litestar.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Define your SQLAlchemy models using Advanced Alchemy's enhanced base classes:
4444

4545
.. code-block:: python
4646
47-
from datetime import date
47+
import datetime
4848
from uuid import UUID
4949
from sqlalchemy import ForeignKey
5050
from sqlalchemy.orm import Mapped, mapped_column, relationship
@@ -54,7 +54,7 @@ Define your SQLAlchemy models using Advanced Alchemy's enhanced base classes:
5454
class AuthorModel(UUIDBase):
5555
__tablename__ = "author"
5656
name: Mapped[str]
57-
dob: Mapped[date | None]
57+
dob: Mapped[datetime.date | None]
5858
books: Mapped[list[BookModel]] = relationship(back_populates="author", lazy="selectin")
5959
6060
class BookModel(UUIDAuditBase):
@@ -70,7 +70,7 @@ Define Pydantic schemas for input validation and response serialization:
7070

7171
.. code-block:: python
7272
73-
from datetime import date
73+
import datetime
7474
from pydantic import BaseModel, ConfigDict
7575
from uuid import UUID
7676
from typing import Optional
@@ -83,17 +83,17 @@ Define Pydantic schemas for input validation and response serialization:
8383
"""Author response schema."""
8484
id: UUID
8585
name: str
86-
dob: Optional[date] = None
86+
dob: Optional[datetime.date] = None
8787
8888
class AuthorCreate(BaseSchema):
8989
"""Schema for creating authors."""
9090
name: str
91-
dob: Optional[date] = None
91+
dob: Optional[datetime.date] = None
9292
9393
class AuthorUpdate(BaseSchema):
9494
"""Schema for updating authors."""
9595
name: Optional[str] = None
96-
dob: Optional[date] = None
96+
dob: Optional[datetime.date] = None
9797
9898
class Book(BaseSchema):
9999
"""Book response schema with author details."""

docs/usage/modeling.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ Let's start with a simple blog post model:
6666
6767
from advanced_alchemy.base import BigIntAuditBase
6868
from sqlalchemy.orm import Mapped, mapped_column
69-
from datetime import datetime
69+
import datetime
7070
from typing import Optional
7171
7272
class Post(BigIntAuditBase):
@@ -83,7 +83,7 @@ Let's start with a simple blog post model:
8383
title: Mapped[str] = mapped_column(index=True)
8484
content: Mapped[str]
8585
published: Mapped[bool] = mapped_column(default=False)
86-
published_at: Mapped[Optional[datetime]] = mapped_column(default=None)
86+
published_at: Mapped[Optional[datetime.datetime]] = mapped_column(default=None)
8787
8888
Many-to-Many Relationships
8989
--------------------------
@@ -253,7 +253,7 @@ Here's an example showing a class to generate a server-side UUID primary key for
253253

254254
.. code-block:: python
255255
256-
from datetime import datetime
256+
import datetime
257257
from uuid import UUID, uuid4
258258
259259
from advanced_alchemy.base import CommonTableAttributes, orm_registry
@@ -294,7 +294,7 @@ Here's an example showing a class to generate a server-side UUID primary key for
294294
email: Mapped[str] = mapped_column(unique=True)
295295
full_name: Mapped[str]
296296
is_active: Mapped[bool] = mapped_column(default=True)
297-
last_login: Mapped[datetime | None] = mapped_column(default=None)
297+
last_login: Mapped[datetime.datetime | None] = mapped_column(default=None)
298298
299299
300300
With this foundation in place, let's look at the repository pattern.

0 commit comments

Comments
 (0)