Skip to content

Commit

Permalink
Better living through py3.8 compatible typing
Browse files Browse the repository at this point in the history
  • Loading branch information
karolyi committed Nov 9, 2024
1 parent f58fdc1 commit 9c36189
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 20 deletions.
12 changes: 6 additions & 6 deletions webpack_loader/loaders.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import json
import os
import time
from functools import cached_property, lru_cache
from functools import lru_cache
from io import open
from typing import Dict, Optional
from urllib.parse import urlparse
from warnings import warn

from django.conf import settings
from django.contrib.staticfiles.storage import staticfiles_storage
from django.http import HttpRequest
from django.http.request import HttpRequest

from .exceptions import (
WebpackError,
Expand All @@ -22,19 +22,19 @@
'The crossorigin attribute might be necessary but you did not pass a '
'request object. django_webpack_loader needs a request object to be able '
'to know when to emit the crossorigin attribute on link and script tags. '
'Bundle name: {chunk_name}')
'Chunk name: {chunk_name}')
_CROSSORIGIN_NO_HOST = (
'You have passed the request object but it does not have a "HTTP_HOST", '
'thus django_webpack_loader can\'t know if the crossorigin header will '
'be necessary or not. Bundle name: {chunk_name}')
'be necessary or not. Chunk name: {chunk_name}')
_NONCE_NO_REQUEST = (
'You have enabled the adding of nonce attributes to generated tags via '
'django_webpack_loader, but haven\'t passed a request. '
'Bundle name: {chunk_name}')
'Chunk name: {chunk_name}')
_NONCE_NO_CSPNONCE = (
'django_webpack_loader can\'t generate a nonce tag for a bundle, '
'because the passed request doesn\'t contain a "csp_nonce". '
'Bundle name: {chunk_name}')
'Chunk name: {chunk_name}')


@lru_cache(maxsize=100)
Expand Down
19 changes: 11 additions & 8 deletions webpack_loader/templatetags/webpack_loader.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from typing import Optional
from warnings import warn

from django.http.request import HttpRequest
from django.template import Library
from django.utils.safestring import mark_safe

Expand All @@ -20,23 +22,24 @@ def render_bundle(
if skip_common_chunks is None:
skip_common_chunks = utils.get_skip_common_chunks(config)

request = context.get('request')
url_to_tag_dict = utils.get_as_url_to_tag_dict(
request: Optional[HttpRequest] = context.get('request')
tags = utils.get_as_url_to_tag_dict(
bundle_name, request=request, extension=extension, config=config,
suffix=suffix, attrs=attrs, is_preload=is_preload)

if request is None:
if skip_common_chunks:
warn(message=_WARNING_MESSAGE, category=RuntimeWarning)
return mark_safe('\n'.join(url_to_tag_dict.values()))
return mark_safe('\n'.join(tags.values()))

used_urls = getattr(request, '_webpack_loader_used_urls', None)
if not used_urls:
used_urls = request._webpack_loader_used_urls = set()
if used_urls is None:
used_urls = set()
setattr(request, '_webpack_loader_used_urls', used_urls)
if skip_common_chunks:
url_to_tag_dict = {url: tag for url, tag in url_to_tag_dict.items() if url not in used_urls}
used_urls.update(url_to_tag_dict)
return mark_safe('\n'.join(url_to_tag_dict.values()))
tags = {url: tag for url, tag in tags.items() if url not in used_urls}
used_urls.update(tags)
return mark_safe('\n'.join(tags.values()))


@register.simple_tag
Expand Down
19 changes: 13 additions & 6 deletions webpack_loader/utils.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
from collections import OrderedDict
from functools import lru_cache
from importlib import import_module
from typing import Optional, OrderedDict

from django.conf import settings
from django.http.request import HttpRequest

from .config import load_config
from .loaders import WebpackLoader


def import_string(dotted_path):
Expand All @@ -21,7 +25,7 @@ def import_string(dotted_path):


@lru_cache(maxsize=None)
def get_loader(config_name):
def get_loader(config_name) -> WebpackLoader:
config = load_config(config_name)
loader_class = import_string(config['LOADER_CLASS'])
return loader_class(config_name, config)
Expand Down Expand Up @@ -56,8 +60,9 @@ def get_files(bundle_name, extension=None, config='DEFAULT'):


def get_as_url_to_tag_dict(
bundle_name, request=None, extension=None, config='DEFAULT', suffix='',
attrs='', is_preload=False):
bundle_name, request: Optional[HttpRequest] = None, extension=None,
config='DEFAULT', suffix='', attrs='', is_preload=False
) -> OrderedDict[str, str]:
'''
Get a dict of URLs to formatted <script> & <link> tags for the assets in the
named bundle.
Expand All @@ -70,7 +75,7 @@ def get_as_url_to_tag_dict(

loader = get_loader(config)
bundle = _get_bundle(loader, bundle_name, extension)
result = OrderedDict()
result = OrderedDict[str, str]()
attrs_l = attrs.lower()

for chunk in bundle:
Expand Down Expand Up @@ -130,6 +135,7 @@ def get_static(asset_name, config='DEFAULT'):

return '{0}{1}'.format(public_path, asset_name)


def get_asset(source_filename, config='DEFAULT'):
'''
Equivalent to Django's 'static' look up but for webpack assets, given its original filename.
Expand All @@ -141,6 +147,7 @@ def get_asset(source_filename, config='DEFAULT'):
'''
loader = get_loader(config)
asset = loader.get_asset_by_source_filename(source_filename)
if not asset: return None
if not asset:
return None

return get_static(asset['name'], config)

0 comments on commit 9c36189

Please sign in to comment.