apexdevkit 1.32.2__tar.gz → 1.32.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/PKG-INFO +1 -1
  2. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/repository/core/decorator.py +6 -6
  3. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/sync/sync.py +20 -5
  4. apexdevkit-1.32.4/apexdevkit/sync/target.py +85 -0
  5. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/pyproject.toml +1 -1
  6. apexdevkit-1.32.2/apexdevkit/sync/target.py +0 -82
  7. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/LICENSE +0 -0
  8. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/README.md +0 -0
  9. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/__init__.py +0 -0
  10. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/annotation/__init__.py +0 -0
  11. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/annotation/deprecate.py +0 -0
  12. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/date.py +0 -0
  13. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/environment.py +0 -0
  14. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/error.py +0 -0
  15. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/fastapi/__init__.py +0 -0
  16. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/fastapi/builder.py +0 -0
  17. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/fastapi/dependable.py +0 -0
  18. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/fastapi/docs.py +0 -0
  19. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/fastapi/name.py +0 -0
  20. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/fastapi/resource.py +0 -0
  21. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/fastapi/response.py +0 -0
  22. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/fastapi/router.py +0 -0
  23. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/fastapi/schema.py +0 -0
  24. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/fastapi/service.py +0 -0
  25. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/fluent.py +0 -0
  26. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/formatter.py +0 -0
  27. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/http/__init__.py +0 -0
  28. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/http/fake.py +0 -0
  29. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/http/fluent.py +0 -0
  30. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/http/httpx/__init__.py +0 -0
  31. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/http/httpx/client.py +0 -0
  32. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/http/httpx/hooks.py +0 -0
  33. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/http/json.py +0 -0
  34. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/http/url.py +0 -0
  35. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/key_fn.py +0 -0
  36. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/py.typed +0 -0
  37. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/query/__init__.py +0 -0
  38. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/query/generator.py +0 -0
  39. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/query/query.py +0 -0
  40. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/repository/__init__.py +0 -0
  41. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/repository/core/__init__.py +0 -0
  42. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/repository/core/database.py +0 -0
  43. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/repository/core/interface.py +0 -0
  44. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/repository/core/mixin.py +0 -0
  45. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/repository/core/multi.py +0 -0
  46. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/repository/in_memory/__init__.py +0 -0
  47. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/repository/in_memory/mixin.py +0 -0
  48. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/repository/in_memory/repository.py +0 -0
  49. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/repository/in_memory/store.py +0 -0
  50. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/repository/sql/__init__.py +0 -0
  51. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/repository/sql/connector.py +0 -0
  52. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/repository/sql/field.py +0 -0
  53. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/repository/sql/mssql.py +0 -0
  54. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/repository/sql/sqlite.py +0 -0
  55. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/security/__init__.py +0 -0
  56. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/security/core.py +0 -0
  57. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/security/hashing.py +0 -0
  58. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/server.py +0 -0
  59. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/sync/__init__.py +0 -0
  60. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/sync/observer.py +0 -0
  61. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/sync/source.py +0 -0
  62. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/testing/__init__.py +0 -0
  63. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/testing/database.py +0 -0
  64. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/testing/fake.py +0 -0
  65. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/testing/rest.py +0 -0
  66. {apexdevkit-1.32.2 → apexdevkit-1.32.4}/apexdevkit/value.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: apexdevkit
3
- Version: 1.32.2
3
+ Version: 1.32.4
4
4
  Summary: Apex Development Tools for python.
5
5
  License-File: LICENSE
6
6
  Author: Apex Dev
@@ -1,4 +1,4 @@
1
- from collections.abc import Container, Iterable, Iterator
1
+ from collections.abc import Collection, Iterable, Iterator
2
2
  from contextlib import suppress
3
3
  from dataclasses import dataclass, field
4
4
 
@@ -58,20 +58,20 @@ class RepositoryDecorator(Repository[ItemT]): # pragma: no cover
58
58
 
59
59
  @dataclass(frozen=True, kw_only=True)
60
60
  class BruteForceBatch(RepositoryDecorator[ItemT]):
61
- def load(self, source: Iterable[ItemT]) -> Iterable[ItemT]:
62
- for item in list(source):
61
+ def load(self, source: Collection[ItemT]) -> Iterable[ItemT]:
62
+ for item in source:
63
63
  with suppress(ExistsError):
64
64
  yield self.inner.create(item)
65
65
 
66
- def prune(self, source: Container[ItemT]) -> Iterable[ItemT]:
66
+ def prune(self, source: Collection[ItemT]) -> Iterable[ItemT]:
67
67
  for item in list(self.inner):
68
68
  if item not in source:
69
69
  with suppress(DoesNotExistError):
70
70
  self.inner.delete(item.id)
71
71
  yield item
72
72
 
73
- def renew(self, source: Iterable[ItemT]) -> Iterable[ItemT]:
74
- for item in list(source):
73
+ def renew(self, source: Collection[ItemT]) -> Iterable[ItemT]:
74
+ for item in source:
75
75
  with suppress(DoesNotExistError):
76
76
  self.inner.update(item)
77
77
  yield item
@@ -1,26 +1,41 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from collections.abc import Callable, Collection, Iterable
4
- from dataclasses import dataclass
4
+ from dataclasses import dataclass, field, replace
5
5
  from typing import Any, Generic, Self, TypeVar
6
6
 
7
7
  from .observer import DefaultLog, ObservableSync
8
- from .source import Source
9
- from .target import Target
8
+ from .source import EmptySource, Source
9
+ from .target import NoTarget, Target
10
10
 
11
11
  T = TypeVar("T")
12
12
 
13
13
 
14
14
  @dataclass(frozen=True, kw_only=True)
15
15
  class Sync(ObservableSync, Generic[T]):
16
- source: Source[T]
17
- target: Target
16
+ source: Source[T] = field(default_factory=EmptySource)
17
+ target: Target[T] = field(default_factory=NoTarget)
18
18
 
19
19
  dry_run: bool = False
20
20
 
21
+ def and_target(self, value: Target[T]) -> Sync[T]:
22
+ return self.with_target(value)
23
+
24
+ def with_target(self, value: Target[T]) -> Sync[T]:
25
+ return replace(self, target=value)
26
+
27
+ def and_source(self, value: Source[T]) -> Sync[T]:
28
+ return self.with_source(value)
29
+
30
+ def with_source(self, value: Source[T]) -> Sync[T]:
31
+ return replace(self, source=value)
32
+
21
33
  def with_log(self, using: Callable[[str], None]) -> Self:
22
34
  return self.attach(DefaultLog(echo=using))
23
35
 
36
+ def dry(self, *, when: bool = True) -> Sync[T]:
37
+ return replace(self, dry_run=when)
38
+
24
39
  def run(self, prune: bool = True, load: bool = True, update: bool = True) -> None:
25
40
  if prune:
26
41
  self.prune()
@@ -0,0 +1,85 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Iterable
4
+ from dataclasses import dataclass, field
5
+ from typing import Any, Generic, Protocol, TypeVar
6
+
7
+ T = TypeVar("T", contravariant=True)
8
+
9
+
10
+ class Target(Protocol[T]): # pragma: no cover
11
+ def prune(self, source: Iterable[T]) -> Any:
12
+ pass
13
+
14
+ def load(self, source: Iterable[T]) -> Any:
15
+ pass
16
+
17
+ def renew(self, source: Iterable[T]) -> Any:
18
+ pass
19
+
20
+
21
+ class NoTarget(Generic[T]): # pragma: no cover
22
+ def prune(self, source: Iterable[T]) -> Any:
23
+ pass
24
+
25
+ def load(self, source: Iterable[T]) -> Any:
26
+ pass
27
+
28
+ def renew(self, source: Iterable[T]) -> Any:
29
+ pass
30
+
31
+
32
+ @dataclass(frozen=True, kw_only=True)
33
+ class TargetDecorator(Generic[T]):
34
+ inner: Target[T] = field(default_factory=NoTarget)
35
+
36
+ def prune(self, source: Iterable[T]) -> Any:
37
+ self.inner.prune(source)
38
+
39
+ def load(self, source: Iterable[T]) -> Any:
40
+ self.inner.load(source)
41
+
42
+ def renew(self, source: Iterable[T]) -> Any:
43
+ self.inner.renew(source)
44
+
45
+
46
+ class TargetFailing(Generic[T]):
47
+ @staticmethod
48
+ def on_everything(using: Target[T] | None = None) -> Target[T]:
49
+ return TargetFailing.on_prune(
50
+ using=TargetFailing.on_load(
51
+ using=TargetFailing.on_update(
52
+ using=using or NoTarget(),
53
+ ),
54
+ ),
55
+ )
56
+
57
+ @staticmethod
58
+ def on_prune(using: Target[T] | None = None) -> Target[T]:
59
+ return _FailOnPrune(inner=using or NoTarget())
60
+
61
+ @staticmethod
62
+ def on_load(using: Target[T] | None = None) -> Target[T]:
63
+ return _FailOnLoad(inner=using or NoTarget())
64
+
65
+ @staticmethod
66
+ def on_update(using: Target[T] | None = None) -> Target[T]:
67
+ return _FailOnUpdate(inner=using or NoTarget())
68
+
69
+
70
+ @dataclass(frozen=True, kw_only=True)
71
+ class _FailOnPrune(TargetDecorator[T]):
72
+ def prune(self, source: Iterable[T]) -> Any: # pragma: no cover
73
+ raise RuntimeError(source)
74
+
75
+
76
+ @dataclass(frozen=True, kw_only=True)
77
+ class _FailOnLoad(TargetDecorator[T]):
78
+ def load(self, source: Iterable[T]) -> Any: # pragma: no cover
79
+ raise RuntimeError(source)
80
+
81
+
82
+ @dataclass(frozen=True, kw_only=True)
83
+ class _FailOnUpdate(TargetDecorator[T]):
84
+ def renew(self, source: Iterable[T]) -> Any: # pragma: no cover
85
+ raise RuntimeError(source)
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "apexdevkit"
3
- version = "1.32.2"
3
+ version = "1.32.4"
4
4
  description = "Apex Development Tools for python."
5
5
  readme = "README.md"
6
6
  authors = [
@@ -1,82 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from collections.abc import Iterable
4
- from dataclasses import dataclass, field
5
- from typing import Any, Protocol, TypeVar
6
-
7
- T = TypeVar("T")
8
-
9
-
10
- class Target(Protocol): # pragma: no cover
11
- def prune(self, source: Iterable[T]) -> Any:
12
- pass
13
-
14
- def load(self, source: Iterable[T]) -> Any:
15
- pass
16
-
17
- def renew(self, source: Iterable[T]) -> Any:
18
- pass
19
-
20
-
21
- class NoTarget: # pragma: no cover
22
- def prune(self, source: Iterable[T]) -> Any:
23
- pass
24
-
25
- def load(self, source: Iterable[T]) -> Any:
26
- pass
27
-
28
- def renew(self, source: Iterable[T]) -> Any:
29
- pass
30
-
31
-
32
- @dataclass(frozen=True, kw_only=True)
33
- class TargetDecorator:
34
- inner: Target = field(default_factory=NoTarget)
35
-
36
- def prune(self, source: Iterable[T]) -> Any:
37
- self.inner.prune(source)
38
-
39
- def load(self, source: Iterable[T]) -> Any:
40
- self.inner.load(source)
41
-
42
- def renew(self, source: Iterable[T]) -> Any:
43
- self.inner.renew(source)
44
-
45
-
46
- class TargetFailing:
47
- @staticmethod
48
- def on_everything(using: Target | None = None) -> Target:
49
- return TargetFailing.on_prune(
50
- using=TargetFailing.on_load(
51
- using=TargetFailing.on_update(
52
- using=using or NoTarget(),
53
- ),
54
- ),
55
- )
56
-
57
- @staticmethod
58
- def on_prune(using: Target | None = None) -> Target:
59
- return TargetFailing.OnPrune(inner=using or NoTarget())
60
-
61
- @dataclass(frozen=True, kw_only=True)
62
- class OnPrune(TargetDecorator):
63
- def prune(self, source: Iterable[T]) -> Any: # pragma: no cover
64
- raise RuntimeError(source)
65
-
66
- @staticmethod
67
- def on_load(using: Target | None = None) -> Target:
68
- return TargetFailing.OnLoad(inner=using or NoTarget())
69
-
70
- @dataclass(frozen=True, kw_only=True)
71
- class OnLoad(TargetDecorator):
72
- def load(self, source: Iterable[T]) -> Any: # pragma: no cover
73
- raise RuntimeError(source)
74
-
75
- @staticmethod
76
- def on_update(using: Target | None = None) -> Target:
77
- return TargetFailing.OnUpdate(inner=using or NoTarget())
78
-
79
- @dataclass(frozen=True, kw_only=True)
80
- class OnUpdate(TargetDecorator):
81
- def renew(self, source: Iterable[T]) -> Any: # pragma: no cover
82
- raise RuntimeError(source)
File without changes
File without changes