Skip to content

Creating a relativedelta instance with floating point value in integer quantity for months or years #411

@arouanet

Description

@arouanet

I ran into an issue when creating a relativedelta instance with a floating point argument for months or years (albeit containing an integer quantity) :

>>> import datetime
>>> from dateutil.relativedelta import relativedelta

>>> relativedelta(months=3.5)                # This raises an error, as expected
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "dateutil/relativedelta.py", line 100, in __init__
    raise ValueError("Non-integer years and months are "
ValueError: Non-integer years and months are ambiguous and not currently supported.

>>> relativedelta(months=3)                                # This is fine
relativedelta(months=+3)

>>> relativedelta(months=float(3))                         # So is this, but...
relativedelta(months=+3)

>>> datetime.date.today() + relativedelta(months=float(3)) # This doesn't work
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "dateutil/relativedelta.py", line 391, in __radd__
    return self.__add__(other)
  File "dateutil/relativedelta.py", line 363, in __add__
    day = min(calendar.monthrange(year, month)[1],
  File "/usr/lib/python2.7/calendar.py", line 121, in monthrange
    day1 = weekday(year, month, 1)
  File "/usr/lib/python2.7/calendar.py", line 113, in weekday
    return datetime.date(year, month, day).weekday()
TypeError: integer argument expected, got float

What is the expected behaviour? Should non-integer values in integer quantities raise an error? This check leads me to believe this is not the case:

# Check for non-integer values in integer-only quantities
if any(x is not None and x != int(x) for x in (years, months)):
    raise ValueError("Non-integer years and months are "
                     "ambiguous and not currently supported.")

Or should months and years arguments be converted to int internally when given as non-int? It doesn't seem quite right to me that calendar.monthrange() could be allowed to fail when the check for non-integer values lets a floating-point value through if it contains an integer quantity.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions