Two commands that the CLI advertises in --help cannot be used at all: both exit with status 1 before any request is sent to the API.
$ python -m deepl --help
...
text (translate) translate text(s)
rephrase rephrase text(s)
Environment
- deepl-python 1.32.0 (
main at 74415f9); the code is unchanged since both were added in v1.21.0 (4107220)
- Python 3.11.15, Linux
Reproduction
No valid key or network access is needed, the failure happens before the HTTP call:
$ python -m deepl --auth-key x translate --to DE "proton beam"
Error: 'action_translate'
$ echo $?
1
$ python -m deepl --auth-key x rephrase --to EN-GB "proton beam"
Error: DeepLClient.rephrase_text() got an unexpected keyword argument 'show_detected_source'
$ echo $?
1
Expected
translate behaves exactly like text, since it is registered as its alias.
rephrase prints the improved text, and --show-detected-source additionally prints the detected source language, as it does for text.
Cause
Both are in deepl/__main__.py:
-
The text subparser is created with aliases=["translate"], so argparse stores command="translate". main() then dispatches with globals()[f"action_{command}"], and there is no action_translate function, so a KeyError is raised and printed as Error: 'action_translate'. (main() already special-cases "translate" a few lines above when reading the text from stdin, so the alias is clearly intended to work.)
-
The rephrase subparser defines --show-detected-source (action="store_true"), so show_detected_source is always present in the parsed arguments. action_rephrase() forwards all of them with deepl_client.rephrase_text(**kwargs), but rephrase_text() has no such parameter. action_text() avoids this by consuming show_detected_source itself; action_rephrase() does not, so the command fails whether or not the flag is passed.
tests/test_cli.py has no test for either rephrase or the translate alias, which is probably why this was not noticed.
Proposed fix
I have a small patch ready and can open a PR if you would like one (CONTRIBUTING asks for an issue first):
--- a/deepl/__main__.py
+++ b/deepl/__main__.py
@@ -116,6 +116,7 @@ def action_text(
def action_rephrase(
deepl_client: deepl.DeepLClient,
+ show_detected_source: bool = False,
**kwargs,
):
"""Action function for the rephrase command."""
@@ -124,6 +125,10 @@ def action_rephrase(
improvement if isinstance(improvement, List) else [improvement]
)
for output in output_list:
+ if show_detected_source:
+ print(
+ f"Detected source language: {output.detected_source_language}"
+ )
print(output.text)
@@ -1054,6 +1059,9 @@ def main(args=None, prog_name=None):
# Call action function corresponding to command with remaining args
# ("translation-memory" maps to action_translation_memory).
command = args.pop("command").replace("-", "_")
+ if command == "translate":
+ # "translate" is an alias of the "text" command
+ command = "text"
globals()[f"action_{command}"](deepl_client, **args)
The patch also adds test_text_translate_alias, test_rephrase and test_rephrase_stdin to tests/test_cli.py. They fail on main and pass with the change when run against a local deepl-mock server; black --check ., flake8 deepl tests and mypy --exclude 'examples/' . are clean.
Two commands that the CLI advertises in
--helpcannot be used at all: both exit with status 1 before any request is sent to the API.Environment
mainat 74415f9); the code is unchanged since both were added in v1.21.0 (4107220)Reproduction
No valid key or network access is needed, the failure happens before the HTTP call:
Expected
translatebehaves exactly liketext, since it is registered as its alias.rephraseprints the improved text, and--show-detected-sourceadditionally prints the detected source language, as it does fortext.Cause
Both are in
deepl/__main__.py:The
textsubparser is created withaliases=["translate"], so argparse storescommand="translate".main()then dispatches withglobals()[f"action_{command}"], and there is noaction_translatefunction, so aKeyErroris raised and printed asError: 'action_translate'. (main()already special-cases"translate"a few lines above when reading the text from stdin, so the alias is clearly intended to work.)The
rephrasesubparser defines--show-detected-source(action="store_true"), soshow_detected_sourceis always present in the parsed arguments.action_rephrase()forwards all of them withdeepl_client.rephrase_text(**kwargs), butrephrase_text()has no such parameter.action_text()avoids this by consumingshow_detected_sourceitself;action_rephrase()does not, so the command fails whether or not the flag is passed.tests/test_cli.pyhas no test for eitherrephraseor thetranslatealias, which is probably why this was not noticed.Proposed fix
I have a small patch ready and can open a PR if you would like one (CONTRIBUTING asks for an issue first):
The patch also adds
test_text_translate_alias,test_rephraseandtest_rephrase_stdintotests/test_cli.py. They fail onmainand pass with the change when run against a localdeepl-mockserver;black --check .,flake8 deepl testsandmypy --exclude 'examples/' .are clean.