From 3c31c2f2697a108c5235361f0463b81be65e2775 Mon Sep 17 00:00:00 2001 From: Vyacheslav Tamarin Date: Thu, 17 Nov 2022 15:10:55 +0300 Subject: [PATCH 1/2] Remove python3parser from python codegen (code for running and code for mypy checking) --- .../python/PythonTestGenerationProcessor.kt | 6 +- .../kotlin/org/utbot/python/UTPythonAPI.kt | 3 + .../kotlin/org/utbot/python/code/CodeGen.kt | 452 ++---------------- .../codegen/model/PythonCodeGenerator.kt | 124 ++++- .../framework/codegen/model/PythonImports.kt | 4 +- .../constructor/name/PythonCgNameGenerator.kt | 2 +- .../tree/PythonCgMethodConstructor.kt | 2 +- .../constructor/util/ConstructorUtils.kt | 2 +- .../constructor/visitor/CgPythonRenderer.kt | 6 +- .../org/utbot/python/utils/ModuleToString.kt | 10 + .../src/main/resources/requirements.txt | 3 +- 11 files changed, 181 insertions(+), 433 deletions(-) create mode 100644 utbot-python/src/main/kotlin/org/utbot/python/utils/ModuleToString.kt diff --git a/utbot-python/src/main/kotlin/org/utbot/python/PythonTestGenerationProcessor.kt b/utbot-python/src/main/kotlin/org/utbot/python/PythonTestGenerationProcessor.kt index f5df5ac24a..7ec0b43c8a 100644 --- a/utbot-python/src/main/kotlin/org/utbot/python/PythonTestGenerationProcessor.kt +++ b/utbot-python/src/main/kotlin/org/utbot/python/PythonTestGenerationProcessor.kt @@ -2,9 +2,9 @@ package org.utbot.python import com.squareup.moshi.Moshi import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory -import org.utbot.framework.codegen.PythonSysPathImport -import org.utbot.framework.codegen.PythonSystemImport -import org.utbot.framework.codegen.PythonUserImport +import org.utbot.python.framework.codegen.model.PythonSysPathImport +import org.utbot.python.framework.codegen.model.PythonSystemImport +import org.utbot.python.framework.codegen.model.PythonUserImport import org.utbot.framework.codegen.TestFramework import org.utbot.framework.codegen.model.constructor.CgMethodTestSet import org.utbot.framework.plugin.api.ExecutableId diff --git a/utbot-python/src/main/kotlin/org/utbot/python/UTPythonAPI.kt b/utbot-python/src/main/kotlin/org/utbot/python/UTPythonAPI.kt index 401f055699..5abed8dead 100644 --- a/utbot-python/src/main/kotlin/org/utbot/python/UTPythonAPI.kt +++ b/utbot-python/src/main/kotlin/org/utbot/python/UTPythonAPI.kt @@ -1,11 +1,13 @@ package org.utbot.python import io.github.danielnaczo.python3parser.model.stmts.compoundStmts.functionStmts.FunctionDef +import io.github.danielnaczo.python3parser.model.mods.Module import org.utbot.framework.plugin.api.UtError import org.utbot.framework.plugin.api.UtExecution import org.utbot.python.framework.api.python.PythonClassId import org.utbot.python.framework.api.python.util.pythonAnyClassId import org.utbot.python.typing.MypyAnnotations +import org.utbot.python.utils.moduleToString data class PythonArgument(val name: String, val annotation: String?) @@ -17,6 +19,7 @@ interface PythonMethod { fun asString(): String fun ast(): FunctionDef val containingPythonClassId: PythonClassId? + fun codeLines(): List = moduleToString(Module(listOf(ast().body))).split('\n') fun methodSignature(): String = "$name(" + arguments.joinToString(", ") { "${it.name}: ${it.annotation ?: pythonAnyClassId.name}" } + ")" diff --git a/utbot-python/src/main/kotlin/org/utbot/python/code/CodeGen.kt b/utbot-python/src/main/kotlin/org/utbot/python/code/CodeGen.kt index 48b46893da..0975f817a7 100644 --- a/utbot-python/src/main/kotlin/org/utbot/python/code/CodeGen.kt +++ b/utbot-python/src/main/kotlin/org/utbot/python/code/CodeGen.kt @@ -1,114 +1,16 @@ package org.utbot.python.code -import io.github.danielnaczo.python3parser.model.Identifier -import io.github.danielnaczo.python3parser.model.expr.Expression -import io.github.danielnaczo.python3parser.model.expr.atoms.Atom -import io.github.danielnaczo.python3parser.model.expr.atoms.Name -import io.github.danielnaczo.python3parser.model.expr.atoms.Str -import io.github.danielnaczo.python3parser.model.expr.atoms.trailers.Attribute -import io.github.danielnaczo.python3parser.model.expr.atoms.trailers.arguments.Arguments -import io.github.danielnaczo.python3parser.model.expr.atoms.trailers.arguments.Keyword -import io.github.danielnaczo.python3parser.model.expr.datastructures.ListExpr -import io.github.danielnaczo.python3parser.model.expr.datastructures.Tuple -import io.github.danielnaczo.python3parser.model.expr.operators.binaryops.Add -import io.github.danielnaczo.python3parser.model.mods.Module -import io.github.danielnaczo.python3parser.model.stmts.Body -import io.github.danielnaczo.python3parser.model.stmts.Statement -import io.github.danielnaczo.python3parser.model.stmts.compoundStmts.functionStmts.FunctionDef -import io.github.danielnaczo.python3parser.model.stmts.compoundStmts.functionStmts.parameters.Parameter -import io.github.danielnaczo.python3parser.model.stmts.compoundStmts.functionStmts.parameters.Parameters -import io.github.danielnaczo.python3parser.model.stmts.compoundStmts.tryExceptStmts.ExceptHandler -import io.github.danielnaczo.python3parser.model.stmts.compoundStmts.tryExceptStmts.Try -import io.github.danielnaczo.python3parser.model.stmts.compoundStmts.withStmts.With -import io.github.danielnaczo.python3parser.model.stmts.compoundStmts.withStmts.WithItem -import io.github.danielnaczo.python3parser.model.stmts.importStmts.Alias -import io.github.danielnaczo.python3parser.model.stmts.importStmts.Import -import io.github.danielnaczo.python3parser.model.stmts.importStmts.ImportFrom -import io.github.danielnaczo.python3parser.model.stmts.smallStmts.assignStmts.Assign -import io.github.danielnaczo.python3parser.visitors.prettyprint.IndentationPrettyPrint -import io.github.danielnaczo.python3parser.visitors.prettyprint.ModulePrettyPrintVisitor +import org.utbot.framework.plugin.api.ExecutableId import org.utbot.framework.plugin.api.UtModel +import org.utbot.framework.plugin.api.util.UtContext +import org.utbot.framework.plugin.api.util.withUtContext import org.utbot.python.PythonMethod -import org.utbot.python.code.AnnotationProcessor.getModulesFromAnnotation import org.utbot.python.framework.api.python.NormalizedPythonAnnotation -import org.utbot.python.framework.api.python.util.pythonAnyClassId +import org.utbot.python.framework.api.python.PythonClassId +import org.utbot.python.framework.codegen.PythonCgLanguageAssistant object PythonCodeGenerator { - private val pythonTreeSerializerCode = PythonCodeGenerator::class.java.getResource("/python_tree_serializer.py") - ?.readText(Charsets.UTF_8) - ?: error("Didn't find preprocessed_values.json") - - private fun toString(module: Module): String { - val modulePrettyPrintVisitor = ModulePrettyPrintVisitor() - return modulePrettyPrintVisitor.visitModule(module, IndentationPrettyPrint(0)) - } - - private fun createArguments( - args: List = emptyList(), - keywords: List = emptyList(), - starredArgs: List = emptyList(), - doubleStarredArgs: List = emptyList() - ): Arguments { - return Arguments(args, keywords, starredArgs, doubleStarredArgs) - } - - private fun generateImportFunctionCode( - functionPath: String, - directoriesForSysPath: Set, - additionalModules: Set = emptySet(), - ): List { - val systemImport = Import( - listOf( - Alias("sys"), - Alias("typing"), - Alias("json"), - Alias("inspect"), - Alias("builtins"), - ) - ) - val systemCalls = directoriesForSysPath.map { path -> - Atom( - Name("sys.path.append"), - listOf( - createArguments( - listOf(Str(path)) - ) - ) - ) - } - - val additionalImport = additionalModules.map { Import(listOf(Alias(it))) } - val import = ImportFrom(functionPath, listOf(Alias("*"))) - return listOf(systemImport) + systemCalls + additionalImport + listOf(import) - } - - private fun generateFunctionCallForTopLevelFunction(method: PythonMethod): Atom { - val keywords = method.arguments.map { - Keyword(Name(it.name), Name(it.name)) - } - return Atom( - Name(method.name), - listOf( - createArguments(emptyList(), keywords) - ) - ) - } - - private fun generateMethodCall(method: PythonMethod): Atom { - assert(method.containingPythonClassId != null) - val keywords = method.arguments.drop(1).map { - Keyword(Name(it.name), Name(it.name)) - } - return Atom( - Name(method.arguments[0].name), - listOf( - Attribute(Identifier(method.name)), - createArguments(emptyList(), keywords) - ) - ) - } - const val successStatus = "success" const val failStatus = "fail" @@ -120,277 +22,23 @@ object PythonCodeGenerator { additionalModules: Set = emptySet(), fileForOutputName: String ): String { - - val importStatements = generateImportFunctionCode( - moduleToImport, - directoriesForSysPath, - additionalModules + setOf("coverage") - ) - - val testFunctionName = "__run_${method.name}" - val testFunction = FunctionDef(testFunctionName) - - val parameters = methodArguments.zip(method.arguments).map { (model, argument) -> - Assign( - listOf(Name(argument.name)), - Name(model.toString()) + val context = UtContext(this::class.java.classLoader) + withUtContext(context) { + val codegen = org.utbot.python.framework.codegen.model.PythonCodeGenerator( + PythonClassId("TopLevelFunction"), + paramNames = emptyMap>().toMutableMap(), + testFramework = PythonCgLanguageAssistant.getLanguageTestFrameworkManager().testFrameworks[0], + testClassPackageName = "", + ) + return codegen.generateFunctionCall( + method, + methodArguments, + directoriesForSysPath, + moduleToImport, + additionalModules, + fileForOutputName ) } - - val resultName = Name("__result") - val startName = Name("__start") - val endName = Name("__end") - val sourcesName = Name("__sources") - val stmtsName = Name("__stmts") - val stmtsFilteredName = Name("__stmts_filtered") - val stmtsFilteredWithDefName = Name("__stmts_filtered_with_def") - val missedName = Name("__missed") - val missedFilteredName = Name("__missed_filtered") - val coverageName = Name("__cov") - val fullpathName = Name("__fullpath") - val statusName = Name("__status") - val exceptionName = Name("__exception") - val serialisedName = Name("__serialized") - val fileName = Name("__out_file") - - val fullpath = Assign( - listOf(fullpathName), - Str(method.moduleFilename) - ) - - val functionCall = - if (method.containingPythonClassId == null) - generateFunctionCallForTopLevelFunction(method) - else - generateMethodCall(method) - - val fullFunctionName = Name( - ( - listOf((functionCall.atomElement as Name).id.name) + functionCall.trailers.mapNotNull { - if (it is Attribute) { - it.attr.name - } else { - null - } - }).joinToString(".") - ) - - val coverage = Assign( - listOf(coverageName), - Name("coverage.Coverage(data_suffix=True)") - ) - val startCoverage = Atom( - coverageName, - listOf(Attribute(Identifier("start")), createArguments()) - ) - - val resultSuccess = Assign( - listOf(resultName), - functionCall - ) - - val statusSuccess = Assign( - listOf(statusName), - Str("\"" + successStatus + "\"") - ) - - val resultError = Assign( - listOf(resultName), - exceptionName - ) - - val statusError = Assign( - listOf(statusName), - Str("\"" + failStatus + "\"") - ) - - val stopCoverage = Atom( - coverageName, - listOf(Attribute(Identifier("stop")), createArguments()) - ) - val sourcesAndStart = Assign( - listOf(Tuple(listOf(sourcesName, startName))), - Atom( - Name("inspect.getsourcelines"), - listOf(createArguments(listOf(fullFunctionName))) - ) - ) - val end = Assign( - listOf(endName), - Add( - startName, - Atom(Name("len"), listOf(createArguments(listOf(sourcesName)))) - ) - ) - val covAnalysis = Assign( - listOf( - Tuple( - listOf( - Name("_"), - stmtsName, - Name("_"), - missedName, - Name("_") - ) - ) - ), - Atom( - coverageName, - listOf( - Attribute(Identifier("analysis2")), - createArguments(listOf(fullpathName)) - ) - ) - ) - val clean = Atom( - coverageName, - listOf(Attribute(Identifier("erase")), createArguments()) - ) - val stmtsFiltered = Assign( - listOf(stmtsFilteredName), - Atom( - Name(getLinesName), - listOf(createArguments(listOf(startName, endName, stmtsName))) - ) - ) - val stmtsFilteredWithDef = Assign( - listOf(stmtsFilteredWithDefName), - Add( - ListExpr(listOf(startName)), - stmtsFilteredName - ) - ) - val missedFiltered = Assign( - listOf(missedFilteredName), - Atom( - Name(getLinesName), - listOf(createArguments(listOf(startName, endName, missedName))) - ) - ) - - val serialize = Assign( - listOf(serialisedName), - Atom( - Name("_PythonTreeSerializer().dumps"), - listOf(createArguments(listOf(resultName))) - ) - ) - - val jsonDumps = Atom( - Name("json"), - listOf( - Attribute(Identifier("dumps")), - createArguments(listOf(serialisedName)) - ) - ) - - val listToJoin = ListExpr( - listOf( - Atom(Name("str"), listOf(createArguments(listOf(statusName)))), - Atom(Name("str"), listOf(createArguments(listOf(jsonDumps)))), - Atom( - Name("str"), - listOf(createArguments(listOf(stmtsFilteredWithDefName))) - ), - Atom( - Name("str"), - listOf(createArguments(listOf(missedFilteredName))) - ) - ) - ) - - val joinedList = - Atom( - Name("\"\\n\""), - listOf( - Attribute(Identifier("join")), - createArguments( - listOf( - listToJoin - ) - ) - ) - ) - - val printStmt = With( - listOf( - WithItem(Name("open(\"$fileForOutputName\", \"w\")"), fileName) - ), - Atom( - fileName, - listOf( - Attribute(Identifier("write")), - createArguments( - listOf( - joinedList - ) - ) - ) - ) - ) - - val tryBody = Body( - listOf( - resultSuccess, - statusSuccess - ) - ) - val suppressedBlock = With( - listOf( - WithItem( - Atom( - Name(getStdoutSuppressName), - listOf(createArguments()) - ) - ) - ), - tryBody - ) - val failBody = Body( - listOf( - resultError, - statusError - ) - ) - val tryHandler = ExceptHandler("Exception", exceptionName.id.name) - val tryBlock = Try(suppressedBlock, listOf(tryHandler), listOf(failBody)) - - (parameters + listOf( - fullpath, - coverage, - startCoverage - )).forEach { testFunction.addStatement(it) } - - testFunction.addStatement(tryBlock) - - listOf( - stopCoverage, - sourcesAndStart, - end, - covAnalysis, - clean, - stmtsFiltered, - stmtsFilteredWithDef, - missedFiltered, - serialize, - printStmt - ).forEach { testFunction.addStatement(it) } - - val runFunction = Atom( - Name(testFunctionName), - listOf(createArguments()) - ) - - return listOf( - getStdoutSuppress, - pythonTreeSerializerCode, - getLines, - toString( - Module( - importStatements + listOf(testFunction, runFunction) - ) - ) - ).joinToString("\n\n") } fun generateMypyCheckCode( @@ -399,52 +47,20 @@ object PythonCodeGenerator { directoriesForSysPath: Set, moduleToImport: String ): String { - val importStatements = generateImportFunctionCode( - moduleToImport, - directoriesForSysPath, - methodAnnotations.values.flatMap { annotation -> - getModulesFromAnnotation(annotation) - }.toSet(), - ) - - val parameters = Parameters( - method.arguments.map { argument -> - Parameter("${argument.name}: ${methodAnnotations[argument.name] ?: pythonAnyClassId.name}") - }, - ) - - val testFunctionName = "__mypy_check_${method.name}" - val testFunction = FunctionDef( - testFunctionName, - parameters, - method.ast().body - ) - - return toString( - Module( - importStatements + listOf(testFunction) + val context = UtContext(this::class.java.classLoader) + withUtContext(context) { + val codegen = org.utbot.python.framework.codegen.model.PythonCodeGenerator( + PythonClassId("TopLevelFunction"), + paramNames = emptyMap>().toMutableMap(), + testFramework = PythonCgLanguageAssistant.getLanguageTestFrameworkManager().testFrameworks[0], + testClassPackageName = "", + ) + return codegen.generateMypyCheckCode( + method, + methodAnnotations, + directoriesForSysPath, + moduleToImport ) - ) + } } - - private const val getLinesName: String = "__get_lines" - private val getLines: String = """ - def ${this.getLinesName}(start, end, lines): - return list(filter(lambda x: start < x < end, lines)) - """.trimIndent() - - private const val getStdoutSuppressName: String = "__suppress_stdout" - private val getStdoutSuppress: String = """ - import os - from contextlib import contextmanager - @contextmanager - def ${this.getStdoutSuppressName}(): - with open(os.devnull, "w") as devnull: - old_stdout = sys.stdout - sys.stdout = devnull - try: - yield - finally: - sys.stdout = old_stdout - """.trimIndent() } diff --git a/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/PythonCodeGenerator.kt b/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/PythonCodeGenerator.kt index 33aec599b1..b7a34e8cf2 100644 --- a/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/PythonCodeGenerator.kt +++ b/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/PythonCodeGenerator.kt @@ -7,12 +7,23 @@ import org.utbot.framework.codegen.model.CodeGeneratorResult import org.utbot.framework.codegen.model.constructor.CgMethodTestSet import org.utbot.framework.codegen.model.constructor.TestClassModel import org.utbot.framework.codegen.model.constructor.context.CgContext -import org.utbot.framework.plugin.api.ClassId -import org.utbot.framework.plugin.api.CodegenLanguage -import org.utbot.framework.plugin.api.ExecutableId -import org.utbot.framework.plugin.api.MockFramework +import org.utbot.framework.codegen.model.tree.* +import org.utbot.framework.codegen.model.util.CgPrinterImpl +import org.utbot.framework.codegen.model.visitor.CgRendererContext +import org.utbot.framework.plugin.api.* +import org.utbot.python.PythonMethod +import org.utbot.python.code.AnnotationProcessor.getModulesFromAnnotation +import org.utbot.python.framework.api.python.NormalizedPythonAnnotation +import org.utbot.python.framework.api.python.PythonClassId +import org.utbot.python.framework.api.python.util.pythonAnyClassId +import org.utbot.python.framework.api.python.util.pythonNoneClassId +import org.utbot.python.framework.api.python.util.pythonStrClassId import org.utbot.python.framework.codegen.PythonCgLanguageAssistant import org.utbot.python.framework.codegen.model.constructor.tree.PythonCgTestClassConstructor +import org.utbot.python.framework.codegen.model.constructor.visitor.CgPythonRenderer +import org.utbot.python.framework.codegen.model.tree.CgPythonDict +import org.utbot.python.framework.codegen.model.tree.CgPythonFunctionCall +import org.utbot.python.framework.codegen.model.tree.CgPythonList class PythonCodeGenerator( classUnderTest: ClassId, @@ -70,4 +81,109 @@ class PythonCodeGenerator( CodeGeneratorResult(renderClassFile(testClassFile), testClassFile.testsGenerationReport) } } + + fun generateFunctionCall( + method: PythonMethod, + methodArguments: List, + directoriesForSysPath: Set, + moduleToImport: String, + additionalModules: Set = emptySet(), + fileForOutputName: String + ): String { + val cgRendererContext = CgRendererContext.fromCgContext(context) + val printer = CgPrinterImpl() + val renderer = CgPythonRenderer(cgRendererContext, printer) + + val executorFunctionName = "run_calculate_function_value" + val executorModuleName = "utbot_executor.executor" + + val importExecutor = PythonUserImport(executorFunctionName, executorModuleName) + val importSys = PythonSystemImport("sys") + val importSysPaths = directoriesForSysPath.map { PythonSysPathImport(it) } + val importFunction = PythonUserImport("*", moduleToImport) + val imports = + listOf(importSys) + importSysPaths + listOf(importExecutor, importFunction) + additionalModules.map { PythonUserImport(it) } + + val containingClass = method.containingPythonClassId + val functionName = + if (containingClass == null) + CgLiteral(pythonAnyClassId, method.name) + else + CgLiteral(pythonAnyClassId, "${containingClass.name}.${method.name}") + + val arguments = method.arguments.map { argument -> + CgVariable(argument.name, argument.annotation?.let { PythonClassId(it) } ?: pythonAnyClassId) + } + + val parameters = methodArguments.zip(arguments).map { (model, argument) -> + CgAssignment( + argument, + CgLiteral(model.classId, model.toString()) + ) + } + + val args = CgPythonList(emptyList()) + val kwargs = CgPythonDict( + arguments.associateBy { argument -> CgLiteral(pythonStrClassId, "'${argument.name}'") } + ) + + val fullpath = CgLiteral(pythonStrClassId, "'${method.moduleFilename}'") + + val outputPath = CgLiteral(pythonStrClassId, "'$fileForOutputName'") + + val executorCall = CgPythonFunctionCall( + pythonNoneClassId, + executorFunctionName, + listOf( + functionName, + args, + kwargs, + fullpath, + outputPath, + ) + ) + + imports.forEach { + renderer.renderPythonImport(it) + } + parameters.forEach { it.accept(renderer) } + executorCall.accept(renderer) + return renderer.toString() + } + + fun generateMypyCheckCode( + method: PythonMethod, + methodAnnotations: Map, + directoriesForSysPath: Set, + moduleToImport: String + ): String { + val cgRendererContext = CgRendererContext.fromCgContext(context) + val printer = CgPrinterImpl() + val renderer = CgPythonRenderer(cgRendererContext, printer) + + val importSys = PythonSystemImport("sys") + val importTyping = PythonSystemImport("typing") + val importSysPaths = directoriesForSysPath.map { PythonSysPathImport(it) } + val importFunction = PythonUserImport("*", moduleToImport) + val additionalModules = methodAnnotations.values.flatMap { annotation -> + getModulesFromAnnotation(annotation).map { PythonUserImport(it) } + } + val imports = listOf(importSys, importTyping) + importSysPaths + (listOf(importFunction) + additionalModules).toSet().toList() + + imports.forEach { renderer.renderPythonImport(it) } + + val parameters = method.arguments.map { argument -> + "${argument.name}: ${methodAnnotations[argument.name] ?: pythonAnyClassId.name}" + } + + val functionPrefix = "__mypy_check" + val functionName = "def ${functionPrefix}_{method.name}(${parameters.joinToString(", ")}):" // TODO: in future can be "async def" + + val mypyCheckCode = listOf( + renderer.toString(), + "", + functionName, + ) + method.codeLines().map { " $it" } + return mypyCheckCode.joinToString("\n") + } } \ No newline at end of file diff --git a/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/PythonImports.kt b/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/PythonImports.kt index e40c76b78e..60c26a21f6 100644 --- a/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/PythonImports.kt +++ b/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/PythonImports.kt @@ -1,4 +1,6 @@ -package org.utbot.framework.codegen +package org.utbot.python.framework.codegen.model + +import org.utbot.framework.codegen.Import sealed class PythonImport(order: Int) : Import(order) { var importName: String = "" diff --git a/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/name/PythonCgNameGenerator.kt b/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/name/PythonCgNameGenerator.kt index 94692fb9b4..0a7f34df5b 100644 --- a/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/name/PythonCgNameGenerator.kt +++ b/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/name/PythonCgNameGenerator.kt @@ -1,6 +1,6 @@ package org.utbot.python.framework.codegen.model.constructor.name -import org.utbot.framework.codegen.PythonImport +import org.utbot.python.framework.codegen.model.PythonImport import org.utbot.framework.codegen.isLanguageKeyword import org.utbot.framework.codegen.model.constructor.context.CgContext import org.utbot.framework.codegen.model.constructor.context.CgContextOwner diff --git a/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/tree/PythonCgMethodConstructor.kt b/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/tree/PythonCgMethodConstructor.kt index 4b78a4cc14..997c9cd226 100644 --- a/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/tree/PythonCgMethodConstructor.kt +++ b/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/tree/PythonCgMethodConstructor.kt @@ -76,7 +76,7 @@ class PythonCgMethodConstructor(context: CgContext) : CgMethodConstructor(contex } } - private fun pythonBuildObject(objectNode: PythonTree.PythonTreeNode): CgValue { + fun pythonBuildObject(objectNode: PythonTree.PythonTreeNode): CgValue { return when (objectNode) { is PythonTree.PrimitiveNode -> { CgLiteral(objectNode.type, objectNode.repr) diff --git a/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/util/ConstructorUtils.kt b/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/util/ConstructorUtils.kt index 222850ac89..24f63b1411 100644 --- a/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/util/ConstructorUtils.kt +++ b/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/util/ConstructorUtils.kt @@ -2,7 +2,7 @@ package org.utbot.python.framework.codegen.model.constructor.util import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.PersistentSet -import org.utbot.framework.codegen.PythonUserImport +import org.utbot.python.framework.codegen.model.PythonUserImport import org.utbot.framework.codegen.model.constructor.context.CgContextOwner import org.utbot.python.framework.api.python.PythonClassId import org.utbot.python.framework.api.python.PythonMethodId diff --git a/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/visitor/CgPythonRenderer.kt b/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/visitor/CgPythonRenderer.kt index e3f1cd36f3..3fd9f3cbed 100644 --- a/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/visitor/CgPythonRenderer.kt +++ b/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/visitor/CgPythonRenderer.kt @@ -3,8 +3,8 @@ package org.utbot.python.framework.codegen.model.constructor.visitor import org.apache.commons.text.StringEscapeUtils import org.utbot.common.WorkaroundReason import org.utbot.common.workaround -import org.utbot.framework.codegen.PythonImport -import org.utbot.framework.codegen.PythonSysPathImport +import org.utbot.python.framework.codegen.model.PythonImport +import org.utbot.python.framework.codegen.model.PythonSysPathImport import org.utbot.framework.codegen.RegularImport import org.utbot.framework.codegen.StaticImport import org.utbot.framework.codegen.model.tree.* @@ -245,7 +245,7 @@ internal class CgPythonRenderer( .forEach { renderPythonImport(it) } } - private fun renderPythonImport(pythonImport: PythonImport) { + fun renderPythonImport(pythonImport: PythonImport) { if (pythonImport is PythonSysPathImport) { println("sys.path.append('${pythonImport.sysPath}')") } else if (pythonImport.moduleName == null) { diff --git a/utbot-python/src/main/kotlin/org/utbot/python/utils/ModuleToString.kt b/utbot-python/src/main/kotlin/org/utbot/python/utils/ModuleToString.kt new file mode 100644 index 0000000000..ffe1b4adfb --- /dev/null +++ b/utbot-python/src/main/kotlin/org/utbot/python/utils/ModuleToString.kt @@ -0,0 +1,10 @@ +package org.utbot.python.utils + +import io.github.danielnaczo.python3parser.model.mods.Module +import io.github.danielnaczo.python3parser.visitors.prettyprint.IndentationPrettyPrint +import io.github.danielnaczo.python3parser.visitors.prettyprint.ModulePrettyPrintVisitor + +fun moduleToString(module: Module): String { + val modulePrettyPrintVisitor = ModulePrettyPrintVisitor() + return modulePrettyPrintVisitor.visitModule(module, IndentationPrettyPrint(0)) +} \ No newline at end of file diff --git a/utbot-python/src/main/resources/requirements.txt b/utbot-python/src/main/resources/requirements.txt index 60cf8c7abe..b57d6cc74b 100644 --- a/utbot-python/src/main/resources/requirements.txt +++ b/utbot-python/src/main/resources/requirements.txt @@ -1,4 +1,5 @@ mypy==0.971 astor typeshed-client -coverage \ No newline at end of file +coverage +utbot-executor \ No newline at end of file From 6e95ecf45b8e54d46fdbc7bd4da7a76b02276c65 Mon Sep 17 00:00:00 2001 From: Vyacheslav Tamarin Date: Thu, 17 Nov 2022 15:26:54 +0300 Subject: [PATCH 2/2] Fix imports --- .../framework/codegen/model/PythonCodeGenerator.kt | 9 +++++++-- .../python/framework/codegen/model/PythonImports.kt | 2 -- .../codegen/model/constructor/util/ConstructorUtils.kt | 3 +-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/PythonCodeGenerator.kt b/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/PythonCodeGenerator.kt index e8495d76c0..9b5ca12f6c 100644 --- a/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/PythonCodeGenerator.kt +++ b/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/PythonCodeGenerator.kt @@ -5,14 +5,18 @@ import org.utbot.framework.codegen.CodeGeneratorResult import org.utbot.framework.codegen.domain.ForceStaticMocking import org.utbot.framework.codegen.domain.HangingTestsTimeout import org.utbot.framework.codegen.domain.ParametrizedTestSource -import org.utbot.framework.codegen.PythonImport import org.utbot.framework.codegen.domain.RuntimeExceptionTestsBehaviour import org.utbot.framework.codegen.domain.StaticsMocking import org.utbot.framework.codegen.domain.TestFramework +import org.utbot.framework.codegen.domain.context.CgContext +import org.utbot.framework.codegen.domain.models.CgLiteral import org.utbot.framework.codegen.domain.models.CgMethodTestSet +import org.utbot.framework.codegen.domain.models.CgVariable +import org.utbot.framework.codegen.domain.models.CgAssignment import org.utbot.framework.codegen.domain.models.TestClassModel -import org.utbot.framework.codegen.domain.context.CgContext import org.utbot.framework.codegen.renderer.CgAbstractRenderer +import org.utbot.framework.codegen.renderer.CgPrinterImpl +import org.utbot.framework.codegen.renderer.CgRendererContext import org.utbot.python.PythonMethod import org.utbot.python.code.AnnotationProcessor.getModulesFromAnnotation import org.utbot.python.framework.api.python.NormalizedPythonAnnotation @@ -23,6 +27,7 @@ import org.utbot.python.framework.api.python.util.pythonStrClassId import org.utbot.framework.plugin.api.ClassId import org.utbot.framework.plugin.api.ExecutableId import org.utbot.framework.plugin.api.MockFramework +import org.utbot.framework.plugin.api.UtModel import org.utbot.python.framework.codegen.PythonCgLanguageAssistant import org.utbot.python.framework.codegen.model.constructor.tree.PythonCgTestClassConstructor import org.utbot.python.framework.codegen.model.constructor.visitor.CgPythonRenderer diff --git a/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/PythonImports.kt b/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/PythonImports.kt index 6930bedf13..32539f397a 100644 --- a/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/PythonImports.kt +++ b/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/PythonImports.kt @@ -1,7 +1,5 @@ package org.utbot.python.framework.codegen.model -import org.utbot.framework.codegen.Import - import org.utbot.framework.codegen.domain.Import sealed class PythonImport(order: Int) : Import(order) { diff --git a/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/util/ConstructorUtils.kt b/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/util/ConstructorUtils.kt index 2246271652..4ac0501fb7 100644 --- a/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/util/ConstructorUtils.kt +++ b/utbot-python/src/main/kotlin/org/utbot/python/framework/codegen/model/constructor/util/ConstructorUtils.kt @@ -2,11 +2,10 @@ package org.utbot.python.framework.codegen.model.constructor.util import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.PersistentSet -import org.utbot.framework.codegen.PythonImport -import org.utbot.framework.codegen.PythonSysPathImport import org.utbot.framework.codegen.domain.context.CgContextOwner import org.utbot.python.framework.api.python.PythonClassId import org.utbot.python.framework.api.python.PythonMethodId +import org.utbot.python.framework.codegen.model.PythonUserImport internal fun CgContextOwner.importIfNeeded(method: PythonMethodId) { collectedImports += PythonUserImport(method.moduleName)