Skip to content

BUG: Placeholders not being filled on docstrings #39139

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jan 17, 2021

Conversation

MicaelJarniac
Copy link
Contributor

@MicaelJarniac MicaelJarniac commented Jan 13, 2021

@MicaelJarniac
Copy link
Contributor Author

MicaelJarniac commented Jan 13, 2021

It's my first time actually working with the code on this repo.

I've contributed previously, but only with minor changes to documentation, and I've always done that from the GitHub built-in editor.

I believe I've done everything correctly, but I'm completely unfamiliar with the codebase here.

I've built the documentation locally and looked around to see if there was anything wrong, and it didn't seem like it.

I didn't expect I'd be able to even find what was causing the bug I reported, let alone fix it, and I can't help but feel like I'm missing something important.

Anyways, the fix I've put together is really simple, but I fear it might not be exactly how the maintainers would like it to be fixed, so if needed I can try to come up with something else to mitigate this issue.

What I mean by "not how the maintainers would like it fixed" is that, for this fix to work, an empty @doc() decorator is used on the first mad method, as to populate it with some docstring generation goodies. This may or may not be a pattern that fits with the rest of the codebase, so although it works, it could be considered an inappropriate solution for breaking consistency or something along those lines.

This was the simplest way I found for fixing this, and in my opinion it has a nice pattern to it, but I do think there are other ways of fixing this.

Copy link
Contributor

@jreback jreback left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the docs are showing warnings which is a bit odd; make sure you have up to date code & precommit hooks

@jreback jreback added the Docs label Jan 13, 2021
@MicaelJarniac
Copy link
Contributor Author

MicaelJarniac commented Jan 13, 2021

the docs are showing warnings which is a bit odd; make sure you have up to date code & precommit hooks

I did run all tests I managed to find. I've run pre-commit (and it's also properly added as a hook), I've run ./ci/code_checks.sh, validate_docstrings.py on the ones I modified, and everything seemed to have worked fine.

I'll run some more tests, and see if I can find out what those warnings are about.

Edit: I forgot to mention, I've just forked this repo yesterday, and I did git pull upstream after cloning my fork to my local machine too (but it was up-to-date already). And the branch I've created was from master.

@jreback
Copy link
Contributor

jreback commented Jan 13, 2021

the docs are showing warnings which is a bit odd; make sure you have up to date code & precommit hooks

I did run all tests I managed to find. I've run pre-commit (and it's also properly added as a hook), I've run ./ci/code_checks.sh, validate_docstrings.py on the ones I modified, and everything seemed to have worked fine.

I'll run some more tests, and see if I can find out what those warnings are about.

try to actually build the docs (these are not tests)

@MicaelJarniac
Copy link
Contributor Author

I did build them, it took ages but worked fine.

@MicaelJarniac
Copy link
Contributor Author

I've also shared a screenshot of the specific doc I was aiming to fix:

#39115 (comment)
Screenshot

@MicaelJarniac
Copy link
Contributor Author

I've merged the current master to my branch, and am running pre-commit run --all-files now, will run all tests I can find afterwards.

@MicaelJarniac
Copy link
Contributor Author

pytest pandas output:

======================================================================================================== FAILURES ========================================================================================================
___________________________________________________________________________________ TestCategoricalWarnings.test_tab_complete_warning ____________________________________________________________________________________

self = <pandas.tests.arrays.categorical.test_warnings.TestCategoricalWarnings object at 0x7fc94a445a00>, ip = <IPython.core.interactiveshell.InteractiveShell object at 0x7fc94a2f3a90>

    @async_mark()
    async def test_tab_complete_warning(self, ip):
        # https://github.com/pandas-dev/pandas/issues/16409
        pytest.importorskip("IPython", minversion="6.0.0")
        from IPython.core.completer import provisionalcompleter
    
        code = "import pandas as pd; c = Categorical([])"
        await ip.run_code(code)
    
        # GH 31324 newer jedi version raises Deprecation warning
        import jedi
    
        if jedi.__version__ < "0.16.0":
            warning = tm.assert_produces_warning(None)
        else:
            warning = tm.assert_produces_warning(
                DeprecationWarning, check_stacklevel=False
            )
        with warning:
            with provisionalcompleter("ignore"):
>               list(ip.Completer.completions("c.", 1))

pandas/tests/arrays/categorical/test_warnings.py:29: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
env/lib/python3.8/site-packages/IPython/core/completer.py:1818: in completions
    for c in self._completions(text, offset, _timeout=self.jedi_compute_type_timeout/1000):
env/lib/python3.8/site-packages/IPython/core/completer.py:1861: in _completions
    matched_text, matches, matches_origin, jedi_matches = self._complete(
env/lib/python3.8/site-packages/IPython/core/completer.py:2029: in _complete
    completions = self._jedi_matches(
env/lib/python3.8/site-packages/IPython/core/completer.py:1373: in _jedi_matches
    interpreter = jedi.Interpreter(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <[AttributeError("'Interpreter' object has no attribute '_orig_path'") raised in repr()] Interpreter object at 0x7fc94a408e80>, code = 'c'
namespaces = [{'In': [''], 'Out': {}, '_': '', '__': '', ...}, {'In': [''], 'Out': {}, '_': '', '__': '', ...}], kwds = {'column': 1, 'line': 1}
environment = <jedi.api.environment.InterpreterEnvironment object at 0x7fc94a4084c0>

    def __init__(self, code, namespaces, **kwds):
        try:
            namespaces = [dict(n) for n in namespaces]
        except Exception:
            raise TypeError("namespaces must be a non-empty list of dicts.")
    
        environment = kwds.get('environment', None)
        if environment is None:
            environment = InterpreterEnvironment()
        else:
            if not isinstance(environment, InterpreterEnvironment):
                raise TypeError("The environment needs to be an InterpreterEnvironment subclass.")
    
>       super().__init__(code, environment=environment,
                         project=Project(Path.cwd()), **kwds)
E       TypeError: __init__() got an unexpected keyword argument 'column'

env/lib/python3.8/site-packages/jedi/api/__init__.py:725: TypeError
-------------------------------------------------------------------------------------------------- Captured stdout call --------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<string> in <module>

NameError: name 'Categorical' is not defined
_________________________________________________________________________________ TestDataFrameMisc.test_tab_complete_warning[DataFrame] _________________________________________________________________________________

self = <pandas.tests.frame.test_api.TestDataFrameMisc object at 0x7fc92fc1c0a0>, ip = <IPython.core.interactiveshell.InteractiveShell object at 0x7fc92fcb0160>, frame_or_series = <class 'pandas.core.frame.DataFrame'>

    @async_mark()
    @td.check_file_leaks
    async def test_tab_complete_warning(self, ip, frame_or_series):
        # GH 16409
        pytest.importorskip("IPython", minversion="6.0.0")
        from IPython.core.completer import provisionalcompleter
    
        if frame_or_series is DataFrame:
            code = "from pandas import DataFrame; obj = DataFrame()"
        else:
            code = "from pandas import Series; obj = Series(dtype=object)"
    
        await ip.run_code(code)
    
        # TODO: remove it when Ipython updates
        # GH 33567, jedi version raises Deprecation warning in Ipython
        import jedi
    
        if jedi.__version__ < "0.17.0":
            warning = tm.assert_produces_warning(None)
        else:
            warning = tm.assert_produces_warning(
                DeprecationWarning, check_stacklevel=False
            )
        with warning:
            with provisionalcompleter("ignore"):
>               list(ip.Completer.completions("obj.", 1))

pandas/tests/frame/test_api.py:289: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
env/lib/python3.8/site-packages/IPython/core/completer.py:1818: in completions
    for c in self._completions(text, offset, _timeout=self.jedi_compute_type_timeout/1000):
env/lib/python3.8/site-packages/IPython/core/completer.py:1861: in _completions
    matched_text, matches, matches_origin, jedi_matches = self._complete(
env/lib/python3.8/site-packages/IPython/core/completer.py:2029: in _complete
    completions = self._jedi_matches(
env/lib/python3.8/site-packages/IPython/core/completer.py:1373: in _jedi_matches
    interpreter = jedi.Interpreter(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <[AttributeError("'Interpreter' object has no attribute '_orig_path'") raised in repr()] Interpreter object at 0x7fc92fd77910>, code = 'o'
namespaces = [{'DataFrame': <class 'pandas.core.frame.DataFrame'>, 'In': [''], 'Out': {}, '_': '', ...}, {'DataFrame': <class 'pandas.core.frame.DataFrame'>, 'In': [''], 'Out': {}, '_': '', ...}]
kwds = {'column': 1, 'line': 1}, environment = <jedi.api.environment.InterpreterEnvironment object at 0x7fc92fd777f0>

    def __init__(self, code, namespaces, **kwds):
        try:
            namespaces = [dict(n) for n in namespaces]
        except Exception:
            raise TypeError("namespaces must be a non-empty list of dicts.")
    
        environment = kwds.get('environment', None)
        if environment is None:
            environment = InterpreterEnvironment()
        else:
            if not isinstance(environment, InterpreterEnvironment):
                raise TypeError("The environment needs to be an InterpreterEnvironment subclass.")
    
>       super().__init__(code, environment=environment,
                         project=Project(Path.cwd()), **kwds)
E       TypeError: __init__() got an unexpected keyword argument 'column'

env/lib/python3.8/site-packages/jedi/api/__init__.py:725: TypeError
__________________________________________________________________________________ TestDataFrameMisc.test_tab_complete_warning[Series] ___________________________________________________________________________________

self = <pandas.tests.frame.test_api.TestDataFrameMisc object at 0x7fc92fc9f8e0>, ip = <IPython.core.interactiveshell.InteractiveShell object at 0x7fc92fc9f490>, frame_or_series = <class 'pandas.core.series.Series'>

    @async_mark()
    @td.check_file_leaks
    async def test_tab_complete_warning(self, ip, frame_or_series):
        # GH 16409
        pytest.importorskip("IPython", minversion="6.0.0")
        from IPython.core.completer import provisionalcompleter
    
        if frame_or_series is DataFrame:
            code = "from pandas import DataFrame; obj = DataFrame()"
        else:
            code = "from pandas import Series; obj = Series(dtype=object)"
    
        await ip.run_code(code)
    
        # TODO: remove it when Ipython updates
        # GH 33567, jedi version raises Deprecation warning in Ipython
        import jedi
    
        if jedi.__version__ < "0.17.0":
            warning = tm.assert_produces_warning(None)
        else:
            warning = tm.assert_produces_warning(
                DeprecationWarning, check_stacklevel=False
            )
        with warning:
            with provisionalcompleter("ignore"):
>               list(ip.Completer.completions("obj.", 1))

pandas/tests/frame/test_api.py:289: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
env/lib/python3.8/site-packages/IPython/core/completer.py:1818: in completions
    for c in self._completions(text, offset, _timeout=self.jedi_compute_type_timeout/1000):
env/lib/python3.8/site-packages/IPython/core/completer.py:1861: in _completions
    matched_text, matches, matches_origin, jedi_matches = self._complete(
env/lib/python3.8/site-packages/IPython/core/completer.py:2029: in _complete
    completions = self._jedi_matches(
env/lib/python3.8/site-packages/IPython/core/completer.py:1373: in _jedi_matches
    interpreter = jedi.Interpreter(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <[AttributeError("'Interpreter' object has no attribute '_orig_path'") raised in repr()] Interpreter object at 0x7fc92fbbd1c0>, code = 'o'
namespaces = [{'In': [''], 'Out': {}, 'Series': <class 'pandas.core.series.Series'>, '_': '', ...}, {'In': [''], 'Out': {}, 'Series': <class 'pandas.core.series.Series'>, '_': '', ...}], kwds = {'column': 1, 'line': 1}
environment = <jedi.api.environment.InterpreterEnvironment object at 0x7fc92fbbd0d0>

    def __init__(self, code, namespaces, **kwds):
        try:
            namespaces = [dict(n) for n in namespaces]
        except Exception:
            raise TypeError("namespaces must be a non-empty list of dicts.")
    
        environment = kwds.get('environment', None)
        if environment is None:
            environment = InterpreterEnvironment()
        else:
            if not isinstance(environment, InterpreterEnvironment):
                raise TypeError("The environment needs to be an InterpreterEnvironment subclass.")
    
>       super().__init__(code, environment=environment,
                         project=Project(Path.cwd()), **kwds)
E       TypeError: __init__() got an unexpected keyword argument 'column'

env/lib/python3.8/site-packages/jedi/api/__init__.py:725: TypeError
__________________________________________________________________________________________ TestIndex.test_tab_complete_warning ___________________________________________________________________________________________

self = <pandas.tests.indexes.test_base.TestIndex object at 0x7fc917a6c940>, ip = <IPython.core.interactiveshell.InteractiveShell object at 0x7fc917a6cf10>

    @async_mark()
    async def test_tab_complete_warning(self, ip):
        # https://github.com/pandas-dev/pandas/issues/16409
        pytest.importorskip("IPython", minversion="6.0.0")
        from IPython.core.completer import provisionalcompleter
    
        code = "import pandas as pd; idx = Index([1, 2])"
        await ip.run_code(code)
    
        # GH 31324 newer jedi version raises Deprecation warning
        import jedi
    
        if jedi.__version__ < "0.16.0":
            warning = tm.assert_produces_warning(None)
        else:
            warning = tm.assert_produces_warning(
                DeprecationWarning, check_stacklevel=False
            )
        with warning:
            with provisionalcompleter("ignore"):
>               list(ip.Completer.completions("idx.", 4))

pandas/tests/indexes/test_base.py:1963: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
env/lib/python3.8/site-packages/IPython/core/completer.py:1818: in completions
    for c in self._completions(text, offset, _timeout=self.jedi_compute_type_timeout/1000):
env/lib/python3.8/site-packages/IPython/core/completer.py:1861: in _completions
    matched_text, matches, matches_origin, jedi_matches = self._complete(
env/lib/python3.8/site-packages/IPython/core/completer.py:2029: in _complete
    completions = self._jedi_matches(
env/lib/python3.8/site-packages/IPython/core/completer.py:1373: in _jedi_matches
    interpreter = jedi.Interpreter(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <[AttributeError("'Interpreter' object has no attribute '_orig_path'") raised in repr()] Interpreter object at 0x7fc926764fa0>, code = 'idx.'
namespaces = [{'In': [''], 'Out': {}, '_': '', '__': '', ...}, {'In': [''], 'Out': {}, '_': '', '__': '', ...}], kwds = {'column': 4, 'line': 1}
environment = <jedi.api.environment.InterpreterEnvironment object at 0x7fc926764040>

    def __init__(self, code, namespaces, **kwds):
        try:
            namespaces = [dict(n) for n in namespaces]
        except Exception:
            raise TypeError("namespaces must be a non-empty list of dicts.")
    
        environment = kwds.get('environment', None)
        if environment is None:
            environment = InterpreterEnvironment()
        else:
            if not isinstance(environment, InterpreterEnvironment):
                raise TypeError("The environment needs to be an InterpreterEnvironment subclass.")
    
>       super().__init__(code, environment=environment,
                         project=Project(Path.cwd()), **kwds)
E       TypeError: __init__() got an unexpected keyword argument 'column'

env/lib/python3.8/site-packages/jedi/api/__init__.py:725: TypeError
-------------------------------------------------------------------------------------------------- Captured stdout call --------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<string> in <module>

NameError: name 'Index' is not defined
___________________________________________________________________________________ TestReadHtml.test_encode[chinese_utf-16.html-bs4] ____________________________________________________________________________________

self = <pandas.tests.io.test_html.TestReadHtml object at 0x7fc8e5ca18b0>, html_encoding_file = '/home/micael/projects/pandas-MicaelJarniac/pandas/tests/io/data/html_encoding/chinese_utf-16.html'

    def test_encode(self, html_encoding_file):
        base_path = os.path.basename(html_encoding_file)
        root = os.path.splitext(base_path)[0]
        _, encoding = root.split("_")
    
        try:
            with open(html_encoding_file, "rb") as fobj:
>               from_string = self.read_html(
                    fobj.read(), encoding=encoding, index_col=0
                ).pop()

pandas/tests/io/test_html.py:1161: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
pandas/util/_decorators.py:299: in wrapper
    return func(*args, **kwargs)
pandas/io/html.py:1081: in read_html
    return _parse(
pandas/io/html.py:909: in _parse
    raise retained
pandas/io/html.py:889: in _parse
    tables = p.parse_tables()
pandas/io/html.py:209: in parse_tables
    tables = self._parse_tables(self._build_doc(), self.match, self.attrs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <pandas.io.html._BeautifulSoupHtml5LibFrameParser object at 0x7fc8e5caaaf0>

    def _build_doc(self):
        from bs4 import BeautifulSoup
    
        bdoc = self._setup_build_doc()
        if isinstance(bdoc, bytes) and self.encoding is not None:
>           udoc = bdoc.decode(self.encoding)
E           UnicodeDecodeError: 'utf-16-le' codec can't decode byte 0x00 in position 850: truncated data

pandas/io/html.py:590: UnicodeDecodeError
___________________________________________________________________________________ TestReadHtml.test_encode[chinese_utf-32.html-bs4] ____________________________________________________________________________________

self = <pandas.tests.io.test_html.TestReadHtml object at 0x7fc8e5ad2ca0>, html_encoding_file = '/home/micael/projects/pandas-MicaelJarniac/pandas/tests/io/data/html_encoding/chinese_utf-32.html'

    def test_encode(self, html_encoding_file):
        base_path = os.path.basename(html_encoding_file)
        root = os.path.splitext(base_path)[0]
        _, encoding = root.split("_")
    
        try:
            with open(html_encoding_file, "rb") as fobj:
>               from_string = self.read_html(
                    fobj.read(), encoding=encoding, index_col=0
                ).pop()

pandas/tests/io/test_html.py:1161: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
pandas/util/_decorators.py:299: in wrapper
    return func(*args, **kwargs)
pandas/io/html.py:1081: in read_html
    return _parse(
pandas/io/html.py:909: in _parse
    raise retained
pandas/io/html.py:889: in _parse
    tables = p.parse_tables()
pandas/io/html.py:209: in parse_tables
    tables = self._parse_tables(self._build_doc(), self.match, self.attrs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <pandas.io.html._BeautifulSoupHtml5LibFrameParser object at 0x7fc8e5af58b0>

    def _build_doc(self):
        from bs4 import BeautifulSoup
    
        bdoc = self._setup_build_doc()
        if isinstance(bdoc, bytes) and self.encoding is not None:
>           udoc = bdoc.decode(self.encoding)
E           UnicodeDecodeError: 'utf-32-le' codec can't decode bytes in position 192-195: code point not in range(0x110000)

pandas/io/html.py:590: UnicodeDecodeError
___________________________________________________________________________________ TestReadHtml.test_encode[chinese_utf-32.html-lxml] ___________________________________________________________________________________

self = <pandas.tests.io.test_html.TestReadHtml object at 0x7fc8e4945370>, html_encoding_file = '/home/micael/projects/pandas-MicaelJarniac/pandas/tests/io/data/html_encoding/chinese_utf-32.html'

    def test_encode(self, html_encoding_file):
        base_path = os.path.basename(html_encoding_file)
        root = os.path.splitext(base_path)[0]
        _, encoding = root.split("_")
    
        try:
            with open(html_encoding_file, "rb") as fobj:
>               from_string = self.read_html(
                    fobj.read(), encoding=encoding, index_col=0
                ).pop()

pandas/tests/io/test_html.py:1161: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
pandas/util/_decorators.py:299: in wrapper
    return func(*args, **kwargs)
pandas/io/html.py:1081: in read_html
    return _parse(
pandas/io/html.py:909: in _parse
    raise retained
pandas/io/html.py:889: in _parse
    tables = p.parse_tables()
pandas/io/html.py:209: in parse_tables
    tables = self._parse_tables(self._build_doc(), self.match, self.attrs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <pandas.io.html._LxmlFrameParser object at 0x7fc8e4945be0>, doc = <Element table at 0x7fc8e5bd89f0>, match = re.compile('.+'), kwargs = None

    def _parse_tables(self, doc, match, kwargs):
        pattern = match.pattern
    
        # 1. check all descendants for the given pattern and only search tables
        # 2. go up the tree until we find a table
        xpath_expr = f"//table//*[re:test(text(), {repr(pattern)})]/ancestor::table"
    
        # if any table attributes were given build an xpath expression to
        # search for them
        if kwargs:
            xpath_expr += _build_xpath_expr(kwargs)
    
        tables = doc.xpath(xpath_expr, namespaces=_re_namespace)
    
        tables = self._handle_hidden_tables(tables, "attrib")
        if self.displayed_only:
            for table in tables:
                # lxml utilizes XPATH 1.0 which does not have regex
                # support. As a result, we find all elements with a style
                # attribute and iterate them to check for display:none
                for elem in table.xpath(".//*[@style]"):
                    if "display:none" in elem.attrib.get("style", "").replace(" ", ""):
                        elem.getparent().remove(elem)
    
        if not tables:
>           raise ValueError(f"No tables found matching regex {repr(pattern)}")
E           ValueError: No tables found matching regex '.+'

pandas/io/html.py:680: ValueError
_____________________________________________________________________________________________ TestS3.test_write_s3_csv_fails _____________________________________________________________________________________________

self = <pandas.tests.io.parser.test_network.TestS3 object at 0x7fc928538640>
tips_df =      total_bill   tip     sex smoker   day    time  size
0         16.99  1.01  Female     No   Sun  Dinner     2
1   ....75    Male     No   Sat  Dinner     2
243       18.78  3.00  Female     No  Thur  Dinner     2

[244 rows x 7 columns]
s3so = {'client_kwargs': {'endpoint_url': 'http://127.0.0.1:5555/'}}

    def test_write_s3_csv_fails(self, tips_df, s3so):
        # GH 32486
        # Attempting to write to an invalid S3 path should raise
        import botocore
    
        # GH 34087
        # https://boto3.amazonaws.com/v1/documentation/api/latest/guide/error-handling.html
        # Catch a ClientError since AWS Service Errors are defined dynamically
        error = (FileNotFoundError, botocore.exceptions.ClientError)
    
        with pytest.raises(error, match="The specified bucket does not exist"):
>           tips_df.to_csv(
                "s3://an_s3_bucket_data_doesnt_exit/not_real.csv", storage_options=s3so
            )
E           Failed: DID NOT RAISE (<class 'FileNotFoundError'>, <class 'botocore.exceptions.ClientError'>)

pandas/tests/io/parser/test_network.py:223: Failed
___________________________________________________________________________________________ TestS3.test_write_s3_parquet_fails ___________________________________________________________________________________________

self = <pandas.tests.io.parser.test_network.TestS3 object at 0x7fc914bcec70>
tips_df =      total_bill   tip     sex smoker   day    time  size
0         16.99  1.01  Female     No   Sun  Dinner     2
1   ....75    Male     No   Sat  Dinner     2
243       18.78  3.00  Female     No  Thur  Dinner     2

[244 rows x 7 columns]
s3so = {'client_kwargs': {'endpoint_url': 'http://127.0.0.1:5555/'}}

    @td.skip_if_no("pyarrow")
    def test_write_s3_parquet_fails(self, tips_df, s3so):
        # GH 27679
        # Attempting to write to an invalid S3 path should raise
        import botocore
    
        # GH 34087
        # https://boto3.amazonaws.com/v1/documentation/api/latest/guide/error-handling.html
        # Catch a ClientError since AWS Service Errors are defined dynamically
        error = (FileNotFoundError, botocore.exceptions.ClientError)
    
        with pytest.raises(error, match="The specified bucket does not exist"):
>           tips_df.to_parquet(
                "s3://an_s3_bucket_data_doesnt_exit/not_real.parquet",
                storage_options=s3so,
            )
E           Failed: DID NOT RAISE (<class 'FileNotFoundError'>, <class 'botocore.exceptions.ClientError'>)

pandas/tests/io/parser/test_network.py:239: Failed
________________________________________________________________________________________ TestDataFrameColor.test_invalid_colormap ________________________________________________________________________________________

self = <pandas.tests.plotting.frame.test_frame_color.TestDataFrameColor object at 0x7fc8aba3faf0>

    def test_invalid_colormap(self):
        df = DataFrame(np.random.randn(3, 2), columns=["A", "B"])
        msg = (
            "'invalid_colormap' is not a valid value for name; supported values are "
            "'Accent', 'Accent_r', 'Blues', 'Blues_r', 'BrBG', 'BrBG_r', 'BuGn', "
            "'BuGn_r', 'BuPu', 'BuPu_r', 'CMRmap', 'CMRmap_r', 'Dark2', 'Dark2_r', "
            "'GnBu', 'GnBu_r', 'Greens', 'Greens_r', 'Greys', 'Greys_r', 'OrRd', "
            "'OrRd_r', 'Oranges', 'Oranges_r', 'PRGn', 'PRGn_r', 'Paired', "
            "'Paired_r', 'Pastel1', 'Pastel1_r', 'Pastel2', 'Pastel2_r', 'PiYG', "
            "'PiYG_r', 'PuBu', 'PuBuGn', 'PuBuGn_r', 'PuBu_r', 'PuOr', 'PuOr_r', "
            "'PuRd', 'PuRd_r', 'Purples', 'Purples_r', 'RdBu', 'RdBu_r', 'RdGy', "
            "'RdGy_r', 'RdPu', 'RdPu_r', 'RdYlBu', 'RdYlBu_r', 'RdYlGn', "
            "'RdYlGn_r', 'Reds', 'Reds_r', 'Set1', 'Set1_r', 'Set2', 'Set2_r', "
            "'Set3', 'Set3_r', 'Spectral', 'Spectral_r', 'Wistia', 'Wistia_r', "
            "'YlGn', 'YlGnBu', 'YlGnBu_r', 'YlGn_r', 'YlOrBr', 'YlOrBr_r', "
            "'YlOrRd', 'YlOrRd_r', 'afmhot', 'afmhot_r', 'autumn', 'autumn_r', "
            "'binary', 'binary_r', 'bone', 'bone_r', 'brg', 'brg_r', 'bwr', "
            "'bwr_r', 'cividis', 'cividis_r', 'cool', 'cool_r', 'coolwarm', "
            "'coolwarm_r', 'copper', 'copper_r', 'cubehelix', 'cubehelix_r', "
            "'flag', 'flag_r', 'gist_earth', 'gist_earth_r', 'gist_gray', "
            "'gist_gray_r', 'gist_heat', 'gist_heat_r', 'gist_ncar', "
            "'gist_ncar_r', 'gist_rainbow', 'gist_rainbow_r', 'gist_stern', "
            "'gist_stern_r', 'gist_yarg', 'gist_yarg_r', 'gnuplot', 'gnuplot2', "
            "'gnuplot2_r', 'gnuplot_r', 'gray', 'gray_r', 'hot', 'hot_r', 'hsv', "
            "'hsv_r', 'inferno', 'inferno_r', 'jet', 'jet_r', 'magma', 'magma_r', "
            "'nipy_spectral', 'nipy_spectral_r', 'ocean', 'ocean_r', 'pink', "
            "'pink_r', 'plasma', 'plasma_r', 'prism', 'prism_r', 'rainbow', "
            "'rainbow_r', 'seismic', 'seismic_r', 'spring', 'spring_r', 'summer', "
            "'summer_r', 'tab10', 'tab10_r', 'tab20', 'tab20_r', 'tab20b', "
            "'tab20b_r', 'tab20c', 'tab20c_r', 'terrain', 'terrain_r', 'turbo', "
            "'turbo_r', 'twilight', 'twilight_r', 'twilight_shifted', "
            "'twilight_shifted_r', 'viridis', 'viridis_r', 'winter', 'winter_r'"
        )
        with pytest.raises(ValueError, match=msg):
>           df.plot(colormap="invalid_colormap")

pandas/tests/plotting/frame/test_frame_color.py:685: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <pandas.plotting._core.PlotAccessor object at 0x7fc8abaa4c10>, args = (), kwargs = {'ax': None, 'colormap': 'invalid_colormap', 'figsize': None, 'fontsize': None, ...}
plot_backend = <module 'pandas.plotting._matplotlib' from '/home/micael/projects/pandas-MicaelJarniac/pandas/plotting/_matplotlib/__init__.py'>, x = None, y = None, kind = 'line'
data =           A         B
0  0.509784  1.251911
1  2.500527 -0.462616
2  0.737699  0.756503, data_cols = Index(['A', 'B'], dtype='object')

    def __call__(self, *args, **kwargs):
        plot_backend = _get_plot_backend(kwargs.pop("backend", None))
    
        x, y, kind, kwargs = self._get_call_args(
            plot_backend.__name__, self._parent, args, kwargs
        )
    
        kind = self._kind_aliases.get(kind, kind)
    
        # when using another backend, get out of the way
        if plot_backend.__name__ != "pandas.plotting._matplotlib":
            return plot_backend.plot(self._parent, x=x, y=y, kind=kind, **kwargs)
    
        if kind not in self._all_kinds:
            raise ValueError(f"{kind} is not a valid plot kind")
    
        # The original data structured can be transformed before passed to the
        # backend. For example, for DataFrame is common to set the index as the
        # `x` parameter, and return a Series with the parameter `y` as values.
        data = self._parent.copy()
    
        if isinstance(data, ABCSeries):
            kwargs["reuse_plot"] = True
    
        if kind in self._dataframe_kinds:
            if isinstance(data, ABCDataFrame):
                return plot_backend.plot(data, x=x, y=y, kind=kind, **kwargs)
            else:
                raise ValueError(f"plot kind {kind} can only be used for data frames")
        elif kind in self._series_kinds:
            if isinstance(data, ABCDataFrame):
                if y is None and kwargs.get("subplots") is False:
                    raise ValueError(
                        f"{kind} requires either y column or 'subplots=True'"
                    )
                elif y is not None:
                    if is_integer(y) and not data.columns.holds_integer():
                        y = data.columns[y]
                    # converted to series actually. copy to not modify
                    data = data[y].copy()
                    data.index.name = y
        elif isinstance(data, ABCDataFrame):
            data_cols = data.columns
            if x is not None:
                if is_integer(x) and not data.columns.holds_integer():
                    x = data_cols[x]
                elif not isinstance(data[x], ABCSeries):
                    raise ValueError("x must be a label or position")
                data = data.set_index(x)
            if y is not None:
                # check if we have y as int or list of ints
                int_ylist = is_list_like(y) and all(is_integer(c) for c in y)
                int_y_arg = is_integer(y) or int_ylist
                if int_y_arg and not data.columns.holds_integer():
                    y = data_cols[y]
    
                label_kw = kwargs["label"] if "label" in kwargs else False
                for kw in ["xerr", "yerr"]:
                    if kw in kwargs and (
                        isinstance(kwargs[kw], str) or is_integer(kwargs[kw])
                    ):
                        try:
                            kwargs[kw] = data[kwargs[kw]]
                        except (IndexError, KeyError, TypeError):
                            pass
    
                # don't overwrite
                data = data[y].copy()
    
                if isinstance(data, ABCSeries):
                    label_name = label_kw or y
                    data.name = label_name
                else:
                    match = is_list_like(label_kw) and len(label_kw) == len(y)
                    if label_kw and not match:
                        raise ValueError(
                            "label should be list-like and same length as y"
                        )
                    label_name = label_kw or data.columns
                    data.columns = label_name
    
>       return plot_backend.plot(data, kind=kind, **kwargs)

pandas/plotting/_core.py:959: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

data =           A         B
0  0.509784  1.251911
1  2.500527 -0.462616
2  0.737699  0.756503, kind = 'line', kwargs = {'ax': None, 'colormap': 'invalid_colormap', 'figsize': None, 'fontsize': None, ...}
plt = <module 'matplotlib.pyplot' from '/home/micael/projects/pandas-MicaelJarniac/env/lib/python3.8/site-packages/matplotlib/pyplot.py'>, plot_obj = <pandas.plotting._matplotlib.core.LinePlot object at 0x7fc8abaaa0a0>

    def plot(data, kind, **kwargs):
        # Importing pyplot at the top of the file (before the converters are
        # registered) causes problems in matplotlib 2 (converters seem to not
        # work)
        import matplotlib.pyplot as plt
    
        if kwargs.pop("reuse_plot", False):
            ax = kwargs.get("ax")
            if ax is None and len(plt.get_fignums()) > 0:
                with plt.rc_context():
                    ax = plt.gca()
                kwargs["ax"] = getattr(ax, "left_ax", ax)
        plot_obj = PLOT_CLASSES[kind](data, **kwargs)
>       plot_obj.generate()

pandas/plotting/_matplotlib/__init__.py:61: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <pandas.plotting._matplotlib.core.LinePlot object at 0x7fc8abaaa0a0>

    def generate(self):
        self._args_adjust()
        self._compute_plot_data()
        self._setup_subplots()
>       self._make_plot()

pandas/plotting/_matplotlib/core.py:279: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <pandas.plotting._matplotlib.core.LinePlot object at 0x7fc8abaaa0a0>

    def _make_plot(self):
        if self._is_ts_plot():
            data = maybe_convert_index(self._get_ax(0), self.data)
    
            x = data.index  # dummy, not used
            plotf = self._ts_plot
            it = self._iter_data(data=data, keep_index=True)
        else:
            x = self._get_xticks(convert_period=True)
            # pandas\plotting\_matplotlib\core.py:1100: error: Incompatible
            # types in assignment (expression has type "Callable[[Any, Any,
            # Any, Any, Any, Any, KwArg(Any)], Any]", variable has type
            # "Callable[[Any, Any, Any, Any, KwArg(Any)], Any]")  [assignment]
            plotf = self._plot  # type: ignore[assignment]
            it = self._iter_data()
    
        stacking_id = self._get_stacking_id()
        is_errorbar = com.any_not_none(*self.errors.values())
    
>       colors = self._get_colors()

pandas/plotting/_matplotlib/core.py:1136: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <pandas.plotting._matplotlib.core.LinePlot object at 0x7fc8abaaa0a0>, num_colors = 2, color_kwds = 'color'

    def _get_colors(self, num_colors=None, color_kwds="color"):
        if num_colors is None:
            num_colors = self.nseries
    
>       return get_standard_colors(
            num_colors=num_colors,
            colormap=self.colormap,
            color=self.kwds.get(color_kwds),
        )

pandas/plotting/_matplotlib/core.py:783: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

num_colors = 2, colormap = 'invalid_colormap', color_type = 'default', color = None

    def get_standard_colors(
        num_colors: int,
        colormap: Optional["Colormap"] = None,
        color_type: str = "default",
        color: Optional[Union[Dict[str, Color], Color, Collection[Color]]] = None,
    ):
        """
        Get standard colors based on `colormap`, `color_type` or `color` inputs.
    
        Parameters
        ----------
        num_colors : int
            Minimum number of colors to be returned.
            Ignored if `color` is a dictionary.
        colormap : :py:class:`matplotlib.colors.Colormap`, optional
            Matplotlib colormap.
            When provided, the resulting colors will be derived from the colormap.
        color_type : {"default", "random"}, optional
            Type of colors to derive. Used if provided `color` and `colormap` are None.
            Ignored if either `color` or `colormap` are not None.
        color : dict or str or sequence, optional
            Color(s) to be used for deriving sequence of colors.
            Can be either be a dictionary, or a single color (single color string,
            or sequence of floats representing a single color),
            or a sequence of colors.
    
        Returns
        -------
        dict or list
            Standard colors. Can either be a mapping if `color` was a dictionary,
            or a list of colors with a length of `num_colors` or more.
    
        Warns
        -----
        UserWarning
            If both `colormap` and `color` are provided.
            Parameter `color` will override.
        """
        if isinstance(color, dict):
            return color
    
>       colors = _derive_colors(
            color=color,
            colormap=colormap,
            color_type=color_type,
            num_colors=num_colors,
        )

pandas/plotting/_matplotlib/style.py:71: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    def _derive_colors(
        *,
        color: Optional[Union[Color, Collection[Color]]],
        colormap: Optional[Union[str, "Colormap"]],
        color_type: str,
        num_colors: int,
    ) -> List[Color]:
        """
        Derive colors from either `colormap`, `color_type` or `color` inputs.
    
        Get a list of colors either from `colormap`, or from `color`,
        or from `color_type` (if both `colormap` and `color` are None).
    
        Parameters
        ----------
        color : str or sequence, optional
            Color(s) to be used for deriving sequence of colors.
            Can be either be a single color (single color string, or sequence of floats
            representing a single color), or a sequence of colors.
        colormap : :py:class:`matplotlib.colors.Colormap`, optional
            Matplotlib colormap.
            When provided, the resulting colors will be derived from the colormap.
        color_type : {"default", "random"}, optional
            Type of colors to derive. Used if provided `color` and `colormap` are None.
            Ignored if either `color` or `colormap`` are not None.
        num_colors : int
            Number of colors to be extracted.
    
        Returns
        -------
        list
            List of colors extracted.
    
        Warns
        -----
        UserWarning
            If both `colormap` and `color` are provided.
            Parameter `color` will override.
        """
        if color is None and colormap is not None:
>           return _get_colors_from_colormap(colormap, num_colors=num_colors)

pandas/plotting/_matplotlib/style.py:121: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

colormap = 'invalid_colormap', num_colors = 2

    def _get_colors_from_colormap(
        colormap: Union[str, "Colormap"],
        num_colors: int,
    ) -> List[Color]:
        """Get colors from colormap."""
>       colormap = _get_cmap_instance(colormap)

pandas/plotting/_matplotlib/style.py:147: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

colormap = 'invalid_colormap'

    def _get_cmap_instance(colormap: Union[str, "Colormap"]) -> "Colormap":
        """Get instance of matplotlib colormap."""
        if isinstance(colormap, str):
            cmap = colormap
>           colormap = cm.get_cmap(colormap)

pandas/plotting/_matplotlib/style.py:155: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

name = 'invalid_colormap', lut = None

    def get_cmap(name=None, lut=None):
        """
        Get a colormap instance, defaulting to rc values if *name* is None.
    
        Colormaps added with :func:`register_cmap` take precedence over
        built-in colormaps.
    
        Notes
        -----
        Currently, this returns the global colormap object, which is deprecated.
        In Matplotlib 3.5, you will no longer be able to modify the global
        colormaps in-place.
    
        Parameters
        ----------
        name : `matplotlib.colors.Colormap` or str or None, default: None
            If a `.Colormap` instance, it will be returned. Otherwise, the name of
            a colormap known to Matplotlib, which will be resampled by *lut*. The
            default, None, means :rc:`image.cmap`.
        lut : int or None, default: None
            If *name* is not already a Colormap instance and *lut* is not None, the
            colormap will be resampled to have *lut* entries in the lookup table.
        """
        if name is None:
            name = mpl.rcParams['image.cmap']
        if isinstance(name, colors.Colormap):
            return name
>       cbook._check_in_list(sorted(_cmap_registry), name=name)

env/lib/python3.8/site-packages/matplotlib/cm.py:204: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

_values = ['Accent', 'Accent_r', 'Blues', 'Blues_r', 'BrBG', 'BrBG_r', ...], kwargs = {'name': 'invalid_colormap'}, values = ['Accent', 'Accent_r', 'Blues', 'Blues_r', 'BrBG', 'BrBG_r', ...], k = 'name'
v = 'invalid_colormap'

    def _check_in_list(_values, **kwargs):
        """
        For each *key, value* pair in *kwargs*, check that *value* is in *_values*;
        if not, raise an appropriate ValueError.
    
        Examples
        --------
        >>> cbook._check_in_list(["foo", "bar"], arg=arg, other_arg=other_arg)
        """
        values = _values
        for k, v in kwargs.items():
            if v not in values:
>               raise ValueError(
                    "{!r} is not a valid value for {}; supported values are {}"
                    .format(v, k, ', '.join(map(repr, values))))
E               ValueError: 'invalid_colormap' is not a valid value for name; supported values are 'Accent', 'Accent_r', 'Blues', 'Blues_r', 'BrBG', 'BrBG_r', 'BuGn', 'BuGn_r', 'BuPu', 'BuPu_r', 'CMRmap', 'CMRmap_r', 'Dark2', 'Dark2_r', 'GnBu', 'GnBu_r', 'Greens', 'Greens_r', 'Greys', 'Greys_r', 'OrRd', 'OrRd_r', 'Oranges', 'Oranges_r', 'PRGn', 'PRGn_r', 'Paired', 'Paired_r', 'Pastel1', 'Pastel1_r', 'Pastel2', 'Pastel2_r', 'PiYG', 'PiYG_r', 'PuBu', 'PuBuGn', 'PuBuGn_r', 'PuBu_r', 'PuOr', 'PuOr_r', 'PuRd', 'PuRd_r', 'Purples', 'Purples_r', 'RdBu', 'RdBu_r', 'RdGy', 'RdGy_r', 'RdPu', 'RdPu_r', 'RdYlBu', 'RdYlBu_r', 'RdYlGn', 'RdYlGn_r', 'Reds', 'Reds_r', 'Set1', 'Set1_r', 'Set2', 'Set2_r', 'Set3', 'Set3_r', 'Spectral', 'Spectral_r', 'Wistia', 'Wistia_r', 'YlGn', 'YlGnBu', 'YlGnBu_r', 'YlGn_r', 'YlOrBr', 'YlOrBr_r', 'YlOrRd', 'YlOrRd_r', 'afmhot', 'afmhot_r', 'autumn', 'autumn_r', 'binary', 'binary_r', 'bone', 'bone_r', 'brg', 'brg_r', 'bwr', 'bwr_r', 'cividis', 'cividis_r', 'cool', 'cool_r', 'coolwarm', 'coolwarm_r', 'copper', 'copper_r', 'crest', 'crest_r', 'cubehelix', 'cubehelix_r', 'flag', 'flag_r', 'flare', 'flare_r', 'gist_earth', 'gist_earth_r', 'gist_gray', 'gist_gray_r', 'gist_heat', 'gist_heat_r', 'gist_ncar', 'gist_ncar_r', 'gist_rainbow', 'gist_rainbow_r', 'gist_stern', 'gist_stern_r', 'gist_yarg', 'gist_yarg_r', 'gnuplot', 'gnuplot2', 'gnuplot2_r', 'gnuplot_r', 'gray', 'gray_r', 'hot', 'hot_r', 'hsv', 'hsv_r', 'icefire', 'icefire_r', 'inferno', 'inferno_r', 'jet', 'jet_r', 'magma', 'magma_r', 'mako', 'mako_r', 'nipy_spectral', 'nipy_spectral_r', 'ocean', 'ocean_r', 'pink', 'pink_r', 'plasma', 'plasma_r', 'prism', 'prism_r', 'rainbow', 'rainbow_r', 'rocket', 'rocket_r', 'seismic', 'seismic_r', 'spring', 'spring_r', 'summer', 'summer_r', 'tab10', 'tab10_r', 'tab20', 'tab20_r', 'tab20b', 'tab20b_r', 'tab20c', 'tab20c_r', 'terrain', 'terrain_r', 'turbo', 'turbo_r', 'twilight', 'twilight_r', 'twilight_shifted', 'twilight_shifted_r', 'viridis', 'viridis_r', 'vlag', 'vlag_r', 'winter', 'winter_r'

env/lib/python3.8/site-packages/matplotlib/cbook/__init__.py:2266: ValueError

During handling of the above exception, another exception occurred:

self = <pandas.tests.plotting.frame.test_frame_color.TestDataFrameColor object at 0x7fc8aba3faf0>

    def test_invalid_colormap(self):
        df = DataFrame(np.random.randn(3, 2), columns=["A", "B"])
        msg = (
            "'invalid_colormap' is not a valid value for name; supported values are "
            "'Accent', 'Accent_r', 'Blues', 'Blues_r', 'BrBG', 'BrBG_r', 'BuGn', "
            "'BuGn_r', 'BuPu', 'BuPu_r', 'CMRmap', 'CMRmap_r', 'Dark2', 'Dark2_r', "
            "'GnBu', 'GnBu_r', 'Greens', 'Greens_r', 'Greys', 'Greys_r', 'OrRd', "
            "'OrRd_r', 'Oranges', 'Oranges_r', 'PRGn', 'PRGn_r', 'Paired', "
            "'Paired_r', 'Pastel1', 'Pastel1_r', 'Pastel2', 'Pastel2_r', 'PiYG', "
            "'PiYG_r', 'PuBu', 'PuBuGn', 'PuBuGn_r', 'PuBu_r', 'PuOr', 'PuOr_r', "
            "'PuRd', 'PuRd_r', 'Purples', 'Purples_r', 'RdBu', 'RdBu_r', 'RdGy', "
            "'RdGy_r', 'RdPu', 'RdPu_r', 'RdYlBu', 'RdYlBu_r', 'RdYlGn', "
            "'RdYlGn_r', 'Reds', 'Reds_r', 'Set1', 'Set1_r', 'Set2', 'Set2_r', "
            "'Set3', 'Set3_r', 'Spectral', 'Spectral_r', 'Wistia', 'Wistia_r', "
            "'YlGn', 'YlGnBu', 'YlGnBu_r', 'YlGn_r', 'YlOrBr', 'YlOrBr_r', "
            "'YlOrRd', 'YlOrRd_r', 'afmhot', 'afmhot_r', 'autumn', 'autumn_r', "
            "'binary', 'binary_r', 'bone', 'bone_r', 'brg', 'brg_r', 'bwr', "
            "'bwr_r', 'cividis', 'cividis_r', 'cool', 'cool_r', 'coolwarm', "
            "'coolwarm_r', 'copper', 'copper_r', 'cubehelix', 'cubehelix_r', "
            "'flag', 'flag_r', 'gist_earth', 'gist_earth_r', 'gist_gray', "
            "'gist_gray_r', 'gist_heat', 'gist_heat_r', 'gist_ncar', "
            "'gist_ncar_r', 'gist_rainbow', 'gist_rainbow_r', 'gist_stern', "
            "'gist_stern_r', 'gist_yarg', 'gist_yarg_r', 'gnuplot', 'gnuplot2', "
            "'gnuplot2_r', 'gnuplot_r', 'gray', 'gray_r', 'hot', 'hot_r', 'hsv', "
            "'hsv_r', 'inferno', 'inferno_r', 'jet', 'jet_r', 'magma', 'magma_r', "
            "'nipy_spectral', 'nipy_spectral_r', 'ocean', 'ocean_r', 'pink', "
            "'pink_r', 'plasma', 'plasma_r', 'prism', 'prism_r', 'rainbow', "
            "'rainbow_r', 'seismic', 'seismic_r', 'spring', 'spring_r', 'summer', "
            "'summer_r', 'tab10', 'tab10_r', 'tab20', 'tab20_r', 'tab20b', "
            "'tab20b_r', 'tab20c', 'tab20c_r', 'terrain', 'terrain_r', 'turbo', "
            "'turbo_r', 'twilight', 'twilight_r', 'twilight_shifted', "
            "'twilight_shifted_r', 'viridis', 'viridis_r', 'winter', 'winter_r'"
        )
        with pytest.raises(ValueError, match=msg):
>           df.plot(colormap="invalid_colormap")
E           AssertionError: Regex pattern "'invalid_colormap' is not a valid value for name; supported values are 'Accent', 'Accent_r', 'Blues', 'Blues_r', 'BrBG', 'BrBG_r', 'BuGn', 'BuGn_r', 'BuPu', 'BuPu_r', 'CMRmap', 'CMRmap_r', 'Dark2', 'Dark2_r', 'GnBu', 'GnBu_r', 'Greens', 'Greens_r', 'Greys', 'Greys_r', 'OrRd', 'OrRd_r', 'Oranges', 'Oranges_r', 'PRGn', 'PRGn_r', 'Paired', 'Paired_r', 'Pastel1', 'Pastel1_r', 'Pastel2', 'Pastel2_r', 'PiYG', 'PiYG_r', 'PuBu', 'PuBuGn', 'PuBuGn_r', 'PuBu_r', 'PuOr', 'PuOr_r', 'PuRd', 'PuRd_r', 'Purples', 'Purples_r', 'RdBu', 'RdBu_r', 'RdGy', 'RdGy_r', 'RdPu', 'RdPu_r', 'RdYlBu', 'RdYlBu_r', 'RdYlGn', 'RdYlGn_r', 'Reds', 'Reds_r', 'Set1', 'Set1_r', 'Set2', 'Set2_r', 'Set3', 'Set3_r', 'Spectral', 'Spectral_r', 'Wistia', 'Wistia_r', 'YlGn', 'YlGnBu', 'YlGnBu_r', 'YlGn_r', 'YlOrBr', 'YlOrBr_r', 'YlOrRd', 'YlOrRd_r', 'afmhot', 'afmhot_r', 'autumn', 'autumn_r', 'binary', 'binary_r', 'bone', 'bone_r', 'brg', 'brg_r', 'bwr', 'bwr_r', 'cividis', 'cividis_r', 'cool', 'cool_r', 'coolwarm', 'coolwarm_r', 'copper', 'copper_r', 'cubehelix', 'cubehelix_r', 'flag', 'flag_r', 'gist_earth', 'gist_earth_r', 'gist_gray', 'gist_gray_r', 'gist_heat', 'gist_heat_r', 'gist_ncar', 'gist_ncar_r', 'gist_rainbow', 'gist_rainbow_r', 'gist_stern', 'gist_stern_r', 'gist_yarg', 'gist_yarg_r', 'gnuplot', 'gnuplot2', 'gnuplot2_r', 'gnuplot_r', 'gray', 'gray_r', 'hot', 'hot_r', 'hsv', 'hsv_r', 'inferno', 'inferno_r', 'jet', 'jet_r', 'magma', 'magma_r', 'nipy_spectral', 'nipy_spectral_r', 'ocean', 'ocean_r', 'pink', 'pink_r', 'plasma', 'plasma_r', 'prism', 'prism_r', 'rainbow', 'rainbow_r', 'seismic', 'seismic_r', 'spring', 'spring_r', 'summer', 'summer_r', 'tab10', 'tab10_r', 'tab20', 'tab20_r', 'tab20b', 'tab20b_r', 'tab20c', 'tab20c_r', 'terrain', 'terrain_r', 'turbo', 'turbo_r', 'twilight', 'twilight_r', 'twilight_shifted', 'twilight_shifted_r', 'viridis', 'viridis_r', 'winter', 'winter_r'" does not match "'invalid_colormap' is not a valid value for name; supported values are 'Accent', 'Accent_r', 'Blues', 'Blues_r', 'BrBG', 'BrBG_r', 'BuGn', 'BuGn_r', 'BuPu', 'BuPu_r', 'CMRmap', 'CMRmap_r', 'Dark2', 'Dark2_r', 'GnBu', 'GnBu_r', 'Greens', 'Greens_r', 'Greys', 'Greys_r', 'OrRd', 'OrRd_r', 'Oranges', 'Oranges_r', 'PRGn', 'PRGn_r', 'Paired', 'Paired_r', 'Pastel1', 'Pastel1_r', 'Pastel2', 'Pastel2_r', 'PiYG', 'PiYG_r', 'PuBu', 'PuBuGn', 'PuBuGn_r', 'PuBu_r', 'PuOr', 'PuOr_r', 'PuRd', 'PuRd_r', 'Purples', 'Purples_r', 'RdBu', 'RdBu_r', 'RdGy', 'RdGy_r', 'RdPu', 'RdPu_r', 'RdYlBu', 'RdYlBu_r', 'RdYlGn', 'RdYlGn_r', 'Reds', 'Reds_r', 'Set1', 'Set1_r', 'Set2', 'Set2_r', 'Set3', 'Set3_r', 'Spectral', 'Spectral_r', 'Wistia', 'Wistia_r', 'YlGn', 'YlGnBu', 'YlGnBu_r', 'YlGn_r', 'YlOrBr', 'YlOrBr_r', 'YlOrRd', 'YlOrRd_r', 'afmhot', 'afmhot_r', 'autumn', 'autumn_r', 'binary', 'binary_r', 'bone', 'bone_r', 'brg', 'brg_r', 'bwr', 'bwr_r', 'cividis', 'cividis_r', 'cool', 'cool_r', 'coolwarm', 'coolwarm_r', 'copper', 'copper_r', 'crest', 'crest_r', 'cubehelix', 'cubehelix_r', 'flag', 'flag_r', 'flare', 'flare_r', 'gist_earth', 'gist_earth_r', 'gist_gray', 'gist_gray_r', 'gist_heat', 'gist_heat_r', 'gist_ncar', 'gist_ncar_r', 'gist_rainbow', 'gist_rainbow_r', 'gist_stern', 'gist_stern_r', 'gist_yarg', 'gist_yarg_r', 'gnuplot', 'gnuplot2', 'gnuplot2_r', 'gnuplot_r', 'gray', 'gray_r', 'hot', 'hot_r', 'hsv', 'hsv_r', 'icefire', 'icefire_r', 'inferno', 'inferno_r', 'jet', 'jet_r', 'magma', 'magma_r', 'mako', 'mako_r', 'nipy_spectral', 'nipy_spectral_r', 'ocean', 'ocean_r', 'pink', 'pink_r', 'plasma', 'plasma_r', 'prism', 'prism_r', 'rainbow', 'rainbow_r', 'rocket', 'rocket_r', 'seismic', 'seismic_r', 'spring', 'spring_r', 'summer', 'summer_r', 'tab10', 'tab10_r', 'tab20', 'tab20_r', 'tab20b', 'tab20b_r', 'tab20c', 'tab20c_r', 'terrain', 'terrain_r', 'turbo', 'turbo_r', 'twilight', 'twilight_r', 'twilight_shifted', 'twilight_shifted_r', 'viridis', 'viridis_r', 'vlag', 'vlag_r', 'winter', 'winter_r'".

pandas/tests/plotting/frame/test_frame_color.py:685: AssertionError
___________________________________________________________________________________________ test_tab_complete_ipython6_warning ___________________________________________________________________________________________

ip = <IPython.core.interactiveshell.InteractiveShell object at 0x7fc8aefd2520>

    @async_mark()
    @td.check_file_leaks
    async def test_tab_complete_ipython6_warning(ip):
        from IPython.core.completer import provisionalcompleter
    
        code = dedent(
            """\
        import pandas._testing as tm
        s = tm.makeTimeSeries()
        rs = s.resample("D")
        """
        )
        await ip.run_code(code)
    
        # TODO: remove it when Ipython updates
        # GH 33567, jedi version raises Deprecation warning in Ipython
        import jedi
    
        if jedi.__version__ < "0.17.0":
            warning = tm.assert_produces_warning(None)
        else:
            warning = tm.assert_produces_warning(DeprecationWarning, check_stacklevel=False)
        with warning:
            with provisionalcompleter("ignore"):
>               list(ip.Completer.completions("rs.", 1))

pandas/tests/resample/test_resampler_grouper.py:44: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
env/lib/python3.8/site-packages/IPython/core/completer.py:1818: in completions
    for c in self._completions(text, offset, _timeout=self.jedi_compute_type_timeout/1000):
env/lib/python3.8/site-packages/IPython/core/completer.py:1861: in _completions
    matched_text, matches, matches_origin, jedi_matches = self._complete(
env/lib/python3.8/site-packages/IPython/core/completer.py:2029: in _complete
    completions = self._jedi_matches(
env/lib/python3.8/site-packages/IPython/core/completer.py:1373: in _jedi_matches
    interpreter = jedi.Interpreter(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <[AttributeError("'Interpreter' object has no attribute '_orig_path'") raised in repr()] Interpreter object at 0x7fc8aeea7400>, code = 'r'
namespaces = [{'In': [''], 'Out': {}, '_': '', '__': '', ...}, {'In': [''], 'Out': {}, '_': '', '__': '', ...}], kwds = {'column': 1, 'line': 1}
environment = <jedi.api.environment.InterpreterEnvironment object at 0x7fc8aeea7ca0>

    def __init__(self, code, namespaces, **kwds):
        try:
            namespaces = [dict(n) for n in namespaces]
        except Exception:
            raise TypeError("namespaces must be a non-empty list of dicts.")
    
        environment = kwds.get('environment', None)
        if environment is None:
            environment = InterpreterEnvironment()
        else:
            if not isinstance(environment, InterpreterEnvironment):
                raise TypeError("The environment needs to be an InterpreterEnvironment subclass.")
    
>       super().__init__(code, environment=environment,
                         project=Project(Path.cwd()), **kwds)
E       TypeError: __init__() got an unexpected keyword argument 'column'

env/lib/python3.8/site-packages/jedi/api/__init__.py:725: TypeError
==================================================================================================== warnings summary ====================================================================================================
pandas/tests/io/parser/test_index_col.py::test_index_col_large_csv[c_high]
pandas/tests/io/parser/test_index_col.py::test_index_col_large_csv[c_low]
pandas/tests/series/methods/test_isin.py::test_isin_large_series_mixed_dtypes_and_nan
  /home/micael/projects/pandas-MicaelJarniac/env/lib/python3.8/site-packages/numpy/lib/arraysetops.py:580: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison
    mask |= (ar1 == a)

pandas/tests/scalar/timedelta/test_arithmetic.py::TestTimedeltaMultiplicationDivision::test_td_div_nan[nan1]
  /home/micael/projects/pandas-MicaelJarniac/pandas/tests/scalar/timedelta/test_arithmetic.py:445: RuntimeWarning: invalid value encountered in double_scalars
    result = td // nan

-- Docs: https://docs.pytest.org/en/stable/warnings.html
================================================================================================ short test summary info =================================================================================================
FAILED pandas/tests/arrays/categorical/test_warnings.py::TestCategoricalWarnings::test_tab_complete_warning - TypeError: __init__() got an unexpected keyword argument 'column'
FAILED pandas/tests/frame/test_api.py::TestDataFrameMisc::test_tab_complete_warning[DataFrame] - TypeError: __init__() got an unexpected keyword argument 'column'
FAILED pandas/tests/frame/test_api.py::TestDataFrameMisc::test_tab_complete_warning[Series] - TypeError: __init__() got an unexpected keyword argument 'column'
FAILED pandas/tests/indexes/test_base.py::TestIndex::test_tab_complete_warning - TypeError: __init__() got an unexpected keyword argument 'column'
FAILED pandas/tests/io/test_html.py::TestReadHtml::test_encode[chinese_utf-16.html-bs4] - UnicodeDecodeError: 'utf-16-le' codec can't decode byte 0x00 in position 850: truncated data
FAILED pandas/tests/io/test_html.py::TestReadHtml::test_encode[chinese_utf-32.html-bs4] - UnicodeDecodeError: 'utf-32-le' codec can't decode bytes in position 192-195: code point not in range(0x110000)
FAILED pandas/tests/io/test_html.py::TestReadHtml::test_encode[chinese_utf-32.html-lxml] - ValueError: No tables found matching regex '.+'
FAILED pandas/tests/io/parser/test_network.py::TestS3::test_write_s3_csv_fails - Failed: DID NOT RAISE (<class 'FileNotFoundError'>, <class 'botocore.exceptions.ClientError'>)
FAILED pandas/tests/io/parser/test_network.py::TestS3::test_write_s3_parquet_fails - Failed: DID NOT RAISE (<class 'FileNotFoundError'>, <class 'botocore.exceptions.ClientError'>)
FAILED pandas/tests/plotting/frame/test_frame_color.py::TestDataFrameColor::test_invalid_colormap - AssertionError: Regex pattern "'invalid_colormap' is not a valid value for name; supported values are 'Accent', 'Ac...
FAILED pandas/tests/resample/test_resampler_grouper.py::test_tab_complete_ipython6_warning - TypeError: __init__() got an unexpected keyword argument 'column'
=========================================================== 11 failed, 151742 passed, 3756 skipped, 1061 xfailed, 5 xpassed, 4 warnings in 2724.45s (0:45:24) ============================================================

I'll run the tests on the master branch and compare the outputs, to see which ones are unique to my branch.

@MicaelJarniac MicaelJarniac marked this pull request as draft January 13, 2021 18:48
@MicaelJarniac
Copy link
Contributor Author

I found one instance where the @doc() decorator was being used with an empty dict, and the documentation that resulted from it actually included the documentation for str, which isn't what was supposed to happen.

I've now modified the fix slightly as to prevent this.

Before:

        decorated.__doc__ = "".join(
            [
                component.format(**params)
                if isinstance(component, str) and params != {}
                else dedent(component.__doc__ or "")
                for component in docstring_components
            ]

After:

        decorated.__doc__ = "".join(
            [
                (component.format(**params) if params != {} else component)
                if isinstance(component, str)
                else dedent(component.__doc__ or "")
                for component in docstring_components
            ]

So now, even if an empty dict is sent as an argument for @doc(), it'll still check if component is a string, and will only skip the .format() part.

What was happening before is that, since @doc() was being used with an empty dict, it was adding component.__doc__ to the docstring, but on this specific case, component was itself a string, so instead of adding the contents of component, it added str.__doc__.

The reason there's this check before using .format() is that, if params is an empty dict, and component happens to include any formatting placeholders ({hi}), that would raise a KeyError.

On this specific docstring, component is a string but didn't have any formatting placeholder, so calling .format() on it with an empty params dict wasn't an issue, and the result was simply that component was added as-is to the docstring, since .format() had nothing to do.

But with the docstring I've been working to fix, component does have formatting placeholders, so without this check it wouldn't work.

I've converted this PR to a draft because I still have to re-run all tests and rebuild the docs since I changed the code again.

@MicaelJarniac
Copy link
Contributor Author

Okay, I've run all tests again, everything seems normal.

Here's the result of pytest on the new branch:

10 failed, 148317 passed, 6247 skipped, 1050 xfailed, 3 xpassed, 1 warning in 1291.63s (0:21:31) 

And on the master branch:

10 failed, 148317 passed, 6247 skipped, 1050 xfailed, 3 xpassed, 1 warning in 1063.60s (0:17:43)

So yeah, there are 10 tests failing, but those tests were failing on master too, without my changes, so I don't believe they're related.

The docs built correctly, and from my inspections everything was in order.

I've also run all pre-commit hooks (and on --all-files too, just to be safe), and everything passed.

And I also compared the output of python scripts/validate_docstrings.py on both the new branch and master, and the only difference is that on the new branch there are 3 fewer documentation errors, all 3 related to the ones I fixed:

- /home/micael/projects/pandas-MicaelJarniac/pandas/core/generic.py:#L#:SS03:pandas.DataFrame.mad:Summary does not end with a period
- None:None:SS03:pandas.core.groupby.DataFrameGroupBy.mad:Summary does not end with a period
- /home/micael/projects/pandas-MicaelJarniac/pandas/core/generic.py:#L#:SS03:pandas.Series.mad:Summary does not end with a period

@MicaelJarniac MicaelJarniac marked this pull request as ready for review January 13, 2021 23:27
@MicaelJarniac MicaelJarniac requested a review from jreback January 13, 2021 23:28
@MicaelJarniac
Copy link
Contributor Author

I've merged master to this branch again. I believe that'll sort out some CI tests not passing here.

On pytest, the results are still the same between master and my branch, but this time they both have 2 fewer fails.

New branch:
8 failed, 148313 passed, 6249 skipped, 1052 xfailed, 3 xpassed, 1 warning in 1023.97s (0:17:03)

master:
8 failed, 148313 passed, 6249 skipped, 1052 xfailed, 3 xpassed, 1 warning in 1191.31s (0:19:51)

@MicaelJarniac
Copy link
Contributor Author

I was thinking about adding tests to catch if {klass}, {desc}, {axis_descr}, {name1}, {name2}, {see_also}, {examples} and similar ends up in final documentation. This should prevent similar issues in the future.

I'm not sure if there's any instance where those are actually supposed to show up like that, but if there are, I don't think they'd be many, so I guess it'd be possible to whitelist (allowlist? passlist?) those specific instances, while having the checks on everything else.

@simonjayhawkins
Copy link
Member

Thanks @MicaelJarniac for the PR.

I think the solution should perhaps be more like...

diff --git a/pandas/util/_decorators.py b/pandas/util/_decorators.py
index d002e8a4eb..91a55d1bf8 100644
--- a/pandas/util/_decorators.py
+++ b/pandas/util/_decorators.py
@@ -372,14 +372,17 @@ def doc(*docstrings: Union[str, Callable], **params) -> Callable[[F], F]:
                 docstring_components.append(docstring)
 
         # formatting templates and concatenating docstring
-        decorated.__doc__ = "".join(
+        docstring = "".join(
             [
-                component.format(**params)
+                component
                 if isinstance(component, str)
                 else dedent(component.__doc__ or "")
                 for component in docstring_components
             ]
         )
+        if params:
+            docstring = docstring.format(**params)
+        decorated.__doc__ = docstring
 
         # error: "F" has no attribute "_docstring_components"
         decorated._docstring_components = (  # type: ignore[attr-defined]

Then we don't need to apply the additional doc decorator while also using the doc decorator to inherit docstrings, e.g.

@doc(ExtensionArray.searchsorted)
    def searchsorted(self, value, side="left", sorter=None):

when no parameters are specified and the inherited docstring contains curly braces, such as

        Parameters
        ----------
        value : array_like
            Values to insert into `self`.
        side : {'left', 'right'}, optional

to prevent KeyError: "'left', 'right'" when no templating is needed

@MicaelJarniac MicaelJarniac marked this pull request as draft January 14, 2021 13:13
@simonjayhawkins
Copy link
Member

@MicaelJarniac a bit of history.

we have @appender and @substition decorators, 177 and 96 usages repspectively.

the @doc decorator was intended to be a replacement for these, currently 189 usages.

The @doc decorator does seem to be causing issues with partial templating and where curly braces appear in the docstring.

I would suspect that any changes to the @doc decorator could cause issues elsewhere and I would be reticent to backport any changes here to fix the broken docs.

An alternative could be to use the legacy @appender and @substition to fix the DataFrame.mad and Series.mad docstrings for now.

@simonjayhawkins
Copy link
Member

IIRC it is also possible for use

       @doc(
            NDFrame.mad.__doc__,
            desc="Return the mean absolute deviation of the values "
            "over the requested axis.",

instead of

       @doc(
            NDFrame.mad,
            desc="Return the mean absolute deviation of the values "
            "over the requested axis.",

to get around the bug. so that would be easier.

@MicaelJarniac
Copy link
Contributor Author

I'll look into those, that does sound like the safest approach for the short term.

And as for the long term, I'll try to think of a way for using the @doc(...) decorator without breaking stuff all over the place. One possibility that comes to mind is using a custom RegEx instead of the built-in .format(...) to fill in the placeholders, as that would give us flexibility as to what should and what shouldn't raise a KeyError when filling templates.

For example, something like:

for placeholder, value in params.items():
    docstring = re.sub("{" + placeholder + "}", value, docstring)

Something like that would mean that only placeholders specifically provided with **params would be replaced, and everything else that just so happens to have curly-braces around it would be left alone, no KeyError needed.

@simonjayhawkins
Copy link
Member

@MicaelJarniac we have a release planned for Monday, so updated this to just fix the Series.mad and DataFrame.mad docstrings for now

Help on function mad in module pandas.core.generic:

mad(self, axis=None, skipna=None, level=None)
    Return the mean absolute deviation of the values over the requested axis.
    
    Parameters
    ----------
    axis : {index (0), columns (1)}
        Axis for the function to be applied on.
    skipna : bool, default None
        Exclude NA/null values when computing the result.
    level : int or level name, default None
        If the axis is a MultiIndex (hierarchical), count along a
        particular level, collapsing into a Series.
    
    Returns
    -------
    Series or DataFrame (if level specified)

@simonjayhawkins
Copy link
Member

and Series.mad


Help on function mad in module pandas.core.generic:

mad(self, axis=None, skipna=None, level=None)
    Return the mean absolute deviation of the values over the requested axis.
    
    Parameters
    ----------
    axis : {index (0)}
        Axis for the function to be applied on.
    skipna : bool, default None
        Exclude NA/null values when computing the result.
    level : int or level name, default None
        If the axis is a MultiIndex (hierarchical), count along a
        particular level, collapsing into a scalar.
    
    Returns
    -------
    scalar or Series (if level specified)

@simonjayhawkins simonjayhawkins marked this pull request as ready for review January 15, 2021 20:47
@simonjayhawkins simonjayhawkins added this to the 1.2.1 milestone Jan 15, 2021
@jreback
Copy link
Contributor

jreback commented Jan 17, 2021

looks ok to me. @simonjayhawkins merge if good; we need a longer term soln right?

@simonjayhawkins
Copy link
Member

we need a longer term soln right?

all the other methods in _add_numeric_operations have the docstring stored as a string variable and are not causing issues. I quite like that the doctstring for mad is in the actual implementation and am therefore happier to add the ignore for mypy for now to keep this issue visible.

@simonjayhawkins
Copy link
Member

Thanks @MicaelJarniac feel free to open another PR with the changes to the @doc decorator that you originally had.

simonjayhawkins pushed a commit that referenced this pull request Jan 17, 2021
luckyvs1 pushed a commit to luckyvs1/pandas that referenced this pull request Jan 20, 2021
nofarm3 pushed a commit to nofarm3/pandas that referenced this pull request Jan 21, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Documentation showing placeholders instead of text
3 participants