Repository: optuna/optuna

Issue:
The doc of `optuna.integration.lightgbm.train` function cannot be generated if LightGBM isn't installed.
Due to the bug the title describes, [the current API reference doc](https://optuna.readthedocs.io/en/latest/) doesn't contain the entry of `optuna.integration.lightgbm.train` function.

# Expected behavior

The build of the function doc should be succeeded even if LightGBM isn't installed in the build environment.

## Error messages, stack traces, or logs

```console
$ cd optuna/docs
$ make html
...
WARNING: autodoc: failed to import function 'train' from module 'optuna.integration.lightgbm'; the following exception was raised:
Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/optuna/envs/latest/lib/python3.7/site-packages/sphinx/util/inspect.py", line 225, in safe_getattr
    return getattr(obj, name, *defargs)
AttributeError: module 'optuna.integration.lightgbm' has no attribute 'train'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/optuna/envs/latest/lib/python3.7/site-packages/sphinx/ext/autodoc/importer.py", line 193, in import_object
    obj = attrgetter(obj, attrname)
  File "/home/docs/checkouts/readthedocs.org/user_builds/optuna/envs/latest/lib/python3.7/site-packages/sphinx/ext/autodoc/__init__.py", line 290, in get_attr
    return autodoc_attrgetter(self.env.app, obj, name, *defargs)
  File "/home/docs/checkouts/readthedocs.org/user_builds/optuna/envs/latest/lib/python3.7/site-packages/sphinx/ext/autodoc/__init__.py", line 1563, in autodoc_attrgetter
    return safe_getattr(obj, name, *defargs)
  File "/home/docs/checkouts/readthedocs.org/user_builds/optuna/envs/latest/lib/python3.7/site-packages/sphinx/util/inspect.py", line 241, in safe_getattr
    raise AttributeError(name)
AttributeError: train
...
```

## Steps to reproduce

1. Ensure that LightGBM isn't installed in the built environment.
2. `$ git clone git://github.com/optuna/optuna.git`
3. `$ cd optuna/docs`
4. `$ make html`





Discussion:
I will take it.
Thanks! Please go for it.

Resolving patch:
diff --git a/optuna/integration/lightgbm.py b/optuna/integration/lightgbm.py
--- a/optuna/integration/lightgbm.py
+++ b/optuna/integration/lightgbm.py
@@ -2,6 +2,8 @@
 
 import optuna
 
+from optuna.integration import lightgbm_tuner as tuner
+
 try:
     import lightgbm as lgb  # NOQA
     _available = True
@@ -13,10 +15,7 @@
 
 # Attach lightgbm API.
 if _available:
-    # API from optuna integration.
-    from optuna.integration import lightgbm_tuner as tuner
-
-    # Workaround for mypy.
+    # To pass tests/integration_tests/lightgbm_tuner_tests/test_optimize.py.
     from lightgbm import Dataset  # NOQA
     from optuna.integration.lightgbm_tuner import LightGBMTuner  # NOQA
 
@@ -28,10 +27,12 @@
             continue
         setattr(sys.modules[__name__], api_name, lgb.__dict__[api_name])
 
+    # API from lightgbm_tuner.
     for api_name in _names_from_tuners:
         setattr(sys.modules[__name__], api_name, tuner.__dict__[api_name])
 else:
-    LightGBMTuner = object  # type: ignore
+    # To create docstring of train.
+    setattr(sys.modules[__name__], 'train', tuner.__dict__['train'])
 
 
 class LightGBMPruningCallback(object):
diff --git a/optuna/integration/lightgbm_tuner/__init__.py b/optuna/integration/lightgbm_tuner/__init__.py
--- a/optuna/integration/lightgbm_tuner/__init__.py
+++ b/optuna/integration/lightgbm_tuner/__init__.py
@@ -1,8 +1,20 @@
 from typing import Any
 
 from optuna._experimental import experimental
-from optuna.integration.lightgbm_tuner.sklearn import LGBMClassifier, LGBMModel, LGBMRegressor  # NOQA
-from optuna.integration.lightgbm_tuner.optimize import LightGBMTuner
+from optuna import type_checking
+
+try:
+    from optuna.integration.lightgbm_tuner.sklearn import LGBMClassifier, LGBMModel, LGBMRegressor  # NOQA
+    from optuna.integration.lightgbm_tuner.optimize import LightGBMTuner
+    _available = True
+except ImportError as e:
+    _import_error = e
+    # LightGBMTuner is disabled because LightGBM is not available.
+    _available = False
+
+
+if type_checking.TYPE_CHECKING:
+    from typing import Any  # NOQA
 
 
 @experimental("0.18.0")
@@ -13,7 +25,19 @@ def train(*args: Any, **kwargs: Any) -> Any:
     stepwise manner. Arguments and keyword arguments for `lightgbm.train()
     <https://lightgbm.readthedocs.io/en/latest/pythonapi/lightgbm.train.html>`_ can be passed.
     """
+    _check_lightgbm_availability()
 
     auto_booster = LightGBMTuner(*args, **kwargs)
     booster = auto_booster.run()
     return booster
+
+
+def _check_lightgbm_availability():
+    # type: () -> None
+
+    if not _available:
+        raise ImportError(
+            'LightGBM is not available. Please install LightGBM to use this feature. '
+            'LightGBM can be installed by executing `$ pip install lightgbm`. '
+            'For further information, please refer to the installation guide of LightGBM. '
+            '(The actual import error is as follows: ' + str(_import_error) + ')')
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -68,7 +68,6 @@ def get_extras_require():
             'scikit-learn>=0.19.0',
         ],
         'document': [
-            'lightgbm',
             'sphinx',
             'sphinx_rtd_theme',
         ],


Test patch: