Skip to content

Commit 2f2eb8c

Browse files
committed
fix #21
1 parent ff5777c commit 2f2eb8c

File tree

8 files changed

+76
-67
lines changed

8 files changed

+76
-67
lines changed

django_routines/__init__.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@
1515

1616
import bisect
1717
import sys
18+
import keyword
1819
import typing as t
1920
from abc import ABC, abstractmethod
2021
from dataclasses import asdict, dataclass, field
2122

2223
from django.core.exceptions import ImproperlyConfigured
2324
from django.utils.functional import Promise
2425

25-
VERSION = (1, 1, 2)
26+
VERSION = (1, 1, 3)
2627

2728
__title__ = "Django Routines"
2829
__version__ = ".".join(str(i) for i in VERSION)
@@ -50,12 +51,15 @@
5051
Command = t.Union["ManagementCommand", "SystemCommand"]
5152

5253

53-
def to_symbol(name: str) -> str:
54-
return name.lstrip("-").replace("-", "_")
54+
def to_symbol(name: str, check_keyword: bool=False) -> str:
55+
symbol = name.lstrip("-").replace("-", "_")
56+
if check_keyword and symbol.lower() in keyword.kwlist:
57+
return f"{symbol}_"
58+
return symbol
5559

5660

5761
def to_cli_option(name: str) -> str:
58-
return f'--{to_symbol(name).replace("_", "-")}'
62+
return f'--{to_symbol(name, check_keyword=False).replace("_", "-")}'
5963

6064

6165
@dataclass

django_routines/management/commands/routine.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -275,18 +275,18 @@ def _list(self) -> None:
275275
switches = routine.switches
276276
switch_args = ", ".join(
277277
[
278-
f"{to_symbol(switch)}: Annotated[bool, typer.Option('{to_cli_option(switch)}', help='{routine.switch_helps.get(switch, '')}')] = False"
278+
f"{to_symbol(switch, check_keyword=True)}: Annotated[bool, typer.Option('{to_cli_option(switch)}', help='{routine.switch_helps.get(switch, '')}')] = False"
279279
for switch in switches
280280
]
281281
)
282282
add_switches = ""
283283
for switch in switches:
284284
add_switches += (
285-
f'\n if all or {to_symbol(switch)}: self.switches.append("{switch}")'
285+
f'\n if all or {to_symbol(switch, check_keyword=True)}: self.switches.append("{switch}")'
286286
)
287287

288288
cmd_code = COMMAND_TMPL.format(
289-
routine_func=to_symbol(routine.name),
289+
routine_func=to_symbol(routine.name, check_keyword=True),
290290
routine=routine.name,
291291
switch_args=switch_args,
292292
add_switches=add_switches,
@@ -336,7 +336,7 @@ def _list(self) -> None:
336336
help=help_txt,
337337
short_help=routine.help_text,
338338
invoke_without_command=True,
339-
)(locals()[to_symbol(routine.name)])
339+
)(locals()[to_symbol(routine.name, check_keyword=True)])
340340

341341
@grp.command(name="list", help=_("List the commands that will be run."))
342342
def list(self):

doc/source/changelog.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
Change Log
33
==========
44

5+
v1.1.3 (17-JUL-2024)
6+
====================
7+
8+
* `Allow routine names that conflict with python keywords (i.e. import) <https://github.com/bckohan/django-routines/issues/21>`_
9+
510
v1.1.2 (15-JUL-2024)
611
====================
712

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "django-routines"
3-
version = "1.1.2"
3+
version = "1.1.3"
44
description = "Define named groups of management commands in Django settings files for batched execution."
55
authors = ["Brian Kohan <bckohan@gmail.com>"]
66
license = "MIT"

tests/settings.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,35 +75,35 @@
7575
demo="Deploy the demo.",
7676
)
7777

78-
command("deploy", "shellcompletion", "install", switches=["initial"])
78+
command("deploy", "shellcompletion", "install", switches=["import"])
7979
command("deploy", "loaddata", "./fixtures/initial_data.json", switches=["demo"])
8080

8181
assert get_routine("deploy").name == "deploy"
8282

8383

84-
command("test", "track", "2", priority=0, switches=("initial", "demo"))
84+
command("import", "track", "2", priority=0, switches=("import", "demo"))
8585
routine(
86-
"test",
86+
"import",
8787
_("Test Routine 1"),
8888
RoutineCommand(
89-
("track", "0"), priority=1, switches=("initial",), options={"verbosity": 0}
89+
("track", "0"), priority=1, switches=("import",), options={"verbosity": 0}
9090
),
9191
RoutineCommand(("track", "1"), priority=4),
9292
SystemCommand((system_cmd, "sys 2"), priority=8),
9393
)
9494

95-
command("test", "track", "3", priority=3, demo=2)
96-
command("test", "track", "4", priority=3, demo=6, flag=True)
97-
command("test", "track", "5", priority=6, switches=["demo"])
98-
system("test", system_cmd, "sys 1", priority=7)
95+
command("import", "track", "3", priority=3, demo=2)
96+
command("import", "track", "4", priority=3, demo=6, flag=True)
97+
command("import", "track", "5", priority=6, switches=["demo"])
98+
system("import", system_cmd, "sys 1", priority=7)
9999

100100

101101
names = set()
102102
for rtn in routines():
103103
assert isinstance(rtn, Routine)
104104
names.add(rtn.name)
105105

106-
assert names == {"deploy", "test"}
106+
assert names == {"deploy", "import"}
107107

108108
routine(
109109
"bad",

tests/test_core.py

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ def test_command(self, no_color=True, verbosity=None, subprocess=False):
7474
*(["--manage-script", "./manage.py"] if subprocess else []),
7575
("--no-color" if no_color else "--force-color"),
7676
*(("--verbosity", str(verbosity)) if verbosity is not None else tuple()),
77-
"test",
77+
"import",
7878
]
7979
if subprocess:
8080
command.append("--subprocess")
@@ -217,7 +217,7 @@ def test_command(self, no_color=True, verbosity=None, subprocess=False):
217217
track_file.write_text(json.dumps(clear_results))
218218

219219
out = StringIO()
220-
call_command(*command, "--demo", "--initial", stdout=out)
220+
call_command(*command, "--demo", "--import", stdout=out)
221221
expected = [2, 0, 3, 4, 1, 5]
222222
if verbosity is None or verbosity > 0:
223223
for line, exp in zip(
@@ -267,7 +267,7 @@ def test_command(self, no_color=True, verbosity=None, subprocess=False):
267267
track_file.write_text(json.dumps(clear_results))
268268

269269
out = StringIO()
270-
call_command(*command, "--initial", stdout=out)
270+
call_command(*command, "--import", stdout=out)
271271
expected = [2, 0, 3, 4, 1]
272272
if verbosity is None or verbosity > 0:
273273
for line, exp in zip(
@@ -327,18 +327,18 @@ def test_verbosity(self):
327327

328328
def test_list(self, no_color=True):
329329
if no_color:
330-
command = ("routine", "--no-color", "test")
330+
command = ("routine", "--no-color", "import")
331331
else:
332-
command = ("routine", "--force-color", "test")
332+
command = ("routine", "--force-color", "import")
333333

334334
out = StringIO()
335335
call_command(*command, "--all", "list", stdout=out)
336336
plan = self.lines(out.getvalue(), no_color=no_color)
337337
self.assertEqual(
338338
plan,
339339
[
340-
"[0] track 2 | initial, demo",
341-
"[1] track 0 (verbosity=0) | initial",
340+
"[0] track 2 | import, demo",
341+
"[1] track 0 (verbosity=0) | import",
342342
"[3] track 3 (demo=2)",
343343
"[3] track 4 (demo=6, flag=True)",
344344
"[4] track 1",
@@ -368,7 +368,7 @@ def test_list(self, no_color=True):
368368
self.assertEqual(
369369
plan,
370370
[
371-
"[0] track 2 | initial, demo",
371+
"[0] track 2 | import, demo",
372372
"[3] track 3 (demo=2)",
373373
"[3] track 4 (demo=6, flag=True)",
374374
"[4] track 1",
@@ -379,13 +379,13 @@ def test_list(self, no_color=True):
379379
)
380380

381381
out = StringIO()
382-
call_command(*command, "--demo", "--initial", "list", stdout=out)
382+
call_command(*command, "--demo", "--import", "list", stdout=out)
383383
plan = self.lines(out.getvalue(), no_color=no_color)
384384
self.assertEqual(
385385
plan,
386386
[
387-
"[0] track 2 | initial, demo",
388-
"[1] track 0 (verbosity=0) | initial",
387+
"[0] track 2 | import, demo",
388+
"[1] track 0 (verbosity=0) | import",
389389
"[3] track 3 (demo=2)",
390390
"[3] track 4 (demo=6, flag=True)",
391391
"[4] track 1",
@@ -396,13 +396,13 @@ def test_list(self, no_color=True):
396396
)
397397

398398
out = StringIO()
399-
call_command(*command, "--initial", "list", stdout=out)
399+
call_command(*command, "--import", "list", stdout=out)
400400
plan = self.lines(out.getvalue(), no_color=no_color)
401401
self.assertEqual(
402402
plan,
403403
[
404-
"[0] track 2 | initial, demo",
405-
"[1] track 0 (verbosity=0) | initial",
404+
"[0] track 2 | import, demo",
405+
"[1] track 0 (verbosity=0) | import",
406406
"[3] track 3 (demo=2)",
407407
"[3] track 4 (demo=6, flag=True)",
408408
"[4] track 1",
@@ -517,20 +517,20 @@ def test_subprocess(self):
517517
╭─ Commands ───────────────────────────────────────────────────────────────────╮
518518
│ bad Bad command test routine │
519519
│ deploy Deploy the site application into production. │
520-
test Test Routine 1 │
520+
import Test Routine 1 │
521521
│ test-hyphen Test that hyphens dont mess everything up. │
522522
╰──────────────────────────────────────────────────────────────────────────────╯
523523
"""
524524

525525
routine_test_help_rich = """
526-
Usage: ./manage.py routine test [OPTIONS] COMMAND [ARGS]...
526+
Usage: ./manage.py routine import [OPTIONS] COMMAND [ARGS]...
527527
528528
529529
Test Routine 1
530530
531531
532-
[0] track 2 | initial, demo
533-
[1] track 0 (verbosity=0) | initial
532+
[0] track 2 | import, demo
533+
[1] track 0 (verbosity=0) | import
534534
[3] track 3 (demo=2)
535535
[3] track 4 (demo=6, flag=True)
536536
[4] track 1
@@ -542,7 +542,7 @@ def test_subprocess(self):
542542
│ --subprocess Run commands as subprocesses. │
543543
│ --all Include all switched commands. │
544544
│ --demo │
545-
│ --initial
545+
│ --import
546546
│ --help Show this message and exit. │
547547
╰──────────────────────────────────────────────────────────────────────────────╯
548548
╭─ Commands ───────────────────────────────────────────────────────────────────╮
@@ -572,7 +572,7 @@ def test_helps_rich(self):
572572
stdout = StringIO()
573573

574574
routine = get_command("routine", TyperCommand, stdout=stdout, no_color=True)
575-
routine.print_help("./manage.py", "routine", "test")
575+
routine.print_help("./manage.py", "routine", "import")
576576
self.assertEqual(
577577
self.strip_ansi(stdout.getvalue()).strip().replace("\x08", ""),
578578
self.routine_test_help_rich.strip(),
@@ -605,18 +605,18 @@ def test_helps_rich(self):
605605
Commands:
606606
bad Bad command test routine
607607
deploy Deploy the site application into production.
608-
test Test Routine 1
608+
import Test Routine 1
609609
test-hyphen Test that hyphens dont mess everything up.
610610
"""
611611

612612
routine_test_help_no_rich = """
613-
Usage: ./manage.py routine test [OPTIONS] COMMAND [ARGS]...
613+
Usage: ./manage.py routine import [OPTIONS] COMMAND [ARGS]...
614614
615615
Test Routine 1
616616
-----------------------------------
617617
618-
[0] track 2 | initial, demo
619-
[1] track 0 (verbosity=0) | initial
618+
[0] track 2 | import, demo
619+
[1] track 0 (verbosity=0) | import
620620
[3] track 3 (demo=2)
621621
[3] track 4 (demo=6, flag=True)
622622
[4] track 1
@@ -628,7 +628,7 @@ def test_helps_rich(self):
628628
--subprocess Run commands as subprocesses.
629629
--all Include all switched commands.
630630
--demo
631-
--initial
631+
--import
632632
--help Show this message and exit.
633633
634634
Commands:
@@ -657,7 +657,7 @@ def test_helps_no_rich(self):
657657
stdout = StringIO()
658658

659659
routine = get_command("routine", TyperCommand, stdout=stdout, no_color=True)
660-
routine.print_help("./manage.py", "routine", "test")
660+
routine.print_help("./manage.py", "routine", "import")
661661
self.assertEqual(
662662
stdout.getvalue().strip().replace("\x08", ""),
663663
self.routine_test_help_no_rich.strip(),
@@ -734,7 +734,7 @@ def test_settings_format(self):
734734
"kind": "management",
735735
"options": {},
736736
"priority": 0,
737-
"switches": ("initial",),
737+
"switches": ("import",),
738738
},
739739
{
740740
"command": ("loaddata", "./fixtures/initial_data.json"),
@@ -754,22 +754,22 @@ def test_settings_format(self):
754754
},
755755
)
756756
self.assertEqual(
757-
routines["test"],
757+
routines["import"],
758758
{
759759
"commands": [
760760
{
761761
"command": ("track", "2"),
762762
"kind": "management",
763763
"options": {},
764764
"priority": 0,
765-
"switches": ("initial", "demo"),
765+
"switches": ("import", "demo"),
766766
},
767767
{
768768
"command": ("track", "0"),
769769
"kind": "management",
770770
"options": {"verbosity": 0},
771771
"priority": 1,
772-
"switches": ("initial",),
772+
"switches": ("import",),
773773
},
774774
{
775775
"command": ("track", "3"),
@@ -813,7 +813,7 @@ def test_settings_format(self):
813813
},
814814
],
815815
"help_text": "Test Routine 1",
816-
"name": "test",
816+
"name": "import",
817817
"switch_helps": {},
818818
"subprocess": False,
819819
},

0 commit comments

Comments
 (0)