Skip to content

Commit

Permalink
Defer Django and sqlalchemy imports
Browse files Browse the repository at this point in the history
  • Loading branch information
adamchainz committed Apr 9, 2024
1 parent dca3a16 commit 79bde24
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 30 deletions.
18 changes: 1 addition & 17 deletions factory/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import importlib.metadata

from . import alchemy, django, mogo, mongoengine
from .base import (
BaseDictFactory,
BaseListFactory,
Expand Down Expand Up @@ -54,22 +55,5 @@
stub_batch,
)

try:
from . import alchemy
except ImportError:
pass
try:
from . import django
except ImportError:
pass
try:
from . import mogo
except ImportError:
pass
try:
from . import mongoengine
except ImportError:
pass

__author__ = 'Raphaël Barrois <[email protected]>'
__version__ = importlib.metadata.version("factory_boy")
6 changes: 3 additions & 3 deletions factory/alchemy.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
# Copyright: See the LICENSE file.

from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm.exc import NoResultFound

from . import base, errors

SESSION_PERSISTENCE_COMMIT = 'commit'
Expand Down Expand Up @@ -64,6 +61,9 @@ def _generate(cls, strategy, params):

@classmethod
def _get_or_create(cls, model_class, session, args, kwargs):
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm.exc import NoResultFound

key_fields = {}
for field in cls._meta.sqlalchemy_get_or_create:
if field not in kwargs:
Expand Down
22 changes: 12 additions & 10 deletions factory/django.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@
import warnings
from typing import Dict, TypeVar

from django.contrib.auth.hashers import make_password
from django.core import files as django_files
from django.db import IntegrityError

from . import base, declarations, errors

logger = logging.getLogger('factory.generate')
Expand Down Expand Up @@ -124,6 +120,7 @@ def _generate(cls, strategy, params):
@classmethod
def _get_or_create(cls, model_class, *args, **kwargs):
"""Create an instance of the model through objects.get_or_create."""
from django.db import IntegrityError
manager = cls._get_manager(model_class)

assert 'defaults' not in cls._meta.django_get_or_create, (
Expand Down Expand Up @@ -193,7 +190,10 @@ def _after_postgeneration(cls, instance, create, results=None):


class Password(declarations.Transformer):
def __init__(self, password, transform=make_password, **kwargs):
def __init__(self, password, transform=None, **kwargs):
if transform is None:
from django.contrib.auth.hashers import make_password
transform = make_password
super().__init__(password, transform=transform, **kwargs)


Expand All @@ -207,6 +207,7 @@ def _make_data(self, params):
return params.get('data', b'')

def _make_content(self, params):
from django.core.files.base import ContentFile, File
path = ''

from_path = params.get('from_path')
Expand All @@ -222,21 +223,21 @@ def _make_content(self, params):
if from_path:
path = from_path
with open(path, 'rb') as f:
content = django_files.base.ContentFile(f.read())
content = ContentFile(f.read())

elif from_file:
f = from_file
content = django_files.File(f)
content = File(f)
path = content.name

elif from_func:
func = from_func
content = django_files.File(func())
content = File(func())
path = content.name

else:
data = self._make_data(params)
content = django_files.base.ContentFile(data)
content = ContentFile(data)

if path:
default_filename = os.path.basename(path)
Expand All @@ -248,8 +249,9 @@ def _make_content(self, params):

def evaluate(self, instance, step, extra):
"""Fill in the field."""
from django.core.files.base import File
filename, content = self._make_content(extra)
return django_files.File(content.file, filename)
return File(content.file, filename)


class ImageField(FileField):
Expand Down

0 comments on commit 79bde24

Please sign in to comment.