Skip to content

Commit 0e97e1d

Browse files
committed
done
1 parent 6cc8f90 commit 0e97e1d

File tree

23 files changed

+111
-98
lines changed

23 files changed

+111
-98
lines changed

mongospecs/__init__.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
from pymongo.collation import Collation
44
from pymongo.operations import IndexModel
55

6-
from .empty import Empty
7-
from .ops import All, And, ElemMatch, Exists, In, Nor, Not, NotIn, Or, Size, SortBy, Type
8-
from .pagination import Page, Paginator
9-
from .query import Q
10-
from .se import MongoDecoder, MongoEncoder
6+
from .helpers.empty import Empty
7+
from .helpers.ops import All, And, ElemMatch, Exists, In, Nor, Not, NotIn, Or, Size, SortBy, Type
8+
from .helpers.pagination import Page, Paginator
9+
from .helpers.query import Q
10+
from .helpers.se import MongoDecoder, MongoEncoder
1111

1212
__all__ = [
1313
# Queries

mongospecs/attrs.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from pymongo import MongoClient
99

1010
from .base import SpecBase, SubSpecBase
11-
from .types import SpecDocumentType
1211
from .helpers.empty import Empty
1312
from .helpers.se import MongoEncoder, mongo_dec_hook
1413

mongospecs/base.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,19 @@
33
import typing as t
44
from copy import deepcopy
55

6-
from mongospecs.types import SpecBaseType, SubSpecBaseType
6+
from mongospecs.types import SubSpecBaseType
77

88
from .mixins.crud import CrudMixin
99
from .mixins.index import IndexManagementMixin
1010
from .mixins.integrity import IntegrityMixin
11-
from .mixins.query import QueryMixin
1211
from .mixins.session import SessionTransactionMixin
1312
from .mixins.signal import SignalMixin
1413

1514
T = t.TypeVar("T")
1615

1716

18-
class SpecBase(CrudMixin, IndexManagementMixin, IntegrityMixin, SessionTransactionMixin, SignalMixin):
19-
...
17+
class SpecBase(CrudMixin, IndexManagementMixin, IntegrityMixin, SessionTransactionMixin, SignalMixin): ...
18+
2019

2120
class SubSpecBase(SubSpecBaseType):
2221
_parent: t.ClassVar[t.Any] = SpecBase
@@ -85,4 +84,3 @@ def _projection_to_paths(cls, root_key: str, projection: t.Mapping[str, t.Any])
8584
return True
8685

8786
return sub_projection
88-

mongospecs/helpers/__init__.py

Whitespace-only changes.

mongospecs/helpers/bson.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def encode(obj: t.Any, enc_hook: t.Optional[t.Callable[[t.Any], t.Any]] = bson_e
3131
return bson.encode(msgspec.to_builtins(obj, enc_hook=enc_hook, builtin_types=(bson.ObjectId,)))
3232

3333

34-
def encode_spec(obj: SpecBase[t.Any]) -> bytes:
34+
def encode_spec(obj: SpecBase) -> bytes:
3535
return bson.encode(obj.to_json_type())
3636

3737

mongospecs/helpers/ops.py

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

33
from pymongo import ASCENDING, DESCENDING
44

5-
from .base import to_refs
5+
from mongospecs.utils import deep_merge, to_refs
6+
67
from .query import Condition, Group, Q
7-
from .utils import deep_merge
88

99
__all__ = [
1010
# Operators

mongospecs/helpers/pagination.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
from copy import deepcopy
88
from dataclasses import dataclass
99

10-
from .base import SpecBase, to_refs
10+
from mongospecs.base import SpecBase
11+
from mongospecs.utils import to_refs
12+
1113
from .query import Condition, Group
1214

1315
__all__ = (
@@ -20,7 +22,7 @@
2022

2123

2224
T = t.TypeVar("T")
23-
TSpec = t.TypeVar("TSpec", bound=SpecBase[t.Any])
25+
TSpec = t.TypeVar("TSpec", bound=SpecBase)
2426

2527

2628
class InvalidPage(Exception):

mongospecs/mixins/base.py

Lines changed: 9 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
from copy import deepcopy
66

77
from bson import BSON, ObjectId
8-
from pymongo import ASCENDING, MongoClient
8+
from pymongo import MongoClient
99
from pymongo.collection import Collection
1010
from pymongo.database import Database
1111
from typing_extensions import Self
1212

1313
from ..helpers.empty import Empty, EmptyObject
14-
from ..types import SpecDocumentType, Specs, RawDocuments, SpecsOrRawDocuments, SubSpecBaseType, SpecBaseType
15-
import typing as t
14+
from ..types import RawDocuments, SpecBaseType, SpecDocumentType, SpecsOrRawDocuments
15+
1616

1717
class MongoBaseMixin(SpecBaseType):
1818
_client: t.ClassVar[t.Optional[MongoClient[t.Any]]] = None
@@ -38,9 +38,8 @@ def __eq__(self, other: t.Any) -> bool:
3838

3939
return self._id == other._id
4040

41-
def __lt__(self, other: t.Any) -> t.Any:
42-
return self._id < other._id
43-
41+
def __lt__(self, other: t.Any) -> bool:
42+
return self._id < other._id # type: ignore[no-any-return]
4443

4544
@classmethod
4645
def get_collection(cls) -> Collection[t.Any]:
@@ -76,7 +75,7 @@ def with_options(cls, **options: t.Any) -> t.Generator[t.Any, t.Any, None]:
7675
cls._collection_context = existing_context
7776

7877
@classmethod
79-
def _path_to_value(cls, path: str, parent_dict: t.MutableMapping[str, t.Any]) -> t.Any:
78+
def _path_to_value(cls, path: str, parent_dict: SpecDocumentType) -> t.Any:
8079
"""Return a value from a dictionary at the given path"""
8180
keys: list[str] = cls._path_to_keys(path)
8281

@@ -97,7 +96,7 @@ def _path_to_keys(cls, path: str) -> list[str]:
9796
return path.split(".")
9897

9998
@classmethod
100-
def _ensure_specs(cls, documents: SpecsOrRawDocuments[SpecDocumentType]) -> Specs[SpecDocumentType]:
99+
def _ensure_specs(cls, documents: SpecsOrRawDocuments) -> t.Sequence[t.Self]:
101100
"""
102101
Ensure all items in a list are specs by converting those that aren't.
103102
"""
@@ -110,7 +109,7 @@ def _ensure_specs(cls, documents: SpecsOrRawDocuments[SpecDocumentType]) -> Spec
110109
return specs
111110

112111
@classmethod
113-
def _apply_sub_specs(cls, documents: RawDocuments[SpecDocumentType], subs: dict[str, t.Any]) -> None:
112+
def _apply_sub_specs(cls, documents: RawDocuments, subs: dict[str, t.Any]) -> None:
114113
"""Convert embedded documents to sub-specs for one or more documents"""
115114

116115
# Dereference each reference
@@ -242,7 +241,7 @@ def _flatten_projection(
242241
return flat_projection, references, subs
243242

244243
@classmethod
245-
def _dereference(cls, documents: RawDocuments[t.Any], references: dict[str, t.Any]) -> None:
244+
def _dereference(cls, documents: RawDocuments, references: dict[str, t.Any]) -> None:
246245
"""Dereference one or more documents"""
247246

248247
# Dereference each reference
@@ -320,24 +319,3 @@ def _remove_keys(cls, parent_dict: dict[str, t.Any], paths: list[str]) -> None:
320319
continue
321320

322321
child_dict.pop(keys[-1], None)
323-
324-
325-
def to_refs(value: t.Any) -> t.Any:
326-
"""Convert all Spec instances within the given value to Ids"""
327-
# Spec
328-
if isinstance(value, SpecBaseType):
329-
return getattr(value, "_id")
330-
331-
# SubSpec
332-
elif isinstance(value, SubSpecBaseType):
333-
return to_refs(value.to_dict())
334-
335-
# Lists
336-
elif isinstance(value, (list, tuple)):
337-
return [to_refs(v) for v in value]
338-
339-
# Dictionaries
340-
elif isinstance(value, dict):
341-
return {k: to_refs(v) for k, v in value.items()}
342-
343-
return value

mongospecs/mixins/crud.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
1-
from mongospecs.mixins.query import QueryMixin
21
import typing as t
2+
33
from blinker import signal
4-
from ..types import SpecDocumentType, FilterType
4+
from pymongo import UpdateOne
5+
from pymongo.collection import Collection
6+
7+
from mongospecs.helpers.query import Condition, Group
8+
from mongospecs.mixins.query import QueryMixin
9+
from mongospecs.types import FilterType, SpecDocumentType, SpecsOrRawDocuments
10+
from mongospecs.utils import to_refs
11+
512

613
class CrudMixin(QueryMixin):
714
# Operations
@@ -171,7 +178,7 @@ def reload(self, **kwargs: t.Any) -> None:
171178
setattr(self, field, spec[field])
172179

173180
@classmethod
174-
def insert_many(cls, documents: SpecsOrRawDocuments[SpecDocumentType], **kwargs: t.Any) -> Specs[t.Any]:
181+
def insert_many(cls, documents: t.Sequence[SpecDocumentType], **kwargs: t.Any) -> t.Sequence[t.Self]:
175182
"""Insert a list of documents"""
176183
# Ensure all documents have been converted to specs
177184
specs = cls._ensure_specs(documents)
@@ -201,7 +208,7 @@ def insert_many(cls, documents: SpecsOrRawDocuments[SpecDocumentType], **kwargs:
201208
@classmethod
202209
def update_many(
203210
cls,
204-
documents: SpecsOrRawDocuments[SpecDocumentType],
211+
documents: SpecsOrRawDocuments,
205212
*fields: t.Any,
206213
update_one_kwargs: t.Any = None,
207214
bulk_write_kwargs: t.Any = None,
@@ -249,9 +256,7 @@ def update_many(
249256
signal("updated").send(cls, specs=specs)
250257

251258
@classmethod
252-
def unset_many(
253-
cls, documents: SpecsOrRawDocuments[SpecDocumentType], *fields: t.Any, **update_many_kwargs: t.Any
254-
) -> None:
259+
def unset_many(cls, documents: SpecsOrRawDocuments, *fields: t.Any, **update_many_kwargs: t.Any) -> None:
255260
"""Unset the given list of fields for given documents."""
256261

257262
# Ensure all documents have been converted to specs
@@ -278,7 +283,7 @@ def unset_many(
278283
signal("updated").send(cls, specs=specs)
279284

280285
@classmethod
281-
def delete_many(cls, documents: SpecsOrRawDocuments[SpecDocumentType], **delete_many_kwargs: t.Any) -> None:
286+
def delete_many(cls, documents: SpecsOrRawDocuments, **delete_many_kwargs: t.Any) -> None:
282287
"""Delete multiple documents"""
283288

284289
# Ensure all documents have been converted to specs
@@ -298,7 +303,7 @@ def delete_many(cls, documents: SpecsOrRawDocuments[SpecDocumentType], **delete_
298303

299304
# Send deleted signal
300305
signal("deleted").send(cls, specs=specs)
301-
306+
302307
def soft_delete(self, **update_one_kwargs: t.Any) -> None:
303308
"""Soft delete this document by setting a deleted flag."""
304309
assert "_id" in self.to_dict(), "Can't delete documents without `_id`"

mongospecs/mixins/index.py

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,18 @@
1-
2-
31
import typing as t
2+
43
from pymongo import ASCENDING
54

5+
from ..types import SpecDocumentType
66
from .base import MongoBaseMixin
77

8-
class IndexManagementMixin(MongoBaseMixin):
98

9+
class IndexManagementMixin(MongoBaseMixin):
1010
@classmethod
11-
def create_index(cls, keys: t.Union[str, list[str]], direction: t.Union[int, str] = ASCENDING, **kwargs: t.Any) -> str:
11+
def create_index(cls, keys: t.Union[str, list[tuple[str, int]]], **kwargs: t.Any) -> str:
1212
"""
1313
Create an index on the specified keys (a single key or a list of keys).
1414
"""
15-
if isinstance(keys, str):
16-
index_keys = [(keys, direction)]
17-
else:
18-
index_keys = [(key, direction) for key in keys]
19-
15+
index_keys = [(keys, ASCENDING)] if isinstance(keys, str) else keys
2016
return cls.get_collection().create_index(index_keys, **kwargs)
2117

2218
@classmethod
@@ -27,7 +23,7 @@ def drop_index(cls, index_name: str) -> None:
2723
cls.get_collection().drop_index(index_name)
2824

2925
@classmethod
30-
def list_indexes(cls) -> list[t.MutableMapping[str, t.Any]]:
26+
def list_indexes(cls) -> list[SpecDocumentType]:
3127
"""
3228
List all indexes on the collection.
3329
"""

0 commit comments

Comments
 (0)