##
# .versionstring
##
"""
PostgreSQL version string parsing.
>>> postgresql.versionstring.split('8.0.1')
(8, 0, 1, None, None)
"""
def split(vstr: str) -> tuple:
"""
Split a PostgreSQL version string into a tuple.
(major, minor, patch, ..., state_class, state_level)
"""
v = vstr.strip().split('.')
# Get rid of the numbers around the state_class (beta,a,dev,alpha, etc)
state_class = v[-1].strip('0123456789')
if state_class:
last_version, state_level = v[-1].split(state_class)
if not state_level:
state_level = None
else:
state_level = int(state_level)
vlist = [int(x or '0') for x in v[:-1]]
if last_version:
vlist.append(int(last_version))
vlist += [None] * (3 - len(vlist))
vlist += [state_class, state_level]
else:
state_level = None
state_class = None
vlist = [int(x or '0') for x in v]
# pad the difference with `None` objects, and +2 for the state_*.
vlist += [None] * ((3 - len(vlist)) + 2)
return tuple(vlist)
def unsplit(vtup: tuple) -> str:
"""
Join a version tuple back into the original version string.
"""
svtup = [str(x) for x in vtup[:-2] if x is not None]
state_class, state_level = vtup[-2:]
return '.'.join(svtup) + ('' if state_class is None else state_class + str(state_level))
def normalize(split_version: tuple) -> tuple:
"""
Given a tuple produced by `split`, normalize the `None` objects into int(0)
or 'final' if it's the ``state_class``.
"""
(*head, state_class, state_level) = split_version
mmp = [x if x is not None else 0 for x in head]
return tuple(mmp + [state_class or 'final', state_level or 0])
default_state_class_priority = [
'dev',
'a',
'alpha',
'b',
'beta',
'rc',
'final',
None,
]
python = repr
def xml(self):
return '