comparison roundup/hyperdb.py @ 6238:6834bb5473da

Summary: Constrain format of classname and document Define the format of a valid classname. Updated design doc, function doc and glossary to document format. Error message for case where we have a redefinition of a classname now says why ValueError is raised since we are raising ValueError for incorrect classname format as well. Tests for all cases including verification of cause for ValueError exceptions.
author John Rouillard <rouilj@ieee.org>
date Tue, 28 Jul 2020 06:24:39 -0400
parents f40c6b5de370
children 95183d73ac64
comparison
equal deleted inserted replaced
6237:0a37979bbd46 6238:6834bb5473da
435 # 435 #
436 class DesignatorError(ValueError): 436 class DesignatorError(ValueError):
437 pass 437 pass
438 438
439 439
440 def splitDesignator(designator, dre=re.compile(r'([^\d]+)(\d+)')): 440 def splitDesignator(designator,
441 dre=re.compile(r'^([A-Za-z](?:[A-Za-z_0-9]*[A-Za-z_]+)?)(\d+)$')):
441 """ Take a foo123 and return ('foo', 123) 442 """ Take a foo123 and return ('foo', 123)
442 """ 443 """
443 m = dre.match(designator) 444 m = dre.match(designator)
444 if m is None: 445 if m is None:
445 raise DesignatorError(_('"%s" not a node designator') % designator) 446 raise DesignatorError(_('"%s" not a node designator') % designator)
1044 1045
1045 All methods except __repr__ and getnode must be implemented by a 1046 All methods except __repr__ and getnode must be implemented by a
1046 concrete backend Class. 1047 concrete backend Class.
1047 """ 1048 """
1048 1049
1050 class_re = r'^([A-Za-z](?:[A-Za-z_0-9]*[A-Za-z_]+)?)$'
1051
1049 def __init__(self, db, classname, **properties): 1052 def __init__(self, db, classname, **properties):
1050 """Create a new class with a given name and property specification. 1053 """Create a new class with a given name and property specification.
1051 1054
1052 'classname' must not collide with the name of an existing class, 1055 'classname' must not collide with the name of an existing class,
1053 or a ValueError is raised. The keyword arguments in 'properties' 1056 or a ValueError is raised. 'classname' must start with an
1054 must map names to property objects, or a TypeError is raised. 1057 alphabetic letter. It must end with an alphabetic letter or '_'.
1058 Internal characters can be alphanumeric or '_'. ValueError is
1059 raised if the classname is not correct.
1060 The keyword arguments in 'properties' must map names to property
1061 objects, or a TypeError is raised.
1055 """ 1062 """
1056 for name in 'creation activity creator actor'.split(): 1063 for name in 'creation activity creator actor'.split():
1057 if name in properties: 1064 if name in properties:
1058 raise ValueError('"creation", "activity", "creator" and ' 1065 raise ValueError('"creation", "activity", "creator" and '
1059 '"actor" are reserved') 1066 '"actor" are reserved')
1067
1068 if not re.match(self.class_re, classname):
1069 raise ValueError('Class name %s is not valid. It must start '
1070 'with a letter, end with a letter or "_", and '
1071 'only have alphanumerics and "_" in the '
1072 'middle.' % (classname,))
1060 1073
1061 self.classname = classname 1074 self.classname = classname
1062 self.properties = properties 1075 self.properties = properties
1063 # Make the class and property name known to the property 1076 # Make the class and property name known to the property
1064 for p in properties: 1077 for p in properties:

Roundup Issue Tracker: http://roundup-tracker.org/