0

I have the following python module:

paths = {}

...

def execute_query(query_to_execute, *args, **kwargs):
    if 'paths' in kwargs:
        paths = kwargs['paths']

    queries = {
        'postgresqlVersion': '''{{postgresqlVersion}}''',
        'entityRelationships': '''{{entityRelationships (entity: "{}") {{name}}}}''',
        'path': '''{{path(name: "{}", path: "{}", annotate: "{}")}}''',
        'path_step': '''{{pathStep(name: "{}", step: "{}", key: {})}}'''
    }
    schema = graphene.Schema(query=Query)

    #schema.execute('''{path(name: "Ventas", path: "general_state/general_city/inventory_store/operations_sale", annotate: "_count")}''')

    result = schema.execute(queries[query_to_execute].format(*list(kwargs.values())))
    dict_result = dict(result.data.items())

    return {'top': dict_result, 'full': paths}

The problem is that the code only works if I remove the first two lines of method execute_query(). If I leave them, I get this error:

File "/Users/hugovillalobos/Documents/Code/agrowareproject/backend/query.py", line 236, in execute_query
    return {'top': dict_result, 'full': paths}
UnboundLocalError: local variable 'paths' referenced before assignment

I don't know why python does not recognize variable paths as the one declared in the first line of the module.

HuLu ViCa
  • 5,077
  • 10
  • 43
  • 93
  • You make it local by assigning to it, even if that assignment is conditional. You need to do `global paths` to use global here. If you just want `paths` to be a default, a better option would be something like `l_paths = kwargs.get('paths', paths)`. – jordanm Nov 02 '20 at 21:41
  • TL;DR - just for the fact that the line `paths = kwargs['paths']` is there, `paths` is considered a ***local*** variable to the function. In cases where `'paths' not in kwargs`, it is not defined. You should probably make it `global` or just pass it as an explicit argument... – Tomerikoo Nov 02 '20 at 21:55

1 Answers1

0

A variable is global so long as you have not assigned it a value in your function. The latter makes the variable local. Even if, like in your case, the condition is not satisfied.

Note: The use of global variables is discouraged.

I suggest you modify your code as below:

def execute_query(query_to_execute, *args, **kwargs):

    paths = kwargs.get('paths', {})

    queries = {
        'postgresqlVersion': '''{{postgresqlVersion}}''',
        'entityRelationships': '''{{entityRelationships (entity: "{}") {{name}}}}''',
        'path': '''{{path(name: "{}", path: "{}", annotate: "{}")}}''',
        'path_step': '''{{pathStep(name: "{}", step: "{}", key: {})}}'''
    }
    schema = graphene.Schema(query=Query)

    #schema.execute('''{path(name: "Ventas", path: "general_state/general_city/inventory_store/operations_sale", annotate: "_count")}''')

    result = schema.execute(queries[query_to_execute].format(*list(kwargs.values())))
    dict_result = dict(result.data.items())

    return {'top': dict_result, 'full': paths}

If you insist on having the paths as a global variable, you can take the following approach (using the variable, but, not assigning to it)

paths = {}

....

def execute_query(query_to_execute, *args, **kwargs):

    new_paths = kwargs.get('paths', paths)

    queries = {
        'postgresqlVersion': '''{{postgresqlVersion}}''',
        'entityRelationships': '''{{entityRelationships (entity: "{}") {{name}}}}''',
        'path': '''{{path(name: "{}", path: "{}", annotate: "{}")}}''',
        'path_step': '''{{pathStep(name: "{}", step: "{}", key: {})}}'''
    }
    schema = graphene.Schema(query=Query)

    #schema.execute('''{path(name: "Ventas", path: "general_state/general_city/inventory_store/operations_sale", annotate: "_count")}''')

    result = schema.execute(queries[query_to_execute].format(*list(kwargs.values())))
    dict_result = dict(result.data.items())

    return {'top': dict_result, 'full': new_paths}
Amir Afianian
  • 2,679
  • 4
  • 22
  • 46