Deprecating rarely used str methods
The str class have some very rarely used methods. When was the last time you used swapcase() (not counting the time of apprenticeship)? These methods take place in a source code, documentation and a memory of developers. Due to the large number of methods, some of the really necessary methods can be neglected. I propose to deprecate rarely used methods (especially that for most of them there is another, more obvious way) and remove them in 4.0. s.ljust(width) == '{:<{}}'.format(s, width) == '%-*s' % (width, s) s.ljust(width, fillchar) == '{:{}<{}}'.format(s, fillchar, width) s.rjust(width) == '{:>{}}'.format(s, width) == '%*s' % (width, s) s.rjust(width, fillchar) == '{:{}>{}}'.format(s, fillchar, width) s.center(width) == '{:^{}}'.format(s, width) s.center(width, fillchar) == '{:{}^{}}'.format(s, fillchar, width) str(n).zfill(width) == '{:0={}}'.format(n, width) == '%0*.f' % (width,n) str.swapcase() is just not needed. str.expandtabs([tabsize]) is rarely used and can be moved to the textwrap module.
On 08/08/2013 19:32, Serhiy Storchaka wrote:
The str class have some very rarely used methods. When was the last time you used swapcase() (not counting the time of apprenticeship)? These methods take place in a source code, documentation and a memory of developers. Due to the large number of methods, some of the really necessary methods can be neglected. I propose to deprecate rarely used methods (especially that for most of them there is another, more obvious way) and remove them in 4.0.
s.ljust(width) == '{:<{}}'.format(s, width) == '%-*s' % (width, s) s.ljust(width, fillchar) == '{:{}<{}}'.format(s, fillchar, width) s.rjust(width) == '{:>{}}'.format(s, width) == '%*s' % (width, s) s.rjust(width, fillchar) == '{:{}>{}}'.format(s, fillchar, width) s.center(width) == '{:^{}}'.format(s, width) s.center(width, fillchar) == '{:{}^{}}'.format(s, fillchar, width)
You could apply the same kind of reasoning that's used with regex: why use .format when .ljust, etc, is shorter and faster?
str(n).zfill(width) == '{:0={}}'.format(n, width) == '%0*.f' % (width,n)
str.swapcase() is just not needed.
I've never used .swapcase, and I doubt I ever will.
str.expandtabs([tabsize]) is rarely used and can be moved to the textwrap module.
I use it to ensure that indentation is always 4 spaces and never tabs in the regex release in case I've missed a setting in an editor somewhere, so it _is_ an important method! :-)
On 8 August 2013 19:58, MRAB
On 08/08/2013 19:32, Serhiy Storchaka wrote:
The str class have some very rarely used methods. When was the last time you used swapcase() (not counting the time of apprenticeship)? These methods take place in a source code, documentation and a memory of developers. Due to the large number of methods, some of the really necessary methods can be neglected. I propose to deprecate rarely used methods (especially that for most of them there is another, more obvious way) and remove them in 4.0.
Planning all the way to 4.0?
s.ljust(width) == '{:<{}}'.format(s, width) == '%-*s' % (width, s) s.ljust(width, fillchar) == '{:{}<{}}'.format(s, fillchar, width) s.rjust(width) == '{:>{}}'.format(s, width) == '%*s' % (width, s) s.rjust(width, fillchar) == '{:{}>{}}'.format(s, fillchar, width) s.center(width) == '{:^{}}'.format(s, width) s.center(width, fillchar) == '{:{}^{}}'.format(s, fillchar, width)
You could apply the same kind of reasoning that's used with regex: why use .format when .ljust, etc, is shorter and faster?
Because .format (or modulo) is the standard way to format? Honestly when first scanning this post I had no idea what "ljust" was until I saw that equivalents were given.
str(n).zfill(width) == '{:0={}}'.format(n, width) == '%0*.f' % (width,n)
str.swapcase() is just not needed.
I've never used .swapcase, and I doubt I ever will.
Same
str.expandtabs([tabsize]) is rarely used and can be moved to the textwrap module.
I use it to ensure that indentation is always 4 spaces and never tabs in the regex release in case I've missed a setting in an editor somewhere, so it _is_ an important method! :-)
Would you be fine with it in textwrap? I don't use this (but I would use a .reindent method...).
08.08.13 21:58, MRAB написав(ла):
On 08/08/2013 19:32, Serhiy Storchaka wrote:
s.ljust(width) == '{:<{}}'.format(s, width) == '%-*s' % (width, s) s.ljust(width, fillchar) == '{:{}<{}}'.format(s, fillchar, width) s.rjust(width) == '{:>{}}'.format(s, width) == '%*s' % (width, s) s.rjust(width, fillchar) == '{:{}>{}}'.format(s, fillchar, width) s.center(width) == '{:^{}}'.format(s, width) s.center(width, fillchar) == '{:{}^{}}'.format(s, fillchar, width)
You could apply the same kind of reasoning that's used with regex: why use .format when .ljust, etc, is shorter and faster?
Because in common case the result of ljust/rjust is concatenated with other strings for output. Instead of print('|' + name.ljust(20) + '|' + str(value).rjust(8) + '|') you can write just print('|%-20s|%8s|' % (name, value)) or print('|{:<20}|{:>8}|'.format(name, value)) which are shorter and cleaner.
str.expandtabs([tabsize]) is rarely used and can be moved to the textwrap module.
I use it to ensure that indentation is always 4 spaces and never tabs in the regex release in case I've missed a setting in an editor somewhere, so it _is_ an important method! :-)
Yes, I do not propose totally remove it. But this method is not used in most applications in contrary to such popular methods as split() or strip(). It looks as one of multiline formatting methods from the textwrap module.
On Aug 8, 2013 12:42 PM, "Serhiy Storchaka"
you can write just
print('|%-20s|%8s|' % (name, value))
or
print('|{:<20}|{:>8}|'.format(name, value))
which are shorter and cleaner.
In what universe are those cleaner? I have to think much harder to figure out what they mean and a typo may completely mangle it w/o failing. Deprecation should be used for removing things that cause problems not for "cleaning up" things that are working fine. If it ain't broke don't fix it. --- Bruce
Bruce Leban wrote:
print('|%-20s|%8s|' % (name, value)) print('|{:<20}|{:>8}|'.format(name, value))
which are shorter and cleaner.
[than .ljust, .rjust, .center, .zfill...]
In what universe are those cleaner?
I found the .format mini language confusing, but the '%'-style it's definitely clearer to me. -- By ZeD
On Thu, Aug 8, 2013 at 2:58 PM, MRAB
On 08/08/2013 19:32, Serhiy Storchaka wrote:
..
str.swapcase() is just not needed.
I've never used .swapcase, and I doubt I ever will.
This group need an FAQ. Any volunteers to create a "Frequently Rejected Ideas" list? http://mail.python.org/pipermail/python-dev/2011-September/113488.html
09.08.13 02:17, Alexander Belopolsky написав(ла):
This group need an FAQ. Any volunteers to create a "Frequently Rejected Ideas" list?
This is a great idea. Should not it be the first entity in this FAQ?
http://mail.python.org/pipermail/python-dev/2011-September/113488.html
Thank you for interesting link.
I'll take the bait and make a list. It would be helpful if those who follow this list (and perhaps other discussions, e.g. python-dev) could point out (just by the title) some often discussed and rejected proposals. I'll go over the archives later, but a list of things to look for would help. - Tal Einat On Fri, Aug 9, 2013 at 2:17 AM, Alexander Belopolsky < alexander.belopolsky@gmail.com> wrote:
On Thu, Aug 8, 2013 at 2:58 PM, MRAB
wrote: On 08/08/2013 19:32, Serhiy Storchaka wrote:
..
str.swapcase() is just not needed.
I've never used .swapcase, and I doubt I ever will.
This group need an FAQ. Any volunteers to create a "Frequently Rejected Ideas" list?
http://mail.python.org/pipermail/python-dev/2011-September/113488.html
_______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
On 08.08.2013 20:32, Serhiy Storchaka wrote:
The str class have some very rarely used methods. When was the last time you used swapcase() (not counting the time of apprenticeship)? These methods take place in a source code, documentation and a memory of developers. Due to the large number of methods, some of the really necessary methods can be neglected. I propose to deprecate rarely used methods (especially that for most of them there is another, more obvious way) and remove them in 4.0.
s.ljust(width) == '{:<{}}'.format(s, width) == '%-*s' % (width, s) s.ljust(width, fillchar) == '{:{}<{}}'.format(s, fillchar, width) s.rjust(width) == '{:>{}}'.format(s, width) == '%*s' % (width, s) s.rjust(width, fillchar) == '{:{}>{}}'.format(s, fillchar, width) s.center(width) == '{:^{}}'.format(s, width) s.center(width, fillchar) == '{:{}^{}}'.format(s, fillchar, width)
str(n).zfill(width) == '{:0={}}'.format(n, width) == '%0*.f' % (width,n)
I don't think any of the .format() alternatives you listed is anywhere near as obvious as the methods :-)
str.swapcase() is just not needed.
If you have you ever typed on a keyboard with shift lock enabled, you'd know what it's needed for ;-) Seriously, that one could get deprecated, provided that a helper function with the same functionality is provided elsewhere.
str.expandtabs([tabsize]) is rarely used and can be moved to the textwrap module.
TABs still exist in lots of files, so I'd rather not get rid of this method. -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, Aug 08 2013)
Python Projects, Consulting and Support ... http://www.egenix.com/ mxODBC.Zope/Plone.Database.Adapter ... http://zope.egenix.com/ mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
::::: Try our mxODBC.Connect Python Database Interface for free ! :::::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 http://www.egenix.com/company/contact/
On 08.08.2013 21:16, M.-A. Lemburg wrote:
On 08.08.2013 20:32, Serhiy Storchaka wrote:
str.expandtabs([tabsize]) is rarely used and can be moved to the textwrap module.
TABs still exist in lots of files, so I'd rather not get rid of this method.
BTW: If more and more text formatting functions get moved to textwrap then the module should be renamed to textformat. -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, Aug 08 2013)
Python Projects, Consulting and Support ... http://www.egenix.com/ mxODBC.Zope/Plone.Database.Adapter ... http://zope.egenix.com/ mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
::::: Try our mxODBC.Connect Python Database Interface for free ! :::::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 http://www.egenix.com/company/contact/
On 08/08/2013 02:19 PM, M.-A. Lemburg wrote:
On 08.08.2013 21:16, M.-A. Lemburg wrote:
On 08.08.2013 20:32, Serhiy Storchaka wrote:
str.expandtabs([tabsize]) is rarely used and can be moved to the textwrap module.
TABs still exist in lots of files, so I'd rather not get rid of this method.
BTW: If more and more text formatting functions get moved to textwrap then the module should be renamed to textformat.
My vote is for texttools. But bike colors aside, I've often thought the textwrap module name is too specialised. A broader meaning name could allow other text processing functions and classes to be added/moved to it. Making it possible to reduce the number of top level modules in future versions. Cheers, Ron
On 08/08/2013 23:21, Greg Ewing wrote:
M.-A. Lemburg wrote:
If you have you ever typed on a keyboard with shift lock enabled,
...on a Windows or Linux PC. If you're using a Mac, no algorithm will rescue you from that blunder. :-)
If you're using a Mac, 30% of the keystrokes will disappear off to Apple. :-)
On 09Aug2013 10:21, Greg Ewing
On 10 August 2013 03:31, Cameron Simpson
On 09Aug2013 10:21, Greg Ewing
wrote: | M.-A. Lemburg wrote: | >If you have you ever typed on a keyboard with shift lock enabled, | | ...on a Windows or Linux PC. If you're using a Mac, | no algorithm will rescue you from that blunder. :-) One of the first things I do on a new machine, Linux or Mac, is to disable the capslock key. It is a simple keyboard pref on the Mac and a kept-in-a-file xmodmap incantation on Linux (assuming X11 desktop).
Interesting. That's a cleverer solution than mine which is to just remove the physical key (with a screwdriver if necessary or whatever else comes to hand). Oscar
On 10 August 2013 03:31, Cameron Simpson
On 09Aug2013 10:21, Greg Ewing
wrote: | M.-A. Lemburg wrote: | >If you have you ever typed on a keyboard with shift lock enabled, | | ...on a Windows or Linux PC. If you're using a Mac, | no algorithm will rescue you from that blunder. :-) One of the first things I do on a new machine, Linux or Mac, is to disable the capslock key. It is a simple keyboard pref on the Mac and a kept-in-a-file xmodmap incantation on Linux (assuming X11 desktop).
Rather, map it to a new modifier. Mod3 is almost always free.
On 10Aug2013 06:37, Joshua Landau
On 10 August 2013 08:43, Cameron Simpson
On 10Aug2013 06:37, Joshua Landau
wrote: | On 10 August 2013 03:31, Cameron Simpson wrote: | > One of the first things I do on a new machine, Linux or Mac, is to | > disable the capslock key. It is a simple keyboard pref on the Mac | > and a kept-in-a-file xmodmap incantation on Linux (assuming X11 | > desktop). | | Rather, map it to a new modifier. Mod3 is almost always free. I think the relevant bit for me is:
add control = Caps_Lock
i.e. make CapsLock another Control key under X11.
Then you have three (3!!) control keys, two of which are spaced apart by a single button. I find I'm quick to run out of shortcuts; an extra modifier helps keep things flatter (no Ctrl-Alt-Mod-Shift-PgDn ;p).
08.08.13 22:16, M.-A. Lemburg написав(ла):
I don't think any of the .format() alternatives you listed is anywhere near as obvious as the methods :-)
I confess that I be forced to look into documentation to write these examples. ;-) It's because I don't use new style formatting very often. However C-style alternatives looks enough obvious to me.
If you have you ever typed on a keyboard with shift lock enabled, you'd know what it's needed for ;-)
Are .swapcase() swaps ";" and ":"? Or "q" and "й" (on my computers I use CapsLock to switch keyboard layout between English and Ukrainian)? ;-)
On 09.08.2013 21:34, Serhiy Storchaka wrote:
08.08.13 22:16, M.-A. Lemburg написав(ла):
I don't think any of the .format() alternatives you listed is anywhere near as obvious as the methods :-)
I confess that I be forced to look into documentation to write these examples. ;-) It's because I don't use new style formatting very often. However C-style alternatives looks enough obvious to me.
If you have you ever typed on a keyboard with shift lock enabled, you'd know what it's needed for ;-)
Are .swapcase() swaps ";" and ":"? Or "q" and "й" (on my computers I use CapsLock to switch keyboard layout between English and Ukrainian)? ;-)
I guess it's one of those functions that someone invented as example of an involutary string function for a tutorial late in the 1980s. It then probably developed a life of its own ;-) There's even a YouTube video on it: http://www.youtube.com/watch?v=RPrqhB1dmJA (the author obviously has a Java background ;-)) -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, Aug 09 2013)
Python Projects, Consulting and Support ... http://www.egenix.com/ mxODBC.Zope/Plone.Database.Adapter ... http://zope.egenix.com/ mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
::::: Try our mxODBC.Connect Python Database Interface for free ! :::::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 http://www.egenix.com/company/contact/
On Fri, Aug 9, 2013 at 2:28 PM, M.-A. Lemburg
I guess it's one of those functions that someone invented as example of an involutary string function for a tutorial late in the 1980s. It then probably developed a life of its own ;-)
Honestly I don't recall why I ever thought I needed it. But it is there in string.py in Python 0.9.1. It almost looks like it was just too cool not to add -- the lower(), upper() an caseswap() functions share a dict mapping between lowercase <--> uppercase.
There's even a YouTube video on it:
http://www.youtube.com/watch?v=RPrqhB1dmJA
(the author obviously has a Java background ;-))
Oh, wow, that's insane. He's trained himself to type #{ and #} around each block before filling in the body of the block. :-) -- --Guido van Rossum (python.org/~guido)
On Thu, Aug 8, 2013, at 14:58, MRAB wrote:
I use [expandtabs] to ensure that indentation is always 4 spaces and never tabs in the regex release in case I've missed a setting in an editor somewhere, so it _is_ an important method! :-)
On Thu, Aug 8, 2013, at 15:16, M.-A. Lemburg wrote:
If you have you ever typed on a keyboard with shift lock enabled, you'd know what [swapcase is] needed for ;-)
What are these text editors that let you call a python function on a range/selection? I've run into both of these situations, and am quite familiar with the Vim commands for fixing them.
-1 on all the parts.
I've used Python long enough to remember being thankful that many of the
functions in the 'string' module were duplicated as str methods. It's
generally convenient to have them there.
I can't actually argue that I use str.swapcase() much (maybe ever), but all
the rest are handy and things I actually use. Yes, you can technically get
the results out of str.format(), but the format mini-language is rather
difficult and arcane and I can't really use it without the documentation
open in another window.
On Thu, Aug 8, 2013 at 11:32 AM, Serhiy Storchaka
The str class have some very rarely used methods. When was the last time you used swapcase() (not counting the time of apprenticeship)? These methods take place in a source code, documentation and a memory of developers. Due to the large number of methods, some of the really necessary methods can be neglected. I propose to deprecate rarely used methods (especially that for most of them there is another, more obvious way) and remove them in 4.0.
s.ljust(width) == '{:<{}}'.format(s, width) == '%-*s' % (width, s) s.ljust(width, fillchar) == '{:{}<{}}'.format(s, fillchar, width) s.rjust(width) == '{:>{}}'.format(s, width) == '%*s' % (width, s) s.rjust(width, fillchar) == '{:{}>{}}'.format(s, fillchar, width) s.center(width) == '{:^{}}'.format(s, width) s.center(width, fillchar) == '{:{}^{}}'.format(s, fillchar, width)
str(n).zfill(width) == '{:0={}}'.format(n, width) == '%0*.f' % (width,n)
str.swapcase() is just not needed.
str.expandtabs([tabsize]) is rarely used and can be moved to the textwrap module.
______________________________**_________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/**mailman/listinfo/python-ideashttp://mail.python.org/mailman/listinfo/python-ideas
-- Keeping medicines from the bloodstreams of the sick; food from the bellies of the hungry; books from the hands of the uneducated; technology from the underdeveloped; and putting advocates of freedom in prisons. Intellectual property is to the 21st century what the slave trade was to the 16th.
On 09/08/13 04:32, Serhiy Storchaka wrote:
The str class have some very rarely used methods. When was the last time you used swapcase() (not counting the time of apprenticeship)? These methods take place in a source code, documentation and a memory of developers. Due to the large number of methods, some of the really necessary methods can be neglected. I propose to deprecate rarely used methods (especially that for most of them there is another, more obvious way) and remove them in 4.0.
-1 It's true that, if swapcase were proposed today, it probably wouldn't be accepted. And maybe it should have been removed in Python 3. But it didn't. Deprecating working code just because (in the opinion of some people) it's not useful enough just causes code churn for no real benefit. Somebody out there is using methods ljust, rjust, center, zfill (I use those last two), yes, even swapcase -- somebody is using it, somewhere. You will break their code for very little benefit. Deprecation is only useful when there is a concrete plan to remove the feature. Python 4000 is so far in the future that it's more of a dream than an actual concrete planned release (this is why I don't refer to it as Python 4). There may not even be a Python 4000. Who knows? For the next ten, or fifteen, or fifty, years, there will be features in CPython flagged as deprecated, but still working, which means that as other implementations become Python 3 compatible they will be tempted to remove these features early. That's a bad thing, since then different implementations of Python running the same version will not be able to run the same code. The chaos and pain this will cause outweighs by far any benefit you might get from eventually removing features. When there are concrete plans for a Python 4000, that is the time to think about backwards incompatible changes. Or, following the ten-year transition period for Python 2 -> 3, maybe the BDFL will decide that Python 4000 will *not* break backwards compatibility. I was reading somebody's blog the other day talking about how he ran FORTRAN 66 code unchanged in a modern Fortran compiler and it worked perfectly. The cost of keeping swapcase etc. is tiny. They're stable code, unlikely to need much in the way of maintenance, and the pain from removing them is likely to outweigh what benefit there is.
s.ljust(width) == '{:<{}}'.format(s, width) == '%-*s' % (width, s)
Especially given that your alternatives are far less readable than a method call, and difficult to override in a subclass. -- Steven
On 09.08.2013 12:07, Richard Oudkerk wrote:
On 09/08/2013 2:45am, Steven D'Aprano wrote:
It's true that, if swapcase were proposed today, it probably wouldn't be accepted.
Or it would throw an error on a string of more than one character. I think it is really a "character method" rather than a string method.
Just a bit of history:
s.swapcase() exists, because a while back we moved from functions
in string.py to methods on string and unicode objects in Python 2.
The swapcase() function in string.py has been there right from
Python's day 1 in VCS history:
http://hg.python.org/cpython-fullhistory/annotate/5570dbb1ce55/Lib/string.py...
author Guido van Rossum
Python Projects, Consulting and Support ... http://www.egenix.com/ mxODBC.Zope/Plone.Database.Adapter ... http://zope.egenix.com/ mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
::::: Try our mxODBC.Connect Python Database Interface for free ! :::::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 http://www.egenix.com/company/contact/
M.-A. Lemburg wrote:
Instead of deprecating this piece of history, perhaps we should start deprecating the caps lock key ;-) ... just think of what would give us: no more accidental yelling on the Internet, confused Nigerian spammers, fewer problems with password entries, just to name a few things.
And it would give us room to put the control key back where it belongs! +1 -- Greg
I'm old enough to also want the function keys on the left, "As God
intended!" (I miss how quick those WordPerfect 4.2 shortcuts were with the
F keys next to the correctly-placed Control and Alt keys).
On Fri, Aug 9, 2013 at 3:52 AM, Greg Ewing
M.-A. Lemburg wrote:
Instead of deprecating this piece of history, perhaps we should start deprecating the caps lock key ;-) ... just think of what would give us: no more accidental yelling on the Internet, confused Nigerian spammers, fewer problems with password entries, just to name a few things.
And it would give us room to put the control key back where it belongs!
+1
-- Greg
______________________________**_________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/**mailman/listinfo/python-ideashttp://mail.python.org/mailman/listinfo/python-ideas
-- Keeping medicines from the bloodstreams of the sick; food from the bellies of the hungry; books from the hands of the uneducated; technology from the underdeveloped; and putting advocates of freedom in prisons. Intellectual property is to the 21st century what the slave trade was to the 16th.
On Thu, Aug 8, 2013, at 21:45, Steven D'Aprano wrote:
Deprecation is only useful when there is a concrete plan to remove the feature. Python 4000 is so far in the future that it's more of a dream than an actual concrete planned release (this is why I don't refer to it as Python 4). There may not even be a Python 4000. Who knows?
Maybe there needs to be an official "to do list" for ideas to be re-examined when Python 4000 becomes a more concrete thing. I think a "list of warts" has been proposed and rejected recently, but I got the impression that was due to the perceived pejorative-ness of calling something that. I would add str % stuff to the list of things that should be deprecated... has anyone done any work on a converter for that, that could be included in a hypothetical 3to4?
On Fri, Aug 9, 2013 at 9:25 PM,
I would add str % stuff to the list of things that should be deprecated... has anyone done any work on a converter for that, that could be included in a hypothetical 3to4?
Why should it be deprecated, though? This keeps coming up - it's too useful to throw away. The sprintf codes are well known from other languages, and they're expressive. The only change I might support would be making it an actual function 'sprintf' rather than an operator on the str class, but that feels like bikeshedding and completely unnecessary incompatibility. ChrisA
On Aug 9, 2013, at 15:11, Chris Angelico
On Fri, Aug 9, 2013 at 9:25 PM,
wrote: I would add str % stuff to the list of things that should be deprecated... has anyone done any work on a converter for that, that could be included in a hypothetical 3to4?
Why should it be deprecated, though?
I agree that there's no point arguing this out yet again. But I don't understand why so many people seem so baffled by the opposite position. Having two very different and relatively complex mini languages for the same purpose is a burden. Not having the same format strings as every other language in the world would also be a burden. Nobody can seriously believe that the other side really doesn't understand their point when the points are this obvious.
On Sat, Aug 10, 2013 at 3:42 AM, Andrew Barnert
On Aug 9, 2013, at 15:11, Chris Angelico
wrote: On Fri, Aug 9, 2013 at 9:25 PM,
wrote: I would add str % stuff to the list of things that should be deprecated... has anyone done any work on a converter for that, that could be included in a hypothetical 3to4?
Why should it be deprecated, though?
I agree that there's no point arguing this out yet again.
But I don't understand why so many people seem so baffled by the opposite position. Having two very different and relatively complex mini languages for the same purpose is a burden. Not having the same format strings as every other language in the world would also be a burden. Nobody can seriously believe that the other side really doesn't understand their point when the points are this obvious.
Oh, I can see the other side's arguments. If str.format existed and str% didn't, there would be insufficient grounds to add it. But they both exist, and the arguments for removing a feature have to be insanely strong. Status quo wins easily. ChrisA
On 10 August 2013 04:58, Chris Angelico
On Sat, Aug 10, 2013 at 3:42 AM, Andrew Barnert
wrote: On Aug 9, 2013, at 15:11, Chris Angelico
wrote: On Fri, Aug 9, 2013 at 9:25 PM,
wrote: I would add str % stuff to the list of things that should be deprecated... has anyone done any work on a converter for that, that could be included in a hypothetical 3to4?
Why should it be deprecated, though?
I agree that there's no point arguing this out yet again.
But I don't understand why so many people seem so baffled by the opposite position. Having two very different and relatively complex mini languages for the same purpose is a burden. Not having the same format strings as every other language in the world would also be a burden. Nobody can seriously believe that the other side really doesn't understand their point when the points are this obvious.
Oh, I can see the other side's arguments. If str.format existed and str% didn't, there would be insufficient grounds to add it. But they both exist, and the arguments for removing a feature have to be insanely strong. Status quo wins easily.
But the arguments for deprecating a feature in favour of the other (so as to aid standardisation) without imminent removal plans don't have to be as strong. Anyway, I've learnt this is not an argument I can win so I'm not trying to prove anything.
On Sat, Aug 10, 2013 at 6:36 AM, Joshua Landau
On 10 August 2013 04:58, Chris Angelico
wrote: Oh, I can see the other side's arguments. If str.format existed and str% didn't, there would be insufficient grounds to add it. But they both exist, and the arguments for removing a feature have to be insanely strong. Status quo wins easily.
But the arguments for deprecating a feature in favour of the other (so as to aid standardisation) without imminent removal plans don't have to be as strong.
What does deprecation mean if you aren't planning to remove it? Why should I change my code if it's not going to break? Deprecation has to be backed by intent to remove. ChrisA
On 10 August 2013 09:09, Chris Angelico
On Sat, Aug 10, 2013 at 6:36 AM, Joshua Landau
wrote: On 10 August 2013 04:58, Chris Angelico
wrote: Oh, I can see the other side's arguments. If str.format existed and str% didn't, there would be insufficient grounds to add it. But they both exist, and the arguments for removing a feature have to be insanely strong. Status quo wins easily.
But the arguments for deprecating a feature in favour of the other (so as to aid standardisation) without imminent removal plans don't have to be as strong.
What does deprecation mean if you aren't planning to remove it? Why should I change my code if it's not going to break? Deprecation has to be backed by intent to remove.
without *imminent* removal plans Also, such a measure would primarily affect new code.
On Fri, Aug 9, 2013, at 23:58, Chris Angelico wrote:
Oh, I can see the other side's arguments. If str.format existed and str% didn't, there would be insufficient grounds to add it. But they both exist, and the arguments for removing a feature have to be insanely strong. Status quo wins easily.
What exactly was the sufficient grounds for adding str.format, and for giving it its own minilanguage instead of using the one % already uses [with extensions like being able to use both positional arguments and %(keyword)s, and maybe something like %1$s for explicit positional arguments]?
On Sun, Aug 11, 2013 at 10:14 PM,
On Fri, Aug 9, 2013, at 23:58, Chris Angelico wrote:
Oh, I can see the other side's arguments. If str.format existed and str% didn't, there would be insufficient grounds to add it. But they both exist, and the arguments for removing a feature have to be insanely strong. Status quo wins easily.
What exactly was the sufficient grounds for adding str.format, and for giving it its own minilanguage instead of using the one % already uses [with extensions like being able to use both positional arguments and %(keyword)s, and maybe something like %1$s for explicit positional arguments]?
Or %[3]s for the 3rd argument (zero-based, so "%s%[0]s" would duplicate the string). And %{...%} to repeat the inner content for every element of the argument iterable. There's a lot that can be done to extend sprintf notation, if someone wants to. But I don't know that Python wants to do that, unless str.format is to be obsoleted. Here's a few ideas that could be borrowed, if desired: http://pike.lysator.liu.se/generated/manual/modref/ex/predef_3A_3A/sprintf.h... ChrisA
On Sun, Aug 11, 2013 at 5:14 PM,
..
What exactly was the sufficient grounds for adding str.format, and for giving it its own minilanguage instead of using the one % already uses [with extensions like being able to use both positional arguments and %(keyword)s, and maybe something like %1$s for explicit positional arguments]?
On 8/11/2013 5:48 PM, Alexander Belopolsky wrote:
On Sun, Aug 11, 2013 at 5:14 PM,
mailto:random832@fastmail.us> wrote: ..
What exactly was the sufficient grounds for adding str.format, and for giving it its own minilanguage instead of using the one % already uses [with extensions like being able to use both positional arguments and %(keyword)s, and maybe something like %1$s for explicit positional arguments]?
To add to that, the special treatment of tuples and sometimes dicts lead to bugs or unexpected exceptions.
'%s' % [1,] '[1]' '%s' % (1,) '1' '%s' % [1,2,3] '[1, 2, 3]' '%s' % (1,2,3) Traceback (most recent call last): File "
", line 1, in <module> '%s' % (1,2,3) TypeError: not all arguments converted during string formatting
-- Terry Jan Reedy
On Sun, Aug 11, 2013 at 11:50 PM, Terry Reedy
To add to that, the special treatment of tuples and sometimes dicts lead to bugs or unexpected exceptions.
'%s' % [1,] '[1]' '%s' % (1,) '1' '%s' % [1,2,3] '[1, 2, 3]' '%s' % (1,2,3) Traceback (most recent call last): File "
", line 1, in <module> '%s' % (1,2,3) TypeError: not all arguments converted during string formatting
This is why I would prefer printf to be a function, rather than an operator. The operator is a coolness that has a cost. ChrisA
Le Thu, 08 Aug 2013 21:32:16 +0300,
Serhiy Storchaka
The str class have some very rarely used methods. When was the last time you used swapcase() (not counting the time of apprenticeship)? These methods take place in a source code, documentation and a memory of developers. Due to the large number of methods, some of the really necessary methods can be neglected. I propose to deprecate rarely used methods (especially that for most of them there is another, more obvious way) and remove them in 4.0.
s.ljust(width) == '{:<{}}'.format(s, width) == '%-*s' % (width, s) s.ljust(width, fillchar) == '{:{}<{}}'.format(s, fillchar, width) s.rjust(width) == '{:>{}}'.format(s, width) == '%*s' % (width, s) s.rjust(width, fillchar) == '{:{}>{}}'.format(s, fillchar, width) s.center(width) == '{:^{}}'.format(s, width) s.center(width, fillchar) == '{:{}^{}}'.format(s, fillchar, width)
-1 for deprecating those 3, they are much more readable than the format equivalent (seriously, those smiley-like format specs are horrible...).
str(n).zfill(width) == '{:0={}}'.format(n, width) == '%0*.f' % (width,n)
str.swapcase() is just not needed.
I'm ok with yanking those two.
str.expandtabs([tabsize]) is rarely used and can be moved to the textwrap module.
No opinion. Regards Antoine.
On 08/09/2013 10:10 AM, Antoine Pitrou wrote:
Le Thu, 08 Aug 2013 21:32:16 +0300, Serhiy Storchaka
a écrit : The str class have some very rarely used methods. When was the last time you used swapcase() (not counting the time of apprenticeship)? These methods take place in a source code, documentation and a memory of developers. Due to the large number of methods, some of the really necessary methods can be neglected. I propose to deprecate rarely used methods (especially that for most of them there is another, more obvious way) and remove them in 4.0.
s.ljust(width) == '{:<{}}'.format(s, width) == '%-*s' % (width, s) s.ljust(width, fillchar) == '{:{}<{}}'.format(s, fillchar, width) s.rjust(width) == '{:>{}}'.format(s, width) == '%*s' % (width, s) s.rjust(width, fillchar) == '{:{}>{}}'.format(s, fillchar, width) s.center(width) == '{:^{}}'.format(s, width) s.center(width, fillchar) == '{:{}^{}}'.format(s, fillchar, width)
-1 for deprecating those 3, they are much more readable than the format equivalent (seriously, those smiley-like format specs are horrible...).
You can write ljust/rjust like this: ljust: s+" "*(width-len(s)) rjust: " "*(width-len(s))+s Is this more readable or less? I'm 0 on this.
On Fri, 09 Aug 2013 21:43:37 +0200
Mathias Panzenböck
On 08/09/2013 10:10 AM, Antoine Pitrou wrote:
Le Thu, 08 Aug 2013 21:32:16 +0300, Serhiy Storchaka
a écrit : The str class have some very rarely used methods. When was the last time you used swapcase() (not counting the time of apprenticeship)? These methods take place in a source code, documentation and a memory of developers. Due to the large number of methods, some of the really necessary methods can be neglected. I propose to deprecate rarely used methods (especially that for most of them there is another, more obvious way) and remove them in 4.0.
s.ljust(width) == '{:<{}}'.format(s, width) == '%-*s' % (width, s) s.ljust(width, fillchar) == '{:{}<{}}'.format(s, fillchar, width) s.rjust(width) == '{:>{}}'.format(s, width) == '%*s' % (width, s) s.rjust(width, fillchar) == '{:{}>{}}'.format(s, fillchar, width) s.center(width) == '{:^{}}'.format(s, width) s.center(width, fillchar) == '{:{}^{}}'.format(s, fillchar, width)
-1 for deprecating those 3, they are much more readable than the format equivalent (seriously, those smiley-like format specs are horrible...).
You can write ljust/rjust like this: ljust: s+" "*(width-len(s)) rjust: " "*(width-len(s))+s
Is this more readable or less?
Rather less, IMHO. Regards Antoine.
On Fri, Aug 9, 2013, at 4:10, Antoine Pitrou wrote:
-1 for deprecating those 3, they are much more readable than the format equivalent (seriously, those smiley-like format specs are horrible...).
99% of the time you're not going to use them in the real world. Yes, the format string in this: s.rjust(width, fillchar) == '{:{}>{}}'.format(s, fillchar, width) is unpleasant, but you should think of it more as this: s.rjust(42,'x') == '{:x>42}'.format(s) since 90% of the time width is constant, 99% for fillchar.
On Fri, 09 Aug 2013 16:29:14 -0400 random832@fastmail.us wrote:
On Fri, Aug 9, 2013, at 4:10, Antoine Pitrou wrote:
-1 for deprecating those 3, they are much more readable than the format equivalent (seriously, those smiley-like format specs are horrible...).
99% of the time you're not going to use them in the real world.
Yes, the format string in this: s.rjust(width, fillchar) == '{:{}>{}}'.format(s, fillchar, width) is unpleasant, but you should think of it more as this: s.rjust(42,'x') == '{:x>42}'.format(s)
... which doesn't strike me as very readable either, let alone easy to remember. Regards Antoine.
On Aug 8, 2013, at 11:32, Serhiy Storchaka
str(n).zfill(width) == '{:0={}}'.format(n, width) == '%0*.f' % (width,n)
This one comes up all the time on Stack Overflow and similar places. Even when I would use format in my own code, it's a whole lot easier to explain zfill to a novice than to explain the format mini language(s) to someone who's never used anything but bare {} (or %s).
str.swapcase() is just not needed.
What about when I need to deliver the secret documents to my CIA contact? If we couldn't swap cases at the baggage carousel, that would affect national security, or at least the ability of Hollywood to write formulaic thrillers.
On Aug 11, 2013, at 20:32, Benjamin Peterson
Serhiy Storchaka
writes: str.swapcase() is just not needed.
I would quite love to get rid of this method, since it's basically useless and wrong on non-ASCII strings.
No it isn't. Most people who say that are mixing up bytes.swapcase with str.swapcase (or talking about Python 2). The bytes method obviously only handles ASCII because bytes objects don't know what encoding they're in (or even whether they're text in the first place) so nothing else would make sense. But the str method handles non-ASCII cases just as well as the rest of Python. For example, 'éåüñ'.swapcase() == 'ÉÅÜÑ'. Of course Unicode case mapping isn't perfect, because it's contextless, and because it doesn't handle language-specific tailoring, and because it has all the usual compromises (like Turkish dotless i). But I doubt you're suggesting that Python reject Unicode. Of course your other reason for rejecting it--that it's useless--I think most people agree with.
Andrew Barnert
On Aug 11, 2013, at 20:32, Benjamin Peterson
wrote: Serhiy Storchaka
writes: str.swapcase() is just not needed.
I would quite love to get rid of this method, since it's basically useless and wrong on non-ASCII strings.
No it isn't.
I realize it "handles" non-ASCII characters, but I claim there is no sensical behavior.
On Aug 11, 2013, at 23:10, Benjamin Peterson
Andrew Barnert
writes: On Aug 11, 2013, at 20:32, Benjamin Peterson
wrote: Serhiy Storchaka
writes: str.swapcase() is just not needed.
I would quite love to get rid of this method, since it's basically useless and wrong on non-ASCII strings.
No it isn't.
I realize it "handles" non-ASCII characters, but I claim there is no sensical behavior.
So you want Python to not follow Unicode in general, or just in case mapping, or just in this one function (leaving upper, lower, etc. alone)? Out of curiosity, what language do you use that has no sensible behavior? Most scripts either have sensible case rules, or just don't have cases (so the function is an obvious no-op). I know some people think Unicode chose the _wrong_ rule for their script (e.g., the Turkish i mentioned earlier--even if it is what most Turkish computer users wanted, there are purists who insist it should work properly, or that Turkish dotted i and dotless I should be separate characters from their Latin equivalents). But that's not the same as saying there _are_ no good rules for their script.
Andrew Barnert
On Aug 11, 2013, at 23:10, Benjamin Peterson
wrote: Andrew Barnert
writes: On Aug 11, 2013, at 20:32, Benjamin Peterson
Serhiy Storchaka
writes: str.swapcase() is just not needed.
I would quite love to get rid of this method, since it's basically useless and wrong on non-ASCII strings.
No it isn't.
I realize it "handles" non-ASCII characters, but I claim there is no sensical behavior.
So you want Python to not follow Unicode in general, or just in case mapping, or just in this one function (leaving upper, lower, etc. alone)?
Out of curiosity, what language do you use that has no sensible behavior? Most scripts either have sensible case rules, or just don't have cases (so the function is an obvious no-op). I know some people think Unicode chose the _wrong_ rule for their script (e.g., the Turkish i mentioned earlier--even if it is what most Turkish computer users wanted, there are purists who insist it should work
wrote: properly, or that Turkish
dotted i and dotless I should be separate characters from their Latin equivalents). But that's not the same as saying there _are_ no good rules for their script.
In the precense of things like title case, "swapping" case isn't always an operation that can make sense.
On Aug 11, 2013, at 23:54, Benjamin Peterson
Andrew Barnert
writes: On Aug 11, 2013, at 23:10, Benjamin Peterson
wrote: Andrew Barnert
writes: On Aug 11, 2013, at 20:32, Benjamin Peterson
Serhiy Storchaka
writes: str.swapcase() is just not needed.
I would quite love to get rid of this method, since it's basically useless and wrong on non-ASCII strings.
No it isn't.
I realize it "handles" non-ASCII characters, but I claim there is no sensical behavior.
So you want Python to not follow Unicode in general, or just in case mapping, or just in this one function (leaving upper, lower, etc. alone)?
Out of curiosity, what language do you use that has no sensible behavior? Most scripts either have sensible case rules, or just don't have cases (so the function is an obvious no-op). I know some people think Unicode chose the _wrong_ rule for their script (e.g., the Turkish i mentioned earlier--even if it is what most Turkish computer users wanted, there are purists who insist it should work
wrote: properly, or that Turkish
dotted i and dotless I should be separate characters from their Latin equivalents). But that's not the same as saying there _are_ no good rules for their script.
In the precense of things like title case, "swapping" case isn't always an operation that can make sense.
As far as I know, there aren't any titlecase characters. The titlecase function
Sorry about the incomplete message. Retrying...
On Aug 11, 2013, at 23:54, Benjamin Peterson
Andrew Barnert
writes: On Aug 11, 2013, at 23:10, Benjamin Peterson
wrote: Andrew Barnert
writes: On Aug 11, 2013, at 20:32, Benjamin Peterson
Serhiy Storchaka
writes: str.swapcase() is just not needed.
I would quite love to get rid of this method, since it's basically useless and wrong on non-ASCII strings.
No it isn't.
I realize it "handles" non-ASCII characters, but I claim there is no sensical behavior.
So you want Python to not follow Unicode in general, or just in case mapping, or just in this one function (leaving upper, lower, etc. alone)?
Out of curiosity, what language do you use that has no sensible behavior? Most scripts either have sensible case rules, or just don't have cases (so the function is an obvious no-op). I know some people think Unicode chose the _wrong_ rule for their script (e.g., the Turkish i mentioned earlier--even if it is what most Turkish computer users wanted, there are purists who insist it should work
wrote: properly, or that Turkish
dotted i and dotless I should be separate characters from their Latin equivalents). But that's not the same as saying there _are_ no good rules for their script.
In the precense of things like title case, "swapping" case isn't always an operation that can make sense.
There aren't any title case characters. Title casing turns each character into one or more uppercase or lowercase characters. And swapcase will do exactly what you'd expect. For example, 'ß'.title() == 'Ss' and it's obvious how that should respond to swapcase. That's a silly example, but hopefully more familiar to most people than Armenian or Church Slavonic; the point is that the same applied to all characters that either turn into two characters, from ligatures like fi to characters that have no pre compose capital form. Are there any counter examples I'm missing?
Sorry, missed one last edit. Last one, I promise.
On Aug 12, 2013, at 0:27, Andrew Barnert
Sorry about the incomplete message. Retrying...
On Aug 11, 2013, at 23:54, Benjamin Peterson
wrote: Andrew Barnert
writes: On Aug 11, 2013, at 23:10, Benjamin Peterson
wrote: Andrew Barnert
writes: On Aug 11, 2013, at 20:32, Benjamin Peterson
Serhiy Storchaka
writes: > str.swapcase() is just not needed.
I would quite love to get rid of this method, since it's basically useless and wrong on non-ASCII strings.
No it isn't.
I realize it "handles" non-ASCII characters, but I claim there is no sensical behavior.
So you want Python to not follow Unicode in general, or just in case mapping, or just in this one function (leaving upper, lower, etc. alone)?
Out of curiosity, what language do you use that has no sensible behavior? Most scripts either have sensible case rules, or just don't have cases (so the function is an obvious no-op). I know some people think Unicode chose the _wrong_ rule for their script (e.g., the Turkish i mentioned earlier--even if it is what most Turkish computer users wanted, there are purists who insist it should work
wrote: properly, or that Turkish
dotted i and dotless I should be separate characters from their Latin equivalents). But that's not the same as saying there _are_ no good rules for their script.
In the precense of things like title case, "swapping" case isn't always an operation that can make sense.
There aren't any title case characters
... That don't have an compatible two-character form. For example, U+01C8 can be interpreted as Lj, which can be swapcased. However, arguably it shouldn't be, because the docs explicitly say that it converts upper to lower an vice-versa, which means Lt characters should be left alone just as numbers and punctuation. So you could argue that it's ambiguous, but you can't argue that nothing makes sense; it's just a choice between two different things that both make sense. Otherwise...
Title casing turns each character into one or more uppercase or lowercase characters. And swapcase will do exactly what you'd expect.
For example, 'ß'.title() == 'Ss' and it's obvious how that should respond to swapcase. That's a silly example, but hopefully more familiar to most people than Armenian or Church Slavonic; the point is that the same applied to all characters that either turn into two characters, from ligatures like fi to characters that have no pre compose capital form.
Are there any counter examples I'm missing? _______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
On Mon, Aug 12, 2013 at 12:27:51AM -0700, Andrew Barnert wrote:
There aren't any title case characters. Title casing turns each character into one or more uppercase or lowercase characters. And swapcase will do exactly what you'd expect.
Actually, there are titlecase characters: http://www.fileformat.info/info/unicode/category/Lt/list.htm http://unicode.org/faq/casemap_charprop.html I think it is reasonable to remove str.swapcase from Python 4000, if and when it exists, provided it is allowed to break backwards compatibility (which is *not* a given). When there is a planned schedule for Python 4000, then it is time to talk about deprecating str.swapcase. Until then, it's a wart that exists for backwards compatibility, but the pain in removing it far outweighs the pain in merely ignoring it. We the Python community are halfway through a ten-year, painful, backwards-incompatible migration from 2.x to 3.x. To justify further backwards-incompatible changes in the 3.x series will require a much stronger rationale than just "I don't know anyone who uses this method". -- Steven
participants (23)
-
Alexander Belopolsky
-
Andrew Barnert
-
Antoine Pitrou
-
Benjamin Peterson
-
Bruce Leban
-
Cameron Simpson
-
Chris Angelico
-
David Mertz
-
Greg Ewing
-
Guido van Rossum
-
Joshua Landau
-
M.-A. Lemburg
-
Mathias Panzenböck
-
MRAB
-
Oscar Benjamin
-
random832@fastmail.us
-
Richard Oudkerk
-
Ron Adam
-
Serhiy Storchaka
-
Steven D'Aprano
-
Tal Einat
-
Terry Reedy
-
Vito De Tullio