Open ASMfreaK opened 6 years ago
A quick hack that I'm using for now:
from plumbum import cli
class GummyBear(str):
def __new__(cls, tids: str):
if not n.startswith('gummybear'):
raise ValueError('{} is not a gummybear!'.format(n))
return n
class GummyConsumer(cli.Application):
def main(self, bear: GummyBear):
print('MUNCH MUNCH MUNCH')
$ python gummy_new.py gummybear
MUNCH MUNCH MUNCH
$ python gummy_new.py gummybe
Error: Argument of bear expected to be <class '__main__.GummyBear'>, not 'gummybe':
ValueError('gummybe is not a gummybear!',)
------
Usage:
gummy_new.py [SWITCHES] bear
Meta-switches
-h, --help Prints this help message and quits
--help-all Print help messages of all subcommands and quit
-v, --version Prints the program's version and quits
$ mypy gummy_new.py
gummy_new.py:2: error: Cannot find module named 'plumbum'
gummy_new.py:2: note: (Perhaps setting MYPYPATH or using the "--ignore-missing-imports" flag would help)
you can see it in my repo
Traceback (most recent call last):
File "gummy.py", line 12, in <module>
GummyConsumer.run()
File "plumbum/cli/application.py", line 480, in run
ordered, tailargs = inst._validate_args(swfuncs, tailargs)
File "plumbum/cli/application.py", line 431, in _validate_args
positional[args_names.index(item)] = m.annotations[item]
ValueError: 'return' is not in list
This traceback is triggered if main()
of cli.Application
has a typed return i.e.:
class GummyConsumer(cli.Application):
def main(self, bear: GummyBear) -> None:
print('MUNCH MUNCH MUNCH')
This should be sorted out somehow for #334 for full typing information.
I'm planning on looking at this eventually, but feel free to investigate, you might be faster!
I'm not sure what the fix would be; a function is not a type, so it is invalid for MyPy. Your workaround is of course reasonable, but don't know of a simpler way.
Correction: the most recent problem should be an easy fix. Try the mypy
branch.
It might be possible for Predicate to transform:
@cli.Predicate
def GummyBear(n) -> str:
if not n.startswith('gummybear'):
raise ValueError('{} is not a gummybear!'.format(n))
return n
to
GummyBear = type('GummyBear', str, '__new__':...)
No, I don't think this will work. Mypy is very static and won't understand (at least for now) the runtime type creation. For now, we should use the class-__new__
workaround as mypy developers are yet to agree on decorators annotations (python/mypy#3157), so I guess this issue is blocked until they are done
@ASMfreaK, yes, I played around with MyPy and realized that wouldn't work.
mypy complains about functions wrapped with
plumbum.cli.Predicate
:error: Invalid type "..."
An example:This should be made consistent