requirements/openstack_requirements/tests/test_requirement.py
Dr. Jens Harbott c7d98564d0 Fix pkg_resources exception handling for py312
The exception that is generated on parsing errors has changed in Python
3.12, match on the generic ValueError instead. Also switch to using
the simpler assertRaises() call instead of explicitly dealing with
exceptions.

Note that this is just a temporary workaround, we should really move
away for using pkg_resources completely, see [0] and [1].

[0] https://setuptools.pypa.io/en/latest/pkg_resources.html
[1] https://importlib-resources.readthedocs.io/en/latest/migration.html

Change-Id: I20422194f6fc6d1c4ba49da754a2c3aab99a282c
2024-06-20 03:22:07 +00:00

218 lines
8.2 KiB
Python

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import textwrap
import testscenarios
import testtools
from openstack_requirements import requirement
load_tests = testscenarios.load_tests_apply_scenarios
class TestParseRequirement(testtools.TestCase):
dist_scenarios = [
('package', dict(
line='swift',
req=requirement.Requirement('swift', '', '', '', ''))),
('specifier', dict(
line='alembic>=0.4.1',
req=requirement.Requirement('alembic', '', '>=0.4.1', '', ''))),
('specifiers', dict(
line='alembic>=0.4.1,!=1.1.8',
req=requirement.Requirement('alembic', '', '!=1.1.8,>=0.4.1', '',
''))),
('comment-only', dict(
line='# foo',
req=requirement.Requirement('', '', '', '', '# foo'))),
('comment', dict(
line='Pint>=0.5 # BSD',
req=requirement.Requirement('Pint', '', '>=0.5', '', '# BSD'))),
('comment-with-semicolon', dict(
line='Pint>=0.5 # BSD;fred',
req=requirement.Requirement('Pint', '', '>=0.5', '', '# BSD;fred'))),
('case', dict(
line='Babel>=1.3',
req=requirement.Requirement('Babel', '', '>=1.3', '', ''))),
('markers', dict(
line="pywin32;sys_platform=='win32'",
req=requirement.Requirement('pywin32', '', '',
"sys_platform=='win32'", ''))),
('markers-with-comment', dict(
line="Sphinx<=1.2; python_version=='2.7'# Sadface",
req=requirement.Requirement('Sphinx', '', '<=1.2',
"python_version=='2.7'", '# Sadface')))]
url_scenarios = [
('url', dict(
line='file:///path/to/thing#egg=thing',
req=requirement.Requirement('thing', 'file:///path/to/thing', '', '',
''),
permit_urls=True)),
('oslo-url', dict(
line='file:///path/to/oslo.thing#egg=oslo.thing',
req=requirement.Requirement('oslo.thing',
'file:///path/to/oslo.thing', '', '', ''),
permit_urls=True)),
('url-comment', dict(
line='file:///path/to/thing#egg=thing # http://altpath#egg=boo',
req=requirement.Requirement('thing', 'file:///path/to/thing', '', '',
'# http://altpath#egg=boo'),
permit_urls=True)),
('editable', dict(
line='-e file:///path/to/bar#egg=bar',
req=requirement.Requirement('bar', '-e file:///path/to/bar', '', '',
''),
permit_urls=True)),
('editable_vcs_git', dict(
line='-e git+http://github.com/path/to/oslo.bar#egg=oslo.bar',
req=requirement.Requirement('oslo.bar',
'-e git+http://github.com'
'/path/to/oslo.bar', '', '', ''),
permit_urls=True)),
('editable_vcs_git_ssh', dict(
line='-e git+ssh://github.com/path/to/oslo.bar#egg=oslo.bar',
req=requirement.Requirement('oslo.bar',
'-e git+ssh://github.com'
'/path/to/oslo.bar', '', '', ''),
permit_urls=True)),
]
scenarios = dist_scenarios + url_scenarios
def test_parse(self):
parsed = requirement.parse_line(
self.line, permit_urls=getattr(self, 'permit_urls', False))
self.assertEqual(self.req, parsed)
class TestParseRequirementFailures(testtools.TestCase):
scenarios = [
('url', dict(line='http://tarballs.openstack.org/oslo.config/'
'oslo.config-1.2.0a3.tar.gz#egg=oslo.config')),
('-e', dict(line='-e git+https://foo.com#egg=foo')),
('-f', dict(line='-f http://tarballs.openstack.org/'))]
def test_does_not_parse(self):
self.assertRaises(ValueError, requirement.parse_line, self.line)
class TestToContent(testtools.TestCase):
def test_smoke(self):
reqs = requirement.to_content(requirement.Requirements(
[requirement.Requirement(
'foo', '', '<=1', "python_version=='2.7'", '# BSD')]),
marker_sep='!')
self.assertEqual(
''.join(requirement._REQS_HEADER
+ ["foo<=1!python_version=='2.7' # BSD\n"]),
reqs)
def test_location(self):
reqs = requirement.to_content(requirement.Requirements(
[requirement.Requirement(
'foo', 'file://foo', '', "python_version=='2.7'", '# BSD')]))
self.assertEqual(
''.join(requirement._REQS_HEADER
+ ["file://foo#egg=foo;python_version=='2.7' # BSD\n"]),
reqs)
class TestToReqs(testtools.TestCase):
def test_editable(self):
line = '-e file:///foo#egg=foo'
reqs = list(requirement.to_reqs(line, permit_urls=True))
req = requirement.Requirement('foo', '-e file:///foo', '', '', '')
self.assertEqual(reqs, [(req, line)])
def test_urls(self):
line = 'file:///foo#egg=foo'
reqs = list(requirement.to_reqs(line, permit_urls=True))
req = requirement.Requirement('foo', 'file:///foo', '', '', '')
self.assertEqual(reqs, [(req, line)])
def test_not_urls(self):
self.assertRaises(
ValueError, list, requirement.to_reqs('file:///foo#egg=foo'))
def test_multiline(self):
content = textwrap.dedent("""\
oslo.config>=1.11.0 # Apache-2.0
oslo.concurrency>=2.3.0 # Apache-2.0
oslo.context>=0.2.0 # Apache-2.0
""")
reqs = requirement.parse(content)
self.assertEqual(
set(['oslo.config', 'oslo.concurrency', 'oslo.context']),
set(reqs.keys()),
)
def test_extras(self):
content = textwrap.dedent("""\
oslo.config>=1.11.0 # Apache-2.0
oslo.concurrency[fixtures]>=1.11.0 # Apache-2.0
oslo.db[fixtures,mysql]>=1.11.0 # Apache-2.0
""")
reqs = requirement.parse(content)
self.assertEqual(
set(['oslo.config', 'oslo.concurrency', 'oslo.db']),
set(reqs.keys()),
)
self.assertEqual(reqs['oslo.config'][0][0].extras, frozenset(()))
self.assertEqual(reqs['oslo.concurrency'][0][0].extras,
frozenset(('fixtures',)))
self.assertEqual(reqs['oslo.db'][0][0].extras,
frozenset(('fixtures', 'mysql')))
self.assertCountEqual(reqs,
['oslo.config', 'oslo.concurrency', 'oslo.db'])
class TestCanonicalName(testtools.TestCase):
def test_underscores(self):
self.assertEqual('foo-bar', requirement.canonical_name('Foo_bar'))
class TestToDict(testtools.TestCase):
def test_canonicalises(self):
req = requirement.Requirement('Foo_bar', '', '', '', '')
self.assertEqual(
{'foo-bar': [(req, '')]}, requirement.to_dict([(req, '')]))
class TestReqPolicy(testtools.TestCase):
def test_requirements_policy_pass(self):
content = textwrap.dedent("""\
cffi!=1.1.2
other
""")
reqs = requirement.parse(content)
policy_check = [x for x in requirement.check_reqs_bounds_policy(reqs)]
self.assertEqual(len(policy_check), 0)
def test_requirements_policy_fail(self):
content = textwrap.dedent("""\
cffi>=1.1.1,!=1.1.0
other>=1,>=2,!=1.1.0
""")
reqs = requirement.parse(content)
self.assertEqual([
'Requirement cffi should not include a >= specifier',
'Requirement other should not include a >= specifier'],
sorted([x for x in requirement.check_reqs_bounds_policy(reqs)]))