ferrum-orm 0.1.5__tar.gz → 0.1.7__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 (80) hide show
  1. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/Cargo.lock +4 -4
  2. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/Cargo.toml +1 -1
  3. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/PKG-INFO +19 -1
  4. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/README.md +18 -0
  5. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/pyproject.toml +1 -1
  6. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/__init__.py +10 -2
  7. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/cli/inspectdb_cmd.py +13 -7
  8. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/models.py +27 -2
  9. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/queryset.py +571 -429
  10. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/LICENSE +0 -0
  11. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/crates/ferrum-core/Cargo.toml +0 -0
  12. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/crates/ferrum-core/benches/hydrate.rs +0 -0
  13. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/crates/ferrum-core/src/compile/mod.rs +0 -0
  14. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/crates/ferrum-core/src/error.rs +0 -0
  15. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/crates/ferrum-core/src/hydrate/mod.rs +0 -0
  16. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/crates/ferrum-core/src/ir/metadata.rs +0 -0
  17. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/crates/ferrum-core/src/ir/mod.rs +0 -0
  18. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/crates/ferrum-core/src/lib.rs +0 -0
  19. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/crates/ferrum-core/src/migrate/mod.rs +0 -0
  20. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/crates/ferrum-pyo3/Cargo.toml +0 -0
  21. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/crates/ferrum-pyo3/src/lib.rs +0 -0
  22. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/crates/ferrum-sql/Cargo.toml +0 -0
  23. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/crates/ferrum-sql/benches/compile.rs +0 -0
  24. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/crates/ferrum-sql/src/dialect.rs +0 -0
  25. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/crates/ferrum-sql/src/emit.rs +0 -0
  26. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/crates/ferrum-sql/src/fts/mod.rs +0 -0
  27. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/crates/ferrum-sql/src/fts/mssql.rs +0 -0
  28. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/crates/ferrum-sql/src/fts/mysql.rs +0 -0
  29. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/crates/ferrum-sql/src/fts/postgres.rs +0 -0
  30. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/crates/ferrum-sql/src/fts/sqlite.rs +0 -0
  31. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/crates/ferrum-sql/src/lib.rs +0 -0
  32. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/_native.pyi +0 -0
  33. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/cli/__init__.py +0 -0
  34. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/cli/app.py +0 -0
  35. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/cli/bootstrap.py +0 -0
  36. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/cli/init.py +0 -0
  37. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/cli/makemigrations_cmd.py +0 -0
  38. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/cli/migrate_cmd.py +0 -0
  39. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/cli/migrations_cmd.py +0 -0
  40. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/cli/resetdb_cmd.py +0 -0
  41. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/cli/revert_cmd.py +0 -0
  42. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/cli/showmigrations_cmd.py +0 -0
  43. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/cli/sqlmigrate_cmd.py +0 -0
  44. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/config.py +0 -0
  45. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/connection.py +0 -0
  46. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/contrib/__init__.py +0 -0
  47. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/contrib/fastapi.py +0 -0
  48. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/drivers/__init__.py +0 -0
  49. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/drivers/mssql.py +0 -0
  50. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/drivers/mysql.py +0 -0
  51. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/drivers/postgres.py +0 -0
  52. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/drivers/protocol.py +0 -0
  53. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/drivers/sqlite.py +0 -0
  54. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/errors.py +0 -0
  55. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/expressions.py +0 -0
  56. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/ext/__init__.py +0 -0
  57. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/ext/fts.py +0 -0
  58. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/ext/pgvector.py +0 -0
  59. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/hooks.py +0 -0
  60. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/migrations/__init__.py +0 -0
  61. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/migrations/base.py +0 -0
  62. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/migrations/drift.py +0 -0
  63. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/migrations/fts/__init__.py +0 -0
  64. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/migrations/fts/mssql.py +0 -0
  65. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/migrations/fts/mysql.py +0 -0
  66. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/migrations/fts/postgres.py +0 -0
  67. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/migrations/fts/sqlite.py +0 -0
  68. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/migrations/gates.py +0 -0
  69. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/migrations/introspect.py +0 -0
  70. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/migrations/ledger.py +0 -0
  71. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/migrations/loader.py +0 -0
  72. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/migrations/operations.py +0 -0
  73. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/migrations/orchestrator.py +0 -0
  74. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/migrations/tokens.py +0 -0
  75. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/observability.py +0 -0
  76. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/py.typed +0 -0
  77. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/registry.py +0 -0
  78. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/relations.py +0 -0
  79. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/runtime.py +0 -0
  80. {ferrum_orm-0.1.5 → ferrum_orm-0.1.7}/python/ferrum/session.py +0 -0
@@ -223,7 +223,7 @@ checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
223
223
 
224
224
  [[package]]
225
225
  name = "ferrum-core"
226
- version = "0.1.5"
226
+ version = "0.1.6"
227
227
  dependencies = [
228
228
  "criterion",
229
229
  "proptest",
@@ -234,7 +234,7 @@ dependencies = [
234
234
 
235
235
  [[package]]
236
236
  name = "ferrum-migrate"
237
- version = "0.1.5"
237
+ version = "0.1.6"
238
238
  dependencies = [
239
239
  "ferrum-core",
240
240
  "serde",
@@ -243,7 +243,7 @@ dependencies = [
243
243
 
244
244
  [[package]]
245
245
  name = "ferrum-pyo3"
246
- version = "0.1.5"
246
+ version = "0.1.6"
247
247
  dependencies = [
248
248
  "ferrum-core",
249
249
  "ferrum-sql",
@@ -255,7 +255,7 @@ dependencies = [
255
255
 
256
256
  [[package]]
257
257
  name = "ferrum-sql"
258
- version = "0.1.5"
258
+ version = "0.1.6"
259
259
  dependencies = [
260
260
  "criterion",
261
261
  "ferrum-core",
@@ -3,7 +3,7 @@ members = ["crates/ferrum-core", "crates/ferrum-sql", "crates/ferrum-pyo3"]
3
3
  resolver = "2"
4
4
 
5
5
  [workspace.package]
6
- version = "0.1.5"
6
+ version = "0.1.6"
7
7
  edition = "2021"
8
8
  authors = ["Ferrum Contributors"]
9
9
  license = "Apache-2.0"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ferrum-orm
3
- Version: 0.1.5
3
+ Version: 0.1.7
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Framework :: AsyncIO
6
6
  Classifier: Intended Audience :: Developers
@@ -173,6 +173,24 @@ users = await (
173
173
  )
174
174
  ```
175
175
 
176
+ ### First-Class IDE Support
177
+
178
+ Ferrum ships a PEP 561 `py.typed` marker, so editors and type checkers (`mypy`, `pyright`,
179
+ `ty`) resolve its inline hints out of the box. `Model.objects` is typed as
180
+ `QuerySet[YourModel]`, chaining preserves the model type, and terminals infer precise results —
181
+ no casts:
182
+
183
+ ```python
184
+ users: list[User] = await User.objects.filter(is_active=True).all(conn) # list[User]
185
+ user: User | None = await User.objects.first(conn) # User | None
186
+ rows: list[dict[str, Any]] = await User.objects.values("id", "email").all(conn)
187
+ ids: list[Any] = await User.objects.values_list("id", flat=True).all(conn)
188
+ ```
189
+
190
+ `values()` / `values_list()` return dedicated `ValuesQuerySet`, `ValuesListQuerySet`, and
191
+ `FlatValuesListQuerySet` variants (all exported from `ferrum`) so `all()` returns
192
+ `list[dict[str, Any]]`, `list[tuple[Any, ...]]`, or `list[Any]` respectively.
193
+
176
194
  ### Rust-Powered Core
177
195
 
178
196
  Performance-critical components are implemented in Rust:
@@ -101,6 +101,24 @@ users = await (
101
101
  )
102
102
  ```
103
103
 
104
+ ### First-Class IDE Support
105
+
106
+ Ferrum ships a PEP 561 `py.typed` marker, so editors and type checkers (`mypy`, `pyright`,
107
+ `ty`) resolve its inline hints out of the box. `Model.objects` is typed as
108
+ `QuerySet[YourModel]`, chaining preserves the model type, and terminals infer precise results —
109
+ no casts:
110
+
111
+ ```python
112
+ users: list[User] = await User.objects.filter(is_active=True).all(conn) # list[User]
113
+ user: User | None = await User.objects.first(conn) # User | None
114
+ rows: list[dict[str, Any]] = await User.objects.values("id", "email").all(conn)
115
+ ids: list[Any] = await User.objects.values_list("id", flat=True).all(conn)
116
+ ```
117
+
118
+ `values()` / `values_list()` return dedicated `ValuesQuerySet`, `ValuesListQuerySet`, and
119
+ `FlatValuesListQuerySet` variants (all exported from `ferrum`) so `all()` returns
120
+ `list[dict[str, Any]]`, `list[tuple[Any, ...]]`, or `list[Any]` respectively.
121
+
104
122
  ### Rust-Powered Core
105
123
 
106
124
  Performance-critical components are implemented in Rust:
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "ferrum-orm"
7
- version = "0.1.5"
7
+ version = "0.1.7"
8
8
  description = "Next-generation async ORM for Python with a Rust-powered core"
9
9
  license = { text = "Apache-2.0" }
10
10
  readme = "README.md"
@@ -6,7 +6,7 @@ Import paths are stable API; internal module paths are not.
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
- __version__ = "0.1.5"
9
+ __version__ = "0.1.7"
10
10
  __all__ = [
11
11
  "CreateExtension",
12
12
  "CreateFunction",
@@ -30,6 +30,7 @@ __all__ = [
30
30
  "FerrumSchemaError",
31
31
  "FerrumTimeoutError",
32
32
  "Field",
33
+ "FlatValuesListQuerySet",
33
34
  "ForeignKey",
34
35
  "FullTextIndex",
35
36
  "Index",
@@ -43,6 +44,8 @@ __all__ = [
43
44
  "RetryPolicy",
44
45
  "TSVector",
45
46
  "Transaction",
47
+ "ValuesListQuerySet",
48
+ "ValuesQuerySet",
46
49
  "Vector",
47
50
  "clear_hooks",
48
51
  "connect",
@@ -101,7 +104,12 @@ from ferrum.models import (
101
104
  Vector,
102
105
  )
103
106
  from ferrum.observability import enable_metrics, enable_opentelemetry, get_metrics
104
- from ferrum.queryset import QuerySet
107
+ from ferrum.queryset import (
108
+ FlatValuesListQuerySet,
109
+ QuerySet,
110
+ ValuesListQuerySet,
111
+ ValuesQuerySet,
112
+ )
105
113
  from ferrum.runtime import RetryPolicy
106
114
  from ferrum.session import (
107
115
  current_setting as get_session_config,
@@ -35,7 +35,7 @@ _HEADER = textwrap.dedent("""\
35
35
  from __future__ import annotations
36
36
  from datetime import date, datetime, time
37
37
  from decimal import Decimal
38
- from typing import Annotated
38
+ from typing import Annotated, ClassVar
39
39
  from uuid import UUID
40
40
 
41
41
  import ferrum
@@ -237,12 +237,18 @@ def _render_class(
237
237
  fk = fk_map[col_name]
238
238
  target_class = _to_class_name(fk["foreign_table_name"])
239
239
  delete_rule = fk["delete_rule"].upper()
240
- # Strip the trailing ``_id`` suffix for the field name if present.
241
- field_name = col_name[:-3] if col_name.endswith("_id") else col_name
242
- lines.append(
243
- f' {field_name}: ForeignKey = ForeignKey(to="{target_class}",'
244
- f' on_delete="{delete_rule}")'
245
- )
240
+ annotation = _pg_type_to_ferrum(pg_type, max_len, precision, scale, is_pk, is_nullable)
241
+ if "Field(" in annotation:
242
+ lines.append(f" {col_name}: {annotation}")
243
+ else:
244
+ lines.append(f" {col_name}: {annotation}")
245
+ # Relation descriptor (ClassVar) — only when the column follows {name}_id.
246
+ if col_name.endswith("_id"):
247
+ rel_name = col_name[:-3]
248
+ lines.append(
249
+ f" {rel_name}: ClassVar[ForeignKey] = ForeignKey("
250
+ f'to="{target_class}", on_delete="{delete_rule}")'
251
+ )
246
252
  continue
247
253
 
248
254
  annotation = _pg_type_to_ferrum(pg_type, max_len, precision, scale, is_pk, is_nullable)
@@ -19,7 +19,20 @@ import re
19
19
  import types as _types
20
20
  from datetime import date, datetime, time
21
21
  from decimal import Decimal
22
- from typing import Annotated, Any, ClassVar, Literal, Union, cast, get_args, get_origin
22
+ from typing import (
23
+ TYPE_CHECKING,
24
+ Annotated,
25
+ Any,
26
+ ClassVar,
27
+ Literal,
28
+ NoReturn,
29
+ TypeVar,
30
+ Union,
31
+ cast,
32
+ get_args,
33
+ get_origin,
34
+ overload,
35
+ )
23
36
  from uuid import UUID
24
37
 
25
38
  from pydantic import BaseModel as _PydanticBaseModel
@@ -950,6 +963,13 @@ def _build_metadata(cls: type[_PydanticBaseModel]) -> ModelMetadata:
950
963
  # Manager descriptor
951
964
  # ---------------------------------------------------------------------------
952
965
 
966
+ if TYPE_CHECKING:
967
+ from ferrum.queryset import QuerySet
968
+
969
+ # Bound to the accessing model type via ``owner`` so ``User.objects`` infers
970
+ # ``QuerySet[User]`` in IDEs / type checkers (PEP 561 descriptor idiom).
971
+ _M = TypeVar("_M", bound="Model")
972
+
953
973
 
954
974
  class _Manager:
955
975
  """Descriptor that vends a fresh ``QuerySet`` bound to the model class.
@@ -962,7 +982,12 @@ class _Manager:
962
982
  ``ferrum.queryset`` (models is the lower layer; queryset depends on it).
963
983
  """
964
984
 
965
- def __get__(self, obj: object, owner: type | None = None) -> Any: # noqa: ANN401
985
+ @overload
986
+ def __get__(self, obj: None, owner: type[_M]) -> QuerySet[_M]: ...
987
+ @overload
988
+ def __get__(self, obj: Model, owner: type[_M]) -> NoReturn: ...
989
+
990
+ def __get__(self, obj: object, owner: type | None = None) -> Any:
966
991
  if obj is not None:
967
992
  raise AttributeError(
968
993
  "'objects' is a class-level manager and cannot be accessed on a model instance."