Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import kotlinx.coroutines.runBlocking
import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.idea.util.module
import org.jetbrains.kotlin.idea.util.projectStructure.sdk
import org.jetbrains.kotlin.konan.file.File
import org.utbot.common.PathUtil.toPath
import org.utbot.common.appendHtmlLine
import org.utbot.framework.UtSettings
Expand Down Expand Up @@ -334,9 +335,9 @@ fun getDirectoriesForSysPath(
}
}

// Select modules only from this project
// Select modules only from this project but not from installation directory
importedPaths.forEach {
if (it.isProjectSubmodule(ancestor)) {
if (it.isProjectSubmodule(ancestor) && !it.path.split(File.separator).contains("site-packages")) {
sources.add(it)
}
}
Expand Down
59 changes: 33 additions & 26 deletions utbot-python/src/main/kotlin/org/utbot/python/PythonEngine.kt
Original file line number Diff line number Diff line change
Expand Up @@ -174,43 +174,25 @@ class PythonEngine(

fun fuzzing(parameters: List<Type>, isCancelled: () -> Boolean, until: Long): Flow<FuzzingExecutionFeedback> = flow {
val additionalModules = parameters.flatMap { it.pythonModules() }

val pmd = PythonMethodDescription(
methodUnderTest.name,
parameters,
fuzzedConcreteValues,
pythonTypeStorage,
Trie(Instruction::id)
)

val coveredLines = initialCoveredLines.toMutableSet()

PythonFuzzing(pmd.pythonTypeStorage) { description, arguments ->
if (isCancelled()) {
logger.info { "Fuzzing process was interrupted" }
return@PythonFuzzing PythonFeedback(control = Control.STOP)
}
if (System.currentTimeMillis() >= until) {
logger.info { "Fuzzing process was interrupted by timeout" }
return@PythonFuzzing PythonFeedback(control = Control.STOP)
}

suspend fun fuzzingResultHandler(description: PythonMethodDescription, arguments: List<PythonFuzzedValue>): PythonFeedback {
val codeExecutor = constructEvaluationInput(arguments, additionalModules)
when (val evaluationResult = codeExecutor.run()) {
return when (val evaluationResult = codeExecutor.run()) {
is PythonEvaluationError -> {
val utError = UtError(
"Error evaluation: ${evaluationResult.status}, ${evaluationResult.message}",
Throwable(evaluationResult.stackTrace.joinToString("\n"))
)
logger.debug(evaluationResult.stackTrace.joinToString("\n"))
emit(InvalidExecution(utError))
return@PythonFuzzing PythonFeedback(control = Control.PASS)
PythonFeedback(control = Control.PASS)
}

is PythonEvaluationTimeout -> {
val utError = UtError(evaluationResult.message, Throwable())
emit(InvalidExecution(utError))
return@PythonFuzzing PythonFeedback(control = Control.PASS)
PythonFeedback(control = Control.PASS)
}

is PythonEvaluationSuccess -> {
Expand All @@ -228,19 +210,44 @@ class PythonEngine(
logger.debug { arguments }
val trieNode: Trie.Node<Instruction> = description.tracer.add(coveredInstructions)
emit(result)
return@PythonFuzzing PythonFeedback(control = Control.CONTINUE, result = trieNode)
PythonFeedback(control = Control.CONTINUE, result = trieNode)
}
is ArgumentsTypeErrorFeedback, is TypeErrorFeedback -> {
emit(result)
return@PythonFuzzing PythonFeedback(control = Control.PASS)
PythonFeedback(control = Control.PASS)
}
is InvalidExecution -> {
emit(result)
return@PythonFuzzing PythonFeedback(control = Control.CONTINUE)
PythonFeedback(control = Control.CONTINUE)
}
}
}
}
}.fuzz(pmd)
}

val pmd = PythonMethodDescription(
methodUnderTest.name,
parameters,
fuzzedConcreteValues,
pythonTypeStorage,
Trie(Instruction::id)
)

if (parameters.isEmpty()) {
fuzzingResultHandler(pmd, emptyList())
} else {
PythonFuzzing(pmd.pythonTypeStorage) { description, arguments ->
if (isCancelled()) {
logger.info { "Fuzzing process was interrupted" }
return@PythonFuzzing PythonFeedback(control = Control.STOP)
}
if (System.currentTimeMillis() >= until) {
logger.info { "Fuzzing process was interrupted by timeout" }
return@PythonFuzzing PythonFeedback(control = Control.STOP)
}

return@PythonFuzzing fuzzingResultHandler(description, arguments)
}.fuzz(pmd)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,32 +149,35 @@ class PythonCodeGenerator(
CgVariable(argument.name, argument.annotation?.let { PythonClassId(it) } ?: pythonAnyClassId)
}

var argumentsTryCatch = tryBlock {
methodArguments.zip(arguments).map { (model, argument) ->
if (model is PythonTreeModel) {
val obj =
(context.cgLanguageAssistant.getVariableConstructorBy(context) as PythonCgVariableConstructor)
.getOrCreateVariable(model)
+CgAssignment(
argument,
(obj as CgPythonTree).value
)
} else {
+CgAssignment(argument, CgLiteral(model.classId, model.toString()))
if (method.arguments.isNotEmpty()) {
var argumentsTryCatch = tryBlock {
methodArguments.zip(arguments).map { (model, argument) ->
if (model is PythonTreeModel) {
val obj =
(context.cgLanguageAssistant.getVariableConstructorBy(context) as PythonCgVariableConstructor)
.getOrCreateVariable(model)
+CgAssignment(
argument,
(obj as CgPythonTree).value
)
} else {
+CgAssignment(argument, CgLiteral(model.classId, model.toString()))
}
}
}
}
argumentsTryCatch = argumentsTryCatch.catch(PythonClassId("builtins.Exception")) { exception ->
+CgPythonFunctionCall(
pythonNoneClassId,
failArgumentsFunctionName,
listOf(
outputPath,
exception,
argumentsTryCatch = argumentsTryCatch.catch(PythonClassId("builtins.Exception")) { exception ->
+CgPythonFunctionCall(
pythonNoneClassId,
failArgumentsFunctionName,
listOf(
outputPath,
exception,
)
)
)
emptyLine()
+CgPythonRepr(pythonAnyClassId, "sys.exit()")
emptyLine()
+CgPythonRepr(pythonAnyClassId, "sys.exit()")
}
argumentsTryCatch.accept(renderer)
}

val args = CgPythonList(emptyList())
Expand All @@ -195,7 +198,6 @@ class PythonCodeGenerator(
)
)

argumentsTryCatch.accept(renderer)
executorCall.accept(renderer)

renderer.toString()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ fun readMypyAnnotationStorageAndInitialErrors(
val result = runCommand(
listOf(
pythonPath,
"-X",
"utf8",
"-m",
"utbot_mypy_runner",
"--config",
Expand Down Expand Up @@ -72,17 +74,18 @@ fun checkWithDMypy(pythonPath: String, fileWithCodePath: String, configFile: Fil

fun setConfigFile(directoriesForSysPath: Set<String>): File {
val file = TemporaryFileManager.assignTemporaryFile(configFilename)
val dirForCache = TemporaryFileManager.assignTemporaryFile(tag = "mypy_cache")
val configContent = """
[mypy]
mypy_path = ${directoriesForSysPath.joinToString(separator = ":") { it.modifyWindowsPath() } }
namespace_packages = True
explicit_package_bases = True
cache_dir = ${dirForCache.absolutePath}
show_absolute_path = True
cache_fine_grained = True
check_untyped_defs = True
implicit_optional = True
strict_optional = False
disable_error_code = assignment,union-attr
implicit_optional = True
""".trimIndent()
TemporaryFileManager.writeToAssignedFile(file, configContent)
return file
Expand Down
Loading