@@ -653,20 +653,30 @@ def _new_version(
653653 dev = _parse_dev (dev ),
654654 local = _parse_local (local ),
655655 is_prefix = is_prefix ,
656- norm = norm ,
657- eq = lambda x : _version_eq (self , x ), # buildifier: disable=uninitialized
658- eqq = lambda x : _version_eqq (self , x ), # buildifier: disable=uninitialized
659- ge = lambda x : _version_ge (self , x ), # buildifier: disable=uninitialized
660- gt = lambda x : _version_gt (self , x ), # buildifier: disable=uninitialized
661- le = lambda x : _version_le (self , x ), # buildifier: disable=uninitialized
662- lt = lambda x : _version_lt (self , x ), # buildifier: disable=uninitialized
663- ne = lambda x : _version_ne (self , x ), # buildifier: disable=uninitialized
664- compatible = lambda x : _version_compatible (self , x ), # buildifier: disable=uninitialized
665- str = lambda : norm ,
666- key = lambda * , local = True : _version_key (self , local = local ), # buildifier: disable=uninitialized
656+ string = norm ,
667657 )
668658
669- return self
659+ public = struct (
660+ eq = mkmethod (self , _version_eq ),
661+ eqq = mkmethod (self , _version_eqq ),
662+ ge = mkmethod (self , _version_ge ),
663+ gt = mkmethod (self , _version_gt ),
664+ le = mkmethod (self , _version_le ),
665+ lt = mkmethod (self , _version_lt ),
666+ ne = mkmethod (self , _version_ne ),
667+ compatible = mkmethod (self , _version_compatible ),
668+ key = mkmethod (self , _version_key ),
669+ epoch = self .epoch ,
670+ release = self .release ,
671+ pre = self .pre ,
672+ post = self .post ,
673+ dev = self .dev ,
674+ local = self .local ,
675+ is_prefix = self .is_prefix ,
676+ string = norm ,
677+ )
678+
679+ return public
670680
671681def _pad_zeros (release , n ):
672682 padding = n - len (release )
@@ -679,9 +689,9 @@ def _pad_zeros(release, n):
679689def _prefix_err (left , op , right ):
680690 if left .is_prefix or right .is_prefix :
681691 fail ("PEP440: only '==' and '!=' operators can use prefix matching: {} {} {}" .format (
682- left .norm ,
692+ left .string ,
683693 op ,
684- right .norm ,
694+ right .string ,
685695 ))
686696
687697def _version_eqq (left , right ):
@@ -691,16 +701,16 @@ def _version_eqq(left, right):
691701
692702 # https://peps.python.org/pep-0440/#arbitrary-equality
693703 # > simple string equality operations
694- return left .norm == right .norm
704+ return left .string == right .string
695705
696706def _version_eq (left , right ):
697707 """== operator"""
698708 if left .is_prefix and right .is_prefix :
699709 fail ("Invalid comparison: both versions cannot be prefix matching" )
700710 if left .is_prefix :
701- return right .norm .startswith ("{}." .format (left .norm ))
711+ return right .string .startswith ("{}." .format (left .string ))
702712 if right .is_prefix :
703- return left .norm .startswith ("{}." .format (right .norm ))
713+ return left .string .startswith ("{}." .format (right .string ))
704714
705715 if left .epoch != right .epoch :
706716 return False
@@ -728,9 +738,15 @@ def _version_compatible(left, right):
728738 # https://peps.python.org/pep-0440/#compatible-release
729739 # Note, the ~= operator can be also expressed as:
730740 # >= V.N, == V.*
731- head , _ , _ = right .norm .partition ("." )
732- right_star = version ("{}.*" .format (head ))
733- return _version_ge (left , right ) and _version_eq (left , right_star )
741+
742+ right_star = "." .join ([str (d ) for d in right .release [:- 1 ]])
743+ if right_star :
744+ right_star = "{}." .format (right_star )
745+
746+ # TODO @aignas 2025-05-09: more tests:
747+ # epoch
748+ # negative tests
749+ return _version_ge (left , right ) and left .string .startswith (right_star )
734750
735751def _version_ne (left , right ):
736752 """!= operator"""
@@ -820,11 +836,12 @@ def _version_ge(left, right):
820836 _right = _version_key (right , local = False )
821837 return _left > _right or _version_eq (left , right )
822838
823- def _version_key (self , * , local , release_key = ( "z" ,) ):
839+ def _version_key (self , * , local = True ):
824840 """This function returns a tuple that can be used in 'sorted' calls.
825841
826842 This implements the PEP440 version sorting.
827843 """
844+ release_key = ("z" ,)
828845 local = self .local if local else []
829846 local = local or []
830847
0 commit comments