core-framework 0.12.3__py3-none-any.whl → 0.12.4__py3-none-any.whl

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.
core/__init__.py CHANGED
@@ -278,7 +278,7 @@ from core.exceptions import (
278
278
  MissingDependency,
279
279
  )
280
280
 
281
- __version__ = "0.12.3"
281
+ __version__ = "0.12.4"
282
282
  __all__ = [
283
283
  # Models
284
284
  "Model",
core/auth/models.py CHANGED
@@ -58,6 +58,7 @@ def _get_pk_column_type(model_class: type) -> type:
58
58
  Detecta o tipo da coluna PK de um modelo.
59
59
 
60
60
  Bug #3 Fix: Detecção robusta do tipo de PK para FKs.
61
+ Verifica toda a cadeia de herança (MRO) para detectar corretamente.
61
62
 
62
63
  Suporta:
63
64
  - Integer (int)
@@ -71,6 +72,7 @@ def _get_pk_column_type(model_class: type) -> type:
71
72
  from sqlalchemy import Integer, BigInteger, String
72
73
  from sqlalchemy.dialects.postgresql import UUID as PG_UUID
73
74
  from sqlalchemy import Uuid
75
+ import uuid as uuid_module
74
76
 
75
77
  # Verifica cache primeiro
76
78
  cache_key = f"{model_class.__module__}.{model_class.__name__}"
@@ -79,7 +81,30 @@ def _get_pk_column_type(model_class: type) -> type:
79
81
 
80
82
  detected_type = Integer # Default
81
83
 
82
- # Método 1: Tenta obter da tabela mapeada
84
+ # Método 0 (MAIS IMPORTANTE): Verifica herança de AbstractUUIDUser
85
+ # Isso é verificado PRIMEIRO porque funciona mesmo durante o mapeamento
86
+ for base in model_class.__mro__:
87
+ base_name = base.__name__
88
+ # Verifica se herda de AbstractUUIDUser ou qualquer classe com UUID no nome
89
+ if base_name == "AbstractUUIDUser":
90
+ detected_type = PG_UUID
91
+ _pk_type_cache[cache_key] = detected_type
92
+ return detected_type
93
+
94
+ # Método 1: Verifica annotations em TODA a cadeia de herança (MRO)
95
+ for base in model_class.__mro__:
96
+ annotations = getattr(base, "__annotations__", {})
97
+ if "id" in annotations:
98
+ ann = annotations["id"]
99
+ ann_str = str(ann)
100
+
101
+ # Detecta UUID (vários formatos)
102
+ if "UUID" in ann_str or "uuid" in ann_str or "Uuid" in ann_str:
103
+ detected_type = PG_UUID
104
+ _pk_type_cache[cache_key] = detected_type
105
+ return detected_type
106
+
107
+ # Método 2: Tenta obter da tabela já mapeada (se existir)
83
108
  if hasattr(model_class, "__table__"):
84
109
  pk_columns = [c for c in model_class.__table__.columns if c.primary_key]
85
110
  if pk_columns:
@@ -102,40 +127,41 @@ def _get_pk_column_type(model_class: type) -> type:
102
127
  _pk_type_cache[cache_key] = detected_type
103
128
  return detected_type
104
129
 
105
- # Método 2: Tenta via annotations
106
- annotations = getattr(model_class, "__annotations__", {})
107
-
108
- if "id" in annotations:
109
- ann = annotations["id"]
110
- ann_str = str(ann)
111
-
112
- # Detecta UUID (vários formatos)
113
- if "UUID" in ann_str or "uuid" in ann_str or "Uuid" in ann_str:
114
- detected_type = PG_UUID
115
- # Detecta int
116
- elif "int" in ann_str.lower() and "uuid" not in ann_str.lower():
117
- detected_type = Integer
118
- # Detecta str
119
- elif "str" in ann_str.lower() and "uuid" not in ann_str.lower():
120
- detected_type = String
121
-
122
- # Método 3: Verifica campos na classe (declared_attr ou column_property)
123
- for attr_name in dir(model_class):
124
- if attr_name == "id":
125
- attr = getattr(model_class, attr_name, None)
130
+ # Método 3: Verifica atributo 'id' diretamente na classe e bases
131
+ for base in model_class.__mro__:
132
+ if hasattr(base, "id"):
133
+ attr = getattr(base, "id", None)
126
134
  if attr is not None:
127
- # Pode ser um InstrumentedAttribute
135
+ # Pode ser um InstrumentedAttribute ou MappedColumn
128
136
  if hasattr(attr, "type"):
129
137
  attr_type = attr.type
130
138
  if isinstance(attr_type, (PG_UUID, Uuid)):
131
139
  detected_type = PG_UUID
132
140
  break
141
+ type_name = type(attr_type).__name__.upper()
142
+ if "UUID" in type_name:
143
+ detected_type = PG_UUID
144
+ break
133
145
  # Pode ser um mapped_column
134
146
  if hasattr(attr, "property") and hasattr(attr.property, "columns"):
135
147
  for col in attr.property.columns:
136
148
  if isinstance(col.type, (PG_UUID, Uuid)):
137
149
  detected_type = PG_UUID
138
150
  break
151
+ type_name = type(col.type).__name__.upper()
152
+ if "UUID" in type_name:
153
+ detected_type = PG_UUID
154
+ break
155
+ # Verifica se é um MappedColumn com tipo definido
156
+ if hasattr(attr, "column") and hasattr(attr.column, "type"):
157
+ col_type = attr.column.type
158
+ if isinstance(col_type, (PG_UUID, Uuid)):
159
+ detected_type = PG_UUID
160
+ break
161
+ type_name = type(col_type).__name__.upper()
162
+ if "UUID" in type_name:
163
+ detected_type = PG_UUID
164
+ break
139
165
 
140
166
  _pk_type_cache[cache_key] = detected_type
141
167
  return detected_type
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: core-framework
3
- Version: 0.12.3
3
+ Version: 0.12.4
4
4
  Summary: Core Framework - Django-inspired, FastAPI-powered. Alta performance, baixo acoplamento, produtividade extrema.
5
5
  Project-URL: Homepage, https://github.com/SorPuti/core-framework
6
6
  Project-URL: Documentation, https://github.com/SorPuti/core-framework#readme
@@ -1,4 +1,4 @@
1
- core/__init__.py,sha256=sy9liwZ93LJntl_s54pgi3oAM8vHPC_dgaOeVAydmtY,12058
1
+ core/__init__.py,sha256=LpMfN4s5QgM0suYMegcYK7uf2m8dIH90qOsbM5IWSNs,12058
2
2
  core/app.py,sha256=sCA3mJI696i7MIjrPxfOr5zEYt0njarQfHHy3EAajk4,21071
3
3
  core/choices.py,sha256=rhcL3p2dB7RK99zIilpmoTFVcibQEIaRpz0CY0kImCE,10502
4
4
  core/config.py,sha256=2-MVF9nLoYmxpYYH_Gzn4-Sa3MU87YZskRPtlNyhg6Q,14049
@@ -23,7 +23,7 @@ core/auth/base.py,sha256=Q7vXgwTmgdmyW7G8eJmDket2bKB_8YFnraZ_kK9_gTs,21425
23
23
  core/auth/decorators.py,sha256=tmC7prKUvHuzQ3J872nM6r83DR9d82dCLXKLvUB1Os8,12288
24
24
  core/auth/hashers.py,sha256=0gIf67TU0k5H744FADpyh9_ugxA7m3mhYPZxLh_lEtc,12808
25
25
  core/auth/middleware.py,sha256=r4F3AIb4k9Z7gbTwcyG-MVWCyGikQqP54IHNKmyNtdc,10963
26
- core/auth/models.py,sha256=3ekHuaiSNhyQ6K1-w-TNmvtC406qhTT8AttA03Zl3pQ,32636
26
+ core/auth/models.py,sha256=aEE7deQKPS1aH0Btzzh3Z1Bwuqy8zvLZwu4JFEmiUNk,34058
27
27
  core/auth/permissions.py,sha256=v3ykAgNpq5wJ0NkuC_FuveMctOkDfM9Xp11XEnUAuBg,12461
28
28
  core/auth/schemas.py,sha256=L0W96dOD348rJDGeu1K5Rz3aJj-GdwMr2vbwwsYfo2g,3469
29
29
  core/auth/tokens.py,sha256=jk-TnMRdVGPhy6pWqSF2Ef8RTqLrP6Mkuo5GvRQh9no,8489
@@ -78,7 +78,7 @@ example/auth.py,sha256=zBpLutb8lVKnGfQqQ2wnyygsSutHYZzeJBuhnFhxBaQ,4971
78
78
  example/models.py,sha256=xKdx0kJ9n0tZ7sCce3KhV3BTvKvsh6m7G69eFm3ukf0,4549
79
79
  example/schemas.py,sha256=wJ9QofnuHp4PjtM_IuMMBLVFVDJ4YlwcF6uQm1ooKiY,6139
80
80
  example/views.py,sha256=GQwgQcW6yoeUIDbF7-lsaZV7cs8G1S1vGVtiwVpZIQE,14338
81
- core_framework-0.12.3.dist-info/METADATA,sha256=XE6KCQJj3FgemixbQXBicIsp3CrsX5al-SzEPH-vtNk,12791
82
- core_framework-0.12.3.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
83
- core_framework-0.12.3.dist-info/entry_points.txt,sha256=lQ65IAOpieqU1VcHCUReeyandpyy8IKGix6IkJW_4Is,39
84
- core_framework-0.12.3.dist-info/RECORD,,
81
+ core_framework-0.12.4.dist-info/METADATA,sha256=YJACIGfMLNMWJNHuGVX2ltcOvKdZDajmp6GLc_GFzNA,12791
82
+ core_framework-0.12.4.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
83
+ core_framework-0.12.4.dist-info/entry_points.txt,sha256=lQ65IAOpieqU1VcHCUReeyandpyy8IKGix6IkJW_4Is,39
84
+ core_framework-0.12.4.dist-info/RECORD,,