Repository: planetarypy/pvl

Issue:
pvl.grammar objects have incorrect documentation, and ISISGrammar needs to handle #-comments
**Describe the bug**
The documentation for the various grammar objects in grammar.py incorrectly conveys that there are some parameters that could be specified on object instantiation.  Additionally, the ISISGrammar needs to be able to handle octothorpe (#) started comments, and it does not.

**Expected behavior**
* The documentation for the grammar objects should properly convey what is and isn't possible via their interface.
* The ISISGrammar object should be able to handle PVL-text with octothorpe comments.

**Additional context**
Please see #72 for a more extended discussion related to these topics.


Discussion:

Patch:
diff --git a/HISTORY.rst b/HISTORY.rst
index ad2bec0..47b0b45 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -30,6 +30,22 @@ and the release date, in year-month-day format (see examples below).
 Unreleased
 ----------
 
+1.1.0 (2020-12-04)
+------------------
+
+Added
++++++
+* Modified `pvl_validate` to more robustly deal with errors, and also provide
+  more error-reporting via `-v` and `-vv`.
+* Modified ISISGrammar so that it can parse comments that begin with an octothorpe (#).
+
+Fixed
++++++
+* Altered documentation in grammar.py that was incorrectly indicating that
+  there were parameters that could be passed on object initiation that would
+  alter how those objects behaved.
+
+
 1.0.1 (2020-09-21)
 ------------------
 
diff --git a/pvl/__init__.py b/pvl/__init__.py
index 917aa4f..0e8f932 100755
--- a/pvl/__init__.py
+++ b/pvl/__init__.py
@@ -24,7 +24,7 @@ from .collections import (
 
 __author__ = "The pvl Developers"
 __email__ = "rbeyer@rossbeyer.net"
-__version__ = "1.0.1"
+__version__ = "1.1.0"
 __all__ = [
     "load",
     "loads",
diff --git a/pvl/grammar.py b/pvl/grammar.py
old mode 100644
new mode 100755
index 2fa3428..02cfa37
--- a/pvl/grammar.py
+++ b/pvl/grammar.py
@@ -1,5 +1,21 @@
 # -*- coding: utf-8 -*-
-"""Describes the language aspects of PVL dialects."""
+"""Describes the language aspects of PVL dialects.
+
+These grammar objects are not particularly meant to be easily
+user-modifiable during running of an external program, which is why
+they have no arguments at initiation time, nor are there any methods
+or functions to modify them.  This is because these grammar objects
+are used both for reading and writing PVL-text.  As such, objects
+like PVLGrammar and ODLGrammar shouldn't be altered, because if
+they are, then the PVL-text written out with them wouldn't conform
+to the spec.
+
+Certainly, these objects do have attributes that can be altered,
+but unless you've carefully read the code, it isn't recommended.
+
+Maybe someday we'll add a more user-friendly interface to allow that,
+but in the meantime, just leave an Issue on the GitHub repo.
+"""
 
 # Copyright 2019-2020, ``pvl`` library authors.
 #
@@ -15,22 +31,19 @@ class PVLGrammar:
     """Describes a PVL grammar for use by the lexer and parser.
 
     The reference for this grammar is the CCSDS-641.0-B-2 'Blue Book'.
-
-    :param whitespace: Tuple of characters to be recognized as PVL
-        White Space (used to separate syntactic elements and promote
-        readability, but the amount or presence of White Space may
-        not be used to provide different meanings).
-
-    :param reserved_characters: Tuple of characters that may not
-        occur in Parameter Names, Unquoted Strings, or Block Names.
-
-    :param comments: Tuple of two-tuples with each two-tuple containing
-        a pair of character sequences that enclose a comment.
     """
 
     spacing_characters = (" ", "\t")
     format_effectors = ("\n", "\r", "\v", "\f")
+
+    # Tuple of characters to be recognized as PVL White Space
+    # (used to separate syntactic elements and promote readability,
+    # but the amount or presence of White Space may not be used to
+    # provide different meanings).
     whitespace = spacing_characters + format_effectors
+
+    # Tuple of characters that may not occur in Parameter Names,
+    # Unquoted Strings, nor Block Names.
     reserved_characters = (
         "&",
         "<",
@@ -63,6 +76,8 @@ class PVLGrammar:
 
     delimiters = (";",)
 
+    # Tuple of two-tuples with each two-tuple containing a pair of character
+    # sequences that enclose a comment.
     comments = (("/*", "*/"),)
 
     # A note on keywords: they should always be compared with
@@ -240,6 +255,10 @@ class ISISGrammar(PVLGrammar):
     object_pref_keywords = ("Object", "End_Object")
     object_keywords = {"OBJECT": "END_OBJECT"}
 
+    # A single-line comment that starts with the octothorpe (#) is not part
+    # of PVL or ODL, but it is used when ISIS writes out comments.
+    comments = (("/*", "*/"), ("#", "\n"))
+
     def __init__(self):
         # ISIS allows for + characters in Unquoted String values.
         self.reserved_characters = tuple(
diff --git a/pvl/pvl_validate.py b/pvl/pvl_validate.py
index f646e39..fa4ca32 100644
--- a/pvl/pvl_validate.py
+++ b/pvl/pvl_validate.py
@@ -85,7 +85,8 @@ def arg_parser():
         "--verbose",
         action="count",
         default=0,
-        help="Will report the errors that are encountered.",
+        help="Will report the errors that are encountered.  A second v will "
+             "include tracebacks for non-pvl exceptions. ",
     )
     p.add_argument("--version", action="version", version=pvl.__version__)
     p.add_argument(
@@ -146,8 +147,17 @@ def pvl_flavor(
     except (LexerError, ParseError) as err:
         logging.error(f"{dialect} load error {filename} {err}")
         loads = False
+    except:  # noqa E722
+        if verbose <= 1:
+            logging.error(
+                f"{dialect} load error {filename}, try -vv for more info."
+            )
+        else:
+            logging.exception(f"{dialect} load error {filename}")
+            logging.error(f"End {dialect} load error {filename}")
+        loads = False
 
-    return (loads, encodes)
+    return loads, encodes
 
 
 def report(reports: list, flavors: list) -> str:
diff --git a/setup.cfg b/setup.cfg
index 1a07447..ffeb34f 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 1.0.1
+current_version = 1.1.0
 commit = False
 tag = False
 parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\-(?P<prerelease>[a-z]+)\.((?P<serial>\d+)))?
@@ -22,3 +22,4 @@ values =
 [bumpversion:file:setup.py]
 
 [bumpversion:file:pvl/__init__.py]
+
diff --git a/setup.py b/setup.py
index 7c39881..39c5fad 100755
--- a/setup.py
+++ b/setup.py
@@ -12,7 +12,7 @@ history = open('HISTORY.rst').read().replace('.. :changelog:', '')
 
 setup(
     name='pvl',
-    version='1.0.1',
+    version='1.1.0',
     description='Python implementation of PVL (Parameter Value Language)',
     long_description=readme + '\n\n' + history,
     author='The PlanetaryPy Developers',


Test patch:
diff --git a/tests/data/isis_octothorpe.txt b/tests/data/isis_octothorpe.txt
new file mode 100644
index 0000000..02a470e
--- /dev/null
+++ b/tests/data/isis_octothorpe.txt
@@ -0,0 +1,23 @@
+Group = Radiometry
+    # Bitweight Correction Parameters
+    BitweightCorrectionPerformed = "No: Table converted"
+    BitweightFile                = "Not applicable: No bitweight correction"
+
+    # Bias Subtraction Parameters
+    BiasSubtractionPerformed     = Yes
+    BiasSubtractionMethod        = "Overclock fit"
+    NumberOfOverclocks           = 2
+
+    # Dark Current Subtraction Parameters
+    DarkSubtractionPerformed     = Yes
+    DarkParameterFile            = /usgs/cpkgs/isis3/data/cassini/calibration-
+                                   /darkcurrent/nac_median_dark_parameters042-
+                                   28.full.cub
+    BiasDistortionTable          = /usgs/cpkgs/isis3/data/cassini/calibration-
+                                   /darkcurrent/nac_bias_distortion.tab
+
+    # Linearity Correction Parameters
+    LinearityCorrectionPerformed = Yes
+    LinearityCorrectionTable     = /usgs/cpkgs/isis3/data/cassini/calibration-
+                                   /linearize/NAC2.lut
+End_Group
diff --git a/tests/test_pvl.py b/tests/test_pvl.py
index 86bea35..ec496a1 100755
--- a/tests/test_pvl.py
+++ b/tests/test_pvl.py
@@ -811,11 +811,16 @@ def test_delimiters():
 
 
 def test_isis_output():
-    label = pvl.load(os.path.join(DATA_DIR, "isis_output.txt"))
-    assert label["Results"]["TotalPixels"] == 2048000
+    # Should test that both the ISISGrammar and OmniGrammar can deal with these:
+    for g in (pvl.grammar.OmniGrammar(), pvl.grammar.ISISGrammar()):
+        label = pvl.load(os.path.join(DATA_DIR, "isis_output.txt"), grammar=g)
+        assert label["Results"]["TotalPixels"] == 2048000
 
-    naif = pvl.load(os.path.join(DATA_DIR, "isis_naif.txt"))
-    assert naif["NaifKeywords"]["INS-143400_LIGHTTIME_CORRECTION"] == "LT+S"
+        naif = pvl.load(os.path.join(DATA_DIR, "isis_naif.txt"), grammar=g)
+        assert naif["NaifKeywords"]["INS-143400_LIGHTTIME_CORRECTION"] == "LT+S"
+
+        aleish = pvl.load(os.path.join(DATA_DIR, "isis_octothorpe.txt"), grammar=g)
+        assert aleish["Radiometry"]["NumberOfOverclocks"] == 2
 
 
 def test_cube_label():