def fromLiteral(cls, literal, destName, valParser, stepParser): """creates a PQLRange from a PQL range literal. For the meaning of the arguments, see PQLPar.fromLiteral. """ if literal == "": return cls(value="") mat = RANGE_RE.match(literal) if not mat: raise base.LiteralParseError( destName, literal, hint="PQL ranges roughly have the form [start][/stop[/stop]]." " Literal slashes need to be escaped (as %2f).") vals = mat.groups() try: if vals[1] is None and vals[2] is None: return cls(value=_parsePQLValue(vals[0], vp=valParser)) else: start, stop, step = vals return cls(start=_parsePQLValue(start, vp=valParser), stop=_parsePQLValue(stop, 1, vp=valParser), step=_parsePQLValue(step, 1, vp=stepParser)) except ValueError, ex: raise base.LiteralParseError("range within %s" % destName, literal, hint=str(ex))
def validate(self): """checks that code content is a parseable python expression and that the destination exists in the tableDef """ self._validateNext(MappedExpression) if (self.content_ and self.source) or not (self.content_ or self.source): raise base.StructureError("Map must have exactly one of source attribute" " or element content") if not utils.identifierPattern.match(self.key): raise base.LiteralParseError("name", self.key, hint="Var keys must be valid python" " identifiers, and '%s' is not"%self.key) if self.source: if not utils.identifierPattern.match(self.source): raise base.LiteralParseError("source", self.source, hint="Map sources must be (python)" " identifiers, and '%s' is not"%self.source) if self.nullExpr is not base.NotGiven: utils.ensureExpression(self.nullExpr) if self.content_: utils.ensureExpression(common.replaceProcDefAt(self.content_), self.name_) if self.nullExcs is not base.NotGiven: utils.ensureExpression(self.nullExcs, "%s.nullExcs"%(self.name_))
def completeElement(self, ctx): try: parsedFields = utils.pyparseString(self._fieldsGrammar, self.content_) except pyparsing.ParseBaseException, ex: raise base.ui.logOldExc(base.LiteralParseError("binaryRecordDef", re.sub("\s+", " ", self.content_), pos=str(ex.loc), hint="The parser said: '%s'"%str(ex)))
def _parsePQLString(cls, val, destName): # this is the implementation of the fromLiteral class method(s) # It's static so the fromLiterals can upcall. if val is None: return None if val == cls.nullvalue: return None mat = QUALIFIER_RE.match(val) if not mat: raise base.LiteralParseError( destName, val, hint="Not more than one" " semicolon is allowed in PQL expressions") qualifier = _parsePQLValue(mat.group(2), 1) ranges = [] listLiteral = mat.group(1) # harmless hack to avoid special-casing for one-element list rangeMat = re.match("", listLiteral) for rangeMat in LIST_RE.finditer(listLiteral): try: ranges.append( cls.rangeClass.fromLiteral(rangeMat.group(1), destName, cls.valParser, cls.stepParser)) except base.LiteralParseError, ex: ex.pos = rangeMat.start() raise
def getCode(self, columns): """returns python source code for this map. """ code = [] if self.content_: code.append('%s["%s"] = %s'%(self.destDict, self.key, self.content_)) else: colDef = columns.getColumnByName(self.key) try: code.append('%s["%s"] = %s'%(self.destDict, self.key, base.sqltypeToPythonCode(colDef.type)%'vars["%s"]'%self.source)) except base.ConversionError: raise base.ui.logOldExc(base.LiteralParseError("map", colDef.type, hint="Auto-mapping to %s is impossible since" " no default map for %s is known"%(self.key, colDef.type))) if self.nullExpr is not base.NotGiven: code.append('\nif %s["%s"]==%s: %s["%s"] = None'%( self.destDict, self.key, self.nullExpr, self.destDict, self.key)) code = "".join(code) if self.nullExcs is not base.NotGiven: code = 'try:\n%s\nexcept (%s): %s["%s"] = None'%( re.sub("(?m)^", " ", code), self.nullExcs, self.destDict, self.key) return code
def _parseAt(self, atSpec, ctx): """returns a tuple ready for cron.repeatAt from atSpec. see the at StringListAttribute for how it would look like; this parses one element of that string list. """ mat = re.match( r"(?P<dow>w\d\s+)?" r"(?P<dom>m\d\d?\s+)?" r"(?P<hr>\d+):(?P<min>\d+)", atSpec) if not mat: raise base.LiteralParseError("at", atSpec, pos=ctx.pos, hint= "This is hour:minute optionally prefixed by either w<weekday> or"\ " m<day of month>, each counted from 1.") hour, minute = int(mat.group("hr")), int(mat.group("min")) if not (0 <= hour <= 23 and 0 <= minute <= 59): raise base.LiteralParseError( "at", atSpec, pos=ctx.pos, hint= "This must be hour:minute with 0<=hour<=23 or 0<=minute<=59") dom = None if mat.group("dom"): dom = int(mat.group("dom")[1:]) if not 1 <= dom <= 28: raise base.LiteralParseError( "at", atSpec, pos=ctx.pos, hint="day-of-month in at must be between 1 and 28.") dow = None if mat.group("dow"): dow = int(mat.group("dow")[1:]) if not 1 <= dow <= 7: raise base.LiteralParseError( "at", atSpec, pos=ctx.pos, hint="day-of-week in at must be between 1 and 7.") return (dom, dow, hour, minute)
def validate(self, parent): for colName in getattr(parent, self.name_): try: parent.getColumnByName(colName) except base.NotFoundError: raise base.ui.logOldExc( base.LiteralParseError( self.name_, colName, hint="Column tuple component %s is not in parent table" % colName))
def _checkTable(self, columns, id): """raises a LiteralParseError if we try to map to non-existing columns. """ for map in self.maps: try: columns.getColumnByName(map.key) except KeyError: raise base.ui.logOldExc(base.LiteralParseError(self.name_, map.key, "Cannot map to '%s' since it does not exist in %s"%( map.key, id)))
def parse(self, value): if not value.strip(): return _roEmptyDict try: return dict([f.split("=") for f in value.split(",")]) except (ValueError, TypeError): raise base.ui.logOldExc( base.LiteralParseError( self.name_, value, hint="DisplayHints have a format like tag=value{,tag=value}" ))
def parse(self, value): try: typesystems.sqltypeToPython(value) except base.Error: raise base.ui.logOldExc( base.LiteralParseError( self.name_, value, hint="A supported SQL type was expected here. If in doubt," " check base/typeconversions.py, in particular ToPythonCodeConverter." )) return value
def _parseColDefs(self, ctx): # the handler for colDefs -- parse shortcut colDefs try: for key, range in utils.pyparseString(self._getColDefGrammar(), self.colDefs): self.colRanges[key] = self._cols.itemAttD.parse(range) except pyparsing.ParseException, ex: raise base.LiteralParseError( "colDefs", self.colDefs, hint="colDefs is a whitespace-separated list of key:range pairs." " Your literal doesn't look like this, and here's what the" " parser had to complain: %s" % ex)
def _resolveSTC(self): """adds STC related attributes to this tables' columns. """ for stcDef in self.stc: for name, type in stcDef.iterColTypes(): destCol = self.getColumnByName(name) if destCol.stc is not None: raise base.LiteralParseError( "stc", stcDef.content_, hint="Column %s is referenced twice from STC" % name) destCol.stc = stcDef.compiled destCol.stcUtype = type
def validate(self): self._validateNext(Param) if self.content_ is base.NotGiven: self.set(None) if self.required and self.value is None: raise base.StructureError("Required value not given for param" " %s" % self.name) try: # the value property will bomb on malformed literals self.value except ValueError, msg: raise base.LiteralParseError( self.name, self.content_, hint="Param content must be parseable by the DC default parsers." " The value you passed caused the error: %s" % msg)
def _compileCustomPage(self): if self.customPage: try: modNs, moddesc = utils.loadPythonModule(self.customPage) modNs.RD = self.rd getattr(modNs, "initModule", lambda: None)() page = modNs.MainPage except ImportError: raise base.ui.logOldExc( base.LiteralParseError( "customPage", self.customPage, hint= "This means that an exception was raised while DaCHS" " tried to import the renderer module. If DaCHS ran" " with --debug, the original traceback is available" " in the logs.")) self.customPageCode = page, (os.path.basename( self.customPage), ) + moddesc
def parse(self, value): if isinstance(value, slice): # we're already parsed return value try: if "-" in value: startLit, endLit = value.split("-") start, end = None, None if startLit.strip(): start = int(startLit) - 1 if endLit.strip(): end = int(endLit) return slice(start, end) else: col = int(value) return slice(col - 1, col) except ValueError: raise base.ui.logOldExc( base.LiteralParseError( "colRanges", value, hint="A column range," " (either int1-int2 or just an int) is expected here."))
def onParentComplete(self): """converts min, max, and options from string literals to python objects. """ dataField = self.parent # It would be nicer if we could handle this in properties for min etc, but # unfortunately parent might not be complete then. The only # way around that would have been delegations from Column, and that's # not very attractive either. if self.min: self.min = self.makePythonVal(self.min, dataField.type) if self.max: self.max = self.makePythonVal(self.max, dataField.type) if self.options: dbt = dataField.type for opt in self.options: opt.content_ = self.makePythonVal(opt.content_, dbt) self.validValues = set([o.content_ for o in self.options]) if self.nullLiteral: try: self.makePythonVal(self.nullLiteral, dataField.type) except ValueError: raise base.LiteralParseError( "nullLiteral", self.nullLiteral, hint="If you want to *parse* whatever you gave into a NULL," " use the parseWithNull function in a rowmaker. The null" " literal gives what value will be used for null values" " when serializing to VOTables and the like.") if self.default and isinstance(self.default, basestring): type, arraysize, xtype = dataField._getVOTableType() self.default = paramval.getVOTParser(type, arraysize, xtype)(self.default)
def validate(self): self._validateNext(RDParameter) if not utils.identifierPattern.match(self.key): raise base.LiteralParseError("name", self.key, hint= "The name you supplied was not defined by any procedure definition.")
def validate(self): self._validateNext(MixinPar) if len(self.key)<2: raise base.LiteralParseError("name", self.key, hint="Names of" " mixin parameters must have at least two characters (since" " they are exposed as macros")