While reviewing my colleague's merge request I saw the usage of a mutable object as a default argument and pointed that out. To my surprise, it works as if have done a deepcopy of the object. I found an example in the project's readme, but without any clarification. And suddenly realized that developers constantly ignore this question for a long time (see links at the bottom).
Indeed, you can write something like this. And expect correct behavior:
from pydantic import BaseModel
class Foo(BaseModel):
    defaulted_list_field: List[str] = []
But what happens underhood?
We need to go deeper...
After a quick search through the source code I found this:
class ModelField(Representation):
    ...
    def get_default(self) -> Any:
        return smart_deepcopy(self.default) if self.default_factory is None else self.default_factory()
While smart_deepcopy function is:
def smart_deepcopy(obj: Obj) -> Obj:
    """
    Return type as is for immutable built-in types
    Use obj.copy() for built-in empty collections
    Use copy.deepcopy() for non-empty collections and unknown objects
    """
    obj_type = obj.__class__
    if obj_type in IMMUTABLE_NON_COLLECTIONS_TYPES:
        return obj  # fastest case: obj is immutable and not collection therefore will not be copied anyway
    try:
        if not obj and obj_type in BUILTIN_COLLECTIONS:
            # faster way for empty collections, no need to copy its members
            return obj if obj_type is tuple else obj.copy()  # type: ignore  # tuple doesn't have copy method
    except (TypeError, ValueError, RuntimeError):
        # do we really dare to catch ALL errors? Seems a bit risky
        pass
    return deepcopy(obj)  # slowest way when we actually might need a deepcopy
Also, as mentioned in the comments you can not use mutable defaults in databases attributes declaration directly (use default_factory instead). So this example is not valid:
from pydantic.dataclasses import dataclass
@dataclass
class Foo:
    bar: list = []
And gives:
ValueError: mutable default <class 'list'> for field bar is not allowed: use default_factory
Links to open discussions (no answers so far):