Skip to content
New issue

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

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

Already on GitHub? # to your account

🩹 Remove mutable default params #959

Closed

Conversation

SBrandeis
Copy link
Contributor

Using mutable defaults for function parameters is a bad practice that can lead to unexpected and tricky bugs.

Defaults are evaluated only once at import time. A new list is created once when the function is defined, and the same list is used in each successive call. Mutating the tags argument would result in mutating the default for subsequent calls of the method.

See https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments

Mutable defaults for function parameters is a bad practice that can
lead to unexpected and tricky bugs.

Defaults being evaluated only once at import time, a new list is created
once when the function is defined and the same list is used in each
successive call. Mutating the `tags` argument would result in mutating
the default for subsequent calls of the method.

See https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments
@HuggingFaceDocBuilderDev
Copy link

HuggingFaceDocBuilderDev commented Jul 26, 2022

The documentation is not available anymore as the PR was closed or merged.

@@ -222,7 +222,7 @@ def __init__(
self.modelId = modelId
self.sha = sha
self.lastModified = lastModified
self.tags = tags
self.tags = tags if tags is not None else []
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
self.tags = tags if tags is not None else []
self.tags = tags

I'd even do this personally (i.e. self.tags can be None)

Copy link
Contributor

@adrinjalali adrinjalali left a comment

Choose a reason for hiding this comment

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

Nice!

Copy link
Member

@LysandreJik LysandreJik left a comment

Choose a reason for hiding this comment

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

Thanks!

Copy link
Contributor

@adrinjalali adrinjalali left a comment

Choose a reason for hiding this comment

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

Personally happy with any of the suggestion or existing variations.

Co-authored-by: Adrin Jalali <adrin.jalali@gmail.com>
@SBrandeis SBrandeis force-pushed the default-mutable-argument-bad branch from a76fbc8 to ef48539 Compare July 26, 2022 15:22
@SBrandeis
Copy link
Contributor Author

After discussing with @julien-c, it happens that sometimes the API does not return tags (example: hf_api.list_models)
In this case, it seems that having self.tags = None is more correct

Co-authored-by: Julien Chaumond <julien-c@users.no-reply.huggingface.co>
Copy link
Contributor

@osanseviero osanseviero left a comment

Choose a reason for hiding this comment

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

Thanks!

@SBrandeis SBrandeis requested a review from Wauplin August 4, 2022 15:44
@Wauplin
Copy link
Contributor

Wauplin commented Aug 5, 2022

Good catch since this can really create unexpected behaviours.

I would really suggest that we start tracking these errors automatically using flake8-bugbear. It is a plugin for flake8 that finds "bad patterns" in code. In particular B006 checks for mutable default values. Since we already check for flake8 issues in our CI, it will integrate seamlessly with current workflow. To use it, we would need to:

  • add flake8-bugbear as dependency in setup.py [quality]
  • adapt existing codebase to remove new "errors" raised by flake8-bugbear. I already checked and the number of changes is quite low and very easy to adapt.

Any opinion about it ? If no-one sees a problem here I can create a PR to enable it.
The only catch I see is that it can "slow down" the dev process but I would argue that it's for the best (+we can always ignore a given error if it's really annoying).

@julien-c
Copy link
Member

julien-c commented Aug 5, 2022

Personally, no objection to your proposal @Wauplin

@SBrandeis
Copy link
Contributor Author

I'm in favor of @Wauplin's suggestion 👍

@Wauplin
Copy link
Contributor

Wauplin commented Aug 9, 2022

Done as part of #967. I'm closing it without merging.

@Wauplin Wauplin closed this Aug 9, 2022
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants