Skip to content

Commit

Permalink
Merge 9681825 into eab99f3
Browse files Browse the repository at this point in the history
  • Loading branch information
shosca committed Apr 7, 2021
2 parents eab99f3 + 9681825 commit bc9bf78
Show file tree
Hide file tree
Showing 38 changed files with 97 additions and 169 deletions.
12 changes: 0 additions & 12 deletions django_sorcery/compat.py

This file was deleted.

8 changes: 2 additions & 6 deletions django_sorcery/db/fields.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Django-esque declarative fields for sqlalchemy."""
from contextlib import suppress

import sqlalchemy as sa
from django import forms as djangoforms
Expand All @@ -7,7 +8,6 @@
from django.forms import fields as djangofields
from django.utils.module_loading import import_string

from ..utils import suppress
from .url import DIALECT_MAP_TO_DJANGO


Expand Down Expand Up @@ -103,11 +103,7 @@ def get_column_kwargs(self, kwargs):
"unique",
"_proxies",
]
column_kwargs = {}
for k in column_args:
if k in kwargs:
column_kwargs[k] = kwargs.pop(k)

column_kwargs = {k: kwargs.pop(k) for k in column_args if k in kwargs}
column_kwargs["primary_key"] = kwargs.pop("primary_key", False)
column_kwargs["nullable"] = kwargs.pop("nullable", not column_kwargs["primary_key"])
return column_kwargs
Expand Down
11 changes: 5 additions & 6 deletions django_sorcery/db/meta/column.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import datetime
import decimal
import enum
from contextlib import suppress

import sqlalchemy as sa
from dateutil.parser import parse
Expand All @@ -15,7 +16,7 @@
from django.utils.text import capfirst

from ... import fields as sorceryfields
from ...utils import sanitize_separators, suppress
from ...utils import sanitize_separators


def _make_naive(value):
Expand Down Expand Up @@ -81,8 +82,7 @@ def __new__(cls, *args, **kwargs):
break

_cls = override_cls or cls
instance = super().__new__(_cls)
return instance
return super().__new__(_cls)

def __init__(self, column, prop=None, parent=None, name=None):
self.property = prop
Expand Down Expand Up @@ -116,9 +116,8 @@ def __init__(self, column, prop=None, parent=None, name=None):
self.label = self.column.info.get("label") or (capfirst(" ".join(self.name.split("_"))) if self.name else None)

self.field_kwargs = {"required": self.required, "validators": self.validators, "help_text": self.help_text}
if self.default:
if not callable(self.default):
self.field_kwargs["initial"] = self.default
if self.default and not callable(self.default):
self.field_kwargs["initial"] = self.default

if self.label:
self.field_kwargs["label"] = self.label
Expand Down
9 changes: 2 additions & 7 deletions django_sorcery/db/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,7 @@ def _deserialize(model, data, identity_map):

info = meta.model_info(model)

kwargs = {}
for prop in info.primary_keys:
if prop in data:
kwargs[prop] = data.get(prop)

kwargs = {prop: data.get(prop) for prop in info.primary_keys if prop in data}
pk = info.identity_key_from_dict(kwargs)
if pk is not None and pk in identity_map:
return identity_map[pk]
Expand Down Expand Up @@ -228,8 +224,7 @@ def clone(instance, *rels, **kwargs):
sub_rels = [(r, kw) for r, kw in relations.items() if r is not attr]
kwargs[relation.key] = clone(sub_instance, *sub_rels, **relations[attr])

cloned = mapper.class_(**kwargs)
return cloned
return mapper.class_(**kwargs)


class BaseMeta(sqlalchemy.ext.declarative.DeclarativeMeta):
Expand Down
13 changes: 5 additions & 8 deletions django_sorcery/db/relations.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
"""sqlalchemy relationship related things."""
from contextlib import suppress
from itertools import chain

import sqlalchemy as sa
from sqlalchemy.ext.declarative import declared_attr

from ..utils import setdefaultattr, suppress
from ..utils import setdefaultattr
from .signals import declare_first


Expand Down Expand Up @@ -161,11 +162,7 @@ def m2m(cls):
return m2m

def _get_kwargs_for_relation(self, kwargs, prefix="fk_"):
opts = {}
for key in list(kwargs.keys()):
if key.startswith(prefix):
opts[key] = kwargs.pop(key)
return opts
return {key: kwargs.pop(key) for key in list(kwargs.keys()) if key.startswith(prefix)}


def _add_foreign_keys(cls, parent_cls, relation):
Expand Down Expand Up @@ -206,9 +203,9 @@ def _add_foreign_keys(cls, parent_cls, relation):
if cols_created:
# pk and fk ordering must match for foreign key constraint
pks, fks = [], []
for pk in cols:
for pk, value in cols.items():
pks.append(pk)
fks.append(cols[pk])
fks.append(value)

constraint = sa.ForeignKeyConstraint(fks, pks, **fk_kwargs)
cls.__table__.append_constraint(constraint)
Expand Down
20 changes: 8 additions & 12 deletions django_sorcery/db/sqlalchemy.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,20 +164,16 @@ def session(self, **kwargs):
If there's already a session in current scope, will raise
InvalidRequestError
"""
if kwargs:
if self.registry.has():
raise sa.exc.InvalidRequestError(
"Scoped session is already present; " "no new arguments may be specified."
)

else:
session = self.session_factory(**kwargs)
self.registry.set(session)
return session

else:
if not kwargs:
return self.registry()

if self.registry.has():
raise sa.exc.InvalidRequestError("Scoped session is already present; " "no new arguments may be specified.")

session = self.session_factory(**kwargs)
self.registry.set(session)
return session

def Table(self, name, *args, **kwargs):
"""Returns a sqlalchemy table that is automatically added to
metadata."""
Expand Down
3 changes: 1 addition & 2 deletions django_sorcery/db/url.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import os
from contextlib import suppress
from importlib import import_module

import sqlalchemy as sa
from django.conf import settings
from django.utils.encoding import force_text
from django.utils.module_loading import import_string

from ..utils import suppress


DIALECT_MAP = {
"django.db.backends.sqlite3": "sqlite",
Expand Down
3 changes: 2 additions & 1 deletion django_sorcery/db/utils.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from contextlib import suppress

import sqlalchemy as sa
from django.db import DEFAULT_DB_ALIAS
from django.utils.module_loading import import_string

from ..utils import suppress
from .sqlalchemy import SQLAlchemy
from .transaction import TransactionContext
from .url import get_settings, make_url
Expand Down
12 changes: 6 additions & 6 deletions django_sorcery/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ def __init__(self, message, code=None, params=None):
super().__init__(message, code, params)

def update_error_dict(self, error_dict):
if hasattr(self, "error_dict"):
for field, errors in self.error_dict.items():
holder = error_dict.setdefault(field, errors.__class__())
(getattr(holder, "update", None) or holder.extend)(errors)
return error_dict
else:
if not hasattr(self, "error_dict"):
return super().update_error_dict(error_dict)

for field, errors in self.error_dict.items():
holder = error_dict.setdefault(field, errors.__class__())
(getattr(holder, "update", None) or holder.extend)(errors)
return error_dict

def __iter__(self):
if hasattr(self, "code"):
yield from super().__iter__()
Expand Down
3 changes: 1 addition & 2 deletions django_sorcery/fields.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
"""Field mapping from SQLAlchemy type's to form fields."""
import json
from contextlib import suppress

from django.core.exceptions import ValidationError
from django.forms import fields as djangofields
from django.utils.translation import gettext_lazy

from .utils import suppress


class EnumField(djangofields.ChoiceField):
"""Form field for using an Enum as choices."""
Expand Down
2 changes: 1 addition & 1 deletion django_sorcery/forms.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Helper functions for creating Form classes from SQLAlchemy models."""
from collections import OrderedDict
from contextlib import suppress
from itertools import chain

from django.core.exceptions import (
Expand All @@ -19,7 +20,6 @@
from django.forms.utils import ErrorList

from .db import meta
from .utils import suppress


def _get_default_kwargs(
Expand Down
3 changes: 1 addition & 2 deletions django_sorcery/formsets/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,7 @@ def _construct_form(self, i, **kwargs):
except IndexError:
pass
kwargs["session"] = self.session
form = super()._construct_form(i, **kwargs)
return form
return super()._construct_form(i, **kwargs)

def add_fields(self, form, index):
info = meta.model_info(self.model)
Expand Down
23 changes: 11 additions & 12 deletions django_sorcery/routers.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ def action(methods=None, detail=None, url_path=None, url_name=None, **kwargs):
def decorator(func):
func.bind_to_methods = methods
func.detail = detail
func.url_path = url_path if url_path else func.__name__
func.url_name = url_name if url_name else func.__name__.replace("_", "-")
func.url_path = url_path or func.__name__
func.url_name = url_name or func.__name__.replace("_", "-")
func.kwargs = kwargs
return func

Expand Down Expand Up @@ -183,7 +183,7 @@ def get_routes(self, viewset):
for route in self.routes:
if isinstance(route, DynamicRoute) and route.detail:
routes += [self._get_dynamic_route(route, action) for action in detail_actions]
elif isinstance(route, DynamicRoute) and not route.detail:
elif isinstance(route, DynamicRoute):
routes += [self._get_dynamic_route(route, action) for action in list_actions]
else:
routes.append(route)
Expand All @@ -208,11 +208,7 @@ def get_method_map(self, viewset, method_map):
"""Given a viewset, and a mapping of http methods to actions, return a
new mapping which only includes any mappings that are actually
implemented by the viewset."""
bound_methods = {}
for method, action in method_map.items():
if hasattr(viewset, action):
bound_methods[method] = action
return bound_methods
return {method: action for method, action in method_map.items() if hasattr(viewset, action)}

def get_lookup_regex(self, viewset, lookup_prefix=""):
"""Given a viewset, return the portion of URL regex that is used to
Expand All @@ -234,11 +230,14 @@ def get_lookup_regex(self, viewset, lookup_prefix=""):
if model:
info = meta.model_info(model)

regexes = []
for key, _ in info.primary_keys.items():
regexes.append(
base_regex.format(lookup_prefix=lookup_prefix, lookup_url_kwarg=key, lookup_value="[^/.]+")
regexes = [
base_regex.format(
lookup_prefix=lookup_prefix,
lookup_url_kwarg=key,
lookup_value="[^/.]+",
)
for key, _ in info.primary_keys.items()
]

return "/".join(regexes)

Expand Down
3 changes: 1 addition & 2 deletions django_sorcery/shortcuts.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
"""Some Django like shortcuts that support sqlalchemy models."""
from contextlib import suppress

from django.core.exceptions import ImproperlyConfigured
from django.http import Http404
from sqlalchemy.exc import InvalidRequestError

from .utils import suppress


def _get_query(klass):

Expand Down
7 changes: 0 additions & 7 deletions django_sorcery/utils.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
"""Some common utilities."""
import contextlib
import inspect
import unicodedata

from django.conf import settings


try:
suppress = contextlib.suppress
except AttributeError: # pragma: nocover
from .compat import suppress # noqa pragma: nocover


def sanitize_separators(value):
"""Sanitize a value according to the current decimal and thousand separator
setting.
Expand Down
2 changes: 1 addition & 1 deletion django_sorcery/views/base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Base model view things with sqlalchemy."""
from contextlib import suppress

from django.apps import apps
from django.core.exceptions import ImproperlyConfigured
Expand All @@ -10,7 +11,6 @@
from sqlalchemy.exc import InvalidRequestError

from ..db import meta
from ..utils import suppress


class SQLAlchemyMixin(ContextMixin):
Expand Down
20 changes: 5 additions & 15 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#!/usr/bin/env python
# fmt:off
import os
import shutil
import sys

from setuptools import find_packages, setup

Expand All @@ -19,19 +17,6 @@ def read(fname):
return open(os.path.join(os.path.dirname(__file__), fname), "rb").read().decode("utf-8")


if sys.argv[-1] == "publish":
twine = shutil.which("twine")
if twine is None:
print("twine not installed.\nUse `pip install twine`.\nExiting.")
sys.exit()
os.system("python setup.py sdist bdist_wheel")
os.system("twine upload dist/*")
print("You probably want to also tag the version now:")
print(" git tag -a {} -m {}".format(about["__version__"], about["__version__"]))
print(" git push --tags")
os.system("make clean")
sys.exit()

setup(
author=about["__author__"],
author_email=about["__author_email__"],
Expand All @@ -53,6 +38,9 @@ def read(fname):
"Framework :: Django :: 2.0",
"Framework :: Django :: 2.1",
"Framework :: Django :: 2.2",
"Framework :: Django :: 3.0",
"Framework :: Django :: 3.1",
"Framework :: Django :: 3.2",
"Framework :: Django",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
Expand All @@ -62,6 +50,8 @@ def read(fname):
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python",
"Topic :: Internet :: WWW/HTTP :: Dynamic Content",
"Topic :: Internet :: WWW/HTTP :: WSGI",
Expand Down
Loading

0 comments on commit bc9bf78

Please sign in to comment.