@@ -598,6 +598,105 @@ class MyAttrs2:
598598 != keyb (MyAttrs ("hi" , 1 ))) # type: ignore[call-arg]
599599
600600
601+ def test_datetime_hashing () -> None :
602+ keyb = KeyBuilder ()
603+
604+ import datetime
605+
606+ # {{{ date
607+ # No timezone info; date is always naive
608+ assert (keyb (datetime .date (2020 , 1 , 1 ))
609+ == keyb (datetime .date (2020 , 1 , 1 ))
610+ == "9fb97d7faabc3603f3e334ca5eb1eb0fe0c92665e5611cb1b5aa77fa0f70f5e3" )
611+ assert keyb (datetime .date (2020 , 1 , 1 )) != keyb (datetime .date (2020 , 1 , 2 ))
612+
613+ # }}}
614+
615+ # {{{ time
616+
617+ # Must distinguish between naive and aware time objects
618+
619+ # Naive time
620+ assert (keyb (datetime .time (12 , 0 ))
621+ == keyb (datetime .time (12 , 0 ))
622+ == keyb (datetime .time (12 , 0 , 0 ))
623+ == keyb (datetime .time (12 , 0 , 0 , 0 ))
624+ == "bf73f48b2f2666b5c42f6993e628fdc15e0b6c3127186c3ab44ce08ed83d0472" )
625+ assert keyb (datetime .time (12 , 0 )) != keyb (datetime .time (12 , 1 ))
626+
627+ # Aware time
628+ t1 = datetime .time (12 , 0 , tzinfo = datetime .timezone .utc )
629+ t2 = datetime .time (7 , 0 ,
630+ tzinfo = datetime .timezone (datetime .timedelta (hours = - 5 )))
631+ t3 = datetime .time (7 , 0 ,
632+ tzinfo = datetime .timezone (datetime .timedelta (hours = - 4 )))
633+
634+ assert t1 == t2
635+ assert (keyb (t1 )
636+ == keyb (t2 )
637+ == "c0947587c92ab6e2df90475dd497aff1d83df55fbd5af6c55b2a0a221b2437a4" )
638+
639+ assert t1 != t3
640+ assert keyb (t1 ) != keyb (t3 )
641+
642+ # }}}
643+
644+ # {{{ datetime
645+
646+ # must distinguish between naive and aware datetime objects
647+
648+ # Aware datetime
649+ dt1 = datetime .datetime (2020 , 1 , 1 , 12 , tzinfo = datetime .timezone .utc )
650+ dt2 = datetime .datetime (2020 , 1 , 1 , 7 ,
651+ tzinfo = datetime .timezone (datetime .timedelta (hours = - 5 )))
652+
653+ assert dt1 == dt2
654+ assert (keyb (dt1 )
655+ == keyb (dt2 )
656+ == "cd35722af47e42cb3bc81c389b87eb2e78ee8e20298bb1d8a193b30940d1c142" )
657+
658+ dt3 = datetime .datetime (2020 , 1 , 1 , 7 ,
659+ tzinfo = datetime .timezone (datetime .timedelta (hours = - 4 )))
660+
661+ assert dt1 != dt3
662+ assert keyb (dt1 ) != keyb (dt3 )
663+
664+ # Naive datetime
665+ dt4 = datetime .datetime (2020 , 1 , 1 , 6 ) # matches dt1 'naively'
666+ assert dt1 != dt4 # naive and aware datetime objects are never equal
667+ assert keyb (dt1 ) != keyb (dt4 )
668+
669+ assert (keyb (datetime .datetime (2020 , 1 , 1 ))
670+ == keyb (datetime .datetime (2020 , 1 , 1 ))
671+ == keyb (datetime .datetime (2020 , 1 , 1 , 0 , 0 , 0 , 0 ))
672+ == "8f3b843d7b9176afd8e2ce97ebc19789098a1c7774c4ec00d4054ec954ce2b88"
673+ )
674+ assert keyb (datetime .datetime (2020 , 1 , 1 )) != keyb (datetime .datetime (2020 , 1 , 2 ))
675+ assert (keyb (datetime .datetime (2020 , 1 , 1 ))
676+ != keyb (datetime .datetime (2020 , 1 , 1 , tzinfo = datetime .timezone .utc )))
677+
678+ # }}}
679+
680+ # {{{ timezone
681+
682+ tz1 = datetime .timezone (datetime .timedelta (hours = - 4 ))
683+ tz2 = datetime .timezone (datetime .timedelta (hours = 0 ))
684+ tz3 = datetime .timezone .utc
685+
686+ assert tz1 != tz2
687+ assert keyb (tz1 ) != keyb (tz2 )
688+
689+ assert tz1 != tz3
690+ assert keyb (tz1 ) != keyb (tz3 )
691+
692+ assert tz2 == tz3
693+ assert (keyb (tz2 )
694+ == keyb (tz3 )
695+ == "89bd615f32c1f209b0853b1fc7d06ddb6fda7f367a00a8621d60337d52cb8d10" )
696+
697+ # }}}
698+
699+
601700def test_xdg_cache_home () -> None :
602701 import os
603702 xdg_dir = "tmpdir_pytools_xdg_test"
0 commit comments