Skip to content

Commit

Permalink
Drop support for python 3.7 and fix typing issues
Browse files Browse the repository at this point in the history
  • Loading branch information
bellini666 committed Jan 28, 2022
1 parent b3646f0 commit 970f498
Show file tree
Hide file tree
Showing 18 changed files with 364 additions and 387 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/cicd.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
---
name: Run Tests

on:
push:
branches: [master]
Expand All @@ -24,7 +26,7 @@ jobs:
strategy:
matrix:
django-version: ["2.2.0", "3.0.0", "3.1.0", "3.2.0"]
python-version: ["3.7", "3.8", "3.9", "3.10"]
python-version: ["3.8", "3.9", "3.10"]

steps:
- name: Checkout
Expand Down
43 changes: 34 additions & 9 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.4.0
rev: v4.1.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
Expand All @@ -14,26 +14,51 @@ repos:
- id: check-added-large-files
args: ["--maxkb=1024"]

- repo: https://github.com/codespell-project/codespell
rev: v2.1.0
hooks:
- id: codespell

- repo: https://github.com/pre-commit/mirrors-prettier
rev: v2.4.1
rev: v2.5.1
hooks:
- id: prettier

- repo: https://github.com/asottile/pyupgrade
rev: v2.21.0
rev: v2.31.0
hooks:
- id: pyupgrade
args: ["--py38-plus"]

- repo: https://github.com/myint/docformatter
rev: v1.4
hooks:
- id: docformatter
args: ["-i", "--wrap-summaries", "0", "--blank"]

- repo: https://github.com/myint/autoflake
rev: v1.4
hooks:
- id: autoflake
args: ["--in-place", "--remove-all-unused-imports"]

- repo: https://github.com/pycqa/isort
rev: 5.8.0
rev: 5.10.1
hooks:
- id: isort
types_or: [cython, pyi, python]
name: isort (python)
- id: isort
name: isort (cython)
types: [cython]
- id: isort
name: isort (pyi)
types: [pyi]

- repo: https://github.com/psf/black
rev: 21.11b0
rev: 21.12b0
hooks:
- id: black
args: ["--config", "pyproject.toml"]

- repo: https://gitlab.com/pycqa/flake8
rev: 3.9.2
Expand All @@ -42,10 +67,10 @@ repos:
additional_dependencies:
[
"flake8-broken-line==0.4.0",
"flake8-bugbear==21.9.2",
"flake8-bugbear==22.1.11",
"flake8-builtins==1.5.3",
"flake8-comprehensions==3.7.0",
"flake8-comprehensions==3.8.0",
"flake8-polyfill==1.0.2",
"flake8-return==1.1.3",
"flake8-simplify==0.14.2",
"flake8-simplify==0.15.1",
]
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ api documentation.

- `graphene_django_plus.models.GuardedModel`: A django model that can be used
either directly or as a mixin. It will provide a `.has_perm` method and a
`.objects.for_user` that will be used by `ModelType` described bellow to
check for object permissions. some utilities to check.
`.objects.for_user` that will be used by `ModelType` described below to
check for object permissions.

### Types and Queries

Expand Down Expand Up @@ -104,13 +104,13 @@ class MyModelType(ModelType):
]

# If unauthenticated users should be allowed to retrieve any object
# of this type. This is not dependant on `GuardedModel` and neither
# of this type. This is not dependent on `GuardedModel` and neither
# `guardian` and is defined as `False` by default
public = False

# A list of Django model permissions to check. Different from
# object_permissions, this uses the basic Django's permission system
# and thus is not dependant on `GuardedModel` and neither `guardian`.
# and thus is not dependent on `GuardedModel` and neither `guardian`.
# This is an empty list by default.
permissions = []

Expand Down Expand Up @@ -205,20 +205,20 @@ class MyModelUpdateMutation(ModelUpdateMutation):
# Make sure only users with the given permissions can modify the
# object.
# If the model doesn't inherid from `GuardedModel`, `guardian` is not
# installed ot this list is empty, any object will be allowed.
# installed on this list is empty, any object will be allowed.
# This is empty by default.
object_permissions = [
'can_write',
]

# If unauthenticated users should be allowed to retrieve any object
# of this type. This is not dependant on `GuardedModel` and neither
# of this type. This is not dependent on `GuardedModel` and neither
# `guardian` and is defined as `False` by default
public = False

# A list of Django model permissions to check. Different from
# object_permissions, this uses the basic Django's permission system
# and thus is not dependant on `GuardedModel` and neither `guardian`.
# and thus is not dependent on `GuardedModel` and neither `guardian`.
# This is an empty list by default.
permissions = []

Expand Down
13 changes: 5 additions & 8 deletions graphene_django_plus/input_types.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
"""
Module that defines the mapping between model fields and GraphQL input types
used in mutations.
"""
import functools
from typing import Union

Expand All @@ -21,14 +17,15 @@
def get_input_field(
field: Union[Field, ForeignObjectRel], registry: Registry
) -> Union[Scalar, Structure]:
"""
Convert a model field into a GraphQL input type used in mutations.
"""Convert a model field into a GraphQL input type used in mutations.
:param field: A model field.
:param registry: Registry which holds a mapping between django models/fields
and Graphene types.
:return: A scalar that can be used as an input field in mutations.
"""
return convert_django_field_with_choices(field, registry)
return convert_django_field_with_choices(field, registry) # type:ignore


@get_input_field.register(models.FileField)
Expand Down Expand Up @@ -66,5 +63,5 @@ def get_many_to_many_field(field, registry):
def get_relation_field(field, registry):
return graphene.List(
graphene.ID,
description="Set list of {}".format(field.related_model._meta.verbose_name_plural),
description=f"Set list of {field.related_model._meta.verbose_name_plural}",
)
9 changes: 6 additions & 3 deletions graphene_django_plus/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
except ImportError:
from collections import Iterable

from typing import TYPE_CHECKING, List, Tuple, Type, TypeVar, Union
from typing import TYPE_CHECKING, List, Tuple, Type, TypeVar, Union, cast

try:
from guardian.conf import settings as guardian_settings
Expand Down Expand Up @@ -61,6 +61,7 @@ def for_user(
:param perms: a string or list of perms to check for
:param any_perm: if any perm or all perms should be considered
:param with_superuser: if a superuser should skip the checks
"""
# No guardian means we are not checking perms
if not has_guardian:
Expand Down Expand Up @@ -123,6 +124,7 @@ def for_user(
app_label, model_name = m.split(".")
m = apps.get_model(app_label=app_label, model_name=model_name)

m = cast(Type[GuardedModel], m)
other_qs = self.all().filter(
**{
f"{self.model.related_attr}__in": m.objects.for_user(
Expand Down Expand Up @@ -180,6 +182,7 @@ def has_perm(
:param any_perm: if any perm or all perms should be considered
:param checker: a `guardian.core.ObjectPermissionChecker` that
can be used to optimize performance in checking for permissions
"""
# No guardian means we are not checking perms
if not has_guardian:
Expand All @@ -195,11 +198,11 @@ def has_perm(
f = any if any_perm else all

# First try to check if the user has global permissions for this
# Otherwise we will check for the object itself bellow
# Otherwise we will check for the object itself below
if f(user.has_perm(p) for p in perms):
return True

# Small performance improvement by mimicing guardian's api
# Small performance improvement by mimicking guardian's api
perms = [p.split(".", 1)[1] if "." in p else p for p in perms]
c_perms = checker.get_perms(self)
return f(p in c_perms for p in perms)
Expand Down
Loading

0 comments on commit 970f498

Please sign in to comment.