pydantic icon indicating copy to clipboard operation
pydantic copied to clipboard

Removing the V2 compatibility layer

Open samuelcolvin opened this issue 2 years ago • 2 comments

We're going to have a fair amount of code to ease the process of migrating from V1 to V2, including:

  • logic to catch old import paths, see #5113
  • similarly, support for from pydantic.settings import BaseSettings, even tough settings is in a new package - if pydantic-settings is installed, the import will work with a warning, if not you'll get an error saying "please install ..."
  • same for types moved/copied to pydantic-extra-types e.g. Color and PaymentCard - they're currently copied, e.g. they still exist in pydantic, but long term we want to remove that logic from pydantic
  • functional validator wrappers, see #5153
  • support for class based config
  • potentially a compatibility mode in pydantic-core that get's some old very common coercions to work, e.g. int -> str and any iterable of pairs -> dict
  • warning/error for things like Config.fields which has been removed

These compatibility features should be temporary. The question is how/when to remove them?

We should decide this before v2 is released so we can be explicit in warnings and errors about when the functionality will change.

Two options:

  1. keep them until v3 - this either means keeping them for a long time, or releasing v3 quite soon even though most of the "changes" will just be removing this stuff
  2. removing them in a future minor release, e.g 2.3 - this would mean they can be removed more quickly, but would break semvar and would require us to know when minor release they'll be removed in now and could potentially restrain us from releasing new features as we have to limit our new minor releases e.g. "so 2.3 isn't released until a year after v2"
  3. Remove them almost immediately in 2.1 - e.g. 2.0 is really just a compatibility release

I guess I'm leaning towards either 1 or 3, what do others think?

samuelcolvin avatar Mar 10 '23 09:03 samuelcolvin

I am Ok with option 1. keeping them in V2 and removing them in V3.

or releasing v3 quite soon even though most of the "changes" will just be removing this stuff

Not so cool IMHO, but we might want to do it because V2 is a special version.

In general, we need to define a deprecation/removal plan and stick to it. for example, everything that is deprecated in a minor release will be removed in the next major release except deprecation in the last minor that has to be removed in minor version 1 of the next major release.

Consider we are in V2 and V2.5 is the latest minor release in V2. then all the deprecated features in V2.0-4 will be removed in V3.0 and deprecated features in V2.5 will be removed in V3.1

Then we can mark the features in code, tests, and docs with a pre-defined format to find them easily for removal. for example:

# RemoveInV3.0: When the deprecation ends, remove the function.
def test_func():
    warnings.warn('`test_func` is deprecated and will be removed in V3.0. use `new_func` instead')
    ....

hramezani avatar Mar 10 '23 12:03 hramezani

I agree with @hramezani's suggestion to keep the items in v2 and remove them in v3, but I also think it's important to have a clear plan for how we will deprecate and remove them.

Essentially, there are two options:

  • Deprecate in v2 and remove in v3.
  • Keep in v2 and remove in v3.

I'm comfortable with either option, but I believe we should have a concrete strategy in place.

For example:

similarly, support for from pydantic.settings import BaseSettings, even tough settings is in a new package - if pydantic-settings is installed, the import will work with a warning, if not you'll get an error saying "please install ..."

same for types moved/copied to pydantic-extra-types e.g. Color and PaymentCard - they're currently copied, e.g. they still exist in pydantic, but long term we want to remove that logic from pydantic.

If we go with the first flow, in the first minor versions ex. v2.2 we should start informing the user that the import is deprecated and will be removed in v3.

def __getattr__(name):
    if name in ('BaseSettings'):
        warnings.warn(
            f'pydantic.{name} is deprecated and will be removed in v3.0, '
            'please use: pip install pydantic-settings instead.',
            DeprecationWarning,
        )
        return getattr(settings, name)
     raise AttributeError(f'module {__name__!r} has no attribute {name!r}')

Depending on the option we choose, we could begin to inform users of deprecation as early as minor version v2.2, or simply inform them that the imports will be removed in v3.

We could also stagger the removal process, with deprecated imports being removed earlier in minor versions ex. v2.5

yezz123 avatar Mar 10 '23 12:03 yezz123

Hey all... I am using pydantic 2.0.2 and it seems that the BaseSettings was removed / split out with no compat code at all. Is this intentional? It seems there was some consensus that compat code should exist, and the BaseSettings case is even mentioned in the most recent comment with some example code... is all that is missing a PR?

CameronNemo avatar Aug 04 '23 18:08 CameronNemo

@CameronNemo: https://docs.pydantic.dev/latest/usage/pydantic_settings/ / https://docs.pydantic.dev/latest/migration/#basesettings-has-moved-to-pydantic-settings

Viicos avatar Aug 09 '23 09:08 Viicos

@Viicos yes, I read the migration notes. but I was under the impression, based on this discussion, that compat code would be added to pydantic with deprecation warnings.

CameronNemo avatar Aug 09 '23 16:08 CameronNemo

Ah yes sorry misunderstood, BaseSettings has indeed moved to a separate package, but also got a massive rewrite. Maybe you can use the compat code from pydantic.v1? (available with pydantic v2)

Viicos avatar Aug 09 '23 16:08 Viicos