From 7d9a9defd4bd039535c6158361bcc5055eb948ae Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Wed, 21 Dec 2016 11:43:46 +0100 Subject: [PATCH] Inherit docstrings --- python/eccodes/high_level/bufr.py | 65 ++--------------------- python/eccodes/high_level/codesfile.py | 15 ++++++ python/eccodes/high_level/codesmessage.py | 47 ++++++++++++++++ python/eccodes/high_level/gribfile.py | 18 +------ python/eccodes/high_level/gribmessage.py | 46 ++-------------- 5 files changed, 72 insertions(+), 119 deletions(-) diff --git a/python/eccodes/high_level/bufr.py b/python/eccodes/high_level/bufr.py index e0d8db1a2..5f0e76f61 100644 --- a/python/eccodes/high_level/bufr.py +++ b/python/eccodes/high_level/bufr.py @@ -13,52 +13,11 @@ from .codesmessage import CodesMessage from .codesfile import CodesFile -# TODO: Docstring is mostly redundant, perhaps move into base class? class BufrMessage(CodesMessage): - """ - A BUFR message. - - Each ``BufrMessage`` is stored as a key/value pair in a dictionary-like - structure. It can be used in a context manager or by itself. When the - ``BufrFile`` it belongs to is closed, it closes any open ``BufrMessage``s - that belong to it. If a ``BufrMessage`` is closed before its ``BufrFile`` - is closed, it informs the ``BufrFile`` of its closure. - - Scalar and vector values are set appropriately through the same method. - - Usage:: - - >>> with BufrFile(filename) as bufr: - ... # Access shortNames of all messages - ... for msg in bufr: - ... print(msg["shortName"]) - ... # Report number of keys in message - ... len(msg) - ... # Report message size in bytes - ... msg.size - ... # Report keys in message - ... msg.keys() - ... # Check if value is missing - ... msg.missing("scaleFactorOfSecondFixedSurface") - ... # Set scalar value - ... msg["scaleFactorOfSecondFixedSurface"] = 5 - ... # Check key's value - ... msg["scaleFactorOfSecondFixedSurface"] - ... # Set value to missing - ... msg.set_missing("scaleFactorOfSecondFixedSurface") - ... # Missing values raise exception when read with dict notation - ... msg["scaleFactorOfSecondFixedSurface"] - ... # Array values are set transparently - ... msg["values"] = [1, 2, 3] - ... # Messages can be written to file - ... with open(testfile, "w") as test: - ... msg.write(test) - ... # Messages can be cloned from other messages - ... msg2 = BufrMessage(clone=msg) - ... # If desired, messages can be closed manually or used in with - ... msg.close() - """ + __doc__ = "\n".join(CodesMessage.__doc__.splitlines()[4:]).format( + prod_type="BUFR", classname="BufrMessage", parent="BufrFile", + alias="bufr") product_kind = eccodes.CODES_PRODUCT_BUFR @@ -114,21 +73,7 @@ class BufrMessage(CodesMessage): class BufrFile(CodesFile): - """ - A BUFR file handle meant for use in a context manager. - - Individual messages can be accessed using the ``next`` method. Of course, - it is also possible to iterate over each message in the file:: - - >>> with BufrFile(filename) as bufr: - ... # Print number of messages in file - ... len(bufr) - ... # Open all messages in file - ... for msg in bufr: - ... print(msg["shortName"]) - ... len(bufr.open_messages) - >>> # When the file is closed, any open messages are closed - >>> len(bufr.open_messages) - """ + __doc__ = "\n".join(CodesFile.__doc__.splitlines()[4:]).format( + prod_type="BUFR", classname="BufrFile", alias="bufr") MessageClass = BufrMessage diff --git a/python/eccodes/high_level/codesfile.py b/python/eccodes/high_level/codesfile.py index 1ff64e169..deb27d9e1 100644 --- a/python/eccodes/high_level/codesfile.py +++ b/python/eccodes/high_level/codesfile.py @@ -13,6 +13,21 @@ class CodesFile(file): """ An abstract class to specify and/or implement common behavior that files read by ecCodes should implement. + + A {prod_type} file handle meant for use in a context manager. + + Individual messages can be accessed using the ``next`` method. Of course, + it is also possible to iterate over each message in the file:: + + >>> with {classname}(filename) as {alias}: + ... # Print number of messages in file + ... len({alias}) + ... # Open all messages in file + ... for msg in {alias}: + ... print(msg[key_name]) + ... len({alias}.open_messages) + >>> # When the file is closed, any open messages are closed + >>> len({alias}.open_messages) """ #: Type of messages belonging to this file diff --git a/python/eccodes/high_level/codesmessage.py b/python/eccodes/high_level/codesmessage.py index c8891e706..a54df7446 100644 --- a/python/eccodes/high_level/codesmessage.py +++ b/python/eccodes/high_level/codesmessage.py @@ -15,6 +15,53 @@ class CodesMessage(object): """ An abstract class to specify and/or implement common behavior that messages read by ecCodes should implement. + + A {prod_type} message. + + Each ``{classname}`` is stored as a key/value pair in a dictionary-like + structure. It can be used in a context manager or by itself. When the + ``{parent}`` it belongs to is closed, the ``{parent}`` closes any open + ``{classname}``s that belong to it. If a ``{classname}`` is closed before + its ``{parent}`` is closed, it informs the ``{parent}`` of its closure. + + Scalar and vector values are set appropriately through the same method. + + ``{classname}``s can be instantiated from a ``{parent}``, cloned from + other ``{classname}``s or taken from samples. Iterating over the members + of a ``{parent}`` extracts the ``{classname}``s it contains until the + ``{parent}`` is exhausted. + + Usage:: + + >>> with {parent}(filename) as {alias}: + ... # Access a key from each message + ... for msg in {alias}: + ... print(msg[key_name]) + ... # Report number of keys in message + ... len(msg) + ... # Report message size in bytes + ... msg.size + ... # Report keys in message + ... msg.keys() + ... # Check if value is missing + ... msg.missing(key_name) + ... # Set scalar value + ... msg[scalar_key] = 5 + ... # Check key's value + ... msg[scalar_key] + ... # Set value to missing + ... msg.set_missing(key_name) + ... # Missing values raise exception when read with dict notation + ... msg[key_name] + ... # Array values are set transparently + ... msg[array_key] = [1, 2, 3] + ... # Messages can be written to file + ... with open(testfile, "w") as test: + ... msg.write(test) + ... # Messages can be cloned from other messages + ... msg2 = {classname}(clone=msg) + ... # If desired, messages can be closed manually or used in with + ... msg.close() """ #: ecCodes enum-like PRODUCT constant diff --git a/python/eccodes/high_level/gribfile.py b/python/eccodes/high_level/gribfile.py index d8e64284e..6e074fe09 100644 --- a/python/eccodes/high_level/gribfile.py +++ b/python/eccodes/high_level/gribfile.py @@ -11,21 +11,7 @@ from .gribmessage import GribMessage class GribFile(CodesFile): - """ - A GRIB file handle meant for use in a context manager. - - Individual messages can be accessed using the ``next`` method. Of course, - it is also possible to iterate over each message in the file:: - - >>> with GribFile(filename) as grib: - ... # Print number of messages in file - ... len(grib) - ... # Open all messages in file - ... for msg in grib: - ... print(msg["shortName"]) - ... len(grib.open_messages) - >>> # When the file is closed, any open messages are closed - >>> len(grib.open_messages) - """ + __doc__ = "\n".join(CodesFile.__doc__.splitlines()[4:]).format( + prod_type="GRIB", classname="GribFile", alias="grib") MessageClass = GribMessage diff --git a/python/eccodes/high_level/gribmessage.py b/python/eccodes/high_level/gribmessage.py index 23399990f..00c3613b6 100644 --- a/python/eccodes/high_level/gribmessage.py +++ b/python/eccodes/high_level/gribmessage.py @@ -16,49 +16,9 @@ class IndexNotSelectedError(Exception): class GribMessage(CodesMessage): - """ - A GRIB message. - - Each ``GribMessage`` is stored as a key/value pair in a dictionary-like - structure. It can be used in a context manager or by itself. When the - ``GribFile`` it belongs to is closed, it closes any open ``GribMessage``s - that belong to it. If a ``GribMessage`` is closed before its ``GribFile`` - is closed, it informs the ``GribFile`` of its closure. - - Scalar and vector values are set appropriately through the same method. - - Usage:: - - >>> with GribFile(filename) as grib: - ... # Access shortNames of all messages - ... for msg in grib: - ... print(msg["shortName"]) - ... # Report number of keys in message - ... len(msg) - ... # Report message size in bytes - ... msg.size - ... # Report keys in message - ... msg.keys() - ... # Check if value is missing - ... msg.missing("scaleFactorOfSecondFixedSurface") - ... # Set scalar value - ... msg["scaleFactorOfSecondFixedSurface"] = 5 - ... # Check key's value - ... msg["scaleFactorOfSecondFixedSurface"] - ... # Set value to missing - ... msg.set_missing("scaleFactorOfSecondFixedSurface") - ... # Missing values raise exception when read with dict notation - ... msg["scaleFactorOfSecondFixedSurface"] - ... # Array values are set transparently - ... msg["values"] = [1, 2, 3] - ... # Messages can be written to file - ... with open(testfile, "w") as test: - ... msg.write(test) - ... # Messages can be cloned from other messages - ... msg2 = GribMessage(clone=msg) - ... # If desired, messages can be closed manually or used in with - ... msg.close() - """ + __doc__ = "\n".join(CodesMessage.__doc__.splitlines()[4:]).format( + prod_type="GRIB", classname="GribMessage", parent="GribFile", + alias="grib") product_kind = eccodes.CODES_PRODUCT_GRIB