Skip to content

Commit

Permalink
Python VersionInfo extension (#2032)
Browse files Browse the repository at this point in the history
  • Loading branch information
KuechA authored Feb 7, 2025
1 parent e109d34 commit fe3a1f2
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,22 @@ class PythonLanguageFrontend(language: Language<PythonLanguageFrontend>, ctx: Tr
}
}

/**
* Returns the version info from the [TranslationConfiguration] as [VersionInfo] or `null` if it was
* not specified.
*/
val TranslationConfiguration.versionInfo: VersionInfo?
get() {
// We need to populate the version info "in-order", to ensure that we do not
// set the micro version if minor and major are not set, i.e., there must not be a
// "gap" in the granularity of version numbers
return this.symbols["PYTHON_VERSION_MAJOR"]?.toLong()?.let { major ->
val minor = this.symbols["PYTHON_VERSION_MINOR"]?.toLong()
val micro = if (minor != null) this.symbols["PYTHON_VERSION_MICRO"]?.toLong() else null
VersionInfo(major, minor, micro)
}
}

/**
* Populate system information from defined symbols that represent our environment. We add it as an
* overlay node to our [TranslationUnitDeclaration].
Expand All @@ -363,17 +379,7 @@ fun populateSystemInformation(
var sysInfo =
SystemInformation(
platform = config.symbols["PYTHON_PLATFORM"],
// We need to populate the version info "in-order", to ensure that we do not
// set the micro version if minor and major are not set, i.e., there must not be a
// "gap" in the granularity of version numbers
versionInfo =
config.symbols["PYTHON_VERSION_MAJOR"]?.toLong()?.let { major ->
val minor = config.symbols["PYTHON_VERSION_MINOR"]?.toLong()
val micro =
if (minor != null) config.symbols["PYTHON_VERSION_MICRO"]?.toLong()
else null
VersionInfo(major, minor, micro)
},
versionInfo = config.versionInfo,
)
sysInfo.underlyingNode = tu
return sysInfo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import de.fraunhofer.aisec.cpg.graph.OverlayNode

/** Represents the contents of `sys.version_info` which contains the Python version. */
data class VersionInfo(var major: Long? = null, var minor: Long? = null, var micro: Long? = null) :
OverlayNode() {
OverlayNode(), Comparable<VersionInfo> {
/**
* Returns the version info as a tuple (major, minor, micro). The length of the tuple depends on
* the information set, e.g., if only major version is set, then the list is 1 element long.
Expand All @@ -46,6 +46,24 @@ data class VersionInfo(var major: Long? = null, var minor: Long? = null, var mic

return list
}

override fun compareTo(other: VersionInfo): Int {
val thisMajor = this.major ?: -1
val otherMajor = other.major ?: -1
val thisMinor = this.minor ?: -1
val otherMinor = other.minor ?: -1
val thisMicro = this.micro ?: -1
val otherMicro = other.micro ?: -1
return if (thisMajor == otherMajor && thisMinor == otherMinor && thisMicro == otherMicro) {
0
} else if (
thisMajor < otherMajor ||
(thisMajor == otherMajor &&
(thisMinor < otherMinor || thisMinor == otherMinor && thisMicro < otherMicro))
) {
-1
} else 1
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright (c) 2025, Fraunhofer AISEC. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $$$$$$\ $$$$$$$\ $$$$$$\
* $$ __$$\ $$ __$$\ $$ __$$\
* $$ / \__|$$ | $$ |$$ / \__|
* $$ | $$$$$$$ |$$ |$$$$\
* $$ | $$ ____/ $$ |\_$$ |
* $$ | $$\ $$ | $$ | $$ |
* \$$$$$ |$$ | \$$$$$ |
* \______/ \__| \______/
*
*/
package de.fraunhofer.aisec.cpg.frontends.python

import kotlin.test.Test
import kotlin.test.assertTrue

class SystemInformationTest {
@Test
fun testVersionInfo() {
val empty = VersionInfo()
val v123_2 = VersionInfo(1, 2, 3)
val v123 = VersionInfo(1, 2, 3)
val v321 = VersionInfo(3, 2, 1)
val v121 = VersionInfo(1, 2, 1)
val v132 = VersionInfo(1, 3, 2)
val v124 = VersionInfo(1, 2, 4)
assertTrue(empty < v123)
assertTrue(v123_2.compareTo(v123) == 0)
assertTrue(v123 > empty)
assertTrue(v123 < v321)
assertTrue(v121 < v123)
assertTrue(v123 < v132)
assertTrue(v123 < v124)

assertTrue(v321 > v123)
assertTrue(v123 > v121)
assertTrue(v132 > v123)
assertTrue(v124 > v123)
}
}

0 comments on commit fe3a1f2

Please sign in to comment.