CLN: Using clearer imports
State: closed

- [ ] closes #xxxx
- [ ] tests added / passed
- [ ] passes `black pandas`
- [ ] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [ ] whatsnew entry


Labels:
name: Clean

Comments:
@MomIsBestFriend in tests.tseries.offsets.test_offset_properties there are a couple of xfailed tests that would be really nice to get fixed.  any interest?
> @MomIsBestFriend in tests.tseries.offsets.test_offset_properties there are a couple of xfailed tests that would be really nice to get fixed. any interest?

@jbrockmendel Sure! will open a PR soon
the most common usage of datetime import in the codebase  is ` from datetime import ...`

```
grep -r "from datetime import" --include=\*.{py,pyx}
asv_bench/benchmarks/series_methods.py:from datetime import datetime
asv_bench/benchmarks/timeseries.py:from datetime import timedelta
asv_bench/benchmarks/tslibs/offsets.py:from datetime import datetime
doc/source/conf.py:from datetime import datetime
pandas/conftest.py:from datetime import date, time, timedelta, timezone
pandas/core/arrays/datetimelike.py:from datetime import datetime, timedelta
pandas/core/arrays/datetimes.py:from datetime import datetime, time, timedelta
pandas/core/arrays/period.py:from datetime import timedelta
pandas/core/arrays/timedeltas.py:from datetime import timedelta
pandas/core/common.py:from datetime import datetime, timedelta
pandas/core/computation/ops.py:from datetime import datetime
pandas/core/dtypes/cast.py:from datetime import date, datetime, timedelta
pandas/core/dtypes/common.py:    >>> from datetime import datetime
pandas/core/generic.py:from datetime import timedelta
pandas/core/indexes/base.py:from datetime import datetime
pandas/core/indexes/datetimelike.py:from datetime import datetime
pandas/core/indexes/datetimes.py:from datetime import date, datetime, time, timedelta, tzinfo
pandas/core/indexes/period.py:from datetime import datetime, timedelta
pandas/core/indexes/range.py:from datetime import timedelta
pandas/core/internals/blocks.py:from datetime import datetime, timedelta
pandas/core/resample.py:from datetime import timedelta
pandas/core/tools/datetimes.py:from datetime import datetime, time
pandas/core/window/rolling.py:from datetime import timedelta
pandas/io/excel/_xlrd.py:from datetime import time
pandas/io/formats/format.py:from datetime import tzinfo
pandas/io/pytables.py:from datetime import date, tzinfo
pandas/io/sas/sas7bdat.py:from datetime import datetime
pandas/io/sas/sas_xport.py:from datetime import datetime
pandas/io/sql.py:from datetime import date, datetime, time
pandas/io/stata.py:    >>> from datetime import datetime
pandas/plotting/_matplotlib/converter.py:from datetime import datetime, timedelta
pandas/tests/api/test_api.py:    from datetime import datetime
pandas/tests/arithmetic/test_datetime64.py:from datetime import datetime, timedelta
pandas/tests/arithmetic/test_timedelta64.py:from datetime import datetime, timedelta
pandas/tests/arrays/categorical/test_constructors.py:from datetime import datetime
pandas/tests/base/test_constructors.py:from datetime import datetime
pandas/tests/base/test_ops.py:from datetime import datetime, timedelta
pandas/tests/dtypes/cast/test_infer_dtype.py:from datetime import date, datetime, timedelta
pandas/tests/dtypes/test_common.py:from datetime import datetime
pandas/tests/dtypes/test_inference.py:from datetime import date, datetime, time, timedelta
pandas/tests/dtypes/test_missing.py:from datetime import datetime
pandas/tests/frame/indexing/test_indexing.py:from datetime import date, datetime, time, timedelta
pandas/tests/frame/indexing/test_where.py:from datetime import datetime
pandas/tests/frame/methods/test_asfreq.py:from datetime import datetime
pandas/tests/frame/methods/test_at_time.py:from datetime import time
pandas/tests/frame/methods/test_between_time.py:from datetime import time
pandas/tests/frame/methods/test_combine_first.py:from datetime import datetime
pandas/tests/frame/methods/test_rank.py:from datetime import datetime, timedelta
pandas/tests/frame/methods/test_replace.py:from datetime import datetime
pandas/tests/frame/methods/test_reset_index.py:from datetime import datetime
pandas/tests/frame/methods/test_to_dict.py:from datetime import datetime
pandas/tests/frame/methods/test_to_timestamp.py:from datetime import timedelta
pandas/tests/frame/test_alter_axes.py:from datetime import datetime, timedelta
pandas/tests/frame/test_analytics.py:from datetime import timedelta
pandas/tests/frame/test_apply.py:from datetime import datetime
pandas/tests/frame/test_arithmetic.py:from datetime import datetime
pandas/tests/frame/test_axis_select_reindex.py:from datetime import datetime
pandas/tests/frame/test_block_internals.py:from datetime import datetime, timedelta
pandas/tests/frame/test_combine_concat.py:from datetime import datetime
pandas/tests/frame/test_constructors.py:from datetime import date, datetime, timedelta
pandas/tests/frame/test_dtypes.py:from datetime import timedelta
pandas/tests/frame/test_join.py:from datetime import datetime
pandas/tests/frame/test_repr_info.py:from datetime import datetime, timedelta
pandas/tests/frame/test_reshape.py:from datetime import datetime
pandas/tests/groupby/test_apply.py:from datetime import datetime
pandas/tests/groupby/test_categorical.py:from datetime import datetime
pandas/tests/groupby/test_groupby.py:from datetime import datetime
pandas/tests/groupby/test_grouping.py:        from datetime import date, timedelta
pandas/tests/groupby/test_timegrouper.py:from datetime import datetime
pandas/tests/groupby/test_timegrouper.py:        from datetime import timedelta as td
pandas/tests/indexes/datetimes/test_astype.py:from datetime import datetime
pandas/tests/indexes/datetimes/test_constructors.py:from datetime import datetime, timedelta, timezone
pandas/tests/indexes/datetimes/test_datetime.py:from datetime import date
pandas/tests/indexes/datetimes/test_datetime.py:        from datetime import time
pandas/tests/indexes/datetimes/test_date_range.py:from datetime import datetime, time, timedelta
pandas/tests/indexes/datetimes/test_formats.py:from datetime import datetime
pandas/tests/indexes/datetimes/test_indexing.py:from datetime import datetime, time, timedelta
pandas/tests/indexes/datetimes/test_join.py:from datetime import datetime
pandas/tests/indexes/datetimes/test_misc.py:from datetime import datetime
pandas/tests/indexes/datetimes/test_ops.py:from datetime import datetime
pandas/tests/indexes/datetimes/test_partial_slicing.py:from datetime import datetime
pandas/tests/indexes/datetimes/test_scalar_compat.py:from datetime import datetime
pandas/tests/indexes/datetimes/test_setops.py:from datetime import datetime
pandas/tests/indexes/datetimes/test_shift.py:from datetime import datetime
pandas/tests/indexes/datetimes/test_timezones.py:from datetime import date, datetime, time, timedelta, tzinfo
pandas/tests/indexes/interval/test_interval_range.py:from datetime import timedelta
pandas/tests/indexes/multi/test_constructors.py:from datetime import date, datetime
pandas/tests/indexes/multi/test_indexing.py:from datetime import timedelta
pandas/tests/indexes/multi/test_reshape.py:from datetime import datetime
pandas/tests/indexes/period/test_indexing.py:from datetime import datetime, timedelta
pandas/tests/indexes/period/test_tools.py:from datetime import datetime
pandas/tests/indexes/ranges/test_constructors.py:from datetime import datetime
pandas/tests/indexes/ranges/test_setops.py:from datetime import datetime, timedelta
pandas/tests/indexes/test_base.py:from datetime import datetime, timedelta
pandas/tests/indexes/test_numeric.py:from datetime import datetime, timedelta
pandas/tests/indexes/timedeltas/test_astype.py:from datetime import timedelta
pandas/tests/indexes/timedeltas/test_constructors.py:from datetime import timedelta
pandas/tests/indexes/timedeltas/test_indexing.py:from datetime import datetime, timedelta
pandas/tests/indexes/timedeltas/test_ops.py:from datetime import timedelta
pandas/tests/indexes/timedeltas/test_timedelta.py:from datetime import timedelta
pandas/tests/indexing/multiindex/test_datetime.py:from datetime import datetime
pandas/tests/indexing/test_datetime.py:from datetime import date, datetime, timedelta
pandas/tests/indexing/test_iloc.py:from datetime import datetime
pandas/tests/indexing/test_indexing.py:from datetime import datetime
pandas/tests/indexing/test_scalar.py:from datetime import datetime, timedelta
pandas/tests/internals/test_internals.py:from datetime import date, datetime
pandas/tests/io/excel/test_readers.py:from datetime import datetime, time
pandas/tests/io/excel/test_writers.py:from datetime import date, datetime, timedelta
pandas/tests/io/formats/test_format.py:from datetime import datetime
pandas/tests/io/formats/test_format.py:        from datetime import datetime, timedelta
pandas/tests/io/formats/test_to_html.py:from datetime import datetime
pandas/tests/io/formats/test_to_latex.py:from datetime import datetime
pandas/tests/io/generate_legacy_storage_files.py:from datetime import timedelta
pandas/tests/io/json/test_pandas.py:from datetime import timedelta
pandas/tests/io/parser/test_common.py:from datetime import datetime
pandas/tests/io/parser/test_parse_dates.py:from datetime import date, datetime
pandas/tests/io/parser/test_read_fwf.py:from datetime import datetime
pandas/tests/io/parser/test_skiprows.py:from datetime import datetime
pandas/tests/io/pytables/test_store.py:from datetime import timedelta
pandas/tests/io/pytables/test_store.py:            from datetime import datetime  # noqa
pandas/tests/io/pytables/test_timezones.py:    from datetime import timedelta
pandas/tests/io/pytables/test_timezones.py:    from datetime import timedelta
pandas/tests/io/sas/test_sas7bdat.py:from datetime import datetime
pandas/tests/io/test_date_converters.py:from datetime import datetime
pandas/tests/io/test_gbq.py:from datetime import datetime
pandas/tests/io/test_sql.py:from datetime import date, datetime, time
pandas/tests/io/test_stata.py:from datetime import datetime
pandas/tests/plotting/test_converter.py:from datetime import date, datetime
pandas/tests/plotting/test_datetimelike.py:from datetime import date, datetime, time, timedelta
pandas/tests/plotting/test_frame.py:from datetime import date, datetime
pandas/tests/plotting/test_series.py:from datetime import datetime
pandas/tests/reductions/test_reductions.py:from datetime import datetime, timedelta
pandas/tests/resample/conftest.py:from datetime import datetime
pandas/tests/resample/test_base.py:from datetime import datetime, timedelta
pandas/tests/resample/test_datetime_index.py:from datetime import datetime, timedelta
pandas/tests/resample/test_period_index.py:from datetime import datetime, timedelta
pandas/tests/resample/test_resample_api.py:from datetime import datetime
pandas/tests/resample/test_timedelta.py:from datetime import timedelta
pandas/tests/resample/test_time_grouper.py:from datetime import datetime
pandas/tests/reshape/merge/test_merge.py:from datetime import date, datetime, timedelta
pandas/tests/reshape/test_concat.py:from datetime import datetime
pandas/tests/reshape/test_pivot.py:from datetime import date, datetime, timedelta
pandas/tests/scalar/period/test_period.py:from datetime import date, datetime, timedelta
pandas/tests/scalar/test_nat.py:from datetime import datetime, timedelta
pandas/tests/scalar/timedelta/test_arithmetic.py:from datetime import datetime, timedelta
pandas/tests/scalar/timedelta/test_constructors.py:from datetime import timedelta
pandas/tests/scalar/timedelta/test_timedelta.py:from datetime import timedelta
pandas/tests/scalar/timestamp/test_arithmetic.py:from datetime import datetime, timedelta
pandas/tests/scalar/timestamp/test_comparisons.py:from datetime import datetime
pandas/tests/scalar/timestamp/test_constructors.py:from datetime import datetime, timedelta
pandas/tests/scalar/timestamp/test_timestamp.py:from datetime import datetime, timedelta
pandas/tests/scalar/timestamp/test_timezones.py:from datetime import date, datetime, timedelta
pandas/tests/scalar/timestamp/test_unary_ops.py:from datetime import datetime
pandas/tests/series/indexing/test_alter_index.py:from datetime import datetime
pandas/tests/series/indexing/test_datetime.py:from datetime import datetime, timedelta
pandas/tests/series/indexing/test_indexing.py:from datetime import timedelta
pandas/tests/series/methods/test_asfreq.py:from datetime import datetime
pandas/tests/series/methods/test_at_time.py:from datetime import time
pandas/tests/series/methods/test_between_time.py:from datetime import datetime, time
pandas/tests/series/methods/test_combine_first.py:from datetime import datetime
pandas/tests/series/methods/test_rename.py:from datetime import datetime
pandas/tests/series/methods/test_to_timestamp.py:from datetime import timedelta
pandas/tests/series/methods/test_truncate.py:from datetime import datetime
pandas/tests/series/test_alter_axes.py:from datetime import datetime
pandas/tests/series/test_constructors.py:from datetime import datetime, timedelta
pandas/tests/series/test_datetime_values.py:from datetime import date, datetime, time
pandas/tests/series/test_datetime_values.py:        from datetime import date, time
pandas/tests/series/test_dtypes.py:from datetime import datetime, timedelta
pandas/tests/series/test_internals.py:from datetime import datetime
pandas/tests/series/test_io.py:from datetime import datetime
pandas/tests/series/test_missing.py:from datetime import datetime, timedelta
pandas/tests/series/test_operators.py:from datetime import datetime, timedelta
pandas/tests/series/test_operators.py:        from datetime import date
pandas/tests/series/test_repr.py:from datetime import datetime, timedelta
pandas/tests/series/test_timezones.py:from datetime import datetime
pandas/tests/test_algos.py:from datetime import datetime
pandas/tests/test_sorting.py:from datetime import datetime
pandas/tests/test_strings.py:from datetime import datetime, timedelta
pandas/tests/test_take.py:from datetime import datetime
pandas/tests/tools/test_to_datetime.py:from datetime import datetime, timedelta
pandas/tests/tools/test_to_time.py:from datetime import time
pandas/tests/tools/test_to_timedelta.py:from datetime import time, timedelta
pandas/tests/tseries/frequencies/test_inference.py:from datetime import datetime, timedelta
pandas/tests/tseries/holiday/test_calendar.py:from datetime import datetime
pandas/tests/tseries/holiday/test_federal.py:from datetime import datetime
pandas/tests/tseries/holiday/test_holiday.py:from datetime import datetime
pandas/tests/tseries/holiday/test_observance.py:from datetime import datetime
pandas/tests/tseries/offsets/test_fiscal.py:from datetime import datetime
pandas/tests/tseries/offsets/test_offsets.py:from datetime import date, datetime, time as dt_time, timedelta
pandas/tests/tseries/offsets/test_offsets.py:        from datetime import time as dt_time
pandas/tests/tseries/offsets/test_offsets.py:        from datetime import time as dt_time
pandas/tests/tseries/offsets/test_ticks.py:from datetime import datetime, timedelta
pandas/tests/tseries/offsets/test_yqm_offsets.py:from datetime import datetime
pandas/tests/tslibs/test_array_to_datetime.py:from datetime import date, datetime
pandas/tests/tslibs/test_ccalendar.py:from datetime import datetime
pandas/tests/tslibs/test_conversion.py:from datetime import datetime
pandas/tests/tslibs/test_liboffsets.py:from datetime import datetime
pandas/tests/tslibs/test_normalize_date.py:from datetime import date, datetime
pandas/tests/tslibs/test_parse_iso8601.py:from datetime import datetime
pandas/tests/tslibs/test_parsing.py:from datetime import datetime
pandas/tests/tslibs/test_timezones.py:from datetime import datetime
pandas/tests/window/common.py:from datetime import datetime
pandas/tests/window/moments/test_moments_rolling.py:from datetime import datetime
pandas/tests/window/test_rolling.py:from datetime import datetime, timedelta
pandas/tseries/frequencies.py:from datetime import timedelta
pandas/tseries/holiday.py:from datetime import datetime, timedelta
pandas/tseries/offsets.py:from datetime import date, datetime, timedelta
pandas/_libs/tslibs/conversion.pyx:from datetime import time as datetime_time
pandas/_libs/tslibs/period.pyx:from datetime import datetime
pandas/_libs/tslibs/strptime.pyx:from datetime import date as datetime_date
pandas/_libs/tslibs/timestamps.pyx:from datetime import time as datetime_time, timedelta
pandas/_libs/tslibs/timezones.pyx:from datetime import timezone
pandas/_testing.py:from datetime import datetime
pandas/_testing.py:    >>> from datetime import datetime
pandas/__init__.py:            from datetime import datetime as dt
pandas/__init__.py:        from datetime import datetime as dt
pandas/__init__.py:            from datetime import datetime as dt
```
vs. 

```
$ grep -r "^import datetime$" --include=\*.{py,pyx}asv_bench/benchmarks/tslibs/timedelta.py:import datetime
asv_bench/benchmarks/tslibs/timestamp.py:import datetime
pandas/core/computation/scope.py:import datetime
pandas/core/frame.py:import datetime
pandas/core/groupby/groupby.py:import datetime
pandas/core/ops/__init__.py:import datetime
pandas/core/reshape/merge.py:import datetime
pandas/io/excel/_base.py:import datetime
pandas/io/parsers.py:import datetime
pandas/io/stata.py:import datetime
pandas/tests/arithmetic/test_object.py:import datetime
pandas/tests/arrays/test_array.py:import datetime
pandas/tests/dtypes/cast/test_promote.py:import datetime
pandas/tests/frame/test_api.py:import datetime
pandas/tests/frame/test_missing.py:import datetime
pandas/tests/io/json/test_pandas.py:import datetime
pandas/tests/io/json/test_ujson.py:import datetime
pandas/tests/io/pytables/test_store.py:import datetime
pandas/tests/io/pytables/test_timezones.py:import datetime
pandas/tests/io/test_orc.py:import datetime
pandas/tests/io/test_parquet.py:import datetime
pandas/tests/io/test_pickle.py:import datetime
pandas/tests/reshape/merge/test_merge_asof.py:import datetime
pandas/tests/test_multilevel.py:import datetime
pandas/tests/util/test_hashing.py:import datetime
web/pandas_web.py:import datetime
```

if we want to be consistent, then i'd be happy with standardising on the more common pattern as that would also address https://github.com/pandas-dev/pandas/pull/32459#discussion_r388351566
> @MomIsBestFriend can we have a discussion on this

@simonjayhawkins Sure!

What are the considerations to use

```python
from datetime import foo bar baz

print(foo)
print(bar)
print(baz)
```
over

```python
import datetime

print(datetime.foo)
print(datetime.bar)
print(datetime.baz)
```

---

I think that the second one is clearer as it gives more context.
just like we use ```os.walk``` and ```ast.walk``` because you can't know from which module the ```walk``` came from.
both styles have pros and cons, and my preference here is mainly due to the prevalence of the first style in our codebase.
> both styles have pros and cons, and my preference here is mainly due to the prevalence of the first style in our codebase.

@simonjayhawkins if the main objection is due to the prevalence of the current pattern in the code base, this should not be a large issue, I can fix all of those pretty easily. 
> I can fix all of those pretty easily.

I don't doubt that, but legacy codebases tend to have significant intrinsic value. So the prevalence argument is based on leveraging the experience of the developers before us.
> legacy codebases tend to have significant intrinsic value.

I see, obviously some parts of the code will be more difficult to tackle than others, but don't you think that we should agree on one specific pattern? (at least for ```datetime```)

I do think that imports like this, are good

```python
from datetime import date as datetime_date
```

I rather prefer, this more (over the previous one)

```python
from datetime import date
``` 


> I see, obviously some parts of the code will be more difficult to tackle than others, but don't you think that we should agree on one specific pattern? (at least for `datetime`)

most definitely and datetime is really the issue since it doesn't follow the style PEP with regards to module and object naming.

I should of made it clear in https://github.com/pandas-dev/pandas/pull/32364#pullrequestreview-366806973 that proper discussion takes place before introducing these changes.

IMO when doing cleaning PRs, the patterns used should ONLY be patterns that have been previously discussed/accepted. Otherwise, a precedent tends to be set and the pattern is not adopted through conscious choice.

Consistency is important, so this PR should also include updates to the style guide, if we are adopting a new pattern. 

@simonjayhawkins what is the PEP import style here that is recommended?
AFAICT both styles are perfectly acceptable and PEP8 doesn't have a preference.

my reference to the PEP above refers to datetime naming the module and an object the same.

so we also have some cases where we use aliases (not many though)

most imports are or the form `from datetime import datetime, timedelta` where we import all the objects we need to avoid needing aliases.

the google style, however, does recommend the second approach http://google.github.io/styleguide/pyguide.html#22-imports and I am fine with this, as long as sufficient discussion has taken place. (and cython performance is not affected)
Outstanding thoughts on this? Personally OK with it but if there are objections I think OK to just leave as is for now and close PR
i do like this if the perf is not impacted
fine by me
@MomIsBestFriend can you run benchmarks and post results to be sure?
> @MomIsBestFriend can you run benchmarks and post results to be sure?

@WillAyd I have ran a benchmark and posted it in https://github.com/pandas-dev/pandas/pull/32459#discussion_r388793721

---

Do you want me to merge master and run it again?
> i do like this if the perf is not impacted

I have no objections to adopting the google style for imports throughout. (would also be happy to adopt the complete google style as a fallback where we don't have a pandas specific recommendation, but that's another discussion)

In the style guide we could make the split into Python style guide and Cython style guide more obvious since some python style patterns may not translate well to Cython. IMO having different styles for Python and Cython is acceptable if documented. 

"A Foolish Consistency is the Hobgoblin of Little Minds".. https://www.python.org/dev/peps/pep-0008/


> Do you want me to merge master and run it again?

Can you run the actual ASV benchmarks for tslibs?
> > Do you want me to merge master and run it again?
> 
> Can you run the actual ASV benchmarks for tslibs?

No actually I can not, I never managed to run ASV, I use ```venv``` and ```pip``` and I have python 3.8.2.

ASV complains I don't have python 3.6

and each time I solve one complain it has another
You can change the python version in the asv config file
thanks