summaryrefslogtreecommitdiffstats
path: root/contrib/tools/cython/Cython/Compiler/Errors.py
diff options
context:
space:
mode:
authornik-bes <[email protected]>2025-05-19 07:20:13 +0300
committernik-bes <[email protected]>2025-05-19 07:36:02 +0300
commit317b7368e24941ff76499f500579fd9b10f6656e (patch)
treeabbcbaea595e7d2e9f23cf59a408b3082fe4340d /contrib/tools/cython/Cython/Compiler/Errors.py
parent6b666a52d40308ab9b3532cd8d3008b9f37cfffb (diff)
Update Cython to 3.0.10.
commit_hash:b43c96b868cd36d636192fd2c6024d9f0d2fb6f8
Diffstat (limited to 'contrib/tools/cython/Cython/Compiler/Errors.py')
-rw-r--r--contrib/tools/cython/Cython/Compiler/Errors.py137
1 files changed, 86 insertions, 51 deletions
diff --git a/contrib/tools/cython/Cython/Compiler/Errors.py b/contrib/tools/cython/Cython/Compiler/Errors.py
index 9761b52c32f..f3be0fd8b02 100644
--- a/contrib/tools/cython/Cython/Compiler/Errors.py
+++ b/contrib/tools/cython/Cython/Compiler/Errors.py
@@ -12,6 +12,13 @@ except ImportError:
import sys
from contextlib import contextmanager
+try:
+ from threading import local as _threadlocal
+except ImportError:
+ class _threadlocal(object): pass
+
+threadlocal = _threadlocal()
+
from ..Utils import open_new_file
from . import DebugFlags
from . import Options
@@ -24,6 +31,8 @@ class PyrexError(Exception):
class PyrexWarning(Exception):
pass
+class CannotSpecialize(PyrexError):
+ pass
def context(position):
source = position[0]
@@ -36,7 +45,7 @@ def context(position):
s = u"[unprintable code]\n"
else:
s = u''.join(F[max(0, position[1]-6):position[1]])
- s = u'...\n%s%s^\n' % (s, u' '*(position[2]-1))
+ s = u'...\n%s%s^\n' % (s, u' '*(position[2]))
s = u'%s\n%s%s\n' % (u'-'*60, s, u'-'*60)
return s
@@ -60,11 +69,9 @@ class CompileError(PyrexError):
self.message_only = message
self.formatted_message = format_error(message, position)
self.reported = False
- # Deprecated and withdrawn in 2.6:
- # self.message = message
Exception.__init__(self, self.formatted_message)
# Python Exception subclass pickling is broken,
- # see http://bugs.python.org/issue1692335
+ # see https://bugs.python.org/issue1692335
self.args = (position, message)
def __str__(self):
@@ -74,8 +81,6 @@ class CompileWarning(PyrexWarning):
def __init__(self, position = None, message = ""):
self.position = position
- # Deprecated and withdrawn in 2.6:
- # self.message = message
Exception.__init__(self, format_position(position) + message)
class InternalError(Exception):
@@ -114,7 +119,7 @@ class CompilerCrash(CompileError):
message += u'%s: %s' % (cause.__class__.__name__, cause)
CompileError.__init__(self, pos, message)
# Python Exception subclass pickling is broken,
- # see http://bugs.python.org/issue1692335
+ # see https://bugs.python.org/issue1692335
self.args = (pos, context, message, cause, stacktrace)
class NoElementTreeInstalledException(PyrexError):
@@ -122,35 +127,29 @@ class NoElementTreeInstalledException(PyrexError):
implementation was found
"""
-listing_file = None
-num_errors = 0
-echo_file = None
-
-def open_listing_file(path, echo_to_stderr = 1):
+def open_listing_file(path, echo_to_stderr=True):
# Begin a new error listing. If path is None, no file
# is opened, the error counter is just reset.
- global listing_file, num_errors, echo_file
if path is not None:
- listing_file = open_new_file(path)
+ threadlocal.cython_errors_listing_file = open_new_file(path)
else:
- listing_file = None
+ threadlocal.cython_errors_listing_file = None
if echo_to_stderr:
- echo_file = sys.stderr
+ threadlocal.cython_errors_echo_file = sys.stderr
else:
- echo_file = None
- num_errors = 0
+ threadlocal.cython_errors_echo_file = None
+ threadlocal.cython_errors_count = 0
def close_listing_file():
- global listing_file
- if listing_file:
- listing_file.close()
- listing_file = None
+ if threadlocal.cython_errors_listing_file:
+ threadlocal.cython_errors_listing_file.close()
+ threadlocal.cython_errors_listing_file = None
def report_error(err, use_stack=True):
+ error_stack = threadlocal.cython_errors_stack
if error_stack and use_stack:
error_stack[-1].append(err)
else:
- global num_errors
# See Main.py for why dual reporting occurs. Quick fix for now.
if err.reported: return
err.reported = True
@@ -159,41 +158,64 @@ def report_error(err, use_stack=True):
# Python <= 2.5 does this for non-ASCII Unicode exceptions
line = format_error(getattr(err, 'message_only', "[unprintable exception message]"),
getattr(err, 'position', None)) + u'\n'
+ listing_file = threadlocal.cython_errors_listing_file
if listing_file:
try: listing_file.write(line)
except UnicodeEncodeError:
listing_file.write(line.encode('ASCII', 'replace'))
+ echo_file = threadlocal.cython_errors_echo_file
if echo_file:
try: echo_file.write(line)
except UnicodeEncodeError:
echo_file.write(line.encode('ASCII', 'replace'))
- num_errors += 1
+ threadlocal.cython_errors_count += 1
if Options.fast_fail:
raise AbortError("fatal errors")
-
def error(position, message):
#print("Errors.error:", repr(position), repr(message)) ###
if position is None:
raise InternalError(message)
err = CompileError(position, message)
- if DebugFlags.debug_exception_on_error: raise Exception(err) # debug
+ if DebugFlags.debug_exception_on_error: raise Exception(err) # debug
report_error(err)
return err
-LEVEL = 1 # warn about all errors level 1 or higher
+LEVEL = 1 # warn about all errors level 1 or higher
+
+def _write_file_encode(file, line):
+ try:
+ file.write(line)
+ except UnicodeEncodeError:
+ file.write(line.encode('ascii', 'replace'))
+
+
+def performance_hint(position, message, env):
+ if not env.directives['show_performance_hints']:
+ return
+ warn = CompileWarning(position, message)
+ line = "performance hint: %s\n" % warn
+ listing_file = threadlocal.cython_errors_listing_file
+ if listing_file:
+ _write_file_encode(listing_file, line)
+ echo_file = threadlocal.cython_errors_echo_file
+ if echo_file:
+ _write_file_encode(echo_file, line)
+ return warn
def message(position, message, level=1):
if level < LEVEL:
return
warn = CompileWarning(position, message)
- line = "note: %s\n" % warn
+ line = u"note: %s\n" % warn
+ listing_file = threadlocal.cython_errors_listing_file
if listing_file:
- listing_file.write(line)
+ _write_file_encode(listing_file, line)
+ echo_file = threadlocal.cython_errors_echo_file
if echo_file:
- echo_file.write(line)
+ _write_file_encode(echo_file, line)
return warn
@@ -203,63 +225,76 @@ def warning(position, message, level=0):
if Options.warning_errors and position:
return error(position, message)
warn = CompileWarning(position, message)
- line = "warning: %s\n" % warn
+ line = u"warning: %s\n" % warn
+ listing_file = threadlocal.cython_errors_listing_file
if listing_file:
- listing_file.write(line)
+ _write_file_encode(listing_file, line)
+ echo_file = threadlocal.cython_errors_echo_file
if echo_file:
- echo_file.write(line)
+ _write_file_encode(echo_file, line)
return warn
-_warn_once_seen = {}
def warn_once(position, message, level=0):
- if level < LEVEL or message in _warn_once_seen:
+ if level < LEVEL:
+ return
+ warn_once_seen = threadlocal.cython_errors_warn_once_seen
+ if message in warn_once_seen:
return
warn = CompileWarning(position, message)
- line = "warning: %s\n" % warn
+ line = u"warning: %s\n" % warn
+ listing_file = threadlocal.cython_errors_listing_file
if listing_file:
- listing_file.write(line)
+ _write_file_encode(listing_file, line)
+ echo_file = threadlocal.cython_errors_echo_file
if echo_file:
- echo_file.write(line)
- _warn_once_seen[message] = True
+ _write_file_encode(echo_file, line)
+ warn_once_seen.add(message)
return warn
# These functions can be used to momentarily suppress errors.
-error_stack = []
-
-
def hold_errors():
- error_stack.append([])
+ errors = []
+ threadlocal.cython_errors_stack.append(errors)
+ return errors
def release_errors(ignore=False):
- held_errors = error_stack.pop()
+ held_errors = threadlocal.cython_errors_stack.pop()
if not ignore:
for err in held_errors:
report_error(err)
def held_errors():
- return error_stack[-1]
+ return threadlocal.cython_errors_stack[-1]
# same as context manager:
@contextmanager
def local_errors(ignore=False):
- errors = []
- error_stack.append(errors)
+ errors = hold_errors()
try:
yield errors
finally:
release_errors(ignore=ignore)
-# this module needs a redesign to support parallel cythonisation, but
-# for now, the following works at least in sequential compiler runs
+# Keep all global state in thread local storage to support parallel cythonisation in distutils.
+
+def init_thread():
+ threadlocal.cython_errors_count = 0
+ threadlocal.cython_errors_listing_file = None
+ threadlocal.cython_errors_echo_file = None
+ threadlocal.cython_errors_warn_once_seen = set()
+ threadlocal.cython_errors_stack = []
def reset():
- _warn_once_seen.clear()
- del error_stack[:]
+ threadlocal.cython_errors_warn_once_seen.clear()
+ del threadlocal.cython_errors_stack[:]
+
+def get_errors_count():
+ return threadlocal.cython_errors_count