Hi Patryk,
On 11/12/2015 05:48 AM, Patryk Zawadzki wrote:
> I have spent quite a while thinking about this and am still not sure
> what the best approach would be or even if there are enough benefits
> to justify the change.
I think the idea is interesting (and I know it's been at least briefly
discussed before, I think back when the system checks framework was
first introduced), but I'm not sure if there are enough benefits to
justify adding it. More comments below:
> If you've ever worked with compiled code, you're probably familiar
> with ABI versioning in dynamic libraries. This is somewhat similar.
>
>
> The idea is to allow a project to specify that is _assumes_ Django to
> behave like a particular version or release. It could do so by
> specifying a TARGET_DJANGO_VERSION (better name needed) setting that
> is a valid semantic version tuple.
>
> Example:
>
> TARGET_DJANGO_VERSION = (1, 8, 6)
>
> New projects would start with the variable set to whatever Django
> version was used to create them. If the variable is not set, Django
> could raise an ImproperlyConfiguredError telling the user what to put
> in the settings file or it could simply issue a warning and assume the
> current version.
I think the latter. Lack of this setting isn't a nearly serious enough
issue to prevent Django starting up (not to mention that in itself would
be a massive backwards-incompatible change).
> Now what that gives us:
>
> * Django version Y could outright tell you that the project that
> targets version X is not compatible and point you to the *relevant*
> upgrade instructions (since we know both the old and the new version).
Ok - I guess this could direct more people to the release notes who
otherwise might have tried to upgrade without reading them. This benefit
only applies if you first upgrade Django without touching your
TARGET_DJANGO_VERSION setting.
> * Setting the target version to a higher value could turn deprecation
> warnings to exceptions for all features deprecated in the target
> version and earlier (which could make future-proofing your code
> easier).
You're proposing this would only activate if your TARGET_DJANGO_VERSION
is higher than your actual Django version? I'm not sure how this feature
is even possible as you've described it, since if you have Django 1.8
installed and you set TARGET_DJANGO_VERSION to (1, 9, 0), that doesn't
magically give Django 1.8 knowledge of future deprecations! Perhaps I'm
misunderstanding.
Plus, it's not hard to use filterwarnings to turn all deprecation
warnings into exceptions (I often do this on my projects, at least for
the test suite). Perhaps this is a technique we should recommend and
demonstrate somewhere in our upgrade docs?
> * Django could introduce A/B feature switches that introduce
> backwards-incompatible behaviour if a high-enough target version is
> specified without breaking existing projects.
This is tempting at first blush, because it allows us to claim that
you've opted in to whatever backwards-incompatible changes we feel like
making by bumping your TARGET_DJANGO_VERSION. I think this is false,
though. You don't know what all you're opting into by bumping your
TARGET_DJANGO_VERSION unless you carefully read the release notes.
(Unlike other opt-ins which typically involve changing the use of
specific APIs in your code.) So how is it any different from us claiming
that you've already "opted in" to backwards incompatible changes simply
by upgrading Django? (In practice, we _do_ claim this already, but we
try to minimize such changes.)
I guess the idea is that you could first upgrade Django but leave your
TARGET_DJANGO_VERSION alone, and nothing would break, and then you could
at some point bump up your TARGET_DJANGO_VERSION when you're ready to
deal with the breaking changes? In the end I'm not sure that's any
better than today's story, which is just "upgrade Django when you're
ready to deal with the breaking changes."
> It would also make it
> theoretically possible for the latest stable version to support the
> last LTS version from the same code tree (although it would probably
> require an enormous legacy/compat module).
As Collin pointed out, this is something we already are attempting to
achieve with our latest deprecation and version-numbering policy.
> Is that something that was discussed in the past? Does it make any sense?
Figuring out backwards-compatibility issues is already a brain-bender
sometimes, when considering both upgrading projects and new projects
(the effects of changes in Django vs changes in the startproject
template, etc).
This proposal would add yet another axis to this matrix, as we'd have to
additionally consider the effects of pairing various
TARGET_DJANGO_VERSIONs with various actual Django versions. At this
point, I'm not seeing enough benefit to justify that complexity.
Happy to discuss further if I'm missing something, though.
Carl