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

Testing types and shapes across modules fails #629

Closed
rebcabin opened this issue Apr 10, 2018 · 5 comments
Closed

Testing types and shapes across modules fails #629

rebcabin opened this issue Apr 10, 2018 · 5 comments

Comments

@rebcabin
Copy link

rebcabin commented Apr 10, 2018

If I create a units.Quantity in one module and test its type in another module, I get failures (see this test in a fork of pint). This failure makes it more difficult to write polymorphic library code that can handle values with and without units.

I can work around this non-robustly by testing a string representation of the type.

If I create a heterogeneous list of units.Quantity in one module and test its numpy.shape in another module, I get exceptions raised in numpy. (see this test in the same fork)

This is more serious and no quick work-around is obvious.

It's possible that these failures simply reflect my misunderstandings of the depths of import and of numpy types and are not defects in pint in any way. However, the things I want to do (create stuff in one module and test it in another module) seem intuitively reasonable and I was surprised by the failures.

EDIT: I added another repo that does cross-module type checking without the errors I see from pint.

@hgrecco
Copy link
Owner

hgrecco commented Apr 10, 2018

Hi! there seems to be several different questions here.

The way to check if a variables is an instance of Quantities, the way to do it is:

>>> ureg = pint.UnitRegistry()
>>> isinstance(x, ureg.Quantity)

Regarding heterogenous list of Quantitities, that is not a problem. What you cannot do is a heterogenous numpy array quantity. i.e. numpy arrays can be the magnitude of a quantity and therefore all elements have the same units

Regarding creating code that can handle values with and without units, you can use wraps with strict=False

Finally, if you want to use pint in different projects we are trying to create a better solution for that (see #623)

@rebcabin
Copy link
Author

This is very helpful. I will refactor my application code and come back to close the issue or ask more questions as things go.

@rebcabin
Copy link
Author

Ok, I changed my code to use the recommended isinstance and I am still getting failures. The called code is

def is_pint_quantity(some_object):
    inspect_in_debugger = isinstance(some_object, units.Quantity)
    return isinstance(some_object, units.Quantity)

in this fork of Pint's test folder. I created a temporary variable called inspect_in_debugger so that one can see the value about to be returned. Indeed it's false when called across modules.

The calling code is

def test_type_other_module():
    """If I have a quantity foo and want to test its type in another module (
    say a target module for the tests I'm writing here), I can't test it by
    the normal method, the test inexplicably fails. Perhaps the reason is that
    types imported into this module are different in an invisible way from
    the same types imported into the other module. If that's the case,
    I need some way to test the types of Pint quantities inside and outside
    collections."""
    foo = units.Quantity(42, 'm/s')
    assert is_pint_quantity(foo)

in this file.

It fails with the following messages:

pint/testsuite/test_type_transfer.py:14 (test_type_other_module)
def test_type_other_module():
        """If I have a quantity foo and want to test its type in another module (
        say a target module for the tests I'm writing here), I can't test it by
        the normal method, the test inexplicably fails. Perhaps the reason is that
        types imported into this module are different in an invisible way from
        the same types imported into the other module. If that's the case,
        I need some way to test the types of Pint quantities inside and outside
        collections."""
        foo = units.Quantity(42, 'm/s')
>       assert is_pint_quantity(foo)
E       AssertionError: assert False
E        +  where False = is_pint_quantity(<Quantity(42, 'meter / second')>)

testsuite/test_type_transfer.py:24: AssertionError

I'll be grateful for any advice.

@rebcabin
Copy link
Author

I'm going to try a 'duck typing' technique as that seems to be the preferred method in Python for dispatching on types. Still, I am curious why type signatures would change across modules.

@rebcabin
Copy link
Author

This turned out to be my misunderstanding: testing the quantities created against one Registry against the units type from another Registry.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants