├── .gitignore ├── .travis.yml ├── MANIFEST.in ├── README.md ├── database_size ├── __init__.py ├── admin.py ├── apps.py ├── models.py ├── sql │ ├── table.mysql.sql │ ├── table.postgresql.sql │ ├── table.sqlite.sql │ └── table.sqlite3.sql ├── tests │ ├── __init__.py │ ├── manage.py │ ├── management │ │ ├── __init__.py │ │ └── commands │ │ │ └── __init__.py │ ├── models.py │ ├── settings.py │ ├── tests.py │ ├── urls.py │ └── views.py └── utils.py ├── init_virtualenv.sh ├── pep8.sh ├── publish.sh ├── pylint.messages ├── pylint.rc ├── requirements-min-django.txt ├── requirements-test.txt ├── requirements.txt ├── setup.py ├── test.sh └── tox.ini /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | bin/ 10 | build/ 11 | develop-eggs/ 12 | dist/ 13 | eggs/ 14 | lib/ 15 | lib64/ 16 | parts/ 17 | sdist/ 18 | var/ 19 | *.egg-info/ 20 | .installed.cfg 21 | *.egg 22 | MANIFEST 23 | 24 | # Installer logs 25 | pip-log.txt 26 | pip-delete-this-directory.txt 27 | 28 | # Unit test / coverage reports 29 | .tox/ 30 | .coverage 31 | .cache 32 | nosetests.xml 33 | coverage.xml 34 | 35 | # Translations 36 | *.mo 37 | 38 | # Mr Developer 39 | .mr.developer.cfg 40 | .project 41 | .pydevproject 42 | .settings 43 | 44 | # Rope 45 | .ropeproject 46 | 47 | # Django stuff: 48 | *.log 49 | *.pot 50 | 51 | # Sphinx documentation 52 | docs/_build/ 53 | 54 | # Local virtualenvs used for testing. 55 | /.env* 56 | 57 | # PIP install version files. 58 | /=* 59 | /*.geany 60 | *.out 61 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | dist: trusty 2 | sudo: required 3 | language: python 4 | python: 5 | - "3.11" 6 | install: 7 | - sudo add-apt-repository -y ppa:fkrull/deadsnakes 8 | - sudo apt-get -yq update 9 | - sudo apt-get -yq install python3.11 python3.11-dev 10 | - pip install -r requirements-test.txt 11 | script: 12 | - ./pep8.sh 13 | - tox 14 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | recursive-include database_size/tests/fixtures * 2 | include requirements-min-django.txt 3 | include requirements.txt 4 | include requirements-test.txt 5 | include README.md 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | django-database-size 2 | ===================== 3 | 4 | [![](https://img.shields.io/pypi/v/django-database-size.svg)](https://pypi.python.org/pypi/django-database-size) [![Build Status](https://img.shields.io/travis/chrisspen/django-database-size.svg?branch=master)](https://travis-ci.org/chrisspen/django-database-size) [![](https://pyup.io/repos/github/chrisspen/django-database-size/shield.svg)](https://pyup.io/repos/github/chrisspen/django-database-size) 5 | 6 | Adds a page to Django admin that lists the size of all tables in the database. 7 | 8 | Installation 9 | ------------ 10 | 11 | python setup.py install 12 | 13 | Or via pip with: 14 | 15 | pip install django-database-size 16 | 17 | Install the appropriate view in /sql (currently only PostgreSQL and MySQL supported). 18 | 19 | Add to your INSTALLED_APPS. 20 | 21 | Usage 22 | ----- 23 | 24 | Browse to /admin/database_size/. 25 | 26 | Development 27 | ----------- 28 | 29 | To run unittests across multiple Python versions, install: 30 | 31 | sudo add-apt-repository ppa:fkrull/deadsnakes 32 | sudo apt-get update 33 | sudo apt-get install python-dev python3-dev python3.3-minimal python3.3-dev python3.4-minimal python3.4-dev python3.5-minimal python3.5-dev python3.6 python3.6-dev 34 | 35 | To run all [tests](http://tox.readthedocs.org/en/latest/): 36 | 37 | export TESTNAME=; tox 38 | 39 | To run tests for a specific environment (e.g. Python 2.7 with Django 1.4): 40 | 41 | export TESTNAME=; tox -e py39-django2 42 | 43 | To run a specific test: 44 | 45 | export TESTNAME=.test_example; tox -e py27-django15 46 | 47 | To run the [documentation server](http://www.mkdocs.org/#getting-started) locally: 48 | 49 | mkdocs serve -a :9999 50 | 51 | To [deploy documentation](http://www.mkdocs.org/user-guide/deploying-your-docs/), run: 52 | 53 | mkdocs gh-deploy --clean 54 | 55 | To build and deploy a versioned package to PyPI, verify [all unittests are passing](https://travis-ci.org/chrisspen/django-chroniker), and then run: 56 | 57 | python setup.py sdist 58 | python setup.py sdist upload 59 | 60 | -------------------------------------------------------------------------------- /database_size/__init__.py: -------------------------------------------------------------------------------- 1 | VERSION = (1, 0, 5) 2 | __version__ = '.'.join(map(str, VERSION)) 3 | 4 | default_app_config = 'database_size.apps.DjangoDatabaseSizeConfig' 5 | -------------------------------------------------------------------------------- /database_size/admin.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | from django.contrib import admin 4 | from django.db import connections 5 | from django.contrib.admin import SimpleListFilter 6 | 7 | from database_size import models 8 | from database_size import utils 9 | 10 | 11 | class SelectDatabaseListFilter(SimpleListFilter): 12 | 13 | title = 'database' 14 | 15 | parameter_name = 'database' 16 | 17 | default_value = 'default' 18 | 19 | def __init__(self, request, params, model, model_admin): 20 | self.parameter_val = None 21 | try: 22 | self.parameter_val = request.GET.get(self.parameter_name, self.default_value) 23 | except Exception as e: 24 | pass 25 | super(SelectDatabaseListFilter, self).__init__(request, params, model, model_admin) 26 | 27 | def lookups(self, request, model_admin): 28 | """ 29 | Must be overriden to return a list of tuples (value, verbose value) 30 | """ 31 | return [(conn, conn) for conn in connections] 32 | 33 | def choices(self, cl): 34 | for lookup, title in self.lookups(None, None): 35 | yield { 36 | 'selected': self.parameter_val == lookup, 37 | 'query_string': cl.get_query_string({ 38 | self.parameter_name: lookup, 39 | }, []), 40 | 'display': title, 41 | } 42 | 43 | def queryset(self, request, queryset): 44 | """ 45 | Returns the filtered queryset. 46 | """ 47 | queryset._db = self.parameter_val 48 | return queryset 49 | 50 | 51 | class TableAdmin(admin.ModelAdmin): 52 | 53 | list_display = ( 54 | #'id', 55 | #'site', 56 | 'table_name', 57 | 'schema_name', 58 | 'table_owner', 59 | 'size_in_bytes', 60 | 'pretty_size', 61 | ) 62 | list_filter = ( 63 | 'schema_name', 64 | 'table_owner', 65 | SelectDatabaseListFilter, 66 | ) 67 | search_fields = ( 68 | 'schema_name', 69 | 'table_name', 70 | 'table_owner', 71 | ) 72 | readonly_fields = ( 73 | 'pretty_size', 74 | ) 75 | 76 | def has_delete_permission(self, request, obj=None): 77 | return False 78 | 79 | def has_add_permission(self, request, obj=None): 80 | return False 81 | 82 | def get_actions(self, request): 83 | actions = super(TableAdmin, self).get_actions(request) 84 | if 'delete_selected' in actions: 85 | del actions['delete_selected'] 86 | return actions 87 | 88 | def get_readonly_fields(self, request, obj=None): 89 | readonly_fields = list(self.readonly_fields) 90 | return readonly_fields + [f.name for f in self.model._meta.fields] 91 | 92 | def pretty_size(self, obj=None): 93 | if obj is None: 94 | return '' 95 | return utils.humanize_bytes(obj.size_in_bytes) 96 | pretty_size.short_description = 'size' 97 | pretty_size.admin_order_field = 'size_in_bytes' 98 | 99 | admin.site.register(models.Table, TableAdmin) 100 | -------------------------------------------------------------------------------- /database_size/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | class DjangoDatabaseSizeConfig(AppConfig): 4 | name = 'database_size' 5 | verbose_name = 'Database Size' 6 | -------------------------------------------------------------------------------- /database_size/models.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | from django.db import models 4 | from django.utils.translation import gettext_lazy as _ 5 | 6 | class StringWithTitle(str): 7 | """ 8 | String class with a title method. Can be used to override 9 | admin app names. 10 | 11 | http://ionelmc.wordpress.com/2011/06/24/custom-app-names-in-the-django-admin/ 12 | """ 13 | 14 | def __new__(cls, value, title): 15 | instance = str.__new__(cls, value) 16 | instance._title = title 17 | return instance 18 | 19 | def title(self): 20 | return self._title 21 | 22 | __copy__ = lambda self: self 23 | __deepcopy__ = lambda self, memodict: self 24 | 25 | APP_LABEL = StringWithTitle('database_size', 'Database Size') 26 | 27 | class Table(models.Model): 28 | 29 | # MySQL can have no more than 255 length... 30 | id = models.CharField(max_length=255, primary_key=True) 31 | 32 | schema_name = models.CharField(max_length=500) 33 | table_name = models.CharField(max_length=500) 34 | table_owner = models.CharField(max_length=500) 35 | size_in_bytes = models.IntegerField() 36 | 37 | class Meta: 38 | managed = False 39 | ordering = ('-size_in_bytes',) 40 | app_label = APP_LABEL 41 | verbose_name = _('table') 42 | 43 | def __unicode__(self): 44 | return '%s.%s' % (self.schema_name, self.table_name) 45 | -------------------------------------------------------------------------------- /database_size/sql/table.mysql.sql: -------------------------------------------------------------------------------- 1 | /* 2 | 2013.11.21 CKS 3 | Lists all table sizes. 4 | */ 5 | DROP VIEW IF EXISTS database_size_table CASCADE; 6 | CREATE OR REPLACE VIEW database_size_table 7 | AS 8 | SELECT CONCAT(table_schema, '-', table_name) AS id, 9 | table_schema AS schema_name, 10 | table_name AS table_name, 11 | null AS table_owner, -- TODO: not available in MySQL?! 12 | (data_length + index_length) AS size_in_bytes 13 | FROM information_schema.TABLES 14 | UNION ALL 15 | SELECT CONCAT(table_schema, '-byschema') AS id, 16 | table_schema AS schema_name, 17 | 'ALL' AS table_name, 18 | 'ALL' AS table_owner, -- TODO: not available in MySQL?! 19 | SUM(data_length + index_length) AS size_in_bytes 20 | FROM information_schema.TABLES 21 | GROUP BY table_schema 22 | UNION ALL 23 | SELECT 'all-all' AS id, 24 | 'ALL' AS schema_name, 25 | 'ALL' AS table_name, 26 | 'ALL' AS table_owner, -- TODO: not available in MySQL?! 27 | SUM(data_length + index_length) AS size_in_bytes 28 | FROM information_schema.TABLES; -------------------------------------------------------------------------------- /database_size/sql/table.postgresql.sql: -------------------------------------------------------------------------------- 1 | /* 2 | 2013.5.12 CKS 3 | Lists all table sizes. 4 | */ 5 | DROP VIEW IF EXISTS database_size_table CASCADE; 6 | CREATE OR REPLACE VIEW database_size_table 7 | AS 8 | SELECT CONCAT(CAST(schemaname AS VARCHAR), '-', CAST(tablename AS VARCHAR)) AS id, 9 | schemaname AS schema_name, 10 | tablename AS table_name, 11 | tableowner AS table_owner, 12 | pg_total_relation_size(schemaname || '.' || tablename) AS size_in_bytes 13 | FROM pg_tables WHERE has_schema_privilege(schemaname, 'USAGE') 14 | UNION ALL 15 | SELECT CONCAT(CAST(schemaname AS VARCHAR), '-byschema') AS id, 16 | schemaname AS schema_name, 17 | 'ALL' AS table_name, 18 | 'ALL' AS table_owner, 19 | SUM(pg_total_relation_size(schemaname || '.' || tablename))::bigint AS size_in_bytes 20 | FROM pg_tables WHERE has_schema_privilege(schemaname, 'USAGE') 21 | GROUP BY schemaname 22 | UNION ALL 23 | SELECT 'all-all' AS id, 24 | 'ALL' AS schema_name, 25 | 'ALL' AS table_name, 26 | 'ALL' AS table_owner, 27 | SUM(pg_total_relation_size(schemaname || '.' || tablename))::bigint AS size_in_bytes 28 | FROM pg_tables WHERE has_schema_privilege(schemaname, 'USAGE'); 29 | -------------------------------------------------------------------------------- /database_size/sql/table.sqlite.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Mock placeholder, so Sqlite3 tests can access the table without throwing a missing table error. 3 | */ 4 | CREATE VIEW database_size_table 5 | AS 6 | SELECT 'id' AS id, 7 | 'schemaname' AS schema_name, 8 | 'tablename' AS table_name, 9 | 'tableowner' AS table_owner, 10 | 123 AS size_in_bytes; 11 | -------------------------------------------------------------------------------- /database_size/sql/table.sqlite3.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Mock placeholder, so Sqlite3 tests can access the table without throwing a missing table error. 3 | */ 4 | CREATE VIEW database_size_table 5 | AS 6 | SELECT 'id' AS id, 7 | 'schemaname' AS schema_name, 8 | 'tablename' AS table_name, 9 | 'tableowner' AS table_owner, 10 | 123 AS size_in_bytes; 11 | -------------------------------------------------------------------------------- /database_size/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisspen/django-database-size/15dc4c9dad2f648513d7b2a106093d342dad0e03/database_size/tests/__init__.py -------------------------------------------------------------------------------- /database_size/tests/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | sys.path.insert(0, '.') 6 | 7 | if __name__ == "__main__": 8 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings") 9 | 10 | from django.core.management import execute_from_command_line 11 | 12 | execute_from_command_line(sys.argv) 13 | -------------------------------------------------------------------------------- /database_size/tests/management/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisspen/django-database-size/15dc4c9dad2f648513d7b2a106093d342dad0e03/database_size/tests/management/__init__.py -------------------------------------------------------------------------------- /database_size/tests/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisspen/django-database-size/15dc4c9dad2f648513d7b2a106093d342dad0e03/database_size/tests/management/commands/__init__.py -------------------------------------------------------------------------------- /database_size/tests/models.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisspen/django-database-size/15dc4c9dad2f648513d7b2a106093d342dad0e03/database_size/tests/models.py -------------------------------------------------------------------------------- /database_size/tests/settings.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | import django 5 | 6 | PROJECT_DIR = os.path.dirname(__file__) 7 | 8 | DATABASES = { 9 | 'default':{ 10 | 'ENGINE': 'django.db.backends.sqlite3', 11 | } 12 | } 13 | 14 | ROOT_URLCONF = 'database_size.tests.urls' 15 | 16 | INSTALLED_APPS = [ 17 | 'django.contrib.auth', 18 | 'django.contrib.admin', 19 | 'django.contrib.contenttypes', 20 | 'django.contrib.sessions', 21 | 'django.contrib.sites', 22 | 'django.contrib.messages', 23 | 'database_size', 24 | 'database_size.tests', 25 | ] 26 | 27 | MEDIA_ROOT = os.path.join(PROJECT_DIR, 'media') 28 | 29 | # Disable migrations. 30 | # http://stackoverflow.com/a/28560805/247542 31 | class DisableMigrations(object): # pylint: disable=bad-option-value,useless-object-inheritance 32 | 33 | def __contains__(self, item): 34 | return True 35 | 36 | def __getitem__(self, item): 37 | return "notmigrations" 38 | 39 | #SOUTH_TESTS_MIGRATE = False # Use syncdb <= Django 1.8 40 | SOUTH_TESTS_MIGRATE = True # Use migrate 41 | #if django.VERSION > (1, 8, 0): # > Django 1.8 42 | # if django.VERSION > (1, 7, 0): # > Django 1.8 43 | # MIGRATION_MODULES = DisableMigrations() 44 | 45 | if django.VERSION < (1, 7, 0): 46 | SOUTH_MIGRATION_MODULES = { 47 | 'database_size': 'database_size.south_migrations', 48 | } 49 | 50 | USE_TZ = True 51 | 52 | AUTH_USER_MODEL = 'auth.User' 53 | 54 | SECRET_KEY = 'abc123' 55 | 56 | SITE_ID = 1 57 | 58 | BASE_SECURE_URL = 'https://localhost' 59 | 60 | BASE_URL = 'http://localhost' 61 | 62 | MIDDLEWARE = MIDDLEWARE_CLASSES = ( 63 | 'django.middleware.common.CommonMiddleware', 64 | 'django.contrib.sessions.middleware.SessionMiddleware', 65 | 'django.middleware.csrf.CsrfViewMiddleware', 66 | #'django.middleware.transaction.TransactionMiddleware', 67 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 68 | 'django.contrib.messages.middleware.MessageMiddleware', 69 | 'django.middleware.locale.LocaleMiddleware', 70 | ) 71 | 72 | # Required in Django>=1.10. 73 | TEMPLATES = [ 74 | { 75 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 76 | 'DIRS': [ 77 | '%s/../templates' % PROJECT_DIR, 78 | '%s/../static' % PROJECT_DIR, 79 | ], 80 | # 'APP_DIRS': True, 81 | 'OPTIONS': { 82 | 'context_processors': [ 83 | 'django.contrib.auth.context_processors.auth', 84 | 'django.template.context_processors.debug', 85 | 'django.template.context_processors.request', 86 | 'django.template.context_processors.i18n', 87 | 'django.template.context_processors.media', 88 | 'django.template.context_processors.static', 89 | 'django.template.context_processors.tz', 90 | 'django.contrib.messages.context_processors.messages', 91 | ], 92 | 'loaders': [ 93 | 'django.template.loaders.filesystem.Loader', 94 | 'django.template.loaders.app_directories.Loader', 95 | ], 96 | 'debug': True, 97 | }, 98 | }, 99 | ] 100 | -------------------------------------------------------------------------------- /database_size/tests/tests.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | import os 4 | from datetime import timedelta, date 5 | import time 6 | import socket 7 | import threading 8 | from functools import cmp_to_key 9 | import warnings 10 | 11 | import django 12 | from django.core.management import call_command 13 | from django.core import mail 14 | from django.test import TestCase 15 | from django.test.client import Client 16 | from django.utils import timezone 17 | from django.contrib.auth.models import User 18 | from django.conf import settings 19 | from django.db import connection 20 | 21 | from database_size import models 22 | from database_size import utils 23 | 24 | warnings.simplefilter('error', RuntimeWarning) 25 | 26 | socket.gethostname = lambda: 'localhost' 27 | 28 | class Tests(TestCase): 29 | 30 | def setUp(self): 31 | with connection.cursor() as cursor: 32 | with open('database_size/sql/table.sqlite3.sql') as fin: 33 | cursor.execute(fin.read()) 34 | 35 | def test_example(self): 36 | username = 'admin@localhost.com' 37 | password = 'password' 38 | admin = User.objects.get_or_create( 39 | username=username, 40 | defaults=dict( 41 | is_superuser=True, is_active=True, is_staff=True, email=username))[0] 42 | admin.set_password(password) 43 | admin.save() 44 | c = Client() 45 | #c.force_login(admin) 46 | ret = c.login(username=username, password=password) 47 | self.assertTrue(ret) 48 | response = c.get('/admin/database_size/') 49 | self.assertEqual(response.status_code, 200) 50 | 51 | def test_table(self): 52 | # Note, this is only empty for Sqlite3. 53 | self.assertEqual(models.Table.objects.all().count(), 1) 54 | -------------------------------------------------------------------------------- /database_size/tests/urls.py: -------------------------------------------------------------------------------- 1 | 2 | try: 3 | # Removed in Django 1.6 4 | from django.conf.urls.defaults import url, include 5 | except ImportError: 6 | from django.conf.urls import url, include 7 | 8 | try: 9 | # Relocated in Django 1.6 10 | from django.conf.urls.defaults import patterns 11 | except ImportError: 12 | # Completely removed in Django 1.10 13 | try: 14 | from django.conf.urls import patterns 15 | except ImportError: 16 | patterns = None 17 | 18 | from django.contrib import admin 19 | from django.core.exceptions import ImproperlyConfigured 20 | 21 | admin.autodiscover() 22 | 23 | try: 24 | _patterns = [ 25 | url(r'^admin/', include(admin.site.urls)), 26 | ] 27 | except ImproperlyConfigured: 28 | _patterns = [ 29 | url(r'^admin/', admin.site.urls), 30 | ] 31 | 32 | if patterns is None: 33 | urlpatterns = _patterns 34 | else: 35 | urlpatterns = patterns('', *_patterns) 36 | -------------------------------------------------------------------------------- /database_size/tests/views.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisspen/django-database-size/15dc4c9dad2f648513d7b2a106093d342dad0e03/database_size/tests/views.py -------------------------------------------------------------------------------- /database_size/utils.py: -------------------------------------------------------------------------------- 1 | from __future__ import division 2 | from __future__ import print_function 3 | 4 | try: 5 | long(1) 6 | except NameError: 7 | long = int # pylint: disable=redefined-builtin 8 | 9 | # http://code.activestate.com/recipes/577081-humanized-representation-of-a-number-of-bytes/ 10 | def humanize_bytes(b, precision=1): 11 | """Return a humanized string representation of a number of bytes. 12 | 13 | Assumes `from __future__ import division`. 14 | 15 | >>> humanize_bytes(1) 16 | '1 byte' 17 | >>> humanize_bytes(1024) 18 | '1.0 kB' 19 | >>> humanize_bytes(1024*123) 20 | '123.0 kB' 21 | >>> humanize_bytes(1024*12342) 22 | '12.1 MB' 23 | >>> humanize_bytes(1024*12342,2) 24 | '12.05 MB' 25 | >>> humanize_bytes(1024*1234,2) 26 | '1.21 MB' 27 | >>> humanize_bytes(1024*1234*1111,2) 28 | '1.31 GB' 29 | >>> humanize_bytes(1024*1234*1111,1) 30 | '1.3 GB' 31 | """ 32 | abbrevs = ( 33 | (1<= factor: 44 | break 45 | return '%.*f %s' % (precision, b / factor, suffix) # pylint: disable=undefined-loop-variable 46 | -------------------------------------------------------------------------------- /init_virtualenv.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | VENV=.env 5 | 6 | # Remove existing virtualenv if it exists. 7 | [ -d $VENV ] && rm -Rf $VENV 8 | 9 | virtualenv -p $(which python) $VENV 10 | . $VENV/bin/activate 11 | pip install -U pip 12 | 13 | pip install -r requirements-test.txt 14 | -------------------------------------------------------------------------------- /pep8.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | pylint --rcfile=pylint.rc database_size setup.py 3 | -------------------------------------------------------------------------------- /publish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Helper script for building and uploading the package to PyPI. 3 | set -e 4 | if [ ! -d .env ]; then 5 | echo "[$(date)] Initializing environment." 6 | virtualenv -p python3.11 .env 7 | . .env/bin/activate 8 | pip install -U pip setuptools wheel 9 | pip install -r requirements-test.txt 10 | fi 11 | . .env/bin/activate 12 | echo "[$(date)] Building package." 13 | python setup.py sdist 14 | FN=`find ./dist -name "*.tar.gz" -print0 | xargs -r -0 ls -1 -t | head -1` 15 | echo "[$(date)] Uploading $FN." 16 | twine upload --repository django-database-size $FN 17 | -------------------------------------------------------------------------------- /pylint.messages: -------------------------------------------------------------------------------- 1 | :blacklisted-name (C0102): *Black listed name "%s"* 2 | Used when the name is listed in the black list (unauthorized names). 3 | :invalid-name (C0103): *Invalid %s name "%s"%s* 4 | Used when the name doesn't match the regular expression associated to its type 5 | (constant, variable, class...). 6 | :missing-docstring (C0111): *Missing %s docstring* 7 | Used when a module, function, class or method has no docstring.Some special 8 | methods like __init__ doesn't necessary require a docstring. 9 | :empty-docstring (C0112): *Empty %s docstring* 10 | Used when a module, function, class or method has an empty docstring (it would 11 | be too easy ;). 12 | :unneeded-not (C0113): *Consider changing "%s" to "%s"* 13 | Used when a boolean expression contains an unneeded negation. 14 | :singleton-comparison (C0121): *Comparison to %s should be %s* 15 | Used when an expression is compared to singleton values like True, False or 16 | None. 17 | :misplaced-comparison-constant (C0122): *Comparison should be %s* 18 | Used when the constant is placed on the left sideof a comparison. It is 19 | usually clearer in intent to place it in the right hand side of the 20 | comparison. 21 | :unidiomatic-typecheck (C0123): *Using type() instead of isinstance() for a typecheck.* 22 | The idiomatic way to perform an explicit typecheck in Python is to use 23 | isinstance(x, Y) rather than type(x) == Y, type(x) is Y. Though there are 24 | unusual situations where these give different results. 25 | :consider-using-enumerate (C0200): *Consider using enumerate instead of iterating with range and len* 26 | Emitted when code that iterates with range and len is encountered. Such code 27 | can be simplified by using the enumerate builtin. 28 | :consider-iterating-dictionary (C0201): *Consider iterating the dictionary directly instead of calling .keys()* 29 | Emitted when the keys of a dictionary are iterated through the .keys() method. 30 | It is enough to just iterate through the dictionary itself, as in "for key in 31 | dictionary". 32 | :bad-classmethod-argument (C0202): *Class method %s should have %s as first argument* 33 | Used when a class method has a first argument named differently than the value 34 | specified in valid-classmethod-first-arg option (default to "cls"), 35 | recommended to easily differentiate them from regular instance methods. 36 | :bad-mcs-method-argument (C0203): *Metaclass method %s should have %s as first argument* 37 | Used when a metaclass method has a first agument named differently than the 38 | value specified in valid-classmethod-first-arg option (default to "cls"), 39 | recommended to easily differentiate them from regular instance methods. 40 | :bad-mcs-classmethod-argument (C0204): *Metaclass class method %s should have %s as first argument* 41 | Used when a metaclass class method has a first argument named differently than 42 | the value specified in valid-metaclass-classmethod-first-arg option (default 43 | to "mcs"), recommended to easily differentiate them from regular instance 44 | methods. 45 | :line-too-long (C0301): *Line too long (%s/%s)* 46 | Used when a line is longer than a given number of characters. 47 | :too-many-lines (C0302): *Too many lines in module (%s/%s)* 48 | Used when a module has too much lines, reducing its readability. 49 | :trailing-whitespace (C0303): *Trailing whitespace* 50 | Used when there is whitespace between the end of a line and the newline. 51 | :missing-final-newline (C0304): *Final newline missing* 52 | Used when the last line in a file is missing a newline. 53 | :trailing-newlines (C0305): *Trailing newlines* 54 | Used when there are trailing blank lines in a file. 55 | :multiple-statements (C0321): *More than one statement on a single line* 56 | Used when more than on statement are found on the same line. 57 | :superfluous-parens (C0325): *Unnecessary parens after %r keyword* 58 | Used when a single item in parentheses follows an if, for, or other keyword. 59 | :bad-whitespace (C0326): *%s space %s %s %s* 60 | Used when a wrong number of spaces is used around an operator, bracket or 61 | block opener. 62 | :mixed-line-endings (C0327): *Mixed line endings LF and CRLF* 63 | Used when there are mixed (LF and CRLF) newline signs in a file. 64 | :unexpected-line-ending-format (C0328): *Unexpected line ending format. There is '%s' while it should be '%s'.* 65 | Used when there is different newline than expected. 66 | :bad-continuation (C0330): *Wrong %s indentation%s%s.* 67 | TODO 68 | :wrong-spelling-in-comment (C0401): *Wrong spelling of a word '%s' in a comment:* 69 | Used when a word in comment is not spelled correctly. 70 | :wrong-spelling-in-docstring (C0402): *Wrong spelling of a word '%s' in a docstring:* 71 | Used when a word in docstring is not spelled correctly. 72 | :invalid-characters-in-docstring (C0403): *Invalid characters %r in a docstring* 73 | Used when a word in docstring cannot be checked by enchant. 74 | :multiple-imports (C0410): *Multiple imports on one line (%s)* 75 | Used when import statement importing multiple modules is detected. 76 | :wrong-import-order (C0411): *%s comes before %s* 77 | Used when PEP8 import order is not respected (standard imports first, then 78 | third-party libraries, then local imports) 79 | :ungrouped-imports (C0412): *Imports from package %s are not grouped* 80 | Used when imports are not grouped by packages 81 | :wrong-import-position (C0413): *Import "%s" should be placed at the top of the module* 82 | Used when code and imports are mixed 83 | :old-style-class (C1001): *Old-style class defined.* 84 | Used when a class is defined that does not inherit from anotherclass and does 85 | not inherit explicitly from "object". This message can't be emitted when using 86 | Python >= 3.0. 87 | :syntax-error (E0001): 88 | Used when a syntax error is raised for a module. 89 | :unrecognized-inline-option (E0011): *Unrecognized file option %r* 90 | Used when an unknown inline option is encountered. 91 | :bad-option-value (E0012): *Bad option value %r* 92 | Used when a bad value for an inline option is encountered. 93 | :init-is-generator (E0100): *__init__ method is a generator* 94 | Used when the special class method __init__ is turned into a generator by a 95 | yield in its body. 96 | :return-in-init (E0101): *Explicit return in __init__* 97 | Used when the special class method __init__ has an explicit return value. 98 | :function-redefined (E0102): *%s already defined line %s* 99 | Used when a function / class / method is redefined. 100 | :not-in-loop (E0103): *%r not properly in loop* 101 | Used when break or continue keywords are used outside a loop. 102 | :return-outside-function (E0104): *Return outside function* 103 | Used when a "return" statement is found outside a function or method. 104 | :yield-outside-function (E0105): *Yield outside function* 105 | Used when a "yield" statement is found outside a function or method. 106 | :return-arg-in-generator (E0106): *Return with argument inside generator* 107 | Used when a "return" statement with an argument is found outside in a 108 | generator function or method (e.g. with some "yield" statements). This message 109 | can't be emitted when using Python >= 3.3. 110 | :nonexistent-operator (E0107): *Use of the non-existent %s operator* 111 | Used when you attempt to use the C-style pre-increment orpre-decrement 112 | operator -- and ++, which doesn't exist in Python. 113 | :duplicate-argument-name (E0108): *Duplicate argument name %s in function definition* 114 | Duplicate argument names in function definitions are syntax errors. 115 | :abstract-class-instantiated (E0110): *Abstract class %r with abstract methods instantiated* 116 | Used when an abstract class with `abc.ABCMeta` as metaclass has abstract 117 | methods and is instantiated. 118 | :bad-reversed-sequence (E0111): *The first reversed() argument is not a sequence* 119 | Used when the first argument to reversed() builtin isn't a sequence (does not 120 | implement __reversed__, nor __getitem__ and __len__ 121 | :continue-in-finally (E0116): *'continue' not supported inside 'finally' clause* 122 | Emitted when the `continue` keyword is found inside a finally clause, which is 123 | a SyntaxError. 124 | :method-hidden (E0202): *An attribute defined in %s line %s hides this method* 125 | Used when a class defines a method which is hidden by an instance attribute 126 | from an ancestor class or set by some client code. 127 | :access-member-before-definition (E0203): *Access to member %r before its definition line %s* 128 | Used when an instance member is accessed before it's actually assigned. 129 | :no-method-argument (E0211): *Method has no argument* 130 | Used when a method which should have the bound instance as first argument has 131 | no argument defined. 132 | :no-self-argument (E0213): *Method should have "self" as first argument* 133 | Used when a method has an attribute different the "self" as first argument. 134 | This is considered as an error since this is a so common convention that you 135 | shouldn't break it! 136 | :invalid-slots-object (E0236): *Invalid object %r in __slots__, must contain only non empty strings* 137 | Used when an invalid (non-string) object occurs in __slots__. 138 | :assigning-non-slot (E0237): *Assigning to attribute %r not defined in class slots* 139 | Used when assigning to an attribute not defined in the class slots. 140 | :invalid-slots (E0238): *Invalid __slots__ object* 141 | Used when an invalid __slots__ is found in class. Only a string, an iterable 142 | or a sequence is permitted. 143 | :inherit-non-class (E0239): *Inheriting %r, which is not a class.* 144 | Used when a class inherits from something which is not a class. 145 | :inconsistent-mro (E0240): *Inconsistent method resolution order for class %r* 146 | Used when a class has an inconsistent method resolutin order. 147 | :duplicate-bases (E0241): *Duplicate bases for class %r* 148 | Used when a class has duplicate bases. 149 | :non-iterator-returned (E0301): *__iter__ returns non-iterator* 150 | Used when an __iter__ method returns something which is not an iterable (i.e. 151 | has no `next` method) 152 | :unexpected-special-method-signature (E0302): *The special method %r expects %s param(s), %d %s given* 153 | Emitted when a special method was defined with an invalid number of 154 | parameters. If it has too few or too many, it might not work at all. 155 | :invalid-length-returned (E0303): *__len__ does not return non-negative integer* 156 | Used when an __len__ method returns something which is not a non-negative 157 | integer 158 | :import-error (E0401): *Unable to import %s* 159 | Used when pylint has been unable to import a module. 160 | :used-before-assignment (E0601): *Using variable %r before assignment* 161 | Used when a local variable is accessed before it's assignment. 162 | :undefined-variable (E0602): *Undefined variable %r* 163 | Used when an undefined variable is accessed. 164 | :undefined-all-variable (E0603): *Undefined variable name %r in __all__* 165 | Used when an undefined variable name is referenced in __all__. 166 | :invalid-all-object (E0604): *Invalid object %r in __all__, must contain only strings* 167 | Used when an invalid (non-string) object occurs in __all__. 168 | :no-name-in-module (E0611): *No name %r in module %r* 169 | Used when a name cannot be found in a module. 170 | :unbalanced-tuple-unpacking (E0632): *Possible unbalanced tuple unpacking with sequence%s: left side has %d label(s), right side has %d value(s)* 171 | Used when there is an unbalanced tuple unpacking in assignment 172 | :unpacking-non-sequence (E0633): *Attempting to unpack a non-sequence%s* 173 | Used when something which is not a sequence is used in an unpack assignment 174 | :bad-except-order (E0701): *Bad except clauses order (%s)* 175 | Used when except clauses are not in the correct order (from the more specific 176 | to the more generic). If you don't fix the order, some exceptions may not be 177 | catched by the most specific handler. 178 | :raising-bad-type (E0702): *Raising %s while only classes or instances are allowed* 179 | Used when something which is neither a class, an instance or a string is 180 | raised (i.e. a `TypeError` will be raised). 181 | :misplaced-bare-raise (E0704): *The raise statement is not inside an except clause* 182 | Used when a bare raise is not used inside an except clause. This generates an 183 | error, since there are no active exceptions to be reraised. An exception to 184 | this rule is represented by a bare raise inside a finally clause, which might 185 | work, as long as an exception is raised inside the try block, but it is 186 | nevertheless a code smell that must not be relied upon. 187 | :raising-non-exception (E0710): *Raising a new style class which doesn't inherit from BaseException* 188 | Used when a new style class which doesn't inherit from BaseException is 189 | raised. 190 | :notimplemented-raised (E0711): *NotImplemented raised - should raise NotImplementedError* 191 | Used when NotImplemented is raised instead of NotImplementedError 192 | :catching-non-exception (E0712): *Catching an exception which doesn't inherit from BaseException: %s* 193 | Used when a class which doesn't inherit from BaseException is used as an 194 | exception in an except clause. 195 | :slots-on-old-class (E1001): *Use of __slots__ on an old style class* 196 | Used when an old style class uses the __slots__ attribute. This message can't 197 | be emitted when using Python >= 3.0. 198 | :super-on-old-class (E1002): *Use of super on an old style class* 199 | Used when an old style class uses the super builtin. This message can't be 200 | emitted when using Python >= 3.0. 201 | :bad-super-call (E1003): *Bad first argument %r given to super()* 202 | Used when another argument than the current class is given as first argument 203 | of the super builtin. 204 | :missing-super-argument (E1004): *Missing argument to super()* 205 | Used when the super builtin didn't receive an argument. This message can't be 206 | emitted when using Python >= 3.0. 207 | :no-member (E1101): *%s %r has no %r member* 208 | Used when a variable is accessed for an unexistent member. 209 | :not-callable (E1102): *%s is not callable* 210 | Used when an object being called has been inferred to a non callable object 211 | :assignment-from-no-return (E1111): *Assigning to function call which doesn't return* 212 | Used when an assignment is done on a function call but the inferred function 213 | doesn't return anything. 214 | :no-value-for-parameter (E1120): *No value for argument %s in %s call* 215 | Used when a function call passes too few arguments. 216 | :too-many-function-args (E1121): *Too many positional arguments for %s call* 217 | Used when a function call passes too many positional arguments. 218 | :unexpected-keyword-arg (E1123): *Unexpected keyword argument %r in %s call* 219 | Used when a function call passes a keyword argument that doesn't correspond to 220 | one of the function's parameter names. 221 | :redundant-keyword-arg (E1124): *Argument %r passed by position and keyword in %s call* 222 | Used when a function call would result in assigning multiple values to a 223 | function parameter, one value from a positional argument and one from a 224 | keyword argument. 225 | :invalid-sequence-index (E1126): *Sequence index is not an int, slice, or instance with __index__* 226 | Used when a sequence type is indexed with an invalid type. Valid types are 227 | ints, slices, and objects with an __index__ method. 228 | :invalid-slice-index (E1127): *Slice index is not an int, None, or instance with __index__* 229 | Used when a slice index is not an integer, None, or an object with an 230 | __index__ method. 231 | :assignment-from-none (E1128): *Assigning to function call which only returns None* 232 | Used when an assignment is done on a function call but the inferred function 233 | returns nothing but None. 234 | :not-context-manager (E1129): *Context manager '%s' doesn't implement __enter__ and __exit__.* 235 | Used when an instance in a with statement doesn't implement the context 236 | manager protocol(__enter__/__exit__). 237 | :invalid-unary-operand-type (E1130): 238 | Emitted when an unary operand is used on an object which does not support this 239 | type of operation 240 | :unsupported-binary-operation (E1131): 241 | Emitted when a binary arithmetic operation between two operands is not 242 | supported. 243 | :repeated-keyword (E1132): *Got multiple values for keyword argument %r in function call* 244 | Emitted when a function call got multiple values for a keyword. 245 | :not-an-iterable (E1133): *Non-iterable value %s is used in an iterating context* 246 | Used when a non-iterable value is used in place whereiterable is expected 247 | :not-a-mapping (E1134): *Non-mapping value %s is used in a mapping context* 248 | Used when a non-mapping value is used in place wheremapping is expected 249 | :unsupported-membership-test (E1135): *Value '%s' doesn't support membership test* 250 | Emitted when an instance in membership test expression doesn'timplement 251 | membership protocol (__contains__/__iter__/__getitem__) 252 | :unsubscriptable-object (E1136): *Value '%s' is unsubscriptable* 253 | Emitted when a subscripted value doesn't support subscription(i.e. doesn't 254 | define __getitem__ method) 255 | :logging-unsupported-format (E1200): *Unsupported logging format character %r (%#02x) at index %d* 256 | Used when an unsupported format character is used in a logging statement 257 | format string. 258 | :logging-format-truncated (E1201): *Logging format string ends in middle of conversion specifier* 259 | Used when a logging statement format string terminates before the end of a 260 | conversion specifier. 261 | :logging-too-many-args (E1205): *Too many arguments for logging format string* 262 | Used when a logging format string is given too few arguments. 263 | :logging-too-few-args (E1206): *Not enough arguments for logging format string* 264 | Used when a logging format string is given too many arguments 265 | :bad-format-character (E1300): *Unsupported format character %r (%#02x) at index %d* 266 | Used when a unsupported format character is used in a format string. 267 | :truncated-format-string (E1301): *Format string ends in middle of conversion specifier* 268 | Used when a format string terminates before the end of a conversion specifier. 269 | :mixed-format-string (E1302): *Mixing named and unnamed conversion specifiers in format string* 270 | Used when a format string contains both named (e.g. '%(foo)d') and unnamed 271 | (e.g. '%d') conversion specifiers. This is also used when a named conversion 272 | specifier contains * for the minimum field width and/or precision. 273 | :format-needs-mapping (E1303): *Expected mapping for format string, not %s* 274 | Used when a format string that uses named conversion specifiers is used with 275 | an argument that is not a mapping. 276 | :missing-format-string-key (E1304): *Missing key %r in format string dictionary* 277 | Used when a format string that uses named conversion specifiers is used with a 278 | dictionary that doesn't contain all the keys required by the format string. 279 | :too-many-format-args (E1305): *Too many arguments for format string* 280 | Used when a format string that uses unnamed conversion specifiers is given too 281 | many arguments. 282 | :too-few-format-args (E1306): *Not enough arguments for format string* 283 | Used when a format string that uses unnamed conversion specifiers is given too 284 | few arguments 285 | :bad-str-strip-call (E1310): *Suspicious argument in %s.%s call* 286 | The argument to a str.{l,r,}strip call contains a duplicate character, 287 | :print-statement (E1601): *print statement used* 288 | Used when a print statement is used (`print` is a function in Python 3) This 289 | message can't be emitted when using Python >= 3.0. 290 | :parameter-unpacking (E1602): *Parameter unpacking specified* 291 | Used when parameter unpacking is specified for a function(Python 3 doesn't 292 | allow it) This message can't be emitted when using Python >= 3.0. 293 | :unpacking-in-except (E1603): *Implicit unpacking of exceptions is not supported in Python 3* 294 | Python3 will not allow implicit unpacking of exceptions in except clauses. See 295 | http://www.python.org/dev/peps/pep-3110/ This message can't be emitted when 296 | using Python >= 3.0. 297 | :old-raise-syntax (E1604): *Use raise ErrorClass(args) instead of raise ErrorClass, args.* 298 | Used when the alternate raise syntax 'raise foo, bar' is used instead of 299 | 'raise foo(bar)'. This message can't be emitted when using Python >= 3.0. 300 | :backtick (E1605): *Use of the `` operator* 301 | Used when the deprecated "``" (backtick) operator is used instead of the str() 302 | function. This message can't be emitted when using Python >= 3.0. 303 | :long-suffix (E1606): *Use of long suffix* 304 | Used when "l" or "L" is used to mark a long integer. This will not work in 305 | Python 3, since `int` and `long` types have merged. This message can't be 306 | emitted when using Python >= 3.0. 307 | :old-ne-operator (E1607): *Use of the <> operator* 308 | Used when the deprecated "<>" operator is used instead of "!=". This is 309 | removed in Python 3. This message can't be emitted when using Python >= 3.0. 310 | :old-octal-literal (E1608): *Use of old octal literal* 311 | Usen when encountering the old octal syntax, removed in Python 3. To use the 312 | new syntax, prepend 0o on the number. This message can't be emitted when using 313 | Python >= 3.0. 314 | :import-star-module-level (E1609): *Import * only allowed at module level* 315 | Used when the import star syntax is used somewhere else than the module level. 316 | This message can't be emitted when using Python >= 3.0. 317 | :fatal (F0001): 318 | Used when an error occurred preventing the analysis of a module (unable to 319 | find it for instance). 320 | :astroid-error (F0002): *%s: %s* 321 | Used when an unexpected error occurred while building the Astroid 322 | representation. This is usually accompanied by a traceback. Please report such 323 | errors ! 324 | :parse-error (F0010): *error while code parsing: %s* 325 | Used when an exception occured while building the Astroid representation which 326 | could be handled by astroid. 327 | :method-check-failed (F0202): *Unable to check methods signature (%s / %s)* 328 | Used when Pylint has been unable to check methods signature compatibility for 329 | an unexpected reason. Please report this kind if you don't make sense of it. 330 | :raw-checker-failed (I0001): *Unable to run raw checkers on built-in module %s* 331 | Used to inform that a built-in module has not been checked using the raw 332 | checkers. 333 | :bad-inline-option (I0010): *Unable to consider inline option %r* 334 | Used when an inline option is either badly formatted or can't be used inside 335 | modules. 336 | :locally-disabled (I0011): *Locally disabling %s (%s)* 337 | Used when an inline option disables a message or a messages category. 338 | :locally-enabled (I0012): *Locally enabling %s (%s)* 339 | Used when an inline option enables a message or a messages category. 340 | :file-ignored (I0013): *Ignoring entire file* 341 | Used to inform that the file will not be checked 342 | :suppressed-message (I0020): *Suppressed %s (from line %d)* 343 | A message was triggered on a line, but suppressed explicitly by a disable= 344 | comment in the file. This message is not generated for messages that are 345 | ignored due to configuration settings. 346 | :useless-suppression (I0021): *Useless suppression of %s* 347 | Reported when a message is explicitly disabled for a line or a block of code, 348 | but never triggered. 349 | :deprecated-pragma (I0022): *Pragma "%s" is deprecated, use "%s" instead* 350 | Some inline pylint options have been renamed or reworked, only the most recent 351 | form should be used. NOTE:skip-all is only available with pylint >= 0.26 352 | :too-many-nested-blocks (R0101): *Too many nested blocks (%s/%s)* 353 | Used when a function or a method has too many nested blocks. This makes the 354 | code less understandable and maintainable. 355 | :simplifiable-if-statement (R0102): *The if statement can be replaced with %s* 356 | Used when an if statement can be replaced with 'bool(test)'. 357 | :no-self-use (R0201): *Method could be a function* 358 | Used when a method doesn't use its bound instance, and so could be written as 359 | a function. 360 | :no-classmethod-decorator (R0202): *Consider using a decorator instead of calling classmethod* 361 | Used when a class method is defined without using the decorator syntax. 362 | :no-staticmethod-decorator (R0203): *Consider using a decorator instead of calling staticmethod* 363 | Used when a static method is defined without using the decorator syntax. 364 | :redefined-variable-type (R0204): *Redefinition of %s type from %s to %s* 365 | Used when the type of a variable changes inside a method or a function. 366 | :cyclic-import (R0401): *Cyclic import (%s)* 367 | Used when a cyclic import between two or more modules is detected. 368 | :duplicate-code (R0801): *Similar lines in %s files* 369 | Indicates that a set of similar lines has been detected among multiple file. 370 | This usually means that the code should be refactored to avoid this 371 | duplication. 372 | :too-many-ancestors (R0901): *Too many ancestors (%s/%s)* 373 | Used when class has too many parent classes, try to reduce this to get a 374 | simpler (and so easier to use) class. 375 | :too-many-instance-attributes (R0902): *Too many instance attributes (%s/%s)* 376 | Used when class has too many instance attributes, try to reduce this to get a 377 | simpler (and so easier to use) class. 378 | :too-few-public-methods (R0903): *Too few public methods (%s/%s)* 379 | Used when class has too few public methods, so be sure it's really worth it. 380 | :too-many-public-methods (R0904): *Too many public methods (%s/%s)* 381 | Used when class has too many public methods, try to reduce this to get a 382 | simpler (and so easier to use) class. 383 | :too-many-return-statements (R0911): *Too many return statements (%s/%s)* 384 | Used when a function or method has too many return statement, making it hard 385 | to follow. 386 | :too-many-branches (R0912): *Too many branches (%s/%s)* 387 | Used when a function or method has too many branches, making it hard to 388 | follow. 389 | :too-many-arguments (R0913): *Too many arguments (%s/%s)* 390 | Used when a function or method takes too many arguments. 391 | :too-many-locals (R0914): *Too many local variables (%s/%s)* 392 | Used when a function or method has too many local variables. 393 | :too-many-statements (R0915): *Too many statements (%s/%s)* 394 | Used when a function or method has too many statements. You should then split 395 | it in smaller functions / methods. 396 | :too-many-boolean-expressions (R0916): *Too many boolean expressions in if statement (%s/%s)* 397 | Used when a if statement contains too many boolean expressions 398 | :unreachable (W0101): *Unreachable code* 399 | Used when there is some code behind a "return" or "raise" statement, which 400 | will never be accessed. 401 | :dangerous-default-value (W0102): *Dangerous default value %s as argument* 402 | Used when a mutable value as list or dictionary is detected in a default value 403 | for an argument. 404 | :pointless-statement (W0104): *Statement seems to have no effect* 405 | Used when a statement doesn't have (or at least seems to) any effect. 406 | :pointless-string-statement (W0105): *String statement has no effect* 407 | Used when a string is used as a statement (which of course has no effect). 408 | This is a particular case of W0104 with its own message so you can easily 409 | disable it if you're using those strings as documentation, instead of 410 | comments. 411 | :expression-not-assigned (W0106): *Expression "%s" is assigned to nothing* 412 | Used when an expression that is not a function call is assigned to nothing. 413 | Probably something else was intended. 414 | :unnecessary-pass (W0107): *Unnecessary pass statement* 415 | Used when a "pass" statement that can be avoided is encountered. 416 | :unnecessary-lambda (W0108): *Lambda may not be necessary* 417 | Used when the body of a lambda expression is a function call on the same 418 | argument list as the lambda itself; such lambda expressions are in all but a 419 | few cases replaceable with the function being called in the body of the 420 | lambda. 421 | :duplicate-key (W0109): *Duplicate key %r in dictionary* 422 | Used when a dictionary expression binds the same key multiple times. 423 | :deprecated-lambda (W0110): *map/filter on lambda could be replaced by comprehension* 424 | Used when a lambda is the first argument to "map" or "filter". It could be 425 | clearer as a list comprehension or generator expression. This message can't be 426 | emitted when using Python >= 3.0. 427 | :useless-else-on-loop (W0120): *Else clause on loop without a break statement* 428 | Loops should only have an else clause if they can exit early with a break 429 | statement, otherwise the statements under else should be on the same scope as 430 | the loop itself. 431 | :exec-used (W0122): *Use of exec* 432 | Used when you use the "exec" statement (function for Python 3), to discourage 433 | its usage. That doesn't mean you can not use it ! 434 | :eval-used (W0123): *Use of eval* 435 | Used when you use the "eval" function, to discourage its usage. Consider using 436 | `ast.literal_eval` for safely evaluating strings containing Python expressions 437 | from untrusted sources. 438 | :confusing-with-statement (W0124): *Following "as" with another context manager looks like a tuple.* 439 | Emitted when a `with` statement component returns multiple values and uses 440 | name binding with `as` only for a part of those values, as in with ctx() as a, 441 | b. This can be misleading, since it's not clear if the context manager returns 442 | a tuple or if the node without a name binding is another context manager. 443 | :using-constant-test (W0125): *Using a conditional statement with a constant value* 444 | Emitted when a conditional statement (If or ternary if) uses a constant value 445 | for its test. This might not be what the user intended to do. 446 | :lost-exception (W0150): *%s statement in finally block may swallow exception* 447 | Used when a break or a return statement is found inside the finally clause of 448 | a try...finally block: the exceptions raised in the try clause will be 449 | silently swallowed instead of being re-raised. 450 | :assert-on-tuple (W0199): *Assert called on a 2-uple. Did you mean 'assert x,y'?* 451 | A call of assert on a tuple will always evaluate to true if the tuple is not 452 | empty, and will always evaluate to false if it is. 453 | :attribute-defined-outside-init (W0201): *Attribute %r defined outside __init__* 454 | Used when an instance attribute is defined outside the __init__ method. 455 | :bad-staticmethod-argument (W0211): *Static method with %r as first argument* 456 | Used when a static method has "self" or a value specified in valid- 457 | classmethod-first-arg option or valid-metaclass-classmethod-first-arg option 458 | as first argument. 459 | :protected-access (W0212): *Access to a protected member %s of a client class* 460 | Used when a protected member (i.e. class member with a name beginning with an 461 | underscore) is access outside the class or a descendant of the class where 462 | it's defined. 463 | :arguments-differ (W0221): *Arguments number differs from %s %r method* 464 | Used when a method has a different number of arguments than in the implemented 465 | interface or in an overridden method. 466 | :signature-differs (W0222): *Signature differs from %s %r method* 467 | Used when a method signature is different than in the implemented interface or 468 | in an overridden method. 469 | :abstract-method (W0223): *Method %r is abstract in class %r but is not overridden* 470 | Used when an abstract method (i.e. raise NotImplementedError) is not 471 | overridden in concrete class. 472 | :super-init-not-called (W0231): *__init__ method from base class %r is not called* 473 | Used when an ancestor class method has an __init__ method which is not called 474 | by a derived class. 475 | :no-init (W0232): *Class has no __init__ method* 476 | Used when a class has no __init__ method, neither its parent classes. 477 | :non-parent-init-called (W0233): *__init__ method from a non direct base class %r is called* 478 | Used when an __init__ method is called on a class which is not in the direct 479 | ancestors for the analysed class. 480 | :unnecessary-semicolon (W0301): *Unnecessary semicolon* 481 | Used when a statement is ended by a semi-colon (";"), which isn't necessary 482 | (that's python, not C ;). 483 | :bad-indentation (W0311): *Bad indentation. Found %s %s, expected %s* 484 | Used when an unexpected number of indentation's tabulations or spaces has been 485 | found. 486 | :mixed-indentation (W0312): *Found indentation with %ss instead of %ss* 487 | Used when there are some mixed tabs and spaces in a module. 488 | :lowercase-l-suffix (W0332): *Use of "l" as long integer identifier* 489 | Used when a lower case "l" is used to mark a long integer. You should use a 490 | upper case "L" since the letter "l" looks too much like the digit "1" This 491 | message can't be emitted when using Python >= 3.0. 492 | :wildcard-import (W0401): *Wildcard import %s* 493 | Used when `from module import *` is detected. 494 | :deprecated-module (W0402): *Uses of a deprecated module %r* 495 | Used a module marked as deprecated is imported. 496 | :relative-import (W0403): *Relative import %r, should be %r* 497 | Used when an import relative to the package directory is detected. This 498 | message can't be emitted when using Python >= 3.0. 499 | :reimported (W0404): *Reimport %r (imported line %s)* 500 | Used when a module is reimported multiple times. 501 | :import-self (W0406): *Module import itself* 502 | Used when a module is importing itself. 503 | :misplaced-future (W0410): *__future__ import is not the first non docstring statement* 504 | Python 2.5 and greater require __future__ import to be the first non docstring 505 | statement in the module. 506 | :fixme (W0511): 507 | Used when a warning note as FIXME or XXX is detected. 508 | :invalid-encoded-data (W0512): *Cannot decode using encoding "%s", unexpected byte at position %d* 509 | Used when a source line cannot be decoded using the specified source file 510 | encoding. This message can't be emitted when using Python >= 3.0. 511 | :global-variable-undefined (W0601): *Global variable %r undefined at the module level* 512 | Used when a variable is defined through the "global" statement but the 513 | variable is not defined in the module scope. 514 | :global-variable-not-assigned (W0602): *Using global for %r but no assignment is done* 515 | Used when a variable is defined through the "global" statement but no 516 | assignment to this variable is done. 517 | :global-statement (W0603): *Using the global statement* 518 | Used when you use the "global" statement to update a global variable. Pylint 519 | just try to discourage this usage. That doesn't mean you can not use it ! 520 | :global-at-module-level (W0604): *Using the global statement at the module level* 521 | Used when you use the "global" statement at the module level since it has no 522 | effect 523 | :unused-import (W0611): *Unused %s* 524 | Used when an imported module or variable is not used. 525 | :unused-variable (W0612): *Unused variable %r* 526 | Used when a variable is defined but not used. 527 | :unused-argument (W0613): *Unused argument %r* 528 | Used when a function or method argument is not used. 529 | :unused-wildcard-import (W0614): *Unused import %s from wildcard import* 530 | Used when an imported module or variable is not used from a `'from X import 531 | *'` style import. 532 | :redefined-outer-name (W0621): *Redefining name %r from outer scope (line %s)* 533 | Used when a variable's name hide a name defined in the outer scope. 534 | :redefined-builtin (W0622): *Redefining built-in %r* 535 | Used when a variable or function override a built-in. 536 | :redefine-in-handler (W0623): *Redefining name %r from %s in exception handler* 537 | Used when an exception handler assigns the exception to an existing name 538 | :undefined-loop-variable (W0631): *Using possibly undefined loop variable %r* 539 | Used when an loop variable (i.e. defined by a for loop or a list comprehension 540 | or a generator expression) is used outside the loop. 541 | :cell-var-from-loop (W0640): *Cell variable %s defined in loop* 542 | A variable used in a closure is defined in a loop. This will result in all 543 | closures using the same value for the closed-over variable. 544 | :bare-except (W0702): *No exception type(s) specified* 545 | Used when an except clause doesn't specify exceptions type to catch. 546 | :broad-except (W0703): *Catching too general exception %s* 547 | Used when an except catches a too general exception, possibly burying 548 | unrelated errors. 549 | :duplicate-except (W0705): *Catching previously caught exception type %s* 550 | Used when an except catches a type that was already caught by a previous 551 | handler. 552 | :nonstandard-exception (W0710): *Exception doesn't inherit from standard "Exception" class* 553 | Used when a custom exception class is raised but doesn't inherit from the 554 | builtin "Exception" class. This message can't be emitted when using Python >= 555 | 3.0. 556 | :binary-op-exception (W0711): *Exception to catch is the result of a binary "%s" operation* 557 | Used when the exception to catch is of the form "except A or B:". If intending 558 | to catch multiple, rewrite as "except (A, B):" 559 | :property-on-old-class (W1001): *Use of "property" on an old style class* 560 | Used when Pylint detect the use of the builtin "property" on an old style 561 | class while this is relying on new style classes features. This message can't 562 | be emitted when using Python >= 3.0. 563 | :logging-not-lazy (W1201): *Specify string format arguments as logging function parameters* 564 | Used when a logging statement has a call form of "logging.(format_string % (format_args...))". Such calls should leave string 566 | interpolation to the logging method itself and be written "logging.(format_string, format_args...)" so that the program may avoid 568 | incurring the cost of the interpolation in those cases in which no message 569 | will be logged. For more, see http://www.python.org/dev/peps/pep-0282/. 570 | :logging-format-interpolation (W1202): *Use % formatting in logging functions and pass the % parameters as arguments* 571 | Used when a logging statement has a call form of "logging.(format_string.format(format_args...))". Such calls should use % 573 | formatting instead, but leave interpolation to the logging function by passing 574 | the parameters as arguments. 575 | :bad-format-string-key (W1300): *Format string dictionary key should be a string, not %s* 576 | Used when a format string that uses named conversion specifiers is used with a 577 | dictionary whose keys are not all strings. 578 | :unused-format-string-key (W1301): *Unused key %r in format string dictionary* 579 | Used when a format string that uses named conversion specifiers is used with a 580 | dictionary that contains keys not required by the format string. 581 | :bad-format-string (W1302): *Invalid format string* 582 | Used when a PEP 3101 format string is invalid. This message can't be emitted 583 | when using Python < 2.7. 584 | :missing-format-argument-key (W1303): *Missing keyword argument %r for format string* 585 | Used when a PEP 3101 format string that uses named fields doesn't receive one 586 | or more required keywords. This message can't be emitted when using Python < 587 | 2.7. 588 | :unused-format-string-argument (W1304): *Unused format argument %r* 589 | Used when a PEP 3101 format string that uses named fields is used with an 590 | argument that is not required by the format string. This message can't be 591 | emitted when using Python < 2.7. 592 | :format-combined-specification (W1305): *Format string contains both automatic field numbering and manual field specification* 593 | Usen when a PEP 3101 format string contains both automatic field numbering 594 | (e.g. '{}') and manual field specification (e.g. '{0}'). This message can't be 595 | emitted when using Python < 2.7. 596 | :missing-format-attribute (W1306): *Missing format attribute %r in format specifier %r* 597 | Used when a PEP 3101 format string uses an attribute specifier ({0.length}), 598 | but the argument passed for formatting doesn't have that attribute. This 599 | message can't be emitted when using Python < 2.7. 600 | :invalid-format-index (W1307): *Using invalid lookup key %r in format specifier %r* 601 | Used when a PEP 3101 format string uses a lookup specifier ({a[1]}), but the 602 | argument passed for formatting doesn't contain or doesn't have that key as an 603 | attribute. This message can't be emitted when using Python < 2.7. 604 | :anomalous-backslash-in-string (W1401): *Anomalous backslash in string: '%s'. String constant might be missing an r prefix.* 605 | Used when a backslash is in a literal string but not as an escape. 606 | :anomalous-unicode-escape-in-string (W1402): *Anomalous Unicode escape in byte string: '%s'. String constant might be missing an r or u prefix.* 607 | Used when an escape like \u is encountered in a byte string where it has no 608 | effect. 609 | :bad-open-mode (W1501): *"%s" is not a valid mode for open.* 610 | Python supports: r, w, a[, x] modes with b, +, and U (only with r) options. 611 | See http://docs.python.org/2/library/functions.html#open 612 | :boolean-datetime (W1502): *Using datetime.time in a boolean context.* 613 | Using datetime.time in a boolean context can hide subtle bugs when the time 614 | they represent matches midnight UTC. This behaviour was fixed in Python 3.5. 615 | See http://bugs.python.org/issue13936 for reference. This message can't be 616 | emitted when using Python >= 3.5. 617 | :redundant-unittest-assert (W1503): *Redundant use of %s with constant value %r* 618 | The first argument of assertTrue and assertFalse is a condition. If a constant 619 | is passed as parameter, that condition will be always true. In this case a 620 | warning should be emitted. 621 | :deprecated-method (W1505): *Using deprecated method %s()* 622 | The method is marked as deprecated and will be removed in a future version of 623 | Python. Consider looking for an alternative in the documentation. 624 | :apply-builtin (W1601): *apply built-in referenced* 625 | Used when the apply built-in function is referenced (missing from Python 3) 626 | This message can't be emitted when using Python >= 3.0. 627 | :basestring-builtin (W1602): *basestring built-in referenced* 628 | Used when the basestring built-in function is referenced (missing from Python 629 | 3) This message can't be emitted when using Python >= 3.0. 630 | :buffer-builtin (W1603): *buffer built-in referenced* 631 | Used when the buffer built-in function is referenced (missing from Python 3) 632 | This message can't be emitted when using Python >= 3.0. 633 | :cmp-builtin (W1604): *cmp built-in referenced* 634 | Used when the cmp built-in function is referenced (missing from Python 3) This 635 | message can't be emitted when using Python >= 3.0. 636 | :coerce-builtin (W1605): *coerce built-in referenced* 637 | Used when the coerce built-in function is referenced (missing from Python 3) 638 | This message can't be emitted when using Python >= 3.0. 639 | :execfile-builtin (W1606): *execfile built-in referenced* 640 | Used when the execfile built-in function is referenced (missing from Python 3) 641 | This message can't be emitted when using Python >= 3.0. 642 | :file-builtin (W1607): *file built-in referenced* 643 | Used when the file built-in function is referenced (missing from Python 3) 644 | This message can't be emitted when using Python >= 3.0. 645 | :long-builtin (W1608): *long built-in referenced* 646 | Used when the long built-in function is referenced (missing from Python 3) 647 | This message can't be emitted when using Python >= 3.0. 648 | :raw_input-builtin (W1609): *raw_input built-in referenced* 649 | Used when the raw_input built-in function is referenced (missing from Python 650 | 3) This message can't be emitted when using Python >= 3.0. 651 | :reduce-builtin (W1610): *reduce built-in referenced* 652 | Used when the reduce built-in function is referenced (missing from Python 3) 653 | This message can't be emitted when using Python >= 3.0. 654 | :standarderror-builtin (W1611): *StandardError built-in referenced* 655 | Used when the StandardError built-in function is referenced (missing from 656 | Python 3) This message can't be emitted when using Python >= 3.0. 657 | :unicode-builtin (W1612): *unicode built-in referenced* 658 | Used when the unicode built-in function is referenced (missing from Python 3) 659 | This message can't be emitted when using Python >= 3.0. 660 | :xrange-builtin (W1613): *xrange built-in referenced* 661 | Used when the xrange built-in function is referenced (missing from Python 3) 662 | This message can't be emitted when using Python >= 3.0. 663 | :coerce-method (W1614): *__coerce__ method defined* 664 | Used when a __coerce__ method is defined (method is not used by Python 3) This 665 | message can't be emitted when using Python >= 3.0. 666 | :delslice-method (W1615): *__delslice__ method defined* 667 | Used when a __delslice__ method is defined (method is not used by Python 3) 668 | This message can't be emitted when using Python >= 3.0. 669 | :getslice-method (W1616): *__getslice__ method defined* 670 | Used when a __getslice__ method is defined (method is not used by Python 3) 671 | This message can't be emitted when using Python >= 3.0. 672 | :setslice-method (W1617): *__setslice__ method defined* 673 | Used when a __setslice__ method is defined (method is not used by Python 3) 674 | This message can't be emitted when using Python >= 3.0. 675 | :no-absolute-import (W1618): *import missing `from __future__ import absolute_import`* 676 | Used when an import is not accompanied by ``from __future__ import 677 | absolute_import`` (default behaviour in Python 3) This message can't be 678 | emitted when using Python >= 3.0. 679 | :old-division (W1619): *division w/o __future__ statement* 680 | Used for non-floor division w/o a float literal or ``from __future__ import 681 | division`` (Python 3 returns a float for int division unconditionally) This 682 | message can't be emitted when using Python >= 3.0. 683 | :dict-iter-method (W1620): *Calling a dict.iter*() method* 684 | Used for calls to dict.iterkeys(), itervalues() or iteritems() (Python 3 lacks 685 | these methods) This message can't be emitted when using Python >= 3.0. 686 | :dict-view-method (W1621): *Calling a dict.view*() method* 687 | Used for calls to dict.viewkeys(), viewvalues() or viewitems() (Python 3 lacks 688 | these methods) This message can't be emitted when using Python >= 3.0. 689 | :next-method-called (W1622): *Called a next() method on an object* 690 | Used when an object's next() method is called (Python 3 uses the next() built- 691 | in function) This message can't be emitted when using Python >= 3.0. 692 | :metaclass-assignment (W1623): *Assigning to a class's __metaclass__ attribute* 693 | Used when a metaclass is specified by assigning to __metaclass__ (Python 3 694 | specifies the metaclass as a class statement argument) This message can't be 695 | emitted when using Python >= 3.0. 696 | :indexing-exception (W1624): *Indexing exceptions will not work on Python 3* 697 | Indexing exceptions will not work on Python 3. Use `exception.args[index]` 698 | instead. This message can't be emitted when using Python >= 3.0. 699 | :raising-string (W1625): *Raising a string exception* 700 | Used when a string exception is raised. This will not work on Python 3. This 701 | message can't be emitted when using Python >= 3.0. 702 | :reload-builtin (W1626): *reload built-in referenced* 703 | Used when the reload built-in function is referenced (missing from Python 3). 704 | You can use instead imp.reload or importlib.reload. This message can't be 705 | emitted when using Python >= 3.0. 706 | :oct-method (W1627): *__oct__ method defined* 707 | Used when a __oct__ method is defined (method is not used by Python 3) This 708 | message can't be emitted when using Python >= 3.0. 709 | :hex-method (W1628): *__hex__ method defined* 710 | Used when a __hex__ method is defined (method is not used by Python 3) This 711 | message can't be emitted when using Python >= 3.0. 712 | :nonzero-method (W1629): *__nonzero__ method defined* 713 | Used when a __nonzero__ method is defined (method is not used by Python 3) 714 | This message can't be emitted when using Python >= 3.0. 715 | :cmp-method (W1630): *__cmp__ method defined* 716 | Used when a __cmp__ method is defined (method is not used by Python 3) This 717 | message can't be emitted when using Python >= 3.0. 718 | :input-builtin (W1632): *input built-in referenced* 719 | Used when the input built-in is referenced (backwards-incompatible semantics 720 | in Python 3) This message can't be emitted when using Python >= 3.0. 721 | :round-builtin (W1633): *round built-in referenced* 722 | Used when the round built-in is referenced (backwards-incompatible semantics 723 | in Python 3) This message can't be emitted when using Python >= 3.0. 724 | :intern-builtin (W1634): *intern built-in referenced* 725 | Used when the intern built-in is referenced (Moved to sys.intern in Python 3) 726 | This message can't be emitted when using Python >= 3.0. 727 | :unichr-builtin (W1635): *unichr built-in referenced* 728 | Used when the unichr built-in is referenced (Use chr in Python 3) This message 729 | can't be emitted when using Python >= 3.0. 730 | :map-builtin-not-iterating (W1636): *map built-in referenced when not iterating* 731 | Used when the map built-in is referenced in a non-iterating context (returns 732 | an iterator in Python 3) This message can't be emitted when using Python >= 733 | 3.0. 734 | :zip-builtin-not-iterating (W1637): *zip built-in referenced when not iterating* 735 | Used when the zip built-in is referenced in a non-iterating context (returns 736 | an iterator in Python 3) This message can't be emitted when using Python >= 737 | 3.0. 738 | :range-builtin-not-iterating (W1638): *range built-in referenced when not iterating* 739 | Used when the range built-in is referenced in a non-iterating context (returns 740 | an iterator in Python 3) This message can't be emitted when using Python >= 741 | 3.0. 742 | :filter-builtin-not-iterating (W1639): *filter built-in referenced when not iterating* 743 | Used when the filter built-in is referenced in a non-iterating context 744 | (returns an iterator in Python 3) This message can't be emitted when using 745 | Python >= 3.0. 746 | :using-cmp-argument (W1640): *Using the cmp argument for list.sort / sorted* 747 | Using the cmp argument for list.sort or the sorted builtin should be avoided, 748 | since it was removed in Python 3. Using either `key` or `functools.cmp_to_key` 749 | should be preferred. This message can't be emitted when using Python >= 3.0. 750 | 751 | -------------------------------------------------------------------------------- /pylint.rc: -------------------------------------------------------------------------------- 1 | # lint Python modules using external checkers. 2 | # 3 | # This is the main checker controlling the other ones and the reports 4 | # generation. It is itself both a raw checker and an astng checker in order 5 | # to: 6 | # * handle message activation / deactivation at the module level 7 | # * handle some basic but necessary stats'data (number of classes, methods...) 8 | # 9 | [MASTER] 10 | 11 | # Specify a configuration file. 12 | #rcfile= 13 | 14 | # Python code to execute, usually for sys.path manipulation such as 15 | # pygtk.require(). 16 | #init-hook= 17 | 18 | # Profiled execution. 19 | profile=no 20 | 21 | # Add to the black list. It should be a base name, not a 22 | # path. You may set this option multiple times. 23 | # Ignore all auto-generated South migration directories. 24 | ignore=migrations,south_migrations 25 | 26 | # Pickle collected data for later comparisons. 27 | persistent=yes 28 | 29 | # Set the cache size for astng objects. 30 | cache-size=500 31 | 32 | # List of plugins (as comma separated values of python modules names) to load, 33 | # usually to register additional checkers. 34 | load-plugins= 35 | 36 | [MESSAGES CONTROL] 37 | 38 | # Enable only checker(s) with the given id(s). This option conflicts with the 39 | # disable-checker option 40 | #enable-checker= 41 | 42 | # Enable all checker(s) except those with the given id(s). This option 43 | # conflicts with the enable-checker option 44 | #disable-checker= 45 | 46 | # Enable all messages in the listed categories (IRCWEF). 47 | #enable-msg-cat= 48 | 49 | # Disable all messages in the listed categories (IRCWEF). 50 | disable-msg-cat=I 51 | 52 | # Enable the message(s) with the given id(s). 53 | #enable-msg= 54 | 55 | #http://docs.pylint.org/features.html 56 | #http://pylint-messages.wikidot.com/all-codes 57 | #pylint --list-msgs > pylint.messages 58 | 59 | # All these are disabled below. 60 | # C1001: old-style class defined (Django uses these for Meta options) 61 | # C0103: variable regex check. 62 | # C0111: missing docstring check. It's too vague. Complains about no docstrings in __init__ and other places we don't care about. 63 | # C0330: bad-continuation 64 | # E1101: member check...this is usually wrong. 65 | # E1103: type inference...this is usually wrong. 66 | # F0401: unable to import 67 | # R0201: method should be function check. 68 | # R0401: cyclic import check...because sometimes it's wrong. 69 | # R0902: too many instance attributes check. 70 | # R0903: too few public methods check...makes no sense with Django. 71 | # R0904: too many public method check. 72 | # R0913: too many argument check. 73 | # R0921: abstract class not referenced check. 74 | # W0104: no effect check. 75 | # W0142: magic check. 76 | # W0212: protected data check. 77 | # W0232: __init__ check. 78 | # W0311: bad-indentation 79 | # W0401: wildcard import. 80 | # W0404: reimport check...this is sometimes wrong. 81 | # W0511: TODO check. 82 | # W0612: unused variable check. 83 | # W0613: unused argument check. Too vague. 84 | # W0614: wildcard import usage check. 85 | # W0704: empty except check. 86 | # E1002: Use of super on an old style class 87 | # E1120: No value for argument 88 | # R0901: Too many ancestors 89 | # W0611: Unused import 90 | # E1123: Unexpected keyword argument %r in %s call 91 | # C0302: *Too many lines in module (%s)* 92 | # R0801: *Similar lines in %s files* 93 | # R0914: *Too many local variables (%s/%s)* 94 | # R0912: *Too many branches (%s/%s)* 95 | # R0915: *Too many statements (%s/%s)* 96 | # W0703: *Catching too general exception %s* 97 | # E1003: *Bad first argument %r given to super()* 98 | # E0202: *An attribute defined in %s line %s hides this method* 99 | # W0201: *Attribute %r defined outside __init__* 100 | # W0221: *Arguments number differs from %s method* 101 | # C0325: *Unnecessary parens after %r keyword* 102 | # R0916: too-many-boolean-expressions 103 | # R0204: *Redefinition of %s type from %s to %s* 104 | # R0101: *Too many nested blocks (%s/%s)* 105 | # I0011: *Locally disabling %s (%s)* 106 | disable=C1001,C0103,R0201,W0212,W0614,W0401,W0704,E1101,W0142,R0904,R0913,W0404,R0903,W0232,C0111,W0613,W0612,W0511,W0104,R0902,R0921,R0401,E1103,W0311,C0330,F0401,E1002,E1120,R0901,W0611,E1123,C0302,R0801,R0914,R0912,R0915,W0703,E1003,E0202,W0201,W0221,C0325,R0916,R0204,R0101,I0011 107 | 108 | [REPORTS] 109 | 110 | # Set the output format. Available formats are text, parseable, colorized, msvs 111 | # (visual studio) and html 112 | output-format=text 113 | 114 | # Include message's id in output 115 | include-ids=yes 116 | 117 | # Put messages in a separate file for each module / package specified on the 118 | # command line instead of printing them on stdout. Reports (if any) will be 119 | # written in a file name "pylint_global.[txt|html]". 120 | files-output=no 121 | 122 | # Tells whether to display a full report or only the messages 123 | #reports=yes 124 | reports=no 125 | 126 | # Python expression which should return a note less than 10 (10 is the highest 127 | # note). You have access to the variables errors warning, statement which 128 | # respectively contain the number of errors / warnings messages and the total 129 | # number of statements analyzed. This is used by the global evaluation report 130 | # (R0004). 131 | evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) 132 | 133 | # Add a comment according to your evaluation note. This is used by the global 134 | # evaluation report (R0004). 135 | comment=no 136 | 137 | # Enable the report(s) with the given id(s). 138 | #enable-report= 139 | 140 | # Disable the report(s) with the given id(s). 141 | #disable-report= 142 | 143 | 144 | # checks for : 145 | # * doc strings 146 | # * modules / classes / functions / methods / arguments / variables name 147 | # * number of arguments, local variables, branches, returns and statements in 148 | # functions, methods 149 | # * required module attributes 150 | # * dangerous default values as arguments 151 | # * redefinition of function / method / class 152 | # * uses of the global statement 153 | # 154 | [BASIC] 155 | 156 | # Regular expression which should only match functions or classes name which do 157 | # not require a docstring 158 | no-docstring-rgx=__.*__ 159 | 160 | # Regular expression which should only match correct module names 161 | module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ 162 | 163 | # Regular expression which should only match correct module level names 164 | const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ 165 | 166 | # Regular expression which should only match correct class names 167 | class-rgx=[A-Z_][a-zA-Z0-9]+$ 168 | 169 | # Regular expression which should only match correct function names 170 | function-rgx=[a-z_][a-z0-9_]{2,30}$ 171 | 172 | # Regular expression which should only match correct method names 173 | method-rgx=[a-z_][a-z0-9_]{2,30}$ 174 | 175 | # Regular expression which should only match correct instance attribute names 176 | attr-rgx=[a-z_][a-z0-9_]{2,30}$ 177 | 178 | # Regular expression which should only match correct argument names 179 | argument-rgx=[a-z_][a-z0-9_]{2,30}$ 180 | 181 | # Regular expression which should only match correct variable names 182 | variable-rgx=[a-z_][a-z0-9_]{2,30}$ 183 | 184 | # Regular expression which should only match correct list comprehension / 185 | # generator expression variable names 186 | inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ 187 | 188 | # Good variable names which should always be accepted, separated by a comma 189 | good-names=i,j,k,ex,Run,_ 190 | 191 | # Bad variable names which should always be refused, separated by a comma 192 | bad-names=foo,bar,baz,toto,tutu,tata 193 | 194 | # List of builtins function names that should not be used, separated by a comma 195 | bad-functions=map,filter,apply,input 196 | 197 | 198 | # try to find bugs in the code using type inference 199 | # 200 | [TYPECHECK] 201 | 202 | # Tells whether missing members accessed in mixin class should be ignored. A 203 | # mixin class is detected if its name ends with "mixin" (case insensitive). 204 | ignore-mixin-members=yes 205 | 206 | # List of classes names for which member attributes should not be checked 207 | # (useful for classes with attributes dynamically set). 208 | ignored-classes=SQLObject 209 | 210 | # When zope mode is activated, add a predefined set of Zope acquired attributes 211 | # to generated-members. 212 | zope=no 213 | 214 | # List of members which are set dynamically and missed by pylint inference 215 | # system, and so shouldn't trigger E0201 when accessed. 216 | generated-members=REQUEST,acl_users,aq_parent 217 | 218 | 219 | # checks for 220 | # * unused variables / imports 221 | # * undefined variables 222 | # * redefinition of variable from builtins or from an outer scope 223 | # * use of variable before assignment 224 | # 225 | [VARIABLES] 226 | 227 | # Tells whether we should check for unused import in __init__ files. 228 | init-import=no 229 | 230 | # A regular expression matching names used for dummy variables (i.e. not used). 231 | dummy-variables-rgx=_|dummy 232 | 233 | # List of additional names supposed to be defined in builtins. Remember that 234 | # you should avoid to define new builtins when possible. 235 | additional-builtins= 236 | 237 | 238 | # checks for 239 | # * external modules dependencies 240 | # * relative / wildcard imports 241 | # * cyclic imports 242 | # * uses of deprecated modules 243 | # 244 | [IMPORTS] 245 | 246 | # Deprecated modules which should not be used, separated by a comma 247 | deprecated-modules=regsub,string,TERMIOS,Bastion,rexec 248 | 249 | # Create a graph of every (i.e. internal and external) dependencies in the 250 | # given file (report R0402 must not be disabled) 251 | import-graph= 252 | 253 | # Create a graph of external dependencies in the given file (report R0402 must 254 | # not be disabled) 255 | ext-import-graph= 256 | 257 | # Create a graph of internal dependencies in the given file (report R0402 must 258 | # not be disabled) 259 | int-import-graph= 260 | 261 | 262 | # checks for sign of poor/misdesign: 263 | # * number of methods, attributes, local variables... 264 | # * size, complexity of functions, methods 265 | # 266 | [DESIGN] 267 | 268 | # Maximum number of arguments for function / method 269 | max-args=5 270 | 271 | # Maximum number of locals for function / method body 272 | max-locals=15 273 | 274 | # Maximum number of return / yield for function / method body 275 | max-returns=6 276 | 277 | # Maximum number of branch for function / method body 278 | max-branchs=12 279 | 280 | # Maximum number of statements in function / method body 281 | max-statements=50 282 | 283 | # Maximum number of parents for a class (see R0901). 284 | max-parents=7 285 | 286 | # Maximum number of attributes for a class (see R0902). 287 | max-attributes=7 288 | 289 | # Minimum number of public methods for a class (see R0903). 290 | min-public-methods=2 291 | 292 | # Maximum number of public methods for a class (see R0904). 293 | max-public-methods=20 294 | 295 | 296 | # checks for : 297 | # * methods without self as first argument 298 | # * overridden methods signature 299 | # * access only to existent members via self 300 | # * attributes not defined in the __init__ method 301 | # * supported interfaces implementation 302 | # * unreachable code 303 | # 304 | [CLASSES] 305 | 306 | # List of interface methods to ignore, separated by a comma. This is used for 307 | # instance to not check methods defines in Zope's Interface base class. 308 | #ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by 309 | 310 | # List of method names used to declare (i.e. assign) instance attributes. 311 | defining-attr-methods=__init__,__new__,setUp 312 | 313 | 314 | # checks for similarities and duplicated code. This computation may be 315 | # memory / CPU intensive, so you should disable it if you experiments some 316 | # problems. 317 | # 318 | [SIMILARITIES] 319 | 320 | # Minimum lines number of a similarity. 321 | min-similarity-lines=4 322 | 323 | # Ignore comments when computing similarities. 324 | ignore-comments=yes 325 | 326 | # Ignore docstrings when computing similarities. 327 | ignore-docstrings=yes 328 | 329 | 330 | # checks for : 331 | # * unauthorized constructions 332 | # * strict indentation 333 | # * line length 334 | # * use of <> instead of != 335 | # 336 | [FORMAT] 337 | 338 | # Maximum number of characters on a single line. 339 | max-line-length=100 340 | 341 | # Maximum number of lines in a module 342 | max-module-lines=1000 343 | 344 | # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 345 | # tab). 346 | indent-string=' ' 347 | 348 | 349 | # checks for: 350 | # * warning notes in the code like FIXME, XXX 351 | # * PEP 263: source code with non ascii character but no encoding declaration 352 | # 353 | [MISCELLANEOUS] 354 | 355 | # List of note tags to take in consideration, separated by a comma. 356 | notes=FIXME,XXX,TODO 357 | -------------------------------------------------------------------------------- /requirements-min-django.txt: -------------------------------------------------------------------------------- 1 | Django>=1.5 2 | -------------------------------------------------------------------------------- /requirements-test.txt: -------------------------------------------------------------------------------- 1 | tox>=2.0.0 2 | pylint>=1.6.5 3 | twine>=1.15.0 4 | 5 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | import os 4 | from os import path 5 | from setuptools import setup, find_packages, Command 6 | 7 | import database_size 8 | 9 | CURRENT_DIR = os.path.abspath(os.path.dirname(__file__)) 10 | 11 | this_directory = path.abspath(path.dirname(__file__)) 12 | try: 13 | with open(path.join(this_directory, 'README.md'), encoding='utf-8') as f: 14 | long_description = f.read() 15 | except TypeError: 16 | with open(path.join(this_directory, 'README.md')) as f: 17 | long_description = f.read() 18 | 19 | def get_reqs(*fns): 20 | lst = [] 21 | for fn in fns: 22 | for package in open(os.path.join(CURRENT_DIR, fn)).readlines(): 23 | package = package.strip() 24 | if not package: 25 | continue 26 | lst.append(package.strip()) 27 | return lst 28 | 29 | setup( 30 | name='django-database-size', 31 | version=database_size.__version__, 32 | description='Monitor the size of database tables from Django admin.', 33 | long_description=long_description, 34 | long_description_content_type='text/markdown', 35 | author='Chris Spencer', 36 | author_email='chrisspen@gmail.com', 37 | url='http://github.com/chrisspen/django-database-size', 38 | packages=find_packages(), 39 | package_data={ 40 | 'database_size': [ 41 | 'sql/*.*', 42 | ], 43 | }, 44 | #https://pypi.python.org/pypi?%3Aaction=list_classifiers 45 | classifiers=[ 46 | 'Development Status :: 5 - Production/Stable', 47 | 'Framework :: Django', 48 | 'Intended Audience :: Developers', 49 | 'License :: OSI Approved :: BSD License', 50 | 'Operating System :: OS Independent', 51 | 'Programming Language :: Python', 52 | 'Programming Language :: Python :: 2.7', 53 | 'Programming Language :: Python :: 3.4', 54 | 'Programming Language :: Python :: 3.5', 55 | 'Programming Language :: Python :: 3.6', 56 | 'Programming Language :: PL/SQL', 57 | ], 58 | install_requires=get_reqs('requirements-min-django.txt', 'requirements.txt'), 59 | tests_require=get_reqs('requirements-test.txt'), 60 | ) 61 | -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Runs all tests. 3 | set -e 4 | VENV=.env 5 | [ -d $VENV ] && . $VENV/bin/activate 6 | ./pep8.sh 7 | export TESTNAME=; tox 8 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = py{311}-django{51} 3 | recreate = True 4 | 5 | [testenv] 6 | basepython = 7 | py311: python3.11 8 | deps = 9 | -r{toxinidir}/requirements.txt 10 | -r{toxinidir}/requirements-test.txt 11 | django51: Django>=5.1,<6 12 | commands = django-admin.py test --traceback --settings=database_size.tests.settings database_size.tests.tests.Tests{env:TESTNAME:} 13 | --------------------------------------------------------------------------------