Git Product home page Git Product logo

wemake-services / wemake-python-styleguide Goto Github PK

View Code? Open in Web Editor NEW
2.4K 2.4K 381.0 10.09 MB

The strictest and most opinionated python linter ever!

Home Page: https://wemake-python-styleguide.rtfd.io

License: MIT License

Python 99.78% Makefile 0.03% Dockerfile 0.09% Shell 0.10%
code-quality flake8 flake8-plugin hacktoberfest linter python python3 styleguide wemake wemake-services

wemake-python-styleguide's People

Contributors

alwxsin avatar bellum avatar blablatdinov avatar cmppoon avatar dependabot-preview[bot] avatar dependabot-support avatar dependabot[bot] avatar dreamsorcerer avatar egorvdot avatar fullset avatar github-actions[bot] avatar hhsdev avatar jrryy avatar ko3luhbka avatar lensvol avatar lk-geimfari avatar lucaionescu avatar monosans avatar novikovfred avatar nsimonoff avatar pawamoy avatar pyup-bot avatar roxe322 avatar serhii73 avatar sizovigor avatar skarzi avatar sobolevn avatar thepabloaguilar avatar waterseeker avatar whysage avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wemake-python-styleguide's Issues

Forbid private variables

Names like __some_name should be forbiden, since there's no single use-case in python for real private variables.

Use public and protected variables instead.

Dependency "pluggy" may have a wrong hash in the lock file

When I do pipenv install -d on MacOS, the pluggy=0.6.0 dependency isn't getting installed because of the wrong hash: THESE PACKAGES DO NOT MATCH THE HASHES FROM Pipfile.lock!.

The package version pipenv tries to install is: https://files.pythonhosted.org/packages/ba/65/ded3bc40bbf8d887f262f150fbe1ae6637765b5c9534bd55690ed2c0b0f7/pluggy-0.6.0-py3-none-any.whl

The problem can be caused by pipenv itself (see pypa/pipenv#210).

Since I'm not sure I'm asking to verify that on other platforms.

Disallow too broad `noqa` comments

Sometime I can see code like this:

try:
    import django  # noqa
except ImportError:
    pass

This bare noqa comment covers all possible issues on this line.
That's not what we want. We need to specify exact error numbers:

try:
    import django  # noqa: F401, Z101
except ImportError:
    pass

Django specific things

Models

  • no signal, because they are evil side effects
  • no BooleanField with null, use NullBooleanField
  • no CharField with null, use blank=True with possible '' as default
  • use CIEmailField instead of EmailField
  • no JSONField other than django.contrib.postgres.fields.JSONField
  • no default={} inJSONField, use default=dict instead
  • no methods on models except magic ones

Structure

  • all applications should be named as *_app
  • apps.py and models.py must be present
  • check filenames in *_app folder, whitelist: models, views, forms, admin, serializers, apps, urls, tasks, __init__

Create configuration

Currently our linter is full of magic constants like:

What we need is:
0. create a file with default configuration values

  1. allow users to override these values with setup.cfg or any other standard flake8 tools
  2. test that when configuration is applied linter respects it

Version 0.0.2 can't be used with pip

In some cases on line

node_parent = getattr(node, 'parent')

of WrongModuleMetadataVisitor we get

AttributeError: 'Assign' object has no attribute 'parent'

The bug can be fixed by the correct usage of getattr:

node_parent = getattr(node, 'parent', None)

The PR with the fix and a regression test will be ready in a day.

Questions

I am not sure about these.

Classes

  • restrict passing attributes in __init_subclass__: class MyClass(MetaClass, option=1)

Restrict any logics inside `__init__.py`

Side effect inside __init__.py are nightmares.

We need to restrict any kind of python code inside __init__.py except:

  1. comments
  2. docstrings

Imports should be forbidden. Each separate module should have its own public API.

Allow the pass keyword inside a class that inherits from other classes

For example, the following is the only way in Django to inherit the Meta class:

class Meta(BaseModel.Meta):
    pass

But unfortunately it triggers WPS100 Found wrong keyword "pass".

More generally, the following should be allowed as it's a common thing to do:

class Foo(BarMixin, FooBase):
    pass

Right now the # noqa comment helps to avoid the warning.

Test that nested classes also have explicit base classes

We need to be sure that cases like:

class Model(models.Model):
     class Meta: ...  # error here, needs explicit base class

are covered.

Correct way to write this example is:

class Model(models.Model):
     class Meta(object): ... 

This should work for all NESTED_CLASSES_WHITELIST.

Forbid `getattr(x, 'foobar') `

As per the docs:

getattr(x, 'foobar') is equivalent to x.foobar

This may lead a reader to believe that getattr(obj, 'attribute') will not throw an exception.

Correct

x.foobar
getattr(x, 'foobar', None)
getattr(x, some_variable, None)

Incorrect

getattr(x, 'foobar')

Forbid `staticmethod`s

In my opinion staticmethod should not be used.

It is better to use regular methods or regular functions.
There should be nothing in between.

Forbid old-styled classes

In python2 we had different classes: class Some: and class Some(object): were totally different things.

Currently, we don't have this thing in python3, but since these times I believe that new-styled classes are still better.

  1. It has more semantics: this class is related to object
  2. It has unified interface: class Base(object) and class Child(Base) vs class Base and class Child(Base)
  3. Explicit is better than implicit

So, I believe we should ban classes with old-styled base class.
General rule is: always write super-classes' names

Correct

class Philosopher(object):
    def __init_subclass__(cls, default_name, **kwargs):
        ...

class AustralianPhilosopher(Philosopher, default_name="Bruce"):
    ...

class WithMetaClass(object, metaclass=MyMeta):
   ...

Wrong

class Philosopher: ...
class AustralianPhilosopher(default_name="Bruce"): ...
class WithMetaClass(metaclass=MyMeta): ...

Rules

Rules to check and implement:

General

  • no nested functions
  • no nested classes (Meta as whitelist)
  • no unused arguments
  • no len(x) == 0 in if conditions
  • no always True checks
  • no raise (without new exception) not within except
  • no raise NotImplemented
  • no __author__
  • no / linebrakes

Complexity

  • too many local variables
  • too many arguments
  • too many branches
  • too many returns
  • too many expressions
  • too many statements
  • too deep nesting

Function calls

  • no exec, eval, and compile
  • no vars(), no dir()
  • no print, pprint
  • no input
  • no globals(), no locals()
  • no short function names

Keywords

  • no global, no nonlocal, no del, no pass

Imports

  • no from some import * aka star-import
  • no from .. import some aka dot import
  • no nested imports
  • no __import__

Classes

  • no return/yield in __init__
  • no self override
  • self is not used
  • first method argument must be cls or self if not staticmethod
  • too few public method (__init__ + one other)
  • too many public methods
  • too many instance attributes
  • no magic methods: __del__
  • no attributes with default None: class Fixture: some_attribute = None

Variables

  • no blacklist variable names: data, result
  • no short variable names

Files

  • no bom
  • no long files, max-file-lines = 600
  • no logic in __init__.py
  • no __{}__ filenames, except __init__ and __main__

mypy

  • follow this pattern: x: List[SomeValue] = [], def cast(element: Element = None) -> str:

Forbid `# type:` comments

We should use annotations to provide types.
The only type comment that is allowed is: # type: ignore

Add `__all__` to restricted metadata list

You should not define your API like that. Use naming conventions: public, _protected.
And you should not use from some import *. Use named imports.

So, we should ban this anti-pattern.

Disallow global file ignores with `flake8: noqa`

I don't like the idea that some files are excluded from linting.
But, I believe that this might be useful for several cases.

But, we need to do it inside the configuration file, not in a separate file.

Why?
Because it is hard to tell which files are ignored, and which files are not.
In configuration it is pretty visible from the very first sight.

Related #53

Implement `TooManyBranchesViolation`

When code has a lot of if, try, for, and other branches it is hard to follow what is going on.

We can restrict the number of logic branches allowed for a single function.
That's how it should work:

  • if is counted as +1 for the complexity, else and elif also counts as +1
  • for is counted as +1, else is also counted as +1
  • while is counted as +1
  • try is counted as +1, each except case is counted as +1
  • with is counted as +1

We need to figure out what number of branches is the most pleasant to have. We can consult pylint for this.

Forbid "@" operator

It is used only for some data-science pacakges, which we obviously do not use.

Other usages of this operator different from matrix multiplications should be banned.

Forbid `__future__` imports

They are not a thing in python3 anymore.
But, we should have a whitelist for things like annotations and some new features that might come.

I also feel like we should save some more error code for imports and move other errors up a bit.

Implement TooDeepNestingViolation

We have to check that code like this:

class Test:
    def method(self):
        with some_manager():
            try:
                if self.call_method():
                    return True
            except:
                  return False

raises TooDeepNestingViolation error.

The optimal nesting level is 4. So, code under try should not have any nesting.

Forbid `__del__` magic method

You should not use __del__, as it is non-pythonic, more like cpp.

This method is not even called in several situations.
So, let's forbid it.

Test that `wemake-python-styleguide` is in `flake8` plugins

def test_call_flake8_version():
    """Checks that module is registered and visible in the meta data."""
    output = subprocess.check_output(
        ['flake8', '--version'],
        stderr=subprocess.STDOUT,
    )
    assert b'wemake-python-styleguide': ' in output

Forbid % string interpolation

As we have decided to stick to .format(), we are banning f strings: #32

But, @vergeev have also suggested to forbid 'string with %s' % some.
Here's the backstory:

  • gforcada/flake8-pep3101#23 has some false positives, that disallow to use regular modulo operator 5 % 2
  • we can only forbid using this operator with string literals, not vars as was suggested in #32 (comment)

So, this would be valid:

some_variable % 'value1'
5 % 2

This would be invalid:

'format me %s' % 'value2'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.