widgetti / ipyvue

Jupyter widgets base for Vue libraries
MIT License
68 stars 18 forks source link

Template get_template UnicodeDecodeError #73

Closed CyberQin closed 1 year ago

CyberQin commented 1 year ago

Enviroment:

How to reproduce:

  1. a ms system with default encoding neigher ascii nor utf8
  2. clone latest solara repo and get ready for its env and deps
  3. run solara run .\solara\website\pages\api\file_drop.py --dev

Error log

Traceback (most recent call last):
  File "C:\Users\qin\anaconda3\envs\solara\lib\site-packages\reacton\core.py", line 364, in _create_widget
    widget = self.component.widget(**kwargs)
  File "C:\Users\qin\anaconda3\envs\solara\lib\site-packages\ipyvue\VueTemplateWidget.py", line 144, in __init__
    self.template = get_template(abs_path)
  File "D:\codes\solara\solara\server\patch.py", line 218, in wrapper
    template = get_template(abs_path)
  File "C:\Users\qin\anaconda3\envs\solara\lib\site-packages\ipyvue\Template.py", line 48, in get_template
    tw = Template(template=f.read())
UnicodeDecodeError: 'gbk' codec can't decode byte 0x8b in position 44: illegal multibyte sequence

MS Windows use 'gbk' as default unicode encoding in China. and Python with open() method will use the system default encoding.

And i belive it will run error in other area with its own encoding.

Temporarily solve it

def get_template(abs_path):
    abs_path = os.path.normpath(abs_path)
    if abs_path not in template_registry:
        with open(abs_path,encoding='utf-8') as f:
            tw = Template(template=f.read())
            template_registry[abs_path] = tw
    else:
        with open(abs_path,encoding='utf-8') as f:
            template_registry[abs_path].template = f.read()
    return template_registry[abs_path]

Project Solution

There are two way to solve it ,one is like the Temporarily method, but limit all vue files to 'utf8' (maybe not a bad idea, since we programmers almost use 'utf8'). the second one is write below:
As the get_template method is used in this repo but also wathed by solara repo, The fix solution needs to change 2 repo

 - make solara.server.patch.auto_watch_get_template wrapper the two param name 
```python
def auto_watch_get_template(get_template):
    """Wraps get_template and adds a file listener for automatic .vue file reloading"""

    def wrapper(abs_path, file_coding):
        template = get_template(abs_path, file_coding)
        reload.reloader.watcher.add_file(abs_path)
        return template

    return wrapper
maartenbreddels commented 1 year ago

This is released in ipyvue 1.9.2 🎉