diff options
-rw-r--r-- | CONTRIBUTING.md | 2 | ||||
-rwxr-xr-x | cmd2/AutoCompleter.py (renamed from AutoCompleter.py) | 2 | ||||
-rw-r--r-- | cmd2/__init__.py | 5 | ||||
-rwxr-xr-x | cmd2/cmd2.py (renamed from cmd2.py) | 15 | ||||
-rw-r--r-- | cmd2/rl_utils.py (renamed from rl_utils.py) | 0 | ||||
-rw-r--r-- | docs/install.rst | 4 | ||||
-rwxr-xr-x | examples/tab_autocompletion.py | 3 | ||||
-rwxr-xr-x | setup.py | 2 | ||||
-rw-r--r-- | tests/__init__.py | 4 | ||||
-rw-r--r-- | tests/test_acargparse.py | 20 | ||||
-rw-r--r-- | tests/test_argparse.py | 2 | ||||
-rw-r--r-- | tests/test_autocompletion.py | 4 | ||||
-rw-r--r-- | tests/test_cmd2.py | 20 | ||||
-rw-r--r-- | tests/test_parsing.py | 36 | ||||
-rw-r--r-- | tests/test_submenu.py | 2 | ||||
-rw-r--r-- | tests/test_transcript.py | 12 |
16 files changed, 60 insertions, 73 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f7eba2fa..e0cbd57b 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/AutoCompleter.py b/cmd2/AutoCompleter.py index 5e6d04bf..7f79cec1 100755 --- a/AutoCompleter.py +++ b/cmd2/AutoCompleter.py @@ -3,7 +3,7 @@ import argparse import re as _re import sys from argparse import OPTIONAL, ZERO_OR_MORE, ONE_OR_MORE, REMAINDER, PARSER, ArgumentError, _ -from rl_utils import rl_force_redisplay +from .rl_utils import rl_force_redisplay try: from typing import List, Dict, Tuple, Callable, Union except: diff --git a/cmd2/__init__.py b/cmd2/__init__.py new file mode 100644 index 00000000..8e744e03 --- /dev/null +++ b/cmd2/__init__.py @@ -0,0 +1,5 @@ +# +# -*- coding: utf-8 -*- +# +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 @@ -49,7 +49,7 @@ import pyparsing import pyperclip # Set up readline -from rl_utils import rl_force_redisplay, readline, rl_type, RlType +from .rl_utils import rl_force_redisplay, readline, rl_type, RlType if rl_type == RlType.PYREADLINE: @@ -70,13 +70,6 @@ elif rl_type == RlType.GNU: rl_basic_quote_characters = ctypes.c_char_p.in_dll(readline_lib, "rl_basic_quote_characters") orig_rl_basic_quote_characters_addr = ctypes.cast(rl_basic_quote_characters, ctypes.c_void_p).value -# Newer versions of pyperclip are released as a single file, but older versions had a more complicated structure -try: - from pyperclip.exceptions import PyperclipException -except ImportError: - # noinspection PyUnresolvedReferences - from pyperclip import PyperclipException - # Collection is a container that is sizable and iterable # It was introduced in Python 3.6. We will try to import it, otherwise use our implementation try: @@ -351,6 +344,12 @@ else: 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/rl_utils.py b/cmd2/rl_utils.py index 1dc83d15..1dc83d15 100644 --- a/rl_utils.py +++ b/cmd2/rl_utils.py diff --git a/docs/install.rst b/docs/install.rst index be7c61dd..6baf4078 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. diff --git a/examples/tab_autocompletion.py b/examples/tab_autocompletion.py index f1453c59..103706ac 100755 --- a/examples/tab_autocompletion.py +++ b/examples/tab_autocompletion.py @@ -3,12 +3,11 @@ """A simple example demonstrating how to use flag and index based tab-completion functions """ import argparse -import AutoCompleter import itertools from typing import List import cmd2 -from cmd2 import with_argparser, with_category +from cmd2 import with_argparser, with_category, AutoCompleter class TabCompleteExample(cmd2.Cmd): @@ -96,7 +96,7 @@ setup( url='https://github.com/python-cmd2/cmd2', license='MIT', platforms=['any'], - py_modules=["cmd2"], + packages=['cmd2'], 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 00000000..2aeb9ddf --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,4 @@ +# +# -*- coding: utf-8 -*- +# + diff --git a/tests/test_acargparse.py b/tests/test_acargparse.py index 01b4dce9..6f40bd42 100644 --- a/tests/test_acargparse.py +++ b/tests/test_acargparse.py @@ -7,26 +7,8 @@ file system paths, and shell commands. Copyright 2017 Todd Leonhardt <todd.leonhardt@gmail.com> Released under MIT license, see LICENSE file """ -import argparse -import os -import sys - -import cmd2 -from unittest import mock import pytest -from AutoCompleter import ACArgumentParser - -# Prefer statically linked gnureadline if available (for macOS compatibility due to issues with libedit) -try: - import gnureadline as readline -except ImportError: - # Try to import readline, but allow failure for convenience in Windows unit testing - # Note: If this actually fails, you should install readline on Linux or Mac or pyreadline on Windows - try: - # noinspection PyUnresolvedReferences - import readline - except ImportError: - pass +from cmd2.AutoCompleter import ACArgumentParser def test_acarg_narg_empty_tuple(): diff --git a/tests/test_argparse.py b/tests/test_argparse.py index 7096848a..6a9a93a7 100644 --- a/tests/test_argparse.py +++ b/tests/test_argparse.py @@ -8,7 +8,7 @@ import pytest 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_autocompletion.py b/tests/test_autocompletion.py index bca46794..0b33095c 100644 --- a/tests/test_autocompletion.py +++ b/tests/test_autocompletion.py @@ -7,14 +7,12 @@ file system paths, and shell commands. Copyright 2017 Todd Leonhardt <todd.leonhardt@gmail.com> Released under MIT license, see LICENSE file """ -import argparse import os import sys -import cmd2 from unittest import mock import pytest -from conftest import run_cmd, normalize, StdOut +from .conftest import run_cmd, normalize, StdOut MY_PATH = os.path.realpath(__file__) sys.path.append(os.path.join(MY_PATH, '..', 'examples')) diff --git a/tests/test_cmd2.py b/tests/test_cmd2.py index e4316757..35ef4c0f 100644 --- a/tests/test_cmd2.py +++ b/tests/test_cmd2.py @@ -22,7 +22,7 @@ except ImportError: from unittest import mock import cmd2 -from conftest import run_cmd, normalize, BASE_HELP, BASE_HELP_VERBOSE, \ +from .conftest import run_cmd, normalize, BASE_HELP, BASE_HELP_VERBOSE, \ HELP_HISTORY, SHORTCUTS_TXT, SHOW_TXT, SHOW_LONG, StdOut @@ -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 @@ optional arguments: 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.can_clip = False + 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 e2367a37..2682ec68 100644 --- a/tests/test_parsing.py +++ b/tests/test_parsing.py @@ -16,8 +16,8 @@ import pytest @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_submenu.py b/tests/test_submenu.py index 3064da56..fbb9857b 100644 --- a/tests/test_submenu.py +++ b/tests/test_submenu.py @@ -5,7 +5,7 @@ Cmd2 testing for argument parsing 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 a24f2fa5..8ee5f3f6 100644 --- a/tests/test_transcript.py +++ b/tests/test_transcript.py @@ -15,10 +15,10 @@ from unittest import mock import pytest import cmd2 -from cmd2 import Cmd, Cmd2TestCase, set_posix_shlex, set_strip_quotes -from conftest import run_cmd, StdOut, normalize +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 @@ class CmdLineApp(Cmd): 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 @@ now: ---> 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() |