miyuchina / mistletoe

A fast, extensible and spec-compliant Markdown parser in pure Python.
MIT License
811 stars 113 forks source link

0.8.2: pytest is failing in `test/test_contrib/test_github_wiki.py::TestGithubWiki::test_parse` unit and `DeprecationWarning` warnings #142

Closed kloczek closed 2 years ago

kloczek commented 2 years ago

I'm trying to package your module as an rpm package. So I'm using the typical PEP517 based build, install and test cycle used on building packages from non-root account.

Here is pytest output:


+ PYTHONPATH=/home/tkloczko/rpmbuild/BUILDROOT/python-mistletoe-0.8.2-2.fc35.x86_64/usr/lib64/python3.8/site-packages:/home/tkloczko/rpmbuild/BUILDROOT/python-mistletoe-0.8.2-2.fc35.x86_64/usr/lib/python3.8/site-packages
+ /usr/bin/pytest -ra
=========================================================================== test session starts ============================================================================
platform linux -- Python 3.8.13, pytest-7.1.1, pluggy-1.0.0
rootdir: /home/tkloczko/rpmbuild/BUILD/mistletoe-0.8.2
collected 208 items

test/test_ast_renderer.py ..                                                                                                                                         [  0%]
test/test_block_token.py ..................................s...........                                                                                              [ 23%]
test/test_cli.py ...............                                                                                                                                     [ 30%]
test/test_core_tokens.py ...........                                                                                                                                 [ 35%]
test/test_html_renderer.py .............................                                                                                                             [ 49%]
test/test_latex_renderer.py ........................                                                                                                                 [ 61%]
test/test_latex_token.py .                                                                                                                                           [ 61%]
test/test_span_token.py ....................                                                                                                                         [ 71%]
test/test_traverse.py .                                                                                                                                              [ 71%]
test/test_contrib/test_github_wiki.py F.                                                                                                                             [ 72%]
test/test_contrib/test_jira_renderer.py ..................................                                                                                           [ 88%]
test/test_contrib/test_mathjax.py ..                                                                                                                                 [ 89%]
test/test_contrib/test_toc_renderer.py ......                                                                                                                        [ 92%]
test/test_contrib/test_xwiki20_renderer.py ...............                                                                                                           [100%]

================================================================================= FAILURES =================================================================================
________________________________________________________________________ TestGithubWiki.test_parse _________________________________________________________________________

self = <test.test_contrib.test_github_wiki.TestGithubWiki testMethod=test_parse>

    def test_parse(self):
        MockRawText = mock.Mock(autospec='mistletoe.span_token.RawText')
        RawText = _token_types.pop()
        _token_types.append(MockRawText)
        try:
            tokens = tokenize_inner('text with [[wiki | target]]')
            token = tokens[1]
            self.assertIsInstance(token, GithubWiki)
            self.assertEqual(token.target, 'target')
>           MockRawText.assert_has_calls([mock.call('text with '), mock.call('wiki')])

test/test_contrib/test_github_wiki.py:23:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <Mock id='140376598689536'>, calls = [call('text with '), call('wiki')], any_order = False

    def assert_has_calls(self, calls, any_order=False):
        """assert the mock has been called with the specified calls.
        The `mock_calls` list is checked for the calls.

        If `any_order` is False (the default) then the calls must be
        sequential. There can be extra calls before or after the
        specified calls.

        If `any_order` is True then the calls can be in any order, but
        they must all appear in `mock_calls`."""
        expected = [self._call_matcher(c) for c in calls]
        cause = next((e for e in expected if isinstance(e, Exception)), None)
        all_calls = _CallList(self._call_matcher(c) for c in self.mock_calls)
        if not any_order:
            if expected not in all_calls:
                if cause is None:
                    problem = 'Calls not found.'
                else:
                    problem = ('Error processing expected calls.\n'
                               'Errors: {}').format(
                                   [e if isinstance(e, Exception) else None
                                    for e in expected])
>               raise AssertionError(
                    f'{problem}\n'
                    f'Expected: {_CallList(calls)}'
                    f'{self._calls_repr(prefix="Actual").rstrip(".")}'
                ) from cause
E               AssertionError: Calls not found.
E               Expected: [call('text with '), call('wiki')]

/usr/lib64/python3.8/unittest/mock.py:950: AssertionError
============================================================================= warnings summary =============================================================================
test/test_span_token.py:102
  /home/tkloczko/rpmbuild/BUILD/mistletoe-0.8.2/test/test_span_token.py:102: DeprecationWarning: invalid escape sequence \*
    self._test_parse(span_token.EscapeSequence, '\*', '*')

test/test_span_token.py:105
  /home/tkloczko/rpmbuild/BUILD/mistletoe-0.8.2/test/test_span_token.py:105: DeprecationWarning: invalid escape sequence \*
    tokens = iter(span_token.tokenize_inner('some \*text*'))

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
========================================================================= short test summary info ==========================================================================
SKIPPED [1] test/test_block_token.py:309: Even GitHub fails in here, workaround: always put a space before `|`
FAILED test/test_contrib/test_github_wiki.py::TestGithubWiki::test_parse - AssertionError: Calls not found.
=========================================================== 1 failed, 206 passed, 1 skipped, 2 warnings in 0.68s ===========================================================
pbodnar commented 2 years ago

@kloczek, thanks for you report.

I have checked and the fact is that the GithubWiki test fails even for older versions of mistletoe. The reason why we haven't noticed this so far is that we use py -m unittest (which can be seen in the "makefile" of this project) instead of the more-attractive py -m pytest here. And while pytest is generally able to run the unittest tests, this one fails for some reason. I guess it might be due to different tests execution order, or due to specific mocking approach in this test method, or maybe both - help in investigation is welcome. It looks like the mock of RawText gets created, yet the original class gets used within the test...

Regarding deprecation warnings on invalid escape sequences, this seems to be an unrelated problem which can be fixed easily, so I think I can do that soon.

Note: Regarding reproduction of this issue, it looks like simply cloning mistletoe from GitHub and running the python3 -m pytest command is sufficient.

kloczek commented 2 years ago

The reason why we haven't noticed this so far is that we use py -m unittest (which can be seen in the "makefile" of this project) instead of the more-attractive py -m pytest here.

BTW unittest or pytest never should be used as python -m foo because when module is used that way pythons automatically adds current directory to os.path. This why there are pytest and unittest scripts which internally iimports those modules and executes the test suite framework code.

pbodnar commented 2 years ago

@kloczek, OK, yet I can't see what the exact problem can be when calling python -m foo in this project. According to the latest pytest docs, it is a supported way:

This is almost equivalent to invoking the command line script pytest [...] directly, except that calling via python will also add the current directory to sys.path.


Anyway, if some "Python testing guru" could tell why the test GithubWiki fails when run via pytest, it would be great, even though I guess it is not of that high priority...

kloczek commented 2 years ago

You can ask on pytest discussin forum https://github.com/pytest-dev/pytest/discussions

pbodnar commented 2 years ago

Fixed by #153, merged into master.