Fix command line argument parsing with Click 6.x

On win32 systems, Click 6.x uses win32 library functions to retrieve
the command line arguments in order to not have their encoding
destroyed. That clashes with rewriting of sys.argv like e.g. the PyCharm
debugger is doing it, causing the debugger parameters to be passed
on to the click parser.

Added a workaround that detects if sys.argv and the os specific
argument list don't have the same length and truncates the os specific
list if that is the case, in order to not pass on arguments from the os
that where already cut off from sys.argv by something else.
This commit is contained in:
Gina Häußge 2016-03-23 12:05:45 +01:00
parent 1d3dfffc67
commit a462f1ce3d

View file

@ -207,8 +207,33 @@ def init_pluginsystem(settings):
#~~ server main method
def main():
import sys
# os args are gained differently on win32
from click.utils import get_os_args
args = get_os_args()
if len(args) >= len(sys.argv):
# Now some ugly preprocessing of our arguments starts. We have a somewhat difficult situation on our hands
# here if we are running under Windows and want to be able to handle utf-8 command line parameters (think
# plugin parameters such as names or something, e.g. for the "dev plugin:new" command) while at the same
# time also supporting sys.argv rewriting for debuggers etc (e.g. PyCharm).
#
# So what we try to do here is solve this... Generally speaking, sys.argv and whatever Windows returns
# for its CommandLineToArgvW win32 function should have the same length. If it doesn't however and
# sys.argv is shorter than the win32 specific command line arguments, obviously stuff was cut off from
# sys.argv which also needs to be cut off of the win32 command line arguments.
#
# So this is what we do here.
# -1 because first entry is the script that was called
sys_args_length = len(sys.argv) - 1
# cut off stuff from the beginning
args = args[-1 * sys_args_length:] if sys_args_length else []
from octoprint.cli import octo
octo(prog_name="octoprint", auto_envvar_prefix="OCTOPRINT")
octo(args=args, prog_name="octoprint", auto_envvar_prefix="OCTOPRINT")
if __name__ == "__main__":