Skip to content
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

Imports from _speedups have side effects #344

Closed
b-kamphorst opened this issue Jan 6, 2023 · 1 comment
Closed

Imports from _speedups have side effects #344

b-kamphorst opened this issue Jan 6, 2023 · 1 comment

Comments

@b-kamphorst
Copy link

b-kamphorst commented Jan 6, 2023

Description

It appears that (binary!) imports from markupsafe._speedups have side-effects in a pylint invocation. The file that is linted attempts to import a missing package in a try-except clause. A common invocation of pylint produces empty (plug-in) reports if markupsafe is imported before pylint is linting (e.g. imported by a pylint plugin). However, output is produced as expected if either:

  • the missing import is installed; or
  • the try block is replaced by a non-import statement (e.g. raise ValueError); or
  • markupsafe.__init__ is modified to prefer imports from markupsafe._native; or
  • one imports a Cython package, e.g. ormsgpack, instead of markupsafe.

The first two observations may help in determining the root issue, but are not the problem themselves. The second two observations are what made me report the issue at MarkupSafe, as that suggests that the issue is specific to this package. However: I don't know where the root cause is, so I'm submitting this issue to both MarkupSafe and Pylint and trust that the community has a more complete understanding of the powers at play.

The issue at Pylint (copy of this issue): pylint-dev/pylint#8026.

This issue lies at the root of https://gitlab.com/smueller18/pylint-gitlab/-/issues/18.

Setup

I have two files in the same directory: invoke_pytest.py and my_module.py

# invoke_pytest.py

import markupsafe  # this import is not used -- it can only contribute side-effects or invoke pylint side-effects!
from pylint import run_pylint

run_pylint(
    argv=[
        "--output-format=pylint_junit.JUnitReporter:pylint-report.xml",
        "my_module.py",
    ]
)
# my_module.py

try:
    import gmpy2
except ImportError:
    pass

I have a virtual environment in which I installed pylint pylint-junit markupsafe. pylint-junit is merely needed to show that a pylint plugin becomes unable to produce output. The issue surfaced originally in pylint-gitlab, which has markupdown as a dependency through jinja2.

$ python invoke_pytest.py; head pylint-report.xml

Expected output

After commenting import markupsafe from invoke_pytest.py, the output is as expected:

$ python invoke_pytest.py; head pylint-report.xml
<?xml version="1.0" ?>
<testsuites disabled="0" errors="0" failures="2" tests="4" time="0.0">
        <testsuite disabled="0" errors="0" failures="0" name="Command line or configuration file" skipped="0" tests="1" time="0">
                <testcase name="Command line or configuration file:0:0" classname="pylint">
                        <system-out>All checks passed for: None</system-out>
                </testcase>
        </testsuite>
        <testsuite disabled="0" errors="0" failures="2" name="my_module" skipped="0" tests="3" time="0">
                <testcase name="my_module:0:0" classname="pylint" file="my_module.py">
                        <system-out>All checks passed for: my_module.py</system-out>

As mentioned above, the same output is achieved if markupsafe.__init__ is adjusted to not import from ._speedups.

Environment

Windows 10 -> WSL2 -> Ubuntu

$ python --version
Python 3.10.9

$ pip list
Package           Version
----------------- -------
astroid           2.12.13
dill              0.3.6
isort             5.11.4
junit-xml-2       1.9
lazy-object-proxy 1.9.0
MarkupSafe        2.1.1
mccabe            0.7.0
pip               22.3.1
platformdirs      2.6.2
pylint            2.15.9
pylint-junit      0.3.2
setuptools        65.5.0
six               1.16.0
tomli             2.0.1
tomlkit           0.11.6
wrapt             1.14.1

I understand that the example is not quite minimal yet -- there is a lot of pylint stuff under the hood. Again, let me emphasize that I reach out to both communities and I hope to jointly reduce the example shortly.

I want to finish this report by stating that I appreciate all your efforts, keep up the good work!

@davidism
Copy link
Member

davidism commented Jan 9, 2023

I have absolutely no idea why this happens, or how to debug it. It sounds like it's an issue with how pylint collects information, but I also have no experience with pylint. We're doing the most basic extension possible, defining a few methods. If that's an issue, then it's an issue with CPython or with pylint.

@davidism davidism closed this as completed Jan 9, 2023
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jan 24, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants