@@ -73,9 +73,89 @@ def get_version_info():
7373        return  version , release 
7474
7575
76- if  __name__  ==  "__main__" :
77-     short_ver , full_ver  =  format_version_info (get_header_version_info ())
78-     if  sys .argv [1 :2 ] ==  ["--short" ]:
76+ def  get_version_hex (info : version_info ) ->  int :
77+     """Convert a version_info object to a hex version number.""" 
78+     levels  =  {"alpha" : 0xA , "beta" : 0xB , "candidate" : 0xC , "final" : 0xF }
79+     return  (
80+         (info .major  <<  24 )
81+         |  (info .minor  <<  16 )
82+         |  (info .micro  <<  8 )
83+         |  (levels [info .releaselevel ] <<  4 )
84+         |  (info .serial  <<  0 )
85+     )
86+ 
87+ 
88+ def  parse_str_version (version : str ) ->  version_info :
89+     """Convert a version string to a version_info object.""" 
90+     tag_cre  =  re .compile (r"(\d+)(?:\.(\d+)(?:\.(\d+))?)?(?:([ab]|rc)(\d+))?$" )
91+     result  =  tag_cre .match (version )
92+     if  not  result :
93+         raise  ValueError (f"Invalid version string: { version }  )
94+ 
95+     parts  =  list (result .groups ())
96+     levels  =  {"a" : "alpha" , "b" : "beta" , "rc" : "candidate" }
97+     return  version_info (
98+         major = int (parts [0 ]),
99+         minor = int (parts [1 ]),
100+         micro = int (parts [2 ] or  0 ),
101+         releaselevel = levels .get (parts [3 ], "final" ),
102+         serial = int (parts [4 ]) if  parts [4 ] else  0 ,
103+     )
104+ 
105+ 
106+ def  parse_hex_version (version : int ) ->  version_info :
107+     """Convert a hex version number to a version_info object.""" 
108+     if  not  isinstance (version , int ):
109+         raise  ValueError (f"Invalid hex version: { version }  )
110+ 
111+     levels  =  {0xA : "alpha" , 0xB : "beta" , 0xC : "candidate" , 0xF : "final" }
112+     return  version_info (
113+         major = (version  >>  24 ) &  0xFF ,
114+         minor = (version  >>  16 ) &  0xFF ,
115+         micro = (version  >>  8 ) &  0xFF ,
116+         releaselevel = levels .get ((version  >>  4 ) &  0xF , "final" ),
117+         serial = version  &  0xF ,
118+     )
119+ 
120+ 
121+ def  main () ->  None :
122+     import  argparse 
123+ 
124+     parser  =  argparse .ArgumentParser (color = True )
125+     parser .add_argument (
126+         "version" ,
127+         nargs = "?" ,
128+         help = "version to convert (default: repo version)" ,
129+     )
130+     group  =  parser .add_mutually_exclusive_group ()
131+     group .add_argument (
132+         "--short" ,
133+         action = "store_true" ,
134+         help = "print version as x.y" ,
135+     )
136+     group .add_argument (
137+         "--hex" ,
138+         action = "store_true" ,
139+         help = "print version as a 4-byte hex number" ,
140+     )
141+     args  =  parser .parse_args ()
142+ 
143+     if  args .version :
144+         try :
145+             info  =  parse_str_version (args .version )
146+         except  ValueError :
147+             info  =  parse_hex_version (int (args .version , 16 ))
148+     else :
149+         info  =  get_header_version_info ()
150+ 
151+     short_ver , full_ver  =  format_version_info (info )
152+     if  args .short :
79153        print (short_ver )
154+     elif  args .hex :
155+         print (hex (get_version_hex (info )))
80156    else :
81157        print (full_ver )
158+ 
159+ 
160+ if  __name__  ==  "__main__" :
161+     main ()
0 commit comments