diff --git a/LICENSE b/LICENSE index 8c1b5843b..cf873f443 100644 --- a/LICENSE +++ b/LICENSE @@ -16,4 +16,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file +THE SOFTWARE. diff --git a/README.rst b/README.rst index 859c879c4..8c1b65721 100644 --- a/README.rst +++ b/README.rst @@ -193,5 +193,3 @@ Colors and Styles colors.rgb(18, 146, 64) | "or full rgb colors", 'can be used.') print("Unsafe " + colors.bg.dark_khaki + "color access" + colors.bg.reset + " is available too.") - - diff --git a/conda.recipe/.gitignore b/conda.recipe/.gitignore index ccaabea19..a6a200688 100644 --- a/conda.recipe/.gitignore +++ b/conda.recipe/.gitignore @@ -4,4 +4,3 @@ /win-32/* /win-64/* /outputdir/* - diff --git a/conda.recipe/README.mkd b/conda.recipe/README.mkd index 6c54d5685..def3a461e 100644 --- a/conda.recipe/README.mkd +++ b/conda.recipe/README.mkd @@ -31,5 +31,3 @@ anaconda login for f in `ls outputdir/*/*.tar.bz2`; do anaconda upload $f; done anaconda logout ``` - - diff --git a/conda.recipe/bld.bat b/conda.recipe/bld.bat index f77970c6d..c40a9bbef 100644 --- a/conda.recipe/bld.bat +++ b/conda.recipe/bld.bat @@ -1,3 +1,2 @@ "%PYTHON%" setup.py install if errorlevel 1 exit 1 - diff --git a/conda.recipe/build.sh b/conda.recipe/build.sh index b161f631b..8e25a1455 100644 --- a/conda.recipe/build.sh +++ b/conda.recipe/build.sh @@ -1,4 +1,3 @@ #!/bin/bash $PYTHON setup.py install - diff --git a/conda.recipe/meta.yaml b/conda.recipe/meta.yaml index 43e318e17..03d5de4ab 100644 --- a/conda.recipe/meta.yaml +++ b/conda.recipe/meta.yaml @@ -42,4 +42,3 @@ about: home: https://plumbum.readthedocs.io license: MIT License summary: 'Plumbum: shell combinators library' - diff --git a/docs/_cheatsheet.rst b/docs/_cheatsheet.rst index 1225800c7..7334b049f 100644 --- a/docs/_cheatsheet.rst +++ b/docs/_cheatsheet.rst @@ -14,9 +14,9 @@ Basics >>> notepad() # Notepad window pops up u'' # Notepad window is closed by user, command returns -Instead of writing ``xxx = local["xxx"]`` for every program you wish to use, you can +Instead of writing ``xxx = local["xxx"]`` for every program you wish to use, you can also :ref:`import commands `: - + >>> from plumbum.cmd import grep, wc, cat, head >>> grep LocalCommand() @@ -36,7 +36,7 @@ Piping ------ .. code-block:: python - + >>> chain = ls["-a"] | grep["-v", "\\.py"] | wc["-l"] >>> print chain /bin/ls -a | /bin/grep -v '\.py' | /usr/bin/wc -l @@ -63,7 +63,7 @@ Working-directory manipulation ------------------------------ .. code-block:: python - + >>> local.cwd >>> with local.cwd(local.cwd / "docs"): @@ -74,7 +74,7 @@ Working-directory manipulation A more explicit, and thread-safe way of running a command in a differet directory is using the ``.with_cwd()`` method: .. code-block:: python - + >>> ls_in_docs = local.cmd.ls.with_cwd("docs") >>> ls_in_docs() 'api\nchangelog.rst\n_cheatsheet.rst\ncli.rst\ncolorlib.rst\n_color_list.html\ncolors.rst\nconf.py\nindex.rst\nlocal_commands.rst\nlocal_machine.rst\nmake.bat\nMakefile\n_news.rst\npaths.rst\nquickref.rst\nremote.rst\n_static\n_templates\ntyped_env.rst\nutils.rst\n' @@ -98,7 +98,7 @@ See :ref:`guide-local-commands-bgfg`. Command nesting ---------------- +--------------- .. code-block:: python @@ -106,7 +106,7 @@ Command nesting >>> print sudo[ifconfig["-a"]] /usr/bin/sudo /sbin/ifconfig -a >>> (sudo[ifconfig["-a"]] | grep["-i", "loop"]) & FG - lo Link encap:Local Loopback + lo Link encap:Local Loopback UP LOOPBACK RUNNING MTU:16436 Metric:1 @@ -115,7 +115,7 @@ See :ref:`guide-local-commands-nesting`. Remote commands (over SSH) -------------------------- -Supports `openSSH `_-compatible clients, +Supports `openSSH `_-compatible clients, `PuTTY `_ (on Windows) and `Paramiko `_ (a pure-Python implementation of SSH2) diff --git a/docs/_news.rst b/docs/_news.rst index 27ef6b1b9..a61fd6d36 100644 --- a/docs/_news.rst +++ b/docs/_news.rst @@ -21,4 +21,3 @@ * **2015.10.16**: Version 1.6.0 released. Highlights include Python 3.5 compatibility, the ``plumbum.colors`` package, ``Path`` becoming a subclass of ``str`` and a host of bugfixes. Special thanks go to Henry for his efforts. * **2015.07.17**: Version 1.5.0 released. This release brings a host of bug fixes, code cleanups and some experimental new features (be sure to check the changelog). Also, say hi to `Henry Schreiner `_, who has joined as a member of the project. - diff --git a/docs/api/commands.rst b/docs/api/commands.rst index 112015c3d..9ee34f852 100644 --- a/docs/api/commands.rst +++ b/docs/api/commands.rst @@ -13,7 +13,7 @@ Package plumbum.commands .. automodule:: plumbum.commands.modifiers :members: :special-members: - + .. automodule:: plumbum.commands.processes :members: :special-members: diff --git a/docs/api/machines.rst b/docs/api/machines.rst index ea25dbf7d..d4272c602 100644 --- a/docs/api/machines.rst +++ b/docs/api/machines.rst @@ -31,9 +31,3 @@ Remote Machines .. automodule:: plumbum.machines.paramiko_machine :members: :special-members: - - - - - - diff --git a/docs/cli.rst b/docs/cli.rst index 3fa8fadc4..4cd45cd52 100644 --- a/docs/cli.rst +++ b/docs/cli.rst @@ -3,9 +3,9 @@ Command-Line Interface (CLI) ============================ -The other side of *executing programs* with ease is **writing CLI programs** with ease. -Python scripts normally use ``optparse`` or the more recent ``argparse``, and their -`derivatives `_; but all of these are somewhat +The other side of *executing programs* with ease is **writing CLI programs** with ease. +Python scripts normally use ``optparse`` or the more recent ``argparse``, and their +`derivatives `_; but all of these are somewhat limited in their expressive power, and are quite **unintuitive** (and even **unpythonic**). Plumbum's CLI toolkit offers a **programmatic approach** to building command-line applications; instead of creating a parser object and populating it with a series of "options", the CLI toolkit @@ -13,20 +13,20 @@ translates these primitives into Pythonic constructs and relies on introspection From a bird's eye view, CLI applications are classes that extend :class:`plumbum.cli.Application`. They define a ``main()`` method and optionally expose methods and attributes as command-line -:func:`switches `. Switches may take arguments, and any remaining positional +:func:`switches `. Switches may take arguments, and any remaining positional arguments are given to the ``main`` method, according to its signature. A simple CLI application might look like this:: from plumbum import cli - + class MyApp(cli.Application): verbose = cli.Flag(["v", "verbose"], help = "If given, I will be very talkative") - + def main(self, filename): print("I will now read {0}".format(filename)) if self.verbose: print("Yadda " * 200) - + if __name__ == "__main__": MyApp.run() @@ -34,15 +34,15 @@ And you can run it:: $ python example.py foo I will now read foo - + $ python example.py --help example.py v1.0 - + Usage: example.py [SWITCHES] filename Meta-switches: -h, --help Prints this help message and quits --version Prints the program's version and quits - + Switches: -v, --verbose If given, I will be very talkative @@ -64,13 +64,13 @@ command-line, all you have to do is :: if __name__ == "__main__": MyApp.run() -Aside from ``run()`` and ``main()``, the ``Application`` class exposes two built-in switch +Aside from ``run()`` and ``main()``, the ``Application`` class exposes two built-in switch functions: ``help()`` and ``version()`` which take care of displaying the help and program's -version, respectively. By default, ``--help`` and ``-h`` invoke ``help()``, and ``--version`` +version, respectively. By default, ``--help`` and ``-h`` invoke ``help()``, and ``--version`` and ``-v`` invoke ``version()``; if any of these functions is called, the application will display the message and quit (without processing any other switch). -You can customize the information displayed by ``help()`` and ``version`` by defining +You can customize the information displayed by ``help()`` and ``version`` by defining class-level attributes, such as ``PROGNAME``, ``VERSION`` and ``DESCRIPTION``. For instance, :: class MyApp(cli.Application): @@ -80,7 +80,7 @@ class-level attributes, such as ``PROGNAME``, ``VERSION`` and ``DESCRIPTION``. F Colors ^^^^^^ .. versionadded:: 1.6 - + Colors are supported. You can use a colored string on ``PROGNAME``, ``VERSION`` and ``DESCRIPTION`` directly. If you set ``PROGNAME`` to a color, you can get auto-naming and color. The color of the usage string is available as ``COLOR_USAGE``, and the different groups can be colored with a @@ -100,9 +100,9 @@ For instance, the following is valid::
     SimpleColorCLI.py 1.0.2
-    
+
     Usage:
-        SimpleColorCLI.py [SWITCHES] 
+        SimpleColorCLI.py [SWITCHES]
 
     Meta-switches
         -h, --help         Prints this help message and quits
@@ -117,7 +117,7 @@ For instance, the following is valid::
 
 Switch Functions
 ----------------
-The decorator :func:`switch ` can be seen as the "heart and soul" of the 
+The decorator :func:`switch ` can be seen as the "heart and soul" of the
 CLI toolkit; it exposes methods of your CLI application as CLI-switches, allowing them to be
 invoked from the command line. Let's examine the following toy application::
 
@@ -128,39 +128,39 @@ invoked from the command line. Let's examine the following toy application::
         def log_to_file(self, filename):
             """Sets the file into which logs will be emitted"""
             logger.addHandler(FileHandle(filename))
-    
+
         @cli.switch(["-r", "--root"])
         def allow_as_root(self):
             """If given, allow running as root"""
             self._allow_root = True
-    
+
         def main(self):
             if os.geteuid() == 0 and not self._allow_root:
                 raise ValueError("cannot run as root")
 
 When the program is run, the switch functions are invoked with their appropriate arguments;
-for instance, ``$ ./myapp.py --log-to-file=/tmp/log`` would translate to a call to 
+for instance, ``$ ./myapp.py --log-to-file=/tmp/log`` would translate to a call to
 ``app.log_to_file("/tmp/log")``. After all switches were processed, control passes to ``main``.
 
 .. note::
    Methods' docstrings and argument names will be used to render the help message, keeping your
    code as `DRY `_ as possible.
-   
+
    There's also :func:`autoswitch `, which infers the name of the switch
    from the function's name, e.g. ::
-        
+
         @cli.autoswitch(str)
         def log_to_file(self, filename):
             pass
-   
+
    Will bind the switch function to ``--log-to-file``.
 
 Arguments
 ^^^^^^^^^
-As demonstrated in the example above, switch functions may take no arguments (not counting 
-``self``) or a single argument argument. If a switch function accepts an argument, it must 
-specify the argument's *type*. If you require no special validation, simply pass ``str``; 
-otherwise, you may pass any type (or any callable, in fact) that will take a string and convert 
+As demonstrated in the example above, switch functions may take no arguments (not counting
+``self``) or a single argument argument. If a switch function accepts an argument, it must
+specify the argument's *type*. If you require no special validation, simply pass ``str``;
+otherwise, you may pass any type (or any callable, in fact) that will take a string and convert
 it to a meaningful object. If conversion is not possible, the type (or callable) is expected to
 raise either ``TypeError`` or ``ValueError``.
 
@@ -168,11 +168,11 @@ For instance ::
 
     class MyApp(cli.Application):
         _port = 8080
-        
+
         @cli.switch(["-p"], int)
         def server_port(self, port):
             self._port = port
-        
+
         def main(self):
             print(self._port)
 
@@ -182,25 +182,25 @@ For instance ::
     17
     $ ./example.py -p foo
     Argument of -p expected to be , not 'foo':
-        ValueError("invalid literal for int() with base 10: 'foo'",)    
+        ValueError("invalid literal for int() with base 10: 'foo'",)
 
 The toolkit includes two additional "types" (or rather, *validators*): ``Range`` and ``Set``.
-``Range`` takes a minimal value and a maximal value and expects an integer in that range 
-(inclusive). ``Set`` takes a set of allowed values, and expects the argument to match one of 
-these values. Here's an example ::  
+``Range`` takes a minimal value and a maximal value and expects an integer in that range
+(inclusive). ``Set`` takes a set of allowed values, and expects the argument to match one of
+these values. Here's an example ::
 
     class MyApp(cli.Application):
         _port = 8080
         _mode = "TCP"
-        
+
         @cli.switch("-p", cli.Range(1024,65535))
         def server_port(self, port):
             self._port = port
-        
+
         @cli.switch("-m", cli.Set("TCP", "UDP", case_sensitive = False))
         def server_mode(self, mode):
             self._mode = mode
-        
+
         def main(self):
             print(self._port, self._mode)
 
@@ -214,8 +214,8 @@ these values. Here's an example ::
         ValueError("Expected one of ['UDP', 'TCP']",)
 
 .. note::
-   The toolkit also provides some other useful validators: `ExistingFile` (ensures the given 
-   argument is an existing file), `ExistingDirectory` (ensures the given argument is an existing 
+   The toolkit also provides some other useful validators: `ExistingFile` (ensures the given
+   argument is an existing file), `ExistingDirectory` (ensures the given argument is an existing
    directory), and `NonexistentPath` (ensures the given argument is not an existing path).
    All of these convert the argument to a :ref:`local path `.
 
@@ -229,11 +229,11 @@ only be given once, unless you allow multiple occurrences by passing ``list = Tr
 
     class MyApp(cli.Application):
         _dirs = []
-        
+
         @cli.switch("-I", str, list = True)
         def include_dirs(self, dirs):
             self._dirs = dirs
-        
+
         def main(self):
             print(self._dirs)
 
@@ -247,23 +247,23 @@ only be given once, unless you allow multiple occurrences by passing ``list = Tr
 
 Mandatory Switches
 ^^^^^^^^^^^^^^^^^^
-If a certain switch is required, you can specify this by passing ``mandatory = True`` to the 
+If a certain switch is required, you can specify this by passing ``mandatory = True`` to the
 ``switch`` decorator. The user will not be able to run the program without specifying a value
 for this switch.
 
 Dependencies
 ^^^^^^^^^^^^
-Many time, the occurrence of a certain switch depends on the occurrence of another, e..g, it 
+Many time, the occurrence of a certain switch depends on the occurrence of another, e..g, it
 may not be possible to give ``-x`` without also giving ``-y``. This constraint can be achieved
 by specifying the ``requires`` keyword argument to the ``switch`` decorator; it is a list
 of switch names that this switch depends on. If the required switches are missing, the user
-will not be able to run the program. :: 
+will not be able to run the program. ::
 
     class MyApp(cli.Application):
         @cli.switch("--log-to-file", str)
         def log_to_file(self, filename):
             logger.addHandler(logging.FileHandler(filename))
-    
+
         @cli.switch("--verbose", requires = ["--log-to-file"])
         def verbose(self):
             logger.setLevel(logging.DEBUG)
@@ -288,11 +288,11 @@ it does not make sense to allow ``--verbose`` and ``--terse``. For this purpose,
         @cli.switch("--log-to-file", str)
         def log_to_file(self, filename):
             logger.addHandler(logging.FileHandler(filename))
-    
+
         @cli.switch("--verbose", requires = ["--log-to-file"], excludes = ["--terse"])
         def verbose(self):
             logger.setLevel(logging.DEBUG)
-        
+
         @cli.switch("--terse", requires = ["--log-to-file"], excludes = ["--verbose"])
         def terse(self):
             logger.setLevel(logging.WARNING)
@@ -304,7 +304,7 @@ it does not make sense to allow ``--verbose`` and ``--terse``. For this purpose,
 
 Grouping
 ^^^^^^^^
-If you wish to group certain switches together in the help message, you can specify 
+If you wish to group certain switches together in the help message, you can specify
 ``group = "Group Name"``, where ``Group Name`` is any string. When the help message is rendered,
 all the switches that belong to the same group will be grouped together. Note that grouping has
 no other effects on the way switches are processed, but it can help improve the readability of
@@ -312,9 +312,9 @@ the help message.
 
 Switch Attributes
 -----------------
-Many times it's desired to simply store a switch's argument in an attribute, or set a flag if 
-a certain switch is given. For this purpose, the toolkit provides 
-:class:`SwitchAttr `, which is `data descriptor 
+Many times it's desired to simply store a switch's argument in an attribute, or set a flag if
+a certain switch is given. For this purpose, the toolkit provides
+:class:`SwitchAttr `, which is `data descriptor
 `_ that stores the argument in an instance attribute.
 There are two additional "flavors" of ``SwitchAttr``: ``Flag`` (which toggles its default value
 if the switch is given) and ``CountOf`` (which counts the number of occurrences of the switch)
@@ -324,7 +324,7 @@ if the switch is given) and ``CountOf`` (which counts the number of occurrences
         log_file = cli.SwitchAttr("--log-file", str, default = None)
         enable_logging = cli.Flag("--no-log", default = True)
         verbosity_level = cli.CountOf("-v")
-        
+
         def main(self):
             print(self.log_file, self.enable_logging, self.verbosity_level)
 
@@ -354,7 +354,7 @@ For example::
 
 Giving the switch on the command line will override the environment variable value.
 
-    
+
 
 Main
 ----
@@ -362,7 +362,7 @@ Main
 The ``main()`` method takes control once all the command-line switches have been processed.
 It may take any number of *positional argument*; for instance, in ``cp -r /foo /bar``,
 ``/foo`` and ``/bar`` are the *positional arguments*. The number of positional arguments
-that the program would accept depends on the signature of the method: if the method takes 5 
+that the program would accept depends on the signature of the method: if the method takes 5
 arguments, 2 of which have default values, then at least 3 positional arguments must be supplied
 by the user and at most 5. If the method also takes varargs (``*args``), the number of
 arguments that may be given is unbound ::
@@ -384,7 +384,7 @@ arguments that may be given is unbound ::
 
 .. note::
    The method's signature is also used to generate the help message, e.g. ::
-    
+
         Usage:  [SWITCHES] src dst [mode='normal']
 
 With varargs::
@@ -423,7 +423,7 @@ specify the validators. For example::
         "Identical to above MyApp"
 
 Annotations are ignored if the positional decorator is present.
-    
+
 Switch Abbreviations
 ^^^^^^^^^^^^^^^^^^^^
 
@@ -456,36 +456,36 @@ Sub-commands
 
 A common practice of CLI applications, as they span out and get larger, is to split their
 logic into multiple, pluggable *sub-applications* (or *sub-commands*). A classic example is version
-control systems, such as `git `_, where ``git`` is the *root* command, 
+control systems, such as `git `_, where ``git`` is the *root* command,
 under which sub-commands such as ``commit`` or ``push`` are nested. Git even supports ``alias``-ing,
-which creates allows users to create custom sub-commands. Plumbum makes writing such applications 
+which creates allows users to create custom sub-commands. Plumbum makes writing such applications
 really easy.
 
 Before we get to the code, it is important to stress out two things:
 
 * Under Plumbum, each sub-command is a full-fledged ``cli.Application`` on its own; if you wish,
   you can execute it separately, detached from its so-called root application. When an application
-  is run independently, its ``parent`` attribute is ``None``; when it is run as a sub-command, 
-  its ``parent`` attribute points to its parent application. Likewise, when an parent application 
+  is run independently, its ``parent`` attribute is ``None``; when it is run as a sub-command,
+  its ``parent`` attribute points to its parent application. Likewise, when an parent application
   is executed with a sub-command, its ``nested_command`` is set to the nested application; otherwise
   it's ``None``.
 
-* Each sub-command is responsible of **all** arguments that follow it (up to the next sub-command). 
+* Each sub-command is responsible of **all** arguments that follow it (up to the next sub-command).
   This allows applications to process their own switches and positional arguments before the nested
   application is invoked. Take, for instance, ``git --foo=bar spam push origin --tags``: the root
   application, ``git``, is in charge of the switch ``--foo`` and the positional argument ``spam``,
-  and the nested application ``push`` is in charge of the arguments that follow it. In theory, 
+  and the nested application ``push`` is in charge of the arguments that follow it. In theory,
   you can nest several sub-applications one into the other; in practice, only a single level
   is normally used.
 
 Here is an example of a mock version control system, called ``geet``. We're going to have a root
-application ``Geet``, which has two sub-commands - ``GeetCommit`` and ``GeetPush``: these are 
+application ``Geet``, which has two sub-commands - ``GeetCommit`` and ``GeetPush``: these are
 attached to the root application using the ``subcommand`` decorator ::
-    
+
     class Geet(cli.Application):
         """The l33t version control"""
         VERSION = "1.7.2"
-        
+
         def main(self, *args):
             if args:
                 print("Unknown command {0!r}".format(args[0]))
@@ -497,7 +497,7 @@ attached to the root application using the ``subcommand`` decorator ::
     @Geet.subcommand("commit")                    # attach 'geet commit'
     class GeetCommit(cli.Application):
         """creates a new commit in the current branch"""
-        
+
         auto_add = cli.Flag("-a", help = "automatically add changed files")
         message = cli.SwitchAttr("-m", str, mandatory = True, help = "sets the commit message")
 
@@ -514,7 +514,7 @@ attached to the root application using the ``subcommand`` decorator ::
         Geet.run()
 
 .. note::
-    * Since ``GeetCommit`` is a ``cli.Application`` on its own right, you may invoke 
+    * Since ``GeetCommit`` is a ``cli.Application`` on its own right, you may invoke
       ``GeetCommit.run()`` directly (should that make sense in the context of your application)
     * You can also attach sub-commands "imperatively", using ``subcommand`` as a method instead
       of a decorator: ``Geet.subcommand("push", GeetPush)``
@@ -524,31 +524,31 @@ Here's an example of running this application::
     $ python geet.py --help
     geet v1.7.2
     The l33t version control
-    
+
     Usage: geet.py [SWITCHES] [SUBCOMMAND [SWITCHES]] args...
     Meta-switches:
         -h, --help                 Prints this help message and quits
         -v, --version              Prints the program's version and quits
-    
+
     Subcommands:
         commit                     creates a new commit in the current branch; see
                                    'geet commit --help' for more info
         push                       pushes the current local branch to the remote
                                    one; see 'geet push --help' for more info
-    
+
     $ python geet.py commit --help
     geet commit v1.7.2
     creates a new commit in the current branch
-    
+
     Usage: geet commit [SWITCHES]
     Meta-switches:
         -h, --help                 Prints this help message and quits
         -v, --version              Prints the program's version and quits
-    
+
     Switches:
         -a                         automatically add changed files
         -m VALUE:str               sets the commit message; required
-    
+
     $ python geet.py commit -m "foo"
     committing...
 
@@ -595,7 +595,7 @@ A command line image plotter (``Image``) is provided in ``plumbum.cli.image``. I
     Image().show_pil(im)
 
 The Image constructor can take an optional size (defaults to the current terminal size if None), and a `char_ratio`, a height to width measure for your current font. It defaults to a common value of 2.45. If set to None, the ratio is ignored and the image will no longer be constrained to scale proportionately. To directly plot an image, the ``show`` method takes a filename and a double parameter, which doubles the vertical resolution on some fonts. The `show_pil` and `show_pil_double`
-methods directly take a PIL-like object. To plot an image from the command line,  
+methods directly take a PIL-like object. To plot an image from the command line,
 the module can be run directly: ``python -m plumbum.cli.image myimage.png``.
 
 For the full list of helpers or more information, see the :ref:`api docs `.
@@ -605,12 +605,9 @@ For the full list of helpers or more information, see the :ref:`api docs `_ example
-* `geet.py `_ - a runnable 
+* `geet.py `_ - a runnable
   example of using sub-commands
 * `RPyC `_ has changed it bash-based build script to Plumbum CLI.
   Notice `how short and readable `_
   it is.
 * A `blog post `_ describing the philosophy of the CLI module
-
-
-
diff --git a/docs/colorlib.rst b/docs/colorlib.rst
index 04192a67c..d6138c1fd 100644
--- a/docs/colorlib.rst
+++ b/docs/colorlib.rst
@@ -42,7 +42,7 @@ The ``colors`` object has the following available objects:
     ``do_nothing``
       Does nothing at all, but otherwise acts like any ``Style`` object. It is its own inverse. Useful for ``cli`` properties.
 
-The ``colors`` object can be used in a with statement, which resets all styles on leaving 
+The ``colors`` object can be used in a with statement, which resets all styles on leaving
 the statement body. Although factories do support
 some of the same methods as a Style, their primary purpose is to generate Styles. The colors object has a
 ``use_color`` property that can be set to force the use of color. A ``stdout`` property is provided
@@ -69,13 +69,13 @@ Full hex codes can be used, too. If no match is found,
 these will be the true 24 bit color value.
 
 The ``fg`` and ``bg`` also can be put in with statements, and they
-will restore the foreground and background color only, respectively. 
+will restore the foreground and background color only, respectively.
 
 ``colors.rgb(r,g,b)`` will create a color from an
 input red, green, and blue values (integers from 0-255). ``colors.rgb(code)`` will allow
 you to input an html style hex sequence. These work on ``fg`` and ``bg`` too. The ``repr`` of
 styles is smart and will show you the closest color to the one you selected if you didn't exactly
-select a color through RGB. 
+select a color through RGB.
 
 Style manipulations
 ===================
@@ -118,13 +118,13 @@ An example of the usage of unsafe ``colors`` manipulations inside a context mana
         print('This is in red')
         colors.green.now()
         print('This is green ' + colors.underline + 'and now also underlined!')
-        print('Underlined' + colors.underline.reset + ' and not underlined but still red') 
+        print('Underlined' + colors.underline.reset + ' and not underlined but still red')
     print('This is completly restored, even if an exception is thrown!')
 
 Output:
 
   .. raw:: html
-    
+
     

This is in red
This is in green and now also underlined!
Underlined and not underlined but still green.
@@ -210,7 +210,7 @@ If you want to enforce a specific representation, you can use ``.basic`` (8 colo the output representation and name of the best match color. The internal RGB colors are remembered, so this is a non-destructive operation. -To limit the use of color to one of these styles, set ``colors.use_color`` to 1 for 8 colors, 2 for 16 colors, +To limit the use of color to one of these styles, set ``colors.use_color`` to 1 for 8 colors, 2 for 16 colors, 3 for 256 colors, or 4 for true color. It will be guessed based on your system on initialisation. The Classes @@ -254,7 +254,7 @@ For example, if you wanted to create an HTMLStyle and HTMLcolors, you could do:: for attr in sorted(self.attributes): if self.attributes[attr]: result += '<' + self.attribute_names[attr] + '>' - + for attr in reversed(sorted(self.attributes)): if not self.attributes[attr]: result += '' @@ -266,7 +266,7 @@ For example, if you wanted to create an HTMLStyle and HTMLcolors, you could do:: return result htmlcolors = StyleFactory(HTMLStyle) - + This doesn't support global resets, since that's not how HTML works, but otherwise is a working implementation. This is an example of how easy it is to add support for other output formats. An example of usage:: @@ -285,7 +285,7 @@ The above color table can be generated with:: .. note:: - + ``HTMLStyle`` is implemented in the library, as well, with the ``htmlcolors`` object available in ``plumbum.colorlib``. It was used to create the colored output in this document, with small changes diff --git a/docs/colors.rst b/docs/colors.rst index cc8b9935a..9989db973 100644 --- a/docs/colors.rst +++ b/docs/colors.rst @@ -8,7 +8,7 @@ Colors The purpose of the `plumbum.colors` library is to make adding text styles (such as color) to Python easy and safe. Color is often a great -addition to shell scripts, but not a necessity, and implementing it properly +addition to shell scripts, but not a necessity, and implementing it properly is tricky. It is easy to end up with an unreadable color stuck on your terminal or with random unreadable symbols around your text. With the color module, you get quick, safe access to ANSI colors and attributes for your scripts. The module also provides an @@ -46,7 +46,7 @@ To create a custom style you would do print(colors.green & colors.bold | "This is green and bold.") .. raw:: html - + This is green and bold. You can use rgb colors, too: @@ -75,7 +75,7 @@ Styles are accessed through the ``plumbum.colors`` object. This has the followin The global reset will restore all properties at once. ``do_nothing`` Does nothing at all, but otherwise acts like any ``Style`` object. It is its own inverse. Useful for ``cli`` properties. - + Styles loaded from a stylesheet dictionary, such as ``warn`` and ``info``. These allow you to set standard styles based on behavior rather than colors, and you can load a new stylesheet with ``colors.load_stylesheet(...)``. @@ -93,8 +93,8 @@ Recreating and loading the default stylesheet would look like this: ... success="fg green") >>> colors.load_stylesheet(default_styles) - - + + The ``colors.from_ansi(code)`` method allows you to create a Style from any ansi sequence, even complex or combined ones. @@ -108,7 +108,7 @@ directly as methods. The first 16 primary colors, ``black``, ``red``, ``green``, ``blue``, ``magenta``, ``cyan``, etc, as well as ``reset``, are available. All 256 color names are available, but do not populate directly, so that auto-completion gives reasonable results. You can also access colors using strings and do ``colors.fg[string]``. -Capitalization, underscores, and spaces (for strings) will be ignored. +Capitalization, underscores, and spaces (for strings) will be ignored. You can also access colors numerically with ``colors.fg[n]`` for the extended 256 color codes. ``colors.fg.rgb(r,g,b)`` will create a color from an @@ -193,7 +193,7 @@ An example of the usage of unsafe ``colors`` manipulations inside a context mana with colors: colors.fg.red.now() print('This is in red') .. raw:: html - +

This is in red
This is in green and now also underlined!
Underlined and not underlined but still green.
@@ -201,13 +201,13 @@ An example of the usage of unsafe ``colors`` manipulations inside a context mana colors.green.now() print('This is green ' + colors.underline + 'and now also underlined!') - print('Underlined' + colors.underline.reset + ' and not underlined but still red') + print('Underlined' + colors.underline.reset + ' and not underlined but still red') print('This is completly restored, even if an exception is thrown!') Output: .. raw:: html - +

This is in red
This is in green and now also underlined!
Underlined and not underlined but still green.
diff --git a/docs/index.rst b/docs/index.rst index c8446af9a..810eaa972 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -16,11 +16,11 @@ Tomer Filiba
-
- @@ -29,33 +29,33 @@ Plumbum: Shell Combinators and More .. comment raw:: html -

- + Sticky
- - Version 3.2.3 + + Version 3.2.3 was released on December 2nd
- - Please use the - mailing list - to ask questions and use - github issues + + Please use the + mailing list + to ask questions and use + github issues to report problems. Please do not email me directly. - +
-Ever wished the compactness of shell scripts be put into a **real** programming language? -Say hello to *Plumbum Shell Combinators*. Plumbum (Latin for *lead*, which was used to create -pipes back in the day) is a small yet feature-rich library for shell script-like programs in Python. -The motto of the library is **"Never write shell scripts again"**, and thus it attempts to mimic -the **shell syntax** (*shell combinators*) where it makes sense, while keeping it all **Pythonic +Ever wished the compactness of shell scripts be put into a **real** programming language? +Say hello to *Plumbum Shell Combinators*. Plumbum (Latin for *lead*, which was used to create +pipes back in the day) is a small yet feature-rich library for shell script-like programs in Python. +The motto of the library is **"Never write shell scripts again"**, and thus it attempts to mimic +the **shell syntax** (*shell combinators*) where it makes sense, while keeping it all **Pythonic and cross-platform**. -Apart from :ref:`shell-like syntax ` and :ref:`handy shortcuts `, -the library provides local and :ref:`remote ` command execution (over SSH), -local and remote file-system :ref:`paths `, easy working-directory and -environment :ref:`manipulation `, quick access to ANSI :ref:`colors `, and a programmatic +Apart from :ref:`shell-like syntax ` and :ref:`handy shortcuts `, +the library provides local and :ref:`remote ` command execution (over SSH), +local and remote file-system :ref:`paths `, easy working-directory and +environment :ref:`manipulation `, quick access to ANSI :ref:`colors `, and a programmatic :ref:`guide-cli` application toolkit. Now let's see some code! News @@ -74,44 +74,44 @@ Cheat Sheet Development and Installation ============================ -The library is developed on `GitHub `_, and will happily -accept `patches `_ from users. Please use the GitHub's -built-in `issue tracker `_ to report any problem -you encounter or to request features. The library is released under the permissive `MIT license +The library is developed on `GitHub `_, and will happily +accept `patches `_ from users. Please use the GitHub's +built-in `issue tracker `_ to report any problem +you encounter or to request features. The library is released under the permissive `MIT license `_. Requirements ------------ -Plumbum supports **Python 2.6-3.7** and **PyPy** and is continually +Plumbum supports **Python 2.6-3.7** and **PyPy** and is continually tested on **Linux**, **Mac**, and **Windows** machines through `Travis CI `_ -and `Appveyor `_. +and `Appveyor `_. Any Unix-like machine should work fine out of the box, -but on Windows, you'll probably want to install a decent `coreutils `_ -environment and add it to your ``PATH``. I can recommend `mingw `_ (which comes -bundled with `Git for Windows `_), but `cygwin `_ -should work too. If you only wish to use Plumbum as a Popen-replacement to run Windows programs, +but on Windows, you'll probably want to install a decent `coreutils `_ +environment and add it to your ``PATH``. I can recommend `mingw `_ (which comes +bundled with `Git for Windows `_), but `cygwin `_ +should work too. If you only wish to use Plumbum as a Popen-replacement to run Windows programs, then there's no need for the Unix tools. -Note that for remote command execution, an **openSSH-compatible** client is required (also bundled -with *Git for Windows*), and a ``bash``-compatible shell and a coreutils environment is also +Note that for remote command execution, an **openSSH-compatible** client is required (also bundled +with *Git for Windows*), and a ``bash``-compatible shell and a coreutils environment is also expected on the host machine. Download -------- -You can **download** the library from the `Python Package Index `_ +You can **download** the library from the `Python Package Index `_ (in a variety of formats), or run ``pip install plumbum`` directly. If you use Anaconda, you can also get it from the ``conda-forge`` channel with ``conda install -c conda-forge plumbum``. User Guide ========== -The user guide covers most of the features of Plumbum, with lots of code-snippets to get you -swimming in no time. It introduces the concepts and "syntax" gradually, so it's recommended +The user guide covers most of the features of Plumbum, with lots of code-snippets to get you +swimming in no time. It introduces the concepts and "syntax" gradually, so it's recommended you read it in order. A quick :ref:`reference guide is available `. .. toctree:: :maxdepth: 2 - + local_commands paths local_machine @@ -125,13 +125,13 @@ you read it in order. A quick :ref:`reference guide is available `_. When I combined the two with *shell combinators* (because shell scripts do have an edge there) the magic happened and here we are. Credits ======= -The project has been inspired by **PBS** (now called `sh `_) -of `Andrew Moffat `_, +The project has been inspired by **PBS** (now called `sh `_) +of `Andrew Moffat `_, and has borrowed some of his ideas (namely treating programs like functions and the -nice trick for importing commands). However, I felt there was too much magic going on in PBS, -and that the syntax wasn't what I had in mind when I came to write shell-like programs. -I contacted Andrew about these issues, but he wanted to keep PBS this way. Other than that, +nice trick for importing commands). However, I felt there was too much magic going on in PBS, +and that the syntax wasn't what I had in mind when I came to write shell-like programs. +I contacted Andrew about these issues, but he wanted to keep PBS this way. Other than that, the two libraries go in different directions, where Plumbum attempts to provide a more wholesome approach. -Plumbum also pays tribute to `Rotem Yaari `_ who suggested a +Plumbum also pays tribute to `Rotem Yaari `_ who suggested a library code-named ``pyplatform`` for that very purpose, but which had never materialized. diff --git a/docs/local_commands.rst b/docs/local_commands.rst index 19736dd35..d6718399d 100644 --- a/docs/local_commands.rst +++ b/docs/local_commands.rst @@ -61,14 +61,14 @@ With just a touch of magic, you can *import* commands from the mock module ``cmd .. note:: - There's no real module named ``plumbum.cmd``; it's a dynamically-created "module", injected + There's no real module named ``plumbum.cmd``; it's a dynamically-created "module", injected into ``sys.modules`` to enable the use of ``from plumbum.cmd import foo``. As of version 1.1, you can actually ``import plumbum.cmd``, for consistency, but it's not recommended. - + It is important to stress that ``from plumbum.cmd import foo`` translates to ``local["foo"]`` behind the scenes. -If underscores (``_``) appear in the name, and the name cannot be found in the path as-is, +If underscores (``_``) appear in the name, and the name cannot be found in the path as-is, the underscores will be replaced by hyphens (``-``) and the name will be looked up again. This allows you to import ``apt_get`` for ``apt-get``. @@ -89,8 +89,8 @@ You can think of bound commands as commands that "remember" their arguments. Cre command does not run the program; in order to run it, you'll need to call (invoke) it, like so: ``ls["-l"]()`` (in fact, ``ls["-l"]()`` is equivalent to ``ls("-l")``). -Now that we can bind arguments to commands, forming pipelines is easy and straight-forwards, -using ``|`` (bitwise-or):: +Now that we can bind arguments to commands, forming pipelines is easy and straight-forwards, +using ``|`` (bitwise-or):: >>> chain = ls["-l"] | grep[".py"] >>> print chain @@ -103,11 +103,11 @@ using ``|`` (bitwise-or):: Input/Output Redirection ------------------------ -We can also use redirection into files (or any object that exposes a real ``fileno()``). -If a string is given, it is assumed to be a file name, and a file with that name is opened +We can also use redirection into files (or any object that exposes a real ``fileno()``). +If a string is given, it is assumed to be a file name, and a file with that name is opened for you. In this example, we're reading from ``stdin`` into ``grep world``, and redirecting the output to a file named ``tmp.txt``:: - + >>> import sys >>> ((grep["world"] < sys.stdin) > "tmp.txt")() hello @@ -129,7 +129,7 @@ Lo and behold, the file was created:: >>> cat("tmp.txt") 'hello world\nwhat has the world become?\n' -If you need to send input into a program (through its ``stdin``), instead of writing the data +If you need to send input into a program (through its ``stdin``), instead of writing the data to a file and redirecting this file into ``stdin``, you can use the shortcut ``<<`` (shift-left):: >>> (cat << "hello world\nfoo\nbar\spam" | grep["oo"]) () @@ -146,13 +146,13 @@ If the command we're running fails (returns a non-zero exit code), we'll get an Command line: | /bin/cat non/existing.file Stderr: | /bin/cat: non/existing.file: No such file or directory -In order to avoid such exceptions, or when a different exit code is expected, just pass -``retcode = xxx`` as a keyword argument. If ``retcode`` is ``None``, no exception checking -is performed (any exit code is accepted); otherwise, the exit code is expected to match the +In order to avoid such exceptions, or when a different exit code is expected, just pass +``retcode = xxx`` as a keyword argument. If ``retcode`` is ``None``, no exception checking +is performed (any exit code is accepted); otherwise, the exit code is expected to match the one you passed:: >>> cat("non/existing.file", retcode = None) - '' + '' >>> cat("non/existing.file", retcode = 17) Traceback (most recent call last): [...] @@ -161,16 +161,16 @@ one you passed:: Stderr: | /bin/cat: non/existing.file: No such file or directory .. note:: - If you wish to accept several valid exit codes, ``retcode`` may be a tuple or a list. - For instance, ``grep("foo", "myfile.txt", retcode = (0, 2))`` - - If you need to have both the output/error and the exit code (using exceptions would provide either + If you wish to accept several valid exit codes, ``retcode`` may be a tuple or a list. + For instance, ``grep("foo", "myfile.txt", retcode = (0, 2))`` + + If you need to have both the output/error and the exit code (using exceptions would provide either but not both), you can use the `run` method, which will provide all of them - + >>> cat["non/existing.file"].run(retcode=None) (1, u'', u'/bin/cat: non/existing.file: No such file or directory\n') - + If you need the value of the exit code, there are two ways to do it. You can call ``.run(retcode=None)`` @@ -204,9 +204,9 @@ code, ``stdout``, and ``stderr``:: >>> ls.run("-a") (0, '.\n..\n.git\n.gitignore\n.project\n.pydevproject\nREADME.rst\nplumbum\[...]', '') -You can also pass ``retcode`` as a keyword argument to ``run`` in the same way discussed above. +You can also pass ``retcode`` as a keyword argument to ``run`` in the same way discussed above. -And, if you want to want to execute commands "in the background" (i.e., not wait for them to +And, if you want to want to execute commands "in the background" (i.e., not wait for them to finish), you can use the :func:`popen ` method, which returns a normal ``subprocess.Popen`` object:: @@ -221,8 +221,8 @@ You can read from its ``stdout``, ``wait()`` for it, ``terminate()`` it, etc. Background and Foreground ------------------------- In order to make programming easier, there are two special objects called ``FG`` and ``BG``, -which are there to help you. ``FG`` runs programs in the foreground (they receive the parent's -``stdin``, ``stdout`` and ``stderr``), and ``BG`` runs programs in the background (much like +which are there to help you. ``FG`` runs programs in the foreground (they receive the parent's +``stdin``, ``stdout`` and ``stderr``), and ``BG`` runs programs in the background (much like ``popen`` above, but it returns a :class:`Future ` object, instead of a ``subprocess.Popen`` one). ``FG`` is especially useful for interactive programs like editors, etc., that require a ``TTY`` or input from the user. :: @@ -235,8 +235,8 @@ like editors, etc., that require a ``TTY`` or input from the user. :: -rw-r--r-- 1 sebulba Administ 0 Apr 27 11:54 setup.py drwxr-xr-x 2 sebulba Administ 0 Apr 27 11:54 tests -rw-r--r-- 1 sebulba Administ 18 Apr 27 11:54 todo.txt - -.. note:: + +.. note:: The output of ``ls`` went straight to the screen :: @@ -270,26 +270,26 @@ If you want to redirect the input or output to something other than ``nohup.out` You can also use the ``TEE`` modifier, which causes output to be redirected to the screen (like ``FG``), but also provides access to the output (like ``BG``). .. _guide-local-commands-nesting: - + Command Nesting --------------- -The arguments of commands can be strings (or any object that can meaningfully-convert to a string), +The arguments of commands can be strings (or any object that can meaningfully-convert to a string), as we've seen above, but they can also be other **commands**! This allows nesting commands into one another, forming complex command objects. The classic example is ``sudo``:: >>> from plumbum.cmd import sudo >>> print sudo[ls["-l", "-a"]] /usr/bin/sudo /bin/ls -l -a - + >>> sudo[ls["-l", "-a"]]() u'total 22\ndrwxr-xr-x 8 sebulba Administ 4096 May 9 20:46 .\n[...]' -In fact, you can nest even command-chains (i.e., pipes and redirections), e.g., -``sudo[ls | grep["\\.py"]]``; however, that would require that the top-level program be able -to handle these shell operators, and this is not the case for ``sudo``. ``sudo`` expects its -argument to be an executable program, and it would complain about ``|`` not being one. +In fact, you can nest even command-chains (i.e., pipes and redirections), e.g., +``sudo[ls | grep["\\.py"]]``; however, that would require that the top-level program be able +to handle these shell operators, and this is not the case for ``sudo``. ``sudo`` expects its +argument to be an executable program, and it would complain about ``|`` not being one. So, there's a inherent differnce between between ``sudo[ls | grep["\\.py"]]`` -and ``sudo[ls] | grep["\\.py"]`` (where the pipe is unnested) -- the first would fail, +and ``sudo[ls] | grep["\\.py"]`` (where the pipe is unnested) -- the first would fail, the latter would work as expected. Some programs (mostly shells) will be able to handle pipes and redirections -- an example of @@ -297,18 +297,18 @@ such a program is ``ssh``. For instance, you could run ``ssh["somehost", ls | gr here, both ``ls`` and ``grep`` would run on ``somehost``, and only the filtered output would be sent (over SSH) to our machine. On the other hand, an invocation such as ``(ssh["somehost", ls] | grep["\\.py"])()`` would run ``ls`` on ``somehost``, send its entire -output to our machine, and ``grep`` would filter it locally. +output to our machine, and ``grep`` would filter it locally. -We'll learn more about remote command execution :ref:`later `. In the -meanwhile, we should learn that command nesting works by *shell-quoting* (or *shell-escaping*) +We'll learn more about remote command execution :ref:`later `. In the +meanwhile, we should learn that command nesting works by *shell-quoting* (or *shell-escaping*) the nested command. Quoting normally takes place from the second level of nesting:: >>> print ssh["somehost", ssh["anotherhost", ls | grep["\\.py"]]] /bin/ssh somehost /bin/ssh anotherhost /bin/ls '|' /bin/grep "'\\.py'" In this example, we first ssh to ``somehost``, from it we ssh to ``anotherhost``, and on that host -we run the command chain. As you can see, ``|`` and the backslashes have been quoted, to prevent -them from executing on the first-level shell; this way, they would safey get to the +we run the command chain. As you can see, ``|`` and the backslashes have been quoted, to prevent +them from executing on the first-level shell; this way, they would safey get to the second-level shell. For further information, see the :ref:`api docs `. diff --git a/docs/local_machine.rst b/docs/local_machine.rst index 397c2fbae..4923da955 100644 --- a/docs/local_machine.rst +++ b/docs/local_machine.rst @@ -3,9 +3,9 @@ The Local Object ================ So far we've only seen running local commands, but there's more to the ``local`` object than -this; it aims to "fully represent" the *local machine*. +this; it aims to "fully represent" the *local machine*. -First, you should get acquainted with ``which``, which performs program name resolution in +First, you should get acquainted with ``which``, which performs program name resolution in the system ``PATH`` and returns the first match (or raises an exception if no match is found):: >>> local.which("ls") @@ -15,7 +15,7 @@ the system ``PATH`` and returns the first match (or raises an exception if no ma [...] plumbum.commands.CommandNotFound: ('nonexistent', [...]) -Another member is ``python``, which is a command object that points to the current interpreter +Another member is ``python``, which is a command object that points to the current interpreter (``sys.executable``):: >>> local.python @@ -54,7 +54,7 @@ Finally, A more explicit and thread-safe way of running a command in a differet Environment ----------- -Much like ``cwd``, ``local.env`` represents the *local environment*. It is a dictionary-like +Much like ``cwd``, ``local.env`` represents the *local environment*. It is a dictionary-like object that holds **environment variables**, which you can get/set intuitively:: >>> local.env["JAVA_HOME"] @@ -84,7 +84,7 @@ it's own private copy of the environment:: | raise KeyError(key) from None | KeyError: 'FOO' -In order to make cross-platform-ness easier, the ``local.env`` object provides some convenience +In order to make cross-platform-ness easier, the ``local.env`` object provides some convenience properties for getting the username (``.user``), the home path (``.home``), and the executable path (``path``) as a list. For instance:: diff --git a/docs/paths.rst b/docs/paths.rst index dd975fe73..12c3724f4 100644 --- a/docs/paths.rst +++ b/docs/paths.rst @@ -41,7 +41,7 @@ You can use ``.with_suffix(suffix, depth=1)`` to replace the last ``depth`` suff If you specify None for the depth, it will replace all suffixes (for example, ``.tar.gz`` is two suffixes). Note that a name like ``file.name.10.15.tar.gz`` will have "5" suffixes. Also available is ``.with_name(name)``, which will will replace the entire name. -``preferred_suffix(suffix)`` will add a suffix if one does not exist (for default suffix situations). +``preferred_suffix(suffix)`` will add a suffix if one does not exist (for default suffix situations). Paths can be composed using ``/`` or ``[]``:: @@ -71,14 +71,14 @@ Paths also supply ``.iterdir()``, which may be faster on Python 3.5. Globing can be easily performed using ``//`` (floor division):: >>> p // "*.dll" - [, ...] + [, ...] >>> p // "*/*.dll" [, ...] >>> local.cwd / "docs" // "*.rst" [, ...] -.. versionadded:: 1.6 +.. versionadded:: 1.6 Globing a tuple will glob for each of the items in the tuple, and return the aggregated result. @@ -91,7 +91,7 @@ Files can be opened and read directly:: Support for treating a path exactly like a ``str``, so they can be used directly in ``open()``. -Paths also supply ``.delete()``, ``.copy(destination, override=False)``, and ``.move(destination)``. On systems that +Paths also supply ``.delete()``, ``.copy(destination, override=False)``, and ``.move(destination)``. On systems that support it, you can also use ``.symlink(destination)``, ``.link(destination)``, and ``.unlink()``. You can change permissions with ``.chmod(mode)``, and change owners with ``.chown(owner=None, group=None, recursive=None)``. If ``recursive`` is ``None``, this will be recursive only if the path is a directory. diff --git a/docs/quickref.rst b/docs/quickref.rst index 21a31004b..395bceaa4 100644 --- a/docs/quickref.rst +++ b/docs/quickref.rst @@ -14,7 +14,7 @@ Optional arguments ================ ========================= Utility Usage ================ ========================= -``Flag`` True or False descriptor +``Flag`` True or False descriptor ``SwitchAttr`` A value as a descriptor ``CountOf`` Counting version of ``Flag`` ``@switch`` A function that runs when passed @@ -42,7 +42,7 @@ Common options ************** ================== ============================ ================== -Option Used in Usage +Option Used in Usage ================== ============================ ================== First argument Non-auto The name, or list of names, includes dash(es) Second argument All The validator @@ -96,7 +96,7 @@ Subtraction Relative path Property Description Compare to Pathlib =================================================== =========================== ================== ``.name`` The file name ✓ -``.basename`` DEPRECATED +``.basename`` DEPRECATED ``.stem`` Name without extension ✓ ``.dirname`` Directory name ✗ ``.root`` The file tree root ✓ @@ -114,7 +114,7 @@ Property Description Missing: .anchor - + =================================================== =========================== ================== Method Description Compare to Pathlib @@ -197,5 +197,3 @@ Main colors: ``black`` ``red`` ``green`` ``yellow`` ``blue`` ``magenta`` ``cyan` Default styles: ``warn`` ``title`` ``fatal`` ``highlight`` ``info`` ``success`` Attrs: ``bold`` ``dim`` ``underline`` ``italics`` ``reverse`` ``strikeout`` ``hidden`` - - diff --git a/docs/remote.rst b/docs/remote.rst index 84e4fbef7..923633648 100644 --- a/docs/remote.rst +++ b/docs/remote.rst @@ -3,7 +3,7 @@ Remote ====== Just like running local commands, Plumbum supports running commands on remote systems, by executing -them over SSH. +them over SSH. .. _guide-remote-machines: @@ -23,7 +23,7 @@ Or as a context-manager:: .. note:: - ``SshMachine`` requires ``ssh`` (``openSSH`` or compatible) installed on your system in order + ``SshMachine`` requires ``ssh`` (``openSSH`` or compatible) installed on your system in order to connect to remote machines. The remote machine must have bash as the default shell (or any shell that supports the ``2>&1`` syntax for stderr redirection). Alternatively, you can use the pure-Python implementation of @@ -34,23 +34,23 @@ your ``id-rsa.pub`` key in its ``authorized_keys`` file, or if you've set up you to login with some user and ``keyfile``, you can simply use ``rem = SshMachine("hostname")``. Much like the :ref:`local object `, remote machines expose ``which()``, -``path()``, ``python``, ``cwd`` and ``env``. You can also run remote commands, create SSH tunnels, -upload/download files, etc. You may also refer to :class:`the full API +``path()``, ``python``, ``cwd`` and ``env``. You can also run remote commands, create SSH tunnels, +upload/download files, etc. You may also refer to :class:`the full API `, as this guide will only survey the features. .. note:: `PuTTY `_ users on Windows should use - the dedicated :class:`PuttyMachine ` instead of + the dedicated :class:`PuttyMachine ` instead of ``SshMachine``. See also :ref:`ParamikoMachine `. .. versionadded:: 1.0.1 Working Directory and Environment ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The ``cwd`` and ``env`` attributes represent the remote machine's working directory and environment -variables, respectively, and can be used to inspect or manipulate them. Much like their local -counterparts, they can be used as context managers, so their effects can be contained. :: +The ``cwd`` and ``env`` attributes represent the remote machine's working directory and environment +variables, respectively, and can be used to inspect or manipulate them. Much like their local +counterparts, they can be used as context managers, so their effects can be contained. :: >>> rem.cwd @@ -68,7 +68,7 @@ Tunneling SSH tunneling is a very useful feature of the SSH protocol. It allows you to connect from your machine to a remote server process, while having your connection authenticated and encrypted out-of-the-box. Say you run on ``machine-A``, and you wish to connect to a server program -running on ``machine-B``. That server program binds to ``localhost:8888`` (where ``localhost`` +running on ``machine-B``. That server program binds to ``localhost:8888`` (where ``localhost`` refers naturally to to ``machine-B``). Using Plumbum, you can easily set up a tunnel from port 6666 on ``machine-A`` to port 8888 on ``machine-B``:: @@ -81,8 +81,8 @@ Or as a context manager:: >>> with rem.tunnel(6666, 8888): ... pass -You can now connect a socket to ``machine-A:6666``, and it will be securely forwarded over SSH -to ``machine-B:8888``. When the tunnel object is closed, all active connections will be +You can now connect a socket to ``machine-A:6666``, and it will be securely forwarded over SSH +to ``machine-B:8888``. When the tunnel object is closed, all active connections will be dropped. @@ -91,8 +91,8 @@ dropped. Remote Commands --------------- -Like local commands, remote commands are created using indexing (``[]``) on a remote machine -object. You can either pass the command's name, in which case it will be resolved by through +Like local commands, remote commands are created using indexing (``[]``) on a remote machine +object. You can either pass the command's name, in which case it will be resolved by through ``which``, or the path to the program. :: >>> rem["ls"] @@ -116,7 +116,7 @@ behind the scenes - it nests each command inside ``ssh``. Here are some examples [...] You can nest multiple commands, one within another. For instance, you can connect to some machine -over SSH and use that machine's SSH client to connect to yet another machine. Here's a sketch:: +over SSH and use that machine's SSH client to connect to yet another machine. Here's a sketch:: >>> from plumbum.cmd import ssh >>> print ssh["localhost", ssh["localhost", "ls"]] @@ -136,11 +136,11 @@ place on the local machine! Consider this code for instance :: >>> (r_ls | r_grep["b"])() u'bin\nPublic\n' -Although ``r_ls`` and ``r_grep`` are remote commands, the data is sent from ``r_ls`` to the local +Although ``r_ls`` and ``r_grep`` are remote commands, the data is sent from ``r_ls`` to the local machine, which then sends it to the remote one for running ``grep``. This will be fixed in a future -version of Plumbum. +version of Plumbum. -It should be noted, however, that piping remote commands into local ones is perfectly fine. +It should be noted, however, that piping remote commands into local ones is perfectly fine. For example, the previous code can be written as :: >>> from plumbum.cmd import grep @@ -166,10 +166,10 @@ Paramiko Machine ``SshMachine`` relies on the system's ``ssh`` client to run commands; this means that for each remote command you run, a local process is spawned and an SSH connection is established. -While relying on a well-known and trusted SSH client is the most stable option, the incurred -overhead of creating a separate SSH connection for each command may be too high. In order to +While relying on a well-known and trusted SSH client is the most stable option, the incurred +overhead of creating a separate SSH connection for each command may be too high. In order to overcome this, Plumbum provides integration for `paramiko `_, -an open-source, pure-Python implementation of the SSH2 protocol. This is the ``ParamikoMachine``, +an open-source, pure-Python implementation of the SSH2 protocol. This is the ``ParamikoMachine``, and it works along the lines of the ``SshMachine``:: >>> from plumbum.machines.paramiko_machine import ParamikoMachine @@ -189,31 +189,31 @@ and it works along the lines of the ``SshMachine``:: Refer to :class:`the API docs ` for more details. -The main advantage of using ``ParamikoMachine`` is that only a single, persistent SSH connection -is created, over which commands execute. Moreover, paramiko has a built-in SFTP client, which is -used instead of ``scp`` to copy files (employed by the ``.download()``/``.upload()`` methods), -and tunneling is much more light weight: In the ``SshMachine``, a tunnel is created by an external +The main advantage of using ``ParamikoMachine`` is that only a single, persistent SSH connection +is created, over which commands execute. Moreover, paramiko has a built-in SFTP client, which is +used instead of ``scp`` to copy files (employed by the ``.download()``/``.upload()`` methods), +and tunneling is much more light weight: In the ``SshMachine``, a tunnel is created by an external process that lives for as long as the tunnel is to remain active. The ``ParamikoMachine``, however, -can simply create an extra *channel* on top of the same underlying connection with ease; this is -exposed by ``connect_sock()``, which creates a tunneled TCP connection and returns a socket-like +can simply create an extra *channel* on top of the same underlying connection with ease; this is +exposed by ``connect_sock()``, which creates a tunneled TCP connection and returns a socket-like object .. warning:: Piping and input/output redirection don't really work with ``ParamikoMachine`` commands. - You'll get all kinds of errors, like ``'ChannelFile' object has no attribute 'fileno'`` or + You'll get all kinds of errors, like ``'ChannelFile' object has no attribute 'fileno'`` or ``I/O operation on closed file`` -- this is due to the fact that Paramiko's channels are not real, OS-level files, so they can't interact with ``subprocess.Popen``. - - This will be solved in a future release; in the meanwhile, you can use the machine's + + This will be solved in a future release; in the meanwhile, you can use the machine's ``.session()`` method, like so :: - + >>> s = mach.session() >>> s.run("ls | grep b") (0, u'bin\nPublic\n', u'') Tunneling Example -^^^^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^ On ``192.168.1.143``, I ran the following sophisticated server (notice it's bound to ``localhost``):: @@ -249,7 +249,7 @@ port 12345, getting back a socket-like object:: Remote Paths ------------ -Analogous to local paths, remote paths represent a file-system path of a remote system, and +Analogous to local paths, remote paths represent a file-system path of a remote system, and expose a set of utility functions for iterating over subpaths, creating subpaths, moving/copying/ renaming paths, etc. :: @@ -265,4 +265,3 @@ renaming paths, etc. :: See the :ref:`guide-utils` guide for copying, moving and deleting remote paths For futher information, see the :ref:`api docs `. - diff --git a/docs/utils.rst b/docs/utils.rst index eaa171223..9320d2d03 100644 --- a/docs/utils.rst +++ b/docs/utils.rst @@ -10,25 +10,25 @@ imported into the namespace of ``plumbum`` directly, and you have to explicitly * :func:`copy(src, dst) ` - Copies ``src`` to ``dst`` (recursively, if ``src`` is a directory). The arguments can be either local or remote paths -- the function will sort out all the necessary details. - + * If both paths are local, the files are copied locally - + * If one path is local and the other is remote, the function uploads/downloads the files - + * If both paths refer to the same remote machine, the function copies the files locally on the remote machine - - * If both paths refer to different remote machines, the function downloads the files to a + + * If both paths refer to different remote machines, the function downloads the files to a temporary location and then uploads them to the destination - -* :func:`move(src, dst) ` - Moves ``src`` onto ``dst``. The arguments can be + +* :func:`move(src, dst) ` - Moves ``src`` onto ``dst``. The arguments can be either local or remote -- the function will sort our all the necessary details (as in ``copy``) * :func:`delete(*paths) ` - Deletes the given sequence of paths; each path may be a string, a local/remote path object, or an iterable of paths. If any of the paths does not exist, the function silently ignores the error and continues. For example :: - + from plumbum.path.utils import delete delete(local.cwd // "*/*.pyc", local.cwd // "*/__pycache__") -* :func:`gui_open(path) ` - Opens a file in the default editor on Windows, Mac, or Linux. Uses `os.startfile` if available (Windows), `xdg_open` (GNU), or `open` (Mac). +* :func:`gui_open(path) ` - Opens a file in the default editor on Windows, Mac, or Linux. Uses `os.startfile` if available (Windows), `xdg_open` (GNU), or `open` (Mac). diff --git a/examples/SimpleColorCLI.py b/examples/SimpleColorCLI.py index 636a75754..3c285a6de 100644 --- a/examples/SimpleColorCLI.py +++ b/examples/SimpleColorCLI.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import plumbum #from plumbum.colorlib import HTMLStyle, StyleFactory #plumbum.colors = StyleFactory(HTMLStyle) @@ -9,7 +10,7 @@ class MyApp(cli.Application): VERSION = colors.blue | "1.0.2" COLOR_GROUPS = {"Meta-switches" : colors.bold & colors.yellow} opts = cli.Flag("--ops", help=colors.magenta | "This is help") - + def main(self): print("HI") diff --git a/examples/alignment.py b/examples/alignment.py index a3bed747a..e39630f86 100755 --- a/examples/alignment.py +++ b/examples/alignment.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- from plumbum import cli class App(cli.Application): diff --git a/examples/color.py b/examples/color.py index 775f33729..f82abc3fc 100755 --- a/examples/color.py +++ b/examples/color.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- from __future__ import with_statement, print_function from plumbum import colors diff --git a/examples/filecopy.py b/examples/filecopy.py index 1f26546ee..72b299ebb 100755 --- a/examples/filecopy.py +++ b/examples/filecopy.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- import logging from plumbum import cli, local from plumbum.path.utils import delete, copy diff --git a/examples/fullcolor.py b/examples/fullcolor.py index 3d85fc761..046a5b01c 100755 --- a/examples/fullcolor.py +++ b/examples/fullcolor.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- from __future__ import with_statement, print_function from plumbum import colors @@ -7,4 +8,3 @@ for i in range(0,255,10): for j in range(0,255,10): print(u''.join(colors.rgb(i,j,k)[u'\u2588'] for k in range(0,255,10))) - diff --git a/examples/geet.py b/examples/geet.py index 8e6a137c8..7298fd805 100755 --- a/examples/geet.py +++ b/examples/geet.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- """ Examples:: diff --git a/examples/make_figures.py b/examples/make_figures.py index 89193d66b..4312a0fb6 100755 --- a/examples/make_figures.py +++ b/examples/make_figures.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- from __future__ import print_function, unicode_literals from plumbum.cmd import pdflatex, convert diff --git a/examples/simple_cli.py b/examples/simple_cli.py index 47178cc9e..5e2460013 100755 --- a/examples/simple_cli.py +++ b/examples/simple_cli.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- """ $ python simple_cli.py --help simple_cli.py v1.0 @@ -56,4 +57,3 @@ def main(self, *srcfiles): if __name__ == "__main__": MyCompiler() - diff --git a/experiments/parallel.py b/experiments/parallel.py index 1d0e1f696..eba4444fd 100644 --- a/experiments/parallel.py +++ b/experiments/parallel.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from plumbum.commands.base import BaseCommand from plumbum.commands.processes import run_proc, CommandNotFound, ProcessExecutionError @@ -174,10 +175,3 @@ def run(self, cmd, retcode=None): print(ret) ret = [int(pid) for pid in stdout] assert(len(set(ret))==3) - - - - - - - diff --git a/experiments/test_parallel.py b/experiments/test_parallel.py index 97b756243..19c52c1d1 100644 --- a/experiments/test_parallel.py +++ b/experiments/test_parallel.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import unittest from plumbum import local, SshMachine diff --git a/plumbum/__init__.py b/plumbum/__init__.py index b680e79ca..f7c6c1e96 100644 --- a/plumbum/__init__.py +++ b/plumbum/__init__.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- r""" Plumbum Shell Combinators ------------------------- diff --git a/plumbum/_testtools.py b/plumbum/_testtools.py index d29c02f77..acaa5770b 100644 --- a/plumbum/_testtools.py +++ b/plumbum/_testtools.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import pytest import os import sys diff --git a/plumbum/cli/__init__.py b/plumbum/cli/__init__.py index f9479adc9..5fde0b591 100644 --- a/plumbum/cli/__init__.py +++ b/plumbum/cli/__init__.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from __future__ import absolute_import from .switches import SwitchError, switch, autoswitch, SwitchAttr, Flag, CountOf, positional diff --git a/plumbum/cli/application.py b/plumbum/cli/application.py index cb5e1fad3..e7a147003 100644 --- a/plumbum/cli/application.py +++ b/plumbum/cli/application.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from __future__ import division, print_function, absolute_import import os import sys diff --git a/plumbum/cli/config.py b/plumbum/cli/config.py index abbc66b68..d9673c058 100644 --- a/plumbum/cli/config.py +++ b/plumbum/cli/config.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from __future__ import print_function, division from abc import abstractmethod diff --git a/plumbum/cli/i18n.py b/plumbum/cli/i18n.py index 987ae0005..39cabb58f 100644 --- a/plumbum/cli/i18n.py +++ b/plumbum/cli/i18n.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import locale # High performance method for English (no translation needed) diff --git a/plumbum/cli/image.py b/plumbum/cli/image.py index 46c5b47aa..8d0bb7e3d 100644 --- a/plumbum/cli/image.py +++ b/plumbum/cli/image.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from __future__ import print_function, division from plumbum import colors diff --git a/plumbum/cli/progress.py b/plumbum/cli/progress.py index ea92f6551..84ecc7199 100644 --- a/plumbum/cli/progress.py +++ b/plumbum/cli/progress.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """ Progress bar ------------ diff --git a/plumbum/cli/switches.py b/plumbum/cli/switches.py index 56ab5c2be..b5cf615ba 100644 --- a/plumbum/cli/switches.py +++ b/plumbum/cli/switches.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from plumbum.lib import six, getdoc from plumbum.cli.i18n import get_translation_for from plumbum import local diff --git a/plumbum/cli/terminal.py b/plumbum/cli/terminal.py index f075cbff3..d89e8fd3c 100644 --- a/plumbum/cli/terminal.py +++ b/plumbum/cli/terminal.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """ Terminal-related utilities -------------------------- diff --git a/plumbum/cli/termsize.py b/plumbum/cli/termsize.py index 5aec4aad3..ca88d5c9e 100644 --- a/plumbum/cli/termsize.py +++ b/plumbum/cli/termsize.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """ Terminal size utility --------------------- diff --git a/plumbum/colorlib/__init__.py b/plumbum/colorlib/__init__.py index 7a3f60de6..7ca3cec6e 100644 --- a/plumbum/colorlib/__init__.py +++ b/plumbum/colorlib/__init__.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """\ The ``ansicolor`` object provides ``bg`` and ``fg`` to access colors, and attributes like bold and diff --git a/plumbum/colorlib/__main__.py b/plumbum/colorlib/__main__.py index 22b317508..2f59e1764 100644 --- a/plumbum/colorlib/__main__.py +++ b/plumbum/colorlib/__main__.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """ This is provided as a quick way to recover your terminal. Simply run ``python -m plumbum.colorlib`` diff --git a/plumbum/colorlib/_ipython_ext.py b/plumbum/colorlib/_ipython_ext.py index b8f9f807a..5d225af12 100644 --- a/plumbum/colorlib/_ipython_ext.py +++ b/plumbum/colorlib/_ipython_ext.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from IPython.core.magic import ( Magics, magics_class, # type: ignore diff --git a/plumbum/colorlib/factories.py b/plumbum/colorlib/factories.py index 441ecce24..865f1653f 100644 --- a/plumbum/colorlib/factories.py +++ b/plumbum/colorlib/factories.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """ Color-related factories. They produce Styles. diff --git a/plumbum/colorlib/names.py b/plumbum/colorlib/names.py index 7b96d0d8a..475173ce1 100644 --- a/plumbum/colorlib/names.py +++ b/plumbum/colorlib/names.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- ''' Names for the standard and extended color set. Extended set is similar to `vim wiki `_, `colored `_, etc. Colors based on `wikipedia `_. diff --git a/plumbum/colorlib/styles.py b/plumbum/colorlib/styles.py index c67526484..c72677553 100644 --- a/plumbum/colorlib/styles.py +++ b/plumbum/colorlib/styles.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """ This file provides two classes, `Color` and `Style`. diff --git a/plumbum/colors.py b/plumbum/colors.py index c6cf7076a..4e12fbb0b 100644 --- a/plumbum/colors.py +++ b/plumbum/colors.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """ This module imitates a real module, providing standard syntax like from `plumbum.colors` and from `plumbum.colors.bg` to work alongside diff --git a/plumbum/commands/__init__.py b/plumbum/commands/__init__.py index a71af0576..9d7484baf 100644 --- a/plumbum/commands/__init__.py +++ b/plumbum/commands/__init__.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from plumbum.commands.base import shquote, shquote_list, BaseCommand, ERROUT, ConcreteCommand from plumbum.commands.modifiers import ExecutionModifier, Future, FG, BG, TEE, TF, RETCODE, NOHUP from plumbum.commands.processes import run_proc diff --git a/plumbum/commands/base.py b/plumbum/commands/base.py index 7d5019263..2c2c9df14 100644 --- a/plumbum/commands/base.py +++ b/plumbum/commands/base.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import shlex import subprocess import sys diff --git a/plumbum/commands/daemons.py b/plumbum/commands/daemons.py index 7b08e7567..e9acdd02f 100644 --- a/plumbum/commands/daemons.py +++ b/plumbum/commands/daemons.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import subprocess import os import time diff --git a/plumbum/commands/modifiers.py b/plumbum/commands/modifiers.py index 27fd31459..107d6dce2 100644 --- a/plumbum/commands/modifiers.py +++ b/plumbum/commands/modifiers.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import os from select import select from subprocess import PIPE diff --git a/plumbum/commands/processes.py b/plumbum/commands/processes.py index 85072ea1a..f2bad37d8 100644 --- a/plumbum/commands/processes.py +++ b/plumbum/commands/processes.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import time import atexit import heapq diff --git a/plumbum/fs/__init__.py b/plumbum/fs/__init__.py index ba7cf8701..c7fcf7833 100644 --- a/plumbum/fs/__init__.py +++ b/plumbum/fs/__init__.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """ file-system related operations -""" \ No newline at end of file +""" diff --git a/plumbum/fs/atomic.py b/plumbum/fs/atomic.py index 6acd6ca37..ac88941e8 100644 --- a/plumbum/fs/atomic.py +++ b/plumbum/fs/atomic.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """ Atomic file operations """ diff --git a/plumbum/fs/mounts.py b/plumbum/fs/mounts.py index faacb6ded..b0d686bb6 100644 --- a/plumbum/fs/mounts.py +++ b/plumbum/fs/mounts.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import re diff --git a/plumbum/lib.py b/plumbum/lib.py index b9404f24a..cecc7d43b 100644 --- a/plumbum/lib.py +++ b/plumbum/lib.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import sys import os from contextlib import contextmanager diff --git a/plumbum/machines/__init__.py b/plumbum/machines/__init__.py index f1f9b3745..ae49c4efd 100644 --- a/plumbum/machines/__init__.py +++ b/plumbum/machines/__init__.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from plumbum.machines.local import LocalCommand, LocalMachine, local from plumbum.machines.remote import BaseRemoteMachine, RemoteCommand from plumbum.machines.ssh_machine import SshMachine, PuttyMachine diff --git a/plumbum/machines/_windows.py b/plumbum/machines/_windows.py index aa1fd559b..e80293113 100644 --- a/plumbum/machines/_windows.py +++ b/plumbum/machines/_windows.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import struct from plumbum.lib import six diff --git a/plumbum/machines/base.py b/plumbum/machines/base.py index 51673ecbf..32aafb59a 100644 --- a/plumbum/machines/base.py +++ b/plumbum/machines/base.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from plumbum.commands.processes import CommandNotFound from plumbum.commands.processes import ProcessExecutionError from plumbum.commands.processes import ProcessTimedOut diff --git a/plumbum/machines/env.py b/plumbum/machines/env.py index ee40d2da8..11e25c577 100644 --- a/plumbum/machines/env.py +++ b/plumbum/machines/env.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import os from contextlib import contextmanager diff --git a/plumbum/machines/local.py b/plumbum/machines/local.py index 73c666ab8..89b219086 100644 --- a/plumbum/machines/local.py +++ b/plumbum/machines/local.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import os import sys import subprocess diff --git a/plumbum/machines/paramiko_machine.py b/plumbum/machines/paramiko_machine.py index d9870d180..a3eddce6c 100644 --- a/plumbum/machines/paramiko_machine.py +++ b/plumbum/machines/paramiko_machine.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import logging import errno import os diff --git a/plumbum/machines/remote.py b/plumbum/machines/remote.py index c237c66da..b9137dad5 100644 --- a/plumbum/machines/remote.py +++ b/plumbum/machines/remote.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import re from contextlib import contextmanager from plumbum.commands import CommandNotFound, shquote, ConcreteCommand diff --git a/plumbum/machines/session.py b/plumbum/machines/session.py index 4fe8191fd..ac3c61510 100644 --- a/plumbum/machines/session.py +++ b/plumbum/machines/session.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import time import random import logging diff --git a/plumbum/machines/ssh_machine.py b/plumbum/machines/ssh_machine.py index c0165c7da..5c22f7f4b 100644 --- a/plumbum/machines/ssh_machine.py +++ b/plumbum/machines/ssh_machine.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from plumbum.lib import _setdoc, IS_WIN32 from plumbum.machines.remote import BaseRemoteMachine from plumbum.machines.session import ShellSession diff --git a/plumbum/path/__init__.py b/plumbum/path/__init__.py index 14dc685cd..e67dd06ad 100644 --- a/plumbum/path/__init__.py +++ b/plumbum/path/__init__.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from plumbum.path.local import LocalPath, LocalWorkdir from plumbum.path.remote import RemotePath, RemoteWorkdir from plumbum.path.base import Path, FSUser, RelativePath diff --git a/plumbum/path/base.py b/plumbum/path/base.py index c76733f10..f17de7c54 100644 --- a/plumbum/path/base.py +++ b/plumbum/path/base.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from __future__ import absolute_import import itertools diff --git a/plumbum/path/local.py b/plumbum/path/local.py index d93cf5601..137346d4b 100644 --- a/plumbum/path/local.py +++ b/plumbum/path/local.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import os import sys import glob diff --git a/plumbum/path/remote.py b/plumbum/path/remote.py index 762168077..4001b7018 100644 --- a/plumbum/path/remote.py +++ b/plumbum/path/remote.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import errno from contextlib import contextmanager from plumbum.path.base import Path, FSUser diff --git a/plumbum/path/utils.py b/plumbum/path/utils.py index dc94d2338..90f128757 100644 --- a/plumbum/path/utils.py +++ b/plumbum/path/utils.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from plumbum.path.base import Path from plumbum.lib import six from plumbum.machines.local import local, LocalPath diff --git a/plumbum/typed_env.py b/plumbum/typed_env.py index 91e3e128a..802e79e9b 100644 --- a/plumbum/typed_env.py +++ b/plumbum/typed_env.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import os import inspect @@ -6,7 +7,7 @@ except ImportError: from collections import MutableMapping - + NO_DEFAULT = object() diff --git a/plumbum/version.py b/plumbum/version.py index cee5851b9..32ae904d9 100644 --- a/plumbum/version.py +++ b/plumbum/version.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- version = (1, 6, 9) version_string = ".".join(map(str, version)) release_date = "2020.03.23" diff --git a/setup.cfg b/setup.cfg index be4c676d4..6c4147ac1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -42,7 +42,7 @@ python_requires = >=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4 packages = find: install_requires = pypiwin32; platform_system=='Windows' and platform_python_implementation!="PyPy" - + [options.package_data] plumbum.cli = i18n/*/LC_MESSAGES/*.mo diff --git a/setup.py b/setup.py index d7dfc7bf8..f64a97955 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- import codecs import os diff --git a/tests/_test_paramiko.py b/tests/_test_paramiko.py index bf4220873..144fe96ef 100644 --- a/tests/_test_paramiko.py +++ b/tests/_test_paramiko.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from plumbum.paramiko_machine import ParamikoMachine as PM from plumbum import local local.env.path.append("c:\\progra~1\\git\\bin") @@ -12,5 +13,3 @@ (mls | grep["\\."])() (ls | mgrep["\\."])() - - diff --git a/tests/conftest.py b/tests/conftest.py index 401808317..236465e9b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import pytest import os import sys diff --git a/tests/not-in-path/dummy-executable b/tests/not-in-path/dummy-executable index 96b4b06ad..1a2485251 100755 --- a/tests/not-in-path/dummy-executable +++ b/tests/not-in-path/dummy-executable @@ -1 +1 @@ -#!/bin/sh \ No newline at end of file +#!/bin/sh diff --git a/tests/slow_process.bash b/tests/slow_process.bash index 2daa94884..c9a8ea1ae 100755 --- a/tests/slow_process.bash +++ b/tests/slow_process.bash @@ -7,4 +7,3 @@ do echo $i >> slow_process.out sleep 1 done - diff --git a/tests/test_3_cli.py b/tests/test_3_cli.py index a754804ee..2d1b3e488 100644 --- a/tests/test_3_cli.py +++ b/tests/test_3_cli.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from plumbum import cli diff --git a/tests/test_cli.py b/tests/test_cli.py index ade6877c2..0da7f4087 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import pytest import sys diff --git a/tests/test_clicolor.py b/tests/test_clicolor.py index d09fc5dfb..8e3b8ab47 100644 --- a/tests/test_clicolor.py +++ b/tests/test_clicolor.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from plumbum import cli, colors colors.use_color = 3 diff --git a/tests/test_color.py b/tests/test_color.py index 2b8105d0f..de5042fcc 100644 --- a/tests/test_color.py +++ b/tests/test_color.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import pytest from plumbum.colorlib.styles import ANSIStyle, Color, AttributeNotFound, ColorNotFound from plumbum.colorlib.names import color_html, FindNearest @@ -66,4 +67,3 @@ def test_allcolors(self): for b in myrange: near = FindNearest(r,g,b) assert near.all_slow() == near.all_fast(), 'Tested: {0}, {1}, {2}'.format(r,g,b) - diff --git a/tests/test_config.py b/tests/test_config.py index 2e4291595..434698070 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from __future__ import print_function import pytest diff --git a/tests/test_env.py b/tests/test_env.py index 49f79f703..fe4bd275c 100644 --- a/tests/test_env.py +++ b/tests/test_env.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import pytest import plumbum @@ -66,4 +67,3 @@ def test_home(self): @skip_on_windows def test_user(self): assert local.env.user - diff --git a/tests/test_factories.py b/tests/test_factories.py index f9b5849b5..e7c26136c 100644 --- a/tests/test_factories.py +++ b/tests/test_factories.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- from __future__ import print_function import pytest from plumbum import colors @@ -16,7 +17,7 @@ def testDifferentImports(self): assert str(bold) == str(colors.bold) class TestANSIColor: - + def setup_method(self, method): colors.use_color = True @@ -179,4 +180,3 @@ def test_html(self): assert "This is tagged" | htmlcolors.red & htmlcolors.em == twin_tagged assert "This is tagged" | htmlcolors.em & htmlcolors.red == twin_tagged assert htmlcolors.em & htmlcolors.red | "This is tagged" == twin_tagged - diff --git a/tests/test_local.py b/tests/test_local.py index 5a4795f03..4e0819f40 100644 --- a/tests/test_local.py +++ b/tests/test_local.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import pytest import pickle import os diff --git a/tests/test_nohup.py b/tests/test_nohup.py index e6793562f..e70a5b763 100644 --- a/tests/test_nohup.py +++ b/tests/test_nohup.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import pytest import os import sys diff --git a/tests/test_putty.py b/tests/test_putty.py index 763407fa0..87a8f1b6a 100644 --- a/tests/test_putty.py +++ b/tests/test_putty.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """Test that PuttyMachine initializes its SshMachine correctly""" import pytest diff --git a/tests/test_remote.py b/tests/test_remote.py index 6c10eae6d..44fc77fae 100644 --- a/tests/test_remote.py +++ b/tests/test_remote.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import pytest import sys import os diff --git a/tests/test_sudo.py b/tests/test_sudo.py index 6a555dc8c..b44dab38d 100644 --- a/tests/test_sudo.py +++ b/tests/test_sudo.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import pytest @@ -19,4 +20,3 @@ class TestSudo: def test_as_user(self): with local.as_root(): local["date"]() - diff --git a/tests/test_terminal.py b/tests/test_terminal.py index 363007f0c..80cd583c8 100644 --- a/tests/test_terminal.py +++ b/tests/test_terminal.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import pytest import sys import time diff --git a/tests/test_typed_env.py b/tests/test_typed_env.py index 505c9469a..05b4fca44 100644 --- a/tests/test_typed_env.py +++ b/tests/test_typed_env.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import pytest from plumbum.typed_env import TypedEnv diff --git a/tests/test_utils.py b/tests/test_utils.py index a214305a0..05acc15b8 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import pytest from plumbum import local, SshMachine from plumbum.path.utils import copy, delete, move @@ -52,4 +53,3 @@ def test_copy_move_delete(self): # test rm delete(dir) - diff --git a/tests/test_validate.py b/tests/test_validate.py index f8014e8d5..e9da6b329 100644 --- a/tests/test_validate.py +++ b/tests/test_validate.py @@ -88,5 +88,3 @@ def main(self, myint, myint2=2): _, rc = MainValidator.run(["prog", "1", "3"], exit = False) assert rc == 0 assert "1 3" == capsys.readouterr()[0].strip() - - diff --git a/tests/test_visual_color.py b/tests/test_visual_color.py index 64a3ada62..36187ea46 100644 --- a/tests/test_visual_color.py +++ b/tests/test_visual_color.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- from __future__ import with_statement, print_function import unittest import os diff --git a/translations.py b/translations.py index 0528faae8..936132d0b 100755 --- a/translations.py +++ b/translations.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- # If you are on macOS and using brew, you might need the following first: # export PATH="/usr/local/opt/gettext/bin:$PATH" @@ -32,5 +33,3 @@ if not local_dir.exists(): local_dir.mkdir() msgfmt['-o', local_dir / 'plumbum.cli.mo', translation] & FG - -