summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.rst25
-rw-r--r--docs/index.rst16
-rw-r--r--docs/intro.rst477
-rw-r--r--tox.ini2
4 files changed, 35 insertions, 485 deletions
diff --git a/README.rst b/README.rst
index 4452363..64a963f 100644
--- a/README.rst
+++ b/README.rst
@@ -29,11 +29,16 @@ Simple yet flexible natural sorting in Python.
- `How Does Natsort Work? <https://natsort.readthedocs.io/en/master/howitworks.html>`_
- `API <https://natsort.readthedocs.io/en/master/api.html>`_
+ - `Quick Description`_
+ - `Examples`_
- `FAQ`_
+ - `Requirements`_
- `Optional Dependencies`_
-
- - `fastnumbers <https://pypi.org/project/fastnumbers>`_ >= 2.0.0
- - `PyICU <https://pypi.org/project/PyICU>`_ >= 1.0.0
+ - `Installation`_
+ - `How to Run Tests`_
+ - `How to Build Documentation`_
+ - `Deprecation Schedule`_
+ - `History`_
**NOTE**: Please see the `Deprecation Schedule`_ section for changes in
``natsort`` version 6.0.0 and in the upcoming version 7.0.0.
@@ -95,6 +100,15 @@ an alternate way to sort in-place naturally.
Examples
--------
+- `Sorting Versions`_
+- `Sorting by Real Numbers (i.e. Signed Floats)`_
+- `Locale-Aware Sorting (or "Human Sorting")`_
+- `Further Customizing Natsort`_
+- `Sorting Mixed Types`_
+- `Handling Bytes on Python 3`_
+- `Generating a Reusable Sorting Key and Sorting In-Place`_
+- `Other Useful Things`_
+
Sorting Versions
++++++++++++++++
@@ -260,6 +274,7 @@ Other Useful Things
- `controlling the case-sensitivity <https://natsort.readthedocs.io/en/master/examples.html#case-sort>`_
- `sorting file paths correctly <https://natsort.readthedocs.io/en/master/examples.html#path-sort>`_
- `allow custom sorting keys <https://natsort.readthedocs.io/en/master/examples.html#custom-sort>`_
+ - `accounting for units <https://natsort.readthedocs.io/en/master/examples.html#accounting-for-units-when-sorting>`_
FAQ
---
@@ -440,8 +455,8 @@ fixes are applied so that users who cannot update from Python 2.7 will not be
forced to use a buggy ``natsort`` version. Once version 7.0.0 is released, new
features will not be added to version 6.X, only bug fixes.
-Deprecated APIs
-+++++++++++++++
+Dropped Deprecated APIs
++++++++++++++++++++++++
In ``natsort`` version 6.0.0, the following APIs and functions were removed
diff --git a/docs/index.rst b/docs/index.rst
index 4c03f3b..80cc87b 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -6,13 +6,25 @@
natsort: Simple yet flexible natural sorting in Python.
=======================================================
-Contents:
+ - Source Code: https://github.com/SethMMorton/natsort
+ - Downloads: https://pypi.org/project/natsort/
+ - Documentation: https://natsort.readthedocs.io/
+
+Please see the `GitHub main page <https://github.com/SethMMorton/natsort#natsort>`_
+for everything else, including
+
+ - Quick description
+ - Basic examples
+ - FAQ
+ - Requirements and optional dependencies
+ - Installation instructions
+ - Testing instructions
+ - Deprecation schedule
.. toctree::
:maxdepth: 2
:numbered:
- intro.rst
howitworks.rst
examples.rst
api.rst
diff --git a/docs/intro.rst b/docs/intro.rst
deleted file mode 100644
index cee463d..0000000
--- a/docs/intro.rst
+++ /dev/null
@@ -1,477 +0,0 @@
-.. default-domain:: py
-.. module:: natsort
-
-The :mod:`natsort` module
-=========================
-
-Simple yet flexible natural sorting in Python.
-
- - Source Code: https://github.com/SethMMorton/natsort
- - Downloads: https://pypi.org/project/natsort/
- - Documentation: https://natsort.readthedocs.io/
- - Optional Dependencies:
-
- - `fastnumbers <https://pypi.org/project/fastnumbers>`_ >= 2.0.0
- - `PyICU <https://pypi.org/project/PyICU>`_ >= 1.0.0
-
-**NOTE**: Please see the `Deprecation Schedule`_ section for changes in
-:mod:`natsort` version 6.0.0 and in the upcoming version 7.0.0.
-
-:mod:`natsort` is a general utility for sorting lists *naturally*; the
-definition of "naturally" is not well-defined, but the most common definition
-is that numbers contained within the string should be sorted as numbers and not
-as you would other characters. If you need to present sorted output to a user,
-you probably want to sort it naturally.
-
-:mod:`natsort` was initially created for sorting scientific output filenames that
-contained signed floating point numbers in the names. There was a lack of
-algorithms out there that could perform a natural sort on `floats` but
-plenty for `ints`; check out
-`this StackOverflow question <https://stackoverflow.com/q/4836710/1399279>`_
-and its answers and links therein,
-`this ActiveState forum <https://code.activestate.com/recipes/285264-natural-string-sorting/>`_,
-and of course `this great article on natural sorting <https://blog.codinghorror.com/sorting-for-humans-natural-sort-order/>`_
-from CodingHorror.com for examples of what I mean.
-:mod:`natsort` was created to fill in this gap, but has since expanded to
-handle just about any definition of a number, as well as other sorting
-customizations.
-
-Quick Description
------------------
-
-When you try to sort a list of strings that contain numbers, the normal python
-sort algorithm sorts lexicographically, so you might not get the results that you
-expect:
-
-.. code-block:: pycon
-
- >>> a = ['2 ft 7 in', '1 ft 5 in', '10 ft 2 in', '2 ft 11 in', '7 ft 6 in']
- >>> sorted(a)
- ['1 ft 5 in', '10 ft 2 in', '2 ft 11 in', '2 ft 7 in', '7 ft 6 in']
-
-Notice that it has the order ('1', '10', '2') - this is because the list is
-being sorted in lexicographical order, which sorts numbers like you would
-letters (i.e. 'b', 'ba', 'c').
-
-:mod:`natsort` provides a function :func:`~natsorted` that helps sort lists
-"naturally" ("naturally" is rather ill-defined, but in general it means
-sorting based on meaning and not computer code point)..
-Using :func:`~natsorted` is simple:
-
-.. code-block:: pycon
-
- >>> from natsort import natsorted
- >>> a = ['2 ft 7 in', '1 ft 5 in', '10 ft 2 in', '2 ft 11 in', '7 ft 6 in']
- >>> natsorted(a)
- ['1 ft 5 in', '2 ft 7 in', '2 ft 11 in', '7 ft 6 in', '10 ft 2 in']
-
-:func:`~natsorted` identifies numbers anywhere in a string and sorts them
-naturally. Below are some other things you can do with :mod:`natsort`
-(please see the :ref:`examples` for a quick start guide, or the :ref:`api`
-for more details).
-
-.. note::
-
- :func:`~natsorted` is designed to be a drop-in replacement for the built-in
- :func:`sorted` function. Like :func:`sorted`, :func:`~natsorted`
- `does not sort in-place`. To sort a list and assign the output to the
- same variable, you must explicitly assign the output to a variable:
-
- .. code-block:: pycon
-
- >>> a = ['2 ft 7 in', '1 ft 5 in', '10 ft 2 in', '2 ft 11 in', '7 ft 6 in']
- >>> natsorted(a)
- ['1 ft 5 in', '2 ft 7 in', '2 ft 11 in', '7 ft 6 in', '10 ft 2 in']
- >>> print(a) # 'a' was not sorted; "natsorted" simply returned a sorted list
- ['2 ft 7 in', '1 ft 5 in', '10 ft 2 in', '2 ft 11 in', '7 ft 6 in']
- >>> a = natsorted(a) # Now 'a' will be sorted because the sorted list was assigned to 'a'
- >>> print(a)
- ['1 ft 5 in', '2 ft 7 in', '2 ft 11 in', '7 ft 6 in', '10 ft 2 in']
-
- Please see `Generating a Reusable Sorting Key and Sorting In-Place`_ for
- an alternate way to sort in-place naturally.
-
-Examples
---------
-
-Sorting Versions
-++++++++++++++++
-
-:mod:`natsort` does not (and never has) actually *comprehend* version numbers.
-It just so happens that the most common versioning schemes are designed to
-work with standard natural sorting techniques; these schemes include
-``MAJOR.MINOR``, ``MAJOR.MINOR.PATCH``, ``YEAR.MONTH.DAY``. If your data
-conforms to a scheme like this, then it will work out-of-the-box with
-``natsorted`` (as of ``natsort`` version >= 4.0.0):
-
-.. code-block:: pycon
-
- >>> a = ['version-1.9', 'version-2.0', 'version-1.11', 'version-1.10']
- >>> natsorted(a)
- ['version-1.9', 'version-1.10', 'version-1.11', 'version-2.0']
-
-If you need to versions that use a more complicated scheme, please see
-:ref:`rc_sorting` for examples.
-
-Sorting by Real Numbers (i.e. Signed Floats)
-++++++++++++++++++++++++++++++++++++++++++++
-
-This is useful in scientific data analysis and was
-the default behavior of :func:`~natsorted` for :mod:`natsort`
-version < 4.0.0. Use the :func:`~realsorted` function:
-
-.. code-block:: pycon
-
- >>> from natsort import realsorted, ns
- >>> # Note that when interpreting as signed floats, the below numbers are
- >>> # +5.10, -3.00, +5.30, +2.00
- >>> a = ['position5.10.data', 'position-3.data', 'position5.3.data', 'position2.data']
- >>> natsorted(a)
- ['position2.data', 'position5.3.data', 'position5.10.data', 'position-3.data']
- >>> natsorted(a, alg=ns.REAL)
- ['position-3.data', 'position2.data', 'position5.10.data', 'position5.3.data']
- >>> realsorted(a) # shortcut for natsorted with alg=ns.REAL
- ['position-3.data', 'position2.data', 'position5.10.data', 'position5.3.data']
-
-Locale-Aware Sorting (or "Human Sorting")
-+++++++++++++++++++++++++++++++++++++++++
-
-This is where the non-numeric characters are ordered based on their meaning,
-not on their ordinal value, and a locale-dependent thousands separator and decimal
-separator is accounted for in the number.
-This can be achieved with the :func:`~humansorted` function:
-
-.. code-block:: pycon
-
- >>> a = ['Apple', 'apple15', 'Banana', 'apple14,689', 'banana']
- >>> natsorted(a)
- ['Apple', 'Banana', 'apple14,689', 'apple15', 'banana']
- >>> import locale
- >>> locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
- 'en_US.UTF-8'
- >>> natsorted(a, alg=ns.LOCALE)
- ['apple15', 'apple14,689', 'Apple', 'banana', 'Banana']
- >>> from natsort import humansorted
- >>> humansorted(a)
- ['apple15', 'apple14,689', 'Apple', 'banana', 'Banana']
-
-You may find you need to explicitly set the locale to get this to work
-(as shown in the example).
-Please see :ref:`locale_issues` and the Installation section
-below before using the :func:`~humansorted` function.
-
-Further Customizing Natsort
-+++++++++++++++++++++++++++
-
-If you need to combine multiple algorithm modifiers (such as ``ns.REAL``,
-``ns.LOCALE``, and ``ns.IGNORECASE``), you can combine the options using the
-bitwise OR operator (``|``). For example,
-
-.. code-block:: pycon
-
- >>> a = ['Apple', 'apple15', 'Banana', 'apple14,689', 'banana']
- >>> natsorted(a, alg=ns.REAL | ns.LOCALE | ns.IGNORECASE)
- ['Apple', 'apple15', 'apple14,689', 'Banana', 'banana']
- >>> # The ns enum provides long and short forms for each option.
- >>> ns.LOCALE == ns.L
- True
- >>> # You can also customize the convenience functions, too.
- >>> natsorted(a, alg=ns.REAL | ns.LOCALE | ns.IGNORECASE) == realsorted(a, alg=ns.L | ns.IC)
- True
- >>> natsorted(a, alg=ns.REAL | ns.LOCALE | ns.IGNORECASE) == humansorted(a, alg=ns.R | ns.IC)
- True
-
-All of the available customizations can be found in the documentation for
-the :class:`~natsort.ns` enum.
-
-You can also add your own custom transformation functions with the ``key``
-argument. These can be used with ``alg`` if you wish:
-
-.. code-block:: pycon
-
- >>> a = ['apple2.50', '2.3apple']
- >>> natsorted(a, key=lambda x: x.replace('apple', ''), alg=ns.REAL)
- ['2.3apple', 'apple2.50']
-
-Sorting Mixed Types
-+++++++++++++++++++
-
-You can mix and match ``int``, ``float``, and ``str`` (or ``unicode``) types
-when you sort:
-
-.. code-block:: pycon
-
- >>> a = ['4.5', 6, 2.0, '5', 'a']
- >>> natsorted(a)
- [2.0, '4.5', '5', 6, 'a']
- >>> # On Python 2, sorted(a) would return [2.0, 6, '4.5', '5', 'a']
- >>> # On Python 3, sorted(a) would raise an "unorderable types" TypeError
-
-Handling Bytes on Python 3
-++++++++++++++++++++++++++
-
-:mod:`natsort` does not officially support the `bytes` type on Python 3, but
-convenience functions are provided that help you decode to `str` first:
-
-.. code-block:: pycon
-
- >>> from natsort import as_utf8
- >>> a = [b'a', 14.0, 'b']
- >>> # On Python 2, natsorted(a) would would work as expected.
- >>> # On Python 3, natsorted(a) would raise a TypeError (bytes() < str())
- >>> natsorted(a, key=as_utf8) == [14.0, b'a', 'b']
- True
- >>> a = [b'a56', b'a5', b'a6', b'a40']
- >>> # On Python 2, natsorted(a) would would work as expected.
- >>> # On Python 3, natsorted(a) would return the same results as sorted(a)
- >>> natsorted(a, key=as_utf8) == [b'a5', b'a6', b'a40', b'a56']
- True
-
-Generating a Reusable Sorting Key and Sorting In-Place
-++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-Under the hood, :func:`~natsorted` works by generating a custom sorting
-key using :func:`~natsort_keygen` and then passes that to the built-in
-:func:`sorted`. You can use the :func:`~natsort_keygen` function yourself to
-generate a custom sorting key to sort in-place using the :meth:`list.sort`
-method.
-
-.. code-block:: pycon
-
- >>> from natsort import natsort_keygen
- >>> natsort_key = natsort_keygen()
- >>> a = ['2 ft 7 in', '1 ft 5 in', '10 ft 2 in', '2 ft 11 in', '7 ft 6 in']
- >>> natsorted(a) == sorted(a, key=natsort_key)
- True
- >>> a.sort(key=natsort_key)
- >>> a
- ['1 ft 5 in', '2 ft 7 in', '2 ft 11 in', '7 ft 6 in', '10 ft 2 in']
-
-All of the algorithm customizations mentioned in the
-`Further Customizing Natsort`_ section can also be applied to :func:`~natsort_keygen`
-through the *alg* keyword option.
-
-Other Useful Things
-+++++++++++++++++++
-
- - recursively descend into lists of lists
- - automatic unicode normalization of input data
- - controlling the case-sensitivity (see :ref:`case_sort`)
- - sorting file paths correctly (see :ref:`path_sort`)
- - allow custom sorting keys (see :ref:`custom_sort`)
-
-FAQ
----
-
-How do I debug :func:`~natsorted`?
- The best way to debug :func:`~natsorted` is to generate a key using :func:`~natsort_keygen`
- with the same options being passed to :func:`~natsorted`. One can take a
- look at exactly what is being done with their input using this key - it is
- highly recommended to `look at this issue describing how to debug <https://github.com/SethMMorton/natsort/issues/13#issuecomment-50422375>`_
- for *how* to debug, and also to review the :ref:`howitworks` page for *why*
- :mod:`natsort` is doing that to your data.
-
- If you are trying to sort custom classes and running into trouble, please
- take a look at https://github.com/SethMMorton/natsort/issues/60. In short,
- custom classes are not likely to be sorted correctly if one relies
- on the behavior of ``__lt__`` and the other rich comparison operators in
- their custom class - it is better to use a ``key`` function with
- :mod:`natsort`, or use the :mod:`natsort` key as part of your rich
- comparison operator definition.
-
-:mod:`natsort` gave me results I didn't expect, and it's a terrible library!
- Did you try to debug using the above advice? If so, and you still cannot figure out
- the error, then please `file an issue <https://github.com/SethMMorton/natsort/issues/new>`_.
-
-How *does* :mod:`natsort` work?
- If you don't want to read :ref:`howitworks`, here is a quick primer.
-
- :mod:`natsort` provides a :term:`key function` that can be passed to
- :meth:`list.sort` or :func:`sorted` in order to modify the default sorting
- behavior. This key is generated on-demand with the key generator
- :func:`natsort.natsort_keygen`. :func:`natsort.natsorted` is essentially a
- wrapper for the following code:
-
- .. code-block:: pycon
-
- >>> from natsort import natsort_keygen
- >>> natsort_key = natsort_keygen()
- >>> sorted(['1', '10', '2'], key=natsort_key)
- ['1', '2', '10']
-
- Users can further customize :mod:`natsort` sorting behavior with the ``key``
- and/or ``alg`` options (see details in the `Further Customizing Natsort`_
- section).
-
- The key generated by :func:`natsort.natsort_keygen` *always* returns a :class:`tuple`. It
- does so in the following way (*some details omitted for clarity*):
-
- 1. Assume the input is a string, and attempt to split it into numbers and
- non-numbers using regular expressions. Numbers are then converted into
- either :class:`int` or :class:`float`.
- 2. If the above fails because the input is not a string, assume the input
- is some other sequence (e.g. :class:`list` or :class:`tuple`), and recursively
- apply the key to each element of the sequence.
- 3. If the above fails because the input is not iterable, assume the input
- is an :class:`int` or :class:`float`, and just return the input in a :class:`tuple`.
-
- Because a :class:`tuple` is always returned, a :exc:`TypeError` should not be common
- unless one tries to do something odd like sort an :class:`int` against a :class:`list`.
-
-Shell script
-------------
-
-:mod:`natsort` comes with a shell script called :mod:`natsort`, or can also be
-called from the command line with ``python -m natsort``.
-
-Requirements
-------------
-
-:mod:`natsort` requires Python 3.4 or greater.
-
-Optional Dependencies
----------------------
-
-fastnumbers
-+++++++++++
-
-The most efficient sorting can occur if you install the
-`fastnumbers <https://pypi.org/project/fastnumbers>`_ package
-(version >=2.0.0); it helps with the string to number conversions.
-:mod:`natsort` will still run (efficiently) without the package, but if you
-need to squeeze out that extra juice it is recommended you include this as a
-dependency. :mod:`natsort` will not require (or check) that
-`fastnumbers <https://pypi.org/project/fastnumbers>`_ is installed
-at installation.
-
-PyICU
-+++++
-
-It is recommended that you install `PyICU <https://pypi.org/project/PyICU>`_
-if you wish to sort in a locale-dependent manner, see :ref:`locale_issues` for
-an explanation why.
-
-Installation
-------------
-
-Use ``pip``!
-
-.. code-block:: sh
-
- $ pip install natsort
-
-If you want to install the `Optional Dependencies`_, you can use the
-`"extras" notation <https://packaging.python.org/tutorials/installing-packages/#installing-setuptools-extras>`_
-at installation time to install those dependencies as well - use ``fast`` for
-`fastnumbers <https://pypi.org/project/fastnumbers>`_ and ``icu`` for
-`PyICU <https://pypi.org/project/PyICU>`_.
-
-.. code-block:: sh
-
- # Install both optional dependencies.
- $ pip install natsort[fast,icu]
- # Install just fastnumbers
- $ pip install natsort[fast]
-
-How to Run Tests
-----------------
-
-Please note that :mod:`natsort` is NOT set-up to support
-``python setup.py test``.
-
-The recommended way to run tests is with `tox <https://tox.readthedocs.io/en/latest/>`_.
-After installing ``tox``, running tests is as simple as executing the following
-in the ``natsort`` directory:
-
-.. code-block:: sh
-
- $ tox
-
-``tox`` will create virtual a virtual environment for your tests and install
-all the needed testing requirements for you. You can specify a particular
-python version with the ``-e`` flag, e.g. ``tox -e py36``. Static analysis is
-done with ``tox -e flake8``. You can see all available testing environments
-with ``tox --listenvs``.
-
-If you do not wish to use ``tox``, you can install the testing dependencies with the
-``dev/requirements.txt`` file and then run the tests manually using
-`pytest <https://docs.pytest.org/en/latest/>`_.
-
-.. code-block:: console
-
- $ pip install -r dev/requirements.txt
- $ python -m pytest
-
-Note that above I invoked ``python -m pytest`` instead of just ``pytest`` - this is because
-`the former puts the CWD on sys.path <https://docs.pytest.org/en/latest/usage.html#calling-pytest-through-python-m-pytest>`_.
-
-How to Build Documentation
---------------------------
-
-If you want to build the documentation for :mod:`natsort`, it is recommended to
-use ``tox``:
-
-.. code-block:: console
-
- $ tox -e docs
-
-This will place the documentation in ``build/sphinx/html``. If you do not
-which to use ``tox``, you can do the following:
-
-.. code-block:: console
-
- $ pip install sphinx sphinx_rtd_theme
- $ python setup.py build_sphinx
-
-Deprecation Schedule
---------------------
-
-Dropping Python 2.7 Support
-+++++++++++++++++++++++++++
-
-:mod:`natsort` version 7.0.0 drops support for Python 2.7.
-
-The version 6.X branch will remain as a "long term support" branch where bug
-fixes are applied so that users who cannot update from Python 2.7 will not be
-forced to use a buggy :mod:`natsort` version. Once version 7.0.0 is released,
-new features will not be added to version 6.X, only bug fixes.
-
-Deprecated APIs
-+++++++++++++++
-
-In :mod:`natsort` version 6.0.0, the following APIs and functions were removed
-
- - ``number_type`` keyword argument (deprecated since 3.4.0)
- - ``signed`` keyword argument (deprecated since 3.4.0)
- - ``exp`` keyword argument (deprecated since 3.4.0)
- - ``as_path`` keyword argument (deprecated since 3.4.0)
- - ``py3_safe`` keyword argument (deprecated since 3.4.0)
- - ``ns.TYPESAFE`` (deprecated since version 5.0.0)
- - ``ns.DIGIT`` (deprecated since version 5.0.0)
- - ``ns.VERSION`` (deprecated since version 5.0.0)
- - :func:`~natsort.versorted` (discouraged since version 4.0.0,
- officially deprecated since version 5.5.0)
- - :func:`~natsort.index_versorted` (discouraged since version 4.0.0,
- officially deprecated since version 5.5.0)
-
-In general, if you want to determine if you are using deprecated APIs you can
-run your code with the following flag
-
-.. code-block:: console
-
- $ python -Wdefault::DeprecationWarning my-code.py
-
-By default :exc:`DeprecationWarnings` are not shown, but this will cause them
-to be shown. Alternatively, you can just set the environment variable
-``PYTHONWARNINGS`` to "default::DeprecationWarning" and then run your code.
-
-Dropped Pipenv for Development
-++++++++++++++++++++++++++++++
-
-:mod:`natsort` version 6.0.0 no longer uses `Pipenv <https://pipenv.readthedocs.io/en/latest/>`_
-to install development dependencies.
-
-Dropped Python 2.6 and 3.3 Support
-++++++++++++++++++++++++++++++++++
-
-:mod:`natsort` version 6.0.0 dropped support for Python 2.6 and Python 3.3.
diff --git a/tox.ini b/tox.ini
index 274ab3d..764ebeb 100644
--- a/tox.ini
+++ b/tox.ini
@@ -24,7 +24,7 @@ extras =
commands =
# Doctests
{envpython} -m doctest -o IGNORE_EXCEPTION_DETAIL docs/howitworks.rst
- pytest README.rst docs/intro.rst docs/examples.rst
+ pytest README.rst docs/examples.rst
pytest --doctest-modules {envsitepackagesdir}/natsort
# Full test suite. Allow the user to pass command-line objects.
pytest --hypothesis-profile=slow-tests --tb=short --cov {envsitepackagesdir}/natsort --cov-report term-missing {posargs:}