|
|
|
|
|
by biorach
1114 days ago
|
|
> Our API server was a Python Tornado service... and one of the most frequently accessed endpoint was used to retrieve user by their name or id. Because it supported retrieval by either name or id, it set default values for both parameters as empty lists. This is a super reasonable thing to do! However, Python only initializes default parameters when the function is first evaluated, which means that the same list is used for every call to the function. As a result, if you mutate those values, the mutations span across invocations. How on earth did such a well-known Python footgun ever make it into production? This is the kind of thing that should leap out of the screen for even a mid-level Python developer - and once you've been trained by bitter experience it's very easy to spot. |
|
A junior developer creates a function with default of [] instead of (), but otherwise no mutations:
Alice introduces a mutation in a place that is currently safe. Meanwhile Bob simplifies the code in a separate branch. Then Charlie does something else on the branch, tries to merge it into master, and Git auto-resolves the conflict because there's no overlap between the changes. And now everyone sees the data of a random user, and your foot is missing.Is it good code? No. Good version control hygiene? Also no. Should you crucify the developer who made this mistake? Of course not, especially once you add the boilerplate chaff that was omitted here. That's why it's called a footgun, it's easy to misuse.