factory_boy icon indicating copy to clipboard operation
factory_boy copied to clipboard

Defer sqlalchemy import

Open adamchainz opened this issue 1 year ago • 1 comments

The problem

factory_boy/__init__.py uses this pattern for its optional sub-packages:

try:
    from . import alchemy
except ImportError:
    pass

I have a Django project that uses factory_boy a lot, and imports it even in view code. It also happens that the project has sqlalchemy installed for another tool, but it doesn’t use it directly.

On a importtime-waterfall profile, I noticed that importing factory_boy.alchemy takes ~300ms, nearly all in sqlalchemy and its submodules.

It would be great if importing factory_boy didn’t automatically import sqlalchemy.

Proposed solution

Defer the few sqlalchemy imports in factory.alchemy to the functions that use them. Drop the except ImportError pattern in factory_boy since it should then work regardless of whether sqlalchemy is installed.

Extra notes

None.

adamchainz avatar Mar 29 '24 11:03 adamchainz

I do agree that import factory should not have imported factory.django or factory.alchemy dynamically. Unfortunately, I'm afraid this ship has sailed :/

Changing this is bound to break lots of existing code — a quick, non refined Github code search yields about 11k files: https://github.com/search?q=%2F%5Eimport+factory%24%2F+%2F%5C%28factory%5C.django%2F+language%3APython&type=code

Any change on that topic would have to be non-breaking to the thousands of users of the existing, documented import style. I do not wish to provoke large amount of code churn for users of the library unless that brings some improvements to them.

Before working on pull requests, I'd like to have a high-level agreement on an approach that wouldn't break the code for lots of people.

rbarrois avatar Apr 09 '24 17:04 rbarrois