Mass replace godot to pandemonium pt3.

This commit is contained in:
Relintai 2023-06-02 11:31:19 +02:00
parent 9b4c18e994
commit e8bff7346e
38 changed files with 114 additions and 117 deletions

View File

@ -149,7 +149,7 @@ jobs:
else else
curl https://downloads.fdossena.com/Projects/Mesa3D/Builds/MesaForWindows-20.0.7.7z -o mesa.7z curl https://downloads.fdossena.com/Projects/Mesa3D/Builds/MesaForWindows-20.0.7.7z -o mesa.7z
fi fi
# opengl32.dll must be extracted in the same directory than Godot binary # opengl32.dll must be extracted in the same directory than Pandemonium binary
7z.exe x mesa.7z 7z.exe x mesa.7z
ls -lh opengl32.dll # Sanity check ls -lh opengl32.dll # Sanity check
popd popd

4
.gitignore vendored
View File

@ -14,11 +14,11 @@ pandemonium_headers/
# mac os thumbs files # mac os thumbs files
.DS_Store .DS_Store
# Godot import folders # Pandemonium import folders
.import .import
.cache .cache
# Godot runtime logs # Pandemonium runtime logs
logs logs
# Scons build artefact # Scons build artefact

View File

@ -28,11 +28,11 @@ example:
@exposed @exposed
class Player(Node2D): class Player(Node2D):
""" """
This is the file's main class which will be made available to Godot. This This is the file's main class which will be made available to Pandemonium. This
class must inherit from `godot.Node` or any of its children (e.g. class must inherit from `godot.Node` or any of its children (e.g.
`godot.KinematicBody`). `godot.KinematicBody`).
Because Godot scripts only accept file paths, you can't have two `exposed` classes in the same file. Because Pandemonium scripts only accept file paths, you can't have two `exposed` classes in the same file.
""" """
# Exposed class can define some attributes as export(<type>) to achieve # Exposed class can define some attributes as export(<type>) to achieve
# similar goal than GDSscript's `export` keyword # similar goal than GDSscript's `export` keyword
@ -48,12 +48,12 @@ example:
def age(self, value): def age(self, value):
self._age = value self._age = value
# All methods are exposed to Godot # All methods are exposed to Pandemonium
def talk(self, msg): def talk(self, msg):
print(f"I'm saying {msg}") print(f"I'm saying {msg}")
def _ready(self): def _ready(self):
# Don't confuse `__init__` with Godot's `_ready`! # Don't confuse `__init__` with Pandemonium's `_ready`!
self.weapon = WEAPON_RES.instance() self.weapon = WEAPON_RES.instance()
self._age = 42 self._age = 42
# Of course you can access property & methods defined in the parent # Of course you can access property & methods defined in the parent
@ -80,10 +80,10 @@ Building
To build the project from source, first checkout the repo or download the To build the project from source, first checkout the repo or download the
latest tarball. latest tarball.
Godot-Python requires Python >= 3.7 and a C compiler. GDNative Python requires Python >= 3.7 and a C compiler.
Godot GDNative header Pandemonium GDNative header
--------------------- ---------------------
TODO (need to be copied from the gdnative module) TODO (need to be copied from the gdnative module)

View File

@ -21,7 +21,7 @@ def pandemonium_binary_converter(val, env):
file = File(val) file = File(val)
if file.exists(): if file.exists():
# Note here `env["pandemonium_binary_download_version"]` is not defined, this is ok given # Note here `env["pandemonium_binary_download_version"]` is not defined, this is ok given
# this variable shouldn't be needed if Godot doesn't have to be downloaded # this variable shouldn't be needed if Pandemonium doesn't have to be downloaded
return file return file
# Provided value is version information with format <major>.<minor>.<patch>[-<extra>] # Provided value is version information with format <major>.<minor>.<patch>[-<extra>]
match = re.match(r"^([0-9]+)\.([0-9]+)\.([0-9]+)(?:-(\w+))?$", val) match = re.match(r"^([0-9]+)\.([0-9]+)\.([0-9]+)(?:-(\w+))?$", val)
@ -29,7 +29,7 @@ def pandemonium_binary_converter(val, env):
major, minor, patch, extra = match.groups() major, minor, patch, extra = match.groups()
else: else:
raise UserError( raise UserError(
f"`{val}` is neither an existing file nor a valid <major>.<minor>.<patch>[-<extra>] Godot version format" f"`{val}` is neither an existing file nor a valid <major>.<minor>.<patch>[-<extra>] Pandemonium version format"
) )
env["pandemonium_binary_download_version"] = (major, minor, patch, extra or "stable") env["pandemonium_binary_download_version"] = (major, minor, patch, extra or "stable")
# `pandemonium_binary` is set to None to indicate it should be downloaded # `pandemonium_binary` is set to None to indicate it should be downloaded
@ -52,11 +52,11 @@ vars.Add(
vars.Add("release_suffix", "Suffix to add to the release archive", extract_version()) vars.Add("release_suffix", "Suffix to add to the release archive", extract_version())
vars.Add( vars.Add(
"pandemonium_binary", "pandemonium_binary",
"Path to Godot binary or version of Godot to use", "Path to Pandemonium binary or version of Pandemonium to use",
default="3.2.2", default="3.2.2",
converter=pandemonium_binary_converter, converter=pandemonium_binary_converter,
) )
vars.Add("pandemonium_headers", "Path to Godot GDnative headers", "") vars.Add("pandemonium_headers", "Path to Pandemonium GDnative headers", "")
vars.Add("debugger", "Run test with a debugger", "") vars.Add("debugger", "Run test with a debugger", "")
vars.Add(BoolVariable("debug", "Compile with debug symbols", False)) vars.Add(BoolVariable("debug", "Compile with debug symbols", False))
vars.Add(BoolVariable("headless", "Run tests in headless mode", False)) vars.Add(BoolVariable("headless", "Run tests in headless mode", False))

View File

@ -5,7 +5,7 @@ from collections import deque
from threading import Thread, Lock, Event from threading import Thread, Lock, Event
from queue import SimpleQueue from queue import SimpleQueue
from _pandemonium import StdoutStderrCaptureToGodot, StdinCapture from _pandemonium import StdoutStderrCaptureToPandemonium, StdinCapture
from pandemonium import exposed, export, ResourceLoader, VBoxContainer from pandemonium import exposed, export, ResourceLoader, VBoxContainer
from .plugin import BASE_RES from .plugin import BASE_RES
@ -14,7 +14,7 @@ from .plugin import BASE_RES
FONT = ResourceLoader.load(f"{BASE_RES}/hack_regular.tres") FONT = ResourceLoader.load(f"{BASE_RES}/hack_regular.tres")
class StdoutStderrCaptureToBufferAndPassthrough(StdoutStderrCaptureToGodot): class StdoutStderrCaptureToBufferAndPassthrough(StdoutStderrCaptureToPandemonium):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self._buffer = "" self._buffer = ""

View File

@ -12,9 +12,9 @@ outside the interpretor) through numerous ways:
- ... - ...
However those functions are no longer relevant when python is embedded However those functions are no longer relevant when python is embedded
into Godot. They can even be dangerous when opening a Godot application to into Pandemonium. They can even be dangerous when opening a Pandemonium application to
modding given a 3rd party python code has suddently full access to the computer ! modding given a 3rd party python code has suddently full access to the computer !
Hence, those functions needs to be adapted to Godot: Hence, those functions needs to be adapted to Pandemonium:
- ``ctype``, ``ffi`` and ``open`` disabled - ``ctype``, ``ffi`` and ``open`` disabled
- ``stdout``, ``stderr`` and ``stdin`` redirected to Godot editor's console - ``stdout``, ``stderr`` and ``stdin`` redirected to Pandemonium editor's console

View File

@ -5,7 +5,7 @@ Object conversion model
Base object types Base object types
----------------- -----------------
Godot Variant Pandemonium Variant
- standalone: bool, int, real - standalone: bool, int, real
- pointer to builtin type (e.g. ``Matrix32``, ``AABB``, etc.) - pointer to builtin type (e.g. ``Matrix32``, ``AABB``, etc.)
- pointer to generic ``Object`` - pointer to generic ``Object``
@ -19,11 +19,11 @@ Python mp_obj_t
needed on themselves. needed on themselves.
Naming conventions: Naming conventions:
- GST: Godot STandalone - GST: Pandemonium STandalone
- GPB: Godot Pointer Builtin - GPB: Pandemonium Pointer Builtin
- GPO: Godot Pointer Object - GPO: Pandemonium Pointer Object
- PST: Python STandalone - PST: Python STandalone
- PPB: Python Pointer Binding (proxy to Godot data) - PPB: Python Pointer Binding (proxy to Pandemonium data)
- PPE: Python Pointer Exposed (defined with `@exposed` decorator) - PPE: Python Pointer Exposed (defined with `@exposed` decorator)
- PPI: Python Pointer Internal - PPI: Python Pointer Internal
@ -51,24 +51,24 @@ Standalone doesn't need garbage collection and doesn't hold reference on
other objects. Hence conversion is trivial. other objects. Hence conversion is trivial.
Conversion Godot -> Python Conversion Pandemonium -> Python
-------------------------- --------------------------
Each GPB has a corresponding PPB, acting like a proxy from within the Each GPB has a corresponding PPB, acting like a proxy from within the
Python interpreter. Python interpreter.
GPO binding is done dynamically with the ``DynamicBinder`` using Godot GPO binding is done dynamically with the ``DynamicBinder`` using Pandemonium
introspection (i.e. ``ObjectTypeDB``). introspection (i.e. ``ObjectTypeDB``).
It is possible in the future that to create static proxy for core GPO and rely It is possible in the future that to create static proxy for core GPO and rely
on dynamic method as a fall-back for unknown classes (i.g. added by 3rd party). on dynamic method as a fall-back for unknown classes (i.g. added by 3rd party).
Conversion Python -> Godot Conversion Python -> Pandemonium
-------------------------- --------------------------
PPB -> GPB described earlier. PPB -> GPB described earlier.
PPI objects cannot be converted back to Godot. PPI objects cannot be converted back to Pandemonium.
PPE instance are exposed as ``PyInstance`` (class exposed as ``PyScript``). PPE instance are exposed as ``PyInstance`` (class exposed as ``PyScript``).

View File

@ -9,7 +9,7 @@ from pandemonium.builtins cimport *
from enum import IntFlag from enum import IntFlag
__ERR_MSG_BINDING_NOT_AVAILABLE = "No Godot binding available" __ERR_MSG_BINDING_NOT_AVAILABLE = "No Pandemonium binding available"
class Error(IntFlag): class Error(IntFlag):
@ -138,11 +138,11 @@ class VariantOperator(IntFlag):
### Class&singletons needed for Pythonscript bootstrap ### ### Class&singletons needed for Pythonscript bootstrap ###
# Godot classes&singletons are not all available when loading Pythonscript. # Pandemonium classes&singletons are not all available when loading Pythonscript.
# Hence greedy loading is done only for items needed for Pythonscript # Hence greedy loading is done only for items needed for Pythonscript
# bootstrap. # bootstrap.
# The remaining loading will be achieved when loading the first python script # The remaining loading will be achieved when loading the first python script
# (where at this point Godot should have finished it initialization). # (where at this point Pandemonium should have finished it initialization).
{% set early_needed_bindings = ["_OS", "_ProjectSettings"] %} {% set early_needed_bindings = ["_OS", "_ProjectSettings"] %}
cdef pandemonium_object *_ptr cdef pandemonium_object *_ptr

View File

@ -40,7 +40,7 @@ cdef class {{ cls.name }}({{ cls.base_class }}):
def __init__(self): def __init__(self):
raise RuntimeError( raise RuntimeError(
f"Use `new()` method to instantiate non-refcounted Godot object (and don't forget to free it !)" f"Use `new()` method to instantiate non-refcounted Pandemonium object (and don't forget to free it !)"
) )
def __repr__(self): def __repr__(self):
@ -101,7 +101,7 @@ cdef class {{ cls.name }}({{ cls.base_class }}):
# return partial(self.call, gdname) # return partial(self.call, gdname)
elif any(x for x in self.get_property_list() if x[gdnamefield] == gdname): elif any(x for x in self.get_property_list() if x[gdnamefield] == gdname):
# TODO: Godot currently lacks a `has_property` method # TODO: Pandemonium currently lacks a `has_property` method
return self.get(gdname) return self.get(gdname)
raise AttributeError( raise AttributeError(
@ -116,11 +116,11 @@ cdef class {{ cls.name }}({{ cls.base_class }}):
PyObject_GenericSetAttr(self, name, value) PyObject_GenericSetAttr(self, name, value)
return return
# Could retrieve the item inside the Godot class, try to look into # Could retrieve the item inside the Pandemonium class, try to look into
# the attached script if it has one # the attached script if it has one
else: else:
if any(x for x in self.get_property_list() if x[gdnamefield] == gdname): if any(x for x in self.get_property_list() if x[gdnamefield] == gdname):
# TODO: Godot currently lacks a `has_property` method # TODO: Pandemonium currently lacks a `has_property` method
self.set(name, value) self.set(name, value)
return return
@ -169,7 +169,7 @@ cdef class {{ cls.name }}({{ cls.base_class }}):
{% if cls.name == "Reference" %} {% if cls.name == "Reference" %}
@classmethod @classmethod
def new(cls): def new(cls):
raise RuntimeError(f"Refcounted Godot object must be created with `{ cls.__name__ }()`") raise RuntimeError(f"Refcounted Pandemonium object must be created with `{ cls.__name__ }()`")
def __dealloc__(self): def __dealloc__(self):
cdef pandemonium_bool __ret cdef pandemonium_bool __ret

View File

@ -108,7 +108,7 @@ with nogil:
{% set retval_as_arg = "NULL" %} {% set retval_as_arg = "NULL" %}
{% elif method.return_type.is_object %} {% elif method.return_type.is_object %}
# It's important to initialize this pointer to null given # It's important to initialize this pointer to null given
# in case of Reference, Godot will try to decrease the # in case of Reference, Pandemonium will try to decrease the
# refcount if the pointer is valid ! # refcount if the pointer is valid !
# (see https://github.com/pandemoniumengine/pandemonium/issues/35609) # (see https://github.com/pandemoniumengine/pandemonium/issues/35609)
cdef pandemonium_object *{{ retval }} = NULL cdef pandemonium_object *{{ retval }} = NULL

View File

@ -79,7 +79,7 @@ cdef class Dictionary:
{{ force_mark_rendered("pandemonium_dictionary_operator_index") }} {{ force_mark_rendered("pandemonium_dictionary_operator_index") }}
cdef pandemonium_variant var_key cdef pandemonium_variant var_key
if not pyobj_to_pandemonium_variant(key, &var_key): if not pyobj_to_pandemonium_variant(key, &var_key):
raise TypeError(f"Cannot convert `{key!r}` to Godot Variant") raise TypeError(f"Cannot convert `{key!r}` to Pandemonium Variant")
cdef pandemonium_variant *p_var_ret = gdapi10.pandemonium_dictionary_operator_index(&self._gd_data, &var_key) cdef pandemonium_variant *p_var_ret = gdapi10.pandemonium_dictionary_operator_index(&self._gd_data, &var_key)
gdapi10.pandemonium_variant_destroy(&var_key) gdapi10.pandemonium_variant_destroy(&var_key)
if p_var_ret == NULL: if p_var_ret == NULL:
@ -93,7 +93,7 @@ cdef class Dictionary:
{{ force_mark_rendered("pandemonium_dictionary_erase_with_return") }} {{ force_mark_rendered("pandemonium_dictionary_erase_with_return") }}
cdef pandemonium_variant var_key cdef pandemonium_variant var_key
if not pyobj_to_pandemonium_variant(key, &var_key): if not pyobj_to_pandemonium_variant(key, &var_key):
raise TypeError(f"Cannot convert `{key!r}` to Godot Variant") raise TypeError(f"Cannot convert `{key!r}` to Pandemonium Variant")
cdef pandemonium_bool ret = gdapi11.pandemonium_dictionary_erase_with_return(&self._gd_data, &var_key) cdef pandemonium_bool ret = gdapi11.pandemonium_dictionary_erase_with_return(&self._gd_data, &var_key)
gdapi10.pandemonium_variant_destroy(&var_key) gdapi10.pandemonium_variant_destroy(&var_key)
if not ret: if not ret:

View File

@ -8,7 +8,7 @@ from libc.stdint cimport int8_t
{{ force_mark_rendered("pandemonium_char_string_destroy") }} {{ force_mark_rendered("pandemonium_char_string_destroy") }}
{{ force_mark_rendered("pandemonium_char_string_get_data") }} {{ force_mark_rendered("pandemonium_char_string_get_data") }}
{{ force_mark_rendered("pandemonium_char_string_length") }} {{ force_mark_rendered("pandemonium_char_string_length") }}
{# Those methods are present in gdnative_api.json but not in the Godot documentation... #} {# Those methods are present in gdnative_api.json but not in the Pandemonium documentation... #}
{{ force_mark_rendered("pandemonium_string_ascii") }} {{ force_mark_rendered("pandemonium_string_ascii") }}
{{ force_mark_rendered("pandemonium_string_ascii_extended") }} {{ force_mark_rendered("pandemonium_string_ascii_extended") }}
{{ force_mark_rendered("pandemonium_string_begins_with_char_array") }} {{ force_mark_rendered("pandemonium_string_begins_with_char_array") }}

View File

@ -27,7 +27,7 @@ def {{ py_name or spec.py_name }}({{ spec.klass.cy_type }} self{%- if args_witho
gdapi10.pandemonium_variant_destroy(&__var_{{ initialized_arg.name }}) gdapi10.pandemonium_variant_destroy(&__var_{{ initialized_arg.name }})
{% endif %} {% endif %}
{% endfor %} {% endfor %}
raise TypeError(f"Cannot convert `{ {{ arg.name}} !r}` to Godot Variant") raise TypeError(f"Cannot convert `{ {{ arg.name}} !r}` to Pandemonium Variant")
{% endif %} {% endif %}
{% endfor %} {% endfor %}
{% if spec.return_type.is_variant %} {% if spec.return_type.is_variant %}

View File

@ -592,7 +592,7 @@ if __name__ == "__main__":
required=True, required=True,
metavar="API_PATH", metavar="API_PATH",
type=argparse.FileType("r", encoding="utf8"), type=argparse.FileType("r", encoding="utf8"),
help="Path to Godot api.json file", help="Path to Pandemonium api.json file",
) )
parser.add_argument( parser.add_argument(
"--output", "--output",

View File

@ -380,7 +380,7 @@ if __name__ == "__main__":
required=True, required=True,
metavar="GDNATIVE_API_PATH", metavar="GDNATIVE_API_PATH",
type=argparse.FileType("r", encoding="utf8"), type=argparse.FileType("r", encoding="utf8"),
help="Path to Godot gdnative_api.json file", help="Path to Pandemonium gdnative_api.json file",
) )
parser.add_argument( parser.add_argument(
"--output", "--output",

View File

@ -1,23 +1,23 @@
# Describe all base types (i.e. scalar such as int and Godot builtins) # Describe all base types (i.e. scalar such as int and Pandemonium builtins)
from dataclasses import dataclass from dataclasses import dataclass
@dataclass @dataclass
class TypeSpec: class TypeSpec:
# Type used within Godot api.json # Type used within Pandemonium api.json
gdapi_type: str gdapi_type: str
# Type used when calling C api functions # Type used when calling C api functions
c_type: str c_type: str
# Type used in Cython, basically similar to c_type for scalars&enums # Type used in Cython, basically similar to c_type for scalars&enums
# and to py_type for Godot objects&builtins # and to py_type for Pandemonium objects&builtins
cy_type: str cy_type: str
# TODO: typing should be divided between argument and return (e.g. `Union[str, NodePath]` vs `NodePath`) # TODO: typing should be divided between argument and return (e.g. `Union[str, NodePath]` vs `NodePath`)
# Type used for PEP 484 Python typing # Type used for PEP 484 Python typing
py_type: str = "" py_type: str = ""
# Type is a Godot object (i.e. defined in api.json) # Type is a Pandemonium object (i.e. defined in api.json)
is_object: bool = False is_object: bool = False
# Type is a Godot builtin (e.g. Vector2) # Type is a Pandemonium builtin (e.g. Vector2)
is_builtin: bool = False is_builtin: bool = False
# Type is a scalar (e.g. int, float) or void # Type is a scalar (e.g. int, float) or void
is_base_type: bool = False is_base_type: bool = False

View File

@ -2,7 +2,9 @@
| Godot Python | | Godot Python |
+---------------------------------------------------------------------------+ +---------------------------------------------------------------------------+
Copyright (c) 2016 by Emmanuel Leblond. Copyright (c) 2023-present Péter Magyar.
Copyright (c) 2016-2023 by Emmanuel Leblond.
MIT License MIT License
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
@ -23,11 +25,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
Godot Python Logo (C) Pinswell
Distributed under the terms of the Creative Commons Attribution License
version 3.0 (CC-BY 3.0)
https://creativecommons.org/licenses/by/3.0/legalcode.
+---------------------------------------------------------------------------+ +---------------------------------------------------------------------------+
| CPython | | CPython |

View File

@ -10,7 +10,7 @@
Introduction Introduction
------------ ------------
This is a beta version of the Python module for Godot. This is a beta version of the Python module for Pandemonium.
You are likely to encounter bugs and catastrophic crashes, if so please You are likely to encounter bugs and catastrophic crashes, if so please
report them to https://github.com/Relintai/gdnative_python. report them to https://github.com/Relintai/gdnative_python.
@ -19,7 +19,7 @@ report them to https://github.com/Relintai/gdnative_python.
Working features Working features
---------------- ----------------
Every Godot core features are expected to work fine: Every Pandemonium core features are expected to work fine:
- builtins (e.g. Vector2) - builtins (e.g. Vector2)
- Objects classes (e.g. Node) - Objects classes (e.g. Node)
- signals - signals

View File

@ -13,15 +13,15 @@ Import("env")
def resolve_pandemonium_download_url(major, minor, patch, extra, platform): def resolve_pandemonium_download_url(major, minor, patch, extra, platform):
#version = f"{major}.{minor}.{patch}" if patch != 0 else f"{major}.{minor}" #version = f"{major}.{minor}.{patch}" if patch != 0 else f"{major}.{minor}"
#if extra == "stable": #if extra == "stable":
# return f"https://downloads.tuxfamily.org/godotengine/{version}/Godot_v{version}-{extra}_{platform}.zip" # return f"https://downloads.tuxfamily.org/godotengine/{version}/Pandemonium_v{version}-{extra}_{platform}.zip"
#else: #else:
# return f"https://downloads.tuxfamily.org/godotengine/{version}/{extra}/Godot_v{version}-{extra}_{platform}.zip" # return f"https://downloads.tuxfamily.org/godotengine/{version}/{extra}/Pandemonium_v{version}-{extra}_{platform}.zip"
returnf "" returnf ""
def resolve_pandemonium_binary_name(major, minor, patch, extra, platform): def resolve_pandemonium_binary_name(major, minor, patch, extra, platform):
version = f"{major}.{minor}.{patch}" if patch != 0 else f"{major}.{minor}" version = f"{major}.{minor}.{patch}" if patch != 0 else f"{major}.{minor}"
return f"Godot_v{version}-{extra}_{platform}" return f"Pandemonium_v{version}-{extra}_{platform}"
SConscript([f"{env['platform']}/SConscript"]) SConscript([f"{env['platform']}/SConscript"])
@ -74,7 +74,7 @@ env.AddMethod(install, "Install")
env.AddMethod(install_as, "InstallAs") env.AddMethod(install_as, "InstallAs")
### Godot binary (to run tests) ### ### Pandemonium binary (to run tests) ###
if not env["pandemonium_binary"]: if not env["pandemonium_binary"]:

View File

@ -14,7 +14,7 @@ cpython_build = Dir("cpython_build")
env["bits"] = "64" env["bits"] = "64"
env["pandemonium_binary_download_platform"] = "osx.64" env["pandemonium_binary_download_platform"] = "osx.64"
env["pandemonium_binary_download_zip_path"] = "Godot.app/Contents/MacOS/Godot" env["pandemonium_binary_download_zip_path"] = "Pandemonium.app/Contents/MacOS/Pandemonium"
env["cpython_build"] = cpython_build env["cpython_build"] = cpython_build
env["cpython_build_dir"] = cpython_build env["cpython_build_dir"] = cpython_build
env["DIST_SITE_PACKAGES"] = Dir(f"{env['DIST_PLATFORM']}/lib/python3.8/site-packages") env["DIST_SITE_PACKAGES"] = Dir(f"{env['DIST_PLATFORM']}/lib/python3.8/site-packages")

View File

@ -1,5 +1,5 @@
# `_pandemoniummonium` module contains all the callbacks needed by Godot's Pluginscript # `_pandemoniummonium` module contains all the callbacks needed by Pandemonium's Pluginscript
# system to expose Python as a language to Godot (see pythonscript.c for # system to expose Python as a language to Pandemonium (see pythonscript.c for
# more on this). # more on this).
# Hence there is no point of importing this module from Python given it # Hence there is no point of importing this module from Python given it
# only expose C functions. # only expose C functions.
@ -45,10 +45,10 @@ cdef api pandemonium_pluginscript_language_data *pythonscript_init() with gil:
p = ProjectSettings.globalize_path(GDString(p)) p = ProjectSettings.globalize_path(GDString(p))
sys.path.insert(0, str(p)) sys.path.insert(0, str(p))
# Redirect stdout/stderr to have it in the Godot editor console # Redirect stdout/stderr to have it in the Pandemonium editor console
if _setup_config_entry("python_script/io_streams_capture", True): if _setup_config_entry("python_script/io_streams_capture", True):
# Note we don't have to remove the stream capture in `pythonscript_finish` given # Note we don't have to remove the stream capture in `pythonscript_finish` given
# Godot print API is available until after the Python interpreter is teardown # Pandemonium print API is available until after the Python interpreter is teardown
install_io_streams_capture() install_io_streams_capture()
# Enable verbose output from pythonscript framework # Enable verbose output from pythonscript framework

View File

@ -149,7 +149,7 @@ cdef api void pythonscript_add_global_constant(
const pandemonium_string *p_variable, const pandemonium_string *p_variable,
const pandemonium_variant *p_value const pandemonium_variant *p_value
) with gil: ) with gil:
# However, Godot add global constants very early (first as an empty variant # However, Pandemonium add global constants very early (first as an empty variant
# placeholder before any script is loaded, then as a proper loaded script). # placeholder before any script is loaded, then as a proper loaded script).
# So it's possible this function get called before `pythonscript_script_init` # So it's possible this function get called before `pythonscript_script_init`
# (which is supposed to do the lazy `_initialize_bindings`). # (which is supposed to do the lazy `_initialize_bindings`).

View File

@ -51,7 +51,7 @@ cdef api pandemonium_bool pythonscript_instance_set_prop(
cdef str key = pandemonium_string_to_pyobj(p_name) cdef str key = pandemonium_string_to_pyobj(p_name)
# Should look among properties added by the script and it parents, # Should look among properties added by the script and it parents,
# not Godot native properties that are handled by the caller # not Pandemonium native properties that are handled by the caller
try: try:
field = instance.__exported[key] field = instance.__exported[key]
except KeyError: except KeyError:
@ -78,7 +78,7 @@ cdef api pandemonium_bool pythonscript_instance_get_prop(
cdef str key = pandemonium_string_to_pyobj(p_name) cdef str key = pandemonium_string_to_pyobj(p_name)
# Should look among properties added by the script and it parents, # Should look among properties added by the script and it parents,
# not Godot native properties that are handled by the caller # not Pandemonium native properties that are handled by the caller
try: try:
field = instance.__exported[key] field = instance.__exported[key]
except KeyError: except KeyError:
@ -155,7 +155,7 @@ cdef api void pythonscript_instance_notification(
int p_notification int p_notification
) with gil: ) with gil:
cdef object instance = <object>p_data cdef object instance = <object>p_data
# Godot's notification should call all parent `_notification` # Pandemonium's notification should call all parent `_notification`
# methods (better not use `super()._notification` in those methods...) # methods (better not use `super()._notification` in those methods...)
# TODO: cache the methods to call ? # TODO: cache the methods to call ?
for parentcls in instance.__class__.__mro__: for parentcls in instance.__class__.__mro__:

View File

@ -88,7 +88,7 @@ class StdoutStderrCapture(TextIOBase):
self._enabled = False self._enabled = False
class StdoutStderrCaptureToGodot(StdoutStderrCapture): class StdoutStderrCaptureToPandemonium(StdoutStderrCapture):
def __init__(self): def __init__(self):
self.buffer = "" self.buffer = ""
@ -125,5 +125,5 @@ cdef _capture_io_streams = None
cdef install_io_streams_capture(): cdef install_io_streams_capture():
global _capture_io_streams global _capture_io_streams
assert _capture_io_streams is None assert _capture_io_streams is None
_capture_io_streams = StdoutStderrCaptureToGodot() _capture_io_streams = StdoutStderrCaptureToPandemonium()
_capture_io_streams.install() _capture_io_streams.install()

View File

@ -115,7 +115,7 @@ cdef pandemonium_pluginscript_script_manifest _build_script_manifest(object cls)
gdapi10.pandemonium_dictionary_new(&manifest.member_lines) gdapi10.pandemonium_dictionary_new(&manifest.member_lines)
if cls.__bases__: if cls.__bases__:
# Only one Godot parent class (checked at class definition time) # Only one Pandemonium parent class (checked at class definition time)
pandemonium_parent_class = next( pandemonium_parent_class = next(
(b for b in cls.__bases__ if issubclass(b, Object)) (b for b in cls.__bases__ if issubclass(b, Object))
) )
@ -150,7 +150,7 @@ cdef api pandemonium_pluginscript_script_manifest pythonscript_script_init(
const pandemonium_string *p_source, const pandemonium_string *p_source,
pandemonium_error *r_error pandemonium_error *r_error
) with gil: ) with gil:
# Godot class&singleton are not all available at Pythonscript bootstrap. # Pandemonium class&singleton are not all available at Pythonscript bootstrap.
# Hence we wait until the Pythonscript start being actually used (i.e. until # Hence we wait until the Pythonscript start being actually used (i.e. until
# the first Python script is loaded) before initializing the bindings. # the first Python script is loaded) before initializing the bindings.
_initialize_bindings() _initialize_bindings()
@ -182,7 +182,7 @@ cdef api pandemonium_pluginscript_script_manifest pythonscript_script_init(
cls = get_exposed_class(modname) cls = get_exposed_class(modname)
# If the module has no exported class, it has no real connection with # If the module has no exported class, it has no real connection with
# Godot and doesn't need to be reloaded # Pandemonium and doesn't need to be reloaded
if cls: if cls:
if get_pythonscript_verbose(): if get_pythonscript_verbose():
print(f"Reloading python script from {path} ({modname})") print(f"Reloading python script from {path} ({modname})")
@ -205,13 +205,13 @@ cdef api pandemonium_pluginscript_script_manifest pythonscript_script_init(
if cls is None: if cls is None:
print( print(
f"Cannot load {path} ({modname}) because it doesn't expose any class to Godot" f"Cannot load {path} ({modname}) because it doesn't expose any class to Pandemonium"
) )
r_error[0] = GODOT_ERR_PARSE_ERROR r_error[0] = GODOT_ERR_PARSE_ERROR
return _build_empty_script_manifest() return _build_empty_script_manifest()
if is_reload: if is_reload:
# During reloading, Godot calls the new class init before the old class finish (so # During reloading, Pandemonium calls the new class init before the old class finish (so
# `pythonscript_script_finish` is going to be called after this function returns). # `pythonscript_script_finish` is going to be called after this function returns).
# Hence we must manually increase the refcount to prevent finish to remove # Hence we must manually increase the refcount to prevent finish to remove
# the class. # the class.

View File

@ -1,4 +1,4 @@
# Start with a sanity check to ensure the loading is done from Godot-Python # Start with a sanity check to ensure the loading is done from Pandemonium-Python
# (and not from a regular Python interpreter which would lead to a segfault). # (and not from a regular Python interpreter which would lead to a segfault).
# The idea is we should have the following loading order: # The idea is we should have the following loading order:
# pandemonium binary -> pythonscript.so -> _pandemonium.so -> pandemonium/__init__.py # pandemonium binary -> pythonscript.so -> _pandemonium.so -> pandemonium/__init__.py
@ -6,10 +6,10 @@ import sys
if "_pandemonium" not in sys.modules: if "_pandemonium" not in sys.modules:
raise ImportError( raise ImportError(
"Cannot initialize pandemonium module given Godot GDNative API not available.\n" "Cannot initialize pandemonium module given Pandemonium GDNative API not available.\n"
"This is most likely because you are running code from a regular Python interpreter" "This is most likely because you are running code from a regular Python interpreter"
" (i.e. doing something like `python my_script.py`) while pandemonium module is only available" " (i.e. doing something like `python my_script.py`) while pandemonium module is only available"
" to Python code loaded from Godot through Godot-Python plugin." " to Python code loaded from Pandemonium through Pandemonium-Python plugin."
) )
del sys del sys

View File

@ -13,7 +13,7 @@ from pandemonium._hazmat.gdnative_api_struct cimport (
from pandemonium.builtins cimport GDString, NodePath from pandemonium.builtins cimport GDString, NodePath
# Godot string are basically a vector of wchar_t, each wchar_t representing # Pandemonium string are basically a vector of wchar_t, each wchar_t representing
# a single unicode character (i.e. there is no surrogates support). # a single unicode character (i.e. there is no surrogates support).
# The sad part is wchar_t is not portable: it is 16bits long on Windows and # The sad part is wchar_t is not portable: it is 16bits long on Windows and
# 32bits long on Linux and MacOS... # 32bits long on Linux and MacOS...

View File

@ -92,7 +92,7 @@ cdef bint is_pytype_compatible_with_pandemonium_variant(object pytype):
cdef object pandemonium_type_to_pytype(pandemonium_variant_type gdtype): cdef object pandemonium_type_to_pytype(pandemonium_variant_type gdtype):
cdef pytype = next((py for gd, py in GD_PY_TYPES if gd == gdtype), None) cdef pytype = next((py for gd, py in GD_PY_TYPES if gd == gdtype), None)
if pytype is None: if pytype is None:
warn(f"No Python equivalent for Godot type `{gdtype}`") warn(f"No Python equivalent for Pandemonium type `{gdtype}`")
return None return None
return pytype return pytype
@ -104,7 +104,7 @@ cdef pandemonium_variant_type pytype_to_pandemonium_type(object pytype):
if issubclass(pytype, Object): if issubclass(pytype, Object):
return pandemonium_variant_type.GODOT_VARIANT_TYPE_OBJECT return pandemonium_variant_type.GODOT_VARIANT_TYPE_OBJECT
else: else:
warn(f"No Godot equivalent for Python type `{pytype}`") warn(f"No Pandemonium equivalent for Python type `{pytype}`")
return pandemonium_variant_type.GODOT_VARIANT_TYPE_NIL return pandemonium_variant_type.GODOT_VARIANT_TYPE_NIL
return gdtype return gdtype
@ -396,7 +396,7 @@ cdef bint pyobj_to_pandemonium_variant(object pyobj, pandemonium_variant *p_var)
elif isinstance(pyobj, Object): elif isinstance(pyobj, Object):
gdapi10.pandemonium_variant_new_object(p_var, (<Object>pyobj)._gd_ptr) gdapi10.pandemonium_variant_new_object(p_var, (<Object>pyobj)._gd_ptr)
else: else:
warn(f"Cannot convert `{type(pyobj)}` to Godot's Variant") warn(f"Cannot convert `{type(pyobj)}` to Pandemonium's Variant")
gdapi10.pandemonium_variant_new_nil(p_var) gdapi10.pandemonium_variant_new_nil(p_var)
return False return False
return True return True

View File

@ -16,7 +16,7 @@ cdef class ModExposedClass:
# /!\ Those containers are strictly private /!\ # /!\ Those containers are strictly private /!\
# They contain class objects that are referenced from Godot without refcounting, # They contain class objects that are referenced from Pandemonium without refcounting,
# so droping an item from there will likely cause a segfault ! # so droping an item from there will likely cause a segfault !
cdef dict __modules_with_exposed_class = {} cdef dict __modules_with_exposed_class = {}
cdef list __all_exposed_classes = [] cdef list __all_exposed_classes = []
@ -40,25 +40,25 @@ cdef void set_exposed_class(object cls):
# We must keep track of reference counts for the module when reloading a script, # We must keep track of reference counts for the module when reloading a script,
# pandemonium calls pythonscript_script_init BEFORE pythonscript_script_finish # pandemonium calls pythonscript_script_init BEFORE pythonscript_script_finish
# this happens because Godot can make multiple PluginScript instances for the same resource. # this happens because Pandemonium can make multiple PluginScript instances for the same resource.
# Godot calls # Pandemonium calls
try: try:
mod = __modules_with_exposed_class[modname] mod = __modules_with_exposed_class[modname]
except KeyError: except KeyError:
__modules_with_exposed_class[modname] = ModExposedClass(cls) __modules_with_exposed_class[modname] = ModExposedClass(cls)
else: else:
# When reloading a script, Godot calls `pythonscript_script_init` BEFORE # When reloading a script, Pandemonium calls `pythonscript_script_init` BEFORE
# `pythonscript_script_finish`. Hence we drop replace the old class # `pythonscript_script_finish`. Hence we drop replace the old class
# here but have to increase the refcount so # here but have to increase the refcount so
mod.kls = cls mod.kls = cls
mod.refcount += 1 mod.refcount += 1
# Sometimes Godot fails to reload a script, and when this happens we end # Sometimes Pandemonium fails to reload a script, and when this happens we end
# up with a stale PyObject* for the class, which is then garbage collected by Python # up with a stale PyObject* for the class, which is then garbage collected by Python
# so next time a script is instantiated from Godot we end up with a sefault :( # so next time a script is instantiated from Pandemonium we end up with a sefault :(
# To avoid this we keep reference forever to all the classes. # To avoid this we keep reference forever to all the classes.
# TODO: This may be troublesome when running the Godot editor given the classes are # TODO: This may be troublesome when running the Pandemonium editor given the classes are
# reloaded each time they are modified, hence leading to a small memory leak... # reloaded each time they are modified, hence leading to a small memory leak...
__all_exposed_classes.append(cls) __all_exposed_classes.append(cls)

View File

@ -1,7 +1,7 @@
# Public low-level APIs are exposed here # Public low-level APIs are exposed here
from pandemoniummonium._hazmat cimport gdnative_api_struct from pandemoniummonium._hazmat cimport gdnative_api_struct
# Re-expose Godot API with better names # Re-expose Pandemonium API with better names
from pandemoniummonium._hazmat.gdapi cimport ( from pandemoniummonium._hazmat.gdapi cimport (
pythonscript_gdapi10 as gdapi10, pythonscript_gdapi10 as gdapi10,
pythonscript_gdapi11 as gdapi11, pythonscript_gdapi11 as gdapi11,

View File

@ -19,7 +19,7 @@ from pandemonium.builtins cimport Array, Dictionary, GDString
from pandemonium.bindings cimport Object, Resource from pandemonium.bindings cimport Object, Resource
# Make Godot enums accesible from Python at runtime # Make Pandemonium enums accesible from Python at runtime
class MethodRPCMode(enum.IntEnum): class MethodRPCMode(enum.IntEnum):
@ -162,14 +162,14 @@ class ExportedField:
type = Dictionary if type == dict else type type = Dictionary if type == dict else type
if not is_pytype_compatible_with_pandemonium_variant(type): if not is_pytype_compatible_with_pandemonium_variant(type):
raise ValueError(f"{type!r} type value not compatible with Godot") raise ValueError(f"{type!r} type value not compatible with Pandemonium")
cdef pandemonium_variant gd_default cdef pandemonium_variant gd_default
if default is not None: if default is not None:
# Convert `default` to a Godot-compatible value (e.g. str -> GDString) # Convert `default` to a Pandemonium-compatible value (e.g. str -> GDString)
if not pyobj_to_pandemonium_variant(default, &gd_default): if not pyobj_to_pandemonium_variant(default, &gd_default):
gdapi10.pandemonium_variant_destroy(&gd_default) gdapi10.pandemonium_variant_destroy(&gd_default)
raise ValueError(f"{default!r} default value not compatible with Godot") raise ValueError(f"{default!r} default value not compatible with Pandemonium")
default = pandemonium_variant_to_pyobj(&gd_default) default = pandemonium_variant_to_pyobj(&gd_default)
gdapi10.pandemonium_variant_destroy(&gd_default) gdapi10.pandemonium_variant_destroy(&gd_default)
@ -245,8 +245,8 @@ def export(
rpc: MethodRPCMode=MethodRPCMode.DISABLED rpc: MethodRPCMode=MethodRPCMode.DISABLED
): ):
""" """
Decorator used to mark a class attribute as beeing exported to Godot Decorator used to mark a class attribute as beeing exported to Pandemonium
(hence making it readable/writable from Godot) (hence making it readable/writable from Pandemonium)
usage:: usage::
@exposed @exposed
@ -276,9 +276,9 @@ def export(
def exposed(cls=None, tool=False): def exposed(cls=None, tool=False):
""" """
Decorator used to mark a class as beeing exposed to Godot (hence making Decorator used to mark a class as beeing exposed to Pandemonium (hence making
it available from other Godot languages and the Godot IDE). it available from other Pandemonium languages and the Pandemonium IDE).
Due to how Godot identifiest classes by their file pathes, only a single Due to how Pandemonium identifiest classes by their file pathes, only a single
class can be marked with this decorator per file. class can be marked with this decorator per file.
usage:: usage::
@ -290,7 +290,7 @@ def exposed(cls=None, tool=False):
def wrapper(cls): def wrapper(cls):
if not issubclass(cls, Object): if not issubclass(cls, Object):
raise ValueError( raise ValueError(
f"{cls!r} must inherit from a Godot (e.g. `pandemonium.bindings.Node`) " f"{cls!r} must inherit from a Pandemonium (e.g. `pandemonium.bindings.Node`) "
"class to be marked as @exposed" "class to be marked as @exposed"
) )
@ -333,15 +333,15 @@ def exposed(cls=None, tool=False):
elif callable(v): elif callable(v):
cls.__exported[k] = v cls.__exported[k] = v
# Overwrite parent __init__ to avoid creating a Godot object given # Overwrite parent __init__ to avoid creating a Pandemonium object given
# exported script are always initialized with an existing Godot object # exported script are always initialized with an existing Pandemonium object
# On top of that, we must initialize the attributes defined in the class # On top of that, we must initialize the attributes defined in the class
# and it parents # and it parents
g = {} g = {}
exec(init_func_code, g) exec(init_func_code, g)
cls.__init__ = g["__init__"] cls.__init__ = g["__init__"]
# Also overwrite parent new otherwise we would return an instance # Also overwrite parent new otherwise we would return an instance
# of a Godot class without our script attached to it... # of a Pandemonium class without our script attached to it...
@classmethod @classmethod
def new(cls): def new(cls):
raise NotImplementedError("Instantiating Python script from Python is not implemented yet :'(") raise NotImplementedError("Instantiating Python script from Python is not implemented yet :'(")
@ -350,7 +350,7 @@ def exposed(cls=None, tool=False):
# except AttributeError: # except AttributeError:
# # It's also possible we try to instantiate a singleton, but a better # # It's also possible we try to instantiate a singleton, but a better
# # message will be provided anyway if the user try the provided hint # # message will be provided anyway if the user try the provided hint
# raise RuntimeError(f"Refcounted Godot object must be created with `{ cls.__name__ }()`") # raise RuntimeError(f"Refcounted Pandemonium object must be created with `{ cls.__name__ }()`")
# instance = cls._from_ptr(ptr) # instance = cls._from_ptr(ptr)
# # TODO: We should generate a Resource instance containing the script # # TODO: We should generate a Resource instance containing the script
# # and attach it to the main class here. # # and attach it to the main class here.

View File

@ -1,11 +1,11 @@
/* /*
* This file gets compiled as a shared library that act as the entry point * This file gets compiled as a shared library that act as the entry point
* to the pythonscript plugin. * to the pythonscript plugin.
* It should be loaded by Godot's GDNative system (see the `pythonscript.gdnlib` * It should be loaded by Pandemonium's GDNative system (see the `pythonscript.gdnlib`
* file in the example/test projects). * file in the example/test projects).
* As part of the loading, GDNative will call the `pandemonium_gdnative_init` * As part of the loading, GDNative will call the `pandemonium_gdnative_init`
* function which will in turn initialize the CPython interpreter then register * function which will in turn initialize the CPython interpreter then register
* Python as a new language using Godot's Pluginscript system. * Python as a new language using Pandemonium's Pluginscript system.
*/ */
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
@ -65,7 +65,7 @@ static PyThreadState *gilstate = NULL;
/* /*
* Global variables exposing Godot API to the pandemonium.hazmat cython module. * Global variables exposing Pandemonium API to the pandemonium.hazmat cython module.
* Hence we must initialized them before loading `_pandemonium`/`pandemonium` modules * Hence we must initialized them before loading `_pandemonium`/`pandemonium` modules
* (which both depend on `pandemonium.hazmat`). * (which both depend on `pandemonium.hazmat`).
*/ */
@ -135,7 +135,7 @@ GDN_EXPORT void pandemonium_gdnative_init(pandemonium_gdnative_init_options *opt
// Check for mandatory plugins // Check for mandatory plugins
if (!pythonscript_gdapi10 || !pythonscript_gdapi11 || !pythonscript_gdapi12) { if (!pythonscript_gdapi10 || !pythonscript_gdapi11 || !pythonscript_gdapi12) {
GD_ERROR_PRINT("Godot-Python requires GDNative API >= v1.2"); GD_ERROR_PRINT("Pandemonium-Python requires GDNative API >= v1.2");
return; return;
} }
if (!pythonscript_gdapi_ext_pluginscript) { if (!pythonscript_gdapi_ext_pluginscript) {

View File

@ -182,7 +182,7 @@ def test_access_property(generate_obj):
def test_new_on_overloaded_class(generate_obj): def test_new_on_overloaded_class(generate_obj):
node = generate_obj(virtualtestbedcls) node = generate_obj(virtualtestbedcls)
# Make sure doing MyClass.new() doesn't return an instance of the # Make sure doing MyClass.new() doesn't return an instance of the
# Godot class we inherit from # Pandemonium class we inherit from
assert isinstance(node, virtualtestbedcls) assert isinstance(node, virtualtestbedcls)

View File

@ -69,7 +69,7 @@ def test_getitem():
assert v[0.5] == Vector2() assert v[0.5] == Vector2()
# Missing items are stored as None # Missing items are stored as None
assert v["dummy"] is None assert v["dummy"] is None
# Cannot store non Godot types # Cannot store non Pandemonium types
with pytest.raises(TypeError): with pytest.raises(TypeError):
v[object()] v[object()]
@ -82,7 +82,7 @@ def test_setitem():
v["a"] = 4 v["a"] = 4
assert len(v) == 4 assert len(v) == 4
assert v["a"] == 4 assert v["a"] == 4
# Cannot store non Godot types # Cannot store non Pandemonium types
with pytest.raises(TypeError): with pytest.raises(TypeError):
v[object()] = 4 v[object()] = 4
with pytest.raises(TypeError): with pytest.raises(TypeError):
@ -99,7 +99,7 @@ def test_delitem():
# Delete on missing items should raise error # Delete on missing items should raise error
with pytest.raises(KeyError): with pytest.raises(KeyError):
del v["missing"] del v["missing"]
# Cannot store non Godot types # Cannot store non Pandemonium types
with pytest.raises(TypeError): with pytest.raises(TypeError):
del v[object()] del v[object()]

View File

@ -27,7 +27,7 @@
# assert isinstance(KEY_ESCAPE, int) # assert isinstance(KEY_ESCAPE, int)
# def test_objects_unicity(self): # def test_objects_unicity(self):
# # Main loop object is a Godot Object, calling `get_main_loop` from # # Main loop object is a Pandemonium Object, calling `get_main_loop` from
# # python returns a different python wrapper on the same object each time. # # python returns a different python wrapper on the same object each time.
# # However those wrappers should feel like they are the same object. # # However those wrappers should feel like they are the same object.
# ml = Engine.get_main_loop() # ml = Engine.get_main_loop()
@ -40,7 +40,7 @@
# assert ml != None # noqa # assert ml != None # noqa
# assert ml != "" # assert ml != ""
# assert ml != 42 # assert ml != 42
# # Don't forget to free the Godot Object # # Don't forget to free the Pandemonium Object
# obj.free() # obj.free()
# def test_class(self): # def test_class(self):

View File

@ -8,7 +8,7 @@ def environment_factory():
# Environment objects are stubbed on headless server, hence # Environment objects are stubbed on headless server, hence
# their corresponding RID is always the same default value # their corresponding RID is always the same default value
if OS.has_feature("Server"): if OS.has_feature("Server"):
pytest.skip("Not available on headless Godot") pytest.skip("Not available on headless Pandemonium")
def _factory(): def _factory():
return Environment() return Environment()

View File

@ -29,7 +29,7 @@ def test_base():
@pytest.mark.parametrize("char", ["e", "é", "", "", "🐍"]) @pytest.mark.parametrize("char", ["e", "é", "", "", "🐍"])
def test_unicode(char): def test_unicode(char):
# Godot supports UCS2 on Windows and UCS4 on other platforms # Pandemonium supports UCS2 on Windows and UCS4 on other platforms
if len(char.encode("utf8")) > 2 and sys.platform == "win32": if len(char.encode("utf8")) > 2 and sys.platform == "win32":
pytest.skip("Windows only supports UCS2") pytest.skip("Windows only supports UCS2")

View File

@ -76,7 +76,7 @@ test_factory(
try: try:
import pandemonium import pandemonium
except ImportError as exc: except ImportError as exc:
assert "Cannot initialize pandemonium module given Godot GDNative API not available." in str(exc) assert "Cannot initialize pandemonium module given Pandemonium GDNative API not available." in str(exc)
""", """,
], ],
) )