I'm currently working with a legacy system that has been developed by half a dozen people before me, each fixing issues and adding new features without bothering with anything silly like "code reviews", "documentation" or "style guides". The people before me have also had very varying levels of coding expertise, and so the resulting codebase could be described as "colourful" for the lack of a better term.
Thus the codebase is filled with normal code, clever bits, brilliant hacks and horrible spaghetti scripts. It is not always obvious which is which. One of my favourite puzzles in the code looks functionally like this:
def main_function(text, number):
check_flag, squared_number = auxiliary_function(number)
if check_flag == False:
error = "Number could not be squared."
return False, error
combined_data = text + str(squared_number)
del check_flag
return True, combined_data
def auxiliary_function(number):
try:
result = number * number
return True, result
except Exception as e:
return False, number
if __name__ == "__main__":
text = "Hello, world! "
number = 42
check_flag, result = main_function(text, number)
print(result)
text = "Hello, world! "
number = "42"
check_flag, result = main_function(text, number)
print(result)
Now, there is a lot going on even in this small snippet, much of it not very Pythonic, but what I really want to focus on is the del check_flag part just before the main_function returns. Why do I call this a puzzle instead of clearly superfluous code? The reason is that so far from basically every piece of weird code in this project I've been able to learn something by either figuring out what kind of edge case could make a given approach theoretically feasible, or by studying enough Python machinery to see why a given piece of code could never work as intended.
But here I am a bit bogged down due to my lacking understanding of the del command, function scope fundamentals and Python garbage collection. (In the past few years I think I've had one occasion where I had a reasonable case of using del, though probably I could have avoided even that by using the Pandas library more fluently.)
Having played around with how function scopes work with del, it seems that the only case where deling anything (primitives or objects) inside a function scope is if the thing to be deleted has been forced to have a wider scope e.g. with global. So in theory this could be used in a case where I want to have a global flag variable that enables me to use tertiary logic with the values of True, False and NameError. (Far-fetched and horrible, I know.)
I know that sometimes bad code is just bad code, but still I would like to ask if anyone could figure any complex settings e.g. in complex object inheritance, async functions or something else where "del just before function return" might actually be even a borderline reasonable thing to do? Or, alternatively, is there something fundamental about function scopes that rules out anything else than deleting objects in larger scopes?
I don't even have a good "bad" reason for doing that on a boolean. Given the history of that code however, it could be a remnant of some experimentation that wasn't properly cleaned up. For example, if the code was doing something with
locals()afterwards (it's not but perhaps in an earlier incarnation), there could be some far fetched logic to determine which local variables were assigned during the process and this would exclude that flag from locals() before using it.