API documentation

This is the API reference for all public classes and functions in Spans.

Ranges

Range class

class spans.types.Range(lower=None, upper=None, lower_inc=None, upper_inc=None)

Abstract base class of all ranges.

Ranges are very strict about types. This means that both lower or upper must be of the given class or subclass or None.

All ranges are immutable. No default methods modify the range in place. Instead it returns a new instance.

Parameters:
  • lower – Lower end of range.

  • upper – Upper end of range.

  • lower_incTrue if lower end should be included in range. Default is True

  • upper_incTrue if upper end should be included in range. Default is False

Raises:
  • TypeError – If lower or upper bound is not of the correct type.

  • ValueError – If upper bound is lower than lower bound.

Changed in version 0.5.0: Changed name from range_ to Range

Note

All examples in this class uses intrange because this class is abstract.

adjacent(other)

Returns True if ranges are directly next to each other but does not overlap.

>>> intrange(1, 5).adjacent(intrange(5, 10))
True
>>> intrange(1, 5).adjacent(intrange(10, 15))
False

The empty set is not adjacent to any set.

This is the same as the -|- operator for two ranges in PostgreSQL.

Parameters:

other – Range to test against.

Returns:

True if this range is adjacent with other, otherwise False.

Raises:

TypeError – If given argument is of invalid type

contains(other)

Return True if this contains other. Other may be either range of same type or scalar of same type as the boundaries.

>>> intrange(1, 10).contains(intrange(1, 5))
True
>>> intrange(1, 10).contains(intrange(5, 10))
True
>>> intrange(1, 10).contains(intrange(5, 10, upper_inc=True))
False
>>> intrange(1, 10).contains(1)
True
>>> intrange(1, 10).contains(10)
False

Contains can also be called using the in operator.

>>> 1 in intrange(1, 10)
True

This is the same as the self @> other in PostgreSQL.

Parameters:

other – Object to be checked whether it exists within this range or not.

Returns:

True if other is completely within this range, otherwise False.

Raises:

TypeError – If other is not of the correct type.

difference(other)

Compute the difference between this and a given range.

>>> intrange(1, 10).difference(intrange(10, 15))
intrange(1, 10)
>>> intrange(1, 10).difference(intrange(5, 10))
intrange(1, 5)
>>> intrange(1, 5).difference(intrange(5, 10))
intrange(1, 5)
>>> intrange(1, 5).difference(intrange(1, 10))
intrange.empty()

The difference can not be computed if the resulting range would be split in two separate ranges. This happens when the given range is completely within this range and does not start or end at the same value.

>>> intrange(1, 15).difference(intrange(5, 10))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Other range must not be within this range

This does not modify the range in place.

This is the same as the - operator for two ranges in PostgreSQL.

Parameters:

other – Range to difference against.

Returns:

A new range that is the difference between this and other.

Raises:

ValueError – If difference bethween this and other can not be computed.

classmethod empty()

Returns an empty set. An empty set is unbounded and only contain the empty set.

>>> intrange.empty() in intrange.empty()
True

It is unbounded but the boundaries are not infinite. Its boundaries are returned as None. Every set contains the empty set.

endsbefore(other)

Test if this range ends before other. other may be either range or scalar. This only takes the upper end of the ranges into consideration. If the scalar or the upper end of the given range is less than or equal to this range’s upper end, True is returned.

>>> intrange(1, 5).endsbefore(5)
True
>>> intrange(1, 5).endsbefore(intrange(1, 5))
True
Parameters:

other – Range or scalar to test.

Returns:

True if this range ends before other, otherwise False

Raises:

TypeError – If other is of the wrong type.

endswith(other)

Test if this range ends with other. other may be either range or scalar.

>>> intrange(1, 5).endswith(4)
True
>>> intrange(1, 10).endswith(intrange(5, 10))
True
Parameters:

other – Range or scalar to test.

Returns:

True if this range ends with other, otherwise False

Raises:

TypeError – If other is of the wrong type.

intersection(other)

Returns a new range containing all points shared by both ranges. If no points are shared an empty range is returned.

>>> intrange(1, 5).intersection(intrange(1, 10))
intrange(1, 5)
>>> intrange(1, 5).intersection(intrange(5, 10))
intrange.empty()
>>> intrange(1, 10).intersection(intrange(5, 10))
intrange(5, 10)

This is the same as the + operator for two ranges in PostgreSQL.

Parameters:

other – Range to interect with.

Returns:

A new range that is the intersection between this and other.

left_of(other)

Test if this range other is strictly left of other.

>>> intrange(1, 5).left_of(intrange(5, 10))
True
>>> intrange(1, 10).left_of(intrange(5, 10))
False

The bitwise right shift operator << is overloaded for this operation too.

>>> intrange(1, 5) << intrange(5, 10)
True

The choice of overloading << might seem strange, but it is to mimick PostgreSQL’s operators for ranges. As this is not obvious the use of << is discouraged.

Parameters:

other – Range to test against.

Returns:

True if this range is completely to the left of other.

property lower

Returns the lower boundary or None if it is unbounded.

>>> intrange(1, 5).lower
1
>>> intrange(upper=5).lower

This is the same as the lower(self) in PostgreSQL.

property lower_inc

Returns True if lower bound is included in range. If lower bound is unbounded this returns False.

>>> intrange(1, 5).lower_inc
True

This is the same as the lower_inc(self) in PostgreSQL.

property lower_inf

Returns True if lower bound is unbounded.

>>> intrange(1, 5).lower_inf
False
>>> intrange(upper=5).lower_inf
True

This is the same as the lower_inf(self) in PostgreSQL.

overlap(other)

Returns True if both ranges share any points.

>>> intrange(1, 10).overlap(intrange(5, 15))
True
>>> intrange(1, 5).overlap(intrange(5, 10))
False

This is the same as the && operator for two ranges in PostgreSQL.

Parameters:

other – Range to test against.

Returns:

True if ranges overlap, otherwise False.

Raises:

TypeError – If other is of another type than this range.

See also

If you need to know which part that overlapped, consider using intersection().

replace(lower=None, upper=None, lower_inc=None, upper_inc=None)

Returns a new instance of self with the given arguments replaced. It takes the exact same arguments as the constructor.

>>> intrange(1, 5).replace(upper=10)
intrange(1, 10)
>>> intrange(1, 10).replace(lower_inc=False)
intrange(2, 10)
>>> intrange(1, 10).replace(5)
intrange(5, 10)

Note that range objects are immutable and are never modified in place.

right_of(other)

Test if this range other is strictly right of other.

>>> intrange(5, 10).right_of(intrange(1, 5))
True
>>> intrange(1, 10).right_of(intrange(1, 5))
False

The bitwise right shift operator >> is overloaded for this operation too.

>>> intrange(5, 10) >> intrange(1, 5)
True

The choice of overloading >> might seem strange, but it is to mimick PostgreSQL’s operators for ranges. As this is not obvious the use of >> is discouraged.

Parameters:

other – Range to test against.

Returns:

True if this range is completely to the right of other.

startsafter(other)

Test if this range starts after other. other may be either range or scalar. This only takes the lower end of the ranges into consideration. If the scalar or the lower end of the given range is greater than or equal to this range’s lower end, True is returned.

>>> intrange(1, 5).startsafter(0)
True
>>> intrange(1, 5).startsafter(intrange(0, 5))
True

If other has the same start as the given

Parameters:

other – Range or scalar to test.

Returns:

True if this range starts after other, otherwise False

Raises:

TypeError – If other is of the wrong type.

startswith(other)

Test if this range starts with other. other may be either range or scalar.

>>> intrange(1, 5).startswith(1)
True
>>> intrange(1, 5).startswith(intrange(1, 10))
True
Parameters:

other – Range or scalar to test.

Returns:

True if this range starts with other, otherwise False

Raises:

TypeError – If other is of the wrong type.

union(other)

Merges this range with a given range.

>>> intrange(1, 5).union(intrange(5, 10))
intrange(1, 10)
>>> intrange(1, 10).union(intrange(5, 15))
intrange(1, 15)

Two ranges can not be merged if the resulting range would be split in two. This happens when the two sets are neither adjacent nor overlaps.

>>> intrange(1, 5).union(intrange(10, 15))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Ranges must be either adjacent or overlapping

This does not modify the range in place.

This is the same as the + operator for two ranges in PostgreSQL.

Parameters:

other – Range to merge with.

Returns:

A new range that is the union of this and other.

Raises:

ValueError – If other can not be merged with this range.

property upper

Returns the upper boundary or None if it is unbounded.

>>> intrange(1, 5).upper
5
>>> intrange(1).upper

This is the same as the upper(self) in PostgreSQL.

property upper_inc

Returns True if upper bound is included in range. If upper bound is unbounded this returns False.

>>> intrange(1, 5).upper_inc
False

This is the same as the upper_inc(self) in PostgreSQL.

property upper_inf

Returns True if upper bound is unbounded.

>>> intrange(1, 5).upper_inf
False
>>> intrange(1).upper_inf
True

This is the same as the upper_inf(self) in PostgreSQL.

within(other)

Tests if this range is within other.

>>> a = intrange(1, 10)
>>> b = intrange(3, 8)
>>> a.contains(b)
True
>>> b.within(a)
True

This is the same as the self <@ other in PostgreSQL. One difference however is that unlike PostgreSQL self in this can’t be a scalar value.

Parameters:

other – Range to test against.

Returns:

True if this range is completely within the given range, otherwise False.

Raises:

TypeError – If given range is of the wrong type.

See also

This method is the inverse of contains()

Discrete range

class spans.types.DiscreteRange(lower=None, upper=None, lower_inc=None, upper_inc=None)

Discrete ranges are a subset of ranges that works on discrete types. This includes int and datetime.date.

>>> intrange(0, 5, lower_inc=False)
intrange(1, 5)
>>> intrange(0, 5, lower_inc=False).lower_inc
True

All discrete ranges must provide a unit attribute containing the step length. For intrange this would be:

class intrange(DiscreteRange):
    type = int
    unit = 1

A range where no values can fit is considered empty:

>>> intrange(0, 1, lower_inc=False)
intrange.empty()

Discrete ranges are iterable.

>>> list(intrange(1, 5))
[1, 2, 3, 4]

Changed in version 0.5.0: Changed name from discreterange to DiscreteRange

endswith(other)

Test if this range ends with other. other may be either range or scalar.

>>> intrange(1, 5).endswith(4)
True
>>> intrange(1, 10).endswith(intrange(5, 10))
True
Parameters:

other – Range or scalar to test.

Returns:

True if this range ends with other, otherwise False

Raises:

TypeError – If other is of the wrong type.

property last

Returns the last element within this range. If the range has no upper limit None is returned.

>>> intrange(1, 10).last
9
>>> intrange(1, 10, upper_inc=True).last
10
>>> intrange(1).last is None
True
Returns:

Last element within this range.

New in version 0.1.4.

classmethod next(curr)

Increment the given value with the step defined for this class.

>>> intrange.next(1)
2
Parameters:

curr – Value to increment.

Returns:

Incremented value.

classmethod prev(curr)

Decrement the given value with the step defined for this class.

>>> intrange.prev(1)
0
Parameters:

curr – Value to decrement.

Returns:

Decremented value.

Offsetable range mixin

class spans.types.OffsetableRangeMixin

Mixin for range types that supports being offset by a value. This value must be of the same type as the range boundaries. For date types this will not work and can be solved by explicitly defining an offset_type:

class datetimerange(Range, OffsetableRangeMixin):
    __slots__ = ()

    type = datetime
    offset_type = timedelta

Changed in version 0.5.0: Changed name from offsetablerange to OffsetableRangeMixin

offset(offset)

Shift the range to the left or right with the given offset

>>> intrange(0, 5).offset(5)
intrange(5, 10)
>>> intrange(5, 10).offset(-5)
intrange(0, 5)
>>> intrange.empty().offset(5)
intrange.empty()

Note that range objects are immutable and are never modified in place.

Parameters:

offset – Scalar to offset by.

New in version 0.1.3.

Integer range

class spans.types.intrange(*args, **kwargs)

Range that operates on int.

>>> intrange(1, 5)
intrange(1, 5)

Inherits methods from Range, DiscreteRange and OffsetableRangeMixin.

Float range

class spans.types.floatrange(lower=None, upper=None, lower_inc=None, upper_inc=None)

Range that operates on float.

>>> floatrange(1.0, 5.0)
floatrange(1.0, 5.0)
>>> floatrange(None, 10.0, upper_inc=True)
floatrange(upper=10.0, upper_inc=True)

Inherits methods from Range and OffsetableRangeMixin.

String range

class spans.types.strrange(*args, **kwargs)

Range that operates on unicode strings. Next character is determined lexicographically. Representation might seem odd due to normalization.

>>> strrange(u"a", u"z")
strrange(u'a', u'z')
>>> strrange(u"a", u"z", upper_inc=True)
strrange(u'a', u'{')

Iteration over a strrange is only sensible when having single character boundaries.

>>> list(strrange(u"a", u"e", upper_inc=True))
[u'a', u'b', u'c', u'd', u'e']
>>> len(list(strrange(u"aa", u"zz", upper_inc=True))) 
27852826

Inherits methods from Range and DiscreteRange.

Date range

class spans.types.daterange(lower=None, upper=None, lower_inc=None, upper_inc=None)

Range that operates on datetime.date.

>>> daterange(date(2015, 1, 1), date(2015, 2, 1))
daterange(datetime.date(2015, 1, 1), datetime.date(2015, 2, 1))

Offsets are done using datetime.timedelta.

>>> daterange(date(2015, 1, 1), date(2015, 2, 1)).offset(timedelta(14))
daterange(datetime.date(2015, 1, 15), datetime.date(2015, 2, 15))

Inherits methods from Range, DiscreteRange and OffsetableRangeMixin.

__len__()

Returns number of dates in range.

>>> len(daterange(date(2013, 1, 1), date(2013, 1, 8)))
7
classmethod from_date(date, period=None)

Create a day long daterange from for the given date.

>>> daterange.from_date(date(2000, 1, 1))
daterange(datetime.date(2000, 1, 1), datetime.date(2000, 1, 2))
Parameters:
  • date – A date to convert.

  • period – The period to normalize date to. A period may be one of: day (default), week, american_week, month, quarter or year.

Returns:

A new range that contains the given date.

See also

There are convenience methods for most period types: from_week(), from_month(), from_quarter() and from_year().

PeriodRange has the same interface but is period aware. This means it is possible to get things like next week or month.

Changed in version 0.4.0: Added the period parameter.

classmethod from_month(year, month)

Create daterange based on a year and amonth

Parameters:
  • year – Year as an integer

  • iso_week – Month as an integer between 1 and 12

Returns:

A new daterange for the given month

New in version 0.4.0.

classmethod from_quarter(year, quarter)

Create daterange based on a year and quarter.

A quarter is considered to be:

  • January through March (Q1),

  • April through June (Q2),

  • July through September (Q3) or,

  • October through December (Q4)

Parameters:
  • year – Year as an integer

  • quarter – Quarter as an integer between 1 and 4

Returns:

A new daterange for the given quarter

New in version 0.4.0.

classmethod from_week(year, iso_week)

Create daterange based on a year and an ISO week

Parameters:
  • year – Year as an integer

  • iso_week – ISO week number

Returns:

A new daterange for the given week

New in version 0.4.0.

classmethod from_year(year)

Create daterange based on a year

Parameters:

year – Year as an integer

Returns:

A new daterange for the given year

New in version 0.4.0.

offset_type

alias of timedelta

type

alias of date

Period range

class spans.types.PeriodRange(lower=None, upper=None, lower_inc=None, upper_inc=None)

A type aware version of daterange.

Type aware refers to being aware of what kind of range it represents. Available types are the same as the period argument for to from_date().

Some methods are unavailable due since they don’t make sense for PeriodRange, and some may return a normal daterange since they may modifify the range in ways not compatible with its type.

New in version 0.4.0.

Note

This class does not have its own range set implementation, but can be used with daterangeset.

property daterange

This PeriodRange represented as a naive daterange.

difference(other)

Compute the difference between this and a given range.

>>> intrange(1, 10).difference(intrange(10, 15))
intrange(1, 10)
>>> intrange(1, 10).difference(intrange(5, 10))
intrange(1, 5)
>>> intrange(1, 5).difference(intrange(5, 10))
intrange(1, 5)
>>> intrange(1, 5).difference(intrange(1, 10))
intrange.empty()

The difference can not be computed if the resulting range would be split in two separate ranges. This happens when the given range is completely within this range and does not start or end at the same value.

>>> intrange(1, 15).difference(intrange(5, 10))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Other range must not be within this range

This does not modify the range in place.

This is the same as the - operator for two ranges in PostgreSQL.

Parameters:

other – Range to difference against.

Returns:

A new range that is the difference between this and other.

Raises:

ValueError – If difference bethween this and other can not be computed.

classmethod empty()
Raises:

TypeError – since typed date ranges must never be empty

classmethod from_date(day, period=None)

Create a day long daterange from for the given date.

>>> daterange.from_date(date(2000, 1, 1))
daterange(datetime.date(2000, 1, 1), datetime.date(2000, 1, 2))
Parameters:
  • date – A date to convert.

  • period – The period to normalize date to. A period may be one of: day (default), week, american_week, month, quarter or year.

Returns:

A new range that contains the given date.

See also

There are convenience methods for most period types: from_week(), from_month(), from_quarter() and from_year().

PeriodRange has the same interface but is period aware. This means it is possible to get things like next week or month.

Changed in version 0.4.0: Added the period parameter.

intersection(other)

Returns a new range containing all points shared by both ranges. If no points are shared an empty range is returned.

>>> intrange(1, 5).intersection(intrange(1, 10))
intrange(1, 5)
>>> intrange(1, 5).intersection(intrange(5, 10))
intrange.empty()
>>> intrange(1, 10).intersection(intrange(5, 10))
intrange(5, 10)

This is the same as the + operator for two ranges in PostgreSQL.

Parameters:

other – Range to interect with.

Returns:

A new range that is the intersection between this and other.

next_period()

The period after this range.

>>> span = PeriodRange.from_date(date(2000, 1, 1), period="month")
>>> span.next_period()
PeriodRange(datetime.date(2000, 2, 1), datetime.date(2000, 3, 1), period='month')
Returns:

A new PeriodRange for the period after this period

offset(offset)

Offset the date range by the given amount of periods.

This differs from offset() on spans.types.daterange by not accepting a timedelta object. Instead it expects an integer to adjust the typed date range by. The given value may be negative as well.

Parameters:

offset – Number of periods to offset this range by. A period is either a day, week, american week, month, quarter or year, depending on this range’s period type.

Returns:

New offset PeriodRange

prev_period()

The period before this range.

>>> span = PeriodRange.from_date(date(2000, 1, 1), period="month")
>>> span.prev_period()
PeriodRange(datetime.date(1999, 12, 1), datetime.date(2000, 1, 1), period='month')
Returns:

A new PeriodRange for the period before this period

replace(lower=None, upper=None, lower_inc=None, upper_inc=None)

Returns a new instance of self with the given arguments replaced. It takes the exact same arguments as the constructor.

>>> intrange(1, 5).replace(upper=10)
intrange(1, 10)
>>> intrange(1, 10).replace(lower_inc=False)
intrange(2, 10)
>>> intrange(1, 10).replace(5)
intrange(5, 10)

Note that range objects are immutable and are never modified in place.

union(other)

Merges this range with a given range.

>>> intrange(1, 5).union(intrange(5, 10))
intrange(1, 10)
>>> intrange(1, 10).union(intrange(5, 15))
intrange(1, 15)

Two ranges can not be merged if the resulting range would be split in two. This happens when the two sets are neither adjacent nor overlaps.

>>> intrange(1, 5).union(intrange(10, 15))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Ranges must be either adjacent or overlapping

This does not modify the range in place.

This is the same as the + operator for two ranges in PostgreSQL.

Parameters:

other – Range to merge with.

Returns:

A new range that is the union of this and other.

Raises:

ValueError – If other can not be merged with this range.

Datetime range

class spans.types.datetimerange(lower=None, upper=None, lower_inc=None, upper_inc=None)

Range that operates on datetime.datetime.

>>> datetimerange(datetime(2015, 1, 1), datetime(2015, 2, 1))
datetimerange(datetime.datetime(2015, 1, 1, 0, 0), datetime.datetime(2015, 2, 1, 0, 0))

Offsets are done using datetime.timedelta.

>>> datetimerange(
...     datetime(2015, 1, 1), datetime(2015, 2, 1)).offset(timedelta(14))
datetimerange(datetime.datetime(2015, 1, 15, 0, 0), datetime.datetime(2015, 2, 15, 0, 0))

Inherits methods from Range and OffsetableRangeMixin.

Timedelta range

class spans.types.timedeltarange(lower=None, upper=None, lower_inc=None, upper_inc=None)

Range that operates on datetime’s timedelta class.

>>> timedeltarange(timedelta(days=1), timedelta(days=5))
timedeltarange(datetime.timedelta(days=1), datetime.timedelta(days=5))

Offsets are done using datetime.timedelta.

>>> timedeltarange(timedelta(days=1), timedelta(days=5)).offset(timedelta(days=14))
timedeltarange(datetime.timedelta(days=15), datetime.timedelta(days=19))

Inherits methods from Range and OffsetableRangeMixin.

Range sets

Range set

class spans.settypes.RangeSet(ranges)

A range set works a lot like a range with some differences:

  • All range sets supports len(). Cardinality for a range set means the number of distinct ranges required to represent this set. See __len__().

  • All range sets are iterable. The iterator returns a range for each iteration. See __iter__() for more details.

  • All range sets are invertible using the ~ operator. The result is a new range set that does not intersect the original range set at all.

    >>> ~intrangeset([intrange(1, 5)])
    intrangeset([intrange(upper=1), intrange(5)])
    
  • Contrary to ranges. A range set may be split into multiple ranges when performing set operations such as union, difference or intersection.

Tip

The RangeSet constructor supports any iterable sequence as argument.

Parameters:

ranges – A sequence of ranges to add to this set.

Raises:

TypeError – If any of the given ranges are of incorrect type.

Changed in version 0.5.0: Changed name from rangeset to RangeSet

__iter__()

Returns an iterator over all ranges within this set. Note that this iterates over the normalized version of the range set:

>>> list(intrangeset(
...     [intrange(1, 5), intrange(5, 10), intrange(15, 20)]))
[intrange(1, 10), intrange(15, 20)]

If the set is empty an empty iterator is returned.

>>> list(intrangeset([]))
[]

Changed in version 0.3.0: This method used to return an empty range when the RangeSet was empty.

__len__()

Returns the cardinality of the set which is 0 for the empty set or else the number of ranges used to represent this range set.

>>> len(intrangeset([]))
0
>>> len(intrangeset([intrange(1,5)]))
1
>>> len(intrangeset([intrange(1,5),intrange(10,20)]))
2

New in version 0.2.0.

add(item)

Adds a range to the set.

>>> rs = intrangeset([])
>>> rs.add(intrange(1, 10))
>>> rs
intrangeset([intrange(1, 10)])
>>> rs.add(intrange(5, 15))
>>> rs
intrangeset([intrange(1, 15)])
>>> rs.add(intrange(20, 30))
>>> rs
intrangeset([intrange(1, 15), intrange(20, 30)])

This operation updates the set in place.

Parameters:

item – Range to add to this set.

Raises:

TypeError – If any of the given ranges are of incorrect type.

contains(item)

Test if this range Return True if one range within the set contains elem, which may be either a range of the same type or a scalar of the same type as the ranges within the set.

>>> intrangeset([intrange(1, 5)]).contains(3)
True
>>> intrangeset([intrange(1, 5), intrange(10, 20)]).contains(7)
False
>>> intrangeset([intrange(1, 5)]).contains(intrange(2, 3))
True
>>> intrangeset(
...     [intrange(1, 5), intrange(8, 9)]).contains(intrange(4, 6))
False

Contains can also be called using the in operator.

>>> 3 in intrangeset([intrange(1, 5)])
True

This operation is O(n) where n is the number of ranges within this range set.

Parameters:

item – Range or scalar to test for.

Returns:

True if element is contained within this set.

New in version 0.2.0.

copy()

Makes a copy of this set. This copy is not deep since ranges are immutable.

>>> rs = intrangeset([intrange(1, 5)])
>>> rs_copy = rs.copy()
>>> rs == rs_copy
True
>>> rs is rs_copy
False
Returns:

A new range set with the same ranges as this range set.

difference(*others)

Returns this set stripped of every subset that are in the other given sets.

>>> intrangeset([intrange(1, 15)]).difference(
...     intrangeset([intrange(5, 10)]))
intrangeset([intrange(1, 5), intrange(10, 15)])
Parameters:

other – Range set to compute difference against.

Returns:

A new range set that is the difference between this and other.

intersection(*others)

Returns a new set of all subsets that exist in this and every given set.

>>> intrangeset([intrange(1, 15)]).intersection(
...     intrangeset([intrange(5, 10)]))
intrangeset([intrange(5, 10)])
Parameters:

other – Range set to intersect this range set with.

Returns:

A new range set that is the intersection between this and other.

remove(item)

Remove a range from the set. This operation updates the set in place.

>>> rs = intrangeset([intrange(1, 15)])
>>> rs.remove(intrange(5, 10))
>>> rs
intrangeset([intrange(1, 5), intrange(10, 15)])
Parameters:

item – Range to remove from this set.

span()

Return a range that spans from the first point to the last point in this set. This means the smallest range containing all elements of this set with no gaps.

>>> intrangeset([intrange(1, 5), intrange(30, 40)]).span()
intrange(1, 40)

This method can be used to implement the PostgreSQL function range_merge(a, b):

>>> a = intrange(1, 5)
>>> b = intrange(10, 15)
>>> intrangeset([a, b]).span()
intrange(1, 15)
Returns:

A new range the contains this entire range set.

union(*others)

Returns this set combined with every given set into a super set for each given set.

>>> intrangeset([intrange(1, 5)]).union(
...     intrangeset([intrange(5, 10)]))
intrangeset([intrange(1, 10)])
Parameters:

other – Range set to merge with.

Returns:

A new range set that is the union of this and other.

Discrete range set mixin

class spans.settypes.DiscreteRangeSetMixin

Mixin that adds support for discrete range set operations. Automatically used by RangeSet when Range type inherits DiscreteRange.

Changed in version 0.5.0: Changed name from discreterangeset to DiscreteRangeSetMixin

values()

Returns an iterator over each value in this range set.

>>> list(intrangeset([intrange(1, 5), intrange(10, 15)]).values())
[1, 2, 3, 4, 10, 11, 12, 13, 14]

Offsetable range set mixin

class spans.settypes.OffsetableRangeSetMixin

Mixin that adds support for offsetable range set operations. Automatically used by RangeSet when range type inherits OffsetableRangeMixin.

Changed in version 0.5.0: Changed name from offsetablerangeset to OffsetableRangeSetMixin

offset(offset)

Shift the range set to the left or right with the given offset

>>> intrangeset([intrange(0, 5), intrange(10, 15)]).offset(5)
intrangeset([intrange(5, 10), intrange(15, 20)])
>>> intrangeset([intrange(5, 10), intrange(15, 20)]).offset(-5)
intrangeset([intrange(0, 5), intrange(10, 15)])

This function returns an offset copy of the original set, i.e. updating is not done in place.

Integer range set

class spans.settypes.intrangeset(ranges)

Range set that operates on intrange.

>>> intrangeset([intrange(1, 5), intrange(10, 15)])
intrangeset([intrange(1, 5), intrange(10, 15)])

Inherits methods from RangeSet, DiscreteRangeset and OffsetableRangeMixinset.

Float range set

class spans.settypes.floatrangeset(ranges)

Range set that operates on floatrange.

>>> floatrangeset([floatrange(1.0, 5.0), floatrange(10.0, 15.0)])
floatrangeset([floatrange(1.0, 5.0), floatrange(10.0, 15.0)])

Inherits methods from RangeSet, DiscreteRangeset and OffsetableRangeMixinset.

String range set

class spans.settypes.strrangeset(ranges)

Range set that operates on .. seealso:: strrange.

>>> strrangeset([
...     strrange(u"a", u"f", upper_inc=True),
...     strrange(u"0", u"9", upper_inc=True)])
strrangeset([strrange(u'0', u':'), strrange(u'a', u'g')])

Inherits methods from RangeSet and DiscreteRangeset.

Date range set

class spans.settypes.daterangeset(ranges)

Range set that operates on daterange.

>>> month = daterange(date(2000, 1, 1), date(2000, 2, 1))
>>> daterangeset([month, month.offset(timedelta(366))]) 
daterangeset([daterange(datetime.date(2000, 1, 1), datetime.date(2000, 2, 1)),
    daterange(datetime.date(2001, 1, 1), datetime.date(2001, 2, 1))])

Inherits methods from RangeSet, DiscreteRangeset and OffsetableRangeMixinset.

Datetime range set

class spans.settypes.datetimerangeset(ranges)

Range set that operates on datetimerange.

>>> month = datetimerange(datetime(2000, 1, 1), datetime(2000, 2, 1))
>>> datetimerangeset([month, month.offset(timedelta(366))]) 
datetimerangeset([datetimerange(datetime.datetime(2000, 1, 1, 0, 0), datetime.datetime(2000, 2, 1, 0, 0)),
    datetimerange(datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2001, 2, 1, 0, 0))])

Inherits methods from RangeSet and OffsetableRangeMixinset.

Timedelta range set

class spans.settypes.timedeltarangeset(ranges)

Range set that operates on timedeltarange.

>>> week = timedeltarange(timedelta(0), timedelta(days=7))
>>> timedeltarangeset([week, week.offset(timedelta(days=7))])
timedeltarangeset([timedeltarange(datetime.timedelta(0), datetime.timedelta(days=14))])

Inherits methods from RangeSet and OffsetableRangeMixinset.

Meta range set

class spans.settypes.MetaRangeSet(name, bases, attrs)

A meta class for RangeSets. The purpose is to automatically add relevant mixins to the range set class based on what mixins and base classes the range class has.

All subclasses of RangeSet uses this class as its metaclass

Changed in version 0.5.0: Changed name from metarangeset to MetaRangeSet

Legacy names

Historically some internal Spans classes had all lowercase names. This was changed in version 0.5.0. The reason some classes still have lowercase names is to match the Python built-ins they map to. date’s range type is and will always be daterange. However, it doesn’t make much sense to maintain this convention for the more hidden classes in Spans.

spans.types.discreterange

This alias exist for legacy reasons. It is considered deprecated but will not likely be removed.

New in version 0.5.0.

spans.types.offsetablerange

This alias exist for legacy reasons. It is considered deprecated but will not likely be removed.

New in version 0.5.0.

spans.types.range_

This alias exist for legacy reasons. It is considered deprecated but will not likely be removed.

New in version 0.5.0.

spans.settypes.metarangeset

This alias exist for legacy reasons. It is considered deprecated but will not likely be removed.

New in version 0.5.0.

spans.settypes.rangeset

This alias exist for legacy reasons. It is considered deprecated but will not likely be removed.

New in version 0.5.0.