Repository: mars-project/mars

Issue:
[BUG] ImportError: cannot import name 'elliprc' from 'mars.tensor.special.ellip_func_integrals' 
<!--
Thank you for your contribution!

Please review https://github.com/mars-project/mars/blob/master/CONTRIBUTING.rst before opening an issue.
-->

**Describe the bug**
A clear and concise description of what the bug is.

```python
Traceback:
/usr/local/python3/lib/python3.7/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
mars/tensor/special/tests/test_special.py:57: in <module>
    from ..ellip_func_integrals import (
E   ImportError: cannot import name 'elliprc' from 'mars.tensor.special.ellip_func_integrals' (/home/jenkins/agent/aci/mars/tensor/special/ellip_func_integrals.py)
```


```python
Traceback:
/usr/local/python3/lib/python3.7/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
mars/tensor/special/tests/test_special.py:18: in <module>
    from scipy.special import (
E   ImportError: cannot import name 'elliprd' from 'scipy.special' (/home/admin/py3/lib/python3.7/site-packages/scipy/special/__init__.py)
```

**To Reproduce**
To help us reproducing this bug, please provide information below:
1. Your Python version 3.7.7
2. The version of Mars you use Latest master
3. Versions of crucial packages, such as numpy, scipy and pandas `scipy==1.5.0`
4. Full stack of the error.
5. Minimized code to reproduce the error.

**Expected behavior**
A clear and concise description of what you expected to happen.

**Additional context**
Add any other context about the problem here.



Discussion:
@RandomY-2 do you have time to look at this issue?
Maybe try ... except ImportError ... needed. (Test code not needed though.)

Resolving patch:
diff --git a/mars/tensor/special/__init__.py b/mars/tensor/special/__init__.py
--- a/mars/tensor/special/__init__.py
+++ b/mars/tensor/special/__init__.py
@@ -151,3 +151,7 @@
     )
 except ImportError:  # pragma: no cover
     pass
+
+_names_to_del = [_name for _name, _val in globals().items() if _val is None]
+[globals().pop(_name) for _name in _names_to_del]
+del _names_to_del
diff --git a/mars/tensor/special/ellip_func_integrals.py b/mars/tensor/special/ellip_func_integrals.py
--- a/mars/tensor/special/ellip_func_integrals.py
+++ b/mars/tensor/special/ellip_func_integrals.py
@@ -154,4 +154,4 @@ def elliprj(x, y, z, p, **kwargs):
 except AttributeError:
     # These functions are not implemented before scipy v1.8 so
     # spsecial.func may cause AttributeError
-    pass
+    elliprc = elliprd = elliprf = elliprg = elliprj = None


Test patch:
diff --git a/mars/tensor/special/tests/test_special.py b/mars/tensor/special/tests/test_special.py
--- a/mars/tensor/special/tests/test_special.py
+++ b/mars/tensor/special/tests/test_special.py
@@ -28,11 +28,6 @@
     ellipkinc as scipy_ellipkinc,
     ellipe as scipy_ellipe,
     ellipeinc as scipy_ellipeinc,
-    elliprc as scipy_elliprc,
-    elliprd as scipy_elliprd,
-    elliprf as scipy_elliprf,
-    elliprg as scipy_elliprg,
-    elliprj as scipy_elliprj,
     betainc as scipy_betainc,
 )
 
@@ -70,16 +65,6 @@
     TensorEllipe,
     ellipeinc,
     TensorEllipeinc,
-    elliprc,
-    TensorElliprc,
-    elliprd,
-    TensorElliprd,
-    elliprf,
-    TensorElliprf,
-    elliprg,
-    TensorElliprg,
-    elliprj,
-    TensorElliprj,
 )
 
 
@@ -432,6 +417,9 @@ def test_ellipeinc():
     reason="function not implemented in scipy.",
 )
 def test_elliprc():
+    from scipy.special import elliprc as scipy_elliprc
+    from ..ellip_func_integrals import elliprc, TensorElliprc
+
     raw1 = np.random.rand(4, 3, 2)
     raw2 = np.random.rand(4, 3, 2)
     a = tensor(raw1, chunk_size=3)
@@ -457,6 +445,9 @@ def test_elliprc():
     reason="function not implemented in scipy.",
 )
 def test_elliprd():
+    from scipy.special import elliprd as scipy_elliprd
+    from ..ellip_func_integrals import elliprd, TensorElliprd
+
     raw1 = np.random.rand(4, 3, 2)
     raw2 = np.random.rand(4, 3, 2)
     raw3 = np.random.rand(4, 3, 2)
@@ -484,6 +475,9 @@ def test_elliprd():
     reason="function not implemented in scipy.",
 )
 def test_elliprf():
+    from scipy.special import elliprf as scipy_elliprf
+    from ..ellip_func_integrals import elliprf, TensorElliprf
+
     raw1 = np.random.rand(4, 3, 2)
     raw2 = np.random.rand(4, 3, 2)
     raw3 = np.random.rand(4, 3, 2)
@@ -511,6 +505,9 @@ def test_elliprf():
     reason="function not implemented in scipy.",
 )
 def test_elliprg():
+    from scipy.special import elliprg as scipy_elliprg
+    from ..ellip_func_integrals import elliprg, TensorElliprg
+
     raw1 = np.random.rand(4, 3, 2)
     raw2 = np.random.rand(4, 3, 2)
     raw3 = np.random.rand(4, 3, 2)
@@ -538,6 +535,9 @@ def test_elliprg():
     reason="function not implemented in scipy.",
 )
 def test_elliprj():
+    from scipy.special import elliprj as scipy_elliprj
+    from ..ellip_func_integrals import elliprj, TensorElliprj
+
     raw1 = np.random.rand(4, 3, 2)
     raw2 = np.random.rand(4, 3, 2)
     raw3 = np.random.rand(4, 3, 2)