├── MANIFEST.in
├── doc
└── sphinx
│ ├── html
│ ├── .nojekyll
│ ├── objects.inv
│ ├── _static
│ │ ├── up.png
│ │ ├── down.png
│ │ ├── file.png
│ │ ├── minus.png
│ │ ├── plus.png
│ │ ├── comment.png
│ │ ├── ajax-loader.gif
│ │ ├── up-pressed.png
│ │ ├── comment-close.png
│ │ ├── down-pressed.png
│ │ ├── comment-bright.png
│ │ ├── pygments.css
│ │ ├── classic.css
│ │ ├── sidebar.js
│ │ ├── doctools.js
│ │ ├── underscore.js
│ │ └── basic.css
│ ├── .buildinfo
│ ├── _sources
│ │ ├── index.rst.txt
│ │ ├── pyment_doc.rst.txt
│ │ └── pyment.rst.txt
│ ├── search.html
│ ├── py-modindex.html
│ ├── index.html
│ └── searchindex.js
│ ├── source
│ ├── index.rst
│ ├── pyment_doc.rst
│ └── conf.py
│ ├── Makefile
│ └── make.bat
├── tests
├── issue30.py
├── issue32.py
├── free_cases.py
├── issue58.py
├── issue47.py
├── issue69.py
├── issue22.py
├── __init__.py
├── issue9.py
├── issue51.py
├── issue46.py
├── issue90.py
├── issue83.py
├── issue83.py.patch
├── issue99.py.patch
├── issue69.py.patch
├── issue99.py
├── issue49.py
├── issue88.py
├── docs_already_reST.py
├── docs_already_javadoc.py
├── issue90.py.patch
├── docs_already_google.py
├── issue10.py.patch.expected
├── issue46.py.patch.expected
├── docs_already_numpydoc.py
├── params.py
├── issue15.py
├── issue10.py
├── issue88.py.patch
├── issue15.py.patch.expected
├── issue85.py
├── issue95.py
├── issue34.py
├── issue95.py.patch
├── issue85.py.patch
├── params.py.patch.reST.expected
├── params.py.patch.javadoc.expected
├── issue93.py
├── params.py.patch.google.expected
├── params.py.patch.numpydoc.expected
├── origin_test.py
├── test_pyment.py
├── test_pyment_cases.py
├── issue93.py.patch
├── test_issues.py
└── test_app.py
├── .coveralls.yml
├── pyment.conf
├── setup.cfg
├── .gitignore
├── pyment
├── __init__.py
└── pymentapp.py
├── .travis.yml
├── .appveyor.yml
├── setup.py
├── CHANGELOG
├── example.py
├── example_numpydoc.py.patch
├── example_javadoc.py.patch
└── README.rst
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | graft tests
2 |
--------------------------------------------------------------------------------
/doc/sphinx/html/.nojekyll:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/issue30.py:
--------------------------------------------------------------------------------
1 | def hello_world(a=22, b='hello'):
2 | return 42
--------------------------------------------------------------------------------
/tests/issue32.py:
--------------------------------------------------------------------------------
1 | def hello_world(a=22, b='hello'):
2 | return 42
--------------------------------------------------------------------------------
/.coveralls.yml:
--------------------------------------------------------------------------------
1 | parallel: true # if the CI is running your build in parallel
2 |
--------------------------------------------------------------------------------
/tests/free_cases.py:
--------------------------------------------------------------------------------
1 | def func1():
2 | """Function 1 no parameter"""
3 | pass
4 |
5 |
--------------------------------------------------------------------------------
/doc/sphinx/html/objects.inv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dadadel/pyment/HEAD/doc/sphinx/html/objects.inv
--------------------------------------------------------------------------------
/tests/issue58.py:
--------------------------------------------------------------------------------
1 | def func(param): # some comment
2 | """some docstring"""
3 | pass
4 |
5 |
6 |
--------------------------------------------------------------------------------
/doc/sphinx/html/_static/up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dadadel/pyment/HEAD/doc/sphinx/html/_static/up.png
--------------------------------------------------------------------------------
/doc/sphinx/html/_static/down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dadadel/pyment/HEAD/doc/sphinx/html/_static/down.png
--------------------------------------------------------------------------------
/doc/sphinx/html/_static/file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dadadel/pyment/HEAD/doc/sphinx/html/_static/file.png
--------------------------------------------------------------------------------
/doc/sphinx/html/_static/minus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dadadel/pyment/HEAD/doc/sphinx/html/_static/minus.png
--------------------------------------------------------------------------------
/doc/sphinx/html/_static/plus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dadadel/pyment/HEAD/doc/sphinx/html/_static/plus.png
--------------------------------------------------------------------------------
/tests/issue47.py:
--------------------------------------------------------------------------------
1 | def func():
2 | """Description
3 | in two lines
4 |
5 | """
6 | pass
7 |
8 |
9 |
--------------------------------------------------------------------------------
/doc/sphinx/html/_static/comment.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dadadel/pyment/HEAD/doc/sphinx/html/_static/comment.png
--------------------------------------------------------------------------------
/doc/sphinx/html/_static/ajax-loader.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dadadel/pyment/HEAD/doc/sphinx/html/_static/ajax-loader.gif
--------------------------------------------------------------------------------
/doc/sphinx/html/_static/up-pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dadadel/pyment/HEAD/doc/sphinx/html/_static/up-pressed.png
--------------------------------------------------------------------------------
/doc/sphinx/html/_static/comment-close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dadadel/pyment/HEAD/doc/sphinx/html/_static/comment-close.png
--------------------------------------------------------------------------------
/doc/sphinx/html/_static/down-pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dadadel/pyment/HEAD/doc/sphinx/html/_static/down-pressed.png
--------------------------------------------------------------------------------
/tests/issue69.py:
--------------------------------------------------------------------------------
1 | def plot_outlier(inlier, outlier, outlier_rgb = [1, 0, 0]):
2 | """Plot the outlier of ..."""
3 | pass
4 |
--------------------------------------------------------------------------------
/doc/sphinx/html/_static/comment-bright.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dadadel/pyment/HEAD/doc/sphinx/html/_static/comment-bright.png
--------------------------------------------------------------------------------
/pyment.conf:
--------------------------------------------------------------------------------
1 | first_line = false
2 | quotes = '''
3 | output_style = numpydoc
4 | input_style = auto
5 | init2class = false
6 | indent = 4
7 |
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [metadata]
2 | description-file = README.rst
3 |
4 | [bdist_wheel]
5 | universal=1
6 |
7 | [coverage:run]
8 | source = tests
9 |
--------------------------------------------------------------------------------
/tests/issue22.py:
--------------------------------------------------------------------------------
1 | class Issue22(object):
2 | """Test class for issue 22"""
3 |
4 | def __init__(self, param1):
5 | pass
6 |
--------------------------------------------------------------------------------
/tests/__init__.py:
--------------------------------------------------------------------------------
1 | import os
2 | import unittest
3 |
4 | current_dir = os.path.dirname(__file__)
5 | test_all = unittest.TestLoader().discover(current_dir)
6 |
--------------------------------------------------------------------------------
/tests/issue9.py:
--------------------------------------------------------------------------------
1 | def func(p):
2 | """
3 | :param p: blabla
4 | :type p: ptype
5 | :return: smthg
6 | :rtype: ret type
7 | """
8 | pass
9 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled files
2 | __pycache__/
3 | *.py[cod]
4 | build
5 |
6 | # Packaging related files
7 | *.egg
8 | *.egg-info
9 |
10 | # pycharm
11 | .idea/
12 |
--------------------------------------------------------------------------------
/tests/issue51.py:
--------------------------------------------------------------------------------
1 | def foo():
2 | """Bar bar bar.
3 |
4 | Args:
5 |
6 | Returns:
7 |
8 | Raises:
9 | test
10 |
11 | """
12 | pass
13 |
--------------------------------------------------------------------------------
/tests/issue46.py:
--------------------------------------------------------------------------------
1 | def func1(param1=[1, None, "hehe"]):
2 | pass
3 |
4 |
5 | def func2(param1=(1, None, "hehe")):
6 | pass
7 |
8 |
9 | def func3(param1={0: 1, "a": None}):
10 | pass
11 |
12 |
--------------------------------------------------------------------------------
/pyment/__init__.py:
--------------------------------------------------------------------------------
1 | from .pyment import PyComment, __version__, __copyright__, __author__, __licence__
2 |
3 | name = "pyment"
4 |
5 | __all__ = ['PyComment', '__version__', '__copyright__', '__author__', '__licence__']
6 |
--------------------------------------------------------------------------------
/doc/sphinx/html/.buildinfo:
--------------------------------------------------------------------------------
1 | # Sphinx build info version 1
2 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
3 | config: b52c7e60bc3c5c9e2dd3dfcfe2ec8fab
4 | tags: 645f666f9bcd5a90fca523b33c5a78b7
5 |
--------------------------------------------------------------------------------
/tests/issue90.py:
--------------------------------------------------------------------------------
1 | def foo():
2 | __doc__ = """\
3 | Foo"""
4 |
5 |
6 | def bar(param):
7 | r"""this is a docstring
8 | """
9 |
10 |
11 | def foobar():
12 | u"""this is a docstring
13 | """
14 |
15 |
16 | def no_docs():
17 | something = '''bla bla bla'''
18 |
--------------------------------------------------------------------------------
/tests/issue83.py:
--------------------------------------------------------------------------------
1 | class Foo:
2 | def __init__(self):
3 | """Some init docstring"""
4 | pass
5 |
6 | class Bar:
7 | def __repr__(self):
8 | """Some repr docstring"""
9 | return 'Foo()'
10 |
11 | def __init__(self):
12 | """Some docstring"""
13 | pass
14 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: python
2 | python:
3 | - "3.6"
4 | - "3.7"
5 | - "3.8"
6 | - "3.9"
7 |
8 | # command to install dependencies
9 | install:
10 | - pip install coverage
11 | - pip install coveralls
12 |
13 | # command to run tests
14 | script:
15 | - coverage run setup.py test
16 |
17 | after_success:
18 | - coveralls
19 |
--------------------------------------------------------------------------------
/tests/issue83.py.patch:
--------------------------------------------------------------------------------
1 | --- a/issue83.py
2 | +++ b/issue83.py
3 | @@ -1,9 +1,11 @@
4 | class Foo:
5 | + """ """
6 | def __init__(self):
7 | """Some init docstring"""
8 | pass
9 |
10 | class Bar:
11 | + """ """
12 | def __repr__(self):
13 | """Some repr docstring"""
14 | return 'Foo()'
15 |
--------------------------------------------------------------------------------
/tests/issue99.py.patch:
--------------------------------------------------------------------------------
1 | --- a/issue99.py
2 | +++ b/issue99.py
3 | @@ -12,11 +12,9 @@
4 | def func2(param1):
5 | """Description
6 |
7 | - Args:
8 | - param1(str):
9 | -
10 | - Returns:
11 | - the return value
12 | + :param param1:
13 | + :type param1: str
14 | + :returns: the return value
15 |
16 | """
17 | pass
18 |
--------------------------------------------------------------------------------
/tests/issue69.py.patch:
--------------------------------------------------------------------------------
1 | --- a/issue69.py
2 | +++ b/issue69.py
3 | @@ -1,3 +1,9 @@
4 | def plot_outlier(inlier, outlier, outlier_rgb = [1, 0, 0]):
5 | - """Plot the outlier of ..."""
6 | + """Plot the outlier of ...
7 | +
8 | + :param inlier:
9 | + :param outlier:
10 | + :param outlier_rgb: (Default value = [1, 0, 0])
11 | +
12 | + """
13 | pass
14 |
--------------------------------------------------------------------------------
/tests/issue99.py:
--------------------------------------------------------------------------------
1 | def func1(param1):
2 | """Description
3 |
4 | :param param1:
5 | :type param1: str
6 | :returns: the return value
7 |
8 | """
9 | pass
10 |
11 |
12 | def func2(param1):
13 | """Description
14 |
15 | Args:
16 | param1(str):
17 |
18 | Returns:
19 | the return value
20 |
21 | """
22 | pass
23 |
24 |
25 |
--------------------------------------------------------------------------------
/tests/issue49.py:
--------------------------------------------------------------------------------
1 | def func1(param1):
2 | """Function to test issue #49
3 |
4 | Parameters
5 | ----------
6 | param1 : object
7 | Description of param1
8 |
9 | Returns
10 | -------
11 | None
12 | Description for return value
13 |
14 | Raises
15 | ------
16 | AssertionError
17 | Raises an error if run
18 |
19 |
20 | """
21 | assert False
22 |
--------------------------------------------------------------------------------
/tests/issue88.py:
--------------------------------------------------------------------------------
1 | def std_func(param="foo", bar=42):
2 | pass
3 |
4 |
5 | async def async_func(param='foo', bar=42):
6 | return param
7 |
8 |
9 | async def async_func2():
10 | raise Exception
11 |
12 |
13 | async def async_func3(param1, param2=None):
14 | """
15 | some comment
16 | :param param1: my parameter 1
17 | :param param2: my second param
18 | :return: nothing
19 | :rtype: None
20 | """
21 | pass
22 |
--------------------------------------------------------------------------------
/tests/docs_already_reST.py:
--------------------------------------------------------------------------------
1 | def func1(param1):
2 | """Function 1
3 | with 1 param
4 |
5 | :param param1: 1st parameter
6 | :type param1: type
7 | :returns: None
8 |
9 | """
10 | return None
11 |
12 |
13 | def func2(param1, param2):
14 | """Function 2
15 | with 2 params
16 |
17 | :param param1: 1st parameter
18 | :type param1: type
19 | :param param2: 2nd parameter
20 |
21 | """
22 | pass
23 |
24 |
25 |
--------------------------------------------------------------------------------
/tests/docs_already_javadoc.py:
--------------------------------------------------------------------------------
1 | def func1(param1):
2 | """Function 1
3 | with 1 param
4 |
5 | @param param1: 1st parameter
6 | @type param1: type
7 | @return: None
8 |
9 | """
10 | return None
11 |
12 |
13 | def func2(param1, param2):
14 | """Function 2
15 | with 2 params
16 |
17 | @param param1: 1st parameter
18 | @type param1: type
19 | @param param2: 2nd parameter
20 |
21 | """
22 | pass
23 |
24 |
25 |
--------------------------------------------------------------------------------
/tests/issue90.py.patch:
--------------------------------------------------------------------------------
1 | --- a/issue90.py
2 | +++ b/issue90.py
3 | @@ -1,17 +1,21 @@
4 | def foo():
5 | + """ """
6 | __doc__ = """\
7 | Foo"""
8 |
9 |
10 | def bar(param):
11 | r"""this is a docstring
12 | +
13 | + :param param:
14 | +
15 | """
16 |
17 |
18 | def foobar():
19 | - u"""this is a docstring
20 | - """
21 | + u"""this is a docstring"""
22 |
23 |
24 | def no_docs():
25 | + """ """
26 | something = '''bla bla bla'''
27 |
--------------------------------------------------------------------------------
/tests/docs_already_google.py:
--------------------------------------------------------------------------------
1 | def func1(param1):
2 | """Function 1
3 | with 1 param
4 |
5 | Args:
6 | param1 (type): 1st parameter
7 |
8 | Returns:
9 | None
10 |
11 | Raises:
12 | Exception: an exception
13 |
14 | """
15 | return None
16 |
17 |
18 | def func2(param1, param2):
19 | """Function 2
20 | with 2 params
21 |
22 | Args:
23 | param1 (type): 1st parameter
24 | param2: 2nd parameter
25 |
26 | Returns:
27 |
28 | """
29 | pass
30 |
31 |
32 |
--------------------------------------------------------------------------------
/doc/sphinx/source/index.rst:
--------------------------------------------------------------------------------
1 | .. Pyment documentation master file, created by
2 | sphinx-quickstart on Wed Sep 27 21:39:14 2017.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | Welcome to Pyment's documentation!
7 | ==================================
8 |
9 | .. toctree::
10 | :maxdepth: 1
11 |
12 | pyment
13 |
14 | pyment_doc
15 |
16 | Indices and tables
17 | ==================
18 |
19 | * :ref:`genindex`
20 | * :ref:`modindex`
21 | * :ref:`search`
22 |
--------------------------------------------------------------------------------
/doc/sphinx/html/_sources/index.rst.txt:
--------------------------------------------------------------------------------
1 | .. Pyment documentation master file, created by
2 | sphinx-quickstart on Wed Sep 27 21:39:14 2017.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | Welcome to Pyment's documentation!
7 | ==================================
8 |
9 | .. toctree::
10 | :maxdepth: 1
11 |
12 | pyment
13 |
14 | pyment_doc
15 |
16 | Indices and tables
17 | ==================
18 |
19 | * :ref:`genindex`
20 | * :ref:`modindex`
21 | * :ref:`search`
22 |
--------------------------------------------------------------------------------
/tests/issue10.py.patch.expected:
--------------------------------------------------------------------------------
1 | --- a/issue10.py
2 | +++ b/issue10.py
3 | @@ -12,12 +12,12 @@
4 |
5 |
6 | def init_test():
7 | - '''
8 | - Only working when in WinPython root directory.
9 | + """Only working when in WinPython root directory.
10 |
11 | - Returns:
12 | - maske, data0, data1, no_motion, motion
13 | - '''
14 | +
15 | + :returns: maske, data0, data1, no_motion, motion
16 | +
17 | + """
18 | maske = read_mask('./MRR/Testdaten/55_mask.bmp')
19 | display(maske)
20 | data0 = read_dicom_set('./MRR/Testdaten/188_13-12-10_56_1',
21 |
--------------------------------------------------------------------------------
/tests/issue46.py.patch.expected:
--------------------------------------------------------------------------------
1 | # Patch generated by Pyment v0.3.2-dev4
2 |
3 | --- a/issue46.py
4 | +++ b/issue46.py
5 | @@ -1,11 +1,26 @@
6 | def func1(param1=[1, None, "hehe"]):
7 | + """
8 | +
9 | + :param param1: (Default value = [1, None, "hehe"])
10 | +
11 | + """
12 | pass
13 |
14 |
15 | def func2(param1=(1, None, "hehe")):
16 | + """
17 | +
18 | + :param param1: (Default value = (1, None, "hehe"))
19 | +
20 | + """
21 | pass
22 |
23 |
24 | def func3(param1={0: 1, "a": None}):
25 | + """
26 | +
27 | + :param param1: (Default value = {0: 1, "a": None})
28 | +
29 | + """
30 | pass
31 |
32 |
--------------------------------------------------------------------------------
/tests/docs_already_numpydoc.py:
--------------------------------------------------------------------------------
1 | def func1(param1):
2 | """Function 1
3 | with 1 param
4 |
5 | Parameters
6 | ----------
7 | param1 : type
8 | 1st parameter
9 |
10 | Returns
11 | -------
12 | string
13 | a message
14 |
15 | Raises
16 | ------
17 | KeyError
18 | when a key error
19 | """
20 | return "huh"
21 |
22 |
23 | def func2(param1, param2):
24 | """Function 2
25 | with 2 params
26 |
27 | Parameters
28 | ----------
29 | param1 : type
30 | 1st parameter
31 | param2 :
32 | 2nd parameter
33 |
34 | Returns
35 | -------
36 |
37 | """
38 | pass
39 |
40 |
41 |
--------------------------------------------------------------------------------
/doc/sphinx/Makefile:
--------------------------------------------------------------------------------
1 | # Minimal makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line.
5 | SPHINXOPTS =
6 | SPHINXBUILD = python -msphinx
7 | SPHINXPROJ = Pyment
8 | SOURCEDIR = source
9 | BUILDDIR = build
10 |
11 | # Put it first so that "make" without argument is like "make help".
12 | help:
13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14 |
15 | .PHONY: help Makefile
16 |
17 | # Catch-all target: route all unknown targets to Sphinx using the new
18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19 | %: Makefile
20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
--------------------------------------------------------------------------------
/tests/params.py:
--------------------------------------------------------------------------------
1 | def func1():
2 | pass
3 |
4 |
5 | def func2(param1):
6 | pass
7 |
8 |
9 | def func3(param1, param2):
10 | pass
11 |
12 |
13 | def func3(param1, param2, param3):
14 | pass
15 |
16 |
17 | def func4(param1=123):
18 | pass
19 |
20 |
21 | def func5(param1, param2=123):
22 | pass
23 |
24 |
25 | def func6(param1, param2, param3=123):
26 | pass
27 |
28 |
29 | def func7(param1, param2=None, param3=123):
30 | pass
31 |
32 |
33 | def func8(param1=123, param2=+456, param3="!:@"):
34 | pass
35 |
36 |
37 | def func9(param1=func1(), param2="stuff"):
38 | pass
39 |
40 |
41 | def func10(param1=func1(), param2="stuff"): # comments with (parentheses):
42 | pass
43 |
--------------------------------------------------------------------------------
/tests/issue15.py:
--------------------------------------------------------------------------------
1 | def func(param1=True, param2='default val'):
2 | '''Description of func with docstring groups style.
3 |
4 | Params:
5 | param1 - descr of param1 that has True for default value.
6 | param2 - descr of param2
7 |
8 | Returns:
9 | some value
10 |
11 | Raises:
12 | keyError: raises key exception
13 | TypeError: raises type exception
14 |
15 | '''
16 | pass
17 |
18 | class A:
19 | def method(self, param1, param2=None):
20 | pass
21 |
22 | if __name__ == "__main__":
23 | import os
24 | from pyment import PyComment
25 |
26 | filename = __file__
27 | print filename
28 |
29 | c = PyComment(filename)
30 | c.proceed()
31 | c.diff_to_file(os.path.basename(filename) + ".patch")
32 | for s in c.get_output_docs():
33 | print(s)
34 |
35 |
--------------------------------------------------------------------------------
/tests/issue10.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | __version__ = '1.3.1'
4 | # $Source$
5 |
6 | #Some commentary
7 |
8 |
9 | from .mod1 import *
10 | #import mod2
11 | from . import mod3, mod4
12 |
13 |
14 | def init_test():
15 | '''
16 | Only working when in WinPython root directory.
17 |
18 | Returns:
19 | maske, data0, data1, no_motion, motion
20 | '''
21 | maske = read_mask('./MRR/Testdaten/55_mask.bmp')
22 | display(maske)
23 | data0 = read_dicom_set('./MRR/Testdaten/188_13-12-10_56_1',
24 | unwrap=True, mask=maske, verbose=False)
25 | data1 = read_dicom_set('./MRR/Testdaten/188_13-12-10_54_1',
26 | unwrap=True, mask=maske, verbose=False)
27 | no_motion = mean(data0, axis=0)
28 | motion = mean(data1, axis=0)
29 | return maske , data0, data1, no_motion, motion
--------------------------------------------------------------------------------
/tests/issue88.py.patch:
--------------------------------------------------------------------------------
1 | --- a/issue88.py
2 | +++ b/issue88.py
3 | @@ -1,21 +1,35 @@
4 | def std_func(param="foo", bar=42):
5 | + """
6 | +
7 | + :param param: (Default value = "foo")
8 | + :param bar: (Default value = 42)
9 | +
10 | + """
11 | pass
12 |
13 |
14 | async def async_func(param='foo', bar=42):
15 | + """
16 | +
17 | + :param param: (Default value = 'foo')
18 | + :param bar: (Default value = 42)
19 | +
20 | + """
21 | return param
22 |
23 |
24 | async def async_func2():
25 | + """ """
26 | raise Exception
27 |
28 |
29 | async def async_func3(param1, param2=None):
30 | - """
31 | - somme comment
32 | + """somme comment
33 | +
34 | :param param1: my parameter 1
35 | - :param param2: my second param
36 | - :return: nothing
37 | + :param param2: my second param (Default value = None)
38 | + :returns: nothing
39 | :rtype: None
40 | +
41 | """
42 | pass
43 |
--------------------------------------------------------------------------------
/doc/sphinx/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | pushd %~dp0
4 |
5 | REM Command file for Sphinx documentation
6 |
7 | if "%SPHINXBUILD%" == "" (
8 | set SPHINXBUILD=python -msphinx
9 | )
10 | set SOURCEDIR=source
11 | set BUILDDIR=build
12 | set SPHINXPROJ=Pyment
13 |
14 | if "%1" == "" goto help
15 |
16 | %SPHINXBUILD% >NUL 2>NUL
17 | if errorlevel 9009 (
18 | echo.
19 | echo.The Sphinx module was not found. Make sure you have Sphinx installed,
20 | echo.then set the SPHINXBUILD environment variable to point to the full
21 | echo.path of the 'sphinx-build' executable. Alternatively you may add the
22 | echo.Sphinx directory to PATH.
23 | echo.
24 | echo.If you don't have Sphinx installed, grab it from
25 | echo.http://sphinx-doc.org/
26 | exit /b 1
27 | )
28 |
29 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
30 | goto end
31 |
32 | :help
33 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
34 |
35 | :end
36 | popd
37 |
--------------------------------------------------------------------------------
/tests/issue15.py.patch.expected:
--------------------------------------------------------------------------------
1 | --- a/issue15.py
2 | +++ b/issue15.py
3 | @@ -1,22 +1,24 @@
4 | def func(param1=True, param2='default val'):
5 | - '''Description of func with docstring groups style.
6 | + """Description of func with docstring groups style.
7 |
8 | - Params:
9 | - param1 - descr of param1 that has True for default value.
10 | - param2 - descr of param2
11 | + :param param1: descr of param1 that has True for default value
12 | + :param param2: descr of param2 (Default value = 'default val')
13 | + :returns: some value
14 | + :raises keyError: raises key exception
15 | + :raises TypeError: raises type exception
16 |
17 | - Returns:
18 | - some value
19 | -
20 | - Raises:
21 | - keyError: raises key exception
22 | - TypeError: raises type exception
23 | -
24 | - '''
25 | + """
26 | pass
27 |
28 | class A:
29 | + """ """
30 | def method(self, param1, param2=None):
31 | + """
32 | +
33 | + :param param1:
34 | + :param param2: (Default value = None)
35 | +
36 | + """
37 | pass
38 |
39 | if __name__ == "__main__":
40 |
--------------------------------------------------------------------------------
/doc/sphinx/source/pyment_doc.rst:
--------------------------------------------------------------------------------
1 | Source code documentation
2 | #########################
3 |
4 | .. contents:: Table of content
5 |
6 | Module pyment
7 | =============
8 |
9 | This is the module that can be imported in a Python program in order to use Pyment with the class `PyComment`.
10 |
11 | .. automodule:: pyment
12 |
13 | PyComment class
14 | ---------------
15 | .. autoclass:: PyComment
16 | :members:
17 | :special-members:
18 |
19 |
20 | Module docstring
21 | ================
22 |
23 | This module is used by `pyment` module and is not intended to be used out of *Pyment*. To use *Pyment* in your project,
24 | you may want to use `pyment.PyComment` (see above).
25 |
26 | .. automodule:: docstring
27 |
28 | NumpydocTools class
29 | -------------------
30 | .. autoclass:: NumpydocTools
31 | :members:
32 | :special-members:
33 |
34 | GoogledocTools class
35 | --------------------
36 |
37 | .. autoclass:: GoogledocTools
38 | :members:
39 | :special-members:
40 |
41 | DocsTools class
42 | ---------------
43 |
44 | .. autoclass:: DocsTools
45 | :members:
46 | :special-members:
47 |
48 | Docstring class
49 | ---------------
50 |
51 | .. autoclass:: DocString
52 | :members:
53 | :special-members:
54 |
--------------------------------------------------------------------------------
/doc/sphinx/html/_sources/pyment_doc.rst.txt:
--------------------------------------------------------------------------------
1 | Source code documentation
2 | #########################
3 |
4 | .. contents:: Table of content
5 |
6 | Module pyment
7 | =============
8 |
9 | This is the module that can be imported in a Python program in order to use Pyment with the class `PyComment`.
10 |
11 | .. automodule:: pyment
12 |
13 | PyComment class
14 | ---------------
15 | .. autoclass:: PyComment
16 | :members:
17 | :special-members:
18 |
19 |
20 | Module docstring
21 | ================
22 |
23 | This module is used by `pyment` module and is not intended to be used out of *Pyment*. To use *Pyment* in your project,
24 | you may want to use `pyment.PyComment` (see above).
25 |
26 | .. automodule:: docstring
27 |
28 | NumpydocTools class
29 | -------------------
30 | .. autoclass:: NumpydocTools
31 | :members:
32 | :special-members:
33 |
34 | GoogledocTools class
35 | --------------------
36 |
37 | .. autoclass:: GoogledocTools
38 | :members:
39 | :special-members:
40 |
41 | DocsTools class
42 | ---------------
43 |
44 | .. autoclass:: DocsTools
45 | :members:
46 | :special-members:
47 |
48 | Docstring class
49 | ---------------
50 |
51 | .. autoclass:: DocString
52 | :members:
53 | :special-members:
54 |
--------------------------------------------------------------------------------
/tests/issue85.py:
--------------------------------------------------------------------------------
1 | def func(param_file, mask):
2 | """
3 | :param lxml.etree.ElementTree param_file: xml-element tree
4 | obtained from the file.
5 | :param str mask: Name of mask to be considered.
6 | """
7 | pass
8 |
9 |
10 | def func2(param1: str, param2):
11 | """
12 | :param str param1: description 1
13 | :param str param2: description 2
14 | :returns: description return
15 | """
16 | pass
17 |
18 |
19 | def func3(param1: str, param2):
20 | """
21 | :param param1: description 1 is
22 | a multiline description
23 | :type param1: str
24 | :param str param2: description 2
25 | :returns: description return
26 | """
27 | pass
28 |
29 |
30 | def func4(param1, param2):
31 | """
32 | :param param1: description 1
33 | :type param1: str
34 | :param str param2: description 2
35 | :returns: description return
36 | """
37 | pass
38 |
39 |
40 | def func5(param1, param2):
41 | """
42 | :param int param1: description 1
43 | :type param1: str
44 | :param param2: description 2
45 | :returns: description return
46 | """
47 | pass
48 |
49 |
50 | def func6(param1: list, param2):
51 | """
52 | :param int param1: description 1
53 | :type param1: str
54 | :param param2: description 2
55 | :returns: description return
56 | """
57 | pass
58 |
59 |
--------------------------------------------------------------------------------
/.appveyor.yml:
--------------------------------------------------------------------------------
1 | environment:
2 |
3 | matrix:
4 |
5 | # For Python versions available on Appveyor, see
6 | # http://www.appveyor.com/docs/installed-software#python
7 | # The list here is complete (excluding Python 2.6, which
8 | # isn't covered by this document) at the time of writing.
9 |
10 | - PYTHON: "C:\\Miniconda"
11 | - PYTHON: "C:\\Miniconda-x64"
12 | - PYTHON: "C:\\Python36-x64"
13 | - PYTHON: "C:\\Miniconda36-x64"
14 | - PYTHON: "C:\\Python37-x64"
15 | - PYTHON: "C:\\Miniconda37-x64"
16 | - PYTHON: "C:\\Python38-x64"
17 | - PYTHON: "C:\\Miniconda38-x64"
18 | - PYTHON: "C:\\Python39-x64"
19 | - PYTHON: "C:\\Miniconda39-x64"
20 |
21 | install:
22 | # We need wheel installed to build wheels
23 | - "pip install coverage"
24 | - "pip install coveralls"
25 |
26 | build: off
27 |
28 | test_script:
29 | # Put your test command here.
30 | - "coverage run setup.py test"
31 |
32 | #after_test:
33 | # This step builds your wheels.
34 | # Again, you only need build.cmd if you're building C extensions for
35 | # 64-bit Python 3.3/3.4. And you need to use %PYTHON% to get the correct
36 | # interpreter
37 |
38 | #artifacts:
39 | # bdist_wheel puts your built wheel in the dist directory
40 |
41 | #on_success:
42 | # You can use this step to upload your artifacts to a public website.
43 | # See Appveyor's documentation for more details. Or you can simply
44 | # access your wheels from the Appveyor "artifacts" tab for your build.
45 |
--------------------------------------------------------------------------------
/tests/issue95.py:
--------------------------------------------------------------------------------
1 | def func1(param1):
2 | """Description
3 |
4 | :param param1:
5 | :returns: the return value
6 | """
7 | pass
8 |
9 |
10 | def func2(param1):
11 | """Description
12 |
13 | :param param1: param's message
14 | :return: the return value
15 | """
16 | pass
17 |
18 |
19 | def func3(param1):
20 | """Description
21 |
22 | :param param1:
23 | :returns: the return value
24 | """
25 | pass
26 |
27 |
28 | def func4(param1, param2):
29 | """Description
30 |
31 | :param param1:
32 | :param param2:
33 | :returns: the return value
34 | """
35 | pass
36 |
37 |
38 | def func5(param1, param2):
39 | """Description
40 |
41 | :param param1:
42 | :type param1: str
43 | :returns: the return value
44 | """
45 | pass
46 |
47 |
48 | def func6(param1, param2):
49 | """Description
50 |
51 | :param param1: parameter description
52 | :param param2:
53 | :returns: the return value
54 | """
55 | pass
56 |
57 |
58 | def func7(param1):
59 | """Description
60 |
61 | Args:
62 | param1:
63 | Returns:
64 | the return value
65 | """
66 | pass
67 |
68 |
69 | def func8(param1):
70 | """Description
71 |
72 | :param param1:
73 | """
74 | pass
75 |
76 |
77 | def func9(param1: str, param2):
78 | """Description
79 |
80 | :type param1:
81 | :param param2:
82 | :returns: foobar
83 |
84 | """
85 | pass
86 |
87 |
88 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | from setuptools import setup
4 | from os import path
5 | import pyment
6 |
7 |
8 | curr_dir = path.abspath(path.dirname(__file__))
9 |
10 | with open(path.join(curr_dir, "README.rst")) as f:
11 | long_desc = f.read()
12 |
13 |
14 | setup(name='Pyment',
15 | version=pyment.__version__,
16 | description='Generate/convert automatically the docstrings from code signature',
17 | long_description=long_desc,
18 | long_description_content_type="text/x-rst",
19 | author='A. Daouzli',
20 | author_email='dadel@hadoly.fr',
21 | license='GPLv3',
22 | keywords="pyment docstring numpydoc googledoc restructuredtext epydoc epytext javadoc development generate auto",
23 | platforms=['any'],
24 | classifiers=[
25 | 'Intended Audience :: Developers',
26 | 'Topic :: Documentation',
27 | 'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
28 | 'Programming Language :: Python :: 3',
29 | 'Programming Language :: Python :: 3.6',
30 | 'Programming Language :: Python :: 3.7',
31 | 'Programming Language :: Python :: 3.8',
32 | 'Programming Language :: Python :: 3.9',
33 | ],
34 | url='https://github.com/dadadel/pyment',
35 | packages=['pyment'],
36 | test_suite='tests.test_all',
37 | entry_points={
38 | 'console_scripts': [
39 | 'pyment = pyment.pymentapp:main'
40 | ]
41 | },
42 | )
43 |
--------------------------------------------------------------------------------
/tests/issue34.py:
--------------------------------------------------------------------------------
1 | def func(a, b):
2 | """desc
3 |
4 | :param a:
5 | :param b:
6 |
7 | """
8 | pass
9 |
10 | def func(a, b):
11 | """desc
12 |
13 | :param a:
14 | :type a:
15 | :param b:
16 | :type b:
17 |
18 | """
19 | pass
20 |
21 | def func(a, b):
22 | """desc
23 |
24 | :param a:
25 | :type a: str
26 | :param b:
27 | :type b: str
28 |
29 | """
30 | pass
31 |
32 | def func(a, b):
33 | """desc
34 |
35 | :param a:
36 | :type a: str
37 | :param b:
38 | :type b:
39 |
40 | """
41 | pass
42 |
43 | def func(a, b):
44 | """desc
45 |
46 | :param a: desc a
47 | :param b:
48 |
49 | """
50 | pass
51 |
52 | def func(a, b):
53 | """desc
54 |
55 | :param b:
56 | :param a: desc a
57 |
58 | """
59 | pass
60 |
61 | def func(a, b):
62 | """desc
63 |
64 | :param a:
65 | :param b: desc b
66 |
67 | """
68 | pass
69 |
70 | def func(a, b, c):
71 | """desc
72 |
73 | :param a:
74 | :param b:
75 | :param c:
76 |
77 | """
78 | pass
79 |
80 | def func(a, b, c):
81 | """desc
82 |
83 | :param a:
84 | :param b: desc b
85 | :param c:
86 |
87 | """
88 | pass
89 |
90 | def func(a, b, c):
91 | """desc
92 |
93 | :param a: desc a
94 | :param b:
95 | :param c:
96 |
97 | """
98 | pass
99 |
100 | def func(a, b, c):
101 | """desc
102 |
103 | :param a: desc a
104 | :param b:
105 | :param c: desc c
106 |
107 | """
108 | pass
109 |
110 |
--------------------------------------------------------------------------------
/tests/issue95.py.patch:
--------------------------------------------------------------------------------
1 | --- a/issue95.py
2 | +++ b/issue95.py
3 | @@ -3,6 +3,7 @@
4 |
5 | :param param1:
6 | :returns: the return value
7 | +
8 | """
9 | pass
10 |
11 | @@ -11,7 +12,8 @@
12 | """Description
13 |
14 | :param param1: param's message
15 | - :return: the return value
16 | + :returns: the return value
17 | +
18 | """
19 | pass
20 |
21 | @@ -19,8 +21,9 @@
22 | def func3(param1):
23 | """Description
24 |
25 | - :param param1:
26 | + :param param1:
27 | :returns: the return value
28 | +
29 | """
30 | pass
31 |
32 | @@ -31,6 +34,7 @@
33 | :param param1:
34 | :param param2:
35 | :returns: the return value
36 | +
37 | """
38 | pass
39 |
40 | @@ -40,7 +44,9 @@
41 |
42 | :param param1:
43 | :type param1: str
44 | + :param param2:
45 | :returns: the return value
46 | +
47 | """
48 | pass
49 |
50 | @@ -51,6 +57,7 @@
51 | :param param1: parameter description
52 | :param param2:
53 | :returns: the return value
54 | +
55 | """
56 | pass
57 |
58 | @@ -58,10 +65,9 @@
59 | def func7(param1):
60 | """Description
61 |
62 | - Args:
63 | - param1:
64 | - Returns:
65 | - the return value
66 | + :param param1:
67 | + :returns: the return value
68 | +
69 | """
70 | pass
71 |
72 | @@ -70,6 +76,7 @@
73 | """Description
74 |
75 | :param param1:
76 | +
77 | """
78 | pass
79 |
80 | @@ -77,7 +84,8 @@
81 | def func9(param1: str, param2):
82 | """Description
83 |
84 | - :type param1:
85 | + :param param1:
86 | + :type param1: str
87 | :param param2:
88 | :returns: foobar
89 |
90 |
--------------------------------------------------------------------------------
/CHANGELOG:
--------------------------------------------------------------------------------
1 | 0.4.0:
2 | - add support to type hints (PEP 484)
3 | - stop supporting running Pyment with Python from version 2.7 to 3.5
4 | - issues #34, #46, #69, #85, #86, #93, #95, #97, #99
5 | - integrate PRs #96, #98, #100
6 |
7 | 0.3.4 - 2021/03/04:
8 | - manage async functions
9 | - add type_stub param
10 | - add option for stdin/stdout
11 | - integrate PRs #64, #71, #75, #91, #92, #94
12 | - issues #51, #63, #87, #88, #90
13 | - add CI using Travis and Appveyor (#68, #70)
14 |
15 | 0.3.3 - 2018/07/25:
16 | - integrate PRs #52, #54, #55, #57, #59, #60
17 | - issues #58
18 |
19 | 0.3.2 - 2017/10/17:
20 | - add new tests
21 | - update docstrings, add sphinx conf and generated html doc
22 | - add tests for issues (#10, #15, #19, #30, #32)
23 | - update setup for Pypi
24 | - fix issues #11, #16, #26, #32
25 | - add option to overwrite a file instead of patching (issue #20)
26 |
27 | 0.3.1 - 2015/05/31:
28 | - add tests for issues (issue #9 and #11)
29 | - use entry_points to get a *.exe on windows
30 | - fix Python3 compatibility (print, xrange)
31 | - fix help message (google)
32 | - convert Pyment's docstrings to reST format using Pyment itself!
33 | - complete docstrings
34 | - add 'returns' in managed tags
35 | - fix issue #12
36 |
37 | 0.3.0 - 2014/10/12:
38 | - add google docstring management
39 |
40 | 0.2.1 - 2014/06/28:
41 | - add option to only convert existing docstrings
42 | - improve documentation
43 | - clean a bit the code
44 | - change readme format from markdown to reStructuredText
45 | - add option to ignore private methods/functions
46 |
47 | 0.2.0 - 2014/04/02:
48 | - enhance customization allowing to use a configuration file
49 | - improve the documentation
50 |
51 | 0.1.0 - 2014/03/30:
52 | - add numpydoc management
53 | - make more configurable (first line, __init__ docstring to class,..)
54 | - fix some bugs
55 |
--------------------------------------------------------------------------------
/tests/issue85.py.patch:
--------------------------------------------------------------------------------
1 | --- a/issue85.py
2 | +++ b/issue85.py
3 | @@ -1,58 +1,76 @@
4 | def func(param_file, mask):
5 | """
6 | - :param lxml.etree.ElementTree param_file: xml-element tree
7 | +
8 | + :param param_file: xml-element tree
9 | obtained from the file.
10 | - :param str mask: Name of mask to be considered.
11 | + :type param_file: lxml.etree.ElementTree
12 | + :param mask: Name of mask to be considered.
13 | + :type mask: str
14 | +
15 | """
16 | pass
17 |
18 |
19 | def func2(param1: str, param2):
20 | """
21 | - :param str param1: description 1
22 | - :param str param2: description 2
23 | +
24 | + :param param1: description 1
25 | + :type param1: str
26 | + :param param2: description 2
27 | + :type param2: str
28 | :returns: description return
29 | +
30 | """
31 | pass
32 |
33 |
34 | def func3(param1: str, param2):
35 | """
36 | +
37 | :param param1: description 1 is
38 | a multiline description
39 | :type param1: str
40 | - :param str param2: description 2
41 | + :param param2: description 2
42 | + :type param2: str
43 | :returns: description return
44 | +
45 | """
46 | pass
47 |
48 |
49 | def func4(param1, param2):
50 | """
51 | +
52 | :param param1: description 1
53 | :type param1: str
54 | - :param str param2: description 2
55 | + :param param2: description 2
56 | + :type param2: str
57 | :returns: description return
58 | +
59 | """
60 | pass
61 |
62 |
63 | def func5(param1, param2):
64 | """
65 | - :param int param1: description 1
66 | - :type param1: str
67 | +
68 | + :param param1: description 1
69 | + :type param1: int
70 | :param param2: description 2
71 | :returns: description return
72 | +
73 | """
74 | pass
75 |
76 |
77 | def func6(param1: list, param2):
78 | """
79 | - :param int param1: description 1
80 | - :type param1: str
81 | +
82 | + :param param1: description 1
83 | + :type param1: list
84 | :param param2: description 2
85 | :returns: description return
86 | +
87 | """
88 | pass
89 |
90 |
--------------------------------------------------------------------------------
/tests/params.py.patch.reST.expected:
--------------------------------------------------------------------------------
1 | # Patch generated by Pyment v0.3.2-dev4
2 |
3 | --- a/params.py
4 | +++ b/params.py
5 | @@ -1,36 +1,87 @@
6 | def func1():
7 | + """ """
8 | pass
9 |
10 |
11 | def func2(param1):
12 | + """
13 | +
14 | + :param param1:
15 | +
16 | + """
17 | pass
18 |
19 |
20 | def func3(param1, param2):
21 | + """
22 | +
23 | + :param param1:
24 | + :param param2:
25 | +
26 | + """
27 | pass
28 |
29 |
30 | def func3(param1, param2, param3):
31 | + """
32 | +
33 | + :param param1:
34 | + :param param2:
35 | + :param param3:
36 | +
37 | + """
38 | pass
39 |
40 |
41 | def func4(param1=123):
42 | + """
43 | +
44 | + :param param1: (Default value = 123)
45 | +
46 | + """
47 | pass
48 |
49 |
50 | def func5(param1, param2=123):
51 | + """
52 | +
53 | + :param param1:
54 | + :param param2: (Default value = 123)
55 | +
56 | + """
57 | pass
58 |
59 |
60 | def func6(param1, param2, param3=123):
61 | + """
62 | +
63 | + :param param1:
64 | + :param param2:
65 | + :param param3: (Default value = 123)
66 | +
67 | + """
68 | pass
69 |
70 |
71 | def func7(param1, param2=None, param3=123):
72 | + """
73 | +
74 | + :param param1:
75 | + :param param2: (Default value = None)
76 | + :param param3: (Default value = 123)
77 | +
78 | + """
79 | pass
80 |
81 |
82 | def func8(param1=123, param2=+456, param3="!:@"):
83 | + """
84 | +
85 | + :param param1: (Default value = 123)
86 | + :param param2: (Default value = +456)
87 | + :param param3: (Default value = "!:@")
88 | +
89 | + """
90 | pass
91 |
92 |
93 | def func9(param1=func1(), param2="stuff"):
94 | + """
95 | +
96 | + :param param1: (Default value = func1())
97 | + :param param2: (Default value = "stuff")
98 | +
99 | + """
100 | pass
101 |
102 |
103 | def func10(param1=func1(), param2="stuff"): # comments with (parentheses):
104 | + """
105 | +
106 | + :param param1: (Default value = func1())
107 | + :param param2: (Default value = "stuff")
108 | +
109 | + """
110 | pass
111 |
--------------------------------------------------------------------------------
/tests/params.py.patch.javadoc.expected:
--------------------------------------------------------------------------------
1 | # Patch generated by Pyment v0.3.2-dev4
2 |
3 | --- a/params.py
4 | +++ b/params.py
5 | @@ -1,36 +1,87 @@
6 | def func1():
7 | + """ """
8 | pass
9 |
10 |
11 | def func2(param1):
12 | + """
13 | +
14 | + @param param1:
15 | +
16 | + """
17 | pass
18 |
19 |
20 | def func3(param1, param2):
21 | + """
22 | +
23 | + @param param1:
24 | + @param param2:
25 | +
26 | + """
27 | pass
28 |
29 |
30 | def func3(param1, param2, param3):
31 | + """
32 | +
33 | + @param param1:
34 | + @param param2:
35 | + @param param3:
36 | +
37 | + """
38 | pass
39 |
40 |
41 | def func4(param1=123):
42 | + """
43 | +
44 | + @param param1: (Default value = 123)
45 | +
46 | + """
47 | pass
48 |
49 |
50 | def func5(param1, param2=123):
51 | + """
52 | +
53 | + @param param1:
54 | + @param param2: (Default value = 123)
55 | +
56 | + """
57 | pass
58 |
59 |
60 | def func6(param1, param2, param3=123):
61 | + """
62 | +
63 | + @param param1:
64 | + @param param2:
65 | + @param param3: (Default value = 123)
66 | +
67 | + """
68 | pass
69 |
70 |
71 | def func7(param1, param2=None, param3=123):
72 | + """
73 | +
74 | + @param param1:
75 | + @param param2: (Default value = None)
76 | + @param param3: (Default value = 123)
77 | +
78 | + """
79 | pass
80 |
81 |
82 | def func8(param1=123, param2=+456, param3="!:@"):
83 | + """
84 | +
85 | + @param param1: (Default value = 123)
86 | + @param param2: (Default value = +456)
87 | + @param param3: (Default value = "!:@")
88 | +
89 | + """
90 | pass
91 |
92 |
93 | def func9(param1=func1(), param2="stuff"):
94 | + """
95 | +
96 | + @param param1: (Default value = func1())
97 | + @param param2: (Default value = "stuff")
98 | +
99 | + """
100 | pass
101 |
102 |
103 | def func10(param1=func1(), param2="stuff"): # comments with (parentheses):
104 | + """
105 | +
106 | + @param param1: (Default value = func1())
107 | + @param param2: (Default value = "stuff")
108 | +
109 | + """
110 | pass
111 |
--------------------------------------------------------------------------------
/tests/issue93.py:
--------------------------------------------------------------------------------
1 | def func(): # comment with (parents):
2 | pass
3 |
4 |
5 | def func0(param1): # comment with (parents):,
6 | """description
7 | :param param1: yoyo
8 | :returns: nothing
9 | """
10 | pass
11 |
12 |
13 | def func1(param1: str):
14 | pass
15 |
16 |
17 | def func2(param1: str) -> int:
18 | pass
19 |
20 |
21 | def func3(param1: str) -> str:
22 | """Func 3
23 |
24 | :param param1: param description
25 | :return: the value
26 | """
27 | pass
28 |
29 |
30 | def func4(param1: str, param2: List[int]):
31 | pass
32 |
33 |
34 | def func5(param1: str, param2: List[int]) -> Dict[str,Object]: # yet:(another) comment
35 | pass
36 |
37 |
38 | def func6(param1: str, param2: Dict[str,Object]) -> str:
39 | """Func 6
40 |
41 | :param param1: the first parameter
42 | :type param1: str
43 | :param param2: the second parameter
44 | :returns: the message
45 | :rtype: str
46 |
47 | """
48 | pass
49 |
50 |
51 | def func7(param1: str, param2: Dict[str, Object], param3: int = 12) -> str:
52 | pass
53 |
54 |
55 | def func8(param1 : str, param2: list=None, param3: str = "foo", param4="bar") -> str:
56 | pass
57 |
58 |
59 | def func9(param1: str,
60 | param2: list = None,
61 | param3: str = "foo") -> str:
62 | pass
63 |
64 |
65 | def func10( param1: str = "", param2='', param3=call_func('foobar') ) :
66 | pass
67 |
68 |
69 | def func11(self, param1: str, param2: Dict[str, Object], param3: OAuth2PasswordRequestForm = Depends(), param4: int = 1) -> str:
70 | pass
71 |
72 |
73 | def func12(cls, param1: str, param2: Dict[str, Object], param3: int = 12) -> str:
74 | pass
75 |
76 |
77 | def func13(param1, param2: Dict["str", Object], param3: int = 12) -> str:
78 | pass
79 |
80 |
81 | def func14(param1=True, param2: str = 'default val'):
82 | '''Description of func with docstring groups style.
83 |
84 | Params:
85 | param1 - descr of param1 that has True for default value.
86 | param2 - descr of param2
87 |
88 | Returns:
89 | some value
90 |
91 | Raises:
92 | keyError: raises key exception
93 | TypeError: raises type exception
94 |
95 | '''
96 | pass
97 |
98 | class A:
99 | def method(self, param1, param2=None) -> int:
100 | pass
101 |
102 |
--------------------------------------------------------------------------------
/tests/params.py.patch.google.expected:
--------------------------------------------------------------------------------
1 | # Patch generated by Pyment v0.3.2-dev4
2 |
3 | --- a/params.py
4 | +++ b/params.py
5 | @@ -1,36 +1,111 @@
6 | def func1():
7 | + """ """
8 | pass
9 |
10 |
11 | def func2(param1):
12 | + """
13 | +
14 | + Args:
15 | + param1:
16 | +
17 | + Returns:
18 | +
19 | + """
20 | pass
21 |
22 |
23 | def func3(param1, param2):
24 | + """
25 | +
26 | + Args:
27 | + param1:
28 | + param2:
29 | +
30 | + Returns:
31 | +
32 | + """
33 | pass
34 |
35 |
36 | def func3(param1, param2, param3):
37 | + """
38 | +
39 | + Args:
40 | + param1:
41 | + param2:
42 | + param3:
43 | +
44 | + Returns:
45 | +
46 | + """
47 | pass
48 |
49 |
50 | def func4(param1=123):
51 | + """
52 | +
53 | + Args:
54 | + param1: (Default value = 123)
55 | +
56 | + Returns:
57 | +
58 | + """
59 | pass
60 |
61 |
62 | def func5(param1, param2=123):
63 | + """
64 | +
65 | + Args:
66 | + param1:
67 | + param2: (Default value = 123)
68 | +
69 | + Returns:
70 | +
71 | + """
72 | pass
73 |
74 |
75 | def func6(param1, param2, param3=123):
76 | + """
77 | +
78 | + Args:
79 | + param1:
80 | + param2:
81 | + param3: (Default value = 123)
82 | +
83 | + Returns:
84 | +
85 | + """
86 | pass
87 |
88 |
89 | def func7(param1, param2=None, param3=123):
90 | + """
91 | +
92 | + Args:
93 | + param1:
94 | + param2: (Default value = None)
95 | + param3: (Default value = 123)
96 | +
97 | + Returns:
98 | +
99 | + """
100 | pass
101 |
102 |
103 | def func8(param1=123, param2=+456, param3="!:@"):
104 | + """
105 | +
106 | + Args:
107 | + param1: (Default value = 123)
108 | + param2: (Default value = +456)
109 | + param3: (Default value = "!:@")
110 | +
111 | + Returns:
112 | +
113 | + """
114 | pass
115 |
116 |
117 | def func9(param1=func1(), param2="stuff"):
118 | + """
119 | +
120 | + Args:
121 | + param1: (Default value = func1())
122 | + param2: (Default value = "stuff")
123 | +
124 | + Returns:
125 | +
126 | + """
127 | pass
128 |
129 |
130 | def func10(param1=func1(), param2="stuff"): # comments with (parentheses):
131 | + """
132 | +
133 | + Args:
134 | + param1: (Default value = func1())
135 | + param2: (Default value = "stuff")
136 | +
137 | + Returns:
138 | +
139 | + """
140 | pass
141 |
--------------------------------------------------------------------------------
/example.py:
--------------------------------------------------------------------------------
1 | def func1(param1: str, param2='default val'):
2 | '''Description of func with docstring javadoc style.
3 |
4 | @param param1: descr of param
5 | @type param1: type
6 | @return: some value
7 | @raise KeyError: raises a key exception
8 |
9 | '''
10 | pass
11 |
12 | def func2(param1, param2='default val2') -> list:
13 | '''Description of func with docstring reST style.
14 |
15 | :param param1: descr of param
16 | :type param1: type
17 | :returns: some value
18 | :raises keyError: raises exception
19 |
20 | '''
21 | pass
22 |
23 | def func3(param1, param2='default val'):
24 | '''Description of func with docstring groups style.
25 |
26 | Params:
27 | param1 - descr of param
28 |
29 | Returns:
30 | some value
31 |
32 | Raises:
33 | keyError: raises key exception
34 | TypeError: raises type exception
35 |
36 | '''
37 | pass
38 |
39 | class SomeClass(object):
40 | '''My class.
41 | '''
42 | def method(self, prm):
43 | '''description'''
44 | pass
45 |
46 | def method2(self, prm1, prm2='defaultprm'):
47 | pass
48 |
49 | def method_numpy(self):
50 | """
51 | My numpydoc description of a kind
52 | of very exhaustive numpydoc format docstring.
53 |
54 | Parameters
55 | ----------
56 | first : array_like
57 | the 1st param name `first`
58 | second :
59 | the 2nd param
60 | third : {'value', 'other'}, optional
61 | the 3rd param, by default 'value'
62 |
63 | Returns
64 | -------
65 | string
66 | a value in a string
67 |
68 | Raises
69 | ------
70 | KeyError
71 | when a key error
72 | OtherError
73 | when an other error
74 |
75 | See Also
76 | --------
77 | a_func : linked (optional), with things to say
78 | on several lines
79 | some blabla
80 |
81 | Note
82 | ----
83 | Some informations.
84 |
85 | Some maths also:
86 | .. math:: f(x) = e^{- x}
87 |
88 | References
89 | ----------
90 | Biblio with cited ref [1]_. The ref can be cited in Note section.
91 |
92 | .. [1] Adel Daouzli, Sylvain Saïghi, Michelle Rudolph, Alain Destexhe,
93 | Sylvie Renaud: Convergence in an Adaptive Neural Network:
94 | The Influence of Noise Inputs Correlation. IWANN (1) 2009: 140-148
95 |
96 | Examples
97 | --------
98 | This is example of use
99 | >>> print "a"
100 | a
101 |
102 | """
103 | pass
104 |
--------------------------------------------------------------------------------
/tests/params.py.patch.numpydoc.expected:
--------------------------------------------------------------------------------
1 | # Patch generated by Pyment v0.3.2-dev4
2 |
3 | --- a/params.py
4 | +++ b/params.py
5 | @@ -1,36 +1,145 @@
6 | def func1():
7 | + """ """
8 | pass
9 |
10 |
11 | def func2(param1):
12 | + """
13 | +
14 | + Parameters
15 | + ----------
16 | + param1 :
17 | +
18 | +
19 | + Returns
20 | + -------
21 | +
22 | + """
23 | pass
24 |
25 |
26 | def func3(param1, param2):
27 | + """
28 | +
29 | + Parameters
30 | + ----------
31 | + param1 :
32 | +
33 | + param2 :
34 | +
35 | +
36 | + Returns
37 | + -------
38 | +
39 | + """
40 | pass
41 |
42 |
43 | def func3(param1, param2, param3):
44 | + """
45 | +
46 | + Parameters
47 | + ----------
48 | + param1 :
49 | +
50 | + param2 :
51 | +
52 | + param3 :
53 | +
54 | +
55 | + Returns
56 | + -------
57 | +
58 | + """
59 | pass
60 |
61 |
62 | def func4(param1=123):
63 | + """
64 | +
65 | + Parameters
66 | + ----------
67 | + param1 :
68 | + (Default value = 123)
69 | +
70 | + Returns
71 | + -------
72 | +
73 | + """
74 | pass
75 |
76 |
77 | def func5(param1, param2=123):
78 | + """
79 | +
80 | + Parameters
81 | + ----------
82 | + param1 :
83 | +
84 | + param2 :
85 | + (Default value = 123)
86 | +
87 | + Returns
88 | + -------
89 | +
90 | + """
91 | pass
92 |
93 |
94 | def func6(param1, param2, param3=123):
95 | + """
96 | +
97 | + Parameters
98 | + ----------
99 | + param1 :
100 | +
101 | + param2 :
102 | +
103 | + param3 :
104 | + (Default value = 123)
105 | +
106 | + Returns
107 | + -------
108 | +
109 | + """
110 | pass
111 |
112 |
113 | def func7(param1, param2=None, param3=123):
114 | + """
115 | +
116 | + Parameters
117 | + ----------
118 | + param1 :
119 | +
120 | + param2 :
121 | + (Default value = None)
122 | + param3 :
123 | + (Default value = 123)
124 | +
125 | + Returns
126 | + -------
127 | +
128 | + """
129 | pass
130 |
131 |
132 | def func8(param1=123, param2=+456, param3="!:@"):
133 | + """
134 | +
135 | + Parameters
136 | + ----------
137 | + param1 :
138 | + (Default value = 123)
139 | + param2 :
140 | + (Default value = +456)
141 | + param3 :
142 | + (Default value = "!:@")
143 | +
144 | + Returns
145 | + -------
146 | +
147 | + """
148 | pass
149 |
150 |
151 | def func9(param1=func1(), param2="stuff"):
152 | + """
153 | +
154 | + Parameters
155 | + ----------
156 | + param1 :
157 | + (Default value = func1())
158 | + param2 :
159 | + (Default value = "stuff")
160 | +
161 | + Returns
162 | + -------
163 | +
164 | + """
165 | pass
166 |
167 |
168 | def func10(param1=func1(), param2="stuff"): # comments with (parentheses):
169 | + """
170 | +
171 | + Parameters
172 | + ----------
173 | + param1 :
174 | + (Default value = func1())
175 | + param2 :
176 | + (Default value = "stuff")
177 | +
178 | + Returns
179 | + -------
180 | +
181 | + """
182 | pass
183 |
--------------------------------------------------------------------------------
/tests/origin_test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | import unittest
4 |
5 | def my_func_full(first, second=None, third="value"):
6 | """This is a description of a method.
7 | It is on several lines.
8 | Several styles exists:
9 | -javadoc,
10 | -reST,
11 | -groups.
12 | It uses the javadoc style.
13 |
14 | @param first: the 1st argument.
15 | with multiple lines
16 | @type first: str
17 | @param second: the 2nd argument.
18 | @return: the result value
19 | @rtype: int
20 | @raise KeyError: raises an exception
21 |
22 | """
23 | print ("this is the code of my full func")
24 |
25 | def my_func_multiline_elem(first,
26 | second,
27 | third=""):
28 | '''multiline'''
29 | print ("this has elems in several lines")
30 |
31 | def my_func_empty_params(first, second=None, third="value"):
32 | print ("this is the code of my empty func")
33 |
34 | def my_func_empty_no_params():
35 | print ("this is the code of my empty func no params")
36 |
37 | def my_func_desc_lines_params(first, second=None, third="value"):
38 | '''This is a description but params not described.
39 | And a new line!
40 | '''
41 | print ("this is the code of my func")
42 |
43 | def my_func_desc_line_params(first, second=None, third="value"):
44 | '''This is a description but params not described.
45 | '''
46 | print ("this is the code of my func")
47 |
48 | def my_func_desc_line_no_params():
49 | '''This is a description but no params.
50 | '''
51 | print ("this is the code of my func")
52 |
53 |
54 | def my_func_groups_style(first, second=None, third="value"):
55 | '''My desc of groups style.
56 |
57 | Parameters:
58 | first: the first param
59 | second: the 2nd param
60 | third: the 3rd param
61 |
62 | '''
63 | print("group style!")
64 |
65 |
66 | class MyTestClass(object):
67 |
68 | def __init__(self, one_param=None):
69 | '''The init with one param
70 |
71 | @param one_param:
72 | '''
73 | self.param = one_param
74 | print("init")
75 |
76 | @classmethod
77 | def my_cls_method(cls):
78 | print("cls method")
79 |
80 | def my_method_no_param(self):
81 | """Do something
82 | perhaps!
83 | """
84 | print("or not")
85 |
86 | def my_method_params_no_docs(self, first, second=None, third="value"):
87 | print("method params no docs")
88 |
89 | def my_method_multiline_shift_elem(self, first,
90 | second,
91 | third="",
92 | **kwargs):
93 | '''there are multilines, shift and kwargs'''
94 | print ("this has elems in several lines")
95 |
96 | def my_method_full(self, first, second=None, third="value"):
97 | '''The description of method with 3 params and return value
98 | on several lines
99 |
100 | @param first: the 1st param
101 | @type first: int
102 | @param second: the 2nd param with default at None
103 | @type first: tuple
104 | @param third: the 3rd param
105 | @type third: str
106 | @return: the value
107 | @rtype: str
108 | @raise KeyError: key exception
109 |
110 | '''
111 | print("method full")
112 | return third
113 |
114 |
115 |
--------------------------------------------------------------------------------
/tests/test_pyment.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | import unittest
4 | import shutil
5 | import os
6 | import pyment.pyment as pym
7 |
8 | myelem = ' def my_method(self, first, second=None, third="value"):'
9 | mydocs = ''' """This is a description of a method.
10 | It is on several lines.
11 | Several styles exists:
12 | -javadoc,
13 | -reST,
14 | -cstyle.
15 | It uses the javadoc style.
16 |
17 | @param first: the 1st argument.
18 | with multiple lines
19 | @type first: str
20 | @param second: the 2nd argument.
21 | @return: the result value
22 | @rtype: int
23 | @raise KeyError: raises exception
24 |
25 | """'''
26 |
27 | current_dir = os.path.dirname(__file__)
28 | absdir = lambda f: os.path.join(current_dir, f)
29 |
30 | inifile = absdir('origin_test.py')
31 | jvdfile = absdir('javadoc_test.py')
32 | rstfile = absdir('rest_test.py')
33 | foo = absdir("foo")
34 |
35 |
36 | class DocStringTests(unittest.TestCase):
37 |
38 | @classmethod
39 | def setUpClass(cls):
40 | # prepare test file
41 | txt = ""
42 | shutil.copyfile(inifile, jvdfile)
43 | with open(jvdfile, 'r') as fs:
44 | txt = fs.read()
45 | txt = txt.replace("@return", ":returns")
46 | txt = txt.replace("@raise", ":raises")
47 | txt = txt.replace("@", ":")
48 | with open(rstfile, 'w') as ft:
49 | ft.write(txt)
50 | with open(foo, "w") as fooo:
51 | fooo.write("foo")
52 | print("setup")
53 |
54 | @classmethod
55 | def tearDownClass(cls):
56 | os.remove(jvdfile)
57 | os.remove(rstfile)
58 | os.remove(foo)
59 | print("end")
60 |
61 | def testParsedJavadoc(self):
62 | p = pym.PyComment(inifile)
63 | p._parse()
64 | self.assertTrue(p.parsed)
65 |
66 | def testSameOutJavadocReST(self):
67 | pj = pym.PyComment(jvdfile)
68 | pr = pym.PyComment(rstfile)
69 | pj._parse()
70 | pr._parse()
71 | self.assertEqual(pj.get_output_docs(), pr.get_output_docs())
72 |
73 | def testMultiLinesElements(self):
74 | p = pym.PyComment(inifile)
75 | p._parse()
76 | self.assertTrue('first' in p.get_output_docs()[1])
77 | self.assertTrue('second' in p.get_output_docs()[1])
78 | self.assertTrue('third' in p.get_output_docs()[1])
79 | self.assertTrue('multiline' in p.get_output_docs()[1])
80 |
81 | def testMultiLinesShiftElements(self):
82 | p = pym.PyComment(inifile)
83 | p._parse()
84 | #TODO: improve this test
85 | self.assertEqual((len(p.get_output_docs()[13])-len(p.get_output_docs()[13].lstrip())), 8)
86 | self.assertTrue('first' in p.get_output_docs()[13])
87 | self.assertTrue('second' in p.get_output_docs()[13])
88 | self.assertTrue('third' in p.get_output_docs()[13])
89 | self.assertTrue('multiline' in p.get_output_docs()[13])
90 |
91 | def testWindowsRename(self):
92 | bar = absdir("bar")
93 | with open(bar, "w") as fbar:
94 | fbar.write("bar")
95 | p = pym.PyComment(foo)
96 | p._windows_rename(bar)
97 | self.assertFalse(os.path.isfile(bar))
98 | self.assertTrue(os.path.isfile(foo))
99 | with open(foo, "r") as fooo:
100 | foo_txt = fooo.read()
101 | self.assertTrue(foo_txt == "bar")
102 |
103 |
104 | def main():
105 | unittest.main()
106 |
107 |
108 | if __name__ == '__main__':
109 | main()
110 |
--------------------------------------------------------------------------------
/doc/sphinx/html/search.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 | Search — Pyment 0.3.2 documentation
9 |
10 |
11 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
Search
55 |
56 |
57 |
58 | Please activate JavaScript to enable the search
59 | functionality.
60 |
61 |
62 |
63 | From here you can search these documents. Enter your search
64 | words into the box below and click "search". Note that the search
65 | function will automatically search for all of the words. Pages
66 | containing fewer words won't appear in the result list.
67 |
68 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
85 |
86 |
87 |
99 |
103 |
104 |
--------------------------------------------------------------------------------
/example_numpydoc.py.patch:
--------------------------------------------------------------------------------
1 | # Patch generated by Pyment v0.4.0dev
2 |
3 | --- a/example.py
4 | +++ b/example.py
5 | @@ -1,54 +1,108 @@
6 | def func1(param1: str, param2='default val'):
7 | - '''Description of func with docstring javadoc style.
8 | + """Description of func with docstring javadoc style.
9 |
10 | - @param param1: descr of param
11 | - @type param1: type
12 | - @return: some value
13 | - @raise KeyError: raises a key exception
14 | + Parameters
15 | + ----------
16 | + param1 : str
17 | + descr of param
18 | + param2 :
19 | + (Default value = 'default val')
20 |
21 | - '''
22 | + Returns
23 | + -------
24 | + type
25 | + some value
26 | +
27 | + Raises
28 | + ------
29 | + KeyError
30 | + raises a key exception
31 | +
32 | + """
33 | pass
34 |
35 | def func2(param1, param2='default val2') -> list:
36 | - '''Description of func with docstring reST style.
37 | + """Description of func with docstring reST style.
38 |
39 | - :param param1: descr of param
40 | - :type param1: type
41 | - :returns: some value
42 | - :raises keyError: raises exception
43 | + Parameters
44 | + ----------
45 | + param1 : type
46 | + descr of param
47 | + param2 :
48 | + (Default value = 'default val2')
49 |
50 | - '''
51 | + Returns
52 | + -------
53 | + list
54 | + some value
55 | +
56 | + Raises
57 | + ------
58 | + keyError
59 | + raises exception
60 | +
61 | + """
62 | pass
63 |
64 | def func3(param1, param2='default val'):
65 | - '''Description of func with docstring groups style.
66 | + """Description of func with docstring groups style.
67 |
68 | - Params:
69 | - param1 - descr of param
70 | + Parameters
71 | + ----------
72 | + param1 :
73 | + descr of param
74 | + param2 :
75 | + (Default value = 'default val')
76 |
77 | - Returns:
78 | + Returns
79 | + -------
80 | + type
81 | some value
82 |
83 | - Raises:
84 | - keyError: raises key exception
85 | - TypeError: raises type exception
86 | + Raises
87 | + ------
88 | + keyError
89 | + raises key exception
90 | + TypeError
91 | + raises type exception
92 |
93 | - '''
94 | + """
95 | pass
96 |
97 | class SomeClass(object):
98 | - '''My class.
99 | - '''
100 | + """My class."""
101 | def method(self, prm):
102 | - '''description'''
103 | + """description
104 | +
105 | + Parameters
106 | + ----------
107 | + prm :
108 | +
109 | +
110 | + Returns
111 | + -------
112 | +
113 | + """
114 | pass
115 |
116 | def method2(self, prm1, prm2='defaultprm'):
117 | + """
118 | +
119 | + Parameters
120 | + ----------
121 | + prm1 :
122 | +
123 | + prm2 :
124 | + (Default value = 'defaultprm')
125 | +
126 | + Returns
127 | + -------
128 | +
129 | + """
130 | pass
131 |
132 | def method_numpy(self):
133 | - """
134 | - My numpydoc description of a kind
135 | + """My numpydoc description of a kind
136 | of very exhautive numpydoc format docstring.
137 |
138 | Parameters
139 | @@ -77,27 +131,24 @@
140 | a_func : linked (optional), with things to say
141 | on several lines
142 | some blabla
143 | -
144 | +
145 | Note
146 | ----
147 | Some informations.
148 | -
149 | +
150 | Some maths also:
151 | .. math:: f(x) = e^{- x}
152 | -
153 | References
154 | ----------
155 | Biblio with cited ref [1]_. The ref can be cited in Note section.
156 | -
157 | +
158 | .. [1] Adel Daouzli, Sylvain Saïghi, Michelle Rudolph, Alain Destexhe,
159 | Sylvie Renaud: Convergence in an Adaptive Neural Network:
160 | The Influence of Noise Inputs Correlation. IWANN (1) 2009: 140-148
161 | -
162 | Examples
163 | --------
164 | This is example of use
165 | >>> print "a"
166 | a
167 | -
168 | """
169 | pass
170 |
--------------------------------------------------------------------------------
/doc/sphinx/html/_static/pygments.css:
--------------------------------------------------------------------------------
1 | .highlight .hll { background-color: #ffffcc }
2 | .highlight { background: #eeffcc; }
3 | .highlight .c { color: #408090; font-style: italic } /* Comment */
4 | .highlight .err { border: 1px solid #FF0000 } /* Error */
5 | .highlight .k { color: #007020; font-weight: bold } /* Keyword */
6 | .highlight .o { color: #666666 } /* Operator */
7 | .highlight .ch { color: #408090; font-style: italic } /* Comment.Hashbang */
8 | .highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */
9 | .highlight .cp { color: #007020 } /* Comment.Preproc */
10 | .highlight .cpf { color: #408090; font-style: italic } /* Comment.PreprocFile */
11 | .highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */
12 | .highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */
13 | .highlight .gd { color: #A00000 } /* Generic.Deleted */
14 | .highlight .ge { font-style: italic } /* Generic.Emph */
15 | .highlight .gr { color: #FF0000 } /* Generic.Error */
16 | .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
17 | .highlight .gi { color: #00A000 } /* Generic.Inserted */
18 | .highlight .go { color: #333333 } /* Generic.Output */
19 | .highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
20 | .highlight .gs { font-weight: bold } /* Generic.Strong */
21 | .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
22 | .highlight .gt { color: #0044DD } /* Generic.Traceback */
23 | .highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
24 | .highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
25 | .highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
26 | .highlight .kp { color: #007020 } /* Keyword.Pseudo */
27 | .highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
28 | .highlight .kt { color: #902000 } /* Keyword.Type */
29 | .highlight .m { color: #208050 } /* Literal.Number */
30 | .highlight .s { color: #4070a0 } /* Literal.String */
31 | .highlight .na { color: #4070a0 } /* Name.Attribute */
32 | .highlight .nb { color: #007020 } /* Name.Builtin */
33 | .highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
34 | .highlight .no { color: #60add5 } /* Name.Constant */
35 | .highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
36 | .highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
37 | .highlight .ne { color: #007020 } /* Name.Exception */
38 | .highlight .nf { color: #06287e } /* Name.Function */
39 | .highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
40 | .highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
41 | .highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */
42 | .highlight .nv { color: #bb60d5 } /* Name.Variable */
43 | .highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
44 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */
45 | .highlight .mb { color: #208050 } /* Literal.Number.Bin */
46 | .highlight .mf { color: #208050 } /* Literal.Number.Float */
47 | .highlight .mh { color: #208050 } /* Literal.Number.Hex */
48 | .highlight .mi { color: #208050 } /* Literal.Number.Integer */
49 | .highlight .mo { color: #208050 } /* Literal.Number.Oct */
50 | .highlight .sa { color: #4070a0 } /* Literal.String.Affix */
51 | .highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
52 | .highlight .sc { color: #4070a0 } /* Literal.String.Char */
53 | .highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */
54 | .highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
55 | .highlight .s2 { color: #4070a0 } /* Literal.String.Double */
56 | .highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
57 | .highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */
58 | .highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
59 | .highlight .sx { color: #c65d09 } /* Literal.String.Other */
60 | .highlight .sr { color: #235388 } /* Literal.String.Regex */
61 | .highlight .s1 { color: #4070a0 } /* Literal.String.Single */
62 | .highlight .ss { color: #517918 } /* Literal.String.Symbol */
63 | .highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
64 | .highlight .fm { color: #06287e } /* Name.Function.Magic */
65 | .highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
66 | .highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
67 | .highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
68 | .highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */
69 | .highlight .il { color: #208050 } /* Literal.Number.Integer.Long */
--------------------------------------------------------------------------------
/doc/sphinx/html/py-modindex.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 | Python Module Index — Pyment 0.3.2 documentation
9 |
10 |
11 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
31 |
32 |
33 |
34 |
35 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
Python Module Index
55 |
56 |
60 |
61 |
62 |
63 |
64 | d
65 |
66 |
67 |
68 | docstring
69 |
70 |
71 |
72 | p
73 |
74 |
75 |
76 | pyment
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
98 |
99 |
100 |
112 |
116 |
117 |
--------------------------------------------------------------------------------
/example_javadoc.py.patch:
--------------------------------------------------------------------------------
1 | # Patch generated by Pyment v0.4.0
2 |
3 | --- a/example.py
4 | +++ b/example.py
5 | @@ -1,103 +1,96 @@
6 | def func1(param1: str, param2='default val'):
7 | - '''Description of func with docstring javadoc style.
8 | + """Description of func with docstring javadoc style.
9 | +
10 | + @param param1: descr of param
11 | + @type param1: str
12 | + @param param2: (Default value = 'default val')
13 | + @return: some value
14 | + @raise KeyError: raises a key exception
15 | +
16 | + """
17 | + pass
18 | +
19 | +def func2(param1, param2='default val2') -> list:
20 | + """Description of func with docstring reST style.
21 |
22 | @param param1: descr of param
23 | @type param1: type
24 | + @param param2: (Default value = 'default val2')
25 | @return: some value
26 | - @raise KeyError: raises a key exception
27 | + @rtype: list
28 | + @raise keyError: raises exception
29 |
30 | - '''
31 | - pass
32 | -
33 | -def func2(param1, param2='default val2') -> list:
34 | - '''Description of func with docstring reST style.
35 | -
36 | - :param param1: descr of param
37 | - :type param1: type
38 | - :returns: some value
39 | - :raises keyError: raises exception
40 | -
41 | - '''
42 | + """
43 | pass
44 |
45 | def func3(param1, param2='default val'):
46 | - '''Description of func with docstring groups style.
47 | + """Description of func with docstring groups style.
48 |
49 | - Params:
50 | - param1 - descr of param
51 | + @param param1: descr of param
52 | + @param param2: (Default value = 'default val')
53 | + @return: some value
54 | + @raise keyError: raises key exception
55 | + @raise TypeError: raises type exception
56 |
57 | - Returns:
58 | - some value
59 | -
60 | - Raises:
61 | - keyError: raises key exception
62 | - TypeError: raises type exception
63 | -
64 | - '''
65 | + """
66 | pass
67 |
68 | class SomeClass(object):
69 | - '''My class.
70 | - '''
71 | + """My class."""
72 | def method(self, prm):
73 | - '''description'''
74 | + """description
75 | +
76 | + @param prm:
77 | +
78 | + """
79 | pass
80 |
81 | def method2(self, prm1, prm2='defaultprm'):
82 | + """
83 | +
84 | + @param prm1:
85 | + @param prm2: (Default value = 'defaultprm')
86 | +
87 | + """
88 | pass
89 |
90 | def method_numpy(self):
91 | - """
92 | - My numpydoc description of a kind
93 | + """My numpydoc description of a kind
94 | of very exhautive numpydoc format docstring.
95 |
96 | - Parameters
97 | - ----------
98 | - first : array_like
99 | - the 1st param name `first`
100 | - second :
101 | - the 2nd param
102 | - third : {'value', 'other'}, optional
103 | - the 3rd param, by default 'value'
104 | -
105 | - Returns
106 | - -------
107 | - string
108 | - a value in a string
109 | -
110 | - Raises
111 | - ------
112 | - KeyError
113 | - when a key error
114 | - OtherError
115 | - when an other error
116 | + @param first: the 1st param name `first`
117 | + @type first: array_like
118 | + @param second: the 2nd param
119 | + @param third: the 3rd param, by default 'value'
120 | + @type third: {'value', 'other'}, optional
121 | + @return: a value in a string
122 | + @rtype: string
123 | + @raise KeyError: when a key error
124 | + @raise OtherError: when an other error
125 |
126 | See Also
127 | --------
128 | a_func : linked (optional), with things to say
129 | on several lines
130 | some blabla
131 | -
132 | +
133 | Note
134 | ----
135 | Some informations.
136 | -
137 | +
138 | Some maths also:
139 | .. math:: f(x) = e^{- x}
140 | -
141 | References
142 | ----------
143 | Biblio with cited ref [1]_. The ref can be cited in Note section.
144 | -
145 | +
146 | .. [1] Adel Daouzli, Sylvain Saïghi, Michelle Rudolph, Alain Destexhe,
147 | Sylvie Renaud: Convergence in an Adaptive Neural Network:
148 | The Influence of Noise Inputs Correlation. IWANN (1) 2009: 140-148
149 | -
150 | Examples
151 | --------
152 | This is example of use
153 | >>> print "a"
154 | a
155 | -
156 | """
157 | pass
158 |
--------------------------------------------------------------------------------
/tests/test_pyment_cases.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | import unittest
4 | import os
5 | import pyment.pyment as pym
6 | import re
7 |
8 | current_dir = os.path.dirname(__file__)
9 | absdir = lambda f: os.path.join(current_dir, f)
10 |
11 |
12 | def get_expected_patch(self, name):
13 | """Open a patch file, and if found Pyment signature remove the 2 first lines"""
14 | try:
15 | f = open(absdir(name))
16 | expected = f.readlines()
17 | if expected[0].startswith("# Patch"):
18 | expected = expected[2:]
19 | expected = "".join(expected)
20 | f.close()
21 | except Exception as e:
22 | self.fail('Raised exception: "{0}"'.format(e))
23 | return expected
24 |
25 |
26 | def remove_diff_header(diff):
27 | return re.sub('@@.+@@', '', diff)
28 |
29 |
30 | class FilesConversionTests(unittest.TestCase):
31 |
32 | def testCaseFreeTesting(self):
33 | # free cases
34 | p = pym.PyComment(absdir("free_cases.py"))
35 | p._parse()
36 | self.assertTrue(p.parsed)
37 | result = ''.join(p.diff())
38 | self.assertTrue(result == '')
39 |
40 | def testCaseGenAllParamsReST(self):
41 | # The file has several functions with no or several parameters,
42 | # so Pyment should produce docstrings in reST format
43 | expected = get_expected_patch(self, "params.py.patch.reST.expected")
44 | p = pym.PyComment(absdir("params.py"))
45 | p._parse()
46 | self.assertTrue(p.parsed)
47 | result = ''.join(p.diff())
48 | self.assertTrue(remove_diff_header(result) == remove_diff_header(expected))
49 |
50 | @unittest.expectedFailure
51 | def testCaseGenAllParamsGoogle(self):
52 | # The file has several functions with no or several parameters,
53 | # so Pyment should produce docstrings in google format
54 | expected = get_expected_patch(self, "params.py.patch.google.expected")
55 | p = pym.PyComment(absdir("params.py"), output_style="google")
56 | p._parse()
57 | self.assertTrue(p.parsed)
58 | result = ''.join(p.diff())
59 | self.assertTrue(remove_diff_header(result) == remove_diff_header(expected))
60 |
61 | def testCaseGenAllParamsNumpydoc(self):
62 | # The file has several functions with no or several parameters,
63 | # so Pyment should produce docstrings in numpydoc format
64 | expected = get_expected_patch(self, "params.py.patch.numpydoc.expected")
65 | p = pym.PyComment(absdir("params.py"), output_style="numpydoc")
66 | p._parse()
67 | self.assertTrue(p.parsed)
68 | result = ''.join(p.diff())
69 | self.assertTrue(remove_diff_header(result) == remove_diff_header(expected))
70 |
71 | def testCaseGenAllParamsJavadoc(self):
72 | # The file has several functions with no or several parameters,
73 | # so Pyment should produce docstrings in javadoc
74 | expected = get_expected_patch(self, "params.py.patch.javadoc.expected")
75 | p = pym.PyComment(absdir("params.py"), output_style="javadoc")
76 | p._parse()
77 | self.assertTrue(p.parsed)
78 | result = ''.join(p.diff())
79 | self.assertTrue(remove_diff_header(result) == remove_diff_header(expected))
80 |
81 | def testCaseNoGenDocsAlreadyReST(self):
82 | # The file has functions with already docstrings in reST format,
83 | # so no docstring should be produced
84 | p = pym.PyComment(absdir("docs_already_reST.py"))
85 | p._parse()
86 | self.assertTrue(p.parsed)
87 | result = ''.join(p.diff())
88 | self.assertTrue(result == '')
89 |
90 | def testCaseNoGenDocsAlreadyJavadoc(self):
91 | # The file has functions with already docstrings in javadoc format,
92 | # so no docstring should be produced
93 | p = pym.PyComment(absdir("docs_already_javadoc.py"), output_style="javadoc")
94 | p._parse()
95 | self.assertTrue(p.parsed)
96 | result = ''.join(p.diff())
97 | self.assertTrue(result == '')
98 |
99 | @unittest.expectedFailure
100 | def testCaseNoGenDocsAlreadyNumpydoc(self):
101 | # The file has functions with already docstrings in numpydoc format,
102 | # so no docstring should be produced
103 | p = pym.PyComment(absdir("docs_already_numpydoc.py"), output_style="numpydoc")
104 | p._parse()
105 | self.assertTrue(p.parsed)
106 | result = ''.join(p.diff())
107 | self.assertTrue(result == '')
108 |
109 | @unittest.expectedFailure
110 | def testCaseNoGenDocsAlreadyGoogle(self):
111 | # The file has functions with already docstrings in google format,
112 | # so no docstring should be produced
113 | p = pym.PyComment(absdir("docs_already_google.py"), output_style="google")
114 | p._parse()
115 | self.assertTrue(p.parsed)
116 | result = ''.join(p.diff())
117 | self.assertTrue(result == '')
118 |
119 |
120 | def main():
121 | unittest.main()
122 |
123 |
124 | if __name__ == '__main__':
125 | main()
126 |
--------------------------------------------------------------------------------
/doc/sphinx/html/_static/classic.css:
--------------------------------------------------------------------------------
1 | /*
2 | * classic.css_t
3 | * ~~~~~~~~~~~~~
4 | *
5 | * Sphinx stylesheet -- classic theme.
6 | *
7 | * :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
8 | * :license: BSD, see LICENSE for details.
9 | *
10 | */
11 |
12 | @import url("basic.css");
13 |
14 | /* -- page layout ----------------------------------------------------------- */
15 |
16 | body {
17 | font-family: sans-serif;
18 | font-size: 100%;
19 | background-color: #11303d;
20 | color: #000;
21 | margin: 0;
22 | padding: 0;
23 | }
24 |
25 | div.document {
26 | background-color: #1c4e63;
27 | }
28 |
29 | div.documentwrapper {
30 | float: left;
31 | width: 100%;
32 | }
33 |
34 | div.bodywrapper {
35 | margin: 0 0 0 230px;
36 | }
37 |
38 | div.body {
39 | background-color: #ffffff;
40 | color: #000000;
41 | padding: 0 20px 30px 20px;
42 | }
43 |
44 | div.footer {
45 | color: #ffffff;
46 | width: 100%;
47 | padding: 9px 0 9px 0;
48 | text-align: center;
49 | font-size: 75%;
50 | }
51 |
52 | div.footer a {
53 | color: #ffffff;
54 | text-decoration: underline;
55 | }
56 |
57 | div.related {
58 | background-color: #133f52;
59 | line-height: 30px;
60 | color: #ffffff;
61 | }
62 |
63 | div.related a {
64 | color: #ffffff;
65 | }
66 |
67 | div.sphinxsidebar {
68 | }
69 |
70 | div.sphinxsidebar h3 {
71 | font-family: 'Trebuchet MS', sans-serif;
72 | color: #ffffff;
73 | font-size: 1.4em;
74 | font-weight: normal;
75 | margin: 0;
76 | padding: 0;
77 | }
78 |
79 | div.sphinxsidebar h3 a {
80 | color: #ffffff;
81 | }
82 |
83 | div.sphinxsidebar h4 {
84 | font-family: 'Trebuchet MS', sans-serif;
85 | color: #ffffff;
86 | font-size: 1.3em;
87 | font-weight: normal;
88 | margin: 5px 0 0 0;
89 | padding: 0;
90 | }
91 |
92 | div.sphinxsidebar p {
93 | color: #ffffff;
94 | }
95 |
96 | div.sphinxsidebar p.topless {
97 | margin: 5px 10px 10px 10px;
98 | }
99 |
100 | div.sphinxsidebar ul {
101 | margin: 10px;
102 | padding: 0;
103 | color: #ffffff;
104 | }
105 |
106 | div.sphinxsidebar a {
107 | color: #98dbcc;
108 | }
109 |
110 | div.sphinxsidebar input {
111 | border: 1px solid #98dbcc;
112 | font-family: sans-serif;
113 | font-size: 1em;
114 | }
115 |
116 |
117 |
118 | /* -- hyperlink styles ------------------------------------------------------ */
119 |
120 | a {
121 | color: #355f7c;
122 | text-decoration: none;
123 | }
124 |
125 | a:visited {
126 | color: #355f7c;
127 | text-decoration: none;
128 | }
129 |
130 | a:hover {
131 | text-decoration: underline;
132 | }
133 |
134 |
135 |
136 | /* -- body styles ----------------------------------------------------------- */
137 |
138 | div.body h1,
139 | div.body h2,
140 | div.body h3,
141 | div.body h4,
142 | div.body h5,
143 | div.body h6 {
144 | font-family: 'Trebuchet MS', sans-serif;
145 | background-color: #f2f2f2;
146 | font-weight: normal;
147 | color: #20435c;
148 | border-bottom: 1px solid #ccc;
149 | margin: 20px -20px 10px -20px;
150 | padding: 3px 0 3px 10px;
151 | }
152 |
153 | div.body h1 { margin-top: 0; font-size: 200%; }
154 | div.body h2 { font-size: 160%; }
155 | div.body h3 { font-size: 140%; }
156 | div.body h4 { font-size: 120%; }
157 | div.body h5 { font-size: 110%; }
158 | div.body h6 { font-size: 100%; }
159 |
160 | a.headerlink {
161 | color: #c60f0f;
162 | font-size: 0.8em;
163 | padding: 0 4px 0 4px;
164 | text-decoration: none;
165 | }
166 |
167 | a.headerlink:hover {
168 | background-color: #c60f0f;
169 | color: white;
170 | }
171 |
172 | div.body p, div.body dd, div.body li, div.body blockquote {
173 | text-align: justify;
174 | line-height: 130%;
175 | }
176 |
177 | div.admonition p.admonition-title + p {
178 | display: inline;
179 | }
180 |
181 | div.admonition p {
182 | margin-bottom: 5px;
183 | }
184 |
185 | div.admonition pre {
186 | margin-bottom: 5px;
187 | }
188 |
189 | div.admonition ul, div.admonition ol {
190 | margin-bottom: 5px;
191 | }
192 |
193 | div.note {
194 | background-color: #eee;
195 | border: 1px solid #ccc;
196 | }
197 |
198 | div.seealso {
199 | background-color: #ffc;
200 | border: 1px solid #ff6;
201 | }
202 |
203 | div.topic {
204 | background-color: #eee;
205 | }
206 |
207 | div.warning {
208 | background-color: #ffe4e4;
209 | border: 1px solid #f66;
210 | }
211 |
212 | p.admonition-title {
213 | display: inline;
214 | }
215 |
216 | p.admonition-title:after {
217 | content: ":";
218 | }
219 |
220 | pre {
221 | padding: 5px;
222 | background-color: #eeffcc;
223 | color: #333333;
224 | line-height: 120%;
225 | border: 1px solid #ac9;
226 | border-left: none;
227 | border-right: none;
228 | }
229 |
230 | code {
231 | background-color: #ecf0f3;
232 | padding: 0 1px 0 1px;
233 | font-size: 0.95em;
234 | }
235 |
236 | th {
237 | background-color: #ede;
238 | }
239 |
240 | .warning code {
241 | background: #efc2c2;
242 | }
243 |
244 | .note code {
245 | background: #d6d6d6;
246 | }
247 |
248 | .viewcode-back {
249 | font-family: sans-serif;
250 | }
251 |
252 | div.viewcode-block:target {
253 | background-color: #f4debf;
254 | border-top: 1px solid #ac9;
255 | border-bottom: 1px solid #ac9;
256 | }
257 |
258 | div.code-block-caption {
259 | color: #efefef;
260 | background-color: #1c4e63;
261 | }
--------------------------------------------------------------------------------
/doc/sphinx/html/_static/sidebar.js:
--------------------------------------------------------------------------------
1 | /*
2 | * sidebar.js
3 | * ~~~~~~~~~~
4 | *
5 | * This script makes the Sphinx sidebar collapsible.
6 | *
7 | * .sphinxsidebar contains .sphinxsidebarwrapper. This script adds
8 | * in .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton
9 | * used to collapse and expand the sidebar.
10 | *
11 | * When the sidebar is collapsed the .sphinxsidebarwrapper is hidden
12 | * and the width of the sidebar and the margin-left of the document
13 | * are decreased. When the sidebar is expanded the opposite happens.
14 | * This script saves a per-browser/per-session cookie used to
15 | * remember the position of the sidebar among the pages.
16 | * Once the browser is closed the cookie is deleted and the position
17 | * reset to the default (expanded).
18 | *
19 | * :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
20 | * :license: BSD, see LICENSE for details.
21 | *
22 | */
23 |
24 | $(function() {
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | // global elements used by the functions.
34 | // the 'sidebarbutton' element is defined as global after its
35 | // creation, in the add_sidebar_button function
36 | var bodywrapper = $('.bodywrapper');
37 | var sidebar = $('.sphinxsidebar');
38 | var sidebarwrapper = $('.sphinxsidebarwrapper');
39 |
40 | // for some reason, the document has no sidebar; do not run into errors
41 | if (!sidebar.length) return;
42 |
43 | // original margin-left of the bodywrapper and width of the sidebar
44 | // with the sidebar expanded
45 | var bw_margin_expanded = bodywrapper.css('margin-left');
46 | var ssb_width_expanded = sidebar.width();
47 |
48 | // margin-left of the bodywrapper and width of the sidebar
49 | // with the sidebar collapsed
50 | var bw_margin_collapsed = '.8em';
51 | var ssb_width_collapsed = '.8em';
52 |
53 | // colors used by the current theme
54 | var dark_color = $('.related').css('background-color');
55 | var light_color = $('.document').css('background-color');
56 |
57 | function sidebar_is_collapsed() {
58 | return sidebarwrapper.is(':not(:visible)');
59 | }
60 |
61 | function toggle_sidebar() {
62 | if (sidebar_is_collapsed())
63 | expand_sidebar();
64 | else
65 | collapse_sidebar();
66 | }
67 |
68 | function collapse_sidebar() {
69 | sidebarwrapper.hide();
70 | sidebar.css('width', ssb_width_collapsed);
71 | bodywrapper.css('margin-left', bw_margin_collapsed);
72 | sidebarbutton.css({
73 | 'margin-left': '0',
74 | 'height': bodywrapper.height()
75 | });
76 | sidebarbutton.find('span').text('»');
77 | sidebarbutton.attr('title', _('Expand sidebar'));
78 | document.cookie = 'sidebar=collapsed';
79 | }
80 |
81 | function expand_sidebar() {
82 | bodywrapper.css('margin-left', bw_margin_expanded);
83 | sidebar.css('width', ssb_width_expanded);
84 | sidebarwrapper.show();
85 | sidebarbutton.css({
86 | 'margin-left': ssb_width_expanded-12,
87 | 'height': bodywrapper.height()
88 | });
89 | sidebarbutton.find('span').text('«');
90 | sidebarbutton.attr('title', _('Collapse sidebar'));
91 | document.cookie = 'sidebar=expanded';
92 | }
93 |
94 | function add_sidebar_button() {
95 | sidebarwrapper.css({
96 | 'float': 'left',
97 | 'margin-right': '0',
98 | 'width': ssb_width_expanded - 28
99 | });
100 | // create the button
101 | sidebar.append(
102 | ''
103 | );
104 | var sidebarbutton = $('#sidebarbutton');
105 | light_color = sidebarbutton.css('background-color');
106 | // find the height of the viewport to center the '<<' in the page
107 | var viewport_height;
108 | if (window.innerHeight)
109 | viewport_height = window.innerHeight;
110 | else
111 | viewport_height = $(window).height();
112 | sidebarbutton.find('span').css({
113 | 'display': 'block',
114 | 'margin-top': (viewport_height - sidebar.position().top - 20) / 2
115 | });
116 |
117 | sidebarbutton.click(toggle_sidebar);
118 | sidebarbutton.attr('title', _('Collapse sidebar'));
119 | sidebarbutton.css({
120 | 'color': '#FFFFFF',
121 | 'border-left': '1px solid ' + dark_color,
122 | 'font-size': '1.2em',
123 | 'cursor': 'pointer',
124 | 'height': bodywrapper.height(),
125 | 'padding-top': '1px',
126 | 'margin-left': ssb_width_expanded - 12
127 | });
128 |
129 | sidebarbutton.hover(
130 | function () {
131 | $(this).css('background-color', dark_color);
132 | },
133 | function () {
134 | $(this).css('background-color', light_color);
135 | }
136 | );
137 | }
138 |
139 | function set_position_from_cookie() {
140 | if (!document.cookie)
141 | return;
142 | var items = document.cookie.split(';');
143 | for(var k=0; k
4 |
5 |
6 |
7 |
8 | Welcome to Pyment’s documentation! — Pyment 0.3.2 documentation
9 |
10 |
11 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
Welcome to Pyment’s documentation!
52 |
58 |
59 |
60 |
Indices and tables
61 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
102 |
103 |
104 |
119 |
123 |
124 |
--------------------------------------------------------------------------------
/tests/issue93.py.patch:
--------------------------------------------------------------------------------
1 | --- a/issue93.py
2 | +++ b/issue93.py
3 | @@ -1,20 +1,36 @@
4 | def func(): # comment with (parents):
5 | + """ """
6 | pass
7 |
8 |
9 | def func0(param1): # comment with (parents):,
10 | """description
11 | +
12 | :param param1: yoyo
13 | :returns: nothing
14 | +
15 | """
16 | pass
17 |
18 |
19 | def func1(param1: str):
20 | + """
21 | +
22 | + :param param1:
23 | + :type param1: str
24 | +
25 | + """
26 | pass
27 |
28 |
29 | def func2(param1: str) -> int:
30 | + """
31 | +
32 | + :param param1:
33 | + :type param1: str
34 | + :rtype: int
35 | +
36 | + """
37 | pass
38 |
39 |
40 | @@ -22,16 +38,36 @@
41 | """Func 3
42 |
43 | :param param1: param description
44 | - :return: the value
45 | + :type param1: str
46 | + :returns: the value
47 | + :rtype: str
48 | +
49 | """
50 | pass
51 |
52 |
53 | def func4(param1: str, param2: List[int]):
54 | + """
55 | +
56 | + :param param1:
57 | + :type param1: str
58 | + :param param2:
59 | + :type param2: List[int]
60 | +
61 | + """
62 | pass
63 |
64 |
65 | def func5(param1: str, param2: List[int]) -> Dict[str,Object]: # yet:(another) comment
66 | + """
67 | +
68 | + :param param1:
69 | + :type param1: str
70 | + :param param2:
71 | + :type param2: List[int]
72 | + :rtype: Dict[str,Object]
73 | +
74 | + """
75 | pass
76 |
77 |
78 | @@ -41,6 +77,7 @@
79 | :param param1: the first parameter
80 | :type param1: str
81 | :param param2: the second parameter
82 | + :type param2: Dict[str,Object]
83 | :returns: the message
84 | :rtype: str
85 |
86 | @@ -49,53 +86,133 @@
87 |
88 |
89 | def func7(param1: str, param2: Dict[str, Object], param3: int = 12) -> str:
90 | + """
91 | +
92 | + :param param1:
93 | + :type param1: str
94 | + :param param2:
95 | + :type param2: Dict[str, Object]
96 | + :param param3: (Default value = 12)
97 | + :type param3: int
98 | + :rtype: str
99 | +
100 | + """
101 | pass
102 |
103 |
104 | def func8(param1 : str, param2: list=None, param3: str = "foo", param4="bar") -> str:
105 | + """
106 | +
107 | + :param param1:
108 | + :type param1: str
109 | + :param param2: (Default value = None)
110 | + :type param2: list
111 | + :param param3: (Default value = "foo")
112 | + :type param3: str
113 | + :param param4: (Default value = "bar")
114 | + :rtype: str
115 | +
116 | + """
117 | pass
118 |
119 |
120 | def func9(param1: str,
121 | param2: list = None,
122 | param3: str = "foo") -> str:
123 | + """
124 | +
125 | + :param param1:
126 | + :type param1: str
127 | + :param param2: (Default value = None)
128 | + :type param2: list
129 | + :param param3: (Default value = "foo")
130 | + :type param3: str
131 | + :rtype: str
132 | +
133 | + """
134 | pass
135 |
136 |
137 | def func10( param1: str = "", param2='', param3=call_func('foobar') ) :
138 | + """
139 | +
140 | + :param param1: (Default value = "")
141 | + :type param1: str
142 | + :param param2: (Default value = '')
143 | + :param param3: (Default value = call_func('foobar'))
144 | +
145 | + """
146 | pass
147 |
148 |
149 | def func11(self, param1: str, param2: Dict[str, Object], param3: OAuth2PasswordRequestForm = Depends(), param4: int = 1) -> str:
150 | + """
151 | +
152 | + :param param1:
153 | + :type param1: str
154 | + :param param2:
155 | + :type param2: Dict[str, Object]
156 | + :param param3: (Default value = Depends())
157 | + :type param3: OAuth2PasswordRequestForm
158 | + :param param4: (Default value = 1)
159 | + :type param4: int
160 | + :rtype: str
161 | +
162 | + """
163 | pass
164 |
165 |
166 | def func12(cls, param1: str, param2: Dict[str, Object], param3: int = 12) -> str:
167 | + """
168 | +
169 | + :param param1:
170 | + :type param1: str
171 | + :param param2:
172 | + :type param2: Dict[str, Object]
173 | + :param param3: (Default value = 12)
174 | + :type param3: int
175 | + :rtype: str
176 | +
177 | + """
178 | pass
179 |
180 |
181 | def func13(param1, param2: Dict["str", Object], param3: int = 12) -> str:
182 | + """
183 | +
184 | + :param param1:
185 | + :param param2:
186 | + :type param2: Dict["str", Object]
187 | + :param param3: (Default value = 12)
188 | + :type param3: int
189 | + :rtype: str
190 | +
191 | + """
192 | pass
193 |
194 |
195 | def func14(param1=True, param2: str = 'default val'):
196 | - '''Description of func with docstring groups style.
197 | -
198 | - Params:
199 | - param1 - descr of param1 that has True for default value.
200 | - param2 - descr of param2
201 | -
202 | - Returns:
203 | - some value
204 | -
205 | - Raises:
206 | - keyError: raises key exception
207 | - TypeError: raises type exception
208 | -
209 | - '''
210 | + """Description of func with docstring groups style.
211 | +
212 | + :param param1: descr of param1 that has True for default value
213 | + :param param2: descr of param2 (Default value = 'default val')
214 | + :type param2: str
215 | + :returns: some value
216 | + :raises keyError: raises key exception
217 | + :raises TypeError: raises type exception
218 | +
219 | + """
220 | pass
221 |
222 | class A:
223 | + """ """
224 | def method(self, param1, param2=None) -> int:
225 | + """
226 | +
227 | + :param param1:
228 | + :param param2: (Default value = None)
229 | + :rtype: int
230 | +
231 | + """
232 | pass
233 |
234 |
--------------------------------------------------------------------------------
/doc/sphinx/source/conf.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # Pyment documentation build configuration file, created by
4 | # sphinx-quickstart on Wed Sep 27 21:39:14 2017.
5 | #
6 | # This file is execfile()d with the current directory set to its
7 | # containing dir.
8 | #
9 | # Note that not all possible configuration values are present in this
10 | # autogenerated file.
11 | #
12 | # All configuration values have a default; values that are commented out
13 | # serve to show the default.
14 |
15 | # If extensions (or modules to document with autodoc) are in another directory,
16 | # add these directories to sys.path here. If the directory is relative to the
17 | # documentation root, use os.path.abspath to make it absolute, like shown here.
18 | #
19 | import os
20 | import sys
21 | sys.path.insert(0, os.path.abspath('../../../pyment'))
22 |
23 |
24 | # -- General configuration ------------------------------------------------
25 |
26 | # If your documentation needs a minimal Sphinx version, state it here.
27 | #
28 | # needs_sphinx = '1.0'
29 |
30 | # Add any Sphinx extension module names here, as strings. They can be
31 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
32 | # ones.
33 | extensions = ['sphinx.ext.autodoc',
34 | 'sphinx.ext.githubpages']
35 |
36 | # Add any paths that contain templates here, relative to this directory.
37 | templates_path = ['_templates']
38 |
39 | # The suffix(es) of source filenames.
40 | # You can specify multiple suffix as a list of string:
41 | #
42 | # source_suffix = ['.rst', '.md']
43 | source_suffix = '.rst'
44 |
45 | # The master toctree document.
46 | master_doc = 'index'
47 |
48 | # General information about the project.
49 | project = u'Pyment'
50 | copyright = u'2017, Daouzli Adel'
51 | author = u'Daouzli Adel'
52 |
53 | # The version info for the project you're documenting, acts as replacement for
54 | # |version| and |release|, also used in various other places throughout the
55 | # built documents.
56 | #
57 | # The short X.Y version.
58 | version = u'0.3.2'
59 | # The full version, including alpha/beta/rc tags.
60 | release = u'0.3.2'
61 |
62 | # The language for content autogenerated by Sphinx. Refer to documentation
63 | # for a list of supported languages.
64 | #
65 | # This is also used if you do content translation via gettext catalogs.
66 | # Usually you set "language" from the command line for these cases.
67 | language = None
68 |
69 | # List of patterns, relative to source directory, that match files and
70 | # directories to ignore when looking for source files.
71 | # This patterns also effect to html_static_path and html_extra_path
72 | exclude_patterns = []
73 |
74 | # The name of the Pygments (syntax highlighting) style to use.
75 | pygments_style = 'sphinx'
76 |
77 | # If true, `todo` and `todoList` produce output, else they produce nothing.
78 | todo_include_todos = False
79 |
80 |
81 | # -- Options for HTML output ----------------------------------------------
82 |
83 | # The theme to use for HTML and HTML Help pages. See the documentation for
84 | # a list of builtin themes.
85 | #
86 | html_theme = 'classic'
87 | #html_theme = 'sphinx_rtd_theme'
88 | html_theme_path = ["_themes", ]
89 | # Theme options are theme-specific and customize the look and feel of a theme
90 | # further. For a list of options available for each theme, see the
91 | # documentation.
92 | #
93 | # html_theme_options = {}
94 |
95 | # Add any paths that contain custom static files (such as style sheets) here,
96 | # relative to this directory. They are copied after the builtin static files,
97 | # so a file named "default.css" will overwrite the builtin "default.css".
98 | html_static_path = ['_static']
99 |
100 | # Custom sidebar templates, must be a dictionary that maps document names
101 | # to template names.
102 | #
103 | # This is required for the alabaster theme
104 | # refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars
105 | # html_sidebars = {
106 | # '**': [
107 | # 'about.html',
108 | # 'navigation.html',
109 | # 'relations.html', # needs 'show_related': True theme option to display
110 | # 'searchbox.html',
111 | # 'donate.html',
112 | # ]
113 | # }
114 |
115 |
116 | # -- Options for HTMLHelp output ------------------------------------------
117 |
118 | # Output file base name for HTML help builder.
119 | htmlhelp_basename = 'Pymentdoc'
120 |
121 |
122 | # -- Options for LaTeX output ---------------------------------------------
123 |
124 | latex_elements = {
125 | # The paper size ('letterpaper' or 'a4paper').
126 | #
127 | # 'papersize': 'letterpaper',
128 |
129 | # The font size ('10pt', '11pt' or '12pt').
130 | #
131 | # 'pointsize': '10pt',
132 |
133 | # Additional stuff for the LaTeX preamble.
134 | #
135 | # 'preamble': '',
136 |
137 | # Latex figure (float) alignment
138 | #
139 | # 'figure_align': 'htbp',
140 | }
141 |
142 | # Grouping the document tree into LaTeX files. List of tuples
143 | # (source start file, target name, title,
144 | # author, documentclass [howto, manual, or own class]).
145 | latex_documents = [
146 | (master_doc, 'Pyment.tex', u'Pyment Documentation',
147 | u'Daouzli Adel', 'manual'),
148 | ]
149 |
150 |
151 | # -- Options for manual page output ---------------------------------------
152 |
153 | # One entry per manual page. List of tuples
154 | # (source start file, name, description, authors, manual section).
155 | man_pages = [
156 | (master_doc, 'pyment', u'Pyment Documentation',
157 | [author], 1)
158 | ]
159 |
160 |
161 | # -- Options for Texinfo output -------------------------------------------
162 |
163 | # Grouping the document tree into Texinfo files. List of tuples
164 | # (source start file, target name, title, author,
165 | # dir menu entry, description, category)
166 | texinfo_documents = [
167 | (master_doc, 'Pyment', u'Pyment Documentation',
168 | author, 'Pyment', 'One line description of project.',
169 | 'Miscellaneous'),
170 | ]
171 |
172 |
173 |
174 |
--------------------------------------------------------------------------------
/doc/sphinx/html/searchindex.js:
--------------------------------------------------------------------------------
1 | Search.setIndex({docnames:["index","pyment","pyment_doc"],envversion:52,filenames:["index.rst","pyment.rst","pyment_doc.rst"],objects:{"":{docstring:[2,0,0,"-"],pyment:[2,0,0,"-"]},"docstring.DocString":{__init__:[2,2,1,""],__weakref__:[2,3,1,""],generate_docs:[2,2,1,""],get_input_docstring:[2,2,1,""],get_input_style:[2,2,1,""],get_output_style:[2,2,1,""],get_raw_docs:[2,2,1,""],get_spaces:[2,2,1,""],parse_docs:[2,2,1,""],parse_element:[2,2,1,""],set_input_style:[2,2,1,""],set_output_style:[2,2,1,""],set_spaces:[2,2,1,""]},"docstring.DocsTools":{__init__:[2,2,1,""],__weakref__:[2,3,1,""],autodetect_style:[2,2,1,""],get_doctests_indexes:[2,2,1,""],get_elem_desc:[2,2,1,""],get_elem_index:[2,2,1,""],get_elem_param:[2,2,1,""],get_group_index:[2,2,1,""],get_group_key_index:[2,2,1,""],get_group_key_line:[2,2,1,""],get_group_line:[2,2,1,""],get_key:[2,2,1,""],get_key_index:[2,2,1,""],get_param_description_indexes:[2,2,1,""],get_param_indexes:[2,2,1,""],get_param_type_indexes:[2,2,1,""],get_raise_description_indexes:[2,2,1,""],get_raise_indexes:[2,2,1,""],get_return_description_indexes:[2,2,1,""],get_return_type_indexes:[2,2,1,""],get_sep:[2,2,1,""],set_input_style:[2,2,1,""],set_known_parameters:[2,2,1,""],set_output_style:[2,2,1,""]},"docstring.GoogledocTools":{__init__:[2,2,1,""],__weakref__:[2,3,1,""],get_excluded_sections:[2,2,1,""],get_key_section_header:[2,2,1,""],get_list_key:[2,2,1,""],get_mandatory_sections:[2,2,1,""],get_next_section_lines:[2,2,1,""],get_next_section_start_line:[2,2,1,""],get_optional_sections:[2,2,1,""],get_param_list:[2,2,1,""],get_raise_list:[2,2,1,""],get_return_list:[2,2,1,""],get_section_key_line:[2,2,1,""]},"docstring.NumpydocTools":{__init__:[2,2,1,""],__weakref__:[2,3,1,""],get_attr_list:[2,2,1,""],get_key_section_header:[2,2,1,""],get_list_key:[2,2,1,""],get_next_section_lines:[2,2,1,""],get_next_section_start_line:[2,2,1,""],get_param_list:[2,2,1,""],get_raise_list:[2,2,1,""],get_raw_not_managed:[2,2,1,""],get_return_list:[2,2,1,""],get_section_key_line:[2,2,1,""]},"pyment.PyComment":{__init__:[2,2,1,""],__weakref__:[2,3,1,""],compute_before_after:[2,2,1,""],diff:[2,2,1,""],diff_to_file:[2,2,1,""],docs_init_to_class:[2,2,1,""],get_output_docs:[2,2,1,""],proceed:[2,2,1,""],write_to_file:[2,2,1,""]},docstring:{DocString:[2,1,1,""],DocsTools:[2,1,1,""],GoogledocTools:[2,1,1,""],NumpydocTools:[2,1,1,""]},pyment:{PyComment:[2,1,1,""]}},objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","attribute","Python attribute"]},objtypes:{"0":"py:module","1":"py:class","2":"py:method","3":"py:attribute"},terms:{"1kz5bu4hurtwbjzopn6xwsvsmttdk6kb89":1,"1st":1,"2nd":1,"3rd":1,"boolean":2,"case":1,"class":1,"default":[1,2],"final":[1,2],"function":[1,2],"import":[1,2],"int":1,"new":1,"return":[1,2],"sa\u00efghi":1,"true":[1,2],"try":2,And:1,But:1,IDE:1,The:[1,2],Then:1,There:1,Will:1,__init__:[1,2],__init__on:2,__weakref__:2,a_func:1,abov:2,accept:2,adapt:1,add:1,address:1,adel:1,after:[1,2],alain:1,all:2,allow:[1,2],alreadi:1,also:[1,2],alwai:1,ani:[1,2],appli:1,archiv:1,arg:1,argpars:1,argument:1,arrang:1,array_lik:1,attr:2,attribut:2,auto:1,autodetect:[1,2],autodetect_styl:2,automat:1,avail:1,back:2,basenam:1,befor:2,begin:2,better:1,between:2,biblio:1,bitcoin:1,blabla:1,bool:1,build:2,can:[1,2],categori:2,chang:[1,2],channel:1,charact:[1,2],choos:2,cite:1,clone:1,code:[0,1],com:1,command:1,comment:1,compat:2,comput:2,compute_before_aft:2,concern:1,config:[1,2],config_fil:2,configur:2,conserv:1,consid:1,contain:[1,2],converg:1,convert:[1,2],convert_onli:[1,2],correl:1,correspond:1,could:2,creat:[1,2],creator:1,current:[1,2],dadadel:1,dadel:1,daouzli:1,data:2,date:1,dedic:1,def:[1,2],defin:2,delimit:1,depend:[1,2],desc:2,descr:1,descript:[1,2],destexh:1,detect:2,determin:2,develop:1,dictionari:2,diff:2,diff_to_fil:[1,2],differ:2,directli:1,doc:[1,2],docs_init_to_class:2,docs_raw:2,docstyl:2,doctest:2,doctr:2,doe:2,don:[1,2],donat:1,done:2,dot:1,each:[1,2],earli:1,easier:1,easiest:1,elem_raw:2,element:2,els:2,email:1,empti:2,end:[1,2],enhanc:1,enjoi:1,enough:1,error:1,escap:1,especi:1,even:2,exampl:2,except:[1,2],exclud:[1,2],excluded_sect:2,exhaut:1,exist:[1,2],exit:1,explain:1,explor:1,extern:2,extract:2,fals:[1,2],favorit:1,field:1,file:2,filenam:1,find:1,first:[1,2],first_lin:[1,2],folder:[1,2],follow:[1,2],format:2,found:[1,2],free:1,freenod:1,from:[1,2],func:1,gener:[1,2],generate_doc:2,get:[1,2],get_attr_list:2,get_doctests_index:2,get_elem_desc:2,get_elem_index:2,get_elem_param:2,get_excluded_sect:2,get_group_index:2,get_group_key_index:2,get_group_key_lin:2,get_group_lin:2,get_input_docstr:2,get_input_styl:2,get_kei:2,get_key_index:2,get_key_section_head:2,get_list_kei:2,get_mandatory_sect:2,get_next_section_lin:2,get_next_section_start_lin:2,get_optional_sect:2,get_output_doc:[1,2],get_output_styl:2,get_param_description_index:2,get_param_index:2,get_param_list:2,get_param_type_index:2,get_raise_description_index:2,get_raise_index:2,get_raise_list:2,get_raw_doc:2,get_raw_not_manag:2,get_return_description_index:2,get_return_list:2,get_return_type_index:2,get_section_key_lin:2,get_sep:2,get_spac:2,git:1,github:1,give:1,given:2,global:[1,2],gmail:1,good:1,googl:[1,2],googledoc:1,great:1,group:[1,2],happi:1,harmon:1,has:1,have:1,head:1,header:2,help:1,here:1,him:1,howev:1,http:1,ignor:1,ignore_priv:2,includ:2,index:[0,2],indic:2,influenc:1,inform:1,init2class:1,initi:2,input:[1,2],input_fil:2,input_styl:[1,2],insert:2,insid:1,instanc:2,instead:1,integ:2,intend:2,intern:2,interpret:1,introspect:1,irc:1,issu:1,its:1,iwann:1,javadoc:[1,2],just:1,kei:[1,2],keyerror:1,kind:[1,2],known:2,kwarg:2,larg:1,last:2,later:1,latest:1,lead:2,less:1,let:[1,2],like:[1,2],limit:1,line:[1,2],link:1,list:2,made:2,mai:[1,2],make:1,manag:2,mandatori:2,math:1,mayb:1,messag:1,method:[1,2],michel:1,miss:[1,2],modul:0,move:1,must:2,name:[1,2],network:1,neural:1,next:2,nois:1,none:[1,2],note:[1,2],now:1,number:[1,2],numpi:2,numpydoc:[1,2],object:2,obtain:1,onc:2,one:[1,2],ones:1,onli:[1,2],open:1,opposit:1,option:[1,2],optional_sect:2,order:2,origin:[1,2],other:[1,2],othererror:1,out:2,output:[1,2],output_styl:[1,2],overload:1,overwrit:1,overwritten:1,own:1,page:0,param1:[1,2],param2:[1,2],param:[1,2],paramet:[1,2],pars:[1,2],parse_doc:2,parse_el:2,part:2,partial:1,pass:1,patch:[1,2],patch_fil:2,path:[1,2],place:2,plane:1,pleas:1,plugin:1,posit:1,prev:2,previou:[1,2],print:1,privat:[1,2],proce:[1,2],prog:1,program:[1,2],programm:1,project:[1,2],properti:1,propos:[1,2],provid:[1,2],pull:1,pycom:1,python:[1,2],quot:[1,2],rais:[1,2],raw:2,reach:2,realli:1,recogn:[1,2],ref:[1,2],refer:[0,2],releas:1,renaud:1,repres:2,request:1,rest:[1,2],restructur:[1,2],result:2,retriev:1,rewrit:2,rtype:[1,2],rudolph:1,sai:1,same:2,save:2,script:[1,2],search:0,second:[1,2],section:[1,2],see:[1,2],self:1,send:1,separ:2,set:[1,2],set_input_styl:2,set_known_paramet:2,set_output_styl:2,set_spac:2,setup:1,sever:[1,2],should:[1,2],show:1,softwar:1,some:1,sourc:0,source_path:2,space:2,sphinx:[1,2],start:[1,2],statu:1,step:1,str:[1,2],string:[1,2],structur:1,style:[1,2],style_in:2,style_out:2,sub:1,subject:1,surround:1,sylvain:1,sylvi:1,target:2,target_path:2,test:1,text:[1,2],than:2,thei:2,thi:[1,2],thing:1,third:1,todo:[1,2],tool:2,trail:2,trailing_spac:2,tupl:2,two:[1,2],type:[1,2],typeerror:1,under:1,underlin:2,underscor:[1,2],unfortun:1,unit:1,unknown:2,updat:1,usabl:1,usag:1,use:[1,2],used:[1,2],useful:1,user:2,using:[1,2],val:1,valu:[1,2],veri:1,version:1,wai:[1,2],want:[1,2],weak:2,well:1,were:2,when:1,where:2,which:[1,2],whitespac:2,without:[1,2],won:1,would:1,write:[1,2],write_to_fil:2,yet:1,you:[1,2],your:[1,2]},titles:["Welcome to Pyment\u2019s documentation!","Reference documentation","Source code documentation"],titleterms:{"class":2,Using:1,code:2,configur:1,contact:1,content:[1,2],contribut:1,custom:1,docstool:2,docstr:[1,2],document:[0,1,2],doe:1,exampl:1,file:1,format:1,full:1,googledoctool:2,how:1,indic:0,instal:1,introduct:1,manag:1,modul:2,numpydoctool:2,pycom:2,pyment:[0,1,2],refer:1,result:1,run:1,sourc:2,support:1,tabl:[0,2],welcom:0,what:1,work:1}})
--------------------------------------------------------------------------------
/pyment/pymentapp.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 |
4 | import glob
5 | import argparse
6 | import os
7 | import sys
8 |
9 | from pyment import PyComment
10 | from pyment import __version__, __copyright__, __author__, __licence__
11 |
12 |
13 | MAX_DEPTH_RECUR = 50
14 | ''' The maximum depth to reach while recursively exploring sub folders'''
15 |
16 |
17 | def get_files_from_dir(path, recursive=True, depth=0, file_ext='.py'):
18 | """Retrieve the list of files from a folder.
19 |
20 | @param path: file or directory where to search files
21 | @param recursive: if True will search also sub-directories
22 | @param depth: if explore recursively, the depth of sub directories to follow
23 | @param file_ext: the files extension to get. Default is '.py'
24 | @return: the file list retrieved. if the input is a file then a one element list.
25 |
26 | """
27 | file_list = []
28 | if os.path.isfile(path) or path == '-':
29 | return [path]
30 | if path[-1] != os.sep:
31 | path = path + os.sep
32 | for f in glob.glob(path + "*"):
33 | if os.path.isdir(f):
34 | if depth < MAX_DEPTH_RECUR: # avoid infinite recursive loop
35 | file_list.extend(get_files_from_dir(f, recursive, depth + 1))
36 | else:
37 | continue
38 | elif f.endswith(file_ext):
39 | file_list.append(f)
40 | return file_list
41 |
42 |
43 | def get_config(config_file):
44 | """Get the configuration from a file.
45 |
46 | @param config_file: the configuration file
47 | @return: the configuration
48 | @rtype: dict
49 |
50 | """
51 | config = {}
52 | tobool = lambda s: True if s.lower() == 'true' else False
53 | if config_file:
54 | try:
55 | f = open(config_file, 'r')
56 | except:
57 | print ("Unable to open configuration file '{0}'".format(config_file))
58 | else:
59 | for line in f.readlines():
60 | if len(line.strip()):
61 | key, value = line.split("=", 1)
62 | key, value = key.strip(), value.strip()
63 | if key in ['init2class', 'first_line', 'convert_only']:
64 | value = tobool(value)
65 | if key == 'indent':
66 | value = int(value)
67 | config[key] = value
68 | return config
69 |
70 |
71 | def run(source, files=[], input_style='auto', output_style='reST', first_line=True, quotes='"""',
72 | init2class=False, convert=False, config_file=None, ignore_private=False, overwrite=False, spaces=4,
73 | skip_empty=False):
74 | if input_style == 'auto':
75 | input_style = None
76 |
77 | config = get_config(config_file)
78 | if 'init2class' in config:
79 | init2class = config.pop('init2class')
80 | if 'convert_only' in config:
81 | convert = config.pop('convert_only')
82 | if 'quotes' in config:
83 | quotes = config.pop('quotes')
84 | if 'input_style' in config:
85 | input_style = config.pop('input_style')
86 | if 'output_style' in config:
87 | output_style = config.pop('output_style')
88 | if 'first_line' in config:
89 | first_line = config.pop('first_line')
90 | for f in files:
91 | if os.path.isdir(source):
92 | path = source + os.sep + os.path.relpath(os.path.abspath(f), os.path.abspath(source))
93 | path = path[:-len(os.path.basename(f))]
94 | else:
95 | path = ''
96 | c = PyComment(f, quotes=quotes,
97 | input_style=input_style,
98 | output_style=output_style,
99 | first_line=first_line,
100 | ignore_private=ignore_private,
101 | convert_only=convert,
102 | num_of_spaces=spaces,
103 | skip_empty=skip_empty,
104 | **config)
105 | c.proceed()
106 | if init2class:
107 | c.docs_init_to_class()
108 |
109 | if overwrite:
110 | list_from, list_to = c.compute_before_after()
111 | lines_to_write = list_to
112 | else:
113 | lines_to_write = c.get_patch_lines(path, path)
114 |
115 | if f == '-':
116 | sys.stdout.writelines(lines_to_write)
117 | else:
118 | if overwrite:
119 | if list_from != list_to:
120 | c.overwrite_source_file(lines_to_write)
121 | else:
122 | c.write_patch_file(os.path.basename(f) + ".patch", lines_to_write)
123 |
124 |
125 | def main():
126 | desc = 'Pyment v{0} - {1} - {2} - {3}'.format(__version__, __copyright__, __author__, __licence__)
127 | parser = argparse.ArgumentParser(description='Generates patches after (re)writing docstrings.')
128 | parser.add_argument('path', type=str,
129 | help='python file or folder containing python files to proceed (explore also sub-folders). Use "-" to read from stdin and write to stdout')
130 | parser.add_argument('-i', '--input', metavar='style', default='auto',
131 | dest='input', help='Input docstring style in ["javadoc", "reST", "numpydoc", "google", "auto"] (default autodetected)')
132 | parser.add_argument('-o', '--output', metavar='style', default="reST",
133 | dest='output', help='Output docstring style in ["javadoc", "reST", "numpydoc", "google"] (default "reST")')
134 | parser.add_argument('-q', '--quotes', metavar='quotes', default='"""',
135 | dest='quotes', help='Type of docstring delimiter quotes: \'\'\' or \"\"\" (default \"\"\"). Note that you may escape the characters using \\ like \\\'\\\'\\\', or surround it with the opposite quotes like \"\'\'\'\"')
136 | parser.add_argument('-f', '--first-line', metavar='status', default="True",
137 | dest='first_line', help='Does the comment starts on the first line after the quotes (default "True")')
138 | parser.add_argument('-t', '--convert', action="store_true", default=False,
139 | help="Existing docstrings will be converted but won't create missing ones")
140 | parser.add_argument('-c', '--config-file', metavar='config', default="",
141 | dest='config_file', help='Get a Pyment configuration from a file. Note that the config values will overload the command line ones.')
142 | parser.add_argument('-d', '--init2class', help='If no docstring to class, then move the __init__ one',
143 | action="store_true")
144 | parser.add_argument('-p', '--ignore-private', metavar='status', default="True",
145 | dest='ignore_private', help='Don\'t proceed the private methods/functions starting with __ (two underscores) (default "True")')
146 | parser.add_argument('-v', '--version', action='version',
147 | version=desc)
148 | parser.add_argument('-w', '--write', action='store_true', dest='overwrite',
149 | default=False, help="Don't write patches. Overwrite files instead. If used with path '-' won\'t overwrite but write to stdout the new content instead of a patch/.")
150 | parser.add_argument('-s', '--spaces', metavar='spaces', dest='spaces', default=4, type=int,
151 | help="The default number of spaces to use for indenting on output. Default is 4.")
152 | parser.add_argument('-e', '--skip-empty', action='store_true', dest='skip_empty',
153 | default=False,
154 | help="Don't write params, returns, or raises sections if they are empty.")
155 | # parser.add_argument('-c', '--config', metavar='config_file',
156 | # dest='config', help='Configuration file')
157 |
158 | args = parser.parse_args()
159 | source = args.path
160 |
161 | files = get_files_from_dir(source)
162 | if not files:
163 | msg = BaseException("No files were found matching {0}".format(args.path))
164 | raise msg
165 | if not args.config_file:
166 | config_file = ''
167 | else:
168 | config_file = args.config_file
169 |
170 | tobool = lambda s: True if s.lower() == 'true' else False
171 | run(source, files, args.input, args.output,
172 | tobool(args.first_line), args.quotes,
173 | args.init2class, args.convert, config_file,
174 | tobool(args.ignore_private), overwrite=args.overwrite,
175 | spaces=args.spaces, skip_empty=args.skip_empty)
176 |
177 |
178 | if __name__ == "__main__":
179 | main()
180 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | pyment
2 | ======
3 |
4 | Create, update or convert docstrings in existing Python files, managing several styles.
5 |
6 | .. contents:: :local:
7 |
8 | Project Status
9 | --------------
10 |
11 | **Test Status**
12 |
13 | Linux: |travis|
14 |
15 | Windows: |appveyor|
16 |
17 |
18 | .. |travis| image:: https://travis-ci.org/dadadel/pyment.svg?branch=master
19 | :target: https://travis-ci.org/dadadel/pyment.svg?branch=master
20 | :alt: Linux tests (TravisCI)
21 |
22 | .. |appveyor| image:: https://ci.appveyor.com/api/projects/status/f9d4jps5fkf4m42h?svg=true
23 | :target: https://ci.appveyor.com/api/projects/status/f9d4jps5fkf4m42h?svg=true
24 | :alt: Windows tests (Appveyor)
25 |
26 | |
27 |
28 | **Supported Versions**
29 |
30 | .. image:: https://img.shields.io/badge/python-3.6-blue.svg
31 | :target: https://img.shields.io/badge/python-3.6-blue.svg
32 | :alt: Supports Python36
33 | .. image:: https://img.shields.io/badge/python-3.7-blue.svg
34 | :target: https://img.shields.io/badge/python-3.7-blue.svg
35 | :alt: Supports Python37
36 | .. image:: https://img.shields.io/badge/python-3.8-blue.svg
37 | :target: https://img.shields.io/badge/python-3.8-blue.svg
38 | :alt: Supports Python38
39 | .. image:: https://img.shields.io/badge/python-3.9-blue.svg
40 | :target: https://img.shields.io/badge/python-3.9-blue.svg
41 | :alt: Supports Python39
42 |
43 | |
44 |
45 | **Code Coverage**
46 |
47 | .. image:: https://coveralls.io/repos/github/wagnerpeer/pyment/badge.svg?branch=enhancement%2Fcoveralls
48 | :target: https://coveralls.io/github/wagnerpeer/pyment?branch=enhancement%2Fcoveralls
49 | :alt: Test coverage (Coveralls)
50 |
51 |
52 | Description
53 | -----------
54 |
55 | This Python3 program intends to help Python programmers to enhance inside code documentation using docstrings.
56 | It is useful for code not well documented, or code without docstrings, or some not yet or partially documented code, or a mix of all of this :-)
57 | It can be helpful also to harmonize or change a project docstring style format.
58 |
59 | It will parse one or several python scripts and retrieve existing docstrings.
60 | Then, for all found functions/methods/classes, it will generate formatted docstrings with parameters, default values,...
61 |
62 | At the end, patches can be generated for each file. Then, man can apply the patches to the initial scripts.
63 | It is also possible to update the files directly without generating patches, or to output on *stdout*.
64 | It is also possible to generate the python file with the new docstrings, or to retrieve only the docstrings...
65 |
66 | Currently, the managed styles in input/output are javadoc, one variant of reST (re-Structured Text, used by Sphinx), numpydoc, google docstrings, groups (other grouped style).
67 |
68 | You can also configure some settings via the command line or a configuration
69 | file.
70 |
71 | To get further information please refer to the `documentation `_.
72 |
73 | The tool, at the time, offer to generate patches or get a list of the new docstrings (created or converted).
74 |
75 | You can contact the developer *dadel* by opening a `discussion `_.
76 |
77 | Start quickly
78 | -------------
79 | - install from Pypi
80 |
81 | .. code-block:: sh
82 |
83 | $ pip install pyment
84 |
85 | - install from sources:
86 |
87 | .. code-block:: sh
88 |
89 | $ pip install git+https://github.com/dadadel/pyment.git
90 | or
91 | $ git clone https://github.com/dadadel/pyment.git
92 | $ cd pyment
93 | $ python setup.py install
94 |
95 | - run from the command line:
96 |
97 | .. code-block:: sh
98 |
99 | $ pyment myfile.py # will generate a patch
100 | $ pyment -w myfile.py # will overwrite the file
101 |
102 | or
103 |
104 | .. code-block:: sh
105 |
106 | $ pyment my/folder/
107 |
108 | - get help:
109 |
110 | .. code-block:: sh
111 |
112 | $ pyment -h
113 |
114 | - run from a script:
115 |
116 | .. code-block:: python
117 |
118 | import os
119 | from pyment import PyComment
120 |
121 | filename = 'test.py'
122 |
123 | c = PyComment(filename)
124 | c.proceed()
125 | c.diff_to_file(os.path.basename(filename) + ".patch")
126 | for s in c.get_output_docs():
127 | print(s)
128 |
129 | Example
130 | -------
131 |
132 | Here is a full example using Pyment to generate a patch and then apply the patch.
133 |
134 | Let's consider a file *test.py* with following content:
135 |
136 | .. code-block:: python
137 |
138 | def func(param1=True, param2: str = 'default val'):
139 | '''Description of func with docstring groups style.
140 |
141 | Params:
142 | param1 - descr of param1 that has True for default value.
143 | param2 - descr of param2
144 |
145 | Returns:
146 | some value
147 |
148 | Raises:
149 | keyError: raises key exception
150 | TypeError: raises type exception
151 |
152 | '''
153 | pass
154 |
155 | class A:
156 | def method(self, param1, param2=None) -> int:
157 | pass
158 |
159 | Now let's use Pyment:
160 |
161 | .. code-block:: sh
162 |
163 | $ pyment test.py
164 |
165 | Using Pyment without any argument will autodetect the docstrings formats and generate a patch using the reStructured Text format.
166 | So the previous command has generated the file *test.py.patch* with following content:
167 |
168 | .. code-block:: patch
169 |
170 | # Patch generated by Pyment v0.4.0
171 |
172 | --- a/test.py
173 | +++ b/test.py
174 | @@ -1,20 +1,22 @@
175 | def func(param1=True, param2: str = 'default val'):
176 | - '''Description of func with docstring groups style.
177 | -
178 | - Params:
179 | - param1 - descr of param1 that has True for default value.
180 | - param2 - descr of param2
181 | -
182 | - Returns:
183 | - some value
184 | -
185 | - Raises:
186 | - keyError: raises key exception
187 | - TypeError: raises type exception
188 | -
189 | - '''
190 | + """Description of func with docstring groups style.
191 | +
192 | + :param param1: descr of param1 that has True for default value
193 | + :param param2: descr of param2 (Default value = 'default val')
194 | + :type param2: str
195 | + :returns: some value
196 | + :raises keyError: raises key exception
197 | + :raises TypeError: raises type exception
198 | +
199 | + """
200 | pass
201 |
202 | class A:
203 | + """ """
204 | def method(self, param1, param2=None) -> int:
205 | + """
206 | +
207 | + :param param1:
208 | + :param param2: (Default value = None)
209 | + :rtype: int
210 | +
211 | + """
212 | pass
213 |
214 | Let's finally apply the patch with the following command:
215 |
216 | .. code-block:: sh
217 |
218 | $ patch -p1 < test.py.patch
219 |
220 | Now the original *test.py* was updated and its content is now:
221 |
222 | .. code-block:: python
223 |
224 | def func(param1=True, param2: str = 'default val'):
225 | """Description of func with docstring groups style.
226 |
227 | :param param1: descr of param1 that has True for default value
228 | :param param2: descr of param2 (Default value = 'default val')
229 | :type param2: str
230 | :returns: some value
231 | :raises keyError: raises key exception
232 | :raises TypeError: raises type exception
233 |
234 | """
235 | pass
236 |
237 | class A:
238 | """ """
239 | def method(self, param1, param2=None) -> int:
240 | """
241 |
242 | :param param1:
243 | :param param2: (Default value = None)
244 | :rtype: int
245 |
246 | """
247 | pass
248 |
249 | Also refer to the files `example.py.patch `_ or `example_numpy.py.patch `_ to see some other results that can be obtained processing the file `example.py `_
250 |
251 |
252 | Offer a coffee or a beer
253 | ------------------------
254 |
255 | If you enjoyed this free software, and want to thank me, you can offer me some
256 | bitcoins for a coffee, a beer, or more, I would be happy :)
257 |
258 | Here's my address for bitcoins : 1Kz5bu4HuRtwbjzopN6xWSVsmtTDK6Kb89
259 |
260 |
--------------------------------------------------------------------------------
/doc/sphinx/html/_static/doctools.js:
--------------------------------------------------------------------------------
1 | /*
2 | * doctools.js
3 | * ~~~~~~~~~~~
4 | *
5 | * Sphinx JavaScript utilities for all documentation.
6 | *
7 | * :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
8 | * :license: BSD, see LICENSE for details.
9 | *
10 | */
11 |
12 | /**
13 | * select a different prefix for underscore
14 | */
15 | $u = _.noConflict();
16 |
17 | /**
18 | * make the code below compatible with browsers without
19 | * an installed firebug like debugger
20 | if (!window.console || !console.firebug) {
21 | var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
22 | "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
23 | "profile", "profileEnd"];
24 | window.console = {};
25 | for (var i = 0; i < names.length; ++i)
26 | window.console[names[i]] = function() {};
27 | }
28 | */
29 |
30 | /**
31 | * small helper function to urldecode strings
32 | */
33 | jQuery.urldecode = function(x) {
34 | return decodeURIComponent(x).replace(/\+/g, ' ');
35 | };
36 |
37 | /**
38 | * small helper function to urlencode strings
39 | */
40 | jQuery.urlencode = encodeURIComponent;
41 |
42 | /**
43 | * This function returns the parsed url parameters of the
44 | * current request. Multiple values per key are supported,
45 | * it will always return arrays of strings for the value parts.
46 | */
47 | jQuery.getQueryParameters = function(s) {
48 | if (typeof s == 'undefined')
49 | s = document.location.search;
50 | var parts = s.substr(s.indexOf('?') + 1).split('&');
51 | var result = {};
52 | for (var i = 0; i < parts.length; i++) {
53 | var tmp = parts[i].split('=', 2);
54 | var key = jQuery.urldecode(tmp[0]);
55 | var value = jQuery.urldecode(tmp[1]);
56 | if (key in result)
57 | result[key].push(value);
58 | else
59 | result[key] = [value];
60 | }
61 | return result;
62 | };
63 |
64 | /**
65 | * highlight a given string on a jquery object by wrapping it in
66 | * span elements with the given class name.
67 | */
68 | jQuery.fn.highlightText = function(text, className) {
69 | function highlight(node) {
70 | if (node.nodeType == 3) {
71 | var val = node.nodeValue;
72 | var pos = val.toLowerCase().indexOf(text);
73 | if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) {
74 | var span = document.createElement("span");
75 | span.className = className;
76 | span.appendChild(document.createTextNode(val.substr(pos, text.length)));
77 | node.parentNode.insertBefore(span, node.parentNode.insertBefore(
78 | document.createTextNode(val.substr(pos + text.length)),
79 | node.nextSibling));
80 | node.nodeValue = val.substr(0, pos);
81 | }
82 | }
83 | else if (!jQuery(node).is("button, select, textarea")) {
84 | jQuery.each(node.childNodes, function() {
85 | highlight(this);
86 | });
87 | }
88 | }
89 | return this.each(function() {
90 | highlight(this);
91 | });
92 | };
93 |
94 | /*
95 | * backward compatibility for jQuery.browser
96 | * This will be supported until firefox bug is fixed.
97 | */
98 | if (!jQuery.browser) {
99 | jQuery.uaMatch = function(ua) {
100 | ua = ua.toLowerCase();
101 |
102 | var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
103 | /(webkit)[ \/]([\w.]+)/.exec(ua) ||
104 | /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
105 | /(msie) ([\w.]+)/.exec(ua) ||
106 | ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
107 | [];
108 |
109 | return {
110 | browser: match[ 1 ] || "",
111 | version: match[ 2 ] || "0"
112 | };
113 | };
114 | jQuery.browser = {};
115 | jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;
116 | }
117 |
118 | /**
119 | * Small JavaScript module for the documentation.
120 | */
121 | var Documentation = {
122 |
123 | init : function() {
124 | this.fixFirefoxAnchorBug();
125 | this.highlightSearchWords();
126 | this.initIndexTable();
127 |
128 | },
129 |
130 | /**
131 | * i18n support
132 | */
133 | TRANSLATIONS : {},
134 | PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; },
135 | LOCALE : 'unknown',
136 |
137 | // gettext and ngettext don't access this so that the functions
138 | // can safely bound to a different name (_ = Documentation.gettext)
139 | gettext : function(string) {
140 | var translated = Documentation.TRANSLATIONS[string];
141 | if (typeof translated == 'undefined')
142 | return string;
143 | return (typeof translated == 'string') ? translated : translated[0];
144 | },
145 |
146 | ngettext : function(singular, plural, n) {
147 | var translated = Documentation.TRANSLATIONS[singular];
148 | if (typeof translated == 'undefined')
149 | return (n == 1) ? singular : plural;
150 | return translated[Documentation.PLURALEXPR(n)];
151 | },
152 |
153 | addTranslations : function(catalog) {
154 | for (var key in catalog.messages)
155 | this.TRANSLATIONS[key] = catalog.messages[key];
156 | this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
157 | this.LOCALE = catalog.locale;
158 | },
159 |
160 | /**
161 | * add context elements like header anchor links
162 | */
163 | addContextElements : function() {
164 | $('div[id] > :header:first').each(function() {
165 | $('').
166 | attr('href', '#' + this.id).
167 | attr('title', _('Permalink to this headline')).
168 | appendTo(this);
169 | });
170 | $('dt[id]').each(function() {
171 | $('').
172 | attr('href', '#' + this.id).
173 | attr('title', _('Permalink to this definition')).
174 | appendTo(this);
175 | });
176 | },
177 |
178 | /**
179 | * workaround a firefox stupidity
180 | * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075
181 | */
182 | fixFirefoxAnchorBug : function() {
183 | if (document.location.hash)
184 | window.setTimeout(function() {
185 | document.location.href += '';
186 | }, 10);
187 | },
188 |
189 | /**
190 | * highlight the search words provided in the url in the text
191 | */
192 | highlightSearchWords : function() {
193 | var params = $.getQueryParameters();
194 | var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
195 | if (terms.length) {
196 | var body = $('div.body');
197 | if (!body.length) {
198 | body = $('body');
199 | }
200 | window.setTimeout(function() {
201 | $.each(terms, function() {
202 | body.highlightText(this.toLowerCase(), 'highlighted');
203 | });
204 | }, 10);
205 | $('' + _('Hide Search Matches') + '
')
207 | .appendTo($('#searchbox'));
208 | }
209 | },
210 |
211 | /**
212 | * init the domain index toggle buttons
213 | */
214 | initIndexTable : function() {
215 | var togglers = $('img.toggler').click(function() {
216 | var src = $(this).attr('src');
217 | var idnum = $(this).attr('id').substr(7);
218 | $('tr.cg-' + idnum).toggle();
219 | if (src.substr(-9) == 'minus.png')
220 | $(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
221 | else
222 | $(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
223 | }).css('display', '');
224 | if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
225 | togglers.click();
226 | }
227 | },
228 |
229 | /**
230 | * helper function to hide the search marks again
231 | */
232 | hideSearchWords : function() {
233 | $('#searchbox .highlight-link').fadeOut(300);
234 | $('span.highlighted').removeClass('highlighted');
235 | },
236 |
237 | /**
238 | * make the url absolute
239 | */
240 | makeURL : function(relativeURL) {
241 | return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
242 | },
243 |
244 | /**
245 | * get the current relative url
246 | */
247 | getCurrentURL : function() {
248 | var path = document.location.pathname;
249 | var parts = path.split(/\//);
250 | $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
251 | if (this == '..')
252 | parts.pop();
253 | });
254 | var url = parts.join('/');
255 | return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
256 | },
257 |
258 | initOnKeyListeners: function() {
259 | $(document).keyup(function(event) {
260 | var activeElementType = document.activeElement.tagName;
261 | // don't navigate when in search box or textarea
262 | if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') {
263 | switch (event.keyCode) {
264 | case 37: // left
265 | var prevHref = $('link[rel="prev"]').prop('href');
266 | if (prevHref) {
267 | window.location.href = prevHref;
268 | return false;
269 | }
270 | case 39: // right
271 | var nextHref = $('link[rel="next"]').prop('href');
272 | if (nextHref) {
273 | window.location.href = nextHref;
274 | return false;
275 | }
276 | }
277 | }
278 | });
279 | }
280 | };
281 |
282 | // quick alias for translations
283 | _ = Documentation.gettext;
284 |
285 | $(document).ready(function() {
286 | Documentation.init();
287 | });
--------------------------------------------------------------------------------
/tests/test_issues.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | import unittest
4 | import os
5 | import pyment.pyment as pym
6 | import pyment.docstring as ds
7 |
8 | current_dir = os.path.dirname(__file__)
9 | absdir = lambda f: os.path.join(current_dir, f)
10 |
11 |
12 | class IssuesTests(unittest.TestCase):
13 |
14 | def testIssue9(self):
15 | # Title: :rtype: is removed from doc comments; :return: loses indentation
16 | issue9 = absdir('issue9.py')
17 | p = pym.PyComment(issue9)
18 | p._parse()
19 | self.assertTrue(p.parsed)
20 | res = p.diff(issue9, "{0}.patch".format(issue9))
21 | self.assertTrue(res[8].strip() == "- :return: smthg")
22 | self.assertTrue(res[9].strip() == "+ :returns: smthg")
23 | self.assertTrue((res[10][1:].rstrip() == " :rtype: ret type")
24 | and (res[10][0] == ' '))
25 |
26 | def testIssue10(self):
27 | # Title: created patch-file not correct
28 | try:
29 | f = open(absdir("issue10.py.patch.expected"))
30 | expected = f.read()
31 | f.close()
32 | except Exception as e:
33 | self.fail('Raised exception: "{0}"'.format(e))
34 | p = pym.PyComment(absdir('issue10.py'))
35 | p._parse()
36 | self.assertTrue(p.parsed)
37 | result = ''.join(p.diff())
38 | self.assertTrue(result == expected)
39 |
40 | def testIssue11(self):
41 | # Title: doctests incorrectly formatted with reST option
42 | deftxt = "def meaning(subject, answer=False):"
43 | txt = '''"""
44 | >>> meaning('life', answer=True)
45 | 42
46 | """'''
47 | expected = ''' """
48 |
49 |
50 | :param subject:
51 | :param answer: (Default value = False)
52 |
53 | >>> meaning('life', answer=True)
54 | 42
55 | """'''
56 | d = ds.DocString(deftxt, quotes='"""')
57 | d.parse_docs(txt)
58 | self.assertTrue(d.get_raw_docs() == expected)
59 |
60 | def testIssue15(self):
61 | # Title: Does not convert existing docstrings
62 | try:
63 | f = open(absdir("issue15.py.patch.expected"))
64 | expected = f.read()
65 | f.close()
66 | except Exception as e:
67 | self.fail('Raised exception: "{0}"'.format(e))
68 | p = pym.PyComment(absdir('issue15.py'))
69 | p._parse()
70 | self.assertTrue(p.parsed)
71 | result = ''.join(p.diff())
72 | self.assertTrue(result == expected)
73 |
74 | def testIssue19(self):
75 | # Title: :raises in reST is incorrectly parsed
76 | txt = '''"""
77 |
78 | :raises ValueError: on incorrect JSON
79 | :raises requests.exceptions.HTTPError: on response error from server
80 | """'''
81 | expected = ''' """
82 |
83 |
84 |
85 | :raises ValueError: on incorrect JSON
86 | :raises requests.exceptions.HTTPError: on response error from server
87 |
88 | """'''
89 | docs = ds.DocString('def test():', quotes='"""')
90 | docs.parse_docs(txt)
91 | self.assertTrue(docs.get_raw_docs() == expected)
92 |
93 | def testIssue22(self):
94 | # Title: Class __init__() docstrings are not generated
95 | expected = '''--- a/issue22.py
96 | +++ b/issue22.py
97 | @@ -2,4 +2,9 @@
98 | """Test class for issue 22"""
99 |
100 | def __init__(self, param1):
101 | + """
102 | +
103 | + :param param1:
104 | +
105 | + """
106 | pass
107 | '''
108 | p = pym.PyComment(absdir('issue22.py'))
109 | p._parse()
110 | self.assertTrue(p.parsed)
111 | result = ''.join(p.diff())
112 | self.assertTrue(result == expected)
113 |
114 | def testIssue30(self):
115 | # if file starting with a function/class definition, patching the file
116 | # will remove the first line!
117 | p = pym.PyComment(absdir('issue30.py'), input_style="numpydoc", output_style="numpydoc")
118 | p._parse()
119 | self.assertTrue(p.parsed)
120 | try:
121 | p.diff()
122 | except Exception as e:
123 | self.fail('Raised exception: "{0}"'.format(e))
124 |
125 | def testIssue32(self):
126 | # Title: def statement gets deleted
127 | # if file starting with a function/class definition, patching the file
128 | # will remove the first line!
129 | expected = '''--- a/issue32.py
130 | +++ b/issue32.py
131 | @@ -1,2 +1,8 @@
132 | def hello_world(a=22, b='hello'):
133 | + """
134 | +
135 | + :param a: (Default value = 22)
136 | + :param b: (Default value = 'hello')
137 | +
138 | + """
139 | return 42'''
140 | p = pym.PyComment(absdir('issue32.py'))
141 | p._parse()
142 | self.assertTrue(p.parsed)
143 | result = ''.join(p.diff())
144 | self.assertTrue(result == expected)
145 |
146 | @unittest.expectedFailure
147 | def testIssue34(self):
148 | # Title: Problem with regenerating empty param docstring
149 | # if two consecutive params have empty descriptions, the first will
150 | # be filled with the full second param line
151 | p = pym.PyComment(absdir('issue34.py'))
152 | p._parse()
153 | self.assertTrue(p.parsed)
154 | result = ''.join(p.diff())
155 | self.assertTrue(result == '')
156 |
157 | def testIssue46(self):
158 | # Title: list, tuple, dict default param values are not parsed correctly
159 | # if a list/tuple/dict is given as default value for a parameter, the
160 | # commas will be considered as separators for parameters
161 | try:
162 | f = open(absdir("issue46.py.patch.expected"))
163 | expected = f.readlines()
164 | if expected[0].startswith("# Patch"):
165 | expected = expected[2:]
166 | expected = "".join(expected)
167 | f.close()
168 | except Exception as e:
169 | self.fail('Raised exception: "{0}"'.format(e))
170 | p = pym.PyComment(absdir('issue46.py'))
171 | p._parse()
172 | self.assertTrue(p.parsed)
173 | result = ''.join(p.diff())
174 | self.assertTrue(result == expected)
175 |
176 | @unittest.expectedFailure
177 | def testIssue47(self):
178 | # Title: Extra blank line for docstring with a muli-line description #47
179 | # If a function has no argument and a multi-line description, Pyment will insert two blank lines
180 | # between the description and the end of the docstring.
181 | p = pym.PyComment(absdir('issue47.py'))
182 | p._parse()
183 | self.assertTrue(p.parsed)
184 | result = ''.join(p.diff())
185 | self.assertTrue(result == '')
186 |
187 | def testIssue49(self):
188 | # Title: If already numpydoc format, will remove the Raises section
189 | # If the last section in a numpydoc docstring is a `Raises` section,
190 | # it will be removed if the output format is also set to numpydoc
191 | p = pym.PyComment(absdir('issue49.py'), output_style='numpydoc')
192 | p._parse()
193 | self.assertTrue(p.parsed)
194 | result = ''.join(p.diff())
195 | print(result)
196 | self.assertTrue(result == '')
197 |
198 | def testIssue51(self):
199 | # Title: Raise block convertion
200 | p = pym.PyComment(absdir('issue51.py'), output_style='google')
201 | p._parse()
202 | self.assertTrue(p.parsed)
203 | result = ''.join(p.diff())
204 | self.assertTrue(result == '')
205 |
206 | def testIssue58(self):
207 | # Title: Comments after def statement not supported
208 | # If a function's def statement is followed by a comment it won't be proceeded.
209 | p = pym.PyComment(absdir('issue58.py'))
210 | expected = '''--- a/issue58.py
211 | +++ b/issue58.py
212 | @@ -1,5 +1,9 @@
213 | def func(param): # some comment
214 | - """some docstring"""
215 | + """some docstring
216 | +
217 | + :param param:
218 | +
219 | + """
220 | pass
221 |
222 |
223 | '''
224 | p._parse()
225 | self.assertTrue(p.parsed)
226 | result = ''.join(p.diff())
227 | self.assertTrue(result == expected)
228 |
229 | def testIssue69(self):
230 | # Title: Wrong Formatting for Input params with default values
231 | # When default value has a list it is split and considers list's elements as parameters
232 | p = pym.PyComment(absdir('issue69.py'))
233 | p._parse()
234 | f = open(absdir('issue69.py.patch'))
235 | patch = f.read()
236 | f.close()
237 | self.assertEqual(''.join(p.diff()), patch)
238 |
239 | def testIssue83(self):
240 | # Title: No docstring in class results in wrong indentation in __init__()
241 | p = pym.PyComment(absdir('issue83.py'), ignore_private=True)
242 | p.proceed()
243 | with open(absdir('issue83.py.patch')) as f:
244 | patch = f.read()
245 | result = ''.join(p.diff())
246 | print(result)
247 | self.assertEqual(result, patch)
248 |
249 | def testIssue85(self):
250 | # Title: When converting from reST, parameter types are not handled correctly
251 | # For reST, Sphinx allows to declare the type inside the parameter statement
252 | # like this: `:param str name: description`
253 | # Pyment should support this.
254 | p = pym.PyComment(absdir('issue85.py'))
255 | p._parse()
256 | f = open(absdir('issue85.py.patch'))
257 | patch = f.read()
258 | f.close()
259 | self.assertEqual(''.join(p.diff()), patch)
260 |
261 | def testIssue88(self):
262 | # Title: Not working on async functions
263 | # The async functions are not managed
264 | p = pym.PyComment(absdir('issue88.py'))
265 | p._parse()
266 | f = open(absdir('issue88.py.patch'))
267 | patch = f.read()
268 | f.close()
269 | self.assertEqual(''.join(p.diff()), patch)
270 |
271 | def testIssue90(self):
272 | # Title: __doc__ is not well parsed
273 | # If the line after function signature contains triple [double] quotes but is not a docstring
274 | # it will be however considered as if it was and will have side effect.
275 | p = pym.PyComment(absdir('issue90.py'))
276 | p._parse()
277 | f = open(absdir('issue90.py.patch'))
278 | patch = f.read()
279 | f.close()
280 | self.assertEqual(''.join(p.diff()), patch)
281 |
282 | def testIssue93(self):
283 | # Title: Support for type hints
284 | # Add support for type hints (PEP 484).
285 | p = pym.PyComment(absdir('issue93.py'))
286 | p._parse()
287 | f = open(absdir('issue93.py.patch'))
288 | patch = f.read()
289 | f.close()
290 | self.assertEqual(''.join(p.diff()), patch)
291 |
292 | def testIssue95(self):
293 | # Title: When there's a parameter without description in reST, Pyment copies the whole next element
294 | p = pym.PyComment(absdir('issue95.py'))
295 | p._parse()
296 | f = open(absdir('issue95.py.patch'))
297 | patch = f.read()
298 | f.close()
299 | self.assertEqual(''.join(p.diff()), patch)
300 |
301 | def testIssue99(self):
302 | # Title: Type is removed from parameter if not in type hints when converting reST docstring
303 | p = pym.PyComment(absdir('issue99.py'))
304 | p._parse()
305 | f = open(absdir('issue99.py.patch'))
306 | patch = f.read()
307 | f.close()
308 | self.assertEqual(''.join(p.diff()), patch)
309 |
310 |
311 | def main():
312 | unittest.main()
313 |
314 |
315 | if __name__ == '__main__':
316 | main()
317 |
--------------------------------------------------------------------------------
/doc/sphinx/html/_static/underscore.js:
--------------------------------------------------------------------------------
1 | // Underscore.js 1.3.1
2 | // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
3 | // Underscore is freely distributable under the MIT license.
4 | // Portions of Underscore are inspired or borrowed from Prototype,
5 | // Oliver Steele's Functional, and John Resig's Micro-Templating.
6 | // For all details and documentation:
7 | // http://documentcloud.github.com/underscore
8 | (function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
9 | c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c,
10 | h)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION="1.3.1";var j=b.each=
11 | b.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e2;a==
12 | null&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=
13 | function(a,c,b){var e;E(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e=
14 | e&&c.call(b,a,g,h)))return n});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return n});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return p&&a.indexOf===p?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck=
15 | function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;bd?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,
17 | c,d){d||(d=b.identity);for(var e=0,f=a.length;e>1;d(a[g])=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e=0;d--)b=[a[d].apply(this,b)];return b[0]}};
24 | b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=J||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.defaults=function(a){j(i.call(arguments,
25 | 1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return q(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=o||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};
26 | b.isArguments=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!b.has(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};
27 | b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return I.call(a,b)};b.noConflict=function(){r._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e /g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.mixin=function(a){j(b.functions(a),
28 | function(c){K(c,b[c]=a[c])})};var L=0;b.uniqueId=function(a){var b=L++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var t=/.^/,u=function(a){return a.replace(/\\\\/g,"\\").replace(/\\'/g,"'")};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape||t,function(a,b){return"',_.escape("+
29 | u(b)+"),'"}).replace(d.interpolate||t,function(a,b){return"',"+u(b)+",'"}).replace(d.evaluate||t,function(a,b){return"');"+u(b).replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e.call(this,a,b)}};b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var v=function(a,c){return c?b(a).chain():a},K=function(a,c){m.prototype[a]=
30 | function(){var a=i.call(arguments);H.call(a,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return v(d,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=
31 | true;return this};m.prototype.value=function(){return this._wrapped}}).call(this);
32 |
--------------------------------------------------------------------------------
/doc/sphinx/html/_static/basic.css:
--------------------------------------------------------------------------------
1 | /*
2 | * basic.css
3 | * ~~~~~~~~~
4 | *
5 | * Sphinx stylesheet -- basic theme.
6 | *
7 | * :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
8 | * :license: BSD, see LICENSE for details.
9 | *
10 | */
11 |
12 | /* -- main layout ----------------------------------------------------------- */
13 |
14 | div.clearer {
15 | clear: both;
16 | }
17 |
18 | /* -- relbar ---------------------------------------------------------------- */
19 |
20 | div.related {
21 | width: 100%;
22 | font-size: 90%;
23 | }
24 |
25 | div.related h3 {
26 | display: none;
27 | }
28 |
29 | div.related ul {
30 | margin: 0;
31 | padding: 0 0 0 10px;
32 | list-style: none;
33 | }
34 |
35 | div.related li {
36 | display: inline;
37 | }
38 |
39 | div.related li.right {
40 | float: right;
41 | margin-right: 5px;
42 | }
43 |
44 | /* -- sidebar --------------------------------------------------------------- */
45 |
46 | div.sphinxsidebarwrapper {
47 | padding: 10px 5px 0 10px;
48 | }
49 |
50 | div.sphinxsidebar {
51 | float: left;
52 | width: 230px;
53 | margin-left: -100%;
54 | font-size: 90%;
55 | word-wrap: break-word;
56 | overflow-wrap : break-word;
57 | }
58 |
59 | div.sphinxsidebar ul {
60 | list-style: none;
61 | }
62 |
63 | div.sphinxsidebar ul ul,
64 | div.sphinxsidebar ul.want-points {
65 | margin-left: 20px;
66 | list-style: square;
67 | }
68 |
69 | div.sphinxsidebar ul ul {
70 | margin-top: 0;
71 | margin-bottom: 0;
72 | }
73 |
74 | div.sphinxsidebar form {
75 | margin-top: 10px;
76 | }
77 |
78 | div.sphinxsidebar input {
79 | border: 1px solid #98dbcc;
80 | font-family: sans-serif;
81 | font-size: 1em;
82 | }
83 |
84 | div.sphinxsidebar #searchbox input[type="text"] {
85 | width: 170px;
86 | }
87 |
88 | img {
89 | border: 0;
90 | max-width: 100%;
91 | }
92 |
93 | /* -- search page ----------------------------------------------------------- */
94 |
95 | ul.search {
96 | margin: 10px 0 0 20px;
97 | padding: 0;
98 | }
99 |
100 | ul.search li {
101 | padding: 5px 0 5px 20px;
102 | background-image: url(file.png);
103 | background-repeat: no-repeat;
104 | background-position: 0 7px;
105 | }
106 |
107 | ul.search li a {
108 | font-weight: bold;
109 | }
110 |
111 | ul.search li div.context {
112 | color: #888;
113 | margin: 2px 0 0 30px;
114 | text-align: left;
115 | }
116 |
117 | ul.keywordmatches li.goodmatch a {
118 | font-weight: bold;
119 | }
120 |
121 | /* -- index page ------------------------------------------------------------ */
122 |
123 | table.contentstable {
124 | width: 90%;
125 | margin-left: auto;
126 | margin-right: auto;
127 | }
128 |
129 | table.contentstable p.biglink {
130 | line-height: 150%;
131 | }
132 |
133 | a.biglink {
134 | font-size: 1.3em;
135 | }
136 |
137 | span.linkdescr {
138 | font-style: italic;
139 | padding-top: 5px;
140 | font-size: 90%;
141 | }
142 |
143 | /* -- general index --------------------------------------------------------- */
144 |
145 | table.indextable {
146 | width: 100%;
147 | }
148 |
149 | table.indextable td {
150 | text-align: left;
151 | vertical-align: top;
152 | }
153 |
154 | table.indextable ul {
155 | margin-top: 0;
156 | margin-bottom: 0;
157 | list-style-type: none;
158 | }
159 |
160 | table.indextable > tbody > tr > td > ul {
161 | padding-left: 0em;
162 | }
163 |
164 | table.indextable tr.pcap {
165 | height: 10px;
166 | }
167 |
168 | table.indextable tr.cap {
169 | margin-top: 10px;
170 | background-color: #f2f2f2;
171 | }
172 |
173 | img.toggler {
174 | margin-right: 3px;
175 | margin-top: 3px;
176 | cursor: pointer;
177 | }
178 |
179 | div.modindex-jumpbox {
180 | border-top: 1px solid #ddd;
181 | border-bottom: 1px solid #ddd;
182 | margin: 1em 0 1em 0;
183 | padding: 0.4em;
184 | }
185 |
186 | div.genindex-jumpbox {
187 | border-top: 1px solid #ddd;
188 | border-bottom: 1px solid #ddd;
189 | margin: 1em 0 1em 0;
190 | padding: 0.4em;
191 | }
192 |
193 | /* -- domain module index --------------------------------------------------- */
194 |
195 | table.modindextable td {
196 | padding: 2px;
197 | border-collapse: collapse;
198 | }
199 |
200 | /* -- general body styles --------------------------------------------------- */
201 |
202 | div.body p, div.body dd, div.body li, div.body blockquote {
203 | -moz-hyphens: auto;
204 | -ms-hyphens: auto;
205 | -webkit-hyphens: auto;
206 | hyphens: auto;
207 | }
208 |
209 | a.headerlink {
210 | visibility: hidden;
211 | }
212 |
213 | h1:hover > a.headerlink,
214 | h2:hover > a.headerlink,
215 | h3:hover > a.headerlink,
216 | h4:hover > a.headerlink,
217 | h5:hover > a.headerlink,
218 | h6:hover > a.headerlink,
219 | dt:hover > a.headerlink,
220 | caption:hover > a.headerlink,
221 | p.caption:hover > a.headerlink,
222 | div.code-block-caption:hover > a.headerlink {
223 | visibility: visible;
224 | }
225 |
226 | div.body p.caption {
227 | text-align: inherit;
228 | }
229 |
230 | div.body td {
231 | text-align: left;
232 | }
233 |
234 | .first {
235 | margin-top: 0 !important;
236 | }
237 |
238 | p.rubric {
239 | margin-top: 30px;
240 | font-weight: bold;
241 | }
242 |
243 | img.align-left, .figure.align-left, object.align-left {
244 | clear: left;
245 | float: left;
246 | margin-right: 1em;
247 | }
248 |
249 | img.align-right, .figure.align-right, object.align-right {
250 | clear: right;
251 | float: right;
252 | margin-left: 1em;
253 | }
254 |
255 | img.align-center, .figure.align-center, object.align-center {
256 | display: block;
257 | margin-left: auto;
258 | margin-right: auto;
259 | }
260 |
261 | .align-left {
262 | text-align: left;
263 | }
264 |
265 | .align-center {
266 | text-align: center;
267 | }
268 |
269 | .align-right {
270 | text-align: right;
271 | }
272 |
273 | /* -- sidebars -------------------------------------------------------------- */
274 |
275 | div.sidebar {
276 | margin: 0 0 0.5em 1em;
277 | border: 1px solid #ddb;
278 | padding: 7px 7px 0 7px;
279 | background-color: #ffe;
280 | width: 40%;
281 | float: right;
282 | }
283 |
284 | p.sidebar-title {
285 | font-weight: bold;
286 | }
287 |
288 | /* -- topics ---------------------------------------------------------------- */
289 |
290 | div.topic {
291 | border: 1px solid #ccc;
292 | padding: 7px 7px 0 7px;
293 | margin: 10px 0 10px 0;
294 | }
295 |
296 | p.topic-title {
297 | font-size: 1.1em;
298 | font-weight: bold;
299 | margin-top: 10px;
300 | }
301 |
302 | /* -- admonitions ----------------------------------------------------------- */
303 |
304 | div.admonition {
305 | margin-top: 10px;
306 | margin-bottom: 10px;
307 | padding: 7px;
308 | }
309 |
310 | div.admonition dt {
311 | font-weight: bold;
312 | }
313 |
314 | div.admonition dl {
315 | margin-bottom: 0;
316 | }
317 |
318 | p.admonition-title {
319 | margin: 0px 10px 5px 0px;
320 | font-weight: bold;
321 | }
322 |
323 | div.body p.centered {
324 | text-align: center;
325 | margin-top: 25px;
326 | }
327 |
328 | /* -- tables ---------------------------------------------------------------- */
329 |
330 | table.docutils {
331 | border: 0;
332 | border-collapse: collapse;
333 | }
334 |
335 | table caption span.caption-number {
336 | font-style: italic;
337 | }
338 |
339 | table caption span.caption-text {
340 | }
341 |
342 | table.docutils td, table.docutils th {
343 | padding: 1px 8px 1px 5px;
344 | border-top: 0;
345 | border-left: 0;
346 | border-right: 0;
347 | border-bottom: 1px solid #aaa;
348 | }
349 |
350 | table.footnote td, table.footnote th {
351 | border: 0 !important;
352 | }
353 |
354 | th {
355 | text-align: left;
356 | padding-right: 5px;
357 | }
358 |
359 | table.citation {
360 | border-left: solid 1px gray;
361 | margin-left: 1px;
362 | }
363 |
364 | table.citation td {
365 | border-bottom: none;
366 | }
367 |
368 | /* -- figures --------------------------------------------------------------- */
369 |
370 | div.figure {
371 | margin: 0.5em;
372 | padding: 0.5em;
373 | }
374 |
375 | div.figure p.caption {
376 | padding: 0.3em;
377 | }
378 |
379 | div.figure p.caption span.caption-number {
380 | font-style: italic;
381 | }
382 |
383 | div.figure p.caption span.caption-text {
384 | }
385 |
386 | /* -- field list styles ----------------------------------------------------- */
387 |
388 | table.field-list td, table.field-list th {
389 | border: 0 !important;
390 | }
391 |
392 | .field-list ul {
393 | margin: 0;
394 | padding-left: 1em;
395 | }
396 |
397 | .field-list p {
398 | margin: 0;
399 | }
400 |
401 | .field-name {
402 | -moz-hyphens: manual;
403 | -ms-hyphens: manual;
404 | -webkit-hyphens: manual;
405 | hyphens: manual;
406 | }
407 |
408 | /* -- other body styles ----------------------------------------------------- */
409 |
410 | ol.arabic {
411 | list-style: decimal;
412 | }
413 |
414 | ol.loweralpha {
415 | list-style: lower-alpha;
416 | }
417 |
418 | ol.upperalpha {
419 | list-style: upper-alpha;
420 | }
421 |
422 | ol.lowerroman {
423 | list-style: lower-roman;
424 | }
425 |
426 | ol.upperroman {
427 | list-style: upper-roman;
428 | }
429 |
430 | dl {
431 | margin-bottom: 15px;
432 | }
433 |
434 | dd p {
435 | margin-top: 0px;
436 | }
437 |
438 | dd ul, dd table {
439 | margin-bottom: 10px;
440 | }
441 |
442 | dd {
443 | margin-top: 3px;
444 | margin-bottom: 10px;
445 | margin-left: 30px;
446 | }
447 |
448 | dt:target, .highlighted {
449 | background-color: #fbe54e;
450 | }
451 |
452 | dl.glossary dt {
453 | font-weight: bold;
454 | font-size: 1.1em;
455 | }
456 |
457 | .optional {
458 | font-size: 1.3em;
459 | }
460 |
461 | .sig-paren {
462 | font-size: larger;
463 | }
464 |
465 | .versionmodified {
466 | font-style: italic;
467 | }
468 |
469 | .system-message {
470 | background-color: #fda;
471 | padding: 5px;
472 | border: 3px solid red;
473 | }
474 |
475 | .footnote:target {
476 | background-color: #ffa;
477 | }
478 |
479 | .line-block {
480 | display: block;
481 | margin-top: 1em;
482 | margin-bottom: 1em;
483 | }
484 |
485 | .line-block .line-block {
486 | margin-top: 0;
487 | margin-bottom: 0;
488 | margin-left: 1.5em;
489 | }
490 |
491 | .guilabel, .menuselection {
492 | font-family: sans-serif;
493 | }
494 |
495 | .accelerator {
496 | text-decoration: underline;
497 | }
498 |
499 | .classifier {
500 | font-style: oblique;
501 | }
502 |
503 | abbr, acronym {
504 | border-bottom: dotted 1px;
505 | cursor: help;
506 | }
507 |
508 | /* -- code displays --------------------------------------------------------- */
509 |
510 | pre {
511 | overflow: auto;
512 | overflow-y: hidden; /* fixes display issues on Chrome browsers */
513 | }
514 |
515 | span.pre {
516 | -moz-hyphens: none;
517 | -ms-hyphens: none;
518 | -webkit-hyphens: none;
519 | hyphens: none;
520 | }
521 |
522 | td.linenos pre {
523 | padding: 5px 0px;
524 | border: 0;
525 | background-color: transparent;
526 | color: #aaa;
527 | }
528 |
529 | table.highlighttable {
530 | margin-left: 0.5em;
531 | }
532 |
533 | table.highlighttable td {
534 | padding: 0 0.5em 0 0.5em;
535 | }
536 |
537 | div.code-block-caption {
538 | padding: 2px 5px;
539 | font-size: small;
540 | }
541 |
542 | div.code-block-caption code {
543 | background-color: transparent;
544 | }
545 |
546 | div.code-block-caption + div > div.highlight > pre {
547 | margin-top: 0;
548 | }
549 |
550 | div.code-block-caption span.caption-number {
551 | padding: 0.1em 0.3em;
552 | font-style: italic;
553 | }
554 |
555 | div.code-block-caption span.caption-text {
556 | }
557 |
558 | div.literal-block-wrapper {
559 | padding: 1em 1em 0;
560 | }
561 |
562 | div.literal-block-wrapper div.highlight {
563 | margin: 0;
564 | }
565 |
566 | code.descname {
567 | background-color: transparent;
568 | font-weight: bold;
569 | font-size: 1.2em;
570 | }
571 |
572 | code.descclassname {
573 | background-color: transparent;
574 | }
575 |
576 | code.xref, a code {
577 | background-color: transparent;
578 | font-weight: bold;
579 | }
580 |
581 | h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
582 | background-color: transparent;
583 | }
584 |
585 | .viewcode-link {
586 | float: right;
587 | }
588 |
589 | .viewcode-back {
590 | float: right;
591 | font-family: sans-serif;
592 | }
593 |
594 | div.viewcode-block:target {
595 | margin: -1px -10px;
596 | padding: 0 10px;
597 | }
598 |
599 | /* -- math display ---------------------------------------------------------- */
600 |
601 | img.math {
602 | vertical-align: middle;
603 | }
604 |
605 | div.body div.math p {
606 | text-align: center;
607 | }
608 |
609 | span.eqno {
610 | float: right;
611 | }
612 |
613 | span.eqno a.headerlink {
614 | position: relative;
615 | left: 0px;
616 | z-index: 1;
617 | }
618 |
619 | div.math:hover a.headerlink {
620 | visibility: visible;
621 | }
622 |
623 | /* -- printout stylesheet --------------------------------------------------- */
624 |
625 | @media print {
626 | div.document,
627 | div.documentwrapper,
628 | div.bodywrapper {
629 | margin: 0 !important;
630 | width: 100%;
631 | }
632 |
633 | div.sphinxsidebar,
634 | div.related,
635 | div.footer,
636 | #top-link {
637 | display: none;
638 | }
639 | }
--------------------------------------------------------------------------------
/tests/test_app.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import os
3 | import re
4 | import subprocess
5 | import sys
6 | import tempfile
7 | import textwrap
8 | import unittest
9 |
10 | import pyment.pyment
11 |
12 |
13 | class AppTests(unittest.TestCase):
14 | """
15 | Test pyment as an app in a shell.
16 |
17 | It's an integration test.
18 | """
19 |
20 | # You have to run this as a module when testing so the relative imports work.
21 | CMD_PREFIX = sys.executable + ' -m pyment.pymentapp {}'
22 |
23 | RE_TYPE = type(re.compile('get the type to test if an argument is an re'))
24 |
25 | # cwd to use when running subprocess.
26 | # It has to be at the repo directory so python -m can be used
27 | CWD = os.path.dirname(os.path.dirname(__file__))
28 |
29 | INPUT = textwrap.dedent('''
30 |
31 | def func():
32 | """First line
33 |
34 | :returns: smthg
35 |
36 | :rtype: ret type
37 |
38 | """
39 | pass
40 | ''')
41 |
42 | # Expected output in overwrite mode.
43 | EXPECTED_OUTPUT = textwrap.dedent('''
44 |
45 | def func():
46 | """First line
47 |
48 | Args:
49 |
50 | Returns:
51 | ret type: smthg
52 |
53 | Raises:
54 |
55 | """
56 | pass
57 | ''')
58 |
59 | PATCH_PREFIX = '# Patch generated by Pyment v{}'.format(pyment.pyment.__version__)
60 |
61 | # a/- and b/- is replaced by a filename when not testing stdin/stdout
62 | EXPECTED_PATCH = textwrap.dedent('''\
63 | {}
64 |
65 | --- a/-
66 | +++ b/-
67 | @@ -3,9 +3,12 @@
68 | def func():
69 | """First line
70 |
71 | - :returns: smthg
72 | + Args:
73 |
74 | - :rtype: ret type
75 | + Returns:
76 | + ret type: smthg
77 | +
78 | + Raises:
79 |
80 |
81 | """
82 | pass
83 |
84 | '''.format(PATCH_PREFIX))
85 |
86 | # The format which will turn INPUT into EXPECTED_PATCH and EXPECTED_OUTPUT
87 | OUTPUT_FORMAT = 'google'
88 |
89 | @classmethod
90 | def normalise_empty_lines(cls, lines):
91 | """
92 | Replace any lines that are only whitespace with a single \n
93 |
94 | textwrap.dedent removes all whitespace characters on lines only containing whitespaces
95 | see: https://bugs.python.org/issue30754
96 |
97 | And some people set their editors to strip trailing white space.
98 |
99 | But sometimes there is a space on an empty line in the output which will fail the comparison.
100 |
101 | So strip the spaces on empty lines
102 |
103 | :param lines: string of lines to normalise
104 | :type lines: str
105 |
106 | :return: normalised lines
107 | """
108 |
109 | return re.sub('^\s+$', '', lines, flags=re.MULTILINE)
110 |
111 | def run_command(self, cmd_to_run, write_to_stdin=None):
112 | """
113 | Run a command in shell mode returning stdout, stderr and the returncode.
114 |
115 | :param cmd_to_run: shell command to run
116 | :type cmd_to_run: str
117 |
118 | :param write_to_stdin: string to put on stdin if not None
119 | :type write_to_stdin: str | None
120 |
121 | :return: stdout, stderr, returncode
122 | :rtype: (str, str, int)
123 | """
124 |
125 | p = subprocess.Popen(
126 | cmd_to_run, shell=True, cwd=self.CWD,
127 | stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE
128 | )
129 | if write_to_stdin:
130 | # Python3 compatibility - input has to be bytes
131 | write_to_stdin = write_to_stdin.encode()
132 |
133 | stdout, stderr = p.communicate(write_to_stdin)
134 |
135 | if isinstance(stdout, bytes):
136 | # Python 3 compatibility - output will be bytes
137 | stdout = stdout.decode()
138 | stderr = stderr.decode()
139 |
140 | return stdout, stderr, p.returncode
141 |
142 | def runPymentAppAndAssertIsExpected(self,
143 | cmd_args, write_to_stdin=None,
144 | expected_stdout='', expected_stderr='', expected_returncode=0,
145 | output_format=None):
146 | """
147 | Run pyment with the cmd_args and output_format specified in a shell and assert it's output matches
148 | the arguments.
149 |
150 | if expected_stdout and expected_stderr is the result of a re.compile() the output will be checked
151 | re.search().
152 |
153 | :param cmd_args: Extra arguments to pass to pyment - excluding the output_format
154 | :param write_to_stdin: the input to put on stdin, use None if there's nothing
155 |
156 | :param expected_stdout: Expected string to see on stdout
157 | :type expected_stdout: str | Pattern[str]
158 |
159 | :param expected_stderr: Expected string to see on stderr
160 | :type expected_stderr: str | Pattern[str]
161 |
162 | :param expected_returncode: Expected returncode after running pyment
163 | :param output_format: The output format - it adds the --output option, use None if auto is required
164 |
165 | :return: None
166 | :raises: Assertion error if the expected result is not found
167 | """
168 |
169 | def assert_output(cmd_to_run, what, got, expected):
170 | """
171 | The comparison works as described in the docstring for runPymentAppAndAssertIsExpected
172 |
173 | :param cmd_to_run: full command that was run - used to build an error message
174 | :param what: The attribute being checked - used for the error message
175 | :param got: The result from the test
176 | :param expected: The expected result from the test
177 | :raises: AssertionError if the expected result was not found
178 | """
179 | if isinstance(expected, self.RE_TYPE):
180 | msg = "Test failed for cmd {}\n{} was expected to match the regex:\n{}\n" \
181 | "But this was the output:\n{!r}\n" \
182 | .format(cmd_to_run, what, expected, got)
183 | assert expected.search(got) is not None, msg
184 | else:
185 | if isinstance(expected, str):
186 | # Turn lines that only have whitespace into single newline lines to workaround textwrap.dedent
187 | # behaviour
188 | got = self.normalise_empty_lines(got).replace('\r\n', '\n')
189 | expected = self.normalise_empty_lines(expected)
190 |
191 | # repr is used instead of str to make it easier to see newlines and spaces if there's a difference
192 | msg = "Test failed for cmd {}\n{} was expected to be:\n{!r}\nBut this was the output:\n{!r}\n" \
193 | .format(cmd_to_run, what, expected, got)
194 | assert got == expected, msg
195 |
196 | cmd_to_run = self.CMD_PREFIX.format(cmd_args)
197 |
198 | if output_format:
199 | cmd_to_run = '{} --output {} '.format(cmd_to_run, output_format)
200 |
201 | stdout, stderr, returncode = self.run_command(cmd_to_run, write_to_stdin)
202 |
203 | assert_output(cmd_to_run, 'stderr', stderr, expected_stderr)
204 | assert_output(cmd_to_run, 'returncode', returncode, expected_returncode)
205 | assert_output(cmd_to_run, 'stdout', stdout, expected_stdout)
206 |
207 | @unittest.skipIf(sys.version_info[:2] >= (3, 3),
208 | 'Python version >= 3.3')
209 | def testNoArgs_lt_py33(self):
210 | # Ensure the app outputs an error if there are no arguments.
211 | self.runPymentAppAndAssertIsExpected(
212 | cmd_args="",
213 | write_to_stdin=None,
214 | expected_stderr=re.compile('too few arguments'),
215 | expected_returncode=2
216 | )
217 |
218 | @unittest.skipIf(sys.version_info[:2] < (3, 3),
219 | 'Python version < 3.3')
220 | def testNoArgs_ge_py33(self):
221 | # Ensure the app outputs an error if there are no arguments.
222 | self.runPymentAppAndAssertIsExpected(
223 | cmd_args="",
224 | write_to_stdin=None,
225 | # expected_stderr=re.compile('too few arguments'),
226 | expected_stderr=re.compile(
227 | r'usage: pymentapp.py \[-h\] \[-i style\] \[-o style\] \[-q quotes\] \[-f status\] \[-t\].?.?\s{20}\[-c config\] \[-d\] \[-p status\] \[-v\] \[-w\].?.?\s{20}path.?.?pymentapp\.py: error: the following arguments are required: path',
228 | re.DOTALL),
229 | expected_returncode=2
230 | )
231 |
232 | def testStdinPatchMode(self):
233 | # Test non overwrite mode when using stdin - which means a patch will be written to stdout
234 | self.runPymentAppAndAssertIsExpected(
235 | cmd_args="-",
236 | write_to_stdin=self.INPUT,
237 | expected_stdout=self.EXPECTED_PATCH,
238 | output_format=self.OUTPUT_FORMAT,
239 | )
240 |
241 | def testRunOnStdinOverwrite(self):
242 | # Check 'overwrite' mode with stdin.
243 | # In overwrite mode the output is the new file, not a patch.
244 | self.runPymentAppAndAssertIsExpected(
245 | cmd_args="-w -",
246 | write_to_stdin=self.INPUT,
247 | expected_stdout=self.EXPECTED_OUTPUT,
248 | output_format=self.OUTPUT_FORMAT,
249 | )
250 |
251 | def runPymentAppWithAFileAndAssertIsExpected(self,
252 | file_contents, cmd_args="", overwrite_mode=False,
253 | expected_file_contents='', expected_stderr='', expected_returncode=0,
254 | output_format=None):
255 | """
256 | Run the pyment app with a file - not stdin.
257 |
258 | A temporary file is created, file_contents is written into it then the test is run.
259 | The .patch and temporary files are removed at the end of the test.
260 |
261 | :param file_contents: write this into the temporary file
262 | :param cmd_args: Arguments to pyment - do not put the '-w' argument here - it is triggered by overwrite_mode
263 | :param overwrite_mode: set to True if in overwrite mode
264 | :param expected_file_contents: expected result - for a patch file ensure the filename is '-'. The '-'
265 | is replaced with the patch filename when overwrite_mode is False
266 | :param expected_stderr: expected output on stderr. You can match on a regex if you pass it the result of
267 | re.compile('some pattern'). Default is empty string.
268 | :param expected_returncode: Expected return code from pyment. Default is 0.
269 | :param output_format: If not using auto mode set the output format to this.
270 |
271 | """
272 |
273 | patch_filename = input_filename = ''
274 | input_file = None
275 |
276 | try:
277 |
278 | # Create the input file
279 | input_fd, input_filename = tempfile.mkstemp(suffix='.input', text=True)
280 | input_file = os.fdopen(input_fd, 'w')
281 | input_file.write(file_contents)
282 | input_file.close()
283 |
284 | # Get the patch file name so it can be removed if it's created.
285 | # pyment will create it in the current working directory
286 | patch_filename = os.path.join(self.CWD, os.path.basename(input_filename) + '.patch')
287 |
288 | cmd_args = "{} {}".format(cmd_args, input_filename)
289 |
290 | if overwrite_mode:
291 | cmd_args = "{} -w ".format(cmd_args)
292 |
293 | self.runPymentAppAndAssertIsExpected(
294 | cmd_args=cmd_args,
295 | expected_stderr=expected_stderr,
296 | expected_returncode=expected_returncode,
297 | write_to_stdin=file_contents,
298 | output_format=output_format,
299 | )
300 |
301 | if overwrite_mode:
302 | with open(input_filename) as f:
303 | output = f.read()
304 | else:
305 | with open(patch_filename) as f:
306 | output = f.read()
307 | # The expected output will have filenames of '-' - replace them with the actual filename
308 | output = re.sub(
309 | r'/{}$'.format(os.path.basename(input_filename)),
310 | r'/-',
311 | output,
312 | flags=re.MULTILINE
313 | )
314 |
315 | normalised_output = self.normalise_empty_lines(output)
316 | normalised_expected_output = self.normalise_empty_lines(expected_file_contents)
317 |
318 | assert normalised_output == normalised_expected_output, \
319 | "Output from cmd: {} was:\n{!r}\nnot the expected:\n{!r}" \
320 | .format(cmd_args, normalised_output, normalised_expected_output)
321 |
322 | finally:
323 | if input_filename:
324 | if input_file:
325 | if not input_file.closed:
326 | input_file.close()
327 | os.remove(input_filename)
328 |
329 | if not overwrite_mode:
330 | if os.path.isfile(patch_filename):
331 | os.remove(patch_filename)
332 |
333 | def testOverwriteFilesTheSame(self):
334 | # Test that the file is correct when the output is the same as the input.
335 | self.runPymentAppWithAFileAndAssertIsExpected(
336 | file_contents=self.EXPECTED_OUTPUT,
337 | expected_file_contents=self.EXPECTED_OUTPUT,
338 | output_format=self.OUTPUT_FORMAT,
339 | overwrite_mode=True,
340 | )
341 |
342 | def testOverwriteFilesDifferent(self):
343 | # Test the file is overwritten with the correct result
344 | self.runPymentAppWithAFileAndAssertIsExpected(
345 | file_contents=self.INPUT,
346 | expected_file_contents=self.EXPECTED_OUTPUT,
347 | output_format=self.OUTPUT_FORMAT,
348 | overwrite_mode=True,
349 | )
350 |
351 | def testPatchFilesTheSame(self):
352 | # Check the patch file created when the files are the same
353 | self.runPymentAppWithAFileAndAssertIsExpected(
354 | file_contents=self.EXPECTED_OUTPUT,
355 | expected_file_contents=self.PATCH_PREFIX + '\n',
356 | output_format=self.OUTPUT_FORMAT
357 | )
358 |
359 | def testPatchFilesDifferent(self):
360 | # Test the patch file is correct
361 | self.runPymentAppWithAFileAndAssertIsExpected(
362 | file_contents=self.INPUT,
363 | expected_file_contents=self.EXPECTED_PATCH,
364 | output_format=self.OUTPUT_FORMAT
365 | )
366 |
367 |
368 | def main():
369 | unittest.main()
370 |
371 |
372 | if __name__ == '__main__':
373 | main()
374 |
--------------------------------------------------------------------------------
/doc/sphinx/html/_sources/pyment.rst.txt:
--------------------------------------------------------------------------------
1 | Reference documentation
2 | #######################
3 |
4 | Pyment: the docstrings manager (creator/converter)
5 |
6 | .. Contents::
7 |
8 |
9 | Introduction
10 | ============
11 |
12 | Pyment is a software allowing to create, update or convert several docstrings formats in existing Python files.
13 | So it should help Python programmers to enhance inside code documentation using docstrings.
14 |
15 | It should be useful for code not yet documented, not well documented, or partially documented and also to harmonize files using several docstring formats.
16 |
17 | Pyment will then be helpful to harmonize or change a project docstring style format.
18 |
19 | How does it work
20 | ----------------
21 |
22 | Pyment will parse one python file or several (automatically exploring a folder and its sub-folder) and retrieve existing docstrings.
23 | Then, for each found function/method/class, it will generate a formatted docstrings with parameters, default values,...
24 |
25 | At the end, depending on options, original files will be overwritten or patches will be generated for each file, in which
26 | case you just have to apply the patches.
27 |
28 | What are the supported formats
29 | ------------------------------
30 |
31 | Currently, the managed styles are javadoc, reST (re-Structured Text, used by Sphinx), numpydoc, google, other groups (like Google).
32 |
33 |
34 | Customization
35 | -------------
36 |
37 | It is planed to provide a large customization properties. However, it is currently limited to some settings.
38 |
39 | There are two ways to customize Pyment.
40 |
41 | The first is using the command line options (`pyment --help`). The second is providing a configuration file as explained later in that document.
42 |
43 |
44 | Using Pyment
45 | ============
46 |
47 | Pyment runs under Python 2.7+/3+. But if *argparser* is installed it can run under Python 2.6, and maybe less.
48 |
49 | Pyment is usable as is on command line using pyment script. But it can also be used into a Python program.
50 |
51 | How to install
52 | --------------
53 |
54 | The better way is to get the latest version from Github:
55 |
56 | .. code-block:: sh
57 |
58 | git clone git@github.com:dadadel/pyment.git # or https://github.com/dadadel/pyment.git
59 | cd pyment
60 | python setup.py install
61 |
62 | You can also get an archive of a released version `from Github `_.
63 |
64 | How to run
65 | ----------
66 |
67 | - To run Pyment from the command line the easiest way is to provide a Python file or a folder:
68 |
69 | .. code-block:: sh
70 |
71 | pyment example.py
72 | pyment folder/to/python/progs
73 |
74 | - To get the available options, run:
75 |
76 | .. code-block:: sh
77 |
78 | pyment -h
79 |
80 | Will provide the output:
81 |
82 | .. code-block:: sh
83 |
84 | usage: pyment [-h] [-i style] [-o style] [-q quotes] [-f status] [-t]
85 | [-c config] [-d] [-p status] [-v] [-w]
86 | path
87 |
88 | Generates patches after (re)writing docstrings.
89 |
90 | positional arguments:
91 | path python file or folder containing python files to
92 | proceed (explore also sub-folders)
93 |
94 | optional arguments:
95 | -h, --help show this help message and exit
96 | -i style, --input style
97 | Input docstring style in ["javadoc", "reST",
98 | "numpydoc", "google", "auto"] (default autodetected)
99 | -o style, --output style
100 | Output docstring style in ["javadoc", "reST",
101 | "numpydoc", "google"] (default "reST")
102 | -q quotes, --quotes quotes
103 | Type of docstring delimiter quotes: ''' or """
104 | (default """). Note that you may escape the characters
105 | using \ like \'\'\', or surround it with the opposite
106 | quotes like "'''"
107 | -f status, --first-line status
108 | Does the comment starts on the first line after the
109 | quotes (default "True")
110 | -t, --convert Existing docstrings will be converted but won't create
111 | missing ones
112 | -c config, --config-file config
113 | Get a Pyment configuration from a file. Note that the
114 | config values will overload the command line ones.
115 | -d, --init2class If no docstring to class, then move the __init__ one
116 | -p status, --ignore-private status
117 | Don't proceed the private methods/functions starting
118 | with __ (two underscores) (default "True")
119 | -v, --version show program's version number and exit
120 | -w, --write Don't write patches. Overwrite files instead.
121 |
122 | - To run the unit-tests:
123 |
124 | .. code-block:: sh
125 |
126 | python setup.py test
127 |
128 | - To run from a Python program:
129 |
130 | .. code-block:: python
131 |
132 | import os
133 | from pyment import PyComment
134 |
135 | filename = 'test.py'
136 |
137 | c = PyComment(filename)
138 | c.proceed()
139 | c.diff_to_file(os.path.basename(filename) + ".patch")
140 | for s in c.get_output_docs():
141 | print(s)
142 |
143 | Note that a documentation will be provided later. Now you can use Python introspection like: *>>> help(PyComment)*
144 |
145 |
146 | Configuration file
147 | ==================
148 |
149 | You can provide a configuration file to manage some settings.
150 |
151 | Note that if you use command line parameters that are also set in the
152 | configuration file, then the command line ones will be ignored.
153 |
154 | The configuration parameters that you can set are:
155 |
156 | - **first_line**
157 |
158 | *True or False*
159 |
160 | Set to **True** then for each docstring, the description should start on the first
161 | line, just after the quotes. In the other case the description will start on the
162 | second line.
163 |
164 | - **quotes**
165 |
166 | *''' or """*
167 |
168 | The quotes used for the docstring limits.
169 |
170 | - **output_style**
171 |
172 | *javadoc, reST, numpydoc, groups*
173 |
174 | The output format for the docstring.
175 |
176 | - **input_style**
177 |
178 | *auto, javadoc, reST, numpydoc, groups*
179 |
180 | The input format for the docstring interpretation. Set to **auto** if you want
181 | Pyment to autodetect for each docstring its format.
182 |
183 | - **init2class**
184 |
185 | *True or False*
186 |
187 | Set to **True** to move the generated docstring for __init__ to the class docstring.
188 | If there was already a docstring for the class, then the __init__ will conserve
189 | its docstring and the class its own.
190 |
191 | - **convert_only**
192 |
193 | *True or False*
194 |
195 | Set to **True** if you want only to convert existing docstring.
196 | So Pyment won't create missing docstrings.
197 |
198 |
199 | **Todo...**
200 |
201 | - Add other command line options
202 | - *optional/excluded sections*
203 |
204 | Pyment will ignore some sections (like *raises*) or will generate some sections only if there was an existing corresponding section in input docstring.
205 |
206 |
207 | Examples
208 | ========
209 |
210 | A full example
211 | --------------
212 |
213 | Here is a full example using Pyment to generate a patch and then apply the patch.
214 |
215 | Let's consider a file *test.py* with following content:
216 |
217 | .. code-block:: python
218 |
219 | def func(param1=True, param2='default val'):
220 | '''Description of func with docstring groups style (Googledoc).
221 |
222 | Params:
223 | param1 - descr of param1 that has True for default value.
224 | param2 - descr of param2
225 |
226 | Returns:
227 | some value
228 |
229 | Raises:
230 | keyError: raises key exception
231 | TypeError: raises type exception
232 |
233 | '''
234 | pass
235 |
236 | class A:
237 | def method(self, param1, param2=None):
238 | pass
239 |
240 | Now let's use Pyment:
241 |
242 | .. code-block:: sh
243 |
244 | $ pyment test.py
245 |
246 | Using Pyment without any argument will autodetect the docstrings formats and generate a patch using the reStructured Text format.
247 | So the previous command has generated the file *test.py.patch* with following content:
248 |
249 | .. code-block:: diff
250 |
251 | # Patch generated by Pyment v0.2.0
252 |
253 | --- a/test.py
254 | +++ b/test.py
255 | @@ -1,20 +1,22 @@
256 | def func(param1=True, param2='default val'):
257 | - '''Description of func with docstring groups style (Googledoc).
258 | + """Description of func with docstring groups style (Googledoc).
259 |
260 | - Params:
261 | - param1 - descr of param1 that has True for default value.
262 | - param2 - descr of param2
263 | + :param param1: descr of param1 that has True for default value
264 | + :param param2: descr of param2 (Default value = 'default val')
265 | + :returns: some value
266 | + :raises keyError: raises key exception
267 | + :raises TypeError: raises type exception
268 |
269 | - Returns:
270 | - some value
271 | -
272 | - Raises:
273 | - keyError: raises key exception
274 | - TypeError: raises type exception
275 | -
276 | - '''
277 | + """
278 | pass
279 |
280 | class A:
281 | + """ """
282 | def method(self, param1, param2=None):
283 | + """
284 | +
285 | + :param param1:
286 | + :param param2: (Default value = None)
287 | +
288 | + """
289 | pass
290 |
291 | Let's finally apply the patch with the following command:
292 |
293 | .. code-block:: sh
294 |
295 | $ patch -p1 < test.py.patch
296 |
297 | Now the original *test.py* was updated and its content is now:
298 |
299 | .. code-block:: python
300 |
301 | def func(param1=True, param2='default val'):
302 | """Description of func with docstring groups style (Googledoc).
303 |
304 | :param param1: descr of param1 that has True for default value
305 | :param param2: descr of param2 (Default value = 'default val')
306 | :returns: some value
307 | :raises keyError: raises key exception
308 | :raises TypeError: raises type exception
309 |
310 | """
311 | pass
312 |
313 | class A:
314 | """ """
315 | def method(self, param1, param2=None):
316 | """
317 |
318 | :param param1:
319 | :param param2: (Default value = None)
320 |
321 | """
322 | pass
323 |
324 |
325 | Results examples
326 | ----------------
327 |
328 | Refer to the files `example.py.patch `_ or `example.py.patch `_ to see what kind of results can be obtained.
329 |
330 | The 1st patch was generated using the following command:
331 |
332 | .. code-block:: sh
333 |
334 | pyment -f false example.py
335 |
336 | And the second using:
337 |
338 | .. code-block:: sh
339 |
340 | pyment -f false -o numpydoc example.py
341 |
342 |
343 | Managed docstrings examples
344 | ---------------------------
345 |
346 | There follows some examples of docstrings that can be recognized or generated.
347 |
348 | - "javadoc" style:
349 |
350 | .. code-block:: python
351 |
352 | """
353 | This is a javadoc style.
354 |
355 | @param param1: this is a first param
356 | @param param2: this is a second param
357 | @return: this is a description of what is returned
358 | @raise keyError: raises an exception
359 | """
360 |
361 | - "reST" style (the kind managed by Sphinx):
362 |
363 | .. code-block:: python
364 |
365 | """
366 | This is a reST style.
367 |
368 | :param param1: this is a first param
369 | :type param1: str
370 | :param param2: this is a second param
371 | :type param2: int
372 | :returns: this is a description of what is returned
373 | :rtype: bool
374 | :raises keyError: raises an exception
375 | """
376 |
377 | - "google" style:
378 |
379 | .. code-block:: python
380 |
381 | """
382 | This is a Google style docs.
383 |
384 | Args:
385 | param1(str): this is the first param
386 | param2(int, optional): this is a second param
387 |
388 | Returns:
389 | bool: This is a description of what is returned
390 |
391 | Raises:
392 | KeyError: raises an exception
393 | """
394 |
395 | - "numpydoc" style:
396 |
397 | .. code-block:: python
398 |
399 | """
400 | My numpydoc description of a kind
401 | of very exhautive numpydoc format docstring.
402 |
403 | Parameters
404 | ----------
405 | first : array_like
406 | the 1st param name `first`
407 | second :
408 | the 2nd param
409 | third : {'value', 'other'}, optional
410 | the 3rd param, by default 'value'
411 |
412 | Returns
413 | -------
414 | string
415 | a value in a string
416 |
417 | Raises
418 | ------
419 | KeyError
420 | when a key error
421 | OtherError
422 | when an other error
423 |
424 | See Also
425 | --------
426 | a_func : linked (optional), with things to say
427 | on several lines
428 | some blabla
429 |
430 | Note
431 | ----
432 | Some informations.
433 |
434 | Some maths also:
435 | .. math:: f(x) = e^{- x}
436 |
437 | References
438 | ----------
439 | Biblio with cited ref [1]_. The ref can be cited in Note section.
440 |
441 | .. [1] Adel Daouzli, Sylvain Saïghi, Michelle Rudolph, Alain Destexhe,
442 | Sylvie Renaud: Convergence in an Adaptive Neural Network:
443 | The Influence of Noise Inputs Correlation. IWANN (1) 2009: 140-148
444 |
445 | Examples
446 | --------
447 | This is example of use
448 | >>> print "a"
449 | a
450 |
451 | """
452 |
453 | - other "groups" style:
454 |
455 | .. code-block:: python
456 |
457 | """
458 | This is a groups style docs.
459 |
460 | Parameters:
461 | param1 - this is the first param
462 | param2 - this is a second param
463 |
464 | Returns:
465 | This is a description of what is returned
466 |
467 | Raises:
468 | KeyError - raises an exception
469 | """
470 |
471 | Contact/Contributing
472 | ====================
473 |
474 | - Contact
475 |
476 | There is a dedicated **IRC** channel on **Freenode**: **#pyment**. The developer is *dadel*.
477 |
478 | You can also send him an email to daouzli AT gmail DOT com (please head your subject with *[Pyment]*).
479 |
480 | - Contribute
481 |
482 | Concerning contributing, note that the development is in early steps, and the global code arrangement can change, especially concerning making easier to add new format support.
483 | However you can contribute by opening issues, proposing pull requests, or contacting directly the developer.
484 |
485 | The tests are unfortunately not good enough, so you can contribute in that field, that would be really great!
486 | An other useful way to contribute should be to create a plugin for you favorite IDE.
487 | You can also find in the code some TODOs, not always up-to-date.
488 |
489 | - Donate
490 |
491 | If you enjoyed this free software, and want to donate you can give me some bitcoins, I would be happy :)
492 |
493 | Here's my address for bitcoins : 1Kz5bu4HuRtwbjzopN6xWSVsmtTDK6Kb89
494 |
--------------------------------------------------------------------------------