/usr/share/pyshared/zope/tal/taldefs.py is in python-zope.tal 3.5.2-0ubuntu4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | ##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# 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.
#
##############################################################################
"""Common definitions used by TAL and METAL compilation and transformation.
$Id: taldefs.py 41477 2006-01-28 19:52:03Z hdima $
"""
import re
from zope.tal.interfaces import ITALExpressionErrorInfo
from zope.interface import implements
TAL_VERSION = "1.6"
XML_NS = "http://www.w3.org/XML/1998/namespace" # URI for XML namespace
XMLNS_NS = "http://www.w3.org/2000/xmlns/" # URI for XML NS declarations
ZOPE_TAL_NS = "http://xml.zope.org/namespaces/tal"
ZOPE_METAL_NS = "http://xml.zope.org/namespaces/metal"
ZOPE_I18N_NS = "http://xml.zope.org/namespaces/i18n"
# This RE must exactly match the expression of the same name in the
# zope.i18n.simpletranslationservice module:
NAME_RE = "[a-zA-Z_][-a-zA-Z0-9_]*"
KNOWN_METAL_ATTRIBUTES = frozenset([
"define-macro",
"extend-macro",
"use-macro",
"define-slot",
"fill-slot",
])
KNOWN_TAL_ATTRIBUTES = frozenset([
"define",
"condition",
"content",
"replace",
"repeat",
"attributes",
"on-error",
"omit-tag",
"script",
"tal tag", # a pseudo attribute that holds the namespace of elements
# like <tal:x>, <metal:y>, <i18n:z>
])
KNOWN_I18N_ATTRIBUTES = frozenset([
"translate",
"domain",
"target",
"source",
"attributes",
"data",
"name",
])
class TALError(Exception):
def __init__(self, msg, position=(None, None)):
assert msg != ""
self.msg = msg
self.lineno = position[0]
self.offset = position[1]
self.filename = None
def setFile(self, filename):
self.filename = filename
def __str__(self):
result = self.msg
if self.lineno is not None:
result = result + ", at line %d" % self.lineno
if self.offset is not None:
result = result + ", column %d" % (self.offset + 1)
if self.filename is not None:
result = result + ', in file %s' % self.filename
return result
class METALError(TALError):
pass
class TALExpressionError(TALError):
pass
class I18NError(TALError):
pass
class ErrorInfo(object):
implements(ITALExpressionErrorInfo)
def __init__(self, err, position=(None, None)):
if isinstance(err, Exception):
self.type = err.__class__
self.value = err
else:
self.type = err
self.value = None
self.lineno = position[0]
self.offset = position[1]
_attr_re = re.compile(r"\s*([^\s]+)\s+([^\s].*)\Z", re.S)
_subst_re = re.compile(r"\s*(?:(text|structure)\s+)?(.*)\Z", re.S)
def parseAttributeReplacements(arg, xml):
dict = {}
for part in splitParts(arg):
m = _attr_re.match(part)
if not m:
raise TALError("Bad syntax in attributes: %r" % part)
name, expr = m.groups()
if not xml:
name = name.lower()
if name in dict:
raise TALError("Duplicate attribute name in attributes: %r" % part)
dict[name] = expr
return dict
def parseSubstitution(arg, position=(None, None)):
m = _subst_re.match(arg)
if not m:
raise TALError("Bad syntax in substitution text: %r" % arg, position)
key, expr = m.groups()
if not key:
key = "text"
return key, expr
def splitParts(arg):
# Break in pieces at undoubled semicolons and
# change double semicolons to singles:
arg = arg.replace(";;", "\0")
parts = arg.split(';')
parts = [p.replace("\0", ";") for p in parts]
if len(parts) > 1 and not parts[-1].strip():
del parts[-1] # It ended in a semicolon
return parts
def isCurrentVersion(program):
version = getProgramVersion(program)
return version == TAL_VERSION
def isinstance_(ob, type):
# Proxy-friendly and faster isinstance_ check for new-style objects
try:
return type in ob.__class__.__mro__
except AttributeError:
return False
def getProgramMode(program):
version = getProgramVersion(program)
if (version == TAL_VERSION and isinstance_(program[1], tuple) and
len(program[1]) == 2):
opcode, mode = program[1]
if opcode == "mode":
return mode
return None
def getProgramVersion(program):
if (len(program) >= 2 and
isinstance_(program[0], tuple) and len(program[0]) == 2):
opcode, version = program[0]
if opcode == "version":
return version
return None
_ent1_re = re.compile('&(?![A-Z#])', re.I)
_entch_re = re.compile('&([A-Z][A-Z0-9]*)(?![A-Z0-9;])', re.I)
_entn1_re = re.compile('&#(?![0-9X])', re.I)
_entnx_re = re.compile('&(#X[A-F0-9]*)(?![A-F0-9;])', re.I)
_entnd_re = re.compile('&(#[0-9][0-9]*)(?![0-9;])')
def attrEscape(s):
"""Replace special characters '&<>' by character entities,
except when '&' already begins a syntactically valid entity."""
s = _ent1_re.sub('&', s)
s = _entch_re.sub(r'&\1', s)
s = _entn1_re.sub('&#', s)
s = _entnx_re.sub(r'&\1', s)
s = _entnd_re.sub(r'&\1', s)
s = s.replace('<', '<')
s = s.replace('>', '>')
s = s.replace('"', '"')
return s
import cgi
def quote(s, escape=cgi.escape):
return '"%s"' % escape(s, 1)
del cgi
|