clig 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. clig-0.2.0/.gitignore +5 -0
  2. clig-0.2.0/.private/argparser_examples/example.py +14 -0
  3. clig-0.2.0/.private/argparser_examples/example4.py +44 -0
  4. clig-0.2.0/.private/argparser_examples/test.py +9 -0
  5. clig-0.2.0/.private/argparser_examples/test0.py +16 -0
  6. clig-0.2.0/.private/argparser_examples/test1.py +41 -0
  7. clig-0.2.0/.private/clig.py +0 -0
  8. clig-0.2.0/.private/clig_draft.py +64 -0
  9. clig-0.2.0/.private/cyclops_examples/example.py +20 -0
  10. clig-0.2.0/.private/dataclass_examples/teste.py +37 -0
  11. clig-0.2.0/.private/dataclass_examples/teste0.py +20 -0
  12. clig-0.2.0/.private/draft_old.py +35 -0
  13. clig-0.2.0/.private/example.py +31 -0
  14. clig-0.2.0/.private/examples_clig/example.py +10 -0
  15. clig-0.2.0/.private/examples_clig/git_clone.py +152 -0
  16. clig-0.2.0/.private/examples_clig/positional.py +47 -0
  17. clig-0.2.0/.private/fire_examples/example.py +17 -0
  18. clig-0.2.0/.private/prototype.py +99 -0
  19. clig-0.2.0/.private/test0.py +20 -0
  20. clig-0.2.0/.private/test1.py +36 -0
  21. clig-0.2.0/.private/test_parameters.py +26 -0
  22. clig-0.2.0/.private/test_subparser.py +21 -0
  23. clig-0.2.0/.private/test_trim.py +34 -0
  24. clig-0.2.0/.private/teste2.py +33 -0
  25. clig-0.2.0/.private/teste3.py +10 -0
  26. clig-0.2.0/.private/teste_typer.py +36 -0
  27. clig-0.2.0/.private/testegpt.py +90 -0
  28. clig-0.2.0/.vscode/cspell.json +11 -0
  29. clig-0.2.0/.vscode/launch.json +15 -0
  30. clig-0.2.0/.vscode/settings.json +32 -0
  31. clig-0.2.0/.vscode/tasks.json +27 -0
  32. clig-0.2.0/LICENSE.txt +9 -0
  33. clig-0.2.0/PKG-INFO +655 -0
  34. clig-0.2.0/README.md +639 -0
  35. clig-0.2.0/desktop.ini +2 -0
  36. clig-0.2.0/docs/sphinx/Makefile +20 -0
  37. clig-0.2.0/docs/sphinx/make.bat +35 -0
  38. clig-0.2.0/docs/sphinx/source/_static/.gitkeep +0 -0
  39. clig-0.2.0/docs/sphinx/source/_static/css/custom.css +4 -0
  40. clig-0.2.0/docs/sphinx/source/conf.py +47 -0
  41. clig-0.2.0/docs/sphinx/source/convert_notebook.py +99 -0
  42. clig-0.2.0/docs/sphinx/source/index.md +8 -0
  43. clig-0.2.0/docs/sphinx/source/logo.png +0 -0
  44. clig-0.2.0/docs/sphinx/source/notebooks/userguide.ipynb +1155 -0
  45. clig-0.2.0/docs/sphinx/source/notebooks/userguide.md +697 -0
  46. clig-0.2.0/icon/clig.ico +0 -0
  47. clig-0.2.0/icon/clig.png +0 -0
  48. clig-0.2.0/icon/clig0.png +0 -0
  49. clig-0.2.0/pyproject.toml +49 -0
  50. clig-0.2.0/src/clig/__about__.py +1 -0
  51. clig-0.2.0/src/clig/__init__.py +1 -0
  52. clig-0.2.0/src/clig/clig.py +909 -0
  53. clig-0.2.0/test/draft_test.py +69 -0
  54. clig-0.2.0/test/test0.py +32 -0
  55. clig-0.2.0/test/test1.py +24 -0
  56. clig-0.2.0/test/test2.py +60 -0
  57. clig-0.2.0/test/test3.py +23 -0
  58. clig-0.2.0/test/test4.py +36 -0
  59. clig-0.2.0/tests/__init__.py +0 -0
  60. clig-0.2.0/tests/functions.py +437 -0
  61. clig-0.2.0/tests/integration/test_subparsers_with_same_parameters.py +26 -0
  62. clig-0.2.0/tests/test_add_parsers.py +14 -0
  63. clig-0.2.0/tests/test_protectattr_argument_data.py +79 -0
  64. clig-0.2.0/tests/test_protectfunc_get_argument_data_from_parameter.py +27 -0
  65. clig-0.2.0/tests/test_protectfunc_normalize_docstring.py +123 -0
  66. clig-0.2.0/tests/test_protectmet_collect_docstring_data_using_template.py +384 -0
  67. clig-0.2.0/tests/test_protectmet_generate_args_to_add_argument.py +217 -0
  68. clig-0.2.0/tests/test_protectmet_get_data_from_docstring_with_templates.py +384 -0
  69. clig-0.2.0/tests/test_protectmet_get_data_from_docstring_without_templates.py +394 -0
  70. clig-0.2.0/tests/test_protectmet_get_data_from_typeannotation.py +65 -0
  71. clig-0.2.0/uv.lock +1909 -0
clig-0.2.0/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ dist/*
2
+ **/__pycache__/
3
+ .coverage
4
+ /docs/sphinx/build/
5
+ /docs/sphinx/source/notebooks/*.py
@@ -0,0 +1,14 @@
1
+ from argparse import ArgumentParser
2
+
3
+ parser = ArgumentParser()
4
+
5
+ parser.add_argument("-o")
6
+
7
+ sub = parser.add_subparsers(dest="opa")
8
+ subp = sub.add_parser("teste")
9
+ subp.add_argument("-a")
10
+
11
+
12
+ if __name__ == "__main__":
13
+ args = parser.parse_args()
14
+ print(args)
@@ -0,0 +1,44 @@
1
+ import sys
2
+ from pathlib import Path
3
+ from pprint import pprint
4
+ from argparse import ArgumentParser, HelpFormatter
5
+
6
+ # path = Path(__file__).parent
7
+ # sys.path.insert(0, str((path).resolve()))
8
+ # sys.path.insert(0, str((path / "../../../../src/clig").resolve()))
9
+ # import clig
10
+
11
+
12
+ # def main(lista: list[str]):
13
+ # print(locals())
14
+
15
+
16
+ # cmd = clig.Command(main, subcommands_description="Teste de descri", formatter_class=HelpFormatter)
17
+
18
+
19
+ # @cmd.subcommand(help="opa remove1")
20
+ # def remove(name: str):
21
+ # print(locals())
22
+
23
+
24
+ # @cmd.subcommand(help="opa add1")
25
+ # def add(name: str):
26
+ # print(locals())
27
+
28
+
29
+ # cmd.run()
30
+ # cmd.add_parsers()
31
+ # pprint(cmd.arguments)
32
+
33
+
34
+ parser = ArgumentParser(prog="main")
35
+ parser.add_argument("lista", nargs="*")
36
+ subparsers = parser.add_subparsers(dest="subcommand_1", description="Teste de descri")
37
+ subparser1 = subparsers.add_parser("remove", help="opa remove")
38
+ subparser1.add_argument("name")
39
+ subparser2 = subparsers.add_parser("add", help="opa add")
40
+ subparser2.add_argument("name")
41
+ args = parser.parse_args()
42
+ print(args)
43
+ #
44
+ # assert parser == cmd.parser
@@ -0,0 +1,9 @@
1
+ from argparse import ArgumentParser
2
+
3
+ parser = ArgumentParser()
4
+
5
+ subparsers1 = parser.add_subparsers(dest="sub1")
6
+ subparsers2 = parser.add_subparsers(dest="sub2") # This is not allowed
7
+
8
+
9
+ args = parser.parse_args(["-h"])
@@ -0,0 +1,16 @@
1
+ from argparse import ArgumentParser
2
+
3
+ parser = ArgumentParser(prog="Diogo")
4
+
5
+ subparsers1 = parser.add_subparsers(dest="sub1", description="Desc do grupo") # prog="opa")
6
+ cmd1 = subparsers1.add_parser("command1")
7
+ subparser11 = cmd1.add_subparsers(dest="sub1")
8
+ cmd11 = subparser11.add_parser("cmd11")
9
+ cmd2 = subparsers1.add_parser("command2")
10
+
11
+ cmd1.add_argument()
12
+
13
+ args = parser.parse_args("command1 -h".split())
14
+ args = parser.parse_args("command1".split())
15
+
16
+ print(args)
@@ -0,0 +1,41 @@
1
+ from functools import partial
2
+ from typing import Callable, overload
3
+
4
+
5
+ @overload
6
+ def foo[**P, T](func: Callable[P, T]) -> Callable[P, T]: ...
7
+
8
+
9
+ @overload
10
+ def foo[**P, T](**kwargs) -> Callable[[Callable[P, T]], Callable[P, T]]: ...
11
+
12
+
13
+ def foo[**P, T](func: Callable[P, T] | None = None, **kwargs) -> Callable[P, T] | Callable[[Callable[P, T]], Callable[P, T]]:
14
+ # foo called as decorator without arguments
15
+ if func is not None:
16
+ # do something using func
17
+ return func
18
+
19
+ # foo is called as decorator with arguments
20
+ return partial(foo, **kwargs)
21
+
22
+ def wrap(func: Callable[P, T]) -> Callable[P, T]:
23
+ # do something using kwargs
24
+ # do something using func
25
+ return func
26
+
27
+ # foo is called as decorator with arguments
28
+ return wrap
29
+
30
+ # print("setting " + str(kwargs))
31
+ # foo is called as decorator with arguments
32
+ return partial(foo, **kwargs)
33
+
34
+
35
+ @foo # (b=666, c="opa")
36
+ def bar(a):
37
+ print(a)
38
+
39
+
40
+ if __name__ == "__main__":
41
+ bar("aba gue")
File without changes
@@ -0,0 +1,64 @@
1
+ def get_argument_data(func: Callable[..., Any]) -> list[ArgumentData]:
2
+ argument_data: list[ArgumentData] = []
3
+ parameters = inspect.signature(func).parameters
4
+ docstring_data = get_docstring_data(len(parameters), func.__doc__)
5
+ helps = docstring_data.helps if docstring_data else {}
6
+ for par in parameters:
7
+ parameter = parameters[par]
8
+ argument = ArgumentData(name=parameter.name)
9
+ argument.help = helps.get(argument.name)
10
+ if parameter.default != parameter.empty:
11
+ argument.default = parameter.default
12
+ argument.name = f"--{argument.name}"
13
+ if parameter.annotation != parameter.empty:
14
+ if callable(parameter.annotation):
15
+ argument.kind = parameter.annotation
16
+ argument_data.append(argument)
17
+ return argument_data
18
+
19
+
20
+ if __name__ == "__main__":
21
+
22
+ def foo(
23
+ a: int, b: str, c: float, d: bool = True, e: list[str] | None = None
24
+ ) -> tuple[str, ...]:
25
+ """Iure qui iusto debitis sit temporibus quos saepe.
26
+
27
+ Dolores laudantium quisquam consequuntur placeat dolor incidunt optio dolor. Ipsum et
28
+ accusamus quibusdam et. Quo tempora aut suscipit enim velit aperiam et accusamus. Illum sunt
29
+ voluptatum et.
30
+
31
+ Parameters
32
+ ----------
33
+ a : int
34
+ Aliquid ratione quam.
35
+ b : str
36
+ Id voluptatem maiores repellat qui.
37
+ c : float
38
+ Distinctio sit nesciunt.
39
+ d : bool, optional
40
+ Qui sit et sequi cupiditate deleniti eaque amet., by default True
41
+ e : list[str] | None, optional
42
+ Facilis quam asperiores repudiandae cupiditate sapiente., by default None
43
+
44
+ Returns
45
+ -------
46
+ tuple[str, ...]
47
+ Sequi labore ut molestias id ea suscipit.
48
+ """
49
+ ...
50
+
51
+ assert foo.__doc__ is not None
52
+ docstring_data = get_docstring_data(5, foo.__doc__)
53
+ assert docstring_data is not None
54
+ arg_data = get_argument_data(foo)
55
+
56
+ parser = ArgumentParser(
57
+ description=docstring_data.description,
58
+ epilog=docstring_data.epilog,
59
+ formatter_class=ArgumentDefaultsHelpFormatter,
60
+ )
61
+
62
+ for arg in arg_data:
63
+ parser.add_argument(arg.name, type=arg.kind, default=arg.default, help=arg.help)
64
+ parser.parse_args(["-h"])
@@ -0,0 +1,20 @@
1
+ import sys
2
+ from pathlib import Path
3
+
4
+ path = Path(__file__).parent
5
+ sys.path.insert(0, str((path).resolve()))
6
+ sys.path.insert(0, str((path / "../../src").resolve()))
7
+
8
+
9
+ from cyclopts import App
10
+
11
+ app = App()
12
+
13
+
14
+ @app.default
15
+ def main(nome: str, idade: int):
16
+ print("Hello World!")
17
+
18
+
19
+ if __name__ == "__main__":
20
+ app()
@@ -0,0 +1,37 @@
1
+ from dataclasses import dataclass, field, fields
2
+
3
+
4
+ @dataclass
5
+ class Person:
6
+ name: str
7
+ age: int = field(metadata={"frozen": True})
8
+
9
+ def __post_init__(self):
10
+ self.__set_fields_frozen(self)
11
+
12
+ @classmethod
13
+ def __set_fields_frozen(cls, self):
14
+ flds = fields(cls)
15
+ for fld in flds:
16
+ if fld.metadata.get("frozen"):
17
+ field_name = fld.name
18
+ field_value = getattr(self, fld.name)
19
+ setattr(self, f"_{fld.name}", field_value)
20
+
21
+ def local_getter(self):
22
+ return getattr(self, f"_{field_name}")
23
+
24
+ def frozen(name):
25
+ def local_setter(self, value):
26
+ raise RuntimeError(f"Field '{name}' is frozen!")
27
+
28
+ return local_setter
29
+
30
+ setattr(cls, field_name, property(local_getter, frozen(field_name)))
31
+
32
+
33
+ person = Person("John", 22)
34
+
35
+ print(person) # prints: Person(name='John', age=36)
36
+ print(person.age) # prints: 36
37
+ person.age = 56 # raise: RuntimeError: Field 'age' is frozen!
@@ -0,0 +1,20 @@
1
+ from dataclasses import dataclass, field, InitVar
2
+
3
+
4
+ @dataclass(repr=True)
5
+ class Person:
6
+ name: InitVar[str]
7
+ _name: str = field(init=False)
8
+ age: int
9
+
10
+ @property
11
+ def name_(self) -> str:
12
+ self._name
13
+
14
+ def __post_init__(self, name: str) -> None:
15
+ self._name = name
16
+
17
+
18
+ p = Person(name="digo", age=36)
19
+
20
+ print(p)
@@ -0,0 +1,35 @@
1
+ import inspect
2
+ from argparse import ArgumentParser
3
+ from inspect import Parameter, Signature, signature
4
+ from typing import Any, Callable, Tuple
5
+
6
+
7
+ def run(command: Callable[..., Any]):
8
+ parser = ArgumentParser()
9
+ signature: Signature = inspect.signature(command)
10
+ parameters = signature.parameters
11
+ for name in parameters:
12
+ parameter: Parameter = parameters[name]
13
+
14
+ default = None
15
+ name = name.replace("_", "-")
16
+ if parameter.default != parameter.empty:
17
+ default = parameter.default
18
+ name = f"--{name}"
19
+ kwargs: dict[str, Any] = dict(type=str, action="store")
20
+
21
+ if parameter.annotation != parameter.empty:
22
+ if hasattr(parameter.annotation, "__metadata__"):
23
+ kwargs["type"] = parameter.annotation.__origin__
24
+ metadata = parameter.annotation.__metadata__
25
+ if callable(parameter.annotation):
26
+ kwargs["type"] = parameter.annotation
27
+
28
+ if kwargs.get("type", None) == bool:
29
+ kwargs["action"] = "store_false" if default else "store_true"
30
+
31
+ if kwargs.get("action", None) in ["store_const", "store_true", "store_false", "help"]:
32
+ kwargs.pop("type", None)
33
+
34
+ parser.add_argument(name, default=default, **kwargs)
35
+ command(**vars(parser.parse_args()))
@@ -0,0 +1,31 @@
1
+ from pprint import pprint
2
+
3
+ import numpy as np
4
+
5
+ from clig import NUMPY_DOCSTRING, get_docstring_data
6
+
7
+ np.array
8
+
9
+ if __name__ == "__main__":
10
+ # Example usage
11
+ docstring = """
12
+ Compute the square root of a number.
13
+
14
+ Teste
15
+
16
+ Parameters
17
+ ----------
18
+ x : float
19
+ The number for which to compute the square root.
20
+ y : float, optional
21
+ An additional number to adjust the result.
22
+ z : int
23
+ A parameter affecting the rounding.
24
+
25
+ Returns
26
+ -------
27
+ float
28
+ The square root of the given number.
29
+ """
30
+
31
+ pprint(get_docstring_data(3, docstring, NUMPY_DOCSTRING))
@@ -0,0 +1,10 @@
1
+ import clig
2
+
3
+
4
+ def hello():
5
+ pass
6
+
7
+
8
+ app = clig.Command(hello).add_subcommand(hello)
9
+
10
+ print(app.subparsers_dest)
@@ -0,0 +1,152 @@
1
+ import sys
2
+ from pathlib import Path
3
+
4
+ path = Path(__file__).parent
5
+ sys.path.insert(0, str((path).resolve()))
6
+ sys.path.insert(0, str((path / "../../src").resolve()))
7
+ from clig import Command, data, Arg
8
+
9
+
10
+ def git(
11
+ exec_path: str = "git",
12
+ bare: bool = False,
13
+ git_dir: str = ".git",
14
+ work_tree: str = ".",
15
+ ):
16
+ """The Git version control system
17
+
18
+ 'git help -a' and 'git help -g' list available subcommands and some concept guides. See 'git help
19
+ <command>' or 'git help <concept>' to read about a specific subcommand or concept. See 'git help git' for
20
+ an overview of the system.
21
+
22
+ Parameters
23
+ ----------
24
+ - `exec_path` (`str`, optional): Defaults to `"git"`.
25
+ The path to the executable.
26
+
27
+ - `bare` (`bool`, optional): Defaults to `False`.
28
+ Whether the repository is bare or not
29
+
30
+ - `git_dir` (`str`, optional): Defaults to `".git"`.
31
+ The path to the repository data base.
32
+
33
+ - `work_tree` (`str`, optional): Defaults to `"."`.
34
+ The path to the worktree.
35
+ """
36
+ print(locals())
37
+ return "Exec git"
38
+
39
+
40
+ def add(pathspec: list[str], interactive: Arg[bool, data("-i")] = False, edit: Arg[bool, data("-e")] = False):
41
+ """Add file contents to the index
42
+
43
+ Used to add file contents to the index
44
+
45
+ Parameters
46
+ ----------
47
+ - `pathspec` (`list[str]`):
48
+ The paths to add
49
+
50
+ - `interactive` (`Arg[bool, data`, optional): Defaults to `False`.
51
+ interactive picking
52
+
53
+ - `edit` (`Arg[bool, data`, optional): Defaults to `False`.
54
+ edit current diff and apply
55
+
56
+ """
57
+ print(locals())
58
+ return "Exec add"
59
+
60
+
61
+ def commit(message: Arg[str, data("-m")], amend: bool = False):
62
+ """Record changes to the repository
63
+
64
+ Use this to commit changes
65
+
66
+ Parameters
67
+ ----------
68
+ - `message` (`Arg[str, data`):
69
+ commit message
70
+
71
+ - `amend` (`bool`, optional): Defaults to `False`.
72
+ amend previous commit
73
+ """
74
+ print(locals())
75
+ return "Exec commit"
76
+
77
+
78
+ def remote(verbose: bool = False):
79
+ """Manage remote repositories
80
+
81
+ Use this subcommand to manage fetched remote repos.
82
+
83
+ Parameters
84
+ ----------
85
+ - `verbose` (`bool`, optional): Defaults to `False`.
86
+ Whether the subcommand is verbose
87
+
88
+ """
89
+ print(locals())
90
+ return "Exec remote"
91
+
92
+
93
+ def rename(old: str, new: str):
94
+ """Renames the remote
95
+
96
+ Use to rename the remote repo
97
+
98
+ Parameters
99
+ ----------
100
+ - `old` (`str`):
101
+ Old name of the repo
102
+
103
+ - `new` (`str`):
104
+ New name of the remote
105
+ """
106
+ print(locals())
107
+ return "Exec rename"
108
+
109
+
110
+ def remove(name: str):
111
+ """Removes a remote
112
+
113
+ Use to remove a remote reference
114
+
115
+ Parameters
116
+ ----------
117
+ - `name` (`str`):
118
+ Name of the remote
119
+ """
120
+ print(locals())
121
+ return "Exec remove"
122
+
123
+
124
+ def prune(name: str, dry_run: bool = False):
125
+ """Prune the remote repo
126
+
127
+ Use to prune the remote repo
128
+
129
+ Parameters
130
+ ----------
131
+ - `name` (`str`):
132
+ Name of the remote
133
+
134
+ - `dry_run` (`bool`, optional): Defaults to `False`.
135
+ Whether to dry run
136
+ """
137
+ print(locals())
138
+ return "Exec prune"
139
+
140
+
141
+ app = (
142
+ Command(git, subcommands_description="These are common Git commands used in various situations:")
143
+ .add_subcommand(add)
144
+ .add_subcommand(commit)
145
+ )
146
+ remote_cmd = (
147
+ app.new_subcommand(remote, subcommands_description="Comands used with git remote")
148
+ .add_subcommand(rename)
149
+ .add_subcommand(remove)
150
+ .add_subcommand(prune)
151
+ )
152
+ print(app.run())
@@ -0,0 +1,47 @@
1
+ # cSpell:disable
2
+ import sys
3
+ from pathlib import Path
4
+
5
+ path = Path(__file__).parent
6
+ sys.path.insert(0, str((path).resolve()))
7
+ sys.path.insert(0, str((path / "../../src").resolve()))
8
+ from clig import Command, data, Arg
9
+
10
+
11
+ def print_echo(
12
+ echo: str,
13
+ upper: Arg[bool, data("-u")] = True,
14
+ value: Arg[int, data("-c", "--const", make_flag=True, action="store_const", const=123)] = 666,
15
+ ):
16
+ """Quam blanditiis qui corporis aut dolor qui officiis quo.
17
+
18
+ Dolor totam repudiandae quam ea sit. Officiis nostrum repellendus. Ut odio omnis sed aut. Est qui fugit
19
+ fuga et dolorem sapiente. Nostrum qui vero cumque tempore. Necessitatibus quo facilis numquam impedit quia
20
+ ipsa minima aliquid vitae.
21
+
22
+ Parameters
23
+ ----------
24
+ - `echo` (`str`):
25
+ Repellendus id distinctio reiciendis dignissimos sit voluptatem et omnis corporis.
26
+
27
+ - `upper` (`Arg[bool, data`, optional): Defaults to `True`.
28
+ Amet sunt nihil consequatur ut dolorem provident aut.
29
+
30
+ - `value` (`Arg[int, data`, optional): Defaults to `"store_const", const=123)]=666`.
31
+ Et facilis cumque voluptatum.
32
+
33
+ """
34
+ print(locals())
35
+
36
+
37
+ def hello(word: str):
38
+ pass
39
+
40
+
41
+ def hi(word: str):
42
+ pass
43
+
44
+
45
+ cmd = Command(print_echo, description="opa")
46
+ cmd.add_command(hi)
47
+ cmd.run()
@@ -0,0 +1,17 @@
1
+ import fire
2
+
3
+
4
+ class BrokenCalculator(object):
5
+
6
+ def __init__(self, offset=1):
7
+ self._offset = offset
8
+
9
+ def add(self, x, y):
10
+ return x + y + self._offset
11
+
12
+ def multiply(self, x, y, *args, **kwargs):
13
+ return x * y + self._offset
14
+
15
+
16
+ if __name__ == "__main__":
17
+ fire.Fire(BrokenCalculator)
@@ -0,0 +1,99 @@
1
+ from pprint import pprint
2
+ import re
3
+
4
+ # Example usage
5
+ docstring_template = r"""
6
+ (.*)
7
+
8
+ Parameters
9
+ ----------
10
+ (.*) : (.*)
11
+ (.*)
12
+ (.*) : (.*)
13
+ (.*)
14
+ (.*) : (.*)
15
+ (.*)
16
+
17
+ Returns
18
+ -------
19
+ float
20
+ The square root of the given number.
21
+ """
22
+
23
+ # Example usage
24
+ docstring = """
25
+ Compute the square root of a number.
26
+
27
+ Parameters
28
+ ----------
29
+ x : float
30
+ The number for which to compute the square root.
31
+ y : float, optional
32
+ An additional number to adjust the result.
33
+ z : int
34
+ A parameter affecting the rounding.
35
+
36
+ Returns
37
+ -------
38
+ float
39
+ The square root of the given number.
40
+ """
41
+
42
+ docstring_temp = """
43
+ {{description}}
44
+
45
+ Parameters
46
+ ----------
47
+ {{parameter_name}} : {{parameter_type}}
48
+ {{parameter_description}}
49
+ """
50
+
51
+ place_holders: dict[str, int | None | str] = {
52
+ "description": None,
53
+ "parameter_name": None,
54
+ "parameter_type": None,
55
+ "parameter_description": None,
56
+ }
57
+
58
+ list_indexes = []
59
+ for place_holder in place_holders:
60
+ place = f"{{{place_holder}}}"
61
+ if place in docstring_temp:
62
+ index = docstring_temp.index(place)
63
+ place_holders[place_holder] = index
64
+ list_indexes.append(index)
65
+ list_indexes.sort()
66
+
67
+ for place_holder in place_holders:
68
+ place_holders[place_holder] = list_indexes.index(place_holders[place_holder])
69
+
70
+ PARAMETER_NUMBER = 3
71
+
72
+ place = "{{parameter_name}}"
73
+ if place in docstring_temp:
74
+ index = docstring_temp.index(place)
75
+ substring = docstring_temp[index:]
76
+
77
+ regex_string = docstring_temp
78
+ for i in range(PARAMETER_NUMBER - 1):
79
+ regex_string += substring
80
+
81
+ for place_holder in place_holders:
82
+ place = f"{{{{{place_holder}}}}}"
83
+ regex_string = regex_string.replace(place, "(.*)")
84
+
85
+ # pprint(substring)
86
+
87
+ # pprint(regex_string)
88
+
89
+
90
+ # current_param = None
91
+
92
+ match = re.match(regex_string, docstring)
93
+ if match:
94
+ params = match.groups()
95
+ # for place_holder in place_holders:
96
+ # place_holders[place_holder] = params[place_holders[place_holder]]
97
+ # pprint(place_holders)
98
+
99
+ # pprint(place_holders)