Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add mypy pre-commit hook #141

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ Use 'x' to check each item: [x] I have ...
* [ ] I have opened this pull request against ``master``
* [ ] I have added or modified the tests when changing logic
* [ ] I have followed [the conventional commits guidelines](https://www.conventionalcommits.org/) to add meaningful information into the changelog
* [ ] I have read the [contribution guidelines ](https://github.com/django-cms/django-cms/blob/develop/CONTRIBUTING.rst) and I have joined #workgroup-pr-review on
* [ ] I have read the [contribution guidelines ](https://github.com/django-cms/django-cms/blob/develop/CONTRIBUTING.rst) and I have joined #workgroup-pr-review on
[Slack](https://www.django-cms.org/slack) to find a “pr review buddy” who is going to review my pull request.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ npm-debug.log
package-lock.json

local.sqlite
.coverage*
8 changes: 4 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ repos:
- id: end-of-file-fixer
- id: trailing-whitespace

# - repo: https://github.com/pre-commit/mirrors-mypy
# rev: v1.3.0
# hooks:
# - id: mypy
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.3.0
hooks:
- id: mypy
8 changes: 4 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,11 @@ You can run tests by executing::

.. |pypi| image:: https://badge.fury.io/py/djangocms-snippet.svg
:target: http://badge.fury.io/py/djangocms-snippet
.. |coverage| image:: https://codecov.io/gh/django-cms/djangocms-snippet/branch/master/graph/badge.svg
.. |coverage| image:: https://codecov.io/gh/django-cms/djangocms-snippet/graph/badge.svg?token=Ztf8ph4OTk
:target: https://codecov.io/gh/django-cms/djangocms-snippet
.. |python| image:: https://img.shields.io/badge/python-3.5+-blue.svg
.. |python| image:: https://img.shields.io/badge/python-3.9+-blue.svg
:target: https://pypi.org/project/djangocms-snippet/
.. |django| image:: https://img.shields.io/badge/django-2.2,%203.0,%203.1-blue.svg
.. |django| image:: https://img.shields.io/badge/django-3.2,%204.2-blue.svg
:target: https://www.djangoproject.com/
.. |djangocms| image:: https://img.shields.io/badge/django%20CMS-3.7%2B-blue.svg
.. |djangocms| image:: https://img.shields.io/badge/django%20CMS-3.10%2B-blue.svg
:target: https://www.django-cms.org/
20 changes: 12 additions & 8 deletions aldryn_config.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import Any

from aldryn_client import forms


Expand All @@ -11,16 +13,18 @@ class Form(forms.BaseForm):
required=False,
)
enable_search = forms.CheckboxField(
'Enable snippet content to be searchable.',
"Enable snippet content to be searchable.",
required=False,
initial=False,
)

def to_settings(self, data, settings):
if data['editor_theme']:
settings['DJANGOCMS_SNIPPET_THEME'] = data['editor_theme']
if data['editor_mode']:
settings['DJANGOCMS_SNIPPET_MODE'] = data['editor_mode']
if data['enable_search']:
settings['DJANGOCMS_SNIPPET_SEARCH'] = data['enable_search']
def to_settings(
self, data: dict[str, Any], settings: dict[str, Any]
) -> dict[str, Any]:
if data["editor_theme"]:
settings["DJANGOCMS_SNIPPET_THEME"] = data["editor_theme"]
if data["editor_mode"]:
settings["DJANGOCMS_SNIPPET_MODE"] = data["editor_mode"]
if data["enable_search"]:
settings["DJANGOCMS_SNIPPET_SEARCH"] = data["enable_search"]
return settings
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ ignore = [
"__init__.py" = [
"F401" # unused-import
]
"snippet_tags.py" = [
"FBT001" # Boolean positional arg in function definition
]

[tool.ruff.isort]
combine-as-imports = true
Expand Down
2 changes: 1 addition & 1 deletion src/djangocms_snippet/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class Media:

list_display = ("slug", "name")
search_fields: ClassVar[list[str]] = ["slug", "name"]
prepopulated_fields: ClassVar[dict[str, list[str]]] = {"slug": ("name",)}
prepopulated_fields: ClassVar[dict[str, tuple[str]]] = {"slug": ("name",)}
change_form_template = "djangocms_snippet/admin/change_form.html"
text_area_attrs: ClassVar[dict[str, Any]] = {
"rows": 20,
Expand Down
11 changes: 10 additions & 1 deletion src/djangocms_snippet/cms_plugins.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
from typing import Any

from cms.models import Placeholder
from cms.plugin_base import CMSPluginBase
from cms.plugin_pool import plugin_pool
from django import template
from django.conf import settings
from django.template.context import BaseContext
from django.utils.html import escape
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _
Expand All @@ -19,7 +23,12 @@ class SnippetPlugin(CMSPluginBase):
text_editor_preview = False
cache = CACHE_ENABLED

def render(self, context, instance, placeholder):
def render(
self,
context: BaseContext,
instance: SnippetPtr,
placeholder: Placeholder,
) -> dict[str, Any]:
try:
if instance.snippet.template:
context = context.flatten()
Expand Down
11 changes: 7 additions & 4 deletions src/djangocms_snippet/migrations/0003_auto_data_fill_slug.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
from collections import Counter
import typing

from django.db import migrations, models
from django.db import migrations
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
from django.db.migrations.state import StateApps
from django.utils.text import slugify


def auto_fill_slugs(apps, schema_editor):
def auto_fill_slugs(apps: StateApps, schema_editor: BaseDatabaseSchemaEditor) -> None:
"""
Go through every snippet to fill them a slug if not any
"""
Snippet = apps.get_model("djangocms_snippet", "Snippet")
SlugCounter = Counter()
SlugCounter: typing.Counter[str] = Counter()
for snippet_item in Snippet.objects.all(): # pragma: no cover
if not snippet_item.slug:
snippet_item.slug = slugify(snippet_item.name)
# Avoid duplicate slug, adding slug occurence count to the slug
# Avoid duplicate slug, adding slug occurrence count to the slug
if snippet_item.slug in SlugCounter:
snippet_item.slug = f"{snippet_item.slug}-{str(SlugCounter[snippet_item.slug])}"
SlugCounter[snippet_item.slug] += 1
Expand Down
4 changes: 2 additions & 2 deletions src/djangocms_snippet/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class Meta:
verbose_name = _("Snippet")
verbose_name_plural = _("Snippets")

def __str__(self):
def __str__(self) -> str:
return self.name


Expand Down Expand Up @@ -77,6 +77,6 @@ class Meta:
verbose_name = _("Snippet Ptr")
verbose_name_plural = _("Snippet Ptrs")

def __str__(self):
def __str__(self) -> str:
# Return the referenced snippet's name rather than the default (ID #)
return self.snippet.name
32 changes: 20 additions & 12 deletions src/djangocms_snippet/templatetags/snippet_tags.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
"""
Snippet template tags
"""
from collections.abc import Generator
from contextlib import contextmanager
from typing import Any

from django import template
from django.template.base import Parser, Token
from django.template.context import BaseContext
from django.utils.html import escape
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _
Expand All @@ -16,17 +20,19 @@


@contextmanager
def exceptionless(truth):
# Accepts one truth parameter, when 'False' normal behavior
# when 'True' any expection will be suppressed
def exceptionless(truth: bool) -> Generator[None, None, None]:
"""
Accepts one truth parameter, when 'False' normal behavior
when 'True' any exception will be suppressed
"""
try:
yield
except Exception:
if truth:
# WARNING: suppressing exception
pass
else:
# Reraising exception
# Re-raising exception
raise


Expand All @@ -35,7 +41,7 @@ class SnippetFragment(template.Node):
Get a snippet HTML fragment
"""

def __init__(self, snippet_id_varname, *args):
def __init__(self, snippet_id_varname: str, *args: Any):
"""
:type insert_instance_varname: string or object
``django.db.models.Model``
Expand All @@ -53,7 +59,7 @@ def __init__(self, snippet_id_varname, *args):
self.parse_until = True
self.nodelist = args[1]

def render(self, context):
def render(self, context: BaseContext) -> str:
"""
:type context: dict
:param context: Context tag object
Expand All @@ -63,6 +69,8 @@ def render(self, context):
"""
# Default assume this is directly an instance
snippet_instance = self.snippet_id_varname.resolve(context)

response = self.nodelist.render(context)
# Assume this is slug
with exceptionless(self.parse_until):
if isinstance(snippet_instance, str):
Expand All @@ -71,15 +79,15 @@ def render(self, context):
elif isinstance(snippet_instance, int): # pragma: no cover
snippet_instance = Snippet.objects.get(pk=snippet_instance)

return mark_safe(
response = mark_safe(
self.get_content_render(context, snippet_instance)
)

# Rely on the fact that manager something went wrong
# render the fallback template
return self.nodelist.render(context)
return response

def get_content_render(self, context, instance):
def get_content_render(
self, context: BaseContext, instance: Snippet
) -> str:
"""
Render the snippet HTML, using a template if defined in its instance
"""
Expand Down Expand Up @@ -113,7 +121,7 @@ def get_content_render(self, context, instance):


@register.tag(name="snippet_fragment")
def do_snippet_fragment(parser, token):
def do_snippet_fragment(parser: Parser, token: Token) -> SnippetFragment:
"""
Display a snippet HTML fragment

Expand Down
25 changes: 14 additions & 11 deletions tests/settings.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
#!/usr/bin/env python
HELPER_SETTINGS = {
'INSTALLED_APPS': [
'tests.utils',
"INSTALLED_APPS": [
"tests.utils",
],
'CMS_LANGUAGES': {
1: [{
'code': 'en',
'name': 'English',
}]
"CMS_LANGUAGES": {
1: [
{
"code": "en",
"name": "English",
}
]
},
'LANGUAGE_CODE': 'en',
'ALLOWED_HOSTS': ['localhost'],
"LANGUAGE_CODE": "en",
"ALLOWED_HOSTS": ["localhost"],
}


def run():
from app_helper import runner
runner.cms('djangocms_snippet')

runner.cms("djangocms_snippet")

if __name__ == '__main__':

if __name__ == "__main__":
run()
17 changes: 8 additions & 9 deletions tests/test_migrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,23 @@


class MigrationTestCase(TestCase):

@override_settings(MIGRATION_MODULES={})
def test_for_missing_migrations(self):
output = StringIO()
options = {
'interactive': False,
'dry_run': True,
'stdout': output,
'check_changes': True,
"interactive": False,
"dry_run": True,
"stdout": output,
"check_changes": True,
}

try:
call_command('makemigrations', **options)
call_command("makemigrations", **options)
except SystemExit as e:
status_code = str(e)
else:
# the "no changes" exit code is 0
status_code = '0'
status_code = "0"

if status_code == '1':
self.fail('There are missing migrations:\n {}'.format(output.getvalue()))
if status_code == "1":
self.fail(f"There are missing migrations:\n {output.getvalue()}")
1 change: 0 additions & 1 deletion tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@


class SnippetModelTestCase(TestCase):

def setUp(self):
pass

Expand Down
Loading
Loading