Fix minor error in dynamic load function
State: closed

- [x] tests added / passed
- [x] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [ ] whatsnew entry

The `validate_docstrings.py` script dynamically loads modules/classes/functions from its command-line argument.

Currently, if the user supplies an invalid argument, an UnboundLocalError can be obtained:
```
Traceback (most recent call last):
...
File "./scripts/validate_docstrings.py", line 275, in _load_obj
    obj = getattr(obj, part)
UnboundLocalError: local variable 'obj' referenced before assignment
```

This PR fixes a check within the relevant function, so that a more informative error can be raised:
```
$ ./scripts/validate_docstrings.py tslibs.Timestamp
Traceback (most recent call last):
...
ImportError: No module can be imported from "tslibs.Timestamp"
```





Labels:
name: Error Reporting
description: Incorrect or improved errors from pandas
name: Code Style
description: Code style, linting, code_checks

Comments:
This is a minor fix to `Docstring._load_obj` in `validate_docstrings.py`, in order to avoid an UnboundLocalError.  As far as I know, that script doesn't have tests, so I was not planning to add tests or add a whatsnew entry.
@datapythonista , could you take a look at this PR?  It fixes a minor issue in `validate_docstrings.py` when the script argument is not valid. 
# [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/25256?src=pr&el=h1) Report
> Merging [#25256](https://codecov.io/gh/pandas-dev/pandas/pull/25256?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/5f73594d49ea06ada4c6779006c00aaf41935595?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/pandas-dev/pandas/pull/25256/graphs/tree.svg?width=650&token=eZ4WkYLtcO&height=150&src=pr)](https://codecov.io/gh/pandas-dev/pandas/pull/25256?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master   #25256   +/-   ##
=======================================
  Coverage   91.93%   91.93%           
=======================================
  Files         166      166           
  Lines       52187    52187           
=======================================
  Hits        47978    47978           
  Misses       4209     4209
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `90.48% <ø> (ø)` | :arrow_up: |
| #single | `42.14% <ø> (ø)` | :arrow_up: |


------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/25256?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/25256?src=pr&el=footer). Last update [5f73594...4b35573](https://codecov.io/gh/pandas-dev/pandas/pull/25256?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

# [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/25256?src=pr&el=h1) Report
> Merging [#25256](https://codecov.io/gh/pandas-dev/pandas/pull/25256?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/54492791116108199c24734a0220560974eb3372?src=pr&el=desc) will **increase** coverage by `<.01%`.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/pandas-dev/pandas/pull/25256/graphs/tree.svg?width=650&token=eZ4WkYLtcO&height=150&src=pr)](https://codecov.io/gh/pandas-dev/pandas/pull/25256?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master   #25256      +/-   ##
==========================================
+ Coverage   91.73%   91.74%   +<.01%     
==========================================
  Files         173      173              
  Lines       52845    52923      +78     
==========================================
+ Hits        48480    48554      +74     
- Misses       4365     4369       +4
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `90.31% <ø> (ø)` | :arrow_up: |
| #single | `41.73% <ø> (+0.01%)` | :arrow_up: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/25256?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/util/testing.py](https://codecov.io/gh/pandas-dev/pandas/pull/25256/diff?src=pr&el=tree#diff-cGFuZGFzL3V0aWwvdGVzdGluZy5weQ==) | `87.57% <0%> (-0.1%)` | :arrow_down: |
| [pandas/compat/\_\_init\_\_.py](https://codecov.io/gh/pandas-dev/pandas/pull/25256/diff?src=pr&el=tree#diff-cGFuZGFzL2NvbXBhdC9fX2luaXRfXy5weQ==) | `58.03% <0%> (-0.07%)` | :arrow_down: |
| [pandas/core/frame.py](https://codecov.io/gh/pandas-dev/pandas/pull/25256/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZnJhbWUucHk=) | `96.85% <0%> (-0.03%)` | :arrow_down: |
| [pandas/core/series.py](https://codecov.io/gh/pandas-dev/pandas/pull/25256/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvc2VyaWVzLnB5) | `93.68% <0%> (-0.02%)` | :arrow_down: |
| [pandas/core/algorithms.py](https://codecov.io/gh/pandas-dev/pandas/pull/25256/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvYWxnb3JpdGhtcy5weQ==) | `94.77% <0%> (-0.01%)` | :arrow_down: |
| [pandas/core/base.py](https://codecov.io/gh/pandas-dev/pandas/pull/25256/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvYmFzZS5weQ==) | `97.76% <0%> (ø)` | :arrow_up: |
| [pandas/core/indexes/category.py](https://codecov.io/gh/pandas-dev/pandas/pull/25256/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvaW5kZXhlcy9jYXRlZ29yeS5weQ==) | `98.61% <0%> (ø)` | :arrow_up: |
| [pandas/errors/\_\_init\_\_.py](https://codecov.io/gh/pandas-dev/pandas/pull/25256/diff?src=pr&el=tree#diff-cGFuZGFzL2Vycm9ycy9fX2luaXRfXy5weQ==) | `100% <0%> (ø)` | :arrow_up: |
| [pandas/core/indexes/base.py](https://codecov.io/gh/pandas-dev/pandas/pull/25256/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvaW5kZXhlcy9iYXNlLnB5) | `96.57% <0%> (+0.01%)` | :arrow_up: |
| [pandas/core/internals/concat.py](https://codecov.io/gh/pandas-dev/pandas/pull/25256/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvaW50ZXJuYWxzL2NvbmNhdC5weQ==) | `96.48% <0%> (+0.02%)` | :arrow_up: |
| ... and [3 more](https://codecov.io/gh/pandas-dev/pandas/pull/25256/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/25256?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/25256?src=pr&el=footer). Last update [5449279...1b1ee48](https://codecov.io/gh/pandas-dev/pandas/pull/25256?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

@nmusolino can you add a test for this?
Yes, I can add tests. More specifically, I can add one or two basic tests of the `Docstring` class defined in `validate_docstrings.py`
Hello @nmusolino! Thanks for updating the PR.





Cheers ! There are no PEP8 issues in this Pull Request. :beers: 

##### Comment last updated on February 28, 2019 at 03:10 Hours UTC
Added tests.  The specific test `TestDocstringClass::test_raises_for_invalid_module_name[panda.DataFrame]` (test_validate_docstrings.py:1013) would fail before this change (an UnboundLocalError was raised), but passes after this change (an ImportError is raised as expected).
@jreback, this is ready to be merged.
thanks, @datapythonista pls merge when satisifed.
@WillAyd Thanks for the cleanup commit.  This is ready to be merged.
thanks @nmusolino