From 2a71297a6844162a6fa1cb55213c87243369d404 Mon Sep 17 00:00:00 2001 From: chriskiehl Date: Mon, 25 May 2015 16:16:16 -0400 Subject: [PATCH] Code cleanup --- gooey/python_bindings/config_generator.py | 3 +- gooey/python_bindings/docopt_to_json.py | 76 ++++++++++++++++++ gooey/python_bindings/gooey_decorator.py | 97 +++++------------------ 3 files changed, 100 insertions(+), 76 deletions(-) create mode 100644 gooey/python_bindings/docopt_to_json.py diff --git a/gooey/python_bindings/config_generator.py b/gooey/python_bindings/config_generator.py index 036467b..2752250 100644 --- a/gooey/python_bindings/config_generator.py +++ b/gooey/python_bindings/config_generator.py @@ -20,7 +20,8 @@ def create_from_parser(parser, source_path, **kwargs): 'default_size': kwargs.get('default_size', (610, 530)), 'requireds_cols': kwargs.get('required_cols', 1), 'optionals_cols': kwargs.get('optional_cols', 3), - 'manual_start': False + 'manual_start': False, + 'layout_type': 'column' } if show_config: diff --git a/gooey/python_bindings/docopt_to_json.py b/gooey/python_bindings/docopt_to_json.py new file mode 100644 index 0000000..fb0c763 --- /dev/null +++ b/gooey/python_bindings/docopt_to_json.py @@ -0,0 +1,76 @@ + +""" +Naval Fate. + +Usage: + naval_fate.py ship new ... + naval_fate.py ship move [--speed=] + naval_fate.py ship shoot + naval_fate.py mine (set|remove) [--moored|--drifting] + naval_fate.py -h | --help + naval_fate.py --version + +Options: + -h --help Show this screen. + --version Show version. + --speed= Speed in knots [default: 10]. + --moored Moored (anchored) mine. + --drifting Drifting mine. + +""" + +# Standard +# choice +# counter +# flag +# mutually_exclusive +# +# types? + + + +from docopt import docopt, Option, Argument + + +class MyOption(Option): + def __init__(self, *args, **kwargs): + self.description = kwargs.pop('description', None) + super(MyOption, self).__init__(*args, **kwargs) + + + @classmethod + def parse(class_, option_description): + short, long, argcount, value = None, None, 0, False + options, _, description = option_description.strip().partition(' ') + options = options.replace(',', ' ').replace('=', ' ') + for s in options.split(): + if s.startswith('--'): + long = s + elif s.startswith('-'): + short = s + else: + argcount = 1 + if argcount: + matched = re.findall('\[default: (.*)\]', description, flags=re.I) + value = matched[0] if matched else None + return class_(short, long, argcount, value, description=description.strip()) + + def __repr__(self): + return 'Option(%r, %r, %r, %r, %r)' % (self.short, self.long, + self.argcount, self.value, self.description) + + +if __name__ == '__main__': + import sys + a = docopt(__doc__) + # import re + # doc = __doc__ + # split = re.split('\n *(<\S+?>|-\S+?)', doc)[1:] + # split = [s1 + s2 for s1, s2 in zip(split[::2], split[1::2])] + # options = [MyOption.parse(s) for s in split if s.startswith('-')] + # arguments = [Argument.parse(s) for s in split if s.startswith('<')] + # #return options, arguments + # print arguments + # print options + print a + a = 10 diff --git a/gooey/python_bindings/gooey_decorator.py b/gooey/python_bindings/gooey_decorator.py index bbb8364..03015b7 100644 --- a/gooey/python_bindings/gooey_decorator.py +++ b/gooey/python_bindings/gooey_decorator.py @@ -3,88 +3,21 @@ Created on Jan 24, 2014 @author: Chris -Hey, whaduya know. This is out of date again. TODO: update giant doctring. - - -##How things work these days (though, likely to change) - -The decorator is used solely as a nice way to get the location -of the executing script. It no longer returns a decorated version -of the client code, but in fact completely hijacks the execution. -So, rather than returning a reference to the client's main, it now -returns itself, thus short-circuiting the execution of the client -program. - -What it DOES do now is grab where the client module is stored and -read it in as a file so that it can hack away at it. - -The first step, as before, is getting the ArgumentParser reference -so that the needed values can be extracted. This is done by reading -the source file up to the point where the `parse_args()` method is -called. This puts us smack in the middle of the client's `main` method. - -This first half guarantees that all imports, modules, variable assignments, -etc.. are caught (unlike before). - -Next step: getting the rest of the source code that's relevant - -The file is again read up to the `parse_args` call, but this time everything -leading up to that point is dropped and we keep only the remainder of the file. -So, now the top and the bottom is located, but the bottom needs to be trimmed a -little more -- we want to drop everything remaining in the main method. - -So, we `dropwhile` lines are currently indented (and thus still part of the `main` -method) - -Finally, we arrive at the end, which gives us an exact copy of the original source -file, minus all of it's main logic. The two pieces are then sandwiched together, -saved to a file, and imported as a new module. Now all that has to be done is call -it (moddified) main function, and bam! It returns to fully populated parser object -to us. No more complicated ast stuff. Just a little bit of string parsing and we're -done. - +TODO: this ''' -from argparse import ArgumentParser -import json import os -import sys +import json import atexit import tempfile -import source_parser -import config_generator - -from gooey.gui import application -from gooey.gui.windows import layouts -from gooey.python_bindings import argparse_to_json - - -def decorator(func): - def graphical_parse_args(self, args=None, namespace=None): - values = [raw_input("Enter %s (%s):" % (a.dest, a.help)) for a in self._actions] - raw_input('Press enter to start') - # update new args with what you get from the graphical widgets - return self.original_parse_args(arg_lst, namespace) - def inner(*args, **kwargs): - ArgumentParser.original_parse_args = ArgumentParser.parse_args - ArgumentParser.parse_args = graphical_parse_args - return func(*args, **kwargs) +from . import source_parser +from . import config_generator +from gooey.gui import application - return inner - -def store_executable_copy(): - main_module_path = get_caller_path() - _, filename = os.path.split(main_module_path) - cleaned_source = clean_source(main_module_path) - - descriptor, tmp_filepath = tempfile.mkstemp(suffix='.py') - atexit.register(cleanup, descriptor, tmp_filepath) +from argparse import ArgumentParser - with open(tmp_filepath, 'w') as f: - f.write(cleaned_source) - return tmp_filepath def Gooey(f=None, advanced=True, @@ -93,7 +26,7 @@ def Gooey(f=None, program_name=None, program_description=None, default_size=(610, 530), - required_cols=3, + required_cols=2, optional_cols=2, dump_build_config=False): ''' @@ -111,7 +44,7 @@ def Gooey(f=None, if dump_build_config: config_path = os.path.join(os.getcwd(), 'gooey_config.json') - print 'Writing Build Config to: {}'.format(config_path) + print( 'Writing Build Config to: {}'.format(config_path)) with open(config_path, 'w') as f: f.write(json.dumps(build_spec, indent=2)) @@ -130,6 +63,19 @@ def Gooey(f=None, return build +def store_executable_copy(): + main_module_path = get_caller_path() + _, filename = os.path.split(main_module_path) + cleaned_source = clean_source(main_module_path) + + descriptor, tmp_filepath = tempfile.mkstemp(suffix='.py') + atexit.register(cleanup, descriptor, tmp_filepath) + + with open(tmp_filepath, 'w') as f: + f.write(cleaned_source) + return tmp_filepath + + def clean_source(module_path): with open(module_path, 'r') as f: return ''.join( @@ -140,6 +86,7 @@ def clean_source(module_path): def get_parser(module_path): return source_parser.extract_parser(module_path) + def get_caller_path(): tmp_sys = __import__('sys') return tmp_sys.argv[0]