Skip to content

Commit f2ff576

Browse files
committed
Log Chipmunk level errors with standard logging module
1 parent 902680e commit f2ff576

File tree

8 files changed

+76
-6
lines changed

8 files changed

+76
-6
lines changed

CHANGELOG.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22
Changelog
33
=========
44

5+
..
6+
Pymunk x.x.x
7+
------------
8+
Changes:
9+
- Fixed issue with SlideJoint when changing body_type.
10+
- Log Chipmunk level erros with logging module
11+
512
Pymunk 6.8.1 (2024-06-05)
613
-------------------------
714

Chipmunk2D

docs/src/overview.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,22 @@ Note that the version of Pymunk used must be the same for the code saving as
311311
the version used when loading the saved object.
312312

313313

314+
Asserts and error handling
315+
==========================
316+
317+
Pymunk uses asserts to guard against bad input, for example to guard against
318+
adding the same Shape twice to a Space. Should an assert fail it can be
319+
handled the normal Python way, for example with a try/catch.
320+
321+
There are also asserts deeper in Pymunk, in the underlying Chipmunk library.
322+
These guards against both bad input that is not possible to check from the
323+
Pymunk side, and against bad simulation state that can happen for various
324+
reasons in the middle of the simulation. These are normally not recoverable,
325+
and will result in a hard crash if failed. The problem will be logged using
326+
the standard Python logging module, with the logger name "pymunk" (or a child
327+
of it).
328+
329+
314330
Additional info
315331
===============
316332

pymunk/__init__.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@
3030
This is the main containing module of Pymunk. It contains among other things
3131
the very central Space, Body and Shape classes.
3232
33+
Pymunk uses the standard logging module to log helpful information. It does
34+
that under the "pymunk" name. If you do not do anything setup, it will print
35+
WARNING and higher messages to stderr. (Note that you most likely do not want
36+
to set logLevel to DEBUG, since Pymunk might log a lot of debug level
37+
messages mostly useful during development of Pymunk itself.)
38+
3339
"""
3440

3541
__docformat__ = "reStructuredText"
@@ -69,10 +75,6 @@
6975
cp = _chipmunk_cffi.lib
7076
ffi = _chipmunk_cffi.ffi
7177

72-
import logging
73-
74-
logging.getLogger(__name__).addHandler(logging.NullHandler())
75-
# logging.basicConfig(level=0)
7678

7779
from . import _version
7880
from .arbiter import Arbiter
@@ -89,6 +91,10 @@
8991
from .transform import Transform
9092
from .vec2d import Vec2d
9193

94+
# import logging
95+
# logging.getLogger(__name__).addHandler(logging.NullHandler())
96+
# logging.basicConfig(level=0)
97+
9298
version: str = _version.version
9399
"""The release version of this pymunk installation.
94100
Valid only if pymunk was installed from a source or binary

pymunk/_callbacks.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,3 +313,9 @@ def ext_cpDampedRotarySpringTorqueFunc(
313313
def ext_cpArbiterIteratorFunc(_arbiter, data): # type: ignore
314314
arbiters = ffi.from_handle(data)
315315
arbiters.append(_arbiter)
316+
317+
318+
# cpMessage / log override
319+
@ffi.def_extern()
320+
def ext_pyLog(formattedMessage):
321+
_logger.error(ffi.string(formattedMessage).decode())

pymunk/pymunk_extension_build.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
include_dirs=[os.path.join("Chipmunk2D", "include")],
7979
sources=sources,
8080
libraries=libraries,
81+
define_macros=[("CP_OVERRIDE_MESSAGE", None)],
8182
)
8283

8384
if __name__ == "__main__":

pymunk_cffi/callbacks_cdef.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,6 @@ extern "Python" {
4343
cpFloat ext_cpMarchSampleFunc(cpVect point, void *data);
4444
void ext_cpMarchSegmentFunc(cpVect v0, cpVect v1, void *data);
4545

46+
// custom method for logging (override of CP_MESSAGE)
47+
void ext_pyLog(const char *formattedMessage);
4648
}

pymunk_cffi/extensions.c

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
#include <stdio.h>
2+
#include <stdarg.h>
3+
14
#include "chipmunk/chipmunk_private.h"
25

36
//
@@ -455,4 +458,33 @@ cpFloat defaultSpringForce(cpDampedSpring *spring, cpFloat dist){
455458

456459
cpFloat defaultSpringTorque(cpDampedRotarySpring *spring, cpFloat relativeAngle){
457460
return (relativeAngle - spring->restAngle)*spring->stiffness;
458-
}
461+
}
462+
463+
464+
//
465+
// Functions to forward logs (printfs) to python code instead of directly printing to stderr
466+
//
467+
468+
//Python side, already formatted message
469+
void ext_pyLog(const char *formattedMessage);
470+
471+
//Chipmunk side, follows existing function declaration
472+
void cpMessage(const char *condition, const char *file, int line, int isError, int isHardError, const char *message, ...)
473+
{
474+
ext_pyLog((isError ? "Aborting due to Chipmunk error: " : "Chipmunk warning: "));
475+
476+
static char formattedMessage[256];
477+
formattedMessage[0] = 0;
478+
479+
va_list vargs;
480+
va_start(vargs, message); {
481+
vsnprintf(formattedMessage, sizeof(formattedMessage), message, vargs);
482+
ext_pyLog(formattedMessage);
483+
} va_end(vargs);
484+
485+
snprintf(formattedMessage, sizeof(formattedMessage), "\tFailed condition: %s", condition);
486+
ext_pyLog(formattedMessage);
487+
488+
snprintf(formattedMessage, sizeof(formattedMessage), "\tSource: %s:%d", file, line);
489+
ext_pyLog(formattedMessage);
490+
}

0 commit comments

Comments
 (0)