-
Notifications
You must be signed in to change notification settings - Fork 420
Add issubset, issuperset and size to Range type #563
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
cc46f14
7096db1
534dce4
44960d3
9cb36ac
ae69caa
797d8fb
07480c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -85,6 +85,52 @@ def upper_inf(self): | |
def isempty(self): | ||
return self._empty | ||
|
||
def issubset(self, other): | ||
if self._empty: | ||
return True | ||
if other._empty: | ||
return False | ||
|
||
if other._lower is None: | ||
lowerOk = True | ||
else: | ||
if self._lower is None: | ||
return False | ||
if other._lower_inc or not self._lower_inc: | ||
lowerOk = self._lower >= other._lower | ||
else: | ||
lowerOk = self._lower > other._lower | ||
|
||
if not lowerOk: | ||
return False | ||
|
||
if other._upper is None: | ||
upperOk = True | ||
else: | ||
if self._upper is None: | ||
return False | ||
if other._upper_inc or not self._upper_inc: | ||
upperOk = self._upper <= other._upper | ||
else: | ||
upperOk = self._upper < other._upper | ||
|
||
return lowerOk and upperOk | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
def issuperset(self, other): | ||
return other.issubset(self) | ||
|
||
def size(self, step=None): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do not understand why the step argument is necessary. The size of the range is determined unambiguously by whether the upper and lower bounds are inclusive. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The returned size for [1,2) and [1,2] should be different. In postgres they have a distinction between a discrete and continuous range. If this was a discrete integer range the results would be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, I think the generic There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The distinction between "discrete" and "continuous" ranges has an impact also on Consider the following two ranges: (1,2]::int4range and [2,3)::int4range. They represent the very same set of values, and indeed >>> r1 = asyncpg.Range(1, 2, lower_inc=False, upper_inc=True)
>>> r2 = asyncpg.Range(2, 3, lower_inc=True, upper_inc=False)
>>> r1.issubset(r2)
False |
||
if self._upper is None or self._lower is None: | ||
return None | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be better to raise a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As I understood it, a None in either lower/upper means infinity which matches the null/missing bound definition of postgres. Hence why I return the "infinity". I'm ok either way. For numbers this could be changed from None to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since postgres only has numeric and date/time ranges adding type check for datetime and numeric and returning values for each one and removing None completely might be worthwhile refactor. It would also simply the logic in here since there is no longer a need for checking None. |
||
if step is None or self._upper_inc != self._lower_inc: | ||
step = 0 | ||
else: | ||
step = abs(step) | ||
if not self._upper_inc: | ||
step *= -1 | ||
|
||
return step + self._upper - self._lower | ||
|
||
def __bool__(self): | ||
return not self._empty | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would read better if you set
lowerOk = False
here and use anelif
. Also, please uselower_ok
for the variable name for style consistency.