Mutating the passed-in 'stuff' creates a leaky abstraction that then has to be documented. In rare cases this is what you want, but most of the time you're better off creating new objects and working with them. There's less to remember in the API, and fewer ways to screw up.
In particular, this code - which looks safe - blows up horribly with the article's function:
Huh? I expect ['foo', 'bar', 'baz', 'quux']. I expect accumulation, esp with a list. If I wanted ['foo', 'bar', 'quux'] I would send in a fresh copy of a list instead of a list I'd been whoring around to other functions.
I would also change MODULE_LEVEL_CONSTANT to not say CONSTANT cause a list is no such thing and doesn't become constant just cause a label says so. Maybe it even leads people to expect silly things.
I dunno, the Python convention is "if you don't mutate, return a value; if you do mutate, return None." Since you wrote function('baz', MODULE_LEVEL_CONSTANT) without an assignment in front of it, I would assume that function must mutate something. Since strings are immutable, that just leaves either the display (print) or the second argument. I guess the real point is don't mutate your arguments and print them. Do one or the other, but not both.
In particular, this code - which looks safe - blows up horribly with the article's function:
The second call will print ['foo', 'bar', 'baz', 'quux'] instead of the expected ['foo', 'bar', 'quux'].