• Python
  • Correctness
  • Maintainability
  • Performance
  • Readability
  • Security
  • Frameworks
  • Django
  • Flask
  • Plone
  • Odoo

Code Quality Newsletter

Tweet
Follow @quantifiedcode

Tweet
Follow @quantifiedcode

This is a collection of best practices and anti-patterns for Python and popular Python frameworks, such as Django, Flask or Odoo. Explore the different sections of this knowledge base, to increase the correctness, security, performance, maintainability, and readability of your Python code. Sign up for free to automatically monitor whether your own projects comply with all these best practices.

You can also explore the code quality of over 5.000 open source projects for free and contribute to this collection by creating or suggesting your own articles.

Python
Django
Odoo
Flask

Add article

Python

Correctness

Maintainability

  • Ask for permission instead of forgiveness

  • Avoid consecutive if-statements

  • Avoid deprecated <> operator

  • Avoid manually cloning a list

  • Avoid “non-Pythonic” method names

  • Avoid temporary kwargs

  • Avoid using intermediate variables whenever possible

  • Avoid using Java style dicts

  • Avoid using len(x) to check if x is empty

  • Avoid using “non-Pythonic” function names

  • Avoid using “non-Pythonic” variable names

  • Avoid using range() of len() to get index of iterable

  • Avoid using the global statement

  • Avoid using .update() to create merged dictionaries

  • Avoid using wildcard (*) imports

  • Consider documenting your class(es)

  • Consider documenting your function(s)

  • Consider simplifying bounds checks

  • Consider simplifying out-of-bounds checks

  • Consider splitting your assert statements

  • Consider using ‘mpl’ as alias for matplotlib imports

  • Consider using ‘np’ as alias for numpy imports

  • Consider using ‘pd’ as alias for pandas imports

  • Consider using ‘plt’ as alias for matplotlib.pyplot imports

  • Consider using ‘sns’ as alias for seaborn imports

  • Consider using ‘sp’ as alias for scipy imports

  • dict.has_key() deprecated

  • Double-check published secret key

  • Module name not matching naming conventions

  • object.__methods__ deprecated

  • Prefer explicitly numbering replacement fields in a format string

  • Prefer format() over % for string interpolation

  • Try to start test methods with “test_”

  • Use constants as default values for arguments

  • Use dump instead of dumps for json files

  • Use isinstance() to check for type

  • Use load instead of loads for json files

  • Use @property instead of Java-style of setter/getter methods

  • Use tuple as 2nd argument of isinstance() to avoid repetition

  • Use .update() instead of setting keys individually

  • Using the global statement is unnecessary at module level

  • .xreadlines() deprecated

Performance

  • Avoid nested loop joins

  • Avoid using C-style increment or decrement operators

  • Consider an iterator instead of materializing the inner list

  • Consider an iterator instead of materializing the list

  • Consider literals instead of dict() constructor to initialize dictionaries

  • Consider using a dict comprehension instead dict(...)

  • Consider using a set comprehensions instead of passing a list to set()

  • Prefer static methods over instance methods when possible

  • Prefer with to open files

  • Refactor expensive if-elif statement

  • Remove unused module(s)

  • Remove unused variable

  • Use a set instead of a list() to find key

  • Use extend() for list concatenation

Readability

  • Avoid assigning a lambda expression to a variable

  • Avoid inline comments

  • Avoid None as a redundant second argument to dict.get()

  • Avoid “non-Pythonic” attribute names

  • Avoid “non-Pythonic” class names

  • Avoid unnecessary name repetition in equality comparisions

  • Avoid unnecessary parentheses after keyword

  • Avoid unnecessary pass statements

  • Clean up unused imports

  • Consider using ‘dt’ as alias for datetime imports

  • not ... is used instead of is not

  • Omit len() as upper boundary

  • Omit len() for indexing/slicing

  • Prefer .format() over string concatenations via +

  • Simplify repetetive unequal checks

  • Test object identity with is or is not

  • Use common abbreviations for libraries

  • Use dict comprehension

  • Use isinstance() instead of comparing types

  • Use is or is not to compare with None

  • Use .items() to iterate over a dictionary

  • Use named tuples when returning more than one value from a function

  • Use new raise syntax

  • Use unpacking to update multiple values at once

  • Use zip() to iterate over a pair of lists

Security

  • Avoid using eval()

  • Avoid using exec()

  • Check published CONSUMER_SECRET

  • Check published OAuth secret

  • Check published OAuth token

  • Check published Stripe API key

  • Check usage of exploitable MD5 hashes

  • Upgrade from md5 to hashlib

Frameworks

Django

  • Access model manager through model class not instance

  • Always define __str__ or __unicode__ for each model

  • Avoid directly altering custom many-to-many relationships

  • Avoid importing from django.db.models.fields

  • Avoid null=True on string fields

  • Avoid overwriting init method of model classes

  • Avoid two consecutive underscores in field name

  • Avoid using len() with RawQuerySet

  • Avoid using locals() to populate view context

  • Avoid using RawQuerySet as boolean value

  • Call super() when overwriting unittest methods

  • Check identical value for SERVER_EMAIL and DEFAULT_FROM_EMAIL

  • Define get_absolute_url whenever possible

  • Directly accessing INSTALLED_APPS

  • Do not interact with database within ready()

  • Do not override field attributes in child model

  • Don’t pass args and kwargs to reverse()

  • Don’t use joins with update()

  • Don’t use same path for MEDIA_ROOT and STATIC_ROOT

  • Don’t use same path for MEDIA_URL and STATIC_URL

  • Don’t use string formatting on raw queries

  • Don’t use unsupported arguments on FileField

  • Double-check published secret key

  • Duplicate application names

  • Ensure indexes on your Django models

  • Inherit proxy models from non-proxy parent

  • Invalid import from django.conf.settings

  • Leverage queryset cache as much as possible

  • Missing required field in settings

  • Model attribute overwrites method definition

  • Place database manipulations in try-except blocks

  • Remove redundant import of global_settings

  • SECURE_PROXY_SSL_HEADER set

  • Set ALLOWED_HOSTS when DEBUG=False

  • Try to start test methods with “test_”

  • Use a NullBooleanField

  • Use django.conf.urls.url() instances for urlpatterns

  • Use django.test.TestCase when accessing the database

  • Use forward slashes in settings

  • Use getobjector_404() instead of catching ObjectDoesNotExist

  • Use model class as first argument for field type

  • Use reverse() instead of hard-coded URL

  • Use settings() method instead of manipulating settings directly

  • Using BinaryField to store raw binary data

Flask

  • Avoid two consecutive underscores in column name

  • Consider using url_prefix for views with similar routes

  • Define SERVER_NAME when using sub domains

  • Define url_prefix or subdomain during blueprint registration

  • Prevent SQL injections by avoiding string interpolations

  • route should be the outermost decorator

  • Use converter for type checking url variables

  • Use relative imports

Plone

  • Catching ImportError to detect package availability

  • Comma-separated imports

  • Prefer explicitly numbering replacement fields in a format string

  • Refactor deprecated unittest aliases

  • Using request.AUTHENTICATED_USER

Odoo

  • Avoid calling magic methods

  • Avoid None as a redundant second argument to dict.get()

  • Avoid temporary kwargs

  • Avoid using intermediate variables whenever possible

  • Avoid using Java style dicts

  • Avoid using len(x) to check if x is empty

  • Avoid using .update() to create merged dictionaries

  • dict.has_key() deprecated

  • Odoo model defaults require four parameters

  • Use constants and avoid magic numbers

  • Use isinstance() to check for type

  • Use tuple as 2nd argument of isinstance() to avoid repetition

  • Use .update() instead of setting keys individually

Sign up — It’s free. Not on Github? Sign up via email.