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""" Format related nodes format/bin/oct/hex/ascii. 19 20These will most often be used for outputs, and the hope is, the type prediction or the 21result prediction will help to be smarter, but generally these should not be that much 22about performance critical. 23 24""" 25from nuitka.PythonVersions import python_version 26from nuitka.specs import BuiltinParameterSpecs 27 28from .ExpressionBases import ( 29 ExpressionBuiltinSingleArgBase, 30 ExpressionChildrenHavingBase, 31) 32from .NodeMakingHelpers import makeStatementExpressionOnlyReplacementNode 33from .shapes.BuiltinTypeShapes import ( 34 tshape_int_or_long, 35 tshape_str, 36 tshape_str_or_unicode, 37) 38 39 40class ExpressionBuiltinFormat(ExpressionChildrenHavingBase): 41 kind = "EXPRESSION_BUILTIN_FORMAT" 42 43 named_children = ("value", "format_spec") 44 45 # Using slots, they don't need that 46 # pylint: disable=access-member-before-definition,attribute-defined-outside-init 47 48 def __init__(self, value, format_spec, source_ref): 49 ExpressionChildrenHavingBase.__init__( 50 self, 51 values={"value": value, "format_spec": format_spec}, 52 source_ref=source_ref, 53 ) 54 55 @staticmethod 56 def getTypeShape(): 57 return tshape_str_or_unicode 58 59 def computeExpression(self, trace_collection): 60 # TODO: Can use the format built-in on compile time constants at least. 61 62 value = self.subnode_value 63 format_spec = self.subnode_format_spec 64 65 # Go to default way if possible. 66 if format_spec is not None and format_spec.isExpressionConstantStrEmptyRef(): 67 self.subnode_format_spec = None 68 format_spec = None 69 70 # Strings format themselves as what they are. 71 if format_spec is None: 72 if value.hasShapeStrExact() or value.hasShapeUnicodeExact(): 73 return ( 74 value, 75 "new_expression", 76 """\ 77Removed useless 'format' on '%s' value.""" 78 % value.getTypeShape().getTypeName(), 79 ) 80 81 # TODO: Provide "__format__" slot based handling. 82 83 # Any code could be run, note that. 84 trace_collection.onControlFlowEscape(self) 85 86 # Any exception may be raised. 87 trace_collection.onExceptionRaiseExit(BaseException) 88 89 return self, None, None 90 91 92class ExpressionBuiltinAscii(ExpressionBuiltinSingleArgBase): 93 kind = "EXPRESSION_BUILTIN_ASCII" 94 95 if python_version >= 0x300: 96 builtin_spec = BuiltinParameterSpecs.builtin_ascii_spec 97 98 @staticmethod 99 def getTypeShape(): 100 return tshape_str 101 102 103class ExpressionBuiltinBin(ExpressionBuiltinSingleArgBase): 104 kind = "EXPRESSION_BUILTIN_BIN" 105 106 builtin_spec = BuiltinParameterSpecs.builtin_bin_spec 107 108 @staticmethod 109 def getTypeShape(): 110 return tshape_str 111 112 113class ExpressionBuiltinOct(ExpressionBuiltinSingleArgBase): 114 kind = "EXPRESSION_BUILTIN_OCT" 115 116 builtin_spec = BuiltinParameterSpecs.builtin_oct_spec 117 118 @staticmethod 119 def getTypeShape(): 120 return tshape_str 121 122 123class ExpressionBuiltinHex(ExpressionBuiltinSingleArgBase): 124 kind = "EXPRESSION_BUILTIN_HEX" 125 126 builtin_spec = BuiltinParameterSpecs.builtin_hex_spec 127 128 @staticmethod 129 def getTypeShape(): 130 return tshape_str 131 132 133class ExpressionBuiltinId(ExpressionBuiltinSingleArgBase): 134 kind = "EXPRESSION_BUILTIN_ID" 135 136 builtin_spec = BuiltinParameterSpecs.builtin_id_spec 137 138 def computeExpression(self, trace_collection): 139 # Note: Quite impossible to predict the pointer value or anything, but 140 # we know the result will be a long. 141 return self, None, None 142 143 def mayRaiseException(self, exception_type): 144 return self.subnode_value.mayRaiseException(exception_type) 145 146 def getIntValue(self): 147 return self 148 149 @staticmethod 150 def getTypeShape(): 151 return tshape_int_or_long 152 153 def computeExpressionDrop(self, statement, trace_collection): 154 result = makeStatementExpressionOnlyReplacementNode( 155 expression=self.subnode_value, node=self 156 ) 157 158 del self.parent 159 160 return ( 161 result, 162 "new_statements", 163 """\ 164Removed id taking for unused result.""", 165 ) 166 167 def mayHaveSideEffects(self): 168 return self.subnode_value.mayHaveSideEffects() 169 170 def extractSideEffects(self): 171 return (self.subnode_value,) 172