Security News
Introducing the Socket Python SDK
The initial version of the Socket Python SDK is now on PyPI, enabling developers to more easily interact with the Socket REST API in Python projects.
Github repo: https://github.com/clvnkhr/immutable-defaults
Simple decorator to force immutability to function arguments by deepcopying. Never again pass None
when your heart wants to pass an empty list. Also works for arbitrary objects that can be deepcopied. Has simple config options for granularity or performance (copy vs deepcopy).
No dependencies.
In order to use various type hints we require Python >=3.12.
pip install immutable-defaults
or your equivalent (e.g. pdm add immutable-defaults
)
from immutable_defaults import immutable_defaults
@immutable_defaults
def my_function(a: list = []):
a.append("world")
return a
print(my_function()) # ['world']
print(my_function(a=["hello"])) # ['hello', 'world']
print(my_function(["HELLO"])) # ['HELLO', 'world']
print(my_function()) # ['world']
@immutable_defaults(ignore=["b"])
def my_function2(a = ["hello"], b = []):
"""basic function with ignore parameter"""
a.append("world")
b.append("!")
return a + b
print(my_function2()) # ['hello', 'world', '!']
print(my_function2()) # ['hello', 'world', '!', '!']
print(my_function2()) # ['hello', 'world', '!', '!', '!']
# more exhaustive tests in tests/tests.py
The decorator works with methods, classmethods and staticmethods. Since @immutable_defaults
requires that the wrapped function is callable
, make sure that the outer decorator is @classmethod
/@staticmethod
.
@immutable_defaults
can be called with keyword arguments deepcopy
and ignore
.
deepcopy: boolean | Iterable[str] = True
True
then defaults are copied with copy.deepcopy
. If False, then with copy.copy
.a
and arg
will be deep copied while b
will be shallow copied. @immutable_defaults(deepcopy=["a","arg"])
def f(a=[[1]], b=[], arg={1: {2}}): ...
ignore: Iterable[str] | None = None
a is b
comparison) marked for both shallow and deep copying. For example, the below will raise an ImmutableDefaultsError
:xss = [[1]]
@immutable_defaults(deepcopy=["xss2"]) # raises ImmutableDefaultsError
def f(x, xss1 = xss, xss2 = xss): ...
ImmutableDefaultsError
:xss = [[1]]
@immutable_defaults(ignore=["xss2"]) # raises ImmutableDefaultsError
def f(x, xss1 = xss, xss2 = xss): ...
KeyError
is raised if either deepcopy
or ignore
have arguments that cannot be found in the signature of the decorated function.
ignore
are not present, but this would make typos very hard to debug.ignore
takes precedence over deepcopy
, i.e. @immutable_defaults(ignore=["x"], deepcopy=["x"])
will do the same thing as @immutable_defaults(ignore=["x"])
(Comments valid May 13 2024)
__deepcopy__
(or optionally __copy__
).FAQs
Immutable defaults for Python
We found that immutable-defaults demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
The initial version of the Socket Python SDK is now on PyPI, enabling developers to more easily interact with the Socket REST API in Python projects.
Security News
Floating dependency ranges in npm can introduce instability and security risks into your project by allowing unverified or incompatible versions to be installed automatically, leading to unpredictable behavior and potential conflicts.
Security News
A new Rust RFC proposes "Trusted Publishing" for Crates.io, introducing short-lived access tokens via OIDC to improve security and reduce risks associated with long-lived API tokens.