pvl package¶
Submodules¶
pvl.collections module¶
Parameter Value Language container datatypes providing enhancements to Python general purpose built-in containers.
To enable efficient operations on parsed PVL text, we need an object that acts as both a dict-like Mapping container and a list-like Sequence container, essentially an ordered multi-dict. There is no existing object or even an Abstract Base Class in the Python Standard Library for such an object. So we define the MutableMappingSequence ABC here, which is (as the name implies) an abstract base class that implements both the Python MutableMapping and Mutable Sequence ABCs. We also provide two implementations, the OrderedMultiDict, and the newer PVLMultiDict.
Additionally, for PVL Values which also have an associated PVL Units Expression, they need to be returned as a quantity object which contains both a notion of a value and the units for that value. Again, there is no fundamental Python type for a quantity, so we define the Quantity class (formerly the Units class).
-
class
pvl.collections.
ItemsView
(mapping)[source]¶ Bases:
pvl.collections.MappingView
-
class
pvl.collections.
KeysView
(mapping)[source]¶ Bases:
pvl.collections.MappingView
-
class
pvl.collections.
MutableMappingSequence
[source]¶ Bases:
collections.abc.MutableMapping
,collections.abc.MutableSequence
ABC for a mutable object that has both mapping and sequence characteristics.
Must implement .getall(k) and .popall(k) since a MutableMappingSequence can have many values for a single key, while .get(k) and .pop(k) return and operate on a single value, the all versions return and operate on all values in the MutableMappingSequence with the key k.
Furthermore, .pop() without an argument should function as the MutableSequence pop() function and pop the last value when considering the MutableMappingSequence in a list-like manner.
-
class
pvl.collections.
OrderedMultiDict
(*args, **kwargs)[source]¶ Bases:
dict
,pvl.collections.MutableMappingSequence
A
dict
like container.This container preserves the original ordering as well as allows multiple values for the same key. It provides similar semantics to a
list
oftuples
but withdict
style access.Using
__setitem__
syntax overwrites all fields with the same key and__getitem__
will return the first value with the key.-
append
(key, value)[source]¶ Adds a (name, value) pair, doesn’t overwrite the value if it already exists.
-
get
(k[, d]) → D[k] if k in D, else d. d defaults to None.¶
-
getall
(key) → collections.abc.Sequence[source]¶ Returns a list of all the values for a named field. Returns KeyError if the key doesn’t exist.
-
getlist
(key) → collections.abc.Sequence[source]¶ Returns a list of all the values for the named field. Returns an empty list if the key doesn’t exist.
-
insert
(index: int, *args) → None[source]¶ Inserts at the index given by index.
The first positional argument will always be taken as the index for insertion.
If three arguments are given, the second will be taken as the key, and the third as the value to insert.
If only two arguments are given, the second must be a sequence.
If it is a sequence of pairs (such that every item in the sequence is itself a sequence of length two), that sequence will be inserted as key, value pairs.
If it happens to be a sequence of two items (the first of which is not a sequence), the first will be taken as the key and the second the value to insert.
-
insert_after
(key, new_item: collections.abc.Iterable, instance=0)[source]¶ Insert an item after a key
-
insert_before
(key, new_item: collections.abc.Iterable, instance=0)[source]¶ Insert an item before a key
-
key_index
(key, instance: int = 0) → int[source]¶ Get the index of the key to insert before or after.
-
popall
(key, default=<object object>)¶ D.pop(k[,d]) -> v, remove specified key and return the corresponding value. If key is not found, d is returned if given, otherwise KeyError is raised.
-
popitem
() → (k, v), remove and return some (key, value) pair as a[source]¶ 2-tuple; but raise KeyError if D is empty.
-
update
([E, ]**F) → None. Update D from mapping/iterable E and F.¶ If E present and has a .keys() method, does: for k in E: D[k] = E[k] If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v In either case, this is followed by: for k, v in F.items(): D[k] = v
-
-
class
pvl.collections.
Quantity
[source]¶ Bases:
pvl.collections.Quantity
A simple collections.namedtuple object to contain a value and units parameter.
If you need more comprehensive units handling, you may want to use the astropy.units.Quantity object, the pint.Quantity object, or some other 3rd party object. Please see the documentation on Quantities: Values and Units for how to use 3rd party Quantity objects with pvl.
-
class
pvl.collections.
Units
[source]¶ Bases:
pvl.collections.Quantity
-
class
pvl.collections.
ValuesView
(mapping)[source]¶ Bases:
pvl.collections.MappingView
-
pvl.collections.
dict_delitem
¶ Delete self[key].
-
pvl.collections.
dict_setitem
¶ Set self[key] to value.
pvl.decoder module¶
Parameter Value Language decoder.
The definition of PVL used in this module is based on the Consultive Committee for Space Data Systems, and their Parameter Value Language Specification (CCSD0006 and CCSD0008), CCSDS 6441.0-B-2, referred to as the Blue Book with a date of June 2000.
A decoder deals with converting strings given to it (typically by the parser) to the appropriate Python type.
-
class
pvl.decoder.
ODLDecoder
(grammar=None, quantity_cls=None, real_cls=None)[source]¶ Bases:
pvl.decoder.PVLDecoder
A decoder based on the rules in the PDS3 Standards Reference (version 3.8, 27 Feb 2009) Chapter 12: Object Description Language Specification and Usage.
Extends PVLDecoder, and if grammar is not specified, it will default to an ODLGrammar() object.
-
decode_datetime
(value: str)[source]¶ Extends parent function to also deal with datetimes and times with a time zone offset.
If it cannot, it will raise a ValueError.
-
decode_non_decimal
(value: str) → int[source]¶ Extends parent function by allowing the wider variety of radix values that ODL permits over PVL.
-
decode_quoted_string
(value: str) → str[source]¶ Extends parent function because the ODL specification allows for a dash (-) line continuation character that results in the dash, the line end, and any leading whitespace on the next line to be removed. It also allows for a sequence of format effectors surrounded by spacing characters to be collapsed to a single space.
-
-
class
pvl.decoder.
OmniDecoder
(grammar=None, quantity_cls=None, real_cls=None)[source]¶ Bases:
pvl.decoder.ODLDecoder
A permissive decoder that attempts to parse all forms of “PVL” that are thrown at it.
Extends ODLDecoder.
-
decode_datetime
(value: str)[source]¶ Returns an appropriate Python datetime time, date, or datetime object by using the 3rd party dateutil library (if present) to parse an ISO 8601 datetime string in value. If it cannot, or the dateutil library is not present, it will raise a ValueError.
-
-
class
pvl.decoder.
PDSLabelDecoder
(grammar=None, quantity_cls=None)[source]¶ Bases:
pvl.decoder.ODLDecoder
A decoder based on the rules in the PDS3 Standards Reference (version 3.8, 27 Feb 2009) Chapter 12: Object Description Language Specification and Usage.
Extends ODLDecoder, and if grammar is not specified, it will default to a PDS3Grammar() object.
-
class
pvl.decoder.
PVLDecoder
(grammar=None, quantity_cls=None, real_cls=None)[source]¶ Bases:
object
A decoder based on the rules in the CCSDS-641.0-B-2 ‘Blue Book’ which defines the PVL language.
Parameters: - grammar – defaults to a
pvl.grammar.PVLGrammar
, but can be any object that implements thepvl.grammar
interface. - quantity_cls – defaults to
pvl.collections.Quantity
, but could be any class object that takes two arguments, where the first is the value, and the second is the units value. - real_cls – defaults to
float
, but could be any class object that can be constructed from a str object.
-
decode_datetime
(value: str)[source]¶ Takes a string and attempts to convert it to the appropriate Python
datetime
time
,date
, ordatetime
type based on this decoder’s grammar, or in one case, astr
.The PVL standard allows for the seconds value to range from zero to 60, so that the 60 can accommodate leap seconds. However, the Python
datetime
classes don’t support second values for more than 59 seconds.If a time with 60 seconds is encountered, it will not be returned as a datetime object (since that is not representable via Python datetime objects), but simply as a string.
The user can then then try and use the
time
module to parse this string into atime.struct_time
. We chose not to do this with pvl becausetime.struct_time
is a full datetime like object, even if it parsed only a time like object, the year, month, and day values in thetime.struct_time
would default, which could be misleading.Alternately, the pvl.grammar.PVLGrammar class contains two regexes:
leap_second_Ymd_re
andleap_second_Yj_re
which could be used along with there.match
object’sgroupdict()
function to extract the string representations of the various numerical values, cast them to the appropriate numerical types, and do something useful with them.
-
decode_decimal
(value: str)[source]¶ Returns a Python
int
orself.real_cls
object, as appropriate based on value. Raises a ValueError otherwise.
-
decode_non_decimal
(value: str) → int[source]¶ Returns a Python
int
as decoded from value on the assumption that value conforms to a non-decimal integer value as defined by this decoder’s grammar, raises ValueError otherwise.
-
decode_quantity
(value, unit)[source]¶ Returns a Python object that represents a value with an associated unit, based on the values provided via value and unit. This function creates an object based on the decoder’s quantity_cls.
-
decode_quoted_string
(value: str) → str[source]¶ Returns a Python
str
if value begins and ends with matching quote characters based on this decoder’s grammar. Raises ValueError otherwise.
-
decode_simple_value
(value: str)[source]¶ Returns a Python object based on value, assuming that value can be decoded as a PVL Simple Value:
<Simple-Value> ::= (<Date-Time> | <Numeric> | <String>)
- grammar – defaults to a
-
pvl.decoder.
for_try_except
(exception, function, *iterable)[source]¶ Return the result of the first successful application of function to an element of iterable. If the function raises an Exception of type exception, it will continue to the next item of iterable. If there are no successful applications an Exception of type exception will be raised.
If additional iterable arguments are passed, function must take that many arguments and is applied to the items from all iterables in parallel (like
map()
). With multiple iterables, the iterator stops when the shortest iterable is exhausted.
pvl.encoder module¶
Parameter Value Langage encoder.
An encoder deals with converting Python objects into string values that conform to a PVL specification.
-
class
pvl.encoder.
ISISEncoder
(grammar=None, decoder=None, indent=2, width=80, aggregation_end=True, end_delimiter=False, newline='n', group_class=<class 'pvl.collections.PVLGroup'>, object_class=<class 'pvl.collections.PVLObject'>)[source]¶ Bases:
pvl.encoder.PVLEncoder
An encoder for writing PVL text that can be parsed by the ISIS PVL text parser.
The ISIS3 implementation (as of 3.9) of PVL/ODL (like) does not strictly follow any of the published standards. It was based on PDS3 ODL from the 1990s, but has several extensions adopted from existing and prior data sets from ISIS2, PDS, JAXA, ISRO, …, and extensions used only within ISIS files (cub, net). This is one of the reasons using ISIS cube files or PVL text written by ISIS as an archive format has been strongly discouraged.
Since there is no specification, only a detailed analysis of the ISIS software that parses and writes its PVL text would yield a strategy for parsing it. This encoder is most likely the least reliable for that reason. We welcome bug reports to help extend our coverage of this flavor of PVL text.
Parameters: - grammar – defaults to pvl.grammar.ISISGrammar().
- decoder – defaults to pvl.decoder.PVLDecoder().
- end_delimiter – defaults to False.
- newline – defaults to ‘\n’.
-
class
pvl.encoder.
ODLEncoder
(grammar=None, decoder=None, indent=2, width=80, aggregation_end=True, end_delimiter=False, newline='rn', group_class=<class 'pvl.collections.PVLGroup'>, object_class=<class 'pvl.collections.PVLObject'>)[source]¶ Bases:
pvl.encoder.PVLEncoder
An encoder based on the rules in the PDS3 Standards Reference (version 3.8, 27 Feb 2009) Chapter 12: Object Description Language Specification and Usage for ODL only. This is almost certainly not what you want. There are very rarely cases where you’d want to use ODL that you wouldn’t also want to use the PDS Label restrictions, so you probably really want the PDSLabelEncoder class, not this one. Move along.
It extends PVLEncoder.
Parameters: - grammar – defaults to pvl.grammar.ODLGrammar().
- decoder – defaults to pvl.decoder.ODLDecoder().
- end_delimiter – defaults to False.
- newline – defaults to ‘\r\n’.
-
encode
(module: collections.abc.Mapping) → str[source]¶ Extends parent function, but ODL requires that there must be a spacing or format character after the END statement and this adds the encoder’s
newline
sequence.
-
encode_assignment
(key, value, level=0, key_len=None) → str[source]¶ Overrides parent function by restricting the length of keywords and enforcing that they be ODL Identifiers and uppercasing their characters.
-
encode_sequence
(value) → str[source]¶ Extends parent function, as ODL only allows one- and two-dimensional sequences of ODL scalar_values.
-
encode_set
(values) → str[source]¶ Extends parent function, ODL only allows sets to contain scalar values.
-
encode_time
(value: datetime.time) → str[source]¶ Extends parent function since ODL allows a time zone offset from UTC to be included, and otherwise recommends that times be suffixed with a ‘Z’ to clearly indicate that they are in UTC.
-
encode_units
(value) → str[source]¶ Overrides parent function since ODL limits what characters and operators can be present in Units Expressions.
-
encode_value
(value)[source]¶ Extends parent function by only allowing Units Expressions for numeric values.
-
is_assignment_statement
(s) → bool[source]¶ Returns true if s is an ODL Assignment Statement, false otherwise.
An ODL Assignment Statement is either an element_identifier or a namespace_identifier joined to an element_identifier with a colon.
-
is_scalar
(value) → bool[source]¶ Returns a boolean indicating whether the value object qualifies as an ODL ‘scalar_value’.
ODL defines a ‘scalar-value’ as a numeric_value, a date_time_string, a text_string_value, or a symbol_value.
For Python, these correspond to the following:
- numeric_value: any of self.numeric_types, and Quantity whose value is one of the self.numeric_types.
- date_time_string: datetime objects
- text_string_value: str
- symbol_value: str
-
is_symbol
(value) → bool[source]¶ Returns true if value is an ODL Symbol String, false otherwise.
An ODL Symbol String is enclosed by single quotes and may not contain any of the following characters:
- The apostrophe, which is reserved as the symbol string delimiter.
- ODL Format Effectors
- Control characters
This means that an ODL Symbol String is a subset of the PVL quoted string, and will be represented in Python as a
str
.
-
class
pvl.encoder.
PDSLabelEncoder
(grammar=None, decoder=None, indent=2, width=80, aggregation_end=True, group_class=<class 'pvl.collections.PVLGroup'>, object_class=<class 'pvl.collections.PVLObject'>, convert_group_to_object=True, tab_replace=4, symbol_single_quote=True, time_trailing_z=True)[source]¶ Bases:
pvl.encoder.ODLEncoder
An encoder based on the rules in the PDS3 Standards Reference (version 3.8, 27 Feb 2009) Chapter 12: Object Description Language Specification and Usage and writes out labels that conform to the PDS 3 standards.
It extends ODLEncoder.
You are not allowed to chose end_delimiter or newline as the parent class allows, because to be PDS-compliant, those are fixed choices. However, in some cases, the PDS3 Standards are asymmetric, allowing for a wider variety of PVL-text on “read” and a more narrow variety of PVL-text on “write”. The default values of the PDSLabelEncoder enforce those strict “write” rules, but if you wish to alter them, but still produce PVL-text that would validate against the PDS3 standard, you may alter them.
Parameters: - convert_group_to_object – Defaults to True, meaning that if a GROUP does not conform to the PDS definition of a GROUP, then it will be written out as an OBJECT. If it is False, then an exception will be thrown if incompatible GROUPs are encountered. In PVL and ODL, the OBJECT and GROUP aggregations are interchangeable, but the PDS applies restrictions to what can appear in a GROUP.
- tab_replace – Defaults to 4 and indicates the number of space characters to replace horizontal tab characters with (since tabs aren’t allowed in PDS labels). If this is set to zero, tabs will not be replaced with spaces.
- symbol_single_quotes – Defaults to True, and if a Python str object qualifies as a PVL Symbol String, it will be written to PVL-text as a single-quoted string. If False, no special handling is done, and any PVL Symbol String will be treated as a PVL Text String, which is typically enclosed with double-quotes.
- time_trailing_z – defaults to True, and suffixes a “Z” to datetimes and times written to PVL-text as the PDS encoding standard requires. If False, no trailing “Z” is written.
-
count_aggs
(module: collections.abc.Mapping, obj_count: int = 0, grp_count: int = 0) -> (<class 'int'>, <class 'int'>)[source]¶ Returns the count of OBJECT and GROUP aggregations that are contained within the module as a two-tuple in that order.
-
encode
(module: collections.abc.MutableMapping) → str[source]¶ Extends the parent function, by adding a restriction. For PDS, if there are any GROUP elements, there must be at least one OBJECT element in the label. Behavior here depends on the value of this encoder’s convert_group_to_object property.
-
encode_aggregation_block
(key, value, level=0)[source]¶ Extends parent function because PDS has restrictions on what may be in a GROUP.
If the encoder’s convert_group_to_object parameter is True, and a GROUP does not conform to the PDS definition of a GROUP, then it will be written out as an OBJECT. If it is False, then an exception will be thrown.
-
encode_set
(values) → str[source]¶ Extends parent function because PDS only allows symbol values and integers within sets.
-
encode_string
(value)[source]¶ Extends parent function to treat Symbol Strings as Text Strings, which typically means that they are double-quoted and not single-quoted.
-
encode_time
(value: datetime.time) → str[source]¶ Overrides parent’s encode_time() function because even though ODL allows for timezones, PDS does not.
Not in the section on times, but at the end of the PDS ODL document, in section 12.7.3, para 14, it indicates that alternate time zones may not be used in a PDS label, only these: 1. YYYY-MM-DDTHH:MM:SS.SSS. 2. YYYY-DDDTHH:MM:SS.SSS.
-
is_PDSgroup
(group: collections.abc.Mapping) → bool[source]¶ Returns true if the dict-like group qualifies as a PDS Group, false otherwise.
PDS applies the following restrictions to GROUPS:
- The GROUP structure may only be used in a data product label which also contains one or more data OBJECT definitions.
- The GROUP statement must contain only attribute assignment statements, include pointers, or related information pointers (i.e., no data location pointers). If there are multiple values, a single statement must be used with either sequence or set syntax; no attribute assignment statement or pointer may be repeated.
- GROUP statements may not be nested.
- GROUP statements may not contain OBJECT definitions.
- Only PSDD elements may appear within a GROUP statement. PSDD is not defined anywhere in the PDS document, so don’t know how to test for it.
- The keyword contents associated with a specific GROUP identifier must be identical across all labels of a single data set (with the exception of the “PARAMETERS” GROUP, as explained).
Use of the GROUP structure must be coordinated with the responsible PDS discipline Node.
Items 1 & 6 and the final sentence above, can’t really be tested by examining a single group, but must be dealt with in a larger context. The ODLEncoder.encode_module() handles #1, at least. You’re on your own for the other two issues.
Item 5: PSDD is not defined anywhere in the ODL PDS document, so don’t know how to test for it.
-
class
pvl.encoder.
PVLEncoder
(grammar=None, decoder=None, indent: int = 2, width: int = 80, aggregation_end: bool = True, end_delimiter: bool = True, newline: str = 'n', group_class=<class 'pvl.collections.PVLGroup'>, object_class=<class 'pvl.collections.PVLObject'>)[source]¶ Bases:
object
An encoder based on the rules in the CCSDS-641.0-B-2 ‘Blue Book’ which defines the PVL language.
Parameters: - grammar – A pvl.grammar object, if None or not specified, it will be set to the grammar parameter of decoder (if decoder is not None) or will default to PVLGrammar().
- grammar – defaults to pvl.grammar.PVLGrammar().
- decoder – defaults to pvl.decoder.PVLDecoder().
- indent – specifies the number of spaces that will be used to indent each level of the PVL document, when Groups or Objects are encountered, defaults to 2.
- width – specifies the number of characters in width that each line should have, defaults to 80.
- aggregation_end – when True the encoder will print the value of the aggregation’s Block Name in the End Aggregation Statement (e.g. END_GROUP = foo), and when false, it won’t (e.g. END_GROUP). Defaults to True.
- end_delimiter – when True the encoder will print the grammar’s delimiter (e.g. ‘;’ for PVL) after each statement, when False it won’t. Defaults to True.
- newline – is the string that will be placed at the end of each ‘line’ of output (and counts against width), defaults to ‘\n’.
- group_class – must this class will be tested against with isinstance() to determine if various elements of the dict-like passed to encode() should be encoded as a PVL Group or PVL Object, defaults to PVLGroup.
- object_class – must be a class that can take a group_class object in its constructor (essentially converting a group_class to an object_class), otherwise will raise TypeError. Defaults to PVLObject.
-
add_quantity_cls
(cls, value_prop: str, units_prop: str)[source]¶ Adds a quantity class to the list of possible quantities that this encoder can handle.
Parameters: - cls – The name of a quantity class that can be tested
with
isinstance()
. - value_prop – A string that is the property name of cls that contains the value or magnitude of the quantity object.
- units_prop – A string that is the property name of cls that contains the units element of the quantity object.
- cls – The name of a quantity class that can be tested
with
-
encode
(module: collections.abc.Mapping) → str[source]¶ Returns a
str
formatted as a PVL document based on the dict-like module object according to the rules of this encoder.
-
encode_aggregation_block
(key: str, value: collections.abc.Mapping, level: int = 0) → str[source]¶ Returns a
str
formatted as a PVL Aggregation Block with key as its name, and its contents based on the dict-like value object according to the rules of this encoder, with an indentation level of level.
-
encode_assignment
(key: str, value, level: int = 0, key_len: int = None) → str[source]¶ Returns a
str
formatted as a PVL Assignment Statement with key as its Parameter Name, and its value based on value object according to the rules of this encoder, with an indentation level of level. It also allows for an optional key_len which indicates the width in characters that the Assignment Statement should be set to, defaults to the width of key.
-
static
encode_date
(value: datetime.date) → str[source]¶ Returns a
str
formatted as a PVL Date based on the value object according to the rules of this encoder.
-
encode_datetime
(value: datetime.datetime) → str[source]¶ Returns a
str
formatted as a PVL Date/Time based on the value object according to the rules of this encoder.
-
encode_datetype
(value) → str[source]¶ Returns a
str
formatted as a PVL Date/Time based on the value object according to the rules of this encoder. If value is not a datetime date, time, or datetime object, it will raise TypeError.
-
encode_module
(module: collections.abc.Mapping, level: int = 0) → str[source]¶ Returns a
str
formatted as a PVL module based on the dict-like module object according to the rules of this encoder, with an indentation level of level.
-
encode_quantity
(value) → str[source]¶ Returns a
str
formatted as a PVL Value followed by a PVL Units Expression if the value object can be encoded this way, otherwise raise ValueError.
-
encode_sequence
(value: collections.abc.Sequence) → str[source]¶ Returns a
str
formatted as a PVL Sequence based on the value object according to the rules of this encoder.
-
encode_set
(value: collections.abc.Set) → str[source]¶ Returns a
str
formatted as a PVL Set based on the value object according to the rules of this encoder.
-
encode_setseq
(values: collections.abc.Collection) → str[source]¶ This function provides shared functionality for encode_sequence() and encode_set().
-
encode_simple_value
(value) → str[source]¶ Returns a
str
formatted as a PVL Simple Value based on the value object according to the rules of this encoder.
-
encode_string
(value) → str[source]¶ Returns a
str
formatted as a PVL String based on the value object according to the rules of this encoder.
-
static
encode_time
(value: datetime.time) → str[source]¶ Returns a
str
formatted as a PVL Time based on the value object according to the rules of this encoder.
-
encode_units
(value: str) → str[source]¶ Returns a
str
formatted as a PVL Units Value based on the value object according to the rules of this encoder.
-
encode_value
(value) → str[source]¶ Returns a
str
formatted as a PVL Value based on the value object according to the rules of this encoder.
-
encode_value_units
(value, units) → str[source]¶ Returns a
str
formatted as a PVL Value from value followed by a PVL Units Expressions from units.
-
class
pvl.encoder.
QuantTup
[source]¶ Bases:
pvl.encoder.QuantTup
This class is just a convenient namedtuple for internally keeping track of quantity classes that encoders can deal with. In general, users should not be instantiating this, instead use your encoder’s add_quantity_cls() function.
pvl.exceptions module¶
Exceptions for the Parameter Value Library.
-
exception
pvl.exceptions.
LexerError
(msg, doc, pos, lexeme)[source]¶ Bases:
ValueError
Subclass of ValueError with the following additional properties:
msg: The unformatted error message doc: The PVL text being parsed pos: The start index in doc where parsing failed lineno: The line corresponding to pos colno: The column corresponding to pos
-
exception
pvl.exceptions.
ParseError
(msg, token=None)[source]¶ Bases:
Exception
An exception to signal errors in the pvl parser.
-
exception
pvl.exceptions.
QuantityError
[source]¶ Bases:
Exception
A simple exception to distinguish errors from Quantity classes.
-
pvl.exceptions.
firstpos
(sub: str, pos: int)[source]¶ On the assumption that sub is a substring contained in a longer string, and pos is the index in that longer string of the final character in sub, returns the position of the first character of sub in that longer string.
This is useful in the PVL library when we know the position of the final character of a token, but want the position of the first character.
pvl.grammar module¶
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.
-
class
pvl.grammar.
ISISGrammar
[source]¶ Bases:
pvl.grammar.PVLGrammar
This defines the ISIS version of PVL.
This is valid as of ISIS 3.9, and before, at least.
The ISIS ‘Pvl’ object typically writes out parameter values and keywords in CamelCase (e.g. ‘Group’, ‘End_Group’, ‘CenterLatitude’, etc.), but it will accept all-uppercase versions.
Technically, since the ISIS ‘Pvl’ object which parses PVL text into C++ objects for ISIS programs to work with does not recognize the ‘BEGIN_<GROUP|OBJECT>’ construction, this means that ISIS does not parse PVL text that would be valid according to the PVL, ODL, or PDS3 specs.
-
comments
= (('/*', '*/'), ('#', '\n'))¶
-
group_keywords
= {'GROUP': 'END_GROUP'}¶
-
group_pref_keywords
= ('Group', 'End_Group')¶
-
object_keywords
= {'OBJECT': 'END_OBJECT'}¶
-
object_pref_keywords
= ('Object', 'End_Object')¶
-
-
class
pvl.grammar.
ODLGrammar
[source]¶ Bases:
pvl.grammar.PVLGrammar
This defines an ODL grammar.
The reference for this grammar is the PDS3 Standards Reference (version 3.8, 27 Feb 2009) Chapter 12: Object Description Language Specification and Usage.
-
char_allowed
(char)[source]¶ Returns true if char is allowed in the ODL Character Set.
The ODL Character Set is limited to ASCII. This is fewer characters than PVL, but appears to allow more control characters to be in quoted strings than PVL does.
-
default_timezone
= None¶
-
group_pref_keywords
= ('GROUP', 'END_GROUP')¶
-
leap_second_Yj_re
= None¶
-
leap_second_Ymd_re
= None¶
-
nondecimal_pre_re
= re.compile('(?P<radix>[2-9]|1[0-6])#(?P<sign>[+-]?)')¶
-
nondecimal_re
= re.compile('(?P<radix>[2-9]|1[0-6])#(?P<sign>[+-]?)(?P<non_decimal>[0-9A-Fa-f]+)#')¶
-
object_pref_keywords
= ('OBJECT', 'END_OBJECT')¶
-
-
class
pvl.grammar.
OmniGrammar
[source]¶ Bases:
pvl.grammar.PVLGrammar
A broadly permissive grammar.
This grammar does not follow a specification, but is meant to allow the broadest possible ingestion of PVL-like text that is found.
This grammar should not be used to write out Python objects to PVL, instead please use one of the grammars that follows a published specification, like the PVLGrammar or the ODLGrammar.
-
char_allowed
(char)[source]¶ Takes all characters, could accept bad things, and the user must beware.
-
comments
= (('/*', '*/'), ('#', '\n'))¶
-
nondecimal_pre_re
= re.compile('(?P<sign>[+-]?)(?P<radix>[2-9]|1[0-6])#(?P<second_sign>[+-]?)')¶
-
nondecimal_re
= re.compile('(?P<sign>[+-]?)(?P<radix>[2-9]|1[0-6])#(?P<second_sign>[+-]?)(?P<non_decimal>[0-9A-Fa-f]+)#')¶
-
-
class
pvl.grammar.
PDSGrammar
[source]¶ Bases:
pvl.grammar.ODLGrammar
This defines a PDS3 ODL grammar.
The reference for this grammar is the PDS3 Standards Reference (version 3.8, 27 Feb 2009) Chapter 12: Object Description Language Specification and Usage.
-
default_timezone
= datetime.timezone.utc¶
-
-
class
pvl.grammar.
PVLGrammar
[source]¶ Bases:
object
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’.
-
aggregation_keywords
= {'BEGIN_GROUP': 'END_GROUP', 'BEGIN_OBJECT': 'END_OBJECT', 'GROUP': 'END_GROUP', 'OBJECT': 'END_OBJECT'}¶
-
binary_re
= re.compile('(?P<sign>[+-]?)(?P<radix>2)#(?P<non_decimal>[01]+)#')¶
-
char_allowed
(char)[source]¶ Returns true if char is allowed in the PVL Character Set.
This is defined as most of the ISO 8859-1 ‘latin-1’ character set with some exclusions.
-
comments
= (('/*', '*/'),)¶
-
d
= '%Y-%j'¶
-
date_formats
= ('%Y-%m-%d', '%Y-%j', '%Y-%m-%dZ', '%Y-%jZ')¶
-
datetime_formats
= ['%Y-%m-%dT%H:%M', '%Y-%m-%dT%H:%MZ', '%Y-%m-%dT%H:%M:%S', '%Y-%m-%dT%H:%M:%SZ', '%Y-%m-%dT%H:%M:%S.%f', '%Y-%m-%dT%H:%M:%S.%fZ', '%Y-%jT%H:%M', '%Y-%jT%H:%MZ', '%Y-%jT%H:%M:%S', '%Y-%jT%H:%M:%SZ', '%Y-%jT%H:%M:%S.%f', '%Y-%jT%H:%M:%S.%fZ']¶
-
default_timezone
= datetime.timezone.utc¶
-
delimiters
= (';',)¶
-
end_statements
= ('END',)¶
-
false_keyword
= 'FALSE'¶
-
format_effectors
= ('\n', '\r', '\x0b', '\x0c')¶
-
group_keywords
= {'BEGIN_GROUP': 'END_GROUP', 'GROUP': 'END_GROUP'}¶
-
group_pref_keywords
= ('BEGIN_GROUP', 'END_GROUP')¶
-
hex_re
= re.compile('(?P<sign>[+-]?)(?P<radix>16)#(?P<non_decimal>[0-9A-Fa-f]+)#')¶
-
leap_second_Yj_re
= re.compile('((?P<year>\\d{3}[1-9])-(?P<doy>(00[1-9]|0[1-9]\\d)|[12]\\d{2}|3[0-5]\\d|36[0-6])T)?(?P<hour>0\\d|1\\d|2[0-3]):(?P<minute>[0-5]\\d):60(\\.(?P<microsecond>\\d+))?Z?')¶
-
leap_second_Ymd_re
= re.compile('((?P<year>\\d{3}[1-9])-(?P<month>0[1-9]|1[0-2])-(?P<day>0[1-9]|[12]\\d|3[01])T)?(?P<hour>0\\d|1\\d|2[0-3]):(?P<minute>[0-5]\\d):60(\\.(?P<microsecond>\\d+))?Z?')¶
-
nondecimal_pre_re
= re.compile('(?P<sign>[+-]?)(?P<radix>2|8|16)#')¶
-
nondecimal_re
= re.compile('(?P<sign>[+-]?)(?P<radix>2|8|16)#(?P<non_decimal>[0-9|A-Fa-f]+)#')¶
-
none_keyword
= 'NULL'¶
-
numeric_start_chars
= ('+', '-')¶
-
object_keywords
= {'BEGIN_OBJECT': 'END_OBJECT', 'OBJECT': 'END_OBJECT'}¶
-
object_pref_keywords
= ('BEGIN_OBJECT', 'END_OBJECT')¶
-
octal_re
= re.compile('(?P<sign>[+-]?)(?P<radix>8)#(?P<non_decimal>[0-7]+)#')¶
-
p
= ('BEGIN_OBJECT', 'END_OBJECT')¶
-
quotes
= ('"', "'")¶
-
reserved_characters
= ('&', '<', '>', "'", '{', '}', ',', '[', ']', '=', '!', '#', '(', ')', '%', '+', '"', ';', '~', '|')¶
-
reserved_keywords
= {'BEGIN_GROUP', 'BEGIN_OBJECT', 'END', 'END_GROUP', 'END_OBJECT', 'GROUP', 'OBJECT'}¶
-
sequence_delimiters
= ('(', ')')¶
-
set_delimiters
= ('{', '}')¶
-
spacing_characters
= (' ', '\t')¶
-
t
= '%H:%M:%S.%f'¶
-
time_formats
= ('%H:%M', '%H:%M:%S', '%H:%M:%S.%f', '%H:%MZ', '%H:%M:%SZ', '%H:%M:%S.%fZ')¶
-
true_keyword
= 'TRUE'¶
-
units_delimiters
= ('<', '>')¶
-
whitespace
= (' ', '\t', '\n', '\r', '\x0b', '\x0c')¶
-
pvl.lexer module¶
Provides lexer functions for PVL.
-
class
pvl.lexer.
Preserve
[source]¶ Bases:
enum.Enum
An enumeration.
-
COMMENT
= 2¶
-
FALSE
= 1¶
-
NONDECIMAL
= 5¶
-
QUOTE
= 4¶
-
UNIT
= 3¶
-
-
pvl.lexer.
lex_char
(char: str, prev_char: str, next_char: str, lexeme: str, preserve: dict, g: pvl.grammar.PVLGrammar, c_info: dict) -> (<class 'str'>, <class 'dict'>)[source]¶ Returns a modified lexeme string and a modified preserve dict in a two-tuple.
This is the main lexer() helper function for determining how to modify (or not) lexeme and preserve based on the single character in char and the other values passed into this function.
-
pvl.lexer.
lex_comment
(char: str, prev_char: str, next_char: str, lexeme: str, preserve: dict, c_info: dict) -> (<class 'str'>, <class 'dict'>)[source]¶ Returns a modified lexeme string and a modified preserve dict in a two-tuple.
This is a lexer() helper function for determining how to modify lexeme and preserve based on the single character in char which may or may not be a comment character.
This function just makes the decision about whether to call lex_multichar_comments() or lex_singlechar_comments(), and then returns what they return.
-
pvl.lexer.
lex_continue
(char: str, next_char: str, lexeme: str, token: pvl.token.Token, preserve: dict, g: pvl.grammar.PVLGrammar) → bool[source]¶ Return True if accumulation of lexeme should continue based on the values passed into this function, false otherwise.
This is a lexer() helper function.
-
pvl.lexer.
lex_multichar_comments
(char: str, prev_char: str, next_char: str, lexeme: str, preserve: dict, comments: (<class 'str'>, <class 'str'>) = (('/*', '*/'), )) -> (<class 'str'>, <class 'dict'>)[source]¶ Returns a modified lexeme string and a modified preserve dict in a two-tuple.
This is a lexer() helper function for determining how to modify lexeme and preserve based on the single character in char which may or may not be part of a multi-character comment character group.
This function has an internal list of allowed pairs of multi-character comments that it can deal with, if the comments tuple contains any two-tuples that cannot be handled, a NotImplementedError will be raised.
This function will determine whether to append char to lexeme or not, and will set the value of the ‘state’ and ‘end’ values of preserve appropriately.
-
pvl.lexer.
lex_preserve
(char: str, lexeme: str, preserve: dict) -> (<class 'str'>, <class 'dict'>)[source]¶ Returns a modified lexeme string and a modified preserve dict in a two-tuple. The modified lexeme will always be the concatenation of lexeme and char.
This is a lexer() helper function that is responsible for changing the state of the preserve dict, if needed.
If the value for ‘end’ in preserve is the same as char, then the modified preserve will have its ‘state’ value set to
Preserve.FALSE
and its ‘end’ value set to None, otherwise second item in the returned tuple will be preserve unchanged.
-
pvl.lexer.
lex_singlechar_comments
(char: str, lexeme: str, preserve: dict, comments: dict) -> (<class 'str'>, <class 'dict'>)[source]¶ Returns a modified lexeme string and a modified preserve dict in a two-tuple.
This is a lexer() helper function for determining how to modify lexeme and preserve based on the single character in char which may or may not be a comment character.
If the preserve ‘state’ value is Preserve.COMMENT then the value of lex_preserve() is returned.
If char is among the keys of the comments dict, then the returned lexeme will be the concatenation of lexeme and char. returned preserve dict will have its ‘state’ value set to Preserve.COMMENT and its ‘end’ value set to the value of comments[char].
Otherwise return lexeme and preserve unchanged in the two-tuple.
-
pvl.lexer.
lexer
(s: str, g=<pvl.grammar.PVLGrammar object>, d=<pvl.decoder.PVLDecoder object>)[source]¶ This is a generator function that returns pvl.Token objects based on the passed in string, s, when the generator’s next() is called.
A call to send(t) will ‘return’ the value t to the generator, which will be yielded upon calling next(). This allows a user to ‘peek’ at the next token, but return it if they don’t like what they see.
g is expected to be an instance of pvl.grammar, and d an instance of pvl.decoder. The lexer will perform differently, given different values of g and d.
pvl.new module¶
pvl.parser module¶
Parameter Value Language parser.
The definition of PVL used in this module is based on the Consultive Committee for Space Data Systems, and their Parameter Value Language Specification (CCSD0006 and CCSD0008), CCSDS 6441.0-B-2, referred to as the Blue Book with a date of June 2000.
Some of the documention in this module represents the structure diagrams from the Blue Book for parsing PVL in a Backus–Naur form.
So Figure 1-1 from the Blue Book would be represented as :
<Item-A> ::= ( [ <Item-B>+ | <Item-C> ] <Item-D> )*
Finally, the Blue Book defines <WSC> as a possibly empty collection of white space characters or comments:
<WSC> ::= ( <white-space-character> | <comment> )*
However, to help remember that <WSC> could be empty, we will typically always show it as <WSC>*.
Likewise the <Statement-Delimiter> is defined as:
<Statement-Delimiter> ::= <WSC>* [ ‘;’ | <EOF> ]
However, since all elements are optional, we will typically show it as [<Statement-Delimiter>].
The parser deals with managing the tokens that come out of the lexer. Once the parser gets to a state where it has something that needs to be converted to a Python object and returned, it uses the decoder to make that conversion.
Throughout this module, various parser functions will take a tokens:
collections.abc.Generator parameter. In all cases, tokens is
expected to be a generator iterator which provides pvl.token.Token
objects. It should allow for a generated object to be ‘returned’
via the generator’s send() function. When parsing the first object
from tokens, if an unexpected object is encountered, it will
‘return’ the object to tokens, and raise a ValueError
, so
that try
-except
blocks can be used, and the generator
iterator is left in a good state. However, if a parsing anomaly
is discovered deeper in parsing a PVL sequence, then a ValueError
will be thrown into the tokens generator iterator (via .throw()).
-
class
pvl.parser.
EmptyValueAtLine
[source]¶ Bases:
str
Empty string to be used as a placeholder for a parameter without a value.
When a label contains a parameter without a value, it is normally considered a broken label in PVL. To allow parsing to continue, we can rectify the broken parameter-value pair by setting the value to have a value of EmptyValueAtLine, which is an empty string (and can be treated as such) with some additional properties.
The argument lineno should be the line number of the error from the original document, which will be available as a property.
- Examples::
>>> from pvl.parser import EmptyValueAtLine >>> EV1 = EmptyValueAtLine(1) >>> EV1 EmptyValueAtLine(1 does not have a value. Treat as an empty string) >>> EV1.lineno 1 >>> print(EV1) <BLANKLINE>
>>> EV1 + 'foo' 'foo' >>> # Can be turned into an integer and float as 0: >>> int(EV1) 0 >>> float(EV1) 0.0
-
class
pvl.parser.
ODLParser
(grammar=None, decoder=None, lexer_fn=None, module_class=<class 'pvl.collections.PVLModule'>, group_class=<class 'pvl.collections.PVLGroup'>, object_class=<class 'pvl.collections.PVLObject'>)[source]¶ Bases:
pvl.parser.PVLParser
A parser based on the rules in the PDS3 Standards Reference (version 3.8, 27 Feb 2009) Chapter 12: Object Description Language Specification and Usage.
It extends PVLParser.
-
parse_set
(tokens: collections.abc.Generator) → set[source]¶ Overrides the parent function to return the decoded <Set> as a Python
set
.The ODL specification only allows scalar_values in Sets, since ODL Sets cannot contain other ODL Sets, an ODL Set can be represented as a Python
set
(unlike PVL Sets, which must be represented as a Pythonfrozenset
objects).
-
-
class
pvl.parser.
OmniParser
(grammar=None, decoder=None, lexer_fn=None, module_class=<class 'pvl.collections.PVLModule'>, group_class=<class 'pvl.collections.PVLGroup'>, object_class=<class 'pvl.collections.PVLObject'>)[source]¶ Bases:
pvl.parser.PVLParser
A permissive PVL/ODL/ISIS label parser that attempts to parse all forms of “PVL” that are thrown at it.
-
parse
(s: str)[source]¶ Extends the parent function.
If any line ends with a dash (-) followed by a carriage return, form-feed, or newline, plus one or more whitespace characters on the following line, then those characters, and all whitespace characters that begin the next line will be removed.
-
parse_assignment_statement
(tokens: collections.abc.Generator) → tuple[source]¶ Extends the parent function to allow for more permissive parsing. If an Assignment-Statement is blank, then the value will be assigned an EmptyValueAtLine object.
-
-
class
pvl.parser.
PVLParser
(grammar=None, decoder=None, lexer_fn=None, module_class=<class 'pvl.collections.PVLModule'>, group_class=<class 'pvl.collections.PVLGroup'>, object_class=<class 'pvl.collections.PVLObject'>)[source]¶ Bases:
object
A parser based on the rules in the CCSDS-641.0-B-2 ‘Blue Book’ which defines the PVL language.
Parameters: - grammar – A pvl.grammar object, if None or not specified, it will
be set to the grammar parameter of decoder (if
decoder is not None) or will default to
pvl.grammar.OmniGrammar()
. - decoder – defaults to
pvl.decoder.OmniDecoder()
. - lexer_fn – must be a lexer function that takes a
str
, a grammar, and a decoder, aspvl.lexer.lexer()
does, which is the default if none is given. - module_class – must be a subclass of PVLModule, and is the type
of object that will be returned from this parser’s
parse()
function. - group_class – must be a subclass of PVLGroup, and is the type
that will be used to hold PVL elements when a PVL Group is
encountered during parsing, and must be able to be added to
via an
.append()
function which should take a two-tuple of name and value. - object_class – must be a subclass of PVLObject, and is the type that will be used to hold PVL elements when a PVL Object is encountered during parsing, otherwise similar to group_class.
-
aggregation_cls
(begin: str)[source]¶ Returns an initiated object of the group_class or object_class as specified on this parser’s creation, according to the value of begin. If begin does not match the Group or Object keywords for this parser’s grammar, then it will raise a ValueError.
-
static
parse_WSC_until
(token: str, tokens: collections.abc.Generator) → bool[source]¶ Consumes objects from tokens, if the object’s .is_WSC() function returns True, it will continue until token is encountered and will return True. If it encounters an object that does not meet these conditions, it will ‘return’ that object to tokens and will return False.
tokens is expected to be a generator iterator which provides
pvl.token
objects.
-
parse_aggregation_block
(tokens: collections.abc.Generator)[source]¶ Parses the tokens for an Aggregation Block, and returns the modcls object that is the result of the parsing and decoding.
- <Aggregation-Block> ::= <Begin-Aggegation-Statement>
- (<WSC>* (Assignment-Statement | Aggregation-Block) <WSC>*)+ <End-Aggregation-Statement>
The Begin-Aggregation-Statement Name must match the Block-Name in the paired End-Aggregation-Statement if a Block-Name is present in the End-Aggregation-Statement.
-
parse_around_equals
(tokens: collections.abc.Generator) → None[source]¶ Parses white space and comments on either side of an equals sign.
tokens is expected to be a generator iterator which provides
pvl.token
objects.This is shared functionality for Begin Aggregation Statements and Assignment Statements. It basically covers parsing anything that has a syntax diagram like this:
<WSC>* ‘=’ <WSC>*
-
parse_assignment_statement
(tokens: collections.abc.Generator) → tuple[source]¶ Parses the tokens for an Assignment Statement.
The returned two-tuple contains the Parameter Name in the first element, and the Value in the second.
- <Assignment-Statement> ::= <Parameter-Name> <WSC>* ‘=’ <WSC>*
- <Value> [<Statement-Delimiter>]
-
parse_begin_aggregation_statement
(tokens: collections.abc.Generator) → tuple[source]¶ Parses the tokens for a Begin Aggregation Statement, and returns the name Block Name as a
str
.- <Begin-Aggregation-Statement-block> ::=
- <Begin-Aggegation-Statement> <WSC>* ‘=’ <WSC>* <Block-Name> [<Statement-Delimiter>]
Where <Block-Name> ::= <Parameter-Name>
-
parse_end_aggregation
(begin_agg: str, block_name: str, tokens: collections.abc.Generator) → None[source]¶ Parses the tokens for an End Aggregation Statement.
- <End-Aggregation-Statement-block> ::=
- <End-Aggegation-Statement> [<WSC>* ‘=’ <WSC>* <Block-Name>] [<Statement-Delimiter>]
Where <Block-Name> ::= <Parameter-Name>
-
parse_end_statement
(tokens: collections.abc.Generator) → None[source]¶ Parses the tokens for an End Statement.
<End-Statement> ::= “END” ( <WSC>* | [<Statement-Delimiter>] )
-
parse_module
(tokens: collections.abc.Generator)[source]¶ Parses the tokens for a PVL Module.
- <PVL-Module-Contents> ::=
- ( <Assignment-Statement> | <WSC>* | <Aggregation-Block> )* [<End-Statement>]
-
parse_module_post_hook
(module: pvl.collections.MutableMappingSequence, tokens: collections.abc.Generator)[source]¶ This function is meant to be overridden by subclasses that may want to perform some extra processing if ‘normal’ parse_module() operations fail to complete. See OmniParser for an example.
This function shall return a two-tuple, with the first item being the module (altered by processing or unaltered), and the second item being a boolean that will signal whether the tokens should continue to be parsed to accumulate more elements into the returned module, or whether the module is in a good state and should be returned by parse_module().
If the operations within this function are unsuccessful, it should raise an exception (any exception descended from Exception), which will result in the operation of parse_module() as if it were not overridden.
-
parse_sequence
(tokens: collections.abc.Generator) → list[source]¶ Parses a PVL Sequence.
- <Set> ::= “(” <WSC>*
- [ <Value> <WSC>* ( “,” <WSC>* <Value> <WSC>* )* ] “)”
Returns the decoded <Sequence> as a Python
list
.
-
parse_set
(tokens: collections.abc.Generator) → frozenset[source]¶ Parses a PVL Set.
- <Set> ::= “{” <WSC>*
- [ <Value> <WSC>* ( “,” <WSC>* <Value> <WSC>* )* ] “}”
Returns the decoded <Set> as a Python
frozenset
. The PVL specification doesn’t seem to indicate that a PVL Set has distinct values (like a Pythonset
), only that the ordering of the values is unimportant. For now, we will implement PVL Sets as Pythonfrozenset
objects.They are returned as
frozenset
objects because PVL Sets can contain as their elements other PVL Sets, but since Pythonset
objects are non-hashable, they cannot be members of a set, however,frozenset
objects can.
-
static
parse_statement_delimiter
(tokens: collections.abc.Generator) → bool[source]¶ Parses the tokens for a Statement Delimiter.
tokens is expected to be a generator iterator which provides
pvl.token
objects.- <Statement-Delimiter> ::= <WSC>*
- (<white-space-character> | <comment> | ‘;’ | <EOF>)
Although the above structure comes from Figure 2-4 of the Blue Book, the <white-space-character> and <comment> elements are redundant with the presence of [WSC]* so it can be simplified to:
<Statement-Delimiter> ::= <WSC>* [ ‘;’ | <EOF> ]Typically written [<Statement-Delimiter>].
-
parse_units
(value, tokens: collections.abc.Generator) → str[source]¶ Parses PVL Units Expression.
- <Units-Expression> ::= “<” [<white-space>] <Units-Value>
- [<white-space>] “>”
and
- <Units-Value> ::= <units-character>
- [ [ <units-character> | <white-space> ]*
- <units-character> ]
Returns the value and the <Units-Value> as a
Units()
object.
-
parse_value
(tokens: collections.abc.Generator)[source]¶ Parses PVL Values.
- <Value> ::= (<Simple-Value> | <Set> | <Sequence>)
- [<WSC>* <Units Expression>]
Returns the decoded <Value> as an appropriate Python object.
-
parse_value_post_hook
(tokens)[source]¶ This function is meant to be overridden by subclasses that may want to perform some extra processing if ‘normal’ parse_value() operations fail to yield a value. See OmniParser for an example.
This function shall return an appropriate Python value, similar to what parse_value() would return.
If the operations within this function are unsuccessful, it should raise a ValueError which will result in the operation of parse_value() as if it were not overridden.
- grammar – A pvl.grammar object, if None or not specified, it will
be set to the grammar parameter of decoder (if
decoder is not None) or will default to
pvl.pvl_translate module¶
A program for converting PVL text to a specific PVL dialect.
The pvl_translate
program will read a file with PVL text (any
of the kinds of files that pvl.load()
reads) or STDIN and
will convert that PVL text to a particular PVL dialect. It is not
particularly robust, and if it cannot make simple conversions, it
will raise errors.
-
class
pvl.pvl_translate.
JSONWriter
[source]¶ Bases:
pvl.pvl_translate.Writer
-
class
pvl.pvl_translate.
PVLWriter
(encoder)[source]¶ Bases:
pvl.pvl_translate.Writer
pvl.pvl_validate module¶
A program for testing and validating PVL text.
The pvl_validate
program will read a file with PVL text (any of
the kinds of files that pvl.load()
reads) and will report
on which of the various PVL dialects were able to load that PVL
text, and then also reports on whether the pvl
library can encode
the Python Objects back out to PVL text.
You can imagine some PVL text that could be loaded, but is not able to be written out in a particular strict PVL dialect (like PDS3 labels).
-
pvl.pvl_validate.
build_line
(elements: list, widths: list, sep=' | ') → str[source]¶ Returns a string formatted from the elements and widths provided.
-
pvl.pvl_validate.
pvl_flavor
(text, dialect, decenc: dict, filename, verbose=False) -> (<class 'bool'>, <class 'bool'>)[source]¶ Returns a two-tuple of booleans which indicate whether the text could be loaded and then encoded.
The first boolean in the two-tuple indicates whether the text could be loaded with the given parser, grammar, and decoder. The second indicates whether the loaded PVL object could be encoded with the given encoder, grammar, and decoder. If the first element is False, the second will be None.
pvl.token module¶
-
class
pvl.token.
Token
(content, grammar=None, decoder=None, pos=0)[source]¶ Bases:
str
A PVL-aware string.
Variables: - content – A string that is the Token text.
- grammar – A pvl.grammar object, if None or not specified, it will be set to the grammar parameter of decoder (if decoder is not None) or will default to PVLGrammar().
- decoder – A pvl.decoder object, defaults to PVLDecoder(grammar=*grammar*).
- pos – Integer that describes the starting position of this Token in the source string, defaults to zero.
-
is_WSC
() → bool[source]¶ Return true if the Token is white space characters or comments according to the Token’s grammar, false otherwise.
-
is_begin_aggregation
() → bool[source]¶ Return true if the Token is a begin aggregation keyword (e.g. ‘BEGIN_GROUP’ in PVL) according to the Token’s grammar, false otherwise.
-
is_comment
() → bool[source]¶ Return true if the Token is a comment according to the Token’s grammar (defined as beginning and ending with comment delimieters), false otherwise.
-
is_datetime
() → bool[source]¶ Return true if the Token’s decoder can convert the Token to a datetime, false otherwise.
Separate is_date() or is_time() functions aren’t needed, since PVL parsing doesn’t distinguish between them. If a user needs that distinction the decoder’s decode_datetime(self) function should return a datetime time, date, or datetime object, as appropriate, and a user can use isinstance() to check.
-
is_decimal
() → bool[source]¶ Return true if the Token’s decoder can convert the Token to a decimal value, false otherwise.
-
is_delimiter
() → bool[source]¶ Return true if the Token is a delimiter character (e.g. the ‘;’ in PVL) according to the Token’s grammar, false otherwise.
-
is_end_statement
() → bool[source]¶ Return true if the Token matches an end statement from its grammar, false otherwise.
-
is_non_decimal
() → bool[source]¶ Return true if the Token’s decoder can convert the Token to a numeric non-decimal value, false otherwise.
-
is_numeric
() → bool[source]¶ Return true if the Token’s is_decimal() or is_non_decimal() functions return true, false otherwise.
-
is_parameter_name
() → bool[source]¶ Return true if the Token is an unquoted string that isn’t a reserved_keyword according to the Token’s grammar, false otherwise.
-
is_quote
() → bool[source]¶ Return true if the Token is a quote character according to the Token’s grammar, false otherwise.
-
is_quoted_string
() → bool[source]¶ Return true if the Token can be converted to a quoted string by the Token’s decoder, false otherwise.
-
is_simple_value
() → bool[source]¶ Return true if the Token’s decoder can convert the Token to a ‘simple value’, however the decoder defines that, false otherwise.
-
is_space
() → bool[source]¶ Return true if the Token contains whitespace according to the definition of whitespace in the Token’s grammar and there is at least one character, false otherwise.
-
is_string
() → bool[source]¶ Return true if either the Token’s is_quoted_string() or is_unquoted_string() return true, false otherwise.
-
is_unquoted_string
() → bool[source]¶ Return false if the Token has any reserved characters, comment characters, whitespace characters or could be interpreted as a number, date, or time according to the Token’s grammar, true otherwise.
-
isnumeric
() → bool[source]¶ Overrides
str.isnumeric()
to be the same as Token’s is_numeric() function, so that we don’t get inconsisent behavior if someone forgets an underbar.
-
isspace
() → bool[source]¶ Overrides
str.isspace()
to be the same as Token’s is_space() function, so that we don’t get inconsisent behavior if someone forgets an underbar.
-
lstrip
(chars=None)[source]¶ Extends
str.lstrip()
to strip whitespace according to the definition of whitespace in the Token’s grammar instead of the default Python whitespace definition.
-
rstrip
(chars=None)[source]¶ Extends
str.rstrip()
to strip whitespace according to the definition of whitespace in the Token’s grammar instead of the default Python whitespace definition.
Module contents¶
Python implementation of PVL (Parameter Value Language).
-
pvl.
load
(path, parser=None, grammar=None, decoder=None, encoding=None, **kwargs)[source]¶ Returns a Python object from parsing the file at path.
Parameters: - path – an
os.PathLike
which presumably has a PVL Module in it to parse. - parser – defaults to
pvl.parser.OmniParser()
. - grammar – defaults to
pvl.grammar.OmniGrammar()
. - decoder – defaults to
pvl.decoder.OmniDecoder()
. - encoding – defaults to None, and has the same meaning as
for
open()
. - **kwargs – the keyword arguments that will be passed
to
loads()
and are described there.
If path is not an
os.PathLike
, it will be assumed to be an already-opened file object, and.read()
will be applied to extract the text.If the
os.PathLike
or file object contains some bytes decodable as text, followed by some that is not (e.g. an ISIS cube file), that’s fine, this function will just extract the decodable text.- path – an
-
pvl.
loads
(s: str, parser=None, grammar=None, decoder=None, **kwargs)[source]¶ Deserialize the string, s, as a Python object.
Parameters: - s – contains some PVL to parse.
- parser – defaults to
pvl.parser.OmniParser()
. - grammar – defaults to
pvl.grammar.OmniGrammar()
. - decoder – defaults to
pvl.decoder.OmniDecoder()
. - **kwargs – the keyword arguments to pass to the parser class if parser is none.
-
pvl.
dump
(module, path, **kwargs)[source]¶ Serialize module as PVL text to the provided path.
Parameters: - module – a
PVLModule
ordict
-like object to serialize. - path – an
os.PathLike
- **kwargs – the keyword arguments to pass to
dumps()
.
If path is an
os.PathLike
, it will attempt to be opened and the serialized module will be written into that file via thepathlib.Path.write_text()
function, and will return what that function returns.If path is not an
os.PathLike
, it will be assumed to be an already-opened file object, and.write()
will be applied on that object to write the serialized module, and will return what that function returns.- module – a
-
pvl.
dumps
(module, encoder=None, grammar=None, decoder=None, **kwargs) → str[source]¶ Returns a string where the module object has been serialized to PVL syntax.
Parameters: - module – a
PVLModule
ordict
like object to serialize. - encoder – defaults to
pvl.parser.PDSLabelEncoder()
. - grammar – defaults to
pvl.grammar.ODLGrammar()
. - decoder – defaults to
pvl.decoder.ODLDecoder()
. - **kwargs – the keyword arguments to pass to the encoder class if encoder is none.
- module – a
-
class
pvl.
Quantity
[source]¶ Bases:
pvl.collections.Quantity
A simple collections.namedtuple object to contain a value and units parameter.
If you need more comprehensive units handling, you may want to use the astropy.units.Quantity object, the pint.Quantity object, or some other 3rd party object. Please see the documentation on Quantities: Values and Units for how to use 3rd party Quantity objects with pvl.
-
class
pvl.
Units
[source]¶ Bases:
pvl.collections.Quantity