Removing url() ?

391 views
Skip to first unread message

Collin Anderson

unread,
May 5, 2020, 11:41:58 AM5/5/20
to Django developers (Contributions to Django itself)
Hi All,

Are we _sure_ we want to completely get rid of url()?

Yesterday, url() was given a RemovedInDjango40Warning [PR]. The removal was approved as part of the new path() syntax back in 2017 [DEP 0201].

Is this really worth it? It's only a few lines of code to keep backward compatibility, and it seems to me it would take almost no work to maintain that compatibility shim compared to the countless programmer hours needed to upgrade their code, including many unpaid programmers working on open source projects. I'll personally need to do a find/replace for url() to re_path() across my ~20 projects, and update all of the imports. Isn't this useless code churn?

Yes, there's an advantage to having one and only one way to do it, so I agree we should encourage people to use re_path() instead of url(), but shouldn't we also make it as easy as possible to upgrade django? Is getting rid of url() really worth the cost?

Yes, the removal is still ~3+ years away, but that's a question of _when_ not _if_.

If we want, we _could_ deprecate url() without giving it an actual removal date [Compatibility Discussion] and leave the compatibility shim around longer, if not indefinitely.

Thanks,
Collin




Mariusz Felisiak

unread,
May 5, 2020, 12:32:58 PM5/5/20
to Django developers (Contributions to Django itself)
Hi,

   I think it's worth to deprecate url() and remove it in Django 4.0 (that's why I accepted this ticket). Aymeric proposed Django 3.1 as a beginning of deprecation period in a discussion about DEP 201 [1], it was three years ago. Moreover we removed it from the docs with the new implementation [2] (also three years ago) and only versions with re_path() are now supported. Also, Django 3.2 is a LTS supported until April 2024 and it will contain url().

Best,
Mariusz

Mariusz Felisiak

unread,
May 5, 2020, 12:41:52 PM5/5/20
to Django developers (Contributions to Django itself)
... and deprecation in Django 3.0 is defined in DEP 201 [1].

אורי

unread,
May 5, 2020, 12:46:06 PM5/5/20
to Django developers (Contributions to Django itself)
My project contains about 100 calls to url() with regex. Can you explain to me what has been changed and why, and how should I change my code to stop using url()? And where is it documented? I checked the documentation and I didn't find an explanation why url() was changed and what are the differences between url() and path() and re_path()?


--
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-develop...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/17899c17-2c07-4a80-baa5-e0a348d9512c%40googlegroups.com.

James Bennett

unread,
May 5, 2020, 1:04:02 PM5/5/20
to django-d...@googlegroups.com
On Tue, May 5, 2020 at 8:42 AM Collin Anderson <cmawe...@gmail.com> wrote:
> Is this really worth it? It's only a few lines of code to keep backward compatibility, and it seems to me it would take almost no work to maintain that compatibility shim compared to the countless programmer hours needed to upgrade their code, including many unpaid programmers working on open source projects. I'll personally need to do a find/replace for url() to re_path() across my ~20 projects, and update all of the imports. Isn't this useless code churn?

I think it should be deprecated and removed.

On the one hand, we're talking about an extremely long (~7 years)
timeline from when re_path() was introduced to when it would become
mandatory for projects that need regex-based URL routing. That seems
like plenty of time for projects to notice that a new URL routing
approach was adopted. And that's a long, *long* time to keep
effectively-dead code in Django, far longer than what the normal
deprecation cycle would be.

On the other hand, if it doesn't get removed, it sets a bad precedent
-- Django needs to be able to evolve over time, and part of that is
ensuring that once something is no longer the recommended approach it
gets removed from the framework. Without raising eventually-loud
deprecation warnings (further along in the cycle), people who still
have url() in their codebases might never even find out that the
simplified DEP 201 URL routing is available. Raising a deprecation
warning makes sure they find out; some projects will undoubtedly just
find-and-replace url() to re_path(), but others will probably be happy
to find out that the simpler path() routing exists.

Collin Anderson

unread,
May 5, 2020, 2:08:31 PM5/5/20
to Django developers (Contributions to Django itself)
> Without raising eventually-loud deprecation warnings (further along in the cycle), people who still have url() in their codebases might never even find out that the
simplified DEP 201 URL routing is available. Raising a deprecation warning makes sure they find out; some projects will undoubtedly just
find-and-replace url() to re_path(), but others will probably be happy to find out that the simpler path() routing exists.

Yes, I'm totally fine with raising a warning, as it brings path() to people's attention. I just think the url() -> re_path() migration should be an optional thing. People who care about code quality will see the warning and make the change. Those who don't care about slighty higher code quality will get a warning, but at least Django isn't forcing them to do something they don't care at all about. Their code will still run just fine on newer versions of Django.

James Bennett

unread,
May 5, 2020, 2:13:30 PM5/5/20
to django-d...@googlegroups.com
On Tue, May 5, 2020 at 9:45 AM ‫אורי‬‎ <u...@speedy.net> wrote:‬
> My project contains about 100 calls to url() with regex. Can you explain to me what has been changed and why, and how should I change my code to stop using url()? And where is it documented? I checked the documentation and I didn't find an explanation why url() was changed and what are the differences between url() and path() and re_path()?

There is no difference; django.conf.urls.url() is just an alias for
django.urls.re_path().

Jon Dufresne

unread,
May 5, 2020, 2:18:02 PM5/5/20
to django-d...@googlegroups.com
+1 for deprecating for eventual removal.

--
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-develop...@googlegroups.com.

Karen Tracey

unread,
May 5, 2020, 2:22:08 PM5/5/20
to django-d...@googlegroups.com

On Tue, May 5, 2020 at 11:42 AM Collin Anderson <cmawe...@gmail.com> wrote:
Hi All,
Are we _sure_ we want to completely get rid of url()?

 
I'm not! I'd be much happier with fewer tedious upgrade tasks and the ability to use client's money for new features rather than "keeping up", sigh.

Mariusz Felisiak

unread,
May 5, 2020, 3:06:12 PM5/5/20
to Django developers (Contributions to Django itself)
TBH, I don't see a reason to create a precedent and deprecate it without any removal plans. Deprecation and removal is described in DEP 201, I don't think that we can revert [1] without a technical board approval 🤔 I would like to highlight that url() is an alias for re_path() so as far as I'm concerned migration is really straightforward and it's not time-consuming, you can use a short script to update all calls, e.g. [2], and you have 4 more years to do this.

Best,
Mariusz

Collin Anderson

unread,
May 5, 2020, 4:05:52 PM5/5/20
to Django developers (Contributions to Django itself)
> I don't think that we can revert [1] without a technical board approval 

Needing technical board approval to keep url() seems fair to me.

I think most of the 2522559 changes are ok. I'd be fine if we only made these changes:



Re migration, we also need to change the imports from "django.conf.urls" to "django.urls". I think this is the sort of thing that changes an effortless django upgrade into an annoying django upgrade. Is it really worth it to force people to do this? Should Django be developer friendly?

> you have 4 more years to do this
If it were 10 years from the proposal being accepted (2017 to 2027), I think that would be fine for removal then. It allows for a more natural upgrade as path() becomes more and more common. I don't see keeping url() around as slowing down Django's ability to evolve over time. It makes it easier for people to upgrade, which means more projects will use newer versions of django, which is a huge benefit to Django's ability to evolve.

James Bennett

unread,
May 5, 2020, 4:39:35 PM5/5/20
to django-d...@googlegroups.com
On Tue, May 5, 2020 at 1:05 PM Collin Anderson <cmawe...@gmail.com> wrote:If it were 10 years from the proposal being accepted (2017 to 2027), I think that would be fine for removal then. It allows for a more natural upgrade as path() becomes more and more common. I don't see keeping url() around as slowing down Django's ability to evolve over time. It makes it easier for people to upgrade, which means more projects will use newer versions of django, which is a huge benefit to Django's ability to evolve.

I just published a kind of rant-y thing about the Python 2/3 transition, so that's at the forefront of my mind. And honestly I think one lesson learned there applies here too: once you get into a timeline of N years, for sufficiently large N, arguments that "N years is not enough time to port, but N+K years would be" simply don't hold up.

I understand as well as anyone that it takes work to keep up with evolving platforms, and that it can feel unrewarding to do that work -- url() already exists and works, why should I have to change to calling it re_path()? -- but I also understand that if seven years wasn't enough time to get around to doing this, ten years also wouldn't be enough. If we postpone this to 2027 (and if Django and all of us are still around), then in 2025 or so when the deprecation warning starts being reintroduced we'll be asked for yet another extension, and every argument being made in favor of extension in this thread will be as applicable on that day as it is today.

Post-2.0, Django is a lot more predictable than it used to be in terms of API stability and compatibility. We now make stronger promises that if you run on a Django LTS and don't have deprecation warnings, you'll be able to run on the next LTS too (and then if you fix deprecation warnings again, you're set for the LTS after that). That's important both for users of Django and for the project itself: users of Django can relax a bit and enjoy a multi-year support cycle before they have to worry about upgrading, and the project can continue to evolve at a reasonable pace. But it only works if we actually stick to it: if we make exceptions and start doing longer and longer and longer deprecation cycles, the deprecation policy won't be taken seriously.

There's also no reason why url() in particular should be given special treatment that other deprecated features or APIs don't get. Some other old-time bits went far more quickly: render_to_response(), for example, got the standard deprecation cycle, and was removed for good in 3.0. The old django.core.urlresolvers module went away in 2.0. We've also long since gotten rid of the patterns() helper in favor of just defining URLs as a standard Python list. All of those were "useless code churn" -- the previous functions/modules worked just fine, after all. But they're all gone, and if you run on a supported Django version you've either dealt with those changes or (in the case of render_to_response()) will deal with them sometime in the near future.

So again, I don't think we should make an exception here. Doing an ultra-ultra-extended deprecation cycle on url() beyond the current merely ultra-extended one would be a bad precedent for Django's future evolution, and I don't see any argument for it being a unique or painful enough change to justify such handling.

Shai Berger

unread,
May 5, 2020, 5:05:14 PM5/5/20
to django-d...@googlegroups.com
I generally sympathize with Collin's position here, but I don't think
deprecation-without-intention-to-remove is a viable option. I think this
discussion is analogous to the Python discussion about the removal of
the ABCs from collections -- they were moved to collections.abc
in 3.3, but a shim was kept; it was slated to be dropped in 3.9 (up to
3.8 there was reason to keep the shim for compatibility with 2.7), but
the intention to execute was met with protests a lot like Collin's. The
deprecation warnings have been loud since 3.7, but the uproar, AFAICT,
only came with the code change in master towards 3.9.

The decision there was to delay the removal to 3.10.

On Tue, 5 May 2020 13:05:52 -0700 (PDT)
Collin Anderson <cmawe...@gmail.com> wrote:

> If it were 10 years from the proposal being accepted (2017 to 2027),
> I think that would be fine for removal then.

Why? Why is 10 years ok where 7 are not? James' points on this are spot
on.

Be that as it may, I can see sense in the request for a longer
warned-deprecation period, which the current path does not offer. I
would be ok with introducing now the RemovedInDjango41 or even
RemovedInDjango50 warning, and waiting a couple more releases (for
comparison, Python usually deprecates and removes in two versions, not
three like Django).

My 2 cents,
Shai.

Tom Carrick

unread,
May 5, 2020, 5:16:09 PM5/5/20
to Django developers (Contributions to Django itself)
I'm in favour. Yes, it's some extra effort, and we have here some 30 or 40-odd projects that have either been migrated to this or will need to be in the future. But if you're hopping between LTS releases, that's another 4 years, which seems a good chunk of time for me, especially if you just move to re_path(), which is pretty trivial, enough to be scripted. And I think if you upgrade at every release then you expect a bit more work to do in that case.

I don't see a compelling enough reason to hold on to dead / undocumented code for close to a decade.

Cheers,
Tom

Adam Johnson

unread,
May 5, 2020, 5:17:36 PM5/5/20
to django-d...@googlegroups.com
+1 for deprecating as per usual, as per all the reasons here.

I'll also reply to Karen's comment:

I'd be much happier with fewer tedious upgrade tasks and the ability to use client's money for new features rather than "keeping up", sigh.

Since becoming a consultant just over a year ago, I've audited a number of projects. I think in every one that started pre-2.0, I found bugs in regex URL's, from missing $ signs that allow the URL to match any suffix, match-nothing patterns, or plain wrongness. So there can be good reason to move to path(). Of course, that's why it was added, because it's simpler and can prevent bugs.

--
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-develop...@googlegroups.com.


--
Adam

James Bennett

unread,
May 5, 2020, 5:18:34 PM5/5/20
to django-d...@googlegroups.com
On Tue, May 5, 2020 at 2:04 PM Shai Berger <sh...@platonix.com> wrote:
> Why? Why is 10 years ok where 7 are not? James' points on this are spot
> on.
>
> Be that as it may, I can see sense in the request for a longer
> warned-deprecation period, which the current path does not offer. I
> would be ok with introducing now the RemovedInDjango41 or even
> RemovedInDjango50 warning, and waiting a couple more releases (for
> comparison, Python usually deprecates and removes in two versions, not
> three like Django).

Not to be contrarian, but I can come right back here with "why is
removal in 5.0 OK but removal in 4.0 isn't".

Under the current removed-in-4.0 plan, people will get *six* Django
feature releases from the time re_path was introduced to the time
url() goes away. Any argument for extending it to nine is also an
argument for extending it to twelve, fifteen, eighteen, and so on. At
some point we have to decide whether we can remove things or not. I
think we can and should, and I still don't see why url() needs this
kind of special treatment when all the other deprecations we do every
LTS-to-LTS cycle don't.

Collin Anderson

unread,
May 5, 2020, 5:24:08 PM5/5/20
to Django developers (Contributions to Django itself)
> I also understand that if seven years wasn't enough time to get around to doing this, ten years also wouldn't be enough. If we postpone this to 2027 (and if Django and all of us are still around), then in 2025 or so when the deprecation warning starts being reintroduced we'll be asked for yet another extension, and every argument being made in favor of extension in this thread will be as applicable on that day as it is today.

Ok fine. No 10 year end date. Please keep it forever/indefinitely.

I feel like Django keeps failing to deliver on its API stability promise. https://docs.djangoproject.com/en/3.0/misc/api-stability/

> All the public APIs (everything in this documentation) will not be moved or renamed without providing backwards-compatible aliases.

> If new features are added to these APIs – which is quite possible – they will not break or change the meaning of existing methods. In other words, “stable” does not (necessarily) mean “complete.”

> If, for some reason, an API declared stable must be removed or replaced, it will be declared deprecated but will remain in the API for at least two feature releases. Warnings will be issued when the deprecated method is called.

I don't see a good reason as to why url() "Must be removed or replaced".

> There's also no reason why url() in particular should be given special treatment that other deprecated features or APIs don't get. Some other old-time bits went far more quickly: render_to_response(), for example, got the standard deprecation cycle, and was removed for good in 3.0. The old django.core.urlresolvers module went away in 2.0. We've also long since gotten rid of the patterns() helper in favor of just defining URLs as a standard Python list. All of those were "useless code churn" -- the previous functions/modules worked just fine, after all. But they're all gone, and if you run on a supported Django version you've either dealt with those changes or (in the case of render_to_response()) will deal with them sometime in the near future.
> So again, I don't think we should make an exception here. Doing an ultra-ultra-extended deprecation cycle on url() beyond the current merely ultra-extended one would be a bad precedent for Django's future evolution, and I don't see any argument for it being a unique or painful enough change to justify such handling.

If exception/special treadment is an issue, then I'd suggest making this an official policy change going forward. I would be much happier if all of the examples you gave were still around with warnings. All of those upgrades were annoying. I think an ultra-ultra-extended deprecation cycle would be a good precedent. I think it makes Django more attractive as a potential platform for people to build their website on. I don't see it getting in the way of future evolution. Could you say more?

> I think this discussion is analogous to the Python discussion about the removal of the ABCs from collections -- they were moved to collections.abc in 3.3, but a shim was kept; it was slated to be dropped in 3.9 (up to 3.8 there was reason to keep the shim for compatibility with 2.7), but the intention to execute was met with protests a lot like Collin's. The deprecation warnings have been loud since 3.7, but the uproar, AFAICT, only came with the code change in master towards 3.9.

Right, yeah I'm trying to catch this as soon as the warning is introduced, rather then when url() is actually removed. I feel like collections.abc is a much rarer thing, however, pretty much every Django project that started pre 2.0 uses url().

James Bennett

unread,
May 5, 2020, 5:43:13 PM5/5/20
to django-d...@googlegroups.com
On Tue, May 5, 2020 at 2:24 PM Collin Anderson <cmawe...@gmail.com> wrote:
> If exception/special treadment is an issue, then I'd suggest making this an official policy change going forward. I would be much happier if all of the examples you gave were still around with warnings. All of those upgrades were annoying. I think an ultra-ultra-extended deprecation cycle would be a good precedent. I think it makes Django more attractive as a potential platform for people to build their website on. I don't see it getting in the way of future evolution. Could you say more?

If you'd like Django to commit to never removing anything, and instead
to preserve every piece of documented API forever, I'm sure the DSF
will be happy to accept the generous monetary donation you no doubt
intend to make in order to assist with that task, which I assume
you'll be willing to provide on an ongoing basis for... well, forever.
An initial contribution of a few million would help to get this
rolling, and we could set up recurring billing for the future
payments.

And I'm not joking about that. Every piece of deprecated code is a
maintenance burden; it requires keeping full regression tests around
and responding to bug reports and considering the possible interaction
of every new feature that ever gets introduced. All of which comes at
a cost of time and effort and -- if it's done by the Django Fellows,
which a lot of that work is -- a cost of literal cash money out of the
DSF's pocket.

Or we could allow Django to continue shedding deprecated APIs on a
predictable and documented cycle. I really do understand that it's
annoying to put in the effort to keep up to date. I lived through
magic-removal. I've done multi-version upgrades of massive codebases
basically by myself in the past. I remember them vividly, and I know
they're not fun. And there are platforms out there which have the
kinds of "nothing is ever removed" compatibility policies you're
advocating for. But Django isn't one of them, and I don't think it
should be or, at this point in its history, can be: to work at all,
that kind of policy has to be introduced early on and has to be
allowed to influence a lot of fundamental design decisions that, in
Django's case, were already made many years ago. If we introduce such
a policy now, the very first thing i'll do is go file a DEP asking for
the old "magic" ORM to be put back, and manipulators along with it.

Anyway. As Adam mentioned, there's a good reason to put the DEP 201
URL routing in front of people's eyes in a way they'll actually
notice. Our only truly reliable tool for doing that is deprecation
backed up by the knowledge that when we deprecate something, it will
end up removed. DEP 201 set out a deprecation schedule for url(); in
hindsight I wish it were shorter and just followed the normal post-2.0
policy of one LTS-to-LTS cycle, but at this point it's too late to
change that. I'll still argue quite strongly that the deprecation
period should not be made any longer, and I'll argue with every breath
I can devote to Django that a "deprecate but never remove" policy
should not be adopted.

Shai Berger

unread,
May 5, 2020, 6:50:55 PM5/5/20
to django-d...@googlegroups.com
On Tue, 5 May 2020 14:18:09 -0700
James Bennett <ubern...@gmail.com> wrote:

> On Tue, May 5, 2020 at 2:04 PM Shai Berger <sh...@platonix.com> wrote:
> > Why? Why is 10 years ok where 7 are not? James' points on this are
> > spot on.
> >
> > Be that as it may, I can see sense in the request for a longer
> > warned-deprecation period, which the current path does not offer. I
> > would be ok with introducing now the RemovedInDjango41 or even
> > RemovedInDjango50 warning, and waiting a couple more releases (for
> > comparison, Python usually deprecates and removes in two versions,
> > not three like Django).
>
> Not to be contrarian, but I can come right back here with "why is
> removal in 5.0 OK but removal in 4.0 isn't".
>

First, to clarify my position: I think removal in 4.0 is fine. I also
think removal later is fine, as long as we don't allow it to be delayed
forever.

> Under the current removed-in-4.0 plan, people will get *six* Django
> feature releases from the time re_path was introduced to the time
> url() goes away. Any argument for extending it to nine is also an
> argument for extending it to twelve, fifteen, eighteen, and so on.

The thing I see sense in extending is not the number of releases since
re_path was introduced, but the number of releases where the use of
url() generates warnings (the number of releases since re_path's
introduction will grow too, of course, but that I consider a tolerable
side-effect, no more).

The reason for this is that people are still writing new code which
uses url() -- because they get very strong hints to do so from existing
code, and virtually no hints to avoid doing so.

My argument is, basically, that because the deprecation so far was in
documentation only, the delay in introducing it was partly "wasted",
and because of that, the argument that justified not deprecating url()
at the moment that re_path() was introduced, still (partly) holds.

But I won't cry too many tears if this position is rejected.

My 2 cents,
Shai.

Kye Russell

unread,
May 5, 2020, 7:20:22 PM5/5/20
to django-d...@googlegroups.com
Excuse the frankness of my reply, but I really don’t see the point in any of this.

Perhaps I am not working at a scale where this becomes a legitimate issue. However I have upgraded more Django projects than I could possibly care to count, usually between LTS versions. Almost all of these upgrades have occurred in an agency / contractor setting where every hour counts…so I am extremely sensitive to pointless API churn without benefit to the user. Django changes like the one being discussed (which is essentially a name change) have never been an area of concern when compared with actual changes to the mechanics of Django, and I am not saying that those changes are not warranted.

I don’t believe that url() is enough of a special case that this proposal wouldn’t introduce a slippery slope scenario that’d result in a lot of deprecation shim cruft in Django. The mental overhead of dealing with a codebase filled with deprecation shims is taxing, and not something that I’d wish on volunteer open source developers.

I am extremely thankful for Django’s deprecation process and its relatively long LTS periods. My experience has been that the current deprecation process is sufficient, and my feeling from my perspective as a Django ‘user’ is that it is sufficient in this case.

Django should not be built with the premise that project code should never need to be updated. Practical (volunteer time) reasons aside, these sorts of policy decisions can leave a framework in the dust as it hinders evolution. Moving my projects from Django to something else because of an inevitable deterioration in Django’s comparative value proposition will take up way more of my time than replacing url() with re_path(), or even path()…

I am sure that there are more 'enterprise-focused' web frameworks that offer the sort of support you are after. Perhaps something written in Java with a EULA? ;-).
--
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-develop...@googlegroups.com.

אורי

unread,
May 6, 2020, 2:34:11 AM5/6/20
to Django developers (Contributions to Django itself)
Hi,

Since url() is deprecated I think it should be removed. Although I'm not sure why it was deprecated and renamed to re_path(). It took me about 10 minutes to replace the calls to "url(regex=" with "re_path(route=" (I usually prefer to call all functions by parameter name) and replace the imports to django.urls (instead of django.conf.urls). I think no harm will be done when deprecating url(). Users can either replace url() with re_path(), or if they want they can declare they own function, like is declared in Django:

def url(regex, view, kwargs=None, name=None):
    return re_path(regex, view, kwargs, name)
And then import it, so they can keep using url() if they want to. So to conclude, I'm not sure what's the reason why url() was deprecated and renamed to re_path(), but since it has been done I think it should be removed in Django 4.0.

Uri.
אורי


--
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-develop...@googlegroups.com.

Carlton Gibson

unread,
May 6, 2020, 3:06:18 AM5/6/20
to Django developers (Contributions to Django itself)
Hi Uri. 


On 6 May 2020, at 08:32, ⁨אורי⁩ <⁨u...@speedy.net⁩> wrote:

Although I'm not sure why it was deprecated and renamed to re_path().

It was part of the effort to simplify the URL routing, as part of Django 2.0


Here’s the DEP that led to that: 


Kind Regards,

Carlton

אורי

unread,
May 6, 2020, 3:25:22 AM5/6/20
to Django developers (Contributions to Django itself)
Thank you, Carlton.


--
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-develop...@googlegroups.com.

Steven Mapes

unread,
May 6, 2020, 4:01:51 AM5/6/20
to Django developers (Contributions to Django itself)
This is the big thing for me which seems to be have been forgotten.

If you need to quickly upgrade a Django project from using url to re_path the fastest way with the least amount of code changes is to simply alias the import in your urls.py files I.E ```from django.urls import re_path as url``` then you won't have to update every individual entry. so I don't see this as a big deal and am in favour of completely removing it and continue to encourage people to not question why they are using re_path and not path anyway which is more secure and fits more common url usage.

Sure if you are going from 1.x up then you have to replace  more but you'll be making much larger changes anyway.

Alasdair Nicol

unread,
May 6, 2020, 5:06:29 AM5/6/20
to Django developers (Contributions to Django itself)
Hi,


On Tuesday, 5 May 2020 21:39:35 UTC+1, James Bennett wrote:

There's also no reason why url() in particular should be given special treatment that other deprecated features or APIs don't get. Some other old-time bits went far more quickly: render_to_response(), for example, got the standard deprecation cycle, and was removed for good in 3.0. The old django.core.urlresolvers module went away in 2.0. We've also long since gotten rid of the patterns() helper in favor of just defining URLs as a standard Python list. All of those were "useless code churn" -- the previous functions/modules worked just fine, after all. But they're all gone, and if you run on a supported Django version you've either dealt with those changes or (in the case of render_to_response()) will deal with them sometime in the near future.


render_to_response was superseded by render in 1.3, but it wasn't removed until Django 3.0. The discussion on deprecating it is here [1].

In retrospect I think we should have removed it sooner, because I saw many beginners getting CSRF errors when they used render_to_response without context_instance=RequestContext(request). 

I'm in favour of removing url() in 4.0. I think it's less likely to catch out users than render_to_response, but I do see beginners doing things like url('<int:pk>', ...). If we remove url() then some of that will be avoided. Hopefully we won't see too many occurrences of path(r'(?P<pk>\d+)', ...)' instead.

Cheers,
Alasdair

Aymeric Augustin

unread,
May 9, 2020, 8:33:28 AM5/9/20
to django-d...@googlegroups.com
Hello,

When proposing deprecations that require numerous but simple code changes, providing an automated upgrade path could reduce frustrations about "useless churn".

Unfortunately, I don't know a great way to do that on Python code. Here are the options I'm aware of:

- Writing 2to3 fixers is painful, in my experience. Also, I don't think that 2to3 will survive the deprecation of lib2to3; removal is scheduled for Python 3.12.
Bowler seems designed to make it less painful, but is also written on top of lib2to3, so not a long term solution.
codemod gives up fully automated refactoring (which is at odds with Python's dynamic nature) and attempts "computer-aided refactoring".
- Most likely IDEs like PyCharm can rename an import throughout a project.

If I had to do something in this area, I'd try codemod, probably.

Of course, it will still be boring to perform the same change across N projects for no direct project-level upside, but at least it may require less time and less focus.

This is relevant for the thread about renaming request.GET/POST/etc. If we proceed with that change, we're bound to have the exact same discussion about removing the original names.

Best regards,

-- 
Aymeric.



--
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-develop...@googlegroups.com.

Adam Johnson

unread,
May 9, 2020, 12:13:51 PM5/9/20
to django-d...@googlegroups.com
Automated upgrade tooling would be great. Developers end up building their own anyway.

One more tool we could copy is pyupgrade ( https://pypi.org/project/pyupgrade/ ). It's based upon an extension to 'tokenize' by the author (Anthony Sottile) that allows roundtripping (which I guess would be useful being merged to the stdlib). But it also looks possibly painful to work with.

I've tried Bowler and it has a nice interface, allowing git-add-patch presentation through its idiff() command. But it doesn't have many examples in its documentation, which made me give up. It's also based on lib2to3, through a separated copy called fissix.

codemod's README lists Python 2 support only :(

regexes for find/replace, maybe with a sed command, would be the lowest common denominator. Combined with "git add --patch", then "git checkout ." that's basically what codemod does (afaiu).



--
Adam

Bruno Alla

unread,
May 10, 2020, 9:12:05 AM5/10/20
to Django developers (Contributions to Django itself)
I've started working on a tool provides a set of codemodders for Django:


It's based on Instagram's libCST (work with Concrete Syntax Tree). This is very much a work in progress, but I think it could help with these kind of deprecations that require changing a lot of files.

I'm not really satisfied by the API of the CLI, I would prefer to get something like pyupgrade, where you specify your min & max Django version, but I guess it's better than nothing.

It's very much a work in progress and feedback is welcome!

On Saturday, 9 May 2020 17:13:51 UTC+1, Adam Johnson wrote:
Automated upgrade tooling would be great. Developers end up building their own anyway.

One more tool we could copy is pyupgrade ( https://pypi.org/project/pyupgrade/ ). It's based upon an extension to 'tokenize' by the author (Anthony Sottile) that allows roundtripping (which I guess would be useful being merged to the stdlib). But it also looks possibly painful to work with.

I've tried Bowler and it has a nice interface, allowing git-add-patch presentation through its idiff() command. But it doesn't have many examples in its documentation, which made me give up. It's also based on lib2to3, through a separated copy called fissix.

codemod's README lists Python 2 support only :(

regexes for find/replace, maybe with a sed command, would be the lowest common denominator. Combined with "git add --patch", then "git checkout ." that's basically what codemod does (afaiu).


-- 
Aymeric.



To unsubscribe from this group and stop receiving emails from it, send an email to django-d...@googlegroups.com.

--
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-d...@googlegroups.com.


--
Adam

Tom Forbes

unread,
May 10, 2020, 9:47:11 AM5/10/20
to django-d...@googlegroups.com
An idea for a Django equivalent to “rails generate” has been floating around my mind for quite a while. Automated codemods are not only useful for fixing deprecations but also many common, repetitive tasks that might involve modifying multiple files or boilerplate (creating a simple model, adding a route, etc).

libCST looks perfect for this, thanks for sharing.

Tom

On 10 May 2020, at 14:12, Bruno Alla <alla....@gmail.com> wrote:


To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/b1a25373-9102-4b1c-a0ad-78eedf335aa5%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages