Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Classes | Functions | Variables
CellMLToNektar.validator Namespace Reference

Classes

class  CellMLValidator
 
class  LxmlRelaxngValidator
 
class  RvpRelaxngValidator
 
class  ValidatorError
 

Functions

def quit
 def del(self): """ Tell our RVP process to quit. More...
 
def validate
 
def get_validation_errors
 
def _error_found
 
def _start_tag_open
 
def _attribute
 
def _start_tag_close
 
def _end_tag
 
def _textonly
 
def _mixed
 
def _start
 
def _send
 
def _recv
 
def _resp
 
def _flush_text
 
def _start_element
 
def _end_element
 
def _characters
 
def check_repo
 Convenience functions #. More...
 
def compare_output_files
 
def get_options
 For running as an executable #. More...
 
def run
 

Variables

tuple pycml_path = os.path.dirname(os.path.realpath(__file__))
 
string __version__ = "$Revision: 25790 $"
 
string profile_name = '/tmp/pycml-profile-%f-%d'
 
 _text
 
 _error_messages
 
 _prevcol
 
 _pat
 
 _parser
 
 _errors
 
 _ismixed
 

Function Documentation

def CellMLToNektar.validator._attribute (   self,
  cur,
  name,
  val 
)
private

Definition at line 339 of file validator.py.

340  def _attribute(self, cur, name, val):
341  self._send('attribute '+cur+' '+name+' '+val)
return self._resp()
def CellMLToNektar.validator._characters (   self,
  data 
)
private

Definition at line 432 of file validator.py.

References CellMLToNektar.validator.check_repo().

433  def _characters(self, data):
434  self._text = self._text + data
435 
436 
437 
438 
439 
def CellMLToNektar.validator._end_element (   self,
  name 
)
private

Definition at line 428 of file validator.py.

429  def _end_element(self, name):
430  self._flush_text()
431  self._pat = self._end_tag(self._pat, name)
self._ismixed = True
def CellMLToNektar.validator._end_tag (   self,
  cur,
  name 
)
private

Definition at line 345 of file validator.py.

346  def _end_tag(self, cur, name):
347  self._send('end-tag '+cur+' '+name)
return self._resp()
def CellMLToNektar.validator._error_found (   self,
  line,
  col,
  msg 
)
private

Definition at line 330 of file validator.py.

331  def _error_found(self, line, col, msg):
332  report = "%d,%d:%s" % (line, col, msg.strip())
333  logging.getLogger('validator').error(report)
334  self._error_messages.append(report)
def CellMLToNektar.validator._flush_text (   self)
private
Apparently Expat doesn't concatenate text nodes, so we do it
manually; the CharDataHandler collects the text, and this
method passes it to the validator.

Definition at line 408 of file validator.py.

409  def _flush_text(self):
410  """
411  Apparently Expat doesn't concatenate text nodes, so we do it
412  manually; the CharDataHandler collects the text, and this
413  method passes it to the validator.
414  """
415  if self._text:
416  if self._ismixed:
417  self._pat = self._mixed(self._pat, self._text)
418  else:
419  self._pat = self._textonly(self._pat, self._text)
self._text = ''
def CellMLToNektar.validator._mixed (   self,
  cur,
  text 
)
private
In mixed content, whitespace is discarded, and any non-whitespace
is counted as equal.

Definition at line 351 of file validator.py.

352  def _mixed(self, cur, text):
353  """
354  In mixed content, whitespace is discarded, and any non-whitespace
355  is counted as equal.
356  """
357  if self._ws.search(text):
358  self._send('mixed '+cur+' .')
359  return self._resp()
360  else:
return cur
def CellMLToNektar.validator._recv (   self)
private
Receive a zero-terminated response from RVP; drop zero byte.

Definition at line 371 of file validator.py.

372  def _recv(self):
373  """
374  Receive a zero-terminated response from RVP; drop zero byte.
375  """
376  s = ''
377  while True:
378  # 16 is a good buffer length for ok responses; errors
379  # should be rare
380  s = s + os.read(self._rvpout, 16)
381  if s[-1] == '\0': break
return s[:-1]
def CellMLToNektar.validator._resp (   self)
private
Get a reply from RVP.
If an error occurs, log the message.
Return the current pattern value.

Definition at line 382 of file validator.py.

383  def _resp(self):
384  """
385  Get a reply from RVP.
386  If an error occurs, log the message.
387  Return the current pattern value.
388  """
389  r = self._recv().split(' ', 3)
390  if r[0] == 'ok': return r[1]
391  if r[0] == 'error':
392  self._errors = True
393  if r[3] != '': # Only report if we have a message
394  line = self._parser.CurrentLineNumber
395  col = self._parser.CurrentColumnNumber
396  if line != self._prevline or col != self._prevcol:
397  # One report per file position
398  self._error_found(line, col, r[3])
399  self._prevline, self._prevcol = line, col
400  return r[1]
401  if r[0] == 'er':
402  self._errors = True
403  return r[1]
404  # Unknown response
405  raise self.RvpProtocolError, "unexpected response '"+r[0]+"'"
406 
def CellMLToNektar.validator._send (   self,
  s 
)
private
Terminate string with zero, encode in UTF-8 and send to RVP.

Definition at line 366 of file validator.py.

367  def _send(self, s):
368  """
369  Terminate string with zero, encode in UTF-8 and send to RVP.
370  """
os.write(self._rvpin, s.encode('UTF-8') + '\0')
def CellMLToNektar.validator._start (   self,
  grammar = '0' 
)
private

Definition at line 361 of file validator.py.

362  def _start(self, grammar = '0'):
363  self._send('start '+grammar)
364  return self._resp()
def CellMLToNektar.validator._start_element (   self,
  name,
  attrs 
)
private

Definition at line 420 of file validator.py.

421  def _start_element(self, name, attrs):
422  self._ismixed = True
423  self._flush_text()
424  self._pat = self._start_tag_open(self._pat, name)
425  self._ismixed = False
426  for n, v in attrs.items():
427  self._pat = self._attribute(self._pat, n, v)
self._pat = self._start_tag_close(self._pat, name)
def CellMLToNektar.validator._start_tag_close (   self,
  cur,
  name 
)
private

Definition at line 342 of file validator.py.

343  def _start_tag_close(self, cur, name):
344  self._send('start-tag-close '+cur+' '+name)
return self._resp()
def CellMLToNektar.validator._start_tag_open (   self,
  cur,
  name 
)
private

Definition at line 336 of file validator.py.

337  def _start_tag_open(self, cur, name):
338  self._send('start-tag-open '+cur+' '+name)
return self._resp()
def CellMLToNektar.validator._textonly (   self,
  cur,
  text 
)
private

Definition at line 348 of file validator.py.

349  def _textonly(self, cur, text):
350  self._send('text '+cur+' '+text)
return self._resp()
def CellMLToNektar.validator.check_repo (   repo_dir = '../../models/all_from_repository',
  model_suffix = 'xml',
  invalid_if_warnings = False,
  compare = True 
)

Convenience functions #.

Validate every model in the CellML repository, and return a list
of invalid models.

If compare is False, writes errors & warnings to log files in the
same folder as the models, otherwise compares the output to log
files already present, and notes differences.

Displays total run time.

Definition at line 447 of file validator.py.

References CellMLToNektar.validator.compare_output_files().

Referenced by CellMLToNektar.validator._characters().

448  compare=True):
449  """
450  Validate every model in the CellML repository, and return a list
451  of invalid models.
452 
453  If compare is False, writes errors & warnings to log files in the
454  same folder as the models, otherwise compares the output to log
455  files already present, and notes differences.
456 
457  Displays total run time.
458  """
459  def close_log_file(stream, filename):
460  stream.close()
461  try:
462  size = os.path.getsize(filename)
463  if size == 0:
464  os.remove(filename)
465  except OSError:
466  pass
467  import glob, time, gc
468  start_time = time.time()
469  v = CellMLValidator()
470  invalid = []
471  files = glob.glob(repo_dir + '/*.' + model_suffix)
472  files.sort()
473  for filename in files:
474  model = os.path.basename(filename)[:-4]
475  fn = os.path.splitext(filename)[0]
476  warnfn, errfn = fn + '_warnings.log', fn + '_errors.log'
477  if compare:
478  warn_stream = StringIO()
479  err_stream = StringIO()
480  else:
481  warn_stream = open(warnfn, 'w')
482  err_stream = open(errfn, 'w')
483  print "Checking model",model,"at",time.strftime("%X %x"),
484  sys.stdout.flush()
485  valid = v.validate(filename, error_stream=err_stream,
486  warning_stream=warn_stream,
487  invalid_if_warnings=invalid_if_warnings)
488  if not valid:
489  print max(1,4 - (5+len(model))//8) * '\t', "X"
490  else:
491  print
492  if compare:
493  compare_output_files(warn_stream, warnfn)
494  compare_output_files(err_stream, errfn)
495  else:
496  close_log_file(err_stream, errfn)
497  close_log_file(warn_stream, warnfn)
498  if not valid:
499  invalid.append(model)
500  gc.collect()
501  elapsed_time = time.time() - start_time
502  mins,secs = int(elapsed_time//60), int(elapsed_time%60)
503  print len(files),"models checked in",mins,"minutes",secs,"seconds."
504  print len(invalid),"invalid"
505  v.quit()
506  return invalid
def CellMLToNektar.validator.compare_output_files (   new_stream,
  old_filename 
)

Definition at line 507 of file validator.py.

Referenced by CellMLToNektar.validator.check_repo().

508 def compare_output_files(new_stream, old_filename):
509  def save_new_output():
510  nfp = open(old_filename + '-new', 'w')
511  nfp.write(new_stream.getvalue())
512  nfp.close()
513  new_stream.seek(0, 2)
514  new_len = new_stream.tell()
515  try:
516  fp = open(old_filename, 'r')
517  except IOError:
518  if new_len > 0:
519  print "Log file", old_filename, "doesn't exist,", \
520  "but we have new output"
521  try:
522  ofp = open(os.path.join(os.path.dirname(old_filename),
523  'new'), 'a')
524  print >>ofp, "Log file", old_filename, "doesn't exist,", \
525  "but we have new output"
526  ofp.close()
527  except IOError:
528  pass
529  save_new_output()
530  return
531  new_stream.seek(0)
532  new_lines = set(new_stream.readlines())
533  old_lines = set(fp.readlines())
534  if old_lines != new_lines:
535  print "Output set differs from log file", old_filename
536  print "Lines added:", new_lines - old_lines
537  print "Lines removed:", old_lines - new_lines
538  try:
539  ofp = open(os.path.join(os.path.dirname(old_filename), 'new'), 'a')
540  print >>ofp, "Output set differs from log file", old_filename
541  print >>ofp, "Lines added:", new_lines - old_lines
542  print >>ofp, "Lines removed:", old_lines - new_lines, "\n"
543  ofp.close()
544  except IOError:
545  pass
546  save_new_output()
547  new_stream.close()
548  fp.close()
549  return
def CellMLToNektar.validator.get_options (   args)

For running as an executable #.

get_options(args):
Process our command-line options.

args is a list of options & positional arguments.

Definition at line 554 of file validator.py.

Referenced by CellMLToNektar.validator.run().

555 def get_options(args):
556  """get_options(args):
557  Process our command-line options.
558 
559  args is a list of options & positional arguments.
560  """
561  usage = 'usage: %prog [options] <cellml file or URI> ...'
562  parser = optparse.OptionParser(version="%%prog %s" % __version__,
563  usage=usage)
564  parser.add_option('-o', dest='outfilename', metavar='OUTFILE',
565  help='write *all* output to OUTFILE (overrides -e and -w)')
566  parser.add_option('-e', '--error-file',
567  dest='errfilename', metavar='ERRFILE',
568  default='stderr',
569  help='write errors to ERRFILE [default %default]')
570  parser.add_option('-w', '--warning-file',
571  dest='warnfilename', metavar='WARNFILE',
572  default='stderr',
573  help='write warnings to WARNFILE [default %default]')
574  parser.add_option('-q', '--quiet',
575  dest='quiet', action='store_true', default=False,
576  help="don't display any output, just set exit status")
577  parser.add_option('--no-warnings', '--only-errors',
578  dest='show_warnings', action='store_false',
579  default=True,
580  help="don't display warning messages")
581  parser.add_option('-s', '--space-messages',
582  dest='space_errors', action='store_true',
583  default=False,
584  help="print a blank line after every warning/error message")
585  parser.add_option('-x', '--xml-context',
586  dest='xml_context', action='store_true', default=False,
587  help="display the MathML tree of any expression with invalid units")
588  parser.add_option('-u', '--warn-on-unit-conversions',
589  action='store_true', default=False,
590  help="generate a warning if unit conversions are required")
591  parser.add_option('--Wu', '--warn-on-units-errors',
592  action='store_true', default=False,
593  dest='warn_on_units_errors',
594  help="give a warning instead of an error for"
595  " dimensional inconsistencies")
596  parser.add_option('-i', '--interactive',
597  action='store_true', default=False,
598  help="use with python -i to enter an interactive session"
599  " after validation")
600  parser.add_option('-d', '--debug', action='store_true', default=False,
601  help="output debug info to stderr")
602  parser.add_option('--profile', action='store_true', default=False,
603  help="turn on profiling of PyCml")
604 
605  options, args = parser.parse_args(args)
606  if len(args) < 1:
607  parser.error("an input CellML file must be specified")
608  return options, args
609 
def get_options
For running as an executable #.
Definition: validator.py:554
def CellMLToNektar.validator.get_validation_errors (   self)
Return the list of all errors found while validating
the current file.

Definition at line 323 of file validator.py.

324  def get_validation_errors(self):
325  """
326  Return the list of all errors found while validating
327  the current file.
328  """
329  return self._error_messages
def CellMLToNektar.validator.quit (   self)

def del(self): """ Tell our RVP process to quit.

This doesn't work well, since del isn't necessarily called at program exit. Hence, there is a manual quit() method. """ self.quit()

Call this method when the validator is finished with.
It terminates the associated RVP process cleanly.
Failure to do so will probably result in an error when your program exits.

Definition at line 288 of file validator.py.

289  def quit(self):
290  """Call this method when the validator is finished with.
291  It terminates the associated RVP process cleanly.
292  Failure to do so will probably result in an error when your program exits.
293  """
294  self._send('quit')
295  return self._resp()
def quit
def del(self): """ Tell our RVP process to quit.
Definition: validator.py:288
def CellMLToNektar.validator.run ( )

Definition at line 610 of file validator.py.

References CellMLToNektar.utilities.close_output_stream(), CellMLToNektar.validator.get_options(), and CellMLToNektar.utilities.open_output_stream().

611 def run():
612  # Validate all files specified on the command line
613  options, files = get_options(sys.argv[1:])
614  validator = CellMLValidator()
615 
616  # Open output streams
617  if not options.outfilename is None:
618  out_s = open_output_stream(options.outfilename)
619  err_s = warn_s = out_s
620  else:
621  out_s = sys.stdout
622  err_s = open_output_stream(options.errfilename)
623  warn_s = open_output_stream(options.warnfilename)
624 
625  # Keyword arguments for validator
626  kwargs = {'show_warnings': options.show_warnings,
627  'warning_stream': warn_s,
628  'show_errors': not options.quiet,
629  'error_stream': err_s,
630  'space_errors': options.space_errors,
631  'xml_context': options.xml_context,
632  'warn_on_units_errors': options.warn_on_units_errors,
633  'check_for_units_conversions': options.warn_on_unit_conversions}
634 
635  if options.debug:
636  formatter = logging.Formatter(fmt="%(name)s %(asctime)s: %(message)s")
637  handler = logging.StreamHandler(sys.stderr)
638  handler.setFormatter(formatter)
639  handler.addFilter(OnlyDebugFilter())
640  logging.getLogger().addHandler(handler)
641  logging.getLogger().setLevel(logging.DEBUG)
642  kwargs['loglevel'] = logging.DEBUG
643 
644  # Validate files
645  result = True
646  for f in files:
647  if not options.quiet:
648  print >>out_s, "Validating file", f, "against CellML 1.0"
649  res = validator.validate(f, **kwargs)
650  if not options.quiet:
651  print >>out_s, "File is%s valid CellML 1.0" % ((' NOT','')[res])
652  result = result and res
653 
654  # Close output streams
655  close_output_stream(out_s)
656  close_output_stream(err_s)
657  close_output_stream(warn_s)
658 
659  # Tidy up validator
660  validator.quit()
661 
662  # Set exit status
663  if not options.interactive:
664  sys.exit(not result)
665 
def get_options
For running as an executable #.
Definition: validator.py:554
def CellMLToNektar.validator.validate (   self,
  stream 
)
Validate an XML document, returning a boolean.

stream should be a file-like object containing the document to
be validated.
Returns True iff the document was valid.

Definition at line 296 of file validator.py.

297  def validate(self, stream):
298  """Validate an XML document, returning a boolean.
299 
300  stream should be a file-like object containing the document to
301  be validated.
302  Returns True iff the document was valid.
303  """
304  # Initialise
305  self._text = ''
306  self._errors, self._error_messages = False, []
307  self._prevline, self._prevcol = -1, -1
308  self._pat = self._start()
309  # Create parser
310  parser = self.expat.ParserCreate(namespace_separator=':')
311  parser.StartElementHandler = self._start_element
312  parser.EndElementHandler = self._end_element
313  parser.CharacterDataHandler = self._characters
314  self._parser = parser
315  # Parse & validate
316  try:
317  self._parser.ParseFile(stream)
318  except self.expat.ExpatError, e:
319  self._errors = True
320  self._error_found(e.lineno, e.offset, str(e))
321  # Any errors
322  return not self._errors

Variable Documentation

string CellMLToNektar.validator.__version__ = "$Revision: 25790 $"

Definition at line 56 of file validator.py.

CellMLToNektar.validator._error_messages

Definition at line 305 of file validator.py.

CellMLToNektar.validator._errors

Definition at line 318 of file validator.py.

CellMLToNektar.validator._ismixed

Definition at line 421 of file validator.py.

CellMLToNektar.validator._parser

Definition at line 313 of file validator.py.

CellMLToNektar.validator._pat

Definition at line 307 of file validator.py.

CellMLToNektar.validator._prevcol

Definition at line 306 of file validator.py.

CellMLToNektar.validator._text

Definition at line 304 of file validator.py.

string CellMLToNektar.validator.profile_name = '/tmp/pycml-profile-%f-%d'

Definition at line 669 of file validator.py.

tuple CellMLToNektar.validator.pycml_path = os.path.dirname(os.path.realpath(__file__))

Definition at line 49 of file validator.py.