| 1 |  |  | """Run docopt in GOATOOLS.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | from __future__ import print_function | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | __copyright__ = "Copyright (C) 2016-2018, DV Klopfenstein, H Tang, All rights reserved." | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | __author__ = "DV Klopfenstein" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | import sys | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  | import re | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | from docopt import docopt | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  | from goatools.gosubdag.utils import get_kwargs | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  | class DocOptParse(object): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  |     """Run docopt in GOATOOLS.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  |     def __init__(self, doc, exp_keys, exp_elems): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  |         self.doc = doc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  |         self.exp_keys = exp_keys if exp_keys else set()     # Expected dictionary keys | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  |         self.exp_elems = exp_elems if exp_elems else set()  # Expected set elements (True/False) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  |     def get_docargs(self, args=None, prt=None, **kws): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  |         """Pare down docopt. Return a minimal dictionary and a set containing runtime arg values.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  |         args_user = sys.argv[1:] if args is None else args | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  |         arg_kws = self._get_docargs(args_user, prt) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  |         if 'intvals' in kws: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  |             self._set_intvals(arg_kws, kws['intvals']) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |         return arg_kws | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  |     def _get_docargs(self, args_user, prt): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  |         """Pare down docopt. Return a minimal dictionary and a set containing runtime arg values.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  |         if prt is not None: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  |             print("DocOptParse BEFORE docopt: {}".format(args_user)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  |         docargs = docopt(self.doc, args_user) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  |         if prt is not None: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  |             print("DocOptParse AFTER  docopt: {}".format(docargs)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  |         kwargs_doc = {re.sub(r'^-{1,2}', '', k):v for k, v in docargs.items()} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |         self._chk_docopt_kws(kwargs_doc, args_user) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  |         kwargs_usr = get_kwargs(kwargs_doc, self.exp_keys, self.exp_elems) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  |         if prt is not None: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |             print("DocOptParse AFTER  pared: {}".format(kwargs_usr)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |         for key in ['taxid']: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |             if key in kwargs_usr: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |                 kwargs_usr[key] = int(kwargs_usr[key]) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |         if prt is not None: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |             print("DocOptParse AFTER  edited/checked: {}".format(kwargs_usr)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |         return kwargs_usr | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 48 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 49 |  |  |     @staticmethod | 
            
                                                                        
                            
            
                                    
            
            
                | 50 |  |  |     def _set_intvals(kws, keys): | 
            
                                                                        
                            
            
                                    
            
            
                | 51 |  |  |         """Convert keyword values to int.""" | 
            
                                                                        
                            
            
                                    
            
            
                | 52 |  |  |         for key in keys: | 
            
                                                                        
                            
            
                                    
            
            
                | 53 |  |  |             if key in kws: | 
            
                                                                        
                            
            
                                    
            
            
                | 54 |  |  |                 kws[key] = int(kws[key]) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |     def _chk_docopt_exit(self, args, exp_letters): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |         """Check if docopt exit was for an unknown argument.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |         if args is None: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |             args = sys.argv[1:] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |         keys_all = self.exp_keys.union(self.exp_elems) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |         if exp_letters: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |             keys_all |= exp_letters | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |         unknown_args = self._chk_docunknown(args, keys_all) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |         if unknown_args: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |             raise RuntimeError("{USAGE}\n    **FATAL: UNKNOWN ARGS: {UNK}".format( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |                 USAGE=self.doc, UNK=" ".join(unknown_args))) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |     def _chk_docopt_kws(self, docdict, exp): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |         """Check for common user errors when running from the command-line.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |         for key, val in docdict.items(): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  |             if isinstance(val, str): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |                 assert '=' not in val, self._err("'=' FOUND IN VALUE", key, val, exp) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |             elif key != 'help' and key not in self.exp_keys and key not in self.exp_elems: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  |                 raise RuntimeError(self._err("UNKNOWN KEY", key, val, exp)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |     def _err(self, msg, key, val, exp): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |         return "{DOC}\n{MSG}: KEY({K}) VAL({V}): {EXP}".format( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |             DOC=self.doc, MSG=msg, K=key, V=val, EXP=" ".join(exp)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |     @staticmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |     def _chk_docunknown(args, exp): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  |         """Return any unknown args.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |         unknown = [] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |         for arg in args: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |             if arg[:2] == '--': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |                 val = arg[2:] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |                 if val not in exp: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |                     unknown.append(arg) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |             elif arg[:1] == '-': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |                 val = arg[1:] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |                 if val not in exp: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  |                     unknown.append(arg) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |         if '-h' in unknown or '--help' in unknown: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |             return [] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  |         return unknown | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |  | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 98 |  |  | # Copyright (C) 2016-2018, DV Klopfenstein, H Tang, All rights reserved. | 
            
                                                        
            
                                    
            
            
                | 99 |  |  |  |