Skip to content

Conversation

@binaryDiv
Copy link
Contributor

This is part of making validataclass mypy-compatible (#116).
Please note that the target branch is dev-mypy instead of main.


This PR refactors how validataclass default objects (Default, DefaultFactory, DefaultUnset, NoDefault) work to make them more typing-compatible.

New base class, generic Default and DefaultFactory

I've introduced an abstract base class BaseDefault[T] which all other default classes inherit from. Previously, Default was the base class, which had several drawbacks.

The classes Default and DefaultFactory both inherit the type parameter T from BaseDefault. The type parameter specifies the type of the default values that these objects provide.

The attributes Default.value and DefaultFactory.factory have been changed to be protected attributes instead (_value and _factory), because they shouldn't be accessed from the outside and definitely should not be changed. This can be considered a minor breaking change, because in practice it's unlikely that user code accessed these attributes.

Another breaking change is that using Default() without arguments is not allowed anymore. Previously, this was equivalent to Default(None). This was never documented and mostly existed for internal purposes. I don't know of any user code that used Default() without arguments, but it should be mentioned in the release notes.

DefaultUnset

The value DefaultUnset used to be a singleton instance of an unnamed/deleted subclass of Default (which customized the __repr__ and provided a __call__ method). This class has been removed and DefaultUnset is now a regular Default object, i.e. it was defined as DefaultUnset = Default(UnsetValue).

This has the side effect that repr(DefaultUnset) is now "Default(UnsetValue)" rather than "DefaultUnset". Code shouldn't really rely on how the repr looks though, so I'd consider this a practically irrelevant minor breaking change.

For compatibility, it's still possible to use DefaultUnset() with parentheses. However, this usage has been deprecated with this MR. Please use DefaultUnset without parentheses instead.

NoDefault

Usage of NoDefault() with parentheses has been deprecated like DefaultUnset(), but contrary to DefaultUnset, I'm not aware of any code that is affected by this change.

Misc changes

Several exception texts have been slightly modified.

@binaryDiv binaryDiv self-assigned this Jan 15, 2026
@binaryDiv binaryDiv added breaking changes This issue will cause a breaking change (or deprecation warning). refactoring Code refactoring, clean up and other code maintenance work. labels Jan 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking changes This issue will cause a breaking change (or deprecation warning). refactoring Code refactoring, clean up and other code maintenance work.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants