[Git][debian-gis-team/cftime][upstream] New upstream version 1.4.1+ds

Bas Couwenberg gitlab at salsa.debian.org
Tue Feb 2 05:52:24 GMT 2021



Bas Couwenberg pushed to branch upstream at Debian GIS Project / cftime


Commits:
f7635189 by Bas Couwenberg at 2021-02-02T06:14:08+01:00
New upstream version 1.4.1+ds
- - - - -


6 changed files:

- Changelog
- README.md
- docs/api.rst
- src/cftime/_cftime.pyx
- src/cftime/_cftime_legacy.pyx
- test/test_cftime.py


Changes:

=====================================
Changelog
=====================================
@@ -1,3 +1,12 @@
+
+version 1.4.1 (release tag v1.4.1.rel)
+======================================
+ * Restore use of calendar-specific sub-classes in `cftime.num2date`,
+   `cftime.datetime.__add__`, and `cftime.datetime.__sub__`.  The use of them 
+   will be removed in a later release.
+ * add 'fromordinal' static method to create a cftime.datetime instance
+   from a julian day ordinal and calendar (inverse of 'toordinal').
+
 version 1.4.0 (release tag v1.4.0.rel)
 ======================================
  * `cftime.date2num` will now always return an array of integers, if the units


=====================================
README.md
=====================================
@@ -11,6 +11,12 @@ Time-handling functionality from netcdf4-python
 ## News
 For details on the latest updates, see the [Changelog](https://github.com/Unidata/cftime/blob/master/Changelog).
 
+2/2/2021:  Version 1.4.1 released. Restore use of calendar-specific subclasses
+in `cftime.num2date`, `cftime.datetime.__add__`, and `cftime.datetime.__sub__`.
+The use of this will be removed in a later release.
+Add 'fromordinal' static method to create a cftime.datetime instance
+from a julian day ordinal and calendar (inverse of 'toordinal').
+
 2/1/2021:  Version 1.4.0 released.  License changed to MIT (GPL'ed code replaced).
 Roundtrip accuracy improved for units other than microseconds. Added 
 cftime.datetime.toordinal method, returns integer julian day number.


=====================================
docs/api.rst
=====================================
@@ -2,5 +2,5 @@ API
 ===
 
 .. automodule:: cftime
-   :members: datetime, date2num, num2date, num2pydate, date2index, JulianDayFromDate, DatetimeJulian, DatetimeProlepticGregorian, DatetimeNoLeap, DatetimeAllLeap, DatetimeGregorian, DateFromJulianDay, time2index
+   :members: datetime, date2num, num2date, num2pydate, date2index, time2index
    :show-inheritance:


=====================================
src/cftime/_cftime.pyx
=====================================
@@ -41,7 +41,7 @@ cdef int[13] _cumdayspermonth_leap = [0, 31, 60, 91, 121, 152, 182, 213, 244, 27
 _rop_lookup = {Py_LT: '__gt__', Py_LE: '__ge__', Py_EQ: '__eq__',
                Py_GT: '__lt__', Py_GE: '__le__', Py_NE: '__ne__'}
 
-__version__ = '1.4.0'
+__version__ = '1.4.1'
 
 # Adapted from http://delete.me.uk/2005/03/iso8601.html
 # Note: This regex ensures that all ISO8601 timezone formats are accepted - but, due to legacy support for other timestrings, not all incorrect formats can be rejected.
@@ -295,6 +295,18 @@ UNIT_CONVERSION_FACTORS = {
     "months": 30 * 86400 * 1000000
 }
 
+DATE_TYPES = {
+     "proleptic_gregorian": DatetimeProlepticGregorian,
+     "standard": DatetimeGregorian,
+     "noleap": DatetimeNoLeap,
+     "365_day": DatetimeNoLeap,
+     "all_leap": DatetimeAllLeap,
+     "366_day": DatetimeAllLeap,
+     "julian": DatetimeJulian,
+     "360_day": Datetime360Day,
+     "gregorian": DatetimeGregorian
+ }
+
 def to_calendar_specific_datetime(dt, calendar, use_python_datetime):
     if use_python_datetime:
         return real_datetime(
@@ -306,7 +318,8 @@ def to_calendar_specific_datetime(dt, calendar, use_python_datetime):
                dt.second,
                dt.microsecond)
     else:
-        return datetime(
+        date_type = DATE_TYPES[calendar]
+        return date_type(
                dt.year,
                dt.month,
                dt.day,
@@ -1089,24 +1102,39 @@ The default format of the string produced by strftime is controlled by self.form
     cdef _add_timedelta(self, other):
         return NotImplemented
 
+    @staticmethod
+    def fromordinal(jday,calendar='standard'):
+        """Create a datetime instance from a julian day ordinal and calendar
+        (inverseeof toordinal)."""
+        if calendar in ['standard','julian','gregorian']:
+            units = 'days since -4713-1-1-12'
+        elif calendar == 'proleptic_gregorian':
+            units = 'days since -4714-11-24-12'
+        else:
+            units = 'days since 0-1-1-12'
+        return num2date(jday,units=units,calendar=calendar)
+
     def toordinal(self,fractional=False):
-        """Return julian day ordinal.
+        """Return (integer) julian day ordinal.
 
-        January 1 of the year -4713 is day 0 for the julian,gregorian and standard
-        calendars.
+        Day 0 starts at noon January 1 of the year -4713 for the
+        julian, gregorian and standard calendars.
 
-        November 11 of the year -4714 is day 0 for the proleptic gregorian calendar.
+        Day 0 starts at noon on November 24 of the year -4714 for the
+        proleptic gregorian calendar.
 
-        January 1 of the year zero is day 0 for the 360_day, 365_day, 366_day and
-        no_leap calendars.
+        Day 0 starts at noon on January 1 of the year zero is for the
+        360_day, 365_day, 366_day, all_leap and noleap calendars.
         
         If fractional=True, fractional part of day is included (default
         False)."""
         ijd = _IntJulianDayFromDate(self.year, self.month, self.day, self.calendar,
                skip_transition=False,has_year_zero=self.has_year_zero)
         if fractional:
-            fracday = self.hour / 24.0 + self.minute / 1440.0 + (self.second +
-                    self.microsecond/1.e6) / 86400.0
+            fracday = self.hour / np.array(24.,np.longdouble) + \
+                      self.minute / np.array(1440.0,np.longdouble) + \
+                      (self.second + self.microsecond/(np.array(1.e6,np.longdouble)))/\
+                      np.array(86400.0,np.longdouble)
             # at this point jd is an integer representing noon UTC on the given
             # year,month,day.
             # compute fractional day from hour,minute,second,microsecond
@@ -1129,17 +1157,23 @@ The default format of the string produced by strftime is controlled by self.form
         # return calendar-specific subclasses for backward compatbility,
         # even though after 1.3.0 this is no longer necessary.
         if calendar == '360_day':
-            return dt.__class__(*add_timedelta_360_day(dt, delta),calendar=calendar)
+            #return dt.__class__(*add_timedelta_360_day(dt, delta),calendar=calendar)
+            return Datetime360Day(*add_timedelta_360_day(dt, delta))
         elif calendar == 'noleap':
-            return dt.__class__(*add_timedelta(dt, delta, no_leap, False, True),calendar=calendar)
+            #return dt.__class__(*add_timedelta(dt, delta, no_leap, False, True),calendar=calendar)
+            return DatetimeNoLeap(*add_timedelta(dt, delta, no_leap, False, True))
         elif calendar == 'all_leap':
-            return dt.__class__(*add_timedelta(dt, delta, all_leap, False, True),calendar=calendar)
+            #return dt.__class__(*add_timedelta(dt, delta, all_leap, False, True),calendar=calendar)
+            return DatetimeAllLeap(*add_timedelta(dt, delta, all_leap, False, True))
         elif calendar == 'julian':
-            return dt.__class__(*add_timedelta(dt, delta, is_leap_julian, False, False),calendar=calendar)
+            #return dt.__class__(*add_timedelta(dt, delta, is_leap_julian, False, False),calendar=calendar)
+            return DatetimeJulian(*add_timedelta(dt, delta, is_leap_julian, False, False))
         elif calendar == 'gregorian':
-            return dt.__class__(*add_timedelta(dt, delta, is_leap_gregorian, True, False),calendar=calendar)
+            #return dt.__class__(*add_timedelta(dt, delta, is_leap_gregorian, True, False),calendar=calendar)
+            return DatetimeGregorian(*add_timedelta(dt, delta, is_leap_gregorian, True, False))
         elif calendar == 'proleptic_gregorian':
-            return dt.__class__(*add_timedelta(dt, delta, is_leap_proleptic_gregorian, False, False),calendar=calendar)
+            #return dt.__class__(*add_timedelta(dt, delta, is_leap_proleptic_gregorian, False, False),calendar=calendar)
+            return DatetimeProlepticGregorian(*add_timedelta(dt, delta, is_leap_proleptic_gregorian, False, False))
         else:
             return NotImplemented
 
@@ -1176,18 +1210,24 @@ datetime object."""
                 # return calendar-specific subclasses for backward compatbility,
                 # even though after 1.3.0 this is no longer necessary.
                 if self.calendar == '360_day':
-                    return self.__class__(*add_timedelta_360_day(self, -other),calendar=self.calendar)
+                    #return self.__class__(*add_timedelta_360_day(self, -other),calendar=self.calendar)
+                    return Datetime360Day(*add_timedelta_360_day(self, -other))
                 elif self.calendar == 'noleap':
-                    return self.__class__(*add_timedelta(self, -other, no_leap, False, True),calendar=self.calendar)
+                    #return self.__class__(*add_timedelta(self, -other, no_leap, False, True),calendar=self.calendar)
+                    return DatetimeNoLeap(*add_timedelta(self, -other, no_leap, False, True))
                 elif self.calendar == 'all_leap':
-                    return self.__class__(*add_timedelta(self, -other, all_leap, False, True),calendar=self.calendar)
+                    #return self.__class__(*add_timedelta(self, -other, all_leap, False, True),calendar=self.calendar)
+                    return DatetimeAllLeap(*add_timedelta(self, -other, all_leap, False, True))
                 elif self.calendar == 'julian':
-                    return self.__class__(*add_timedelta(self, -other, is_leap_julian, False, False),calendar=self.calendar)
+                    #return self.__class__(*add_timedelta(self, -other, is_leap_julian, False, False),calendar=self.calendar)
+                    return DatetimeJulian(*add_timedelta(self, -other, is_leap_julian, False, False))
                 elif self.calendar == 'gregorian':
-                    return self.__class__(*add_timedelta(self, -other, is_leap_gregorian, True, False),calendar=self.calendar)
+                    #return self.__class__(*add_timedelta(self, -other, is_leap_gregorian, True, False),calendar=self.calendar)
+                    return DatetimeGregorian(*add_timedelta(self, -other, is_leap_gregorian, True, False))
                 elif self.calendar == 'proleptic_gregorian':
-                    return self.__class__(*add_timedelta(self, -other,
-                        is_leap_proleptic_gregorian, False, False),calendar=self.calendar)
+                    #return self.__class__(*add_timedelta(self, -other,
+                    #    is_leap_proleptic_gregorian, False, False),calendar=self.calendar)
+                    return DatetimeProlepticGregorian(*add_timedelta(self, -other, is_leap_proleptic_gregorian, False, False))
                 else:
                     return NotImplemented
             else:
@@ -1594,5 +1634,134 @@ cdef _IntJulianDayFromDate(int year,int month,int day,calendar,skip_transition=F
             else:
                 return jday_greg
 
+ at cython.embedsignature(True)
+cdef class DatetimeNoLeap(datetime):
+    """
+Phony datetime object which mimics the python datetime object,
+but uses the "noleap" ("365_day") calendar.
+    """
+    def __init__(self, *args, **kwargs):
+        kwargs['calendar']='noleap'
+        super().__init__(*args, **kwargs)
+    def __repr__(self):
+        return "{0}.{1}({2}, {3}, {4}, {5}, {6}, {7}, {8})".format('cftime',
+        self.__class__.__name__,
+        self.year,self.month,self.day,self.hour,self.minute,self.second,self.microsecond)
+    cdef _getstate(self):
+        return (self.year, self.month, self.day, self.hour,
+                self.minute, self.second, self.microsecond,
+                self._dayofwk, self._dayofyr)
+
+ at cython.embedsignature(True)
+cdef class DatetimeAllLeap(datetime):
+    """
+Phony datetime object which mimics the python datetime object,
+but uses the "all_leap" ("366_day") calendar.
+    """
+    def __init__(self, *args, **kwargs):
+        kwargs['calendar']='all_leap'
+        super().__init__(*args, **kwargs)
+    def __repr__(self):
+        return "{0}.{1}({2}, {3}, {4}, {5}, {6}, {7}, {8})".format('cftime',
+        self.__class__.__name__,
+        self.year,self.month,self.day,self.hour,self.minute,self.second,self.microsecond)
+    cdef _getstate(self):
+        return (self.year, self.month, self.day, self.hour,
+                self.minute, self.second, self.microsecond,
+                self._dayofwk, self._dayofyr)
+
+ at cython.embedsignature(True)
+cdef class Datetime360Day(datetime):
+    """
+Phony datetime object which mimics the python datetime object,
+but uses the "360_day" calendar.
+    """
+    def __init__(self, *args, **kwargs):
+        kwargs['calendar']='360_day'
+        super().__init__(*args, **kwargs)
+    def __repr__(self):
+        return "{0}.{1}({2}, {3}, {4}, {5}, {6}, {7}, {8})".format('cftime',
+        self.__class__.__name__,
+        self.year,self.month,self.day,self.hour,self.minute,self.second,self.microsecond)
+    cdef _getstate(self):
+        return (self.year, self.month, self.day, self.hour,
+                self.minute, self.second, self.microsecond,
+                self._dayofwk, self._dayofyr)
+
+ at cython.embedsignature(True)
+cdef class DatetimeJulian(datetime):
+    """
+Phony datetime object which mimics the python datetime object,
+but uses the "julian" calendar.
+    """
+    def __init__(self, *args, **kwargs):
+        kwargs['calendar']='julian'
+        super().__init__(*args, **kwargs)
+    def __repr__(self):
+        return "{0}.{1}({2}, {3}, {4}, {5}, {6}, {7}, {8})".format('cftime',
+        self.__class__.__name__,
+        self.year,self.month,self.day,self.hour,self.minute,self.second,self.microsecond)
+    cdef _getstate(self):
+        return (self.year, self.month, self.day, self.hour,
+                self.minute, self.second, self.microsecond,
+                self._dayofwk, self._dayofyr)
+
+
+ at cython.embedsignature(True)
+cdef class DatetimeGregorian(datetime):
+    """
+Phony datetime object which mimics the python datetime object,
+but uses the mixed Julian-Gregorian ("standard", "gregorian") calendar.
+
+The last date of the Julian calendar is 1582-10-4, which is followed
+by 1582-10-15, using the Gregorian calendar.
+
+Instances using the date after 1582-10-15 can be compared to
+datetime.datetime instances and used to compute time differences
+(datetime.timedelta) by subtracting a DatetimeGregorian instance from
+a datetime.datetime instance or vice versa.
+    """
+    def __init__(self, *args, **kwargs):
+        kwargs['calendar']='gregorian'
+        super().__init__(*args, **kwargs)
+    def __repr__(self):
+        return "{0}.{1}({2}, {3}, {4}, {5}, {6}, {7}, {8})".format('cftime',
+                                     self.__class__.__name__,
+                                     self.year,self.month,self.day,self.hour,self.minute,self.second,self.microsecond)
+    cdef _getstate(self):
+        return (self.year, self.month, self.day, self.hour,
+                self.minute, self.second, self.microsecond,
+                self._dayofwk, self._dayofyr)
+
+ at cython.embedsignature(True)
+cdef class DatetimeProlepticGregorian(datetime):
+    """
+Phony datetime object which mimics the python datetime object,
+but allows for dates that don't exist in the proleptic gregorian calendar.
+
+Supports timedelta operations by overloading + and -.
+
+Has strftime, timetuple, replace, __repr__, and __str__ methods. The
+format of the string produced by __str__ is controlled by self.format
+(default %Y-%m-%d %H:%M:%S). Supports comparisons with other
+datetime instances using the same calendar; comparison with
+native python datetime instances is possible for cftime.datetime
+instances using 'gregorian' and 'proleptic_gregorian' calendars.
+
+Instance variables are year,month,day,hour,minute,second,microsecond,dayofwk,dayofyr,
+format, and calendar.
+    """
+    def __init__(self, *args, **kwargs):
+        kwargs['calendar']='proleptic_gregorian'
+        super().__init__( *args, **kwargs)
+    def __repr__(self):
+        return "{0}.{1}({2}, {3}, {4}, {5}, {6}, {7}, {8})".format('cftime',
+                                     self.__class__.__name__,
+                                     self.year,self.month,self.day,self.hour,self.minute,self.second,self.microsecond)
+    cdef _getstate(self):
+        return (self.year, self.month, self.day, self.hour,
+                self.minute, self.second, self.microsecond,
+                self._dayofwk, self._dayofyr)
+
 # include legacy stuff no longer used by cftime.datetime
 include "_cftime_legacy.pyx"


=====================================
src/cftime/_cftime_legacy.pyx
=====================================
@@ -1,134 +1,5 @@
 # stuff below no longer used by cftime.datetime, kept here for backwards compatibility.
 
- at cython.embedsignature(True)
-cdef class DatetimeNoLeap(datetime):
-    """
-Phony datetime object which mimics the python datetime object,
-but uses the "noleap" ("365_day") calendar.
-    """
-    def __init__(self, *args, **kwargs):
-        kwargs['calendar']='noleap'
-        super().__init__(*args, **kwargs)
-    def __repr__(self):
-        return "{0}.{1}({2}, {3}, {4}, {5}, {6}, {7}, {8})".format('cftime',
-        self.__class__.__name__,
-        self.year,self.month,self.day,self.hour,self.minute,self.second,self.microsecond)
-    cdef _getstate(self):
-        return (self.year, self.month, self.day, self.hour,
-                self.minute, self.second, self.microsecond,
-                self._dayofwk, self._dayofyr)
-
- at cython.embedsignature(True)
-cdef class DatetimeAllLeap(datetime):
-    """
-Phony datetime object which mimics the python datetime object,
-but uses the "all_leap" ("366_day") calendar.
-    """
-    def __init__(self, *args, **kwargs):
-        kwargs['calendar']='all_leap'
-        super().__init__(*args, **kwargs)
-    def __repr__(self):
-        return "{0}.{1}({2}, {3}, {4}, {5}, {6}, {7}, {8})".format('cftime',
-        self.__class__.__name__,
-        self.year,self.month,self.day,self.hour,self.minute,self.second,self.microsecond)
-    cdef _getstate(self):
-        return (self.year, self.month, self.day, self.hour,
-                self.minute, self.second, self.microsecond,
-                self._dayofwk, self._dayofyr)
-
- at cython.embedsignature(True)
-cdef class Datetime360Day(datetime):
-    """
-Phony datetime object which mimics the python datetime object,
-but uses the "360_day" calendar.
-    """
-    def __init__(self, *args, **kwargs):
-        kwargs['calendar']='360_day'
-        super().__init__(*args, **kwargs)
-    def __repr__(self):
-        return "{0}.{1}({2}, {3}, {4}, {5}, {6}, {7}, {8})".format('cftime',
-        self.__class__.__name__,
-        self.year,self.month,self.day,self.hour,self.minute,self.second,self.microsecond)
-    cdef _getstate(self):
-        return (self.year, self.month, self.day, self.hour,
-                self.minute, self.second, self.microsecond,
-                self._dayofwk, self._dayofyr)
-
- at cython.embedsignature(True)
-cdef class DatetimeJulian(datetime):
-    """
-Phony datetime object which mimics the python datetime object,
-but uses the "julian" calendar.
-    """
-    def __init__(self, *args, **kwargs):
-        kwargs['calendar']='julian'
-        super().__init__(*args, **kwargs)
-    def __repr__(self):
-        return "{0}.{1}({2}, {3}, {4}, {5}, {6}, {7}, {8})".format('cftime',
-        self.__class__.__name__,
-        self.year,self.month,self.day,self.hour,self.minute,self.second,self.microsecond)
-    cdef _getstate(self):
-        return (self.year, self.month, self.day, self.hour,
-                self.minute, self.second, self.microsecond,
-                self._dayofwk, self._dayofyr)
-
- at cython.embedsignature(True)
-cdef class DatetimeGregorian(datetime):
-    """
-Phony datetime object which mimics the python datetime object,
-but uses the mixed Julian-Gregorian ("standard", "gregorian") calendar.
-
-The last date of the Julian calendar is 1582-10-4, which is followed
-by 1582-10-15, using the Gregorian calendar.
-
-Instances using the date after 1582-10-15 can be compared to
-datetime.datetime instances and used to compute time differences
-(datetime.timedelta) by subtracting a DatetimeGregorian instance from
-a datetime.datetime instance or vice versa.
-    """
-    def __init__(self, *args, **kwargs):
-        kwargs['calendar']='gregorian'
-        super().__init__(*args, **kwargs)
-    def __repr__(self):
-        return "{0}.{1}({2}, {3}, {4}, {5}, {6}, {7}, {8})".format('cftime',
-                                     self.__class__.__name__,
-                                     self.year,self.month,self.day,self.hour,self.minute,self.second,self.microsecond)
-    cdef _getstate(self):
-        return (self.year, self.month, self.day, self.hour,
-                self.minute, self.second, self.microsecond,
-                self._dayofwk, self._dayofyr)
-
- at cython.embedsignature(True)
-cdef class DatetimeProlepticGregorian(datetime):
-    """
-Phony datetime object which mimics the python datetime object,
-but allows for dates that don't exist in the proleptic gregorian calendar.
-
-Supports timedelta operations by overloading + and -.
-
-Has strftime, timetuple, replace, __repr__, and __str__ methods. The
-format of the string produced by __str__ is controlled by self.format
-(default %Y-%m-%d %H:%M:%S). Supports comparisons with other
-datetime instances using the same calendar; comparison with
-native python datetime instances is possible for cftime.datetime
-instances using 'gregorian' and 'proleptic_gregorian' calendars.
-
-Instance variables are year,month,day,hour,minute,second,microsecond,dayofwk,dayofyr,
-format, and calendar.
-    """
-    def __init__(self, *args, **kwargs):
-        kwargs['calendar']='proleptic_gregorian'
-        super().__init__( *args, **kwargs)
-    def __repr__(self):
-        return "{0}.{1}({2}, {3}, {4}, {5}, {6}, {7}, {8})".format('cftime',
-                                     self.__class__.__name__,
-                                     self.year,self.month,self.day,self.hour,self.minute,self.second,self.microsecond)
-    cdef _getstate(self):
-        return (self.year, self.month, self.day, self.hour,
-                self.minute, self.second, self.microsecond,
-                self._dayofwk, self._dayofyr)
-
-
 # The following function (_IntJulianDayToDate) is based on
 # algorithms described in the book
 # "Calendrical Calculations" by Dershowitz and Rheingold, 3rd edition, Cambridge University Press, 2007


=====================================
test/test_cftime.py
=====================================
@@ -291,13 +291,16 @@ class cftimeTestCase(unittest.TestCase):
         self.assertTrue(str(d) == str(date))
         # test julian day from date, date from julian day
         d = cftime.datetime(1858, 11, 17, calendar='standard')
-        # toordinal should produce same result as JulidaDayFromDate
+        # toordinal should produce same result as JulianDayFromDate
         mjd1 = d.toordinal(fractional=True)
         mjd2 = JulianDayFromDate(d)
         assert_almost_equal(mjd1, 2400000.5)
         assert_almost_equal(mjd1,mjd2)
-        date = DateFromJulianDay(mjd1)
-        self.assertTrue(str(date) == str(d))
+        # fromordinal should produce the same result as DateFromJulianDay
+        date1 = DateFromJulianDay(mjd1)
+        date2 = cftime.datetime.fromordinal(mjd1)
+        self.assertTrue(str(date1) == str(d))
+        self.assertTrue(str(date1) == str(date2))
         # test iso 8601 units string
         d = datetime(1970, 1, 1, 1)
         t = self.cdftime_iso.date2num(d)
@@ -740,8 +743,7 @@ class cftimeTestCase(unittest.TestCase):
         test = dates == np.ma.masked_array([datetime(1848, 1, 17, 6, 0, 0, 40), None],mask=[0,1])
         assert(test.all())
         dates = num2date(times, units=units, calendar='standard')
-        assert(str(dates)==\
-        "[cftime.datetime(1848, 1, 17, 6, 0, 0, 40, calendar='gregorian') --]")
+        assert(str(dates)=="[cftime.DatetimeGregorian(1848, 1, 17, 6, 0, 0, 40) --]")
 #  check that time range of 200,000 + years can be represented accurately
         calendar='standard'
         _MAX_INT64 = np.iinfo("int64").max



View it on GitLab: https://salsa.debian.org/debian-gis-team/cftime/-/commit/f763518945bd5d770cf445c052264965f68449a1

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/cftime/-/commit/f763518945bd5d770cf445c052264965f68449a1
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20210202/aded6799/attachment-0001.html>


More information about the Pkg-grass-devel mailing list