All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Classes | Macros | Functions | Variables
fclmodule.cxx File Reference
#include "Python.h"
#include <iostream>
#include <iomanip>
#include <sstream>
#include "cetlib/search_path.h"
#include "cetlib_except/exception.h"
#include "fhiclcpp/ParameterSet.h"
#include "fhiclcpp/ParameterSetWalker.h"
#include "fhiclcpp/ParameterSetRegistry.h"
#include "fhiclcpp/make_ParameterSet.h"

Go to the source code of this file.

Classes

class  PythonDictConverter
 

Macros

#define PY_SSIZE_T_CLEAN
 

Functions

static std::string format (PyObject *obj, unsigned int pos, unsigned int indent, unsigned int maxlen, unsigned int depth)
 
static PyObjectmake_pset (PyObject *self, PyObject *args)
 
static PyObjectpretty (PyObject *self, PyObject *args)
 
void initfcl ()
 

Variables

static struct PyMethodDef fclmodule_methods []
 

Macro Definition Documentation

#define PY_SSIZE_T_CLEAN

Definition at line 51 of file fclmodule.cxx.

Function Documentation

static std::string format ( PyObject obj,
unsigned int  pos,
unsigned int  indent,
unsigned int  maxlen,
unsigned int  depth 
)
static

Definition at line 374 of file fclmodule.cxx.

398 {
399  // Result string stream.
400 
401  std::ostringstream ss;
402 
403  if(PyBytes_Check(obj)) {
404 
405  // String objects, add double quotes, but don't do any other formatting.
406 
407  ss << "\"" << PyBytes_AsString(obj) << "\"";
408  }
409 
410  else if(PyUnicode_Check(obj)) {
411 
412  // Unicode objects, convert to byte string and add double quotes.
413 
414  PyObject* bytes = PyUnicode_AsUTF8String(obj);
415  ss << "\"" << PyBytes_AsString(bytes) << "\"";
416  }
417 
418  else if(PyDict_Check(obj)) {
419 
420  // Always print dictionary objects in multiline format, one key per line.
421 
422  // Get list of keys. Keys are assumed to be strings.
423 
424  PyObject* keys = PyDict_Keys(obj);
425 
426  // Make a first pass over the list of keys to determine the maximum length key.
427 
428  int n = PyList_Size(keys);
429  int keymaxlen = 0;
430  for(int i=0; i<n; ++i) {
431  PyObject* key = PyList_GetItem(keys, i);
432  int keylen = python_string_len(key);
433  if(keylen > keymaxlen)
434  keymaxlen = keylen;
435  }
436 
437  // Print enclosing braces, but not for outermost table (i.e. the whole parameter set).
438 
439  bool outer = (pos == 0 && indent == 0);
440  if(!outer && n != 0)
441  ss << "{\n";
442 
443  // Second pass, loop over keys and values and convert them to strings.
444 
445  for(int i=0; i<n; ++i) {
446  PyObject* key = PyList_GetItem(keys, i);
447  PyObject* value = PyDict_GetItem(obj, key);
448  std::string ks = python_to_cxx_str(key);
449  ss << std::setw(indent) << ""
450  << std::setw(keymaxlen) << std::left << ks << " : "
451  << format(value, indent + keymaxlen + 3, indent+2, maxlen, depth+1)
452  << '\n';
453  }
454  if(n == 0)
455  ss << "{}";
456  else if(!outer)
457  ss << std::setw(indent-1) << std::right << '}';
458 
459  Py_DECREF(keys);
460 
461  }
462 
463  else if(PyList_Check(obj) || PyTuple_Check(obj)) {
464 
465  // Sequence printing handled here.
466  // Break lines only when position exceeds maxlen.
467 
468  char open_seq = 0;
469  char close_seq = 0;
470  int n = 0;
471  if(PyList_Check(obj)) {
472  open_seq = '[';
473  close_seq = ']';
474  n = PyList_Size(obj);
475  }
476  else {
477  open_seq = '(';
478  close_seq = ')';
479  n = PyTuple_Size(obj);
480  }
481 
482  // Loop over elements of this sequence.
483 
484  std::string sep(1, open_seq);
485  unsigned int break_indent = pos+1;
486  for(int i=0; i<n; ++i) {
487  ss << sep;
488  pos += sep.size();
489  PyObject* ele = PySequence_GetItem(obj, i);
490 
491  // Get the formatted string representation of this object.
492 
493  std::string f = format(ele, pos, break_indent, maxlen, depth+1);
494 
495  // Get the number of characters before the first newline.
496 
497  std::string::size_type fs = f.size();
498  std::string::size_type n1 = std::min(f.find('\n'), fs);
499 
500  // Decide if we want to break the line before printing this element.
501  // Never break at the first element of a sequence.
502  // Force a break (except at first element) if this is a structured element.
503  // If we do break here, reformat this element with the updated position.
504 
505  bool force_break = PyList_Check(ele) || PyTuple_Check(ele) || PyDict_Check(ele);
506  if(i > 0 && (force_break || pos + n1 > maxlen)) {
507  ss << '\n' << std::setw(break_indent) << "";
508  pos = break_indent;
509  f = format(ele, pos, break_indent, maxlen, depth+1);
510  fs = f.size();
511  }
512 
513  // Print this element
514 
515  ss << f;
516 
517  // Update the current character position, taking into account
518  // whether the string we just printed contains a newline.
519 
520  std::string::size_type n2 = f.find_last_of('\n');
521  if(n2 >= fs)
522  pos += fs;
523  else
524  pos = fs - n2 - 1;
525 
526  sep = std::string(", ");
527  Py_DECREF(ele);
528  }
529 
530  // Close sequence.
531 
532  if(n == 0)
533  ss << open_seq;
534  ss << close_seq;
535  }
536 
537  else {
538 
539  // Last resort, use python's string representation.
540 
541  PyObject* pystr = PyObject_Str(obj);
542  std::string s = python_to_cxx_str(pystr);
543 
544  // Print booleans in lower case instead of python default case.
545 
546  if(s == std::string("True"))
547  s = "true";
548  else if(s == std::string("False"))
549  s = "false";
550  ss << s;
551  }
552 
553  // Done.
554 
555  return ss.str();
556 }
_object PyObject
Definition: PyUtils.h:4
static std::string format(PyObject *obj, unsigned int pos, unsigned int indent, unsigned int maxlen, unsigned int depth)
Definition: fclmodule.cxx:374
walls no right
Definition: selectors.fcl:105
walls no left
Definition: selectors.fcl:105
then echo File list $list not found else cat $list while read file do echo $file sed s
Definition: file_to_url.sh:60
temporary value
byte bytes
Alias for common language habits.
Definition: datasize.h:101
void initfcl ( )

Definition at line 665 of file fclmodule.cxx.

666  {
667  Py_InitModule("fcl", fclmodule_methods);
668  }
static struct PyMethodDef fclmodule_methods[]
Definition: fclmodule.cxx:638
static PyObject* make_pset ( PyObject self,
PyObject args 
)
static

Definition at line 558 of file fclmodule.cxx.

567 {
568  // Extract argument as string.
569 
570  const char* fclname;
571  if(!PyArg_ParseTuple(args, "s", &fclname))
572  return 0;
573  std::string fclstr(fclname);
574 
575  // Make parameter set.
576 
577  PyObject* result = 0;
578  try {
579  std::string pathvar("FHICL_FILE_PATH");
580  cet::filepath_lookup maker(pathvar);
581  auto pset = fhicl::ParameterSet::make(fclstr, maker);
582  PythonDictConverter converter;
583  pset.walk(converter);
584  result = converter.result();
585  }
586  catch(cet::exception& e) {
587  PyErr_SetString(PyExc_IOError, e.what());
588  result = 0;
589  }
590 
591  // Done.
592 
593  return result;
594 }
_object PyObject
Definition: PyUtils.h:4
PyObject * result() const
Definition: fclmodule.cxx:162
do i e
static PyObject* pretty ( PyObject self,
PyObject args 
)
static

Definition at line 596 of file fclmodule.cxx.

607 {
608  // Result.
609 
610  PyObject* result = 0;
611 
612  // Extract argument.
613 
614  int n = PySequence_Length(args);
615  if(n == 0) {
616 
617  // No arguments, return none.
618 
619  result = Py_None;
620  Py_INCREF(result);
621  }
622  else {
623 
624  // Otherwise, extract the first element.
625 
626  PyObject* obj = PySequence_GetItem(args, 0);
627  std::string s = format(obj, 0, 0, 80, 0);
628  result = cxx_str_to_python(s);
629  }
630 
631  // Done.
632 
633  return result;
634 }
_object PyObject
Definition: PyUtils.h:4
static std::string format(PyObject *obj, unsigned int pos, unsigned int indent, unsigned int maxlen, unsigned int depth)
Definition: fclmodule.cxx:374
then echo File list $list not found else cat $list while read file do echo $file sed s
Definition: file_to_url.sh:60

Variable Documentation

struct PyMethodDef fclmodule_methods[]
static
Initial value:
= {
{"make_pset", make_pset, METH_VARARGS, "Convert fcl ParameterSet to python dictionary"},
{"pretty", pretty, METH_VARARGS, "Convert dictionary parameter set to fcl text"},
{0, 0, 0, 0}
}
static PyObject * make_pset(PyObject *self, PyObject *args)
Definition: fclmodule.cxx:558
static PyObject * pretty(PyObject *self, PyObject *args)
Definition: fclmodule.cxx:596

Definition at line 638 of file fclmodule.cxx.