Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default_value option in Arguments inside Mutation is not working as expected #1534

Open
VicGoico opened this issue Jan 9, 2024 · 2 comments

Comments

@VicGoico
Copy link

VicGoico commented Jan 9, 2024

Hi,

  • What is the current behavior?
    When I am working with the following set up of graphene Mutation:
class AnimalFarm(graphene.Mutation):
    class Arguments:
        animals = graphene.List(graphene.String, default_value=[])

    output = graphene.List(graphene.String)

    def mutate(root, info, **filters):
        import pdb; pdb.set_trace()
        animals_mio = filters["animals"]
        animals_mio.append('duck')
        
        return animals_mio


class Mutation(graphene.ObjectType):
    animal_farm = AnimalFarm.Field()

where you can see that I am declaring a Mutation that have and argument called "animals" which type is "graphene.List(graphene.String, default_value=[])", that means if I dont pass this argument in the mutation, graphene automatically filled this argument ("animals") with an empty list.

At this point all works perfect, but when I try the following steps, I reckon that could be a little bug in to reset the old value of "animals" argument.

  • Step 1: Install the latest version of graphene, in a linux OS, in my case is Ubuntu 22.04.3 LTS:
pip install "graphene>=3.1"
  • Step 2: Copy this code in a file with extension ".py", for example:
nano cool_file_name.py
  • Step 3: Copy this code to have the example, where you can this bug:
import graphene



class Query(graphene.ObjectType):
    nothing = graphene.String()
    
    def resolve_nothing(root, info):
        return "empty"

class AnimalFarm(graphene.Mutation):
    class Arguments:
        animals = graphene.List(graphene.String, default_value=[])

    output = graphene.List(graphene.String)

    def mutate(root, info, **filters):
        import pdb; pdb.set_trace()
        animals_local = filters["animals"]
        animals_local.append('duck')
        
        return animals_local


class Mutation(graphene.ObjectType):
    animal_farm = AnimalFarm.Field()


schema = graphene.Schema(query=Query, mutation=Mutation)

mutation = """
    mutation addAnimals{
        animalFarm {
            output
        }
    }
"""

def test_mutation():
    # First request
    result = schema.execute(mutation)
    print(result)

    # Second request, in this request it is the problem !!!
    result = schema.execute(mutation)
    print(result)

test_mutation()
  • Step 4: Then save the changes and launch the file:
python3 cool_file_name.py
  • Step 5: Execute "n" + Enter, to check this steps that works as expected in the first request, where we can see that both variables:
    animals_local
    filters["animals"]
    are equal as an empty list, as you can see in this image:
    image
    Now if we add a value to the variable "aniamls_local" we also see that works perfect:
    image

  • Step 6: The bug appear in the second request, where we do same steps that in the Step 5, but in this second request if we check the value of varieble filters["animals"] we can see that its default value is the old value of the previous request, where we added "duck" word to "animals" list argument:
    image

  • What is the expected behavior?
    The expected behavior is that if I launch multiple request of this mutation and I dont pass any value for "animals" argument, the default_value must be what I declare in set up type (an empty list).
    So graphene have to reset correctly the default_value and not persist old values.

  • Please tell us about your environment:

    • Version: graphene>=3.1
    • Platform: Ubuntu 22.04.3 LTS
@erikwrede
Copy link
Member

Hey @VicGoico, from my point of view, this is not a bug but expected behavior. Default values should be treated as READ-Only. We cannot expect all default values to implement copy to satisfaction. Due to that, it is on the user to avoid mutating the defaults. My recommendation for lists: use an empty tuple for defaults (,). However, documentation could be improved to mention this.

@VicGoico
Copy link
Author

VicGoico commented Jan 11, 2024

Hi @erikwrede , thanks for your answer.

Therefore, the solution is to use .copy(), when we want to handle the value argument, to isolate it.

To sum up, the example that I mentioned, will work fine doing this:

class AnimalFarm(graphene.Mutation):
    class Arguments:
        animals = graphene.List(graphene.String, default_value=(,))

    output = graphene.List(graphene.String)

    def mutate(root, info, **filters):
        animals_mio = filters["animals"].copy() # Here is the solution
        animals_mio.append('duck')
        
        return animals_mio


class Mutation(graphene.ObjectType):
    animal_farm = AnimalFarm.Field()

Any mantainer can close the issue if they see it necessary.

Thanks for your work and have a nice day

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants