-
Notifications
You must be signed in to change notification settings - Fork 36
Open
Description
Description
It's impossible to use needle.autograd.Tensor as type hints for functions under needle.init.
For example executing import needle as ndl in jupyter notebook fails with following error: AttributeError: module 'needle' has no attribute 'Tensor' if init.py contains following function:
import needle as ndl
def rand(*shape, low=0.0, high=1.0, device=None, dtype="float32", requires_grad=False) -> ndl.Tensor:
""" Generate random numbers uniform between low and high """
device = ndl.cpu() if device is None else device
array = device.rand(*shape) * (high - low) + low
return ndl.Tensor(array, device=device, dtype=dtype, requires_grad=requires_grad)However, import needle as ndl works fine if there is no type hint for return value in init.py function:
import needle as ndl
def rand(*shape, low=0.0, high=1.0, device=None, dtype="float32", requires_grad=False):
""" Generate random numbers uniform between low and high """
device = ndl.cpu() if device is None else device
array = device.rand(*shape) * (high - low) + low
return ndl.Tensor(array, device=device, dtype=dtype, requires_grad=requires_grad)The reason is that:
__init__.pyimportsautograd.Tensorbeforeinitmodule:from .autograd import Tensor, cpu, all_devices from . import ops from .ops import * from . import init from . import data from . import nn from . import optim
- import of
autograd.Tensorleads to a subsequent import ofinitmodule becauseautograd.pycontains following line:by the way, relative import would be much clear in this case:from needle import init
from . import init. but that's not the issue - when
init.pyis imported byautograd.py, function signatures insideinit.pyare analyzed.
type hintdef rand(...) -> ndl.Tensorleads to an errorAttributeError: module 'needle' has no attribute 'Tensor'
because the process of importingautogradin not finished yet.
on import, only function signatures are analyzed. it allows to usendl.Tensorinside function body (as is right now). the reason, I guess, is when functions are executed, all imports (includingneedle.autograd.Tensor) are alredy resolved.
To wrap up, it is impossible to use ndl.Tensor as type hints in init.py because of the current order of imports:
__init__.py -> autograd.py -> init.py
Solution
Solution is to:
- change the order of imports in
__init.py__to importinitearlier thanautograd:from . import init from .autograd import Tensor, cpu, all_devices from . import ops from .ops import * from . import data from . import nn from . import optim
- and to replace "global" import in
init.pyto a relative one:
replacewithimport needle as ndl
from .autograd import Tensor, cpu
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels