예제 #1
0
 def visit_conversion(
     self,
     tp: AnyType,
     conversion: Optional[Any],
     dynamic: bool,
     next_conversion: Optional[AnyConversion] = None,
 ):
     ref_types = []
     if not dynamic:
         for ref_tp in self.resolve_conversion(tp):
             ref_types.append(ref_tp)
             if self._incr_ref(get_type_name(ref_tp).json_schema, ref_tp):
                 return
     if not is_hashable(tp):
         return super().visit_conversion(tp, conversion, dynamic,
                                         next_conversion)
     # 2 because the first type encountered of the recursive cycle can have no ref
     # (see test_recursive_by_conversion_schema)
     if self._rec_guard[(tp, self._conversions)] > 2:
         raise TypeError(f"Recursive type {tp} need a ref")
     self._rec_guard[(tp, self._conversions)] += 1
     try:
         super().visit_conversion(tp, conversion, dynamic, next_conversion)
     except Unsupported:
         for ref_tp in ref_types:
             self.refs.pop(get_type_name(ref_tp).json_schema,
                           ...)  # type: ignore
     finally:
         self._rec_guard[(tp, self._conversions)] -= 1
예제 #2
0
 def generic(self, cls: AnyType) -> JsonSchema:
     origin = get_origin(cls)
     if is_hashable(origin) and self.is_extra_conversions(origin):
         self._schema = None
     else:
         self._merge_schema(get_schema(origin))
     return super().generic(cls)
예제 #3
0
    def visit(self, tp: AnyType) -> Result:
        if not is_hashable(tp):
            return super().visit(tp)
        cache_key = (tp, self._conversions, self._cache_key())
        if cache_key in self._visit_cache:
            return self._visit_cache[cache_key]
        result = None

        def lazy_result():
            assert result is not None
            return result

        self._visit_cache[cache_key] = self._recursive_result(lazy_result)
        try:
            result = super().visit(tp)
        finally:
            del self._visit_cache[cache_key]
        return result
예제 #4
0
 def visit_with_schema(
         self, cls: AnyType, ref: Optional[str],
         schema: Optional[Schema]) -> Thunk[graphql.GraphQLType]:
     if self.is_id(cls):
         return graphql.GraphQLNonNull(graphql.GraphQLID)
     if is_hashable(cls) and not self.is_extra_conversions(cls):
         ref, schema = ref or get_ref(cls), merge_schema(
             get_schema(cls), schema)
     else:
         schema, ref = None, None
     ref_save, schema_save, non_null_save = self._ref, self._schema, self._non_null
     self._ref, self._schema, self._non_null = ref, schema, True
     try:
         result = super().visit(cls)
         non_null = self._non_null
         return lambda: exec_thunk(result, non_null=non_null)
     except MissingRef:
         raise TypeError(f"Missing ref for type {cls}")
     finally:
         self._ref, self._schema = ref_save, schema_save
         self._non_null = non_null_save
예제 #5
0
 def visit_with_schema(self, cls: AnyType,
                       schema: Optional[Schema]) -> JsonSchema:
     schema_save = self._schema
     if not is_hashable(cls):
         self._schema = schema
     elif self.is_extra_conversions(cls):
         self._schema = None
     else:
         self._schema = schema
         ref = get_ref(cls)
         if ref in self.refs:
             if self._ignore_first_ref:
                 self._ignore_first_ref = False
             else:
                 assert isinstance(ref, str)
                 return self._ref_schema(ref)
         self._merge_schema(get_schema(cls))
     try:
         return super().visit(cls)
     finally:
         self._schema = schema_save
예제 #6
0
 def visit_conversion(
     self,
     tp: AnyType,
     conversion: Any,
     dynamic: bool,
     next_conversion: Optional[AnyConversion] = None,
 ) -> Sequence[AnyType]:
     if conversion is not None and self._skip_conversion:
         return [] if dynamic else [tp]
     self._skip_conversion = False
     results: Sequence[AnyType] = []
     if not is_hashable(tp):
         with suppress(NotImplementedError, Unsupported):
             results = super().visit_conversion(tp, conversion, dynamic,
                                                next_conversion)
     elif (tp, conversion) not in self._rec_guard:
         self._rec_guard.add((tp, conversion))
         with suppress(NotImplementedError, Unsupported):
             results = super().visit_conversion(tp, conversion, dynamic,
                                                next_conversion)
         self._rec_guard.remove((tp, conversion))
     if not dynamic and (conversion is not None or not results):
         results = [tp, *results]
     return results
예제 #7
0
파일: refs.py 프로젝트: aubustou/apischema
 def visit(self, cls: AnyType):
     if (not is_hashable(cls) or self.is_extra_conversions(cls)
             or not self._incr_ref(get_ref(cls), cls)):
         super().visit(cls)