Skip to content

Commit d291240

Browse files
committed
Configure linting tools
1 parent 8c09248 commit d291240

15 files changed

+112
-65
lines changed

.flake8

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[flake8]
2+
ignore = D203, W503
3+
exclude =
4+
.git,
5+
__pycache__,
6+
*/migrations/*,
7+
max-complexity = 10
8+
ban-relative-imports = true
9+
per-file-ignores =
10+
*/__init__.py: F401,E501

Makefile

+8-7
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ usage:
2929
@echo "build....................Builds the django docker image"
3030
@echo "chown....................Change ownership of files to own user"
3131
@echo "clear_pyc................Remove all pyc files"
32+
@echo "down.....................Stop the Django server"
3233
@echo "help.....................Display available commands"
3334
@echo "isort....................Sort Python imports"
3435
@echo "isort_check..............Checks Python import are sorted correctly without making changes"
@@ -44,9 +45,6 @@ usage:
4445
@echo "up.......................Start the Django server"
4546
@echo "usage....................Display available commands"
4647

47-
build:
48-
COMPOSE_DOCKER_CLI_BUILD=1 DOCKER_BUILDKIT=1 docker-compose build django
49-
5048
black:
5149
@docker-compose run --rm django black src ${ARGS}
5250
ifneq ($(OS),Darwin)
@@ -56,6 +54,9 @@ endif
5654
black_check:
5755
$(MAKE) black ARGS="--check"
5856

57+
build:
58+
COMPOSE_DOCKER_CLI_BUILD=1 DOCKER_BUILDKIT=1 docker-compose build django
59+
5960
chown:
6061
@docker-compose run --rm django chown -R "`id -u`:`id -u`" "/usr/src/app/${ARGS}"
6162

@@ -98,11 +99,11 @@ PG_DB_NAME=postgres
9899
PG_DB_USER=postgres
99100
PG_DB_PASSWORD=postgres
100101

101-
db:
102-
@docker-compose run --rm -e PGPASSWORD=$(PG_DB_PASSWORD) db psql -h $(PG_DB_HOST) -p $(PG_DB_PORT) -U $(PG_DB_USER) -d $(PG_DB_NAME) $(ARGS)
103-
104102
prep:
105-
@docker-compose run --no-deps --rm django /bin/sh -c "isort src && black src && mypy --cache-dir=/dev/null src && flake8 src"
103+
@docker-compose run --no-deps --rm django /bin/sh -c "isort src && black src && flake8 src && mypy --cache-dir=/dev/null src"
104+
105+
psql:
106+
@docker-compose run --rm -e PGPASSWORD=$(PG_DB_PASSWORD) db psql -h $(PG_DB_HOST) -p $(PG_DB_PORT) -U $(PG_DB_USER) -d $(PG_DB_NAME) $(ARGS)
106107

107108
shell:
108109
$(MAKE) manage ARGS="shell ${ARGS}"

README.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Additional arguments may be provided to some commands by providing the `ARGS=""`
2929
### How do I run the project locally?
3030
* Run `make build` to build the container(s) needed.
3131
* Run `make up` to start the Django application and any dependent services defined in the compose file.
32-
* Run `make manage ARGS="migrate"` to prepare the database (this runs Django's `python manage.py ${ARGS}` command inside the container).
32+
* Run `make manage ARGS="migrate"` to prepare the database (this runs Django's `python manage.py ${ARGS}` command inside the container). This can be run in another shell window if you didn't run `make up` with the `ARGS="--detach"` flag.
3333
* You'll need a user to log into the admin console. To create an admin user for the project run `make manage ARGS="createsuperuser"`.
3434
* You should now be able to access the Django admin console from `http://localhost:8000/admin`, and a "Hello, world" page at `http://localhost:8000/task`
3535

@@ -40,6 +40,6 @@ Additional arguments may be provided to some commands by providing the `ARGS=""`
4040
- `make prep` - run code formatting and linting tools: `black`, `isort`, `mypy`, `lint`. These can also be run individually with the corresponding make command.
4141

4242
### Examples
43-
- Instead of `make test ARGS="path/to/test.py"`
44-
- Instead of running `make test ARGS="-k test_specific_test_case"`
45-
- Instead of `make manage ARGS="createsuperuser`
43+
- Rebuild and re-run the application in detached mode: `make up ARGS="--build --detach"`
44+
- Running a specific test file: `make test ARGS="path/to/test.py"`
45+
- Running tests matching a keyword: `make test ARGS="-k test_specific_test_case"`

mypy.ini

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[mypy]
2+
plugins = mypy_django_plugin.main
3+
ignore_missing_imports = True
4+
5+
[mypy-*.migrations.*]
6+
ignore_errors = True
7+
8+
[mypy.plugins.django-stubs]
9+
django_settings_module = "src.octotest.settings"

pyproject.toml

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[tool.black]
2+
line-length = 79
3+
skip-numeric-underscore-normalization = 1
4+
5+
[tool.isort]
6+
multi_line_output = 3
7+
include_trailing_comma = "True"
8+
force_grid_wrap = 0
9+
use_parentheses = "True"
10+
line_length = 79
11+
skip_glob="**/migrations/**"

requirements.txt

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
asgiref==3.8.1
22
black==22.3.0
33
Django==5.1.3
4-
psycopg2-binary>=2.8
5-
sqlparse==0.5.2
6-
typing_extensions==4.12.2
4+
django-stubs==1.8.0
5+
django-stubs-ext==0.3.1
76
flake8==7.0.0
87
isort==5.6.4
98
mypy==1.10.0
109
mypy-extensions==1.0.0
10+
psycopg2-binary>=2.8
1111
pytest>=7.2.1
12-
pytest-django>=4.5.2
12+
pytest-django>=4.5.2
13+
sqlparse==0.5.2
14+
typing_extensions==4.12.2

src/octotest/asgi.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@
1111

1212
from django.core.asgi import get_asgi_application
1313

14-
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'src.octotest.settings')
14+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "src.octotest.settings")
1515

1616
application = get_asgi_application()

src/octotest/settings.py

+55-41
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import os
1414
from pathlib import Path
15+
from typing import Iterable
1516

1617
# Build paths inside the project like this: BASE_DIR / 'subdir'.
1718
BASE_DIR = Path(__file__).resolve().parent.parent
@@ -21,67 +22,69 @@
2122
# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/
2223

2324
# SECURITY WARNING: keep the secret key used in production secret!
24-
SECRET_KEY = 'django-insecure-8c#%3-*$+ifulrb*$786w@xb$!vg2*db98%g2d+(kh!h-1su(('
25+
SECRET_KEY = (
26+
"django-insecure-8c#%3-*$+ifulrb*$786w@xb$!vg2*db98%g2d+(kh!h-1su(("
27+
)
2528

2629
# SECURITY WARNING: don't run with debug turned on in production!
2730
DEBUG = True
2831

29-
ALLOWED_HOSTS = []
32+
ALLOWED_HOSTS: Iterable[str] = []
3033

3134

3235
# Application definition
3336

3437
INSTALLED_APPS = [
35-
'django.contrib.admin',
36-
'django.contrib.auth',
37-
'django.contrib.contenttypes',
38-
'django.contrib.sessions',
39-
'django.contrib.messages',
40-
'django.contrib.staticfiles',
38+
"django.contrib.admin",
39+
"django.contrib.auth",
40+
"django.contrib.contenttypes",
41+
"django.contrib.sessions",
42+
"django.contrib.messages",
43+
"django.contrib.staticfiles",
4144
]
4245

4346
MIDDLEWARE = [
44-
'django.middleware.security.SecurityMiddleware',
45-
'django.contrib.sessions.middleware.SessionMiddleware',
46-
'django.middleware.common.CommonMiddleware',
47-
'django.middleware.csrf.CsrfViewMiddleware',
48-
'django.contrib.auth.middleware.AuthenticationMiddleware',
49-
'django.contrib.messages.middleware.MessageMiddleware',
50-
'django.middleware.clickjacking.XFrameOptionsMiddleware',
47+
"django.middleware.security.SecurityMiddleware",
48+
"django.contrib.sessions.middleware.SessionMiddleware",
49+
"django.middleware.common.CommonMiddleware",
50+
"django.middleware.csrf.CsrfViewMiddleware",
51+
"django.contrib.auth.middleware.AuthenticationMiddleware",
52+
"django.contrib.messages.middleware.MessageMiddleware",
53+
"django.middleware.clickjacking.XFrameOptionsMiddleware",
5154
]
5255

53-
ROOT_URLCONF = 'src.octotest.urls'
56+
ROOT_URLCONF = "src.octotest.urls"
5457

5558
TEMPLATES = [
5659
{
57-
'BACKEND': 'django.template.backends.django.DjangoTemplates',
58-
'DIRS': [],
59-
'APP_DIRS': True,
60-
'OPTIONS': {
61-
'context_processors': [
62-
'django.template.context_processors.debug',
63-
'django.template.context_processors.request',
64-
'django.contrib.auth.context_processors.auth',
65-
'django.contrib.messages.context_processors.messages',
60+
"BACKEND": "django.template.backends.django.DjangoTemplates",
61+
"DIRS": [],
62+
"APP_DIRS": True,
63+
"OPTIONS": {
64+
"context_processors": [
65+
"django.template.context_processors.debug",
66+
"django.template.context_processors.request",
67+
"django.contrib.auth.context_processors.auth",
68+
"django.contrib.messages.context_processors.messages",
6669
],
6770
},
6871
},
6972
]
7073

71-
WSGI_APPLICATION = 'src.octotest.wsgi.application'
74+
WSGI_APPLICATION = "src.octotest.wsgi.application"
7275

7376

7477
# Database
7578
# https://docs.djangoproject.com/en/5.1/ref/settings/#databases
7679

7780
DATABASES = {
78-
'default': {
79-
'ENGINE': 'django.db.backends.postgresql',
80-
'NAME': os.environ.get('POSTGRES_NAME'),
81-
'USER': os.environ.get('POSTGRES_USER'),
82-
'PASSWORD': os.environ.get('POSTGRES_PASSWORD'),
83-
'HOST': 'db',
84-
'PORT': 5432,
81+
"default": {
82+
"ENGINE": "django.db.backends.postgresql",
83+
"NAME": os.environ.get("POSTGRES_NAME"),
84+
"USER": os.environ.get("POSTGRES_USER"),
85+
"PASSWORD": os.environ.get("POSTGRES_PASSWORD"),
86+
"HOST": "db",
87+
"PORT": 5432,
8588
}
8689
}
8790

@@ -91,26 +94,37 @@
9194

9295
AUTH_PASSWORD_VALIDATORS = [
9396
{
94-
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
97+
"NAME": (
98+
"django.contrib.auth.password_validation."
99+
"UserAttributeSimilarityValidator"
100+
),
95101
},
96102
{
97-
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
103+
"NAME": (
104+
"django.contrib.auth.password_validation." "MinimumLengthValidator"
105+
),
98106
},
99107
{
100-
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
108+
"NAME": (
109+
"django.contrib.auth.password_validation."
110+
"CommonPasswordValidator"
111+
),
101112
},
102113
{
103-
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
114+
"NAME": (
115+
"django.contrib.auth.password_validation."
116+
"NumericPasswordValidator"
117+
),
104118
},
105119
]
106120

107121

108122
# Internationalization
109123
# https://docs.djangoproject.com/en/5.1/topics/i18n/
110124

111-
LANGUAGE_CODE = 'en-us'
125+
LANGUAGE_CODE = "en-us"
112126

113-
TIME_ZONE = 'UTC'
127+
TIME_ZONE = "UTC"
114128

115129
USE_I18N = True
116130

@@ -120,9 +134,9 @@
120134
# Static files (CSS, JavaScript, Images)
121135
# https://docs.djangoproject.com/en/5.1/howto/static-files/
122136

123-
STATIC_URL = 'static/'
137+
STATIC_URL = "static/"
124138

125139
# Default primary key field type
126140
# https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field
127141

128-
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
142+
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

src/octotest/urls.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,5 @@
1919

2020
urlpatterns = [
2121
path("task/", include("src.task.urls")),
22-
path('admin/', admin.site.urls),
22+
path("admin/", admin.site.urls),
2323
]

src/octotest/wsgi.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@
1111

1212
from django.core.wsgi import get_wsgi_application
1313

14-
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'src.octotest.settings')
14+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "src.octotest.settings")
1515

1616
application = get_wsgi_application()

src/task/admin.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
from django.contrib import admin
1+
# from django.contrib import admin
22

33
# Register your models here.

src/task/apps.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33

44
class TaskConfig(AppConfig):
5-
default_auto_field = 'django.db.models.BigAutoField'
6-
name = 'src.task'
5+
default_auto_field = "django.db.models.BigAutoField"
6+
name = "src.task"

src/task/models.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
from django.db import models
1+
# from django.db import models
22

33
# Create your models here.

src/task/tests.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
from django.test import TestCase
1+
# import pytest
22

33
# Create your tests here.

src/task/urls.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44

55
urlpatterns = [
66
path("", views.index, name="index"),
7-
]
7+
]

0 commit comments

Comments
 (0)