From 76dae1075b15921aa1aaf2a4b91d78b569c28933 Mon Sep 17 00:00:00 2001 From: Hernan Grecco Date: Sun, 2 Apr 2017 00:59:22 -0300 Subject: [PATCH 1/4] Modified the contributing docs to reflect the new guidelines --- docs/contributing.rst | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/docs/contributing.rst b/docs/contributing.rst index f905fb3..c3cb6ca 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -5,23 +5,30 @@ Contributing to Pint You can contribute in different ways: + Report issues ------------- -You can report any issues with the package, the documentation to the Pint `issue tracker`_. Also feel free to submit feature requests, comments or questions. +You can report any issues with the package, the documentation to the Pint `issue tracker`_. +Also feel free to submit feature requests, comments or questions. Contribute code --------------- -To contribute fixes, code or documentation to Pint, send us a patch, or fork Pint in github_ and submit the changes using a pull request. +To contribute fixes, code or documentation to Pint, fork Pint in github_ and submit +the changes using a pull request against the **master** branch. -If you are contributing **documentation** or **bug fixes**, do it based on the **master** branch. +- If you are fixing a bug, add a test to test_issues.py + Also add "Close # as described in the `github docs`_. +- If you are submitting new code, add tests and documentation. -If you are contributing **new features** or code that changes the behaviour, do it based the **develop** branch. +Pint uses `bors-ng` as a merge bot and therefore every PR is tested before merging. In any case, feel free to use the `issue tracker`_ to discuss ideas for new features or improvements. .. _github: http://github.com/hgrecco/pint .. _`issue tracker`: https://github.com/hgrecco/pint/issues +.. _`bors-ng`: https://github.com/bors-ng/bors-ng +.. _`github docs`: https://help.github.com/articles/closing-issues-via-commit-messages/ \ No newline at end of file From dc26676a4bb532e97e965434c05c1e2eff3bd1b7 Mon Sep 17 00:00:00 2001 From: Hernan Grecco Date: Sun, 2 Apr 2017 01:00:53 -0300 Subject: [PATCH 2/4] Removed zappr, we are using bors-ng --- .zappr.yaml | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 .zappr.yaml diff --git a/.zappr.yaml b/.zappr.yaml deleted file mode 100644 index 0de7f9e..0000000 --- a/.zappr.yaml +++ /dev/null @@ -1,8 +0,0 @@ -approvals: - minimum: 1 - groups: - core: - minimum: 1 - from: - users: - - hgrecco From 6b838aa9a2fe921fdff44c2d6a18420737cd2165 Mon Sep 17 00:00:00 2001 From: Hernan Grecco Date: Sun, 2 Apr 2017 01:17:16 -0300 Subject: [PATCH 3/4] Add warning when a System contains an unknown Group The commit also add a test to make sure that the definition file included in Pint does not contain System with references to unknown Groups Close #472 --- pint/default_en.txt | 2 +- pint/systems.py | 7 +++++-- pint/testsuite/test_systems.py | 5 +++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/pint/default_en.txt b/pint/default_en.txt index 391febe..4035883 100644 --- a/pint/default_en.txt +++ b/pint/default_en.txt @@ -455,7 +455,7 @@ stere = meter ** 3 pound @end -@system US using USCSLiquidVolume, USCSDryVolume, USCSVolume, USCSLengthInternational, USCSLengthSurvey, AvoirdupoisUS +@system US using USCSLiquidVolume, USCSDryVolume, USCSVolumeOther, USCSLengthInternational, USCSLengthSurvey, AvoirdupoisUS yard pound @end diff --git a/pint/systems.py b/pint/systems.py index e74b6de..336f69b 100644 --- a/pint/systems.py +++ b/pint/systems.py @@ -15,7 +15,7 @@ import re from .definitions import Definition, UnitDefinition from .errors import DefinitionSyntaxError, RedefinitionError -from .util import to_units_container, SharedRegistryObject, SourceIterator +from .util import to_units_container, SharedRegistryObject, SourceIterator, logger from .babel_names import _babel_systems from pint.compat import Loc @@ -309,7 +309,10 @@ class _System(SharedRegistryObject): self._computed_members = set() for group_name in self._used_groups: - self._computed_members |= d[group_name].members + try: + self._computed_members |= d[group_name].members + except KeyError: + logger.warning('Could not resolve {0} in System {1}'.format(group_name, self.name)) self._computed_members = frozenset(self._computed_members) diff --git a/pint/testsuite/test_systems.py b/pint/testsuite/test_systems.py index 603c860..c868a77 100644 --- a/pint/testsuite/test_systems.py +++ b/pint/testsuite/test_systems.py @@ -340,3 +340,8 @@ class TestSystem(QuantityTestCase): c = ureg.get_base_units('kph', system=sysname) self.assertAlmostEqual(c[0], 0.6213, places=3) self.assertEqual(c[1], {'mph': 1}) + + def test_members_nowarning(self): + ureg = self.ureg + for name in dir(ureg.sys): + s = dir(getattr(ureg.sys, name)) \ No newline at end of file From c5bf1ab77e0b9b4d7768fc693e032f7c9f280c6f Mon Sep 17 00:00:00 2001 From: Hernan Grecco Date: Sun, 2 Apr 2017 01:55:07 -0300 Subject: [PATCH 4/4] Implemented a function decorator to ensure that a context is active Close #465 --- pint/registry.py | 29 ++++++++++++++++++++++++ pint/testsuite/test_contexts.py | 40 ++++++++++++++++++++++++++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/pint/registry.py b/pint/registry.py index 03782e4..de6c8d6 100644 --- a/pint/registry.py +++ b/pint/registry.py @@ -35,6 +35,7 @@ from __future__ import division, unicode_literals, print_function, absolute_impo import os import re import math +import functools import itertools import pkg_resources from decimal import Decimal @@ -1140,6 +1141,34 @@ class ContextRegistry(BaseRegistry): # the added contexts are removed from the active one. self.disable_contexts(len(names)) + def with_context(self, name, **kw): + """Decorator to wrap a function call in a Pint context. + + Use it to ensure that a certain context is active when + calling a function:: + + >>> @ureg.with_context('sp') + ... def my_cool_fun(wavelenght): + ... print('This wavelength is equivalent to: %s', wavelength.to('terahertz')) + + + :param names: name of the context. + :param kwargs: keyword arguments for the contexts. + :return: the wrapped function. + """ + def decorator(func): + assigned = tuple(attr for attr in functools.WRAPPER_ASSIGNMENTS if hasattr(func, attr)) + updated = tuple(attr for attr in functools.WRAPPER_UPDATES if hasattr(func, attr)) + + @functools.wraps(func, assigned=assigned, updated=updated) + def wrapper(*values, **kwargs): + with self.context(name, **kw): + return func(*values, **kwargs) + + return wrapper + + return decorator + def _convert(self, value, src, dst, inplace=False): """Convert value from some source to destination units. diff --git a/pint/testsuite/test_contexts.py b/pint/testsuite/test_contexts.py index cb54d55..46ecc9e 100644 --- a/pint/testsuite/test_contexts.py +++ b/pint/testsuite/test_contexts.py @@ -5,7 +5,7 @@ from __future__ import division, unicode_literals, print_function, absolute_impo import itertools from collections import defaultdict -from pint import UnitRegistry +from pint import UnitRegistry, errors from pint.context import Context from pint.util import UnitsContainer from pint.testsuite import QuantityTestCase @@ -619,3 +619,41 @@ class TestDefinedContexts(QuantityTestCase): for a, b in itertools.product(eq, eq): self.assertQuantityAlmostEqual(a.to(b.units, 'sp'), b, rtol=0.01) + + def test_decorator(self): + ureg = self.ureg + + a = 532. * ureg.nm + with ureg.context('sp'): + b = a.to('terahertz') + + def f(wl): + return wl.to('terahertz') + + self.assertRaises(errors.DimensionalityError, f, a) + + @ureg.with_context('sp') + def g(wl): + return wl.to('terahertz') + + self.assertEqual(b, g(a)) + + def test_decorator_composition(self): + ureg = self.ureg + + a = 532. * ureg.nm + with ureg.context('sp'): + b = a.to('terahertz') + + @ureg.with_context('sp') + @ureg.check('[length]') + def f(wl): + return wl.to('terahertz') + + @ureg.with_context('sp') + @ureg.check('[length]') + def g(wl): + return wl.to('terahertz') + + self.assertEqual(b, f(a)) + self.assertEqual(b, g(a)) \ No newline at end of file