Repository: beam Updated Branches: refs/heads/master d035a345f -> 84a23793c
http://git-wip-us.apache.org/repos/asf/beam/blob/e1baf55d/sdks/python/apache_beam/transforms/display.py ---------------------------------------------------------------------- diff --git a/sdks/python/apache_beam/transforms/display.py b/sdks/python/apache_beam/transforms/display.py index 152f16e..88a1fee 100644 --- a/sdks/python/apache_beam/transforms/display.py +++ b/sdks/python/apache_beam/transforms/display.py @@ -16,21 +16,24 @@ # """ -DisplayData, its classes, interfaces and methods. +:class:`DisplayData`, its classes, interfaces and methods. The classes in this module allow users and transform developers to define -static display data to be displayed when a pipeline runs. PTransforms, DoFns -and other pipeline components are subclasses of the HasDisplayData mixin. To -add static display data to a component, you can override the display_data -method of the HasDisplayData class. +static display data to be displayed when a pipeline runs. +:class:`~apache_beam.transforms.ptransform.PTransform` s, +:class:`~apache_beam.transforms.core.DoFn` s +and other pipeline components are subclasses of the :class:`HasDisplayData` +mixin. To add static display data to a component, you can override the +:meth:`HasDisplayData.display_data()` method. Available classes: -- HasDisplayData - Components that inherit from this class can have static - display data shown in the UI. -- DisplayDataItem - This class represents static display data elements. -- DisplayData - Internal class that is used to create display data and - communicate it to the API. +* :class:`HasDisplayData` - Components that inherit from this class can have + static display data shown in the UI. +* :class:`DisplayDataItem` - This class represents static display data + elements. +* :class:`DisplayData` - Internal class that is used to create display data + and communicate it to the API. """ from __future__ import absolute_import @@ -57,17 +60,19 @@ class HasDisplayData(object): static display data. Returns: - A dictionary containing key:value pairs. The value might be an - integer, float or string value; a DisplayDataItem for values that - have more data (e.g. short value, label, url); or a HasDisplayData - instance that has more display data that should be picked up. For - example: - - { 'key1': 'string_value', - 'key2': 1234, - 'key3': 3.14159265, - 'key4': DisplayDataItem('apache.org', url='http://apache.org'), - 'key5': subComponent } + Dict[str, Any]: A dictionary containing ``key:value`` pairs. + The value might be an integer, float or string value; a + :class:`DisplayDataItem` for values that have more data + (e.g. short value, label, url); or a :class:`HasDisplayData` instance + that has more display data that should be picked up. For example:: + + { + 'key1': 'string_value', + 'key2': 1234, + 'key3': 3.14159265, + 'key4': DisplayDataItem('apache.org', url='http://apache.org'), + 'key5': subComponent + } """ return {} @@ -111,18 +116,19 @@ class DisplayData(object): @classmethod def create_from_options(cls, pipeline_options): - """ Creates DisplayData from a PipelineOptions instance. + """ Creates :class:`DisplayData` from a + :class:`~apache_beam.options.pipeline_options.PipelineOptions` instance. - When creating DisplayData, this method will convert the value of any - item of a non-supported type to its string representation. - The normal DisplayData.create_from method rejects those items. + When creating :class:`DisplayData`, this method will convert the value of + any item of a non-supported type to its string representation. + The normal :meth:`.create_from()` method rejects those items. Returns: - A DisplayData instance with populated items. + DisplayData: A :class:`DisplayData` instance with populated items. Raises: - ValueError: If the has_display_data argument is not an instance of - HasDisplayData. + ~exceptions.ValueError: If the **has_display_data** argument is + not an instance of :class:`HasDisplayData`. """ from apache_beam.options.pipeline_options import PipelineOptions if not isinstance(pipeline_options, PipelineOptions): @@ -138,14 +144,14 @@ class DisplayData(object): @classmethod def create_from(cls, has_display_data): - """ Creates DisplayData from a HasDisplayData instance. + """ Creates :class:`DisplayData` from a :class:`HasDisplayData` instance. Returns: - A DisplayData instance with populated items. + DisplayData: A :class:`DisplayData` instance with populated items. Raises: - ValueError: If the has_display_data argument is not an instance of - HasDisplayData. + ~exceptions.ValueError: If the **has_display_data** argument is + not an instance of :class:`HasDisplayData`. """ if not isinstance(has_display_data, HasDisplayData): raise ValueError('Element of class {}.{} does not subclass HasDisplayData' @@ -214,11 +220,13 @@ class DisplayDataItem(object): return False def is_valid(self): - """ Checks that all the necessary fields of the DisplayDataItem are - filled in. It checks that neither key, namespace, value or type are None. + """ Checks that all the necessary fields of the :class:`DisplayDataItem` + are filled in. It checks that neither key, namespace, value or type are + :data:`None`. Raises: - ValueError: If the item does not have a key, namespace, value or type. + ~exceptions.ValueError: If the item does not have a key, namespace, + value or type. """ if self.key is None: raise ValueError('Invalid DisplayDataItem. Key must not be None') @@ -247,14 +255,15 @@ class DisplayDataItem(object): return res def get_dict(self): - """ Returns the internal-API dictionary representing the DisplayDataItem. + """ Returns the internal-API dictionary representing the + :class:`DisplayDataItem`. Returns: - A dictionary. The internal-API dictionary representing the - DisplayDataItem + Dict[str, Any]: A dictionary. The internal-API dictionary representing + the :class:`DisplayDataItem`. Raises: - ValueError: if the item is not valid. + ~exceptions.ValueError: if the item is not valid. """ self.is_valid() return self._get_dict() http://git-wip-us.apache.org/repos/asf/beam/blob/e1baf55d/sdks/python/apache_beam/transforms/ptransform.py ---------------------------------------------------------------------- diff --git a/sdks/python/apache_beam/transforms/ptransform.py b/sdks/python/apache_beam/transforms/ptransform.py index a798fa1..f6e08ca 100644 --- a/sdks/python/apache_beam/transforms/ptransform.py +++ b/sdks/python/apache_beam/transforms/ptransform.py @@ -214,38 +214,44 @@ class PTransform(WithTypeHints, HasDisplayData): return self.__class__.__name__ def with_input_types(self, input_type_hint): - """Annotates the input type of a PTransform with a type-hint. + """Annotates the input type of a :class:`PTransform` with a type-hint. Args: - input_type_hint: An instance of an allowed built-in type, a custom class, - or an instance of a typehints.TypeConstraint. + input_type_hint (type): An instance of an allowed built-in type, a custom + class, or an instance of a + :class:`~apache_beam.typehints.typehints.TypeConstraint`. Raises: - TypeError: If 'type_hint' is not a valid type-hint. See - typehints.validate_composite_type_param for further details. + ~exceptions.TypeError: If **input_type_hint** is not a valid type-hint. + See + :obj:`apache_beam.typehints.typehints.validate_composite_type_param()` + for further details. Returns: - A reference to the instance of this particular PTransform object. This - allows chaining type-hinting related methods. + PTransform: A reference to the instance of this particular + :class:`PTransform` object. This allows chaining type-hinting related + methods. """ validate_composite_type_param(input_type_hint, 'Type hints for a PTransform') return super(PTransform, self).with_input_types(input_type_hint) def with_output_types(self, type_hint): - """Annotates the output type of a PTransform with a type-hint. + """Annotates the output type of a :class:`PTransform` with a type-hint. Args: - type_hint: An instance of an allowed built-in type, a custom class, or a - typehints.TypeConstraint. + type_hint (type): An instance of an allowed built-in type, a custom class, + or a :class:`~apache_beam.typehints.typehints.TypeConstraint`. Raises: - TypeError: If 'type_hint' is not a valid type-hint. See - typehints.validate_composite_type_param for further details. + ~exceptions.TypeError: If **type_hint** is not a valid type-hint. See + :obj:`~apache_beam.typehints.typehints.validate_composite_type_param()` + for further details. Returns: - A reference to the instance of this particular PTransform object. This - allows chaining type-hinting related methods. + PTransform: A reference to the instance of this particular + :class:`PTransform` object. This allows chaining type-hinting related + methods. """ validate_composite_type_param(type_hint, 'Type hints for a PTransform') return super(PTransform, self).with_output_types(type_hint) @@ -491,13 +497,16 @@ class _ChainedPTransform(PTransform): class PTransformWithSideInputs(PTransform): - """A superclass for any PTransform (e.g. FlatMap or Combine) + """A superclass for any :class:`PTransform` (e.g. + :func:`~apache_beam.transforms.core.FlatMap` or + :class:`~apache_beam.transforms.core.CombineFn`) invoking user code. - PTransforms like FlatMap invoke user-supplied code in some kind of - package (e.g. a DoFn) and optionally provide arguments and side inputs - to that code. This internal-use-only class contains common functionality - for PTransforms that fit this model. + :class:`PTransform` s like :func:`~apache_beam.transforms.core.FlatMap` + invoke user-supplied code in some kind of package (e.g. a + :class:`~apache_beam.transforms.core.DoFn`) and optionally provide arguments + and side inputs to that code. This internal-use-only class contains common + functionality for :class:`PTransform` s that fit this model. """ def __init__(self, fn, *args, **kwargs): @@ -543,16 +552,20 @@ class PTransformWithSideInputs(PTransform): of an allowed built-in type, a custom class, or a typehints.TypeConstraint. - Example of annotating the types of side-inputs: + Example of annotating the types of side-inputs:: + FlatMap().with_input_types(int, int, bool) Raises: - TypeError: If 'type_hint' is not a valid type-hint. See - typehints.validate_composite_type_param for further details. + :class:`~exceptions.TypeError`: If **type_hint** is not a valid type-hint. + See + :func:`~apache_beam.typehints.typehints.validate_composite_type_param` + for further details. Returns: - A reference to the instance of this particular PTransform object. This - allows chaining type-hinting related methods. + :class:`PTransform`: A reference to the instance of this particular + :class:`PTransform` object. This allows chaining type-hinting related + methods. """ super(PTransformWithSideInputs, self).with_input_types(input_type_hint) http://git-wip-us.apache.org/repos/asf/beam/blob/e1baf55d/sdks/python/apache_beam/typehints/decorators.py ---------------------------------------------------------------------- diff --git a/sdks/python/apache_beam/typehints/decorators.py b/sdks/python/apache_beam/typehints/decorators.py index d5954e2..3f5b4c9 100644 --- a/sdks/python/apache_beam/typehints/decorators.py +++ b/sdks/python/apache_beam/typehints/decorators.py @@ -310,38 +310,54 @@ def with_input_types(*positional_hints, **keyword_hints): be type-hinted in totality if even one parameter is type-hinted. Once fully decorated, if the arguments passed to the resulting function - violate the type-hint constraints defined, a TypeCheckError detailing the - error will be raised. + violate the type-hint constraints defined, a :class:`TypeCheckError` + detailing the error will be raised. - To be used as:: + To be used as: - * @with_input_types(s=str) # just @with_input_types(str) will work too. - def upper(s): - return s.upper() + .. testcode:: - Or:: + from apache_beam.typehints import with_input_types - * @with_input_types(ls=List[Tuple[int, int]) - def increment(ls): - [(i + 1, j + 1) for (i,j) in ls] + @with_input_types(str) + def upper(s): + return s.upper() + + Or: + + .. testcode:: + + from apache_beam.typehints import with_input_types + from apache_beam.typehints import List + from apache_beam.typehints import Tuple + + @with_input_types(ls=List[Tuple[int, int]]) + def increment(ls): + [(i + 1, j + 1) for (i,j) in ls] Args: *positional_hints: Positional type-hints having identical order as the function's formal arguments. Values for this argument must either be a - built-in Python type or an instance of a TypeContraint created by - 'indexing' a CompositeTypeHint instance with a type parameter. + built-in Python type or an instance of a + :class:`~apache_beam.typehints.typehints.TypeConstraint` created by + 'indexing' a + :class:`~apache_beam.typehints.typehints.CompositeTypeHint` instance + with a type parameter. **keyword_hints: Keyword arguments mirroring the names of the parameters to the decorated functions. The value of each keyword argument must either be one of the allowed built-in Python types, a custom class, or an - instance of a TypeContraint created by 'indexing' a CompositeTypeHint - instance with a type parameter. + instance of a :class:`~apache_beam.typehints.typehints.TypeConstraint` + created by 'indexing' a + :class:`~apache_beam.typehints.typehints.CompositeTypeHint` instance + with a type parameter. Raises: - ValueError: If not all function arguments have corresponding type-hints - specified. Or if the inner wrapper function isn't passed a function - object. - TypeCheckError: If the any of the passed type-hint constraints are not a - type or TypeContraint instance. + :class:`~exceptions.ValueError`: If not all function arguments have + corresponding type-hints specified. Or if the inner wrapper function isn't + passed a function object. + :class:`TypeCheckError`: If the any of the passed type-hint + constraints are not a type or + :class:`~apache_beam.typehints.typehints.TypeConstraint` instance. Returns: The original function decorated such that it enforces type-hint constraints @@ -375,37 +391,53 @@ def with_output_types(*return_type_hint, **kwargs): Only a single type-hint is accepted to specify the return type of the return value. If the function to be decorated has multiple return values, then one - should use: 'Tuple[type_1, type_2]' to annotate the types of the return + should use: ``Tuple[type_1, type_2]`` to annotate the types of the return values. If the ultimate return value for the function violates the specified type-hint - a TypeCheckError will be raised detailing the type-constraint violation. + a :class:`TypeCheckError` will be raised detailing the type-constraint + violation. + + This decorator is intended to be used like: + + .. testcode:: + + from apache_beam.typehints import with_output_types + from apache_beam.typehints import Set + + class Coordinate: + def __init__(self, x, y): + self.x = x + self.y = y + + @with_output_types(Set[Coordinate]) + def parse_ints(ints): + return {Coordinate(i, i) for i in ints} - This decorator is intended to be used like:: + Or with a simple type-hint: - * @with_output_types(Set[Coordinate]) - def parse_ints(ints): - .... - return [Coordinate.from_int(i) for i in ints] + .. testcode:: - Or with a simple type-hint:: + from apache_beam.typehints import with_output_types - * @with_output_types(bool) - def negate(p): - return not p if p else p + @with_output_types(bool) + def negate(p): + return not p if p else p Args: *return_type_hint: A type-hint specifying the proper return type of the function. This argument should either be a built-in Python type or an - instance of a 'TypeConstraint' created by 'indexing' a - 'CompositeTypeHint'. + instance of a :class:`~apache_beam.typehints.typehints.TypeConstraint` + created by 'indexing' a + :class:`~apache_beam.typehints.typehints.CompositeTypeHint`. **kwargs: Not used. Raises: - ValueError: If any kwarg parameters are passed in, or the length of - 'return_type_hint' is greater than 1. Or if the inner wrapper function - isn't passed a function object. - TypeCheckError: If the 'return_type_hint' object is in invalid type-hint. + :class:`~exceptions.ValueError`: If any kwarg parameters are passed in, + or the length of **return_type_hint** is greater than ``1``. Or if the + inner wrapper function isn't passed a function object. + :class:`TypeCheckError`: If the **return_type_hint** object is + in invalid type-hint. Returns: The original function decorated such that it enforces type-hint constraints http://git-wip-us.apache.org/repos/asf/beam/blob/e1baf55d/sdks/python/apache_beam/typehints/native_type_compatibility.py ---------------------------------------------------------------------- diff --git a/sdks/python/apache_beam/typehints/native_type_compatibility.py b/sdks/python/apache_beam/typehints/native_type_compatibility.py index d88f933..26c584e 100644 --- a/sdks/python/apache_beam/typehints/native_type_compatibility.py +++ b/sdks/python/apache_beam/typehints/native_type_compatibility.py @@ -82,13 +82,14 @@ def convert_to_beam_type(typ): """Convert a given typing type to a Beam type. Args: - typ: typing type. + typ (type): typing type. Returns: - The given type converted to a Beam type as far as we can do the conversion. + type: The given type converted to a Beam type as far as we can do the + conversion. Raises: - ValueError: The type was malformed. + ~exceptions.ValueError: The type was malformed. """ type_map = [ http://git-wip-us.apache.org/repos/asf/beam/blob/e1baf55d/sdks/python/apache_beam/typehints/typehints.py ---------------------------------------------------------------------- diff --git a/sdks/python/apache_beam/typehints/typehints.py b/sdks/python/apache_beam/typehints/typehints.py index 6039e0e..98d399b 100644 --- a/sdks/python/apache_beam/typehints/typehints.py +++ b/sdks/python/apache_beam/typehints/typehints.py @@ -73,7 +73,6 @@ __all__ = [ 'Union', 'Optional', 'Tuple', - 'Tuple', 'List', 'KV', 'Dict', @@ -109,9 +108,10 @@ class TypeConstraint(object): """The base-class for all created type-constraints defined below. - A TypeConstraint is the result of parameterizing a CompositeTypeHint with - with one of the allowed Python types or another CompositeTypeHint. It - binds and enforces a specific version of a generalized TypeHint. + A :class:`TypeConstraint` is the result of parameterizing a + :class:`CompositeTypeHint` with with one of the allowed Python types or + another :class:`CompositeTypeHint`. It binds and enforces a specific + version of a generalized TypeHint. """ def _consistent_with_check_(self, sub): @@ -135,12 +135,14 @@ class TypeConstraint(object): instance: An instance of a Python object. Raises: - TypeError: The passed 'instance' doesn't satisfy this TypeConstraint. - Subclasses of TypeConstraint are free to raise any of the subclasses of - TypeError defined above, depending on the manner of the type hint error. - - All TypeConstraint sub-classes must define this method in other for the - class object to be created. + :class:`~exceptions.TypeError`: The passed **instance** doesn't satisfy + this :class:`TypeConstraint`. Subclasses of + :class:`TypeConstraint` are free to raise any of the subclasses of + :class:`~exceptions.TypeError` defined above, depending on + the manner of the type hint error. + + All :class:`TypeConstraint` sub-classes must define this method in other + for the class object to be created. """ raise NotImplementedError @@ -296,19 +298,21 @@ class CompositeTypeHint(object): def validate_composite_type_param(type_param, error_msg_prefix): - """Determines if an object is a valid type parameter to a CompositeTypeHint. + """Determines if an object is a valid type parameter to a + :class:`CompositeTypeHint`. + + Implements sanity checking to disallow things like:: - Implements sanity checking to disallow things like: - * List[1, 2, 3] or Dict[5]. + List[1, 2, 3] or Dict[5]. Args: type_param: An object instance. - error_msg_prefix: A string prefix used to format an error message in the - case of an exception. + error_msg_prefix (:class:`str`): A string prefix used to format an error + message in the case of an exception. Raises: - TypeError: If the passed 'type_param' is not a valid type parameter for a - CompositeTypeHint. + ~exceptions.TypeError: If the passed **type_param** is not a valid type + parameter for a :class:`CompositeTypeHint`. """ # Must either be a TypeConstraint instance or a basic Python type. is_not_type_constraint = ( http://git-wip-us.apache.org/repos/asf/beam/blob/e1baf55d/sdks/python/generate_pydoc.sh ---------------------------------------------------------------------- diff --git a/sdks/python/generate_pydoc.sh b/sdks/python/generate_pydoc.sh index 1fea6f1..662bd09 100755 --- a/sdks/python/generate_pydoc.sh +++ b/sdks/python/generate_pydoc.sh @@ -31,43 +31,132 @@ rm -rf target/docs/* mkdir -p target/docs/source -# Exclude internal/experimental files from the documentation. -excluded_internal_code=( +# Sphinx apidoc autodoc options +export SPHINX_APIDOC_OPTIONS=\ +members,\ +undoc-members,\ +show-inheritance + +# Exclude internal, test, and Cython paths/patterns from the documentation. +excluded_patterns=( + apache_beam/coders/stream.* + apache_beam/coders/coder_impl.* apache_beam/examples/ apache_beam/internal/clients/ - apache_beam/io/gcp/internal/clients/ + apache_beam/io/gcp/internal/ + apache_beam/io/gcp/tests/ + apache_beam/metrics/execution.* + apache_beam/runners/common.* apache_beam/runners/api/ apache_beam/runners/test/ + apache_beam/runners/dataflow/internal/ apache_beam/runners/portability/ apache_beam/runners/worker/ - apache_beam/runners/dataflow/internal/clients/ - apache_beam/testing/data/) - -python $(type -p sphinx-apidoc) -f -o target/docs/source apache_beam \ - "${excluded_internal_code[@]}" "*_test.py" + apache_beam/transforms/cy_combiners.* + apache_beam/utils/counters.* + apache_beam/utils/windowed_value.* + *_pb2.py + *_test.py + *_test_common.py +) -# Remove Cython modules from doc template; they won't load -sed -i -e '/.. automodule:: apache_beam.coders.stream/d' \ - target/docs/source/apache_beam.coders.rst +python $(type -p sphinx-apidoc) -fMeT -o target/docs/source apache_beam \ + "${excluded_patterns[@]}" # Create the configuration and index files +#=== conf.py ===# cat > target/docs/source/conf.py <<'EOF' import os import sys +import sphinx_rtd_theme + sys.path.insert(0, os.path.abspath('../../..')) +exclude_patterns = [ + '_build', + 'target/docs/source/apache_beam.rst', +] + extensions = [ 'sphinx.ext.autodoc', + 'sphinx.ext.doctest', + 'sphinx.ext.intersphinx', 'sphinx.ext.napoleon', 'sphinx.ext.viewcode', ] master_doc = 'index' -html_theme = 'sphinxdoc' +html_theme = 'sphinx_rtd_theme' +html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] project = 'Apache Beam' + +autoclass_content = 'both' +autodoc_member_order = 'bysource' + +doctest_global_setup = ''' +import apache_beam as beam +''' + +intersphinx_mapping = { + 'python': ('https://docs.python.org/2', None), + 'hamcrest': ('https://pyhamcrest.readthedocs.io/en/latest/', None), +} + +# Since private classes are skipped by sphinx, if there is any cross reference +# to them, it will be broken. This can happen if a class inherits from a +# private class. +ignore_identifiers = [ + # Ignore "custom" builtin types + '', + 'Any', + 'Dict', + 'Iterable', + 'List', + 'Set', + 'Tuple', + + # Ignore private classes + 'apache_beam.coders.coders._PickleCoderBase', + 'apache_beam.coders.coders.FastCoder', + 'apache_beam.io._AvroSource', + 'apache_beam.io.gcp.bigquery.RowAsDictJsonCoder', + 'apache_beam.io.gcp.datastore.v1.datastoreio._Mutate', + 'apache_beam.io.gcp.internal.clients.bigquery.' + 'bigquery_v2_messages.TableSchema', + 'apache_beam.io.iobase.SourceBase', + 'apache_beam.io.source_test_utils.ExpectedSplitOutcome', + 'apache_beam.metrics.metric.MetricResults', + 'apache_beam.pipeline.PipelineVisitor', + 'apache_beam.pipeline.PTransformOverride', + 'apache_beam.pvalue.AsSideInput', + 'apache_beam.pvalue.DoOutputsTuple', + 'apache_beam.pvalue.PValue', + 'apache_beam.runners.direct.executor.CallableTask', + 'apache_beam.transforms.core.CallableWrapperCombineFn', + 'apache_beam.transforms.ptransform.PTransformWithSideInputs', + 'apache_beam.transforms.trigger._ParallelTriggerFn', + 'apache_beam.transforms.trigger.InMemoryUnmergedState', + 'apache_beam.typehints.typehints.AnyTypeConstraint', + 'apache_beam.typehints.typehints.CompositeTypeHint', + 'apache_beam.typehints.typehints.TypeConstraint', + 'apache_beam.typehints.typehints.validate_composite_type_param()', + + # Private classes which are used within the same module + 'WindowedTypeConstraint', # apache_beam.typehints.typehints +] + +# When inferring a base class it will use ':py:class'; if inferring a function +# argument type or return type, it will use ':py:obj'. We'll generate both. +nitpicky = True +nitpick_ignore = [] +nitpick_ignore += [('py:class', iden) for iden in ignore_identifiers] +nitpick_ignore += [('py:obj', iden) for iden in ignore_identifiers] EOF + +#=== index.rst ===# cat > target/docs/source/index.rst <<'EOF' -.. include:: ./modules.rst +.. include:: ./apache_beam.rst + :start-line: 2 EOF # Build the documentation using sphinx @@ -76,10 +165,21 @@ python $(type -p sphinx-build) -v -a -E -q target/docs/source \ target/docs/_build -c target/docs/source \ -w "target/docs/sphinx-build.warnings.log" +# Fail if there are errors or warnings in docs +! grep -q "ERROR:" target/docs/sphinx-build.warnings.log || exit 1 +! grep -q "WARNING:" target/docs/sphinx-build.warnings.log || exit 1 + +# Run tests for code samples, these can be: +# - Code blocks using '.. testsetup::', '.. testcode::' and '.. testoutput::' +# - Interactive code starting with '>>>' +python -msphinx -M doctest target/docs/source \ + target/docs/_build -c target/docs/source \ + -w "target/docs/sphinx-doctest.warnings.log" + +# Fail if there are errors or warnings in docs +! grep -q "ERROR:" target/docs/sphinx-doctest.warnings.log || exit 1 +! grep -q "WARNING:" target/docs/sphinx-doctest.warnings.log || exit 1 + # Message is useful only when this script is run locally. In a remote # test environment, this path will be removed when the test completes. echo "Browse to file://$PWD/target/docs/_build/index.html" - -# Fail if there are errors or warnings in docs -! grep -q "ERROR:" target/docs/sphinx-build.warnings.log -! grep -q "WARNING:" target/docs/sphinx-build.warnings.log http://git-wip-us.apache.org/repos/asf/beam/blob/e1baf55d/sdks/python/tox.ini ---------------------------------------------------------------------- diff --git a/sdks/python/tox.ini b/sdks/python/tox.ini index eff91fe..fea3854 100644 --- a/sdks/python/tox.ini +++ b/sdks/python/tox.ini @@ -99,6 +99,7 @@ deps= nose==1.3.7 grpcio-tools==1.3.5 Sphinx==1.5.5 + sphinx_rtd_theme==0.2.4 commands = pip install -e .[test,gcp,docs] {toxinidir}/generate_pydoc.sh