Fix instances of functions using a mutable list as a default param value

Bug #1174809 reported by Brian Cline
12
This bug affects 2 people
Affects Status Importance Assigned to Milestone
OpenStack Object Storage (swift)
Fix Released
Undecided
Brian Cline

Bug Description

In at least the object replicator (swift/obj/replicator.py), a few functions are actually using an empty list (mutable) as a default param value.

In Python, this is an issue since functions are treated as objects that can maintain state between calls. As a result, this only gets set once, and it's possible for it to stack list values over time in cases when you might expect them to be empty. Depending on use, this can cause incredibly complex and yet very subtle bugs in code that reads just fine (at least once you've digested the incredibly high density of some of this codebase ;-).

There are no comments in the code I've seen, however, indicating that this usage is meant specifically to take advantage of this subtlety in the language. We'd definitely want to document that if it is the case.

Here's some additional information explaining this behavior in Python:
http://effbot.org/zone/default-values.htm
http://stackoverflow.com/questions/1132941/least-astonishment-in-python-the-mutable-default-argument

Wanted to create this as a discussion point if needed, and as a courtesy to attach it to the patch I'm going to push in a few minutes. Very curious to see whether or not the tests are affected at all by a correction.

Brian Cline (briancline)
Changed in swift:
assignee: nobody → Brian Cline (briancline)
status: New → In Progress
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix proposed to swift (master)

Fix proposed to branch: master
Review: https://review.openstack.org/27825

Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix merged to swift (master)

Reviewed: https://review.openstack.org/27825
Committed: http://github.com/openstack/swift/commit/7bf0db6b759f28def422594b523b55a06d25a1d5
Submitter: Jenkins
Branch: master

commit 7bf0db6b759f28def422594b523b55a06d25a1d5
Author: Brian Cline <email address hidden>
Date: Tue Apr 30 11:07:34 2013 -0500

    Uses None instead of mutable lists for function param defaults

    Addressing bug 1174809, changes use of mutable lists as as default
    arguments and defaults them within the function. Otherwise, those
    defaults can be unexpectedly persisted with the function between
    invocations and erupt into mass hysteria on the streets.

    To my knowledge there aren't known cases of the current use causing
    specific issues, but even stylistically needs addressing to avoid
    problems in the future. I couldn't find any comments or related
    historical commit messages indicating the current use is meant to take
    advantage of this behavior in Python.

    Change-Id: I4a89afada08b2ce220724f585631a9e2072bf1bd
    Fixes: bug 1174809

Changed in swift:
status: In Progress → Fix Committed
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix proposed to swift (master)

Fix proposed to branch: master
Review: https://review.openstack.org/27845

Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix merged to swift (master)

Reviewed: https://review.openstack.org/27845
Committed: http://github.com/openstack/swift/commit/d69fa437cd7d4b7c92a62d3005399ffa57611551
Submitter: Jenkins
Branch: master

commit d69fa437cd7d4b7c92a62d3005399ffa57611551
Author: Brian Cline <email address hidden>
Date: Tue Apr 30 15:36:48 2013 -0500

    Uses None instead of mutable dicts for default function arguments

    Forgot to update dicts with changeset I4a89afad, which updated lists.

    Change-Id: Ieca71b9c90ee5dae83a43f6851b6b8b2924bcb8e
    Fixes: bug 1174809

Changed in swift:
milestone: none → 1.9.0
Thierry Carrez (ttx)
Changed in swift:
status: Fix Committed → Fix Released
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Related fix proposed to swift (master)

Related fix proposed to branch: master
Review: https://review.openstack.org/87490

Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Related fix merged to swift (master)

Reviewed: https://review.openstack.org/87490
Committed: https://git.openstack.org/cgit/openstack/swift/commit/?id=b4c5a136642bb87816bfbbad81b79efd4551a05e
Submitter: Jenkins
Branch: master

commit b4c5a136642bb87816bfbbad81b79efd4551a05e
Author: Brian Cline <email address hidden>
Date: Sat May 10 05:15:12 2014 -0500

    Uses None instead of mutables for function param defaults

    As seen on #1174809, changes use of mutable types as default
    arguments and defaults them within the method. Otherwise, those
    defaults can be unexpectedly persisted with the function between
    invocations and erupt into mass hysteria on the streets.

    There was indeed a test (TestSimpleClient.test_get_with_retries)
    that was erroneously relying on this behavior. Since previous tests
    had populated their own instantiations with a token, this test only
    passed because the modified headers dict from previous tests was
    being overridden. As expected, with the mutable defaults fix in
    SimpleClient, this test begain to fail since it never specified any
    token, yet it has always passed anyway. This change also now provides
    the expected token.

    Change-Id: If95f11d259008517dab511e88acfe9731e5a99b5
    Related-Bug: #1174809

Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Related fix proposed to swift (feature/ec)

Related fix proposed to branch: feature/ec
Review: https://review.openstack.org/93823

Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Related fix merged to swift (feature/ec)
Download full text (9.7 KiB)

Reviewed: https://review.openstack.org/93823
Committed: https://git.openstack.org/cgit/openstack/swift/commit/?id=aa8d5518d2080b3811cc74b9b9fcca0368fc7299
Submitter: Jenkins
Branch: feature/ec

commit 4cd3478b4b996108f5a581ef09add348e6246596
Author: Christian Berendt <email address hidden>
Date: Sun May 11 14:44:47 2014 +0200

    debug level logs should not be translated

    According to the OpenStack translation policy available at
    https://wiki.openstack.org/wiki/LoggingStandards debug messages
    should not be translated. Like mentioned in several changes in
    Nova by garyk this is to help prioritize log translation.

    Change-Id: I59486b1110f08510d83a4aec2a1666805c59d1cd
    Closes-Bug: #1318333

commit b4c5a136642bb87816bfbbad81b79efd4551a05e
Author: Brian Cline <email address hidden>
Date: Sat May 10 05:15:12 2014 -0500

    Uses None instead of mutables for function param defaults

    As seen on #1174809, changes use of mutable types as default
    arguments and defaults them within the method. Otherwise, those
    defaults can be unexpectedly persisted with the function between
    invocations and erupt into mass hysteria on the streets.

    There was indeed a test (TestSimpleClient.test_get_with_retries)
    that was erroneously relying on this behavior. Since previous tests
    had populated their own instantiations with a token, this test only
    passed because the modified headers dict from previous tests was
    being overridden. As expected, with the mutable defaults fix in
    SimpleClient, this test begain to fail since it never specified any
    token, yet it has always passed anyway. This change also now provides
    the expected token.

    Change-Id: If95f11d259008517dab511e88acfe9731e5a99b5
    Related-Bug: #1174809

commit 1dfe5186542486342581ab66cd5364b6b7d04e93
Author: Morgan Fainberg <email address hidden>
Date: Wed May 7 12:15:43 2014 -0700

    Update mailmap for Morgan Fainberg

    Change-Id: Ia46c28c86ef3f440556b1b027d2bf0a7f3e721c5

commit bcdafa3831111f334caadd30505f051c81abcb1f
Author: Eamonn O'Toole <email address hidden>
Date: Tue Apr 29 15:04:42 2014 +0100

    Sleep between object ZBF process forks

    We've found that, on fresh systems where the ZBF run completes
    almost instantaneously, the Swift logs (syslog by default) get
    filled-up with object ZBF scan start and completion messages.
    This patch calls self._sleep() between ZBF scan runs to cut-down
    on these messages and the related unnecessary ZBF scan runs
    without impacting the integrity of the object auditing process.

    Change-Id: I057c5ca235467cfa115a7a3d44e21c350900059a

commit 067b41e85479b29a7018e2f9ce7afd330bf3fdef
Author: Peter Portante <email address hidden>
Date: Sat Jan 11 00:18:04 2014 -0500

    In-process swift server for functional tests

    Provide a way to run the functional tests using a p/a/c/o server setup
    in the same process running the nosetests infrastructure.

    By setting the environment variable, SWIFT_TEST_IN_PROCESS, to a true
    value, the functional test framework will construct a set of proxy,
    account, container...

Read more...

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.