Skip to content

Commit

Permalink
Improve import startup time
Browse files Browse the repository at this point in the history
  • Loading branch information
Viicos committed Feb 15, 2024
1 parent a42c406 commit 0eca1cc
Showing 1 changed file with 35 additions and 7 deletions.
42 changes: 35 additions & 7 deletions weasyprint/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@

import contextlib
from datetime import datetime
import importlib
from os.path import getctime, getmtime
from pathlib import Path
from typing import TYPE_CHECKING
from urllib.parse import urljoin

import cssselect2
Expand Down Expand Up @@ -89,7 +91,7 @@
fetch, default_url_fetcher, path2url, ensure_url, url_is_absolute)
from .logger import LOGGER, PROGRESS_LOGGER # noqa isort:skip
# Some imports are at the end of the file (after the CSS class)
# to work around circular imports.
# as they can significantly increase increase startup import time


def _find_base_url(html_document, fallback_base_url):
Expand Down Expand Up @@ -300,6 +302,10 @@ def __init__(self, guess=None, filename=None, url=None, file_obj=None,
self.base_url = base_url
self.matcher = matcher or cssselect2.Matcher()
self.page_rules = [] if page_rules is None else page_rules

# Work around circular import:
from .css import preprocess_stylesheet

preprocess_stylesheet(
media_type, base_url, stylesheet, url_fetcher, self.matcher,
self.page_rules, font_config, counter_style)
Expand Down Expand Up @@ -415,9 +421,31 @@ def _select_source(guess=None, filename=None, url=None, file_obj=None,
assert string is not None
yield 'string', string, base_url, None

# Work around circular imports.
from .css import preprocess_stylesheet # noqa isort:skip
from .html import ( # noqa isort:skip
HTML5_UA_COUNTER_STYLE, HTML5_UA_STYLESHEET, HTML5_UA_FORM_STYLESHEET,
HTML5_PH_STYLESHEET)
from .document import Document, Page # noqa isort:skip

if TYPE_CHECKING:
# To help type checkers and tools discover dynamic imports
from .document import Document, Page
from .html import (
HTML5_UA_COUNTER_STYLE,
HTML5_UA_STYLESHEET,
HTML5_UA_FORM_STYLESHEET,
HTML5_PH_STYLESHEET,
)


_heavy_imports = {
"HTML5_UA_COUNTER_STYLE": "html",
"HTML5_UA_STYLESHEET": "html",
"HTML5_UA_FORM_STYLESHEET": "html",
"HTML5_PH_STYLESHEET": "html",
"Document": "document",
"Page": "document",
}

def __getattr__(attr_name: str) -> object:
module = _heavy_imports.get(attr_name)
if module is None:
return importlib.import_module(f".{attr_name}", __package__)

module_obj = importlib.import_module(f".{module}", __package__)
return getattr(module_obj, attr_name)

0 comments on commit 0eca1cc

Please sign in to comment.