Skip to content

Commit

Permalink
Create rule S6928: Python side effects should not be used inside a "t…
Browse files Browse the repository at this point in the history
…f.function" (#3638)
  • Loading branch information
github-actions[bot] authored Mar 21, 2024
1 parent 6197098 commit f24a1fb
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 0 deletions.
2 changes: 2 additions & 0 deletions rules/S6928/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}
24 changes: 24 additions & 0 deletions rules/S6928/python/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"title": "Python side effects should not be used inside a \"tf.function\"",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
],
"defaultSeverity": "Major",
"ruleSpecification": "RSPEC-6928",
"sqKey": "S6928",
"scope": "All",
"defaultQualityProfiles": ["Sonar way"],
"quickfix": "unknown",
"code": {
"impacts": {
"MAINTAINABILITY": "MEDIUM",
"RELIABILITY": "HIGH"
},
"attribute": "CONVENTIONAL"
}
}
64 changes: 64 additions & 0 deletions rules/S6928/python/rule.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
This rule raises an issue when a Python side effect happens inside a `tensorflow.function`.

== Why is this an issue?

Python sides effects such as printing, mutating a list or a global variable, inside of a `tensorflow.function` may not behave as expected.
Because of the https://www.tensorflow.org/guide/function#rules_of_tracing[Rules of tracing],
the execution of side effects will depend on the input values of the function and will execute only once per tracing.

[source,python]
----
import tensorflow as tf
@tf.function
def f(x):
print("A side effect", x)
f(1) # prints "A side effect 1"
f(1) # does not print anything
f(2) # prints "A side effect 2"
----

The example above depicts the issue encountered when using Python side effects in a `tensorflow.function`. As a single trace is created per input values,
the second call to `f(1)` does not output anything to the console.

The best practice would be to avoid using Python side effects and prefer the usage of the TensorFlow API with functions such as `tf.print` or tf.TensorArray`.


== How to fix it

To fix this issue either remove the side effect or use the corresponding TensorFlow function.

=== Code examples

==== Noncompliant code example

[source,python,diff-id=1,diff-type=noncompliant]
----
import tensorflow as tf
@tf.function
def f(x):
print("Printing", x) # Noncompliant print is a side effect
----

==== Compliant solution

[source,python,diff-id=1,diff-type=compliant]
----
import tensorflow as tf
@tf.function
def f(x):
tf.print("Printing", x) # Compliant
----

== Resources
=== Documentation
* TensorFlow Documentation - https://www.tensorflow.org/guide/function#executing_python_side_effects[Executing Python side effects]
* TensorFlow Documentation - https://www.tensorflow.org/api_docs/python/tf/print[tf.print reference]
* TensorFlow Documentation - https://www.tensorflow.org/api_docs/python/tf/summary[tf.summary reference]
* TensorFlow Documentation - https://www.tensorflow.org/api_docs/python/tf/Variable#methods[tf.Variable methods reference]
* TensorFlow Documentation - https://www.tensorflow.org/api_docs/python/tf/TensorArray[tf.TensorArray reference]
* TensorFlow Documentation - https://www.tensorflow.org/api_docs/python/tf/data[tf.data reference]

0 comments on commit f24a1fb

Please sign in to comment.