From 3e44a54c1befecf91b2a8a91ad888f71bf7d0726 Mon Sep 17 00:00:00 2001 From: Sam Whited Date: Tue, 30 Jun 2015 22:05:25 -0500 Subject: [PATCH 1/3] Use napolean and Google's docstring guidelines Fixes #61 --- docs/source/conf.py | 1 + libraw/bindings.py | 8 ++--- libraw/callbacks.py | 37 +++++++++++++---------- libraw/errors.py | 32 ++++++++++---------- rawkit/errors.py | 3 +- rawkit/options.py | 48 +++++++++++++++--------------- rawkit/raw.py | 71 ++++++++++++++++++++++++++------------------- rawkit/util.py | 17 ++++++++--- setup.py | 2 +- 9 files changed, 123 insertions(+), 96 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index e4c1d1f..46dc355 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -39,6 +39,7 @@ 'sphinx.ext.doctest', 'sphinx.ext.coverage', 'sphinx.ext.viewcode', + 'sphinx.ext.napoleon', 'alabaster', ] diff --git a/libraw/bindings.py b/libraw/bindings.py index 8faa13d..d2a7965 100644 --- a/libraw/bindings.py +++ b/libraw/bindings.py @@ -163,8 +163,8 @@ def version_number(self): (0, 16, 1) - :returns: The version number - :rtype: :class:`3 tuple` + Returns: + 3 tuple: The version number """ v = self.libraw_versionNumber() return ((v >> 16) & 0x0000ff, (v >> 8) & 0x0000ff, v & 0x0000ff) @@ -177,8 +177,8 @@ def version(self): "0.16.1-Release" - :returns: The version - :rtype: :class:`str` + Returns: + str: The version """ return self.libraw_version().decode('utf-8') diff --git a/libraw/callbacks.py b/libraw/callbacks.py index 00a27ea..4e04de3 100644 --- a/libraw/callbacks.py +++ b/libraw/callbacks.py @@ -31,10 +31,12 @@ def exif_cb(context, tag, type, len, ord, ifp): void *context, int tag, int type, int len, unsigned int ord, void *ifp ); -:param callback: the Python function to convert to a C callback. -:type callback: :class:`function` -:returns: A C callback -:rtype: :class:`_ctypes.PyCFuncPtrType` + +Args: + callback (function): The Python function to convert to a C callback. + +Returns: + _ctypes.PyCFuncPtrType: A C callback. """ memory_callback = CFUNCTYPE(c_void_p, c_char_p, c_char_p) @@ -58,10 +60,11 @@ def memory_cb(data, file, where): void *data, const char *file, const char *where ); -:param callback: the Python function to convert to a C callback. -:type callback: :class:`function` -:returns: A C callback -:rtype: :class:`_ctypes.PyCFuncPtrType` +Args: + callback (function): The Python function to convert to a C callback. + +Returns: + _ctypes.PyCFuncPtrType: A C callback. """ data_callback = CFUNCTYPE(c_void_p, c_char_p, c_int) @@ -85,10 +88,11 @@ def data_cb(data, file, offset): void *data, const char *file, const int offset ); -:param callback: the Python function to convert to a C callback. -:type callback: :class:`function` -:returns: A C callback -:rtype: :class:`_ctypes.PyCFuncPtrType` +Args: + callback (function): The Python function to convert to a C callback. + +Returns: + _ctypes.PyCFuncPtrType: A C callback. """ progress_callback = CFUNCTYPE(c_void_p, c_int, c_int, c_int) @@ -112,8 +116,9 @@ def progress_cb(data, stage, iteration, expected): void *data, enum LibRaw_progress stage, int iterationa, int expected ); -:param callback: the Python function to convert to a C callback. -:type callback: :class:`function` -:returns: A C callback -:rtype: :class:`_ctypes.PyCFuncPtrType` +Args: + callback (function): The Python function to convert to a C callback. + +Returns: + _ctypes.PyCFuncPtrType: A C callback. """ diff --git a/libraw/errors.py b/libraw/errors.py index 61f770b..868782c 100644 --- a/libraw/errors.py +++ b/libraw/errors.py @@ -105,21 +105,23 @@ def check_call(exit_code, func, arguments): """ Throws a Python error which corresponds to the given LibRaw exit code. - :param exit_code: the exit code returned by a LibRaw function - :type exit_code: :class:`int` - :raises: :exc:`~UnspecifiedError` - :exc:`~FileUnsupported` - :exc:`~FileUnsupported` - :exc:`~RequestForNonexistentImage` - :exc:`~OutOfOrderCall` - :exc:`~NoThumbnail` - :exc:`~UnsupportedThumbnail` - :exc:`~InputClosed` - :exc:`~InsufficientMemory` - :exc:`~DataError` - :exc:`~IOError` - :exc:`~CancelledByCallback` - :exc:`~BadCrop` + Args: + exit_code (int): An exit code returned by a LibRaw function. + + Raises: + UnspecifiedError: We're not sure what happened. + FileUnsupported: The file is not a raw file that we recognize. + RequestForNonexistentImage: The given IFD does not contain an image. + OutOfOrderCall: Something was called out of order (eg. before data was + unpacked) + NoThumbnail: The image does not have a thumbnail. + UnsupportedThumbnail: The embedded thumbnail format is unsupported. + InputClosed: The input stream has been closed. + InsufficientMemory: We're out of memory. + DataError: The unpacking step failed. + IOError: Reading was interrupted (or the file is corrupt). + CancelledByCallback: A callback canceled the operation. + BadCrop: The crop range was invalid. """ if func.restype is c_error and exit_code.value != 0: diff --git a/rawkit/errors.py b/rawkit/errors.py index 1279515..b56f13d 100644 --- a/rawkit/errors.py +++ b/rawkit/errors.py @@ -11,8 +11,7 @@ class InvalidFileType(ValueError): """ Raised when an invalid file type or file extension is passed to a rawkit - method. If rawkit does not know what the filetype is, a - :exc:`libraw.errors.FileUnsupported` may be raised instead. + method. """ diff --git a/rawkit/options.py b/rawkit/options.py index f195f48..b3140ff 100644 --- a/rawkit/options.py +++ b/rawkit/options.py @@ -174,16 +174,16 @@ class WhiteBalance(namedtuple('WhiteBalance', white balance multipliers stack (eg. you can use auto white balance, and then specify a manual ``rgbg`` multiplier on top of that). - :param auto: determines if we should automatically set the WB - :type auto: :class:`boolean` - :param camera: causes us to use the camera defined WB if present - :type camera: :class:`boolean` - :param greybox: set the WB based on a neutral grey region of the image - :type greybox: :class:`4 int tuple` - :param rgbg: set the WB manually based on an RGBG channel multiplier - :type rgbg: :class:`4 float tuple` - :returns: A white blance object - :rtype: :class:`WhiteBalance` + Args: + auto (boolean): Determines if we should automatically set the WB. + camera (boolean): Causes us to use the camera defined WB if present. + greybox (4 int tuple): Set the WB based on a neutral grey region of the + image. + rgbg (4 float tuple): Set the WB manually based on an RGBG channel + multiplier. + + Returns: + WhiteBalance: A white balance object. """ __slots__ = () @@ -198,9 +198,9 @@ class Options(object): """ Represents a set of options which can be used when processing raw data. - :param attrs: a subscriptable object from which to take the initial state - of the options object. - :type attrs: :class:`dict` + Args: + attrs (dict): A subscriptable object from which to take the initial + state of the options object. """ __slots__ = [ @@ -231,7 +231,6 @@ class Options(object): '_green_matching', '_bad_pixels_file', ] - """The options which are supported by this class.""" def __init__(self, attrs=None): """ @@ -256,9 +255,7 @@ def __iter__(self): raise StopIteration def __repr__(self): - """ - Represents the options as a dict. - """ + """Represents the options as a dict.""" return repr(dict(self)) def keys(self): @@ -267,8 +264,8 @@ def keys(self): been set by the user (even if those options are set to the default value). - :returns: List of option keys which have been set - :rtype: :class:`tuple` + Returns: + tuple: List of option keys which have been set. """ return [slot[1:] for slot in self.__slots__ if getattr(self, slot) is not None] @@ -277,14 +274,16 @@ def values(self): """ The values of all options which appear in :func:`keys`. - :returns: List of options values - :rtype: :class:`tuple` + Returns: + tuple: List of options values. """ return [self.__getitem__(k) for k in self.keys()] def __getitem__(self, k): """ - Allow accessing options with dictionary syntax eg. opts['half_size']. + Allow accessing options with dictionary syntax eg. :: + + opts['half_size']. """ return getattr(self, k) @@ -746,8 +745,9 @@ def _map_to_libraw_params(self, params): Internal method that writes rawkit options into the libraw options struct with the proper C data types. - :param params: the output params struct to set - :type params: :class:`libraw.structs.libraw_output_params_t` + Args: + params (libraw.structs.libraw_output_params_t): + The output params struct to set. """ for slot in self.__slots__: prop = slot[1:] diff --git a/rawkit/raw.py b/rawkit/raw.py index c312b44..18c5879 100644 --- a/rawkit/raw.py +++ b/rawkit/raw.py @@ -31,11 +31,14 @@ class Raw(object): raw.options.white_balance = WhiteBalance(camera=False, auto=True) raw.save(filename='some/destination/image.ppm') - :param filename: the name of a raw file to load - :type filename: :class:`str` - :returns: A raw object - :rtype: :class:`Raw` - :raises: :exc:`rawkit.errors.NoFileSpecified` + Args: + filename (str): The name of a raw file to load. + + Returns: + Raw: A raw object. + + Raises: + rawkit.errors.NoFileSpecified: If `filename` is ``None``. """ def __init__(self, filename=None): @@ -84,12 +87,14 @@ def save(self, filename=None, filetype='ppm'): """ Save the image data as a new PPM or TIFF image. - :param filename: the name of an image file to save - :type filename: :class:`str` - :param filetype: the type of file to output (``ppm`` or ``tiff``) - :type filetype: :class:`str` - :raises: :exc:`rawkit.errors.NoFileSpecified` - :exc:`rawkit.errors.InvalidFileTypeError` + Args: + filename (str): The name of an image file to save. + filetype (str): The type of file to output (``ppm`` or ``tiff``). + + Raises: + rawkit.errors.NoFileSpecified: If `filename` is ``None``. + rawkit.errors.InvalidFileTypeError: If `filetype` is not ``ppm`` or + ``tiff``. """ if filename is None: raise NoFileSpecified() @@ -107,9 +112,15 @@ def save_thumb(self, filename=None): """ Save the thumbnail data. - :param filename: the name of an image file to save - :type filename: :class:`str` + Args: + filename (str): The name of an image file to save. + + Raises: + rawkit.errors.NoFileSpecified: If `filename` is ``None``. """ + if filename is None: + raise NoFileSpecified() + self.unpack_thumb() self.libraw.libraw_dcraw_thumb_writer( @@ -117,10 +128,10 @@ def save_thumb(self, filename=None): def to_buffer(self): """ - Return the image data as an RGB buffer. + Convert the image to an RGB buffer. - :returns: RGB data of the image - :rtype: :class:`bytearray` + Returns: + bytearray: RGB data of the image. """ self.unpack() self.process() @@ -137,10 +148,10 @@ def to_buffer(self): def thumbnail_to_buffer(self): """ - Return the thumbnail data as an RGB buffer. + Convert the thumbnail data as an RGB buffer. - :returns: RGB data of the thumbnail - :rtype: :class:`bytearray` + Returns: + bytearray: RGB data of the thumbnail. """ self.unpack_thumb() @@ -159,8 +170,8 @@ def metadata(self): """ Common metadata for the photo - :returns: A metadata object - :rtype: :class:`~rawkit.metadata.Metadata` + Returns: + rawkit.metadata.Metadata: A metadata object. """ return Metadata( aperture=self.data.contents.other.aperture, @@ -185,8 +196,6 @@ class DarkFrame(Raw): Creates a temporary file which is not cleaned up until the dark frame is closed. - - :See also: :class:`rawkit.raw.Raw` """ def __init__(self, filename=None): @@ -215,11 +224,13 @@ def save(self, filename=None, filetype='ppm'): """ Save the image data, defaults to using a temp file. - :param filename: the name of an image file to save - :type filename: :class:`str` - :param filetype: the type of file to output (``ppm`` or ``tiff``) - :type filetype: :class:`str` - :raises: :exc:`rawkit.errors.InvalidFileTypeError` + Args: + filename (str): The name of an image file to save. + filetype (str): The type of file to output (``ppm`` or ``tiff``). + + Raises: + rawkit.errors.InvalidFileTypeError: If `filetype` is not ``ppm`` or + ``tiff``. """ if filename is None: @@ -233,8 +244,8 @@ def name(self): """ A tempfile in a unique directory. - :returns: The name of a temp file - :rtype: :class:`str` + Returns: + str: The name of a temp file. """ return self._tmp diff --git a/rawkit/util.py b/rawkit/util.py index f54b7a4..b836514 100644 --- a/rawkit/util.py +++ b/rawkit/util.py @@ -1,3 +1,11 @@ +""":mod:`rawkit.util` --- Utility functions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +These functions perform helpful tasks which don't really fit anywhere else such +as searching for Raw files on the disk, or checking what cameras are supported +by LibRaw. +""" + import ctypes import os @@ -7,8 +15,9 @@ def discover(path): """ Recursively search for raw files in a given directory. - :param path: the directory to recursively search - :type path: :class:`str` + + Args: + path (str): A tree to recursively search. """ file_list = [] libraw = LibRaw() @@ -30,8 +39,8 @@ def camera_list(): Return a list of cameras which are supported by the currently linked version of LibRaw. - :returns: A list of supported cameras - :rtype: :class:`str tuple` + Returns: + str array: A list of supported cameras. """ libraw = LibRaw() diff --git a/setup.py b/setup.py index 9779d02..7d804e5 100644 --- a/setup.py +++ b/setup.py @@ -39,5 +39,5 @@ def readme(): 'tox >= 2.0.1', 'mock >= 1.0.1' ], - extras_require={'doc': ['sphinx >= 1.0']}, + extras_require={'doc': ['sphinx >= 1.3']}, ) From e187c864c36469ce8e0f0ef1c87cd297e6ef274f Mon Sep 17 00:00:00 2001 From: Sam Whited Date: Tue, 30 Jun 2015 22:07:32 -0500 Subject: [PATCH 2/3] Format callback warning [ci skip] --- libraw/callbacks.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libraw/callbacks.py b/libraw/callbacks.py index 4e04de3..79060d3 100644 --- a/libraw/callbacks.py +++ b/libraw/callbacks.py @@ -1,9 +1,11 @@ """:mod:`libraw.callbacks` --- LibRaw callback definitions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Note that you will need to keep a reference to your callback functions for as -long as you want to call them from C code, otherwise they may be garbage -collected and lead to a segmentation fault. +Warning: + + You will need to keep a reference to your callback functions for as long as + you want to call them from C code, otherwise they may be garbage collected + and lead to a segmentation fault. """ from ctypes import * # noqa From 9f889a413ceee432a64ae6031f32ce89f57dfaf8 Mon Sep 17 00:00:00 2001 From: Sam Whited Date: Tue, 30 Jun 2015 22:13:07 -0500 Subject: [PATCH 3/3] Add test for saving thumbnail w/o a filename --- tests/unit/raw_test.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/unit/raw_test.py b/tests/unit/raw_test.py index b952387..e4dfb12 100644 --- a/tests/unit/raw_test.py +++ b/tests/unit/raw_test.py @@ -129,6 +129,11 @@ def test_save_thumb(raw, output_file): ) +def test_save_thumb_no_filename(raw): + with pytest.raises(NoFileSpecified): + raw.save_thumb() + + def test_to_buffer(raw): # Quick hack because to_buffer does some ctypes acrobatics with mock.patch('rawkit.raw.ctypes'):