From deb584639f053d70924cd3aeb6e8f1614709fc91 Mon Sep 17 00:00:00 2001 From: Donald Stufft Date: Tue, 9 Feb 2016 17:30:05 -0500 Subject: [PATCH] Implement name normalization from PEP 503 --- CHANGELOG.rst | 2 ++ docs/index.rst | 1 + docs/utils.rst | 28 ++++++++++++++++++++++++++++ packaging/utils.py | 14 ++++++++++++++ tests/test_utils.py | 27 +++++++++++++++++++++++++++ 5 files changed, 72 insertions(+) create mode 100644 docs/utils.rst create mode 100644 packaging/utils.py create mode 100644 tests/test_utils.py diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 10cf7336f..43940555b 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,8 @@ Changelog .. note:: This version is not yet released and is under active development. +* Add a function that implements the name canonicalization from PEP 503. + 16.1 - 2016-02-07 ~~~~~~~~~~~~~~~~~ diff --git a/docs/index.rst b/docs/index.rst index 9851045c0..91897cc5f 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -24,6 +24,7 @@ API specifiers markers requirements + utils Project diff --git a/docs/utils.rst b/docs/utils.rst new file mode 100644 index 000000000..06cbbf7bf --- /dev/null +++ b/docs/utils.rst @@ -0,0 +1,28 @@ +Utilities +========= + +.. currentmodule:: packaging.utils + + +A set of small, helper utilities for dealing with Python packages. + + +Reference +--------- + +.. function:: canonicalize_name(name) + + This function takes a valid Python package name, and returns the normalized + form of it. + + :param str name: The name to normalize. + + .. doctest:: + + >>> from packaging.utils import canonicalize_name + >>> canonicalize_name("Django") + 'django' + >>> canonicalize_name("oslo.concurrency") + 'oslo-concurrency' + >>> canonicalize_name("requests") + 'requests' diff --git a/packaging/utils.py b/packaging/utils.py new file mode 100644 index 000000000..942387cef --- /dev/null +++ b/packaging/utils.py @@ -0,0 +1,14 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import re + + +_canonicalize_regex = re.compile(r"[-_.]+") + + +def canonicalize_name(name): + # This is taken from PEP 503. + return _canonicalize_regex.sub("-", name).lower() diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 000000000..1c96b3125 --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,27 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import pytest + +from packaging.utils import canonicalize_name + + +@pytest.mark.parametrize( + ("name", "expected"), + [ + ("foo", "foo"), + ("Foo", "foo"), + ("fOo", "foo"), + ("foo.bar", "foo-bar"), + ("Foo.Bar", "foo-bar"), + ("Foo.....Bar", "foo-bar"), + ("foo_bar", "foo-bar"), + ("foo___bar", "foo-bar"), + ("foo-bar", "foo-bar"), + ("foo----bar", "foo-bar"), + ], +) +def test_canonicalize_name(name, expected): + assert canonicalize_name(name) == expected