Merging upstream version 0.56+dfsg.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
683f3a672a
commit
aeb0367086
23 changed files with 131 additions and 20 deletions
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
github: jpsca
|
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2021-2022 Juan-Pablo Scaletti
|
||||
Copyright (c) Juan-Pablo Scaletti <juanpablo@jpscaletti.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
"""
|
||||
JinjaX Benchmark
|
||||
Copyright (c) Juan-Pablo Scaletti <juanpablo@jpscaletti.com>
|
||||
"""
|
||||
import timeit
|
||||
from pathlib import Path
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
"""
|
||||
JinjaX Benchmark
|
||||
Copyright (c) Juan-Pablo Scaletti <juanpablo@jpscaletti.com>
|
||||
"""
|
||||
from pathlib import Path
|
||||
|
||||
from jinjax import Catalog, Component
|
||||
|
|
|
@ -4,7 +4,7 @@ requires = ["setuptools"]
|
|||
|
||||
[project]
|
||||
name = "jinjax"
|
||||
version = "0.55"
|
||||
version = "0.56"
|
||||
description = "Replace your HTML templates with Python server-Side components"
|
||||
authors = [
|
||||
{name = "Juan Pablo Scaletti", email = "juanpablo@jpscaletti.com"},
|
||||
|
@ -45,7 +45,7 @@ documentation = "https://jinjax.scaletti.dev/guides/"
|
|||
[dependency-groups]
|
||||
dev = [
|
||||
"ipdb >= 0.13",
|
||||
"pyright >= 1.1",
|
||||
"pyright >= 1.1.400",
|
||||
"pre-commit",
|
||||
"ruff >= 0.2.0",
|
||||
"tox-uv",
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
"""
|
||||
JinjaX
|
||||
Copyright (c) Juan-Pablo Scaletti <juanpablo@jpscaletti.com>
|
||||
"""
|
||||
from . import utils # noqa
|
||||
from .catalog import Catalog
|
||||
from .component import Component
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
"""
|
||||
JinjaX
|
||||
Copyright (c) Juan-Pablo Scaletti <juanpablo@jpscaletti.com>
|
||||
"""
|
||||
import os
|
||||
import typing as t
|
||||
from collections import UserString
|
||||
|
@ -40,6 +44,8 @@ collected_css: dict[int, ContextVar[list[str]]] = {}
|
|||
collected_js: dict[int, ContextVar[list[str]]] = {}
|
||||
tmpl_globals: dict[int, ContextVar[dict[str, t.Any]]] = {}
|
||||
|
||||
RelPath = Path
|
||||
|
||||
|
||||
class CallerWrapper(UserString):
|
||||
_content = ""
|
||||
|
@ -590,7 +596,7 @@ class Catalog:
|
|||
html_js.append(f'<script type="module" src="{full_url}"></script>')
|
||||
rendered_urls.add(full_url)
|
||||
|
||||
return Markup("\n".join(html_css + html_js))
|
||||
return Markup("\n".join(sorted(html_css) + sorted(html_js)))
|
||||
|
||||
# Private
|
||||
|
||||
|
@ -712,7 +718,7 @@ class Catalog:
|
|||
prefix: str,
|
||||
name: str,
|
||||
file_ext: str,
|
||||
) -> tuple[Path, Path] | None:
|
||||
) -> tuple[Path, RelPath] | None:
|
||||
root_paths = self.prefixes[prefix].searchpath
|
||||
|
||||
name = name.replace(DELIMITER, SLASH)
|
||||
|
@ -724,11 +730,21 @@ class Catalog:
|
|||
root_path, topdown=False, followlinks=True
|
||||
):
|
||||
relfolder = os.path.relpath(curr_folder, root_path).strip(".")
|
||||
if relfolder and not (
|
||||
name.startswith(relfolder)
|
||||
or kebab_name.startswith(relfolder)
|
||||
):
|
||||
continue
|
||||
if relfolder:
|
||||
if not (
|
||||
name.startswith(relfolder)
|
||||
or kebab_name.startswith(relfolder)
|
||||
):
|
||||
continue
|
||||
|
||||
# Allow for index.jinja files in subfolders
|
||||
# to be used as the folder name
|
||||
if relfolder in (name, kebab_name):
|
||||
filename = f"index{file_ext}"
|
||||
fullpath = Path(curr_folder) / filename
|
||||
if fullpath.is_file():
|
||||
relpath = Path(f"{relfolder}/{filename}")
|
||||
return fullpath, relpath
|
||||
|
||||
for filename in files:
|
||||
if relfolder:
|
||||
|
@ -737,7 +753,10 @@ class Catalog:
|
|||
filepath = filename
|
||||
|
||||
if filepath.startswith(dot_names) and filepath.endswith(file_ext):
|
||||
return Path(curr_folder) / filename, Path(filepath)
|
||||
fullpath = Path(curr_folder) / filename
|
||||
relpath = Path(filepath)
|
||||
if fullpath.is_file():
|
||||
return fullpath, relpath
|
||||
|
||||
def _render_attrs(self, attrs: dict[str, t.Any]) -> Markup:
|
||||
html_attrs = []
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
"""
|
||||
JinjaX
|
||||
Copyright (c) Juan-Pablo Scaletti <juanpablo@jpscaletti.com>
|
||||
"""
|
||||
import ast
|
||||
import re
|
||||
import typing as t
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
"""
|
||||
JinjaX
|
||||
Copyright (c) Juan-Pablo Scaletti <juanpablo@jpscaletti.com>
|
||||
"""
|
||||
|
||||
class ComponentNotFound(Exception):
|
||||
"""
|
||||
Raised when JinjaX can't find a component by name in none of the
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
"""
|
||||
JinjaX
|
||||
Copyright (c) Juan-Pablo Scaletti <juanpablo@jpscaletti.com>
|
||||
"""
|
||||
import re
|
||||
import typing as t
|
||||
from collections import UserString
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
"""
|
||||
JinjaX
|
||||
Copyright (c) Juan-Pablo Scaletti <juanpablo@jpscaletti.com>
|
||||
"""
|
||||
import re
|
||||
import typing as t
|
||||
from uuid import uuid4
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
"""
|
||||
JinjaX
|
||||
Copyright (c) Juan-Pablo Scaletti <juanpablo@jpscaletti.com>
|
||||
"""
|
||||
import re
|
||||
import typing as t
|
||||
from pathlib import Path
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
"""
|
||||
JinjaX
|
||||
Copyright (c) Juan-Pablo Scaletti <juanpablo@jpscaletti.com>
|
||||
"""
|
||||
import logging
|
||||
import re
|
||||
import uuid
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
"""
|
||||
JinjaX
|
||||
Copyright (c) Juan-Pablo Scaletti <juanpablo@jpscaletti.com>
|
||||
"""
|
||||
import pytest
|
||||
|
||||
import jinjax
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
"""
|
||||
JinjaX
|
||||
Copyright (c) Juan-Pablo Scaletti <juanpablo@jpscaletti.com>
|
||||
"""
|
||||
import pytest
|
||||
|
||||
import jinjax
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
"""
|
||||
JinjaX
|
||||
Copyright (c) Juan-Pablo Scaletti <juanpablo@jpscaletti.com>
|
||||
"""
|
||||
import pytest
|
||||
|
||||
from jinjax import Component, DuplicateDefDeclaration, InvalidArgument
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
"""
|
||||
JinjaX
|
||||
Copyright (c) Juan-Pablo Scaletti <juanpablo@jpscaletti.com>
|
||||
"""
|
||||
import pytest
|
||||
|
||||
from jinjax.html_attrs import HTMLAttrs
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
"""
|
||||
JinjaX
|
||||
Copyright (c) Juan-Pablo Scaletti <juanpablo@jpscaletti.com>
|
||||
"""
|
||||
import typing as t
|
||||
from pathlib import Path
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
"""
|
||||
JinjaX
|
||||
Copyright (c) Juan-Pablo Scaletti <juanpablo@jpscaletti.com>
|
||||
"""
|
||||
import jinja2
|
||||
import pytest
|
||||
from markupsafe import Markup
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
"""
|
||||
JinjaX
|
||||
Copyright (c) Juan-Pablo Scaletti <juanpablo@jpscaletti.com>
|
||||
"""
|
||||
import time
|
||||
from textwrap import dedent
|
||||
|
||||
|
@ -243,6 +247,24 @@ def test_subfolder(catalog, folder, autoescape, undefined):
|
|||
assert html == Markup('<div class="tab">Meh</div>')
|
||||
|
||||
|
||||
@pytest.mark.parametrize("undefined", [jinja2.Undefined, jinja2.StrictUndefined])
|
||||
@pytest.mark.parametrize("autoescape", [True, False])
|
||||
def test_subfolder_index_file(catalog, folder, autoescape, undefined):
|
||||
"""Components named "index.jinja" in subfolders can be called
|
||||
using the subfolder names.
|
||||
"""
|
||||
catalog.jinja_env.autoescape = autoescape
|
||||
catalog.jinja_env.undefined = undefined
|
||||
|
||||
sub = folder / "tab"
|
||||
sub.mkdir()
|
||||
(sub / "index.jinja").write_text("Hello")
|
||||
(sub / "panel.jinja").write_text("World")
|
||||
|
||||
assert catalog.render("Tab") == Markup("Hello")
|
||||
assert catalog.render("Tab.Panel") == Markup("World")
|
||||
|
||||
|
||||
@pytest.mark.parametrize("undefined", [jinja2.Undefined, jinja2.StrictUndefined])
|
||||
@pytest.mark.parametrize("autoescape", [True, False])
|
||||
def test_default_attr(catalog, folder, autoescape, undefined):
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
"""
|
||||
JinjaX
|
||||
Copyright (c) Juan-Pablo Scaletti <juanpablo@jpscaletti.com>
|
||||
"""
|
||||
from pathlib import Path
|
||||
|
||||
import jinja2
|
||||
|
@ -57,14 +61,14 @@ def test_render_assets(catalog, folder, autoescape, undefined):
|
|||
assert (
|
||||
"""
|
||||
<html>
|
||||
<link rel="stylesheet" href="https://somewhere.com/style.css">
|
||||
<link rel="stylesheet" href="/static/components/card.css">
|
||||
<link rel="stylesheet" href="/static/components/greeting.css">
|
||||
<link rel="stylesheet" href="http://example.com/super.css">
|
||||
<script type="module" src="https://somewhere.com/blabla.js"></script>
|
||||
<script type="module" src="/static/components/shared.js"></script>
|
||||
<link rel="stylesheet" href="https://somewhere.com/style.css">
|
||||
<script type="module" src="/static/components/card.js"></script>
|
||||
<script type="module" src="/static/components/greeting.js"></script>
|
||||
<script type="module" src="/static/components/shared.js"></script>
|
||||
<script type="module" src="https://somewhere.com/blabla.js"></script>
|
||||
<section class="card">
|
||||
<div class="greeting [&_a]:flex">Hello</div>
|
||||
<button type="button">Close</button>
|
||||
|
@ -195,8 +199,8 @@ def test_auto_load_assets_with_same_name(catalog, folder, autoescape, undefined)
|
|||
<link rel="stylesheet" href="/static/components/Page.css">
|
||||
<link rel="stylesheet" href="/static/components/common/Form.css">
|
||||
<script type="module" src="/static/components/Page.js"></script>
|
||||
<script type="module" src="/static/components/shared.js"></script>
|
||||
<script type="module" src="/static/components/common/Form.js"></script>
|
||||
<script type="module" src="/static/components/shared.js"></script>
|
||||
<form></form>
|
||||
""".strip()
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
"""
|
||||
JinjaX
|
||||
Copyright (c) Juan-Pablo Scaletti <juanpablo@jpscaletti.com>
|
||||
"""
|
||||
from threading import Thread
|
||||
|
||||
from markupsafe import Markup
|
||||
|
|
10
uv.lock
generated
10
uv.lock
generated
|
@ -215,7 +215,7 @@ wheels = [
|
|||
|
||||
[[package]]
|
||||
name = "jinjax"
|
||||
version = "0.55"
|
||||
version = "0.56"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "jinja2" },
|
||||
|
@ -254,7 +254,7 @@ provides-extras = ["whitenoise"]
|
|||
dev = [
|
||||
{ name = "ipdb", specifier = ">=0.13" },
|
||||
{ name = "pre-commit" },
|
||||
{ name = "pyright", specifier = ">=1.1" },
|
||||
{ name = "pyright", specifier = ">=1.1.400" },
|
||||
{ name = "ruff", specifier = ">=0.2.0" },
|
||||
{ name = "tox-uv" },
|
||||
]
|
||||
|
@ -451,15 +451,15 @@ wheels = [
|
|||
|
||||
[[package]]
|
||||
name = "pyright"
|
||||
version = "1.1.396"
|
||||
version = "1.1.400"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "nodeenv" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/bd/73/f20cb1dea1bdc1774e7f860fb69dc0718c7d8dea854a345faec845eb086a/pyright-1.1.396.tar.gz", hash = "sha256:142901f5908f5a0895be3d3befcc18bedcdb8cc1798deecaec86ef7233a29b03", size = 3814400 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/6c/cb/c306618a02d0ee8aed5fb8d0fe0ecfed0dbf075f71468f03a30b5f4e1fe0/pyright-1.1.400.tar.gz", hash = "sha256:b8a3ba40481aa47ba08ffb3228e821d22f7d391f83609211335858bf05686bdb", size = 3846546 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/80/be/ecb7cfb42d242b7ee764b52e6ff4782beeec00e3b943a3ec832b281f9da6/pyright-1.1.396-py3-none-any.whl", hash = "sha256:c635e473095b9138c471abccca22b9fedbe63858e0b40d4fc4b67da041891844", size = 5689355 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c8/a5/5d285e4932cf149c90e3c425610c5efaea005475d5f96f1bfdb452956c62/pyright-1.1.400-py3-none-any.whl", hash = "sha256:c80d04f98b5a4358ad3a35e241dbf2a408eee33a40779df365644f8054d2517e", size = 5563460 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue