Repository: godotengine/godot-cpp
Issue: UnicodeDecodeError: 'gbk' codec can't decode byte 0xa2 in position 4094106: illegal multibyte sequence

### Godot version

4.1.beta2

### godot-cpp version

4.1.beta(be25a50617d89dd20688f76fcedd87ffd133dbd1)

### System information

windows 10 amd 2500u

### Issue description

Python:3.9.0 Scons:4.4.0
When compiling the latest version, there will be the following errors.
```
UnicodeDecodeError: 'gbk' codec can't decode byte 0xa2 in position 4094106: illegal multibyte sequence:
  File "D:\\Temp\\godot\\bug\\godot-cpp\\godot-cpp\\SConstruct", line 232:
    bindings = env.GenerateBindings(
  File "d:\\programlanguage\\python\\python39\\lib\\site-packages\\SCons\\Environment.py", line 439:
    return super().__call__(target, source, *args, **kw)
  File "d:\\programlanguage\\python\\python39\\lib\\site-packages\\SCons\\Util\\envs.py", line 242:
    return self.method(*nargs, **kwargs)
  File "d:\\programlanguage\\python\\python39\\lib\\site-packages\\SCons\\Builder.py", line 663:
    return self._execute(env, target, source, OverrideWarner(kw), ekw)
  File "d:\\programlanguage\\python\\python39\\lib\\site-packages\\SCons\\Builder.py", line 569:
    tlist, slist = self._create_nodes(env, target, source)
  File "d:\\programlanguage\\python\\python39\\lib\\site-packages\\SCons\\Builder.py", line 531:
    target, source = self.emitter(target=tlist, source=slist, env=env)
  File "D:\\Temp\\godot\\bug\\godot-cpp\\godot-cpp\\binding_generator.py", line 146:
    files = [env.File(f) for f in get_file_list(str(source[0]), target[0].abspath, True, True)]
  File "D:\\Temp\\godot\\bug\\godot-cpp\\godot-cpp\\binding_generator.py", line 79:
    api = json.load(api_file)
  File "d:\\programlanguage\\python\\python39\\lib\\json\\__init__.py", line 293:
    return loads(fp.read(),
```

When I used git bisect, I found that the error originated from this [commit](c669f0b78a1a046dd2f7c2589b27abd28ab13101).

Because the default value of push_list(https://github.com/godotengine/godot/pull/75017) has this symbol `Bullet 2022 •` , but gbk does not have it.

Run the python code `local.getdefaultlocale()`, it returns `'zh_CN', 'cp936'`, so open the file and read it in gbk encoding by default instead of utf8.

This method can override the default function.
```python
import _locale
_locale._getdefaultlocale = (lambda *args: ['en_US', 'UTF-8'])
```
Another way to fix the problem is by setting environment variables `set PYTHONUTF8=1`

The last one is to specify the encoding as utf-8 when opening the file
```python
def get_file_list(api_filepath, output_dir, headers=False, sources=False):
    api = {}
    files = []
    with open(api_filepath, encoding='utf-8') as api_file:
        api = json.load(api_file)
```



### Steps to reproduce

If your system's default encoding is not cp936, you can set it with the following code.
```python
import _locale
_locale._getdefaultlocale = (lambda *args: ['zh_CN', 'cp936'])
```
Then compile the code and you can see a similar error.

### Minimal reproduction project

N/A

Changed files:
binding_generator.py

diff --git a/binding_generator.py b/binding_generator.py
index 3a00049..6d356f0 100644
--- a/binding_generator.py
+++ b/binding_generator.py
@@ -66,14 +66,14 @@ def generate_wrappers(target):
 
     txt += "\\n#endif\\n"
 
-    with open(target, "w") as f:
+    with open(target, "w", encoding="utf-8") as f:
         f.write(txt)
 
 
 def get_file_list(api_filepath, output_dir, headers=False, sources=False):
     api = {}
     files = []
-    with open(api_filepath) as api_file:
+    with open(api_filepath, encoding="utf-8") as api_file:
         api = json.load(api_file)
 
     core_gen_folder = Path(output_dir) / "gen" / "include" / "godot_cpp" / "core"
@@ -163,7 +163,7 @@ def generate_bindings(api_filepath, use_template_get_node, bits="64", precision=
 
     target_dir = Path(output_dir) / "gen"
 
-    with open(api_filepath) as api_file:
+    with open(api_filepath, encoding="utf-8") as api_file:
         api = json.load(api_file)
 
     shutil.rmtree(target_dir, ignore_errors=True)
@@ -219,7 +219,7 @@ def generate_builtin_bindings(api, output_dir, build_config):
 
     # Create a file for Variant size, since that class isn't generated.
     variant_size_filename = include_gen_folder / "variant_size.hpp"
-    with variant_size_filename.open("+w") as variant_size_file:
+    with variant_size_filename.open("+w", encoding="utf-8") as variant_size_file:
         variant_size_source = []
         add_header("variant_size.hpp", variant_size_source)
 
@@ -295,15 +295,15 @@ def generate_builtin_bindings(api, output_dir, build_config):
         fully_used_classes = list(fully_used_classes)
         fully_used_classes.sort()
 
-        with header_filename.open("w+") as header_file:
+        with header_filename.open("w+", encoding="utf-8") as header_file:
             header_file.write(generate_builtin_class_header(builtin_api, size, used_classes, fully_used_classes))
 
-        with source_filename.open("w+") as source_file:
+        with source_filename.open("w+", encoding="utf-8") as source_file:
             source_file.write(generate_builtin_class_source(builtin_api, size, used_classes, fully_used_classes))
 
     # Create a header with all builtin types for convenience.
     builtin_header_filename = include_gen_folder / "builtin_types.hpp"
-    with builtin_header_filename.open("w+") as builtin_header_file:
+    with builtin_header_filename.open("w+", encoding="utf-8") as builtin_header_file:
         builtin_header = []
         add_header("builtin_types.hpp", builtin_header)
 
@@ -323,7 +323,7 @@ def generate_builtin_bindings(api, output_dir, build_config):
 
     # Create a header with bindings for builtin types.
     builtin_binds_filename = include_gen_folder / "builtin_binds.hpp"
-    with builtin_binds_filename.open("w+") as builtin_binds_file:
+    with builtin_binds_filename.open("w+", encoding="utf-8") as builtin_binds_file:
         builtin_binds = []
         add_header("builtin_binds.hpp", builtin_binds)
 
@@ -1149,18 +1149,18 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
         fully_used_classes = list(fully_used_classes)
         fully_used_classes.sort()
 
-        with header_filename.open("w+") as header_file:
+        with header_filename.open("w+", encoding="utf-8") as header_file:
             header_file.write(
                 generate_engine_class_header(class_api, used_classes, fully_used_classes, use_template_get_node)
             )
 
-        with source_filename.open("w+") as source_file:
+        with source_filename.open("w+", encoding="utf-8") as source_file:
             source_file.write(
                 generate_engine_class_source(class_api, used_classes, fully_used_classes, use_template_get_node)
             )
 
     register_engine_classes_filename = Path(output_dir) / "src" / "register_engine_classes.cpp"
-    with register_engine_classes_filename.open("w+") as source_file:
+    with register_engine_classes_filename.open("w+", encoding="utf-8") as source_file:
         source_file.write(generate_register_engine_classes_source(api))
 
     for native_struct in api["native_structures"]:
@@ -1208,7 +1208,7 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
         result.append("")
         result.append(f"#endif // ! {header_guard}")
 
-        with header_filename.open("w+") as header_file:
+        with header_filename.open("w+", encoding="utf-8") as header_file:
             header_file.write("\\n".join(result))
 
 
@@ -1648,7 +1648,7 @@ def generate_global_constants(api, output_dir):
     header.append("")
     header.append(f"#endif // ! {header_guard}")
 
-    with header_filename.open("w+") as header_file:
+    with header_filename.open("w+", encoding="utf-8") as header_file:
         header_file.write("\\n".join(header))
 
 
@@ -1689,7 +1689,7 @@ def generate_global_constant_binds(api, output_dir):
 
     header.append(f"#endif // ! {header_guard}")
 
-    with header_filename.open("w+") as header_file:
+    with header_filename.open("w+", encoding="utf-8") as header_file:
         header_file.write("\\n".join(header))
 
 
@@ -1738,7 +1738,7 @@ def generate_utility_functions(api, output_dir):
     header.append("")
     header.append(f"#endif // ! {header_guard}")
 
-    with header_filename.open("w+") as header_file:
+    with header_filename.open("w+", encoding="utf-8") as header_file:
         header_file.write("\\n".join(header))
 
     # Generate source.
@@ -1816,7 +1816,7 @@ def generate_utility_functions(api, output_dir):
 
     source.append("} // namespace godot")
 
-    with source_filename.open("w+") as source_file:
+    with source_filename.open("w+", encoding="utf-8") as source_file:
         source_file.write("\\n".join(source))