def get_schema_object( name: Union[str, qlast.BaseObjectRef], module: Optional[str] = None, *, item_type: Optional[Type[s_obj.Object]] = None, condition: Optional[Callable[[s_obj.Object], bool]] = None, label: Optional[str] = None, ctx: context.ContextLevel, srcctx: Optional[parsing.ParserContext] = None) -> s_obj.Object: if isinstance(name, qlast.ObjectRef): if srcctx is None: srcctx = name.context module = name.module name = name.name elif isinstance(name, qlast.AnyType): return s_pseudo.PseudoType.get(ctx.env.schema, 'anytype') elif isinstance(name, qlast.AnyTuple): return s_pseudo.PseudoType.get(ctx.env.schema, 'anytuple') elif isinstance(name, qlast.BaseObjectRef): raise AssertionError(f"Unhandled BaseObjectRef subclass: {name!r}") if module: name = sn.Name(name=name, module=module) elif isinstance(name, str): view = _get_type_variant(name, ctx) if view is not None: return view try: stype = ctx.env.get_track_schema_object( name=name, modaliases=ctx.modaliases, type=item_type, condition=condition, label=label, ) except errors.QueryError as e: s_utils.enrich_schema_lookup_error(e, name, modaliases=ctx.modaliases, schema=ctx.env.schema, item_type=item_type, condition=condition, context=srcctx) raise view = _get_type_variant(stype.get_name(ctx.env.schema), ctx) if view is not None: return view elif stype == ctx.defining_view: # stype is the view in process of being defined and as such is # not yet a valid schema object raise errors.SchemaDefinitionError( f'illegal self-reference in definition of {name!r}', context=srcctx) else: return stype
def get_schema_object( name: Union[str, qlast.BaseObjectRef], module: Optional[str] = None, *, item_types: Tuple[s_obj.ObjectMeta, ...] = (), condition: Optional[Callable[[s_obj.Object], bool]] = None, label: Optional[str] = None, ctx: context.ContextLevel, srcctx: Optional[parsing.ParserContext] = None) -> s_obj.Object: if isinstance(name, qlast.ObjectRef): if srcctx is None: srcctx = name.context module = name.module name = name.name elif isinstance(name, qlast.AnyType): return s_pseudo.Any.instance() elif isinstance(name, qlast.AnyTuple): return s_pseudo.AnyTuple.instance() elif isinstance(name, qlast.BaseObjectRef): raise AssertionError(f"Unhandled BaseObjectRef subclass: {name!r}") if module: name = sn.Name(name=name, module=module) elif isinstance(name, str): view = ctx.aliased_views.get(name) if view is not None: ctx.must_use_views.pop(view, None) return view try: stype = ctx.env.get_track_schema_object( name=name, modaliases=ctx.modaliases, type=item_types, condition=condition, label=label, ) except errors.QueryError as e: s_utils.enrich_schema_lookup_error(e, name, modaliases=ctx.modaliases, schema=ctx.env.schema, item_types=item_types, condition=condition, context=srcctx) raise view = ctx.aliased_views.get(stype.get_name(ctx.env.schema)) if view is not None: ctx.must_use_views.pop(view, None) return view else: return stype
def get_schema_object( name: typing.Union[str, qlast.BaseObjectRef], module: typing.Optional[str] = None, *, item_types: typing.Optional[typing.Sequence[s_obj.ObjectMeta]], condition: typing.Optional[typing.Callable[[s_types.Type], bool]] = None, label: typing.Optional[str] = None, ctx: context.ContextLevel, srcctx: typing.Optional[parsing.ParserContext] = None) -> s_obj.Object: if isinstance(name, qlast.ObjectRef): if srcctx is None: srcctx = name.context module = name.module name = name.name elif isinstance(name, qlast.AnyType): return s_pseudo.Any.instance elif isinstance(name, qlast.AnyTuple): return s_pseudo.AnyTuple.instance if module: name = sn.Name(name=name, module=module) elif isinstance(name, str): view = ctx.aliased_views.get(name) if view is not None: return view try: stype = ctx.env.get_track_schema_object( name=name, modaliases=ctx.modaliases, type=item_types, condition=condition, label=label, ) except errors.QueryError as e: s_utils.enrich_schema_lookup_error(e, name, modaliases=ctx.modaliases, schema=ctx.env.schema, item_types=item_types, condition=condition, context=srcctx) raise view = ctx.aliased_views.get(stype.get_name(ctx.env.schema)) if view is not None: return view else: return stype
def _get_ref_obj(self, ref, item_type): clsname = self._get_ref_name(ref) try: obj = self._schema.get( clsname, type=item_type, module_aliases=self._mod_aliases) except errors.InvalidReferenceError as e: s_utils.enrich_schema_lookup_error( e, clsname, modaliases=self._mod_aliases, schema=self._schema, item_types=(item_type,)) e.set_source_context(ref.context) raise e return obj
def resolve_ptr(near_endpoint: s_sources.Source, pointer_name: str, *, direction: s_pointers.PointerDirection = ( s_pointers.PointerDirection.Outbound), source_context: typing.Optional[parsing.ParserContext] = None, ctx: context.ContextLevel) -> s_pointers.Pointer: if not isinstance(near_endpoint, s_sources.Source): # Reference to a property on non-object msg = 'invalid property reference on a primitive type expression' raise errors.InvalidReferenceError(msg, context=source_context) ctx.env.schema, ptr = near_endpoint.resolve_pointer(ctx.env.schema, pointer_name, direction=direction) if ptr is None: if isinstance(near_endpoint, s_links.Link): msg = (f'{near_endpoint.get_displayname(ctx.env.schema)} ' f'has no property {pointer_name!r}') elif direction == s_pointers.PointerDirection.Outbound: msg = (f'{near_endpoint.get_displayname(ctx.env.schema)} ' f'has no link or property {pointer_name!r}') else: nep_name = near_endpoint.get_displayname(ctx.env.schema) path = f'{nep_name}.{direction}{pointer_name}' msg = f'{path!r} does not resolve to any known path' err = errors.InvalidReferenceError(msg, context=source_context) if direction == s_pointers.PointerDirection.Outbound: near_enpoint_pointers = near_endpoint.get_pointers(ctx.env.schema) s_utils.enrich_schema_lookup_error( err, pointer_name, modaliases=ctx.modaliases, item_types=(s_pointers.Pointer, ), collection=near_enpoint_pointers.objects(ctx.env.schema), schema=ctx.env.schema) raise err return ptr
def _get_ref_type(self, ref): clsname = self._get_ref_name(ref.maintype) if ref.subtypes: subtypes = [self._get_ref_type(s) for s in ref.subtypes] ccls = s_types.Collection.get_class(clsname) typ = ccls.from_subtypes(self._schema, subtypes) else: try: typ = self._schema.get( clsname, module_aliases=self._mod_aliases) except errors.InvalidReferenceError as e: s_utils.enrich_schema_lookup_error( e, clsname, modaliases=self._mod_aliases, schema=self._schema, item_types=(s_types.Type,)) e.set_source_context(ref.context) raise e return typ
def get_schema_object( name: typing.Union[str, qlast.ObjectRef], module: typing.Optional[str] = None, *, item_types: typing.Optional[typing.List[s_obj.ObjectMeta]], ctx: context.ContextLevel, srcctx: typing.Optional[parsing.ParserContext] = None) -> s_obj.Object: if isinstance(name, qlast.ObjectRef): if srcctx is None: srcctx = name.context module = name.module name = name.name elif isinstance(name, qlast.AnyType): return s_pseudo.Any.instance elif isinstance(name, qlast.AnyTuple): return s_pseudo.AnyTuple.instance if module: name = sn.Name(name=name, module=module) if not module: result = ctx.aliased_views.get(name) if result is not None: return result try: stype = ctx.env.schema.get(name=name, module_aliases=ctx.modaliases, type=item_types) except errors.QueryError as e: s_utils.enrich_schema_lookup_error(e, name, modaliases=ctx.modaliases, schema=ctx.env.schema, item_types=item_types) raise result = ctx.aliased_views.get(stype.get_name(ctx.env.schema)) if result is None: result = stype return result
def _resolve_schema_ref( name: s_name.Name, type: Type[s_obj.Object_T], sourcectx: parsing.ParserContext, *, ctx: LayoutTraceContext, ) -> s_obj.Object_T: try: return ctx.schema.get(name, type=type, sourcectx=sourcectx) except errors.InvalidReferenceError as e: s_utils.enrich_schema_lookup_error( e, name, schema=ctx.schema, modaliases=ctx.modaliases, item_type=type, context=sourcectx, ) raise
def _resolve_schema_ref( name: s_name.Name, type: Type[qltracer.NamedObject], sourcectx: Optional[parsing.ParserContext], *, ctx: LayoutTraceContext, ) -> s_obj.SubclassableObject: real_type = TRACER_TO_REAL_TYPE_MAP[type] try: return ctx.schema.get(name, type=real_type, sourcectx=sourcectx) except errors.InvalidReferenceError as e: s_utils.enrich_schema_lookup_error( e, name, schema=ctx.schema, modaliases=ctx.modaliases, item_type=real_type, context=sourcectx, ) raise
def resolve_ptr( near_endpoint: s_obj.Object, pointer_name: str, *, upcoming_intersections: Sequence[s_types.Type] = (), far_endpoints: Iterable[s_obj.Object] = (), direction: s_pointers.PointerDirection = ( s_pointers.PointerDirection.Outbound), source_context: Optional[parsing.ParserContext] = None, track_ref: Optional[Union[qlast.Base, Literal[False]]], ctx: context.ContextLevel, ) -> s_pointers.Pointer: if not isinstance(near_endpoint, s_sources.Source): # Reference to a property on non-object msg = 'invalid property reference on a primitive type expression' raise errors.InvalidReferenceError(msg, context=source_context) ptr: Optional[s_pointers.Pointer] = None if direction is s_pointers.PointerDirection.Outbound: ptr = near_endpoint.maybe_get_ptr( ctx.env.schema, s_name.UnqualName(pointer_name), ) if ptr is not None: ref = ptr.get_nearest_non_derived_parent(ctx.env.schema) if track_ref is not False: ctx.env.add_schema_ref(ref, track_ref) else: ptrs = near_endpoint.getrptrs(ctx.env.schema, pointer_name, sources=far_endpoints) if ptrs: if track_ref is not False: # If this reverse pointer access is followed by # intersections, we filter out any pointers that # couldn't be picked up by the intersections. This avoids # creating spurious dependencies when reverse # links are used in schemas. dep_ptrs = { ptr for ptr in ptrs if (src := ptr.get_source(ctx.env.schema)) and all( src.issubclass(ctx.env.schema, typ) or any( dsrc.issubclass(ctx.env.schema, typ) for dsrc in src.descendants(ctx.env.schema)) for typ in upcoming_intersections) } for p in dep_ptrs: ctx.env.add_schema_ref( p.get_nearest_non_derived_parent(ctx.env.schema), track_ref) opaque = not far_endpoints ctx.env.schema, ptr = s_pointers.get_or_create_union_pointer( ctx.env.schema, ptrname=s_name.UnqualName(pointer_name), source=near_endpoint, direction=direction, components=ptrs, opaque=opaque, modname=ctx.derived_target_module, ) if ptr is not None: return ptr if isinstance(near_endpoint, s_links.Link): vname = near_endpoint.get_verbosename(ctx.env.schema, with_parent=True) msg = f'{vname} has no property {pointer_name!r}' elif direction == s_pointers.PointerDirection.Outbound: msg = (f'{near_endpoint.get_verbosename(ctx.env.schema)} ' f'has no link or property {pointer_name!r}') else: nep_name = near_endpoint.get_displayname(ctx.env.schema) path = f'{nep_name}.{direction}{pointer_name}' msg = f'{path!r} does not resolve to any known path' err = errors.InvalidReferenceError(msg, context=source_context) if direction is s_pointers.PointerDirection.Outbound: near_enpoint_pointers = near_endpoint.get_pointers(ctx.env.schema) s_utils.enrich_schema_lookup_error( err, s_name.UnqualName(pointer_name), modaliases=ctx.modaliases, item_type=s_pointers.Pointer, collection=near_enpoint_pointers.objects(ctx.env.schema), schema=ctx.env.schema, ) raise err
def resolve_ptr( near_endpoint: s_obj.Object, pointer_name: str, *, far_endpoints: Iterable[s_obj.Object] = (), direction: s_pointers.PointerDirection = ( s_pointers.PointerDirection.Outbound ), source_context: Optional[parsing.ParserContext] = None, track_ref: Optional[Union[qlast.Base, Literal[False]]], ctx: context.ContextLevel, ) -> s_pointers.Pointer: if not isinstance(near_endpoint, s_sources.Source): # Reference to a property on non-object msg = 'invalid property reference on a primitive type expression' raise errors.InvalidReferenceError(msg, context=source_context) ptr: Optional[s_pointers.Pointer] = None if direction is s_pointers.PointerDirection.Outbound: ptr = near_endpoint.maybe_get_ptr( ctx.env.schema, s_name.UnqualName(pointer_name), ) if ptr is not None: ref = ptr.get_nearest_non_derived_parent(ctx.env.schema) if track_ref is not False: ctx.env.add_schema_ref(ref, track_ref) else: ptrs = near_endpoint.getrptrs(ctx.env.schema, pointer_name, sources=far_endpoints) if ptrs: if track_ref is not False: for p in ptrs: ctx.env.add_schema_ref( p.get_nearest_non_derived_parent(ctx.env.schema), track_ref) opaque = not far_endpoints ctx.env.schema, ptr = s_pointers.get_or_create_union_pointer( ctx.env.schema, ptrname=s_name.UnqualName(pointer_name), source=near_endpoint, direction=direction, components=ptrs, opaque=opaque, modname=ctx.derived_target_module, ) if ptr is not None: return ptr if isinstance(near_endpoint, s_links.Link): vname = near_endpoint.get_verbosename(ctx.env.schema, with_parent=True) msg = f'{vname} has no property {pointer_name!r}' elif direction == s_pointers.PointerDirection.Outbound: msg = (f'{near_endpoint.get_verbosename(ctx.env.schema)} ' f'has no link or property {pointer_name!r}') else: nep_name = near_endpoint.get_displayname(ctx.env.schema) path = f'{nep_name}.{direction}{pointer_name}' msg = f'{path!r} does not resolve to any known path' err = errors.InvalidReferenceError(msg, context=source_context) if direction is s_pointers.PointerDirection.Outbound: near_enpoint_pointers = near_endpoint.get_pointers(ctx.env.schema) s_utils.enrich_schema_lookup_error( err, s_name.UnqualName(pointer_name), modaliases=ctx.modaliases, item_type=s_pointers.Pointer, collection=near_enpoint_pointers.objects(ctx.env.schema), schema=ctx.env.schema, ) raise err
def resolve_ptr( near_endpoint: s_sources.Source, pointer_name: str, *, direction: s_pointers.PointerDirection=( s_pointers.PointerDirection.Outbound ), source_context: typing.Optional[parsing.ParserContext]=None, ctx: context.ContextLevel) -> s_pointers.Pointer: if not isinstance(near_endpoint, s_sources.Source): # Reference to a property on non-object msg = 'invalid property reference on a primitive type expression' raise errors.InvalidReferenceError(msg, context=source_context) if direction is s_pointers.PointerDirection.Outbound: ptr = near_endpoint.getptr(ctx.env.schema, pointer_name) else: ptrs = near_endpoint.getrptrs(ctx.env.schema, pointer_name) if not ptrs: ptr = None else: if len(ptrs) == 1: ptr = next(iter(ptrs)) else: ctx.env.schema_refs.update( p.get_nearest_non_derived_parent(ctx.env.schema) for p in ptrs ) ctx.env.schema, ptr = s_pointers.get_or_create_union_pointer( ctx.env.schema, ptrname=pointer_name, source=near_endpoint, direction=direction, components=ptrs, modname=ctx.derived_target_module) if ptr is None: if isinstance(near_endpoint, s_links.Link): msg = (f'{near_endpoint.get_verbosename(ctx.env.schema)} ' f'has no property {pointer_name!r}') elif direction == s_pointers.PointerDirection.Outbound: msg = (f'{near_endpoint.get_verbosename(ctx.env.schema)} ' f'has no link or property {pointer_name!r}') else: nep_name = near_endpoint.get_displayname(ctx.env.schema) path = f'{nep_name}.{direction}{pointer_name}' msg = f'{path!r} does not resolve to any known path' err = errors.InvalidReferenceError(msg, context=source_context) if direction == s_pointers.PointerDirection.Outbound: near_enpoint_pointers = near_endpoint.get_pointers( ctx.env.schema) s_utils.enrich_schema_lookup_error( err, pointer_name, modaliases=ctx.modaliases, item_types=(s_pointers.Pointer,), collection=near_enpoint_pointers.objects(ctx.env.schema), schema=ctx.env.schema ) raise err ref = ptr.get_nearest_non_derived_parent(ctx.env.schema) ctx.env.schema_refs.add(ref) return ptr