Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

the Gravity of Python 2

288 views
Skip to first unread message

Mark Lawrence

unread,
Jan 6, 2014, 2:26:21 PM1/6/14
to pytho...@python.org
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?

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

Mark Lawrence

Mark Janssen

unread,
Jan 6, 2014, 2:41:34 PM1/6/14
to Mark Lawrence, Python List
> 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

Mark Lawrence

unread,
Jan 6, 2014, 2:44:25 PM1/6/14
to pytho...@python.org
I've just had a really good chuckle reading that coming from you. Got
the new dealer yet?

Chris Angelico

unread,
Jan 6, 2014, 7:19:20 PM1/6/14
to pytho...@python.org
On Tue, Jan 7, 2014 at 6:26 AM, Mark Lawrence <bream...@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

Devin Jeanpierre

unread,
Jan 6, 2014, 7:27:04 PM1/6/14
to Chris Angelico, pytho...@python.org
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

Chris Angelico

unread,
Jan 6, 2014, 8:00:40 PM1/6/14
to pytho...@python.org
On Tue, Jan 7, 2014 at 11:27 AM, Devin Jeanpierre
<jeanpi...@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

Chris Angelico

unread,
Jan 6, 2014, 9:00:59 PM1/6/14
to pytho...@python.org
On Tue, Jan 7, 2014 at 12:55 PM, Devin Jeanpierre
<jeanpi...@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

Devin Jeanpierre

unread,
Jan 6, 2014, 8:55:01 PM1/6/14
to Chris Angelico, pytho...@python.org
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
> <jeanpi...@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.)
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

Devin Jeanpierre

unread,
Jan 6, 2014, 9:15:18 PM1/6/14
to Chris Angelico, pytho...@python.org
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
> <jeanpi...@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

Chris Angelico

unread,
Jan 6, 2014, 9:28:39 PM1/6/14
to pytho...@python.org
On Tue, Jan 7, 2014 at 1:15 PM, Devin Jeanpierre <jeanpi...@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

Devin Jeanpierre

unread,
Jan 6, 2014, 10:12:05 PM1/6/14
to Chris Angelico, pytho...@python.org
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

Chris Angelico

unread,
Jan 6, 2014, 10:59:42 PM1/6/14
to pytho...@python.org
On Tue, Jan 7, 2014 at 2:12 PM, Devin Jeanpierre <jeanpi...@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

Martijn Faassen

unread,
Jan 7, 2014, 7:54:18 AM1/7/14
to
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

Martijn Faassen

unread,
Jan 7, 2014, 11:07:10 AM1/7/14
to
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


Martijn Faassen

unread,
Jan 7, 2014, 11:42:42 AM1/7/14
to
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

Chris Angelico

unread,
Jan 7, 2014, 12:00:26 PM1/7/14
to pytho...@python.org
On Wed, Jan 8, 2014 at 3:42 AM, Martijn Faassen <faa...@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

Martijn Faassen

unread,
Jan 8, 2014, 7:36:18 AM1/8/14
to
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

Chris Angelico

unread,
Jan 8, 2014, 7:46:14 AM1/8/14
to pytho...@python.org
On Wed, Jan 8, 2014 at 11:36 PM, Martijn Faassen <faa...@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

Steven D'Aprano

unread,
Jan 8, 2014, 8:01:29 AM1/8/14
to
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

Mark Lawrence

unread,
Jan 8, 2014, 9:08:10 AM1/8/14
to pytho...@python.org
Big +1 from me to all the above.

Roy Smith

unread,
Jan 8, 2014, 9:15:35 AM1/8/14
to
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.

Mark Lawrence

unread,
Jan 8, 2014, 9:15:45 AM1/8/14
to pytho...@python.org
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?

Mark Lawrence

unread,
Jan 8, 2014, 9:30:20 AM1/8/14
to pytho...@python.org
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.

Pedro Larroy

unread,
Jan 8, 2014, 9:45:04 AM1/8/14
to Mark Lawrence, pytho...@python.org
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 <bream...@yahoo.co.uk> wrote:
On 08/01/2014 14:15, Roy Smith wrote:
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

Chris Angelico

unread,
Jan 8, 2014, 9:50:46 AM1/8/14
to pytho...@python.org
On Thu, Jan 9, 2014 at 1:30 AM, Mark Lawrence <bream...@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

Grant Edwards

unread,
Jan 8, 2014, 10:06:28 AM1/8/14
to
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.edwards Yow! Psychoanalysis??
at I thought this was a nude
gmail.com rap session!!!

Martijn Faassen

unread,
Jan 8, 2014, 10:08:09 AM1/8/14
to
On 01/08/2014 01:46 PM, Chris Angelico wrote:
> On Wed, Jan 8, 2014 at 11:36 PM, Martijn Faassen <faa...@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

Martijn Faassen

unread,
Jan 8, 2014, 10:22:12 AM1/8/14
to
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

Martijn Faassen

unread,
Jan 8, 2014, 10:26:18 AM1/8/14
to
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


Chris Angelico

unread,
Jan 8, 2014, 10:31:00 AM1/8/14
to pytho...@python.org
On Thu, Jan 9, 2014 at 2:06 AM, Grant Edwards <inv...@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

Chris Angelico

unread,
Jan 8, 2014, 10:39:18 AM1/8/14
to pytho...@python.org
On Thu, Jan 9, 2014 at 2:22 AM, Martijn Faassen <faa...@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

Mark Lawrence

unread,
Jan 8, 2014, 10:50:03 AM1/8/14
to pytho...@python.org
On 08/01/2014 15:39, Chris Angelico wrote:
> On Thu, Jan 9, 2014 at 2:22 AM, Martijn Faassen <faa...@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?

Terry Reedy

unread,
Jan 8, 2014, 3:45:16 PM1/8/14
to pytho...@python.org
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

Steven D'Aprano

unread,
Jan 8, 2014, 4:55:36 PM1/8/14
to
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

Kevin Walzer

unread,
Jan 8, 2014, 6:42:42 PM1/8/14
to
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

Roy Smith

unread,
Jan 8, 2014, 8:27:30 PM1/8/14
to
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.

Chris Angelico

unread,
Jan 8, 2014, 8:47:53 PM1/8/14
to pytho...@python.org
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

Ethan Furman

unread,
Jan 8, 2014, 8:52:05 PM1/8/14
to pytho...@python.org
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~

Chris Angelico

unread,
Jan 8, 2014, 9:09:26 PM1/8/14
to pytho...@python.org
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

Roy Smith

unread,
Jan 8, 2014, 9:25:55 PM1/8/14
to
In article <mailman.5222.1389232...@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.

Chris Angelico

unread,
Jan 8, 2014, 10:17:07 PM1/8/14
to pytho...@python.org
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

Ben Finney

unread,
Jan 8, 2014, 10:34:54 PM1/8/14
to pytho...@python.org
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

Roy Smith

unread,
Jan 8, 2014, 10:35:14 PM1/8/14
to
In article <mailman.5226.1389237...@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.

Chris Angelico

unread,
Jan 8, 2014, 10:42:53 PM1/8/14
to pytho...@python.org
On Thu, Jan 9, 2014 at 2:34 PM, Ben Finney <ben+p...@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

Roy Smith

unread,
Jan 8, 2014, 10:44:50 PM1/8/14
to
In article <mailman.5227.1389238...@python.org>,
Ben Finney <ben+p...@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?"

Ben Finney

unread,
Jan 8, 2014, 10:54:48 PM1/8/14
to pytho...@python.org
Chris Angelico <ros...@gmail.com> writes:

> On Thu, Jan 9, 2014 at 2:34 PM, Ben Finney <ben+p...@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?

Twenty-four time zones, yes. My mistake.

I'm currently reading <URL:http://savingthedaylight.com/> David Prerau's
_Saving the Daylight: Why We Put The Clocks Forward_. It's got an
acknowledged bias, that DST is overall a good thing; I disagree strongly
with that position. But it's also very well researched and engagingly
written.

Not only does it explain the motivations and history of the present
system of Daylight Shifting Time (or, as the world misleadingly calls
it, Daylight “Saving” Time), it goes into the history that pre-dates
that system and led to the system of time zones at all.

I'm approaching it with the goal of knowing better what I'm talking
about when I advocate scrapping the whole DST system :-)

--
\ “Only the educated are free.” —Epictetus, _Discourses_ |
`\ |
_o__) |
Ben Finney

Chris Angelico

unread,
Jan 8, 2014, 11:03:45 PM1/8/14
to pytho...@python.org
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

Chris Angelico

unread,
Jan 8, 2014, 11:14:55 PM1/8/14
to pytho...@python.org
On Thu, Jan 9, 2014 at 2:54 PM, Ben Finney <ben+p...@benfinney.id.au> wrote:
> I'm approaching it with the goal of knowing better what I'm talking
> about when I advocate scrapping the whole DST system :-)

I would definitely support the scrapping of DST. I'm less sure that we
need exactly 24 timezones around the world, though. It's not nearly as
big a problem to have the half-hour and quarter-hour timezones -
though it would be easier if timezone were strictly an integer number
of hours. But DST is the real pain.

What I find, most of the time, is that it's Americans who can't handle
DST. I run an international Dungeons and Dragons campaign (we play
online, and new players are most welcome, as are people watching!),
and the Aussies (myself included) know to check UTC time, the Brits
and Europeans check UTC or just know what UTC is, and the Americans
say "Doesn't that happen at 8 o'clock Eastern time?" and get confused.
I don't understand this. Are my players drawn exclusively from the
pool of people who've never worked with anyone in Arizona [1]? Yes,
I'm stereotyping a bit here, and not every US player has had problems
with this, but it's the occasional US player who knows to check, and
the rare European, British, or Aussie player who doesn't.

In any case, the world-wide abolition of DST would eliminate the
problem. The only remaining problem would be reminding people to
change the batteries in their smoke detectors.

ChrisA

[1] For those who aren't right up on timezone trivia, AZ has no DST.
Similarly the Australian state of Queensland does not shift its
clocks.

Roy Smith

unread,
Jan 8, 2014, 11:29:01 PM1/8/14
to
In article <mailman.5231.1389240...@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 :-)

Chris Angelico

unread,
Jan 8, 2014, 11:34:17 PM1/8/14
to pytho...@python.org
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

Chris Angelico

unread,
Jan 8, 2014, 11:38:19 PM1/8/14
to pytho...@python.org
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

Ethan Furman

unread,
Jan 9, 2014, 12:31:02 AM1/9/14
to pytho...@python.org
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~

Chris Angelico

unread,
Jan 9, 2014, 1:34:33 AM1/9/14
to pytho...@python.org
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

Ben Finney

unread,
Jan 9, 2014, 1:57:21 AM1/9/14
to pytho...@python.org
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

Mark Lawrence

unread,
Jan 9, 2014, 2:10:28 AM1/9/14
to pytho...@python.org
On 09/01/2014 03:42, Chris Angelico wrote:
> On Thu, Jan 9, 2014 at 2:34 PM, Ben Finney <ben+p...@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.

Mark Lawrence

unread,
Jan 9, 2014, 2:17:25 AM1/9/14
to pytho...@python.org
I remember this "From February 1968 to November 1971 the UK kept
daylight saving time throughout the year mainly for commercial reasons,
especially regarding time conformity with other European countries". My
source http://www.timeanddate.com/time/uk/time-zone-background.html

Chris Angelico

unread,
Jan 9, 2014, 2:56:34 AM1/9/14
to pytho...@python.org
On Thu, Jan 9, 2014 at 5:57 PM, Ben Finney <ben+p...@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

Kushal Kumaran

unread,
Jan 9, 2014, 1:06:29 AM1/9/14
to pytho...@python.org
Roy Smith <r...@panix.com> writes:

> In article <mailman.5231.1389240...@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

Mark Lawrence

unread,
Jan 9, 2014, 3:42:43 AM1/9/14
to pytho...@python.org
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 Lawrence

unread,
Jan 9, 2014, 3:53:28 AM1/9/14
to pytho...@python.org
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)

Ben Finney

unread,
Jan 9, 2014, 4:03:18 AM1/9/14
to pytho...@python.org
Kushal Kumaran <kushal....@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

Kushal Kumaran

unread,
Jan 9, 2014, 4:21:51 AM1/9/14
to pytho...@python.org
Ben Finney <ben+p...@benfinney.id.au> writes:

> Kushal Kumaran <kushal....@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

Mark Lawrence

unread,
Jan 9, 2014, 4:51:40 AM1/9/14
to pytho...@python.org
On 09/01/2014 09:03, Ben Finney wrote:
> Kushal Kumaran <kushal....@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)".

Piet van Oostrum

unread,
Jan 9, 2014, 6:26:21 AM1/9/14
to
Kushal Kumaran <kushal....@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 <pi...@vanoostrum.org>
WWW: http://pietvanoostrum.com/
PGP key: [8DAE142BE17999C4]

Alister

unread,
Jan 9, 2014, 7:07:41 AM1/9/14
to
we dont have "Daylight saving time" we switch between GMT (Greenwich Mean
Time) and BST (British Summer Time) at some point in the past we have
also used DST (Double Summer Time).



--
Endless the world's turn, endless the sun's spinning
Endless the quest;
I turn again, back to my own beginning,
And here, find rest.

Ben Finney

unread,
Jan 9, 2014, 8:35:00 AM1/9/14
to pytho...@python.org
Kushal Kumaran <kushal....@gmail.com> writes:

> Ben Finney <ben+p...@benfinney.id.au> writes:
>
> > Kushal Kumaran <kushal....@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

Piet van Oostrum

unread,
Jan 9, 2014, 9:06:00 AM1/9/14
to
Even 24 doesn't take into account DST.

Roy Smith

unread,
Jan 9, 2014, 9:14:22 AM1/9/14
to
In article <mailman.5244.1389254...@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.

Roy Smith

unread,
Jan 9, 2014, 9:32:39 AM1/9/14
to
In article <mailman.5257.1389274...@python.org>,
Ben Finney <ben+p...@benfinney.id.au> wrote:

> Kushal Kumaran <kushal....@gmail.com> writes:
>
> > Ben Finney <ben+p...@benfinney.id.au> writes:
> >
> > > Kushal Kumaran <kushal....@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.

Chris Angelico

unread,
Jan 9, 2014, 9:34:13 AM1/9/14
to pytho...@python.org
On Fri, Jan 10, 2014 at 1:06 AM, Piet van Oostrum <pi...@vanoostrum.org> wrote:
> Chris Angelico <ros...@gmail.com> writes:
>
>> On Thu, Jan 9, 2014 at 2:34 PM, Ben Finney <ben+p...@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

Roy Smith

unread,
Jan 9, 2014, 9:44:56 AM1/9/14
to
In article <mailman.5259.1389278...@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.

Chris Angelico

unread,
Jan 9, 2014, 9:57:57 AM1/9/14
to pytho...@python.org
On Fri, Jan 10, 2014 at 1:14 AM, Roy Smith <r...@panix.com> wrote:
> In article <mailman.5244.1389254...@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(-100000))
Traceback (most recent call last):
File "<pyshell#163>", line 1, in <module>
time.strftime("%Y%m",time.gmtime(-100000))
OSError: [Errno 22] Invalid argument

Linux:
>>> time.strftime("%Y%m",time.gmtime(-100000))
'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!

Dan Sommers

unread,
Jan 9, 2014, 10:01:18 AM1/9/14
to
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

Chris Angelico

unread,
Jan 9, 2014, 10:17:45 AM1/9/14
to pytho...@python.org
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

Dave Angel

unread,
Jan 9, 2014, 10:34:02 AM1/9/14
to pytho...@python.org
On Thu, 9 Jan 2014 15:14:55 +1100, Chris Angelico <ros...@gmail.com>
wrote:
> [1] For those who aren't right up on timezone trivia, AZ has no DST.
> Similarly the Australian state of Queensland does not shift its
> clocks.

And Indiana.

--
DaveA

Roy Smith

unread,
Jan 9, 2014, 11:21:33 AM1/9/14
to
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.

Mark Lawrence

unread,
Jan 9, 2014, 11:30:31 AM1/9/14
to pytho...@python.org
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?

Tim Golden

unread,
Jan 9, 2014, 11:41:16 AM1/9/14
to pytho...@python.org
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

Nick Cash

unread,
Jan 9, 2014, 11:42:03 AM1/9/14
to Roy Smith, pytho...@python.org
> 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.

Ethan Furman

unread,
Jan 9, 2014, 10:56:20 AM1/9/14
to pytho...@python.org
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! :)

Ethan Furman

unread,
Jan 9, 2014, 11:01:41 AM1/9/14
to pytho...@python.org
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~

Piet van Oostrum

unread,
Jan 9, 2014, 11:51:36 AM1/9/14
to
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.

Mark Lawrence

unread,
Jan 9, 2014, 11:50:36 AM1/9/14
to pytho...@python.org
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.

Roy Smith

unread,
Jan 9, 2014, 12:07:30 PM1/9/14
to
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.

Mark Lawrence

unread,
Jan 9, 2014, 1:18:20 PM1/9/14
to pytho...@python.org
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?

Mark Lawrence

unread,
Jan 9, 2014, 1:20:40 PM1/9/14
to pytho...@python.org
No thank you, I don't want the Python docs getting anywhere near the
size of their Java equivalents.

Ethan Furman

unread,
Jan 9, 2014, 1:33:10 PM1/9/14
to pytho...@python.org
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~

Ethan Furman

unread,
Jan 9, 2014, 1:29:37 PM1/9/14
to pytho...@python.org
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~

Chris Angelico

unread,
Jan 9, 2014, 3:35:05 PM1/9/14
to pytho...@python.org
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

Chris Angelico

unread,
Jan 9, 2014, 3:43:36 PM1/9/14
to pytho...@python.org
On Fri, Jan 10, 2014 at 3:51 AM, Piet van Oostrum <pi...@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

Roy Smith

unread,
Jan 9, 2014, 3:54:10 PM1/9/14
to
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().

Chris Angelico

unread,
Jan 9, 2014, 4:12:27 PM1/9/14
to pytho...@python.org
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 quadrrrruple 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 quadrrrruple letter in it!")
<_sre.SRE_Match object; span=(33, 37), match='rrrr'>

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

Bob Martin

unread,
Jan 10, 2014, 2:31:11 AM1/10/14
to
in 714232 20140109 120741 Alister <aliste...@ntlworld.com> wrote:
>On Thu, 09 Jan 2014 07:17:25 +0000, Mark Lawrence wrote:
>
>> On 09/01/2014 04:14, Chris Angelico wrote:
>>> On Thu, Jan 9, 2014 at 2:54 PM, Ben Finney <ben+p...@benfinney.id.au>
>>> wrote:
>>>> I'm approaching it with the goal of knowing better what I'm talking
>>>> about when I advocate scrapping the whole DST system :-)
>>>
>>> I would definitely support the scrapping of DST. I'm less sure that we
>>> need exactly 24 timezones around the world, though. It's not nearly as
>>> big a problem to have the half-hour and quarter-hour timezones -
>>> though it would be easier if timezone were strictly an integer number
>>> of hours. But DST is the real pain.
>>>
>>> What I find, most of the time, is that it's Americans who can't handle
>>> DST. I run an international Dungeons and Dragons campaign (we play
>>> online, and new players are most welcome, as are people watching!),
>>> and the Aussies (myself included) know to check UTC time, the Brits and
>>> Europeans check UTC or just know what UTC is, and the Americans say
>>> "Doesn't that happen at 8 o'clock Eastern time?" and get confused.
>>> I don't understand this. Are my players drawn exclusively from the pool
>>> of people who've never worked with anyone in Arizona [1]? Yes,
>>> I'm stereotyping a bit here, and not every US player has had problems
>>> with this, but it's the occasional US player who knows to check, and
>>> the rare European, British, or Aussie player who doesn't.
>>>
>>> In any case, the world-wide abolition of DST would eliminate the
>>> problem. The only remaining problem would be reminding people to change
>>> the batteries in their smoke detectors.
>>>
>>> ChrisA
>>>
>>> [1] For those who aren't right up on timezone trivia, AZ has no DST.
>>> Similarly the Australian state of Queensland does not shift its clocks.
>>>
>>>
>> I remember this "From February 1968 to November 1971 the UK kept
>> daylight saving time throughout the year mainly for commercial reasons,
>> especially regarding time conformity with other European countries". My
>> source http://www.timeanddate.com/time/uk/time-zone-background.html
>
>we dont have "Daylight saving time" we switch between GMT (Greenwich Mean
>Time) and BST (British Summer Time) at some point in the past we have
>also used DST (Double Summer Time).

British Summer Time *is* Daylight Saving Time.

Alister

unread,
Jan 10, 2014, 4:04:09 AM1/10/14
to
My point is in the UK we have never refered to it as Daylight saving Time
that is an Americanism :-)



--
if (argc > 1 && strcmp(argv[1], "-advice") == 0) {
printf("Don't Panic!\n");
exit(42);
}
-- Arnold Robbins in the LJ of February '95, describing RCS

Peter Pearson

unread,
Jan 10, 2014, 1:22:41 PM1/10/14
to
On Thu, 9 Jan 2014 15:14:55 +1100, Chris Angelico wrote:
[snip]
> What I find, most of the time, is that it's Americans who can't handle
> DST. I run an international Dungeons and Dragons campaign (we play
> online, and new players are most welcome, as are people watching!),
> and the Aussies (myself included) know to check UTC time, the Brits
> and Europeans check UTC or just know what UTC is, and the Americans
> say "Doesn't that happen at 8 o'clock Eastern time?" and get confused.

Around 30 years ago, the Wall Street Journal ran an opinion piece
advocating the abandonment of time zones and the unification of the
globe into a single glorious time zone. After enumerating the
efficiencies to be achieved by this system, the writer briefly
addressed the question of whose time zone would become the global
standard, promptly arriving at the conclusion that, due to the
concentration of important commerce, the logical choice was the
east coast of the United States.

My point: we deserve the teasing.

--
To email me, substitute nowhere->spamcop, invalid->net.

MRAB

unread,
Jan 10, 2014, 1:48:41 PM1/10/14
to pytho...@python.org, pytho...@python.org
What a silly idea!

The logical choice is UTC. :-)

Mark Lawrence

unread,
Jan 10, 2014, 1:53:18 PM1/10/14
to pytho...@python.org
On 10/01/2014 18:48, MRAB wrote:
> On 2014-01-10 18:22, Peter Pearson wrote:
> What a silly idea!
>
> The logical choice is UTC. :-)

Hell will freeze over first. But apparently it already has in
Minnesota. Drat, drat and double drat!!!

>
>> My point: we deserve the teasing.
>>
>


--

Grant Edwards

unread,
Jan 10, 2014, 2:55:37 PM1/10/14
to
On 2014-01-10, Mark Lawrence <bream...@yahoo.co.uk> wrote:

> Hell will freeze over first. But apparently it already has in
> Minnesota. Drat, drat and double drat!!!

It got darned cold here in Minnesota on Monday (-23F in Minneapolis,
-35F in Embarass), but Hell is in Michigan -- where it only got down
to -15F.

http://en.wikipedia.org/wiki/Hell,_Michigan
http://www.roadsideamerica.com/tip/2456


Gene Heskett

unread,
Jan 10, 2014, 3:26:22 PM1/10/14
to pytho...@python.org
On Friday 10 January 2014 15:24:11 Mark Lawrence did opine:

> On 10/01/2014 18:48, MRAB wrote:
> > On 2014-01-10 18:22, Peter Pearson wrote:
> >> On Thu, 9 Jan 2014 15:14:55 +1100, Chris Angelico wrote:
> >> [snip]
> >>
> >>> What I find, most of the time, is that it's Americans who can't
> >>> handle DST. I run an international Dungeons and Dragons campaign
> >>> (we play online, and new players are most welcome, as are people
> >>> watching!), and the Aussies (myself included) know to check UTC
> >>> time, the Brits and Europeans check UTC or just know what UTC is,
> >>> and the Americans say "Doesn't that happen at 8 o'clock Eastern
> >>> time?" and get confused.
> >>
> >> Around 30 years ago, the Wall Street Journal ran an opinion piece
> >> advocating the abandonment of time zones and the unification of the
> >> globe into a single glorious time zone. After enumerating the
> >> efficiencies to be achieved by this system, the writer briefly
> >> addressed the question of whose time zone would become the global
> >> standard, promptly arriving at the conclusion that, due to the
> >> concentration of important commerce, the logical choice was the
> >> east coast of the United States.
> >
> > What a silly idea!
> >
> > The logical choice is UTC. :-)
>
> Hell will freeze over first. But apparently it already has in
> Minnesota. Drat, drat and double drat!!!

That Hell the headlines referred to is in Michigan... Its a headline they
drag out every time we get a cold snap & its ano otherwise slow news day.

Nothing to see here, now move along please...

>
> >> My point: we deserve the teasing.


Cheers, Gene
--
"There are four boxes to be used in defense of liberty:
soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author)
Genes Web page <http://geneslinuxbox.net:6309/gene>

Young men want to be faithful and are not; old men want to be faithless and
cannot.
-- Oscar Wilde
A pen in the hand of this president is far more
dangerous than 200 million guns in the hands of
law-abiding citizens.
Message has been deleted
It is loading more messages.
0 new messages