Repository: Project-MONAI/MONAI

Issue:
Network alias is conflicting with the module names
**Describe the bug**
some network modules can't be imported, due to incorrect alias settings.

**To Reproduce**
```py
import monai.networks.nets.densenet as mod
print(type(mod))
```
The outcome is `<class 'type'>`.

**Expected behavior**
The outcome should be `<class 'module'>`, because `monai/networks/nets/densenet.py` is a file.

**Additional context**
for example https://github.com/Project-MONAI/MONAI/blob/ff083340c6aa674b43e36e6da42dcf7bef5c9bdd/monai/networks/nets/densenet.py#L393 the alias name `densenet` is conflicting with the file name `monai/networks/nets/densenet.py`.



Discussion:

Patch:
diff --git a/monai/losses/__init__.py b/monai/losses/__init__.py
--- a/monai/losses/__init__.py
+++ b/monai/losses/__init__.py
@@ -18,7 +18,6 @@
     GeneralizedDiceLoss,
     GeneralizedWassersteinDiceLoss,
     MaskedDiceLoss,
-    dice,
     dice_ce,
     dice_focal,
     generalized_dice,
diff --git a/monai/losses/dice.py b/monai/losses/dice.py
--- a/monai/losses/dice.py
+++ b/monai/losses/dice.py
@@ -819,7 +819,7 @@ def forward(self, input: torch.Tensor, target: torch.Tensor) -> torch.Tensor:
         return total_loss
 
 
-dice = Dice = DiceLoss
+Dice = DiceLoss
 dice_ce = DiceCELoss
 dice_focal = DiceFocalLoss
 generalized_dice = GeneralizedDiceLoss
diff --git a/monai/networks/blocks/convolutions.py b/monai/networks/blocks/convolutions.py
--- a/monai/networks/blocks/convolutions.py
+++ b/monai/networks/blocks/convolutions.py
@@ -18,7 +18,7 @@
 from monai.networks.blocks import ADN
 from monai.networks.layers.convutils import same_padding, stride_minus_kernel_padding
 from monai.networks.layers.factories import Conv
-from monai.utils.deprecated import deprecated_arg
+from monai.utils.deprecate_utils import deprecated_arg
 
 
 class Convolution(nn.Sequential):
diff --git a/monai/networks/nets/__init__.py b/monai/networks/nets/__init__.py
--- a/monai/networks/nets/__init__.py
+++ b/monai/networks/nets/__init__.py
@@ -9,7 +9,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from .ahnet import AHnet, Ahnet, AHNet, ahnet
+from .ahnet import AHnet, Ahnet, AHNet
 from .autoencoder import AutoEncoder
 from .basic_unet import BasicUNet, BasicUnet, Basicunet, basicunet
 from .classifier import Classifier, Critic, Discriminator
@@ -24,13 +24,12 @@
     Densenet201,
     DenseNet264,
     Densenet264,
-    densenet,
     densenet121,
     densenet169,
     densenet201,
     densenet264,
 )
-from .dynunet import DynUNet, DynUnet, Dynunet, dynunet
+from .dynunet import DynUNet, DynUnet, Dynunet
 from .efficientnet import (
     BlockArgs,
     EfficientNet,
@@ -80,7 +79,7 @@
 )
 from .torchvision_fc import TorchVisionFCModel, TorchVisionFullyConvModel
 from .transchex import BertAttention, BertMixedLayer, BertOutput, BertPreTrainedModel, MultiModal, Pooler, Transchex
-from .unet import UNet, Unet, unet
+from .unet import UNet, Unet
 from .unetr import UNETR
 from .varautoencoder import VarAutoEncoder
 from .vit import ViT
diff --git a/monai/networks/nets/ahnet.py b/monai/networks/nets/ahnet.py
--- a/monai/networks/nets/ahnet.py
+++ b/monai/networks/nets/ahnet.py
@@ -19,7 +19,7 @@
 from monai.networks.blocks.fcn import FCN
 from monai.networks.layers.factories import Act, Conv, Norm, Pool
 
-__all__ = ["AHnet", "Ahnet", "ahnet", "AHNet"]
+__all__ = ["AHnet", "Ahnet", "AHNet"]
 
 
 class Bottleneck3x3x1(nn.Module):
@@ -559,4 +559,4 @@ def copy_bn_param(module2d, module3d):
         p3d.data[:] = p2d.data[:]  # Two parameter gamma and beta
 
 
-AHnet = Ahnet = ahnet = AHNet
+AHnet = Ahnet = AHNet
diff --git a/monai/networks/nets/densenet.py b/monai/networks/nets/densenet.py
--- a/monai/networks/nets/densenet.py
+++ b/monai/networks/nets/densenet.py
@@ -23,7 +23,6 @@
 
 __all__ = [
     "DenseNet",
-    "densenet",
     "Densenet",
     "DenseNet121",
     "densenet121",
@@ -390,7 +389,7 @@ def __init__(
             raise NotImplementedError("Currently PyTorch Hub does not provide densenet264 pretrained models.")
 
 
-Densenet = densenet = DenseNet
+Densenet = DenseNet
 Densenet121 = densenet121 = DenseNet121
 Densenet169 = densenet169 = DenseNet169
 Densenet201 = densenet201 = DenseNet201
diff --git a/monai/networks/nets/dynunet.py b/monai/networks/nets/dynunet.py
--- a/monai/networks/nets/dynunet.py
+++ b/monai/networks/nets/dynunet.py
@@ -18,7 +18,7 @@
 
 from monai.networks.blocks.dynunet_block import UnetBasicBlock, UnetOutBlock, UnetResBlock, UnetUpBlock
 
-__all__ = ["DynUNet", "DynUnet", "Dynunet", "dynunet"]
+__all__ = ["DynUNet", "DynUnet", "Dynunet"]
 
 
 class DynUNetSkipLayer(nn.Module):
@@ -308,4 +308,4 @@ def initialize_weights(module):
                 module.bias = nn.init.constant_(module.bias, 0)
 
 
-DynUnet = Dynunet = dynunet = DynUNet
+DynUnet = Dynunet = DynUNet
diff --git a/monai/networks/nets/unet.py b/monai/networks/nets/unet.py
--- a/monai/networks/nets/unet.py
+++ b/monai/networks/nets/unet.py
@@ -20,7 +20,7 @@
 from monai.networks.layers.simplelayers import SkipConnection
 from monai.utils import alias, deprecated_arg, export
 
-__all__ = ["UNet", "Unet", "unet"]
+__all__ = ["UNet", "Unet"]
 
 
 @export("monai.networks.nets")
@@ -282,4 +282,4 @@ def forward(self, x: torch.Tensor) -> torch.Tensor:
         return x
 
 
-Unet = unet = UNet
+Unet = UNet
diff --git a/monai/networks/utils.py b/monai/networks/utils.py
--- a/monai/networks/utils.py
+++ b/monai/networks/utils.py
@@ -20,7 +20,7 @@
 import torch
 import torch.nn as nn
 
-from monai.utils.deprecated import deprecated_arg
+from monai.utils.deprecate_utils import deprecated_arg
 
 __all__ = [
     "one_hot",
diff --git a/monai/transforms/intensity/array.py b/monai/transforms/intensity/array.py
--- a/monai/transforms/intensity/array.py
+++ b/monai/transforms/intensity/array.py
@@ -39,7 +39,7 @@
     ensure_tuple_size,
     fall_back_tuple,
 )
-from monai.utils.deprecated import deprecated_arg
+from monai.utils.deprecate_utils import deprecated_arg
 from monai.utils.enums import TransformBackends
 from monai.utils.type_conversion import convert_to_tensor, get_equivalent_dtype
 
diff --git a/monai/transforms/intensity/dictionary.py b/monai/transforms/intensity/dictionary.py
--- a/monai/transforms/intensity/dictionary.py
+++ b/monai/transforms/intensity/dictionary.py
@@ -54,7 +54,7 @@
 from monai.transforms.transform import MapTransform, RandomizableTransform
 from monai.transforms.utils import is_positive
 from monai.utils import ensure_tuple, ensure_tuple_rep
-from monai.utils.deprecated import deprecated_arg
+from monai.utils.deprecate_utils import deprecated_arg
 
 __all__ = [
     "RandGaussianNoised",
diff --git a/monai/transforms/spatial/array.py b/monai/transforms/spatial/array.py
--- a/monai/transforms/spatial/array.py
+++ b/monai/transforms/spatial/array.py
@@ -47,7 +47,7 @@
     issequenceiterable,
     optional_import,
 )
-from monai.utils.deprecated import deprecated_arg
+from monai.utils.deprecate_utils import deprecated_arg
 from monai.utils.enums import TransformBackends
 from monai.utils.module import look_up_option
 from monai.utils.type_conversion import convert_data_type, convert_to_dst_type
diff --git a/monai/transforms/spatial/dictionary.py b/monai/transforms/spatial/dictionary.py
--- a/monai/transforms/spatial/dictionary.py
+++ b/monai/transforms/spatial/dictionary.py
@@ -59,7 +59,7 @@
     ensure_tuple_rep,
     fall_back_tuple,
 )
-from monai.utils.deprecated import deprecated_arg
+from monai.utils.deprecate_utils import deprecated_arg
 from monai.utils.enums import InverseKeys
 from monai.utils.module import optional_import
 from monai.utils.type_conversion import convert_data_type, convert_to_dst_type
diff --git a/monai/utils/__init__.py b/monai/utils/__init__.py
--- a/monai/utils/__init__.py
+++ b/monai/utils/__init__.py
@@ -12,7 +12,7 @@
 # have to explicitly bring these in here to resolve circular import issues
 from .aliases import alias, resolve_name
 from .decorators import MethodReplacer, RestartGenerator
-from .deprecated import DeprecatedError, deprecated, deprecated_arg
+from .deprecate_utils import DeprecatedError, deprecated, deprecated_arg
 from .dist import evenly_divisible_all_gather, get_dist_device, string_list_all_gather
 from .enums import (
     Average,
diff --git a/monai/utils/deprecated.py b/monai/utils/deprecate_utils.py
similarity index 100%
rename from monai/utils/deprecated.py
rename to monai/utils/deprecate_utils.py


Test patch:
diff --git a/tests/test_alias.py b/tests/test_alias.py
new file mode 100644
--- /dev/null
+++ b/tests/test_alias.py
@@ -0,0 +1,39 @@
+# Copyright 2020 - 2021 MONAI Consortium
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#     http://www.apache.org/licenses/LICENSE-2.0
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import glob
+import inspect
+import os
+import unittest
+
+from monai.utils import optional_import
+
+
+class TestModuleAlias(unittest.TestCase):
+    """check that 'import monai.xx.file_name' returns a module"""
+
+    def test_files(self):
+        src_dir = os.path.dirname(os.path.dirname(__file__))
+        monai_dir = os.path.join(src_dir, "monai")
+        py_files = glob.glob(os.path.join(monai_dir, "**", "*.py"), recursive=True)
+        for x in py_files:
+            if os.path.basename(x).startswith("_"):
+                continue
+            mod_name = x[len(src_dir) : -3]  # create relative path
+            mod_name = mod_name[1:].replace(mod_name[0], ".")
+            mod, cls = mod_name.rsplit(".", 1)
+            obj, exist = optional_import(mod, name=cls)
+            if exist:
+                self.assertTrue(inspect.ismodule(obj), msg=mod_name)
+
+
+if __name__ == "__main__":
+    unittest.main()