5
any_string_type = (bytes, str)
8
from contextlib import contextmanager
11
from threading import local as _threadlocal
13
class _threadlocal: pass
15
threadlocal = _threadlocal()
17
from ..Utils import open_new_file
18
from . import DebugFlags
22
class PyrexError(Exception):
26
class PyrexWarning(Exception):
29
class CannotSpecialize(PyrexError):
34
assert not (isinstance(source, any_string_type)), (
35
"Please replace filename strings with Scanning.FileSourceDescriptor instances %r" % source)
37
F = source.get_lines()
38
except UnicodeDecodeError:
40
s = "[unprintable code]\n"
42
s = ''.join(F[max(0, position[1]-6):position[1]])
43
s = '...\n%s%s^\n' % (s, ' '*(position[2]))
44
s = '%s\n%s%s\n' % ('-'*60, s, '-'*60)
47
def format_position(position):
49
return "%s:%d:%d: " % (position[0].get_error_description(),
50
position[1], position[2])
53
def format_error(message, position):
55
pos_str = format_position(position)
56
cont = context(position)
57
message = '\nError compiling Cython file:\n%s\n%s%s' % (cont, pos_str, message or '')
60
class CompileError(PyrexError):
62
def __init__(self, position = None, message = ""):
63
self.position = position
64
self.message_only = message
65
self.formatted_message = format_error(message, position)
67
Exception.__init__(self, self.formatted_message)
70
self.args = (position, message)
73
return self.formatted_message
75
class CompileWarning(PyrexWarning):
77
def __init__(self, position = None, message = ""):
78
self.position = position
79
Exception.__init__(self, format_position(position) + message)
81
class InternalError(Exception):
84
def __init__(self, message):
85
self.message_only = message
86
Exception.__init__(self, "Internal compiler error: %s"
89
class AbortError(Exception):
92
def __init__(self, message):
93
self.message_only = message
94
Exception.__init__(self, "Abort error: %s" % message)
96
class CompilerCrash(CompileError):
98
def __init__(self, pos, context, message, cause, stacktrace=None):
100
message = '\n' + message
103
self.message_only = message
105
message = "Compiler crash in %s%s" % (context, message)
109
'\n\nCompiler crash traceback from this point on:\n' +
110
''.join(traceback.format_tb(stacktrace)))
114
message += '%s: %s' % (cause.__class__.__name__, cause)
115
CompileError.__init__(self, pos, message)
118
self.args = (pos, context, message, cause, stacktrace)
120
class NoElementTreeInstalledException(PyrexError):
121
"""raised when the user enabled options.gdb_debug but no ElementTree
122
implementation was found
125
def open_listing_file(path, echo_to_stderr=True):
129
threadlocal.cython_errors_listing_file = open_new_file(path)
131
threadlocal.cython_errors_listing_file = None
133
threadlocal.cython_errors_echo_file = sys.stderr
135
threadlocal.cython_errors_echo_file = None
136
threadlocal.cython_errors_count = 0
138
def close_listing_file():
139
if threadlocal.cython_errors_listing_file:
140
threadlocal.cython_errors_listing_file.close()
141
threadlocal.cython_errors_listing_file = None
143
def report_error(err, use_stack=True):
144
error_stack = threadlocal.cython_errors_stack
145
if error_stack and use_stack:
146
error_stack[-1].append(err)
149
if err.reported: return
151
try: line = "%s\n" % err
152
except UnicodeEncodeError:
154
line = format_error(getattr(err, 'message_only', "[unprintable exception message]"),
155
getattr(err, 'position', None)) + '\n'
156
listing_file = threadlocal.cython_errors_listing_file
158
try: listing_file.write(line)
159
except UnicodeEncodeError:
160
listing_file.write(line.encode('ASCII', 'replace'))
161
echo_file = threadlocal.cython_errors_echo_file
163
try: echo_file.write(line)
164
except UnicodeEncodeError:
165
echo_file.write(line.encode('ASCII', 'replace'))
166
threadlocal.cython_errors_count += 1
167
if Options.fast_fail:
168
raise AbortError("fatal errors")
170
def error(position, message):
173
raise InternalError(message)
174
err = CompileError(position, message)
175
if DebugFlags.debug_exception_on_error: raise Exception(err)
182
def _write_file_encode(file, line):
185
except UnicodeEncodeError:
186
file.write(line.encode('ascii', 'replace'))
189
def performance_hint(position, message, env):
190
if not env.directives['show_performance_hints']:
192
warn = CompileWarning(position, message)
193
line = "performance hint: %s\n" % warn
194
listing_file = threadlocal.cython_errors_listing_file
196
_write_file_encode(listing_file, line)
197
echo_file = threadlocal.cython_errors_echo_file
199
_write_file_encode(echo_file, line)
203
def message(position, message, level=1):
206
warn = CompileWarning(position, message)
207
line = "note: %s\n" % warn
208
listing_file = threadlocal.cython_errors_listing_file
210
_write_file_encode(listing_file, line)
211
echo_file = threadlocal.cython_errors_echo_file
213
_write_file_encode(echo_file, line)
217
def warning(position, message, level=0):
220
if Options.warning_errors and position:
221
return error(position, message)
222
warn = CompileWarning(position, message)
223
line = "warning: %s\n" % warn
224
listing_file = threadlocal.cython_errors_listing_file
226
_write_file_encode(listing_file, line)
227
echo_file = threadlocal.cython_errors_echo_file
229
_write_file_encode(echo_file, line)
233
def warn_once(position, message, level=0):
236
warn_once_seen = threadlocal.cython_errors_warn_once_seen
237
if message in warn_once_seen:
239
warn = CompileWarning(position, message)
240
line = "warning: %s\n" % warn
241
listing_file = threadlocal.cython_errors_listing_file
243
_write_file_encode(listing_file, line)
244
echo_file = threadlocal.cython_errors_echo_file
246
_write_file_encode(echo_file, line)
247
warn_once_seen.add(message)
255
threadlocal.cython_errors_stack.append(errors)
259
def release_errors(ignore=False):
260
held_errors = threadlocal.cython_errors_stack.pop()
262
for err in held_errors:
267
return threadlocal.cython_errors_stack[-1]
273
def local_errors(ignore=False):
274
errors = hold_errors()
278
release_errors(ignore=ignore)
284
threadlocal.cython_errors_count = 0
285
threadlocal.cython_errors_listing_file = None
286
threadlocal.cython_errors_echo_file = None
287
threadlocal.cython_errors_warn_once_seen = set()
288
threadlocal.cython_errors_stack = []
291
threadlocal.cython_errors_warn_once_seen.clear()
292
del threadlocal.cython_errors_stack[:]
294
def get_errors_count():
295
return threadlocal.cython_errors_count