Bug
For bugs/questions:
import sys; print(sys.version):import pydantic; print(pydantic.VERSION): 0.27Where possible please include a self contained code snippet describing your
bug, question, or where applicable feature request:
the below model causes pylint model.py to complain about
model.py:12:4: E0213: Method should have "self" as first argument (no-self-argument)
model.py:12:4: R0201: Method could be a function (no-self-use)
model.py:7:0: R0903: Too few public methods (1/2) (too-few-public-methods)
from typing import Optional
import pydantic
class DemoModel(pydantic.BaseModel):
some: Optional[str] = None
@pydantic.validator("some")
def check_some(cls, val):
return val
These complaints does not occur with pydantic 0.26.
Marking the validator as @classmethod will cause it to not execute at all, so the only option I have found is to disable these checks in pylint.
The major change in v0.27 was that pydantic was compiled with cython, I guess this makes introspection by pylint of the pydantic code harder or impossible.
There might be some way to trick pylint into think you're using the non-compiled pydantic code (should behave exactly the same), but I'm afraid that's a question for pylint.
Otherwise I don't really know how to help as I've never used pylint.
Let me know if you find a solution.
The issue seems to be in the published version of pydantic.
To replicate this I cloned the pydantic git and did the following.
Running pylint in a docker container with the source mounted I see the following.
$ docker run --rm -it -v `pwd`:/src -w /src -e https_proxy python:3.7 bash -c "pip install -q pylint && cat demo_model.py && pylint demo_model.py"
# pylint: disable=missing-docstring
from typing import Optional
import pydantic
class DemoModel(pydantic.BaseModel):
some: Optional[str] = None
@pydantic.validator("some")
def check_some(cls, val):
return val
------------------------------------
Your code has been rated at 10.00/10
But if I use the published pydantic version I get the errors mentioned in the bug report.
$ docker run --rm -it -v `pwd`/demo_model.py:/src/demo_model.py -w /src -e https_proxy python:3.7 bash -c "pip install -q pydantic==0.27 pylint && cat demo_model.py && pylint demo_model.py"
# pylint: disable=missing-docstring
from typing import Optional
import pydantic
class DemoModel(pydantic.BaseModel):
some: Optional[str] = None
@pydantic.validator("some")
def check_some(cls, val):
return val
************* Module demo_model
demo_model.py:12:4: E0213: Method should have "self" as first argument (no-self-argument)
demo_model.py:12:4: R0201: Method could be a function (no-self-use)
demo_model.py:7:0: R0903: Too few public methods (1/2) (too-few-public-methods)
------------------------------------
Your code has been rated at -1.67/10
This might be related to the cython changes done for this release.
And on a side note. When introducing potentially breaking changes, please step up the major version to indicate this. It's hell to investigate and fix test environments due to breaking changes in minor version bumps.
confirmed with
curl -L https://files.pythonhosted.org/packages/28/06/5faf55ff0fc320c508bbdc6d3a85ca1da7537fb42617863eda1a524e4bcd/pydantic-0.27-py36.py37.py38-none-any.whl > pydantic-0.27-py36.py37.py38-none-any.whl
pip uninstall -y pydantic
pip install pydantic-0.27-py36.py37.py38-none-any.whl
pylint test.py
Doesn't give the error, while default install from pypi does.
You might be able to use something like the above for linting, but make sure you're using the compiled pydantic for tests and production.
@gangefors
And on a side note. When introducing potentially breaking changes, please step up the major version to indicate this. It's hell to investigate and fix test environments due to breaking changes in minor version bumps.
Is that really not sufficient?
But we should move to version 1, I agree.
I would suggest you use something like pyup to upgrade dependencies, the changelog included in PRs will avoid "hell".
I hear you regarding following semvar. But then one could argue that it's easy to stay at 0.x.y for all future releases which would make life easy for the developer but not for the users.
This software is awesome and we have considered it really stable for many versions now, sans a couple of breaking updates. We do hope that you decide to "release" it soon. Thanks for your work and fast respones in the community.
thanks, I agree - just trying to work out if there's anything big I want to change before releasing.
This is still an issue in pydantic 1.5.1.
Seeing the same issue on pydantic 1.5.1
I'm also having the same issue :/
The code works, its just the pylint complain that annoys, but in the meantime this error could be disabled if you write this comment on top of the class
# pylint: disable=E0213
I did find this information on this post:
https://stackoverflow.com/questions/27965324/how-to-disable-pylint-no-self-use-warning
Please reopen, I also have the same issue in 1.5.1 . It is very annoying
What's the problem in pydantic? As far as I know this is an issue with pylint.
I need some indication of what pydantic is doing wrong or how we might fix it to reopen this.
If you find the open source code I work on in my free time and give away for free annoying, don't use it.
pydantic isn't doing anything wrong, it's pylint that can't introspect the code properly.
AFAICT pydantic.validator returns a classmethod type object and pylint should be able to pick this up but it doesn't.
There might be ways to rewrite the code to make pylint happy, but I do think that it would be better to make pylint handle the code as it is written since it's totally valid code.
Possibly related pylint issue. https://github.com/PyCQA/pylint/issues/1694
I'm pretty sure the code is typed correctly since it passes mypy and didn't used to, but the typing around validators is pretty complicated, I wouldn't be surprised if it was too complicated for pylint.
In general I find mypy + black + isort + flake8 enough. That more does pylint provide?
@samuelcolvin
Even flake8 complains about the first argument not being self. Furthermore, I don't think that changing linters is something that most people would consider.
Nevertheless, the problem is clearly with pylint which doesn't support custom decorators/descriptors.
A hackish workaround is to add a @classmethod decorator after the pydantic.validator one. For simple cases it seems to work and it does silence the linters. Not sure if there are any side-effects though and I haven't tested it in bigger codebases:
import pydantic
class Model(pydantic.BaseModel):
value: int
@pydantic.validator("value")
@classmethod
def _get_the_answer(cls, val: int) -> int:
print(val)
return 42
instance = Model(value=3)
print(instance)
In my case, I will probably just add an explicit # pylint: disable=no-self-argument,no-self-use though
Most helpful comment
@samuelcolvin
Even flake8 complains about the first argument not being
self. Furthermore, I don't think that changing linters is something that most people would consider.Nevertheless, the problem is clearly with pylint which doesn't support custom decorators/descriptors.
A hackish workaround is to add a
@classmethoddecorator after thepydantic.validatorone. For simple cases it seems to work and it does silence the linters. Not sure if there are any side-effects though and I haven't tested it in bigger codebases:In my case, I will probably just add an explicit
# pylint: disable=no-self-argument,no-self-usethough