Skip to content

Commit

Permalink
Merge #1116
Browse files Browse the repository at this point in the history
1116: Harmonize most doctests with Pint's current behavior r=hgrecco a=clarkgwillison

- [ ] Closes # (no single issue)
- [x] Executed ``black -t py36 . && isort -rc . && flake8`` with no errors
- [x] The change is fully covered by automated unit tests
- [x] Documented in docs/ as appropriate
- [x] Added an entry to the CHANGES file

This PR partially addresses #947, #972, and #990 

After merging, the number of failing doctests in the Sphinx documentation should go from 92 (as mentioned in #947) down to 3:
```
Doctest summary
===============
  335 tests
    3 failures in tests
    0 failures in setup code
    0 failures in cleanup code
build finished with problems.
make: *** [doctest] Error 1
```
Which will put us well in reach of enabling doctests in Travis to prevent documentation regressions in the future.

Most tests were fixed in this PR by deferring to the current behavior of Pint, however `Quantity.__repr__()` was modified to round floating point magnitudes to 9 digits to avoid several test failures that were being caused by floating point ambiguities.

Issue #1115 was opened to track the 3 tests that I could not easily resolve. Once that issue is resolved, we can enable doctests in Travis without breaking CI.

Co-authored-by: Clark Willison <clarkgwillison@gmail.com>
  • Loading branch information
bors[bot] and clarkgwillison authored Jun 17, 2020
2 parents f8ec2ca + 8e1f1c2 commit 4959f0f
Show file tree
Hide file tree
Showing 18 changed files with 235 additions and 146 deletions.
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Pint Changelog
- Fixed crash when some specific combinations of contexts were enabled
(Issue #1112, Thanks Guido Imperiale)
- Added support for checking prefixed units using `in` keyword (Issue #1086)
- Updated many examples in the documentation to reflect Pint's current behavior


0.12 (2020-05-29)
Expand Down
28 changes: 21 additions & 7 deletions docs/contexts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,15 @@ Contexts can be also enabled for blocks of code using the `with` statement:
<Quantity(5.99584916e+14, 'hertz')>

If you need a particular context in all your code, you can enable it for all
operations with the registry::
operations with the registry

.. doctest::

>>> ureg.enable_contexts('sp')

To disable the context, just call::
To disable the context, just call

.. doctest::

>>> ureg.disable_contexts()

Expand All @@ -69,17 +73,23 @@ Enabling multiple contexts

You can enable multiple contexts:

.. doctest::

>>> q.to('Hz', 'sp', 'boltzmann')
<Quantity(5.99584916e+14, 'hertz')>

This works also using the `with` statement:

.. doctest::

>>> with ureg.context('sp', 'boltzmann'):
... q.to('Hz')
<Quantity(5.99584916e+14, 'hertz')>

or in the registry:

.. doctest::

>>> ureg.enable_contexts('sp', 'boltzmann')
>>> q.to('Hz')
<Quantity(5.99584916e+14, 'hertz')>
Expand All @@ -88,6 +98,8 @@ If a conversion rule between two dimensions appears in more than one context,
the one in the last context has precedence. This is easy to remember if you
think that the previous syntax is equivalent to nest contexts:

.. doctest::

>>> with ureg.context('sp'):
... with ureg.context('boltzmann') :
... q.to('Hz')
Expand All @@ -106,7 +118,7 @@ calculate, for example, the wavelength in water of a laser which on air is 530 n
>>> wl = 530. * ureg.nm
>>> f = wl.to('Hz', 'sp')
>>> f.to('nm', 'sp', n=1.33)
<Quantity(398.496240602, 'nanometer')>
<Quantity(398.4962..., 'nanometer')>

Contexts can also accept Pint Quantity objects as parameters. For example, the
'chemistry' context accepts the molecular weight of a substance (as a Quantity
Expand Down Expand Up @@ -135,7 +147,7 @@ context and the parameters that you wish to set.
... def f(wl):
... return wl.to('Hz').magnitude
>>> f(wl)
398.496240602
425297855014895.6


This decorator can be combined with **wraps** or **check** decorators described in
Expand Down Expand Up @@ -194,14 +206,16 @@ functions. For example:
... lambda ureg, x: x * ureg.speed_of_light)
>>> ureg.add_context(c)
>>> ureg("1 s").to("km", "ab")
299792.458 kilometer
<Quantity(299792.458, 'kilometer')>

It is also possible to create anonymous contexts without invoking add_context:

.. doctest::

>>> c = pint.Context()
...
>>> c.add_transformation('[time]', '[length]', lambda ureg, x: x * ureg.speed_of_light)
>>> ureg("1 s").to("km", c)
299792.458 kilometer
<Quantity(299792.458, 'kilometer')>

Using contexts for unit redefinition
------------------------------------
Expand Down
32 changes: 32 additions & 0 deletions docs/contributing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,38 @@ Pint uses `bors-ng` as a merge bot and therefore every PR is tested before mergi
In any case, feel free to use the `issue tracker`_ to discuss ideas for new features or improvements.


Setting up your environment
---------------------------

If you're contributing to this project for the fist time, you can set up your
environment on Linux or OSX with the following commands::

$ git clone git@github.com:hgrecco/pint.git
$ cd pint
$ python -m virtualenv venv
$ source venv/bin/activate
$ pip install -e .
$ pip install -r requirements_docs.txt

Running tests and building documentation
----------------------------------------

To run the test suite, invoke pytest from the ``pint`` directory::

$ cd pint
$ pytest

To run the doctests, invoke Sphinx's doctest module from the ``docs`` directory::

$ cd docs
$ make doctest

To build the documentation, invoke Sphinx from the ``docs`` directory::

$ cd docs
$ make html


.. _github: http://github.com/hgrecco/pint
.. _`issue tracker`: https://github.com/hgrecco/pint/issues
.. _`bors-ng`: https://github.com/bors-ng/bors-ng
Expand Down
4 changes: 2 additions & 2 deletions docs/defining.rst
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ Let's add a dog_year (sometimes written as dy) equivalent to 52 (human) days:
# We create a quantity based on that unit and we convert to years.
>>> lassie_lifespan = Q_(10, 'year')
>>> print(lassie_lifespan.to('dog_years'))
70.23888438100961 dog_year
70.240384... dog_year

Note that we have used the name `dog_years` even though we have not defined the
plural form as an alias. Pint takes care of that, so you don't have to.
Expand All @@ -132,7 +132,7 @@ Same for aliases and derived dimensions:
.. doctest::

>>> ureg.define('@alias meter = metro = metr')
>>> ureg.define('[hypervolume] = [length ** 4]')
>>> ureg.define('[hypervolume] = [length] ** 4')


.. warning::
Expand Down
2 changes: 1 addition & 1 deletion docs/developers_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,4 @@ Pint
:members:

.. automodule:: pint.testsuite.test_util
:members:
:members:
10 changes: 6 additions & 4 deletions docs/getting.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ You can install it (or upgrade to the latest version) using pip_::

That's all! You can check that Pint is correctly installed by starting up python, and importing pint:

.. testcode::
.. code-block::
>>> import pint # doctest: +SKIP
>>> pint.__version__ # doctest: +SKIP
>>> import pint
>>> pint.__version__
.. note:: If you have an old system installation of Python and you don't want to
mess with it, you can try `Anaconda CE`_. It is a free Python distribution by
Expand All @@ -25,7 +25,9 @@ That's all! You can check that Pint is correctly installed by starting up python

You can check the installation with the following command:

>>> pint.test() # doctest: +SKIP
.. code-block::
>>> pint.test()
On Arch Linux, you can alternatively install Pint from the Arch User Repository
Expand Down
2 changes: 1 addition & 1 deletion docs/measurement.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Mathematical operations with Measurements, return new measurements following the
.. doctest::

>>> print(2 * book_length)
(40.0 +/- 4.0) centimeter
(40 +/- 4) centimeter
>>> width = (10 * ureg.centimeter).plus_minus(1)
>>> print('{:.02f}'.format(book_length + width))
(30.00 +/- 2.24) centimeter
Expand Down
62 changes: 30 additions & 32 deletions docs/nonmult.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,24 @@ kelvin and rankine abbreviated as degF, degC, degK, and degR.

For example, to convert from celsius to fahrenheit:

.. testsetup::

from pint import UnitRegistry
ureg = UnitRegistry()
ureg.default_format = '.3f'
Q_ = ureg.Quantity

.. doctest::

>>> from pint import UnitRegistry
>>> ureg = UnitRegistry()
>>> Q_ = ureg.Quantity
>>> home = Q_(25.4, ureg.degC)
>>> print(home.to('degF'))
77.7200004 degF
>>> from pint import UnitRegistry
>>> ureg = UnitRegistry()
>>> ureg.default_format = '.3f'
>>> Q_ = ureg.Quantity
>>> home = Q_(25.4, ureg.degC)
>>> print(home.to('degF'))
77.720 degree_Fahrenheit

or to other kelvin or rankine:

.. doctest::

>>> print(home.to('kelvin'))
298.55 kelvin
298.550 kelvin
>>> print(home.to('degR'))
537.39 degR
537.390 degree_Rankine

Additionally, for every non-multiplicative temperature unit
in the registry, there is also a *delta* counterpart to specify
Expand All @@ -48,28 +42,28 @@ is different).

.. doctest::

>>> increase = 12.3 * ureg.delta_degC
>>> print(increase.to(ureg.kelvin))
12.3 kelvin
>>> print(increase.to(ureg.delta_degF))
22.14 delta_degF
>>> increase = 12.3 * ureg.delta_degC
>>> print(increase.to(ureg.kelvin))
12.300 kelvin
>>> print(increase.to(ureg.delta_degF))
22.140 delta_degree_Fahrenheit

Subtraction of two temperatures given in offset units yields a *delta* unit:

.. doctest::

>>> Q_(25.4, ureg.degC) - Q_(10., ureg.degC)
<Quantity(15.4, 'delta_degC')>
<Quantity(15.4, 'delta_degree_Celsius')>

You can add or subtract a quantity with *delta* unit and a quantity with
offset unit:

.. doctest::

>>> Q_(25.4, ureg.degC) + Q_(10., ureg.delta_degC)
<Quantity(35.4, 'degC')>
<Quantity(35.4, 'degree_Celsius')>
>>> Q_(25.4, ureg.degC) - Q_(10., ureg.delta_degC)
<Quantity(15.4, 'degC')>
<Quantity(15.4, 'degree_Celsius')>

If you want to add a quantity with absolute unit to one with offset unit, like here

Expand All @@ -94,7 +88,7 @@ or convert the absolute unit to a *delta* unit:
.. doctest::

>>> Q_(10., ureg.degC) + heating_rate.to('delta_degC/min') * Q_(30, ureg.min)
<Quantity(25.0, 'degC')>
<Quantity(25.0, 'degree_Celsius')>

In contrast to subtraction, the addition of quantities with offset units
is ambiguous, e.g. for *10 degC + 100 degC* two different result are reasonable
Expand All @@ -108,7 +102,7 @@ Quantities with *delta* units are multiplicative:

>>> speed = 60. * ureg.delta_degC / ureg.min
>>> print(speed.to('delta_degC/second'))
1.0 delta_degC / second
1.000 delta_degree_Celsius / second

However, multiplication, division and exponentiation of quantities with
offset units is problematic just like addition. Pint (since version 0.6)
Expand All @@ -125,7 +119,7 @@ to be explicitly created:
...
OffsetUnitCalculusError: Ambiguous operation with offset unit (degC).
>>> Q_(25.4, ureg.degC)
<Quantity(25.4, 'degC')>
<Quantity(25.4, 'degree_Celsius')>

As an alternative to raising an error, pint can be configured to work more
relaxed via setting the UnitRegistry parameter *autoconvert_offset_to_baseunit*
Expand All @@ -139,20 +133,24 @@ to true. In this mode, pint behaves differently:
>>> ureg = UnitRegistry(autoconvert_offset_to_baseunit = True)
>>> T = 25.4 * ureg.degC
>>> T
<Quantity(25.4, 'degC')>
<Quantity(25.4, 'degree_Celsius')>

* Before all other multiplications, all divisions and in case of
exponentiation [#f1]_ involving quantities with offset-units, pint
will convert the quantities with offset units automatically to the
corresponding base unit before performing the operation.

.. doctest::

>>> 1/T
<Quantity(0.00334952269302, '1 / kelvin')>
<Quantity(0.0033495..., '1 / kelvin')>
>>> T * 10 * ureg.meter
<Quantity(527.15, 'kelvin * meter')>

You can change the behaviour at any time:

.. doctest::

>>> ureg.autoconvert_offset_to_baseunit = False
>>> 1/T
Traceback (most recent call last):
Expand All @@ -165,28 +163,28 @@ is found in a multiplicative context. For example, here:
.. doctest::

>>> print(ureg.parse_units('degC/meter'))
delta_degC / meter
delta_degree_Celsius / meter

but not here:

.. doctest::

>>> print(ureg.parse_units('degC'))
degC
degree_Celsius

You can override this behaviour:

.. doctest::

>>> print(ureg.parse_units('degC/meter', as_delta=False))
degC / meter
degree_Celsius / meter

Note that the magnitude is left unchanged:

.. doctest::

>>> Q_(10, 'degC/meter')
<Quantity(10, 'delta_degC / meter')>
<Quantity(10, 'delta_degree_Celsius / meter')>

To define a new temperature, you need to specify the offset. For example,
this is the definition of the celsius and fahrenheit::
Expand Down
2 changes: 1 addition & 1 deletion docs/pitheorem.rst
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ There are 3 fundamental physical units in this equation: time, mass, and length,
... 'M': '[mass]',
... 'L': '[length]',
... 'g': '[acceleration]'})
[{'T': 2.0, 'g': 1.0, 'L': -1.0}]
[{'T': 2.0, 'L': -1.0, 'g': 1.0}]

which means that the dimensionless quantity is:

Expand Down
Loading

0 comments on commit 4959f0f

Please sign in to comment.