diff --git a/meta-opencentauri/recipes-apps/klipper/files/0001-Lazy-load-optional-NumPy-users.patch b/meta-opencentauri/recipes-apps/klipper/files/0001-Lazy-load-optional-NumPy-users.patch new file mode 100644 index 00000000..a20f80c1 --- /dev/null +++ b/meta-opencentauri/recipes-apps/klipper/files/0001-Lazy-load-optional-NumPy-users.patch @@ -0,0 +1,107 @@ +From 7f1b2a37d5cb51aabbec6483588f6a58c91bcf31 Mon Sep 17 00:00:00 2001 +From: OpenCentauri +Date: Mon, 20 Jul 2026 15:00:00 -0400 +Subject: [PATCH] Lazy-load optional NumPy users + +Upstream-Status: Pending + +Importing NumPy 1.26 brings a substantial set of numerical modules into the +Klippy process. Do not make every configuration pay that cost merely for JSON +conversion or for temperature-fan control modes which do not use curves. + +Recognize NumPy values by their type metadata in the JSON fallback, which is +only invoked for otherwise non-serializable objects. Import NumPy from the +curve controller itself so watermark and PID temperature fans remain free of +that dependency. +--- + klippy/extras/temperature_fan.py | 13 +++++++------ + klippy/webhooks.py | 15 ++++++++------- + 2 files changed, 15 insertions(+), 13 deletions(-) + +diff --git a/klippy/extras/temperature_fan.py b/klippy/extras/temperature_fan.py +index 757b494..a358d2c 100644 +--- a/klippy/extras/temperature_fan.py ++++ b/klippy/extras/temperature_fan.py +@@ -4,8 +4,6 @@ + # + # This file may be distributed under the terms of the GNU GPLv3 license. + +-import numpy as np +- + from . import fan + + KELVIN_TO_CELSIUS = -273.15 +@@ -250,7 +248,12 @@ class ControlPID: + + class ControlCurve: + def __init__(self, temperature_fan, config): ++ # Curve control is the only temperature-fan mode which needs NumPy. ++ # Keep PID and watermark configurations from importing it at startup. ++ import numpy as np ++ + self.temperature_fan = temperature_fan ++ self.numpy = np + + points = list( + config.getlists("points", seps=(",", "\n"), parser=float, count=2) +@@ -316,19 +319,19 @@ class ControlCurve: + + def temperature_callback(self, read_time, temp): + current_speed = self.temperature_fan.last_speed_value +- upper_temp = np.interp( ++ upper_temp = self.numpy.interp( + current_speed, self.curve_heating[1], self.curve_heating[0] + ) +- lower_temp = np.interp( ++ lower_temp = self.numpy.interp( + current_speed, self.curve_cooling[1], self.curve_cooling[0] + ) + + if temp < lower_temp: +- next_speed = np.interp( ++ next_speed = self.numpy.interp( + temp, self.curve_cooling[0], self.curve_cooling[1] + ) + elif temp > upper_temp: +- next_speed = np.interp( ++ next_speed = self.numpy.interp( + temp, self.curve_heating[0], self.curve_heating[1] + ) + else: +diff --git a/klippy/webhooks.py b/klippy/webhooks.py +index f53cd1b..3037f25 100644 +--- a/klippy/webhooks.py ++++ b/klippy/webhooks.py +@@ -13,8 +13,6 @@ import pwd + import socket + import sys + +-import numpy +- + from . import APP_NAME, gcode + from .extras.danger_options import get_danger_options + +@@ -322,13 +320,15 @@ class ClientConnection: + self.send(result) + + def _json_convert(self, obj): +- # numpy bool/array objects aren't directly serializable; +- # convert to regular types in case they leak into state dicts +- # to avoid a shutdown +- if isinstance(obj, numpy.bool_): +- return bool(obj) +- elif isinstance(obj, numpy.ndarray): ++ # NumPy scalars and arrays are not directly serializable. This ++ # fallback is only called for otherwise unsupported values, so avoid ++ # importing all of NumPy just to recognize them. Both ndarray and ++ # NumPy scalar types provide one of these conversion methods. ++ obj_type = type(obj) ++ if obj_type.__module__.startswith("numpy") and hasattr(obj, "tolist"): + return obj.tolist() ++ if obj_type.__module__.startswith("numpy") and hasattr(obj, "item"): ++ return obj.item() + # anything else will fail + logging.warning( + f"_json_convert: can't serialize object of type {type(obj)}: '{str(obj)}'" +-- +2.47.2 diff --git a/meta-opencentauri/recipes-apps/klipper/files/klipper-init-d b/meta-opencentauri/recipes-apps/klipper/files/klipper-init-d index 5d0bc2e9..9ad7c1ab 100644 --- a/meta-opencentauri/recipes-apps/klipper/files/klipper-init-d +++ b/meta-opencentauri/recipes-apps/klipper/files/klipper-init-d @@ -10,7 +10,7 @@ KLIPPY_EXEC="/usr/bin/python3" KLIPPER_PRINTER_CONFIG="/etc/klipper/config/printer.cfg" -KLIPPY_ARGS="-O /usr/share/klipper/klippy/klippy.py $KLIPPER_PRINTER_CONFIG -l /board-resource/klippy.log -a /run/klippy.sock" +KLIPPY_ARGS="-O -X no_debug_ranges /usr/share/klipper/klippy/klippy.py $KLIPPER_PRINTER_CONFIG -l /board-resource/klippy.log -a /run/klippy.sock" PIDFILE="/var/run/klipper.pid" KLIPPER_VAR_CONFIG_BUILDER="/usr/bin/build-klipper-var-config" KLIPPER_CONFIG_VERSION="0.0.8-2" diff --git a/meta-opencentauri/recipes-apps/klipper/kalico_2026.02.00.bb b/meta-opencentauri/recipes-apps/klipper/kalico_2026.02.00.bb index dc8e319a..c47b555e 100644 --- a/meta-opencentauri/recipes-apps/klipper/kalico_2026.02.00.bb +++ b/meta-opencentauri/recipes-apps/klipper/kalico_2026.02.00.bb @@ -7,6 +7,7 @@ FILESEXTRAPATHS:prepend := "${THISDIR}/files:" SRC_URI += " \ file://klipper-init-d \ + file://0001-Lazy-load-optional-NumPy-users.patch \ file://printer.cfg \ file://macros.cfg \ file://machine.cfg \ diff --git a/meta-opencentauri/recipes-apps/moonraker/files/moonraker-init-d b/meta-opencentauri/recipes-apps/moonraker/files/moonraker-init-d index 73ef744e..d2a929e1 100644 --- a/meta-opencentauri/recipes-apps/moonraker/files/moonraker-init-d +++ b/meta-opencentauri/recipes-apps/moonraker/files/moonraker-init-d @@ -9,7 +9,7 @@ ### END INIT INFO MOONRAKER_EXEC="/usr/bin/python3" -MOONRAKER_ARGS="-m moonraker.moonraker -d /etc/klipper -l /board-resource/moonraker.log -u /run/moonraker.sock" +MOONRAKER_ARGS="-X no_debug_ranges -m moonraker.moonraker -d /etc/klipper -l /board-resource/moonraker.log -u /run/moonraker.sock" PIDFILE="/var/run/moonraker.pid" export PYTHONPATH="/usr/share/moonraker" diff --git a/meta-opencentauri/recipes-devtools/python/python3-numpy/0001-Lazy-load-heavy-public-subpackages.patch b/meta-opencentauri/recipes-devtools/python/python3-numpy/0001-Lazy-load-heavy-public-subpackages.patch new file mode 100644 index 00000000..dc6fabf0 --- /dev/null +++ b/meta-opencentauri/recipes-devtools/python/python3-numpy/0001-Lazy-load-heavy-public-subpackages.patch @@ -0,0 +1,69 @@ +From a9f7ee07c78910755311648026226644a3250c4f Mon Sep 17 00:00:00 2001 +From: OpenCentauri +Date: Mon, 20 Jul 2026 15:00:00 -0400 +Subject: [PATCH] Lazy-load heavy public subpackages + +Upstream-Status: Backport [https://github.com/numpy/numpy/commit/250e1479ce342d9d7ab8a592508f6ce892d4c98b] + +NumPy 1.26 imports several independent numerical subpackages whenever the root +package is imported. Embedded users of core array operations consequently map +FFT, linear algebra, polynomial, random-number, ctypes, and masked-array code +which they may never call. + +Retain the public NumPy 1.26 API by importing these modules on first attribute +access and caching them in the package globals. This follows the lazy public +submodule behavior used by newer NumPy releases while leaving core and lib +namespace initialization unchanged. +--- + numpy/__init__.py | 27 ++++++++++++++++++++++----- + 1 file changed, 22 insertions(+), 5 deletions(-) + +diff --git a/numpy/__init__.py b/numpy/__init__.py +index 63a63bf..54d6a97 100644 +--- a/numpy/__init__.py ++++ b/numpy/__init__.py +@@ -141,12 +141,7 @@ else: + # See gh-14454 and gh-15672 for discussion. + from .lib import * + +- from . import linalg +- from . import fft +- from . import polynomial +- from . import random +- from . import ctypeslib +- from . import ma ++ # Heavy public subpackages are loaded on first access in __getattr__. + from . import matrixlib as _mat + from .matrixlib import * + +@@ -289,6 +284,28 @@ else: + numarray = 'removed' + + def __getattr__(attr): ++ # NumPy 1.26 historically imported these independent subpackages at ++ # root-package startup. Preserve np. while avoiding their ++ # code and extension mappings for core-only embedded workloads. ++ if attr == 'linalg': ++ import numpy.linalg as linalg ++ return linalg ++ elif attr == 'fft': ++ import numpy.fft as fft ++ return fft ++ elif attr == 'random': ++ import numpy.random as random ++ return random ++ elif attr == 'polynomial': ++ import numpy.polynomial as polynomial ++ return polynomial ++ elif attr == 'ma': ++ import numpy.ma as ma ++ return ma ++ elif attr == 'ctypeslib': ++ import numpy.ctypeslib as ctypeslib ++ return ctypeslib ++ + # Warn for expired attributes, and return a dummy function + # that always raises an exception. + import warnings +-- +2.47.2 diff --git a/meta-opencentauri/recipes-devtools/python/python3-numpy_%.bbappend b/meta-opencentauri/recipes-devtools/python/python3-numpy_%.bbappend new file mode 100644 index 00000000..6a50e8d3 --- /dev/null +++ b/meta-opencentauri/recipes-devtools/python/python3-numpy_%.bbappend @@ -0,0 +1,3 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/python3-numpy:" + +SRC_URI += "file://0001-Lazy-load-heavy-public-subpackages.patch"