Skip to content

Commit 48fcfa1

Browse files
committed
Add code python docstring command to, you know...
1 parent 2c6160c commit 48fcfa1

File tree

4 files changed

+142
-0
lines changed

4 files changed

+142
-0
lines changed

ocd/code/__init__.py

Whitespace-only changes.

ocd/code/python/__init__.py

Whitespace-only changes.

ocd/code/python/docstring.py

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
# -*- coding: utf-8 -*-
2+
3+
"""
4+
Create a docstring for Python code.
5+
"""
6+
7+
# Standard imports
8+
import logging
9+
import sys
10+
11+
from pathlib import Path
12+
13+
# External imports
14+
from cliff.command import Command
15+
16+
# Local imports
17+
import openai
18+
from ocd.utils import ( # pylint: disable=no-name-in-module
19+
Defaults,
20+
ranged_type,
21+
)
22+
23+
# pyright: reportGeneralTypeIssues=false
24+
25+
defaults = Defaults()
26+
27+
28+
class CodePythonDocstring(Command):
29+
"""
30+
Create a docstring for Python code.
31+
32+
Defaults to the current version of Python being used to run 'ocd'.
33+
To use a different Python version, use the `--python-version` option.
34+
35+
By default, this command works like a filter, reading code from
36+
standard input and writing to standard output. You can instead
37+
get the code from a file using the `--source` option and can write
38+
the result to a file using the `--destination` option.
39+
"""
40+
41+
logger = logging.getLogger(__name__)
42+
43+
def get_parser(self, prog_name): # noqa
44+
python_version = ".".join([
45+
str(sys.version_info.major),
46+
str(sys.version_info.minor)
47+
])
48+
parser = super().get_parser(prog_name)
49+
# Hack to validate Python version. Not ideal, but sort of works.
50+
parser.add_argument(
51+
"--python-version",
52+
default=float(python_version),
53+
type=ranged_type(float, 3.7, 3.10),
54+
help="Python version to use",
55+
)
56+
parser.add_argument(
57+
"-m", "--model",
58+
dest="model_id",
59+
default=defaults.CODEX_MODEL_ID,
60+
help="ID of the model to use",
61+
)
62+
parser.add_argument(
63+
"--temperature",
64+
default=defaults.CODE_TEMPERATURE,
65+
type=ranged_type(float, 0.0, 1.0),
66+
help="sampling temperature to use",
67+
)
68+
parser.add_argument(
69+
"--max-tokens",
70+
default=defaults.MAX_CODE_TOKENS,
71+
help="maximum tokens",
72+
)
73+
parser.add_argument(
74+
"--top-p",
75+
type=float,
76+
default=1.0,
77+
help="top p",
78+
)
79+
parser.add_argument(
80+
"--frequency-penalty",
81+
type=float,
82+
default=0.0,
83+
help="frequency penalty",
84+
)
85+
parser.add_argument(
86+
"--presence-penalty",
87+
type=float,
88+
default=0.0,
89+
help="presence penalty",
90+
)
91+
parser.add_argument(
92+
"--source",
93+
default='-',
94+
help="read code from source file instead of stdin",
95+
)
96+
parser.add_argument(
97+
"--destination",
98+
default='-',
99+
help="write docstring to file instead of stdout",
100+
)
101+
return parser
102+
103+
def take_action(self, parsed_args): # noqa
104+
if parsed_args.source == '-':
105+
source_code = sys.stdin.read()
106+
else:
107+
source_code = Path(parsed_args.source).read_text(encoding='utf-8')
108+
prompt = (
109+
f'# Python {parsed_args.python_version}\n'
110+
f'\n{source_code}\n'
111+
'# An elaborate, high quality docstring for the above function:\n'
112+
'"""'
113+
)
114+
response = openai.Completion.create(
115+
prompt=prompt,
116+
model=parsed_args.model_id,
117+
temperature=parsed_args.temperature,
118+
max_tokens=parsed_args.max_tokens,
119+
top_p=parsed_args.top_p,
120+
frequency_penalty=parsed_args.frequency_penalty,
121+
presence_penalty=parsed_args.presence_penalty,
122+
stop=['#', '"""']
123+
)
124+
if not response:
125+
raise RuntimeError("[-] no response received")
126+
finish_reason = response['choices'][0]['finish_reason']
127+
docstring = response['choices'][0]['text']
128+
result = f'"""\n{docstring}\n"""\n'
129+
if finish_reason != 'stop':
130+
self.logger.info(
131+
"[-] completion did not stop normally: %s",
132+
finish_reason,
133+
)
134+
if parsed_args.destination == '-':
135+
print(result)
136+
else:
137+
outfile_path = Path(parsed_args.destination)
138+
outfile_path.write_text(result, encoding='utf-8')
139+
140+
141+
# vim: set fileencoding=utf-8 ts=4 sw=4 tw=0 et :

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ console_scripts =
6262
ocd = ocd.__main__:main
6363

6464
ocd =
65+
code_python_docstring = ocd.code.python.docstring:CodePythonDocstring
6566
completions_create = ocd.completions.create:CompletionsCreate
6667
edits_create = ocd.edits.create:EditsCreate
6768
fine-tune list = ocd.fine_tune.list:FineTuneList

0 commit comments

Comments
 (0)