# Path: src/foolscap/tokens.py
# class BananaError(Exception):
#     """This exception is raised in response to a fundamental protocol
#     violation. The connection should be dropped immediately.
# 
#     .where is an optional string that describes the node of the object graph
#     where the failure was noticed.
#     """
#     where = None
# 
#     def __str__(self):
#         if self.where:
#             return "BananaError(in %s): %s" % (self.where, self.args)
#         else:
#             return "BananaError: %s" % (self.args,)
# 
# class Violation(Exception):
#     """This exception is raised in response to a schema violation. It
#     indicates that the incoming token stream has violated a constraint
#     imposed by the recipient. The current Unslicer is abandoned and the
#     error is propagated upwards to the enclosing Unslicer parent by
#     providing an BananaFailure object to the parent's .receiveChild method.
#     All remaining tokens for the current Unslicer are to be dropped.
#     """
# 
#     """.where: this string describes which node of the object graph was
#     being handled when the exception took place."""
#     where = ""
# 
#     def setLocation(self, where):
#         self.where = where
#     def getLocation(self):
#         return self.where
#     def prependLocation(self, prefix):
#         if self.where:
#             self.where = prefix + " " + self.where
#         else:
#             self.where = prefix
#     def appendLocation(self, suffix):
#         if self.where:
#             self.where = self.where + " " + suffix
#         else:
#             self.where = suffix
# 
#     def __str__(self):
#         if self.where:
#             return "Violation (%s): %s" % (self.where, self.args)
#         else:
#             return "Violation: %s" % (self.args,)


import six
from twisted.python import failure, reflect, log as twlog
from twisted.internet import defer
from foolscap import copyable, slicer, tokens
from foolscap.copyable import AttributeDictConstraint
from foolscap.constraint import ByteStringConstraint
from foolscap.slicers.list import ListConstraint
from .tokens import BananaError, Violation
from foolscap.util import AsyncAND
from foolscap.logging import log
    def setConstraint(self, methodSchema):
        self.methodSchema = methodSchema

    def start(self, count):
        if self.debug:
            log.msg("%s.start: %s" % (self, count))
        self.numargs = None
        self.args = []
        self.kwargs = {}
        self.argname = None
        self.argConstraint = None
        self.num_unreferenceable_children = 0
        self._all_children_are_referenceable_d = None
        self._ready_deferreds = []
        self.closed = False

    def checkToken(self, typebyte, size):
        if self.numargs is None:
            # waiting for positional-arg count
            if typebyte != tokens.INT:
                raise BananaError("posarg count must be an INT")
            return
        if len(self.args) < self.numargs:
            # waiting for a positional arg
            if self.argConstraint:
                self.argConstraint.checkToken(typebyte, size)
            return
        if self.argname is None:
            # waiting for the name of a keyword arg
            if typebyte not in (tokens.STRING, tokens.VOCAB):

# Path: src/foolscap/tokens.py
# class BananaError(Exception):
#     """This exception is raised in response to a fundamental protocol
#     violation. The connection should be dropped immediately.
# 
#     .where is an optional string that describes the node of the object graph
#     where the failure was noticed.
#     """
#     where = None
# 
#     def __str__(self):
#         if self.where:
#             return "BananaError(in %s): %s" % (self.where, self.args)
#         else:
#             return "BananaError: %s" % (self.args,)
# 
# class Violation(Exception):
#     """This exception is raised in response to a schema violation. It
#     indicates that the incoming token stream has violated a constraint
#     imposed by the recipient. The current Unslicer is abandoned and the
#     error is propagated upwards to the enclosing Unslicer parent by
#     providing an BananaFailure object to the parent's .receiveChild method.
#     All remaining tokens for the current Unslicer are to be dropped.
#     """
# 
#     """.where: this string describes which node of the object graph was
#     being handled when the exception took place."""
#     where = ""
# 
#     def setLocation(self, where):
#         self.where = where
#     def getLocation(self):
#         return self.where
#     def prependLocation(self, prefix):
#         if self.where:
#             self.where = prefix + " " + self.where
#         else:
#             self.where = prefix
#     def appendLocation(self, suffix):
#         if self.where:
#             self.where = self.where + " " + suffix
#         else:
#             self.where = suffix
# 
#     def __str__(self):
#         if self.where:
#             return "Violation (%s): %s" % (self.where, self.args)
#         else:
#             return "Violation: %s" % (self.args,)


# Path: src/foolscap/call.py
import six
from twisted.python import failure, reflect, log as twlog
from twisted.internet import defer
from foolscap import copyable, slicer, tokens
from foolscap.copyable import AttributeDictConstraint
from foolscap.constraint import ByteStringConstraint
from foolscap.slicers.list import ListConstraint
from .tokens import BananaError, Violation
from foolscap.util import AsyncAND
from foolscap.logging import log

    def setConstraint(self, methodSchema):
        self.methodSchema = methodSchema

    def start(self, count):
        if self.debug:
            log.msg("%s.start: %s" % (self, count))
        self.numargs = None
        self.args = []
        self.kwargs = {}
        self.argname = None
        self.argConstraint = None
        self.num_unreferenceable_children = 0
        self._all_children_are_referenceable_d = None
        self._ready_deferreds = []
        self.closed = False

    def checkToken(self, typebyte, size):
        if self.numargs is None:
            # waiting for positional-arg count
            if typebyte != tokens.INT:
                raise BananaError("posarg count must be an INT")
            return
        if len(self.args) < self.numargs:
            # waiting for a positional arg
            if self.argConstraint:
                self.argConstraint.checkToken(typebyte, size)
            return
        if self.argname is None:
            # waiting for the name of a keyword arg
            if typebyte not in (tokens.STRING, tokens.VOCAB):

                raise BananaError("kwarg name must be a STRING")