class IIntInfo(IFieldInfo): min = Int(title=u("Start of the range"), required=False, default=None) max = Int(title=u("End of the range (excluding the value itself)"), required=False, default=None)
def test_fromUnicode_strips_ws(self): from zope.schema import Text from zope.configuration._compat import u tok = self._makeOne(value_type=Text()) context = object() self.assertEqual(tok.fromUnicode(u(' one two three ')), [u('one'), u('two'), u('three')])
class IZopeConfigure(Interface): """The ``zope:configure`` Directive The zope configuration directive is a pure grouping directive. It doesn't compute any actions on it's own. Instead, it allows a package to be specified, affecting the interpretation of relative dotted names and file paths. It also allows an i18n domain to be specified. The information collected is used by subdirectives. It may seem that this directive can only be used once per file, but it can be applied whereever it is convenient. """ package = GlobalObject( title=u("Package"), description=u("The package to be used for evaluating relative imports " "and file names."), required=False) i18n_domain = BytesLine( title=u("Internationalization domain"), description=u("This is a name for the software project. It must be a " "legal file-system name as it will be used to contruct " "names for directories containing translation data. " "\n" "The domain defines a namespace for the message ids " "used by a project."), required=False)
class IRegister(Interface): """Trivial sample registry.""" id = Id( title=u("Identifier"), description=u("Some identifier that can be checked."), required=True, )
class IDirectivesInfo(Interface): """Schema for the ``directives`` directive """ namespace = URI( title=u("Namespace"), description=u("The namespace in which directives' names " "will be defined"), )
def __str__(self): #pragma NO COVER r = ["Conflicting configuration actions"] for discriminator, infos in sorted(self._conflicts.items()): r.append(" For: %s" % (discriminator, )) for info in infos: for line in text_type(info).rstrip().split(u('\n')): r.append(u(" ") + line) return "\n".join(r)
class IRegisterFile(Interface): path = Path( title=u("File path"), description=u("This is the path name of the file to be registered."), ) title = Text(title=u("Short summary of the file"), description=u("This will be used in file listings"), required=False)
class IProvidesDirectiveInfo(Interface): """Information for a <meta:provides> directive""" feature = TextLine( title=u("Feature name"), description=u("""The name of the feature being provided You can test available features with zcml:condition="have featurename". """), )
class ISchemaInfo(Interface): """Parameter schema for the schema directive """ name = TextLine( title=u("The schema name"), description=u("This is a descriptive name for the schema."), ) id = Id(title=u("The unique id for the schema"))
class IDirectiveInfo(Interface): """Information common to all directive definitions have """ name = TextLine( title=u("Directive name"), description=u("The name of the directive being defined"), ) schema = DirectiveSchema( title=u("Directive handler"), description=u("The dotted name of the directive handler"), )
class IFullInfo(IDirectiveInfo): """Information that all top-level directives (not subdirectives) have """ handler = GlobalObject( title=u("Directive handler"), description=u("The dotted name of the directive handler"), ) usedIn = GlobalInterface( title=u("The directive types the directive can be used in"), description=u("The interface of the directives that can contain " "the directive"), default=IConfigurationContext, )
def test_fromUnicode_invalid(self): from zope.schema import Int from zope.configuration.interfaces import InvalidToken from zope.configuration._compat import u tok = self._makeOne(value_type=Int(min=0)) context = object() self.assertRaises(InvalidToken, tok.fromUnicode, u(' 1 -1 3 '))
def registerFile(context, path, title=u("")): info = context.info description = info.text.strip() context.action(discriminator=('RegisterFile', path), callable=file_registry.append, args=(FileInfo(path, title, description, info),) )
def __str__(self): if (self.line, self.column) == (self.eline, self.ecolumn): return 'File "%s", line %s.%s' % ( self.file, self.line, self.column) file = self.file if file == 'tests//sample.zcml': # special case for testing file = os.path.join(os.path.dirname(__file__), 'tests', 'sample.zcml') try: with open(file) as f: lines = f.readlines()[self.line-1:self.eline] except IOError: src = " Could not read source." else: ecolumn = self.ecolumn if lines[-1][ecolumn:ecolumn+2] == '</': #pragma NO COVER # We're pointing to the start of an end tag. Try to find # the end l = lines[-1].find('>', ecolumn) if l >= 0: lines[-1] = lines[-1][:l+1] else: #pragma NO COVER lines[-1] = lines[-1][:ecolumn+1] column = self.column if lines[0][:column].strip(): #pragma NO COVER # Remove text before start if it's noy whitespace lines[0] = lines[0][self.column:] pad = u(' ') blank = u('') try: src = blank.join([pad + l for l in lines]) except UnicodeDecodeError: #pragma NO COVER # XXX: # I hope so most internation zcml will use UTF-8 as encoding # otherwise this code must be made more clever src = blank.join([pad + l.decode('utf-8') for l in lines]) # unicode won't be printable, at least on my console src = src.encode('ascii','replace') return "%s\n%s" % (repr(self), src)
def __str__(self): if (self.line, self.column) == (self.eline, self.ecolumn): return 'File "%s", line %s.%s' % (self.file, self.line, self.column) file = self.file if file == 'tests//sample.zcml': # special case for testing file = os.path.join(os.path.dirname(__file__), 'tests', 'sample.zcml') try: with open(file) as f: lines = f.readlines()[self.line - 1:self.eline] except IOError: src = " Could not read source." else: ecolumn = self.ecolumn if lines[-1][ecolumn:ecolumn + 2] == '</': #pragma NO COVER # We're pointing to the start of an end tag. Try to find # the end l = lines[-1].find('>', ecolumn) if l >= 0: lines[-1] = lines[-1][:l + 1] else: #pragma NO COVER lines[-1] = lines[-1][:ecolumn + 1] column = self.column if lines[0][:column].strip(): #pragma NO COVER # Remove text before start if it's noy whitespace lines[0] = lines[0][self.column:] pad = u(' ') blank = u('') try: src = blank.join([pad + l for l in lines]) except UnicodeDecodeError: #pragma NO COVER # XXX: # I hope so most internation zcml will use UTF-8 as encoding # otherwise this code must be made more clever src = blank.join([pad + l.decode('utf-8') for l in lines]) # unicode won't be printable, at least on my console src = src.encode('ascii', 'replace') return "%s\n%s" % (repr(self), src)
def test__validate_w_value_type(self): from zope.schema import Text from zope.schema.interfaces import WrongType from zope.configuration._compat import u from zope.configuration._compat import b go = self._makeOne(value_type=Text()) go.validate(u('')) for value in [0, 0.0, (), [], set(), frozenset(), b('')]: self.assertRaises(WrongType, go._validate, value)
class ITextInfo(IFieldInfo): min_length = Int( title=u("Minimum length"), description=u( "Value after whitespace processing cannot have less than " "min_length characters. If min_length is None, there is " "no minimum."), required=False, min=0, # needs to be a positive number default=0) max_length = Int( title=u("Maximum length"), description=u("Value after whitespace processing cannot have greater " "or equal than max_length characters. If max_length is " "None, there is no maximum."), required=False, min=0, # needs to be a positive number default=None)
def test_w_id_and_default(self): import warnings from zope.configuration._compat import u mid = self._makeOne() context = self._makeContext() bound = mid.bind(context) with warnings.catch_warnings(record=True) as log: msgid = bound.fromUnicode(u('[testing] default')) self.assertEqual(len(log), 0) self.assertEqual(msgid, 'testing') self.assertEqual(msgid.default, 'default') self.assertEqual(msgid.domain, 'testing_domain') self.assertEqual(context.i18n_strings, {'testing_domain': {'testing': [('test_file', 42)]}})
def test_wo_domain(self): import warnings from zope.configuration._compat import u mid = self._makeOne() context = self._makeContext(None) bound = mid.bind(context) with warnings.catch_warnings(record=True) as log: msgid = bound.fromUnicode(u('testing')) self.assertEqual(len(log), 1) self.assertTrue(str(log[0].message).startswith( 'You did not specify an i18n translation domain')) self.assertEqual(msgid, 'testing') self.assertEqual(msgid.default, None) self.assertEqual(msgid.domain, 'untranslated') self.assertEqual(context.i18n_strings, {'untranslated': {'testing': [('test_file', 42)]}})
class IFieldInfo(Interface): name = BytesLine(title=u("The field name"), ) title = TextLine( title=u("Title"), description=u("A short summary or label"), default=u(""), required=False, ) required = Bool(title=u("Required"), description=u("Determines whether a value is required."), default=True) readonly = Bool(title=u("Read Only"), description=u("Can the value be modified?"), required=False, default=False)
class IInclude(Interface): """The ``include``, ``includeOverrides`` and ``exclude`` directives These directives allows you to include or preserve including of another ZCML file in the configuration. This enables you to write configuration files in each package and then link them together. """ file = NativeStringLine( title=u("Configuration file name"), description=u("The name of a configuration file to be included/" "excluded, relative to the directive containing the " "including configuration file."), required=False, ) files = NativeStringLine( title=u("Configuration file name pattern"), description=u(""" The names of multiple configuration files to be included/excluded, expressed as a file-name pattern, relative to the directive containing the including or excluding configuration file. The pattern can include: - ``*`` matches 0 or more characters - ``?`` matches a single character - ``[<seq>]`` matches any character in seq - ``[!<seq>]`` matches any character not in seq The file names are included in sorted order, where sorting is without regard to case. """), required=False, ) package = GlobalObject( title=u("Include or exclude package"), description=u(""" Include or exclude the named file (or configure.zcml) from the directory of this package. """), required=False, )
def __init__(self, context, a, c, b=u("xxx")): self.a, self.b, self.c = a, b, c context.action("Complex.__init__")
def test__validate_wo_value_type(self): from zope.configuration._compat import u from zope.configuration._compat import b go = self._makeOne(value_type=None) for value in [0, 0.0, (), [], set(), frozenset(), u(''), b('')]: go._validate(value) #noraise
class IConfigurationContext(Interface): """Configuration Context The configuration context manages information about the state of the configuration system, such as the package containing the configuration file. More importantly, it provides methods for importing objects and opening files relative to the package. """ package = BytesLine( title=u("The current package name"), description=u("""\ This is the name of the package containing the configuration file being executed. If the configuration file was not included by package, then this is None. """), required=False, ) def resolve(dottedname): """Resolve a dotted name to an object A dotted name is constructed by concatenating a dotted module name with a global name within the module using a dot. For example, the object named "spam" in the foo.bar module has a dotted name of foo.bar.spam. If the current package is a prefix of a dotted name, then the package name can be relaced with a leading dot, So, for example, if the configuration file is in the foo package, then the dotted name foo.bar.spam can be shortened to .bar.spam. If the current package is multiple levels deep, multiple leading dots can be used to refer to higher-level modules. For example, if the current package is x.y.z, the dotted object name ..foo refers to x.y.foo. """ def path(filename): """Compute a full file name for the given file If the filename is relative to the package, then the returned name will include the package path, otherwise, the original file name is returned. """ def checkDuplicate(filename): """Check for duplicate imports of the same file. Raises an exception if this file had been processed before. This is better than an unlimited number of conflict errors. """ def processFile(filename): """Check whether a file needs to be processed. Return True if processing is needed and False otherwise. If the file needs to be processed, it will be marked as processed, assuming that the caller will procces the file if it needs to be procssed. """ def action(discriminator, callable, args=(), kw={}, order=0, includepath=None, info=None): """Record a configuration action The job of most directives is to compute actions for later processing. The action method is used to record those actions. The discriminator is used to to find actions that conflict. Actions conflict if they have the same discriminator. The exception to this is the special case of the discriminator with the value None. An actions with a discriminator of None never conflicts with other actions. This is possible to add an order argument to crudely control the order of execution. 'info' is optional source line information, 'includepath' is None (the default) or a tuple of include paths for this action. """ def provideFeature(name): """Record that a named feature is available in this context.""" def hasFeature(name): """Check whether a named feature is available in this context."""
from zope.configuration.config import defineSimpleDirective from zope.configuration.config import GroupingContextDecorator from zope.configuration.config import GroupingStackItem from zope.configuration.config import resolveConflicts from zope.configuration.exceptions import ConfigurationError from zope.configuration.fields import GlobalObject from zope.configuration.zopeconfigure import IZopeConfigure from zope.configuration.zopeconfigure import ZopeConfigure from zope.configuration._compat import StringIO from zope.configuration._compat import reraise from zope.configuration._compat import u logger = logging.getLogger("config") ZCML_NAMESPACE = "http://namespaces.zope.org/zcml" ZCML_CONDITION = (ZCML_NAMESPACE, u("condition")) class ZopeXMLConfigurationError(ConfigurationError): """Zope XML Configuration error These errors are wrappers for other errors. They include configuration info and the wrapped error type and value. """ def __init__(self, info, etype, evalue): self.info, self.etype, self.evalue = info, etype, evalue def __str__(self): # Only use the repr of the info. This is because we expect to # get a parse info and we only want the location information. return "%s\n %s: %s" % (
def test__validate_hit(self): from zope.configuration._compat import u pi = self._makeOne() pi._validate(u('is_an_identifier'))
def test__validate_miss(self): from zope.schema import ValidationError from zope.configuration._compat import u pi = self._makeOne() with self.assertRaises(ValidationError): pi._validate(u('not-an-identifier'))
def test__validate_miss(self): from zope.schema import ValidationError from zope.configuration._compat import u pi = self._makeOne() self.assertRaises(ValidationError, pi._validate, u('not-an-identifier'))
def registerFile(context, path, title=u("")): info = context.info description = info.text.strip() context.action(discriminator=('RegisterFile', path), callable=file_registry.append, args=(FileInfo(path, title, description, info), ))
def newsimple(context, a, c, b=u("xxx")): context.action(('newsimple', a, b, c), f, (a, b, c))
def simple(context, a=None, c=None, b=u("xxx")): return [(('simple', a, b, c), f, (a, b, c))]
# # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # ############################################################################## """Test zope.configuration.xmlconfig. """ import unittest from zope.configuration._compat import u NS = u('ns') FOO = u('foo') XXX = u('xxx') SPLAT = u('splat') SPLATV = u('splatv') A = u('a') AVALUE = u('avalue') B = u('b') BVALUE = u('bvalue') class ZopeXMLConfigurationErrorTests(unittest.TestCase): def _getTargetClass(self): from zope.configuration.xmlconfig import ZopeXMLConfigurationError return ZopeXMLConfigurationError
from zope.interface import implementer from zope.schema import Bool as schema_Bool from zope.schema import Field from zope.schema import InterfaceField from zope.schema import List from zope.schema import Text from zope.schema import TextLine from zope.schema import ValidationError from zope.schema.interfaces import IFromUnicode from zope.configuration.exceptions import ConfigurationError from zope.configuration.interfaces import InvalidToken from zope.configuration._compat import u PYIDENTIFIER_REGEX = u('\\A[a-zA-Z_]+[a-zA-Z0-9_]*\\Z') pyidentifierPattern = re.compile(PYIDENTIFIER_REGEX) @implementer(IFromUnicode) class PythonIdentifier(TextLine): """This field describes a python identifier, i.e. a variable name. """ def fromUnicode(self, u): return u.strip() def _validate(self, value): super(PythonIdentifier, self)._validate(value) if pyidentifierPattern.match(value) is None: raise ValidationError(value)
from zope.configuration.config import defineSimpleDirective from zope.configuration.config import GroupingContextDecorator from zope.configuration.config import GroupingStackItem from zope.configuration.config import resolveConflicts from zope.configuration.exceptions import ConfigurationError from zope.configuration.fields import GlobalObject from zope.configuration.zopeconfigure import IZopeConfigure from zope.configuration.zopeconfigure import ZopeConfigure from zope.configuration._compat import StringIO from zope.configuration._compat import reraise from zope.configuration._compat import u logger = logging.getLogger("config") ZCML_NAMESPACE = "http://namespaces.zope.org/zcml" ZCML_CONDITION = (ZCML_NAMESPACE, u("condition")) class ZopeXMLConfigurationError(ConfigurationError): """Zope XML Configuration error These errors are wrappers for other errors. They include configuration info and the wrapped error type and value. """ def __init__(self, info, etype, evalue): self.info, self.etype, self.evalue = info, etype, evalue def __str__(self): # Only use the repr of the info. This is because we expect to # get a parse info and we only want the location information. return "%s\n %s: %s" % (repr(
# # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # ############################################################################## """Test zope.configuration.xmlconfig. """ import unittest from zope.configuration._compat import u NS = u('ns') FOO = u('foo') XXX = u('xxx') SPLAT = u('splat') SPLATV = u('splatv') A = u('a') AVALUE = u('avalue') B = u('b') BVALUE = u('bvalue') class ZopeXMLConfigurationErrorTests(unittest.TestCase): def _getTargetClass(self): from zope.configuration.xmlconfig import ZopeXMLConfigurationError