Skip to content

Commit 4e2e6a0

Browse files
committed
Pip: Make the Python version configurable
Add a configuration option to set the Python version to be used for resolving dependencies. The configured version is now always used and the guessed version is ignored for resolving dependencies, this allows further simplications in a later commit. Signed-off-by: Martin Nonnenmacher <[email protected]>
1 parent ff55d5b commit 4e2e6a0

File tree

2 files changed

+31
-17
lines changed

2 files changed

+31
-17
lines changed

analyzer/src/funTest/kotlin/managers/PipFunTest.kt

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import java.io.File
2626

2727
import org.ossreviewtoolkit.downloader.VersionControlSystem
2828
import org.ossreviewtoolkit.model.config.AnalyzerConfiguration
29+
import org.ossreviewtoolkit.model.config.PackageManagerConfiguration
2930
import org.ossreviewtoolkit.model.config.RepositoryConfiguration
3031
import org.ossreviewtoolkit.utils.common.Os
3132
import org.ossreviewtoolkit.utils.ort.normalizeVcsUrl
@@ -42,7 +43,7 @@ class PipFunTest : WordSpec({
4243
"resolve setup.py dependencies correctly for spdx-tools-python" {
4344
val definitionFile = projectsDir.resolve("external/spdx-tools-python/setup.py")
4445

45-
val result = createPip().resolveSingleProject(definitionFile)
46+
val result = createPip(pythonVersion = "2.7").resolveSingleProject(definitionFile)
4647
val expectedResult = projectsDir.resolve("external/spdx-tools-python-expected-output.yml").readText()
4748

4849
result.toYaml() shouldBe expectedResult
@@ -59,7 +60,7 @@ class PipFunTest : WordSpec({
5960
path = vcsPath
6061
)
6162

62-
val result = createPip().resolveSingleProject(definitionFile)
63+
val result = createPip(pythonVersion = "2.7").resolveSingleProject(definitionFile)
6364

6465
result.toYaml() shouldBe expectedResult
6566
}
@@ -116,4 +117,14 @@ class PipFunTest : WordSpec({
116117
}
117118
})
118119

119-
private fun createPip() = Pip("PIP", USER_DIR, AnalyzerConfiguration(), RepositoryConfiguration())
120+
private fun createPip(pythonVersion: String = "3.10") =
121+
Pip("PIP", USER_DIR, createAnalyzerConfiguration(pythonVersion), RepositoryConfiguration())
122+
123+
private fun createAnalyzerConfiguration(pythonVersion: String) =
124+
AnalyzerConfiguration(
125+
packageManagers = mapOf(
126+
Pip.Factory().managerName to PackageManagerConfiguration(
127+
options = mapOf("pythonVersion" to pythonVersion)
128+
)
129+
)
130+
)

analyzer/src/main/kotlin/managers/Pip.kt

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ private const val OPTION_OPERATING_SYSTEM = "operatingSystem"
120120
private const val OPTION_OPERATING_SYSTEM_DEFAULT = "linux"
121121
private val OPERATING_SYSTEMS = listOf("linux", "mac", "windows")
122122

123+
private const val OPTION_PYTHON_VERSION = "pythonVersion"
124+
private const val OPTION_PYTHON_VERSION_DEFAULT = "3.10"
125+
private val PYTHON_VERSIONS = listOf("2.7", "3.6", "3.7", "3.8", "3.9", "3.10")
126+
123127
/**
124128
* The [PIP](https://pip.pypa.io/) package manager for Python. Also see
125129
* [install_requires vs requirements files](https://packaging.python.org/discussions/install-requires-vs-requirements/)
@@ -128,6 +132,7 @@ private val OPERATING_SYSTEMS = listOf("linux", "mac", "windows")
128132
* This package manager supports the following [options][PackageManagerConfiguration.options]:
129133
* - *operatingSystem*: The name of the operating system to resolve dependencies for. One of "linux", "mac", or
130134
* "windows". Defaults to "linux".
135+
* - *pythonVersion*: The Python version to resolve dependencies for. Defaults to "3.10".
131136
*/
132137
@Suppress("TooManyFunctions")
133138
class Pip(
@@ -157,6 +162,13 @@ class Pip(
157162
}
158163
}
159164

165+
private val pythonVersionOption = (options[OPTION_PYTHON_VERSION] ?: OPTION_PYTHON_VERSION_DEFAULT)
166+
.also { pythonVersion ->
167+
require(pythonVersion in PYTHON_VERSIONS) {
168+
"The 'pythonVersion' option must be one of ${PYTHON_VERSIONS.joinToString { "'$it'" }}."
169+
}
170+
}
171+
160172
override fun command(workingDir: File?) = "pip"
161173

162174
override fun transformVersion(output: String) = output.removePrefix("pip ").substringBefore(' ')
@@ -193,7 +205,7 @@ class Pip(
193205
val virtualEnvDir = setupVirtualEnv(workingDir, pythonMajorVersion)
194206

195207
val project = getProjectBasics(definitionFile, virtualEnvDir)
196-
val (packages, installDependencies) = getInstallDependencies(definitionFile, pythonMajorVersion)
208+
val (packages, installDependencies) = getInstallDependencies(definitionFile)
197209

198210
// TODO: Handle "extras" and "tests" dependencies.
199211
val scopes = sortedSetOf(
@@ -287,29 +299,20 @@ class Pip(
287299
)
288300
}
289301

290-
private fun getInstallDependencies(
291-
definitionFile: File,
292-
pythonMajorVersion: Int
293-
): Pair<SortedSet<Package>, SortedSet<PackageReference>> {
302+
private fun getInstallDependencies(definitionFile: File): Pair<SortedSet<Package>, SortedSet<PackageReference>> {
294303
val workingDir = definitionFile.parentFile
295304

296-
val pythonVersion = when (pythonMajorVersion) {
297-
2 -> "2.7" // 2.7 is the only 2.x version supported by python-inspector.
298-
3 -> "3.10" // 3.10 is the version currently used in the ORT Docker image.
299-
else -> throw IllegalArgumentException("Unsupported Python major version '$pythonMajorVersion'.")
300-
}
301-
302305
logger.info {
303-
"Resolving dependencies for '${definitionFile.absolutePath}' with Python version '$pythonVersion' and " +
304-
"operating system '$operatingSystemOption'."
306+
"Resolving dependencies for '${definitionFile.absolutePath}' with Python version '$pythonVersionOption' " +
307+
"and operating system '$operatingSystemOption'."
305308
}
306309

307310
val pythonInspectorResult = runCatching {
308311
try {
309312
PythonInspector.run(
310313
workingDir = workingDir,
311314
definitionFile = definitionFile,
312-
pythonVersion = pythonVersion.replace(".", ""),
315+
pythonVersion = pythonVersionOption.replace(".", ""),
313316
operatingSystem = operatingSystemOption
314317
)
315318
} finally {

0 commit comments

Comments
 (0)