86: Actually change *all* tab indentation to 4-space: 'sed s/\t/ /g'

This commit is contained in:
Jason Gerard DeRose 2008-08-08 21:40:03 +00:00
parent 58a3b1d091
commit fdfa827a36
10 changed files with 711 additions and 711 deletions

126
ipa
View File

@ -38,44 +38,44 @@ def _(msg):
class row(object):
def __init__(self, tab, c1, c2=None):
assert type(tab) is int
assert type(c1) in (str, int)
assert type(c2) is str or c2 is None
self.tab = tab
self.c1 = c1
self.c2 = c2
assert type(tab) is int
assert type(c1) in (str, int)
assert type(c2) is str or c2 is None
self.tab = tab
self.c1 = c1
self.c2 = c2
def __len__(self):
return len(str(self.c1))
return len(str(self.c1))
def pretty_print(self, just):
tab = ' ' * (self.tab * TAB_WIDTH)
if self.c2 is None:
print '%s%s' % (tab, self.c1)
else:
if type(self.c1) is int:
c1 = str(self.c1).rjust(just)
else:
c1 = self.c1.ljust(just)
print '%s%s %s' % (tab, c1, self.c2)
tab = ' ' * (self.tab * TAB_WIDTH)
if self.c2 is None:
print '%s%s' % (tab, self.c1)
else:
if type(self.c1) is int:
c1 = str(self.c1).rjust(just)
else:
c1 = self.c1.ljust(just)
print '%s%s %s' % (tab, c1, self.c2)
def pretty_print(rows):
rows = tuple(rows)
def get_lengths():
yield 0
for r in rows:
if r.c2 is not None:
yield len(r)
yield 0
for r in rows:
if r.c2 is not None:
yield len(r)
max_len = max(get_lengths())
for r in rows:
r.pretty_print(max_len)
r.pretty_print(max_len)
def print_commands():
print 'Commands:'
m = api.max_cmd_len
for cmd in api.cmd:
print ' %s %s' % (str(cmd).ljust(m), cmd.get_doc(_))
print ' %s %s' % (str(cmd).ljust(m), cmd.get_doc(_))
def print_help(cmd):
print 'Help on %s' % cmd
@ -95,53 +95,53 @@ def print_help(cmd):
def print_api():
def iter_api(tab):
for name in api:
ns = getattr(api, name)
yield row(
tab,
name,
repr(ns),
)
for i in ns:
yield row(
tab + 1,
i.name,
repr(i)
)
for name in api:
ns = getattr(api, name)
yield row(
tab,
name,
repr(ns),
)
for i in ns:
yield row(
tab + 1,
i.name,
repr(i)
)
def iter_obj(tab):
for obj in api.obj:
yield row(
tab,
obj.name,
repr(obj),
)
for (n, f) in [('mthd', '.%s()'), ('prop', '.%s')]:
ns = getattr(obj, n)
yield row(
tab + 1,
n,
repr(ns),
)
for attr in ns:
yield row(
tab + 2,
f % attr.name,
repr(attr),
)
for obj in api.obj:
yield row(
tab,
obj.name,
repr(obj),
)
for (n, f) in [('mthd', '.%s()'), ('prop', '.%s')]:
ns = getattr(obj, n)
yield row(
tab + 1,
n,
repr(ns),
)
for attr in ns:
yield row(
tab + 2,
f % attr.name,
repr(attr),
)
def iter_summary(tab):
for name in api:
ns = getattr(api, name)
yield row(
tab,
len(ns),
name
)
for name in api:
ns = getattr(api, name)
yield row(
tab,
len(ns),
name
)
def print_heading(h):
print '\n%s:' % h
print '-' * (len(h) + 1)
print '\n%s:' % h
print '-' * (len(h) + 1)
tab = 1
print_heading('API Overview')

View File

@ -29,44 +29,44 @@ class IPAError(Exception):
msg = None
def __init__(self, *args, **kw):
self.args = args
self.kw = kw
self.args = args
self.kw = kw
def __str__(self):
"""
Returns the string representation of this exception.
"""
if self.msg is None:
if len(self.args) == 1:
return unicode(self.args[0])
return unicode(self.args)
if len(self.args) > 0:
return self.msg % self.args
return self.msg % self.kw
"""
Returns the string representation of this exception.
"""
if self.msg is None:
if len(self.args) == 1:
return unicode(self.args[0])
return unicode(self.args)
if len(self.args) > 0:
return self.msg % self.args
return self.msg % self.kw
class ValidationError(IPAError):
msg = 'invalid %r value %r: %s'
def __init__(self, name, value, error):
self.name = name
self.value = value
self.error = error
super(ValidationError, self).__init__(name, value, error)
self.name = name
self.value = value
self.error = error
super(ValidationError, self).__init__(name, value, error)
class NormalizationError(ValidationError):
def __init__(self, name, value, type):
self.type = type
super(NormalizationError, self).__init__(name, value,
'not %r' % type
)
self.type = type
super(NormalizationError, self).__init__(name, value,
'not %r' % type
)
class RuleError(ValidationError):
def __init__(self, name, value, rule, error):
self.rule = rule
super(RuleError, self).__init__(name, value, error)
self.rule = rule
super(RuleError, self).__init__(name, value, error)
@ -93,11 +93,11 @@ class SubclassError(RegistrationError):
msg = 'plugin %r not subclass of any base in %r'
def __init__(self, cls, allowed):
self.cls = cls
self.allowed = allowed
self.cls = cls
self.allowed = allowed
def __str__(self):
return self.msg % (self.cls, self.allowed)
return self.msg % (self.cls, self.allowed)
class DuplicateError(RegistrationError):
@ -108,10 +108,10 @@ class DuplicateError(RegistrationError):
msg = '%r at %d was already registered'
def __init__(self, cls):
self.cls = cls
self.cls = cls
def __str__(self):
return self.msg % (self.cls, id(self.cls))
return self.msg % (self.cls, id(self.cls))
class OverrideError(RegistrationError):
@ -122,11 +122,11 @@ class OverrideError(RegistrationError):
msg = 'unexpected override of %s.%s with %r (use override=True if intended)'
def __init__(self, base, cls):
self.base = base
self.cls = cls
self.base = base
self.cls = cls
def __str__(self):
return self.msg % (self.base.__name__, self.cls.__name__, self.cls)
return self.msg % (self.base.__name__, self.cls.__name__, self.cls)
class MissingOverrideError(RegistrationError):
@ -137,11 +137,11 @@ class MissingOverrideError(RegistrationError):
msg = '%s.%s has not been registered, cannot override with %r'
def __init__(self, base, cls):
self.base = base
self.cls = cls
self.base = base
self.cls = cls
def __str__(self):
return self.msg % (self.base.__name__, self.cls.__name__, self.cls)
return self.msg % (self.base.__name__, self.cls.__name__, self.cls)

View File

@ -6,49 +6,49 @@
def get_label(self, _):
return _('Title') # Enum?
return _('Title') # Enum?
def get_label(self, _):
return _('First Name')
return _('First Name')
def get_label(self, _):
return _('Last Name')
return _('Last Name')
def get_label(self, _):
return _('Full Name') # Autofill
return _('Full Name') # Autofill
def get_label(self, _):
return _('Display Name') # Autofill
return _('Display Name') # Autofill
def get_label(self, _):
return _('Initials') # generated/ro?
return _('Initials') # generated/ro?
def get_label(self, _):
return _('Account Status') # Enum (active, inactive)
return _('Account Status') # Enum (active, inactive)
def get_label(self, _):
return _('Login')
return _('Login')
def get_label(self, _):
return _('Password')
return _('Password')
def get_label(self, _): # Same field as above, special interface
return _('Confirm Password')
return _('Confirm Password')
def get_label(self, _):
return _('UID') #ro
return _('UID') #ro
def get_label(self, _):
return _('GID') #ro
return _('GID') #ro
def get_label(self, _):
return _('Home Directory') #ro
return _('Home Directory') #ro
def get_label(self, _):
return _('Login Shell')
return _('Login Shell')
def get_label(self, _):
return _('GECOS')
return _('GECOS')
def get_label(self, _):
return _('')
return _('')

View File

@ -51,7 +51,7 @@ def check_identifier(name):
"""
regex = r'^[a-z][_a-z0-9]*[a-z0-9]$'
if re.match(regex, name) is None:
raise errors.NameSpaceError(name, regex)
raise errors.NameSpaceError(name, regex)
class Abstract(object):
@ -79,39 +79,39 @@ class Plugin(object):
__api = None
def __get_api(self):
"""
Returns the plugable.API instance passed to Plugin.finalize(), or
or returns None if finalize() has not yet been called.
"""
return self.__api
"""
Returns the plugable.API instance passed to Plugin.finalize(), or
or returns None if finalize() has not yet been called.
"""
return self.__api
api = property(__get_api)
def finalize(self, api):
"""
After all the plugins are instantiated, the plugable.API calls this
method, passing itself as the only argument. This is where plugins
should check that other plugins they depend upon have actually be
loaded.
"""
assert self.__api is None, 'finalize() can only be called once'
assert api is not None, 'finalize() argument cannot be None'
self.__api = api
"""
After all the plugins are instantiated, the plugable.API calls this
method, passing itself as the only argument. This is where plugins
should check that other plugins they depend upon have actually be
loaded.
"""
assert self.__api is None, 'finalize() can only be called once'
assert api is not None, 'finalize() argument cannot be None'
self.__api = api
def __get_name(self):
"""
Returns the class name of this instance.
"""
return self.__class__.__name__
"""
Returns the class name of this instance.
"""
return self.__class__.__name__
name = property(__get_name)
def __repr__(self):
"""
Returns a fully qualified <module><name> representation of the class.
"""
return '%s.%s()' % (
self.__class__.__module__,
self.__class__.__name__
)
"""
Returns a fully qualified <module><name> representation of the class.
"""
return '%s.%s()' % (
self.__class__.__module__,
self.__class__.__name__
)
class ReadOnly(object):
@ -125,79 +125,79 @@ class ReadOnly(object):
self.__locked = True
def __setattr__(self, name, value):
"""
Raises an AttributeError if ReadOnly._lock() has already been called;
otherwise calls object.__setattr__()
"""
if self.__locked:
raise AttributeError('read-only: cannot set %s.%s' %
(self.__class__.__name__, name)
)
return object.__setattr__(self, name, value)
"""
Raises an AttributeError if ReadOnly._lock() has already been called;
otherwise calls object.__setattr__()
"""
if self.__locked:
raise AttributeError('read-only: cannot set %s.%s' %
(self.__class__.__name__, name)
)
return object.__setattr__(self, name, value)
def __delattr__(self, name):
"""
Raises an AttributeError if ReadOnly._lock() has already been called;
otherwise calls object.__delattr__()
"""
if self.__locked:
raise AttributeError('read-only: cannot del %s.%s' %
(self.__class__.__name__, name)
)
"""
Raises an AttributeError if ReadOnly._lock() has already been called;
otherwise calls object.__delattr__()
"""
if self.__locked:
raise AttributeError('read-only: cannot del %s.%s' %
(self.__class__.__name__, name)
)
return object.__delattr__(self, name)
class Proxy(ReadOnly):
__slots__ = (
'__base',
'__target',
'__name_attr',
'name',
'__public__',
'__base',
'__target',
'__name_attr',
'name',
'__public__',
)
def __init__(self, base, target, name_attr='name'):
if not inspect.isclass(base):
raise TypeError('arg1 must be a class, got %r' % base)
if not isinstance(target, base):
raise ValueError('arg2 must be instance of arg1, got %r' % target)
if not inspect.isclass(base):
raise TypeError('arg1 must be a class, got %r' % base)
if not isinstance(target, base):
raise ValueError('arg2 must be instance of arg1, got %r' % target)
self.__base = base
self.__target = target
self.__name_attr = name_attr
self.name = getattr(target, name_attr)
self.__public__ = base.__public__
assert type(self.__public__) is frozenset
check_identifier(self.name)
self._lock()
self.__target = target
self.__name_attr = name_attr
self.name = getattr(target, name_attr)
self.__public__ = base.__public__
assert type(self.__public__) is frozenset
check_identifier(self.name)
self._lock()
def __iter__(self):
for name in sorted(self.__public__):
yield name
for name in sorted(self.__public__):
yield name
def __getitem__(self, key):
if key in self.__public__:
return getattr(self.__target, key)
raise KeyError('no proxy attribute %r' % key)
if key in self.__public__:
return getattr(self.__target, key)
raise KeyError('no proxy attribute %r' % key)
def __getattr__(self, name):
if name in self.__public__:
return getattr(self.__target, name)
raise AttributeError('no proxy attribute %r' % name)
if name in self.__public__:
return getattr(self.__target, name)
raise AttributeError('no proxy attribute %r' % name)
def __call__(self, *args, **kw):
return self['__call__'](*args, **kw)
return self['__call__'](*args, **kw)
def _clone(self, name_attr):
return self.__class__(self.__base, self.__target, name_attr)
return self.__class__(self.__base, self.__target, name_attr)
def __repr__(self):
return '%s(%s, %r, %r)' % (
self.__class__.__name__,
self.__base.__name__,
self.__target,
self.__name_attr,
)
return '%s(%s, %r, %r)' % (
self.__class__.__name__,
self.__base.__name__,
self.__target,
self.__name_attr,
)
class NameSpace(ReadOnly):
@ -207,167 +207,167 @@ class NameSpace(ReadOnly):
"""
def __init__(self, proxies):
"""
NameSpace
"""
self.__proxies = tuple(proxies)
self.__d = dict()
for proxy in self.__proxies:
assert isinstance(proxy, Proxy)
assert proxy.name not in self.__d
self.__d[proxy.name] = proxy
assert not hasattr(self, proxy.name)
setattr(self, proxy.name, proxy)
self._lock()
"""
NameSpace
"""
self.__proxies = tuple(proxies)
self.__d = dict()
for proxy in self.__proxies:
assert isinstance(proxy, Proxy)
assert proxy.name not in self.__d
self.__d[proxy.name] = proxy
assert not hasattr(self, proxy.name)
setattr(self, proxy.name, proxy)
self._lock()
def __iter__(self):
"""
Iterates through the proxies in this NameSpace in the same order they
were passed in the contructor.
"""
for proxy in self.__proxies:
yield proxy
"""
Iterates through the proxies in this NameSpace in the same order they
were passed in the contructor.
"""
for proxy in self.__proxies:
yield proxy
def __len__(self):
"""
Returns number of proxies in this NameSpace.
"""
return len(self.__proxies)
"""
Returns number of proxies in this NameSpace.
"""
return len(self.__proxies)
def __contains__(self, key):
"""
Returns True if a proxy named `key` is in this NameSpace.
"""
return key in self.__d
"""
Returns True if a proxy named `key` is in this NameSpace.
"""
return key in self.__d
def __getitem__(self, key):
"""
Returns proxy named `key`; otherwise raises KeyError.
"""
if key in self.__d:
return self.__d[key]
raise KeyError('NameSpace has no item for key %r' % key)
"""
Returns proxy named `key`; otherwise raises KeyError.
"""
if key in self.__d:
return self.__d[key]
raise KeyError('NameSpace has no item for key %r' % key)
def __repr__(self):
return '%s(<%d proxies>)' % (self.__class__.__name__, len(self))
return '%s(<%d proxies>)' % (self.__class__.__name__, len(self))
class Registrar(object):
def __init__(self, *allowed):
"""
`*allowed` is a list of the base classes plugins can be subclassed
from.
"""
self.__allowed = frozenset(allowed)
self.__d = {}
self.__registered = set()
assert len(self.__allowed) == len(allowed)
for base in self.__allowed:
assert inspect.isclass(base)
assert base.__name__ not in self.__d
self.__d[base.__name__] = {}
"""
`*allowed` is a list of the base classes plugins can be subclassed
from.
"""
self.__allowed = frozenset(allowed)
self.__d = {}
self.__registered = set()
assert len(self.__allowed) == len(allowed)
for base in self.__allowed:
assert inspect.isclass(base)
assert base.__name__ not in self.__d
self.__d[base.__name__] = {}
def __findbase(self, cls):
"""
If `cls` is a subclass of a base in self.__allowed, returns that
base; otherwise raises SubclassError.
"""
assert inspect.isclass(cls)
found = False
for base in self.__allowed:
if issubclass(cls, base):
found = True
yield base
if not found:
raise errors.SubclassError(cls, self.__allowed)
"""
If `cls` is a subclass of a base in self.__allowed, returns that
base; otherwise raises SubclassError.
"""
assert inspect.isclass(cls)
found = False
for base in self.__allowed:
if issubclass(cls, base):
found = True
yield base
if not found:
raise errors.SubclassError(cls, self.__allowed)
def __call__(self, cls, override=False):
"""
Register the plugin `cls`.
"""
if not inspect.isclass(cls):
raise TypeError('plugin must be a class: %r' % cls)
"""
Register the plugin `cls`.
"""
if not inspect.isclass(cls):
raise TypeError('plugin must be a class: %r' % cls)
# Raise DuplicateError if this exact class was already registered:
if cls in self.__registered:
raise errors.DuplicateError(cls)
# Raise DuplicateError if this exact class was already registered:
if cls in self.__registered:
raise errors.DuplicateError(cls)
# Find the base class or raise SubclassError:
for base in self.__findbase(cls):
sub_d = self.__d[base.__name__]
# Find the base class or raise SubclassError:
for base in self.__findbase(cls):
sub_d = self.__d[base.__name__]
# Check override:
if cls.__name__ in sub_d:
# Must use override=True to override:
if not override:
raise errors.OverrideError(base, cls)
else:
# There was nothing already registered to override:
if override:
raise errors.MissingOverrideError(base, cls)
# Check override:
if cls.__name__ in sub_d:
# Must use override=True to override:
if not override:
raise errors.OverrideError(base, cls)
else:
# There was nothing already registered to override:
if override:
raise errors.MissingOverrideError(base, cls)
# The plugin is okay, add to sub_d:
sub_d[cls.__name__] = cls
# The plugin is okay, add to sub_d:
sub_d[cls.__name__] = cls
# The plugin is okay, add to __registered:
self.__registered.add(cls)
# The plugin is okay, add to __registered:
self.__registered.add(cls)
def __getitem__(self, item):
"""
Returns a copy of the namespace dict of the base class named `name`.
"""
if inspect.isclass(item):
if item not in self.__allowed:
raise KeyError(repr(item))
key = item.__name__
else:
key = item
return dict(self.__d[key])
"""
Returns a copy of the namespace dict of the base class named `name`.
"""
if inspect.isclass(item):
if item not in self.__allowed:
raise KeyError(repr(item))
key = item.__name__
else:
key = item
return dict(self.__d[key])
def __contains__(self, item):
"""
Returns True if a base class named `name` is in this Registrar.
"""
if inspect.isclass(item):
return item in self.__allowed
return item in self.__d
"""
Returns True if a base class named `name` is in this Registrar.
"""
if inspect.isclass(item):
return item in self.__allowed
return item in self.__d
def __iter__(self):
"""
Iterates through a (base, registered_plugins) tuple for each allowed
base.
"""
for base in self.__allowed:
sub_d = self.__d[base.__name__]
yield (base, tuple(sub_d[k] for k in sorted(sub_d)))
"""
Iterates through a (base, registered_plugins) tuple for each allowed
base.
"""
for base in self.__allowed:
sub_d = self.__d[base.__name__]
yield (base, tuple(sub_d[k] for k in sorted(sub_d)))
class API(ReadOnly):
def __init__(self, *allowed):
keys = tuple(b.__name__ for b in allowed)
keys = tuple(b.__name__ for b in allowed)
self.register = Registrar(*allowed)
self._lock()
def __call__(self):
"""
Finalize the registration, instantiate the plugins.
"""
d = {}
def plugin_iter(base, classes):
for cls in classes:
if cls not in d:
d[cls] = cls()
plugin = d[cls]
yield Proxy(base, plugin)
"""
Finalize the registration, instantiate the plugins.
"""
d = {}
def plugin_iter(base, classes):
for cls in classes:
if cls not in d:
d[cls] = cls()
plugin = d[cls]
yield Proxy(base, plugin)
for (base, classes) in self.register:
ns = NameSpace(plugin_iter(base, classes))
assert not hasattr(self, base.__name__)
object.__setattr__(self, base.__name__, ns)
for plugin in d.values():
plugin.finalize(self)
assert plugin.api is self
for (base, classes) in self.register:
ns = NameSpace(plugin_iter(base, classes))
assert not hasattr(self, base.__name__)
object.__setattr__(self, base.__name__, ns)
for plugin in d.values():
plugin.finalize(self)
assert plugin.api is self
def __iter__(self):
for key in self.__keys:
yield key
for key in self.__keys:
yield key

View File

@ -28,34 +28,34 @@ from run import api
# Hypothetical functional commands (not associated with any object):
class krbtest(public.cmd):
def get_doc(self, _):
return _('test your Kerberos ticket')
return _('test your Kerberos ticket')
api.register(krbtest)
class discover(public.cmd):
def get_doc(self, _):
return _('discover IPA servers on network')
return _('discover IPA servers on network')
api.register(discover)
# Register some methods for the 'user' object:
class user_add(public.mthd):
def get_doc(self, _):
return _('add new user')
return _('add new user')
api.register(user_add)
class user_del(public.mthd):
def get_doc(self, _):
return _('delete existing user')
return _('delete existing user')
api.register(user_del)
class user_mod(public.mthd):
def get_doc(self, _):
return _('edit existing user')
return _('edit existing user')
api.register(user_mod)
class user_find(public.mthd):
def get_doc(self, _):
return _('search for users')
return _('search for users')
api.register(user_find)
@ -76,44 +76,44 @@ api.register(user_login)
# Register some methods for the 'group' object:
class group_add(public.mthd):
def get_doc(self, _):
return _('add new group')
return _('add new group')
api.register(group_add)
class group_del(public.mthd):
def get_doc(self, _):
return _('delete existing group')
return _('delete existing group')
api.register(group_del)
class group_mod(public.mthd):
def get_doc(self, _):
return _('edit existing group')
return _('edit existing group')
api.register(group_mod)
class group_find(public.mthd):
def get_doc(self, _):
return _('search for groups')
return _('search for groups')
api.register(group_find)
# Register some methods for the 'service' object
class service_add(public.mthd):
def get_doc(self, _):
return _('add new service')
return _('add new service')
api.register(service_add)
class service_del(public.mthd):
def get_doc(self, _):
return _('delete existing service')
return _('delete existing service')
api.register(service_del)
class service_mod(public.mthd):
def get_doc(self, _):
return _('edit existing service')
return _('edit existing service')
api.register(service_mod)
class service_find(public.mthd):
def get_doc(self, _):
return _('search for services')
return _('search for services')
api.register(service_find)
@ -121,15 +121,15 @@ api.register(service_find)
# we'll register the objects last:
class group(public.obj):
def get_doc(self, _):
return _('')
return _('')
api.register(group)
class service(public.obj):
def get_doc(self, _):
return _('')
return _('')
api.register(service)
class user(public.obj):
def get_doc(self, _):
return _('')
return _('')
api.register(user)

View File

@ -44,249 +44,249 @@ class option(object):
"""
__public__ = frozenset((
'normalize',
'validate',
'default',
'required',
'type',
'normalize',
'validate',
'default',
'required',
'type',
))
__rules = None
# type = unicode, int, float # Set in subclass
def normalize(self, value):
"""
Returns the normalized form of `value`. If `value` cannot be
normalized, NormalizationError is raised, which is a subclass of
ValidationError.
"""
Returns the normalized form of `value`. If `value` cannot be
normalized, NormalizationError is raised, which is a subclass of
ValidationError.
The base class implementation only does type coercion, but subclasses
might do other normalization (e.g., a unicode option might strip
leading and trailing white-space).
"""
try:
return self.type(value)
except (TypeError, ValueError):
raise errors.NormalizationError(
self.__class__.__name__, value, self.type
)
The base class implementation only does type coercion, but subclasses
might do other normalization (e.g., a unicode option might strip
leading and trailing white-space).
"""
try:
return self.type(value)
except (TypeError, ValueError):
raise errors.NormalizationError(
self.__class__.__name__, value, self.type
)
def validate(self, value):
"""
Calls each validation rule and if any rule fails, raises RuleError,
which is a subclass of ValidationError.
"""
for rule in self.rules:
msg = rule(value)
if msg is not None:
raise errors.RuleError(
self.__class__.__name__,
value,
rule,
msg,
)
"""
Calls each validation rule and if any rule fails, raises RuleError,
which is a subclass of ValidationError.
"""
for rule in self.rules:
msg = rule(value)
if msg is not None:
raise errors.RuleError(
self.__class__.__name__,
value,
rule,
msg,
)
def __get_rules(self):
"""
Returns the tuple of rule methods used for input validation. This
tuple is lazily initialized the first time the property is accessed.
"""
if self.__rules is None:
self.__rules = tuple(sorted(
self.__rules_iter(),
key=lambda f: getattr(f, '__name__'),
))
return self.__rules
"""
Returns the tuple of rule methods used for input validation. This
tuple is lazily initialized the first time the property is accessed.
"""
if self.__rules is None:
self.__rules = tuple(sorted(
self.__rules_iter(),
key=lambda f: getattr(f, '__name__'),
))
return self.__rules
rules = property(__get_rules)
def __rules_iter(self):
"""
Iterates through the attributes in this instance to retrieve the
methods implementing validation rules.
"""
for name in dir(self.__class__):
if name.startswith('_'):
continue
base_attr = getattr(self.__class__, name)
if is_rule(base_attr):
attr = getattr(self, name)
if is_rule(attr):
yield attr
"""
Iterates through the attributes in this instance to retrieve the
methods implementing validation rules.
"""
for name in dir(self.__class__):
if name.startswith('_'):
continue
base_attr = getattr(self.__class__, name)
if is_rule(base_attr):
attr = getattr(self, name)
if is_rule(attr):
yield attr
def default(self, **kw):
"""
Returns a default or auto-completed value for this option. If no
default is available, this method should return None.
"""
Returns a default or auto-completed value for this option. If no
default is available, this method should return None.
All the keywords are passed so it's possible to build an
auto-completed value from other options values, e.g., build 'initials'
from 'givenname' + 'sn'.
"""
return None
All the keywords are passed so it's possible to build an
auto-completed value from other options values, e.g., build 'initials'
from 'givenname' + 'sn'.
"""
return None
class cmd(plugable.Plugin):
__public__ = frozenset((
'normalize',
'autofill',
'__call__',
'get_doc',
'opt',
'normalize',
'autofill',
'__call__',
'get_doc',
'opt',
))
__opt = None
def get_doc(self, _):
"""
Returns the gettext translated doc-string for this command.
"""
Returns the gettext translated doc-string for this command.
For example:
For example:
>>> def get_doc(self, _):
>>> return _('add new user')
"""
raise NotImplementedError('%s.get_doc()' % self.name)
>>> def get_doc(self, _):
>>> return _('add new user')
"""
raise NotImplementedError('%s.get_doc()' % self.name)
def get_options(self):
"""
Returns iterable with opt_proxy objects used to create the opt
NameSpace when __get_opt() is called.
"""
raise NotImplementedError('%s.get_options()' % self.name)
"""
Returns iterable with opt_proxy objects used to create the opt
NameSpace when __get_opt() is called.
"""
raise NotImplementedError('%s.get_options()' % self.name)
def __get_opt(self):
"""
Returns the NameSpace containing opt_proxy objects.
"""
if self.__opt is None:
self.__opt = plugable.NameSpace(self.get_options())
return self.__opt
"""
Returns the NameSpace containing opt_proxy objects.
"""
if self.__opt is None:
self.__opt = plugable.NameSpace(self.get_options())
return self.__opt
opt = property(__get_opt)
def normalize_iter(self, kw):
for (key, value) in kw.items():
if key in self.options:
yield (
key, self.options[key].normalize(value)
)
else:
yield (key, value)
for (key, value) in kw.items():
if key in self.options:
yield (
key, self.options[key].normalize(value)
)
else:
yield (key, value)
def normalize(self, **kw):
return dict(self.normalize_iter(kw))
return dict(self.normalize_iter(kw))
def validate(self, **kw):
for (key, value) in kw.items():
if key in self.options:
self.options.validate(value)
for (key, value) in kw.items():
if key in self.options:
self.options.validate(value)
def default(self, **kw):
d = {}
for opt in self.options:
if opt.name not in kw:
value = opt.default(**kw)
if value is not None:
d[opt.name] = value
assert not set(kw).intersection(d)
kw.update(d)
return kw
for opt in self.options:
if opt.name not in kw:
value = opt.default(**kw)
if value is not None:
d[opt.name] = value
assert not set(kw).intersection(d)
kw.update(d)
return kw
def __call__(self, **kw):
(args, kw) = self.normalize(*args, **kw)
(args, kw) = self.autofill(*args, **kw)
self.validate(*args, **kw)
self.execute(*args, **kw)
(args, kw) = self.normalize(*args, **kw)
(args, kw) = self.autofill(*args, **kw)
self.validate(*args, **kw)
self.execute(*args, **kw)
class obj(plugable.Plugin):
__public__ = frozenset((
'mthd',
'prop',
'mthd',
'prop',
))
__mthd = None
__prop = None
def __get_mthd(self):
return self.__mthd
return self.__mthd
mthd = property(__get_mthd)
def __get_prop(self):
return self.__prop
return self.__prop
prop = property(__get_prop)
def finalize(self, api):
super(obj, self).finalize(api)
self.__mthd = self.__create_ns('mthd')
self.__prop = self.__create_ns('prop')
super(obj, self).finalize(api)
self.__mthd = self.__create_ns('mthd')
self.__prop = self.__create_ns('prop')
def __create_ns(self, name):
return plugable.NameSpace(self.__filter(name))
return plugable.NameSpace(self.__filter(name))
def __filter(self, name):
for i in getattr(self.api, name):
if i.obj_name == self.name:
yield i._clone('attr_name')
for i in getattr(self.api, name):
if i.obj_name == self.name:
yield i._clone('attr_name')
class attr(plugable.Plugin):
__obj = None
def __init__(self):
m = re.match('^([a-z]+)_([a-z]+)$', self.__class__.__name__)
assert m
self.__obj_name = m.group(1)
self.__attr_name = m.group(2)
m = re.match('^([a-z]+)_([a-z]+)$', self.__class__.__name__)
assert m
self.__obj_name = m.group(1)
self.__attr_name = m.group(2)
def __get_obj_name(self):
return self.__obj_name
return self.__obj_name
obj_name = property(__get_obj_name)
def __get_attr_name(self):
return self.__attr_name
return self.__attr_name
attr_name = property(__get_attr_name)
def __get_obj(self):
"""
Returns the obj instance this attribute is associated with, or None
if no association has been set.
"""
return self.__obj
"""
Returns the obj instance this attribute is associated with, or None
if no association has been set.
"""
return self.__obj
obj = property(__get_obj)
def finalize(self, api):
super(attr, self).finalize(api)
self.__obj = api.obj[self.obj_name]
super(attr, self).finalize(api)
self.__obj = api.obj[self.obj_name]
class mthd(attr, cmd):
__public__ = frozenset((
'obj',
'obj_name',
'obj',
'obj_name',
))
class prop(attr):
__public__ = frozenset((
'obj',
'obj_name',
'obj',
'obj_name',
))
def get_doc(self, _):
return _('prop doc')
return _('prop doc')
class PublicAPI(plugable.API):
__max_cmd_len = None
def __init__(self):
super(PublicAPI, self).__init__(cmd, obj, mthd, prop)
super(PublicAPI, self).__init__(cmd, obj, mthd, prop)
def __get_max_cmd_len(self):
if self.__max_cmd_len is None:
if not hasattr(self, 'cmd'):
return None
max_cmd_len = max(len(str(cmd)) for cmd in self.cmd)
object.__setattr__(self, '_PublicAPI__max_cmd_len', max_cmd_len)
return self.__max_cmd_len
if self.__max_cmd_len is None:
if not hasattr(self, 'cmd'):
return None
max_cmd_len = max(len(str(cmd)) for cmd in self.cmd)
object.__setattr__(self, '_PublicAPI__max_cmd_len', max_cmd_len)
return self.__max_cmd_len
max_cmd_len = property(__get_max_cmd_len)

View File

@ -40,25 +40,25 @@ def test_from_cli():
def test_valid_identifier():
f = plugable.check_identifier
okay = [
'user_add',
'stuff2junk',
'sixty9',
'user_add',
'stuff2junk',
'sixty9',
]
nope = [
'_user_add',
'__user_add',
'user_add_',
'user_add__',
'_user_add_',
'__user_add__',
'60nine',
'_user_add',
'__user_add',
'user_add_',
'user_add__',
'_user_add_',
'__user_add__',
'60nine',
]
for name in okay:
f(name)
f(name)
for name in nope:
raises(errors.NameSpaceError, f, name)
raises(errors.NameSpaceError, f, name)
for name in okay:
raises(errors.NameSpaceError, f, name.upper())
raises(errors.NameSpaceError, f, name.upper())
def test_Abstract():
@ -126,7 +126,7 @@ def test_Plugin():
raises(AssertionError, p.finalize, api)
class some_plugin(plugable.Plugin):
pass
pass
p = some_plugin()
assert read_only(p, 'name') == 'some_plugin'
assert repr(p) == '%s.some_plugin()' % __name__
@ -142,17 +142,17 @@ def test_ReadOnly():
obj._lock()
names = ['not_an_attribute', 'an_attribute']
for name in names:
no_set(obj, name)
no_del(obj, name)
no_set(obj, name)
no_del(obj, name)
class some_ro_class(plugable.ReadOnly):
def __init__(self):
self.an_attribute = 'Hello world!'
self._lock()
def __init__(self):
self.an_attribute = 'Hello world!'
self._lock()
obj = some_ro_class()
for name in names:
no_set(obj, name)
no_del(obj, name)
no_set(obj, name)
no_del(obj, name)
assert read_only(obj, 'an_attribute') == 'Hello world!'
@ -162,30 +162,30 @@ def test_Proxy():
# Setup:
class base(object):
__public__ = frozenset((
'public_0',
'public_1',
'__call__',
))
__public__ = frozenset((
'public_0',
'public_1',
'__call__',
))
def public_0(self):
return 'public_0'
def public_0(self):
return 'public_0'
def public_1(self):
return 'public_1'
def public_1(self):
return 'public_1'
def __call__(self, caller):
return 'ya called it, %s.' % caller
def __call__(self, caller):
return 'ya called it, %s.' % caller
def private_0(self):
return 'private_0'
def private_0(self):
return 'private_0'
def private_1(self):
return 'private_1'
def private_1(self):
return 'private_1'
class plugin(base):
name = 'user_add'
attr_name = 'add'
name = 'user_add'
attr_name = 'add'
# Test that TypeError is raised when base is not a class:
raises(TypeError, cls, base(), None)
@ -201,13 +201,13 @@ def test_Proxy():
# Test normal methods:
for n in xrange(2):
pub = 'public_%d' % n
priv = 'private_%d' % n
assert getattr(i, pub)() == pub
assert getattr(p, pub)() == pub
assert hasattr(p, pub)
assert getattr(i, priv)() == priv
assert not hasattr(p, priv)
pub = 'public_%d' % n
priv = 'private_%d' % n
assert getattr(i, pub)() == pub
assert getattr(p, pub)() == pub
assert hasattr(p, pub)
assert getattr(i, priv)() == priv
assert not hasattr(p, priv)
# Test __call__:
value = 'ya called it, dude.'
@ -236,23 +236,23 @@ def test_NameSpace():
assert issubclass(cls, plugable.ReadOnly)
class base(object):
__public__ = frozenset((
'plusplus',
))
__public__ = frozenset((
'plusplus',
))
def plusplus(self, n):
return n + 1
def plusplus(self, n):
return n + 1
class plugin(base):
def __init__(self, name):
self.name = name
def __init__(self, name):
self.name = name
def get_name(i):
return 'noun_verb%d' % i
return 'noun_verb%d' % i
def get_proxies(n):
for i in xrange(n):
yield plugable.Proxy(base, plugin(get_name(i)))
for i in xrange(n):
yield plugable.Proxy(base, plugin(get_name(i)))
cnt = 20
ns = cls(get_proxies(cnt))
@ -263,20 +263,20 @@ def test_NameSpace():
# Test __iter__
i = None
for (i, proxy) in enumerate(ns):
assert type(proxy) is plugable.Proxy
assert proxy.name == get_name(i)
assert type(proxy) is plugable.Proxy
assert proxy.name == get_name(i)
assert i == cnt - 1
# Test __contains__, __getitem__, getattr():
proxies = frozenset(ns)
for i in xrange(cnt):
name = get_name(i)
assert name in ns
proxy = ns[name]
assert proxy.name == name
assert type(proxy) is plugable.Proxy
assert proxy in proxies
assert read_only(ns, name) is proxy
name = get_name(i)
assert name in ns
proxy = ns[name]
assert proxy.name == name
assert type(proxy) is plugable.Proxy
assert proxy in proxies
assert read_only(ns, name) is proxy
# Test dir():
assert set(get_name(i) for i in xrange(cnt)).issubset(set(dir(ns)))
@ -291,27 +291,27 @@ def test_NameSpace():
def test_Registrar():
class Base1(object):
pass
pass
class Base2(object):
pass
pass
class Base3(object):
pass
pass
class plugin1(Base1):
pass
pass
class plugin2(Base2):
pass
pass
class plugin3(Base3):
pass
pass
# Test creation of Registrar:
r = plugable.Registrar(Base1, Base2)
# Test __hasitem__, __getitem__:
for base in [Base1, Base2]:
assert base in r
assert base.__name__ in r
assert r[base] == {}
assert r[base.__name__] == {}
assert base in r
assert base.__name__ in r
assert r[base] == {}
assert r[base.__name__] == {}
# Check that TypeError is raised trying to register something that isn't
@ -339,9 +339,9 @@ def test_Registrar():
# name and same base:
orig1 = plugin1
class base1_extended(Base1):
pass
pass
class plugin1(base1_extended):
pass
pass
raises(errors.OverrideError, r, plugin1)
# Check that overriding works
@ -364,40 +364,40 @@ def test_Registrar():
# Setup to test __iter__:
class plugin1a(Base1):
pass
pass
r(plugin1a)
class plugin1b(Base1):
pass
pass
r(plugin1b)
class plugin2a(Base2):
pass
pass
r(plugin2a)
class plugin2b(Base2):
pass
pass
r(plugin2b)
m = {
'Base1': set([plugin1, plugin1a, plugin1b]),
'Base2': set([plugin2, plugin2a, plugin2b]),
'Base1': set([plugin1, plugin1a, plugin1b]),
'Base2': set([plugin2, plugin2a, plugin2b]),
}
# Now test __iter__:
for (base, plugins) in r:
assert base in [Base1, Base2]
assert set(plugins) == m[base.__name__]
assert base in [Base1, Base2]
assert set(plugins) == m[base.__name__]
assert len(list(r)) == 2
# Again test __hasitem__, __getitem__:
for base in [Base1, Base2]:
assert base in r
assert base.__name__ in r
d = dict((p.__name__, p) for p in m[base.__name__])
assert len(d) == 3
assert r[base] == d
assert r[base.__name__] == d
assert base in r
assert base.__name__ in r
d = dict((p.__name__, p) for p in m[base.__name__])
assert len(d) == 3
assert r[base] == d
assert r[base.__name__] == d
def test_API():
@ -405,20 +405,20 @@ def test_API():
# Setup the test bases, create the API:
class base0(plugable.Plugin):
__public__ = frozenset((
'method',
))
__public__ = frozenset((
'method',
))
def method(self, n):
return n
def method(self, n):
return n
class base1(plugable.Plugin):
__public__ = frozenset((
'method',
))
__public__ = frozenset((
'method',
))
def method(self, n):
return n + 1
def method(self, n):
return n + 1
api = plugable.API(base0, base1)
r = api.register
@ -426,48 +426,48 @@ def test_API():
assert read_only(api, 'register') is r
class base0_plugin0(base0):
pass
pass
r(base0_plugin0)
class base0_plugin1(base0):
pass
pass
r(base0_plugin1)
class base0_plugin2(base0):
pass
pass
r(base0_plugin2)
class base1_plugin0(base1):
pass
pass
r(base1_plugin0)
class base1_plugin1(base1):
pass
pass
r(base1_plugin1)
class base1_plugin2(base1):
pass
pass
r(base1_plugin2)
# Test API instance:
api() # Calling instance performs finalization
def get_base(b):
return 'base%d' % b
return 'base%d' % b
def get_plugin(b, p):
return 'base%d_plugin%d' % (b, p)
return 'base%d_plugin%d' % (b, p)
for b in xrange(2):
base_name = get_base(b)
ns = getattr(api, base_name)
assert isinstance(ns, plugable.NameSpace)
assert read_only(api, base_name) is ns
assert len(ns) == 3
for p in xrange(3):
plugin_name = get_plugin(b, p)
proxy = ns[plugin_name]
assert isinstance(proxy, plugable.Proxy)
assert proxy.name == plugin_name
assert read_only(ns, plugin_name) is proxy
assert read_only(proxy, 'method')(7) == 7 + b
base_name = get_base(b)
ns = getattr(api, base_name)
assert isinstance(ns, plugable.NameSpace)
assert read_only(api, base_name) is ns
assert len(ns) == 3
for p in xrange(3):
plugin_name = get_plugin(b, p)
proxy = ns[plugin_name]
assert isinstance(proxy, plugable.Proxy)
assert proxy.name == plugin_name
assert read_only(ns, plugin_name) is proxy
assert read_only(proxy, 'method')(7) == 7 + b

View File

@ -33,13 +33,13 @@ def test_rule():
flag = public.RULE_FLAG
rule = public.rule
def my_func():
pass
pass
assert not hasattr(my_func, flag)
rule(my_func)
assert getattr(my_func, flag) is True
@rule
def my_func2():
pass
pass
assert getattr(my_func2, flag) is True
@ -48,14 +48,14 @@ def test_is_rule():
flag = public.RULE_FLAG
class no_call(object):
def __init__(self, value):
if value is not None:
assert value in (True, False)
setattr(self, flag, value)
def __init__(self, value):
if value is not None:
assert value in (True, False)
setattr(self, flag, value)
class call(no_call):
def __call__(self):
pass
def __call__(self):
pass
assert is_rule(call(True))
assert not is_rule(no_call(True))
@ -90,81 +90,81 @@ class test_option(ClassChecker):
_cls = public.option
def get_subcls(self):
rule = public.rule
class int_opt(self.cls):
type = int
@rule
def rule_0(self, value):
if value == 0:
return 'cannot be 0'
@rule
def rule_1(self, value):
if value == 1:
return 'cannot be 1'
@rule
def rule_2(self, value):
if value == 2:
return 'cannot be 2'
return int_opt
rule = public.rule
class int_opt(self.cls):
type = int
@rule
def rule_0(self, value):
if value == 0:
return 'cannot be 0'
@rule
def rule_1(self, value):
if value == 1:
return 'cannot be 1'
@rule
def rule_2(self, value):
if value == 2:
return 'cannot be 2'
return int_opt
def test_class(self):
"""
Perform some tests on the class (not an instance).
"""
#assert issubclass(cls, plugable.ReadOnly)
assert type(self.cls.rules) is property
"""
Perform some tests on the class (not an instance).
"""
#assert issubclass(cls, plugable.ReadOnly)
assert type(self.cls.rules) is property
def test_normalize(self):
assert 'normalize' in self.cls.__public__
o = self.subcls()
# Test with values that can't be converted:
nope = (
'7.0'
'whatever',
object,
None,
)
for val in nope:
e = raises(errors.NormalizationError, o.normalize, val)
assert isinstance(e, errors.ValidationError)
assert e.name == 'int_opt'
assert e.value == val
assert e.error == "not <type 'int'>"
assert e.type is int
# Test with values that can be converted:
okay = (
7,
7.0,
7.2,
7L,
'7',
' 7 ',
)
for val in okay:
assert o.normalize(val) == 7
o = self.subcls()
# Test with values that can't be converted:
nope = (
'7.0'
'whatever',
object,
None,
)
for val in nope:
e = raises(errors.NormalizationError, o.normalize, val)
assert isinstance(e, errors.ValidationError)
assert e.name == 'int_opt'
assert e.value == val
assert e.error == "not <type 'int'>"
assert e.type is int
# Test with values that can be converted:
okay = (
7,
7.0,
7.2,
7L,
'7',
' 7 ',
)
for val in okay:
assert o.normalize(val) == 7
def test_validate(self):
"""
Test the validate method.
"""
assert 'validate' in self.cls.__public__
o = self.subcls()
o.validate(9)
for i in xrange(3):
e = raises(errors.RuleError, o.validate, i)
assert e.error == 'cannot be %d' % i
assert e.value == i
"""
Test the validate method.
"""
assert 'validate' in self.cls.__public__
o = self.subcls()
o.validate(9)
for i in xrange(3):
e = raises(errors.RuleError, o.validate, i)
assert e.error == 'cannot be %d' % i
assert e.value == i
def test_rules(self):
"""
Test the rules property.
"""
o = self.subcls()
assert len(o.rules) == 3
def get_rule(i):
return getattr(o, 'rule_%d' % i)
rules = tuple(get_rule(i) for i in xrange(3))
assert o.rules == rules
"""
Test the rules property.
"""
o = self.subcls()
assert len(o.rules) == 3
def get_rule(i):
return getattr(o, 'rule_%d' % i)
rules = tuple(get_rule(i) for i in xrange(3))
assert o.rules == rules
def test_default(self):
assert 'default' in self.cls.__public__
@ -190,10 +190,10 @@ def test_attr():
assert issubclass(cls, plugable.Plugin)
class api(object):
obj = dict(user='the user obj')
obj = dict(user='the user obj')
class user_add(cls):
pass
pass
i = user_add()
assert read_only(i, 'obj_name') == 'user'
@ -222,11 +222,11 @@ def test_PublicAPI():
api = cls()
class cmd1(public.cmd):
pass
pass
api.register(cmd1)
class cmd2(public.cmd):
pass
pass
api.register(cmd2)
api()

View File

@ -26,23 +26,23 @@ import tstutil
class Prop(object):
def __init__(self, *ops):
self.__ops = frozenset(ops)
self.__prop = 'prop value'
self.__ops = frozenset(ops)
self.__prop = 'prop value'
def __get_prop(self):
if 'get' not in self.__ops:
raise AttributeError('get prop')
return self.__prop
if 'get' not in self.__ops:
raise AttributeError('get prop')
return self.__prop
def __set_prop(self, value):
if 'set' not in self.__ops:
raise AttributeError('set prop')
self.__prop = value
if 'set' not in self.__ops:
raise AttributeError('set prop')
self.__prop = value
def __del_prop(self):
if 'del' not in self.__ops:
raise AttributeError('del prop')
self.__prop = None
if 'del' not in self.__ops:
raise AttributeError('del prop')
self.__prop = None
prop = property(__get_prop, __set_prop, __del_prop)
@ -51,36 +51,36 @@ def test_yes_raised():
f = tstutil.raises
class SomeError(Exception):
pass
pass
class AnotherError(Exception):
pass
pass
def callback1():
'raises correct exception'
raise SomeError()
'raises correct exception'
raise SomeError()
def callback2():
'raises wrong exception'
raise AnotherError()
'raises wrong exception'
raise AnotherError()
def callback3():
'raises no exception'
'raises no exception'
f(SomeError, callback1)
raised = False
try:
f(SomeError, callback2)
f(SomeError, callback2)
except AnotherError:
raised = True
raised = True
assert raised
raised = False
try:
f(SomeError, callback3)
f(SomeError, callback3)
except tstutil.ExceptionNotRaised:
raised = True
raised = True
assert raised
@ -91,9 +91,9 @@ def test_no_set():
# Tests that ExceptionNotRaised is raised when prop *can* be set:
raised = False
try:
tstutil.no_set(Prop('set'), 'prop')
tstutil.no_set(Prop('set'), 'prop')
except tstutil.ExceptionNotRaised:
raised = True
raised = True
assert raised
@ -104,9 +104,9 @@ def test_no_del():
# Tests that ExceptionNotRaised is raised when prop *can* be set:
raised = False
try:
tstutil.no_del(Prop('del'), 'prop')
tstutil.no_del(Prop('del'), 'prop')
except tstutil.ExceptionNotRaised:
raised = True
raised = True
assert raised
@ -117,32 +117,32 @@ def test_read_only():
# Test that ExceptionNotRaised is raised when prop can be set:
raised = False
try:
tstutil.read_only(Prop('get', 'set'), 'prop')
tstutil.read_only(Prop('get', 'set'), 'prop')
except tstutil.ExceptionNotRaised:
raised = True
raised = True
assert raised
# Test that ExceptionNotRaised is raised when prop can be deleted:
raised = False
try:
tstutil.read_only(Prop('get', 'del'), 'prop')
tstutil.read_only(Prop('get', 'del'), 'prop')
except tstutil.ExceptionNotRaised:
raised = True
raised = True
assert raised
# Test that ExceptionNotRaised is raised when prop can be both set and
# deleted:
raised = False
try:
tstutil.read_only(Prop('get', 'del'), 'prop')
tstutil.read_only(Prop('get', 'del'), 'prop')
except tstutil.ExceptionNotRaised:
raised = True
raised = True
assert raised
# Test that AttributeError is raised when prop can't be read:
raised = False
try:
tstutil.read_only(Prop(), 'prop')
tstutil.read_only(Prop(), 'prop')
except AttributeError:
raised = True
raised = True
assert raised

View File

@ -29,10 +29,10 @@ class ExceptionNotRaised(Exception):
msg = 'expected %s'
def __init__(self, expected):
self.expected = expected
self.expected = expected
def __str__(self):
return self.msg % self.expected.__name__
return self.msg % self.expected.__name__
def raises(exception, callback, *args, **kw):
@ -42,11 +42,11 @@ def raises(exception, callback, *args, **kw):
"""
raised = False
try:
callback(*args, **kw)
callback(*args, **kw)
except exception, e:
raised = True
raised = True
if not raised:
raise ExceptionNotRaised(exception)
raise ExceptionNotRaised(exception)
return e
@ -93,7 +93,7 @@ def is_prop(prop):
class ClassChecker(object):
def new(self, *args, **kw):
return self.cls(*args, **kw)
return self.cls(*args, **kw)
def get_sub(self):
raise NotImplementedError('get_sub()')
raise NotImplementedError('get_sub()')