[Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Jess Austin
hi,

I'm new to python core development, and I've been advised to write to
python-dev concerning a feature/patch I've placed at
http://bugs.python.org/issue5434, with Rietveld at
http://codereview.appspot.com/25079.

This patch adds a monthdelta class and a monthmod function to the
datetime module.  The monthdelta class is much like the existing
timedelta class, except that it represents months offset from a date,
rather than an exact period offset from a date.  This allows us to
easily say, e.g. 3 months from now without worrying about the number
of days in the intervening months.

 date(2008, 1, 30) + monthdelta(1)
datetime.date(2008, 2, 29)
 date(2008, 1, 30) + monthdelta(2)
datetime.date(2008, 3, 30)

The monthmod function, named in (imperfect) analogy to divmod, allows
us to round-trip by returning the interim between two dates
represented as a (monthdelta, timedelta) tuple:

 monthmod(date(2008, 1, 14), date(2009, 4, 2))
(datetime.monthdelta(14), datetime.timedelta(19))

Invariant: dt + monthmod(dt, dt+td)[0] + monthmod(dt, dt+td)[1] == dt + td

These also work with datetimes!  There are more details in the
documentation included in the patch.  In addition to the C module
file, I've updated the datetime CAPI, the documentation, and tests.

I feel this would be a good addition to core python.  In my work, I've
often ended up writing annoying one-off add-a-month or similar
functions.  I think since months work differently than most other time
periods, a new object is justified rather than trying to shoe-horn
something like this into timedelta.  I also think that the round-trip
functionality provided by monthmod is important to ensure that
monthdeltas are first-class objects.

Please let me know what you think of the idea and/or its execution.

thanks,
Jess Austin
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Tennessee Leeuwenburg
Hi Jess,

I'm sorry if I'm failing to understand the use of this function from not
looking closely at your code. I'm a bit dubious about the usefulness of this
(I'm not sure I understand the use cases), but I'm very open to being
convinced. Datetime semantics are very important in some areas -- I use them
a lot.

I'm not convinced the semantics of monthdelta are obvious.

A month doesn't have a consistent length -- it could be 28, 29, 30 or 31
days.

What happens when you ask for the date in 1 month's time on the 31st Jan?
What date is a month after the 31st Jan?

Do you have a good spec (er, I mean PEP) for this describing what happens in
the edge cases and what is meant by a monthdelta? The bug notes say it
deals sensibly with these issues, but that's really not enough to
understand what the function is likely to do. At the very least, a few
well-chosen examples would help to illustrate the functionality much more
clearly.

Cheers,
-Tennessee


On Thu, Apr 16, 2009 at 4:18 PM, Jess Austin jess.aus...@gmail.com wrote:

 hi,

 I'm new to python core development, and I've been advised to write to
 python-dev concerning a feature/patch I've placed at
 http://bugs.python.org/issue5434, with Rietveld at
 http://codereview.appspot.com/25079.

 This patch adds a monthdelta class and a monthmod function to the
 datetime module.  The monthdelta class is much like the existing
 timedelta class, except that it represents months offset from a date,
 rather than an exact period offset from a date.  This allows us to
 easily say, e.g. 3 months from now without worrying about the number
 of days in the intervening months.

 date(2008, 1, 30) + monthdelta(1)
datetime.date(2008, 2, 29)
 date(2008, 1, 30) + monthdelta(2)
datetime.date(2008, 3, 30)

 The monthmod function, named in (imperfect) analogy to divmod, allows
 us to round-trip by returning the interim between two dates
 represented as a (monthdelta, timedelta) tuple:

 monthmod(date(2008, 1, 14), date(2009, 4, 2))
(datetime.monthdelta(14), datetime.timedelta(19))

 Invariant: dt + monthmod(dt, dt+td)[0] + monthmod(dt, dt+td)[1] == dt + td

 These also work with datetimes!  There are more details in the
 documentation included in the patch.  In addition to the C module
 file, I've updated the datetime CAPI, the documentation, and tests.

 I feel this would be a good addition to core python.  In my work, I've
 often ended up writing annoying one-off add-a-month or similar
 functions.  I think since months work differently than most other time
 periods, a new object is justified rather than trying to shoe-horn
 something like this into timedelta.  I also think that the round-trip
 functionality provided by monthmod is important to ensure that
 monthdeltas are first-class objects.

 Please let me know what you think of the idea and/or its execution.

 thanks,
 Jess Austin
 ___
 Python-Dev mailing list
 Python-Dev@python.org
 http://mail.python.org/mailman/listinfo/python-dev
 Unsubscribe:
 http://mail.python.org/mailman/options/python-dev/tleeuwenburg%40gmail.com




-- 
--
Tennessee Leeuwenburg
http://myownhat.blogspot.com/
Don't believe everything you think
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Oleg Broytmann
On Thu, Apr 16, 2009 at 01:18:01AM -0500, Jess Austin wrote:
 I'm new to python core development, and I've been advised to write to
 python-dev concerning a feature/patch I've placed at
 http://bugs.python.org/issue5434, with Rietveld at
 http://codereview.appspot.com/25079.

   I have read the python code and it looks good. I often have a need to do
month-based calculations.

 This patch adds a monthdelta class and a monthmod function to the
 datetime module.  The monthdelta class is much like the existing
 timedelta class, except that it represents months offset from a date,
 rather than an exact period offset from a date.

   I'd rather see the code merged with timedelta: timedelta(months=n).

Oleg.
-- 
 Oleg Broytmannhttp://phd.pp.ru/p...@phd.pp.ru
   Programmers don't die, they just GOSUB without RETURN.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread skip
 date(2008, 1, 30) + monthdelta(1)
datetime.date(2008, 2, 29)

What would this loop would print?

for d in range(1, 32):
print date(2008, 1, d) + monthdelta(1)

I have this funny feeling that arithmetic using monthdelta wouldn't always
be intuitive.

Skip
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread James Pye

On Apr 16, 2009, at 1:10 AM, Oleg Broytmann wrote:

This patch adds a monthdelta class and a monthmod function to the
datetime module.  The monthdelta class is much like the existing
timedelta class, except that it represents months offset from a date,
rather than an exact period offset from a date.


  I'd rather see the code merged with timedelta: timedelta(months=n).


+1
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Amaury Forgeot d'Arc
On Thu, Apr 16, 2009 at 10:45,  s...@pobox.com wrote:
     date(2008, 1, 30) + monthdelta(1)
    datetime.date(2008, 2, 29)

 What would this loop would print?

    for d in range(1, 32):
        print date(2008, 1, d) + monthdelta(1)

 I have this funny feeling that arithmetic using monthdelta wouldn't always
 be intuitive.

FWIW, the Oracle database has two methods for adding months:
1- the add_months() function
add_months(to_date('31-jan-2005'), 1)
2- the ANSI interval:
to_date('31-jan-2005') + interval '1' month

add_months is calendar sensitive, interval is not.
interval raises an exception if the day is not valid for the target
month (which is the case in my example)

add_months is similar to the proposed monthdelta(),
except that it has a special case for the last day of the month:

If date is the last day of the month or if the resulting month has
fewer days than the day
component of date, then the result is the last day of the resulting month.
Otherwise, the result has the same day component as date.

indeed:
add_months(to_date('28-feb-2005'), 1) == to_date('31-mar-2005')



In my opinion:
arithmetic with months is a mess. There is no such month interval or
year interval with a precise definition.
If we adopt some kind of month manipulation, it should be a function
or a method, like you would do for features like last_day_of_month(d),
or following_weekday(d, 'monday').

date(2008, 1, 30).add_months(1) == date(2008, 2, 29)

-- 
Amaury Forgeot d'Arc
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Dirkjan Ochtman
On Thu, Apr 16, 2009 at 11:54, Amaury Forgeot d'Arc amaur...@gmail.com wrote:
 In my opinion:
 arithmetic with months is a mess. There is no such month interval or
 year interval with a precise definition.
 If we adopt some kind of month manipulation, it should be a function
 or a method, like you would do for features like last_day_of_month(d),
 or following_weekday(d, 'monday').

    date(2008, 1, 30).add_months(1) == date(2008, 2, 29)

I concur. Trying to shoehorn month arithmetic into timedelta is a
PITA, precisely because it's somewhat inexact. It's better to have
some separate behavior that has well-defined behavior in edge cases.

Cheers,

Dirkjan
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Jon Ribbens
On Thu, Apr 16, 2009 at 12:10:36PM +0400, Oleg Broytmann wrote:
  This patch adds a monthdelta class and a monthmod function to the
  datetime module.  The monthdelta class is much like the existing
  timedelta class, except that it represents months offset from a date,
  rather than an exact period offset from a date.
 
I'd rather see the code merged with timedelta: timedelta(months=n).

Unfortunately, that's simply impossible. A timedelta is a fixed number
of seconds, and the time between one month and the next varies.

I am very much in favour of there being the ability to add months to
dates though. Obviously there is the question of what to do when you
move forward 1 month from the 31st January; in my opinion an optional
argument to specify different behaviours would be nice.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] RELEASED Python 2.6.2

2009-04-16 Thread Ronald Oussoren


On 15 Apr, 2009, at 22:47, Russell E. Owen wrote:


Thank you for 2.6.2.

I see the Mac binary installer isn't out yet (at least it is not  
listed

on the downloads page). Any chance that it will be compatible with 3rd
party Tcl/Tk?


The Mac installer is late because I missed the pre-announcement of the  
2.6.2 tag. I sent the installer to Barry earlier today.


The installer was build using a 3th-party installation of Tcl/Tk.

Ronald

smime.p7s
Description: S/MIME cryptographic signature
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Paul Moore
2009/4/16 Jess Austin jess.aus...@gmail.com:
 I'm new to python core development, and I've been advised to write to
 python-dev concerning a feature/patch I've placed at
 http://bugs.python.org/issue5434, with Rietveld at
 http://codereview.appspot.com/25079.

 This patch adds a monthdelta class and a monthmod function to the
 datetime module.  The monthdelta class is much like the existing
 timedelta class, except that it represents months offset from a date,
 rather than an exact period offset from a date.  This allows us to
 easily say, e.g. 3 months from now without worrying about the number
 of days in the intervening months.

     date(2008, 1, 30) + monthdelta(1)
    datetime.date(2008, 2, 29)
     date(2008, 1, 30) + monthdelta(2)
    datetime.date(2008, 3, 30)

 The monthmod function, named in (imperfect) analogy to divmod, allows
 us to round-trip by returning the interim between two dates
 represented as a (monthdelta, timedelta) tuple:

     monthmod(date(2008, 1, 14), date(2009, 4, 2))
    (datetime.monthdelta(14), datetime.timedelta(19))

 Invariant: dt + monthmod(dt, dt+td)[0] + monthmod(dt, dt+td)[1] == dt + td

I like the idea in principle. In practice, of course, month
calculations are inherently ill-defined, so you need to be very
specific in documenting all of the edge cases, and you should have
strong use cases to ensure that the behaviour implemented matches user
requirements. (I haven't yet had time to read the patch - you may well
already have these points covered, certainly your comments above
indicate that you appreciate the subtleties involved).

 These also work with datetimes!  There are more details in the
 documentation included in the patch.  In addition to the C module
 file, I've updated the datetime CAPI, the documentation, and tests.

 I feel this would be a good addition to core python.  In my work, I've
 often ended up writing annoying one-off add-a-month or similar
 functions.  I think since months work differently than most other time
 periods, a new object is justified rather than trying to shoe-horn
 something like this into timedelta.  I also think that the round-trip
 functionality provided by monthmod is important to ensure that
 monthdeltas are first-class objects.

I agree that ultimately it would be useful in the core. However, I'd
suggest that you release the functionality as an independent module in
the first instance, to establish it outside of the core. Once it has
matured somewhat as a 3rd party module, it would then be ready for
integration in the core. This also has the benefit that it makes the
functionality available to users of Python 2.6 (and possibly earlier)
rather than just in 2.7/3.1 onwards.

 Please let me know what you think of the idea and/or its execution.

I hope the above comments help. Ultimately, I'd like to see this added
to the core. It's tricky enough that having a standard
implementation is a definite benefit in itself. But equally, I'd give
it time to iron out the corner cases on a faster development cycle
than the core offers before freezing it as part of the stdlib.

Paul.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Paul Moore
2009/4/16  s...@pobox.com:
     date(2008, 1, 30) + monthdelta(1)
    datetime.date(2008, 2, 29)

 What would this loop would print?

    for d in range(1, 32):
        print date(2008, 1, d) + monthdelta(1)

 I have this funny feeling that arithmetic using monthdelta wouldn't always
 be intuitive.

Oh, certainly! But in the absence of intuitive, I've found in the
past that standardised is often better than nothing :-) (For
example, I use Oracle's add_months function fairly often - it's not
perfect, and not always intuitive, but at least it's well-defined in
the corner cases, and fine for normal use).

Paul.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Antoine Pitrou
Paul Moore p.f.moore at gmail.com writes:
 
 Oh, certainly! But in the absence of intuitive, I've found in the
 past that standardised is often better than nothing  (For
 example, I use Oracle's add_months function fairly often - it's not
 perfect, and not always intuitive, but at least it's well-defined in
 the corner cases, and fine for normal use).

I think something like date.add_months() would be better than the proposed
monthdelta. The monthdelta proposal suggests that addition is something
well-defined and rigourous, which is not really the case here (for example, if
you add a monthdelta and then substract it again, I'm not sure you always get
back the original date).

Regards

Antoine.


___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 382: Namespace Packages

2009-04-16 Thread P.J. Eby

At 03:46 AM 4/16/2009 +, gl...@divmod.com wrote:


On 15 Apr, 09:11 pm, p...@telecommunity.com wrote:
I think that there is some confusion here.  A main package or 
buildout that assembles a larger project from components is not the 
same thing as having a base package for a namespace package.


I'm certainly confused.

Twisted has its own system for namespace packages, and I'm not 
really sure where we fall in this discussion.  I haven't been able 
to follow the whole thread, but my original understanding was that 
the PEP supports defining packages, which we now seem to be 
calling base packages, just fine.


Yes, it does.  The discussion since the original proposal, however, 
has been dominated by MAL's counterproposal, which *requires* a 
defining package.


There is a slight distinction between base package and defining 
package, although I suppose I've been using them a bit interchangeably.


Base package describes a use case: you have a base package which is 
extended in the same namespace.  In that use case, you may want to 
place your base package in the defining package.


In contrast, setuptools does not support a defining package, so if 
you have a base package, you must place it in a submodule or 
subpackage of the namespace.


Does that all make sense now?

MAL's proposal requires a defining package, which is 
counterproductive if you have a pure package with no base, since it 
now requires you to create an additional project on PyPI just to hold 
your defining package.



I'd appreciate it if the PEP could also be extended cover Twisted's 
very similar mechanism for namespace packages, 
twisted.plugin.pluginPackagePaths.  I know this is not quite as 
widely used as setuptools' namespace package support, but its 
existence belies a need for standardization.


The PEP also seems a bit vague with regard to the treatment of other 
directories containing __init__.py and *.pkg files.


Do you have a clarification to suggest?  My understanding (probably a 
projection) is that to be a nested namespace package, you have to 
have a parent namespace package.



  The concept of a defining package seems important to avoid 
conflicts like this one:


   http://twistedmatrix.com/trac/ticket/2339

More specifically I don't quite understand the PEP's intentions 
towards hierarchical packages.  It says that all of sys.path will be 
searched, but what about this case?


In Twisted, the suggested idiom to structure a project which wants 
to provide Twisted plugins is to have a directory structure like this:


 MyProject/
   myproject/
 __init__.py
   twisted/
 plugins/
   myproject_plugin.py

If you then put MyProject on PYTHONPATH, MyProject/twisted/plugins 
will be picked up automatically by the plugin machinery.


Namespaces are not plugins and vice versa.  The purpose of a 
namespace package is to allow projects managed by the same entity to 
share a namespace (ala Java package names) and avoid naming 
conflicts with other authors.


A plugin system, by contrast, is explicitly intended for use by 
multiple authors, so the use case is rather different...  and using 
namespace packages for plugins actually *increases* the possibility 
of naming conflicts, unless you add back in another level of 
hierarchy.  (As apparently you are recommending via myproject_plugin.)



  However, as twisted is *not* a namespace package in the same 
way, .py files in MyProject/twisted/ would not be picked up - this 
is very much intentional, since the twisted namespace is intended 
to be reserved for packages that we actually produce.  If either 
MyProject/twisted or MyProject/twisted/plugins/ had an __init__.py, 
then no modules in MyProject/twisted/plugins/ would be picked up, 
because it would be considered a conflicting package.


Precisely.  Note, however, that neither is twisted.plugins a 
namespace package, and it should not contain any .pkg files.  I don't 
think it's reasonable to abuse PEP 382 namespace packages as a plugin 
system.  In setuptools' case, a different mechanism is provided for 
locating plugin code, and of course Twisted already has its own 
system for the same thing.  It would be nice to have a standardized 
way of locating plugins in the stdlib, but that will need to be a 
different PEP.



I hope this all makes sense.  As I understand it, both setuptools 
and the proposed standard would either still have the bug described 
by ticket 2339 above, or would ignore twisted/plugins/ as a 
namespace package because its parent isn't a namespace package.


If twisted/ lacked an __init__.py, then setuptools would ignore 
it.  Under PEP 382, the same, unless it had .pkg files.  (Again, 
setuptools explicitly does not support using namespace packages as a 
plugin mechanism.)



P.S.: vendor packaging systems *ARE* a major use case for just about 
any aspect of Python's package structure.  I really liked MvL's 
coverage of vendor packages, in the PEP, since this could equally 
well apply to 

Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Ned Deily
In article 
b8ad139e0904152318p5473cbe5yb5f55a19894cc...@mail.gmail.com,
 Jess Austin jess.aus...@gmail.com wrote:
 I'm new to python core development, and I've been advised to write to
 python-dev concerning a feature/patch I've placed at
 http://bugs.python.org/issue5434, with Rietveld at
 http://codereview.appspot.com/25079.

Without having looked at the code, I wonder whether you've looked at 
python-dateutil.   I believe its relativedelta type does what you 
propose, plus much more, and it has the advantage of being widely used 
and tested.

http://labix.org/python-dateutil

-- 
 Ned Deily,
 n...@acm.org

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Jess Austin
On Thu, Apr 16, 2009 at 3:45 AM,  s...@pobox.com wrote:
     date(2008, 1, 30) + monthdelta(1)
    datetime.date(2008, 2, 29)

 What would this loop would print?

    for d in range(1, 32):
        print date(2008, 1, d) + monthdelta(1)


 for d in range(1, 32):
... print(date(2008, 1, d) + monthdelta(1))
...
2008-02-01
2008-02-02
2008-02-03
2008-02-04
2008-02-05
2008-02-06
2008-02-07
2008-02-08
2008-02-09
2008-02-10
2008-02-11
2008-02-12
2008-02-13
2008-02-14
2008-02-15
2008-02-16
2008-02-17
2008-02-18
2008-02-19
2008-02-20
2008-02-21
2008-02-22
2008-02-23
2008-02-24
2008-02-25
2008-02-26
2008-02-27
2008-02-28
2008-02-29
2008-02-29
2008-02-29


 I have this funny feeling that arithmetic using monthdelta wouldn't always
 be intuitive.

I think that's true, especially since these calculations are not
necessarily invertible:


 date(2008, 1, 30) + monthdelta(1)
datetime.date(2008, 2, 29)
 date(2008, 2, 29) - monthdelta(1)
datetime.date(2008, 1, 29)


It could be that non-intuitivity is inherent in the problem of dealing
with dates and months.  I've aimed for a good compromise between the
needs of the problem and the pythonic example of timedelta.  I would
submit that timedelta itself isn't intuitive at first blush,
especially if one was weaned on the arcana of RDBMS date functions,
but after one uses timedelta for just a bit it makes total sense.  I
hope the same may be said of monthdelta.

cheers,
Jess
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Paul Moore
2009/4/16 Antoine Pitrou solip...@pitrou.net:
 Paul Moore p.f.moore at gmail.com writes:

 Oh, certainly! But in the absence of intuitive, I've found in the
 past that standardised is often better than nothing  (For
 example, I use Oracle's add_months function fairly often - it's not
 perfect, and not always intuitive, but at least it's well-defined in
 the corner cases, and fine for normal use).

 I think something like date.add_months() would be better than the proposed
 monthdelta. The monthdelta proposal suggests that addition is something
 well-defined and rigourous, which is not really the case here (for example, if
 you add a monthdelta and then substract it again, I'm not sure you always get
 back the original date).

I didn't particularly get that impression, but I understand what
you're saying. Personally, I don't think it matters much one way or
the other.

But as well as monthdelta, the proposal included monthmod. I'm not
entirely happy with the name, but I like the idea - and particularly
the invariant dt + monthmod(dt, dt+td)[0] + monthmod(dt, dt+td)[1] ==
dt + td. For me, that makes it a lot easier to reason about month
increments.

One thing I have certainly needed in the past is a robust way of
converting a difference between two dates into natural language - 3
years, 2 months, 1 week and 5 days (or whatever). For that type of
application, monthmod would have been invaluable.

In my view, monthdelta seems a lot more natural alongside monthmod,
than an add_months method would. And as monthmod is a function of two
dates, it can't really be a method (OK, I know, something horrid like
date1.monthdiff(date2) is possible, but honestly, I don't see that as
reasonable).

But this type of API design discussion does emphasise why I think the
module should be a 3rd party package for a while before going into the
stdlib.

Paul.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Jess Austin
On Thu, Apr 16, 2009 at 5:16 AM, Dirkjan Ochtman dirk...@ochtman.nl wrote:
 On Thu, Apr 16, 2009 at 11:54, Amaury Forgeot d'Arc amaur...@gmail.com 
 wrote:
 In my opinion:
 arithmetic with months is a mess. There is no such month interval or
 year interval with a precise definition.
 If we adopt some kind of month manipulation, it should be a function
 or a method, like you would do for features like last_day_of_month(d),
 or following_weekday(d, 'monday').

    date(2008, 1, 30).add_months(1) == date(2008, 2, 29)

 I concur. Trying to shoehorn month arithmetic into timedelta is a
 PITA, precisely because it's somewhat inexact. It's better to have
 some separate behavior that has well-defined behavior in edge cases.

This is my experience also, and including a distinct and well-defined
behavior in the core is exactly my intention with this patch.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Jess Austin
Thanks for everyone's comments!

On Thu, Apr 16, 2009 at 9:54 AM, Paul Moore p.f.mo...@gmail.com wrote:
 I like the idea in principle. In practice, of course, month
 calculations are inherently ill-defined, so you need to be very
 specific in documenting all of the edge cases, and you should have
 strong use cases to ensure that the behaviour implemented matches user
 requirements. (I haven't yet had time to read the patch - you may well
 already have these points covered, certainly your comments above
 indicate that you appreciate the subtleties involved).

 I agree that ultimately it would be useful in the core. However, I'd
 suggest that you release the functionality as an independent module in
 the first instance, to establish it outside of the core. Once it has
 matured somewhat as a 3rd party module, it would then be ready for
 integration in the core. This also has the benefit that it makes the
 functionality available to users of Python 2.6 (and possibly earlier)
 rather than just in 2.7/3.1 onwards.

I have uploaded a python-coded version of this functionality to the
bug page.  I should backport it through 2.3 and post that to pypi, but
I haven't done that yet.  The current effort was focused on the C
module since that's how the rest of datetime is implemented, and also
I wanted to learn a bit about CPython internals.  To the latter point,
I would _really_ appreciate it if someone could leave a few comments
on Rietveld.

 Please let me know what you think of the idea and/or its execution.

 I hope the above comments help. Ultimately, I'd like to see this added
 to the core. It's tricky enough that having a standard
 implementation is a definite benefit in itself. But equally, I'd give
 it time to iron out the corner cases on a faster development cycle
 than the core offers before freezing it as part of the stdlib.


I understand these concerns.  I think I was too brief in my initial
message.  Here are the docstrings:

 print(monthdelta.__doc__)
Months offset from a date or datetime.

monthdeltas allow date calculation without regard to the different lengths
of different months. A monthdelta value added to a date produces another
date that has the same day-of-the-month, regardless of the lengths of the
intervening months. If the resulting date is in too short a month, the
last day in that month will result:

date(2008,1,30) + monthdelta(1) - date(2008,2,29)

monthdeltas may be added, subtracted, multiplied, and floor-divided
similarly to timedeltas. They may not be added to timedeltas directly, as
both classes are intended to be used directly with dates and datetimes.
Only ints may be passed to the constructor, the default argument of which
is 1 (one). monthdeltas are immutable.

NOTE: in calculations involving the 29th, 30th, and 31st days of the
month, monthdeltas are not necessarily invertible [i.e., the result above
would NOT imply that date(2008,2,29) - monthdelta(1) - date(2008,1,30)].

 print(monthmod.__doc__)
monthmod(start, end) - (monthdelta, timedelta)

Distribute the interim between start and end dates into monthdelta and
timedelta portions. If and only if start is after end, returned monthdelta
will be negative. Returned timedelta is never negative, and is always
smaller than the month in which end occurs.

Invariant: dt + monthmod(dt, dt+td)[0] + monthmod(dt, dt+td)[1] = dt + td


There is better-looking documentation in html/library/datetime.html
and html/c-api/datetime.html in the patch.  By all means, if you're
curious, download the patch and try it out yourself!

cheers,
Jess
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] RELEASED Python 2.6.2

2009-04-16 Thread Russell Owen
I installed the Mac binary on my Intel 10.5.6 system and it works,  
except it still uses Apple's system Tcl/Tk 8.4.7 instead of my  
ActiveState 8.4.19 (which is in /Library/Frameworks where one would  
expect).


I just built python from source and that version does use ActiveState  
8.4.19.


I wish I knew what's going on. Not being able to use the binary  
distros is a bit of a pain.


Just out of curiosity: which 3rd party Tcl/Tk did you have installed  
when you made the installer? Perhaps if it was 8.5 that would explain  
it. If so I may try updating my Tcl/Tk -- I've been wanting some of  
the bug fixes in 8.5 anyway.


-- Russell

On Apr 16, 2009, at 5:35 AM, Ronald Oussoren wrote:



On 15 Apr, 2009, at 22:47, Russell E. Owen wrote:


Thank you for 2.6.2.

I see the Mac binary installer isn't out yet (at least it is not  
listed
on the downloads page). Any chance that it will be compatible with  
3rd

party Tcl/Tk?


The Mac installer is late because I missed the pre-announcement of  
the 2.6.2 tag. I sent the installer to Barry earlier today.


The installer was build using a 3th-party installation of Tcl/Tk.

Ronald


___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Jared Grubb

On 16 Apr 2009, at 11:42, Paul Moore wrote:
The key thing missing (I believe) from dateutil is any equivalent of  
monthmod.



I agree with that. It's well-defined and it makes a lot of sense. +1

But, I dont think monthdelta can be made to work... what should the  
following be?


print(date(2008,1,30) + monthdelta(1))
print(date(2008,1,30) + monthdelta(2))
print(date(2008,1,30) + monthdelta(1) + monthdelta(1))

Jared

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Robert Kern

On 2009-04-16 13:42, Paul Moore wrote:

2009/4/16 Ned Deilyn...@acm.org:

In article
b8ad139e0904152318p5473cbe5yb5f55a19894cc...@mail.gmail.com,
  Jess Austinjess.aus...@gmail.com  wrote:

I'm new to python core development, and I've been advised to write to
python-dev concerning a feature/patch I've placed at
http://bugs.python.org/issue5434, with Rietveld at
http://codereview.appspot.com/25079.

Without having looked at the code, I wonder whether you've looked at
python-dateutil.   I believe its relativedelta type does what you
propose, plus much more, and it has the advantage of being widely used
and tested.


The key thing missing (I believe) from dateutil is any equivalent of monthmod.

Hmm, it might be possible via relativedelta(d1,d2), but it's not clear
to me from the documentation precisely what attributes/methods of a
relativedelta object are valid for getting data *out* of it.


I thought the examples were quite clear. relativedelta() has an alternate 
constructor precisely suited to these calculations but is general and handles 
more than just months.


 from dateutil.relativedelta import *
 dt = relativedelta(months=1)
 dt
relativedelta(months=+1)
 from datetime import datetime
 datetime(2009, 1, 15) + dt
datetime.datetime(2009, 2, 15, 0, 0)
 datetime(2009, 1, 31) + dt
datetime.datetime(2009, 2, 28, 0, 0)
 dt.months
1
 datetime(2009, 1, 31) + relativedelta(years=-1)
datetime.datetime(2008, 1, 31, 0, 0)

--
Robert Kern

I have come to believe that the whole world is an enigma, a harmless enigma
 that is made terrible by our own mad attempt to interpret it as though it had
 an underlying truth.
  -- Umberto Eco

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Python-Dev Digest, Vol 69, Issue 143

2009-04-16 Thread Jess Austin
Jared Grubb jared.gr...@gmail.com wrote:
 On 16 Apr 2009, at 11:42, Paul Moore wrote:
 The key thing missing (I believe) from dateutil is any equivalent of
 monthmod.


 I agree with that. It's well-defined and it makes a lot of sense. +1

 But, I dont think monthdelta can be made to work... what should the
 following be?

 print(date(2008,1,30) + monthdelta(1))
2008-02-29
 print(date(2008,1,30) + monthdelta(2))
2008-03-30
 print(date(2008,1,30) + monthdelta(1) + monthdelta(1))
2008-03-29

This is a perceptive observation: in the absence of parentheses to
dictate a different order of operations, the third quantity will
differ from the second.  Furthermore, this won't _always_ be true,
just for dates near the end of the month, which is nonintuitive.
(Incidentally, this is another reason why this functionality should
not just be lumped into timedelta; guarantees that have long existed
for operations with timedelta would no longer hold if it tried to deal
with months.)

I find that date calculations involving months involve a certain
amount of inherent confusion.  I've tried to reduce this by
introducing well-specified functionality that will allow accurate
reasoning, as part of the core's included batteries.  I think that one
who uses these objects will develop an intuition and write accurate
code quickly.  It is nonintuitive that order of operation matters for
addition of months, just as it matters for subtraction and division of
all objects, but with the right tools we can deal with this.  An
interesting consequence is that if I want to determine if date b is
more than a month after date a, sometimes I should use:

b - monthdelta(1)  a

rather than

a + monthdelta(1)  b

[Consider a list of run dates for a process that should run the last
day of every month: a might be date(2008, 2, 29) while b is
date(2008, 3, 31). In this case the two expressions would have
different values.]

cheers,
Jess
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Jess Austin
Jon Ribbens jon+python-...@unequivocal.co.uk wrote:
 On Thu, Apr 16, 2009 at 12:10:36PM +0400, Oleg Broytmann wrote:
  This patch adds a monthdelta class and a monthmod function to the
  datetime module.  The monthdelta class is much like the existing
  timedelta class, except that it represents months offset from a date,
  rather than an exact period offset from a date.

    I'd rather see the code merged with timedelta: timedelta(months=n).

 Unfortunately, that's simply impossible. A timedelta is a fixed number
 of seconds, and the time between one month and the next varies.

I agree.


 I am very much in favour of there being the ability to add months to
 dates though. Obviously there is the question of what to do when you
 move forward 1 month from the 31st January; in my opinion an optional
 argument to specify different behaviours would be nice.

Others have suggested raising an exception when a month calculation
lands on an invalid date.  Python already has that; it's spelled like
this:

 dt = date(2008, 1, 31)
 dt.replace(month=dt.month + 1)
Traceback (most recent call last):
  File stdin, line 1, in module
ValueError: day is out of range for month

What other behavior options besides last-valid-day-of-the-month
would you like to see?

cheers,
Jess
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Antoine Pitrou
Jess Austin jess.austin at gmail.com writes:
 
 What other behavior options besides last-valid-day-of-the-month
 would you like to see?

IMHO, the question is rather what the use case is for the behaviour you are
proposing. In which kind of situation is it acceptable to turn 31/2 silently
into 29/2?



___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Eric Smith

Jess Austin wrote:

What other behavior options besides last-valid-day-of-the-month
would you like to see?


- Add 30 days to the source date.
I'm sure there are others.

Followups to python-ideas.

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Paul Moore
2009/4/16 Robert Kern robert.k...@gmail.com:
 On 2009-04-16 13:42, Paul Moore wrote:

 2009/4/16 Ned Deilyn...@acm.org:

 In article
 b8ad139e0904152318p5473cbe5yb5f55a19894cc...@mail.gmail.com,
  Jess Austinjess.aus...@gmail.com  wrote:

 I'm new to python core development, and I've been advised to write to
 python-dev concerning a feature/patch I've placed at
 http://bugs.python.org/issue5434, with Rietveld at
 http://codereview.appspot.com/25079.

 Without having looked at the code, I wonder whether you've looked at
 python-dateutil.   I believe its relativedelta type does what you
 propose, plus much more, and it has the advantage of being widely used
 and tested.

 The key thing missing (I believe) from dateutil is any equivalent of
 monthmod.

 Hmm, it might be possible via relativedelta(d1,d2), but it's not clear
 to me from the documentation precisely what attributes/methods of a
 relativedelta object are valid for getting data *out* of it.

 I thought the examples were quite clear. relativedelta() has an alternate
 constructor precisely suited to these calculations but is general and
 handles more than just months.

 from dateutil.relativedelta import *
 dt = relativedelta(months=1)
 dt
 relativedelta(months=+1)
 from datetime import datetime
 datetime(2009, 1, 15) + dt
 datetime.datetime(2009, 2, 15, 0, 0)
 datetime(2009, 1, 31) + dt
 datetime.datetime(2009, 2, 28, 0, 0)
 dt.months
 1
 datetime(2009, 1, 31) + relativedelta(years=-1)
 datetime.datetime(2008, 1, 31, 0, 0)

Yes, but given

r = relativedelta(d1, d2)

how do I determine the number of months between d1 and d2, and the
remainder - what monthmod gives me. From the code, r.months looks
like it works, but it's not documented, and I'm not 100% sure if it's
always computed.

The use case I'm thinking of is converting the difference between 2
dates into 3 years, 2 months, 5 days or whatever. I've got an
application which needs to get this right for one of the dates being
29th Feb, so I *really* get to exercise the corner cases :-)

Paul
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Robert Kern

On 2009-04-16 17:17, Paul Moore wrote:

2009/4/16 Robert Kernrobert.k...@gmail.com:



from dateutil.relativedelta import *
dt = relativedelta(months=1)
dt

relativedelta(months=+1)

from datetime import datetime
datetime(2009, 1, 15) + dt

datetime.datetime(2009, 2, 15, 0, 0)

datetime(2009, 1, 31) + dt

datetime.datetime(2009, 2, 28, 0, 0)

dt.months

1

datetime(2009, 1, 31) + relativedelta(years=-1)

datetime.datetime(2008, 1, 31, 0, 0)


Yes, but given

r = relativedelta(d1, d2)

how do I determine the number of months between d1 and d2, and the
remainder - what monthmod gives me.


Oops! Sorry, I read too quickly and misread monthmod as monthdelta.


From the code, r.months looks
like it works, but it's not documented, and I'm not 100% sure if it's
always computed.


The result of relativedelta(d1, d2) is the same thing as if it were explicitly 
constructed from the years=, months=, etc. keyword arguments. From this example, 
I think this is something that can be relied upon:



It works with dates too.

 relativedelta(TODAY, johnbirthday)
relativedelta(years=+25, months=+5, days=+11, hours=+12)



The use case I'm thinking of is converting the difference between 2
dates into 3 years, 2 months, 5 days or whatever. I've got an
application which needs to get this right for one of the dates being
29th Feb, so I *really* get to exercise the corner cases :-)


I believe relativedelta() is intended for this use case although it may resolve 
ambiguities in a different way than you were hoping.


--
Robert Kern

I have come to believe that the whole world is an enigma, a harmless enigma
 that is made terrible by our own mad attempt to interpret it as though it had
 an underlying truth.
  -- Umberto Eco

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Jess Austin
Antoine Pitrou solip...@pitrou.net wrote:
 Jess Austin jess.austin at gmail.com writes:

 What other behavior options besides last-valid-day-of-the-month
 would you like to see?

 IMHO, the question is rather what the use case is for the behaviour you are
 proposing. In which kind of situation is it acceptable to turn 31/2 silently
 into 29/2?

I have worked in utility/telecom billing, and needed to examine large
numbers of invoice dates, fulfillment dates, disconnection dates,
payment dates, collection event dates, etc.  There would often be
particular rules for the relationships among these dates, and since
many companies generate invoices every day of the month, you couldn't
rely on rules like this always happens on the 5th.  Here is an
example (modified) from the doc page.  We want to find missing
invoices:

 invoices = {123: [date(2008, 1, 31),
...   date(2008, 2, 29),
...   date(2008, 3, 31),
...   date(2008, 4, 30),
...   date(2008, 5, 31),
...   date(2008, 6, 30),
...   date(2008, 7, 31),
...   date(2008, 12, 31)],
... 456: [date(2008, 1, 1),
...   date(2008, 5, 1),
...   date(2008, 6, 1),
...   date(2008, 7, 1),
...   date(2008, 8, 1),
...   date(2008, 11, 1),
...   date(2008, 12, 1)]}
 for account, dates in invoices.items():
... a = dates[0]
... for b in dates[1:]:
... if b - monthdelta(1)  a:
... print('account', account, 'missing between', a, 'and', b)
... a = b
...
account 456 missing between 2008-01-01 and 2008-05-01
account 456 missing between 2008-08-01 and 2008-11-01
account 123 missing between 2008-07-31 and 2008-12-31


In general, sometimes we care more about the number of months that
separate dates than we do about the exact dates themselves.  This is
perhaps not the most common situation for date calculations, but it
does come up for some of us.  I tired of writing one-off solutions
that would fail in unexpected corner cases, so I created this patch.
Paul Moore has also described his favorite use-case for this
functionality.

cheers,
Jess
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread James Y Knight

On Apr 16, 2009, at 5:47 PM, Antoine Pitrou wrote:
IMHO, the question is rather what the use case is for the behaviour  
you are
proposing. In which kind of situation is it acceptable to turn 31/2  
silently

into 29/2?


Essentially any situation in which you'd actually want a next month  
operation it's acceptable to do that.


It's a human-interface operation, and as such, everyone (ahem) knows  
what it means to say 2 months from now, but the details don't  
usually have to be thought about too much. Of course when you have a  
computer program, you actually need to tell it what you really mean.


I do a fair amount of date calculating, and use two different kinds of  
add-month:


Option 1)
Add n to the month number, truncate day number to fit the month you  
end up in.


Option 2)
As above, but with the additional caveat that if the original date is  
the last day of its month, the new day should also be the last day of  
the new month. That is:

April 30th + 1 month = May 31st, instead of May 30th.

They're both useful behaviors, in different circumstances.

James
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread skip

 I have this funny feeling that arithmetic using monthdelta wouldn't
 always be intuitive.

Jess I think that's true, especially since these calculations are not
Jess necessarily invertible:

 date(2008, 1, 30) + monthdelta(1)
datetime.date(2008, 2, 29)
 date(2008, 2, 29) - monthdelta(1)
datetime.date(2008, 1, 29)

Jess It could be that non-intuitivity is inherent in the problem of
Jess dealing with dates and months.

To which I would respond:

 import this
The Zen of Python, by Tim Peters

...
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
...

From the discussion I've seen so far, it's not clear that there is one
obvious way to do it, and the ambiguity of the problem forces people to
guess.  

My recommendations after letting it roll around in the back of my brain for
the day:

* I think it would be best to leave the definition of monthdelta up to
  individual users.  That is, add nothing to the datetime module and let
  them write a function which does what they want it to do.

* The idea/implementation probably needs to bake on the python-ideas
  list and perhaps comp.lang.python for a bit to see if some concensus
  can be reached on reasonable functionality.

(I'm a bit behind on this thread.  Hopefully someone else has already
suggested these two things.)

Skip
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Tennessee Leeuwenburg
My thoughts on balance regarding monthdeltas:
  -- Month operations are useful, people will want to do them
  -- I think having a monthdelta object rather than a method makes sense to
me
  -- I think the documentation is severely underdone. The functionality is
not intuitive
 and therefore the docs need a lot more detail than usual
  -- Can you specify 1 month plus 10 days?, i.e. add a monthdelta to a
timedelta?
  -- What about other cyclical periods (fortnights, 28 days, lunar cycles,
high tides)?

Cheers,
-T
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Jess Austin
On Thu, Apr 16, 2009 at 7:18 PM,  s...@pobox.com wrote:

     I have this funny feeling that arithmetic using monthdelta wouldn't
     always be intuitive.

    Jess I think that's true, especially since these calculations are not
    Jess necessarily invertible:

     date(2008, 1, 30) + monthdelta(1)
    datetime.date(2008, 2, 29)
     date(2008, 2, 29) - monthdelta(1)
    datetime.date(2008, 1, 29)

    Jess It could be that non-intuitivity is inherent in the problem of
    Jess dealing with dates and months.

 To which I would respond:

     import this
    The Zen of Python, by Tim Peters

    ...
    In the face of ambiguity, refuse the temptation to guess.
    There should be one-- and preferably only one --obvious way to do it.
    Although that way may not be obvious at first unless you're Dutch.
    ...

 From the discussion I've seen so far, it's not clear that there is one
 obvious way to do it, and the ambiguity of the problem forces people to
 guess.

 My recommendations after letting it roll around in the back of my brain for
 the day:

    * I think it would be best to leave the definition of monthdelta up to
      individual users.  That is, add nothing to the datetime module and let
      them write a function which does what they want it to do.

    * The idea/implementation probably needs to bake on the python-ideas
      list and perhaps comp.lang.python for a bit to see if some concensus
      can be reached on reasonable functionality.

So far, all the other solutions to the problem that have been
mentioned are easily supported in current python.

Raise an exception when a calculation results in an invalid date:

 dt = date(2008, 1, 31)
 dt.replace(month=dt.month + 1)
Traceback (most recent call last):
  File stdin, line 1, in module
ValueError: day is out of range for month


Add exactly 30 days to a date:

 dt + timedelta(30)
datetime.date(2008, 3, 1)


These operations are useful in particular contexts.  What I've
submitted is also useful, and currently isn't easy in core,
batteries-included python.  While I would consider the foregoing
interpretation of the Zen to be backwards (this doesn't add another
way to do something that's already possible, it makes possible
something that currently encourages one to pull her hair out), I
suppose it doesn't matter.  If adding a class and a function to a
module will require extended advocacy on -ideas and c.l.p, I'm
probably not the person for the job.

If, on the other hand, one of the committers wants to toss this in at
some point, whether now or 3 versions down the road, the patch is up
at bugs.python.org (and I'm happy to make any suggested
modifications).  I'm glad to have written this; I learned a bit about
CPython internals and scraped a layer of rust off my C skills.  I will
go ahead and backport the python-coded version to 2.3.  I'll continue
this conversation with whomever for however long, but I suspect this
topic will soon have worn out its welcome on python-dev.

cheers,
Jess
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Python-Dev Digest, Vol 69, Issue 143

2009-04-16 Thread Greg Ewing

Jess Austin wrote:


This is a perceptive observation: in the absence of parentheses to
dictate a different order of operations, the third quantity will
differ from the second.


Another aspect of this is the use case mentioned right
at the beginning of this discussion concerning a recurring
event on a particular day of the month.

If you do this the naive way by just repeatedly adding one
of these monthdeltas to the previous date, and the date is
near the end of the month, it will eventually end up
drifting to the 28th of every month.

--
Greg
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Python-Dev Digest, Vol 69, Issue 143

2009-04-16 Thread Tennessee Leeuwenburg
Actually, that's a point.

If its' the 31st of Jan, then +1 monthdelta will be 28 Feb and another +1
will be 28 March whereas 31st Jan +2 monthdeltas will be 31 March.

That's the kind of thing which really needs to be documented, or I think
people really will make mistakes.

For example, should a monthdelta include a goal-day so that the example
above would go 31 Jan / 28 Feb / 31 March?

-T

On Fri, Apr 17, 2009 at 11:55 AM, Greg Ewing greg.ew...@canterbury.ac.nzwrote:

 Jess Austin wrote:

  This is a perceptive observation: in the absence of parentheses to
 dictate a different order of operations, the third quantity will
 differ from the second.


 Another aspect of this is the use case mentioned right
 at the beginning of this discussion concerning a recurring
 event on a particular day of the month.

 If you do this the naive way by just repeatedly adding one
 of these monthdeltas to the previous date, and the date is
 near the end of the month, it will eventually end up
 drifting to the 28th of every month.

 --
 Greg

 ___
 Python-Dev mailing list
 Python-Dev@python.org
 http://mail.python.org/mailman/listinfo/python-dev
 Unsubscribe:
 http://mail.python.org/mailman/options/python-dev/tleeuwenburg%40gmail.com




-- 
--
Tennessee Leeuwenburg
http://myownhat.blogspot.com/
Don't believe everything you think
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Steven D'Aprano
On Fri, 17 Apr 2009 07:41:19 am Jess Austin wrote:

 Others have suggested raising an exception when a month calculation
 lands on an invalid date.  Python already has that; it's spelled like

 this:
  dt = date(2008, 1, 31)
  dt.replace(month=dt.month + 1)

 Traceback (most recent call last):
   File stdin, line 1, in module
 ValueError: day is out of range for month

 What other behavior options besides last-valid-day-of-the-month
 would you like to see?


Adding one month to 31st January could mean:

1: raise an exception
2: return 28th February (last day of February)
3: return 3rd April (1 month = 31 days)
4: return 2nd April (1 month = 30 days)
5: return 28th February (1 month = 4 weeks = 28 days)
6: next business day after any of the above dates

I don't really expect Python to support scenario 6, as that would 
require knowledge of local public holidays and conventions for week 
ends and working days.

Open Office spreadsheet includes the following relevant functions:

EDATE(start date; months)
returns the serial number of the date that is a specified number of 
months before or after the start date.

EOMONTH(start date; months)
returns the serial number of the last day of the month that comes a 
certain number of months before or after the start date.

MONTHS(start date; end date; type)
calculate the difference in months between start and end date, possible 
values for type include 0 (interval) and 1 (in calendar months).

Rather than a series of almost-identical functions catering for people 
who want 28 day months and 31 day months, I propose a keyword argument 
days_in_month which specifies the number of days in a month. Any 
positive integer should be accepted, but of course only 28, 30 and 31 
will be meaningful for the common English meaning of the word month. 
0 or None (the default) should trigger last day of the month 
behaviour (scenario 2 above).

That will (I think) simplify both documentation and implementation. 
Adding 1 month to a day will be defined as adding days_in_month days 
(if given), and if not given, adding 31 days but truncating the result 
to the last day of the next month.

Thoughts?




-- 
Steven D'Aprano
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Steven D'Aprano
On Fri, 17 Apr 2009 12:29:11 pm Steven D'Aprano wrote:

 Adding one month to 31st January could mean:

 1: raise an exception
 2: return 28th February (last day of February)
 3: return 3rd April (1 month = 31 days)
 4: return 2nd April (1 month = 30 days)
 5: return 28th February (1 month = 4 weeks = 28 days)

Obviously I meant March, not April. Oops.



-- 
Steven D'Aprano
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread glyph


On 16 Apr, 11:11 pm, f...@fuhm.net wrote:

On Apr 16, 2009, at 5:47 PM, Antoine Pitrou wrote:


It's a human-interface operation, and as such, everyone (ahem) knows 
what it means to say 2 months from now, but the details don't 
usually have to be thought about too much. Of course when you have a 
computer program, you actually need to tell it what you really mean.


I do a fair amount of date calculating, and use two different kinds of 
add-month:


Option 1)
Add n to the month number, truncate day number to fit the month you 
end up in.


Option 2)
As above, but with the additional caveat that if the original date is 
the last day of its month, the new day should also be the last day of 
the new month. That is:

April 30th + 1 month = May 31st, instead of May 30th.

They're both useful behaviors, in different circumstances.


I don't have a third option, but something that would be useful to 
mention in the documentation for monthdelta: frequently users will 
want a recurring monthly event.  It's important to note that you need 
to keep your original date around if you want these rules to be 
consistently applied.  For example, if you have a monthly billing cycle 
that starts on May 31, you need to keep the original May 31 around to 
add monthdelta(X) if you want it to be May 31 when it rolls around next 
year; otherwise every time February rolls around all of your end-of- 
month dates get clamped to the 28th of every month.  (Unless you're 
following James's option 2, of course, in which case things which are 
normally on the 28th will get clamped to the 31st of following months.)


My experience with month-calculating software suggests that this is 
something very easy to screw up.

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Steven D'Aprano
On Fri, 17 Apr 2009 07:47:14 am Antoine Pitrou wrote:
 Jess Austin jess.austin at gmail.com writes:
  What other behavior options besides last-valid-day-of-the-month
  would you like to see?

 IMHO, the question is rather what the use case is for the behaviour
 you are proposing. In which kind of situation is it acceptable to
 turn 31/2 silently into 29/2?

Any time the user expects one month from the last day of January to 
mean the last day of February. I dare say that if you did a poll of 
non-programmers, that would be a very common expectation, possibly the 
most common.

I just asked the missus, who is a non-programmer, what date is one month 
after 31st January and her answer was 2rd of March on leap years, 
otherwise 3rd of March.


-- 
Steven D'Aprano
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread skip

Jess If, on the other hand, one of the committers wants to toss this in
Jess at some point, whether now or 3 versions down the road, the patch
Jess is up at bugs.python.org (and I'm happy to make any suggested
Jess modifications).

Again, I think it needs to bake a bit.  I understand the desire and need for
doing date arithmetic with months.  Python is mature enough though that I
don't think you can just toss this in.  It should be available as a module
outside of Python so people can beat on it, flush out bugs, make suggestions
for enhancements, whatever.  I believe you mentioned putting it up on PyPI.
I think that's an excellent idea.

I've used parts of Gustavo Niemeyer's dateutil package for a couple years
and love it.  It's widely used.  Adding it to dateutil seems like another
possibility.  That would guarantee an instant user base.  From there, if it
is found to be useful it could make the leap to be part of the datetime
module.

Skip
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Python-Dev Digest, Vol 69, Issue 143

2009-04-16 Thread skip

Tennessee If its' the 31st of Jan, then +1 monthdelta will be 28 Feb
Tennessee and another +1 will be 28 March whereas 31st Jan +2
Tennessee monthdeltas will be 31 March.

Other possible arithmetics:

* 31 Jan 2008 + monthdelta(2) might be
31 Jan 2008 + 31 days (# days in Jan) + 29 days (# days in Feb)

* 31 Jan 2008 + monthdelta(2) might be
31 Jan 2008 + 29 days (# days in Feb) + 31 days (# days in Mar)

* Treat the day of the month of the base datetime as an offset from the
  end of the month.  29 Jan 2007 would thus have an EOM offset of -2.
  Adding monthdelta(2) would advance you into March with the resulting
  day being two from the end of the month, or 29 Mar 2007.  OTOH, adding
  monthdelta(1) you'd wind up on 26 Feb 2007.

* Consider the day of the month in the base datetime as an offset from
  the start of the month if it is closer to the start or as an offset
  from the end of the month if it is closer to the end.  12 Mar 2009 -
  monthdelta(2) would land you at 12 Jan 2009 whereas 17 Mar 2009 -
  monthdelta(1) would land you at 12 Feb 2009.

My mind spins at all the possibilities.  I suspect we've seen at least ten
different monthdelta rules just in this thread.  I don't know how much sense
they all make, but we can probably keep dreaming up new ones until the cows
come home.  Except for completely wacko sets of rules you can probably find
uses for most of them.  Bake, baby, bake.

pillsbury-doughboy-ly, y'rs,

Skip
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Python-Dev Digest, Vol 69, Issue 143

2009-04-16 Thread Steven D'Aprano
On Fri, 17 Apr 2009 12:10:59 pm Tennessee Leeuwenburg wrote:
 Actually, that's a point.

 If its' the 31st of Jan, then +1 monthdelta will be 28 Feb and
 another +1 will be 28 March whereas 31st Jan +2 monthdeltas will be
 31 March.

 That's the kind of thing which really needs to be documented, or I
 think people really will make mistakes.

It might be worth noting as an aside, but it should be obvious in the 
same way that string concatenation is different from numerical 
addition:

1 + 2 = 2 + 1
'1' + '2' != '2' + '1'


 For example, should a monthdelta include a goal-day so that the
 example above would go 31 Jan / 28 Feb / 31 March?

No, that just adds complexity.

Consider floating point addition. If you want to step through a loop 
while doing addition, you need to be aware of round-off error:

 x = 0.0
 step = 0.001
 for i in xrange(1000):
... x += step
...
 x
1.0007

The solution isn't to add a goal to the plus operator, but to fix your 
code to use a better algorithm:

 y = 0.0
 for i in xrange(1, 1001):
... y = i*step
...
 y
1.0

Same with monthdelta.



-- 
Steven D'Aprano
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] RELEASED Python 2.6.2

2009-04-16 Thread Ned Deily
In article dd982bd4-02ab-4395-afee-cd3d0eeb7...@u.washington.edu,
 Russell Owen ro...@u.washington.edu wrote:
 I installed the Mac binary on my Intel 10.5.6 system and it works,  
 except it still uses Apple's system Tcl/Tk 8.4.7 instead of my  
 ActiveState 8.4.19 (which is in /Library/Frameworks where one would  
 expect).
 
 I just built python from source and that version does use ActiveState  
 8.4.19.
 
 I wish I knew what's going on. Not being able to use the binary  
 distros is a bit of a pain.

You're right, the tkinter included with the 2.6.2 installer is not 
linked properly:

Is:
$ cd /Library/Frameworks/Python.framework/Versions/2.6
$ cd lib/python2.6/lib-dynload
$ otool -L _tkinter.so 
_tkinter.so:
   /System/Library/Frameworks/Tcl.framework/Versions/8.4/Tcl 
(compatibility version 8.4.0, current version 8.4.0)
   /System/Library/Frameworks/Tk.framework/Versions/8.4/Tk 
(compatibility version 8.4.0, current version 8.4.0)
   /usr/lib/libSystem.B.dylib [...]

should be:
_tkinter.so:
   /Library/Frameworks/Tcl.framework/Versions/8.4/Tcl (compatibility 
version 8.4.0, current version 8.4.19)
   /Library/Frameworks/Tk.framework/Versions/8.4/Tk (compatibility 
version 8.4.0, current version 8.4.19)
   /usr/lib/libSystem.B.dylib [...]

-- 
 Ned Deily,
 n...@acm.org

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 382: Namespace Packages

2009-04-16 Thread glyph

On 16 Apr, 03:36 pm, p...@telecommunity.com wrote:

At 03:46 AM 4/16/2009 +, gl...@divmod.com wrote:

On 15 Apr, 09:11 pm, p...@telecommunity.com wrote:


Twisted has its own system for namespace packages, and I'm not 
really sure where we fall in this discussion.  I haven't been able to 
follow the whole thread, but my original understanding was that the 
PEP supports defining packages, which we now seem to be calling 
base packages, just fine.


Yes, it does.  The discussion since the original proposal, however, has 
been dominated by MAL's counterproposal, which *requires* a defining 
package.


[snip clarifications]

Does that all make sense now?


Yes.  Thank you very much for the detailed explanation.  It was more 
than I was due :-).
MAL's proposal requires a defining package, which is counterproductive 
if you have a pure package with no base, since it now requires you to 
create an additional project on PyPI just to hold your defining 
package.


Just as a use-case: would the Java com.* namespace be an example of a 
pure package with no base?  i.e. lots of projects are in it, but no 
project owns it?
I'd appreciate it if the PEP could also be extended cover Twisted's 
very similar mechanism for namespace packages,


twisted.plugin.pluginPackagePaths.  I know this is not quite as 
widely used as setuptools' namespace package support, but its 
existence belies a need for standardization.


The PEP also seems a bit vague with regard to the treatment of other 
directories containing __init__.py and *.pkg files.


Do you have a clarification to suggest?  My understanding (probably a 
projection) is that to be a nested namespace package, you have to have 
a parent namespace package.


Just to clarify things on my end: namespace package to *me* means 
package with modules provided from multiple distributions (the 
distutils term).  The definition provided by the PEP, that a package is 
spread over multiple directories on disk, seems like an implementation 
detail.


Entries on __path__ slow down import, so my understanding of the 
platonic ideal of a system python installation is one which has a single 
directory where all packages reside, and a set of metadata off to the 
side explaining which files belong to which distributions so they can be 
uninstalled by a package manager.


Of course, for a development installation, easy uninstallation and quick 
swapping between different versions of relevant dependencies is more 
important than good import performance.  So in that case, you would want 
to optimize differently by having all of your distributions installed 
into separate directories, with a long PYTHONPATH or lots of .pth files 
to point at them.


And of course you may want a hybrid of the two.

So another clarification I'd like in the PEP is an explanation of 
motivation.  For example, it comes as a complete surprise to me that the 
expectation of namespace packages was to provide only single-source 
namespaces like zope.*, peak.*, twisted.*.  As I mentioned above, I 
implicitly thought this was more for com.*, twisted.plugins.*.


Right now it just says that it's a package which resides in multiple 
directories, and it's not made clear why that's a desirable feature.
  The concept of a defining package seems important to avoid 
conflicts like this one:


   http://twistedmatrix.com/trac/ticket/2339


[snip some stuff about plugins and package layout]
Namespaces are not plugins and vice versa.  The purpose of a namespace 
package is to allow projects managed by the same entity to share a 
namespace (ala Java package names) and avoid naming conflicts with 
other authors.


I think this is missing a key word: *separate* projects managed by the 
same entity.


Hmm.  I thought I could illustrate that the same problem actually occurs 
without using a plugin system, but I can actually only come up with an 
example if an application implements multi-library-version compatibility 
by doing


   try:
   from bad_old_name import bad_old_feature as feature
   except ImportError:
   from good_new_name import good_new_feature as feature

rather than the other way around; and that's a terrible idea for other 
reasons.  Other than that, you'd have to use 
pkg_resources.resource_listdir or somesuch, at which point you pretty 
much are implementing a plugin system.


So I started this reply disagreeing but I think I've convinced myself 
that you're right.
Precisely.  Note, however, that neither is twisted.plugins a namespace 
package, and it should not contain any .pkg files.  I don't think it's 
reasonable to abuse PEP 382 namespace packages as a plugin system.  In 
setuptools' case, a different mechanism is provided for locating plugin 
code, and of course Twisted already has its own system for the same 
thing. It would be nice to have a standardized way of locating plugins 
in the stdlib, but that will need to be a different PEP.


Okay.  So what I'm hearing is that Twisted should happily 

Re: [Python-Dev] Issue5434: datetime.monthdelta

2009-04-16 Thread Greg Ewing

Steven D'Aprano wrote:


2rd of March on leap years,

   ^^^

The turd of March?

--
Greg
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 382: Namespace Packages

2009-04-16 Thread P.J. Eby

At 03:58 AM 4/17/2009 +, gl...@divmod.com wrote:
Just as a use-case: would the Java com.* namespace be an example 
of a pure package with no base?  i.e. lots of projects are in it, 
but no project owns it?


Er, I suppose.  I was thinking more of the various 'com.foo' and 
'org.bar' packages as being the pure namespaces in question.  For 
Python, a flat is better than nested approach seems fine at the moment.



Just to clarify things on my end: namespace package to *me* means 
package with modules provided from multiple distributions (the 
distutils term).  The definition provided by the PEP, that a 
package is spread over multiple directories on disk, seems like an 
implementation detail.


Agreed.


Entries on __path__ slow down import, so my understanding of the 
platonic ideal of a system python installation is one which has a 
single directory where all packages reside, and a set of metadata 
off to the side explaining which files belong to which distributions 
so they can be uninstalled by a package manager.


True... except that part of the function of the PEP is to ensure that 
if you install those separately-distributed modules to the same 
directory, it still needs to work as a package and not have any 
inter-package file conflicts.



Of course, for a development installation, easy uninstallation and 
quick swapping between different versions of relevant dependencies 
is more important than good import performance.  So in that case, 
you would want to optimize differently by having all of your 
distributions installed into separate directories, with a long 
PYTHONPATH or lots of .pth files to point at them.


And of course you may want a hybrid of the two.


Yep.


So another clarification I'd like in the PEP is an explanation of 
motivation.  For example, it comes as a complete surprise to me that 
the expectation of namespace packages was to provide only 
single-source namespaces like zope.*, peak.*, twisted.*.  As I 
mentioned above, I implicitly thought this was more for com.*, 
twisted.plugins.*.


Well, aside from twisted.plugins, I wasn't aware of anybody in Python 
doing that...  and as I described, I never really interpreted that 
through the lens of namespace package vs. plugin finding.



Right now it just says that it's a package which resides in multiple 
directories, and it's not made clear why that's a desirable feature.


Good point; perhaps you can suggest some wording on these matters to Martin?


Okay.  So what I'm hearing is that Twisted should happily continue 
using our own wacky __path__-calculation logic for twisted.plugins, 
but that *twisted* should be a namespace package so that our 
separate distributions (TwistedCore, TwistedWeb, TwistedConch, et. 
al.) can be installed into separate directories.


Yes.

Thanks for taking the time to participate in this and add another 
viewpoint to the mix, not to mention clarifying some areas where the 
PEP could be clearer.


___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com