best-doctor / flake8-class-attributes-order Goto Github PK
View Code? Open in Web Editor NEWA flake8 extension that checks classes attributes order
License: MIT License
A flake8 extension that checks classes attributes order
License: MIT License
I've got an error on a module:
viz/amount.py:30:5: CCE001 Amount.asset should be after Amount.None
And it's like "Wtf? What None? I don't have def None
"
Can be reproduced with https://github.com/VIZ-Blockchain/viz-python-lib/blob/master/viz/amount.py
SQLAlchemy has @declared_attr
decorator which adds declarative fields for "base" models. It would be nice to allow to keep @declared_attr
methods close to class attributes like this:
class Foo:
field = Column(String(45), nullable=False)
other_field = Column(String(45), nullable=False)
more_field = Column(String(45), nullable=False)
@declared_attr
def client_id(cls):
return Column(String(256), ForeignKey("UserModel.client_id"), nullable=False)
# other stuff
@property
def timestamp(self) -> Timestamp_ms:
return self.last_update_timestamp
Is your feature request related to a problem? Please describe.
According to Django's default coding style there is a next order of model inner classes and standard methods:
Describe the solution you'd like
I would like to specify get_absolute_url
after save
or delete
option so it will be like next configuration:
class_attributes_order =
field,
meta_class,
nested_class,
magic_method,
save,
delete,
get_absolute_url,
property_method,
static_method,
class_method,
method,
private_method
class Foo:
__ACLASSATTR = 0
def __init__(n: int):
self.__n = n
@property
def n(self):
"""The n getter."""
return self.__n
@n.setter
def n(self, new_n: int):
"""The n setter befor @classmethod creates a warning."""
self.__n = new_n
@classmethod
def a_classattr(cls):
return cls.__ACLASSATTR
no warning
Foo.n should be after Foo.a_classattr
Because of the false positive result of mypy (see python/mypy#1465) the two warnings make the problem unfeasible.
But I think it is a great idea to keep getter and setter near to each other for the same attribute.
So let consider you have to keep setter just after the getter
3.9.5
3.9.0
0.1.2
Thank you for your work!
Describe the bug
class T:
_d = "a"
M = _d
$ flake8 test.py
Unable to find qualified name for module: test.py
`file_tokens` will be removed in a future version
test.py:1:1: D100 Missing docstring in public module
test.py:1:1: D101 Missing docstring in public class
test.py:2:5: CCE001 T._d should be after T.M
test.py:3:5: VNE001 single letter variable names like 'M' are not allowed
but the fix gives:
$ python3 test.py
Traceback (most recent call last):
File "test.py", line 1, in <module>
class T:
File "test.py", line 2, in T
M = _d
NameError: name '_d' is not defined
To Reproduce
Steps to reproduce the behavior:
Expected behavior
A clear and concise description of what you expected to happen.
Screenshots
If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
Smartphone (please complete the following information):
Additional context
Add any other context about the problem here.
It would be great to have ability to change ordering of methods without changing of source code.
Is there a bug with the magic methods? The extension is telling me I should move my __iter__
, __eq__
, and similar functions to the bottom of the class, however that is not what the README specifies.
In node_type_weights.py
, "magic_method" is given a weight of 27 - however, according to the README, I think it should be given a weight of 12?
Thanks!
flake8-class-attributes-order can't create valid error message for special method such as save
,delete
and __init__
.
for example
class A:
def foo(self):
pass
def __init__(self):
pass
Expected result
CCE001 A.foo should be after A.__init__
Actual result
A.foo should be after A.None
There are only 4 magic methods, respectively __new__
, __init__
, __post_init__
and __str__
.
def get_funcdef_type(child_node) -> str:
special_methods_names = {
'__new__',
'__init__',
'__post_init__',
'__str__',
'save',
'delete',
}
Add other magic methods such as __repr__
https://docs.python.org/3/reference/datamodel.html#special-method-names.
Hi!
As far as I understand, your plugin should be able to deal with it.
Maybe I don't use it properly?
Your validation order: __init__
, __str__
, save, delete, @property
, @staticmethod
, @classmethod
, other methods, underscored methods.
My order: __init__
, @classmethod
, @staticmethod
, underscored method, other method, @property
class Demo:
aaa = 1
bbb = 2
def __init__(self):
self.ccc = 3
@classmethod
def classm():
pass
@staticmethod
def staticm():
pass
def _prim():
pass
def defm():
pass
@property
def propm():
pass
Usage:
➜ python --version
Python 3.7.3
➜ flake8 --version
3.7.8 (flake-mutable: 1.2.0, flake8-blind-except: 0.1.1, flake8-bugbear: 19.3.0, flake8-class-attributes-order: 0.0.3, flake8-comprehensions: 2.1.0, flake8-debugger: 3.1.0, flake8
-eradicate: 0.2.1, flake8-print: 3.1.0, flake8-pytest: 1.3, flake8-string-format: 0.2.3, flake8-variables-names: 0.0.1, flake8_builtins: 1.4.1, flake8_commas: 2.0.0, flake8_isort:
2.3, flake8_quotes: 2.0.1, logging-format: 0.6.0, mccabe: 0.6.1, pycodestyle: 2.5.0, pyflakes: 2.1.1) CPython 3.7.3 on Darwin
➜ flake8 demo.py
Need change header "flake8-annotations-complexity" to "flake8-class-attributes-order"
─$ flake8 backend 1 ↵
multiprocessing.pool.RemoteTraceback:
"""
Traceback (most recent call last):
File "/usr/lib64/python3.6/multiprocessing/pool.py", line 119, in worker
result = (True, func(*args, **kwds))
File "/usr/lib64/python3.6/multiprocessing/pool.py", line 44, in mapstar
return list(map(*args))
File "/home/lowit/.local/share/virtualenvs/filmover--nVAlw3n/lib/python3.6/site-packages/flake8/checker.py", line 669, in _run_checks
return checker.run_checks()
File "/home/lowit/.local/share/virtualenvs/filmover--nVAlw3n/lib/python3.6/site-packages/flake8/checker.py", line 608, in run_checks
self.run_ast_checks()
File "/home/lowit/.local/share/virtualenvs/filmover--nVAlw3n/lib/python3.6/site-packages/flake8/checker.py", line 504, in run_ast_checks
for (line_number, offset, text, check) in runner:
File "/home/lowit/.local/share/virtualenvs/filmover--nVAlw3n/lib/python3.6/site-packages/flake8_class_attributes_order/checker.py", line 206, in run
model_parts_info = self._get_model_parts_info(class_def, weight_info)
File "/home/lowit/.local/share/virtualenvs/filmover--nVAlw3n/lib/python3.6/site-packages/flake8_class_attributes_order/checker.py", line 127, in _get_model_parts_info
'weight': weights[node_type],
KeyError: None
"""
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/lowit/.local/share/virtualenvs/filmover--nVAlw3n/bin/flake8", line 10, in <module>
sys.exit(main())
File "/home/lowit/.local/share/virtualenvs/filmover--nVAlw3n/lib/python3.6/site-packages/flake8/main/cli.py", line 18, in main
app.run(argv)
File "/home/lowit/.local/share/virtualenvs/filmover--nVAlw3n/lib/python3.6/site-packages/flake8/main/application.py", line 394, in run
self._run(argv)
File "/home/lowit/.local/share/virtualenvs/filmover--nVAlw3n/lib/python3.6/site-packages/flake8/main/application.py", line 382, in _run
self.run_checks()
File "/home/lowit/.local/share/virtualenvs/filmover--nVAlw3n/lib/python3.6/site-packages/flake8/main/application.py", line 301, in run_checks
self.file_checker_manager.run()
File "/home/lowit/.local/share/virtualenvs/filmover--nVAlw3n/lib/python3.6/site-packages/flake8/checker.py", line 328, in run
self.run_parallel()
File "/home/lowit/.local/share/virtualenvs/filmover--nVAlw3n/lib/python3.6/site-packages/flake8/checker.py", line 292, in run_parallel
for ret in pool_map:
File "/usr/lib64/python3.6/multiprocessing/pool.py", line 347, in <genexpr>
return (item for chunk in result for item in chunk)
File "/usr/lib64/python3.6/multiprocessing/pool.py", line 735, in next
raise value
KeyError: None
Python 3.6.8
flake8 3.7.7
Hi, I have used this one for my Django app, it's great tool (thank you) but it always raises a lint error for an extra field defined in Django admin:
class MyAdmin(admin.ModelAdmin):
.....
def is_married(self, obj):
return obj.maritial_status == 'single
is_married.short_description = 'Is married
....
so it's kinda annoying to avoid every extra field (i.g. adding # noqa CCE001)
can we handle it; (Ignore error for short_description attr of the subclass admin.ModelAdmin?
thanks
Hi!
Can we use ellipsis operator as pass to cover dummy classes like:
class Foo:
...
?
For those who prefer to use it over pass
. I didn't find any clarification whether pass
or ...
is recommended.
We can just slightly change logic in ast.Expr
handling to distinguish ast.Ellipsis
as pass
. Of course to be more strict we can add config var like pass_attribute=pass|...
, but imho this is not about this plugin.
Hi.
This code:
class Foo:
bar()
var1, var2 = foobar()
Throws:
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "C:\ProgramData\Anaconda3\lib\runpy.py", line 85, in _run_code
exec(code, run_globals)
File "C:\ProgramData\Anaconda3\lib\site-packages\flake8\__main__.py", line 4, in <module>
cli.main()
File "C:\ProgramData\Anaconda3\lib\site-packages\flake8\main\cli.py", line 18, in main
app.run(argv)
File "C:\ProgramData\Anaconda3\lib\site-packages\flake8\main\application.py", line 393, in run
self._run(argv)
File "C:\ProgramData\Anaconda3\lib\site-packages\flake8\main\application.py", line 381, in _run
self.run_checks()
File "C:\ProgramData\Anaconda3\lib\site-packages\flake8\main\application.py", line 300, in run_checks
self.file_checker_manager.run()
File "C:\ProgramData\Anaconda3\lib\site-packages\flake8\checker.py", line 331, in run
self.run_serial()
File "C:\ProgramData\Anaconda3\lib\site-packages\flake8\checker.py", line 315, in run_serial
checker.run_checks()
File "C:\ProgramData\Anaconda3\lib\site-packages\flake8\checker.py", line 598, in run_checks
self.run_ast_checks()
File "C:\ProgramData\Anaconda3\lib\site-packages\flake8\checker.py", line 502, in run_ast_checks
for (line_number, offset, text, check) in runner:
File "C:\ProgramData\Anaconda3\lib\site-packages\flake8_class_attributes_order\checker.py", line 215, in run
errors += self._get_ordering_errors(model_parts_info)
File "C:\ProgramData\Anaconda3\lib\site-packages\flake8_class_attributes_order\checker.py", line 190, in _get_ordering_errors
cls._get_node_name(next_model_part['node'], next_model_part['type']),
File "C:\ProgramData\Anaconda3\lib\site-packages\flake8_class_attributes_order\checker.py", line 107, in _get_node_name
return name_getter(node)
File "C:\ProgramData\Anaconda3\lib\site-packages\flake8_class_attributes_order\checker.py", line 96, in <lambda>
n.targets[0].id if isinstance(n.targets[0], ast.Name) else n.targets[0].attr
AttributeError: 'Tuple' object has no attribute 'attr'
That might be a bad code styling, but it not supposed to throw exception.
Install plugin, than call flake8
with Popen
andcheck output on test file.
This is required to make sure, that plugin works.
Is your feature request related to a problem? Please describe.
Similar to the style of isort or black, is it possible to automatically sort the functions?
It seems doable to come up with a script using the results of this extension.
Describe the solution you'd like
It could be a separate project or just an additional script to run - just some way for me to stop having to rearrange these by hand!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.