Skip to content

Commit b811939

Browse files
committed
Added context manager to ignore Unicode<Decode/Encode>Error
1 parent 15cd667 commit b811939

File tree

1 file changed

+47
-0
lines changed
  • addons/source-python/packages/source-python/core

1 file changed

+47
-0
lines changed

addons/source-python/packages/source-python/core/__init__.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@
66
# >> IMPORTS
77
# =============================================================================
88
# Python Imports
9+
# Codecs
10+
import codecs
911
# Collections
1012
from collections import defaultdict
13+
# Contextlib
14+
from contextlib import contextmanager
1115
# Inspect
1216
from inspect import getmodule
1317
from inspect import stack
@@ -33,6 +37,7 @@
3337
from paths import GAME_PATH
3438

3539

40+
3641
# =============================================================================
3742
# >> FORWARD IMPORTS
3843
# =============================================================================
@@ -57,6 +62,7 @@
5762
'console_message',
5863
'echo_console',
5964
'get_interface',
65+
'ignore_unicode_errors',
6066
)
6167

6268

@@ -156,3 +162,44 @@ def echo_console(text):
156162
"""
157163
for line in text.split('\n'):
158164
console_message(line + '\n')
165+
166+
@contextmanager
167+
def ignore_unicode_errors(errors='ignore'):
168+
"""Overwrite the ``strict`` codecs error handler temporarily.
169+
170+
This is useful e.g. if the engine truncates a string, which results in a
171+
string that contains a splitted multi-byte character at the end of the
172+
string.
173+
174+
:param str errors:
175+
Error handler that will be looked up via :func:`codecs.lookup_error`.
176+
:raise LookupError:
177+
Raised if the error handler was not found.
178+
179+
Example:
180+
181+
.. code:: python
182+
183+
import memory
184+
185+
# Allocate four bytes to create an erroneous string
186+
ptr = memory.alloc(4)
187+
188+
# Write data to the memory that will usually result in a
189+
# UnicodeDecodeError
190+
ptr.set_uchar(ord('a'), 0)
191+
ptr.set_uchar(ord('b'), 1)
192+
ptr.set_uchar(226, 2) # Add the invalid byte
193+
ptr.set_uchar(0, 3) # Indicate the end of the string
194+
195+
with ignore_unicode_errors():
196+
# Read the data as a string. Now, it will only print 'ab', because
197+
# the invalid byte has been removed/ignored.
198+
print(ptr.get_string_array())
199+
"""
200+
old_handler = codecs.lookup_error('strict')
201+
codecs.register_error('strict', codecs.lookup_error(errors))
202+
try:
203+
yield
204+
finally:
205+
codecs.register_error('strict', old_handler)

0 commit comments

Comments
 (0)