test for docstring existence

  • Last Update :
  • Techknowledgy :

Make default .pylintrc with this command:

 pylint--generate - rcfile > .pylintrc

Edit change docstring-min-length variable to:

 docstring - min - length = 10

Then execute this script... echo will print the exit code from pylint test:

 pylint --disable=all --enable=missing-docstring <package-name>
    echo $?

The easy way to do this, without using external programs like pylint, is to check if the functions doc attribute is None.

def f():
   pass

print(f.__doc__ is None) # Prints None.

Suggestion : 2

The doctest module searches for pieces of text that look like interactive Python sessions, and then executes those sessions to verify that they work exactly as shown. There are several common ways to use doctest:,In most cases a copy-and-paste of an interactive console session works fine, but doctest isn’t trying to do an exact emulation of any specific Python shell.,A single interactive example, consisting of a Python statement and its expected output. The constructor arguments are used to initialize the attributes of the same names.,The advanced API revolves around two container classes, which are used to store the interactive examples extracted from doctest cases:

""
"
This is the "example"
module.

The example module supplies one
function, factorial().For example,

   >>>
   factorial(5)
120
   ""
"

def factorial(n):
   ""
"Return the factorial of n, an exact integer >= 0.

>>>
[factorial(n) for n in range(6)]
[1, 1, 2, 6, 24, 120] >>>
factorial(30)
265252859812191058636308480000000
   >>>
   factorial(-1)
Traceback(most recent call last):
   ...
   ValueError: n must be >= 0

Factorials of floats are OK, but the float must be an exact integer:
   >>>
   factorial(30.1)
Traceback(most recent call last):
   ...
   ValueError: n must be exact integer >>>
   factorial(30.0)
265252859812191058636308480000000

It must also not be ridiculously large:
   >>>
   factorial(1e100)
Traceback(most recent call last):
   ...
   OverflowError: n too large ""
"

import math
if not n >= 0:
   raise ValueError("n must be >= 0")
if math.floor(n) != n:
   raise ValueError("n must be exact integer")
if n + 1 == n: #
catch a value like 1e300
raise OverflowError("n too large")
result = 1
factor = 2
while factor <= n:
   result *= factor
factor += 1
return result

if __name__ == "__main__":
   import doctest
doctest.testmod()
$ python example.py
$
$ python example.py - v
Trying:
   factorial(5)
Expecting:
   120
ok
Trying: [factorial(n) for n in range(6)]
Expecting: [1, 1, 2, 6, 24, 120]
ok
Trying:
   factorial(1e100)
Expecting:
   Traceback(most recent call last):
   ...
   OverflowError: n too large
ok
2 items passed all tests:
   1 tests in __main__
8 tests in __main__.factorial
9 tests in 2 items.
9 passed and 0 failed.
Test passed.
$
if __name__ == "__main__":
   import doctest
doctest.testmod()
python M.py

Suggestion : 3

Last Updated : 15 Jun, 2018

Output:

Trying:
   factorial(3)
Expecting:
   6
ok
Trying:
   factorial(5)
Expecting:
   120
ok
1 items had no tests:
   factorial
1 items passed all tests:
   2 tests in factorial.factorial
2 tests in 2 items.
2 passed and 0 failed.
Test passed.

Suggestion : 4

Running the module as a script causes the examples in the docstrings to get executed and verified:,In addition, if M.__test__ exists and “is true”, it must be a dict, and each entry maps a (string) name to a function object, class object, or string. Function and class object docstrings found from M.__test__ are searched, and strings are treated as if they were docstrings. In output, a key K in M.__test__ appears with name,The module docstring, and all function, class and method docstrings are searched. Objects imported into the module are not searched.,example is the example about to be processed. test is the test containing example. out is the output function that was passed to DocTestRunner.run().

""
"
This is the "example"
module.

The example module supplies one
function, factorial().For example,

   >>>
   factorial(5)
120
   ""
"

def factorial(n):
   ""
"Return the factorial of n, an exact integer >= 0.

>>>
[factorial(n) for n in range(6)]
[1, 1, 2, 6, 24, 120] >>>
factorial(30)
265252859812191058636308480000000
   >>>
   factorial(-1)
Traceback(most recent call last):
   ...
   ValueError: n must be >= 0

Factorials of floats are OK, but the float must be an exact integer:
   >>>
   factorial(30.1)
Traceback(most recent call last):
   ...
   ValueError: n must be exact integer >>>
   factorial(30.0)
265252859812191058636308480000000

It must also not be ridiculously large:
   >>>
   factorial(1e100)
Traceback(most recent call last):
   ...
   OverflowError: n too large ""
"

import math
if not n >= 0:
   raise ValueError("n must be >= 0")
if math.floor(n) != n:
   raise ValueError("n must be exact integer")
if n + 1 == n: #
catch a value like 1e300
raise OverflowError("n too large")
result = 1
factor = 2
while factor <= n:
   result *= factor
factor += 1
return result

if __name__ == "__main__":
   import doctest
doctest.testmod()
$ python example.py
$
$ python example.py - v
Trying:
   factorial(5)
Expecting:
   120
ok
Trying: [factorial(n) for n in range(6)]
Expecting: [1, 1, 2, 6, 24, 120]
ok
Trying:
   factorial(1e100)
Expecting:
   Traceback(most recent call last):
   ...
   OverflowError: n too large
ok
2 items passed all tests:
   1 tests in __main__
8 tests in __main__.factorial
9 tests in 2 items.
9 passed and 0 failed.
Test passed.
$
if __name__ == "__main__":
   import doctest
doctest.testmod()
python M.py

Suggestion : 5

As the name says, doctest is documentation first and a test later. Their goal is not to replace tests but to provide up to date documentation. You can read more about doctests in the ExUnit.DocTest docs.,In this section, we will implement the parsing functionality, document it and make sure our documentation is up to date with doctests. This helps us provide documentation with accurate code samples.,Finally, you may have observed that each doctest corresponds to a different test in our suite, which now reports a total of 7 doctests. That is because ExUnit considers the following to define two different doctests:,Doctests are specified by an indentation of four spaces followed by the iex> prompt in a documentation string. If a command spans multiple lines, you can use ...>, as in IEx. The expected result should start at the next line after iex> or ...> line(s) and is terminated either by a newline or a new iex> prefix.

CREATE shopping
OK

PUT shopping milk 1
OK

PUT shopping eggs 3
OK

GET shopping milk
1
OK

DELETE shopping eggs
OK
defmodule KVServer.Command do
      @doc~S ""
   "
Parses the given `line`
into a command.

# # Examples

iex > KVServer.Command.parse("CREATE shopping\r\n") {
   : ok, {
      : create,
      "shopping"
   }
}

""
"
def parse(_line) do
      : not_implemented
   end
end
defmodule KVServer.CommandTest do
      use ExUnit.Case, async: true
   doctest KVServer.Command
end
  1) test doc at KVServer.Command.parse / 1(1)(KVServer.CommandTest)
  test / kv_server / command_test.exs: 3
  Doctest failed
  code: KVServer.Command.parse "CREATE shopping\r\n" === {
     : ok,
     {
        : create,
        "shopping"
     }
  }
  lhs:: not_implemented
  stacktrace:
     lib / kv_server / command.ex: 7: KVServer.Command(module)
def parse(line) do
      case String.split(line) do
         ["CREATE", bucket] - > {
            : ok,
            {
               : create,
               bucket
            }
         }
      end
   end
@doc~S ""
"
Parses the given `line`
into a command.

# # Examples

iex > KVServer.Command.parse "CREATE shopping\r\n" {
   : ok, {
      : create,
      "shopping"
   }
}

iex > KVServer.Command.parse "CREATE  shopping  \r\n" {
   : ok, {
      : create,
      "shopping"
   }
}

iex > KVServer.Command.parse "PUT shopping milk 1\r\n" {
   : ok, {
      : put,
      "shopping",
      "milk",
      "1"
   }
}

iex > KVServer.Command.parse "GET shopping milk\r\n" {
   : ok, {
      : get,
      "shopping",
      "milk"
   }
}

iex > KVServer.Command.parse "DELETE shopping eggs\r\n" {
   : ok, {
      : delete,
      "shopping",
      "eggs"
   }
}

Unknown commands or commands with the wrong number of
   arguments
return an error:

   iex > KVServer.Command.parse "UNKNOWN shopping eggs\r\n" {
      : error,: unknown_command
   }

iex > KVServer.Command.parse "GET shopping\r\n" {
   : error,: unknown_command
}

""
"