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""" Node for the calls to the 'int' and 'long' (Python2) built-ins. 19 20These are divided into variants for one and two arguments and they have a 21common base class, because most of the behavior is the same there. The ones 22with 2 arguments only work on strings, and give errors otherwise, the ones 23with one argument, use slots, "__int__" and "__long__", so what they do does 24largely depend on the arguments slot. 25""" 26 27from nuitka.__past__ import long # pylint: disable=I0021,redefined-builtin 28from nuitka.PythonVersions import python_version 29from nuitka.specs import BuiltinParameterSpecs 30 31from .ConstantRefNodes import makeConstantRefNode 32from .ExpressionBases import ( 33 ExpressionChildHavingBase, 34 ExpressionChildrenHavingBase, 35 ExpressionSpecBasedComputationMixin, 36) 37from .shapes.BuiltinTypeShapes import ( 38 tshape_int_or_long, 39 tshape_int_or_long_derived, 40 tshape_long, 41 tshape_long_derived, 42) 43 44 45class ExpressionBuiltinInt1(ExpressionChildHavingBase): 46 kind = "EXPRESSION_BUILTIN_INT1" 47 48 named_child = "value" 49 50 def __init__(self, value, source_ref): 51 ExpressionChildHavingBase.__init__(self, value=value, source_ref=source_ref) 52 53 @staticmethod 54 def getTypeShape(): 55 # TODO: Depending on input type shape and value, we should improve this. 56 return tshape_int_or_long_derived 57 58 def computeExpression(self, trace_collection): 59 return self.subnode_value.computeExpressionInt( 60 int_node=self, trace_collection=trace_collection 61 ) 62 63 def mayRaiseException(self, exception_type): 64 return self.subnode_value.mayRaiseExceptionInt(exception_type) 65 66 67class ExpressionBuiltinIntLong2Base( 68 ExpressionSpecBasedComputationMixin, ExpressionChildrenHavingBase 69): 70 named_children = ("value", "base") 71 72 # Note: Version specific, may be allowed or not. 73 try: 74 int(base=2) 75 except TypeError: 76 base_only_value = False 77 else: 78 base_only_value = True 79 80 # To be overloaded by child classes with int/long. 81 builtin = int 82 83 def __init__(self, value, base, source_ref): 84 if value is None and self.base_only_value: 85 value = makeConstantRefNode( 86 constant="0", source_ref=source_ref, user_provided=True 87 ) 88 89 ExpressionChildrenHavingBase.__init__( 90 self, values={"value": value, "base": base}, source_ref=source_ref 91 ) 92 93 def computeExpression(self, trace_collection): 94 value = self.subnode_value 95 base = self.subnode_base 96 97 if value is None: 98 if base is not None: 99 if not self.base_only_value: 100 return trace_collection.getCompileTimeComputationResult( 101 node=self, 102 computation=lambda: self.builtin(base=2), 103 description="""\ 104%s built-in call with only base argument""" 105 % self.builtin.__name__, 106 ) 107 108 given_values = () 109 else: 110 given_values = (value, base) 111 112 return self.computeBuiltinSpec( 113 trace_collection=trace_collection, given_values=given_values 114 ) 115 116 117class ExpressionBuiltinInt2(ExpressionBuiltinIntLong2Base): 118 kind = "EXPRESSION_BUILTIN_INT2" 119 120 builtin_spec = BuiltinParameterSpecs.builtin_int_spec 121 builtin = int 122 123 @staticmethod 124 def getTypeShape(): 125 return tshape_int_or_long 126 127 128if python_version < 0x300: 129 130 class ExpressionBuiltinLong1(ExpressionChildHavingBase): 131 kind = "EXPRESSION_BUILTIN_LONG1" 132 133 named_child = "value" 134 135 def __init__(self, value, source_ref): 136 ExpressionChildHavingBase.__init__(self, value=value, source_ref=source_ref) 137 138 @staticmethod 139 def getTypeShape(): 140 # TODO: Depending on input type shape and value, we should improve this. 141 return tshape_long_derived 142 143 def computeExpression(self, trace_collection): 144 return self.subnode_value.computeExpressionLong( 145 long_node=self, trace_collection=trace_collection 146 ) 147 148 def mayRaiseException(self, exception_type): 149 return self.subnode_value.mayRaiseExceptionLong(exception_type) 150 151 class ExpressionBuiltinLong2(ExpressionBuiltinIntLong2Base): 152 kind = "EXPRESSION_BUILTIN_LONG2" 153 154 builtin_spec = BuiltinParameterSpecs.builtin_long_spec 155 builtin = long 156 157 @staticmethod 158 def getTypeShape(): 159 return tshape_long 160