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

wtform import performances #727

Closed
azmeuk opened this issue Jan 10, 2022 · 0 comments · Fixed by #729
Closed

wtform import performances #727

azmeuk opened this issue Jan 10, 2022 · 0 comments · Fixed by #729

Comments

@azmeuk
Copy link
Member

azmeuk commented Jan 10, 2022

I have been profiling the unit test part of a flask project lately. My issue is that launching a single unit test takes ~4s on a very capable computer. This is not acceptable to me as I do test driven development, each second is multiplied by dozen and dozen runs each day, and this gives me a frustrating sensation. My investigations lead me to look around import times.

I have been profiling my tests with the unfamous importtime python option with something like: python -X importtime -c "import web; web.create_app()".

By deferring some library calls from the conftest.py files root to the inside of my pytest fixtures, I could save some precious seconds. Now the bottleneck has moved, and it seems some of latency is due to wtforms, and among others this import and the ones behind it:

try:
import email_validator
except ImportError:
email_validator = None

In addition to that, the wtforms descriptor-like behavior implies that the fields are instantiated at import time the if a form class is defined at the module level. In addition to that, validators objects must be instantiated to be passed to fields:

if inspect.isclass(validator):
raise TypeError(
"{} is not a valid validator because it is a class, "
"it should be an instance".format(validator)
)

So if a form class is defined at the module level, all the fields and all the objects validators are instantiated.

In order to slightly improve those performances I suggest to :

  • Move the library imports (email_validator, ipaddress etc.) from the module level to inside the validators
  • Either:
    • allow fields to take class validators (that should be instantiated a bit later) and not just objects and callable validators
    • transform all the class validators in functions validators. This one is my favorite option.

I would love to hear you on that @davidism

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

1 participant