Skip to content

[SYNPY-1708] None values don't become annotations#1417

Open
andrewelamb wants to merge 8 commits into
developfrom
SYNPY-1708
Open

[SYNPY-1708] None values don't become annotations#1417
andrewelamb wants to merge 8 commits into
developfrom
SYNPY-1708

Conversation

@andrewelamb

@andrewelamb andrewelamb commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Problem:

Setting an annotation key to None (or to a value that contains no real data) did not behave intuitively when storing an entity:

  • A key set to None was stored as the literal string "None" rather than being treated as "no value".
  • A list containing only None values (e.g. [None, None]) was stored as ["None", "None"].
  • A list mixing None with real values (e.g. [None, "value"]) was stored as ["None", "value"], polluting the data with a bogus "None" element.

Solution:

_convert_to_annotations_list now treats None as the absence of a value:

  • A value of None is skipped entirely (the key is omitted), rather than being stringified.
  • None elements are stripped from list values before type inference, so a mixed list like [None, "value"] is stored as ["value"].
  • A value that resolves to an empty list after stripping None (including None, [], and [None, None]) is omitted.

Type inference now runs on the None-stripped element list, so the inferred Synapse type (STRING/BOOLEAN/LONG/DOUBLE/TIMESTAMP_MS) is no longer skewed by None placeholders. The literal string "None" is unaffected and is still stored as a normal string value.

The function also gained a full docstring documenting the conversion behavior, including the heterogeneous-list fallback to STRING.

Testing:

  • Added integration test test_setting_annotation_key_to_none in tests/integration/synapseclient/models/async/test_file_async.py that stores a file with one annotation set to a primitive None, one to a list of None values, one to an empty list, one to a list mixing None with a real value, and one to the literal string "None", then retrieves a fresh copy and asserts:
    • None, list-of-None, and empty-list keys are not stored at all.
    • The mixed list [None, "None"] round-trips as ["None"] (the None stripped).
    • The literal string "None" is stored as a normal string value.
  • Added unit tests in tests/unit/synapseclient/unit_test_annotations.py covering _convert_to_annotations_list directly:
    • test__convert_to_annotations_list__none_values — asserts a primitive None, a list of only None ([None, None]), and an empty list are all omitted; a mixed list ([None, "value", None]) has its Nones stripped to ["value"]; and the literal string "None" is kept as a normal STRING value.
    • test__convert_to_annotations_list__mixed_list_preserves_type — asserts that stripping None from typed lists still infers the correct Synapse type (LONG, DOUBLE, BOOLEAN) rather than falling back to STRING.

@andrewelamb andrewelamb requested a review from a team as a code owner June 25, 2026 16:22
@andrewelamb andrewelamb marked this pull request as draft June 25, 2026 16:23
@andrewelamb andrewelamb marked this pull request as ready for review June 25, 2026 16:26
Comment thread tests/integration/synapseclient/models/async/test_file_async.py Outdated
Comment thread synapseclient/annotations.py Outdated
Comment thread synapseclient/annotations.py
Comment thread synapseclient/annotations.py

@linglp linglp left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @andrewelamb ! I could approve too. I found some edge cases of null values that we could consider to cover, but I am also fine with how you have written here. There's also a small piece of dead code that can be removed.

Comment thread tests/unit/synapseclient/unit_test_annotations.py
Comment thread synapseclient/annotations.py
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 this pull request may close these issues.

4 participants