@Override
 public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) {
   for (PyTypeProvider provider : Extensions.getExtensions(PyTypeProvider.EP_NAME)) {
     final PyType type = provider.getCallableType(this, context);
     if (type != null) {
       return type;
     }
   }
   final PyFunctionTypeImpl type = new PyFunctionTypeImpl(this);
   if (PyKnownDecoratorUtil.hasUnknownDecorator(this, context) && getProperty() == null) {
     return PyUnionType.createWeakType(type);
   }
   return type;
 }
 @Nullable
 private PyType analyzeCallType(
     @Nullable PyType type,
     @Nullable PyExpression receiver,
     @NotNull Map<PyExpression, PyNamedParameter> parameters,
     @NotNull TypeEvalContext context) {
   if (PyTypeChecker.hasGenerics(type, context)) {
     final Map<PyGenericType, PyType> substitutions =
         PyTypeChecker.unifyGenericCall(receiver, parameters, context);
     if (substitutions != null) {
       type = PyTypeChecker.substitute(type, substitutions, context);
     } else {
       type = null;
     }
   }
   if (receiver != null) {
     type = replaceSelf(type, receiver, context);
   }
   if (type != null && isDynamicallyEvaluated(parameters.values(), context)) {
     type = PyUnionType.createWeakType(type);
   }
   return type;
 }