def is_compatible(requested_version, current_version, same_major=True):
"""Determine whether `requested_version` is satisfied by
`current_version`; in other words, `current_version` is >=
`requested_version`.
:param requested_version: version to check for compatibility
:param current_version: version to check against
:param same_major: if True, the major version must be identical between
`requested_version` and `current_version`. This is used when a
major-version difference indicates incompatibility between the two
versions. Since this is the common-case in practice, the default is
True.
:returns: True if compatible, False if not
"""
requested_parts = pkg_resources.parse_version(requested_version)
current_parts = pkg_resources.parse_version(current_version)
if same_major and (requested_parts[0] != current_parts[0]):
return False
return current_parts >= requested_parts
python类parse_version()的实例源码
def is_compatible(requested_version, current_version, same_major=True):
"""Determine whether `requested_version` is satisfied by
`current_version`; in other words, `current_version` is >=
`requested_version`.
:param requested_version: version to check for compatibility
:param current_version: version to check against
:param same_major: if True, the major version must be identical between
`requested_version` and `current_version`. This is used when a
major-version difference indicates incompatibility between the two
versions. Since this is the common-case in practice, the default is
True.
:returns: True if compatible, False if not
"""
requested_parts = pkg_resources.parse_version(requested_version)
current_parts = pkg_resources.parse_version(current_version)
if same_major and (requested_parts[0] != current_parts[0]):
return False
return current_parts >= requested_parts
# Track the messages we have sent already. See
# report_deprecated_feature().
def has_environment_marker_support():
#type: () -> bool
"""
Tests that setuptools has support for PEP-426 environment marker support.
The first known release to support it is 0.7 (and the earliest on PyPI seems to be 0.7.2
so we're using that), see: http://pythonhosted.org/setuptools/history.html#id142
References:
* https://wheel.readthedocs.io/en/latest/index.html#defining-conditional-dependencies
* https://www.python.org/dev/peps/pep-0426/#environment-markers
Method extended from pytest. Credit goes to developers there.
"""
try:
from pkg_resources import parse_version
return parse_version(setuptools.__version__) >= parse_version('0.7.2')
except Exception as exc:
sys.stderr.write("Could not test setuptool's version: %s\n" % exc)
return False
def get_migrations(application, from_version=None, to_version=None):
from plone.server import app_settings
if from_version:
from_version = parse_version(from_version)
if to_version:
to_version = parse_version(to_version)
applications = app_settings['applications'] + ['plone.server']
migrations = []
for migration in _migrations:
if migration.application != application or migration.application not in applications:
continue
if from_version and migration.to_version <= from_version:
continue
if to_version and migration.to_version > to_version:
continue
if migration.application not in applications:
continue
migrations.append(migration)
migrations.sort()
return migrations
def skip_by_version(request, openshift_version):
if request.node.cls.tasks.get('version_limits') and openshift_version:
lowest_version = request.node.cls.tasks['version_limits'].get('min')
highest_version = request.node.cls.tasks['version_limits'].get('max')
skip_latest = request.node.cls.tasks['version_limits'].get('skip_latest')
too_low = lowest_version and parse_version(lowest_version) > parse_version(openshift_version)
too_high = highest_version and parse_version(highest_version) < parse_version(openshift_version)
if openshift_version == 'latest':
if skip_latest:
pytest.skip('This API is not supported in the latest openshift version')
elif too_low:
pytest.skip('This API is not supported in openshift versions > {}. You are using version {}'.format(lowest_version, openshift_version))
elif too_high:
pytest.skip('This API is not supported in openshift versions < {}. You are using version {}'.format(highest_version, openshift_version))
def test_181_execute_gte_v10(self):
if self.client.server_version < pkg_resources.parse_version('10.0'):
raise unittest.SkipTest(
'Not applicable to Odoo version less then 10.0')
res = self.client.execute('res.partner', 'read', 1)
self.assertIsInstance(res, list)
self.assertEqual(len(res), 1)
self.assertIsInstance(res[0], dict)
self.assertEqual(res[0]['id'], 1)
res = self.client.execute('res.partner', 'read', [1])
self.assertIsInstance(res, list)
self.assertEqual(len(res), 1)
self.assertIsInstance(res[0], dict)
self.assertEqual(res[0]['id'], 1)
def _has_cython(self):
extensions = self.distribution.ext_modules
if not USE_CYTHON or not any(_.endswith('.pyx')
for ext in extensions
for _ in ext.sources):
return False
try:
import Cython
except ImportError:
print('Cython is not installed, defaulting to C/C++ files.')
return False
if parse_version(Cython.__version__) < \
parse_version(MIN_VERSION_CYTHON):
print("The Cython version is older than that required ('{0}' < '{1"
"}'). Defaulting to C/C++ files."
.format(Cython.__version__, MIN_VERSION_CYTHON))
return False
return True
def check_core_update(self) -> Optional[str]:
"""Check if there is an update of the core and if so, return the name of the new version."""
with urlopen('https://pext.hackerchick.me/version/stable') as update_url:
available_version = update_url.readline().decode("utf-8").strip()
# Normalize own version
if self.version.find('+') != -1:
print("Current version is an untagged development version, can only check for stable updates")
normalized_version = self.version[:self.version.find('+')]
elif self.version.find('-') != -1:
normalized_version = self.version[:self.version.find('-', self.version.find('-') + 1)]
else:
normalized_version = self.version
if parse_version(normalized_version.lstrip('v')) < parse_version(available_version.lstrip('v')):
return available_version
return None
def is_version_gte(actual, expected):
""" Checks two versions for actual >= epected condition
Versions need to be in Major.Minor.Patch format.
Args:
actual (str): the actual version being checked
expected (str): the expected version being checked
Returns:
bool: True if the actual version is greater than or equal to
the expected version.
Raises:
ValueError: if expected ot actual version is not in Major.Minor.Patch
format.
"""
if isinstance(parse_version(actual), SetuptoolsVersion):
# This handles versions that end in things like `rc0`
return parse_version(actual) >= parse_version(expected)
else:
# This handles versions that end in things like `-v7+` and `-generic`
return LooseVersion(actual) >= LooseVersion(expected)
def get_numpy_status():
"""
Returns a dictionary containing a boolean specifying whether NumPy
is up-to-date, along with the version string (empty string if
not installed).
"""
numpy_status = {}
try:
import numpy
numpy_version = numpy.__version__
numpy_status['up_to_date'] = parse_version(
numpy_version) >= parse_version(NUMPY_MIN_VERSION)
numpy_status['version'] = numpy_version
except ImportError:
traceback.print_exc()
numpy_status['up_to_date'] = False
numpy_status['version'] = ""
return numpy_status
def __init__(self, driver_name):
self.driver_name = driver_name
LOG.debug('Loading bareon data-driver "%s"', self.driver_name)
try:
manager = stevedore.driver.DriverManager(
self._namespace, self.driver_name, verify_requirements=True)
extension = manager[driver_name]
version = extension.entry_point.dist.version
version = pkg_resources.parse_version(version)
LOG.info('Driver %s-%s loaded', extension.name, version)
if version < self._min_version:
raise RuntimeError(
'bareon version less than {} does not support '
'deployment config validation'.format(self._min_version))
except RuntimeError as e:
LOG.warning(
'Fail to load bareon data-driver "%s": %s',
self.driver_name, e)
return
self._driver = manager.driver
def parse_version(version):
"""Use parse_version from pkg_resources or distutils as available."""
global parse_version
try:
from pkg_resources import parse_version
except ImportError:
from distutils.version import LooseVersion as parse_version
return parse_version(version)
def _sort_key(self):
return (self.parsed_filename.group('name'),
parse_version(self.parsed_filename.group('ver')),
tuple(-x for x in self.rank),
self.filename)
def __lt__(self, other):
if self.context != other.context:
raise TypeError("{0}.context != {1}.context".format(self, other))
return self._sort_key < other._sort_key
# XXX prune
sn = self.parsed_filename.group('name')
on = other.parsed_filename.group('name')
if sn != on:
return sn < on
sv = parse_version(self.parsed_filename.group('ver'))
ov = parse_version(other.parsed_filename.group('ver'))
if sv != ov:
return sv < ov
# Compatibility
if self.context != other.context:
raise TypeError("{0}.context != {1}.context".format(self, other))
sc = self.rank
oc = other.rank
if sc != None and oc != None and sc != oc:
# Smaller compatibility ranks are "better" than larger ones,
# so we have to reverse the sense of the comparison here!
return sc > oc
elif sc == None and oc != None:
return False
return self.filename < other.filename
def parse_version(version):
"""Use parse_version from pkg_resources or distutils as available."""
global parse_version
try:
from pkg_resources import parse_version
except ImportError:
from distutils.version import LooseVersion as parse_version
return parse_version(version)
def _sort_key(self):
return (self.parsed_filename.group('name'),
parse_version(self.parsed_filename.group('ver')),
tuple(-x for x in self.rank),
self.filename)
def __lt__(self, other):
if self.context != other.context:
raise TypeError("{0}.context != {1}.context".format(self, other))
return self._sort_key < other._sort_key
# XXX prune
sn = self.parsed_filename.group('name')
on = other.parsed_filename.group('name')
if sn != on:
return sn < on
sv = parse_version(self.parsed_filename.group('ver'))
ov = parse_version(other.parsed_filename.group('ver'))
if sv != ov:
return sv < ov
# Compatibility
if self.context != other.context:
raise TypeError("{0}.context != {1}.context".format(self, other))
sc = self.rank
oc = other.rank
if sc is not None and oc is not None and sc != oc:
# Smaller compatibility ranks are "better" than larger ones,
# so we have to reverse the sense of the comparison here!
return sc > oc
elif sc is None and oc is not None:
return False
return self.filename < other.filename
def parse_version(version):
"""Use parse_version from pkg_resources or distutils as available."""
global parse_version
try:
from pkg_resources import parse_version
except ImportError:
from distutils.version import LooseVersion as parse_version
return parse_version(version)
def _sort_key(self):
return (self.parsed_filename.group('name'),
parse_version(self.parsed_filename.group('ver')),
tuple(-x for x in self.rank),
self.filename)
def __lt__(self, other):
if self.context != other.context:
raise TypeError("{0}.context != {1}.context".format(self, other))
return self._sort_key < other._sort_key
# XXX prune
sn = self.parsed_filename.group('name')
on = other.parsed_filename.group('name')
if sn != on:
return sn < on
sv = parse_version(self.parsed_filename.group('ver'))
ov = parse_version(other.parsed_filename.group('ver'))
if sv != ov:
return sv < ov
# Compatibility
if self.context != other.context:
raise TypeError("{0}.context != {1}.context".format(self, other))
sc = self.rank
oc = other.rank
if sc != None and oc != None and sc != oc:
# Smaller compatibility ranks are "better" than larger ones,
# so we have to reverse the sense of the comparison here!
return sc > oc
elif sc == None and oc != None:
return False
return self.filename < other.filename
def parse_version(version):
"""Use parse_version from pkg_resources or distutils as available."""
global parse_version
try:
from pkg_resources import parse_version
except ImportError:
from distutils.version import LooseVersion as parse_version
return parse_version(version)
def _sort_key(self):
return (self.parsed_filename.group('name'),
parse_version(self.parsed_filename.group('ver')),
tuple(-x for x in self.rank),
self.filename)
def __lt__(self, other):
if self.context != other.context:
raise TypeError("{0}.context != {1}.context".format(self, other))
return self._sort_key < other._sort_key
# XXX prune
sn = self.parsed_filename.group('name')
on = other.parsed_filename.group('name')
if sn != on:
return sn < on
sv = parse_version(self.parsed_filename.group('ver'))
ov = parse_version(other.parsed_filename.group('ver'))
if sv != ov:
return sv < ov
# Compatibility
if self.context != other.context:
raise TypeError("{0}.context != {1}.context".format(self, other))
sc = self.rank
oc = other.rank
if sc != None and oc != None and sc != oc:
# Smaller compatibility ranks are "better" than larger ones,
# so we have to reverse the sense of the comparison here!
return sc > oc
elif sc == None and oc != None:
return False
return self.filename < other.filename
def parse_version(version):
"""Use parse_version from pkg_resources or distutils as available."""
global parse_version
try:
from pkg_resources import parse_version
except ImportError:
from distutils.version import LooseVersion as parse_version
return parse_version(version)
def _sort_key(self):
return (self.parsed_filename.group('name'),
parse_version(self.parsed_filename.group('ver')),
tuple(-x for x in self.rank),
self.filename)
def parse_version(version):
"""Use parse_version from pkg_resources or distutils as available."""
global parse_version
try:
from pkg_resources import parse_version
except ImportError:
from distutils.version import LooseVersion as parse_version
return parse_version(version)
def _sort_key(self):
return (self.parsed_filename.group('name'),
parse_version(self.parsed_filename.group('ver')),
tuple(-x for x in self.rank),
self.filename)
def __lt__(self, other):
if self.context != other.context:
raise TypeError("{0}.context != {1}.context".format(self, other))
return self._sort_key < other._sort_key
# XXX prune
sn = self.parsed_filename.group('name')
on = other.parsed_filename.group('name')
if sn != on:
return sn < on
sv = parse_version(self.parsed_filename.group('ver'))
ov = parse_version(other.parsed_filename.group('ver'))
if sv != ov:
return sv < ov
# Compatibility
if self.context != other.context:
raise TypeError("{0}.context != {1}.context".format(self, other))
sc = self.rank
oc = other.rank
if sc != None and oc != None and sc != oc:
# Smaller compatibility ranks are "better" than larger ones,
# so we have to reverse the sense of the comparison here!
return sc > oc
elif sc == None and oc != None:
return False
return self.filename < other.filename
def parse_version(version):
"""Use parse_version from pkg_resources or distutils as available."""
global parse_version
try:
from pkg_resources import parse_version
except ImportError:
from distutils.version import LooseVersion as parse_version
return parse_version(version)
def _sort_key(self):
return (self.parsed_filename.group('name'),
parse_version(self.parsed_filename.group('ver')),
tuple(-x for x in self.rank),
self.filename)