添加注册登录功能

This commit is contained in:
2025-08-29 00:34:40 +08:00
parent 09065f2ce7
commit 2fe3474d9e
3060 changed files with 29217 additions and 87137 deletions

View File

@@ -99,6 +99,7 @@ def association_proxy(
compare: Union[_NoArg, bool] = _NoArg.NO_ARG,
kw_only: Union[_NoArg, bool] = _NoArg.NO_ARG,
hash: Union[_NoArg, bool, None] = _NoArg.NO_ARG, # noqa: A002
dataclass_metadata: Union[_NoArg, Mapping[Any, Any], None] = _NoArg.NO_ARG,
) -> AssociationProxy[Any]:
r"""Return a Python property implementing a view of a target
attribute which references an attribute on members of the
@@ -206,6 +207,12 @@ def association_proxy(
.. versionadded:: 2.0.36
:param dataclass_metadata: Specific to
:ref:`orm_declarative_native_dataclasses`, supplies metadata
to be attached to the generated dataclass field.
.. versionadded:: 2.0.42
:param info: optional, will be assigned to
:attr:`.AssociationProxy.info` if present.
@@ -245,7 +252,14 @@ def association_proxy(
cascade_scalar_deletes=cascade_scalar_deletes,
create_on_none_assignment=create_on_none_assignment,
attribute_options=_AttributeOptions(
init, repr, default, default_factory, compare, kw_only, hash
init,
repr,
default,
default_factory,
compare,
kw_only,
hash,
dataclass_metadata,
),
)

View File

@@ -71,26 +71,26 @@ class ReversibleProxy(Generic[_PT]):
cls._proxy_objects.pop(ref, None)
@classmethod
def _regenerate_proxy_for_target(cls, target: _PT) -> Self:
def _regenerate_proxy_for_target(
cls, target: _PT, **additional_kw: Any
) -> Self:
raise NotImplementedError()
@overload
@classmethod
def _retrieve_proxy_for_target(
cls,
target: _PT,
regenerate: Literal[True] = ...,
cls, target: _PT, regenerate: Literal[True] = ..., **additional_kw: Any
) -> Self: ...
@overload
@classmethod
def _retrieve_proxy_for_target(
cls, target: _PT, regenerate: bool = True
cls, target: _PT, regenerate: bool = True, **additional_kw: Any
) -> Optional[Self]: ...
@classmethod
def _retrieve_proxy_for_target(
cls, target: _PT, regenerate: bool = True
cls, target: _PT, regenerate: bool = True, **additional_kw: Any
) -> Optional[Self]:
try:
proxy_ref = cls._proxy_objects[weakref.ref(target)]
@@ -102,7 +102,7 @@ class ReversibleProxy(Generic[_PT]):
return proxy # type: ignore
if regenerate:
return cls._regenerate_proxy_for_target(target)
return cls._regenerate_proxy_for_target(target, **additional_kw)
else:
return None
@@ -215,7 +215,7 @@ class GeneratorStartableContext(StartableContext[_T_co]):
def asyncstartablecontext(
func: Callable[..., AsyncIterator[_T_co]]
func: Callable[..., AsyncIterator[_T_co]],
) -> Callable[..., GeneratorStartableContext[_T_co]]:
"""@asyncstartablecontext decorator.

View File

@@ -255,7 +255,7 @@ class AsyncConnection(
@classmethod
def _regenerate_proxy_for_target(
cls, target: Connection
cls, target: Connection, **additional_kw: Any # noqa: U100
) -> AsyncConnection:
return AsyncConnection(
AsyncEngine._retrieve_proxy_for_target(target.engine), target
@@ -1041,7 +1041,9 @@ class AsyncEngine(ProxyComparable[Engine], AsyncConnectable):
return self.sync_engine
@classmethod
def _regenerate_proxy_for_target(cls, target: Engine) -> AsyncEngine:
def _regenerate_proxy_for_target(
cls, target: Engine, **additional_kw: Any # noqa: U100
) -> AsyncEngine:
return AsyncEngine(target)
@contextlib.asynccontextmanager
@@ -1344,7 +1346,7 @@ class AsyncTransaction(
@classmethod
def _regenerate_proxy_for_target(
cls, target: Transaction
cls, target: Transaction, **additional_kw: Any # noqa: U100
) -> AsyncTransaction:
sync_connection = target.connection
sync_transaction = target
@@ -1429,7 +1431,7 @@ def _get_sync_engine_or_connection(
def _get_sync_engine_or_connection(
async_engine: Union[AsyncEngine, AsyncConnection]
async_engine: Union[AsyncEngine, AsyncConnection],
) -> Union[Engine, Connection]:
if isinstance(async_engine, AsyncConnection):
return async_engine._proxied

View File

@@ -93,6 +93,7 @@ class AsyncResult(_WithKeys, AsyncCommon[Row[_TP]]):
self._metadata = real_result._metadata
self._unique_filter_state = real_result._unique_filter_state
self._source_supports_scalars = real_result._source_supports_scalars
self._post_creational_filter = None
# BaseCursorResult pre-generates the "_row_getter". Use that
@@ -824,7 +825,7 @@ class AsyncTupleResult(AsyncCommon[_R], util.TypingOnly):
"""
...
async def __aiter__(self) -> AsyncIterator[_R]: ...
def __aiter__(self) -> AsyncIterator[_R]: ...
async def __anext__(self) -> _R: ...

View File

@@ -1175,8 +1175,7 @@ class async_scoped_session(Generic[_AS]):
Proxied for the :class:`_asyncio.AsyncSession` class on
behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
Raises ``sqlalchemy.orm.exc.NoResultFound`` if the query selects
no rows.
Raises :class:`_exc.NoResultFound` if the query selects no rows.
..versionadded: 2.0.22

View File

@@ -628,8 +628,7 @@ class AsyncSession(ReversibleProxy[Session]):
"""Return an instance based on the given primary key identifier,
or raise an exception if not found.
Raises ``sqlalchemy.orm.exc.NoResultFound`` if the query selects
no rows.
Raises :class:`_exc.NoResultFound` if the query selects no rows.
..versionadded: 2.0.22
@@ -812,7 +811,9 @@ class AsyncSession(ReversibleProxy[Session]):
"""
trans = self.sync_session.get_transaction()
if trans is not None:
return AsyncSessionTransaction._retrieve_proxy_for_target(trans)
return AsyncSessionTransaction._retrieve_proxy_for_target(
trans, async_session=self
)
else:
return None
@@ -828,7 +829,9 @@ class AsyncSession(ReversibleProxy[Session]):
trans = self.sync_session.get_nested_transaction()
if trans is not None:
return AsyncSessionTransaction._retrieve_proxy_for_target(trans)
return AsyncSessionTransaction._retrieve_proxy_for_target(
trans, async_session=self
)
else:
return None
@@ -1865,6 +1868,21 @@ class AsyncSessionTransaction(
await greenlet_spawn(self._sync_transaction().commit)
@classmethod
def _regenerate_proxy_for_target( # type: ignore[override]
cls,
target: SessionTransaction,
async_session: AsyncSession,
**additional_kw: Any, # noqa: U100
) -> AsyncSessionTransaction:
sync_transaction = target
nested = target.nested
obj = cls.__new__(cls)
obj.session = async_session
obj.sync_transaction = obj._assign_proxied(sync_transaction)
obj.nested = nested
return obj
async def start(
self, is_ctxmanager: bool = False
) -> AsyncSessionTransaction:

View File

@@ -216,6 +216,7 @@ for indexed access, instead of the usual index operator of ``->``::
>>> query = session.query(Person).filter(Person.age < 20)
The above query will render:
.. sourcecode:: sql
SELECT person.id, person.data

View File

@@ -524,6 +524,7 @@ class MutableBase:
if val is not None:
if coerce:
val = cls.coerce(key, val)
assert val is not None
state.dict[key] = val
val._parents[state] = key

View File

@@ -297,7 +297,7 @@ def type_id_for_callee(callee: Expression) -> Optional[int]:
def type_id_for_named_node(
node: Union[NameExpr, MemberExpr, SymbolNode]
node: Union[NameExpr, MemberExpr, SymbolNode],
) -> Optional[int]:
type_id, fullnames = _lookup.get(node.name, (None, None))

View File

@@ -4,7 +4,6 @@
#
# This module is part of SQLAlchemy and is released under
# the MIT License: https://www.opensource.org/licenses/mit-license.php
# mypy: ignore-errors
"""A custom list that manages index/position information for contained
elements.
@@ -129,17 +128,24 @@ start numbering at 1 or some other integer, provide ``count_from=1``.
"""
from __future__ import annotations
from typing import Any
from typing import Callable
from typing import Dict
from typing import Iterable
from typing import List
from typing import Optional
from typing import overload
from typing import Sequence
from typing import Type
from typing import TypeVar
from typing import Union
from ..orm.collections import collection
from ..orm.collections import collection_adapter
from ..util.typing import SupportsIndex
_T = TypeVar("_T")
OrderingFunc = Callable[[int, Sequence[_T]], int]
OrderingFunc = Callable[[int, Sequence[_T]], object]
__all__ = ["ordering_list"]
@@ -148,9 +154,9 @@ __all__ = ["ordering_list"]
def ordering_list(
attr: str,
count_from: Optional[int] = None,
ordering_func: Optional[OrderingFunc] = None,
ordering_func: Optional[OrderingFunc[_T]] = None,
reorder_on_append: bool = False,
) -> Callable[[], OrderingList]:
) -> Callable[[], OrderingList[_T]]:
"""Prepares an :class:`OrderingList` factory for use in mapper definitions.
Returns an object suitable for use as an argument to a Mapper
@@ -196,22 +202,22 @@ def ordering_list(
# Ordering utility functions
def count_from_0(index, collection):
def count_from_0(index: int, collection: object) -> int:
"""Numbering function: consecutive integers starting at 0."""
return index
def count_from_1(index, collection):
def count_from_1(index: int, collection: object) -> int:
"""Numbering function: consecutive integers starting at 1."""
return index + 1
def count_from_n_factory(start):
def count_from_n_factory(start: int) -> OrderingFunc[Any]:
"""Numbering function: consecutive integers starting at arbitrary start."""
def f(index, collection):
def f(index: int, collection: object) -> int:
return index + start
try:
@@ -221,7 +227,7 @@ def count_from_n_factory(start):
return f
def _unsugar_count_from(**kw):
def _unsugar_count_from(**kw: Any) -> Dict[str, Any]:
"""Builds counting functions from keyword arguments.
Keyword argument filter, prepares a simple ``ordering_func`` from a
@@ -249,13 +255,13 @@ class OrderingList(List[_T]):
"""
ordering_attr: str
ordering_func: OrderingFunc
ordering_func: OrderingFunc[_T]
reorder_on_append: bool
def __init__(
self,
ordering_attr: Optional[str] = None,
ordering_func: Optional[OrderingFunc] = None,
ordering_attr: str,
ordering_func: Optional[OrderingFunc[_T]] = None,
reorder_on_append: bool = False,
):
"""A custom list that manages position information for its children.
@@ -315,10 +321,10 @@ class OrderingList(List[_T]):
# More complex serialization schemes (multi column, e.g.) are possible by
# subclassing and reimplementing these two methods.
def _get_order_value(self, entity):
def _get_order_value(self, entity: _T) -> Any:
return getattr(entity, self.ordering_attr)
def _set_order_value(self, entity, value):
def _set_order_value(self, entity: _T, value: Any) -> None:
setattr(entity, self.ordering_attr, value)
def reorder(self) -> None:
@@ -334,7 +340,9 @@ class OrderingList(List[_T]):
# As of 0.5, _reorder is no longer semi-private
_reorder = reorder
def _order_entity(self, index, entity, reorder=True):
def _order_entity(
self, index: int, entity: _T, reorder: bool = True
) -> None:
have = self._get_order_value(entity)
# Don't disturb existing ordering if reorder is False
@@ -345,34 +353,44 @@ class OrderingList(List[_T]):
if have != should_be:
self._set_order_value(entity, should_be)
def append(self, entity):
def append(self, entity: _T) -> None:
super().append(entity)
self._order_entity(len(self) - 1, entity, self.reorder_on_append)
def _raw_append(self, entity):
def _raw_append(self, entity: _T) -> None:
"""Append without any ordering behavior."""
super().append(entity)
_raw_append = collection.adds(1)(_raw_append)
def insert(self, index, entity):
def insert(self, index: SupportsIndex, entity: _T) -> None:
super().insert(index, entity)
self._reorder()
def remove(self, entity):
def remove(self, entity: _T) -> None:
super().remove(entity)
adapter = collection_adapter(self)
if adapter and adapter._referenced_by_owner:
self._reorder()
def pop(self, index=-1):
def pop(self, index: SupportsIndex = -1) -> _T:
entity = super().pop(index)
self._reorder()
return entity
def __setitem__(self, index, entity):
@overload
def __setitem__(self, index: SupportsIndex, entity: _T) -> None: ...
@overload
def __setitem__(self, index: slice, entity: Iterable[_T]) -> None: ...
def __setitem__(
self,
index: Union[SupportsIndex, slice],
entity: Union[_T, Iterable[_T]],
) -> None:
if isinstance(index, slice):
step = index.step or 1
start = index.start or 0
@@ -381,26 +399,18 @@ class OrderingList(List[_T]):
stop = index.stop or len(self)
if stop < 0:
stop += len(self)
entities = list(entity) # type: ignore[arg-type]
for i in range(start, stop, step):
self.__setitem__(i, entity[i])
self.__setitem__(i, entities[i])
else:
self._order_entity(index, entity, True)
super().__setitem__(index, entity)
self._order_entity(int(index), entity, True) # type: ignore[arg-type] # noqa: E501
super().__setitem__(index, entity) # type: ignore[assignment]
def __delitem__(self, index):
def __delitem__(self, index: Union[SupportsIndex, slice]) -> None:
super().__delitem__(index)
self._reorder()
def __setslice__(self, start, end, values):
super().__setslice__(start, end, values)
self._reorder()
def __delslice__(self, start, end):
super().__delslice__(start, end)
self._reorder()
def __reduce__(self):
def __reduce__(self) -> Any:
return _reconstitute, (self.__class__, self.__dict__, list(self))
for func_name, func in list(locals().items()):
@@ -414,7 +424,9 @@ class OrderingList(List[_T]):
del func_name, func
def _reconstitute(cls, dict_, items):
def _reconstitute(
cls: Type[OrderingList[_T]], dict_: Dict[str, Any], items: List[_T]
) -> OrderingList[_T]:
"""Reconstitute an :class:`.OrderingList`.
This is the adjoint to :meth:`.OrderingList.__reduce__`. It is used for