Writing items: list[str] = [] on a Pydantic model is safe. Pydantic deep-copies the default for each instance, so two models do not share the list. The same line in a plain class or a dataclass is the classic shared-mutable-default bug, and a dataclass rejects it outright with a ValueError telling you to use default_factory.
This asymmetry causes real confusion in codebases that mix the two, because the identical syntax is a bug in one file and correct in the next. Confirm the Pydantic behaviour with two instances and an is comparison on the field.
There are two reasons to prefer Field(default_factory=list) anyway. Deep-copying an expensive default on every instantiation costs more than calling a factory. And a default that must be computed per instance, such as datetime.now() or a generated UUID, cannot be expressed as a copied constant at all. Note that defaults are not validated by default, so a default that violates the field's own type passes silently unless you set validate_default=True.