Merge pull request 'Propositions liées à la qualité du code (pep8, pylint, ...)' (#58) from propal/pep8-pylint into master

Reviewed-on: #58
This commit is contained in:
Fred 2021-06-19 08:29:35 +02:00
commit 3376abd5b2
11 changed files with 87 additions and 35 deletions

View File

@ -3,17 +3,22 @@
# A comma-separated list of package or module names from where C extensions may # A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may # be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code. # run arbitrary code.
extension-pkg-allow-list=
# A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code. (This is an alternative name to extension-pkg-allow-list
# for backward compatibility.)
extension-pkg-whitelist= extension-pkg-whitelist=
# Specify a score threshold to be exceeded before program exits with error. # Specify a score threshold to be exceeded before program exits with error.
fail-under=10.0 fail-under=10.0
# Add files or directories to the blacklist. They should be base names, not # Files or directories to be skipped. They should be base names, not paths.
# paths.
ignore=CVS ignore=CVS
# Add files or directories matching the regex patterns to the blacklist. The # Files or directories matching the regex patterns are skipped. The regex
# regex matches against base names, not paths. # matches against base names, not paths.
ignore-patterns= ignore-patterns=
# Python code to execute, usually for sys.path manipulation such as # Python code to execute, usually for sys.path manipulation such as
@ -181,7 +186,7 @@ max-nested-blocks=5
# inconsistent-return-statements if a never returning function is called then # inconsistent-return-statements if a never returning function is called then
# it will be considered as an explicit return statement and no message will be # it will be considered as an explicit return statement and no message will be
# printed. # printed.
never-returning-functions=sys.exit never-returning-functions=sys.exit,argparse.parse_error
[STRING] [STRING]
@ -227,6 +232,8 @@ single-line-if-stmt=no
[VARIABLES] [VARIABLES]
django-settings-module=khana.settings
# List of additional names supposed to be defined in builtins. Remember that # List of additional names supposed to be defined in builtins. Remember that
# you should avoid defining new builtins when possible. # you should avoid defining new builtins when possible.
additional-builtins= additional-builtins=
@ -234,6 +241,9 @@ additional-builtins=
# Tells whether unused global variables should be treated as a violation. # Tells whether unused global variables should be treated as a violation.
allow-global-unused-variables=yes allow-global-unused-variables=yes
# List of names allowed to shadow builtins
allowed-redefined-builtins=
# List of strings which can identify a callback function by name. A callback # List of strings which can identify a callback function by name. A callback
# name must start or end with one of those strings. # name must start or end with one of those strings.
callbacks=cb_, callbacks=cb_,
@ -367,6 +377,13 @@ class-attribute-naming-style=any
# attribute-naming-style. # attribute-naming-style.
#class-attribute-rgx= #class-attribute-rgx=
# Naming style matching correct class constant names.
class-const-naming-style=UPPER_CASE
# Regular expression matching correct class constant names. Overrides class-
# const-naming-style.
#class-const-rgx=
# Naming style matching correct class names. # Naming style matching correct class names.
class-naming-style=PascalCase class-naming-style=PascalCase
@ -455,9 +472,13 @@ variable-naming-style=snake_case
max-spelling-suggestions=4 max-spelling-suggestions=4
# Spelling dictionary name. Available dictionaries: none. To make it work, # Spelling dictionary name. Available dictionaries: none. To make it work,
# install the python-enchant package. # install the 'python-enchant' package.
spelling-dict= spelling-dict=
# List of comma separated words that should be considered directives if they
# appear and the beginning of a comment and should not be checked.
spelling-ignore-comment-directives=fmt: on,fmt: off,noqa:,noqa,nosec,isort:skip,mypy:
# List of comma separated words that should not be checked. # List of comma separated words that should not be checked.
spelling-ignore-words= spelling-ignore-words=
@ -519,6 +540,9 @@ min-public-methods=2
[CLASSES] [CLASSES]
# Warn about protected attribute access inside special methods
check-protected-access-in-special-methods=no
# List of method names used to declare (i.e. assign) instance attributes. # List of method names used to declare (i.e. assign) instance attributes.
defining-attr-methods=__init__, defining-attr-methods=__init__,
__new__, __new__,
@ -557,16 +581,17 @@ analyse-fallback-blocks=no
# Deprecated modules which should not be used, separated by a comma. # Deprecated modules which should not be used, separated by a comma.
deprecated-modules=optparse,tkinter.tix deprecated-modules=optparse,tkinter.tix
# Create a graph of external dependencies in the given file (report RP0402 must # Output a graph (.gv or any supported image format) of external dependencies
# not be disabled). # to the given file (report RP0402 must not be disabled).
ext-import-graph= ext-import-graph=
# Create a graph of every (i.e. internal and external) dependencies in the # Output a graph (.gv or any supported image format) of all (i.e. internal and
# given file (report RP0402 must not be disabled). # external) dependencies to the given file (report RP0402 must not be
# disabled).
import-graph= import-graph=
# Create a graph of internal dependencies in the given file (report RP0402 must # Output a graph (.gv or any supported image format) of internal dependencies
# not be disabled). # to the given file (report RP0402 must not be disabled).
int-import-graph= int-import-graph=
# Force import order to recognize a module as part of the standard # Force import order to recognize a module as part of the standard

View File

@ -3,7 +3,9 @@
black==19.10b0 black==19.10b0
coverage==5.5 coverage==5.5
flake8==3.9.1 flake8==3.9.1
pylint==2.8.2
pylint-django==2.4.4
django-spaghetti-and-meatballs==0.4.2 django-spaghetti-and-meatballs==0.4.2
docutils==0.16 docutils==0.16
pytest==6.2.4 pytest==6.2.4
pytest-django==4.2.0 pytest-django==4.2.0

3
setup.cfg Normal file
View File

@ -0,0 +1,3 @@
[flake8]
max-line-length=100
max-complexity=10

View File

@ -20,5 +20,5 @@ class Markdownizable(models.Model):
def to_markdown(self): def to_markdown(self):
"""Convertit le champ `content` en (Github-flavored) Markdown.""" """Convertit le champ `content` en (Github-flavored) Markdown."""
return markdown.markdown(self.content) return markdown.markdown(self.content)

View File

@ -11,6 +11,6 @@ class TestMarkdownizable(TestCase):
def test_to_markdown(self): def test_to_markdown(self):
"""Vérifie qu'un contenu Markdown est correctement convertit en HTML.""" """Vérifie qu'un contenu Markdown est correctement convertit en HTML."""
m = Markdownizable(information="# Title") markdown_content = Markdownizable(information="# Title")
self.assertEqual(m.to_markdown(), "<h1>Title</h1>") self.assertEqual(markdown_content.to_markdown(), "<h1>Title</h1>")

View File

@ -7,6 +7,8 @@ from .models import Message
@admin.register(Message) @admin.register(Message)
class MessageAdmin(admin.ModelAdmin): class MessageAdmin(admin.ModelAdmin):
"""La classe `MessageAdmin` contrôle la gestion des messages
"""
list_display = ("sender", "recipient", "written_at", "is_read", "read_at") list_display = ("sender", "recipient", "written_at", "is_read", "read_at")
ordering = ("written_at", "sender") ordering = ("written_at", "sender")
search_fields = ("sender", "recipient", "message_title") search_fields = ("sender", "recipient", "message_title")

View File

@ -1,14 +1,13 @@
"""Configuration et représentation des forms liés aux messages.""" """Configuration et représentation des forms liés aux messages."""
from datetime import date
from django import forms from django import forms
from people.models import Gymnast
from .models import Message from .models import Message
class MessageForm(forms.ModelForm): class MessageForm(forms.ModelForm):
"""Formulaire de base pour la création et la modification de messages
"""
class Meta: class Meta:
model = Message model = Message
fields = ( fields = (

View File

@ -1,10 +1,23 @@
"""Modelisation de tout ce qui touche à la communication entre utilisateurs.
Cette application gère:
* Les messages
* Ah, c'est tout en fait :-)
"""
from django.db import models
from django.contrib.auth.models import User
from datetime import datetime from datetime import datetime
from django.db import models
from django.contrib.auth import get_user_model
from base.models import Markdownizable from base.models import Markdownizable
User = get_user_model()
class Message(Markdownizable): class Message(Markdownizable):
"""Représente un message échangé entre deux utilisateurs. """Représente un message échangé entre deux utilisateurs.

View File

@ -1,12 +1,19 @@
# coding=UTF-8 """Tests liés au modèle de l'application Communication"""
from datetime import datetime from datetime import datetime
from .models import Message
from django.contrib.auth.models import User
import pytest
def test_message_tostring(): from django.contrib.auth import get_user_model
from .models import Message
User = get_user_model()
def test_message_to_string():
"""Vérifie la représentation textuelle d'un message
"""
timing = datetime.now() timing = datetime.now()
u = User(username='fred', password='fredpassword') user = User(username='fred', password='fredpassword')
m = Message(sender=u, written_at=timing, title="test") message = Message(sender=user, written_at=timing, title="test")
assert str(m) == "fred - " + str(timing) + " : test" assert str(message) == "fred - " + str(timing) + " : test"

View File

@ -1,6 +1,6 @@
"""Définition des routes d'actions permettant de contrôler les messages et la communication.""" """Définition des routes d'actions permettant de contrôler les messages et la communication."""
from django.urls import path, re_path from django.urls import path
from . import views from . import views

View File

@ -1,17 +1,18 @@
"""Vues et fonctions pour tout ce qui touche à la communication entre plusieurs utilisateurs.""" """Vues et fonctions pour tout ce qui touche à la communication entre plusieurs utilisateurs."""
from datetime import datetime
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.http import HttpResponse, HttpResponseRedirect from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404
from django.views.decorators.http import require_http_methods from django.views.decorators.http import require_http_methods
from django.urls import reverse from django.urls import reverse
from datetime import datetime
from .forms import MessageForm from .forms import MessageForm
from .models import Message from .models import Message
@login_required @login_required
def get_number_of_unread_message(request): def get_number_of_unread_message(request):
"""Récupère le nombre de messages non lus associés à l'utilisateur en session. """Récupère le nombre de messages non lus associés à l'utilisateur en session.
@ -80,7 +81,7 @@ def delete_message(request, messageid):
""" """
try: try:
message = Message.objects.get(pk=messageid) message = Message.objects.get(pk=messageid)
if message.sender == request.user or message.recipient == request.user : if message.sender == request.user or message.recipient == request.user :
message.delete() message.delete()
else: else:
@ -103,8 +104,8 @@ def compose_message(request):
if form.is_valid(): if form.is_valid():
form.save() form.save()
return HttpResponseRedirect(reverse("sent_messages")) return HttpResponseRedirect(reverse("sent_messages"))
else:
print("Invalid form") print("Invalid form")
else: else:
form = MessageForm() form = MessageForm()