From d7569a84b94ab304a1b7f353ea71c15061ebd5d4 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Thu, 31 Jul 2008 18:57:10 +0000 Subject: 31: Renamed exceptions.py to errors.py --- ipalib/errors.py | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 ipalib/errors.py (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py new file mode 100644 index 00000000..53a0870e --- /dev/null +++ b/ipalib/errors.py @@ -0,0 +1,127 @@ +# Authors: +# Jason Gerard DeRose +# +# Copyright (C) 2008 Red Hat +# see file 'COPYING' for use and warranty inmsgion +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; version 2 only +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +""" +All custom errors raised by `ipalib` package. +""" + +class IPAError(Exception): + """ + Use this base class for your custom IPA errors unless there is a + specific reason to subclass from AttributeError, KeyError, etc. + """ + msg = None + + def __init__(self, *args, **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 + + + + + +class SetError(IPAError): + msg = 'setting %r, but NameSpace does not allow attribute setting' + + + + + + + +class RegistrationError(IPAError): + """ + Base class for errors that occur during plugin registration. + """ + + +class SubclassError(RegistrationError): + """ + Raised when registering a plugin that is not a subclass of one of the + allowed bases. + """ + msg = 'plugin %r not subclass of any base in %r' + + def __init__(self, cls, allowed): + self.cls = cls + self.allowed = allowed + + def __str__(self): + return self.msg % (self.cls, self.allowed) + + +class DuplicateError(RegistrationError): + """ + Raised when registering a plugin whose exact class has already been + registered. + """ + msg = '%r at %d was already registered' + + def __init__(self, cls): + self.cls = cls + + def __str__(self): + return self.msg % (self.cls, id(self.cls)) + + +class OverrideError(RegistrationError): + """ + Raised when override=False yet registering a plugin that overrides an + existing plugin in the same namespace. + """ + msg = 'unexpected override of %s.%s with %r (use override=True if intended)' + + def __init__(self, base, cls): + self.base = base + self.cls = cls + + def __str__(self): + return self.msg % (self.base.__name__, self.cls.__name__, self.cls) + + +class MissingOverrideError(RegistrationError): + """ + Raised when override=True yet no preexisting plugin with the same name + and base has been registered. + """ + msg = '%s.%s has not been registered, cannot override with %r' + + def __init__(self, base, cls): + self.base = base + self.cls = cls + + def __str__(self): + return self.msg % (self.base.__name__, self.cls.__name__, self.cls) + + + +class TwiceSetError(IPAError): + msg = '%s.%s cannot be set twice' -- cgit From 56fa454fdd229524999127a5b89cc7c9077b9bd6 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Tue, 5 Aug 2008 06:33:09 +0000 Subject: 47: Added plugable.check_identifier() function; added corresponding unit tests --- ipalib/errors.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index 53a0870e..e9f78477 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -56,13 +56,16 @@ class SetError(IPAError): - class RegistrationError(IPAError): """ Base class for errors that occur during plugin registration. """ +class NameSpaceError(RegistrationError): + msg = 'name %r does not re.match %r' + + class SubclassError(RegistrationError): """ Raised when registering a plugin that is not a subclass of one of the -- cgit From f13f1226b4b798fd901ece6b9a37c06ca25c3c2e Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Wed, 6 Aug 2008 21:54:56 +0000 Subject: 65: Finished simplified Proxy2 class; updated unit tests --- ipalib/errors.py | 3 --- 1 file changed, 3 deletions(-) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index e9f78477..b86ffcdb 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -53,9 +53,6 @@ class SetError(IPAError): - - - class RegistrationError(IPAError): """ Base class for errors that occur during plugin registration. -- cgit From fadbae642053565be1d10bc5d6b40b151a97ff16 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Thu, 7 Aug 2008 03:38:49 +0000 Subject: 72: Started work on public.opt class; added corresponding unit tests --- ipalib/errors.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index b86ffcdb..6b1a898a 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -45,6 +45,26 @@ class IPAError(Exception): 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) + +class NormalizationError(ValidationError): + def __init__(self, name, value, type): + self.type = type + super(NormalizationError, self).__init__(name, value, + 'not %r' % type + ) + + + +class ValidationRuleError(ValidationError): + msg = '%r is invalid %r: %s' -- cgit From 14a0658464b0a4696a2788692610a7fdade2fdbd Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Thu, 7 Aug 2008 06:23:02 +0000 Subject: 76: Fleshed out opt.validate(); added corresponding unit tests --- ipalib/errors.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index 6b1a898a..f1162827 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -54,6 +54,7 @@ class ValidationError(IPAError): self.error = error super(ValidationError, self).__init__(name, value, error) + class NormalizationError(ValidationError): def __init__(self, name, value, type): self.type = type @@ -62,9 +63,10 @@ class NormalizationError(ValidationError): ) - -class ValidationRuleError(ValidationError): - msg = '%r is invalid %r: %s' +class RuleError(ValidationError): + def __init__(self, name, value, rule, error): + self.rule = rule + super(RuleError, self).__init__(name, value, error) -- cgit From 8e468248155947075689e6d01c3ab90fbd9f1643 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Fri, 8 Aug 2008 17:11:29 +0000 Subject: 81: Switch from tab to 4-space indentation --- ipalib/errors.py | 160 +++++++++++++++++++++++++++---------------------------- 1 file changed, 80 insertions(+), 80 deletions(-) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index f1162827..ee0b931b 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -22,128 +22,128 @@ All custom errors raised by `ipalib` package. """ class IPAError(Exception): - """ - Use this base class for your custom IPA errors unless there is a - specific reason to subclass from AttributeError, KeyError, etc. - """ - msg = None - - def __init__(self, *args, **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 + """ + Use this base class for your custom IPA errors unless there is a + specific reason to subclass from AttributeError, KeyError, etc. + """ + msg = None + + def __init__(self, *args, **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 class ValidationError(IPAError): - msg = 'invalid %r value %r: %s' + 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) + def __init__(self, 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 - ) + def __init__(self, name, value, 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) + def __init__(self, name, value, rule, error): + self.rule = rule + super(RuleError, self).__init__(name, value, error) class SetError(IPAError): - msg = 'setting %r, but NameSpace does not allow attribute setting' + msg = 'setting %r, but NameSpace does not allow attribute setting' class RegistrationError(IPAError): - """ - Base class for errors that occur during plugin registration. - """ + """ + Base class for errors that occur during plugin registration. + """ class NameSpaceError(RegistrationError): - msg = 'name %r does not re.match %r' + msg = 'name %r does not re.match %r' class SubclassError(RegistrationError): - """ - Raised when registering a plugin that is not a subclass of one of the - allowed bases. - """ - msg = 'plugin %r not subclass of any base in %r' + """ + Raised when registering a plugin that is not a subclass of one of the + allowed bases. + """ + msg = 'plugin %r not subclass of any base in %r' - def __init__(self, cls, allowed): - self.cls = cls - self.allowed = allowed + def __init__(self, cls, allowed): + self.cls = cls + self.allowed = allowed - def __str__(self): - return self.msg % (self.cls, self.allowed) + def __str__(self): + return self.msg % (self.cls, self.allowed) class DuplicateError(RegistrationError): - """ - Raised when registering a plugin whose exact class has already been - registered. - """ - msg = '%r at %d was already registered' + """ + Raised when registering a plugin whose exact class has already been + registered. + """ + msg = '%r at %d was already registered' - def __init__(self, cls): - self.cls = cls + def __init__(self, cls): + self.cls = cls - def __str__(self): - return self.msg % (self.cls, id(self.cls)) + def __str__(self): + return self.msg % (self.cls, id(self.cls)) class OverrideError(RegistrationError): - """ - Raised when override=False yet registering a plugin that overrides an - existing plugin in the same namespace. - """ - msg = 'unexpected override of %s.%s with %r (use override=True if intended)' + """ + Raised when override=False yet registering a plugin that overrides an + existing plugin in the same namespace. + """ + msg = 'unexpected override of %s.%s with %r (use override=True if intended)' - def __init__(self, base, cls): - self.base = base - self.cls = cls + def __init__(self, base, cls): + self.base = base + self.cls = cls - def __str__(self): - return self.msg % (self.base.__name__, self.cls.__name__, self.cls) + def __str__(self): + return self.msg % (self.base.__name__, self.cls.__name__, self.cls) class MissingOverrideError(RegistrationError): - """ - Raised when override=True yet no preexisting plugin with the same name - and base has been registered. - """ - msg = '%s.%s has not been registered, cannot override with %r' + """ + Raised when override=True yet no preexisting plugin with the same name + and base has been registered. + """ + msg = '%s.%s has not been registered, cannot override with %r' - def __init__(self, base, cls): - self.base = base - self.cls = cls + def __init__(self, base, cls): + self.base = base + self.cls = cls - def __str__(self): - return self.msg % (self.base.__name__, self.cls.__name__, self.cls) + def __str__(self): + return self.msg % (self.base.__name__, self.cls.__name__, self.cls) class TwiceSetError(IPAError): - msg = '%s.%s cannot be set twice' + msg = '%s.%s cannot be set twice' -- cgit From fdfa827a36df87fd6b228fc1560576e268413104 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Fri, 8 Aug 2008 21:40:03 +0000 Subject: 86: Actually change *all* tab indentation to 4-space: 'sed s/\t/ /g' --- ipalib/errors.py | 66 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index ee0b931b..1fc0c90c 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -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) -- cgit From 47fed6c4c2ec509f1283bf18c4aad6eff9a4b756 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Wed, 13 Aug 2008 04:11:26 +0000 Subject: 142: python2.4: Fixed custom exceptions in errors.py as exceptions in Python2.4 are not new-style classes --- ipalib/errors.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index 1fc0c90c..47e0a3ed 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -52,13 +52,13 @@ class ValidationError(IPAError): self.name = name self.value = value self.error = error - super(ValidationError, self).__init__(name, value, error) + IPAError.__init__(self, name, value, error) class NormalizationError(ValidationError): def __init__(self, name, value, type): self.type = type - super(NormalizationError, self).__init__(name, value, + ValidationError.__init__(self, name, value, 'not %r' % type ) @@ -66,7 +66,7 @@ class NormalizationError(ValidationError): class RuleError(ValidationError): def __init__(self, name, value, rule, error): self.rule = rule - super(RuleError, self).__init__(name, value, error) + ValidationError.__init__(self, name, value, error) -- cgit From b4ad681f410ee5be56b0b02f73306aa49e5c668a Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Wed, 13 Aug 2008 05:14:12 +0000 Subject: 143: Added errors.RequirementError exception; cmd.validate() now raises RequirementError if a required option is missing --- ipalib/errors.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index 47e0a3ed..afc61dd8 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -64,11 +64,23 @@ class NormalizationError(ValidationError): class RuleError(ValidationError): + """ + Raised when a required option was not provided. + """ def __init__(self, name, value, rule, error): self.rule = rule ValidationError.__init__(self, name, value, error) +class RequirementError(ValidationError): + """ + Raised when a required option was not provided. + """ + def __init__(self, name): + ValidationError.__init__(self, name, None, + 'missing required value' + ) + class SetError(IPAError): msg = 'setting %r, but NameSpace does not allow attribute setting' -- cgit From 992a5dadbea27b21075617daf4216396d18404de Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Thu, 28 Aug 2008 20:30:08 +0000 Subject: 218: Finished unit tests for Option2.validate(), Option2.validate_scalar() --- ipalib/errors.py | 1 + 1 file changed, 1 insertion(+) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index afc61dd8..a25df091 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -67,6 +67,7 @@ class RuleError(ValidationError): """ Raised when a required option was not provided. """ + # FIXME: `rule` should really be after `error` def __init__(self, name, value, rule, error): self.rule = rule ValidationError.__init__(self, name, value, error) -- cgit From 8dc0e263dac8bf4074e48fcca593a00cadec03e0 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Fri, 29 Aug 2008 03:48:33 +0000 Subject: 221: Added errors.IPATypeError exception; added new test_errors.py module with corresponding unit tests --- ipalib/errors.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index a25df091..70128f7c 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -21,6 +21,26 @@ All custom errors raised by `ipalib` package. """ + +class IPATypeError(TypeError): + """ + TypeError subclass with standard message for easier debugging. + + Also has two custom attributes: + + ``type`` - The type being tested against. + ``value`` - The offending value that caused the exception. + """ + + format = 'need a %r; got %r' + + def __init__(self, type_, value): + assert type(value) is not type, 'no error: %r, %r' % (type_, value) + self.type = type_ + self.value = value + TypeError.__init__(self, self.format % (self.type, self.value)) + + class IPAError(Exception): """ Use this base class for your custom IPA errors unless there is a -- cgit From 03daa91d1c9c355f5f964095371c81d73fb9e08a Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Fri, 29 Aug 2008 04:29:29 +0000 Subject: 222: Fixed broken assertion in IPATypeError; did more work on docstrings in same --- ipalib/errors.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index 70128f7c..52225373 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -24,18 +24,22 @@ All custom errors raised by `ipalib` package. class IPATypeError(TypeError): """ - TypeError subclass with standard message for easier debugging. + A TypeError subclass with with a standard message. Also has two custom attributes: ``type`` - The type being tested against. ``value`` - The offending value that caused the exception. + + There is no edict that all TypeError should be raised with IPATypeError, + but when it fits, use it... it makes the unit tests faster to write and + the debugging easier to read. """ format = 'need a %r; got %r' def __init__(self, type_, value): - assert type(value) is not type, 'no error: %r, %r' % (type_, value) + assert type(value) is not type_, '%r is a %r' % (value, type_) self.type = type_ self.value = value TypeError.__init__(self, self.format % (self.type, self.value)) -- cgit From 76b30dff15de9eb50f0d9cb00b6df18ecd91a8f5 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Fri, 29 Aug 2008 06:04:38 +0000 Subject: 223: IPATypeError takes as first argument, has attribute --- ipalib/errors.py | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index 52225373..f88fdd5a 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -24,25 +24,38 @@ All custom errors raised by `ipalib` package. class IPATypeError(TypeError): """ - A TypeError subclass with with a standard message. + A TypeError subclass with a helpful message format. - Also has two custom attributes: + IPATypeError has three custom instance attributes: - ``type`` - The type being tested against. - ``value`` - The offending value that caused the exception. + ``name`` - Name of the argument TypeError is being raised for. + + ``type`` - Type that the argument should be. + + ``value`` - Value (of incorrect type) supplied for the argument. There is no edict that all TypeError should be raised with IPATypeError, but when it fits, use it... it makes the unit tests faster to write and the debugging easier to read. + + Here is an example: + + >>> raise IPATypeError('islate', bool, '4 AM') + Traceback (most recent call last): + File "", line 1, in + IPATypeError: islate: need a ; got '4 AM' """ - format = 'need a %r; got %r' + format = '%s: need a %r; got %r' - def __init__(self, type_, value): - assert type(value) is not type_, '%r is a %r' % (value, type_) + def __init__(self, name, type_, value): + assert type(name) is str, self.format % ('name', str, name) + assert type(type_) is type, self.format % ('type_', type, type_) + assert type(value) is not type_, 'value: %r is a %r' % (value, type_) + self.name = name self.type = type_ self.value = value - TypeError.__init__(self, self.format % (self.type, self.value)) + TypeError.__init__(self, self.format % (name, type_, value)) class IPAError(Exception): -- cgit From 44ff0b3d23c0473106a6c0da90cc8d80df98ee78 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Fri, 29 Aug 2008 07:05:06 +0000 Subject: 224: Reworked IPATypeError class into raise_TypeError function --- ipalib/errors.py | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index f88fdd5a..dea7cd73 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -22,40 +22,45 @@ All custom errors raised by `ipalib` package. """ -class IPATypeError(TypeError): +def raise_TypeError(name, type_, value): """ - A TypeError subclass with a helpful message format. + Raises a TypeError with a nicely formatted message and helpful attributes. - IPATypeError has three custom instance attributes: + The TypeError raised will have three custom attributes: - ``name`` - Name of the argument TypeError is being raised for. + ``name`` - The name (identifier) of the argument in question. - ``type`` - Type that the argument should be. + ``type`` - The type expected for the arguement. - ``value`` - Value (of incorrect type) supplied for the argument. + ``value`` - The value (of incorrect type) revieved for argument. - There is no edict that all TypeError should be raised with IPATypeError, + There is no edict that all TypeError should be raised with raise_TypeError, but when it fits, use it... it makes the unit tests faster to write and the debugging easier to read. Here is an example: - >>> raise IPATypeError('islate', bool, '4 AM') + >>> raise_TypeError('message', str, u'Hello.') Traceback (most recent call last): File "", line 1, in - IPATypeError: islate: need a ; got '4 AM' + File "/home/jderose/projects/freeipa2/ipalib/errors.py", line 61, in raise_TypeError + raise e + TypeError: message: need a ; got u'Hello.' + + :param name: The name (identifier) of the argument in question. + :param type_: The type expected for the arguement. + :param value: The value (of incorrect type) revieved for argument. """ format = '%s: need a %r; got %r' - - def __init__(self, name, type_, value): - assert type(name) is str, self.format % ('name', str, name) - assert type(type_) is type, self.format % ('type_', type, type_) - assert type(value) is not type_, 'value: %r is a %r' % (value, type_) - self.name = name - self.type = type_ - self.value = value - TypeError.__init__(self, self.format % (name, type_, value)) + assert type(name) is str, format % ('name', str, name) + assert type(type_) is type, format % ('type_', type, type_) + assert type(value) is not type_, 'value: %r is a %r' % (value, type_) + e = TypeError(format % (name, type_, value)) + setattr(e, 'name', name) + setattr(e, 'type', type_) + setattr(e, 'value', value) + raise e class IPAError(Exception): -- cgit From 2fa8d3be74ca45ee5989dd53b7fb818b21d23680 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Fri, 29 Aug 2008 23:53:04 +0000 Subject: 225: Added errors.check_type() and errors.check_isinstance() functions; added corresponding unit tests --- ipalib/errors.py | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index dea7cd73..1c109ed6 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -21,6 +21,7 @@ All custom errors raised by `ipalib` package. """ +TYPE_FORMAT = '%s: need a %r; got %r' def raise_TypeError(name, type_, value): """ @@ -30,9 +31,9 @@ def raise_TypeError(name, type_, value): ``name`` - The name (identifier) of the argument in question. - ``type`` - The type expected for the arguement. + ``type`` - The type expected for the argument. - ``value`` - The value (of incorrect type) revieved for argument. + ``value`` - The value (of incorrect type) passed as argument. There is no edict that all TypeError should be raised with raise_TypeError, but when it fits, use it... it makes the unit tests faster to write and @@ -48,21 +49,40 @@ def raise_TypeError(name, type_, value): TypeError: message: need a ; got u'Hello.' :param name: The name (identifier) of the argument in question. - :param type_: The type expected for the arguement. - :param value: The value (of incorrect type) revieved for argument. + :param type_: The type expected for the argument. + :param value: The value (of incorrect type) passed argument. """ - format = '%s: need a %r; got %r' - assert type(name) is str, format % ('name', str, name) - assert type(type_) is type, format % ('type_', type, type_) + assert type(name) is str, TYPE_FORMAT % ('name', str, name) + assert type(type_) is type, TYPE_FORMAT % ('type_', type, type_) assert type(value) is not type_, 'value: %r is a %r' % (value, type_) - e = TypeError(format % (name, type_, value)) + e = TypeError(TYPE_FORMAT % (name, type_, value)) setattr(e, 'name', name) setattr(e, 'type', type_) setattr(e, 'value', value) raise e +def check_type(name, type_, value, allow_None=False): + assert type(name) is str, TYPE_FORMAT % ('name', str, name) + assert type(type_) is type, TYPE_FORMAT % ('type_', type, type_) + assert type(allow_None) is bool, TYPE_FORMAT % ('allow_None', bool, allow_None) + if value is None and allow_None: + return + if type(value) is not type_: + raise_TypeError(name, type_, value) + + +def check_isinstance(name, type_, value, allow_None=False): + assert type(name) is str, TYPE_FORMAT % ('name', str, name) + assert type(type_) is type, TYPE_FORMAT % ('type_', type, type_) + assert type(allow_None) is bool, TYPE_FORMAT % ('allow_None', bool, allow_None) + if value is None and allow_None: + return + if not isinstance(value, type_): + raise_TypeError(name, type_, value) + + class IPAError(Exception): """ Use this base class for your custom IPA errors unless there is a -- cgit From 5af91df9a58c5066cbd526561886023d5edbfc0f Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Tue, 2 Sep 2008 15:15:03 +0000 Subject: 226: check_type() and check_isinstance() now return the value; updated corresponding unit tests --- ipalib/errors.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index 1c109ed6..8c1df455 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -71,6 +71,7 @@ def check_type(name, type_, value, allow_None=False): return if type(value) is not type_: raise_TypeError(name, type_, value) + return value def check_isinstance(name, type_, value, allow_None=False): @@ -81,6 +82,7 @@ def check_isinstance(name, type_, value, allow_None=False): return if not isinstance(value, type_): raise_TypeError(name, type_, value) + return value class IPAError(Exception): -- cgit From 6697b955eea6c5170cd68fef130d415ef3fa69cc Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Tue, 2 Sep 2008 16:42:39 +0000 Subject: 227: check_type() and check_isinstance() now take arguments in (value, type_, name) order so the first two match the built-in isinstance() call signature --- ipalib/errors.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index 8c1df455..1b556c33 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -23,17 +23,17 @@ All custom errors raised by `ipalib` package. TYPE_FORMAT = '%s: need a %r; got %r' -def raise_TypeError(name, type_, value): +def raise_TypeError(value, type_, name): """ Raises a TypeError with a nicely formatted message and helpful attributes. The TypeError raised will have three custom attributes: - ``name`` - The name (identifier) of the argument in question. + ``value`` - The value (of incorrect type) passed as argument. ``type`` - The type expected for the argument. - ``value`` - The value (of incorrect type) passed as argument. + ``name`` - The name (identifier) of the argument in question. There is no edict that all TypeError should be raised with raise_TypeError, but when it fits, use it... it makes the unit tests faster to write and @@ -48,40 +48,40 @@ def raise_TypeError(name, type_, value): raise e TypeError: message: need a ; got u'Hello.' - :param name: The name (identifier) of the argument in question. + :param value: The value (of incorrect type) passed as argument. :param type_: The type expected for the argument. - :param value: The value (of incorrect type) passed argument. + :param name: The name (identifier) of the argument in question. """ - assert type(name) is str, TYPE_FORMAT % ('name', str, name) assert type(type_) is type, TYPE_FORMAT % ('type_', type, type_) assert type(value) is not type_, 'value: %r is a %r' % (value, type_) + assert type(name) is str, TYPE_FORMAT % ('name', str, name) e = TypeError(TYPE_FORMAT % (name, type_, value)) - setattr(e, 'name', name) - setattr(e, 'type', type_) setattr(e, 'value', value) + setattr(e, 'type', type_) + setattr(e, 'name', name) raise e -def check_type(name, type_, value, allow_None=False): +def check_type(value, type_, name, allow_None=False): assert type(name) is str, TYPE_FORMAT % ('name', str, name) assert type(type_) is type, TYPE_FORMAT % ('type_', type, type_) assert type(allow_None) is bool, TYPE_FORMAT % ('allow_None', bool, allow_None) if value is None and allow_None: return if type(value) is not type_: - raise_TypeError(name, type_, value) + raise_TypeError(value, type_, name) return value -def check_isinstance(name, type_, value, allow_None=False): - assert type(name) is str, TYPE_FORMAT % ('name', str, name) +def check_isinstance(value, type_, name, allow_None=False): assert type(type_) is type, TYPE_FORMAT % ('type_', type, type_) + assert type(name) is str, TYPE_FORMAT % ('name', str, name) assert type(allow_None) is bool, TYPE_FORMAT % ('allow_None', bool, allow_None) if value is None and allow_None: return if not isinstance(value, type_): - raise_TypeError(name, type_, value) + raise_TypeError(value, type_, name) return value -- cgit From bc08225dcd719eba0134e8a59ea7932fdea8513d Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Tue, 2 Sep 2008 17:44:07 +0000 Subject: 230: Renamed allow_None kwarg to allow_none --- ipalib/errors.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index 1b556c33..d68bac40 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -63,22 +63,22 @@ def raise_TypeError(value, type_, name): raise e -def check_type(value, type_, name, allow_None=False): +def check_type(value, type_, name, allow_none=False): assert type(name) is str, TYPE_FORMAT % ('name', str, name) assert type(type_) is type, TYPE_FORMAT % ('type_', type, type_) - assert type(allow_None) is bool, TYPE_FORMAT % ('allow_None', bool, allow_None) - if value is None and allow_None: + assert type(allow_none) is bool, TYPE_FORMAT % ('allow_none', bool, allow_none) + if value is None and allow_none: return if type(value) is not type_: raise_TypeError(value, type_, name) return value -def check_isinstance(value, type_, name, allow_None=False): +def check_isinstance(value, type_, name, allow_none=False): assert type(type_) is type, TYPE_FORMAT % ('type_', type, type_) assert type(name) is str, TYPE_FORMAT % ('name', str, name) - assert type(allow_None) is bool, TYPE_FORMAT % ('allow_None', bool, allow_None) - if value is None and allow_None: + assert type(allow_none) is bool, TYPE_FORMAT % ('allow_none', bool, allow_none) + if value is None and allow_none: return if not isinstance(value, type_): raise_TypeError(value, type_, name) -- cgit From 085ea3f62f37539a279f7d4ade51208fcbe868b9 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Wed, 3 Sep 2008 18:32:49 +0000 Subject: 239: Added errors.ConversionError; started big clean up of how ValidationError is raised so it works well with multivalues --- ipalib/errors.py | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index d68bac40..8ecccf2b 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -119,6 +119,14 @@ class ValidationError(IPAError): IPAError.__init__(self, name, value, error) +class ConversionError(ValidationError): + def __init__(self, name, value, type_, position): + self.type = type_ + self.position = position + ValidationError.__init__(self, name, value, type_.conversion_error) + + + class NormalizationError(ValidationError): def __init__(self, name, value, type): self.type = type -- cgit From 9b9615df79d27a74b3cefd1dab708c98a5832b71 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Wed, 3 Sep 2008 18:48:58 +0000 Subject: 241: Added additional index=None kwarg to errors.ValidationError.__init__() --- ipalib/errors.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index 8ecccf2b..7629d8f5 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -112,10 +112,11 @@ class IPAError(Exception): class ValidationError(IPAError): msg = 'invalid %r value %r: %s' - def __init__(self, name, value, error): + def __init__(self, name, value, error, index=None): self.name = name self.value = value self.error = error + self.index = index IPAError.__init__(self, name, value, error) -- cgit From 5e8f945a1ea2f34f40a5e033801d66162fc63850 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Wed, 3 Sep 2008 19:38:39 +0000 Subject: 242: Started cleanup of custom exceptions; added unit tests for errors.IPAError --- ipalib/errors.py | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index 7629d8f5..eb08a7be 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -87,32 +87,38 @@ def check_isinstance(value, type_, name, allow_none=False): class IPAError(Exception): """ + Base class for all custom IPA errors. + Use this base class for your custom IPA errors unless there is a specific reason to subclass from AttributeError, KeyError, etc. """ - msg = None - def __init__(self, *args, **kw): + format = None + + def __init__(self, *args): 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 + return self.format % self.args class ValidationError(IPAError): - msg = 'invalid %r value %r: %s' + """ + Base class for all types of validation errors. + """ + + format = 'invalid %r value %r: %s' def __init__(self, name, value, error, index=None): + """ + :param name: The name of the value that failed validation. + :param value: The value that failed validation. + :param error: The error message describing the failure. + :param index: If multivalue, index of value in multivalue tuple + """ self.name = name self.value = value self.error = error @@ -138,12 +144,11 @@ class NormalizationError(ValidationError): class RuleError(ValidationError): """ - Raised when a required option was not provided. + Raised when a value fails a validation rule. """ - # FIXME: `rule` should really be after `error` - def __init__(self, name, value, rule, error): - self.rule = rule - ValidationError.__init__(self, name, value, error) + def __init__(self, name, value, error, rule, index=None): + self.rule_name = rule.__name__ + ValidationError.__init__(self, name, value, error, index) class RequirementError(ValidationError): -- cgit From 390c1aa4ba9d2c54ac4c737c128f0561d14b58ab Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Wed, 3 Sep 2008 20:05:24 +0000 Subject: 243: Added unit tests for errors.ValidationError --- ipalib/errors.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index eb08a7be..cf213d70 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -119,6 +119,8 @@ class ValidationError(IPAError): :param error: The error message describing the failure. :param index: If multivalue, index of value in multivalue tuple """ + assert type(name) is str + assert index is None or (type(index) is int and index >= 0) self.name = name self.value = value self.error = error -- cgit From 6f739bcf671ee3028ffeab736e7ea1ff16489907 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Wed, 3 Sep 2008 21:53:15 +0000 Subject: 244: Added unit tests for errors.ConversionError --- ipalib/errors.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index cf213d70..6f0941e2 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -129,11 +129,15 @@ class ValidationError(IPAError): class ConversionError(ValidationError): - def __init__(self, name, value, type_, position): - self.type = type_ - self.position = position - ValidationError.__init__(self, name, value, type_.conversion_error) + """ + Raised when a value cannot be converted to the correct type. + """ + def __init__(self, name, value, type_, index=None): + self.type = type_ + ValidationError.__init__(self, name, value, type_.conversion_error, + index=index, + ) class NormalizationError(ValidationError): -- cgit From 62533bfb2baa2eac7a1361627f90bdda97452605 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Wed, 3 Sep 2008 21:55:44 +0000 Subject: 245: Removed depreciated NormalizationError --- ipalib/errors.py | 8 -------- 1 file changed, 8 deletions(-) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index 6f0941e2..de9a43a5 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -140,14 +140,6 @@ class ConversionError(ValidationError): ) -class NormalizationError(ValidationError): - def __init__(self, name, value, type): - self.type = type - ValidationError.__init__(self, name, value, - 'not %r' % type - ) - - class RuleError(ValidationError): """ Raised when a value fails a validation rule. -- cgit From 004e989dc493a703b0f85be164409443416bf894 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Wed, 3 Sep 2008 22:14:25 +0000 Subject: 246: Added unit tests for errors.RuleError --- ipalib/errors.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index de9a43a5..9f40ddae 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -145,8 +145,9 @@ class RuleError(ValidationError): Raised when a value fails a validation rule. """ def __init__(self, name, value, error, rule, index=None): - self.rule_name = rule.__name__ - ValidationError.__init__(self, name, value, error, index) + assert callable(rule) + self.rule = rule + ValidationError.__init__(self, name, value, error, index=index) class RequirementError(ValidationError): @@ -233,6 +234,5 @@ class MissingOverrideError(RegistrationError): return self.msg % (self.base.__name__, self.cls.__name__, self.cls) - class TwiceSetError(IPAError): msg = '%s.%s cannot be set twice' -- cgit From 296d59d27a33bedff00e126439730558b4cc93d3 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Wed, 3 Sep 2008 22:29:01 +0000 Subject: 247: Added unit tests for errors.RequirementError --- ipalib/errors.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index 9f40ddae..fc1b2c49 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -19,6 +19,8 @@ """ All custom errors raised by `ipalib` package. + +Also includes a few utility functions for raising exceptions. """ TYPE_FORMAT = '%s: need a %r; got %r' @@ -155,16 +157,13 @@ class RequirementError(ValidationError): Raised when a required option was not provided. """ def __init__(self, name): - ValidationError.__init__(self, name, None, - 'missing required value' - ) + ValidationError.__init__(self, name, None, 'Required') class SetError(IPAError): msg = 'setting %r, but NameSpace does not allow attribute setting' - class RegistrationError(IPAError): """ Base class for errors that occur during plugin registration. -- cgit From 490eaee8a9f35975f7db5739a882894e10fb79a7 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Wed, 3 Sep 2008 22:41:53 +0000 Subject: 248: Removed depreciated SetError and TwiceSetError exceptions --- ipalib/errors.py | 8 -------- 1 file changed, 8 deletions(-) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index fc1b2c49..5e8af9d4 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -160,10 +160,6 @@ class RequirementError(ValidationError): ValidationError.__init__(self, name, None, 'Required') -class SetError(IPAError): - msg = 'setting %r, but NameSpace does not allow attribute setting' - - class RegistrationError(IPAError): """ Base class for errors that occur during plugin registration. @@ -231,7 +227,3 @@ class MissingOverrideError(RegistrationError): def __str__(self): return self.msg % (self.base.__name__, self.cls.__name__, self.cls) - - -class TwiceSetError(IPAError): - msg = '%s.%s cannot be set twice' -- cgit From 100492d98a199169a985086c20746dea7ff1fd3e Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Wed, 10 Sep 2008 20:05:45 +0000 Subject: 285: Started work on Command.args_to_kw() method; added unit test for functionality so far in args_to_kw() --- ipalib/errors.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index 5e8af9d4..a961ecb6 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -107,6 +107,19 @@ class IPAError(Exception): return self.format % self.args +class ArgumentError(IPAError): + """ + Raised when a command is called with wrong number of arguments. + """ + + format = '%s %s' + + def __init__(self, command, error): + self.command = command + self.error = error + IPAError.__init__(self, command.name, error) + + class ValidationError(IPAError): """ Base class for all types of validation errors. -- cgit From fec6fc2e8c373c698966816ee97fe3a660eb503e Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Tue, 7 Oct 2008 22:35:45 -0600 Subject: Fixed example in raise_TypeError() docstring (thanks, mnagy) --- ipalib/errors.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index a961ecb6..097747ac 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -43,12 +43,12 @@ def raise_TypeError(value, type_, name): Here is an example: - >>> raise_TypeError('message', str, u'Hello.') + >>> raise_TypeError(u'Hello, world!', str, 'message') Traceback (most recent call last): File "", line 1, in - File "/home/jderose/projects/freeipa2/ipalib/errors.py", line 61, in raise_TypeError + File "ipalib/errors.py", line 65, in raise_TypeError raise e - TypeError: message: need a ; got u'Hello.' + TypeError: message: need a ; got u'Hello, world!' :param value: The value (of incorrect type) passed as argument. :param type_: The type expected for the argument. -- cgit From 83bb41faebc0a61269f2869e9123166254fff5b3 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Wed, 8 Oct 2008 23:31:49 -0400 Subject: Mechanism to convert from xmlrpclib.Fault to an IPAError exception Include slew of new exceptions, not all of which are used yet --- ipalib/errors.py | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index 097747ac..c00db9dc 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -240,3 +240,140 @@ class MissingOverrideError(RegistrationError): def __str__(self): return self.msg % (self.base.__name__, self.cls.__name__, self.cls) + +class GenericError(IPAError): + """Base class for our custom exceptions""" + faultCode = 1000 + fromFault = False + def __str__(self): + try: + return str(self.args[0]['args'][0]) + except: + try: + return str(self.args[0]) + except: + return str(self.__dict__) + +class DatabaseError(GenericError): + """A database error has occurred""" + faultCode = 1001 + +class MidairCollision(GenericError): + """Change collided with another change""" + faultCode = 1002 + +class NotFound(GenericError): + """Entry not found""" + faultCode = 1003 + +class Duplicate(GenericError): + """This entry already exists""" + faultCode = 1004 + +class MissingDN(GenericError): + """The distinguished name (DN) is missing""" + faultCode = 1005 + +class EmptyModlist(GenericError): + """No modifications to be performed""" + faultCode = 1006 + +class InputError(GenericError): + """Error on input""" + faultCode = 1007 + +class SameGroupError(InputError): + """You can't add a group to itself""" + faultCode = 1008 + +class AdminsImmutable(InputError): + """The admins group cannot be renamed""" + faultCode = 1009 + +class UsernameTooLong(InputError): + """The requested username is too long""" + faultCode = 1010 + +class PrincipalError(GenericError): + """There is a problem with the kerberos principal""" + faultCode = 1011 + +class MalformedServicePrincipal(PrincipalError): + """The requested service principal is not of the form: service/fully-qualified host name""" + faultCode = 1012 + +class RealmMismatch(PrincipalError): + """The realm for the principal does not match the realm for this IPA server""" + faultCode = 1013 + +class PrincipalRequired(PrincipalError): + """You cannot remove IPA server service principals""" + faultCode = 1014 + +class InactivationError(GenericError): + """This entry cannot be inactivated""" + faultCode = 1015 + +class ConnectionError(GenericError): + """Connection to database failed""" + faultCode = 1016 + +class NoCCacheError(GenericError): + """No Kerberos credentials cache is available. Connection cannot be made""" + faultCode = 1017 + +class GSSAPIError(GenericError): + """GSSAPI Authorization error""" + faultCode = 1018 + +class ServerUnwilling(GenericError): + """Account inactivated. Server is unwilling to perform""" + faultCode = 1018 + +class ConfigurationError(GenericError): + """A configuration error occurred""" + faultCode = 1019 + +class DefaultGroup(ConfigurationError): + """You cannot remove the default users group""" + faultCode = 1020 + +class FunctionDeprecated(GenericError): + """Raised by a deprecated function""" + faultCode = 2000 + +def convertFault(fault): + """Convert a fault to the corresponding Exception type, if possible""" + code = getattr(fault,'faultCode',None) + if code is None: + return fault + for v in globals().values(): + if type(v) == type(Exception) and issubclass(v,GenericError) and \ + code == getattr(v,'faultCode',None): + ret = v(fault.faultString) + ret.fromFault = True + return ret + #otherwise... + return fault + +def listFaults(): + """Return a list of faults + + Returns a list of dictionaries whose keys are: + faultCode: the numeric code used in fault conversion + name: the name of the exception + desc: the description of the exception (docstring) + """ + ret = [] + for n,v in globals().items(): + if type(v) == type(Exception) and issubclass(v,GenericError): + code = getattr(v,'faultCode',None) + if code is None: + continue + info = {} + info['faultCode'] = code + info['name'] = n + info['desc'] = getattr(v,'__doc__',None) + ret.append(info) + ret.sort(lambda a,b: cmp(a['faultCode'],b['faultCode'])) + return ret -- cgit From 5c07d978659b3f91441a42295531539a1ae8eacc Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Thu, 9 Oct 2008 01:43:23 -0400 Subject: Slight change to how exceptions are handled --- ipalib/errors.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index c00db9dc..d0d917f6 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -266,7 +266,7 @@ class NotFound(GenericError): """Entry not found""" faultCode = 1003 -class Duplicate(GenericError): +class DuplicateEntry(GenericError): """This entry already exists""" faultCode = 1004 @@ -349,7 +349,7 @@ def convertFault(fault): return fault for v in globals().values(): if type(v) == type(Exception) and issubclass(v,GenericError) and \ - code == getattr(v,'faultCode',None): + code == getattr(v,'faultCode',None): ret = v(fault.faultString) ret.fromFault = True return ret -- cgit From 6d2705b363e95b5bd692b695cdcbbfcbca6d12b9 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Mon, 13 Oct 2008 17:17:00 -0400 Subject: Implement user lock and unlock --- ipalib/errors.py | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index d0d917f6..f1c9e26e 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -286,57 +286,73 @@ class SameGroupError(InputError): """You can't add a group to itself""" faultCode = 1008 +class NotGroupMember(InputError): + """This entry is not a member of the group""" + faultCode = 1009 + class AdminsImmutable(InputError): """The admins group cannot be renamed""" - faultCode = 1009 + faultCode = 1010 class UsernameTooLong(InputError): """The requested username is too long""" - faultCode = 1010 + faultCode = 1011 class PrincipalError(GenericError): """There is a problem with the kerberos principal""" - faultCode = 1011 + faultCode = 1012 class MalformedServicePrincipal(PrincipalError): """The requested service principal is not of the form: service/fully-qualified host name""" - faultCode = 1012 + faultCode = 1013 class RealmMismatch(PrincipalError): """The realm for the principal does not match the realm for this IPA server""" - faultCode = 1013 + faultCode = 1014 class PrincipalRequired(PrincipalError): """You cannot remove IPA server service principals""" - faultCode = 1014 + faultCode = 1015 class InactivationError(GenericError): """This entry cannot be inactivated""" - faultCode = 1015 + faultCode = 1016 + +class AlreadyActiveError(InactivationError): + """This entry is already locked""" + faultCode = 1017 + +class AlreadyInactiveError(InactivationError): + """This entry is already unlocked""" + faultCode = 1018 + +class HasNSAccountLock(InactivationError): + """This entry appears to have the nsAccountLock attribute in it so the Class of Service activation/inactivation will not work. You will need to remove the attribute nsAccountLock for this to work.""" + faultCode = 1019 class ConnectionError(GenericError): """Connection to database failed""" - faultCode = 1016 + faultCode = 1020 class NoCCacheError(GenericError): """No Kerberos credentials cache is available. Connection cannot be made""" - faultCode = 1017 + faultCode = 1021 class GSSAPIError(GenericError): """GSSAPI Authorization error""" - faultCode = 1018 + faultCode = 1022 class ServerUnwilling(GenericError): """Account inactivated. Server is unwilling to perform""" - faultCode = 1018 + faultCode = 1023 class ConfigurationError(GenericError): """A configuration error occurred""" - faultCode = 1019 + faultCode = 1024 class DefaultGroup(ConfigurationError): """You cannot remove the default users group""" - faultCode = 1020 + faultCode = 1025 class FunctionDeprecated(GenericError): """Raised by a deprecated function""" -- cgit From b045f220692e016a105f03af025d49f9a9cddc74 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Thu, 16 Oct 2008 23:33:44 -0400 Subject: Add mod_python-based XML-RPC server. Use -e kerberos on the command-line to use the mod_python server, otherwise it defaults to use the simple-server URL. --- ipalib/errors.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index f1c9e26e..36df0690 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -23,6 +23,8 @@ All custom errors raised by `ipalib` package. Also includes a few utility functions for raising exceptions. """ +IPA_ERROR_BASE = 1000 + TYPE_FORMAT = '%s: need a %r; got %r' def raise_TypeError(value, type_, name): -- cgit From 59a2cffff45499e1898ebbc7b76ede12d848addb Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Thu, 23 Oct 2008 21:21:51 -0600 Subject: IPAError now more appropriately subclasses from StandardError instead of Exception --- ipalib/errors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index 36df0690..9c40981f 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -89,7 +89,7 @@ def check_isinstance(value, type_, name, allow_none=False): return value -class IPAError(Exception): +class IPAError(StandardError): """ Base class for all custom IPA errors. -- cgit From 34520981eeaac5d4f37915509a9e26428e26f5c0 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Fri, 24 Oct 2008 14:17:20 -0400 Subject: Don't allow service-add to create host/ principals --- ipalib/errors.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index 9c40981f..c2d83e73 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -356,6 +356,10 @@ class DefaultGroup(ConfigurationError): """You cannot remove the default users group""" faultCode = 1025 +class HostService(ConfigurationError): + """You must enroll a host in order to create a host service""" + faultCode = 1026 + class FunctionDeprecated(GenericError): """Raised by a deprecated function""" faultCode = 2000 -- cgit From f5594dd489317dc406d20f897fc720e0cf89c9d2 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Thu, 13 Nov 2008 23:29:35 -0700 Subject: Started work on cleaning up how exceptions are caught and sys.exit() is called in ipalib.cli.CLI --- ipalib/errors.py | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index c2d83e73..71a837e9 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -98,6 +98,7 @@ class IPAError(StandardError): """ format = None + faultCode = 1 def __init__(self, *args): self.args = args @@ -109,6 +110,16 @@ class IPAError(StandardError): return self.format % self.args +class InvocationError(IPAError): + pass + +class UnknownCommandError(InvocationError): + format = 'unknown command "%s"' + +class UnknownHelpError(InvocationError): + format = 'no command nor topic "%s"' + + class ArgumentError(IPAError): """ Raised when a command is called with wrong number of arguments. -- cgit From 2d458a12339fbb7ef006ff7defc1e2f541e2f23f Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Mon, 24 Nov 2008 21:34:01 -0700 Subject: Stared some RPC-related error cleanup; started work on ipa_server.rcp.xmlrpc plugin --- ipalib/errors.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index 71a837e9..a0108250 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -113,9 +113,33 @@ class IPAError(StandardError): class InvocationError(IPAError): pass + class UnknownCommandError(InvocationError): format = 'unknown command "%s"' +def _(text): + return text + + +class HandledError(StandardError): + """ + Base class for errors that can be raised across a remote procecdure call. + """ + def __init__(self, message=None, **kw): + self.kw = kw + if message is None: + message = self.format % kw + StandardError.__init__(self, message) + + +class CommandError(HandledError): + format = _('Unknown command %(name)r') + + +class RemoteCommandError(HandledError): + format = 'Server at %(uri)r has no command %(command)r' + + class UnknownHelpError(InvocationError): format = 'no command nor topic "%s"' -- cgit From 7350ccbffefdf81992b3ccd8aac814f3bb954be8 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Tue, 25 Nov 2008 11:54:51 -0700 Subject: Started fleshing out doodles in xmlrpc.execute() --- ipalib/errors.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index a0108250..8412d1f6 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -125,6 +125,9 @@ class HandledError(StandardError): """ Base class for errors that can be raised across a remote procecdure call. """ + + code = 1 + def __init__(self, message=None, **kw): self.kw = kw if message is None: @@ -132,12 +135,22 @@ class HandledError(StandardError): StandardError.__init__(self, message) + +class UnknownError(HandledError): + """ + Raised when the true error is not a handled error. + """ + + format = _('An unknown internal error has occurred') + + class CommandError(HandledError): format = _('Unknown command %(name)r') + class RemoteCommandError(HandledError): - format = 'Server at %(uri)r has no command %(command)r' + format = 'Server at %(uri)r has no command %(name)r' class UnknownHelpError(InvocationError): -- cgit From 7e21ea5ad826e65da10d7a12917fd4d0d4f1874e Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Mon, 8 Dec 2008 16:56:24 -0700 Subject: Fixed Warning messages about log dir in unit test --- ipalib/errors.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index 8412d1f6..25f594f2 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -123,7 +123,7 @@ def _(text): class HandledError(StandardError): """ - Base class for errors that can be raised across a remote procecdure call. + Base class for errors that can be raised across a remote procedure call. """ code = 1 @@ -135,7 +135,6 @@ class HandledError(StandardError): StandardError.__init__(self, message) - class UnknownError(HandledError): """ Raised when the true error is not a handled error. @@ -145,10 +144,12 @@ class UnknownError(HandledError): class CommandError(HandledError): + """ + Raised when an unknown command is called client-side. + """ format = _('Unknown command %(name)r') - class RemoteCommandError(HandledError): format = 'Server at %(uri)r has no command %(name)r' -- cgit From fc8ac693726ec33b5c0924f9b8ff5d663705a5a3 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Fri, 5 Dec 2008 15:31:18 -0500 Subject: Port plugins to use the new output_for_cli() argument list Fix some errors uncovered by the nosetests --- ipalib/errors.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index 25f594f2..989721be 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -409,6 +409,10 @@ class HostService(ConfigurationError): """You must enroll a host in order to create a host service""" faultCode = 1026 +class InsufficientAccess(GenericError): + """You do not have permission to perform this task""" + faultCode = 1027 + class FunctionDeprecated(GenericError): """Raised by a deprecated function""" faultCode = 2000 -- cgit From e41fcf19fe82c41fe024b261d94814e092e6abaf Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Thu, 11 Dec 2008 10:31:27 -0500 Subject: Raise an error on bad principals instead of printing one when changing passwords Fix logic in determining what to do with an incoming principal --- ipalib/errors.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index 989721be..724654ff 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -413,6 +413,10 @@ class InsufficientAccess(GenericError): """You do not have permission to perform this task""" faultCode = 1027 +class InvalidUserPrincipal(GenericError): + """Invalid user principal""" + faultCode = 1028 + class FunctionDeprecated(GenericError): """Raised by a deprecated function""" faultCode = 2000 -- cgit From f0bbe1b5a09e1e2fc33d662c4775203f594af416 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Wed, 17 Dec 2008 17:17:02 -0700 Subject: Add body for the NameSpaceError exception --- ipalib/errors.py | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index 25f594f2..d8591304 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -231,8 +231,19 @@ class RegistrationError(IPAError): class NameSpaceError(RegistrationError): + """ + Raised when name is not a valid Python identifier for use for use as + the name of NameSpace member. + """ msg = 'name %r does not re.match %r' + def __init__(self, name, regex): + self.name = name + self.regex = regex + + def __str__(self): + return self.msg % (self.name, self.regex) + class SubclassError(RegistrationError): """ -- cgit From 360f95341a78e2fd601a38ffa103a5f5cbe8c424 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Wed, 17 Dec 2008 17:21:25 -0700 Subject: Fix show_api command --- ipalib/errors.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index d8591304..bc4074d2 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -117,6 +117,9 @@ class InvocationError(IPAError): class UnknownCommandError(InvocationError): format = 'unknown command "%s"' +class NoSuchNamespaceError(InvocationError): + format = 'api has no such namespace: %s' + def _(text): return text -- cgit From 4390523b7f854cefcb91843e1df3ca7575d43fea Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Sun, 21 Dec 2008 17:12:00 -0700 Subject: Improved Plugin.call() method and added its unit test --- ipalib/errors.py | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index 6dd6eb01..7191ff40 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -124,6 +124,14 @@ def _(text): return text +class SubprocessError(StandardError): + def __init__(self, returncode, argv): + self.returncode = returncode + self.argv = argv + StandardError.__init__(self, + 'return code %d from %r' % (returncode, argv) + ) + class HandledError(StandardError): """ Base class for errors that can be raised across a remote procedure call. -- cgit From 0d3ddef93b0a72b824297e5504e435a4427f14bd Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Sat, 3 Jan 2009 02:35:36 -0700 Subject: Started fleshing out reoganization of errors in errors.py (with gettext support) --- ipalib/errors.py | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'ipalib/errors.py') diff --git a/ipalib/errors.py b/ipalib/errors.py index 7191ff40..beb6342d 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -241,21 +241,6 @@ class RegistrationError(IPAError): """ -class NameSpaceError(RegistrationError): - """ - Raised when name is not a valid Python identifier for use for use as - the name of NameSpace member. - """ - msg = 'name %r does not re.match %r' - - def __init__(self, name, regex): - self.name = name - self.regex = regex - - def __str__(self): - return self.msg % (self.name, self.regex) - - class SubclassError(RegistrationError): """ Raised when registering a plugin that is not a subclass of one of the -- cgit