Re: the Gravity of Python 2

2014-01-09 Thread Kushal Kumaran
Roy Smith r...@panix.com writes:

 In article mailman.5231.1389240235.18130.python-l...@python.org,
  Chris Angelico ros...@gmail.com wrote:

 On Thu, Jan 9, 2014 at 2:35 PM, Roy Smith r...@panix.com wrote:
  Yes, it *is* simple. It *is* easy. I've been working with pure-UTC
  times (either called time_t, or TIMESTAMP WITH TIME ZONE, or even just
  float) for decades. Like with so many other things, the easiest
  solution is also the best, because you can just work with one stable
  representation and abstraction on the inside, with conversions to/from
  it at the boundaries. It IS that easy.
 
  Please show me the simple code to obtain an aware UTC datetime
  representing the current time.
 
 In Pike:
 time();
 
 In PostgreSQL:
 SELECT now();
 
 In C:
 time(0);
 
 All of these give a value in UTC.

 None of which answer my question.  How, in Python, do you get an aware 
 UTC datetime object?  I know how to get a numeric representation of the 
 time as the number of seconds since the Unix epoch.  That's not what I 
 asked.


My local copy of the python 3.2.3 docs says:

classmethod datetime.utcnow()

Return the current UTC date and time, with tzinfo None. This is like
now(), but returns the current UTC date and time, as a naive
datetime object. An aware current UTC datetime can be obtained by
calling datetime.now(timezone.utc). See also now().

Hope this helps.

 So maybe the key is to use utcfromtimestamp()? I don't know.

 So, I'm really confused what point you're trying to make.  You started 
 out arguing that I should be using aware datetimes instead of naive 
 datetimes.  I said that the reason I don't use aware datetimes is 
 because they're so much more difficult to generate.  You said they were 
 simple to generate.

 So, I'd like to see your code which generates an aware UTC datetime 
 object in Python.  And then we can argue about whether it's simple or 
 not :-)

-- 
regards,
kushal


pgpj8L6oBjbeP.pgp
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Mark Lawrence

On 09/01/2014 01:27, Roy Smith wrote:

In article laknps$umv$1...@dont-email.me,
  Kevin Walzer k...@codebykevin.com wrote:


I haven't updated my Python apps to 3.x because there's nothing in 3.x
that offers benefits to my users.


I almost found a reason to move to Python 3 today.  Then I got smacked.

I had a datetime.  I needed a unix timestamp.  People need to go back
and forth between these two things all the time and in Python 2 it's the
very definition of impedance mismatch.  What should be a dead simple
operation involves long threads on stackoverflow discussing which of
several amalgamations of duct tape is the least ugly.

Anyway, I discovered that Python 3.3's datetime has a .timestamp()
method.  Yeah.  Finally.  Exactly what the world had needed for years.
Then I kept reading and found:

Note: There is no method to obtain the POSIX timestamp directly from a
naive datetime instance representing UTC time.

Ugh.  So, we're back to square one.  They go on to suggest one of two
workarounds, either calling datetime.replace() to insert a timezone, or
subtracting from the epoch manually.

Naive datetimes are what everybody uses.  It's what utcnow() gives you.
So why make life difficult for everybody?  Python 3 didn't win a convert
today.



Yep, dates and times are easy.  That's why there are 17 issues open on 
the bug tracker referencing tzinfo alone.  Poor old 1100942 is high 
priority, was created 12/01/2005 and has missed 3.4.  So if it gets into 
3.5 it'll have already celebrated its 10th birthday.  It doesn't say 
much for the amount of effort that we put into looking after issues.


--
My fellow Pythonistas, ask not what our language can do for you, ask 
what you can do for our language.


Mark Lawrence

--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Mark Lawrence

On 09/01/2014 06:06, Kushal Kumaran wrote:


My local copy of the python 3.2.3 docs says:

classmethod datetime.utcnow()

 Return the current UTC date and time, with tzinfo None. This is like
 now(), but returns the current UTC date and time, as a naive
 datetime object. An aware current UTC datetime can be obtained by
 calling datetime.now(timezone.utc). See also now().

Hope this helps.



Blimey, you learn something new everyday, thanks.  And it works :)

In [7]: datetime.datetime.now(datetime.timezone.utc)
Out[7]: datetime.datetime(2014, 1, 9, 8, 51, 13, 945312, 
tzinfo=datetime.timezone.utc)


--
My fellow Pythonistas, ask not what our language can do for you, ask 
what you can do for our language.


Mark Lawrence

--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Ben Finney
Kushal Kumaran kushal.kuma...@gmail.com writes:

 Roy Smith r...@panix.com writes:
  How, in Python, do you get an aware UTC datetime object?

 My local copy of the python 3.2.3 docs says:

 classmethod datetime.utcnow()

 Return the current UTC date and time, with tzinfo None. This is
 like now(), but returns the current UTC date and time, as a naive
 datetime object. An aware current UTC datetime can be obtained by
 calling datetime.now(timezone.utc). See also now().

 Hope this helps.

No, that won't do what was asked. The ‘datetime.datetime.utcnow’
function explicitly returns a naive datetime object, not an aware
datetime object.

-- 
 \   “We must respect the other fellow's religion, but only in the |
  `\   sense and to the extent that we respect his theory that his |
_o__) wife is beautiful and his children smart.” —Henry L. Mencken |
Ben Finney

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Kushal Kumaran
Ben Finney ben+pyt...@benfinney.id.au writes:

 Kushal Kumaran kushal.kuma...@gmail.com writes:

 Roy Smith r...@panix.com writes:
  How, in Python, do you get an aware UTC datetime object?

 My local copy of the python 3.2.3 docs says:

 classmethod datetime.utcnow()

 Return the current UTC date and time, with tzinfo None. This is
 like now(), but returns the current UTC date and time, as a naive
 datetime object. An aware current UTC datetime can be obtained by
 calling datetime.now(timezone.utc). See also now().

 Hope this helps.

 No, that won't do what was asked. The ‘datetime.datetime.utcnow’
 function explicitly returns a naive datetime object, not an aware
 datetime object.


Yes, but the documentation for utcnow explicitly tells you how to get
an aware object.

  An aware current UTC datetime can be obtained by calling
   datetime.now(timezone.utc).

-- 
regards,
kushal


pgpkuzTEDWuQ3.pgp
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Mark Lawrence

On 09/01/2014 09:03, Ben Finney wrote:

Kushal Kumaran kushal.kuma...@gmail.com writes:


Roy Smith r...@panix.com writes:

How, in Python, do you get an aware UTC datetime object?


My local copy of the python 3.2.3 docs says:

classmethod datetime.utcnow()

 Return the current UTC date and time, with tzinfo None. This is
 like now(), but returns the current UTC date and time, as a naive
 datetime object. An aware current UTC datetime can be obtained by
 calling datetime.now(timezone.utc). See also now().

Hope this helps.


No, that won't do what was asked. The ‘datetime.datetime.utcnow’
function explicitly returns a naive datetime object, not an aware
datetime object.



How closely do you bother to read posts that people like Kushal Kumaran 
have taken the trouble to post?  Eleven lines above this one it says (my 
emphasis) An *AWARE* current UTC datetime can be obtained by

calling datetime.now(timezone.utc).

--
My fellow Pythonistas, ask not what our language can do for you, ask 
what you can do for our language.


Mark Lawrence

--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Piet van Oostrum
Kushal Kumaran kushal.kuma...@gmail.com writes:

 Yes, but the documentation for utcnow explicitly tells you how to get
 an aware object.

   An aware current UTC datetime can be obtained by calling
datetime.now(timezone.utc).

And in Python 2.7 you can just copy the definition of utc from the doc and use 
that:

from datetime import tzinfo, timedelta, datetime

ZERO = timedelta(0)

class UTC(tzinfo):
UTC

def utcoffset(self, dt):
return ZERO

def tzname(self, dt):
return UTC

def dst(self, dt):
return ZERO

utc = UTC()
-- 
Piet van Oostrum p...@vanoostrum.org
WWW: http://pietvanoostrum.com/
PGP key: [8DAE142BE17999C4]
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Ben Finney
Kushal Kumaran kushal.kuma...@gmail.com writes:

 Ben Finney ben+pyt...@benfinney.id.au writes:

  Kushal Kumaran kushal.kuma...@gmail.com writes:
 
  Roy Smith r...@panix.com writes:
   How, in Python, do you get an aware UTC datetime object?
 
  classmethod datetime.utcnow()
 
  Return the current UTC date and time, with tzinfo None. […]
 
  No, that won't do what was asked. The ‘datetime.datetime.utcnow’
  function explicitly returns a naive datetime object, not an aware
  datetime object.

 Yes, but the documentation for utcnow explicitly tells you how to get
 an aware object.

   An aware current UTC datetime can be obtained by calling
datetime.now(timezone.utc).

And we come full circle: This is exactly what Roy's original question
was (IIUC) trying to address. That process is not obvious, and it's not
simple: it's a series of difficult-to-discover function calls instead of
just one obvious one.

-- 
 \   “If you don't know what your program is supposed to do, you'd |
  `\ better not start writing it.” —Edsger W. Dijkstra |
_o__)  |
Ben Finney

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Piet van Oostrum
Chris Angelico ros...@gmail.com writes:

 On Thu, Jan 9, 2014 at 2:34 PM, Ben Finney ben+pyt...@benfinney.id.au wrote:
 [ a bunch of stuff that I totally agree with ]

 No response needed here :)

 So I was wrong on the specific example of .today(), but asking the
 question the other way is at least helpful. Maybe the best solution is
 exactly what Roy already posted, or maybe there's some other way to
 achieve that. In any case, there is a solution, albeit not as clean as
 I would have liked.

 With time zones, as with text encodings, there is a single technically
 elegant solution (for text: Unicode; for time zones: twelve simple,
 static zones that never change)

 Twelve or twenty-four? Or are you thinking we should all be an even
 number of hours away from UTC, which would also work?

Even 24 doesn't take into account DST.
-- 
Piet van Oostrum p...@vanoostrum.org
WWW: http://pietvanoostrum.com/
PGP key: [8DAE142BE17999C4]
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Roy Smith
In article mailman.5244.1389254198.18130.python-l...@python.org,
 Chris Angelico ros...@gmail.com wrote:

 What can you (Roy), with your use-case, achieve with datetime that 
 you can't achieve (at least reasonably easily) with a timestamp?

As I'm mentioned several times, when you print a datetime, you get 
something that's human friendly.  When you print a timestamp (i.e. a 
float), you get a lot of digits.  I don't know about you, but I can't 
look at 1389274842 and get any feel for whether that was in the middle 
of the night or at 5 in the afternoon, near our peak traffic time.  Nor 
can I tell if it was today, yesterday, last month, or a week from next 
Tuesday.

Datetimes make it easy to do things like, find the time of the 
preceding (or following) midnight.  Or, what month is this timestamp 
part of?  These are operations we need to do a lot, to answer questions 
like, How many unique users did we have on a given day?, or Which 
monthly database archive file do I need to grab to get information about 
this historical event?

Datetimes are self-documenting.  If I'm in the python shell and have 
something called t, I can do help(t) or dir(t) to find out what 
operations it has.

Datetimes are self-describing.  If I have a datetime or a timedelta, I 
know what I've got.  I've written more than one bug where I assumed a 
number somebody handed me was in seconds but it turned out to be in ms.  
That can never happen with a timedelta.  We do a lot of stuff in 
javascript, where times are ms, so this is a common problem for us.

Oh, and another thing I can do with a datetime that I can't do with a 
unix timestamp.  I can represent the day I was born.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Chris Angelico
On Fri, Jan 10, 2014 at 1:06 AM, Piet van Oostrum p...@vanoostrum.org wrote:
 Chris Angelico ros...@gmail.com writes:

 On Thu, Jan 9, 2014 at 2:34 PM, Ben Finney ben+pyt...@benfinney.id.au 
 wrote:
 With time zones, as with text encodings, there is a single technically
 elegant solution (for text: Unicode; for time zones: twelve simple,
 static zones that never change)

 Twelve or twenty-four? Or are you thinking we should all be an even
 number of hours away from UTC, which would also work?

 Even 24 doesn't take into account DST.

That was the point. We can abolish codepages by using Unicode, which
covers everything. We could abolish time messes by having every
locality settle permanently on one timezone; Ben's theory demands that
all timezones be some integer number of hours +/- UTC, which IMO is
optional, but mainly it should be easy to figure out any two
locations' difference: just subtract one's UTC offset from the
other's. Similarly, you can calculate the difference between two times
at the same location by simple subtraction; currently, you also have
to consider the possibility of a DST switch (from noon to noon across
a switch is either 23 or 25 hours).

Actually, the nearest parallel to Unicode is probably use UTC
everywhere, which makes for a superb internal representation and
transmission format, but bugs most human beings :)

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Roy Smith
In article mailman.5259.1389278063.18130.python-l...@python.org,
 Chris Angelico ros...@gmail.com wrote:

 Actually, the nearest parallel to Unicode is probably use UTC
 everywhere, which makes for a superb internal representation and
 transmission format, but bugs most human beings :)

It is, by the way, the solution that the aviation industry has adopted.  
All communication between aircraft and controllers is in UTC (pronounced 
zulu).  Weather reports and forecasts are in UTC.  Regulatory notices 
are in UTC.  The time when one edition of a chart will be replaced by 
the next edition is in UTC.

If I'm somewhere over the Atlantic, talking to a controller sitting in 
Shannon, Ireland, negotiating when I'm going to be allowed to continue 
on my route from New York to Istambul, the last thing I want is anybody 
to be confused about timezones.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Roy Smith
In article mailman.5257.1389274514.18130.python-l...@python.org,
 Ben Finney ben+pyt...@benfinney.id.au wrote:

 Kushal Kumaran kushal.kuma...@gmail.com writes:
 
  Ben Finney ben+pyt...@benfinney.id.au writes:
 
   Kushal Kumaran kushal.kuma...@gmail.com writes:
  
   Roy Smith r...@panix.com writes:
How, in Python, do you get an aware UTC datetime object?
  
   classmethod datetime.utcnow()
  
   Return the current UTC date and time, with tzinfo None. […]
  
   No, that won't do what was asked. The ‘datetime.datetime.utcnow’
   function explicitly returns a naive datetime object, not an aware
   datetime object.
 
  Yes, but the documentation for utcnow explicitly tells you how to get
  an aware object.
 
An aware current UTC datetime can be obtained by calling
 datetime.now(timezone.utc).
 
 And we come full circle: This is exactly what Roy's original question
 was (IIUC) trying to address. That process is not obvious, and it's not
 simple: it's a series of difficult-to-discover function calls instead of
 just one obvious one.

Yes, exactly.  Thank you.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Chris Angelico
On Fri, Jan 10, 2014 at 1:14 AM, Roy Smith r...@panix.com wrote:
 In article mailman.5244.1389254198.18130.python-l...@python.org,
  Chris Angelico ros...@gmail.com wrote:

 What can you (Roy), with your use-case, achieve with datetime that
 you can't achieve (at least reasonably easily) with a timestamp?

Thanks for this collection! Now we can discuss.

 As I'm mentioned several times, when you print a datetime, you get
 something that's human friendly.  When you print a timestamp (i.e. a
 float), you get a lot of digits.  I don't know about you, but I can't
 look at 1389274842 and get any feel for whether that was in the middle
 of the night or at 5 in the afternoon, near our peak traffic time.  Nor
 can I tell if it was today, yesterday, last month, or a week from next
 Tuesday.

Sure. There is a lot of value in having a class that knows how it
should be displayed. I'm not sure the current datetime repr is good
for anything more than debugging, but I agree that
datetime.datetime(2014, 1, 9, 5, 57, 59, 929176) is more likely to
be useful than a raw number.

 Datetimes make it easy to do things like, find the time of the
 preceding (or following) midnight.  Or, what month is this timestamp
 part of?  These are operations we need to do a lot, to answer questions
 like, How many unique users did we have on a given day?, or Which
 monthly database archive file do I need to grab to get information about
 this historical event?

That's true; the same operations done with timestamps look like this:

 ts = time.time()
 ts_at_midnight_utc = ts - ts%86400
 ts_at_midnight_utc
1389225600.0

Not nearly as obvious what's happening. And months are more
complicated still, so it's probably easiest to use strftime:

 time.strftime(%Y%m,time.gmtime(ts))
'201401'

which could then be used as a lookup key for a counter or whatever.
Yep, that's not as clean as simply calling a method.

 Datetimes are self-documenting.  If I'm in the python shell and have
 something called t, I can do help(t) or dir(t) to find out what
 operations it has.

Partly true, but not everything's there. For instance, if you have a
list of strings, you won't find a way to join them together in its
help() or dir(), and yet it's a fundamental and very important
operation.

 Datetimes are self-describing.  If I have a datetime or a timedelta, I
 know what I've got.  I've written more than one bug where I assumed a
 number somebody handed me was in seconds but it turned out to be in ms.
 That can never happen with a timedelta.  We do a lot of stuff in
 javascript, where times are ms, so this is a common problem for us.

Sure. Though that's no different from other cases where you need
out-of-band information to understand something, as we've just been
discussing in the threads about text handling - if you have a puddle
of bytes, you can't decode them to text without knowing what the
encoding is. [1] If your data's coming from JS, it won't be a
timedelta, it'll be a number; at some point you have to turn that into
a timedelta object, so you still have the same problem.

 Oh, and another thing I can do with a datetime that I can't do with a
 unix timestamp.  I can represent the day I was born.

Maybe you can't with the original C definition of time_t as an
unsigned integer, but the notion of a Unix timestamp can plausibly be
extended (a) to negative numbers, and (b) to non-integers. Python
definitely does the latter; its ability to do the former depends
somewhat on the underlying C library's support:

Windows:
 time.strftime(%Y%m,time.gmtime(-10))
Traceback (most recent call last):
  File pyshell#163, line 1, in module
time.strftime(%Y%m,time.gmtime(-10))
OSError: [Errno 22] Invalid argument

Linux:
 time.strftime(%Y%m,time.gmtime(-10))
'196912'
 time.strftime(%Y%m,time.gmtime(-2**31))
'190112'
 time.strftime(%Y%m,time.gmtime(-2**31-1))
Traceback (most recent call last):
  File stdin, line 1, in module
ValueError: timestamp out of range for platform time_t

So what I'm seeing here is that the direct use of a time_t will cover
everything in an ugly way, but that a class wrapping it up could fix
that. And fundamentally, the only problem with datetime (which, for
the most part, is exactly that wrapper) is that it's unobvious how to
get a simple UTC timestamp.

Has the unobviousness been solved by a simple recipe? And if so,
should that tip be added to the datetime module docs somewhere?

ChrisA

[1] Yes, I said puddle of bytes. What would you call it? Am
interested to hear!
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Dan Sommers
On Thu, 09 Jan 2014 09:14:22 -0500, Roy Smith wrote:

 Oh, and another thing I can do with a datetime that I can't do with a
 unix timestamp.  I can represent the day I was born.

At the risk of dating myself, the day I was born is -231094800.

Dan
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Chris Angelico
On Fri, Jan 10, 2014 at 2:01 AM, Dan Sommers d...@tombstonezero.net wrote:
 On Thu, 09 Jan 2014 09:14:22 -0500, Roy Smith wrote:

 Oh, and another thing I can do with a datetime that I can't do with a
 unix timestamp.  I can represent the day I was born.

 At the risk of dating myself, the day I was born is -231094800.

Which, according to a Unix build of Python, is quite representable:

 time.strftime(%Y-%m-%d,time.gmtime(-231094800))
'1962-09-05'

This isn't a problem. Now, if you were considering yourself for a
romantic candle-lit dinner and a movie afterward, then maybe there's
some risk in dating yourself :)

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Roy Smith
On Thursday, January 9, 2014 9:57:57 AM UTC-5, Chris Angelico wrote:


 And months are more
 complicated still, so it's probably easiest to use strftime:
 
  time.strftime(%Y%m,time.gmtime(ts))
 
 '201401'

strftime is a non-starter at far as easy goes.  I don't know about you, but I 
certainly haven't memorized the table of all the format specifiers.  Is month 
m or M?  What's %U or %B.  Every time I use strftime, I have to go pull 
up the docs and read the table.  Not to mention that %z is not available on 
all platforms, and %s (which is incredibly useful) is not even documented (I 
suspect it's also not available on all platforms).

 So what I'm seeing here is that the direct use of a time_t will cover
 everything in an ugly way, but that a class wrapping it up could fix
 that. And fundamentally, the only problem with datetime (which, for
 the most part, is exactly that wrapper) is that it's unobvious how to
 get a simple UTC timestamp.
 
 Has the unobviousness been solved by a simple recipe? And if so,
 should that tip be added to the datetime module docs somewhere?

No, it would be solved by a built-in method.  Recipes are a cop-out.  If 
something is complicated enough to require a recipe, and used frequently enough 
to be worth writing that recipe up and documenting it, you might as well have 
gone the one additional step and made it a method.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Mark Lawrence

On 09/01/2014 16:21, Roy Smith wrote:


No, it would be solved by a built-in method.  Recipes are a cop-out.  If 
something is complicated enough to require a recipe, and used frequently enough 
to be worth writing that recipe up and documenting it, you might as well have 
gone the one additional step and made it a method.



So all of the itertools recipes should be part of the Python module and 
not in more-itertools on pypi?


--
My fellow Pythonistas, ask not what our language can do for you, ask 
what you can do for our language.


Mark Lawrence

--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Tim Golden
On 09/01/2014 16:30, Mark Lawrence wrote:
 On 09/01/2014 16:21, Roy Smith wrote:

 No, it would be solved by a built-in method.  Recipes are a cop-out. 
 If something is complicated enough to require a recipe, and used
 frequently enough to be worth writing that recipe up and documenting
 it, you might as well have gone the one additional step and made it a
 method.

 
 So all of the itertools recipes should be part of the Python module and
 not in more-itertools on pypi?

To be fair, Mark, it's a matter of taste. Raymond [the author/maintainer
of itertools] prefers not to multiply the API; other developers might
legitimately make other calls. Sometimes the cut-off is more obvious;
say, when the effort to make a recipe general purpose creates an
over-engineered API. Other times it's just preference.

Does that mean that every recipe ever conceived should be stuffed into
the class or module it uses? No; but it doesn't rule out adding things
which are genuinely useful.

I think the new statistics module has hit a nice balance on its initial
release: it's a stripped down aesthetic without precluding later additions.

TJG
-- 
https://mail.python.org/mailman/listinfo/python-list


RE: the Gravity of Python 2

2014-01-09 Thread Nick Cash
 and %s (which is incredibly useful) is not even documented (I suspect it's 
 also not available on all platforms).

The format specifiers available to Python are just whatever is available to the 
underlying c time.h. 
The manpage for strftime indicates that %s isn't part of the C standard, but 
part of Olson's timezone package, which means it's not available on Windows. 
Your suspicion is unfortunately correct.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Mark Lawrence

On 09/01/2014 16:42, Nick Cash wrote:

and %s (which is incredibly useful) is not even documented (I suspect it's 
also not available on all platforms).


The format specifiers available to Python are just whatever is available to the 
underlying c time.h.
The manpage for strftime indicates that %s isn't part of the C standard, but part of 
Olson's timezone package, which means it's not available on Windows. Your 
suspicion is unfortunately correct.



Methinks http://www.python.org/dev/peps/pep-0431/ Time zone support 
improvements may be of interest here.  Still at draft issue unfortunately.


--
My fellow Pythonistas, ask not what our language can do for you, ask 
what you can do for our language.


Mark Lawrence

--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Ethan Furman

On 01/09/2014 12:42 AM, Mark Lawrence wrote:

On 09/01/2014 01:27, Roy Smith wrote:


Naive datetimes are what everybody uses.  It's what utcnow() gives you.
So why make life difficult for everybody?  Python 3 didn't win a convert
today.


Yep, dates and times are easy.  That's why there are 17 issues open on the bug 
tracker referencing tzinfo alone.  Poor
old 1100942 is high priority, was created 12/01/2005 and has missed 3.4.  So if 
it gets into 3.5 it'll have already
celebrated its 10th birthday.  It doesn't say much for the amount of effort 
that we put into looking after issues.


Mark, I hope you are addressing the community at large and not the core-devs.  There are only so many of us, with 
limited time available.


--
~Ethan~
--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Piet van Oostrum
Chris Angelico ros...@gmail.com writes:

 On Fri, Jan 10, 2014 at 1:06 AM, Piet van Oostrum p...@vanoostrum.org wrote:
 Chris Angelico ros...@gmail.com writes:

 On Thu, Jan 9, 2014 at 2:34 PM, Ben Finney ben+pyt...@benfinney.id.au 
 wrote:
 With time zones, as with text encodings, there is a single technically
 elegant solution (for text: Unicode; for time zones: twelve simple,
 static zones that never change)

 Twelve or twenty-four? Or are you thinking we should all be an even
 number of hours away from UTC, which would also work?

 Even 24 doesn't take into account DST.

 That was the point. We can abolish codepages by using Unicode, which
 covers everything. We could abolish time messes by having every
 locality settle permanently on one timezone; Ben's theory demands that
 all timezones be some integer number of hours +/- UTC, which IMO is
 optional, but mainly it should be easy to figure out any two
 locations' difference: just subtract one's UTC offset from the
 other's. Similarly, you can calculate the difference between two times
 at the same location by simple subtraction; currently, you also have
 to consider the possibility of a DST switch (from noon to noon across
 a switch is either 23 or 25 hours).

 Actually, the nearest parallel to Unicode is probably use UTC
 everywhere, which makes for a superb internal representation and
 transmission format, but bugs most human beings :)

I don't know how other countries do it, but here, when the clock goes back, it 
goes from 03:00 to 02:00. So I wonder how they communicate when your plane 
leaves at 02:30 in that night. Which 02:30? In that case using UTC may come out 
handy, if it would be understood. Or do the planes just stop leaving during 
that interval? Not that there will be many leaving during that time in general, 
I presume.

-- 
Piet van Oostrum p...@vanoostrum.org
WWW: http://pietvanoostrum.com/
PGP key: [8DAE142BE17999C4]
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Ethan Furman

On 01/09/2014 06:57 AM, Chris Angelico wrote:

On Fri, Jan 10, 2014 at 1:14 AM, Roy Smith r...@panix.com wrote:




Thanks for this collection! Now we can discuss.


[snip]


Datetimes are self-describing.  If I have a datetime or a timedelta, I
know what I've got.  I've written more than one bug where I assumed a
number somebody handed me was in seconds but it turned out to be in ms.
That can never happen with a timedelta.  We do a lot of stuff in
javascript, where times are ms, so this is a common problem for us.


Sure. Though that's no different from other cases where you need
out-of-band information to understand something, as we've just been
discussing in the threads about text handling - if you have a puddle
of bytes, you can't decode them to text without knowing what the
encoding is. [1] If your data's coming from JS, it won't be a
timedelta, it'll be a number; at some point you have to turn that into
a timedelta object, so you still have the same problem.


Yup, and you do at the boundary instead of having a float wandering through your code with an easily forgotten meta-data 
type.




So what I'm seeing here is that the direct use of a time_t will cover
everything in an ugly way, but that a class wrapping it up could fix
that. And fundamentally, the only problem with datetime (which, for
the most part, is exactly that wrapper) is that it's unobvious how to
get a simple UTC timestamp.


It has at least one other problem:  bool(midnight) == False.

--
~Ethan~



[1] Yes, I said puddle of bytes. What would you call it? Am
interested to hear!


I think that's a perfect name!  :)
--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Roy Smith
I wrote:
 Recipes are a cop-out

On Thursday, January 9, 2014 11:30:31 AM UTC-5, Mark Lawrence wrote:
 So all of the itertools recipes should be part of the Python module and 
 not in more-itertools on pypi?

Certainly, the recipes that are documented on the official itertools page, yes.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Mark Lawrence

On 09/01/2014 16:01, Ethan Furman wrote:

On 01/09/2014 12:42 AM, Mark Lawrence wrote:

On 09/01/2014 01:27, Roy Smith wrote:


Naive datetimes are what everybody uses.  It's what utcnow() gives you.
So why make life difficult for everybody?  Python 3 didn't win a convert
today.


Yep, dates and times are easy.  That's why there are 17 issues open on
the bug tracker referencing tzinfo alone.  Poor
old 1100942 is high priority, was created 12/01/2005 and has missed
3.4.  So if it gets into 3.5 it'll have already
celebrated its 10th birthday.  It doesn't say much for the amount of
effort that we put into looking after issues.


Mark, I hope you are addressing the community at large and not the
core-devs.  There are only so many of us, with limited time available.

--
~Ethan~


As I'm not a core dev to whom do you think I'm referring?  I'm aware 
that the high horse I get on about this is so tall that you'll need an 
oxygen supply to survive should you want to sit on it, but to me this is 
easily the worst aspect of the Python community as a whole.  If every 
regular contributor to this list was to fix even one bug a week the 
figures would look rather better.  Still, you can no more enforce that 
than you can enforce the core devs working on Python 2.8 :)


Talking of which, have we got a PEP for that yet, or are the whingers 
still simply in whinging mode?


--
My fellow Pythonistas, ask not what our language can do for you, ask 
what you can do for our language.


Mark Lawrence

--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Mark Lawrence

On 09/01/2014 17:07, Roy Smith wrote:

I wrote:

Recipes are a cop-out


On Thursday, January 9, 2014 11:30:31 AM UTC-5, Mark Lawrence wrote:

So all of the itertools recipes should be part of the Python module and
not in more-itertools on pypi?


Certainly, the recipes that are documented on the official itertools page, yes.



No thank you, I don't want the Python docs getting anywhere near the 
size of their Java equivalents.


--
My fellow Pythonistas, ask not what our language can do for you, ask 
what you can do for our language.


Mark Lawrence

--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Ethan Furman

On 01/09/2014 10:18 AM, Mark Lawrence wrote:

On 09/01/2014 16:01, Ethan Furman wrote:

On 01/09/2014 12:42 AM, Mark Lawrence wrote:

On 09/01/2014 01:27, Roy Smith wrote:


Naive datetimes are what everybody uses.  It's what utcnow() gives you.
So why make life difficult for everybody?  Python 3 didn't win a convert
today.


Yep, dates and times are easy.  That's why there are 17 issues open on
the bug tracker referencing tzinfo alone.  Poor
old 1100942 is high priority, was created 12/01/2005 and has missed
3.4.  So if it gets into 3.5 it'll have already
celebrated its 10th birthday.  It doesn't say much for the amount of
effort that we put into looking after issues.


Mark, I hope you are addressing the community at large and not the
core-devs.  There are only so many of us, with limited time available.


As I'm not a core dev to whom do you think I'm referring?


Cool, just double-checking.  :)



Still, you can no more enforce that than you can enforce the core devs
 working on Python 2.8 :)

Talking of which, have we got a PEP for that yet. . .


As a matter of fact.  It's called PEP 404.  ;)

--
~Ethan~
--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Ethan Furman

On 01/09/2014 10:20 AM, Mark Lawrence wrote:

On Thursday, January 9, 2014 11:30:31 AM UTC-5, Mark Lawrence wrote:

So all of the itertools recipes should be part of the Python module and
not in more-itertools on pypi?


Certainly, the recipes that are documented on the official itertools page, yes.


No thank you, I don't want the Python docs getting anywhere near the size of 
their Java equivalents.


To be fair, the recipes on the itertools page are there so that minor changes can be made (flavor to taste, so to speak) 
to get exactly the semantics needed by the individual programmer.


With the timezone stuff we're looking for The One Obvious Way, which should be 
a method, not a recipe.

--
~Ethan~
--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Chris Angelico
On Fri, Jan 10, 2014 at 3:21 AM, Roy Smith r...@panix.com wrote:
 On Thursday, January 9, 2014 9:57:57 AM UTC-5, Chris Angelico wrote:
 And months are more
 complicated still, so it's probably easiest to use strftime:

  time.strftime(%Y%m,time.gmtime(ts))

 '201401'

 strftime is a non-starter at far as easy goes.  I don't know about you, but 
 I certainly haven't memorized the table of all the format specifiers.  Is 
 month m or M?  What's %U or %B.  Every time I use strftime, I have to 
 go pull up the docs and read the table.  Not to mention that %z is not 
 available on all platforms, and %s (which is incredibly useful) is not even 
 documented (I suspect it's also not available on all platforms).


Have you ever used a regular expression? Does it bother you that both
percent-formatting and str.format() have compact/cryptic
mini-languages? Why is it a problem to have a mini-language for
formatting dates? It at least follows a measure of common sense,
unlike the PHP date function. In fact, I've given end users the
ability to enter strftime strings (eg to construct a filename), and
it's worked just fine. *Non-programmers* can figure them out without
much difficulty.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Chris Angelico
On Fri, Jan 10, 2014 at 3:51 AM, Piet van Oostrum p...@vanoostrum.org wrote:
 I don't know how other countries do it, but here, when the clock goes back, 
 it goes from 03:00 to 02:00. So I wonder how they communicate when your plane 
 leaves at 02:30 in that night. Which 02:30? In that case using UTC may come 
 out handy, if it would be understood. Or do the planes just stop leaving 
 during that interval? Not that there will be many leaving during that time in 
 general, I presume.


The fundamental is that the timezone changes. Times roll from 02:00
Daylight time through 02:30 Daylight time to the instant before 03:00
Daylight time, which doesn't happen, and instead time jumps to 02:00
Standard time and starts rolling forward.

How this is adequately communicated on the plane ticket is a separate
issue, though, and as I've never actually flown during a DST
changeover, I wouldn't know. I'm sure there would be planes departing
during those two hours (neither airlines nor airports can afford to
have two, or even one, dead hour!), so this must have been solved
somehow. Maybe people could figure it out from the check-in by time?
For instance, last time I flew, the plane departed at 0240 local time
(but this was in July, so not anywhere near changeover), and check-in
opened at 2340; so if it were the other 0240, then check-in would
have opened at 0040 instead. Either that, or they'll tell everyone to
arrive in time for the first instance of that time, and then just make
us all wait around for an extra hour

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Roy Smith
On Thursday, January 9, 2014 3:35:05 PM UTC-5, Chris Angelico wrote:
 In fact, I've given end users the ability to enter strftime strings (eg
 to construct a filename), and it's worked just fine.

I assume you realize that 
../../../../../../../../../../../../../../../../etc/passwd is a valid 
strftime() format specifier? :-)

But, to answer your question, no, I have nothing against small languages, 
per-se (and I've done plenty of regex work).  But, if my goal is to print a 
time in some human-readable form:

 print t

is a lot easier than anything involving strftime().
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-09 Thread Chris Angelico
On Fri, Jan 10, 2014 at 7:54 AM, Roy Smith r...@panix.com wrote:
 On Thursday, January 9, 2014 3:35:05 PM UTC-5, Chris Angelico wrote:
 In fact, I've given end users the ability to enter strftime strings (eg
 to construct a filename), and it's worked just fine.

 I assume you realize that 
 ../../../../../../../../../../../../../../../../etc/passwd is a valid 
 strftime() format specifier? :-)

Yes, and since this was for the creation of a log file by an
unprivileged process, that would simply fail :) Though the specific
case I'm thinking of here was on Windows, so you could probably find
an equivalent filename (it didn't prevent absolute names, so you could
just stuff whatever you want in) and shoot yourself in the foot
big-time. It's the user's own system, let him make a mess of it if he
wants :)

 But, to answer your question, no, I have nothing against small languages, 
 per-se (and I've done plenty of regex work).  But, if my goal is to print a 
 time in some human-readable form:

 print t

 is a lot easier than anything involving strftime().

Sure, it's easier. But there are plenty of types that don't provide a
particularly useful repr - regexes being one that only recently
changed:

2.7 and 3.3:
 re.compile(r(.)\1\1\1)
_sre.SRE_Pattern object at 0x012464F0
 _.search(This is a test string with a quaduple letter in it!)
_sre.SRE_Match object at 0x012C3EE0

3.4:
 re.compile(r(.)\1\1\1)
re.compile('(.)\\1\\1\\1')
 _.search(This is a test string with a quaduple letter in it!)
_sre.SRE_Match object; span=(33, 37), match=''

Would you avoid using regexes in anything less than 3.4 simply because
of this lack of repr? It's a convenience, not a deal-breaker. (Or if
you disagree with me on that point, you're cutting out a lot of very
useful types.) It's not hard to call time.ctime(ts) or strftime(...)
for display; the big loser is the interactive interpreter, where a
good repr is everything.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Martijn Faassen

Hi there,

On 01/07/2014 06:00 PM, Chris Angelico wrote:

I'm still not sure how Python 2.8 needs to differ from 2.7. Maybe the
touted upgrade path is simply a Python 2.7 installer plus a few handy
libraries/modules that will now be preinstalled? These modules look
great (I can't say, as I don't have a huge Py2 codebase to judge based
on), and they presumably work on the existing Pythons.


Well, in the original article I argue that it may be risky for the 
Python community to leave the large 2.7 projects behind because they 
tend to be the ones that pay us in the end.


I also argue that for those projects to move anywhere, they need a 
clear, blessed, official, as simple as possible, incremental upgrade 
path. That's why I argue for a Python 2.8.


Pointing out the 'future' module is existence proof that further 
incremental steps could be taken on top of what Python 2.7 already does.


I may be that these points are wrong or should be weighed differently. 
It's possible that:


* the risk of losing existing big 2.x projects is low, they'll port 
anyway, the money will keep flowing into our community, they won't look 
at other languages, etc.


* these big 2.x projects are going to all find the 'future' module 
themselves and use it as incremental upgrade path, so there's no need 
for a new blessed Python 2.x.


* the approach of the 'future' module turns out to be fatally flawed 
and/or doesn't really help with incremental upgrades after all.


But that's how I reason about it, and how I weigh things. I think the 
current strategy is risky.


Regards,

Martijn

--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Chris Angelico
On Wed, Jan 8, 2014 at 11:36 PM, Martijn Faassen faas...@startifact.com wrote:
 Well, in the original article I argue that it may be risky for the Python
 community to leave the large 2.7 projects behind because they tend to be the
 ones that pay us in the end.

 I also argue that for those projects to move anywhere, they need a clear,
 blessed, official, as simple as possible, incremental upgrade path. That's
 why I argue for a Python 2.8.

 Pointing out the 'future' module is existence proof that further incremental
 steps could be taken on top of what Python 2.7 already does.

Yep, but suppose it were simply that the future module is blessed as
the official, simple, incremental upgrade path. That doesn't violate
PEP 404, it allows the future module to continue to be expanded
without worrying about the PSF's schedules (more stuff might be added
to it in response to Python 3.5, but this is all in the hands of
future's maintainer), and it should be relatively simple to produce an
installer that goes and grabs it.

I'm all in favour of changes that don't require core support :) Let's
see how much can be done without touching the Python language in any
way at all. Maybe it'll turn out that there's some tiny change to
Python that would facilitate a huge improvement in commonality, but we
won't know without first trying to solve the problem under the
restriction of there will be no Py2.8.

As Mark Rosewater is fond of saying, restrictions breed creativity.
Can the porting community take the PEP 404 restriction and be creative
within it? I suspect it'll go a long way.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Steven D'Aprano
Martijn Faassen wrote:

 I also argue that for those projects to move anywhere, they need a
 clear, blessed, official, as simple as possible, incremental upgrade
 path. That's why I argue for a Python 2.8.

That incremental upgrade path is Python 2.7.

Remember, when Python 3 first came out, the current version of Python was
2.5. 2.6 came out roughly simultaneously with Python 3. So the expected
upgrade path is:


Bleeding edge adaptors:
2.5 - 3.0

Early adaptors:
2.5 - 2.6 - 3.1 or 3.2

Slower adaptors:
2.5 - 2.6 - 2.7 - 3.3 or 3.4

Late adaptors:
2.5 - 2.6 - 2.7 - 3.5 (expected to be about 18-24 months)

Laggards who wait until support for 2.7 is dropped:
2.5 - 2.6 - 2.7 - 3.6 or 3.7

Adding 2.8 doesn't help. It just gives people another excuse to delay
migrating. Then, in another two or three years, they'll demand 2.9, and put
it off again. Then they'll insist that 15 years wasn't long enough to
migrate their code, and demand 2.10.

I have no objection to people delaying migrating. There were lots of risks
and difficulties in migrating to 3.1 or 3.2, there are fewer risks and
difficulties in migrating to 3.3 and 3.4, and there will be even fewer by
the time 3.5 and 3.6 come out. People should migrate when they are
comfortable. They may even decide to stick to 2.7 for as long as they can
find a computer capable of running it, security updates or no security
updates. That's all fine.

What's not fine though is people holding the rest of us back with their
negativity and FUD that Python 3 is a mistake.


-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Mark Lawrence

On 08/01/2014 13:01, Steven D'Aprano wrote:

Martijn Faassen wrote:


I also argue that for those projects to move anywhere, they need a
clear, blessed, official, as simple as possible, incremental upgrade
path. That's why I argue for a Python 2.8.


That incremental upgrade path is Python 2.7.

Remember, when Python 3 first came out, the current version of Python was
2.5. 2.6 came out roughly simultaneously with Python 3. So the expected
upgrade path is:


Bleeding edge adaptors:
2.5 - 3.0

Early adaptors:
2.5 - 2.6 - 3.1 or 3.2

Slower adaptors:
2.5 - 2.6 - 2.7 - 3.3 or 3.4

Late adaptors:
2.5 - 2.6 - 2.7 - 3.5 (expected to be about 18-24 months)

Laggards who wait until support for 2.7 is dropped:
2.5 - 2.6 - 2.7 - 3.6 or 3.7

Adding 2.8 doesn't help. It just gives people another excuse to delay
migrating. Then, in another two or three years, they'll demand 2.9, and put
it off again. Then they'll insist that 15 years wasn't long enough to
migrate their code, and demand 2.10.

I have no objection to people delaying migrating. There were lots of risks
and difficulties in migrating to 3.1 or 3.2, there are fewer risks and
difficulties in migrating to 3.3 and 3.4, and there will be even fewer by
the time 3.5 and 3.6 come out. People should migrate when they are
comfortable. They may even decide to stick to 2.7 for as long as they can
find a computer capable of running it, security updates or no security
updates. That's all fine.

What's not fine though is people holding the rest of us back with their
negativity and FUD that Python 3 is a mistake.




Big +1 from me to all the above.

--
My fellow Pythonistas, ask not what our language can do for you, ask 
what you can do for our language.


Mark Lawrence

--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Mark Lawrence

On 08/01/2014 12:36, Martijn Faassen wrote:

Hi there,

On 01/07/2014 06:00 PM, Chris Angelico wrote:

I'm still not sure how Python 2.8 needs to differ from 2.7. Maybe the
touted upgrade path is simply a Python 2.7 installer plus a few handy
libraries/modules that will now be preinstalled? These modules look
great (I can't say, as I don't have a huge Py2 codebase to judge based
on), and they presumably work on the existing Pythons.


Well, in the original article I argue that it may be risky for the
Python community to leave the large 2.7 projects behind because they
tend to be the ones that pay us in the end.

I also argue that for those projects to move anywhere, they need a
clear, blessed, official, as simple as possible, incremental upgrade
path. That's why I argue for a Python 2.8.

Pointing out the 'future' module is existence proof that further
incremental steps could be taken on top of what Python 2.7 already does.

I may be that these points are wrong or should be weighed differently.
It's possible that:

* the risk of losing existing big 2.x projects is low, they'll port
anyway, the money will keep flowing into our community, they won't look
at other languages, etc.

* these big 2.x projects are going to all find the 'future' module
themselves and use it as incremental upgrade path, so there's no need
for a new blessed Python 2.x.

* the approach of the 'future' module turns out to be fatally flawed
and/or doesn't really help with incremental upgrades after all.

But that's how I reason about it, and how I weigh things. I think the
current strategy is risky.

Regards,

Martijn



My understanding is that 95% of core developers won't work on 2.8, 
partly I suspect because of the massive overhead they've already had to 
do supporting 2 and 3 in parellel.  Assuming that I'm correct, who is 
going to do the work involved, you Martijn?


--
My fellow Pythonistas, ask not what our language can do for you, ask 
what you can do for our language.


Mark Lawrence

--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Roy Smith
As somebody who is still firmly in the 2.x world, I'm worried about the 
idea of a 2.x fork.  While I have my doubts that 3.x was a good idea, 
the fact is, it's here.  Having the community fractured between the two 
camps is not good.  Let's say I'm somebody who wants to contribute some 
OSS.  I have three basic choices:

1) I can make it 3.x only.  Now, (nominally) half of the python 
community is unable to realize value from my contribution.

2) I can make it 2.x only.  Same thing in reverse.

3) I can make it work on both 2.x and 3.x, which means I'm investing 
more effort than I had to if it were single platform.

Any of those alternatives is worse than ideal.  Forking 2.x to create an 
unofficial 2.8 release would just prolong the situation.  As I've stated 
before, I don't see any urgency in moving to 3.x, and don't imagine 
doing there for another couple of years, but I absolutely can't imagine 
moving to a 2.8 fork.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Mark Lawrence

On 08/01/2014 14:15, Roy Smith wrote:

As somebody who is still firmly in the 2.x world, I'm worried about the
idea of a 2.x fork.  While I have my doubts that 3.x was a good idea,
the fact is, it's here.  Having the community fractured between the two
camps is not good.  Let's say I'm somebody who wants to contribute some
OSS.  I have three basic choices:

1) I can make it 3.x only.  Now, (nominally) half of the python
community is unable to realize value from my contribution.

2) I can make it 2.x only.  Same thing in reverse.

3) I can make it work on both 2.x and 3.x, which means I'm investing
more effort than I had to if it were single platform.

Any of those alternatives is worse than ideal.  Forking 2.x to create an
unofficial 2.8 release would just prolong the situation.  As I've stated
before, I don't see any urgency in moving to 3.x, and don't imagine
doing there for another couple of years, but I absolutely can't imagine
moving to a 2.8 fork.



The above strikes me as common sense.  Surely that's out of place on 
this list? :)


But to be serious why not stick with 2.x if there's no compelling reason 
to move?  Whatever happened to if it ain't broke, don't fix it?  And 
before anyone says anything please don't start on about the bytes versus 
string debate, I'm fairly certain that there are a substantial number of 
application areas that don't run into these problems.


--
My fellow Pythonistas, ask not what our language can do for you, ask 
what you can do for our language.


Mark Lawrence

--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Pedro Larroy
I think for new projects one should go with 3.x this is the right thing to
do. If you require a module that's 2.x only it's easy enough to port it
unless it depends on some monster like protobuf which doesn't have
python3.x support


Pedro.


On Wed, Jan 8, 2014 at 3:30 PM, Mark Lawrence breamore...@yahoo.co.ukwrote:

 On 08/01/2014 14:15, Roy Smith wrote:

 As somebody who is still firmly in the 2.x world, I'm worried about the
 idea of a 2.x fork.  While I have my doubts that 3.x was a good idea,
 the fact is, it's here.  Having the community fractured between the two
 camps is not good.  Let's say I'm somebody who wants to contribute some
 OSS.  I have three basic choices:

 1) I can make it 3.x only.  Now, (nominally) half of the python
 community is unable to realize value from my contribution.

 2) I can make it 2.x only.  Same thing in reverse.

 3) I can make it work on both 2.x and 3.x, which means I'm investing
 more effort than I had to if it were single platform.

 Any of those alternatives is worse than ideal.  Forking 2.x to create an
 unofficial 2.8 release would just prolong the situation.  As I've stated
 before, I don't see any urgency in moving to 3.x, and don't imagine
 doing there for another couple of years, but I absolutely can't imagine
 moving to a 2.8 fork.


 The above strikes me as common sense.  Surely that's out of place on this
 list? :)

 But to be serious why not stick with 2.x if there's no compelling reason
 to move?  Whatever happened to if it ain't broke, don't fix it?  And
 before anyone says anything please don't start on about the bytes versus
 string debate, I'm fairly certain that there are a substantial number of
 application areas that don't run into these problems.


 --
 My fellow Pythonistas, ask not what our language can do for you, ask what
 you can do for our language.

 Mark Lawrence

 --
 https://mail.python.org/mailman/listinfo/python-list

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Chris Angelico
On Thu, Jan 9, 2014 at 1:30 AM, Mark Lawrence breamore...@yahoo.co.uk wrote:
 But to be serious why not stick with 2.x if there's no compelling reason to
 move?  Whatever happened to if it ain't broke, don't fix it?  And before
 anyone says anything please don't start on about the bytes versus string
 debate, I'm fairly certain that there are a substantial number of
 application areas that don't run into these problems.

Two reasons for moving:

1) Support for newer hardware, underlying libraries, etc
2) Bug fixes and security patches.

#1 won't be a visible problem for most people - they'll be using a
Python packaged by their OS, so if there are any issues with building
Python against version X.Y of libfoobar, the OS maintainers will
either ship the older version of libfoobar, or make Python work. Only
a handful of people (the OS package maintainers themselves) will even
need to consider that. So it's #2 that people will be thinking about.
There's going to come a time when python.org will no longer provide
updates for Python 2.7, and at that point, everyone has to decide
which is greater: the risk of undiscovered flaws, or the hassle of
shifting. For most end users, they'll choose to stick with an
unsupported Python rather than shift, but there are those (corporates,
mainly) for whom a promise of bug fixes is critical, so that'd be
their date to shift. After all, it worked for Windows XP, right?
End-of-life date rolls around and everyone moves onto Windows 7
hmm, maybe that didn't quite happen. Still, it does put pressure on
people.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Martijn Faassen

On 01/08/2014 01:46 PM, Chris Angelico wrote:

On Wed, Jan 8, 2014 at 11:36 PM, Martijn Faassen faas...@startifact.com wrote:

Well, in the original article I argue that it may be risky for the Python
community to leave the large 2.7 projects behind because they tend to be the
ones that pay us in the end.

I also argue that for those projects to move anywhere, they need a clear,
blessed, official, as simple as possible, incremental upgrade path. That's
why I argue for a Python 2.8.

Pointing out the 'future' module is existence proof that further incremental
steps could be taken on top of what Python 2.7 already does.


Yep, but suppose it were simply that the future module is blessed as
the official, simple, incremental upgrade path. That doesn't violate
PEP 404, it allows the future module to continue to be expanded
without worrying about the PSF's schedules (more stuff might be added
to it in response to Python 3.5, but this is all in the hands of
future's maintainer), and it should be relatively simple to produce an
installer that goes and grabs it.


That would be better than nothing, but would break the: upgrade path 
should be totally obvious guideline. Also the core developers are 
generally not in the habit of blessing external projects except by 
taking them into the stdlib, so that'd be a first.



As Mark Rosewater is fond of saying, restrictions breed creativity.
Can the porting community take the PEP 404 restriction and be creative
within it? I suspect it'll go a long way.


How many actively maintained applications on Python 2.7 are being 
ported? Do we know? If not many, is this a problem? As problems also 
breed creativity.


Regards,

Martijn

--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Grant Edwards
On 2014-01-08, Chris Angelico ros...@gmail.com wrote:

 Two reasons for moving:

 1) Support for newer hardware

How does Python 3.x support newer hardware than Python 2.7?

-- 
Grant Edwards   grant.b.edwardsYow! Psychoanalysis??
  at   I thought this was a nude
  gmail.comrap session!!!
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Martijn Faassen

Hey,

I'm pointing out possible improvements that Python 2.8 could offer that 
would help incremental porting efforts of applications. I'm pointing 
about that helping application developers move forward incrementally may 
be a worthwhile consideration. Like, there's money there.


You can point out that 2.6 and 2.7 were already such releases, and I 
will then point out that many people *have* upgraded their applications 
to these releases. Is there now going to be a giant leap forward to 
Python 3 by these projects, or is the jump still too far? Opinions differ.


On 01/08/2014 02:01 PM, Steven D'Aprano wrote:

Adding 2.8 doesn't help. It just gives people another excuse to delay
migrating. Then, in another two or three years, they'll demand 2.9, and put
it off again. Then they'll insist that 15 years wasn't long enough to
migrate their code, and demand 2.10.


I can play this kind of rhetorical game too, including demands and such 
fun. Who is demanding who does what?


It's not really a surprise that people expect there to be a compatible 
release of a programming language. We'll have to see whether the demand 
for it is strong enough to tear out community apart, or whether all will 
be right in the end.



What's not fine though is people holding the rest of us back with their
negativity and FUD that Python 3 is a mistake.


That's not what I believe I've been doing. Though if people do this, is 
the Python community really so fragile it can't deal with a little bit 
of pushback?


What's not fine is that people who think all is well tell the people who 
disagree to shut up. Maybe we should introduce the concept of check 
your Python 3 privilege.


Regards,

Martijn

--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Martijn Faassen

Hey,

On 01/08/2014 03:30 PM, Mark Lawrence wrote:


But to be serious why not stick with 2.x if there's no compelling reason
to move?  Whatever happened to if it ain't broke, don't fix it?


That's fine for static applications that don't have to change.

Successful applications tend to grow new features over the years. It's 
not fun to do so if new capabilities are growing out of reach in Python 
3 land.


It's possible if enough features exist in Python 3 land bosses of 
successful applications will fund a port, with all the risks of 
introducing bugs that this entails. But a smoother upgrade path would 
help those applications more. And as I pointed out before, these 
applications are where a lot of money and development resources are 
coming from in our community.


Of course it's possible my assessment of the importance of these 
applications, their development resources, and the bump a Python 3 port 
presents for them, is off.


Regards,

Martijn


--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Chris Angelico
On Thu, Jan 9, 2014 at 2:06 AM, Grant Edwards invalid@invalid.invalid wrote:
 On 2014-01-08, Chris Angelico ros...@gmail.com wrote:

 Two reasons for moving:

 1) Support for newer hardware

 How does Python 3.x support newer hardware than Python 2.7?

At the moment, I would say there's no difference between those two
versions. But there was an issue a short while ago about OS X 10.9 and
the compilers/libraries available for it, which necessitated some
patches, and those patches would have been applied to all
currently-supported versions of Python. That means that 2.7 got them
(in 2.7.6 [1]), so it'll build nicely, but 2.6 won't have, so anyone
who wants to use 2.6 on 10.9 will have to manually backport that fix.
I mention hardware because there are times when the new hardware won't
run the old OS, the new OS won't work with the old compiler and/or
library, and the new compiler/library won't work with the old Python.
At that point, you have to either run a virtual machine (overkill) or
remain on the old hardware (hence, Python X.Y doesn't support your
hardware).

So long as 2.7 is being supported, there are no problems with this.
Same with the bug fixes and security patches that I mention in the
next line. Once it's out of support, though, both will cease (or they
might cease at different times), and then new hardware, new compilers,
new versions of required libraries, could cause problems. I elaborated
further down that these issues would be mainly dealt with by OS
package maintainers (I'm sure Red Hat have been doing this for years),
but they'll still be problems.

[1] http://www.python.org/download/releases/2.7.6/

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Chris Angelico
On Thu, Jan 9, 2014 at 2:22 AM, Martijn Faassen faas...@startifact.com wrote:
 I'm pointing out possible improvements that Python 2.8 could offer that
 would help incremental porting efforts of applications. I'm pointing about
 that helping application developers move forward incrementally may be a
 worthwhile consideration. Like, there's money there.

I'm not sure who's actually paying the PSF to develop a 2.8, so I'm
not sure why you can say there's money there. Are you offering? Or do
you have reason to believe someone else will?

 You can point out that 2.6 and 2.7 were already such releases, and I will
 then point out that many people *have* upgraded their applications to these
 releases. Is there now going to be a giant leap forward to Python 3 by these
 projects, or is the jump still too far? Opinions differ.

Still waiting for a solid suggestion as to what would actually be
different in 2.8 that can't be done with a module. If there's a really
brilliant module that massively eases the burden of porting, then
python.org / the PSF might well even add it to the stdlib, or at least
point people to it from the home page. That would make for an
excellent smooth upgrade path, dealing with the renamed modules and
so on, and it takes no language changes at all.

I'm pretty sure most people here are in broad agreement with your goal
of making it easy to migrate to Py3. What we're not seeing - or at
least, what I'm not seeing - is how a Python 2.8 would achieve that;
and what several of us ARE seeing is how a Python 2.8 actually makes
it harder.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Mark Lawrence

On 08/01/2014 15:39, Chris Angelico wrote:

On Thu, Jan 9, 2014 at 2:22 AM, Martijn Faassen faas...@startifact.com wrote:

I'm pointing out possible improvements that Python 2.8 could offer that
would help incremental porting efforts of applications. I'm pointing about
that helping application developers move forward incrementally may be a
worthwhile consideration. Like, there's money there.


I'm not sure who's actually paying the PSF to develop a 2.8, so I'm
not sure why you can say there's money there. Are you offering? Or do
you have reason to believe someone else will?



There can be £1,000,000 in the PSF kitty but if the core developers 
don't want to do the work it won't happen!!!


Personally I still think the whole idea of a 2.8 is nonsense that would 
only serve to divert already scarce resources.  Fixing some of the 4,000 
(?) open issues on the bug tracker would come higher up my list, 
particularly as some of them have been sitting there for ten years.  Or 
how about finally getting the new regex module into the standard library?


--
My fellow Pythonistas, ask not what our language can do for you, ask 
what you can do for our language.


Mark Lawrence

--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Terry Reedy

On 1/8/2014 9:15 AM, Roy Smith wrote:

As somebody who is still firmly in the 2.x world, I'm worried about the
idea of a 2.x fork.  While I have my doubts that 3.x was a good idea,
the fact is, it's here.  Having the community fractured between the two
camps is not good.  Let's say I'm somebody who wants to contribute some
OSS.  I have three basic choices:

1) I can make it 3.x only.  Now, (nominally) half of the python
community is unable to realize value from my contribution.

2) I can make it 2.x only.  Same thing in reverse.

3) I can make it work on both 2.x and 3.x, which means I'm investing
more effort than I had to if it were single platform.

Any of those alternatives is worse than ideal.  Forking 2.x to create an
unofficial 2.8 release would just prolong the situation.  As I've stated
before, I don't see any urgency in moving to 3.x, and don't imagine
doing there for another couple of years, but I absolutely can't imagine
moving to a 2.8 fork.


This question cannot be answered generically.

I think it worth noting that in part this is the same dilemma as 'how 
many versions to support' within each of 2.x and 3.x. Limiting code to 
3.3+ allows use of the new asyncio module (via Pypy for 3.3) and the new 
FSR unicode. Use of asyncio or FSR features* also forces the choice you 
give above as neither can be backported to 2.7.


* IE, support of all of unicode on all Python systems with 
straightforward code, without contortions.


If I were giving away 'stand-alone' application code whose dependencies 
were available on both 2.7 and 3.x+, I would write for 3.x+ on the basis 
that everyone could install 3.x, and that new users are increasingly 
likely to only have 3.x only. I would have little sympathy for 
organizations that prohibit 3.x -- unless they were to pay me to.


For numerical or combinatorial code, adding 'from __future__ import 
division' (which I think one should do anyway for 2.x code) might be the 
only extra work needed for option 3).


--
Terry Jan Reedy

--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Steven D'Aprano
Martijn Faassen wrote:

 Hey,
 
 I'm pointing out possible improvements that Python 2.8 could offer that
 would help incremental porting efforts of applications. I'm pointing
 about that helping application developers move forward incrementally may
 be a worthwhile consideration. Like, there's money there.

Why don't you grab it? If you think people will pay for somebody to backport
Python 3 to Python 2.8, just go ahead and do it and rake the money in.
Python is open source, you don't have to ask anyone's permission. The only
thing you may not be able to do is call it Python 2.8, but the name isn't
important.


 You can point out that 2.6 and 2.7 were already such releases, and I
 will then point out that many people *have* upgraded their applications
 to these releases. Is there now going to be a giant leap forward to
 Python 3 by these projects, or is the jump still too far? Opinions differ.

It's not a giant leap. 95% of the migration can be handled by a relatively
simple script, 2to3. The hardest part is supporting 2 *and* 3 in a single
project, but for end-user applications that target a single Python version,
rather than libraries and frameworks that target many different versions,
migrating is a once-off cost, and for most apps, not a large one.

Certainly much less than re-writing the app in another language.



-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Kevin Walzer

On 1/8/14, 9:30 AM, Mark Lawrence wrote:

But to be serious why not stick with 2.x if there's no compelling reason
to move?  Whatever happened to if it ain't broke, don't fix it?  And
before anyone says anything please don't start on about the bytes versus
string debate, I'm fairly certain that there are a substantial number of
application areas that don't run into these problems.


+1 to this.

I haven't updated my Python apps to 3.x because there's nothing in 3.x 
that offers benefits to my users.


I deal with constant API churn as a Mac developer. I have no interest in 
adding to this complexity and headaches by switching from 2.x to 3.x.


I imagine I'll update someday, but not anytime soon.

--Kevin

--
Kevin Walzer
Code by Kevin/Mobile Code by Kevin
http://www.codebykevin.com
http://www.wtmobilesoftware.com
--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Roy Smith
In article laknps$umv$1...@dont-email.me,
 Kevin Walzer k...@codebykevin.com wrote:

 I haven't updated my Python apps to 3.x because there's nothing in 3.x 
 that offers benefits to my users.

I almost found a reason to move to Python 3 today.  Then I got smacked.

I had a datetime.  I needed a unix timestamp.  People need to go back 
and forth between these two things all the time and in Python 2 it's the 
very definition of impedance mismatch.  What should be a dead simple 
operation involves long threads on stackoverflow discussing which of 
several amalgamations of duct tape is the least ugly.

Anyway, I discovered that Python 3.3's datetime has a .timestamp() 
method.  Yeah.  Finally.  Exactly what the world had needed for years.  
Then I kept reading and found:

Note: There is no method to obtain the POSIX timestamp directly from a 
naive datetime instance representing UTC time.

Ugh.  So, we're back to square one.  They go on to suggest one of two 
workarounds, either calling datetime.replace() to insert a timezone, or 
subtracting from the epoch manually.

Naive datetimes are what everybody uses.  It's what utcnow() gives you.  
So why make life difficult for everybody?  Python 3 didn't win a convert 
today.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Chris Angelico
On Thu, Jan 9, 2014 at 12:27 PM, Roy Smith r...@panix.com wrote:
 Anyway, I discovered that Python 3.3's datetime has a .timestamp()
 method.  Yeah.  Finally.  Exactly what the world had needed for years.
 Then I kept reading and found:

 Note: There is no method to obtain the POSIX timestamp directly from a
 naive datetime instance representing UTC time.

In my experiments (admittedly with 3.4, not 3.3, but I don't know that
there's any difference), I was able to round-trip a time_t through
datetime with no problems. Why not simply use a UTC datetime instead
of a naive one? What do you gain by using a naive datetime? You seem
to know what timezone it's in anyway.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Ethan Furman

On 01/08/2014 05:27 PM, Roy Smith wrote:

In article laknps$umv$1...@dont-email.me,
  Kevin Walzer k...@codebykevin.com wrote:


I haven't updated my Python apps to 3.x because there's nothing in 3.x
that offers benefits to my users.


I almost found a reason to move to Python 3 today.  Then I got smacked.


[snip]


Naive datetimes are what everybody uses.  It's what utcnow() gives you.
So why make life difficult for everybody?  Python 3 didn't win a convert
today.


Naive datetimes suffer from the same problem as the old str/unicode problems: as soon as you try to mix different 
timezone datetimes that are naive, you have a mess (temporal-bake, anyone?).


--
~Ethan~
--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Chris Angelico
On Thu, Jan 9, 2014 at 12:52 PM, Ethan Furman et...@stoneleaf.us wrote:
 as soon as you try to mix different timezone datetimes that are naive, you
 have a mess (temporal-bake, anyone?).

Doctor Who gets into cookies?

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Roy Smith
In article mailman.5222.1389232077.18130.python-l...@python.org,
 Chris Angelico ros...@gmail.com wrote:

 Why not simply use a UTC datetime instead of a naive one?

[Pet peeve of mine: uses of simple or just to imply that something 
is easy, when it's not.  Why not just get the Arabs and the Jews to be 
friends?  Why not simply find a safe way to store nuclear waste?]

Because it's easy to get a naive one.  You call datetime.utcnow().  If 
utcnow() returned an aware datetime, that's probably what we would be 
using.  Why didn't utcnow() just return an aware datetime to begin with?

Conversely, it's a pain in the butt to get an aware one.  As far as I 
can tell, you have to do something like:

utcnow().replace(tzinfo=pytz.utc)

which is not only ugly, but requires installing a third-party module 
(pytz) to get the UTC timezone definition.

Not to mention, our database (mongodb), doesn't support storing aware 
datetimes.  I can insert a document with an aware datetime, but when I 
retrieve that document, I get back a naive one.  I don't know what other 
databases do.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Chris Angelico
On Thu, Jan 9, 2014 at 1:25 PM, Roy Smith r...@panix.com wrote:
 Because it's easy to get a naive one.  You call datetime.utcnow().  If
 utcnow() returned an aware datetime, that's probably what we would be
 using.  Why didn't utcnow() just return an aware datetime to begin with?

 Conversely, it's a pain in the butt to get an aware one.  As far as I
 can tell, you have to do something like:

 utcnow().replace(tzinfo=pytz.utc)

 which is not only ugly, but requires installing a third-party module
 (pytz) to get the UTC timezone definition.

What's datetime.today() give you? I'm not experienced with the module,
but a glance at the docs and then a quick try interactively suggests
that this might be what you need.

But even so, the problem is not why can't naive timestamps do
everything I want. The problem is why is it so hard to get an aware
timestamp for the current instant. And if you ask *that* question,
then there's likely to be an answer. I might be wrong with my
suggestion above, and maybe there isn't even any answer right now, but
there certainly could be.

Yes, it *is* simple. It *is* easy. I've been working with pure-UTC
times (either called time_t, or TIMESTAMP WITH TIME ZONE, or even just
float) for decades. Like with so many other things, the easiest
solution is also the best, because you can just work with one stable
representation and abstraction on the inside, with conversions to/from
it at the boundaries. It IS that easy.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Ben Finney
Chris Angelico ros...@gmail.com writes:

 On Thu, Jan 9, 2014 at 1:25 PM, Roy Smith r...@panix.com wrote:
  Because it's easy to get a naive one. You call datetime.utcnow(). If
  utcnow() returned an aware datetime, that's probably what we would
  be using. Why didn't utcnow() just return an aware datetime to begin
  with?
[…]

 But even so, the problem is not why can't naive timestamps do
 everything I want. The problem is why is it so hard to get an aware
 timestamp for the current instant. And if you ask *that* question,
 then there's likely to be an answer.

I think Roy's question hits close to a related problem: that the
standard library makes it easy to do a sub-optimal thing, and the
behaviour we all agree is best is not the default.

So, two questions are raised. One is what you've correctly identified:
“Why is it so hard to get an aware timestamp for the current instant?”
The short answer is: because doing that requires a lookup into a
frequently-updated database, which (because it's so frequently updated)
isn't installed along with Python.

The other is: “Why is the default behaviour from the standard library
doing something which I later discover is the wrong thing to do?” The
answer to that is, of course, related to the first one: the right thing
to do isn't currently feasible by default. Not a very satisfactory
answer, but nevertheless a situation we need to deal with today.

 Yes, it *is* simple. It *is* easy. I've been working with pure-UTC
 times (either called time_t, or TIMESTAMP WITH TIME ZONE, or even just
 float) for decades. Like with so many other things, the easiest
 solution is also the best, because you can just work with one stable
 representation and abstraction on the inside, with conversions to/from
 it at the boundaries. It IS that easy.

The difficulty isn't in doing the right thing; the difficulty is in
doscovering that the default behaviour is sub-optimal and then learning
what, exactly *is* the right thing to do.

The right behaviour is easy, but it's not default, and it's not obvious,
and it's a difficult learning process to differentiate the right thing
to do from the several competing easier-to-understand but wrong things.

So, I think you're both correct. The messiness of getting to the right
behaviour is highly obnoxious and technically unnecessary, if only the
bureaucrats and politicians would give up trying to make their mark on
time zones URL:https://www.youtube.com/watch?v=-5wpm-gesOY.

With time zones, as with text encodings, there is a single technically
elegant solution (for text: Unicode; for time zones: twelve simple,
static zones that never change) that would work for the whole world if
we could just be free to sweep away all the messy legacy crap and expect
people to stop complicating the matter further.

Until that day comes, though, we as programmers need to learn this messy
arbitrary crap, at least to the point of knowing unambiguously what we
ask the computer to do when it interacts with the messy real world.

-- 
 \   “I prayed for twenty years but received no answer until I |
  `\  prayed with my legs.” —Frederick Douglass, escaped slave |
_o__)  |
Ben Finney

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Roy Smith
In article mailman.5226.1389237436.18130.python-l...@python.org,
 Chris Angelico ros...@gmail.com wrote:

 On Thu, Jan 9, 2014 at 1:25 PM, Roy Smith r...@panix.com wrote:
  Because it's easy to get a naive one.  You call datetime.utcnow().  If
  utcnow() returned an aware datetime, that's probably what we would be
  using.  Why didn't utcnow() just return an aware datetime to begin with?
 
  Conversely, it's a pain in the butt to get an aware one.  As far as I
  can tell, you have to do something like:
 
  utcnow().replace(tzinfo=pytz.utc)
 
  which is not only ugly, but requires installing a third-party module
  (pytz) to get the UTC timezone definition.
 
 What's datetime.today() give you?

It almost gives you an aware UTC datetime.  Other than it being naive, 
and being in local time, that is :-)

 But even so, the problem is not why can't naive timestamps do
 everything I want. The problem is why is it so hard to get an aware
 timestamp for the current instant. And if you ask *that* question,
 then there's likely to be an answer.

You asked,  Why not simply use a UTC datetime instead
of a naive one?  My answer is that it's not simple at all.

 Yes, it *is* simple. It *is* easy. I've been working with pure-UTC
 times (either called time_t, or TIMESTAMP WITH TIME ZONE, or even just
 float) for decades. Like with so many other things, the easiest
 solution is also the best, because you can just work with one stable
 representation and abstraction on the inside, with conversions to/from
 it at the boundaries. It IS that easy.

Please show me the simple code to obtain an aware UTC datetime 
representing the current time.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Chris Angelico
On Thu, Jan 9, 2014 at 2:34 PM, Ben Finney ben+pyt...@benfinney.id.au wrote:
 [ a bunch of stuff that I totally agree with ]

No response needed here :)

So I was wrong on the specific example of .today(), but asking the
question the other way is at least helpful. Maybe the best solution is
exactly what Roy already posted, or maybe there's some other way to
achieve that. In any case, there is a solution, albeit not as clean as
I would have liked.

 With time zones, as with text encodings, there is a single technically
 elegant solution (for text: Unicode; for time zones: twelve simple,
 static zones that never change)

Twelve or twenty-four? Or are you thinking we should all be an even
number of hours away from UTC, which would also work?

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Roy Smith
In article mailman.5227.1389238511.18130.python-l...@python.org,
 Ben Finney ben+pyt...@benfinney.id.au wrote:

 Chris Angelico ros...@gmail.com writes:
 
  On Thu, Jan 9, 2014 at 1:25 PM, Roy Smith r...@panix.com wrote:
   Because it's easy to get a naive one. You call datetime.utcnow(). If
   utcnow() returned an aware datetime, that's probably what we would
   be using. Why didn't utcnow() just return an aware datetime to begin
   with?
 […]
 
  But even so, the problem is not why can't naive timestamps do
  everything I want. The problem is why is it so hard to get an aware
  timestamp for the current instant. And if you ask *that* question,
  then there's likely to be an answer.
 
 I think Roy's question hits close to a related problem: that the
 standard library makes it easy to do a sub-optimal thing, and the
 behaviour we all agree is best is not the default.
 
 So, two questions are raised. One is what you've correctly identified:
 “Why is it so hard to get an aware timestamp for the current instant?”
 The short answer is: because doing that requires a lookup into a
 frequently-updated database, which (because it's so frequently updated)
 isn't installed along with Python.

We have a call in the standard library named utcnow().  That shouldn't 
require a lookup in a database.  I'm sorry, which value of zero did you 
want?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Chris Angelico
On Thu, Jan 9, 2014 at 2:35 PM, Roy Smith r...@panix.com wrote:
 Yes, it *is* simple. It *is* easy. I've been working with pure-UTC
 times (either called time_t, or TIMESTAMP WITH TIME ZONE, or even just
 float) for decades. Like with so many other things, the easiest
 solution is also the best, because you can just work with one stable
 representation and abstraction on the inside, with conversions to/from
 it at the boundaries. It IS that easy.

 Please show me the simple code to obtain an aware UTC datetime
 representing the current time.

In Pike:
time();

In PostgreSQL:
SELECT now();

In C:
time(0);

All of these give a value in UTC. The PostgreSQL one gives it to you
as a TIMESTAMP WITH TIME ZONE, the others just as a simple value. I
don't know how they go about figuring out what UTC is, on systems
where the computer clock is in local time (eg Windows), but figure out
they do. It might be expensive but it's done somehow. (Easiest way to
check timezone in C is to look at what time(0)%86400/3600 is - that
should be the hour-of-day in UTC, which as I type is 3. And it is.)

I don't know how to do it in Python because I'm not familiar with the
datetime module. But time.time() returns a value in UTC, which is
verifiable by the above method:

 int(time.time())%86400//3600
3

So maybe the key is to use utcfromtimestamp()? I don't know. My
personal preference would be to simply use either int or float
everywhere (float if you need subsecond resolution, int if you're
concerned about massively past or future timestamps), and then
translate to something else for display. Effectively, instead of
working with a datetime object, I would just work with an alternative
representation of instant-in-time which is simply seconds since 1970
(dealing with leap seconds whichever way you like). If the datetime
module causes you pain, don't use it.

Ben, if it's that expensive to get an aware timestamp, why does
time.time() effectively do that? Is it a much more expensive call?

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Roy Smith
In article mailman.5231.1389240235.18130.python-l...@python.org,
 Chris Angelico ros...@gmail.com wrote:

 On Thu, Jan 9, 2014 at 2:35 PM, Roy Smith r...@panix.com wrote:
  Yes, it *is* simple. It *is* easy. I've been working with pure-UTC
  times (either called time_t, or TIMESTAMP WITH TIME ZONE, or even just
  float) for decades. Like with so many other things, the easiest
  solution is also the best, because you can just work with one stable
  representation and abstraction on the inside, with conversions to/from
  it at the boundaries. It IS that easy.
 
  Please show me the simple code to obtain an aware UTC datetime
  representing the current time.
 
 In Pike:
 time();
 
 In PostgreSQL:
 SELECT now();
 
 In C:
 time(0);
 
 All of these give a value in UTC.

None of which answer my question.  How, in Python, do you get an aware 
UTC datetime object?  I know how to get a numeric representation of the 
time as the number of seconds since the Unix epoch.  That's not what I 
asked.

 So maybe the key is to use utcfromtimestamp()? I don't know.

So, I'm really confused what point you're trying to make.  You started 
out arguing that I should be using aware datetimes instead of naive 
datetimes.  I said that the reason I don't use aware datetimes is 
because they're so much more difficult to generate.  You said they were 
simple to generate.

So, I'd like to see your code which generates an aware UTC datetime 
object in Python.  And then we can argue about whether it's simple or 
not :-)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Chris Angelico
On Thu, Jan 9, 2014 at 3:29 PM, Roy Smith r...@panix.com wrote:
 So, I'd like to see your code which generates an aware UTC datetime
 object in Python.  And then we can argue about whether it's simple or
 not :-)

Like I said, I don't use the datetime module. But fundamentally, an
aware datetime represents an instant in time - which is exactly what a
POSIX timestamp (time_t) represents. So I can't offer exact code for
working with them, other than to say that time.time() is precisely
accomplishing the same job. Maybe there needs to be a recipe posted
somewhere saying To create a datetime from a POSIX time, do this.

This is simple:

 time.time()
1389242048.669482

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Chris Angelico
On Thu, Jan 9, 2014 at 3:29 PM, Roy Smith r...@panix.com wrote:
 So, I'd like to see your code which generates an aware UTC datetime
 object in Python.  And then we can argue about whether it's simple or
 not :-)

In fact, I'll go further. Why do you need a datetime object at all?
What is it that you need? Arithmetic can be done with int and/or
float, parsing and formatting can be done with time.str[pf]time, etc,
etc. It's like if someone asks How can I build a regular expression
that will tell me if a string is valid JSON?. The question poses a
restriction that may be unnecessary, and may eliminate all possible
answers.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Ethan Furman

On 01/08/2014 08:34 PM, Chris Angelico wrote:

On Thu, Jan 9, 2014 at 3:29 PM, Roy Smith r...@panix.com wrote:

So, I'd like to see your code which generates an aware UTC datetime
object in Python.  And then we can argue about whether it's simple or
not :-)


Like I said, I don't use the datetime module. But fundamentally, an
aware datetime represents an instant in time - which is exactly what a
POSIX timestamp (time_t) represents. So I can't offer exact code for
working with them, other than to say that time.time() is precisely
accomplishing the same job. Maybe there needs to be a recipe posted
somewhere saying To create a datetime from a POSIX time, do this.

This is simple:


time.time()

1389242048.669482


I agree, and I'm sure Roy also agrees, that that is simple.  However, that is *not* a timezone-aware datetime.  The 
point of having the datetime module is so we all don't have to reroll our own from scratch, and yet this particular (and 
increasingly important) operation wasn't intuitive nor easy.



http://docs.python.org/dev/library/datetime.html?highlight=datetime#datetime.tzinfo
===

class datetime.tzinfo

An abstract base class for time zone information objects. These are used by the datetime and time classes to 
provide a customizable notion of time adjustment (for example, to account for time zone and/or daylight saving time).


class datetime.timezone

A class that implements the tzinfo abstract base class as a fixed offset 
from the UTC.

New in version 3.2.

Objects of these types are immutable.

Objects of the date type are always naive.

An object of type time or datetime may be naive or aware. A datetime object d is aware if d.tzinfo is not None and 
d.tzinfo.utcoffset(d) does not return None. If d.tzinfo is None, or if d.tzinfo is not None but d.tzinfo.utcoffset(d) 
returns None, d is naive. A time object t is aware if t.tzinfo is not None and t.tzinfo.utcoffset(None) does not return 
None. Otherwise, t is naive.

===

That is not simple.

This however, may qualify (emphasis added):
===
classmethod datetime.utcnow()

Return the current UTC date and time, with tzinfo None. This is like now(), but returns the current UTC date and 
time, as a naive datetime object. An aware current UTC datetime can be obtained by calling *datetime.now(timezone.utc)*. 
See also now().

===

It looks like the .fromtimestamp also accepts tz=timezone.utc, so perhaps that is the simple way to get the timezone 
aware datetime.  I haven't tested, I'm going to bed.  :/


--
~Ethan~
--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Chris Angelico
On Thu, Jan 9, 2014 at 4:31 PM, Ethan Furman et...@stoneleaf.us wrote:
 On 01/08/2014 08:34 PM, Chris Angelico wrote:

 This is simple:

 time.time()

 1389242048.669482


 I agree, and I'm sure Roy also agrees, that that is simple.  However, that
 is *not* a timezone-aware datetime.  The point of having the datetime module
 is so we all don't have to reroll our own from scratch, and yet this
 particular (and increasingly important) operation wasn't intuitive nor easy.

What exactly does datetime offer you that a timestamp doesn't? Can we
get a quick run-down, please?

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Ben Finney
Chris Angelico ros...@gmail.com writes:

 What exactly does datetime offer you that a timestamp doesn't? Can we
 get a quick run-down, please?

Isn't this answered by you reading the standard library documentation
for the ‘datetime’ and ‘time’ modules? Are you asking for someone to
read those for you? If not, can you explain more precisely what you're
asking?

-- 
 \ “A child of five could understand this. Fetch me a child of |
  `\  five.” —Groucho Marx |
_o__)  |
Ben Finney

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Mark Lawrence

On 09/01/2014 03:42, Chris Angelico wrote:

On Thu, Jan 9, 2014 at 2:34 PM, Ben Finney ben+pyt...@benfinney.id.au wrote:

[ a bunch of stuff that I totally agree with ]


No response needed here :)

So I was wrong on the specific example of .today(), but asking the
question the other way is at least helpful. Maybe the best solution is
exactly what Roy already posted, or maybe there's some other way to
achieve that. In any case, there is a solution, albeit not as clean as
I would have liked.


With time zones, as with text encodings, there is a single technically
elegant solution (for text: Unicode; for time zones: twelve simple,
static zones that never change)


Twelve or twenty-four? Or are you thinking we should all be an even
number of hours away from UTC, which would also work?

ChrisA



I don't care what anyone says, I'm sticking with GMT.  (UTC == 
Universal Coordinated Time) == False.  And what the hell *IS* 
coordinated?  If that was the case this part of this thread wouldn't 
exist :)


Perhaps the solution is the Chinese way, don't have timezones at all.

--
My fellow Pythonistas, ask not what our language can do for you, ask 
what you can do for our language.


Mark Lawrence

--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-08 Thread Chris Angelico
On Thu, Jan 9, 2014 at 5:57 PM, Ben Finney ben+pyt...@benfinney.id.au wrote:
 Chris Angelico ros...@gmail.com writes:

 What exactly does datetime offer you that a timestamp doesn't? Can we
 get a quick run-down, please?

 Isn't this answered by you reading the standard library documentation
 for the ‘datetime’ and ‘time’ modules? Are you asking for someone to
 read those for you? If not, can you explain more precisely what you're
 asking?

Sorry. I'm more specifically asking what Roy's using, here. I can see
what functions it offers, so my language was a bit sloppy. What I
meant is: What can you (Roy), with your use-case, achieve with
datetime that you can't achieve (at least reasonably easily) with a
timestamp? Nobody ever uses every feature of a module, and I often see
people using some library/module/function when they could be using a
simpler and easier base function (like using JQuery for basic web page
scripting).

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-07 Thread Martijn Faassen

On 01/07/2014 01:19 AM, Chris Angelico wrote:


Can we get a run-down of everything that actually must be broken in
2.7 - 3.3, that can't be backported via __future__, so we can start
cherry-picking which bits to break in 2.8? The biggest one is going to
be Unicode strings, for a large number of people (the print statement
and division operators can be __future__'d, lots of other stuff got
backported into 2.7). I'd be prepared to bet money that that one will
NOT be broken in 2.8, meaning that it achieves nothing on that score.
So how much easier will the migration actually be?


That's a good question. I envision support for per-module upgrades, 
though I'm not 100% sure that it would work. This way a large project 
can incrementally start porting modules to the Python 3 unicode behavior.


The 'future' module (python-future.org) effectively backports the Python 
3 str and bytes into Python 2.7. The question is then what happens when 
they interact with Python 2 str and unicode.


I'm speculating about the behavior of the 'future' module here, but 
here's what I could imagine.


First the Python 3 behavior:

py3str + py3str = py3str

py3bytes + py3bytes = py3bytes

py3str + py3bytes = error

Then the behavior of when Python 3 str/bytes are mixed with Python 2 str 
and unicode:


py3str + py2unicode = py2unicode

py3str + py2str = py2unicode

py3bytes + py2str = py2str

Plus the regular old Python 2 behavior.

I'm quite sure I could be getting something wrong; it's only a few days 
since I saw 'future' and started thinking along these lines.


Regards,

Martijn

--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-07 Thread Martijn Faassen

Hi there,

I just tried this out with the future module to see what it actually 
does, and I got this:


On 01/07/2014 01:54 PM, Martijn Faassen wrote:


First the Python 3 behavior:

py3str + py3str = py3str


Yup, of course.


py3bytes + py3bytes = py3bytes


Again of course.


py3str + py3bytes = error


Yup, that's an error.


Then the behavior of when Python 3 str/bytes are mixed with Python 2 str
and unicode:

py3str + py2unicode = py2unicode


This didn't work as I expected; I'd have expected py2unicode for 
compatibility reasons, as py3str cannot be combined with py2str (but in 
fact it *can*, odd).



py3str + py2str = py2unicode


This in fact returns py3str, which I didn't expect either.


py3bytes + py2str = py2str


And this gets me py3bytes.

I'll get in touch with the author of the 'future' module to try to 
understand why his reasoning is different from mine, i.e. where I'm wrong.


Regards,

Martijn


--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-07 Thread Martijn Faassen

Hi,

I've posted a documentation issue to the 'future' module which includes 
a further evolution of my thinking. As I expected, the author of the 
'future' module has thought this through more than I had:


https://github.com/PythonCharmers/python-future/issues/27

To get back to a hypothetical Python 2.8, it could implement this kind 
of behavior, and I think it would help support incremental upgrades. As 
long as you're using Py 3 bytes and str in your code, you'll be aware of 
errors and be forced to think about it. Other Python code in the system 
can remain unchanged, and to the magic of ducktyping will continue to 
work. You can then tackle things incrementally.


Regards,

Martijn

--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-07 Thread Chris Angelico
On Wed, Jan 8, 2014 at 3:42 AM, Martijn Faassen faas...@startifact.com wrote:
 To get back to a hypothetical Python 2.8, it could implement this kind of
 behavior, and I think it would help support incremental upgrades. As long as
 you're using Py 3 bytes and str in your code, you'll be aware of errors and
 be forced to think about it. Other Python code in the system can remain
 unchanged, and to the magic of ducktyping will continue to work. You can
 then tackle things incrementally.

I'm still not sure how Python 2.8 needs to differ from 2.7. Maybe the
touted upgrade path is simply a Python 2.7 installer plus a few handy
libraries/modules that will now be preinstalled? These modules look
great (I can't say, as I don't have a huge Py2 codebase to judge based
on), and they presumably work on the existing Pythons.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-06 Thread Mark Janssen
 http://blog.startifact.com/posts/python-2-gravity.html

 A Way Forward - How to go forward then? I think it makes sense to work as
 hard as possible to lift those Python 2 codebases out of the gravity well.

 I think this is complete nonsense.  There's only been five years since the
 first release of Python 3.  Surely much more time should be made available
 for people using Python 2 to plan for a migration?

What makes no sense is that you've started a whole 'nother thread on
an issue whose gravity is right here, already on the list.  Add your
new commentary and links to existing threads would be easier, yes?

Mark unLawrence
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-06 Thread Mark Lawrence

On 06/01/2014 19:41, Mark Janssen wrote:

http://blog.startifact.com/posts/python-2-gravity.html

A Way Forward - How to go forward then? I think it makes sense to work as
hard as possible to lift those Python 2 codebases out of the gravity well.

I think this is complete nonsense.  There's only been five years since the
first release of Python 3.  Surely much more time should be made available
for people using Python 2 to plan for a migration?


What makes no sense is that you've started a whole 'nother thread on
an issue whose gravity is right here, already on the list.  Add your
new commentary and links to existing threads would be easier, yes?



I've just had a really good chuckle reading that coming from you.  Got 
the new dealer yet?


--
My fellow Pythonistas, ask not what our language can do for you, ask 
what you can do for our language.


Mark Lawrence

--
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-06 Thread Chris Angelico
On Tue, Jan 7, 2014 at 6:26 AM, Mark Lawrence breamore...@yahoo.co.uk wrote:
 http://blog.startifact.com/posts/python-2-gravity.html

 A Way Forward - How to go forward then? I think it makes sense to work as
 hard as possible to lift those Python 2 codebases out of the gravity well.

 I think this is complete nonsense.  There's only been five years since the
 first release of Python 3.  Surely much more time should be made available
 for people using Python 2 to plan for a migration?

And to make it even more obvious, we need Python 2.x releases where
the deprecated stuff is removed, incrementally. Breaking code is
making it as obvious as you can get! But you don't want to break it
all at once, because then people will be inclined to give up before
they even start.

Suppose there's a Python 2.8 that breaks just some of the things that
might break in 2.7-3.3 migration. What does it achieve?

1) Everything that has to be fixed before moving onto 3.3+ will still
need to be fixed.
2) Instead of ONE code-breaking shift with a major version number to
highlight it, there are now TWO code-breaking shifts.

Can we get a run-down of everything that actually must be broken in
2.7 - 3.3, that can't be backported via __future__, so we can start
cherry-picking which bits to break in 2.8? The biggest one is going to
be Unicode strings, for a large number of people (the print statement
and division operators can be __future__'d, lots of other stuff got
backported into 2.7). I'd be prepared to bet money that that one will
NOT be broken in 2.8, meaning that it achieves nothing on that score.
So how much easier will the migration actually be?

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-06 Thread Devin Jeanpierre
On Mon, Jan 6, 2014 at 4:19 PM, Chris Angelico ros...@gmail.com wrote:
 Can we get a run-down of everything that actually must be broken in
 2.7 - 3.3, that can't be backported via __future__, so we can start
 cherry-picking which bits to break in 2.8? The biggest one is going to
 be Unicode strings, for a large number of people (the print statement
 and division operators can be __future__'d, lots of other stuff got
 backported into 2.7). I'd be prepared to bet money that that one will
 NOT be broken in 2.8, meaning that it achieves nothing on that score.
 So how much easier will the migration actually be?

Actually, this brings up something I'm unsure of. Is there any change
that can't, in theory, be put into __future__, so that if every module
in your project and its transitive dependencies imports everything
from __future__, it can run on Python 3 without changes, and where it
is realistically feasible to allow different modules to have different
things they import from __future__?

For example, I imagine that it is kind of _silly_ to have a
__future__.disable_str_autoencoding on a per-module basis, because
some modules' functions will fail when they are given the wrong type,
and some won't -- but in the context of making migration easier, that
silliness is probably OK. More fundamental is probably that it can't
actually be done easily or without serious performance penalties (e.g.
the relevant string method would have to look up the callstack to see
if its direct caller came from a module which enabled that future
feature).

I'm not sure there's anything that can't in principle be
sort-of-sanely encoded as a __future__ feature though.

-- Devin
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-06 Thread Chris Angelico
On Tue, Jan 7, 2014 at 11:27 AM, Devin Jeanpierre
jeanpierr...@gmail.com wrote:
 For example, I imagine that it is kind of _silly_ to have a
 __future__.disable_str_autoencoding on a per-module basis, because
 some modules' functions will fail when they are given the wrong type,
 and some won't -- but in the context of making migration easier, that
 silliness is probably OK.

At what point does the auto-encoding happen, though? If a function
calls another function calls another function, at what point do you
decide that this ought to have become a str?

I suspect there'll be quite a few problems that can't be solved
per-module. The division change is easy, because it just changes the
way code gets compiled (there's still integer division and float
division, it's just that / gets compiled into the latter instead of
the former). With print_function I can imagine there might be some
interactions that are affected, but nothing too major. Deploying
new-style classes exclusively could be minorly problematic, but it'd
probably work (effectively, a future directive stipulates that
everything in this module inherits from object - technically should
work, but might cause code readability confusion). But there are much
subtler issues. Compare this code in Python 2 and Python 3:

def f1():
return {1:2, 11:22, 111:222}

def f2(d):
return d.keys()

def f3(k):
return k.pop()

process_me = f2(f1())
try:
while True:
current = f3(process_me)
# 
except IndexError:
pass

Obviously this works in Python 2, and fails in Python 3 (because
keys() returns a view). Now imagine these are four separate modules.
Somewhere along the way, something needs to pass the view through
list() to make it poppable. Or, putting it the other way, somewhere
there needs to be an alert saying that this won't work in Py3. Whose
responsibility is it?

* Is it f1's responsibility to create a different sort of dict that
has a keys() method that returns a view?
* Is it f2's responsibility to notice that it's calling keys() on a
dictionary, and that it should warn that this will change (or switch
to compatibility mode, or raise error, or whatever)? This is where the
error actually is.
* Is it f3's responsibility? This one I'm pretty sure is not so.
* Is it the main routine's job to turn process_me into a list? I don't
think so. There's nothing in that code that indicates that it's using
either a dictionary or a list.

I'd put the job either on f1 or on f2. A __future__ directive could
change the interpretation of the { } literal syntax and have it return
a dictionary with a keys view, but the fix would be better done in f2
- where it's not obvious that it's using a dictionary at all.

I'm not sure that a future directive can really solve this one. Maybe
a command-line argument could, but that doesn't help with the gradual
migration of individual modules.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-06 Thread Devin Jeanpierre
On Mon, Jan 6, 2014 at 5:00 PM, Chris Angelico ros...@gmail.com wrote:
 On Tue, Jan 7, 2014 at 11:27 AM, Devin Jeanpierre
 jeanpierr...@gmail.com wrote:
 For example, I imagine that it is kind of _silly_ to have a
 __future__.disable_str_autoencoding on a per-module basis, because
 some modules' functions will fail when they are given the wrong type,
 and some won't -- but in the context of making migration easier, that
 silliness is probably OK.

 At what point does the auto-encoding happen, though? If a function
 calls another function calls another function, at what point do you
 decide that this ought to have become a str?

Python has a defined place where it happens. For example the __add__
method of str objects can do it.

As you note below for dicts, the place where you change behavior can
change, though. e.g. maybe all str objects created in a module cannot
be coerced anywhere else, or maybe it's coercions that happen inside a
module that are disabled. The former is more efficient, but it has
effects that creep out transitively in the most difficult way
possible. The latter is essentially just an API change (rather than
type change), and so easy enough, but it's prohibitively expensive, in
a way that makes all code everywhere in Python slower. In the end, we
can still choose one of those, and in principle the __future__ feature
would work, even if it's not the best. (In fact, if you want, you
could even do both.)

 I suspect there'll be quite a few problems that can't be solved
 per-module. The division change is easy, because it just changes the
 way code gets compiled (there's still integer division and float
 division, it's just that / gets compiled into the latter instead of
 the former). With print_function I can imagine there might be some
 interactions that are affected, but nothing too major. Deploying
 new-style classes exclusively could be minorly problematic, but it'd
 probably work (effectively, a future directive stipulates that
 everything in this module inherits from object - technically should
 work, but might cause code readability confusion). But there are much
 subtler issues. Compare this code in Python 2 and Python 3:

 def f1():
 return {1:2, 11:22, 111:222}

 def f2(d):
 return d.keys()

 def f3(k):
 return k.pop()

 process_me = f2(f1())
 try:
 while True:
 current = f3(process_me)
 # 
 except IndexError:
 pass

 Obviously this works in Python 2, and fails in Python 3 (because
 keys() returns a view). Now imagine these are four separate modules.
 Somewhere along the way, something needs to pass the view through
 list() to make it poppable. Or, putting it the other way, somewhere
 there needs to be an alert saying that this won't work in Py3. Whose
 responsibility is it?

 * Is it f1's responsibility to create a different sort of dict that
 has a keys() method that returns a view?
 * Is it f2's responsibility to notice that it's calling keys() on a
 dictionary, and that it should warn that this will change (or switch
 to compatibility mode, or raise error, or whatever)? This is where the
 error actually is.
 * Is it f3's responsibility? This one I'm pretty sure is not so.
 * Is it the main routine's job to turn process_me into a list? I don't
 think so. There's nothing in that code that indicates that it's using
 either a dictionary or a list.

 I'd put the job either on f1 or on f2. A __future__ directive could
 change the interpretation of the { } literal syntax and have it return
 a dictionary with a keys view, but the fix would be better done in f2
 - where it's not obvious that it's using a dictionary at all.

 I'm not sure that a future directive can really solve this one. Maybe
 a command-line argument could, but that doesn't help with the gradual
 migration of individual modules.

What if we decide there is no single source of responsibility, and it
can't be limited exactly to a module, and make a __future__ feature
the best we can regardless? We can still exact some benefit from a
sloppy __future__ feature: we can still move code piecemeal.

If whatever __future__ feature there is, when enabled on the module
with f2 (or, in another case, f1), causes an error in f3, that's a
little misleading in that the error is in the wrong place, but it
doesn't fundamentally mean we can't move the codebase piecemeal. It
means that the change we make to the file for f2 (or f1) might require
some additional changes elsewhere or internally due to outside-facing
changes in semantics. It makes the required changes larger than in the
case of division, like you say, but it's still potentially smaller and
simpler than in the case of an atomic migration to Python 3.

-- Devin
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-06 Thread Chris Angelico
On Tue, Jan 7, 2014 at 12:55 PM, Devin Jeanpierre
jeanpierr...@gmail.com wrote:
 What if we decide there is no single source of responsibility, and it
 can't be limited exactly to a module, and make a __future__ feature
 the best we can regardless? We can still exact some benefit from a
 sloppy __future__ feature: we can still move code piecemeal.

I worry that it's starting to get into the realm of magic, though.
Maybe dict.keys() isn't the best example (you can easily make your
code 2+3 compat by just calling list() on it immediately, which is
effectively from __past__ import absence_of_views), but the issue is
the same with string autoencodings. It's really hard to define that
the + operator will do magic differently based on a future directive,
and changing the object (this string will not autoencode) means
you're not tweaking things per-module, and behaviour will change
and/or break based on where some object was created, rather than the
settings on the module with the code in it.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-06 Thread Devin Jeanpierre
On Mon, Jan 6, 2014 at 6:00 PM, Chris Angelico ros...@gmail.com wrote:
 On Tue, Jan 7, 2014 at 12:55 PM, Devin Jeanpierre
 jeanpierr...@gmail.com wrote:
 What if we decide there is no single source of responsibility, and it
 can't be limited exactly to a module, and make a __future__ feature
 the best we can regardless? We can still exact some benefit from a
 sloppy __future__ feature: we can still move code piecemeal.

 I worry that it's starting to get into the realm of magic, though.
 Maybe dict.keys() isn't the best example (you can easily make your
 code 2+3 compat by just calling list() on it immediately, which is
 effectively from __past__ import absence_of_views), but the issue is
 the same with string autoencodings. It's really hard to define that
 the + operator will do magic differently based on a future directive,
 and changing the object (this string will not autoencode) means
 you're not tweaking things per-module, and behaviour will change
 and/or break based on where some object was created, rather than the
 settings on the module with the code in it.

Well, what's magic? There are two ideas that I know roughly how to
implement, and that maybe would make the world better.

Behaviour that changes or breaks based on what module some object was
created in sounds pretty bad, but I don't think it's so bad that it's
not a tolerable solution. The error messages can be made obvious, and
it would still allow a gradual migration. Allowing the exception to be
toned down to a warning might help with the gradual move without
breaking code unpredictably. It's bad, but if there were no better
alternative, I would be OK with it. (i.e. I think it's better than
nothing.)

The other alternative is having + (etc.) do something different
depending on what module it's in. It's not hard to do: add a condition
to all places where Python automatically converts, and check the call
stack to see what module you're in. I mostly retract my worries about
performance, I for some reason was thinking you'd do it on all
operations, but it only has to be checked if the string is about to be
automatically encoded or decoded, (and that's already slow). It still
has the effect that your API is different and you raise exceptions
when you didn't before, which usually affects your callers more than
it affects you, but I feel like it propagates outside of the module
more nicely.

It's magic in that looking at the call stack is magic, but that's
the kind of magic that you can even do without touching the
interpreter, using functions from sys. I don't think the definition of
when exactly automatic encoding/decoding occurs is magical. It's
already a part of Python behaviour, changing it isn't outrageous.

-- Devin
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-06 Thread Chris Angelico
On Tue, Jan 7, 2014 at 1:15 PM, Devin Jeanpierre jeanpierr...@gmail.com wrote:
 The other alternative is having + (etc.) do something different
 depending on what module it's in. It's not hard to do: add a condition
 to all places where Python automatically converts, and check the call
 stack to see what module you're in.

Currently, there are __add__ methods (and __radd__ but let's focus on
__add__) on a bunch of objects, which determine what happens when you
use the + operator.

class Foo(str):
def __add__(self, other):
if isinstance(other, unicode): return self + other.encode(cp500)
return str.__add__(self, other)

What happens if you have the __future__ directive disabling
autoencoding on (a) the module in which this class is defined, (b) the
one in which the it was instantiated, (c) the one that actually uses
the +?

This is why I think it's getting magical. Far better to do this sort
of change on a per-application basis - maybe with a warning parameter
that you can enable when running your test suite, as has been
suggested (and in many cases implemented) for other 2-vs-3 problems.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-06 Thread Devin Jeanpierre
On Mon, Jan 6, 2014 at 6:28 PM, Chris Angelico ros...@gmail.com wrote:
 class Foo(str):
 def __add__(self, other):
 if isinstance(other, unicode): return self + other.encode(cp500)
 return str.__add__(self, other)

 What happens if you have the __future__ directive disabling
 autoencoding on (a) the module in which this class is defined, (b) the
 one in which the it was instantiated, (c) the one that actually uses
 the +?

In both methods I described, all uses of instances of the class are
changed, but only in case A. That's a really good point, I hadn't
considered that the second case could be converted into the first.

 This is why I think it's getting magical.

Yes, it's magical, but to be fair that's stack inspection as it always is.

I am OK with a little ugliness if it makes actual work easier.

 Far better to do this sort
 of change on a per-application basis - maybe with a warning parameter
 that you can enable when running your test suite, as has been
 suggested (and in many cases implemented) for other 2-vs-3 problems.

Doing a flag like that that enables a backwards incompatible change
does in fact address that issue you were worried about originally, so
that's something. And feature-by-feature moves are, like the OP said,
still lower cost than a wholesale move.

In the end a gradual transition can still be done with the polyglot
approach, but I'm not happy that there's no way to enforce/test a
polyglot conversion until it is complete. Any kind of granularity
would have helped. :(

-- Devin
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: the Gravity of Python 2

2014-01-06 Thread Chris Angelico
On Tue, Jan 7, 2014 at 2:12 PM, Devin Jeanpierre jeanpierr...@gmail.com wrote:
 Doing a flag like that that enables a backwards incompatible change
 does in fact address that issue you were worried about originally, so
 that's something. And feature-by-feature moves are, like the OP said,
 still lower cost than a wholesale move.

 In the end a gradual transition can still be done with the polyglot
 approach, but I'm not happy that there's no way to enforce/test a
 polyglot conversion until it is complete. Any kind of granularity
 would have helped. :(

Yeah, feature-by-feature is possible; but it doesn't help with one of
the big (and common) complaints, that a library can't migrate without
the application migrating. The way I see it, polyglot coding should be
considered a superset of 2.7 coding, at which point there should
hopefully be some perceived value in boasting Requires 2.7 *OR
3.3*!, and ideally that value should be greater than the cost of
supporting both. There are two ways to achieve that: Increase the
perceived value, and decrease the cost. Making 3.3 (or 3.4, or
whatever) look better is simply a matter of there being more
applications (or potential applications) written for that, and that's
going to be largely circular, and it's completely not in the hands of
Python development, so the focus has to be on decreasing the cost.

Hence the question: What are the breakages between 2.7 and 3.3, and
which ones can be solved per-module? If the solution to the breakage
has to be done per-application, that's a problem, even if it is
feature-by-feature. But stuff that can be changed per-module can
entirely eliminate the cost of polyglot code (for that feature), as
it'll simply be written in the Py3 way, with one little future
directive at the top.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list