def ast_objref_to_objref(node: ql_ast.ObjectRef, *, metaclass: typing.Optional[so.ObjectMeta] = None, modaliases: typing.Dict[typing.Optional[str], str], schema) -> so.Object: if metaclass is not None and issubclass(metaclass, so.GlobalObject): return schema.get_global(metaclass, node.name) nqname = node.name module = node.module if module is not None: lname = sn.Name(module=module, name=nqname) else: lname = nqname obj = schema.get(lname, module_aliases=modaliases, default=None) if obj is not None: return obj if module is None: err = errors.InvalidReferenceError( f'reference to a non-existent schema item {nqname!r}', context=node.context) enrich_schema_lookup_error( err, lname, modaliases=modaliases, schema=schema, item_types=(metaclass, ) if metaclass is not None else None) raise err return so.ObjectRef(name=sn.Name(module=module, name=nqname))
def __new__(cls, name, module=None): if not name: raise NameError('name must not be empty') if isinstance(name, SchemaName): _name = name.name _module = name.module elif module is not None: _name = name _module = module else: _module, _, _name = name.rpartition('::') if not _module: if not module: err = 'improperly formed name: ' \ 'module is not specified: {}'.format(name) raise errors.InvalidReferenceError(err) else: _module = module result = super().__new__(cls, _module + '::' + _name) result.name = _name result.module = _module return result
def _check_factoring_errors( self, path_id: pathid.PathId, descendant: ScopeTreeNodeWithPathId, factor_point: ScopeTreeNode, existing: ScopeTreeNodeWithPathId, unnest_fence: bool, existing_finfo: FenceInfo, context: Optional[pctx.ParserContext], ) -> None: if existing_finfo.factoring_fence: # This node is already present in the surrounding # scope and cannot be factored out, such as # a reference to a correlated set inside a DML # statement. raise errors.InvalidReferenceError( f'cannot reference correlated set ' f'{path_id.pformat()!r} here', context=context, ) if (unnest_fence and (factor_point.find_child( path_id, in_branches=True, pfx_with_invariant_card=True, ) is None) and (not path_id.is_type_intersection_path() or ((src_path := path_id.src_path()) and src_path is not None and not self.is_visible(src_path)))):
def get(self, name, default=_void, *, module_aliases=None, type=None, condition=None, label=None): def getter(schema, name): obj = schema._get_by_name(name, type=type) if obj is not None and condition is not None: if not condition(obj): obj = None return obj obj = self._get(name, getter=getter, module_aliases=module_aliases, default=default) if obj is not _void: return obj if label is None: if type is not None: if isinstance(type, tuple): label = " or ".join(t.get_schema_class_displayname() for t in type) else: label = type.get_schema_class_displayname() else: label = 'schema item' raise errors.InvalidReferenceError(f'{label} {name!r} does not exist')
def resolve_name( lname: sn.Name, *, metaclass: Optional[Type[so.Object]] = None, modaliases: Mapping[Optional[str], str], schema: s_schema.Schema, ) -> sn.Name: obj = schema.get( lname, type=metaclass, module_aliases=modaliases, default=None, ) if obj is not None: name = obj.get_name(schema) elif isinstance(lname, sn.QualName): name = sn.QualName( module=modaliases.get(lname.module, lname.module), name=lname.name, ) elif metaclass is not None and issubclass(metaclass, so.QualifiedObject): actual_module = modaliases.get(None) if actual_module is None: raise errors.InvalidReferenceError( 'unqualified name and no default module alias set') name = sn.QualName(module=actual_module, name=lname.name) else: # Do not assume the name is fully-qualified unless asked # explicitly. name = lname return name
def resolve_special_anchor( anchor: qlast.SpecialAnchor, *, ctx: context.ContextLevel) -> irast.Set: # '__source__' and '__subject__` can only appear as the # starting path label syntactically and must be pre-populated # by the compile() caller. if isinstance(anchor, qlast.SpecialAnchor): token = anchor.name else: raise errors.InternalServerError( f'unexpected special anchor kind: {anchor!r}' ) anchors = ctx.anchors path_tip = anchors.get(token) if path_tip is None: raise errors.InvalidReferenceError( f'{token} cannot be used in this expression', context=anchor.context, ) return path_tip
def __new__( cls: Type[NameT], name: Union[SchemaName, str], module: Optional[str] = None, ) -> NameT: if not name: raise NameError('name must not be empty') if isinstance(name, SchemaName): _name = name.name _module = name.module elif module is not None: _name = name _module = module else: _module, _, _name = name.rpartition('::') if not _module: if not module: err = 'improperly formed name: ' \ 'module is not specified: {}'.format(name) raise errors.InvalidReferenceError(err) else: _module = module # Ignore below since Mypy doesn't believe you can pass `_fullname` to # object.__new__. _fullname = f"{_module}::{_name}" result = super().__new__(cls, _fullname) # type: ignore result.name = _name result.module = _module return cast(NameT, result)
def _delete(self, obj: so.Object) -> Schema: data = self._id_to_data.get(obj.id) if data is None: raise errors.InvalidReferenceError( f'cannot delete {obj!r}: not in this schema') name = data['name'] updates = {} name_to_id, shortname_to_id, globalname_to_id = self._update_obj_name( obj.id, self._id_to_type[obj.id], name, None) refs_to = self._update_refs_to(obj, self._id_to_data[obj.id], None) updates.update( dict( name_to_id=name_to_id, shortname_to_id=shortname_to_id, globalname_to_id=globalname_to_id, id_to_data=self._id_to_data.delete(obj.id), id_to_type=self._id_to_type.delete(obj.id), refs_to=refs_to, )) return self._replace(**updates) # type: ignore
def _get_local_obj( refname: s_name.QualName, tracer_type: Type[qltracer.NamedObject], sourcectx: Optional[parsing.ParserContext], *, ctx: LayoutTraceContext, ) -> Optional[qltracer.NamedObject]: obj = ctx.objects.get(refname) if isinstance(obj, s_pseudo.PseudoType): raise errors.SchemaError( f'invalid type: {obj.get_verbosename(ctx.schema)} is a generic ' f'type and they are not supported in user-defined schema', context=sourcectx, ) elif obj is not None and not isinstance(obj, tracer_type): obj_type = TRACER_TO_REAL_TYPE_MAP[type(obj)] real_type = TRACER_TO_REAL_TYPE_MAP[tracer_type] raise errors.InvalidReferenceError( f'{str(refname)!r} exists, but is ' f'{english.add_a(obj_type.get_schema_class_displayname())}, ' f'not {english.add_a(real_type.get_schema_class_displayname())}', context=sourcectx, ) return obj
def _delete(self, obj): data = self._id_to_data.get(obj.id) if data is None: raise errors.InvalidReferenceError( f'cannot delete {obj!r}: not in this schema') name = data['name'] updates = {} if isinstance(obj, s_modules.Module): updates['modules'] = self._modules.delete(name) name_to_id, shortname_to_id = self._update_obj_name( obj.id, self._id_to_type[obj.id], name, None) refs_to = self._update_refs_to(obj, self._id_to_data[obj.id], None) updates.update( dict( name_to_id=name_to_id, shortname_to_id=shortname_to_id, id_to_data=self._id_to_data.delete(obj.id), id_to_type=self._id_to_type.delete(obj.id), refs_to=refs_to, )) return self._replace(**updates)
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_global(self, objtype, name, default=_void): obj_id = self._globalname_to_id.get((objtype, name)) if obj_id is not None: return self._id_to_type[obj_id] elif default is not _void: return default else: raise errors.InvalidReferenceError( f'reference to a non-existent {objtype.__name__}: {name}')
def get_global(self, objtype, name, default=_void): obj_id = self._globalname_to_id.get((objtype, name)) if obj_id is not None: return self._id_to_type[obj_id] elif default is not _void: return default else: desc = objtype.get_schema_class_displayname() raise errors.InvalidReferenceError( f'{desc} {name!r} does not exist')
def get_operators(self, name, default=_void, *, module_aliases=None): funcs = self._get(name, getter=_get_operators, module_aliases=module_aliases, default=default) if funcs is not _void: return funcs raise errors.InvalidReferenceError(f'operator {name!r} does not exist')
def get_object(self, schema, context, *, name=None): try: return super().get_object(schema, context, name=name) except errors.InvalidReferenceError: referrer_ctx = self.get_referrer_context(context) referrer = referrer_ctx.scls expr = self.get_attribute_value('expr') raise errors.InvalidReferenceError( f"index {expr.origtext!r} does not exist on " f"{referrer.get_verbosename(schema)}") from None
def get_by_id(self, obj_id, default=_void): try: return self._id_to_type[obj_id] except KeyError: if default is _void: raise errors.InvalidReferenceError( f'reference to a non-existent schema item {obj_id}' f' in schema {self!r}') from None else: return default
def normalize_index(self, schema, field: str) -> str: if self.named and field.isdecimal(): idx = int(field) if idx >= 0 and idx < len(self.element_types): return list(self.element_types.keys())[idx] else: raise errors.InvalidReferenceError( f'{field} is not a member of ' f'{self.get_displayname(schema)}') return field
def get_operators(self, name, default=_void, *, module_aliases=None): funcs = self._get(name, getter=_get_operators, module_aliases=module_aliases, default=default) if funcs is not _void: return funcs raise errors.InvalidReferenceError( f'reference to a non-existent operator: {name}')
def normalize_index(self, schema, field: str) -> str: if self.is_named(schema) and field.isdecimal(): idx = int(field) el_names = self.get_element_names(schema) if idx >= 0 and idx < len(el_names): return el_names[idx] else: raise errors.InvalidReferenceError( f'{field} is not a member of ' f'{self.get_displayname(schema)}') return field
def get_subtype(self, schema, field: str) -> Type: # index can be a name or a position if field.isdecimal(): idx = int(field) if idx >= 0 and idx < len(self.element_types): return list(self.element_types.values())[idx] elif self.named and field in self.element_types: return self.element_types[field] raise errors.InvalidReferenceError( f'{field} is not a member of {self.get_displayname(schema)}')
def index_of(self, schema, field: str) -> int: if field.isdecimal(): idx = int(field) if idx >= 0 and idx < len(self.element_types): if self.named: return list(self.element_types.keys()).index(field) else: return idx elif self.named and field in self.element_types: return list(self.element_types.keys()).index(field) raise errors.InvalidReferenceError( f'{field} is not a member of {self.get_displayname(schema)}')
def get_by_id( # NoQA: F811 self, obj_id: uuid.UUID, default: Union[so.Object_T, so.NoDefaultT, None] = so.NoDefault, *, type: Optional[Type[so.Object_T]] = None, ) -> Optional[so.Object_T]: try: obj = self._id_to_type[obj_id] except KeyError: if default is so.NoDefault: raise errors.InvalidReferenceError( f'reference to a non-existent schema item {obj_id}' f' in schema {self!r}') from None else: return default else: if type is not None and not isinstance(obj, type): raise errors.InvalidReferenceError( f'schema object {obj_id!r} exists, but is not ' f'{type.get_schema_class_displayname()}') return cast(so.Object_T, obj)
def get(self, name, default=_void, *, module_aliases=None, type=None): def getter(schema, name): return schema._get_by_name(name, type=type) obj = self._get(name, getter=getter, module_aliases=module_aliases, default=default) if obj is not _void: return obj raise errors.InvalidReferenceError( f'reference to a non-existent schema item {name}')
def get_by_id( # NoQA: F811 self, obj_id: uuid.UUID, default: Union[so.Object, so.NoDefaultT, None] = so.NoDefault, ) -> Optional[so.Object]: try: return self._id_to_type[obj_id] except KeyError: if default is so.NoDefault: raise errors.InvalidReferenceError( f'reference to a non-existent schema item {obj_id}' f' in schema {self!r}') from None else: return default
def get_functions(self, name, default=so.NoDefault, *, module_aliases=None): funcs = self._get(name, getter=_get_functions, module_aliases=module_aliases, default=default) if funcs is not so.NoDefault: return funcs raise errors.InvalidReferenceError(f'function {name!r} does not exist')
def get_global( # NoQA: F811 self, objtype: Type[so.Object_T], name: str, default: Union[so.Object_T, so.NoDefaultT, None] = so.NoDefault, ) -> Optional[so.Object_T]: obj_id = self._globalname_to_id.get((objtype, name)) if obj_id is not None: return cast(so.Object_T, self._id_to_type[obj_id]) elif default is not so.NoDefault: return default else: desc = objtype.get_schema_class_displayname() raise errors.InvalidReferenceError( f'{desc} {name!r} does not exist')
def get_subtype(self, schema, field: str) -> Type: # index can be a name or a position if field.isdecimal(): idx = int(field) subtypes = list(self.get_subtypes(schema)) if idx >= 0 and idx < len(subtypes): return subtypes[idx] elif self.is_named(schema): subtypes = dict(self.iter_subtypes(schema)) if field in subtypes: return subtypes[field] raise errors.InvalidReferenceError( f'{field} is not a member of {self.get_displayname(schema)}')
def from_string( cls: Type[QualNameT], name: str, ) -> QualNameT: module, _, nqname = name.rpartition('::') if not module: err = (f'improperly formed name {name!r}: ' f'module is not specified') raise errors.InvalidReferenceError(err) return cls( module=module, name=nqname, )
def get_object( # type: ignore self, schema: s_schema.Schema, context: sd.CommandContext, *, name: Optional[str] = None, ) -> Optional[Index]: try: return super().get_object(schema, context, name=name) except errors.InvalidReferenceError: referrer_ctx = self.get_referrer_context_or_die(context) referrer = referrer_ctx.scls expr = self.get_attribute_value('expr') raise errors.InvalidReferenceError( f"index {expr.origtext!r} does not exist on " f"{referrer.get_verbosename(schema)}") from None
def get( # NoQA: F811 self, name: str, default: Union[so.Object_T, so.NoDefaultT, None] = so.NoDefault, *, module_aliases: Optional[Mapping[Optional[str], str]] = None, type: Optional[Type[so.Object_T]] = None, condition: Optional[Callable[[so.Object], bool]] = None, label: Optional[str] = None, sourcectx: Optional[parsing.ParserContext] = None, ) -> Optional[so.Object_T]: def getter(schema: Schema, name: str) -> Optional[so.Object]: obj = schema._get_by_name(name, type=type) if obj is not None and condition is not None: if not condition(obj): obj = None return obj obj = self._get(name, getter=getter, module_aliases=module_aliases, default=default) if obj is not so.NoDefault: return cast(so.Object_T, obj) if label is None: if type is not None: label = type.get_schema_class_displayname() else: label = 'schema item' refname = name if type is not None: if not sn.Name.is_qualified(refname): if module_aliases is not None: default_module = module_aliases.get(None) if default_module is not None: refname = type.get_displayname_static( f'{default_module}::{refname}', ) else: refname = type.get_displayname_static(refname) raise errors.InvalidReferenceError( f'{label} {refname!r} does not exist', context=sourcectx)