Giter Site home page Giter Site logo

plac's People

Contributors

ajschumacher avatar awhetter avatar fabianoengler avatar ialbert avatar jspeed-meyers avatar mariusvniekerk avatar micheles avatar pabs3 avatar poleguy avatar radek-sprta avatar refi64 avatar weepingclown13 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

plac's Issues

plac 0.9.3 broken in Python 2

plac is now producing an universal wheel with use_2to3 which does not appear to work. If you pip install plac in Python 2 you will get the 2to3 fixes, eg. print('Process %d killed by CTRL-C' % os.getpid(), file=sys.stderr) withouth from __future__ import print_function.

I guess that until you remove 2to3 (which would be a good change!) you will have to use the old way and distribute Python 2 and Python 3 versions.

Thanks

When kwargs are used, option values cannot have "="

I know this is painful to fix, but I call it a bug anyway because it is very unexpected: users would think it easy to know that "--opt", requiring one option, will take the "abc=" below.

$ cat test_plac.py 
#!/usr/bin/env python
def func(opt: ('opt', 'option', 'o') = 'foo', **kw: ('kw',)):
    print(opt, kw)
import plac
plac.call(func)
$ python test_plac.py --opt abc=
usage: test_plac.py [-h] [-o foo] [kw [kw ...]]
test_plac.py: error: argument -o/--opt: expected one argument

Named Arguments

Does plac support named arguments, like below?

python myfile.py positional1 positional2 --some-named=True

Specify version of BSD license / include copy with source

Hey-lo,

I'm building a version of plac using conda for conda-forge. When possible, we try to both include a link to the license file in the meta.yaml specification for the build and pin down the exact identity of the license.
Two questions for you:

  1. Can you specify whether plac is under the BSD 2-Clause or 3-Clause license?
  2. Would you consider including a copy of the license with the source tarball the next time you cut a release?

Unable to run script inside IPython with %run magic command

Not sure if I am doing something wrong, but I am trying to run this simple test from the IPython prompt where I do most of my dev work but it is not picking up the -h flag or any other normal arguments. I am printing the sys.argv just for debugging purposes.

It seems like this should work just like from the bash prompt. Here is my code:

#!/usr/bin/env python
"""
Testing CLI
"""
import sys
import plac

# @plac.annotations(
#     dsn=("Random input", "option", "dsn", int))
def main(dsn):
    print dsn

if __name__ == '__main__':
    print sys.argv
    plac.call(main)

Output:

# IPython prompt
In [43]: %run clitest.py -h
['clitest.py', '-h']
usage: clitest.py [-h] dsn
clitest.py: error: too few arguments
An exception has occurred, use %tb to see the full traceback.

SystemExit: 2

In [44]:

Does not support dashes in long arguments

plac currently requires option names to be valid python identifiers, so it is 
impossible to have an option like "--dry-run". You have to use "--dry_run" 
instead, which is awkward because it has both dashes and underscores in it. 
This can be fixed with just a one-line patch that replaces underscores with 
dashes in option names before calling add_argument.

I'm including the patch below. It includes two possibilities: either accept 
*only* dashed options, or accept options with either dashes or underscores, 
which would be more backward-compatible, but sometimes confusing in the help 
screen.

$ hg diff -w plac_core.py              
diff --git a/plac_core.py b/plac_core.py
--- a/plac_core.py
+++ b/plac_core.py
@@ -255,6 +255,10 @@
                     shortlong = (prefix + a.abbrev, prefix*2 + name)
                 else:
                     shortlong = (prefix + name,)
+                # Replace underscores with dashes in argument names
+                # shortlong = [ s.replace('_', '-') for s in shortlong ]
+                # # Accept either dashes or underscores
+                shortlong = tuple([ s.replace('_', '-') for s in shortlong if 
s.find('_') != -1 ]) + shortlong
             elif default is NONE: # required argument
                 self.add_argument(name, help=a.help, type=a.type, 
                                    choices=a.choices, metavar=metavar)

Original issue reported on code.google.com by [email protected] on 16 Dec 2011 at 1:01

When kwargs are used, unrecognized arguments are not notified

Without kwargs, unrecognized arguments leads to an error notifying the user that the command used is wrong. But with kwargs...

$ cat test_plac.py 
#!/usr/bin/env python
def func(**kw: ('kw',)):
    print(kw)
import plac
plac.call(func)
$ ./test_plac.py foo
{}

AttributeError when using Interpreter Class

Use the same example from the tutorial (ishelve), I'm using python2.7 on amd64 
Arch Linux.

What is the expected output? What do you see instead?
There is the following traceback:

python2.7 ishelve_i.py -i
Traceback (most recent call last):
  File "ishelve_i.py", line 19, in <module>
    plac.call(main)
  File "/usr/lib/python2.7/site-packages/plac_core.py", line 309, in call
    cmd, result = parser_from(obj).consume(arglist)
  File "/usr/lib/python2.7/site-packages/plac_core.py", line 195, in consume
    return cmd, self.func(*(args + varargs + extraopts), **kwargs)
  File "ishelve_i.py", line 13, in main
    plac.Interpreter(ishelve.main).interact()
  File "/usr/lib/python2.7/site-packages/plac_ext.py", line 805, in __init__
    self.tm = TaskManager(obj)
  File "/usr/lib/python2.7/site-packages/plac_ext.py", line 482, in __init__
    obj, prog='' if interact else None, formatter_class=PlacFormatter)
  File "/usr/lib/python2.7/site-packages/plac_core.py", line 127, in parser_from
    parser.populate_from(obj)
  File "/usr/lib/python2.7/site-packages/plac_core.py", line 275, in populate_from
    self.add_argument(action='store_true', help=a.help, *shortlong)
  File "/usr/lib/python2.7/argparse.py", line 1291, in add_argument
    self._get_formatter()._format_args(action, None)
  File "/usr/lib/python2.7/argparse.py", line 572, in _format_args
    get_metavar = self._metavar_formatter(action, default_metavar)
  File "/usr/lib/python2.7/site-packages/plac_ext.py", line 165, in _metavar_formatter
    action.choices = dict((n, c) for n, c in action.choices.iteritems()
AttributeError: 'NoneType' object has no attribute 'iteritems'
[1]    7853 exit 1     python2.7 ishelve_i.py -i

What version of the product are you using? On what operating system?
plac 0.9.0, Python 2.7.2

Please provide any additional information below.

Original issue reported on code.google.com by [email protected] on 31 Oct 2011 at 8:28

`plac cmd -h` dies if docstring contains unicode character

What steps will reproduce the problem?
1. Define a command; insert unicode character into docstring
2. Attempt to print script's help

Expect to see the help string; instead experience a stack trace.

pip show plac

---
Name: plac
Version: 0.9.1

See attached test case. Use with:

python test.py -h

See attached patch for one way to fix.


Original issue reported on code.google.com by [email protected] on 20 Jan 2015 at 7:57

Attachments:

Guidance on pluggable subcommands

Assuming a package with multiple CLIs powered by plac, is there a pattern that is recommended to allow "pluggable" subcommands? In other words, there is an entry point for a package for a CLI command powered by plac, would it be possible to have subcommands from that CLI trigger other CLIs in the package (and then hopefully from other plac CLIs)?

mypackage:
 - setup.py (entry point for mycli=mypackage/__main__.py:run)
 - main/
   - __main__.py (plac powered)
   - ...
 - foo/
   - __main__.py (plac powered)
   - ...
 - bar/
   - __main__.py (plac powered)
   - ...

All three CLIs could be called independently (mycli --> main or python -m mypackage.main, and then python -m mypackage.foo and python -m mypackage.bar)

Execution examples:
mycli toplevel_command
mycli foo [args_for_foo]
mycli bar [args_for_foo]

Ref for a native solution: https://stackoverflow.com/questions/54263164/pluggable-python-sub-command-pattern

Corrections to docs and examples

Please find some corrections to docs and examples: 
<http://code.google.com/r/nicolalarosa-plac/source/detail?r=cd156d9657bb60056e47
e202c419a71d118c0b91>.

Thanks for plac!

Original issue reported on code.google.com by [email protected] on 8 Apr 2013 at 11:21

There seems to be no way to implement global arguments when using subcommands

I have a script with two subcommands (say install and update), and I want to 
add a argument that is common to all subcommands (verbose), in order to do this 
:

python myscript.py -v install
or
python myscript.py -v update

without having to write the code to handle -v twice.

I couln't find it in the docs nor by reading the code. Is there a way to do so 
? If I think this is a valid use case.

Original issue reported on code.google.com by [email protected] on 6 Feb 2012 at 9:50

test_cmds fails with python 3.3.1

What steps will reproduce the problem?
1. download plac-0.9.1.tar.gz from pypi
2. install to python 3.3.1 with 
    py -3.3 setup.py install 
(this is equivalent to c:\python33\python.exe setup.py install)

3. cd plac-0.9.1
   py -3.3 test_plac.py

What is the expected output?

A message telling all ok or no output at all

 What do you see instead?
D:\tmp\plac-0.9.1\doc>py -3 test_plac.py
Running test_batch
Running test_cmd_abbrevs
usage: test_plac.py {help,commit} ...
test_plac.py: error: No command 'foo'
Running test_cmds
Traceback (most recent call last):
  File "test_plac.py", line 230, in <module>
    maybegen = test()
  File "test_plac.py", line 184, in test_cmds
    expect(SystemExit, plac.call, cmds, [])
  File "test_plac.py", line 18, in expect
    func(*args, **kw)
  File "C:\Python33\lib\site-packages\plac-0.9.1-py3.3.egg\plac_core.py", line 3
09, in call
    cmd, result = parser_from(obj).consume(arglist)
  File "C:\Python33\lib\site-packages\plac-0.9.1-py3.3.egg\plac_core.py", line 1
89, in consume
    args = [getattr(ns, a) for a in self.argspec.args]
AttributeError: 'ArgumentParser' object has no attribute 'argspec'


What version of the product are you using? On what operating system?
plac 0.9.1
On windows xp sp3

Please provide any additional information below.
Installing and testing to python 2.7 shows no error.

Running test_plac.py in py 3.3.1 with  pytest 2.3.5 tells that it is the only 
test failing in the file, (besides the one for sqlalchemy, which fails because 
the module is missing)

Additionally, deprecation warnings are seen for module imp. 

Original issue reported on code.google.com by [email protected] on 9 May 2013 at 10:49

Using global options with sub-commands

I know that this was already raised here 
(https://code.google.com/p/plac/issues/detail?id=8) and was declared invalid, 
but my use-case is quite different so might be reconsidered?

If you consider svn as an example of a program with sub-commands, you might 
want to have an `svn --version` option. This is a global setting that should 
always have the same effect, independent of the sub-command and in fact should 
work without a sub-command. 

If there is already a way to achieve this, I'd appreciate your help.

Thanks,
David

Original issue reported on code.google.com by [email protected] on 9 Aug 2013 at 11:45

SystemExit Error when ran inside a Jupyter Notebook

since plac is a wrapper over argparse, it seems there is an issue when running it inside a Jupyter Notebook.

Here's an example from spacy tutorials

At runtime, I get the following error:

usage: ipykernel_launcher.py [-h] [-m None] [-o None] [-n 100]
ipykernel_launcher.py: error: unrecognized arguments: -f /Users/<my_user>/Library/Jupyter/runtime/kernel-b09996b6-dd81-4a9a-8619-c99b6c9a4919.json
An exception has occurred, use %tb to see the full traceback.

SystemExit: 2

/Users/<my_user>/anaconda3/lib/python3.6/site-packages/IPython/core/interactiveshell.py:2918: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.
warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)

I found a workaround for argparse on stackoverflow, but I am not sure if it can be applied to plac.

sqlsoup test dependency is unmaintained, doesn't work with SQLAlchemy 1.4.23

The SQLSoup Python module is unmaintained upstream and doesn't work with SQLAlchemy 1.4.23, which Debian has upgraded to, leading to build and CI failures in Debian infrastructure for things that use SQLSoup. The SQLSoup author suggested to switch to the SQLAlchemy automap extension. Since the SQLSoup Python module is only used in plac as an optional test dependency, the Debian package of plac will likely just drop it, but you might want to add support for using the SQLAlchemy automap extension as an alternative to the SQLSoup Python module.

https://bugs.debian.org/995781
https://bugs.debian.org/997325
zzzeek/sqlsoup#1
https://docs.sqlalchemy.org/en/14/orm/extensions/automap.html

Improvement: Documentation is hard to read

The documentation is bit hard to read, mostly due to it's presentation/templating I guess, which is very off from the expected python standards used in the community.

I am attaching some screenshots for comparison, showing the extremes of a 4k desktop and a mobile screen:

Plac:

desktop

Screenshot_2019-10-20 plac rst

mobile

Screenshot_2019-10-20 plac rst(1)


Click:

https://click.palletsprojects.com/en/7.x/options/

desktop

Screenshot_2019-10-20 Options — Click Documentation (7 x)

mobile

Screenshot_2019-10-20 Options — Click Documentation (7 x)(1)


Scrapy:

https://docs.scrapy.org/en/latest/intro/tutorial.html

desktop

Screenshot_2019-10-20 Scrapy Tutorial — Scrapy 1 7 3 documentation

mobile

Screenshot_2019-10-20 Scrapy Tutorial — Scrapy 1 7 3 documentation(1)


Requests:
https://requests.kennethreitz.org/en/master/user/advanced/

desktop

Screenshot_2019-10-20 Advanced Usage — Requests 2 22 0 documentation(1)

mobile

Screenshot_2019-10-20 Advanced Usage — Requests 2 22 0 documentation(2)


The counter examples seem so more easier to follow and pleasant to read, both on mobile and on larger screens (except for requests on mobile, which is a little bit off).

The main points for improvement I identified are:

  • Use a sensible max witdh
  • Use syntax highlighting for code samples
  • Perhaps a little larger font size and increased spacing between lines

The pdf version has the same issues, except for the fixed margin, which helps on desktop, but it is still not responsive (friendly on a range of screens).

I personally love this project and how it scales down, but at a first contact I did find it very welcoming for the questions I had that the README didn't answer and I almost skipped it. I'm glad I stayed but I wonder if the same happened to others. I would love to see this project gaining more visibility and adoption and I believe a more pleasant documentation could help.

I can see a fair amount of time was already spent on the documentation content, it's just that its current presentation doesn't do it justice :neckbeard: .

I think the https://readthedocs.org/ project already has a very good default template that addresses most of the issues I am pointing. They use sphinx, which support rst format that plac is already using, so I believe the migration would be fairly simple.

If the issue seems fair and help is wanted, let me know 😉

Plac does not strip function doc before using it as help

When a function has multi-line comments, it is usually the case that it has to end with extra spaces, e.g., to satisfy coding standards. But this results into ugly help string.

$ cat test_plac.py 
#!/usr/bin/env python
def func(opt: ('opt',)):
    """This is title

This is content

    """
    print(opt)
import plac
plac.call(func)
$ ./test_plac.py -h
usage: test_plac.py [-h] opt

This is title

This is content

    

positional arguments:
  opt         opt

optional arguments:
  -h, --help  show this help message and exit

Double dash vs single dash for long options

I just have a quick question that the doc doesn't seem to explain.

I have this program taking many options, and sometimes plac generates option flags with two dashes (like epochs becomes --epochs), but sometimes for more long winded argument names, it generates flags with a single dash (like train_vgg becomes -train-vgg, validation_steps becomes -validation-steps).

I'd like to understand why that is the case. Is there a practical reason for this behaviour ?

From my CLI experience, I usually expect long argument names to have two dashes and one letter argument names to have one dash.

As an example, here is the help display for nmap:

$ nmap --help

SCAN TECHNIQUES:
  -sS/sT/sA/sW/sM: TCP SYN/Connect()/ACK/Window/Maimon scans
  -sU: UDP Scan
  -sN/sF/sX: TCP Null, FIN, and Xmas scans
  --scanflags <flags>: Customize TCP scan flags
  -sI <zombie host[:probeport]>: Idle scan
  -sY/sZ: SCTP INIT/COOKIE-ECHO scans
  -sO: IP protocol scan
  -b <FTP relay host>: FTP bounce scan
PORT SPECIFICATION AND SCAN ORDER:
  -p <port ranges>: Only scan specified ports
    Ex: -p22; -p1-65535; -p U:53,111,137,T:21-25,80,139,8080,S:9
  --exclude-ports <port ranges>: Exclude the specified ports from scanning
  -F: Fast mode - Scan fewer ports than the default scan
  -r: Scan ports consecutively - don't randomize
  --top-ports <number>: Scan <number> most common ports
  --port-ratio <ratio>: Scan ports more common than <ratio>
SERVICE/VERSION DETECTION:
  -sV: Probe open ports to determine service/version info
  --version-intensity <level>: Set from 0 (light) to 9 (try all probes)
  --version-light: Limit to most likely probes (intensity 2)
  --version-all: Try every single probe (intensity 9)
  --version-trace: Show detailed version scan activity (for debugging)

This strange behaviour of plac makes using the flags unintuitive. Is there a way to force plac to use double dash instead of single dash ?

Is there a reason why one might prefer using single dash with long argument names ?

Idea: gh-pages branch

It would be neat if you could add a gh-pages branch with plac.html as index.html. That way, one could access the docs online via micheles.github.io/plac.

See here for more info.

Migrate from imp to importlib

When running python scripts that depend on plac_ext.py under a recent version of Python, a deprecation warning will be issued on every run:

/home/leonard/.local/lib64/python3.6/site-packages/plac_ext.py:6: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
  import imp            

Quick start and API doc

Plac looks great, but I never use it because it takes too long to read through the documentation. When I'm working I really want a quick way to lookup methods and suggested usage. It's great that there's documentation with all the motivations behind plac, and comparisons to other approaches such as argparse, but to be useful, I need documentation without all that. Something efficient to use while I'm in the middle of writing code.

I suggest adding 2 pieces of documentation which are separate from the existing documentation.

  1. Quick Start
    This would show the top N common uses. For example, these uses cases could be covered:

    • How to support a program with a single variable
    • How to support a program with multiple variables
    • How to support a program with optional variables
    • How to support a program requiring default values and types
  2. API Doc
    Something in the style of https://docs.python.org/3/library/argparse.html where the doc follows other python documentation in style and organization. It should have:

    • A short description of what plac does
    • A handful of examples
    • Documentation of the useful functions, classes and methods.

rethink the import_main mechanism

The problem is that imp.load_module is not looking in the current directory in 
the search path. You can see the problem with

$ plac_runner.py doc/ishelve3.py 

or

$ plac_runner.py doc/ishelve2.py 

not finding ishelve2.py

Original issue reported on code.google.com by [email protected] on 19 Jun 2011 at 9:37

Determine argument type automatically from default

if an argument data type is not provided explicitly but a default value is:
    if default is not a tuple:
        argtype = type(default)
    elif all(type(val) == type(default[0]) for val in default[1:]):
        argtype = type(default[0])

Default value of None does not work

It seems the feature "Determine argument type automatically from default" described on issue #22
breaks the default value of None, which is pretty common idiom in python.

See, this works:

def main(posarg1, posarg2, posarg3=''):
    pass

But this does not:

def main(posarg1, posarg2, posarg3=None):
    pass

Output:

$ python plac_exp.py aaaa bbbb cccc
usage: plac_exp.py [-h] arg1 arg2 [arg3]
plac_exp.py: error: argument arg3: invalid NoneType value: 'cccc'

This idiom is very commonly used to differentiate falsy objects with is not None instead of just boolean check.

For instance, in the example above, empty string is a valid input for me and None is used to differentiate it from an omitted argument.

Syntax error when using flags on plac 0.9.6

Hello,

Using a straight copy-paste of example9.py as listed on http://micheles.github.io/plac/#scripts-with-flags , I get the following error:
./plactest00.py hello
./plactest00.py: line 3: syntax error near unexpected token (' ./plactest00.py: line 3: def main(verbose: ('prints more info', 'flag', 'v'), dsn: 'connection string'):'

I am a Python novice, so if I'm missing anything obvious I apologize in advance.

OS: Mac OS X 10.12.6
Python: Python 2.7.10
virtualenv:
certifi (2017.7.27.1)
chardet (3.0.4)
idna (2.6)
keyring (5.4)
pip (9.0.1)
plac (0.9.6)
requests (2.18.4)
setuptools (18.2)
urllib3 (1.22)
wheel (0.24.0)

How to call an intermediate function which calls project's main?

This looks like a very promising library for simplifying command line argument handling. However I have a use case which may not be handled. I read the documentation but am not sure if it is possible or not.

I was wondering how to go about calling an intermediate function (named facade) in a library that uses some arguments and then passes back to the project's main function?

eg.

def main(hdx_site: str = "prod", output_failures: bool = False):
    print(f"I only use output_failures which is {output_failures}")

if __name__ == "__main__":
    plac.call(main)

The library has the intermediate function, facade:

def facade(projectmainfn: Callable[[Any], None], **kwargs: Any):
    print(f"I do some setup and use hdx_site which is {hdx_site} then I call the project's main")
    projectmainfn(**kwargs)    

The plac.call line needs to use main to get the allowed command line arguments, but call facade passing main and the the parsed keyword arguments as parameters to facade. facade does some stuff using some of those arguments then calls main with them (although not all are actually used by main).

Is this possible somehow?

Make plac parser object easily available during execution

In some cases, the programmer has to perform additional validation of arguments 
beyond what is possible in Plac (for example, when arguments depend on each 
other or conflict with each other). When doing this additional validation, it 
would be nice to be able to print an error message followed by the script's 
help text, or simply print the help text by itself. I have an example 
implementation of this (linked below), but it's imperfect because it requires 
you to tell it how far up the stack the "main" function is. I wonder if it is 
possible to make available the "currently active" plac parser object, i.e. the 
parser generated by the latest call to "plac.call".

https://github.com/DarwinAwardWinner/placsupport/blob/master/placsupport/__init_
_.py

Original issue reported on code.google.com by [email protected] on 17 Jun 2012 at 8:39

How can we choose the function to call in the command line?

First of all, thank you very much for plac, it is a very useful tool.
I would like to know if it is possible to choose the function to call in the command line?
Simply by taking the example of the doc.

# updatedb.py
import sys
from datetime import datetime

def main(dsn, table='product', today=datetime.today()):
    "Do something on the database"
    print(dsn, table, today)

def main2(dsn, table='product', today=datetime.today()):
    "Do something on the database"
    print(dsn, table, today)

FUNCTION_MAP = {'main' : main, 
                'main2': main2}

if __name__ == '__main__':
    import plac
    plac.call(FUNCTION_MAP[sys.argv[1]])

Like this, an error is raised:
python updatedb.py "main2" hello
Is there a way? I don't think I saw an example like this in the doc. Thank you for your help.

plac does not work with console_scripts in setup.py

I'm writing a program that I want to distribute with a setup.py that contains the following lines:

entry_points={
        'console_scripts': [
            'git-explorer=git_explorer.cli:main',
            'git-explorer-similar=git_explorer.find_similar:main',
        ],
    },

the find_similar.py contains this:

if __name__ == '__main__':
    plac.call(main)

And the main function declaration looks like this:

@plac.annotations(
    repo_url=("Repository", "positional", None, str, None, 'REPOSITORY'),
    commit_id=("Commit", "positional", None, str, None, 'COMMIT'),
    limit=("Only search among the LIMIT latest commits (tip: supports negavive numbers)", "option", 'l', int, None, 'LIMIT'),
    fast=("Skip fetching if local repository exists", "flag", 's', bool, False),
    git_cache= ("Git repository dir", "option", 'g', str, GIT_CACHE, 'GIT_CACHE'),
    verbose=("Verbose", "flag", 'v', bool),
    )
def main(repo_url, commit_id, limit=0, fast=False, git_cache=GIT_CACHE, verbose=False):
.....
.....

Now, if I install the package and try to use the console script git-explorer-similar I get the following:

Traceback (most recent call last):
  File "/home/xxxxxx/.local/share/virtualenvs/git_explorer-Hd8x6_Ku/bin/git-explorer-similar", line 11, in <module>
    load_entry_point('git-explorer', 'console_scripts', 'git-explorer-similar')()
TypeError: main() missing 2 required positional arguments: 'repo_url' and 'commit_id'

What is the correct way to use plac in combination with the console_scripts directive of a standard setup.py? I could not find anything in the otherwise excellent documentation...

Bug report: not working when type hint is str

Minimum code to replicate this bug:

Python 3.6.8 |Anaconda, Inc.| (default, Dec 29 2018, 19:04:46)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.4.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import plac

In [2]: def foo(a: str): return

In [3]: p = plac.parser_from(foo)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-3cd6684a2926> in <module>()
----> 1 p = plac.parser_from(foo)

~/anaconda3/lib/python3.6/site-packages/plac_core.py in parser_from(obj, **confparams)
    182         parser.addsubcommands(obj.commands, obj, 'subcommands')
    183     else:
--> 184         parser.populate_from(obj)
    185     return parser
    186

~/anaconda3/lib/python3.6/site-packages/plac_core.py in populate_from(self, func)
    332         for name, default in zip(f.args, alldefaults):
    333             ann = f.annotations.get(name, ())
--> 334             a = Annotation.from_(ann)
    335             metavar = a.metavar
    336             if default is NONE:

~/anaconda3/lib/python3.6/site-packages/plac_core.py in from_(cls, obj)
    136             return obj  # do nothing
    137         elif hasattr(obj, '__iter__') and not isinstance(obj, (str, bytes)):
--> 138             return cls(*obj)
    139         return cls(obj)
    140     from_ = classmethod(from_)

TypeError: type object argument after * must be an iterable, not type

In [4]:

The problematic code is here:

elif hasattr(obj, '__iter__') and not isinstance(obj, (str, bytes)):

Help confusing when default value is empty string

Plac shows default argument as argparse metavar. But when argparse is given a metavar of an empty string, the results look more like a flag than an option, which is confusing. (To be fair, there are differences, but very hard to spot.)

$ cat test_plac.py 
#!/usr/bin/env python
def func(opt: ('opt', 'option', 'o') = ''):
    print(opt)
import plac
plac.call(func)
$ ./test_plac.py -h
usage: test_plac.py [-h] [-o]

optional arguments:
  -h, --help   show this help message and exit
  -o , --opt   opt

Remaining Python 2 print

print >> sys.stderr, 'Process %d killed by CTRL-C' % os.getpid() in plac_tk.py will break in Python 3.

Thanks

Cannot parse Python 3.5/3.6 typing annotations

Following the examples in the documentation,


def main(dirname):
    """ Do something with this directory. 
    """

if __name__ == "__main__":
    import plac; plac.call(main)

works correctly. but changing the definition to

def main(dirname: str):

which is valid Python 3.5 (with typing package) or valid Python 3.6, results in

Traceback (most recent call last):
  File "process.py", line 47, in <module>
    import plac; plac.call(main)
  File "/home/user/.local/lib/python3.6/site-packages/plac_core.py", line 324, in call
    parser = parser_from(obj)
  File "/home/user/.local/lib/python3.6/site-packages/plac_core.py", line 133, in parser_from
    parser.populate_from(obj)
  File "/home/user/.local/lib/python3.6/site-packages/plac_core.py", line 257, in populate_from
    a = Annotation.from_(ann)
  File "/home/user/.local/lib/python3.6/site-packages/plac_core.py", line 91, in from_
    return cls(*obj)
TypeError: type object argument after * must be an iterable, not type

Multiline help string should be de-dented.

Thanks for the great tool. It is very enjoyable to use.

One problem that impacts usability is that multiline docstrings will be printed indented in the automatically generated help. This basically forces us to only have single quote docstrings which does two things, limits help to one line but also interferes with code formatting standards. Many tools will reformat docstrings to triple quote blocks.

I was wondering if you have plans to add an automatic de-denting of the docstring, or if not if you could point me to the code where I could add this de-denting myself in a local fork of the code.

thanks.

Improvement: Restructure project folder layout

I think current folder structure in the project is a bit confusing. First time I looked around I thought the project had no tests, for my first PR I then found them "hidden" in the doc folder, there is a lot of files in there and it is the only folder in the project.

Perhaps a layout like this could make things much more clearer to users and contributors:

plac/
│
├── docs/
│   ├── snippets/
│   │   ├── example1.py
│   │   ├── example2.py
│   │   ├── example3.help
│   │   ├── example3.py
│   │   └── ...
│   ├── plac_adv.rst
│   ├── plac_core.rst
│   └── plac.rst
│
├── plac/
│   ├── __init__.py
│   ├── core.py
│   ├── ext.py
│   ├── runner.py
│   └── tk.py
│
├── tests/
│   ├── test_ishelve_more.py
│   ├── test_ishelve.py
│   ├── test_pi.py
│   ├── test_plac.py
│   ├── test_runp.py
│   └── test_server.py
│
├── .travis.yml
├── LICENSE.txt
├── Makefile
├── MANIFEST.in
├── README.rst
├── setup.cfg
└── setup.py

Since plac supports multiple python versions, an added benefit would be easier future integration with tox.

Some interesting references on project layouts:

"raise etype, exc, tb" - python gives syntax error

What steps will reproduce the problem?
1. install python 3.2.3 and plac 0.9.1
2. in plac doc folder execute "example3.py foo"


What is the expected output? What do you see instead?

expected:
foo

instead:
Traceback (most recent call last):
  File "C:\Setup\ heruntergeladen\Python\plac-0.9.1.tar\dist\plac-0.9.1\doc\example3.py", line 8, in <module>
    import plac; plac.call(main)
  File "C:\run\Python\lib\site-packages\plac.py", line 35, in <module>
    from plac_ext import (Interpreter, import_main, ReadlineInput,
  File "C:\run\Python\lib\site-packages\plac_ext.py", line 33
    raise etype, exc, tb
               ^
SyntaxError: invalid syntax


What version of the product are you using? On what operating system?
Windows 7
Python 3.2.3
plac-0.9.1.tar.gz, downloaded from PyPi, installed via "python setup.py install"


Please provide any additional information below.
i have seen this multible tracebacks thing anywhere, but cant find it anymore, 
isnt that a new python 3.x thing?

Original issue reported on code.google.com by [email protected] on 2 Jul 2012 at 5:18

'choices' do not show up in help message.

I would expect this decoration
@plac.opt('n', "Number of iterations", type=int, choices=[100,200] )
to show the choices on the help message (like it does using argparse directly)

Example:
`@plac.pos('gds', "GDSII input file name", type=Path)
@plac.opt('out', "Optional output directory", type=Path)
@plac.opt('n', "Number of iterations", type=int, choices=[100,200] )
@plac.flg('debug', "Enable debug mode")
def main(
gds, # required
out='.', #optional. Default to cwd.
n=100, #optional. Example of int.
debug=False,#optional. Example of boolean.
):
''' What does this program not do? ''' # Displayed in usage message.

print(f"-gds {gds}")
print(f"-out {out}")
print(f"-n {n}")
print(f"-debug {debug}")

return
`

But output does not show choices 100, 200 :

...
optional arguments:
-h, --help show this help message and exit
-o ., --out . Optional output directory
-n 100, --n 100 Number of iterations
-d, --debug Enable debug mode

...

Nargs support

Is there a way to still support nargs while using plac? I know there is no plan to support it in plac but is there a workaround that can be used?

how to dynamically load modules and still use plac annotations?

Hi . I want to read a list of plugins from a config file, then dynamically generate usage and options parsing information for them. The config file is also specified via an argument on the command line invocation, but the modules are loaded with import_module at runtime based on the config.

Are there any examples of how to do this?

Not providing positional args when using a container class will not print out descriptive info with -h/help

def main():
    plac.Interpreter.(FooContainer)

class FooContainer(object):
    [...]
    commands=('foo_command',)
    @plac.annotate(
        foo="The default argument"
    )
    def __init__(self, foo):
        self.foo = foo

then run foo.py and get:

$  ./foo.py -h
usage: foo.py [-i] foo [args [args ...]]
foo.py: error: too few arguments


What is the expected output? What do you see instead?

For a user, it's important to know what the first argument can/should be.  the 
examples indicate that this can be done by outputting examples as though the 
full help messages, including annotations for the constructor of the container, 
but in practice I can't get this output. 

What version of the product are you using? On what operating system?
0.9 with argparse 1.2.1 on solaris 10.




Original issue reported on code.google.com by [email protected] on 14 Jul 2011 at 9:01

lack of simple documentation limits the reach of this tool

I really like this library and have been using it regularly.

While doing so made me realize several substantial limitations in the way this tool is documented and explained, that, in my opinion, is perhaps the greatest hindrance to the acceptance of the tool.

Whenever I forget the exact invocation or I want to look up more details I find that the documentation website at

https://micheles.github.io/plac/

is very tedious and non-supportive to help get things done. It has a long-winded writing style and goes into various tangential issues on the rationale. Overall it fails to support the practical use cases that a programmer needs and wants. Give us examples on how to use the tool.

Imagine that you are using a library and trying to look up the use cases, instead the documentation writer continuously talks about the rationale then and produces examples that are either too simplistic or too complicated - that is exactly how I feel reading the docs.

The entire library is meant to demonstrate the importance of scaling down" yet the help and documentation is anything but scaling down.

In the eagerness to demonstrate how easy is to use the library everything is documented in several, alternative and different ways - only adding to the confusion.

The actual feature that everyone will eventually use for anything but the most trivial code is listed deep down in the "More features" section, this is the line I have to constantly find to remind myself of the order of annotations:

(help, kind, abbrev, type, choices, metavar)

The entire documentation should start with a simple example like so

@plac.annotations(
    fname=("input file", "option", "f", str, None, "PATH"),
    count=("word count", "option", "c", int, None, "INT"),
)
def run(fname, count):
    pass

perhaps adding a few variants to cover the main use-cases

so that people can look that up and move on and not have to continuously scour through pages and pages of content they don't care about.

Automatically exported

Please change Description text

Automatically exported from code.google.com/p/plac

into

Plac: Parsing the Command Line the Easy Way

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.