pauleveritt / fdom

Template engine based on tag strings and functional ideas.
0 stars 0 forks source link

Support hyperpython as a mixin #22

Open jimbaker opened 11 months ago

jimbaker commented 11 months ago

The htm library uses hyperpython for its actual rendering. This looks useful as a mixin for what I've been doing with the FDOM compiler (really that should be "FDOM", need to add dependencies etc of course) I committed today, which is more or less complete enough to drive hyperpython.

Here's the code that FDOM compiler currently emits:

>>> from fdom.fdom_htmltag import html
>>> html'<p foo="bar" { {"style": body_style} } disabled>{body}</p>'

which produces this code

def __call__(self):
  return \
  self.tags.p(
    attrs={
      'foo': 'bar',
      **self.get_attrs_dict(1),
      'disabled': True,
    },
    children=[
      self.getvalue(3),
    ]
  )

That's quite close to what hyperpython would consume.

Separately, the overall codebase layout is a bit of a mess right now. I think something like fdom.ast.parser, fdom.base.compiler, etc would be a lot cleaner. Whatever it is, it shouldn't be fdomcompiler, that's just hard to read. I will address this shortly as I add in the mixin support.

jimbaker commented 11 months ago

Unfortunately hyperpython is not supported on the tagstr branch or in 3.12.0 itself, because of this bug in sidekick:

$ python -c "import hyperpython"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/jimbaker/opensource/test/venv/lib/python3.12/site-packages/hyperpython/__init__.py", line 7, in <module>
    from .core import Element, Text, Blob, Block, Json, Component
  File "/home/jimbaker/opensource/test/venv/lib/python3.12/site-packages/hyperpython/core.py", line 7, in <module>
    from sidekick import lazy, delegate_to
  File "/home/jimbaker/opensource/test/venv/lib/python3.12/site-packages/sidekick/__init__.py", line 16, in <module>
    from .api import *
  File "/home/jimbaker/opensource/test/venv/lib/python3.12/site-packages/sidekick/api.py", line 3, in <module>
    from . import op
  File "/home/jimbaker/opensource/test/venv/lib/python3.12/site-packages/sidekick/op.py", line 8, in <module>
    from .functions import fn as _fn
  File "/home/jimbaker/opensource/test/venv/lib/python3.12/site-packages/sidekick/functions/__init__.py", line 1, in <module>
    from . import core_functions as _core
  File "/home/jimbaker/opensource/test/venv/lib/python3.12/site-packages/sidekick/functions/core_functions.py", line 111, in <module>
    to_callable.register(Mapping, lambda dic: lambda x: map_function(dic, x))
  File "/home/jimbaker/.pyenv/versions/3.12.0/lib/python3.12/functools.py", line 864, in register
    raise TypeError(
TypeError: Invalid first argument to `register()`. typing.Mapping is not a class or union type.

Supporting a subset of the hyperpython API is straightforward, so there's no need to work through this, given that sidekick appears to be unsupported.

pauleveritt commented 11 months ago

All interesting points. It's a shame, this means there's even less a chance that I could do a ViewDOM replacement that worked in Python < 3.13.

jimbaker commented 11 months ago

I'm pretty certain that a lot of hyperpython could be done in Pydantic (especially v2), namely the free JSON support.

Maybe we want something like this as well: https://docs.rs/json-patch/latest/json_patch/ - I don't know if there's a Python wrapper, but it's a small package.

pauleveritt commented 11 months ago

While htm promotes the use of the (very dead) Hyperpython for rendering, ViewDOM shows that it really isn't needed.

What's your thinking of the need for Pydantic/JSON/patch in the render-to-string equation?