Commit e77528ab authored by Stefan Behnel's avatar Stefan Behnel

Use a context manager for holding back compile errors.

parent 0c6c64c0
...@@ -10,6 +10,7 @@ except ImportError: ...@@ -10,6 +10,7 @@ except ImportError:
any_string_type = (bytes, str) any_string_type = (bytes, str)
import sys import sys
from contextlib import contextmanager
from ..Utils import open_new_file from ..Utils import open_new_file
from . import DebugFlags from . import DebugFlags
...@@ -228,19 +229,34 @@ def warn_once(position, message, level=0): ...@@ -228,19 +229,34 @@ def warn_once(position, message, level=0):
error_stack = [] error_stack = []
def hold_errors(): def hold_errors():
error_stack.append([]) error_stack.append([])
def release_errors(ignore=False): def release_errors(ignore=False):
held_errors = error_stack.pop() held_errors = error_stack.pop()
if not ignore: if not ignore:
for err in held_errors: for err in held_errors:
report_error(err) report_error(err)
def held_errors(): def held_errors():
return error_stack[-1] return error_stack[-1]
# same as context manager:
@contextmanager
def local_errors(ignore=False):
errors = []
error_stack.append(errors)
try:
yield errors
finally:
release_errors(ignore=ignore)
# this module needs a redesign to support parallel cythonisation, but # this module needs a redesign to support parallel cythonisation, but
# for now, the following works at least in sequential compiler runs # for now, the following works at least in sequential compiler runs
......
...@@ -7,7 +7,7 @@ from __future__ import absolute_import ...@@ -7,7 +7,7 @@ from __future__ import absolute_import
import cython import cython
cython.declare(error=object, warning=object, warn_once=object, InternalError=object, cython.declare(error=object, warning=object, warn_once=object, InternalError=object,
CompileError=object, UtilityCode=object, TempitaUtilityCode=object, CompileError=object, UtilityCode=object, TempitaUtilityCode=object,
StringEncoding=object, operator=object, Options=object, StringEncoding=object, operator=object, local_errors=object, report_error=object,
Naming=object, Nodes=object, PyrexTypes=object, py_object_type=object, Naming=object, Nodes=object, PyrexTypes=object, py_object_type=object,
list_type=object, tuple_type=object, set_type=object, dict_type=object, list_type=object, tuple_type=object, set_type=object, dict_type=object,
unicode_type=object, str_type=object, bytes_type=object, type_type=object, unicode_type=object, str_type=object, bytes_type=object, type_type=object,
...@@ -21,13 +21,12 @@ import copy ...@@ -21,13 +21,12 @@ import copy
import os.path import os.path
import operator import operator
from .Errors import error, warning, warn_once, InternalError, CompileError from .Errors import (
from .Errors import hold_errors, release_errors, held_errors, report_error error, warning, InternalError, CompileError, report_error, local_errors)
from .Code import UtilityCode, TempitaUtilityCode from .Code import UtilityCode, TempitaUtilityCode
from . import StringEncoding from . import StringEncoding
from . import Naming from . import Naming
from . import Nodes from . import Nodes
from . import Options
from .Nodes import Node, utility_code_for_imports, analyse_type_annotation from .Nodes import Node, utility_code_for_imports, analyse_type_annotation
from . import PyrexTypes from . import PyrexTypes
from .PyrexTypes import py_object_type, c_long_type, typecast, error_type, \ from .PyrexTypes import py_object_type, c_long_type, typecast, error_type, \
...@@ -1363,7 +1362,7 @@ def _analyse_name_as_type(name, pos, env): ...@@ -1363,7 +1362,7 @@ def _analyse_name_as_type(name, pos, env):
type = PyrexTypes.parse_basic_type(name) type = PyrexTypes.parse_basic_type(name)
if type is not None: if type is not None:
return type return type
hold_errors() with local_errors(ignore=True):
from .TreeFragment import TreeFragment from .TreeFragment import TreeFragment
pos = (pos[0], pos[1], pos[2]-7) pos = (pos[0], pos[1], pos[2]-7)
try: try:
...@@ -1373,7 +1372,6 @@ def _analyse_name_as_type(name, pos, env): ...@@ -1373,7 +1372,6 @@ def _analyse_name_as_type(name, pos, env):
else: else:
sizeof_node = declaration.root.stats[0].expr sizeof_node = declaration.root.stats[0].expr
sizeof_node = sizeof_node.analyse_types(env) sizeof_node = sizeof_node.analyse_types(env)
release_errors(ignore=True)
if isinstance(sizeof_node, SizeofTypeNode): if isinstance(sizeof_node, SizeofTypeNode):
return sizeof_node.arg_type return sizeof_node.arg_type
return None return None
...@@ -7755,11 +7753,10 @@ class ListNode(SequenceNode): ...@@ -7755,11 +7753,10 @@ class ListNode(SequenceNode):
return node.coerce_to_pyobject(env) return node.coerce_to_pyobject(env)
def analyse_types(self, env): def analyse_types(self, env):
hold_errors() with local_errors(ignore=True) as errors:
self.original_args = list(self.args) self.original_args = list(self.args)
node = SequenceNode.analyse_types(self, env) node = SequenceNode.analyse_types(self, env)
node.obj_conversion_errors = held_errors() node.obj_conversion_errors = errors
release_errors(ignore=True)
if env.is_module_scope: if env.is_module_scope:
self.in_module_scope = True self.in_module_scope = True
node = node._create_merge_node_if_necessary(env) node = node._create_merge_node_if_necessary(env)
...@@ -8407,11 +8404,12 @@ class DictNode(ExprNode): ...@@ -8407,11 +8404,12 @@ class DictNode(ExprNode):
return dict_type return dict_type
def analyse_types(self, env): def analyse_types(self, env):
hold_errors() with local_errors(ignore=True) as errors:
self.key_value_pairs = [ item.analyse_types(env) self.key_value_pairs = [
for item in self.key_value_pairs ] item.analyse_types(env)
self.obj_conversion_errors = held_errors() for item in self.key_value_pairs
release_errors(ignore=True) ]
self.obj_conversion_errors = errors
return self return self
def may_be_none(self): def may_be_none(self):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment