From 261e258ed45d476ccea8010fe71f5ddbcd5726e2 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 10 Aug 2023 09:23:02 -0300 Subject: [PATCH 1/3] =?UTF-8?q?=F0=9F=90=9B=20fix(loading.py):=20make=20a?= =?UTF-8?q?=20copy=20of=20the=20params=20before=20modifying=20it=20to=20pr?= =?UTF-8?q?event=20unintended=20side=20effects?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/interface/initialize/loading.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/backend/langflow/interface/initialize/loading.py b/src/backend/langflow/interface/initialize/loading.py index e72e5091b0..dc8188ea5c 100644 --- a/src/backend/langflow/interface/initialize/loading.py +++ b/src/backend/langflow/interface/initialize/loading.py @@ -116,9 +116,12 @@ def instantiate_based_on_type(class_object, base_type, node_type, params): def instantiate_custom_component(node_type, class_object, params): - class_object = get_function_custom(params.pop("code")) + # we need to make a copy of the params because we will be + # modifying it + params_copy = params.copy() + class_object = get_function_custom(params_copy.pop("code")) custom_component = class_object() - built_object = custom_component.build(**params) + built_object = custom_component.build(**params_copy) return built_object, {"repr": custom_component.custom_repr()} From 564634d36c21bb0da54f1fe13215dc43e8d1f0fd Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 10 Aug 2023 09:23:36 -0300 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=90=9B=20fix(directory=5Freader.py):?= =?UTF-8?q?=20handle=20SyntaxError=20when=20parsing=20code=20to=20prevent?= =?UTF-8?q?=20crashes=20=F0=9F=90=9B=20fix(directory=5Freader.py):=20retur?= =?UTF-8?q?n=20False=20if=20code=20is=20not=20valid=20Python=20to=20preven?= =?UTF-8?q?t=20false=20positives=20=F0=9F=90=9B=20fix(directory=5Freader.p?= =?UTF-8?q?y):=20fix=20method=20name=20from=20is=5Ftype=5Fhint=5Fused=5Fbu?= =?UTF-8?q?t=5Fnot=5Fimported=20to=20=5Fis=5Ftype=5Fhint=5Fused=5Fin=5Farg?= =?UTF-8?q?s=20for=20consistency=20=F0=9F=90=9B=20fix(directory=5Freader.p?= =?UTF-8?q?y):=20fix=20method=20name=20from=20is=5Ftype=5Fhint=5Fimported?= =?UTF-8?q?=20to=20=5Fis=5Ftype=5Fhint=5Fimported=20for=20consistency=20?= =?UTF-8?q?=F0=9F=90=9B=20fix(directory=5Freader.py):=20fix=20return=20val?= =?UTF-8?q?ue=20of=20=5Fis=5Ftype=5Fhint=5Fused=5Fin=5Fargs=20method=20to?= =?UTF-8?q?=20return=20False=20if=20type=20hint=20is=20used=20but=20not=20?= =?UTF-8?q?imported?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../interface/custom/directory_reader.py | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/backend/langflow/interface/custom/directory_reader.py b/src/backend/langflow/interface/custom/directory_reader.py index 57bb3ca959..7bff7b5f52 100644 --- a/src/backend/langflow/interface/custom/directory_reader.py +++ b/src/backend/langflow/interface/custom/directory_reader.py @@ -152,15 +152,19 @@ class DirectoryReader: Check if a specific type hint is used in the function definitions within the given code. """ - module = ast.parse(code) + try: + module = ast.parse(code) - for node in ast.walk(module): - if isinstance(node, ast.FunctionDef): - for arg in node.args.args: - if self._is_type_hint_in_arg_annotation( - arg.annotation, type_hint_name - ): - return True + for node in ast.walk(module): + if isinstance(node, ast.FunctionDef): + for arg in node.args.args: + if self._is_type_hint_in_arg_annotation( + arg.annotation, type_hint_name + ): + return True + except SyntaxError: + # Returns False if the code is not valid Python + return False return False def _is_type_hint_in_arg_annotation(self, annotation, type_hint_name: str) -> bool: @@ -204,8 +208,13 @@ class DirectoryReader: return False, "Syntax error" elif not self.validate_build(file_content): return False, "Missing build function" - elif self.is_type_hint_used_but_not_imported("Optional", file_content): - return False, "Type hint 'Optional' is used but not imported in the code." + elif self._is_type_hint_used_in_args( + "Optional", file_content + ) and not self._is_type_hint_imported("Optional", file_content): + return ( + False, + "Type hint 'Optional' is used but not imported in the code.", + ) else: if self.compress_code_field: file_content = str(StringCompressor(file_content).compress_string()) From df77ba81f7aac282c91f1acda65c69988884a451 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 10 Aug 2023 09:24:10 -0300 Subject: [PATCH 3/3] =?UTF-8?q?=F0=9F=90=9B=20fix(custom=5Fcomponent.py):?= =?UTF-8?q?=20fix=20condition=20to=20check=20if=20Optional=20type=20hint?= =?UTF-8?q?=20is=20used=20but=20not=20imported=20in=20the=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/interface/custom/custom_component.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/backend/langflow/interface/custom/custom_component.py b/src/backend/langflow/interface/custom/custom_component.py index c1de48a98f..74d06215f8 100644 --- a/src/backend/langflow/interface/custom/custom_component.py +++ b/src/backend/langflow/interface/custom/custom_component.py @@ -49,7 +49,9 @@ class CustomComponent(Component, extra=Extra.allow): reader = DirectoryReader("", False) for type_hint in TYPE_HINT_LIST: - if reader.is_type_hint_used_but_not_imported(type_hint, code): + if reader._is_type_hint_used_in_args( + "Optional", code + ) and not reader._is_type_hint_imported("Optional", code): error_detail = { "error": "Type hint Error", "traceback": f"Type hint '{type_hint}' is used but not imported in the code.",