1313 "parse_index_pattern" ,
1414 "format_namepart" ,
1515 "format_template_name" ,
16+ "timeparts_from_date" ,
1617)
1718
1819import collections
@@ -103,10 +104,8 @@ def _each_timeparts_for_timerange(
103104 if timedepth <= 0 :
104105 yield (), True # reached timedepth; wildcard
105106 return
106- _from_part , * _from_rest = from_timeparts
107- _until_part , * _until_rest = until_timeparts
108- assert _from_part <= _until_part
109-
107+ _from_part , * _from_rest = from_timeparts or [0 ]
108+ _until_part , * _until_rest = until_timeparts or [0 ]
110109 if include_less_granular :
111110 yield (), False # include less-granular non-wildcard index, if it exists
112111 if _from_part == _until_part :
@@ -118,7 +117,7 @@ def _each_timeparts_for_timerange(
118117 include_less_granular = include_less_granular ,
119118 ):
120119 yield (_from_part , * _rest_parts ), _is_wildcard
121- elif (_until_part - _from_part ) <= max_fanout : # not too far apart
120+ elif 0 < (_until_part - _from_part ) <= max_fanout : # not too far apart
122121 for _parallel_part in range (_from_part , _until_part ):
123122 yield (_parallel_part ,), True # wildcard
124123 if any (_until_rest ): # some of the "until" bucket is included
@@ -250,22 +249,13 @@ def format_index_pattern_for_range(
250249 >>> format_index_pattern_for_range('ap', 'rt',
251250 ... (200, 5), datetime.date(200, 5, 8),
252251 ... timedepth=3)
252+ 'ap_rt_200_05_*'
253253 """
254- _from_timeparts = (
255- timeparts_from_date (from_when , timedepth )
256- if isinstance (from_when , datetime .date )
257- else from_when
258- )
259- _until_timeparts = (
260- timeparts_from_date (until_when , timedepth )
261- if isinstance (until_when , datetime .date )
262- else until_when
263- )
264254 return format_index_pattern_for_timerange (
265- prefix ,
266- recordtype ,
267- _from_timeparts ,
268- _until_timeparts ,
255+ prefix = prefix ,
256+ recordtype = recordtype ,
257+ from_timeparts = _whenparts ( from_when , timedepth ) ,
258+ until_timeparts = _whenparts ( until_when , timedepth ) ,
269259 timedepth = timedepth ,
270260 include_less_granular = include_less_granular ,
271261 only_datelike = True ,
@@ -365,7 +355,7 @@ def _parse_timename(given_timename: str) -> Iterator[int]:
365355 yield int (_part )
366356
367357
368- def timename_from_datestr (given_date : str , part_count : int ) -> str :
358+ def timename_from_datestr (given_date : str , timedepth : int ) -> str :
369359 """
370360 >>> timename_from_datestr('2345-06-07', 1)
371361 '2345'
@@ -384,28 +374,32 @@ def timename_from_datestr(given_date: str, part_count: int) -> str:
384374 """
385375 return timename_from_date (
386376 datetime .datetime .fromisoformat (given_date ),
387- part_count = part_count ,
377+ timedepth = timedepth ,
388378 )
389379
390380
391- def timename_from_date (given_date : datetime .date , part_count : int ) -> str :
381+ def timename_from_date (given_date : datetime .date , timedepth : int ) -> str :
392382 """
393383 >>> timename_from_date(datetime.date(3456, 7, 8), 2)
394384 '3456_07'
395385 """
396- _timeparts = itertools .islice (_each_timepart_from_date (given_date ), part_count )
386+ _timeparts = itertools .islice (_each_timepart_from_date (given_date ), timedepth )
397387 return _format_timename (* _timeparts )
398388
399389
400- def timeparts_from_date (given_date : datetime .date , part_count : int ) -> tuple [int , ...]:
390+ def timeparts_from_date (given_date : datetime .date , timedepth : int ) -> tuple [int , ...]:
401391 """
402392 >>> timeparts_from_date(datetime.date(3456, 7, 8), 2)
403393 (3456, 7)
404394 >>> timeparts_from_date(datetime.date(3456, 7, 8), 4)
405395 (3456, 7, 8, 0)
406396 """
407- _parts = itertools .chain (_each_timepart_from_date (given_date ), itertools .repeat (0 ))
408- return tuple (itertools .islice (_parts , part_count ))
397+ return tuple (
398+ itertools .islice (
399+ _zeropadded_timeparts (_each_timepart_from_date (given_date )),
400+ timedepth ,
401+ )
402+ )
409403
410404
411405def _each_timepart_from_date (given_date : datetime .date ) -> Iterator [int ]:
@@ -418,5 +412,66 @@ def _each_timepart_from_date(given_date: datetime.date) -> Iterator[int]:
418412 yield given_date .second
419413
420414
415+ def _zeropadded_timeparts (
416+ timeparts : collections .abc .Iterable [int ],
417+ ) -> collections .abc .Iterator [int ]:
418+ yield from timeparts
419+ yield from itertools .repeat (0 )
420+
421+
421422def _format_timepart (timepart : int ) -> str :
422423 return f"{ timepart :0{_TIMEPART_MIN_LEN }} "
424+
425+
426+ def _whenparts (
427+ when : tuple [int , ...] | datetime .date ,
428+ timedepth : int ,
429+ ) -> tuple [int , ...]:
430+ return (
431+ timeparts_from_date (when , timedepth )
432+ if isinstance (when , datetime .date )
433+ else tuple (itertools .islice (_zeropadded_timeparts (when ), timedepth ))
434+ )
435+
436+
437+ def full_semverlike_timeparts (when : tuple [int , ...] | datetime .date ) -> str :
438+ """
439+ >>> full_semverlike_timeparts((3000, 2))
440+ '3000.2'
441+ >>> full_semverlike_timeparts(datetime.date(3000, 7, 12))
442+ '3000.7.12'
443+ >>> full_semverlike_timeparts(datetime.datetime(3000, 9, 1))
444+ '3000.9.1.0.0.0'
445+ """
446+ _parts = (
447+ timeparts_from_date (
448+ when , timedepth = (6 if isinstance (when , datetime .datetime ) else 3 )
449+ )
450+ if isinstance (when , datetime .date )
451+ else when
452+ )
453+ return "." .join (map (str , _parts ))
454+
455+
456+ def semverlike_timeparts (when : tuple [int , ...] | datetime .date , timedepth : int ) -> str :
457+ """
458+ >>> semverlike_timeparts((3000, 2, 7, 9), timedepth=2)
459+ '3000.2'
460+ >>> semverlike_timeparts((3000, 2), timedepth=1)
461+ '3000'
462+ >>> semverlike_timeparts((3000, 2, 7, 9), timedepth=5)
463+ '3000.2.7.9.0'
464+
465+ >>> semverlike_timeparts(datetime.date(3000, 7, 12), timedepth=3)
466+ '3000.7.12'
467+ >>> semverlike_timeparts(datetime.date(3000, 7, 12), timedepth=2)
468+ '3000.7'
469+ >>> semverlike_timeparts(datetime.date(3000, 7, 12), timedepth=1)
470+ '3000'
471+
472+ >>> semverlike_timeparts(datetime.datetime(3000, 9, 1, 5, 2), timedepth=6)
473+ '3000.9.1.5.2.0'
474+ >>> semverlike_timeparts(datetime.datetime(3000, 9, 1, 5, 2), timedepth=3)
475+ '3000.9.1'
476+ """
477+ return full_semverlike_timeparts (_whenparts (when , timedepth ))
0 commit comments