From 46ebe95304de710145ded8caf421c6b6950dba6d Mon Sep 17 00:00:00 2001 From: kotfu Date: Mon, 16 Apr 2018 23:21:59 -0600 Subject: [PATCH 1/6] Basic structure for cmd2 as a package --- cmd2/__init__.py | 6 ++++++ cmd2.py => cmd2/cmd2.py | 0 setup.py | 2 +- tests/__init__.py | 5 +++++ tests/test_argparse.py | 2 +- tests/test_cmd2.py | 4 ++-- tests/test_submenu.py | 2 +- tests/test_transcript.py | 2 +- 8 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 cmd2/__init__.py rename cmd2.py => cmd2/cmd2.py (100%) create mode 100644 tests/__init__.py diff --git a/cmd2/__init__.py b/cmd2/__init__.py new file mode 100644 index 000000000..fe3747e06 --- /dev/null +++ b/cmd2/__init__.py @@ -0,0 +1,6 @@ +# +# -*- coding: utf-8 -*- +# +from .cmd2 import Cmd, Cmd2TestCase, set_posix_shlex, set_strip_quotes, AddSubmenu +from .cmd2 import can_clip, with_category, categorize +from .cmd2 import with_argument_list, with_argparser, with_argparser_and_unknown_args diff --git a/cmd2.py b/cmd2/cmd2.py similarity index 100% rename from cmd2.py rename to cmd2/cmd2.py diff --git a/setup.py b/setup.py index 88e4cf7de..3df4cf760 100755 --- a/setup.py +++ b/setup.py @@ -95,7 +95,7 @@ url='https://github.com/python-cmd2/cmd2', license='MIT', platforms=['any'], - py_modules=["cmd2"], + packages=find_packages(), keywords='command prompt console cmd', install_requires=INSTALL_REQUIRES, extras_require=EXTRAS_REQUIRE, diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 000000000..6d3e5a823 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,5 @@ +# +# -*- coding: utf-8 -*- +# +from .conftest import run_cmd, StdOut, normalize, BASE_HELP, BASE_HELP_VERBOSE, \ + HELP_HISTORY, SHORTCUTS_TXT, SHOW_TXT, SHOW_LONG diff --git a/tests/test_argparse.py b/tests/test_argparse.py index 7096848a3..569dc57bc 100644 --- a/tests/test_argparse.py +++ b/tests/test_argparse.py @@ -8,7 +8,7 @@ import cmd2 from unittest import mock -from conftest import run_cmd, StdOut +#from conftest import run_cmd, StdOut # Prefer statically linked gnureadline if available (for macOS compatibility due to issues with libedit) try: diff --git a/tests/test_cmd2.py b/tests/test_cmd2.py index e4316757a..bf6d52422 100644 --- a/tests/test_cmd2.py +++ b/tests/test_cmd2.py @@ -22,8 +22,8 @@ from unittest import mock import cmd2 -from conftest import run_cmd, normalize, BASE_HELP, BASE_HELP_VERBOSE, \ - HELP_HISTORY, SHORTCUTS_TXT, SHOW_TXT, SHOW_LONG, StdOut +#from conftest import run_cmd, normalize, BASE_HELP, BASE_HELP_VERBOSE, \ +# HELP_HISTORY, SHORTCUTS_TXT, SHOW_TXT, SHOW_LONG, StdOut def test_ver(): diff --git a/tests/test_submenu.py b/tests/test_submenu.py index 3064da56d..f91991ea9 100644 --- a/tests/test_submenu.py +++ b/tests/test_submenu.py @@ -5,7 +5,7 @@ import pytest import cmd2 -from conftest import run_cmd, StdOut, normalize +#from conftest import run_cmd, StdOut, normalize class SecondLevelB(cmd2.Cmd): diff --git a/tests/test_transcript.py b/tests/test_transcript.py index a24f2fa50..f3d98b0a1 100644 --- a/tests/test_transcript.py +++ b/tests/test_transcript.py @@ -16,7 +16,7 @@ import cmd2 from cmd2 import Cmd, Cmd2TestCase, set_posix_shlex, set_strip_quotes -from conftest import run_cmd, StdOut, normalize +#from conftest import run_cmd, StdOut, normalize class CmdLineApp(Cmd): From ff4ebc85bb5185efec9a072e38129c3982ad83af Mon Sep 17 00:00:00 2001 From: kotfu Date: Mon, 16 Apr 2018 23:34:23 -0600 Subject: [PATCH 2/6] Most of the unit tests fixed. --- cmd2/__init__.py | 4 +++- tests/__init__.py | 3 +-- tests/test_argparse.py | 2 +- tests/test_cmd2.py | 4 ++-- tests/test_submenu.py | 2 +- tests/test_transcript.py | 2 +- 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/cmd2/__init__.py b/cmd2/__init__.py index fe3747e06..d5db3b069 100644 --- a/cmd2/__init__.py +++ b/cmd2/__init__.py @@ -1,6 +1,8 @@ # # -*- coding: utf-8 -*- # -from .cmd2 import Cmd, Cmd2TestCase, set_posix_shlex, set_strip_quotes, AddSubmenu +from .cmd2 import Cmd, Cmd2TestCase, set_posix_shlex, set_strip_quotes, AddSubmenu, cast +from .cmd2 import _which, get_paste_buffer, __version__, POSIX_SHLEX from .cmd2 import can_clip, with_category, categorize from .cmd2 import with_argument_list, with_argparser, with_argparser_and_unknown_args +from .cmd2 import ParserManager, History, HistoryItem, EmptyStatement diff --git a/tests/__init__.py b/tests/__init__.py index 6d3e5a823..2aeb9ddfc 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,5 +1,4 @@ # # -*- coding: utf-8 -*- # -from .conftest import run_cmd, StdOut, normalize, BASE_HELP, BASE_HELP_VERBOSE, \ - HELP_HISTORY, SHORTCUTS_TXT, SHOW_TXT, SHOW_LONG + diff --git a/tests/test_argparse.py b/tests/test_argparse.py index 569dc57bc..6a9a93a74 100644 --- a/tests/test_argparse.py +++ b/tests/test_argparse.py @@ -8,7 +8,7 @@ import cmd2 from unittest import mock -#from conftest import run_cmd, StdOut +from .conftest import run_cmd, StdOut # Prefer statically linked gnureadline if available (for macOS compatibility due to issues with libedit) try: diff --git a/tests/test_cmd2.py b/tests/test_cmd2.py index bf6d52422..b3d903ca0 100644 --- a/tests/test_cmd2.py +++ b/tests/test_cmd2.py @@ -22,8 +22,8 @@ from unittest import mock import cmd2 -#from conftest import run_cmd, normalize, BASE_HELP, BASE_HELP_VERBOSE, \ -# HELP_HISTORY, SHORTCUTS_TXT, SHOW_TXT, SHOW_LONG, StdOut +from .conftest import run_cmd, normalize, BASE_HELP, BASE_HELP_VERBOSE, \ + HELP_HISTORY, SHORTCUTS_TXT, SHOW_TXT, SHOW_LONG, StdOut def test_ver(): diff --git a/tests/test_submenu.py b/tests/test_submenu.py index f91991ea9..fbb9857b1 100644 --- a/tests/test_submenu.py +++ b/tests/test_submenu.py @@ -5,7 +5,7 @@ import pytest import cmd2 -#from conftest import run_cmd, StdOut, normalize +from .conftest import run_cmd, StdOut, normalize class SecondLevelB(cmd2.Cmd): diff --git a/tests/test_transcript.py b/tests/test_transcript.py index f3d98b0a1..e25d8532f 100644 --- a/tests/test_transcript.py +++ b/tests/test_transcript.py @@ -16,7 +16,7 @@ import cmd2 from cmd2 import Cmd, Cmd2TestCase, set_posix_shlex, set_strip_quotes -#from conftest import run_cmd, StdOut, normalize +from .conftest import run_cmd, StdOut, normalize class CmdLineApp(Cmd): From 4eadcac45b1f95edc8eb36b8f8a20bf2395b2470 Mon Sep 17 00:00:00 2001 From: Todd Leonhardt Date: Tue, 17 Apr 2018 00:35:08 -0700 Subject: [PATCH 3/6] Fix unit tests on package branch --- cmd2/__init__.py | 6 +++--- cmd2/cmd2.py | 6 ++++++ tests/test_cmd2.py | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/cmd2/__init__.py b/cmd2/__init__.py index d5db3b069..18b80585a 100644 --- a/cmd2/__init__.py +++ b/cmd2/__init__.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- # from .cmd2 import Cmd, Cmd2TestCase, set_posix_shlex, set_strip_quotes, AddSubmenu, cast -from .cmd2 import _which, get_paste_buffer, __version__, POSIX_SHLEX -from .cmd2 import can_clip, with_category, categorize +from .cmd2 import _which, get_paste_buffer, __version__, POSIX_SHLEX, STRIP_QUOTES_FOR_NON_POSIX +from .cmd2 import can_clip, disable_clip, with_category, categorize from .cmd2 import with_argument_list, with_argparser, with_argparser_and_unknown_args -from .cmd2 import ParserManager, History, HistoryItem, EmptyStatement +from .cmd2 import ParserManager, History, HistoryItem, EmptyStatement, CmdResult diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py index 54eff811b..b9928a4b2 100755 --- a/cmd2/cmd2.py +++ b/cmd2/cmd2.py @@ -375,6 +375,12 @@ def cmd_wrapper(instance, cmdline): can_clip = True +def disable_clip(): + """ Allows user of cmd2 to manually disable clipboard cut-and-paste functionality.""" + global can_clip + can_clip = False + + def get_paste_buffer(): """Get the contents of the clipboard / paste buffer. diff --git a/tests/test_cmd2.py b/tests/test_cmd2.py index b3d903ca0..daa58a064 100644 --- a/tests/test_cmd2.py +++ b/tests/test_cmd2.py @@ -1363,7 +1363,7 @@ def test_multiline_complete_statement_without_terminator(multiline_app): def test_clipboard_failure(capsys): # Force cmd2 clipboard to be disabled - cmd2.can_clip = False + cmd2.disable_clip() app = cmd2.Cmd() # Redirect command output to the clipboard when a clipboard isn't present From 7bad93fbe4214a767f7dc92dc9ee5958f4bb379c Mon Sep 17 00:00:00 2001 From: Todd Leonhardt Date: Tue, 17 Apr 2018 00:42:31 -0700 Subject: [PATCH 4/6] Attempting to fix tox run of unit tests Local py.test run of unit tests now passes. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 3df4cf760..d925ccc22 100755 --- a/setup.py +++ b/setup.py @@ -95,7 +95,7 @@ url='https://github.com/python-cmd2/cmd2', license='MIT', platforms=['any'], - packages=find_packages(), + packages=['cmd2'], keywords='command prompt console cmd', install_requires=INSTALL_REQUIRES, extras_require=EXTRAS_REQUIRE, From b3e6625001e64a2516eba33ca526d45e25d1ca5f Mon Sep 17 00:00:00 2001 From: Todd Leonhardt Date: Tue, 17 Apr 2018 00:56:36 -0700 Subject: [PATCH 5/6] Fix documentation which referred to a single/one source file --- CONTRIBUTING.md | 2 +- docs/install.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f7eba2fa5..e0cbd57b2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -236,7 +236,7 @@ This bit is up to you! #### How to find the code in the cmd2 codebase to fix/edit? The cmd2 project directory structure is pretty simple and straightforward. All actual code for cmd2 -is located in a single file, `cmd2.py`. The code to generate the documentation is in the `docs` directory. Unit tests are in the `tests` directory. The `examples` directory contains examples of how +is located underneath the `cmd2` directory. The code to generate the documentation is in the `docs` directory. Unit tests are in the `tests` directory. The `examples` directory contains examples of how to use cmd2. There are various other files in the root directory, but these are primarily related to continuous integration and to release deployment. diff --git a/docs/install.rst b/docs/install.rst index be7c61dda..6baf4078a 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -88,10 +88,10 @@ This will also install the required 3rd-party dependencies. Deploy cmd2.py with your project ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -``cmd2`` is contained in only one Python file (**cmd2.py**), so it can be easily copied into your project. *The +``cmd2`` is contained in a small number of Python files, which can be easily copied into your project. *The copyright and license notice must be retained*. -This is an option suitable for advanced Python users. You can simply include this file within your project's hierarchy. +This is an option suitable for advanced Python users. You can simply include the files within your project's hierarchy. If you want to modify ``cmd2``, this may be a reasonable option. Though, we encourage you to use stock ``cmd2`` and either composition or inheritance to achieve the same goal. From 9697bf1858c6ef06e13bdfd3dfaea6d0376d9a6a Mon Sep 17 00:00:00 2001 From: Todd Leonhardt Date: Tue, 17 Apr 2018 19:30:18 -0700 Subject: [PATCH 6/6] Cleaned up __init__.py Removed things which were only needed for unit tests from __init__.py - Converted to importing from cmd2.cmd2. within the relevant unit tests --- cmd2/__init__.py | 7 ++----- tests/test_cmd2.py | 18 +++++++++--------- tests/test_parsing.py | 36 ++++++++++++++++++------------------ tests/test_transcript.py | 10 +++++----- 4 files changed, 34 insertions(+), 37 deletions(-) diff --git a/cmd2/__init__.py b/cmd2/__init__.py index 18b80585a..8e744e03d 100644 --- a/cmd2/__init__.py +++ b/cmd2/__init__.py @@ -1,8 +1,5 @@ # # -*- coding: utf-8 -*- # -from .cmd2 import Cmd, Cmd2TestCase, set_posix_shlex, set_strip_quotes, AddSubmenu, cast -from .cmd2 import _which, get_paste_buffer, __version__, POSIX_SHLEX, STRIP_QUOTES_FOR_NON_POSIX -from .cmd2 import can_clip, disable_clip, with_category, categorize -from .cmd2 import with_argument_list, with_argparser, with_argparser_and_unknown_args -from .cmd2 import ParserManager, History, HistoryItem, EmptyStatement, CmdResult +from .cmd2 import __version__, Cmd, set_posix_shlex, set_strip_quotes, AddSubmenu, CmdResult, categorize +from .cmd2 import with_argument_list, with_argparser, with_argparser_and_unknown_args, with_category diff --git a/tests/test_cmd2.py b/tests/test_cmd2.py index daa58a064..35ef4c0f1 100644 --- a/tests/test_cmd2.py +++ b/tests/test_cmd2.py @@ -105,8 +105,8 @@ def test_base_show_readonly(base_app): Strip Quotes after splitting arguments: {} """.format(base_app.terminators, base_app.allow_cli_args, base_app.allow_redirection, - "POSIX" if cmd2.POSIX_SHLEX else "non-POSIX", - "True" if cmd2.STRIP_QUOTES_FOR_NON_POSIX and not cmd2.POSIX_SHLEX else "False")) + "POSIX" if cmd2.cmd2.POSIX_SHLEX else "non-POSIX", + "True" if cmd2.cmd2.STRIP_QUOTES_FOR_NON_POSIX and not cmd2.cmd2.POSIX_SHLEX else "False")) assert out == expected @@ -643,18 +643,18 @@ def test_pipe_to_shell_error(base_app, capsys): assert err.startswith("EXCEPTION of type '{}' occurred with message:".format(expected_error)) -@pytest.mark.skipif(not cmd2.can_clip, +@pytest.mark.skipif(not cmd2.cmd2.can_clip, reason="Pyperclip could not find a copy/paste mechanism for your system") def test_send_to_paste_buffer(base_app): # Test writing to the PasteBuffer/Clipboard run_cmd(base_app, 'help >') expected = normalize(BASE_HELP) - assert normalize(cmd2.get_paste_buffer()) == expected + assert normalize(cmd2.cmd2.get_paste_buffer()) == expected # Test appending to the PasteBuffer/Clipboard run_cmd(base_app, 'help history >>') expected = normalize(BASE_HELP + '\n' + HELP_HISTORY) - assert normalize(cmd2.get_paste_buffer()) == expected + assert normalize(cmd2.cmd2.get_paste_buffer()) == expected def test_base_timing(base_app, capsys): @@ -1310,7 +1310,7 @@ def test_help_with_no_docstring(capsys): reason="cmd2._which function only used on Mac and Linux") def test_which_editor_good(): editor = 'vi' - path = cmd2._which(editor) + path = cmd2.cmd2._which(editor) # Assert that the vi editor was found because it should exist on all Mac and Linux systems assert path @@ -1318,7 +1318,7 @@ def test_which_editor_good(): reason="cmd2._which function only used on Mac and Linux") def test_which_editor_bad(): editor = 'notepad.exe' - path = cmd2._which(editor) + path = cmd2.cmd2._which(editor) # Assert that the editor wasn't found because no notepad.exe on non-Windows systems ;-) assert path is None @@ -1345,7 +1345,7 @@ def multiline_app(): return app def test_multiline_complete_empty_statement_raises_exception(multiline_app): - with pytest.raises(cmd2.EmptyStatement): + with pytest.raises(cmd2.cmd2.EmptyStatement): multiline_app._complete_statement('') def test_multiline_complete_statement_without_terminator(multiline_app): @@ -1363,7 +1363,7 @@ def test_multiline_complete_statement_without_terminator(multiline_app): def test_clipboard_failure(capsys): # Force cmd2 clipboard to be disabled - cmd2.disable_clip() + cmd2.cmd2.disable_clip() app = cmd2.Cmd() # Redirect command output to the clipboard when a clipboard isn't present diff --git a/tests/test_parsing.py b/tests/test_parsing.py index e2367a376..2682ec686 100644 --- a/tests/test_parsing.py +++ b/tests/test_parsing.py @@ -16,8 +16,8 @@ @pytest.fixture def hist(): - from cmd2 import HistoryItem - h = cmd2.History([HistoryItem('first'), HistoryItem('second'), HistoryItem('third'), HistoryItem('fourth')]) + from cmd2.cmd2 import HistoryItem + h = cmd2.cmd2.History([HistoryItem('first'), HistoryItem('second'), HistoryItem('third'), HistoryItem('fourth')]) return h # Case-sensitive parser @@ -25,12 +25,12 @@ def hist(): def parser(): c = cmd2.Cmd() c.multilineCommands = ['multiline'] - c.parser_manager = cmd2.ParserManager(redirector=c.redirector, terminators=c.terminators, - multilineCommands=c.multilineCommands, legalChars=c.legalChars, - commentGrammars=c.commentGrammars, commentInProgress=c.commentInProgress, - blankLinesAllowed=c.blankLinesAllowed, prefixParser=c.prefixParser, - preparse=c.preparse, postparse=c.postparse, aliases=c.aliases, - shortcuts=c.shortcuts) + c.parser_manager = cmd2.cmd2.ParserManager(redirector=c.redirector, terminators=c.terminators, + multilineCommands=c.multilineCommands, legalChars=c.legalChars, + commentGrammars=c.commentGrammars, commentInProgress=c.commentInProgress, + blankLinesAllowed=c.blankLinesAllowed, prefixParser=c.prefixParser, + preparse=c.preparse, postparse=c.postparse, aliases=c.aliases, + shortcuts=c.shortcuts) return c.parser_manager.main_parser # Case-sensitive ParserManager @@ -38,12 +38,12 @@ def parser(): def cs_pm(): c = cmd2.Cmd() c.multilineCommands = ['multiline'] - c.parser_manager = cmd2.ParserManager(redirector=c.redirector, terminators=c.terminators, - multilineCommands=c.multilineCommands, legalChars=c.legalChars, - commentGrammars=c.commentGrammars, commentInProgress=c.commentInProgress, - blankLinesAllowed=c.blankLinesAllowed, prefixParser=c.prefixParser, - preparse=c.preparse, postparse=c.postparse, aliases=c.aliases, - shortcuts=c.shortcuts) + c.parser_manager = cmd2.cmd2.ParserManager(redirector=c.redirector, terminators=c.terminators, + multilineCommands=c.multilineCommands, legalChars=c.legalChars, + commentGrammars=c.commentGrammars, commentInProgress=c.commentInProgress, + blankLinesAllowed=c.blankLinesAllowed, prefixParser=c.prefixParser, + preparse=c.preparse, postparse=c.postparse, aliases=c.aliases, + shortcuts=c.shortcuts) return c.parser_manager @@ -77,7 +77,7 @@ def test_history_get(hist): def test_cast(): - cast = cmd2.cast + cast = cmd2.cmd2.cast # Boolean assert cast(True, True) == True @@ -101,7 +101,7 @@ def test_cast(): def test_cast_problems(capsys): - cast = cmd2.cast + cast = cmd2.cmd2.cast expected = 'Problem setting parameter (now {}) to {}; incorrect type?\n' @@ -327,8 +327,8 @@ def test_parse_input_redirect_from_unicode_filename(input_parser): def test_empty_statement_raises_exception(): app = cmd2.Cmd() - with pytest.raises(cmd2.EmptyStatement): + with pytest.raises(cmd2.cmd2.EmptyStatement): app._complete_statement('') - with pytest.raises(cmd2.EmptyStatement): + with pytest.raises(cmd2.cmd2.EmptyStatement): app._complete_statement(' ') diff --git a/tests/test_transcript.py b/tests/test_transcript.py index e25d8532f..8ee5f3f6f 100644 --- a/tests/test_transcript.py +++ b/tests/test_transcript.py @@ -15,10 +15,10 @@ import pytest import cmd2 -from cmd2 import Cmd, Cmd2TestCase, set_posix_shlex, set_strip_quotes +from cmd2 import set_posix_shlex, set_strip_quotes from .conftest import run_cmd, StdOut, normalize -class CmdLineApp(Cmd): +class CmdLineApp(cmd2.Cmd): MUMBLES = ['like', '...', 'um', 'er', 'hmmm', 'ahh'] MUMBLE_FIRST = ['so', 'like', 'well'] @@ -82,7 +82,7 @@ def do_mumble(self, opts, arg): self.poutput(' '.join(output)) -class DemoApp(Cmd): +class DemoApp(cmd2.Cmd): hello_parser = argparse.ArgumentParser() hello_parser.add_argument('-n', '--name', help="your name") @cmd2.with_argparser_and_unknown_args(hello_parser) @@ -189,7 +189,7 @@ def test_base_with_transcript(_cmdline_app): assert out == expected -class TestMyAppCase(Cmd2TestCase): +class TestMyAppCase(cmd2.cmd2.Cmd2TestCase): CmdApp = CmdLineApp CmdApp.testfiles = ['tests/transcript.txt'] @@ -293,7 +293,7 @@ def test_transcript(request, capsys, filename, feedback_to_output): def test_parse_transcript_expected(expected, transformed): app = CmdLineApp() - class TestMyAppCase(Cmd2TestCase): + class TestMyAppCase(cmd2.cmd2.Cmd2TestCase): cmdapp = app testcase = TestMyAppCase()