1# Copyright 2021, Kay Hayen, mailto:kay.hayen@gmail.com 2# 3# Part of "Nuitka", an optimizing Python compiler that is compatible and 4# integrates with CPython, but also works on its own. 5# 6# Licensed under the Apache License, Version 2.0 (the "License"); 7# you may not use this file except in compliance with the License. 8# You may obtain a copy of the License at 9# 10# http://www.apache.org/licenses/LICENSE-2.0 11# 12# Unless required by applicable law or agreed to in writing, software 13# distributed under the License is distributed on an "AS IS" BASIS, 14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15# See the License for the specific language governing permissions and 16# limitations under the License. 17# 18""" Reformulation of assert statements. 19 20Consult the developer manual for information. TODO: Add ability to sync 21source code comments with developer manual sections. 22 23""" 24from nuitka.nodes.BuiltinRefNodes import ExpressionBuiltinExceptionRef 25from nuitka.nodes.ConditionalNodes import makeStatementConditional 26from nuitka.nodes.ContainerMakingNodes import makeExpressionMakeTuple 27from nuitka.nodes.ExceptionNodes import StatementRaiseException 28from nuitka.nodes.OperatorNodesUnary import ExpressionOperationNot 29from nuitka.Options import hasPythonFlagNoAsserts 30from nuitka.PythonVersions import python_version 31 32from .TreeHelpers import buildNode 33 34 35def buildAssertNode(provider, node, source_ref): 36 # Build assert statements. These are re-formulated as described in the 37 # developer manual too. They end up as conditional statement with raises of 38 # AssertionError exceptions. 39 40 # Underlying assumption: 41 # 42 # Assert x, y is the same as: 43 # if not x: 44 # raise AssertionError, y 45 46 # Therefore assert statements are really just conditional statements with a 47 # static raise contained. 48 # 49 50 exception_value = buildNode(provider, node.msg, source_ref, True) 51 52 if hasPythonFlagNoAsserts(): 53 return None 54 55 if exception_value is not None and python_version >= 0x272: 56 exception_value = makeExpressionMakeTuple( 57 elements=(exception_value,), source_ref=source_ref 58 ) 59 60 raise_statement = StatementRaiseException( 61 exception_type=ExpressionBuiltinExceptionRef( 62 exception_name="AssertionError", source_ref=source_ref 63 ), 64 exception_value=exception_value, 65 exception_trace=None, 66 exception_cause=None, 67 source_ref=source_ref, 68 ) 69 70 return makeStatementConditional( 71 condition=ExpressionOperationNot( 72 operand=buildNode(provider, node.test, source_ref), source_ref=source_ref 73 ), 74 yes_branch=raise_statement, 75 no_branch=None, 76 source_ref=source_ref, 77 ) 78