Uploaded image for project: 'SonarPython'
  1. SonarPython
  2. SONARPY-583

Rule S5717: Function parameters' default values should not be modified or assigned

    XMLWordPrintable

    Details

    • Type: New Feature
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 2.8
    • Component/s: Rules
    • Labels:

      Description

      This rule should raise issues every time:

      • (The default value has one of the types listed in the RSPEC
        AND (
        • A/ A method or operator from the blacklist is called on the parameter.
          OR
        • B/ A property is set on the parameter. i.e. param.property = 42
          OR
        • C/ The parameter is on the right side of an assignment (=) AND the left side is not a variable.
          ))
      • OR (the default value has any type except None AND an attribute of the parameter is set).

      Blacklisted methods and operators

      For all types listed

      • __delitem__, or its equivalent del param[1]
      • __setitem__, or its equivalent param[1] = 42
      • any method starting with __i and finishing with __, such as __iadd__
      • any use of the equivalent operator +=, -=, *=, @=, /=, //=, %=, **=, <<=, >>=, &=, ^=, |= with the parameteter on the left side.

      For list type

      • append
      • clear
      • extend
      • insert
      • pop
      • remove
      • reverse
      • sort

      For set type

      • update
      • intersection_update
      • difference_update
      • symmetric_difference_update
      • add
      • remove
      • discard
      • pop
      • clear

      For dict type

      • clear
      • pop
      • popitem
      • setdefault
      • update

      For deque type

      Same as list and:

      • appendleft
      • extendleft
      • popleft
      • rotate

      For UserList type

      Same as list

      For UserDict type

      Same as dict

      collections.ChainMap

      Same as dict.

      collections.Counter

      same as dict and:

      • subtract

      collections.OrderedDict

      same as dict and:

      • move_to_end

      collections.defaultdict. Accessing a key in this dictionary will create it.

      same as dict and:

      • __getitem__, or its equivalent param[1]

      Additional Code Examples

      In the following example the same dictionary is stored in multiple other dictionaries.

      def set_value(a_dict, key, values={}):  # Noncompliant
          a_dict[key] = values  # Multiple maps will share the same "values" dict
      
      d1, d2 = ({}, {})
      set_value(d1, "test")
      set_value(d2, "test")
      d1["test"][0] = 1
      print(d2)  # {'test': {0: 1}}
      

      In the following example the attribute of param is overwriten every time the function is called.

      class A:
          pass
      
      def myfunction(value, param=A()):
          param.attribute = value
          return param
      
      a1 = myfunction(1)
      print(a1.attribute)  # prints "1"
      a2 = myfunction(2)
      print(a1.attribute)  # prints "2"
      

      Compliant Solution

      def set_value(a_dict, key, values=None):
          if values is None:
              a_dict[key] = {}
          else:
              a_dict[key] = values
      
      d1, d2 = ({}, {})
      set_value(d1, "test")
      set_value(d2, "test")
      d1["test"][0] = 1
      print(d2)  # {'test': {}}
      
      class A:
          pass
      
      def myfunction(value, param=None):
          if param is None:
              param = A()
          param.attribute = value
          return param
      
      a1 = myfunction(1)
      print(a1.attribute)  # prints "1"
      a2 = myfunction(2)
      print(a1.attribute)  # prints "1"
      

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              andrea.guarino Andrea Guarino
              Reporter:
              nicolas.harraudeau Nicolas Harraudeau (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Dates

                Due:
                Created:
                Updated:
                Resolved: