tholo / pytest-flake8

pytest plugin to run flake8
Other
117 stars 47 forks source link

Flake 8 - StringIO wrapper error with [FLAKE8 - AttributeError: '_io.StringIO' object has no attribute 'buffer'] #81

Closed klausmyrseth closed 2 years ago

klausmyrseth commented 3 years ago

Installed flake through pipenv

$ pipenv install -d pytest
$ pipenv install -d flake8

Please provide the exact, unmodified output of flake8 --bug-report

{
  "dependencies": [],
  "platform": {
    "python_implementation": "CPython",
    "python_version": "3.9.5",
    "system": "Linux"
  },
  "plugins": [
    {
      "is_local": false,
      "plugin": "mccabe",
      "version": "0.6.1"
    },
    {
      "is_local": false,
      "plugin": "pycodestyle",
      "version": "2.8.0"
    },
    {
      "is_local": false,
      "plugin": "pyflakes",
      "version": "2.4.0"
    }
  ],
  "version": "4.0.1"
}

Please describe the problem or feature I have a project where flake aparently works as intended, and when I use the commandline flake it still works to some extent without all the pytest.ini setup, but within the Pipenv project it fails through pytest when it finds an error. I run flake8:

$ python -m pytest --flake8

In all other projects we have it works flawlessly, and I really like the tool :D In general the error comes when the file contains an error and flake8 tries to write to stdout.

This is my pipfile (removed the internal libs, but they dont wrap output in any way:

... removed private pypis ...

[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]
pytest = {version="*", index="pypi"}
pytest-flake8 = {version="*", index="pypi"}
pylint = {version="*", index="pypi"}
strenum = {version="*", index="pypi"}
... private libs ...
google-cloud-datastore = {version="*", index="pypi"}
geojson = {version="*", index="pypi"}
firebase_admin = "*"

[packages]

[requires]
python_version = "3.9"

checked the locks, and same lib versions as bug-report and: pytest 6.2.5 pytest-flake8 1.0.7

We have the same setup in other projects without the same issue so I'm a bit confused. I however suspect something wrap the stdout StringIO so the expected attributes are not accessible by flake when it needs to report its findings.

klausmyrseth commented 3 years ago

I forceably downgraded flake 4.0.1 to 3.9.2 in my Pipfile so the updated version looks like:

... removed private pypis ...

[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]
pytest = {version="*", index="pypi"}
flake8 = {version="==3.9.2", index="pypi"}
pytest-flake8 = {version="*", index="pypi"}
pylint = {version="*", index="pypi"}
strenum = {version="*", index="pypi"}
... private libs ...
google-cloud-datastore = {version="*", index="pypi"}
geojson = {version="*", index="pypi"}
firebase_admin = "*"

[packages]

[requires]
python_version = "3.9"

and it started working again, so there is something going on with the new flake 4.0.1

VRGhost commented 3 years ago

My PR to fix this on the flake8 side had been rejected. :-(

https://github.com/PyCQA/flake8/pull/1422

VRGhost commented 3 years ago

This is more an integration issue between flake9 and pytests's "py.io.StdCapture" class. Sadly, flake8 developer seems to be quite adamant that he is developing an CLI tool rather than a library ( https://flake8.pycqa.org/en/latest/user/python-api.html ), so he can claim that the issue should be fixed elsewhere

sigmavirus24 commented 3 years ago

This is more an integration issue between flake9 and pytests's "py.io.StdCapture" class. Sadly, flake8 developer seems to be quite adamant that he is developing an CLI tool rather than a library ( https://flake8.pycqa.org/en/latest/user/python-api.html ), so he can claim that the issue should be fixed elsewhere

That has been the flake8 maintenance team's attitude since flake8 2.x. 3.0 reinforced that. This isn't new and contrary to your implications isn't arbitrary

VRGhost commented 3 years ago

contrary to your implications isn't arbitrary

I did not try to imply anything, sir.

Just described my findings on the subject to help the libraries maintainer. I have no desire running circles around three product teams trying to convenience someone to do something.

I'm not associated with any of the projects so I don't have any intrinsic stakes in any of them succeeding.

VRGhost commented 3 years ago

I did choose to raise PR against flake8 just because I thought that that change contributed to the Python community the most. Rather than py.io that seems mostly dead or pytest-flake8 integration that isn't doing anything that usual or bad.

BracketJohn commented 3 years ago

I've encountered the same exception:

――――――――――――――――――――――――――――――――――― FLAKE8-check ―――――――――――――――――――――――――――――――――――
.venv/lib/python3.9/site-packages/pluggy/_hooks.py:265: in __call__
    return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
.venv/lib/python3.9/site-packages/pluggy/_manager.py:80: in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
.venv/lib/python3.9/site-packages/_pytest/runner.py:170: in pytest_runtest_call
    raise e
.venv/lib/python3.9/site-packages/_pytest/runner.py:162: in pytest_runtest_call
    item.runtest()
.venv/lib/python3.9/site-packages/pytest_flake8.py:120: in runtest
    found_errors, out, err = call(
.venv/lib/python3.9/site-packages/py/_io/capture.py:150: in call
    res = func(*args, **kwargs)
.venv/lib/python3.9/site-packages/pytest_flake8.py:222: in check_file
    app.report_errors()
.venv/lib/python3.9/site-packages/flake8/main/application.py:309: in report_errors
    results = self.file_checker_manager.report()
.venv/lib/python3.9/site-packages/flake8/checker.py:247: in report
    results_reported += self._handle_results(filename, results)
.venv/lib/python3.9/site-packages/flake8/checker.py:153: in _handle_results
    reported_results_count += style_guide.handle_error(
.venv/lib/python3.9/site-packages/flake8/style_guide.py:429: in handle_error
    return guide.handle_error(
.venv/lib/python3.9/site-packages/flake8/style_guide.py:581: in handle_error
    self.formatter.handle(error)
.venv/lib/python3.9/site-packages/flake8/formatting/base.py:100: in handle
    self.write(line, source)
.venv/lib/python3.9/site-packages/flake8/formatting/base.py:203: in write
    self._write(line)
.venv/lib/python3.9/site-packages/flake8/formatting/base.py:187: in _write
    sys.stdout.buffer.write(output.encode() + self.newline.encode())
E   AttributeError: '_io.StringIO' object has no attribute 'buffer'

Problem only occured with 4.0.0 and 4.0.1. Downgrading to 3.9.2 fixed the problem!

erikkemperman commented 3 years ago

If you can live with dropping support for Python 2, https://github.com/tholo/pytest-flake8/pull/82 might fix this.

jaraco commented 3 years ago

In PyCQA/flake8#1419, this issue was reported to flake8. I attempted to report the error in pytest-dev/pytest#9217, but was redirected here.

m-aciek commented 2 years ago

In the meantime, while #82 is not yet merged, could we add flake8<4 requirement in setup.py file?

VRGhost commented 2 years ago

Hello all,

Just FYI: I have forked this repo ( https://github.com/VRGhost/pytest-flake8 ), fixed the issue (by stealing the https://github.com/tholo/pytest-flake8/pull/82 PR) and uploaded the fixed library under the "pytest-flake8-v2" name to the PyPI ( https://pypi.org/project/pytest-flake8-v2/ ).

Just to confirm: only the PyPI name has changed, not the name the library is imported under (that one is still "pytest_flake8").

I have also raised a PEP 541 request to acquire the original PyPI name (as @tholo did not respond to any of my hails), but I have no idea of if/how long the transfer will take. I'd guess a month at very least.

In the meantime - please feel free to use the "pytest-flake8-v2" as a drop in replacement.

erikkemperman commented 2 years ago

@VRGhost I agree things were moving kind of slow here, so I understand the urge to fork and republish… But just as a matter of etiquette, when repurposing other people’s efforts in an open source context, I believe it would have been nicer to cherry-pick the commits you like (retaining the original authorship) rather than patch and commit under your own name. Just saying. Best of luck with your fork!

VRGhost commented 2 years ago

@erikkemperman Yes, I completely agree that this would've been a better option, thank you for pointing this out.

VRGhost commented 2 years ago

@erikkemperman Oh, you've raised that PR. My apologies once again. I didn't mean to appropriate your contribution.

erikkemperman commented 2 years ago

@VRGhost well, the important thing is that this fix, if that’s what it is, gets in the hands of the community — and perhaps a new custodian is just what this codebase needs, I honestly don’t know enough about its circumstances. It was just meant as friendly advice!

jaraco commented 2 years ago

Thanks for the fix and release in 1.1.0!