def _find_cast(orig_stype: s_types.Type, new_stype: s_types.Type, *, srcctx: Optional[parsing.ParserContext], ctx: context.ContextLevel) -> Optional[s_casts.Cast]: casts = ctx.env.schema.get_casts_to_type(new_stype) if not casts and isinstance(new_stype, s_types.InheritingType): ancestors = new_stype.get_ancestors(ctx.env.schema) for t in ancestors.objects(ctx.env.schema): casts = ctx.env.schema.get_casts_to_type(t) if casts: break else: return None args = [ (orig_stype, irast.EmptySet()), (new_stype, irast.EmptySet()), ] matched = polyres.find_callable((CastCallableWrapper(c) for c in casts), args=args, kwargs={}, ctx=ctx) if len(matched) == 1: return cast(CastCallableWrapper, matched[0].func)._cast elif len(matched) > 1: raise errors.QueryError( f'cannot unambiguously cast ' f'{orig_stype.get_displayname(ctx.env.schema)!r} ' f'to {new_stype.get_displayname(ctx.env.schema)!r}', context=srcctx) else: return None
def new_empty_set(*, stype: typing.Optional[s_types.Type]=None, alias: str, ctx: context.ContextLevel, srcctx: typing.Optional[ parsing.ParserContext]=None) -> irast.Set: if stype is None: stype = s_pseudo.Any.create() ctx.env.type_origins[stype] = srcctx typeref = irtyputils.type_to_typeref(ctx.env.schema, stype) path_id = pathctx.get_expression_path_id(stype, alias, ctx=ctx) ir_set = irast.EmptySet(path_id=path_id, typeref=typeref) ctx.env.set_types[ir_set] = stype return ir_set
def new_empty_set(*, stype: typing.Optional[s_types.Type] = None, alias: str, ctx: context.ContextLevel) -> irast.Set: if stype is None: path_id_scls = s_pseudo.Any.create() else: path_id_scls = stype path_id = pathctx.get_expression_path_id(path_id_scls, alias, ctx=ctx) ir_set = irast.EmptySet(path_id=path_id) ctx.env.set_types[ir_set] = stype return ir_set
def new_empty_set(*, stype: Optional[s_types.Type]=None, alias: str, ctx: context.ContextLevel, srcctx: Optional[ parsing.ParserContext]=None) -> irast.Set: if stype is None: stype = s_pseudo.PseudoType.get(ctx.env.schema, 'anytype') if srcctx is not None: ctx.env.type_origins[stype] = srcctx typeref = typegen.type_to_typeref(stype, env=ctx.env) path_id = pathctx.get_expression_path_id(stype, alias, ctx=ctx) ir_set = irast.EmptySet(path_id=path_id, typeref=typeref) ctx.env.set_types[ir_set] = stype return ir_set
def find_callable_typemods( candidates: Sequence[s_func.CallableLike], *, num_args: int, kwargs_names: AbstractSet[str], ctx: context.ContextLevel) -> Dict[Union[int, str], ft.TypeModifier]: """Find the type modifiers for a callable. We do this early, before we've compiled/checked the arguments, so that we can compile the arguments with the proper fences. """ typ = s_pseudo.PseudoType.get(ctx.env.schema, 'anytype') dummy = irast.EmptySet() # type: ignore args = [(typ, dummy)] * num_args kwargs = {k: (typ, dummy) for k in kwargs_names} options = find_callable(candidates, basic_matching_only=True, args=args, kwargs=kwargs, ctx=ctx) # No options means an error is going to happen later, but for now, # just return some placeholders so that we can make it to the # error later. if not options: return {k: _SINGLETON for k in set(range(num_args)) | kwargs_names} fts: Dict[Union[int, str], ft.TypeModifier] = {} for choice in options: for barg in choice.args: if not barg.param or barg.arg_id is None: continue ft = barg.param.get_typemod(ctx.env.schema) if barg.arg_id in fts and fts[barg.arg_id] != ft: if ft == _SET_OF or fts[barg.arg_id] == _SET_OF: raise errors.QueryError( f'argument could be SET OF or not in call to ' f'{candidates[0].get_verbosename(ctx.env.schema)}: ' f'seems like a stdlib bug!') else: # If there is a mix between OPTIONAL and SINGLETON # arguments in possible call sites, we just call it # optional. Generated code quality will be a little # worse but still correct. fts[barg.arg_id] = _OPTIONAL else: fts[barg.arg_id] = ft return fts
def _find_cast( orig_stype: s_types.Type, new_stype: s_types.Type, *, srcctx: Optional[parsing.ParserContext], ctx: context.ContextLevel) -> Optional[s_casts.Cast]: # Don't try to pick up casts when there is a direct subtyping # relationship. if (orig_stype.issubclass(ctx.env.schema, new_stype) or new_stype.issubclass(ctx.env.schema, orig_stype)): return None casts = ctx.env.schema.get_casts_to_type(new_stype) if not casts and isinstance(new_stype, s_types.InheritingType): ancestors = new_stype.get_ancestors(ctx.env.schema) for t in ancestors.objects(ctx.env.schema): casts = ctx.env.schema.get_casts_to_type(t) if casts: break else: return None dummy_set = irast.EmptySet() # type: ignore args = [ (orig_stype, dummy_set), (new_stype, dummy_set), ] matched = polyres.find_callable( (CastCallableWrapper(c) for c in casts), args=args, kwargs={}, ctx=ctx) if len(matched) == 1: return cast(CastCallableWrapper, matched[0].func)._cast elif len(matched) > 1: raise errors.QueryError( f'cannot unambiguously cast ' f'{orig_stype.get_displayname(ctx.env.schema)!r} ' f'to {new_stype.get_displayname(ctx.env.schema)!r}', context=srcctx) else: return None