Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split quantity (No __array_function__) #875

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ env:
- UNCERTAINTIES="N" PYTHON="3.5" NUMPY_VERSION=1.14 PANDAS=0
- UNCERTAINTIES="Y" PYTHON="3.5" NUMPY_VERSION=1.14 PANDAS=0
- UNCERTAINTIES="N" PYTHON="3.6" NUMPY_VERSION=1.14 PANDAS=0
# Test with the newer numpy versions
- UNCERTAINTIES="N" PYTHON="3.6" NUMPY_VERSION=1.17 PANDAS=0
- UNCERTAINTIES="N" PYTHON="3.6" NUMPY_VERSION=1.16 PANDAS=0


before_install:
- sudo apt-get update
Expand Down Expand Up @@ -51,6 +55,10 @@ before_install:
install:
- conda create --yes -n $ENV_NAME python=$PYTHON pip
- source activate $ENV_NAME
- if [[ "$NUMPY_VERSION" == 1.17 ]]; then
conda config --add channels conda-forge;
conda config --set channel_priority strict;
fi
- if [ $UNCERTAINTIES == 'Y' ]; then pip install 'uncertainties==2.4.7.1'; fi
- if [ $NUMPY_VERSION != '0' ]; then conda install --yes numpy==$NUMPY_VERSION; fi
- if [[ $TRAVIS_PYTHON_VERSION == '3.5' && $NUMPY_VERSION == 1.11.2 && $UNCERTAINTIES == "Y" ]]; then pip install babel serialize pyyaml; fi
Expand Down
5 changes: 4 additions & 1 deletion pint/compat/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ def u(x):
HAS_NUMPY = True
NUMPY_VER = np.__version__
NUMERIC_TYPES = (Number, Decimal, ndarray, np.number)

if "dev" in NUMPY_VER:
NUMPY_VER = NUMPY_VER[:NUMPY_VER.index("dev")-1]

def _to_magnitude(value, force_ndarray=False):
if isinstance(value, (dict, bool)) or value is None:
Expand Down Expand Up @@ -128,7 +131,7 @@ def _to_magnitude(value, force_ndarray=False):
import pandas as pd
HAS_PANDAS = True
# pin Pandas version for now
HAS_PROPER_PANDAS = pd.__version__.startswith("0.24.0.dev0+625.gbdb7a16")
HAS_PROPER_PANDAS = pd.__version__.startswith("0.25")
except ImportError:
HAS_PROPER_PANDAS = HAS_PANDAS = False

Expand Down
27 changes: 20 additions & 7 deletions pint/measurement.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
from .compat import ufloat
from .formatting import _FORMATS, siunitx_format_unit

from .quantity import BaseQuantity

MISSING = object()


class _Measurement(object):
class BaseMeasurement(object):
"""Implements a class to describe a quantity with uncertainty.

:param value: The most likely value of the measurement.
Expand All @@ -24,7 +26,8 @@ class _Measurement(object):
:type error: Quantity or Number
"""

def __new__(cls, value, error, units=MISSING):
@classmethod
def _new(cls, value, error, units=MISSING):
if units is MISSING:
try:
value, units = value.magnitude, value.units
Expand All @@ -47,8 +50,7 @@ def __new__(cls, value, error, units=MISSING):
raise ValueError('The magnitude of the error cannot be negative'.format(value, error))
else:
mag = ufloat(value,error)

inst = super(_Measurement, cls).__new__(cls, mag, units)
inst = super(BaseMeasurement, cls)._new(mag, units)
return inst

@property
Expand Down Expand Up @@ -136,10 +138,21 @@ def __init__(self, *args):
raise RuntimeError("Pint requires the 'uncertainties' package to create a Measurement object.")

else:
class Measurement(_Measurement, registry.Quantity):
pass

class Measurement(BaseMeasurement, registry.Quantity):
def __new__(cls, value, error, units=MISSING):
if hasattr(value, "__iter__"):
return MeasurementSequence._new(value, error, units)
else:
return MeasurementScalar._new(value, error, units)
Measurement._REGISTRY = registry
Measurement.force_ndarray = force_ndarray

class MeasurementScalar(Measurement):
def __new__(cls, value, error, units=MISSING):
inst = Measurement.__new__(Measurement, value, error, units)
return inst

class MeasurementSequence(Measurement):
def __new__(cls, value, error, units=MISSING):
inst = Measurement.__new__(Measurement, value, error, units)
return Measurement
Loading