Insert custom units into top level namespace

I have a module in my project where I define a few custom units. How can i add these units so they are accessible like any of the other built-in units, like u.meter?

For example, if I have my units defined like this:


import astropy.units as u

foobar = def_unit('foobar')

I want to be able to access built-in units like this:

from myproj.units import u

x = np.array((1, 2, 3)) * u.meter
y = np.array((1, 2, 3)) * u.foobar

The pint library does this automatically with it’s u.define function. I would like to replicate this with astropy.

Would adding them with u.add_enabled_units([foobar]) etc. as described in
satisfy your needs, or are you trying to create a complete wrapper around astropy’s units that already has all your custom units enabled?

The latter. I would prefer to not have any distinction when accessing custom created units vs the built-in ones.

In my package with custom unit, I basically have user import from the units module in my package. So, not completely transparent, but once the quantity is defined, it works just like any other quantity. Perhaps not the answer you are looking for but I am not aware of a better way (would be interested if there is one).

The only thing I can think to do is create a units module in my package and import all astropy units there, as @pllim said.


from astropy.units import *

my_unit = def_unit('my_unit')

And then the units can be accessed the same way

from foobar import units

x = 1 * units.m
y = 1 * units.my_unit

But are they all available under your units this way? Wouldn’t they need to be added to __all__ similar to synphot.units — synphot v1.2.1.dev3+g11db7cf ?
Wondering if something like

__all__ = ['my_unit', 'foobar'] + dir(astropy.units)

would work then.

It seems to work fine.

It still would be nice to have Pint-like behavior for def_unit, though.