summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTING.md2
-rwxr-xr-xcmd2/AutoCompleter.py (renamed from AutoCompleter.py)2
-rw-r--r--cmd2/__init__.py5
-rwxr-xr-xcmd2/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.rst4
-rwxr-xr-xexamples/tab_autocompletion.py3
-rwxr-xr-xsetup.py2
-rw-r--r--tests/__init__.py4
-rw-r--r--tests/test_acargparse.py20
-rw-r--r--tests/test_argparse.py2
-rw-r--r--tests/test_autocompletion.py4
-rw-r--r--tests/test_cmd2.py20
-rw-r--r--tests/test_parsing.py36
-rw-r--r--tests/test_submenu.py2
-rw-r--r--tests/test_transcript.py12
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
diff --git a/cmd2.py b/cmd2/cmd2.py
index bdf8c95c..34f3dfc5 100755
--- a/cmd2.py
+++ b/cmd2/cmd2.py
@@ -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):
diff --git a/setup.py b/setup.py
index e90f49d6..3020cf24 100755
--- a/setup.py
+++ b/setup.py
@@ -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()