Skip to content
49 changes: 34 additions & 15 deletions gel/_internal/_codegen/_models/_pydantic.py
Original file line number Diff line number Diff line change
Expand Up @@ -1131,7 +1131,8 @@ def write_schema_reflection(
base_types: Iterable[str] = (),
base_metadata_class: str = "GelSchemaMetadata",
) -> None:
schemapath = self.import_name(BASE_IMPL, "SchemaPath")
sp_clsname = self.import_name(BASE_IMPL, "SchemaPath")
ptn_clsname = self.import_name(BASE_IMPL, "ParametricTypeName")
base_types = list(base_types)
if not base_types:
if isinstance(sobj, reflection.InheritingType):
Expand All @@ -1148,14 +1149,21 @@ def write_schema_reflection(
base_types,
),
):
self.write(f"name = {sobj.schemapath.as_code(schemapath)}")
obj_name = sobj.schemapath.as_python_code(sp_clsname, ptn_clsname)
self.write(f"name = {obj_name}")
if isinstance(sobj, reflection.Type):
type_name = sobj.get_type_name(self._types).as_python_code(
sp_clsname, ptn_clsname
)
self.write(f"type_name = {type_name}")

def write_object_type_reflection(
self,
objtype: reflection.ObjectType,
base_types: list[str],
) -> None:
sp = self.import_name(BASE_IMPL, "SchemaPath")
sp_clsname = self.import_name(BASE_IMPL, "SchemaPath")
ptn_clsname = self.import_name(BASE_IMPL, "ParametricTypeName")
lazyclassproperty = self.import_name(BASE_IMPL, "LazyClassProperty")
objecttype_t = self.get_type(
self._schema_object_type,
Expand Down Expand Up @@ -1186,7 +1194,14 @@ def write_object_type_reflection(
"__gel_reflection__",
_map_name(lambda s: f"{s}.__gel_reflection__", class_bases),
):
self.write(f"name = {objtype.schemapath.as_code(sp)}")
obj_name = objtype.schemapath.as_python_code(
sp_clsname, ptn_clsname
)
type_name = objtype.get_type_name(self._types).as_python_code(
sp_clsname, ptn_clsname
)
self.write(f"name = {obj_name}")
self.write(f"type_name = {type_name}")
# Need a cheap at runtime way to check if the type is abstract
# in GelModel.__new__
self.write(f"abstract = {objtype.abstract!r}")
Expand Down Expand Up @@ -1263,6 +1278,9 @@ def _write_pointers_reflection(
self.write(f"my_ptrs: {ptr_ref_t} = {{")
classes = {
"SchemaPath": self.import_name(BASE_IMPL, "SchemaPath"),
"ParametricTypeName": self.import_name(
BASE_IMPL, "ParametricTypeName"
),
"GelPointerReflection": gel_ptr_ref,
"Cardinality": self.import_name(BASE_IMPL, "Cardinality"),
"PointerKind": self.import_name(BASE_IMPL, "PointerKind"),
Expand Down Expand Up @@ -1301,8 +1319,9 @@ def _reflect_pointer(
target_type = self._types[ptr.target_id]
kwargs: dict[str, str] = {
"name": repr(ptr.name),
"type": target_type.schemapath.as_code(classes["SchemaPath"]),
"typexpr": repr(target_type.edgeql),
"type": target_type.get_type_name(self._types).as_python_code(
classes["SchemaPath"], classes["ParametricTypeName"]
),
"kind": f"{classes['PointerKind']}({str(ptr.kind)!r})",
"cardinality": f"{classes['Cardinality']}({str(ptr.card)!r})",
"computed": str(ptr.is_computed),
Expand Down Expand Up @@ -2800,7 +2819,7 @@ def _write_prefix_op_method_node_ctor(
args = [
"expr=self", # The operand is always 'self' for method calls
f'op="{op_name}"', # Gel operator name (e.g., "-", "+")
"type_=__rtype__.__gel_reflection__.name", # Result type info
"type_=__rtype__.__gel_reflection__.type_name", # Result type info
]

self.write(self.format_list(f"{node_cls}({{list}}),", args))
Expand Down Expand Up @@ -2866,7 +2885,7 @@ def _write_prefix_op_func_node_ctor(
args = [
f"expr={other}",
f'op="{op_name}"', # Gel operator name (e.g., "-", "+")
"type_=__rtype__.__gel_reflection__.name", # Result type info
"type_=__rtype__.__gel_reflection__.type_name", # Result type info
]

self.write(self.format_list(f"{node_cls}({{list}}),", args))
Expand Down Expand Up @@ -2928,7 +2947,7 @@ def _write_infix_op_func_node_ctor(
self.write(f"{op_chain}(")
self.write(f' "{op_name}",')
self.write(" __args__,")
self.write(" __rtype__.__gel_reflection__.name,")
self.write(" __rtype__.__gel_reflection__.type_name,")
self.write(")")
return

Expand All @@ -2951,7 +2970,7 @@ def _write_infix_op_func_node_ctor(
f"lexpr={this}",
f'op="{op_name}"',
f"rexpr={other}",
"type_=__rtype__.__gel_reflection__.name",
"type_=__rtype__.__gel_reflection__.type_name",
]

self.write(self.format_list(f"{node_cls}({{list}}),", args))
Expand Down Expand Up @@ -3027,7 +3046,7 @@ def _write_infix_op_method_node_ctor(

args = [
f'op="{op_name}"', # Gel operator name (e.g., "+", "[]")
"type_=__rtype__.__gel_reflection__.name", # Result type info
"type_=__rtype__.__gel_reflection__.type_name", # Result type info
]

if swapped:
Expand Down Expand Up @@ -5164,7 +5183,7 @@ def _write_func_node_ctor(
self.write("args=__args__,")
if bool(sig.kwargs):
self.write("kwargs=__kwargs__,")
self.write("type_=__rtype__.__gel_reflection__.name,")
self.write("type_=__rtype__.__gel_reflection__.type_name,")
self.write(")")

def _write_function_overload(
Expand Down Expand Up @@ -5485,7 +5504,7 @@ def write_cast_match(
with self.if_(f"{type_var} is None"):
self.write(
f"{type_var} = "
f"{cast_t}.__gel_reflection__.name"
f"{cast_t}.__gel_reflection__.type_name"
)
if type_var is not None:
anytype = self.get_type(self._types_by_name["anytype"])
Expand All @@ -5494,7 +5513,7 @@ def write_cast_match(
with self.if_(f"{type_var} is None"):
self.write(
f"{type_var} = "
f"{var}.__gel_reflection__.name"
f"{var}.__gel_reflection__.type_name"
)

# Build a `match` block for Python-to-Gel coercion of values.
Expand Down Expand Up @@ -5608,7 +5627,7 @@ def write_cast_match(
self.write(
f"{new_pident} = {set_lit}("
f"items=(*{pident},), "
f"type_={canon_type}.__gel_reflection__.name)"
f"type_={canon_type}.__gel_reflection__.type_name)"
)

rt_generics = generic_param_map.get("__return__")
Expand Down
56 changes: 32 additions & 24 deletions gel/_internal/_edgeql/_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,13 @@

from __future__ import annotations

from typing import TYPE_CHECKING, final
from typing import final

import re
import uuid

from gel._internal._polyfills._strenum import StrEnum

if TYPE_CHECKING:
from collections.abc import Iterable
from gel._internal._schemapath import ParametricTypeName, SchemaPath, TypeName


@final
Expand Down Expand Up @@ -73,46 +71,56 @@ def _get_type_id(name: str, cls: str) -> uuid.UUID:


def get_array_type_id_and_name(
element: str,
) -> tuple[uuid.UUID, str]:
type_id = _get_type_id(f"array<{_mangle_name(element)}>", "Array")
type_name = f"array<{element}>"
element: TypeName,
) -> tuple[uuid.UUID, TypeName]:
type_id = _get_type_id(
f"array<{_mangle_name(element.as_schema_name())}>", "Array"
)
type_name = ParametricTypeName(SchemaPath("std", "array"), [element])
return type_id, type_name


def get_range_type_id_and_name(
element: str,
) -> tuple[uuid.UUID, str]:
type_id = _get_type_id(f"range<{_mangle_name(element)}>", "Range")
type_name = f"range<{element}>"
element: TypeName,
) -> tuple[uuid.UUID, TypeName]:
type_id = _get_type_id(
f"range<{_mangle_name(element.as_schema_name())}>", "Range"
)
type_name = ParametricTypeName(
SchemaPath("std", "range"),
[element],
)
return type_id, type_name


def get_multirange_type_id_and_name(
element: str,
) -> tuple[uuid.UUID, str]:
element: TypeName,
) -> tuple[uuid.UUID, TypeName]:
type_id = _get_type_id(
f"multirange<{_mangle_name(element)}>", "MultiRange"
f"multirange<{_mangle_name(element.as_schema_name())}>", "MultiRange"
)
type_name = ParametricTypeName(
SchemaPath("std", "range"),
[element],
)
type_name = f"multirange<{element}>"
return type_id, type_name


def get_tuple_type_id_and_name(
elements: Iterable[str],
) -> tuple[uuid.UUID, str]:
body = ", ".join(elements)
elements: list[TypeName],
) -> tuple[uuid.UUID, TypeName]:
body = ", ".join(element.as_schema_name() for element in elements)
type_id = _get_type_id(f"tuple<{_mangle_name(body)}>", "Tuple")
type_name = f"tuple<{body}>"
type_name = ParametricTypeName(SchemaPath("std", "tuple"), elements)
return type_id, type_name


def get_named_tuple_type_id_and_name(
elements: dict[str, str],
) -> tuple[uuid.UUID, str]:
body = ", ".join(f"{n}:{t}" for n, t in elements.items())
elements: dict[str, TypeName],
) -> tuple[uuid.UUID, TypeName]:
body = ", ".join(f"{n}:{t.as_schema_name()}" for n, t in elements.items())
type_id = _get_type_id(f"tuple<{_mangle_name(body)}>", "Tuple")
type_name = f"tuple<{body}>"
type_name = ParametricTypeName(SchemaPath("std", "tuple"), elements)
return type_id, type_name


Expand Down
10 changes: 5 additions & 5 deletions gel/_internal/_qb/_abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

if TYPE_CHECKING:
from collections.abc import Iterable, Iterator, Mapping
from gel._internal._schemapath import SchemaPath
from gel._internal._schemapath import TypeName


@dataclass(kw_only=True, frozen=True)
Expand Down Expand Up @@ -89,7 +89,7 @@ class Expr(Node):
def precedence(self) -> _edgeql.Precedence: ...

@abc.abstractproperty
def type(self) -> SchemaPath: ...
def type(self) -> TypeName: ...

@abc.abstractmethod
def __edgeql_expr__(self, *, ctx: ScopeContext) -> str: ...
Expand All @@ -100,10 +100,10 @@ def __edgeql_qb_expr__(self) -> Self:

@dataclass(kw_only=True, frozen=True)
class TypedExpr(Expr):
type_: SchemaPath
type_: TypeName

@property
def type(self) -> SchemaPath:
def type(self) -> TypeName:
return self.type_


Expand Down Expand Up @@ -499,7 +499,7 @@ class ImplicitIteratorStmt(IteratorExpr, Stmt):
"""Base class for statements that are implicit iterators"""

@property
def type(self) -> SchemaPath:
def type(self) -> TypeName:
return self.iter_expr.type

@property
Expand Down
Loading