Skip to content

Commit 44beef1

Browse files
committed
Finishing touches.
1 parent 01f9bff commit 44beef1

File tree

9 files changed

+104
-48
lines changed

9 files changed

+104
-48
lines changed

buildconfig/stubs/gen_stubs.py

+1-7
Original file line numberDiff line numberDiff line change
@@ -104,15 +104,9 @@ def get_all(mod: Any):
104104
except KeyError:
105105
pygame_all_imports[f".{k}"] = val
106106

107-
# this is overriden by __init__.py
108-
if ".base" in pygame_all_imports and "warn" in pygame_all_imports[".base"]:
109-
pygame_all_imports[".base"].remove("warn")
110107

111108
# misc stubs that must be added to __init__.pyi
112-
misc_stubs = """from typing import Type
113-
114-
def warn(message: str, urgency: int, level: int = 2, category: Type[Warning] = UserWarning): ...
115-
"""
109+
misc_stubs = """"""
116110

117111
# write constants.pyi file
118112
constants_file = pathlib.Path(__file__).parent / "pygame" / "constants.pyi"

buildconfig/stubs/pygame/__init__.pyi

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
# buildconfig/stubs/gen_stubs.py
22
# A script to auto-generate locals.pyi, constants.pyi, debug.pyi and __init__.pyi typestubs
33
# IMPORTANT NOTE: Do not edit this file by hand!
4-
from typing import Type
5-
6-
def warn(message: str, urgency: int, level: int = 2, category: Type[Warning] = UserWarning): ...
74

85
from pygame import (
96
display as display,
@@ -74,6 +71,7 @@ from .base import (
7471
register_quit as register_quit,
7572
set_error as set_error,
7673
set_warnings_filter as set_warnings_filter,
74+
warn as warn,
7775
)
7876

7977
from .rwobject import (

buildconfig/stubs/pygame/base.pyi

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@ def register_quit(callable: Callable[[], Any], /) -> None: ...
1919

2020
# undocumented part of pygame API, kept here to make stubtest happy
2121
def get_array_interface(arg: Any, /) -> dict: ...
22-
def warn(message: str, category: Type[Warning], level: int, urgency: int, /): ...
22+
def warn(message: str, urgency: int, level: int = 1, category: Type[Warning] = UserWarning): ...
2323
def get_warnings_filter() -> int: ...
2424
def set_warnings_filter(val: int, /): ...

buildconfig/stubs/pygame/debug.pyi

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
# buildconfig/stubs/gen_stubs.py
22
# A script to auto-generate locals.pyi, constants.pyi, debug.pyi and __init__.pyi typestubs
33
# IMPORTANT NOTE: Do not edit this file by hand!
4-
from typing import Type
5-
6-
def warn(message: str, urgency: int, level: int = 2, category: Type[Warning] = UserWarning): ...
74

85
from pygame import (
96
display as display,
@@ -74,6 +71,7 @@ from .base import (
7471
register_quit as register_quit,
7572
set_error as set_error,
7673
set_warnings_filter as set_warnings_filter,
74+
warn as warn,
7775
)
7876

7977
from .rwobject import (

docs/reST/ref/pygame.rst

+32-4
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ object instead of the module, which can be used to test for availability.
227227
.. function:: warn
228228

229229
| :sl:`throws a warning`
230-
| :sg:`warn(message, urgency, level=2, category=UserWarning)`
230+
| :sg:`warn(message, urgency, level=1, category=UserWarning)`
231231
232232
Throws a warning with a given urgency. See documentation for :c:func:`pgWarn` for more information on urgency system.
233233

@@ -236,14 +236,17 @@ object instead of the module, which can be used to test for availability.
236236

237237
.. note::
238238
This function is mostly used internally, but might be also useful for extensions.
239-
Arg ``level`` denotes how much to trace back in the call stack.
240-
Beware, that the default value is 2, meaning the caller of a function with ``pygame.warn(...)`` will be blamed: ::
239+
Arg ``level`` denotes how much to trace back in the call stack. If it is equal to 0, that means that the caller wil be blamed.
240+
Beware, that the default value is 1, meaning the caller of a function with ``pygame.warn(...)`` will be blamed: ::
241241
242242
>>> def my_func():
243243
... pygame.warn("Warning!", urgency=0)
244244
...
245245
>>> my_func()
246-
<stdin>:1: UserWarning: Warning! (0: urgent)
246+
<stdin>:1: UserWarning: Warning! (urgent: 0)
247+
>>> def my_func2():
248+
... pygame.warn("Warning!", urgency=0, level=0)
249+
<stdin>:2: UserWarning: Warning! (urgent: 0)
247250

248251
.. # pygame.warn ""
249252
@@ -584,4 +587,29 @@ This hint only affects the windows platform, other platforms can control DPI awa
584587
via a Window creation keyword parameter called "allow_high_dpi".
585588

586589

590+
:mod:`pygame.debug`
591+
=====================
592+
593+
.. module:: pygame.debug
594+
:synopsis: small plug-in for enabling debugging information
595+
596+
| :sl:`small plug-in for enabling debugging information`
597+
598+
This is a simple plug-in that can be used as a drop-in repleacement for ``import pygame`` and imports alike.
599+
Example usage: ::
600+
601+
import pygame.debug as pg # works the same as "import pygame as pg"
602+
603+
window = pg.display.set_mode((100, 100))
604+
605+
while True:
606+
for event in pg.event.get():
607+
if event.type == pg.QUIT:
608+
pg.quit()
609+
quit()
610+
611+
pg.display.flip()
612+
613+
Doing this will enable more detailed warnings and will print additional debug information.
614+
(Side note: this will automatically call ``pygame.init()`` to make debug information more complete, but this shouldn't have any side effects.)
587615

src_c/base.c

+65-8
Original file line numberDiff line numberDiff line change
@@ -2088,28 +2088,85 @@ pg_EnvShouldBlendAlphaSDL2(void)
20882088
return pg_env_blend_alpha_SDL2;
20892089
}
20902090

2091+
static inline int
2092+
intSizeAsStr(int num)
2093+
{
2094+
if (num == 0) {
2095+
// printf("i s=1, zero");
2096+
return 1;
2097+
}
2098+
else if (num < 0) {
2099+
// printf("i s=%i, neg", ceil(log10(-num + 1)) + 1);
2100+
return ceil(log10(-num + 1)) + 1;
2101+
}
2102+
return ceil(log10(num + 1));
2103+
}
2104+
20912105
static int
20922106
pgWarn(PyObject *category, const char *message, Py_ssize_t stack_level,
20932107
int urgency)
20942108
{
20952109
if (pg_warn_filter < urgency)
20962110
return 0;
2097-
return PyErr_WarnEx(category, message, stack_level);
2111+
2112+
const char *extra;
2113+
2114+
switch (urgency) {
2115+
case 0:
2116+
extra = "urgent: ";
2117+
break;
2118+
case 1:
2119+
extra = "mild: ";
2120+
break;
2121+
case 2:
2122+
extra = "note: ";
2123+
break;
2124+
default:
2125+
extra = "";
2126+
}
2127+
2128+
// 12 3 4
2129+
// "message (extra{urgency})\0"
2130+
printf("%s (%s%i)\n", message, extra, urgency);
2131+
printf("%lu, %lu, %i\n", strlen(message), strlen(extra),
2132+
intSizeAsStr(urgency));
2133+
size_t str_size =
2134+
strlen(message) + strlen(extra) + intSizeAsStr(urgency) + 4;
2135+
2136+
char *formatted = malloc(str_size);
2137+
if (formatted == NULL) {
2138+
PyErr_SetString(PyExc_MemoryError,
2139+
"cannot allocate memory to format warning message");
2140+
return -1;
2141+
}
2142+
2143+
PyOS_snprintf(formatted, str_size, "%s (%s%i)", message, extra, urgency);
2144+
2145+
int ret = PyErr_WarnEx(category, formatted, stack_level);
2146+
free(formatted);
2147+
return ret;
20982148
}
20992149

21002150
static PyObject *
2101-
pg_warn(PyObject *self, PyObject *args)
2151+
pg_warn(PyObject *self, PyObject *args, PyObject *kwargs)
21022152
{
2103-
PyObject *category;
2153+
PyObject *category = NULL;
21042154
const char *message;
2105-
Py_ssize_t stack_level;
2155+
Py_ssize_t stack_level = -1;
21062156
int urgency;
2157+
char *kw_names[] = {"message", "urgency", "level", "category", NULL};
21072158

2108-
if (!PyArg_ParseTuple(args, "sOni", &message, &category, &stack_level,
2109-
&urgency))
2159+
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "si|nO", kw_names, &message,
2160+
&urgency, &stack_level, &category))
21102161
return NULL;
21112162

2112-
if (pgWarn(category, message, stack_level, urgency) < 0)
2163+
if (category == NULL)
2164+
category = PyExc_UserWarning;
2165+
2166+
if (stack_level < 0)
2167+
stack_level = 1;
2168+
2169+
if (pgWarn(category, message, stack_level + 1, urgency) < 0)
21132170
return NULL;
21142171

21152172
Py_RETURN_NONE;
@@ -2246,7 +2303,7 @@ static PyMethodDef _base_methods[] = {
22462303

22472304
{"get_array_interface", (PyCFunction)pg_get_array_interface, METH_O,
22482305
"return an array struct interface as an interface dictionary"},
2249-
{"warn", (PyCFunction)pg_warn, METH_VARARGS,
2306+
{"warn", (PyCFunction)pg_warn, METH_VARARGS | METH_KEYWORDS,
22502307
"throw a warning with a given severity which is only used for filtering"},
22512308
{"get_warnings_filter", (PyCFunction)pg_get_warnings_filter, METH_NOARGS,
22522309
"get value of a warning filter by severity (smaller number - more "

src_c/doc/pygame_doc.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@
1313
#define DOC_ENCODESTRING "encode_string([obj [, encoding [, errors [, etype]]]]) -> bytes or None\nEncode a Unicode or bytes object"
1414
#define DOC_ENCODEFILEPATH "encode_file_path([obj [, etype]]) -> bytes or None\nEncode a Unicode or bytes object as a file system path"
1515
#define DOC_PRINTDEBUGINFO "print_debug_info(filename=None) -> None\nretrieves useful information for debugging and issue-reporting purposes"
16-
#define DOC_WARN "warn(message, urgency, level=2, category=UserWarning)\nthrows a warning"
16+
#define DOC_WARN "warn(message, urgency, level=1, category=UserWarning)\nthrows a warning"
1717
#define DOC_VERSION "small module containing version information"
1818
#define DOC_VERSION_VER "ver = '1.2'\nversion number as a string"
1919
#define DOC_VERSION_VERNUM "vernum = (1, 5, 3)\ntupled integers of the version"
2020
#define DOC_VERSION_REV "rev = 'a6f89747b551+'\nrepository revision of the build"
2121
#define DOC_VERSION_SDL "SDL = '(2, 26, 5)'\ntupled integers of the SDL library version"
22+
#define DOC_DEBUG "small plug-in for enabling debugging information"

src_py/__init__.py

-20
Original file line numberDiff line numberDiff line change
@@ -94,26 +94,6 @@ def _attribute_undefined(name):
9494
from pygame.constants import * # now has __all__ pylint: disable=wildcard-import; lgtm[py/polluting-import]
9595
from pygame.version import * # pylint: disable=wildcard-import; lgtm[py/polluting-import]
9696

97-
_warn = warn
98-
del warn
99-
100-
101-
def warn(message, urgency, level=2, category=UserWarning): # pylint: disable=function-redefined
102-
"""Throws a warning with a given urgency"""
103-
names = {0: "urgent", 1: "mild", 2: "note"}
104-
105-
if urgency in names:
106-
note = f"{urgency}: {names[urgency]}"
107-
else:
108-
note = str(urgency)
109-
110-
_warn(
111-
f"{message} ({note})",
112-
category,
113-
level + 1,
114-
urgency,
115-
)
116-
11797

11898
from pygame.rect import Rect, FRect
11999
from pygame.rwobject import encode_string, encode_file_path

test/base_test.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ def test_warn(self):
629629
self._warn("message", 0)
630630
self.assertEqual(len(cx.warnings), 1)
631631
warning = cx.warnings[0]
632-
self.assertEqual(str(warning.message), "message (0: urgent)")
632+
self.assertEqual(str(warning.message), "message (urgent: 0)")
633633
self.assertIn("base_test.py", warning.filename)
634634

635635
with self.assertWarns(UserWarning) as cx:

0 commit comments

Comments
 (0)