Beispiel #1
0
    def _handleNonLocal(node):
        # Take closure variables for non-local declarations.

        for non_local_names, source_ref in node.getNonlocalDeclarations():
            for non_local_name in non_local_names:
                variable = node.getClosureVariable(
                    variable_name = non_local_name
                )

                if variable.isModuleVariable():
                    SyntaxErrors.raiseSyntaxError(
                        "no binding for nonlocal '%s' found" % (
                            non_local_name
                        ),
                        source_ref   = None
                                         if isFullCompat() and \
                                         python_version < 340 else
                                       source_ref,
                        display_file = not isFullCompat() or \
                                       python_version >= 340,
                        display_line = not isFullCompat() or \
                                       python_version >= 340
                    )

                node.registerProvidedVariable(variable)
                addVariableUsage(variable, node)
Beispiel #2
0
    def _handleNonLocal(node):
        # Take closure variables for non-local declarations.

        for non_local_names, source_ref in node.getNonlocalDeclarations():
            for non_local_name in non_local_names:
                variable = node.getClosureVariable(
                    variable_name=non_local_name)

                if variable.isModuleVariable():
                    SyntaxErrors.raiseSyntaxError(
                        "no binding for nonlocal '%s' found" % (
                            non_local_name
                        ),
                        source_ref   = None
                                         if isFullCompat() and \
                                         python_version < 340 else
                                       source_ref,
                        display_file = not isFullCompat() or \
                                       python_version >= 340,
                        display_line = not isFullCompat() or \
                                       python_version >= 340
                    )

                node.registerProvidedVariable(variable)
                variable.addVariableUser(node)
Beispiel #3
0
    def onEnterNode(self, node):
        assert python_version < 300

        if node.isStatementDelVariable():
            variable = node.getTargetVariableRef().getVariable()

            if not variable.isModuleVariable() and \
               isSharedLogically(variable):
                SyntaxErrors.raiseSyntaxError(
                    reason="""\
can not delete variable '%s' referenced in nested scope""" %
                    (variable.getName()),
                    source_ref=(None if isFullCompat() else
                                node.getSourceReference()),
                    display_file=not isFullCompat(),
                    display_line=not isFullCompat())
Beispiel #4
0
    def onEnterNode(self, node):
        if python_version < 300 and node.isStatementDelVariable():
            variable = node.getTargetVariableRef().getVariable()

            if not variable.isModuleVariable() and \
               variable.isSharedAmongScopes():
                SyntaxErrors.raiseSyntaxError(
                    reason="""\
can not delete variable '%s' referenced in nested scope""" %
                    (variable.getName()),
                    source_ref=(None if isFullCompat() else
                                node.getSourceReference()),
                    display_file=not isFullCompat(),
                    display_line=not isFullCompat())
        elif node.isStatementsFrame():
            node.updateLocalNames()
Beispiel #5
0
    def onEnterNode(self, node):
        assert python_version < 300

        if node.isStatementDelVariable():
            variable = node.getTargetVariableRef().getVariable()

            if variable.isSharedLogically():
                SyntaxErrors.raiseSyntaxError(
                    reason       = """\
can not delete variable '%s' referenced in nested scope""" % (
                       variable.getName()
                    ),
                    source_ref   = (
                        None if isFullCompat() else node.getSourceReference()
                    ),
                    display_file = not isFullCompat(),
                    display_line = not isFullCompat()
                )
Beispiel #6
0
    def onEnterNode(self, node):
        if python_version < 300 and node.isStatementDelVariable():
            variable = node.getTargetVariableRef().getVariable()

            if not variable.isModuleVariable() and \
               isSharedAmongScopes(variable):
                SyntaxErrors.raiseSyntaxError(
                    reason       = """\
can not delete variable '%s' referenced in nested scope""" % (
                       variable.getName()
                    ),
                    source_ref   = (
                        None if isFullCompat() else node.getSourceReference()
                    ),
                    display_file = not isFullCompat(),
                    display_line = not isFullCompat()
                )
        elif node.isStatementsFrame():
            node.updateLocalNames()
Beispiel #7
0
def doShowUnknownEncodingName():
    # It's best to do it.
    if not isFullCompat():
        return True

    # Python 3.3.3 or higher does it, 3.4 always did.
    if python_version >= 333:
        return True

    # Python2.7 after 2.7.6 does it.
    if isAtLeastSubVersion(276):
        return True

    # Debian back ports do it.
    if "2.7.5+" in sys.version or "3.3.2+" in sys.version:
        return True

    return False
Beispiel #8
0
def doShowUnknownEncodingName():
    # It's best to do it.
    if not isFullCompat():
        return True

    # Python 3.3.3 or higher does it, 3.4 always did.
    if python_version >= 333:
        return True

    # Python2.7 after 2.7.6 does it.
    if isAtLeastSubVersion(276):
        return True

    # Debian back ports do it.
    if  "2.7.5+" in sys.version or "3.3.2+" in sys.version:
        return True

    return False
Beispiel #9
0
    def computeExpressionComplex(self, complex_node, trace_collection):
        shape = self.getTypeShape()

        if shape.hasShapeSlotComplex() is False:
            return makeRaiseTypeErrorExceptionReplacementFromTemplateAndValue(
                "complex() argument must be a string or a number"
                if isFullCompat() and python_version < 300 else
                "complex() argument must be a string or a number, not '%s'",
                operation="complex",
                original_node=complex_node,
                value_node=self)

        self.onContentEscapes(trace_collection)

        # Any code could be run, note that.
        trace_collection.onControlFlowEscape(self)

        # Any exception may be raised.
        trace_collection.onExceptionRaiseExit(BaseException)

        return complex_node, None, None
Beispiel #10
0
    def computeExpressionComplex(self, complex_node, trace_collection):
        shape = self.getTypeShape()

        if shape.hasShapeSlotComplex() is False:
            return makeRaiseTypeErrorExceptionReplacementFromTemplateAndValue(
                "complex() argument must be a string or a number"
                if isFullCompat() and python_version < 300
                else "complex() argument must be a string or a number, not '%s'",
                operation="complex",
                original_node=complex_node,
                value_node=self,
            )

        self.onContentEscapes(trace_collection)

        # Any code could be run, note that.
        trace_collection.onControlFlowEscape(self)

        # Any exception may be raised.
        trace_collection.onExceptionRaiseExit(BaseException)

        return complex_node, None, None
Beispiel #11
0
    def onEnterNode( self, node ):
        if node.isExpressionTargetVariableRef():
            if node.getVariable() is None:
                variable_name = node.getVariableName()
                provider = node.getParentVariableProvider()

                variable = provider.getVariableForAssignment(
                    variable_name = variable_name
                )

                # Inside an exec, we need to ignore global declarations that are
                # not ours, so we replace it with ours, unless it came from an
                # 'global' declaration inside the exec
                if node.source_ref.isExecReference() and not provider.isPythonModule():
                    if variable.isModuleVariableReference() and not variable.isFromExecStatement():
                        variable = provider.providing[ variable_name ] = provider.createProvidedVariable(
                            variable_name = variable_name
                        )

                node.setVariable( variable )
        elif node.isExpressionVariableRef():
            if node.getVariable() is None:
                provider = node.getParentVariableProvider()

                if provider.isEarlyClosure():
                    node.setVariable(
                        provider.getVariableForReference(
                            variable_name = node.getVariableName()
                        )
                    )
        elif node.isExpressionTempVariableRef():
            if node.getVariable().getOwner().getParentVariableProvider() != node.getParentVariableProvider():
                node.setVariable(
                    node.getParentVariableProvider().addClosureVariable( node.getVariable() )
                )

                assert node.getVariable().isClosureReference(), node.getVariable()
        elif python_version >= 300 and node.isExpressionFunctionBody():
            # Take closure variables for non-local declarations.

            for non_local_names, source_ref in node.getNonlocalDeclarations():
                for non_local_name in non_local_names:
                    # print( "nonlocal reference from", node, "to name", non_local_name )

                    variable = node.getClosureVariable(
                        variable_name = non_local_name
                    )

                    node.registerProvidedVariable( variable )

                    if variable.isModuleVariableReference():
                        SyntaxErrors.raiseSyntaxError(
                            "no binding for nonlocal '%s' found" % (
                                non_local_name
                            ),
                            source_ref   = None if isFullCompat() else source_ref,
                            display_file = not isFullCompat(),
                            display_line = not isFullCompat()
                        )
        # Attribute access of names of class functions should be mangled, if they start
        # with "__", but do not end in "__" as well.
        elif node.isExpressionAttributeLookup() or node.isStatementAssignmentAttribute() or \
             node.isStatementDelAttribute():
            attribute_name = node.getAttributeName()

            if attribute_name.startswith( "__" ) and not attribute_name.endswith( "__" ):
                seen_function = False

                current = node

                while True:
                    current = current.getParentVariableProvider()

                    if current.isPythonModule():
                        break

                    assert current.isExpressionFunctionBody()

                    if current.isClassDictCreation():
                        if seen_function:
                            node.setAttributeName( "_" + current.getName() + attribute_name )

                        break
                    else:
                        seen_function = True
        # Check if continue and break are properly in loops. If not, raise a syntax error.
        elif node.isStatementBreakLoop() or node.isStatementContinueLoop():
            current = node

            while True:
                if current.isPythonModule() or current.isExpressionFunctionBody():
                    if node.isStatementContinueLoop():
                        message = "'continue' not properly in loop"
                        col_offset   = 16 if python_version >= 300 else None
                        display_line = True
                        source_line  = None
                    else:
                        message = "'break' outside loop"

                        if isFullCompat():
                            col_offset   = 2 if python_version >= 300 else None
                            display_line = True
                            source_line  = "" if python_version >= 300 else None
                        else:
                            col_offset   = 13
                            display_line = True
                            source_line  = None

                    source_ref = node.getSourceReference()
                    # source_ref.line += 1

                    SyntaxErrors.raiseSyntaxError(
                        message,
                        source_ref   = node.getSourceReference(),
                        col_offset   = col_offset,
                        display_line = display_line,
                        source_line  = source_line
                    )

                current = current.getParent()

                if current.isStatementLoop():
                    break
Beispiel #12
0
    def onEnterNode(self, node):
        # Mighty complex code with lots of branches and statements, but it
        # couldn't be less without making it more difficult.
        # pylint: disable=R0912,R0915

        if node.isExpressionTargetVariableRef():
            provider = node.getParentVariableProvider()

            if node.getVariable() is None:
                variable_name = node.getVariableName()

                variable = provider.getVariableForAssignment(
                    variable_name = variable_name
                )

                node.setVariable(variable)

            addVariableUsage(node.getVariable(), provider)
        elif node.isExpressionTargetTempVariableRef():
            provider = node.getParentVariableProvider()

            addVariableUsage(node.getVariable(), provider)
        elif node.isExpressionVariableRef():
            if node.getVariable() is None:
                provider = node.getParentVariableProvider()

                if provider.isEarlyClosure():
                    variable = provider.getVariableForReference(
                        variable_name = node.getVariableName()
                    )

                    # Python3.4 version respects closure variables taken can be
                    # overridden by writes to locals. It should be done for
                    # globals too, on all versions, but for Python2 the locals
                    # dictionary is avoided unless "exec" appears, so it's not
                    # done.
                    if variable.getOwner() is not provider:
                        if python_version >= 340 or \
                           (python_version >= 300 and \
                            variable.isModuleVariable()):
                            variable = Variables.MaybeLocalVariable(
                                owner          = provider,
                                maybe_variable = variable
                            )

                    node.setVariable(variable)
        elif node.isExpressionTempVariableRef():
            if node.getVariable().getOwner() != node.getParentVariableProvider():
                node.setVariable(
                    node.getParentVariableProvider().addClosureVariable(
                        node.getVariable()
                    )
                )
        elif node.isExpressionGeneratorObjectBody():
            self._handleNonLocal(node)
            # Python3.4 allows for class declarations to be made global, even
            # after they were declared, so we need to fix this up.

            # TODO: Then this may not even have to be here at all.
            if python_version >= 340:
                self._handleQualnameSetup(node)
        elif node.isExpressionCoroutineObjectBody():
            self._handleNonLocal(node)

            # TODO: Then this may not even have to be here at all.
            self._handleQualnameSetup(node)
        elif node.isExpressionClassBody():
            self._handleNonLocal(node)

            # Python3.4 allows for class declarations to be made global, even
            # after they were declared, so we need to fix this up.
            if python_version >= 340:
                self._handleQualnameSetup(node)
        elif node.isExpressionFunctionBody():
            self._handleNonLocal(node)

            for variable in node.getParameters().getAllVariables():
                addVariableUsage(variable, node)

            # Python3.4 allows for class declarations to be made global, even
            # after they were declared, so we need to fix this up.
            if python_version >= 340:
                self._handleQualnameSetup(node)
        # Attribute access of names of class functions should be mangled, if
        # they start with "__", but do not end in "__" as well.
        elif node.isExpressionAttributeLookup() or \
             node.isStatementAssignmentAttribute() or \
             node.isStatementDelAttribute():
            attribute_name = node.getAttributeName()

            if attribute_name.startswith("__") and \
               not attribute_name.endswith("__"):
                seen_function = False

                current = node

                while True:
                    current = current.getParentVariableProvider()

                    if current.isCompiledPythonModule():
                        break

                    if current.isExpressionClassBody():
                        if seen_function:
                            node.setAttributeName(
                                "_%s%s" % (
                                    current.getName().lstrip('_'),
                                    attribute_name
                                )
                            )

                        break
                    else:
                        seen_function = True
        # Check if continue and break are properly in loops. If not, raise a
        # syntax error.
        elif node.isStatementLoopBreak() or node.isStatementLoopContinue():
            current = node

            while True:
                if current.isParentVariableProvider():
                    if node.isStatementLoopContinue():
                        message = "'continue' not properly in loop"

                        col_offset   = 16 if python_version >= 300 else None
                        display_line = True
                        source_line  = None
                    else:
                        message = "'break' outside loop"

                        if isFullCompat():
                            col_offset   = 2 if python_version >= 300 else None
                            display_line = True
                            source_line  = "" if python_version >= 300 else None
                        else:
                            col_offset   = 13
                            display_line = True
                            source_line  = None

                    SyntaxErrors.raiseSyntaxError(
                        message,
                        source_ref   = node.getSourceReference(),
                        col_offset   = col_offset,
                        display_line = display_line,
                        source_line  = source_line
                    )

                current = current.getParent()

                if current.isStatementLoop():
                    break
    def onEnterNode(self, node):
        # Mighty complex code with lots of branches and statements, but it
        # couldn't be less without making it more difficult.
        # pylint: disable=R0912,R0915

        if node.isExpressionTargetVariableRef():
            provider = node.getParentVariableProvider()

            if node.getVariable() is None:
                variable_name = node.getVariableName()

                variable = provider.getVariableForAssignment(
                    variable_name = variable_name
                )

                node.setVariable(variable)

            addVariableUsage(node.getVariable(), provider)
        elif node.isExpressionTargetTempVariableRef():
            provider = node.getParentVariableProvider()

            addVariableUsage(node.getVariable(), provider)
        elif node.isExpressionVariableRef():
            if node.getVariable() is None:
                provider = node.getParentVariableProvider()

                if provider.isEarlyClosure():
                    node.setVariable(
                        provider.getVariableForReference(
                            variable_name = node.getVariableName()
                        )
                    )
        elif node.isExpressionTempVariableRef():
            if node.getVariable().getOwner() != node.getParentVariableProvider():
                node.setVariable(
                    node.getParentVariableProvider().addClosureVariable(
                        node.getVariable()
                    )
                )

                assert node.getVariable().isClosureReference(), \
                  node.getVariable()
        elif node.isExpressionFunctionBody():
            if python_version >= 300:
                self._handleNonLocal(node)

            for variable in node.getParameters().getAllVariables():
                addVariableUsage(variable, node)

            # Python3.4 allows for class declarations to be made global, even
            # after they were declared, so we need to fix this up.
            if python_version >= 340 and node.isClassDictCreation():
                class_assign, qualname_assign = node.qualname_setup
                class_variable = class_assign.getTargetVariableRef().getVariable()

                if class_variable.isModuleVariable() and \
                   class_variable.isFromGlobalStatement():
                    qualname_node = qualname_assign.getAssignSource()

                    qualname_node.replaceWith(
                        makeConstantReplacementNode(
                            constant = class_variable.getName(),
                            node     = qualname_node
                        )
                    )

                    node.qualname_provider = node.getParentModule()

                    # TODO: Actually for nested global classes, this approach
                    # may not work, as their qualnames will be wrong. In that
                    # case a dedicated node for qualname references might be
                    # needed.

                del node.qualname_setup




        # Attribute access of names of class functions should be mangled, if
        # they start with "__", but do not end in "__" as well.
        elif node.isExpressionAttributeLookup() or \
             node.isStatementAssignmentAttribute() or \
             node.isStatementDelAttribute():
            attribute_name = node.getAttributeName()

            if attribute_name.startswith( "__" ) and \
               not attribute_name.endswith( "__" ):
                seen_function = False

                current = node

                while True:
                    current = current.getParentVariableProvider()

                    if current.isPythonModule():
                        break

                    assert current.isExpressionFunctionBody()

                    if current.isClassDictCreation():
                        if seen_function:
                            node.setAttributeName(
                                "_%s%s" % (
                                    current.getName().lstrip("_"),
                                    attribute_name
                                )
                            )

                        break
                    else:
                        seen_function = True
        # Check if continue and break are properly in loops. If not, raise a
        # syntax error.
        elif node.isStatementBreakLoop() or node.isStatementContinueLoop():
            current = node

            while True:
                if current.isPythonModule() or current.isExpressionFunctionBody():
                    if node.isStatementContinueLoop():
                        message = "'continue' not properly in loop"
                        col_offset   = 16 if python_version >= 300 else None
                        display_line = True
                        source_line  = None
                    else:
                        message = "'break' outside loop"

                        if isFullCompat():
                            col_offset   = 2 if python_version >= 300 else None
                            display_line = True
                            source_line  = "" if python_version >= 300 else None
                        else:
                            col_offset   = 13
                            display_line = True
                            source_line  = None

                    source_ref = node.getSourceReference()
                    # source_ref.line += 1

                    SyntaxErrors.raiseSyntaxError(
                        message,
                        source_ref   = node.getSourceReference(),
                        col_offset   = col_offset,
                        display_line = display_line,
                        source_line  = source_line
                    )

                current = current.getParent()

                if current.isStatementLoop():
                    break
Beispiel #14
0
    def onEnterNode(self, node):
        # Mighty complex code with lots of branches and statements, but it
        # couldn't be less without making it more difficult.
        # pylint: disable=R0912,R0915

        if node.isExpressionTargetVariableRef():
            provider = node.getParentVariableProvider()

            if node.getVariable() is None:
                variable_name = node.getVariableName()

                variable = provider.getVariableForAssignment(
                    variable_name=variable_name)

                node.setVariable(variable)

            addVariableUsage(node.getVariable(), provider)
        elif node.isExpressionTargetTempVariableRef():
            provider = node.getParentVariableProvider()

            addVariableUsage(node.getVariable(), provider)
        elif node.isExpressionVariableRef():
            if node.getVariable() is None:
                provider = node.getParentVariableProvider()

                if provider.isEarlyClosure():
                    node.setVariable(
                        provider.getVariableForReference(
                            variable_name=node.getVariableName()))
        elif node.isExpressionTempVariableRef():
            if node.getVariable().getOwner() != node.getParentVariableProvider(
            ):
                node.setVariable(
                    node.getParentVariableProvider().addClosureVariable(
                        node.getVariable()))

                assert node.getVariable().isClosureReference(), \
                  node.getVariable()
        elif node.isExpressionFunctionBody():
            if python_version >= 300:
                self._handleNonLocal(node)

            for variable in node.getParameters().getAllVariables():
                addVariableUsage(variable, node)

        # Attribute access of names of class functions should be mangled, if
        # they start with "__", but do not end in "__" as well.
        elif node.isExpressionAttributeLookup() or \
             node.isStatementAssignmentAttribute() or \
             node.isStatementDelAttribute():
            attribute_name = node.getAttributeName()

            if attribute_name.startswith( "__" ) and \
               not attribute_name.endswith( "__" ):
                seen_function = False

                current = node

                while True:
                    current = current.getParentVariableProvider()

                    if current.isPythonModule():
                        break

                    assert current.isExpressionFunctionBody()

                    if current.isClassDictCreation():
                        if seen_function:
                            node.setAttributeName(
                                "_%s%s" % (current.getName().lstrip("_"),
                                           attribute_name))

                        break
                    else:
                        seen_function = True
        # Check if continue and break are properly in loops. If not, raise a
        # syntax error.
        elif node.isStatementBreakLoop() or node.isStatementContinueLoop():
            current = node

            while True:
                if current.isPythonModule(
                ) or current.isExpressionFunctionBody():
                    if node.isStatementContinueLoop():
                        message = "'continue' not properly in loop"
                        col_offset = 16 if python_version >= 300 else None
                        display_line = True
                        source_line = None
                    else:
                        message = "'break' outside loop"

                        if isFullCompat():
                            col_offset = 2 if python_version >= 300 else None
                            display_line = True
                            source_line = "" if python_version >= 300 else None
                        else:
                            col_offset = 13
                            display_line = True
                            source_line = None

                    source_ref = node.getSourceReference()
                    # source_ref.line += 1

                    SyntaxErrors.raiseSyntaxError(
                        message,
                        source_ref=node.getSourceReference(),
                        col_offset=col_offset,
                        display_line=display_line,
                        source_line=source_line)

                current = current.getParent()

                if current.isStatementLoop():
                    break
Beispiel #15
0
    def onEnterNode(self, node):
        # Mighty complex code with lots of branches and statements, but it
        # couldn't be less without making it more difficult.
        # pylint: disable=R0912,R0915

        if node.isExpressionTargetVariableRef():
            provider = node.getParentVariableProvider()

            if node.getVariable() is None:
                variable_name = node.getVariableName()

                variable = provider.getVariableForAssignment(
                    variable_name=variable_name)

                node.setVariable(variable)

            addVariableUsage(node.getVariable(), provider)
        elif node.isExpressionTargetTempVariableRef():
            provider = node.getParentVariableProvider()

            addVariableUsage(node.getVariable(), provider)
        elif node.isExpressionVariableRef():
            if node.getVariable() is None:
                provider = node.getParentVariableProvider()

                if provider.isEarlyClosure():
                    variable = provider.getVariableForReference(
                        variable_name=node.getVariableName())

                    # Python3.4 version respects closure variables taken can be
                    # overridden by writes to locals. It should be done for
                    # globals too, on all versions, but for Python2 the locals
                    # dictionary is avoided unless "exec" appears, so it's not
                    # done.
                    if variable.getOwner() is not provider:
                        if python_version >= 340 or \
                           (python_version >= 300 and \
                            variable.isModuleVariable()):
                            variable = Variables.MaybeLocalVariable(
                                owner=provider, maybe_variable=variable)

                    node.setVariable(variable)
        elif node.isExpressionTempVariableRef():
            if node.getVariable().getOwner() != node.getParentVariableProvider(
            ):
                node.setVariable(
                    node.getParentVariableProvider().addClosureVariable(
                        node.getVariable()))
        elif node.isExpressionFunctionBody():
            if python_version >= 300:
                self._handleNonLocal(node)

            for variable in node.getParameters().getAllVariables():
                addVariableUsage(variable, node)

            # Python3.4 allows for class declarations to be made global, even
            # after they were declared, so we need to fix this up.
            if python_version >= 340:
                self._handleQualnameSetup(node)
        # Attribute access of names of class functions should be mangled, if
        # they start with "__", but do not end in "__" as well.
        elif node.isExpressionAttributeLookup() or \
             node.isStatementAssignmentAttribute() or \
             node.isStatementDelAttribute():
            attribute_name = node.getAttributeName()

            if attribute_name.startswith("__") and \
               not attribute_name.endswith("__"):
                seen_function = False

                current = node

                while True:
                    current = current.getParentVariableProvider()

                    if current.isPythonModule():
                        break

                    assert current.isExpressionFunctionBody()

                    if current.isClassDictCreation():
                        if seen_function:
                            node.setAttributeName(
                                "_%s%s" % (current.getName().lstrip("_"),
                                           attribute_name))

                        break
                    else:
                        seen_function = True
        # Check if continue and break are properly in loops. If not, raise a
        # syntax error.
        elif node.isStatementBreakLoop() or node.isStatementContinueLoop():
            current = node

            while True:
                if current.isPythonModule() or \
                   current.isExpressionFunctionBody():
                    if node.isStatementContinueLoop():
                        message = "'continue' not properly in loop"
                        col_offset = 16 if python_version >= 300 else None
                        display_line = True
                        source_line = None
                    else:
                        message = "'break' outside loop"

                        if isFullCompat():
                            col_offset = 2 if python_version >= 300 else None
                            display_line = True
                            source_line = "" if python_version >= 300 else None
                        else:
                            col_offset = 13
                            display_line = True
                            source_line = None

                    SyntaxErrors.raiseSyntaxError(
                        message,
                        source_ref=node.getSourceReference(),
                        col_offset=col_offset,
                        display_line=display_line,
                        source_line=source_line)

                current = current.getParent()

                if current.isStatementLoop():
                    break
Beispiel #16
0
    def onEnterNode(self, node):
        if node.isExpressionTargetVariableRef():
            if node.getVariable() is None:
                variable_name = node.getVariableName()
                provider = node.getParentVariableProvider()

                variable = provider.getVariableForAssignment(
                    variable_name = variable_name
                )

                # Inside an exec, we need to ignore global declarations that are
                # not ours, so we replace it with ours, unless it came from an
                # 'global' declaration inside the exec
                if node.source_ref.isExecReference() and not provider.isPythonModule():
                    if variable.isModuleVariableReference() and not variable.isFromExecStatement():
                        variable = provider.providing[ variable_name ] = provider.createProvidedVariable(
                            variable_name = variable_name
                        )

                node.setVariable( variable )
        elif node.isExpressionVariableRef():
            if node.getVariable() is None:
                provider = node.getParentVariableProvider()

                if provider.isEarlyClosure():
                    node.setVariable(
                        provider.getVariableForReference(
                            variable_name = node.getVariableName()
                        )
                    )
        elif node.isExpressionTempVariableRef():
            if node.getVariable().getOwner() != node.getParentVariableProvider():
                node.setVariable(
                    node.getParentVariableProvider().addClosureVariable(
                        node.getVariable()
                    )
                )

                assert node.getVariable().isClosureReference(), node.getVariable()
        elif python_version >= 300 and node.isExpressionFunctionBody():
            # Take closure variables for non-local declarations.

            for non_local_names, source_ref in node.getNonlocalDeclarations():
                for non_local_name in non_local_names:
                    # print( "nonlocal reference from", node, "to name", non_local_name )

                    variable = node.getClosureVariable(
                        variable_name = non_local_name
                    )

                    node.registerProvidedVariable( variable )

                    if variable.isModuleVariableReference():
                        SyntaxErrors.raiseSyntaxError(
                            "no binding for nonlocal '%s' found" % (
                                non_local_name
                            ),
                            source_ref   = None if isFullCompat() else source_ref,
                            display_file = not isFullCompat(),
                            display_line = not isFullCompat()
                        )
        # Attribute access of names of class functions should be mangled, if
        # they start with "__", but do not end in "__" as well.
        elif node.isExpressionAttributeLookup() or node.isStatementAssignmentAttribute() or \
             node.isStatementDelAttribute():
            attribute_name = node.getAttributeName()

            if attribute_name.startswith( "__" ) and not attribute_name.endswith( "__" ):
                seen_function = False

                current = node

                while True:
                    current = current.getParentVariableProvider()

                    if current.isPythonModule():
                        break

                    assert current.isExpressionFunctionBody()

                    if current.isClassDictCreation():
                        if seen_function:
                            node.setAttributeName(
                                "_%s%s" % (
                                    current.getName().lstrip("_"),
                                    attribute_name
                                )
                            )

                        break
                    else:
                        seen_function = True
        # Check if continue and break are properly in loops. If not, raise a
        # syntax error.
        elif node.isStatementBreakLoop() or node.isStatementContinueLoop():
            current = node

            while True:
                if current.isPythonModule() or current.isExpressionFunctionBody():
                    if node.isStatementContinueLoop():
                        message = "'continue' not properly in loop"
                        col_offset   = 16 if python_version >= 300 else None
                        display_line = True
                        source_line  = None
                    else:
                        message = "'break' outside loop"

                        if isFullCompat():
                            col_offset   = 2 if python_version >= 300 else None
                            display_line = True
                            source_line  = "" if python_version >= 300 else None
                        else:
                            col_offset   = 13
                            display_line = True
                            source_line  = None

                    source_ref = node.getSourceReference()
                    # source_ref.line += 1

                    SyntaxErrors.raiseSyntaxError(
                        message,
                        source_ref   = node.getSourceReference(),
                        col_offset   = col_offset,
                        display_line = display_line,
                        source_line  = source_line
                    )

                current = current.getParent()

                if current.isStatementLoop():
                    break