/usr/lib/python2.7/dist-packages/foolscap/schema.py is in python-foolscap 0.13.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | # This module contains all user-visible Constraint subclasses, for
# convenience by user code which is defining RemoteInterfaces. The primitive
# ones are defined in constraint.py, while the constraints associated with
# specific open sequences (list, unicode, etc) are defined in the related
# slicer/list.py module, etc. A few are defined here.
# It also defines the constraintMap and constraintTypeMap, used when
# constructing constraints out of the convenience shorthand. This is used
# when processing the methods defined in a RemoteInterface (such that a
# default argument like x=int gets turned into an IntegerConstraint). New
# slicers that want to add to these mappings can use addToConstraintTypeMap
# or manipulate constraintMap directly.
# this imports slicers and constraints.py, but is not allowed to import any
# other Foolscap modules, to avoid import cycles.
"""
primitive constraints:
- types.StringType: string with maxLength=1k
- String(maxLength=1000): string with arbitrary maxLength
- types.BooleanType: boolean
- types.IntType: integer that fits in s_int32_t
- types.LongType: integer with abs(num) < 2**8192 (fits in 1024 bytes)
- Int(maxBytes=1024): integer with arbitrary maxValue=2**(8*maxBytes)
- types.FloatType: number
- Number(maxBytes=1024): float or integer with maxBytes
- interface: instance which implements (or adapts to) the Interface
- class: instance of the class or a subclass
- # unicode? types? none?
container constraints:
- TupleOf(constraint1, constraint2..): fixed size, per-element constraint
- ListOf(constraint, maxLength=30): all elements obey constraint
- DictOf(keyconstraint, valueconstraint): keys and values obey constraints
- AttributeDict(*attrTuples, ignoreUnknown=False):
- attrTuples are (name, constraint)
- ignoreUnknown=True means that received attribute names which aren't
listed in attrTuples should be ignored instead of raising an
UnknownAttrName exception
composite constraints:
- tuple: alternatives: must obey one of the different constraints
modifiers:
- Shared(constraint, refLimit=None): object may be referenced multiple times
within the serialization domain (question: which domain?). All
constraints default to refLimit=1, and a MultiplyReferenced exception
is raised as soon as the reference count goes above the limit.
refLimit=None means no limit is enforced.
- Optional(name, constraint, default=None): key is not required. If not
provided and default is None, key/attribute will not be created
Only valid inside DictOf and AttributeDict.
"""
from foolscap.tokens import Violation, UnknownSchemaType, BananaError, \
tokenNames
# make constraints available in a single location
from foolscap.constraint import Constraint, Any, ByteStringConstraint, \
IntegerConstraint, NumberConstraint, IConstraint, Optional, Shared
from foolscap.slicers.unicode import UnicodeConstraint
from foolscap.slicers.bool import BooleanConstraint
from foolscap.slicers.dict import DictConstraint
from foolscap.slicers.list import ListConstraint
from foolscap.slicers.set import SetConstraint
from foolscap.slicers.tuple import TupleConstraint
from foolscap.slicers.none import Nothing
# we don't import RemoteMethodSchema from remoteinterface.py, because
# remoteinterface.py needs to import us (for addToConstraintTypeMap)
ignored = [Constraint, Any, ByteStringConstraint, UnicodeConstraint,
IntegerConstraint, NumberConstraint, BooleanConstraint,
DictConstraint, ListConstraint, SetConstraint, TupleConstraint,
Nothing, Optional, Shared,
] # hush pyflakes
# convenience shortcuts
TupleOf = TupleConstraint
ListOf = ListConstraint
DictOf = DictConstraint
SetOf = SetConstraint
# note: using PolyConstraint (aka ChoiceOf) for inbound tasting is probably
# not fully vetted. One of the issues would be with something like
# ListOf(ChoiceOf(TupleOf(stuff), SetOf(stuff))). The ListUnslicer, when
# handling an inbound Tuple, will do
# TupleUnslicer.setConstraint(polyconstraint), since that's all it really
# knows about, and the TupleUnslicer will then try to look inside the
# polyconstraint for attributes that talk about tuples, and might fail.
class PolyConstraint(Constraint):
name = "PolyConstraint"
def __init__(self, *alternatives):
self.alternatives = [IConstraint(a) for a in alternatives]
self.alternatives = tuple(self.alternatives)
# TODO: taster/opentypes should be a union of the alternatives'
def checkToken(self, typebyte, size):
ok = False
for c in self.alternatives:
try:
c.checkToken(typebyte, size)
ok = True
except (Violation, BananaError):
pass
if not ok:
raise Violation("typebyte %s does not satisfy any of %s"
% (tokenNames[typebyte], self.alternatives))
def checkObject(self, obj, inbound):
ok = False
for c in self.alternatives:
try:
c.checkObject(obj, inbound)
ok = True
except Violation:
pass
if not ok:
raise Violation("object type %s does not satisfy any of %s"
% (type(obj), self.alternatives))
ChoiceOf = PolyConstraint
def AnyStringConstraint(*args, **kwargs):
return ChoiceOf(ByteStringConstraint(*args, **kwargs),
UnicodeConstraint(*args, **kwargs))
# keep the old meaning, for now. Eventually StringConstraint should become an
# AnyStringConstraint
StringConstraint = ByteStringConstraint
constraintMap = {
str: ByteStringConstraint(),
unicode: UnicodeConstraint(),
bool: BooleanConstraint(),
int: IntegerConstraint(),
long: IntegerConstraint(maxBytes=1024),
float: NumberConstraint(),
None: Nothing(),
}
# This module provides a function named addToConstraintTypeMap() which helps
# to resolve some import cycles.
constraintTypeMap = []
def addToConstraintTypeMap(typ, constraintMaker):
constraintTypeMap.insert(0, (typ, constraintMaker))
def _tupleConstraintMaker(t):
return TupleConstraint(*t)
addToConstraintTypeMap(tuple, _tupleConstraintMaker)
# this function transforms the simple syntax (as used in RemoteInterface
# method definitions) into Constraint instances. This function is registered
# as a zope.interface adapter hook, so that once we've been loaded, other
# code can just do IConstraint(stuff) and expect it to work.
def adapt_obj_to_iconstraint(iface, t):
if iface is not IConstraint:
return None
assert not IConstraint.providedBy(t) # not sure about this
c = constraintMap.get(t, None)
if c:
return c
for (typ, constraintMaker) in constraintTypeMap:
if isinstance(t, typ):
c = constraintMaker(t)
if c:
return c
# RIFoo means accept either a Referenceable that implements RIFoo, or a
# RemoteReference that points to just such a Referenceable. This is
# hooked in by remoteinterface.py, when it calls addToConstraintTypeMap
# we are the only way to make constraints
raise UnknownSchemaType("can't make constraint from '%s' (%s)" %
(t, type(t)))
from zope.interface.interface import adapter_hooks
adapter_hooks.append(adapt_obj_to_iconstraint)
# how to accept "([(ref0" ?
# X = "TupleOf(ListOf(TupleOf(" * infinity
# ok, so you can't write a constraint that accepts it. I'm ok with that.
|