r0x0r / pywebview

Build GUI for your Python program with JavaScript, HTML, and CSS
https://pywebview.flowrl.com
BSD 3-Clause "New" or "Revised" License
4.77k stars 555 forks source link

If there is a new URL redirect program, it will get stuck #1528

Closed wall-git closed 1 week ago

wall-git commented 1 week ago

Specification

Description

When I try to pass window into an object instance ,If there is a new URL redirect program, it will get stuck thanks

code example

import webview
api = None
class ViewApi:
    win = None
    def setWindow(self,window):
        self.win = window  
def on_loaded(window):
    print('DOM is ready')
    #If there is a new URL redirect program, it will get stuck
    api.setWindow(window)

if __name__ == '__main__':
    api = ViewApi()
    #Click on any link
    window = webview.create_window(
        'Simple browser', 'https://www.bing.com/', js_api=api
    )
    window.events.loaded += on_loaded
    webview.start()
r0x0r commented 1 week ago

This occurs because of it tries to expose to win object of ViewApi class and goes into an infinite loop. Prefix win with an underscore to prevent exposing.

wall-git commented 1 week ago

Thank you so much, buddy,It has indeed solved my problem. I analyzed that it may be caused by the following code, and I will pay attention to it. Thank you util.py

    def get_functions(obj: object, base_name: str = '', functions: dict[str, object] = None):
        if obj in exposed_objects:
            return functions
        else:
            exposed_objects.append(obj)

        if functions is None:
            functions = {}

        for name in dir(obj):
            full_name = f"{base_name}.{name}" if base_name else name

            if name.startswith('_'):
                continue
            #wall : this line will get stuck
            attr = getattr(obj, name)
            if inspect.ismethod(attr):
                functions[full_name] = get_args(attr)[1:]
            # If the attribute is a class or a non-callable object, make a recursive call
            elif inspect.isclass(attr) or (isinstance(attr, object) and not callable(attr) and hasattr(attr, "__module__")):
                get_functions(attr, full_name, functions)
r0x0r commented 1 week ago

Having said that, there is still a bug in JS code loading logic that results in this bug. The root of the problem is that objects under window.pywebview are referenced, before they are created.

I will address this.

wall-git commented 1 week ago

Looking forward to your solution👍

r0x0r commented 1 day ago

Fixed in this PR https://github.com/r0x0r/pywebview/pull/1533 among other improvements