@@ 1740,7 1740,7 @@ bugfixes and enhancements, and a new governance model.")
(define-public python-renpy
(package
(name "python-renpy")
- (version "8.3.0")
+ (version "8.5.0")
(source
(origin
(method url-fetch)
@@ 1748,8 1748,11 @@ bugfixes and enhancements, and a new governance model.")
"/renpy-" version "-source.tar.bz2"))
(sha256
(base32
- "1xb9ixb73nm271frkchrqpf64bcrdvrk3n4281dxzm4k4wj60rwb"))
+ "1dv856sb8mak21kkj0ys0k6zc6ly2k8102ahnfdrc04cwdrryw6b"))
(modules '((guix build utils)))
+ ;; TODO: Remove when updating Python to 3.12 or higher.
+ (patches (search-patches "renpy-python-3.11-compat.patch"
+ "renpy-fix-integer-slots.patch"))
(snippet
#~(begin
;; Build without sync service.
@@ 1759,15 1762,29 @@ bugfixes and enhancements, and a new governance model.")
(for-each delete-file
'("renpy/encryption.pyx"
"renpy/common/00sync.rpy"))
- (substitute* "module/setup.py"
- (("cython\\(\"renpy\\.encryption\"\\)") ""))
+ (delete-file-recursively "src/libhydrogen")
+ (substitute* "setup.py"
+ (("cython\\(\"renpy\\.encryption\"\\)") "")
+ (("version = .*") (string-append "version = \"" #$version "\"")))
(substitute* "renpy/__init__.py"
(("import renpy\\.encryption") ""))
;; Trust vc_version.py when it comes to detecting whether a
;; version is official.
(substitute* "renpy/__init__.py"
- (("official = official and .*") ""))))))
- (build-system python-build-system)
+ (("official = official and .*") ""))
+
+ ;; Make source compatible with Python 3.11.
+ ;; Drop this part once a newer Python is used.
+ (substitute* (find-files "renpy" "\\.py$")
+ (("type ([A-Za-z0-9]+) =" all id)
+ (string-append id " =")))
+ (substitute* "renpy/minstore.py"
+ ((", override") ""))
+
+ ;; Use SDL2/ prefix.
+ (substitute* "src/pygame/sdl_image_compat.h"
+ (("\"SDL_image.h\"") "<SDL2/SDL_image.h>"))))))
+ (build-system pyproject-build-system)
(arguments
(list
#:tests? #f ; Ren'py doesn't seem to package tests
@@ 1785,49 1802,36 @@ bugfixes and enhancements, and a new governance model.")
(search-input-file (or native-inputs inputs)
"/bin/cython"))
(setenv "RENPY_DEPS_INSTALL" (string-join (map cdr inputs) ":"))))
- (add-before 'build 'relax-gcc-14-strictness
+ (add-after 'build 'build-renpy
(lambda _
- (setenv "CFLAGS" (string-join
- (list "-g" "-O2"
- "-Wno-error=incompatible-pointer-types"
- "-Wno-error=implicit-function-declaration")
- " "))))
- (replace 'build
- (lambda* (#:key inputs outputs #:allow-other-keys #:rest args)
- ;; The "module" subdirectory contains a python (really cython)
- ;; project, which is built using a script, that is thankfully
- ;; named "setup.py".
- (with-directory-excursion "module"
- (apply (assoc-ref %standard-phases 'build) args))
- ;; The above only builds the cython modules, but nothing else,
- ;; so we do that here.
(invoke "python" "-m" "compileall" "renpy")))
- (replace 'install
- (lambda* (#:key inputs outputs #:allow-other-keys #:rest args)
- ;; Again, we have to wrap the module installation.
- ;; Additionally, we want to install the python code
- ;; (both source and compiled) in the same directory.
- (let* ((out (assoc-ref outputs "out"))
- (site (string-append "/lib/python"
+ (add-after 'install 'install-renpy
+ (lambda* (#:key inputs outputs #:allow-other-keys)
+ (let ((site (string-append (assoc-ref outputs "out")
+ "/lib/python"
(python-version
(assoc-ref inputs "python"))
"/site-packages")))
- (with-directory-excursion "module"
- (apply (assoc-ref %standard-phases 'install) args))
(copy-recursively "renpy"
- (string-append out site "/renpy"))
- (delete-file-recursively (string-append out site
- "/renpy/common"))))))))
- (native-inputs (list python-cython-0))
+ (string-append site "/renpy"))
+ (delete-file-recursively
+ (string-append site "/renpy/common"))
+ (for-each delete-file
+ (find-files site "\\.py[ix]"))))))))
+ (native-inputs (list pkg-config
+ python-cython
+ python-setuptools
+ python-wheel))
(inputs
- (list ffmpeg-6
+ (list assimp
+ ffmpeg
freetype
fribidi
glew
libpng
(sdl-union (list sdl2 sdl2-image sdl2-mixer sdl2-ttf))
xdg-utils))
- (propagated-inputs (list python-ecdsa python-future python-pygame-sdl2))
+ (propagated-inputs (list python-ecdsa python-future))
(home-page "https://www.renpy.org/")
(synopsis "Ren'py python module")
(description "This package contains the shared libraries and Python modules
@@ 0,0 1,40 @@
+Index: renpy-8.5.0-source/renpy/cslots.pyx
+===================================================================
+--- renpy-8.5.0-source.orig/renpy/cslots.pyx
++++ renpy-8.5.0-source/renpy/cslots.pyx
+@@ -32,6 +32,9 @@ Value unions, followed by a series of by
+ from cpython.mem cimport PyMem_Calloc, PyMem_Free
+ from cpython.object cimport PyObject, PyTypeObject, Py_TPFLAGS_HAVE_GC, PyObject_Free
+ from cpython.ref cimport Py_XINCREF, Py_XDECREF, Py_CLEAR
++cdef extern from "<limits.h>":
++ const long long LLONG_MIN
++ const long long LLONG_MAX
+
+ from copyreg import __newobj__
+
+@@ -51,7 +54,7 @@ cdef unsigned char DEFAULT_VALUE = 0xff
+
+ cdef union Value:
+ PyObject *object
+- unsigned long long integer
++ long long integer
+
+ cdef class CMetaclass(type):
+
+@@ -369,10 +372,15 @@ cdef class IntegerSlot(Slot):
+ super(IntegerSlot, self).__init__(default_value)
+ self.default_int_value = default_value
+
+- def __set__(self, CObject instance, unsigned int value):
++ def __set__(self, CObject instance, long long value):
+
+ cdef Value v
+
++ if value >= (LLONG_MAX >> 1):
++ raise OverflowError("Value is too large for an IntegerSlot")
++ if value <= (LLONG_MIN >> 1):
++ raise OverflowError("Value is too small for an IntegerSlot")
++
+ if value == self.default_int_value:
+ v.object = NULL
+ else:
@@ 0,0 1,189 @@
+Index: renpy-8.5.0-source/renpy/color.py
+===================================================================
+--- renpy-8.5.0-source.orig/renpy/color.py
++++ renpy-8.5.0-source/renpy/color.py
+@@ -19,7 +19,7 @@
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+-from typing import final, overload
++from typing import final, overload, ForwardRef
+
+ import re
+ import colorsys
+@@ -32,7 +32,7 @@ _LONG_COLOR_STRING_RE = re.compile(
+ r"#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})?",
+ )
+
+-type ColorLike = "Color" | tuple[int, int, int, int] | tuple[int, int, int] | str
++type ColorLike = ForwardRef("Color") | tuple[int, int, int, int] | tuple[int, int, int] | str
+ """
+ The color, in one of the standard formats Ren'Py understands. These are:
+ - A Color object.
+@@ -409,11 +409,11 @@ class Color(tuple[int, int, int, int]):
+
+ __rmul__ = __mul__ # type: ignore
+
+- def _interpolate_tuple[T: tuple](self, a: T, b: T, fraction: float) -> T:
++ def _interpolate_tuple(self, a: tuple, b: tuple, fraction: float) -> tuple:
+ i = self._interpolate_num
+ return type(a)(tuple(i(ac, bc, fraction) for ac, bc in zip(a, b)))
+
+- def _interpolate_num[T: (float, int)](self, a: T, b: T, fraction: float) -> T:
++ def _interpolate_num(self, a: int | float, b: int | float, fraction: float) -> int | float:
+ return type(a)(a + (b - a) * fraction)
+
+ def interpolate(self, other: ColorLike, fraction: float) -> "Color":
+Index: renpy-8.5.0-source/renpy/cslots.pyi
+===================================================================
+--- renpy-8.5.0-source.orig/renpy/cslots.pyi
++++ renpy-8.5.0-source/renpy/cslots.pyi
+@@ -19,6 +19,8 @@
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
++from typing import TypeVar, Generic
++
+ class Object:
+ linenumber: int
+ "If known, the line number of the object in the source file."
+@@ -45,7 +47,9 @@ class Object:
+ and setting all slots to the default, breaking reference cycles.
+ """
+
+-class Slot[T]:
++T = TypeVar('T')
++
++class Slot(Generic(T)):
+ number: int
+ "A number assigned to this slot."
+
+Index: renpy-8.5.0-source/renpy/easy.py
+===================================================================
+--- renpy-8.5.0-source.orig/renpy/easy.py
++++ renpy-8.5.0-source/renpy/easy.py
+@@ -21,7 +21,7 @@
+
+ """Functions that make the user's life easier."""
+
+-from typing import Any, Callable
++from typing import Any, Callable, ParamSpec, TypeVar
+ from collections.abc import Iterable
+
+ import contextlib
+@@ -262,7 +262,10 @@ def split_properties(properties: dict[st
+ return rv
+
+
+-def to_list[T](value: T | Iterable[T], copy: bool = False) -> list[T]:
++T = TypeVar('T')
++
++
++def to_list(value: T | Iterable[T], copy: bool = False) -> list[T]:
+ """
+ If the value is an iterable, turns it into a list, otherwise wraps it into one.
+ If a list is provided and `copy` is True, a new list will be returned.
+@@ -281,7 +284,7 @@ def to_list[T](value: T | Iterable[T], c
+ return [value]
+
+
+-def to_tuple[T](value: T | Iterable[T]) -> tuple[T, ...]:
++def to_tuple(value: T | Iterable[T]) -> tuple[T, ...]:
+ """
+ Same as to_list, but with tuples.
+ """
+@@ -299,7 +302,11 @@ def to_tuple[T](value: T | Iterable[T])
+ return (value,)
+
+
+-def run_callbacks[**P, R](
++P = ParamSpec('P')
++R = TypeVar('R')
++
++
++def run_callbacks(
+ cb: Callable[P, R] | list[Callable[P, R]] | None,
+ *args: P.args,
+ **kwargs: P.kwargs,
+Index: renpy-8.5.0-source/renpy/display/position.py
+===================================================================
+--- renpy-8.5.0-source.orig/renpy/display/position.py
++++ renpy-8.5.0-source/renpy/display/position.py
+@@ -19,11 +19,14 @@
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+-from typing import final, overload, SupportsIndex, Any
++from typing import final, overload, SupportsIndex, Any, TypeVar
+
+ from renpy.types import Position
+
+
++T = TypeVar('T', int, float, "absolute")
++
++
+ @final
+ class absolute(float):
+ """
+@@ -176,7 +179,7 @@ class absolute(float):
+
+ @overload
+ @staticmethod
+- def compute_raw[T: ("int | float | absolute")](value: T, room: float) -> T: ...
++ def compute_raw(value: T, room: float) -> T: ...
+
+ @staticmethod
+ def compute_raw(value: Position, room: float) -> "int | float | absolute":
+Index: renpy-8.5.0-source/renpy/types.py
+===================================================================
+--- renpy-8.5.0-source.orig/renpy/types.py
++++ renpy-8.5.0-source/renpy/types.py
+@@ -29,10 +29,11 @@
+ # be inconvenient.
+
+ import renpy
++from typing import ForwardRef
+
+-type Displayable = renpy.display.displayable.Displayable
++type Displayable = ForwardRef('renpy.display.displayable.Displayable')
+
+-type DisplayableLike = Displayable | str | list[str] | renpy.color.Color
++type DisplayableLike = Displayable | str | list[str] | ForwardRef('renpy.color.Color')
+ """
+ This describes anything that Ren'Py considers to be a displayable.
+
+@@ -45,7 +46,7 @@ Apart from Displayable itself, this coul
+ - renpy.color.Color object.
+ """
+
+-type Position = int | float | renpy.display.position.absolute | renpy.display.position.position
++type Position = int | float | ForwardRef('renpy.display.position.absolute') | ForwardRef('renpy.display.position.position')
+ """
+ This describes a position, which can be one of:
+ - An integer - treated as pixels from the top left corner of the area.
+Index: renpy-8.5.0-source/renpy/__init__.py
+===================================================================
+--- renpy-8.5.0-source.orig/renpy/__init__.py
++++ renpy-8.5.0-source/renpy/__init__.py
+@@ -227,6 +227,7 @@ backup_blacklist = {
+ "renpy.test.testreporter",
+ "renpy.test.testsettings",
+ "renpy.tfd",
++ "renpy.types",
+ "renpy.gl2",
+ "renpycoverage",
+ }
+@@ -245,9 +246,13 @@ name_blacklist = {
+ "renpy.savelocation.disk_lock",
+ "renpy.character.TAG_RE",
++ "renpy.color.ColorLike",
+ "renpy.display.im.cache",
++ "renpy.display.position.Position",
+ "renpy.display.render.main_thread",
+ "renpy.display.render.blit_lock",
+ "renpy.display.render.IDENTITY",
++ "renpy.easy.Displayable",
++ "renpy.easy.DisplayableLike",
+ "renpy.loader.auto_lock",
+ "renpy.display.screen.cprof",
+ "renpy.audio.audio.lock",
@@ 1,57 0,0 @@
-See also [Arch] and [Gentoo] for similar patches in other distros.
-[Arch] https://github.com/archlinux/svntogit-community/blob/packages/renpy/trunk/renpy-system-fribidi.patch
-[Gentoo] https://gitweb.gentoo.org/repo/gentoo.git/tree/games-engines/renpy/files/renpy-7.3.5-use-system-fribidi.patch
-
-Index: renpy-7.4.0-source/module/renpybidicore.c
-===================================================================
---- renpy-7.4.0-source.orig/module/renpybidicore.c
-+++ renpy-7.4.0-source/module/renpybidicore.c
-@@ -1,9 +1,3 @@
- #include <Python.h>
--
--#ifdef RENPY_BUILD
- #include <fribidi.h>
--#else
--#include <fribidi-src/lib/fribidi.h>
--#endif
--
- #include <stdlib.h>
-
- #ifndef alloca
-Index: renpy-7.4.0-source/module/setup.py
-===================================================================
---- renpy-7.4.0-source.orig/module/setup.py
-+++ renpy-7.4.0-source/module/setup.py
-@@ -125,30 +125,13 @@ cython(
- sdl + [ png, 'z', 'm' ])
-
- FRIBIDI_SOURCES = """
--fribidi-src/lib/fribidi.c
--fribidi-src/lib/fribidi-arabic.c
--fribidi-src/lib/fribidi-bidi.c
--fribidi-src/lib/fribidi-bidi-types.c
--fribidi-src/lib/fribidi-deprecated.c
--fribidi-src/lib/fribidi-joining.c
--fribidi-src/lib/fribidi-joining-types.c
--fribidi-src/lib/fribidi-mem.c
--fribidi-src/lib/fribidi-mirroring.c
--fribidi-src/lib/fribidi-run.c
--fribidi-src/lib/fribidi-shape.c
- renpybidicore.c
- """.split()
- cython(
- "_renpybidi",
- FRIBIDI_SOURCES,
-- includes=[
-- BASE + "/fribidi-src/",
-- BASE + "/fribidi-src/lib/",
-- ],
-- define_macros=[
-- ("FRIBIDI_ENTRY", ""),
-- ("HAVE_CONFIG_H", "1"),
-- ])
-+ includes=["/usr/include/fribidi"],
-+ libs=["fribidi"])
-
-
- cython("_renpysteam", language="c++", compile_if=steam_sdk, libs=["steam_api"])