ENH: set __module__ for objects in pandas pd.DataFrame API
State: closed

- [x] part of #55178
- [ ] [Tests added and passed](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#writing-tests) if fixing a bug or adding a new feature
- [x] All [code checks passed](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#pre-commit).
- [ ] Added [type annotations](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#type-hints) to new arguments/methods/functions.
- [ ] Added an entry in the latest `doc/source/whatsnew/vX.X.X.rst` file if fixing a bug or adding a new feature.

This PR add ```@set_module``` decorator around ```class pd.DataFrame```

Before this PR
```
>>> import pandas as pd
>>> pd.DataFrame
<class 'pandas.core.frame.DataFrame'>
```

After this PR
```
>>> import pandas as pd
>>> pd.DataFrame
<class 'pandas.DataFrame'>
```

This change would discourage users from incorrectly using
```
from pandas.core.frame import DataFrame
```
Inspired by the similar implementation in numpy: 
https://github.com/numpy/numpy/pull/12382




Labels:
name: Output-Formatting
description: __repr__ of pandas objects, to_string
name: Sprints
description: Sprint Pull Requests

Comments:
> inspired by similar implementation in numpy

Whenever I try to figure out how something in numpy works I have a hard time finding out where something is defined because they use patterns like `from foo import *` at the top level.  I don't know if the pattern in this PR contributes to that pain point, but my spidey sense is tingling that it might.
> > inspired by similar implementation in numpy
> 
> Whenever I try to figure out how something in numpy works I have a hard time finding out where something is defined because they use patterns like `from foo import *` at the top level. I don't know if the pattern in this PR contributes to that pain point, but my spidey sense is tingling that it might.

@jbrockmendel this has nothing to do with a `*` import though, so I don't fully understand your comment. 
It is true that it _does_ mask where the object actually lives, so it makes it harder to find the location (the file) in the source code. But this masking is actually the purpose, with the idea that users don't need to see this (with the drawback for contributors, but in making the trade-off, there are much more users, so I would prefer prioritizing that use case).

EDIT: opened https://github.com/pandas-dev/pandas/issues/55178 to keep the general discussion there
@deepak-george there are a bunch of tests where it seems we rely on this exact "pandas.core.frame" string that will have to be updated as well.

First, there are some doctest failures (i.e. docstrings that need to be updated):

```



=================================== FAILURES ===================================
______________ [doctest] pandas.core.indexing.IndexingMixin.iloc _______________
207         c    3
208         d    4
209         Name: 0, dtype: int64
210 
211         With a list of integers.
212 
213         >>> df.iloc[[0]]
214            a  b  c  d
215         0  1  2  3  4
216         >>> type(df.iloc[[0]])
Expected:
    <class 'pandas.core.frame.DataFrame'>
Got:
    <class 'pandas.DataFrame'>

/home/runner/micromamba/envs/test/lib/python3.10/site-packages/pandas/core/indexing.py:216: DocTestFailure
_________________ [doctest] pandas.core.indexing._iLocIndexer __________________
1583 c    3
1584 d    4
1585 Name: 0, dtype: int64
1586 
1587 With a list of integers.
1588 
1589 >>> df.iloc[[0]]
1590    a  b  c  d
1591 0  1  2  3  4
1592 >>> type(df.iloc[[0]])
Expected:
    <class 'pandas.core.frame.DataFrame'>
Got:
    <class 'pandas.DataFrame'>

/home/runner/micromamba/envs/test/lib/python3.10/site-packages/pandas/core/indexing.py:1592: DocTestFailure
```

And then there are also normal test failures like:

```
____________________________ test_info_int_columns _____________________________
[gw2] darwin -- Python 3.9.18 /Users/runner/micromamba/envs/test/bin/python3.9

    @pytest.mark.xfail(not IS64, reason="GH 36579: fail on 32-bit system")
    def test_info_int_columns():
        # GH#37245
        df = DataFrame({1: [1, 2], 2: [2, 3]}, index=["A", "B"])
        buf = StringIO()
        df.info(show_counts=True, buf=buf)
        result = buf.getvalue()
        expected = textwrap.dedent(
            """\
            <class 'pandas.core.frame.DataFrame'>
            Index: 2 entries, A to B
            Data columns (total 2 columns):
             #   Column  Non-Null Count  Dtype
            ---  ------  --------------  -----
             0   1       2 non-null      int64
             1   2       2 non-null      int64
            dtypes: int64(2)
            memory usage: 48.0+ bytes
            """
        )
>       assert result == expected
E       AssertionError

pandas/tests/io/formats/test_info.py:501: AssertionError
```

and for all, see the failing CI logs.

It might be possible to fix most of them with a search replace of "pandas.core.frame.DataFrame" -> "pandas.DataFrame"
@jorisvandenbossche Thanks for the feedback! I have made the changes  like pandas.core.frame.DataFrame -> pandas.DataFrame & pylint fix

Now all the tests except "Unit Tests / Linux-32-bit (pull_request)"  passed. I am looking into the logs and trying to fix but not sure yet what is going on.
> @jorisvandenbossche Thanks for the feedback! I have made the changes like pandas.core.frame.DataFrame -> pandas.DataFrame & pylint fix
> 
> Now all the tests except "Unit Tests / Linux-32-bit (pull_request)" passed. I am looking into the logs and trying to fix but not sure yet what is going on.

@jorisvandenbossche 
`../../numpy/meson.build:207:4: ERROR: Problem encountered: No BLAS library detected! Install one, or use the `allow-noblas` build option (note, this may be up to 100x slower for some linear algebra operations).`

I believe BLAS is already installed, so not sure if this should be fixed in this PR.
@deepak-george you can ignore that error, that looks unrelated (and probably if you merge with the latest main branch, that might be resolved)
> @deepak-george you can ignore that error, that looks unrelated (and probably if you merge with the latest main branch, that might be resolved)

Ok. Now all the tests including the new test added to check this functionality have passed. Is there something else that need to be done before you could merge? Please let me know the next step. 
@jorisvandenbossche What is the next step for this PR? Could this be merged?
I have pulled the recent changes from main and all checks have passed as well.
@aimlnerd sorry for the slow follow-up here. But we _might_ want to only merge this after pandas 2.2 is cut, so we merge this in the main branch for 3.0. Reason for this: in theory it could be a breaking change if someone relies on the `__module__` attribute, so for safety it might be better to only do this in the major release.

It is the plan to branch 2.2.x in one week or two, so we can revisit this shortly!
@jorisvandenbossche Thanks for the context! Please let me know when you want to revisit, happy to make changes and complete it!
Sorry for the slow follow-up, but in the meantime main is targetting 3.0 for a while, so we can merge this now. @aimlnerd thanks again!