Skip to content

[bugfix] Fix sanitize function for nd_rest module (DCNE-684)#210

Open
gmicol wants to merge 2 commits intoCiscoDevNet:masterfrom
gmicol:nd_rest_bug_fix_181
Open

[bugfix] Fix sanitize function for nd_rest module (DCNE-684)#210
gmicol wants to merge 2 commits intoCiscoDevNet:masterfrom
gmicol:nd_rest_bug_fix_181

Conversation

@gmicol
Copy link
Copy Markdown
Collaborator

@gmicol gmicol commented Mar 30, 2026

fix #181

The sanitize function will now return an empty dict when the obj_to_sanitize is None: Deals with cases where the API returns None.

…when The API-returned object to sanitize is None.
Copy link
Copy Markdown
Collaborator

@shrsr shrsr left a comment

Choose a reason for hiding this comment

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

LGTM

"""Clean up a Python object of type list or dict from specific keys, values and None values if specified"""
if isinstance(obj_to_sanitize, dict):
if obj_to_sanitize is None:
return {}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why determine to return a dict and not a list because the function cleans list or dict? Why not return None in this case?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

None makes definitely more sense. Changed it

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@gmicol I checked the modules to see where sanitize() is being used and looks like nd_rest is the only module using it so far. However, In nd_rest could you please verify whether we could replace:

if sanitize(nd.result["jsondata"], ND_REST_KEYS_TO_SANITIZE) != nd.previous and method != "GET":
    nd.result["changed"] = True

with

if nd.existing != nd.previous and method != "GET":
    nd.result["changed"] = True

@gmicol gmicol requested a review from akinross March 31, 2026 17:51
@shrsr shrsr self-requested a review April 1, 2026 01:28
Copy link
Copy Markdown
Collaborator

@akinross akinross left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Copy Markdown
Collaborator

@mikewiebe mikewiebe left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Copy Markdown
Collaborator

@allenrobel allenrobel left a comment

Choose a reason for hiding this comment

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

LGTM

"""Clean up a Python object of type list or dict from specific keys, values and None values if specified"""
if isinstance(obj_to_sanitize, dict):
if obj_to_sanitize is None:
return None
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Although None makes sense in isolation here, I tend to agree with the initial change of returning {}. This is based on how sanitize is used in nd_rest.
Since existing & previous all default to dict() there might be issues related to comparison of {} != None.
It could surface issues like always setting changed=True on line 279 in nd_rest.py for certain cases. Although it might only be an issue for edge cases.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I tend to disagree with that statement. I think nd_rest should return exactly what the API is returning: If a POST or PUT request has been made and the API returns no content, we should return None as well.

If we go back to the initial change of returning to an empty dict, we face the opposite issue of the one you are mentioning: changed will always be equal to False on line 279 if the API returns None even though potential changes have been pushed.

it's true that might be issues related to comparison of {} != None. However, I think there would just a few of edge cases compared to the opposite scenario. I would rather indicate to our users that a change has potentially been made rather than the opposite.

But it raises an issue on how we want the nd_rest module to behave when indicating a change, knowing that the API is very inconsistent.

Copy link
Copy Markdown
Collaborator

@samiib samiib Apr 9, 2026

Choose a reason for hiding this comment

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

There are places we adjust what the API returns for usability. Example in other modules that have comma separated string properties which get converted to lists. Or error messages that get additional validation. Since nd_rest is simply a passthrough for the API we just need to make sure the module clearly shows what the API is returning. I can see changed being false is also a potential usability issue aswell.
Does a None in the existing/previous results returned as explicit null or get omitted?

@gmicol gmicol requested a review from samiib April 8, 2026 14:38
def sanitize(obj_to_sanitize, keys=None, values=None, recursive=True, remove_none_values=True):
"""Clean up a Python object of type list or dict from specific keys, values and None values if specified"""
if isinstance(obj_to_sanitize, dict):
if obj_to_sanitize is None:
Copy link
Copy Markdown
Collaborator

@samiib samiib Apr 9, 2026

Choose a reason for hiding this comment

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

I can see an opportunity to add tests for this to increase test coverage of nd_rest.

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.

nd_rest module crashes with TypeError when API returns empty response body (DCNE-684)

6 participants