Alright, so another usual night and I was trying to figure out a strange behavior with a Python class I was working. Looks like I had OOP lectures only in C++, and things are little bit different here. So here you go!
I had this strange class method here described as:
class BenchmarkResults(object): @classmethod def _generate_db_entries(cls, tests, skip_aggregated=False, parent=None, test_table = ): # This function recursively calls _generate_db_entries with # test_table param set to a list
and this was processing in a JSON file from one of my POST API and doing some crazy stuff. The API calls this class like
class BotReportView(APIView): def post(self, request, format=None): test_data_results = BenchmarkResults(json.load(self.request.FILES.get('test_data'))) results_table = test_data_results._generate_db_entries(test_data_results)
Now the funny part. I found that on subsequent calls to the API, the
test_data_results kept on multiplying 😮 like the data from the previous POST also got appended to the current JSON which-should-be-processed. Thinking it was a problem with the client, I tried switching to curl, but with little luck.
pycharm got me figuring out what went wrong, as it showed a warning on the
test_table =  something like:
The default method argument is mutable. Bah, taking at look at http://stackoverflow.com/questions/9039191/mutable-default-method-arguments-in-python I see that when an empty list
 is kept as a default formal argument for a function, the list is not killed in between, and keeps on growing on subsequent calls – surprise
Quoting http://stackoverflow.com/a/9039224/3355893, when we have something like:
def status(options=): options.append('new_option') return options print status() print status() print status()
will print something like
['new_option'] ['new_option', 'new_option'] ['new_option', 'new_option', 'new_option']
Tough luck finding it out, but it took couple of hours 😀 I got my code easily fixed by not allowing
 to stay as a default param, but separately passing an empty list to the function during the call. Like
class BenchmarkResults(object): @classmethod def _generate_db_entries_helper(cls, tests, skip_aggregated=False, parent=None): test_table =  self._generate_db_entries(cls, tests, test_tables skip_aggregated=False, parent=None): @classmethod def _generate_db_entries(cls, tests, test_table, skip_aggregated=False, parent=None): # This function recursively calls _generate_db_entries with test_table param set to a list
Yay. that was it, and latter called in the helper function, and things started working. You can see the change here, and finally, Happy New year 2017! Make every commit count!