Removes the use of mutables as default args

Passing mutable objects as default args is a known Python pitfall.
We'd better avoid this. This commit changes mutable default args with
None, then use 'arg = arg or {}', 'arg = arg or []'. For unit code which
doesn't use the args , just set with None. This commit also adds hacking
check.

Change-Id: Ib4f195c9c00ca2c49579f9d62648bff7c8109fcf
Closes-Bug: #1327473
This commit is contained in:
Bertrand Lallau 2015-10-30 08:11:46 +01:00 committed by Bertrand Lallau
parent 456a07f60a
commit 76e1e02e15
4 changed files with 13 additions and 4 deletions

View File

@ -16,6 +16,7 @@ Octavia Specific Commandments
- [O322] Don't use author tags
- [O323] Change assertEqual(True, A) or assertEqual(False, A) to the more
specific assertTrue(A) or assertFalse(A)
- [O324] Method's default argument shouldn't be mutable
- [O338] Change assertEqual(A in B, True), assertEqual(True, A in B),
assertEqual(A in B, False) or assertEqual(False, A in B) to the more
specific assertIn/NotIn(A, B)

View File

@ -211,13 +211,13 @@ class SNI(BaseDataModel):
class TLSContainer(BaseDataModel):
def __init__(self, id=None, primary_cn=None, certificate=None,
private_key=None, passphrase=None, intermediates=[]):
private_key=None, passphrase=None, intermediates=None):
self.id = id
self.primary_cn = primary_cn
self.certificate = certificate
self.private_key = private_key
self.passphrase = passphrase
self.intermediates = intermediates
self.intermediates = intermediates or []
class Amphora(BaseDataModel):

View File

@ -66,6 +66,7 @@ assert_equal_with_true_re = re.compile(
r"assertEqual\(True,")
assert_equal_with_false_re = re.compile(
r"assertEqual\(False,")
mutable_default_args = re.compile(r"^\s*def .+\((.+=\{\}|.+=\[\])")
def _directory_to_check_translation(filename):
@ -155,6 +156,12 @@ def assert_equal_true_or_false(logical_line):
"sentences not allowed")
def no_mutable_default_args(logical_line):
msg = "O324: Method's default argument shouldn't be mutable!"
if mutable_default_args.match(logical_line):
yield (0, msg)
def assert_equal_in(logical_line):
"""Check for assertEqual(A in B, True), assertEqual(True, A in B),
@ -177,4 +184,5 @@ def factory(register):
register(use_jsonutils)
register(no_author_tags)
register(assert_equal_true_or_false)
register(no_mutable_default_args)
register(assert_equal_in)

View File

@ -205,13 +205,13 @@ def sample_tls_sni_containers_tuple(tls_container=None):
def sample_tls_container_tuple(id='cont_id_1', certificate=None,
private_key=None, intermediates=[],
private_key=None, intermediates=None,
primary_cn=None):
sc = collections.namedtuple(
'tls_container',
'id, certificate, private_key, intermediates, primary_cn')
return sc(id=id, certificate=certificate, private_key=private_key,
intermediates=intermediates, primary_cn=primary_cn)
intermediates=intermediates or [], primary_cn=primary_cn)
def sample_pool_tuple(proto=None, monitor=True, persistence=True,