Re: Feature proposal: Target API version

2015-11-12 Thread Shai Berger
If I get this correctly, this has an interesting effect:

If Django 1.9 supports API Target Versions 1.7 and 1.8 at its launch, then it 
must also support them for its lifetime (dropping them would be the kind of 
change we don't introduce in minor versions). 1.7's API would need to be 
supported as long as 1.9 lives. This, essentially, makes every Django release 
an LTS.

I suppose many users would be happy about that outcome. Contributors, less so.

-1,

Shai.


Re: Odd behavior change in 1.8 with {% if %}, RelatedObjectDoesNotExist, and TEMPLATE_STRING_IF_INVALID

2015-11-12 Thread Shai Berger
On Thursday 12 November 2015 18:22:23 Tim Graham wrote:
> The expected behavior of the {% if %} tag isn't clear to me. How do you
> propose to solve the "bug"? As I noted in the ticket:
> 
> We end up checking {% if  %} which passes for a
> non-empty string_if_invalid. 

It seems pretty obvious to me that anything which would be replaced by 
string_if_invalid should be falsey. This is because string_if_invalid is 
supposed to be a debug aid -- showing when "invalid" happens -- while the 
"production" value in a template is an empty string. It is also what happens 
for undefined variables, irrespective of string_if_invalid. That is, the bug as 
I see it is the mismatch between

{% if undefined %}
   This is not rendered, regardless of string_if_invalid
{% endif %}

and

{% if obj.missing_relation %}
   This may be rendered, depending on string_if_invalid
{% endif %}

They should be the same (and the former seems less wrong than the latter).

What am I missing?


Re: Feature proposal: Target API version

2015-11-12 Thread Patryk Zawadzki
2015-11-12 17:40 GMT+01:00 Carl Meyer :
> On 11/12/2015 05:48 AM, Patryk Zawadzki wrote:
>> * 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.

Consider Django version 1.9 that also happens to support API versions
1.7 and 1.8 and an application that originally targetted 1.7.

I could leave my target API at 1.7 and get the app to work. This
requires minimum resources. I would assume during normal operation
deprecations introduced in 1.8 and later would not show up since I'm
explicitly targetting 1.7.
I could also bump my target API to 1.8 and get some more deprecation
warnings for things deprecated in 1.8 (but not in 1.9). At this point
things deprecated since 1.7 should stop working so I can make sure
that I am actually targetting the "intended" APIs of 1.8.
I could finally go all the way up to 1.9 and possibly get different
behaviour when calling the same functions I did while targetting 1.8.
See below for discussion.

> 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?

Yes, this is how I imagine this to work. Specifying the target could
among other things configure which warnings are ignored and which are
explicitly turned into errors.

>> * 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."

Yes, you could upgrade Django safely at least X times before having to
touch any code. You could also target a major version like 2.5 and not
experience potentially incompatible but more secure change to default
settings introduced in its point release, 2.5.7, while allowing new
projects to benefit from that change.

Cheers,

-- 
Patryk Zawadzki
I solve problems.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CANw2pUF3CsY0%2B_q_ABk2bfHeHzF3HVF9m39iYXapM0ox7Te%2BxQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Odd behavior change in 1.8 with {% if %}, RelatedObjectDoesNotExist, and TEMPLATE_STRING_IF_INVALID

2015-11-12 Thread Carl Meyer
On 11/12/2015 09:22 AM, Tim Graham wrote:
> The expected behavior of the {% if %} tag isn't clear to me. How do you
> propose to solve the "bug"? As I noted in the ticket:
> 
> We end up checking {% if  %} which passes for a
> non-empty string_if_invalid. I'm not sure we should add special handling
> of RelatedObjectDoesNotExist in the template engine to restore the old
> behavior (and I'm not sure how to since RelatedObjectDoesNotExist is a
> dynamically generated exception based on the related descriptors).

RelatedObjectDoesNotExist inherits from ObjectDoesNotExist, so we could
catch ObjectDoesNotExist, I suppose. It is possible to construct a
rationale for that: "an object that does not exist should evaluate to
false." But I'm not sure I buy that rationale; I don't like adding more
ad-hoc differing handling of particular exception types in the template
engine.

A better option for resolving this might be to have a dedicated Invalid
type which always evaluates to false in boolean context, but renders
itself as TEMPLATE_STRING_IF_INVALID if asked to coerce to a string.

I guess it could be arguable whether Invalid should be truthy or falsy,
but at least that way it would always be consistent, not dependent on
TEMPLATE_STRING_IF_INVALID.

Carl

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/5644C38E.8030804%40oddbird.net.
For more options, visit https://groups.google.com/d/optout.


signature.asc
Description: OpenPGP digital signature


Re: Feature proposal: Target API version

2015-11-12 Thread Carl Meyer
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

-- 
You received this message because you are subscribed to th

Re: Odd behavior change in 1.8 with {% if %}, RelatedObjectDoesNotExist, and TEMPLATE_STRING_IF_INVALID

2015-11-12 Thread Tim Graham
The expected behavior of the {% if %} tag isn't clear to me. How do you 
propose to solve the "bug"? As I noted in the ticket:

We end up checking {% if  %} which passes for a 
non-empty string_if_invalid. I'm not sure we should add special handling of 
RelatedObjectDoesNotExist in the template engine to restore the old 
behavior (and I'm not sure how to since RelatedObjectDoesNotExist is a 
dynamically generated exception based on the related descriptors).

I guess this is related to https://code.djangoproject.com/ticket/17664 
which describes inconsistencies in how the if tag silences exceptions.

On Wednesday, November 11, 2015 at 4:56:03 PM UTC-5, Shai Berger wrote:
>
> On Tuesday 10 November 2015 21:32:36 Tim Graham wrote: 
> > I'd appreciate some opinions on whether or not we should treat this 
> issue 
> > as a regression: https://code.djangoproject.com/ticket/25600 
>
> Since this is essentially about the `string_if_invalid` configuration 
> option, 
> whose documentation carries a very clear "For debug purposes only!" 
> admonition, my inclination is to treat it as a normal bug on the grounds 
> that 
> it should not affect any production site. 
>
> It is still a bug though, I'd like to see it fixed for 1.9. 
>
> Shai. 
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/ec3d10ea-6f0a-4828-8d17-50a31f30e472%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Feature proposal: Target API version

2015-11-12 Thread Collin Anderson
Hi,

"It would also make it theoretically possible for the latest stable version 
to support the 
last LTS version from the same code tree".

Have you seen the latest changes to the deprecation policy? We hope we've 
done exactly that (having the latest version of Django support code that 
was written for the last LTS.)
https://docs.djangoproject.com/en/dev/internals/release-process/#deprecation-policy

Collin


On Thursday, November 12, 2015 at 7:48:28 AM UTC-5, Patryk Zawadzki wrote:
>
> Hello everyone, 
>
> 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. 
>
> 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. 
>
>
> 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). 
>
> * 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). 
>
> * Django could introduce A/B feature switches that introduce 
> backwards-incompatible behaviour if a high-enough target version is 
> specified without breaking existing projects. 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). 
>
>
> Is that something that was discussed in the past? Does it make any sense? 
>
> Cheers, 
>
> -- 
> Patryk Zawadzki 
> I solve problems. 
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/26073e01-8517-4ee2-bdf1-c81c9503a88e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Feature proposal: Target API version

2015-11-12 Thread Patryk Zawadzki
Hello everyone,

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.

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.


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).

* 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).

* Django could introduce A/B feature switches that introduce
backwards-incompatible behaviour if a high-enough target version is
specified without breaking existing projects. 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).


Is that something that was discussed in the past? Does it make any sense?

Cheers,

-- 
Patryk Zawadzki
I solve problems.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CANw2pUGty5ndZsREqjbqjT-RZYc3Vjo5%2Begc7Et3C2nbj5OzNw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Provide a way to pass kwargs when initializing the storage class

2015-11-12 Thread James Aylett
On 8 Nov 2015, at 08:31, Marc Tamlyn  wrote:

> I'm definitely in favour of a format allowing multiple storage back ends 
> referred to by name. For larger sites it is not unusual to manage files 
> across multiple locations (eg several S3 buckets). The storage param to 
> FileField would be allowed to be the key, and there would be a get_storage 
> function like get_cache.

It would remove the assymetry between the default backends and per-field ones, 
which does feel a little odd. However I don’t think that’s a strong enough 
reason to go for more complicated. Ballooning dictionaries can feel 
overwhelming when looking at modern Django settings (for instance, the new 
templates configuration is more daunting than it used to be), and as pointed 
out, overriding is more fiddly.

For testing, you need to be explicit per-field no matter what, so it’s a change 
from an instance to a symbolic reference. The instance is probably a variable 
anyway by declaration of the test model, which I suspect is slightly easier to 
chase.

So I’d be slightly more in favour of the terse, tuple-based syntax.

J

-- 
 James Aylett
 I make: devfort.com, spacelog.org
 Films: talktorex.co.uk
 Everything else: tartarus.org/james/

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/9462EC40-4D41-4664-A272-D6A9C58DDBB3%40tartarus.org.
For more options, visit https://groups.google.com/d/optout.