Reformat lines that became too long. And enforce 119 line length.

This commit is contained in:
Emil Stenström 2024-02-11 22:50:15 +01:00 committed by Emil Stenström
parent ef6a082238
commit 48fe8171b4
25 changed files with 314 additions and 733 deletions

View file

@ -26,9 +26,7 @@ class AppSettings:
@property
def CONTEXT_BEHAVIOR(self):
raw_value = self.settings.setdefault(
"context_behavior", ContextBehavior.GLOBAL.value
)
raw_value = self.settings.setdefault("context_behavior", ContextBehavior.GLOBAL.value)
return self._validate_context_behavior(raw_value)
def _validate_context_behavior(self, raw_value):
@ -36,9 +34,7 @@ class AppSettings:
return ContextBehavior(raw_value)
except ValueError:
valid_values = [behavior.value for behavior in ContextBehavior]
raise ValueError(
f"Invalid context behavior: {raw_value}. Valid options are {valid_values}"
)
raise ValueError(f"Invalid context behavior: {raw_value}. Valid options are {valid_values}")
app_settings = AppSettings()

View file

@ -80,9 +80,7 @@ class Component(View, metaclass=SimplifiedInterfaceMediaDefiningClass):
self,
registered_name: Optional[str] = None,
outer_context: Optional[Context] = None,
fill_content: Union[
DefaultFillContent, Iterable[NamedFillContent]
] = (),
fill_content: Union[DefaultFillContent, Iterable[NamedFillContent]] = (),
):
self.registered_name: Optional[str] = registered_name
self.outer_context: Context = outer_context or Context()
@ -152,14 +150,10 @@ class Component(View, metaclass=SimplifiedInterfaceMediaDefiningClass):
if slots_data:
self._fill_slots(slots_data, escape_slots_content)
updated_filled_slots_context: FilledSlotsContext = (
self._process_template_and_update_filled_slot_context(
context, template
)
updated_filled_slots_context: FilledSlotsContext = self._process_template_and_update_filled_slot_context(
context, template
)
with context.update(
{FILLED_SLOTS_CONTENT_CONTEXT_KEY: updated_filled_slots_context}
):
with context.update({FILLED_SLOTS_CONTENT_CONTEXT_KEY: updated_filled_slots_context}):
return template.render(context)
def render_to_response(
@ -201,19 +195,14 @@ class Component(View, metaclass=SimplifiedInterfaceMediaDefiningClass):
named_fills_content = {}
else:
default_fill_content = None
named_fills_content = {
name: (nodelist, alias)
for name, nodelist, alias in self.fill_content
}
named_fills_content = {name: (nodelist, alias) for name, nodelist, alias in self.fill_content}
# If value is `None`, then slot is unfilled.
slot_name2fill_content: Dict[SlotName, Optional[FillContent]] = {}
default_slot_encountered: bool = False
required_slot_names: Set[str] = set()
for node in template.nodelist.get_nodes_by_type(
(SlotNode, IfSlotFilledConditionBranchNode) # type: ignore
):
for node in template.nodelist.get_nodes_by_type((SlotNode, IfSlotFilledConditionBranchNode)): # type: ignore
if isinstance(node, SlotNode):
# Give slot node knowledge of its parent template.
node.template = template
@ -225,9 +214,7 @@ class Component(View, metaclass=SimplifiedInterfaceMediaDefiningClass):
f"To fix, check template '{template.name}' "
f"of component '{self.registered_name}'."
)
content_data: Optional[FillContent] = (
None # `None` -> unfilled
)
content_data: Optional[FillContent] = None # `None` -> unfilled
if node.is_required:
required_slot_names.add(node.name)
if node.is_default:
@ -245,9 +232,7 @@ class Component(View, metaclass=SimplifiedInterfaceMediaDefiningClass):
elif isinstance(node, IfSlotFilledConditionBranchNode):
node.template = template
else:
raise RuntimeError(
f"Node of {type(node).__name__} does not require linking."
)
raise RuntimeError(f"Node of {type(node).__name__} does not require linking.")
# Check: Only component templates that include a 'default' slot
# can be invoked with implicit filling.
@ -258,12 +243,8 @@ class Component(View, metaclass=SimplifiedInterfaceMediaDefiningClass):
f"even though none of its slots is marked as 'default'."
)
unfilled_slots: Set[str] = set(
k for k, v in slot_name2fill_content.items() if v is None
)
unmatched_fills: Set[str] = (
named_fills_content.keys() - slot_name2fill_content.keys()
)
unfilled_slots: Set[str] = set(k for k, v in slot_name2fill_content.items() if v is None)
unmatched_fills: Set[str] = named_fills_content.keys() - slot_name2fill_content.keys()
# Check that 'required' slots are filled.
for slot_name in unfilled_slots:
@ -286,9 +267,7 @@ class Component(View, metaclass=SimplifiedInterfaceMediaDefiningClass):
# Higher values make matching stricter. This is probably preferable, as it
# reduces false positives.
for fill_name in unmatched_fills:
fuzzy_slot_name_matches = difflib.get_close_matches(
fill_name, unfilled_slots, n=1, cutoff=0.7
)
fuzzy_slot_name_matches = difflib.get_close_matches(fill_name, unfilled_slots, n=1, cutoff=0.7)
msg = (
f"Component '{self.registered_name}' passed fill "
f"that refers to undefined slot: '{fill_name}'."
@ -305,9 +284,7 @@ class Component(View, metaclass=SimplifiedInterfaceMediaDefiningClass):
if content_data # Slots whose content is None (i.e. unfilled) are dropped.
}
try:
prev_context: FilledSlotsContext = context[
FILLED_SLOTS_CONTENT_CONTEXT_KEY
]
prev_context: FilledSlotsContext = context[FILLED_SLOTS_CONTENT_CONTEXT_KEY]
return prev_context.new_child(filled_slots_map)
except KeyError:
return ChainMap(filled_slots_map)

View file

@ -12,13 +12,8 @@ class ComponentRegistry(object):
def register(self, name=None, component=None):
existing_component = self._registry.get(name)
if (
existing_component
and existing_component.class_hash != component.class_hash
):
raise AlreadyRegistered(
'The component "%s" has already been registered' % name
)
if existing_component and existing_component.class_hash != component.class_hash:
raise AlreadyRegistered('The component "%s" has already been registered' % name)
self._registry[name] = component
def unregister(self, name):

View file

@ -9,9 +9,7 @@ class Command(BaseCommand):
help = "Creates a new component"
def add_arguments(self, parser):
parser.add_argument(
"name", type=str, help="The name of the component to create"
)
parser.add_argument("name", type=str, help="The name of the component to create")
parser.add_argument(
"--path",
type=str,
@ -71,9 +69,7 @@ class Command(BaseCommand):
elif base_dir:
component_path = os.path.join(base_dir, "components", name)
else:
raise CommandError(
"You must specify a path or set BASE_DIR in your django settings"
)
raise CommandError("You must specify a path or set BASE_DIR in your django settings")
if os.path.exists(component_path):
if force:
@ -84,11 +80,7 @@ class Command(BaseCommand):
)
)
else:
self.stdout.write(
self.style.WARNING(
f'The component "{name}" already exists. Overwriting...'
)
)
self.stdout.write(self.style.WARNING(f'The component "{name}" already exists. Overwriting...'))
else:
raise CommandError(
f'The component "{name}" already exists at {component_path}. Use --force to overwrite.'
@ -107,9 +99,7 @@ class Command(BaseCommand):
)
f.write(script_content.strip())
with open(
os.path.join(component_path, css_filename), "w"
) as f:
with open(os.path.join(component_path, css_filename), "w") as f:
style_content = dedent(
f"""
.component-{name} {{
@ -119,9 +109,7 @@ class Command(BaseCommand):
)
f.write(style_content.strip())
with open(
os.path.join(component_path, template_filename), "w"
) as f:
with open(os.path.join(component_path, template_filename), "w") as f:
template_content = dedent(
f"""
<div class="component-{name}">
@ -133,9 +121,7 @@ class Command(BaseCommand):
)
f.write(template_content.strip())
with open(
os.path.join(component_path, f"{name}.py"), "w"
) as f:
with open(os.path.join(component_path, f"{name}.py"), "w") as f:
py_content = dedent(
f"""
from django_components import component
@ -157,16 +143,8 @@ class Command(BaseCommand):
f.write(py_content.strip())
if verbose:
self.stdout.write(
self.style.SUCCESS(
f"Successfully created {name} component at {component_path}"
)
)
self.stdout.write(self.style.SUCCESS(f"Successfully created {name} component at {component_path}"))
else:
self.stdout.write(
self.style.SUCCESS(
f"Successfully created {name} component"
)
)
self.stdout.write(self.style.SUCCESS(f"Successfully created {name} component"))
else:
raise CommandError("You must specify a component name")

View file

@ -11,9 +11,7 @@ CSS_DEPENDENCY_PLACEHOLDER = '<link name="CSS_PLACEHOLDER">'
JS_DEPENDENCY_PLACEHOLDER = '<script name="JS_PLACEHOLDER"></script>'
SCRIPT_TAG_REGEX = re.compile("<script")
COMPONENT_COMMENT_REGEX = re.compile(
rb"<!-- _RENDERED (?P<name>[\w\-/]+?) -->"
)
COMPONENT_COMMENT_REGEX = re.compile(rb"<!-- _RENDERED (?P<name>[\w\-/]+?) -->")
PLACEHOLDER_REGEX = re.compile(
rb"<!-- _RENDERED (?P<name>[\w\-/]+?) -->"
rb'|<link name="CSS_PLACEHOLDER">'
@ -32,9 +30,7 @@ class ComponentDependencyMiddleware:
def __call__(self, request):
response = self.get_response(request)
if (
getattr(settings, "COMPONENTS", {}).get(
"RENDER_DEPENDENCIES", False
)
getattr(settings, "COMPONENTS", {}).get("RENDER_DEPENDENCIES", False)
and not isinstance(response, StreamingHttpResponse)
and response.get("Content-Type", "").startswith("text/html")
):
@ -43,23 +39,12 @@ class ComponentDependencyMiddleware:
def process_response_content(content):
component_names_seen = {
match.group("name")
for match in COMPONENT_COMMENT_REGEX.finditer(content)
}
all_components = [
registry.get(name.decode("utf-8"))("") for name in component_names_seen
]
component_names_seen = {match.group("name") for match in COMPONENT_COMMENT_REGEX.finditer(content)}
all_components = [registry.get(name.decode("utf-8"))("") for name in component_names_seen]
all_media = join_media(all_components)
js_dependencies = b"".join(
media.encode("utf-8") for media in all_media.render_js()
)
css_dependencies = b"".join(
media.encode("utf-8") for media in all_media.render_css()
)
return PLACEHOLDER_REGEX.sub(
DependencyReplacer(css_dependencies, js_dependencies), content
)
js_dependencies = b"".join(media.encode("utf-8") for media in all_media.render_js())
css_dependencies = b"".join(media.encode("utf-8") for media in all_media.render_css())
return PLACEHOLDER_REGEX.sub(DependencyReplacer(css_dependencies, js_dependencies), content)
def add_module_attribute_to_scripts(scripts):

View file

@ -12,9 +12,7 @@ class SaferStaticFilesConfig(StaticFilesConfig):
by the static file server.
"""
default = (
True # Ensure that _this_ app is registered, as opposed to parent cls.
)
default = True # Ensure that _this_ app is registered, as opposed to parent cls.
ignore_patterns = StaticFilesConfig.ignore_patterns + [
"*.py",
"*.html",

View file

@ -9,13 +9,7 @@ else:
import django.template
from django.conf import settings
from django.template import Context, Template
from django.template.base import (
FilterExpression,
Node,
NodeList,
TextNode,
TokenType,
)
from django.template.base import FilterExpression, Node, NodeList, TextNode, TokenType
from django.template.defaulttags import CommentNode
from django.template.exceptions import TemplateSyntaxError
from django.template.library import parse_bits
@ -24,10 +18,7 @@ from django.utils.safestring import mark_safe
from django_components.app_settings import app_settings
from django_components.component_registry import ComponentRegistry
from django_components.component_registry import registry as component_registry
from django_components.middleware import (
CSS_DEPENDENCY_PLACEHOLDER,
JS_DEPENDENCY_PLACEHOLDER,
)
from django_components.middleware import CSS_DEPENDENCY_PLACEHOLDER, JS_DEPENDENCY_PLACEHOLDER
if TYPE_CHECKING:
from django_components.component import Component
@ -88,16 +79,8 @@ def component_dependencies_tag(preload=""):
if is_dependency_middleware_active():
preloaded_dependencies = []
for component in get_components_from_preload_str(preload):
preloaded_dependencies.append(
RENDERED_COMMENT_TEMPLATE.format(
name=component.registered_name
)
)
return mark_safe(
"\n".join(preloaded_dependencies)
+ CSS_DEPENDENCY_PLACEHOLDER
+ JS_DEPENDENCY_PLACEHOLDER
)
preloaded_dependencies.append(RENDERED_COMMENT_TEMPLATE.format(name=component.registered_name))
return mark_safe("\n".join(preloaded_dependencies) + CSS_DEPENDENCY_PLACEHOLDER + JS_DEPENDENCY_PLACEHOLDER)
else:
rendered_dependencies = []
for component in get_components_from_registry(component_registry):
@ -113,14 +96,8 @@ def component_css_dependencies_tag(preload=""):
if is_dependency_middleware_active():
preloaded_dependencies = []
for component in get_components_from_preload_str(preload):
preloaded_dependencies.append(
RENDERED_COMMENT_TEMPLATE.format(
name=component.registered_name
)
)
return mark_safe(
"\n".join(preloaded_dependencies) + CSS_DEPENDENCY_PLACEHOLDER
)
preloaded_dependencies.append(RENDERED_COMMENT_TEMPLATE.format(name=component.registered_name))
return mark_safe("\n".join(preloaded_dependencies) + CSS_DEPENDENCY_PLACEHOLDER)
else:
rendered_dependencies = []
for component in get_components_from_registry(component_registry):
@ -136,14 +113,8 @@ def component_js_dependencies_tag(preload=""):
if is_dependency_middleware_active():
preloaded_dependencies = []
for component in get_components_from_preload_str(preload):
preloaded_dependencies.append(
RENDERED_COMMENT_TEMPLATE.format(
name=component.registered_name
)
)
return mark_safe(
"\n".join(preloaded_dependencies) + JS_DEPENDENCY_PLACEHOLDER
)
preloaded_dependencies.append(RENDERED_COMMENT_TEMPLATE.format(name=component.registered_name))
return mark_safe("\n".join(preloaded_dependencies) + JS_DEPENDENCY_PLACEHOLDER)
else:
rendered_dependencies = []
for component in get_components_from_registry(component_registry):
@ -151,6 +122,7 @@ def component_js_dependencies_tag(preload=""):
return mark_safe("\n".join(rendered_dependencies))
class UserSlotVar:
"""
Extensible mechanism for offering 'fill' blocks in template access to properties
@ -216,24 +188,17 @@ class SlotNode(Node, TemplateAwareNodeMixin):
def render(self, context):
try:
filled_slots_map: FilledSlotsContext = context[
FILLED_SLOTS_CONTENT_CONTEXT_KEY
]
filled_slots_map: FilledSlotsContext = context[FILLED_SLOTS_CONTENT_CONTEXT_KEY]
except KeyError:
raise TemplateSyntaxError(
f"Attempted to render SlotNode '{self.name}' outside a parent component."
)
raise TemplateSyntaxError(f"Attempted to render SlotNode '{self.name}' outside a parent component.")
extra_context = {}
try:
slot_fill_content: Optional[FillContent] = filled_slots_map[
(self.name, self.template)
]
slot_fill_content: Optional[FillContent] = filled_slots_map[(self.name, self.template)]
except KeyError:
if self.is_required:
raise TemplateSyntaxError(
f"Slot '{self.name}' is marked as 'required' (i.e. non-optional), "
f"yet no fill is provided. "
f"Slot '{self.name}' is marked as 'required' (i.e. non-optional), " f"yet no fill is provided. "
)
nodelist = self.nodelist
else:
@ -257,9 +222,7 @@ def do_slot(parser, token):
if 1 <= len(args) <= 3:
slot_name, *options = args
if not is_wrapped_in_quotes(slot_name):
raise TemplateSyntaxError(
f"'{bits[0]}' name must be a string 'literal'."
)
raise TemplateSyntaxError(f"'{bits[0]}' name must be a string 'literal'.")
slot_name = strip_quotes(slot_name)
modifiers_count = len(options)
if SLOT_REQUIRED_OPTION_KEYWORD in options:
@ -273,9 +236,7 @@ def do_slot(parser, token):
SLOT_REQUIRED_OPTION_KEYWORD,
SLOT_DEFAULT_OPTION_KEYWORD,
]
raise TemplateSyntaxError(
f"Invalid options passed to 'slot' tag. Valid choices: {keywords}."
)
raise TemplateSyntaxError(f"Invalid options passed to 'slot' tag. Valid choices: {keywords}.")
else:
raise TemplateSyntaxError(
"'slot' tag does not match pattern "
@ -354,14 +315,10 @@ def do_fill(parser, token):
elif len(args) == 3:
tgt_slot_name, as_keyword, alias = args
if as_keyword.lower() != "as":
raise TemplateSyntaxError(
f"{tag} tag args do not conform to pattern '<target slot> as <alias>'"
)
raise TemplateSyntaxError(f"{tag} tag args do not conform to pattern '<target slot> as <alias>'")
alias_fexp = FilterExpression(alias, parser)
else:
raise TemplateSyntaxError(
f"'{tag}' tag takes either 1 or 3 arguments: Received {len(args)}."
)
raise TemplateSyntaxError(f"'{tag}' tag takes either 1 or 3 arguments: Received {len(args)}.")
nodelist = parser.parse(parse_until=["endfill"])
parser.delete_first_token()
@ -397,27 +354,18 @@ class ComponentNode(Node):
def __repr__(self):
return "<ComponentNode: %s. Contents: %r>" % (
self.name_fexp,
getattr(
self, "nodelist", None
), # 'nodelist' attribute only assigned later.
getattr(self, "nodelist", None), # 'nodelist' attribute only assigned later.
)
def render(self, context: Context):
resolved_component_name = self.name_fexp.resolve(context)
component_cls: Type[Component] = component_registry.get(
resolved_component_name
)
component_cls: Type[Component] = component_registry.get(resolved_component_name)
# Resolve FilterExpressions and Variables that were passed as args to the
# component, then call component's context method
# to get values to insert into the context
resolved_context_args = [
safe_resolve(arg, context) for arg in self.context_args
]
resolved_context_kwargs = {
key: safe_resolve(kwarg, context)
for key, kwarg in self.context_kwargs.items()
}
resolved_context_args = [safe_resolve(arg, context) for arg in self.context_args]
resolved_context_kwargs = {key: safe_resolve(kwarg, context) for key, kwarg in self.context_kwargs.items()}
if isinstance(self.fill_nodes, ImplicitFillNode):
fill_content = self.fill_nodes.nodelist
@ -437,9 +385,7 @@ class ComponentNode(Node):
)
else:
resolved_alias: None = None
fill_content.append(
(resolved_name, fill_node.nodelist, resolved_alias)
)
fill_content.append((resolved_name, fill_node.nodelist, resolved_alias))
component: Component = component_cls(
registered_name=resolved_component_name,
@ -447,9 +393,7 @@ class ComponentNode(Node):
fill_content=fill_content,
)
component_context: dict = component.get_context_data(
*resolved_context_args, **resolved_context_kwargs
)
component_context: dict = component.get_context_data(*resolved_context_args, **resolved_context_kwargs)
if self.isolated_context:
context = context.new()
@ -457,10 +401,7 @@ class ComponentNode(Node):
rendered_component = component.render(context)
if is_dependency_middleware_active():
return (
RENDERED_COMMENT_TEMPLATE.format(name=resolved_component_name)
+ rendered_component
)
return RENDERED_COMMENT_TEMPLATE.format(name=resolved_component_name) + rendered_component
else:
return rendered_component
@ -482,9 +423,7 @@ def do_component_block(parser, token):
bits = token.split_contents()
bits, isolated_context = check_for_isolated_context_keyword(bits)
component_name, context_args, context_kwargs = parse_component_with_args(
parser, bits, "component_block"
)
component_name, context_args, context_kwargs = parse_component_with_args(parser, bits, "component_block")
body: NodeList = parser.parse(parse_until=["endcomponent_block"])
parser.delete_first_token()
fill_nodes = ()
@ -575,10 +514,7 @@ def is_whitespace_token(token):
def is_block_tag_token(token, name):
return (
token.token_type == TokenType.BLOCK
and token.split_contents()[0] == name
)
return token.token_type == TokenType.BLOCK and token.split_contents()[0] == name
@register.tag(name="if_filled")
@ -610,9 +546,7 @@ def do_if_filled_block(parser, token):
slot_name, is_positive = parse_if_filled_bits(bits)
nodelist = parser.parse(("elif_filled", "else_filled", "endif_filled"))
branches: List[_IfSlotFilledBranchNode] = [
IfSlotFilledConditionBranchNode(
slot_name=slot_name, nodelist=nodelist, is_positive=is_positive
)
IfSlotFilledConditionBranchNode(slot_name=slot_name, nodelist=nodelist, is_positive=is_positive)
]
token = parser.next_token()
@ -621,13 +555,9 @@ def do_if_filled_block(parser, token):
while token.contents.startswith("elif_filled"):
bits = token.split_contents()
slot_name, is_positive = parse_if_filled_bits(bits)
nodelist: NodeList = parser.parse(
("elif_filled", "else_filled", "endif_filled")
)
nodelist: NodeList = parser.parse(("elif_filled", "else_filled", "endif_filled"))
branches.append(
IfSlotFilledConditionBranchNode(
slot_name=slot_name, nodelist=nodelist, is_positive=is_positive
)
IfSlotFilledConditionBranchNode(slot_name=slot_name, nodelist=nodelist, is_positive=is_positive)
)
token = parser.next_token()
@ -656,9 +586,7 @@ def parse_if_filled_bits(
tag, args = bits[0], bits[1:]
if tag in ("else_filled", "endif_filled"):
if len(args) != 0:
raise TemplateSyntaxError(
f"Tag '{tag}' takes no arguments. Received '{' '.join(args)}'"
)
raise TemplateSyntaxError(f"Tag '{tag}' takes no arguments. Received '{' '.join(args)}'")
else:
return None, None
if len(args) == 1:
@ -669,13 +597,10 @@ def parse_if_filled_bits(
is_positive = bool_from_string(args[1])
else:
raise TemplateSyntaxError(
f"{bits[0]} tag arguments '{' '.join(args)}' do not match pattern "
f"'<slotname> (<is_positive>)'"
f"{bits[0]} tag arguments '{' '.join(args)}' do not match pattern " f"'<slotname> (<is_positive>)'"
)
if not is_wrapped_in_quotes(slot_name):
raise TemplateSyntaxError(
f"First argument of '{bits[0]}' must be a quoted string 'literal'."
)
raise TemplateSyntaxError(f"First argument of '{bits[0]}' must be a quoted string 'literal'.")
slot_name = strip_quotes(slot_name)
return slot_name, is_positive
@ -691,9 +616,7 @@ class _IfSlotFilledBranchNode(Node):
raise NotImplementedError
class IfSlotFilledConditionBranchNode(
_IfSlotFilledBranchNode, TemplateAwareNodeMixin
):
class IfSlotFilledConditionBranchNode(_IfSlotFilledBranchNode, TemplateAwareNodeMixin):
def __init__(
self,
slot_name: str,
@ -706,9 +629,7 @@ class IfSlotFilledConditionBranchNode(
def evaluate(self, context) -> bool:
try:
filled_slots: FilledSlotsContext = context[
FILLED_SLOTS_CONTENT_CONTEXT_KEY
]
filled_slots: FilledSlotsContext = context[FILLED_SLOTS_CONTENT_CONTEXT_KEY]
except KeyError:
raise TemplateSyntaxError(
f"Attempted to render {type(self).__name__} outside a Component rendering context."
@ -777,9 +698,7 @@ def parse_component_with_args(parser, bits, tag_name):
)
if tag_name != tag_args[0].token:
raise RuntimeError(
f"Internal error: Expected tag_name to be {tag_name}, but it was {tag_args[0].token}"
)
raise RuntimeError(f"Internal error: Expected tag_name to be {tag_name}, but it was {tag_args[0].token}")
if len(tag_args) > 1:
# At least one position arg, so take the first as the component name
component_name = tag_args[1].token
@ -791,9 +710,7 @@ def parse_component_with_args(parser, bits, tag_name):
context_args = []
context_kwargs = tag_kwargs
except IndexError:
raise TemplateSyntaxError(
f"Call the '{tag_name}' tag with a component name as the first parameter"
)
raise TemplateSyntaxError(f"Call the '{tag_name}' tag with a component name as the first parameter")
return component_name, context_args, context_kwargs
@ -801,11 +718,7 @@ def parse_component_with_args(parser, bits, tag_name):
def safe_resolve(context_item, context):
"""Resolve FilterExpressions and Variables in context if possible. Return other items unchanged."""
return (
context_item.resolve(context)
if hasattr(context_item, "resolve")
else context_item
)
return context_item.resolve(context) if hasattr(context_item, "resolve") else context_item
def is_wrapped_in_quotes(s):
@ -813,9 +726,7 @@ def is_wrapped_in_quotes(s):
def is_dependency_middleware_active():
return getattr(settings, "COMPONENTS", {}).get(
"RENDER_DEPENDENCIES", False
)
return getattr(settings, "COMPONENTS", {}).get("RENDER_DEPENDENCIES", False)
def norm_and_validate_name(name: str, tag: str, context: Optional[str] = None):
@ -826,10 +737,7 @@ def norm_and_validate_name(name: str, tag: str, context: Optional[str] = None):
name = strip_quotes(name)
if not name.isidentifier():
context = f" in '{context}'" if context else ""
raise TemplateSyntaxError(
f"{tag} name '{name}'{context} "
"is not a valid Python identifier."
)
raise TemplateSyntaxError(f"{tag} name '{name}'{context} " "is not a valid Python identifier.")
return name