mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 21:51:50 +00:00 
			
		
		
		
	gh-49766: Make date-datetime comparison more symmetric and flexible (GH-114760)
Now the special comparison methods like `__eq__` and `__lt__` return NotImplemented if one of comparands is date and other is datetime instead of ignoring the time part and the time zone or forcefully return "not equal" or raise TypeError. It makes comparison of date and datetime subclasses more symmetric and allows to change the default behavior by overriding the special comparison methods in subclasses. It is now the same as if date and datetime was independent classes.
This commit is contained in:
		
							parent
							
								
									d9d6909697
								
							
						
					
					
						commit
						b104360788
					
				
					 5 changed files with 91 additions and 84 deletions
				
			
		|  | @ -556,10 +556,6 @@ def _check_tzinfo_arg(tz): | |||
|     if tz is not None and not isinstance(tz, tzinfo): | ||||
|         raise TypeError("tzinfo argument must be None or of a tzinfo subclass") | ||||
| 
 | ||||
| def _cmperror(x, y): | ||||
|     raise TypeError("can't compare '%s' to '%s'" % ( | ||||
|                     type(x).__name__, type(y).__name__)) | ||||
| 
 | ||||
| def _divide_and_round(a, b): | ||||
|     """divide a by b and round result to the nearest integer | ||||
| 
 | ||||
|  | @ -1113,32 +1109,33 @@ def replace(self, year=None, month=None, day=None): | |||
|     # Comparisons of date objects with other. | ||||
| 
 | ||||
|     def __eq__(self, other): | ||||
|         if isinstance(other, date): | ||||
|         if isinstance(other, date) and not isinstance(other, datetime): | ||||
|             return self._cmp(other) == 0 | ||||
|         return NotImplemented | ||||
| 
 | ||||
|     def __le__(self, other): | ||||
|         if isinstance(other, date): | ||||
|         if isinstance(other, date) and not isinstance(other, datetime): | ||||
|             return self._cmp(other) <= 0 | ||||
|         return NotImplemented | ||||
| 
 | ||||
|     def __lt__(self, other): | ||||
|         if isinstance(other, date): | ||||
|         if isinstance(other, date) and not isinstance(other, datetime): | ||||
|             return self._cmp(other) < 0 | ||||
|         return NotImplemented | ||||
| 
 | ||||
|     def __ge__(self, other): | ||||
|         if isinstance(other, date): | ||||
|         if isinstance(other, date) and not isinstance(other, datetime): | ||||
|             return self._cmp(other) >= 0 | ||||
|         return NotImplemented | ||||
| 
 | ||||
|     def __gt__(self, other): | ||||
|         if isinstance(other, date): | ||||
|         if isinstance(other, date) and not isinstance(other, datetime): | ||||
|             return self._cmp(other) > 0 | ||||
|         return NotImplemented | ||||
| 
 | ||||
|     def _cmp(self, other): | ||||
|         assert isinstance(other, date) | ||||
|         assert not isinstance(other, datetime) | ||||
|         y, m, d = self._year, self._month, self._day | ||||
|         y2, m2, d2 = other._year, other._month, other._day | ||||
|         return _cmp((y, m, d), (y2, m2, d2)) | ||||
|  | @ -2137,42 +2134,32 @@ def dst(self): | |||
|     def __eq__(self, other): | ||||
|         if isinstance(other, datetime): | ||||
|             return self._cmp(other, allow_mixed=True) == 0 | ||||
|         elif not isinstance(other, date): | ||||
|             return NotImplemented | ||||
|         else: | ||||
|             return False | ||||
|             return NotImplemented | ||||
| 
 | ||||
|     def __le__(self, other): | ||||
|         if isinstance(other, datetime): | ||||
|             return self._cmp(other) <= 0 | ||||
|         elif not isinstance(other, date): | ||||
|             return NotImplemented | ||||
|         else: | ||||
|             _cmperror(self, other) | ||||
|             return NotImplemented | ||||
| 
 | ||||
|     def __lt__(self, other): | ||||
|         if isinstance(other, datetime): | ||||
|             return self._cmp(other) < 0 | ||||
|         elif not isinstance(other, date): | ||||
|             return NotImplemented | ||||
|         else: | ||||
|             _cmperror(self, other) | ||||
|             return NotImplemented | ||||
| 
 | ||||
|     def __ge__(self, other): | ||||
|         if isinstance(other, datetime): | ||||
|             return self._cmp(other) >= 0 | ||||
|         elif not isinstance(other, date): | ||||
|             return NotImplemented | ||||
|         else: | ||||
|             _cmperror(self, other) | ||||
|             return NotImplemented | ||||
| 
 | ||||
|     def __gt__(self, other): | ||||
|         if isinstance(other, datetime): | ||||
|             return self._cmp(other) > 0 | ||||
|         elif not isinstance(other, date): | ||||
|             return NotImplemented | ||||
|         else: | ||||
|             _cmperror(self, other) | ||||
|             return NotImplemented | ||||
| 
 | ||||
|     def _cmp(self, other, allow_mixed=False): | ||||
|         assert isinstance(other, datetime) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Serhiy Storchaka
						Serhiy Storchaka