void (@NotNull String elementQName, @NotNull String scopeOwnerQName, @NotNull String text) { VirtualFile virtualFile; try { virtualFile = myFixture.getTempDirFixture().createFile("a.py", text); } catch (IOException e) { throw new RuntimeException(e); } TypeEvalContext typeEvalContext = TypeEvalContext.codeAnalysis(myFixture.getProject(), myFixture.getFile()); PyFile pyFile = (PyFile)PsiManager.getInstance(myFixture.getProject()).findFile(virtualFile); QualifiedName elementQualifiedName = QualifiedName.fromDottedString(elementQName); PsiElement resolvedElement = resolveQualifiedName(pyFile, elementQualifiedName, typeEvalContext); assertNotNull(elementQName, resolvedElement); PyTypedElement typedElement = assertInstanceOf(resolvedElement, PyTypedElement.class); PyType type = typeEvalContext.getType(typedElement); if (type instanceof PyClassType classType) { PyCollectionType genericClassType = PyTypeChecker.findGenericDefinitionType(classType.getPyClass(), typeEvalContext); assertNotNull(genericClassType); type = genericClassType.getElementTypes().get(0); } else if (type instanceof PyFunctionType functionType) { type = functionType.getReturnType(typeEvalContext); if (type instanceof PyCallableType callableType && !(type instanceof PyClassLikeType)) { // For ParamSpecs, they cannot appear as a standalone type type = callableType.getParameters(typeEvalContext).get(0).getType(typeEvalContext); } } if (type instanceof PyTupleType tupleType) { type = tupleType.getElementType(0); } PyTypeParameterType typeVar = assertInstanceOf(type, PyTypeParameterType.class); QualifiedName ownerQualifiedName = QualifiedName.fromDottedString(scopeOwnerQName); PsiElement owner = resolveQualifiedName(pyFile, ownerQualifiedName, typeEvalContext); assertNotNull(scopeOwnerQName, owner); assertEquals(owner, typeVar.getScopeOwner()); assertNotParsed(pyFile); }