So I have been recently getting back into some python, just to write little scripts. In this script I am getting a bunch of Jira tickets and then I wrote myself a recursive function to flatten them into a flat dictionary structure, for easier filtering. All of that works fine, but one thing stumps me. In the recursive function called get_flattened_dict
I have made myself to... well, flatten the dictionaries, I created a variable called mega_dict
that gets spit out in the end, containing the contents of all nested dictionaries from the initial value. This argument has a default value, which is an empty dictionary. On the first run through this works fine. By the end of the function, before returning, I explicitly erase the value of the variable. However, on the second run through of the function, the variable retains the value it was assigned from the initial run through.
Code:
# from third_party.python3.atlassian import Confluence
# from third_party.python3.jira import JIRA
from atlassian import Confluence
from jira import JIRA
class ConfluenceHelper:
def __init__(self, username, api_key):
# sets up connection to jira api
def get_jira_tickets(self, jql_query):
# Gets tickets from Jira with jql query
return tickets
def get_flattened_dict(self, field_name, og_dict, calling_from="", lookingfor="", mega_dict={}, original_key=""):
print("calling from:", calling_from)
print(bool(mega_dict))
for dict_key in og_dict.keys():
if isinstance(og_dict[dict_key], dict):
calling_from = "recursive"
mega_dict = self.get_flattened_dict(field_name, og_dict[dict_key], calling_from, lookingfor, mega_dict, original_key=dict_key)
elif original_key:
new_key = field_name + "_" + original_key + "_" + dict_key
mega_dict[new_key] = og_dict[dict_key]
else:
new_key = field_name + "_" + dict_key
mega_dict[new_key] = og_dict[dict_key]
return_dict = dict(mega_dict)
mega_dict = {}
return return_dict
def get_filtered_tickets(self, tickets):
field_name = "CustomField"
filtered_tickets = {}
for ticket in tickets:
flattened_dict = {}
field_value = ticket.raw['fields'][field_name]
if field_value and isinstance(field_value, list):
for list_value in field_value:
if isinstance(list_value, dict):
callingfrom = "outside"
flattened_dict = self.get_flattened_dict(field_name, list_value, callingfrom, str(ticket))
# Some filtering happening here
return filtered_tickets
def nice_text_for_filter(self, filtered_tickets):
# Create nicer output for human eyes
return
if __name__ == "__main__":
# Parser Arguments set here
args = parser.parse_args()
confluence_helper = ConfluenceHelper(args.username, args.api_key)
print("Running Script...")
tickets = confluence_helper.get_jira_tickets(args.jql_query)
filtered_tickets = confluence_helper.get_filtered_tickets(tickets)
confluence_helper.nice_text_for_filter(filtered_tickets)
Here is some of the output of the print statements set in get_flattened_dict()
:
calling from: outside
False
calling from: recursive
True
calling from: recursive
True
calling from: recursive
True
calling from: recursive
True
calling from: recursive
True
calling from: recursive
True
calling from: recursive
True
calling from: outside
True
calling from: recursive
As you can see, the second time the function gets called from the outside, the dictionary already has a value, even though I explicitly clean it. I just don't understand where that value is coming from.
Thank you for taking the time to read this, I much appreciate any answer!