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

Setting <UnicodeSetAttribute>.set([]) (empty list) throws "Nonetype is not iterable" error. #962

Closed
hoIIer opened this issue Jul 30, 2021 · 6 comments · Fixed by #1189
Closed

Comments

@hoIIer
Copy link

hoIIer commented Jul 30, 2021

During an update operation a UnicodeSet field may have it's value changed back to empty e.g. []

The following code fails:

(Pdb) actions = []
(Pdb) actions.append(attr.set([]))
(Pdb) record.update(actions)

*** TypeError: 'NoneType' object is not iterable

The following two examples work:

(Pdb) actions = []
(Pdb) actions.append(attr.set(None))
(Pdb) record.update(actions)
(Pdb) actions = []
(Pdb) actions.append(attr.set(['foo', 'bar']))
(Pdb) record.update(actions)

Is this a bug?

@hoIIer hoIIer closed this as completed Mar 20, 2022
@hoIIer hoIIer reopened this Jul 3, 2023
@hoIIer
Copy link
Author

hoIIer commented Jul 3, 2023

@ikonst reopening as I ran into this again, is it a bug?

Feels very annoying to not be able to reset a UnicodeSetAttribute to empty in an update operation.

instance.update(actions=[model.Thing.set_or_list.set({}|[])]) -> *** TypeError: 'NoneType' object is not iterable

@ikonst
Copy link
Contributor

ikonst commented Jul 3, 2023

I wonder what causes this error.

For what it's worth, though, underlying dynamodb does not support empty sets:
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html#HowItWorks.DataTypes
so it's unclear how it would behave, e.g.

  • same as unsetting (assigning None and then you read None back)
  • give an error, but a clearer one

@hoIIer
Copy link
Author

hoIIer commented Jul 11, 2023

I guess the annoying part is by removing it, you have to ensure any uses of the value explicitly test for None versus knowing it would always be an instance of list or set

@ikonst
Copy link
Contributor

ikonst commented Jul 12, 2023

I agree. Since the underlying database cannot store an empty set for us, we have to pick an alternative representation. An attribute being unset in the DynamoDB item manifests as None in the Pythonic model, so we cannot use unset as the representation, since it'll read back as None.

We could decide on a rule e.g. an empty set serializes as {"__MAGIC_PYNAMODB_VALUE_UNSET__"}, but that would be awkward.

Another compromise would be:

  • UnicodeSetAttribute(null=True) serializes set() as unset, and reads back as None
  • UnicodeSetAttribute(null=False) serializes set() as unset, and reads back as set()

ikonst added a commit that referenced this issue Jul 18, 2023
Fixes #962.

Allows update expressions to assign empty values to set-typed attributes by converting those SETs to REMOVEs.
@hoIIer
Copy link
Author

hoIIer commented Aug 6, 2023

@ikonst thank you!

@erovira
Copy link

erovira commented Oct 12, 2023

Ran into this. Thanks for the fix!

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

Successfully merging a pull request may close this issue.

3 participants