Repository: j178/leetgo (language: python)

Issue:
[Bug] Local testing for python doesnt take None type
### leetgo debug

NA

### Debug log

```shell
NA
```


### Description

![image](https://github.com/j178/leetgo/assets/27308928/d1ab8090-05ea-4ff2-8c1c-01f8ca4c4393)
I returned a None type and it doesnt parse through it in parse.py for ListNode type questions.

To replicate this, try to return None in merge-two-sorted-lists


Discussion / hints:

Fix patch:
diff --git a/lang/python.go b/lang/python.go
index 2b0abff7..b4e449fd 100644
--- a/lang/python.go
+++ b/lang/python.go
@@ -117,12 +117,10 @@ func toPythonType(typeName string) string {
 }
 
 func (p python) generateNormalTestCode(q *leetcode.QuestionData) (string, error) {
-	const template = `if __name__ == "__main__":
-%s
-	print("\n%s", serialize(ans))
-`
-	code := ""
+	code := "if __name__ == \"__main__\":\n"
+
 	paramNames := make([]string, 0, len(q.MetaData.Params))
+	paramTypes := make([]string, 0, len(q.MetaData.Params))
 	for _, param := range q.MetaData.Params {
 		varName := param.Name
 		varType := toPythonType(param.Type)
@@ -133,6 +131,7 @@ func (p python) generateNormalTestCode(q *leetcode.QuestionData) (string, error)
 			varType,
 		)
 		paramNames = append(paramNames, param.Name)
+		paramTypes = append(paramTypes, varType)
 	}
 	if q.MetaData.Return != nil && q.MetaData.Return.Type != "void" {
 		code += fmt.Sprintf(
@@ -140,6 +139,7 @@ func (p python) generateNormalTestCode(q *leetcode.QuestionData) (string, error)
 			q.MetaData.Name,
 			strings.Join(paramNames, ", "),
 		)
+		code += fmt.Sprintf("\tprint(\"\\n%s\", serialize(ans, \"%s\"))\n", testCaseOutputMark, q.MetaData.Return.Type)
 	} else {
 		code += fmt.Sprintf(
 			"\t%s(%s)\n",
@@ -149,16 +149,21 @@ func (p python) generateNormalTestCode(q *leetcode.QuestionData) (string, error)
 		if q.MetaData.Output != nil {
 			ansName := paramNames[q.MetaData.Output.ParamIndex]
 			code += fmt.Sprintf("\tans = %s\n", ansName)
+			code += fmt.Sprintf(
+				"\tprint(\"\\n%s\", serialize(ans, \"%s\"))\n",
+				testCaseOutputMark,
+				paramTypes[q.MetaData.Output.ParamIndex],
+			)
 		} else {
 			code += "\tans = None\n"
+			code += fmt.Sprintf("\tprint(\"\\n%s\", \"null\")\n", testCaseOutputMark)
 		}
 	}
 
-	testContent := fmt.Sprintf(template, code, testCaseOutputMark)
 	if q.MetaData.Manual {
-		testContent = fmt.Sprintf("# %s\n%s", manualWarning, testContent)
+		code = fmt.Sprintf("# %s\n%s", manualWarning, code)
 	}
-	return testContent, nil
+	return code, nil
 }
 
 func (p python) generateSystemDesignTestCode(q *leetcode.QuestionData) (string, error) {


Test patch:
diff --git a/lang/test.go b/lang/test.go
index 5222397f..25c5a837 100644
--- a/lang/test.go
+++ b/lang/test.go
@@ -87,6 +87,9 @@ func extractOutput(s string) (string, string) {
 	var output string
 	var others []string
 	for _, line := range utils.SplitLines(s) {
+		if strings.TrimSpace(line) == "" {
+			continue
+		}
 		if strings.HasPrefix(line, testCaseOutputMark) {
 			// If there are multiple output lines, only the last one is used.
 			output = strings.TrimSpace(line[len(testCaseOutputMark):])
@@ -194,7 +197,13 @@ func runTest(q *leetcode.QuestionData, genResult *GenerateResult, args []string,
 			cmd.Stderr = outputBuf
 			err = cmd.Start()
 			if err != nil {
-				l.AppendItem(fmt.Sprintf("Case %d:    %s", c.No, config.ErrorStyle.Render("Failed to start")))
+				l.AppendItem(
+					fmt.Sprintf(
+						"Case %d:    %s",
+						c.No,
+						config.ErrorStyle.Render("Failed to start:", err.Error()),
+					),
+				)
 				return
 			}
 			err = cmd.Wait()
diff --git a/testutils/python/pyproject.toml b/testutils/python/pyproject.toml
index cc05fcd1..ff127892 100644
--- a/testutils/python/pyproject.toml
+++ b/testutils/python/pyproject.toml
@@ -1,6 +1,6 @@
 [tool.poetry]
 name = "leetgo-py"
-version = "0.2.3"
+version = "0.2.4"
 description = "Python test utils for leetgo"
 authors = ["j178 <10510431+j178@users.noreply.github.com>"]
 license = "MIT"
diff --git a/testutils/python/src/leetgo_py/parse.py b/testutils/python/src/leetgo_py/parse.py
index 70f24d94..baa50022 100644
--- a/testutils/python/src/leetgo_py/parse.py
+++ b/testutils/python/src/leetgo_py/parse.py
@@ -14,8 +14,14 @@ def split_array(s: str) -> List[str]:
     return res
 
 
-def serialize(val: Any) -> str:
-    if isinstance(val, bool):
+def serialize(val: Any, ty: str = None) -> str:
+    if val is None:
+        if ty is None:
+            raise Exception("None value without type")
+        if ty == "ListNode" or ty == "TreeNode":
+            return "[]"
+        return "null"
+    elif isinstance(val, bool):
         return "true" if val else "false"
     elif isinstance(val, int):
         return str(val)