docopt / docopt

Create *beautiful* command-line interfaces with Python
MIT License
7.94k stars 557 forks source link

Crashes with "from __future__ import print_function" #133

Open mhubig opened 11 years ago

mhubig commented 11 years ago

Hi @halst,

found a bug today. docopt crashes with this example. But if you remove the from __future__ import print_function primer, all works fine.

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

from __future__ import print_function
from docopt import docopt

"""HTML Cleaner.

Usage:
  cleanup [-p | --pretty] <element> <replacement> <filename>
  cleanup (-h | --help)
  cleanup (-V | --version)

Options:
  -h --help     Show this screen.
  -p --pretty   Prettify the output.
  -V --version  Show version.

"""
if __name__ == '__main__':
    arguments = docopt(__doc__, version='0.1.0')
    print(arguments)

Here is the traceback I get. Im using python 2.7.5

$ python test.py
Traceback (most recent call last):
  File "test.py", line 21, in <module>
    arguments = docopt(__doc__, version='0.1.0')
  File "/Users/markus/Development/hp/ENV/lib/python2.7/site-packages/docopt.py", line 558, in docopt
    DocoptExit.usage = printable_usage(doc)
  File "/Users/markus/Development/hp/ENV/lib/python2.7/site-packages/docopt.py", line 466, in printable_usage
    usage_split = re.split(r'([Uu][Ss][Aa][Gg][Ee]:)', doc)
  File "/Users/markus/Development/hp/ENV/lib/python2.7/re.py", line 173, in split
    return _compile(pattern, flags).split(string, maxsplit)
TypeError: expected string or buffer
mhubig commented 11 years ago

Ups false one. It was my mistake ... seems the doctring must be on to of the file. This works:

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

"""HTML Cleaner.

Usage:
  cleanup [-p | --pretty] <element> <replacement> <filename>
  cleanup (-h | --help)
  cleanup (-V | --version)

Options:
  -h --help     Show this screen.
  -p --pretty   Prettify the output.
  -V --version  Show version.

"""

from __future__ import print_function
from docopt import docopt

if __name__ == '__main__':
    arguments = docopt(__doc__, version='0.1.0')
    print(arguments)
keleshev commented 11 years ago

Interesting, thoug, that the error was so obscure. Some runtime type checking on docopt might improve this.

e3krisztian commented 10 years ago

I have also run into this on first use, interestingly I also used from __future__ import unicode_literals. Generally from __future__ works only when it is "first thing" in file - before all other imports (otherwise python says SyntaxError: from __future__ imports must occur at the beginning of the file)!

But __doc__ is None if there is anything executable before the "doc-string".


The confusion about which comes first from the doc-string and __future__ imports are highlighted by this experiment:

experiment.py:

'''
doc
'''

from __future__ import unicode_literals

print(type(__doc__))

python experiment.py prints <type 'unicode'> for me (Python 2.7.5+ - ubuntu), so __future__ import has influence over __doc__'s type, which precedes it!

j-funk commented 7 years ago

Just ran into this - grateful for the thread.