igdZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl mZddlmZddlmZmZmZmZmZmZmZmZmZmZmZmZddlmZddl m!Z!m"Z"erddl#Z#e j$e%Z&ne j$Z&ed Z'd e%d e(fd Z)d e%d e%fd Z*d e%d e%fdZ+d e%d e%fdZ,ded e(fdZ-GddZ.de%d e(fdZ/dee'd ee'fdZ0de%d e%fdZ1dee%d ee%fdZ2de%d ee3e%ffdZ4de%d eee3e%ffdZ5dee%d ee%fdZ6d ee%d!ee%d dfd"Z7d ee%d#ee%d dfd$Z8d%e%d e%fd&Z9d ee%d dfd'Z:d ee%fd(Z;ej<fd)e%d*e3d ee%fd+Z=ej<fd,ee%d*e3d ee%fd-Z>d.e%d ee%fd/Z?Gd0d1Z@Gd2d3ZAGd4d5ZBGd6d7ZCGd8d9ZDd:ee%d ee%fd;ZEGd<d=eZFd>dd?d@dAdBe%dCeFdDe%dEee3dFe3dGe(d e%fdHZGd>dd?d@dAdBe%dDe%dEee3dFe3dGe(d e%f dIZHd>dd?d@dAdBe%dDe%dEee3dFe3dGe(d e%f dJZId>dd?d@dAdBe%dDe%dEee3dFe3dGe(d e%f dKZJd?dLdMe%dNe3dFe3d e%fdOZKdBe%d ee3e%ffdPZLdQeedRefeedReffdSe%d dfdTZMdUedRefd eeefdVZNGdWdXeZOGdYdZZPd[e%d e%fd\ZQd]e%d^e%d eRfd_ZSd`ZT dedae%dbee%dceee%e%geRfd ee%fddZUdS)fzShared utility functionsN)SequenceMatcher)Enum) TYPE_CHECKINGAnyCallableDictIterableListOptionalTextIOTypeTypeVarUnioncast) constants)ChoicesProviderFunc CompleterFunc_Targreturnctt|dko%|d|dko|dtjvS)z Checks if a string is quoted :param arg: the string being checked for quotes :return: True if a string is quoted rr)lenrQUOTESrs Z/home/jenkins/workspace/simtester-sanitize/venv/lib/python3.11/site-packages/cmd2/utils.py is_quotedr7s7 s88a< LCFc"g- L#a&I>  s4yy ( (4 ^^  U + +5CDDD C   CyyrceZdZdZdddddddedeeeeegeffdede de ed e eee e gefd e e ed e e d e ed dfdZd efdZded dfdZdS)SettablezLUsed to configure an attribute to be settable via the set command in the CLIN)settable_attrib_name onchange_cbchoiceschoices_provider completernameval_type descriptionsettable_objectr5r6r7r8r9rc|tur2dttfd} t}t t | }||_||_||_||_ ||n||_ ||_ ||_ ||_ | |_dS)a  Settable Initializer :param name: name of the instance attribute being made settable :param val_type: callable used to cast the string value from the command line into its proper type and even validate its value. Setting this to bool provides tab completion for true/false and validation using to_bool(). The val_type function should raise an exception if it fails. This exception will be caught and printed by Cmd.do_set(). :param description: string describing this setting :param settable_object: object to which the instance attribute belongs (e.g. self) :param settable_attrib_name: name which displays to the user in the output of the set command. Defaults to `name` if not specified. :param onchange_cb: optional function or method to call when the value of this settable is altered by the set command. (e.g. onchange_cb=self.debug_changed) Cmd.do_set() passes the following 3 arguments to onchange_cb: param_name: str - name of the changed parameter old_value: Any - the value before being changed new_value: Any - the value after being changed The following optional settings provide tab completion for a parameter's values. They correspond to the same settings in argparse-based tab completion. A maximum of one of these should be provided. :param choices: iterable of accepted values :param choices_provider: function that provides choices for this argument :param completer: tab completion function that provides choices for this argument rc ddgS)z-Used to tab complete lowercase boolean valuestruefalser#)_s rget_bool_choicesz+Settable.__init__..get_bool_choicess ((rN)r1r r.r2rrr:r;r< settable_objr5r6r7r8r9) selfr:r;r<r=r5r6r7r8r9rCs r__init__zSettable.__init__ysP t   )tCy ) ) ) )H#$79IJJ    &+ > > > > # " " "r)__name__ __module__ __qualname____doc__r.rr rrobjectr rr rrrFrJrUr#rrr4r4vs4VV/3>B+/:>-19#9#9#9#S 8SE3J#7789# 9#  9#'sm9#hR}c'9:;9#(3-(9###679#M*9# 9#9#9#9#vE3EEEE?s?t??????rr4 file_pathcddl}tjtj|}d} ||dd5}td|Ddkrd}dddn #1swxYwYn#t$rt$rYnwxYw|S) zReturns if a file contains only ASCII or UTF-8 encoded text and isn't empty. :param file_path: path to the file being checked :return: True if the file is a non-empty text file, otherwise False :raises OSError: if file can't be read rNFutf-8strictencodingerrorsc3K|]}dVdS)rNr#).0rBs r zis_text_file..s..1......rT) codecsospathabspath expanduserstripopensumOSErrorUnicodeDecodeError)r[re expanded_pathvalid_text_filefs r is_text_filerrsMMMGOOBG$6$6y7H7H$I$IJJMO  [[[ J J 'a..a...  1$$"& ' ' ' ' ' ' ' ' ' ' ' ' ' ' '        s6B&. B B&BB&!B"B&&B=<B= list_to_prunec~tj}|D]}d||<t|S)zRemoves duplicates from a list while preserving order of the items. :param list_to_prune: the list being pruned of duplicates :return: The pruned list N) collections OrderedDictlistkeys)rs temp_dictitems rremove_duplicatesr{sD 3>2I2K2KI $    ! !!rastrcPtjd|S)zNormalize and casefold Unicode strings for saner comparisons. :param astr: input unicode string :return: a normalized and case-folded version of the input string NFC) unicodedata normalizecasefold)r|s r norm_foldrs#   - - 6 6 8 88r list_to_sortc.t|tS)a)Sorts a list of strings alphabetically. For example: ['a1', 'A11', 'A2', 'a22', 'a3'] To sort a list in place, don't call this method, which makes a copy. Instead, do this: my_list.sort(key=norm_fold) :param list_to_sort: the list being sorted :return: the sorted list key)sortedrrs ralphabetical_sortrs ,I . . ..r input_strc` t|S#t$rt|cYSwxYw)z Tries to convert the passed-in string to an integer. If that fails, it converts it to lower case using norm_fold. :param input_str: string to convert :return: the string as an integer or a lower case version of the string )intr0rrs rtry_int_or_force_to_lower_casersB $9~~ $$$#####$s --c@dtjd|DS)a Converts a string into a list of integers and strings to support natural sorting (see natural_sort). For example: natural_keys('abc123def') -> ['abc', '123', 'def'] :param input_str: string to convert :return: list of strings and integers c,g|]}t|Sr#)r)rcsubstrs r z natural_keys..#s! _ _ _v *6 2 2 _ _ _rz(\d+))resplitrs r natural_keysrs& ` _(T]A^A^ _ _ __rc.t|tS)aV Sorts a list of strings case insensitively as well as numerically. For example: ['a1', 'A2', 'a3', 'A11', 'a22'] To sort a list in place, don't call this method, which makes a copy. Instead, do this: my_list.sort(key=natural_keys) :param list_to_sort: the list being sorted :return: the list sorted naturally r)rrrs r natural_sortr&s ,L 1 1 11rtokenstokens_to_quotec\t|D]\}}||vrt|||<dS)z Quote specific tokens in a list :param tokens: token list being edited :param tokens_to_quote: the tokens, which if present in tokens, to quote N) enumerater%)rritokens rquote_specific_tokensr6sFf%%,,5 O # #$U++F1I,,rtokens_to_unquotec`t|D]\}}t|}||vr|||<dS)z Unquote specific tokens in a list :param tokens: token list being edited :param tokens_to_unquote: the tokens, which if present in tokens, to unquote N)rr*)rrrrunquoted_tokens runquote_specific_tokensrBsLf%%''5%e,, . . .&F1I''rrc|rRt|r|d}t|}nd}tj|}|r||z|z}|S)zn Wrap os.expanduser() to support expanding ~ in quoted strings :param token: the string to expand r)rr*rfrgri)r quote_chars r expand_userrOsl  4 U   qJ ''EEJ""5))  4&3E Lrc`t|D]\}}t||||<dS)zc Call expand_user() on all tokens in a list of strings :param tokens: tokens to expand N)rr)rindexrBs rexpand_user_in_tokensrds@ f%%33q#F5M22u 33rctjd}|s"tjdddkrgd}ngd}tjd}|g}n.d|tjjD}tj ||D]\}}tj ||}tj |r^tj |tjr?tjdddkr%tj|d }nd}|S) z Used to set cmd2.Cmd.DEFAULT_EDITOR. If EDITOR env variable is set, that will be used. Otherwise the function will look for a known editor in directories specified by PATH env variable. :return: Default editor or None EDITORNwin)zcode.cmdz notepad++.exez notepad.exe) vimviemacsnanopicojoecodesublatomgeditgeanykatePATHcPg|]#}tj|!|$Sr#rfrgislinkrcps rrzfind_editor..s,YYY1rw~~VWGXGXYQYYYrr)rfenvirongetsysplatformgetenvrrgpathsep itertoolsproductrNisfileaccessX_OKsplitext)editoreditorsenv_pathpathsrg editor_paths r find_editorrms. Z^^H % %F  < u $ $BBBGGuuuG9V$$  EEYYrw ? ?YYYE%-gu==  LFD',,tV44Kw~~k** rybg/N/N <#u,,W--f55a8FF MrpatternrcDfdtj|DS)avReturn a list of file paths based on a glob pattern. Only files are returned, not directories, and optionally only files for which the user has a specified access to. :param pattern: file name or glob pattern :param access: file access type to verify (os.* where * is F_OK, R_OK, W_OK, or X_OK) :return: list of files matching the name or glob pattern c|g|]8}tj|!tj|6|9Sr#)rfrgrr)rcrqrs rrz+files_from_glob_pattern..s> X X X!RW^^A->-> X29QPVCWCW XA X X Xr)glob)rrs `rfiles_from_glob_patternrs* Y X X Xty)) X X XXrpatternsc`g}|D](}t||}||)|S)aReturn a list of file paths based on a list of glob patterns. Only files are returned, not directories, and optionally only files for which the user has a specified access to. :param patterns: list of file names and/or glob patterns :param access: file access type to verify (os.* where * is F_OK, R_OK, W_OK, or X_OK) :return: list of files matching the names and/or glob patterns r)rextend)rrfilesrmatchess rfiles_from_glob_patternsrsD E)'&AAA W Lr starts_withcddg}|D] }||vrgcS tjd}|g}n.d|tjjD}t }|D]w}tj||}t|dztj}|D]4} | tj | 5xt|S)zReturns names of executables in a user's path :param starts_with: what the exes should start with. leave blank for all exes in path. :return: a list of matching exe names *?rNcPg|]#}tj|!|$Sr#rrs rrz$get_exes_in_path..s,UUUq27>>RSCTCTUUUUrr) rfrrrgrsetrNrraddbasenamerw) r wildcardswildcardrrexes_setrg full_pathrmatchs rget_exes_in_pathrsc I { " "III #y  HUUHNN27?;;UUUuuH22GLL{33 ))c/"'JJJ 2 2E LL))%00 1 1 1 1 2 >>rc eZdZdZdddddeedfdeded ed d f d Zd ed d fdZ d efdZ d e fdZ dde ed efdZd e fdZddZd efdZed efdZded efdZd S)StdSimz Class to simulate behavior of sys.stdout or sys.stderr. Stores contents in internal buffer and optionally echos to the inner stream it is simulating. Fr]replace)echor`ra inner_streamrr`rarNct||_||_||_||_d|_t ||_dS)an StdSim Initializer :param inner_stream: the wrapped stream. Should be a TextIO or StdSim instance. :param echo: if True, then all input will be echoed to inner_stream :param encoding: codec for encoding/decoding strings (defaults to utf-8) :param errors: how to handle encoding/decoding errors (defaults to replace) FN)rrr`ra pause_storageByteBufbuffer)rErrr`ras rrFzStdSim.__init__s: )    "dmm rsc*t|tstdt||js4|jxj||j|j z c_|j r|j |dSdS)z Add str to internal bytes buffer and if echo is True, echo contents to inner stream :param s: String to write to the stream z"write() argument must be str, not r_N) r-r. TypeErrortyperrbyte_bufencoder`rarrwrite)rErs rrz StdSim.writes !S!! LJaJJKK K! Y K AHHdmDKH$X$X X 9 '   # #A & & & & & ' 'rcX|jj|j|jS)z"Get the internal contents as a strr_)rrdecoder`rarIs rgetvaluezStdSim.getvalues${#**DM$+*VVVrc4t|jjS)z"Get the internal contents as bytes)bytesrrrIs rgetbyteszStdSim.getbytessT[)***rrsizec ||dkr)|}|nQ|jjd||j|j}|jj|d|j_|S)z Read from the internal contents as a str and then clear them out :param size: Number of bytes to read from the stream Nrr_)rclearrrrr`ra)rErresults rreadz StdSim.readsv <42::]]__F JJLLLL[)%4%077W[Wb7ccF#';#7#>DK  rcV|}||S)z@Read from the internal contents as bytes and then clear them out)rr)rErs r readbyteszStdSim.readbytes s!  rcB|jjdS)zClear the internal contentsN)rrrrIs rrz StdSim.clears ""$$$$$rcF|jr|jSdS)z[StdSim only considered an interactive stream if `echo` is True and `inner_stream` is a tty.F)rrisattyrIs rr z StdSim.isattys& 9 $++-- -5rcX t|jjS#t$rYdSwxYw)z Handle when the inner stream doesn't have a line_buffering attribute which is the case when running unit tests because pytest sets stdout to a pytest EncodedFile object. F)r1rline_bufferingAttributeErrorrIs rr zStdSim.line_bufferings=  )899 9   55 s  ))rzcX||jvr |j|St|j|SN)__dict__rHr)rErzs r __getattr__zStdSim.__getattr__)s/ 4= =& &4,d33 3r)rrN)rVrWrXrYrr r1r.rFrrrrr rrrrr propertyr rrr#rrrrs $$$FH,-$ $  $  $ $$$$. 's 't ' ' ' 'W#WWWW+%++++  #     5 %%%%X44444444rrc:eZdZdZddgZdeddfdZdeddfd ZdS) rzQ Used by StdSim to write binary data and stores the actual bytes written   std_sim_instancerNc:t|_||_dSr) bytearrayrr)rErs rrFzByteBuf.__init__8s!  0rbcttstdt|jjs|xjz c_|jjrp|jjj |jj rBtfdtjDr|jdSdSdSdS)zVAdd bytes to internal bytes buffer and if echo is True, echo contents to inner stream.z%a bytes-like object is required, not c3 K|]}|vV dSrr#)rcnewliners rrdz ByteBuf.write..Js'DDw!|DDDDDDrN)r-rrrrrrrrrrr anyrNEWLINESflush)rErs `rrz ByteBuf.write<s!U## OMDGGMMNN N$2  MMQ MM  % 2  ! . 5 ; ;A > > > $3 2DDDD73CDDDDD2)//11111 2 2 2 222r) rVrWrXrYr rrFrrr#rrrr0sm u~H11D11112u2222222rrceZdZdZdedeeefdeeefddfdZddZ dd Z dd Z d e ddfd Z ed eeefdeeefddfdZdS) ProcReaderz Used to capture stdout and stderr from a Popen process if any of those were set to subprocess.PIPE. If neither are pipes, then the process will run normally and no output will be captured. procstdoutstderrrNcT||_||_||_tjd|jddi|_tjd|jddi|_|jj|j |jj |j dSdS)z ProcReader initializer :param proc: the Popen process being read from :param stdout: the stream to write captured stdout :param stderr: the stream to write captured stderr out_thread read_stdoutT)r:targetkwargs err_threadFN) _proc_stdout_stderr threadingThread_reader_thread_func _out_thread _err_threadr%startr&)rEr$r%r&s rrFzProcReader.__init__Ts   $+dF^huw{g|}}}$+dF^huw|g}~~~ :  (   " " $ $ $ :  (   " " $ $ $ $ $ ) (rc"ddl}tjdr!|j|jdS tj|jj }tj ||j dS#t$rYdSwxYw)z@Send a SIGINT to the process similar to if +C were pressedrNr) signalrr startswithr- send_signalCTRL_BREAK_EVENTrfgetpgidpidkillpgSIGINTProcessLookupError)rEr7group_ids r send_sigintzProcReader.send_sigintis < " "5 ) )  J " "6#: ; ; ; ; ; :djn55 (FM22222%    s8B B Bc8|jdS)zTerminate the processN)r- terminaterIs rrCzProcReader.terminatezs rc~|jr|j|jr|j|j\}}|r||j||r||j|dSdS)zWait for the process to finishN) r3is_aliverNr4r- communicate _write_bytesr.r/)rEouterrs rwaitzProcReader.wait~s   $ $ & & $   ! ! # # #   $ $ & & $   ! ! # # #:))++S  1   dlC 0 0 0  1   dlC 0 0 0 0 0 1 1rr)cd|r|jj}|j}n|jj}|j}|J|ji|}|r8|t|| |||jgdSdS)z Thread function that reads a stream from the process :param read_stdout: if True, then this thread deals with stdout. Otherwise it deals with stderr. N) r-r%r.r&r/pollpeekrrrG)rEr) read_stream write_stream availables rr2zProcReader._reader_thread_funcs  (*+K2 eE3J>O TX   \   rr#c>eZdZdZd dZdefdZd dZdeddfdZ dS) ContextFlaga{A context manager which is also used as a boolean flag value within the default sigint handler. Its main use is as a flag to prevent the SIGINT handler in cmd2 from raising a KeyboardInterrupt while a critical code section has set the flag to True. Because signal handling is always done on the main thread, this class is not thread-safe since there is no need. rNcd|_dSNr_ContextFlag__countrIs rrFzContextFlag.__init__s rc|jdkSrZr[rIs r__bool__zContextFlag.__bool__s|arc&|xjdz c_dS)Nrr[rIs r __enter__zContextFlag.__enter__s  rargscZ|xjdzc_|jdkrtddS)Nrrzcount has gone below 0)r\r0)rEras r__exit__zContextFlag.__exit__s6  *3&&.)3#:. 3  3  333333rrestyles_to_parsecRddlm}Gdd}|}t|D]T\}}|t|jjt|jjfvr|}||_n|j |s4|j |s|j |r/|j |j |j ||_ n|j |s4|j |s|j |r/|j|j |j||_n|t|jjt|jjt|jjfvr/|j|j |j||_n|t|jjt|jjfvr/|j|j |j||_n%|t|jjt|jjfvr.|j|j |j||_n|t|jjt|jjfvr.|j|j |j||_na|t|jj t|jj!fvr-|j"|j |j"||_"||j |<VtG|j $S)a Utility function for align_text() / truncate_line() which filters a style list down to only those which would still be in effect if all were processed in order. This is mainly used to reduce how many style strings are stored in memory when building large multiline strings with ANSI styles. We only need to carry over styles from previous lines that are still in effect. :param styles_to_parse: list of styles to evaluate. :return: list of styles that are still in effect. ransiceZdZdZddZdS)-_remove_overridden_styles..StyleStatez+Keeps track of what text styles are enabledrNct|_d|_d|_d|_d|_d|_d|_d|_d|_ dSr) dict style_dict reset_allfgbg intensityitalicoverline strikethrough underlinerIs rrFz6_remove_overridden_styles..StyleState.__init__sL.2ffDO-1DN%)DG%)DG,0DN)-DK+/DM04D ,0DNNNrr)rVrWrXrYrFr#rr StyleStaterts.99 1 1 1 1 1 1rr)%rrrrr. TextStyle RESET_ALL ALT_RESET_ALLrx STD_FG_RErEIGHT_BIT_FG_RE RGB_FG_REryrwpop STD_BG_REEIGHT_BIT_BG_RE RGB_BG_RErzINTENSITY_BOLD INTENSITY_DIMINTENSITY_NORMALr{ ITALIC_ENABLEITALIC_DISABLEr|OVERLINE_ENABLEOVERLINE_DISABLEr}STRIKETHROUGH_ENABLESTRIKETHROUGH_DISABLEr~UNDERLINE_ENABLEUNDERLINE_DISABLErrwvalues)rorrr style_staterstyles r_remove_overridden_stylesrs11111111$*,,K!/22(.(. u S122C8T4U4UV V V$*,,K$)K ! ! ^ ! !% ( ( *D,@,F,Fu,M,M *QUQ_QeQefkQlQl *~)&**;>:::"KNN ^ ! !% ( ( *D,@,F,Fu,M,M *QUQ_QeQefkQlQl *~)&**;>:::"KNN  - . . , - - / 0 0   $0&**;+@AAA$)K ! ! s4>788#dn>[:\:\] ] ]!-&**;+=>>>!&K   s4>9::C@_<`<`a a a#/&**;+?@@@#(K s4>>??T^EiAjAjk k k(4&**;+DEEE(-K % % s4>:;;SAa=b=bc c c$0&**;+@AAA$)K !). u%%  &--// 0 00rceZdZdZdZdZdZdS) TextAlignmentzHorizontal text alignmentrrN)rVrWrXrYLEFTCENTERRIGHTr#rrrr<s### D F EEErrr'F fill_charwidth tab_widthtruncatetext alignmentrrrrcddl}ddl}ddlm}|%|jp t j}|dkrtd| dd|z}| dd}| |} t| dkrtd| |} | d krtd || \} } |r|} nd g} |}g}t#| D]\}}|dkr|d |rt'||}| |}|d krtd t)t+|}||krd}n||z }|t.jkrd}|}n|t.jkr |dz}||z }n|}d}|| z| z}|| z| z}|d|| |z zz }|d|| |z zz }| s| s|s|rL|r|jj| z|z| z}||jjz }|r|jj| z|z| z}||jjz }||d |z|z|z||t=|}|S)u Align text for display within a given width. Supports characters with display widths greater than 1. ANSI style sequences do not count toward the display width. If text has line breaks, then each line is aligned independently. There are convenience wrappers around this function: align_left(), align_center(), and align_right() :param text: text to align (can contain multiple lines) :param alignment: how to align the text :param fill_char: character that fills the alignment gap. Defaults to space. (Cannot be a line breaking character) :param width: display width of the aligned text. Defaults to width of the terminal. :param tab_width: any tabs in the text will be replaced with this many spaces. if fill_char is a tab, then it will be converted to one space. :param truncate: if True, then each line will be shortened to fit within the display width. The truncated portions are replaced by a '…' character. Defaults to False. :return: aligned text :raises TypeError: if fill_char is more than one character (not including ANSI style sequences) :raises ValueError: if text or fill_char contains an unprintable character :raises ValueError: if width is less than 1 rNrrqzwidth must be at least 1 r'z1Fill character must be exactly one character longrz*Fill character is an unprintable characterr z/Text to align contains an unprintable characterr) ioshutilrrrget_terminal_sizecolumnsrDEFAULT_TERMINAL_WIDTHr0r strip_stylerrstyle_aware_wcswidthr splitlinesStringIOrr truncate_linerwget_styles_dictrrrrrrrNrrr)rrrrrrrrrrstripped_fill_charfill_char_widthfill_char_style_beginfill_char_style_endlinestext_bufprevious_stylesrline line_width line_stylestotal_fill_widthleft_fill_widthright_fill_width left_fill right_fills r align_textrDs:IIIMMM }((**2Vi6V qyy3444 <<cIo . .D!!$,,I)))44 !##KLLL// ::O"FGGH2;AS1T1T.. !!{{}}H "$O ''8E8E t 199 NN4  . u--D..t44   OPP Q?4007799::     !  $z1   * * *O/   -. . ..!3O//A  .O %7;MM &/9=OO  SOd.G.G .R.RRSS c-0I0I*0U0UUVV  ! 3$7 3? 3k 3 o N47LLyX[nn 1 1I q!^58MMPZZ]pp $.2 2J y277?#;#;;dBZOPPP {+++3ODD     rc@t|tj||||S)uo Left align text for display within a given width. Supports characters with display widths greater than 1. ANSI style sequences do not count toward the display width. If text has line breaks, then each line is aligned independently. :param text: text to left align (can contain multiple lines) :param fill_char: character that fills the alignment gap. Defaults to space. (Cannot be a line breaking character) :param width: display width of the aligned text. Defaults to width of the terminal. :param tab_width: any tabs in the text will be replaced with this many spaces. if fill_char is a tab, then it will be converted to one space. :param truncate: if True, then text will be shortened to fit within the display width. The truncated portion is replaced by a '…' character. Defaults to False. :return: left-aligned text :raises TypeError: if fill_char is more than one character (not including ANSI style sequences) :raises ValueError: if text or fill_char contains an unprintable character :raises ValueError: if width is less than 1 r)rrrrrrrrs r align_leftrs$( dM.)5\epx y y yyrc@t|tj||||S)uc Center text for display within a given width. Supports characters with display widths greater than 1. ANSI style sequences do not count toward the display width. If text has line breaks, then each line is aligned independently. :param text: text to center (can contain multiple lines) :param fill_char: character that fills the alignment gap. Defaults to space. (Cannot be a line breaking character) :param width: display width of the aligned text. Defaults to width of the terminal. :param tab_width: any tabs in the text will be replaced with this many spaces. if fill_char is a tab, then it will be converted to one space. :param truncate: if True, then text will be shortened to fit within the display width. The truncated portion is replaced by a '…' character. Defaults to False. :return: centered text :raises TypeError: if fill_char is more than one character (not including ANSI style sequences) :raises ValueError: if text or fill_char contains an unprintable character :raises ValueError: if width is less than 1 r)rrrrs r align_centerrs$( dM0IU^grz { { {{rc@t|tj||||S)ur Right align text for display within a given width. Supports characters with display widths greater than 1. ANSI style sequences do not count toward the display width. If text has line breaks, then each line is aligned independently. :param text: text to right align (can contain multiple lines) :param fill_char: character that fills the alignment gap. Defaults to space. (Cannot be a line breaking character) :param width: display width of the aligned text. Defaults to width of the terminal. :param tab_width: any tabs in the text will be replaced with this many spaces. if fill_char is a tab, then it will be converted to one space. :param truncate: if True, then text will be shortened to fit within the display width. The truncated portion is replaced by a '…' character. Defaults to False. :return: right-aligned text :raises TypeError: if fill_char is more than one character (not including ANSI style sequences) :raises ValueError: if text or fill_char contains an unprintable character :raises ValueError: if width is less than 1 r)rrrrs r align_rightrs$( dM/9E]fqy z z zzr)rr max_widthcddl}ddlm}|dd|z}||dkrt d|dkrt d |||kr|St |}d }d}d}|} |s||vrK| ||t||} | ||| z }Q||} || } | |z|kr#tj } || } d }|| z }| | |dz }|tt|} | d | | S) u Truncate a single line to fit within a given display width. Any portion of the string that is truncated is replaced by a '…' character. Supports characters with display widths greater than 1. ANSI style sequences do not count toward the display width. If there are ANSI style sequences in the string after where truncation occurs, this function will append them to the returned string. This is done to prevent issues caused in cases like: truncate_line(Fg.BLUE + hello + Fg.RESET, 3) In this case, "hello" would be truncated before Fg.RESET resets the color from blue. Appending the remaining style sequences makes sure the style is in the same state had the entire string been printed. align_text() relies on this behavior when preserving style over multiple lines. :param line: text to truncate :param max_width: the maximum display width the resulting string is allowed to have :param tab_width: any tabs in the text will be replaced with this many spaces :return: line that has a display width less than or equal to width :raises ValueError: if text contains an unprintable character like a newline :raises ValueError: if max_width is less than 1 rNrrqrr'rz&text contains an unprintable characterzmax_width must be at least 1FTr)rrrrrrr0rrrrrrHORIZONTAL_ELLIPSISrrwrrNr)rrrrrr styles_dictdoner total_width truncated_buf style_lenchar char_widthremaining_styless rrrs*III <<cIo . .D   &&",,BCCD1}}7888   &&)33 "$''K D EKKKMMM K      E 2 3 3 3K.//I OOE " " " Y E E{..t44   #y 0 00D22488JDz! D!!!  ).1k6H6H6J6J1K1KLL 011222  ! ! # ##rcddlm}d}tj} |j||}|nN|||<|t|z }l|S)a8 Return an OrderedDict containing all ANSI style sequences found in a string The structure of the dictionary is: key: index where sequences begins value: ANSI style sequence found at index in text Keys are in ascending order :param text: text to search for style sequences rrqr) rrrrurv ANSI_STYLE_REsearchgroupr5r)rrrr5stylesrs rrr]s E  $ & &F$"))$66 =  % u{{}} U[[]]### $ Mrfunc.categoryct|tr"|D]}t|tj|dSt j|r"t|jtj|dSt|tj|dS)a*Categorize a function. The help command output will group the passed function under the specified category heading :param func: function or list of functions to categorize :param category: category to put it in Example: ```py import cmd2 class MyApp(cmd2.Cmd): def do_echo(self, arglist): self.poutput(' '.join(arglist) cmd2.utils.categorize(do_echo, "Text Processing") ``` For an alternative approach to categorizing commands using a decorator, see [cmd2.decorators.with_category][] N)r-r rQrCMD_ATTR_HELP_CATEGORYinspectismethod__func__)rrrzs r categorizerzs,$!!F F FD D):H E E E E F F  D ! ! F DM9#CX N N N N N D):H E E E E Ermethct|tjrt|jSt j|s9t j|rit|dYt|j drDt j |j j D]}|j |j vr|cSt|d|}t j|rrtt j||jdddddd}t|t&r|St)t&t|d dS) a* Attempts to resolve the class that defined a method. Inspired by implementation published here: https://stackoverflow.com/a/25959545/1956611 :param meth: method to inspect :return: class type in which the supplied method was defined. None if it couldn't be resolved. __self__N __class__rz .rr. __objclass__)r- functoolspartialget_defining_classrrr isbuiltinrHrgetmrorrVr isfunction getmodulerXrrsplitrr)rclss rrrsQ$ )**-!$),,,/$/$+D*$=$=$IgVZVcepNqNq$I>$-"9::  C} ,, -tZ..$g'--t/@/F/F{TU/V/VWX/Y/`/`adfg/h/hij/kll c4  J gdND99 : ::rceZdZdZdZdZdZdS)CompletionModezHEnum for what type of tab completion to perform in cmd2.Cmd.read_input()rrrN)rVrWrXrYNONECOMMANDSCUSTOMr#rrrrs)RR D H FFFrrc6eZdZdZdddejdeddfdZdS) CustomCompletionSettingszPUsed by cmd2.Cmd.complete() to tab complete strings other than command argumentsF)preserve_quotesparserrrNc"||_||_dS)aa Initializer :param parser: arg parser defining format of string being tab completed :param preserve_quotes: if True, then quoted tokens will keep their quotes when processed by ArgparseCompleter. This is helpful in cases when you're tab completing flag-like tokens (e.g. -o, --option) and you don't want them to be treated as argparse flags when quoted. Set this to True if you plan on passing the string to argparse with the tokens still quoted. N)rr)rErrs rrFz!CustomCompletionSettings.__init__s .r)rVrWrXrYargparseArgumentParserr1rFr#rrrrsTZZSX / / /x6 /D /]a / / / / / /rrdoccd}d}|D]E}|}|dr|rn0|r|r|dz }||z }d}A|rnF|S)zt Strip annotations from a docstring leaving only the text description :param doc: documentation string rF:rT)rrjr8)rcmd_desc found_firstdoc_line stripped_lines rstrip_doc_annotationsrsHKNN$$   ((   # #C ( (      !D   %HKK   E  Ors1s2cttd||td||Sr)maxrratio)rr s rsimilarity_functionr sE tR,,2244odBPR6S6S6Y6Y6[6[ \ \\rgffffff?requested_commandoptionssimilarity_function_to_usecd}t}|}|pt}|D]*}|||}||kr|}|}+|S)a Given a requested command and an iterable of possible options returns the most similar (if any is similar) :param requested_command: The command entered by the user :param options: The list of available commands to search for the most similar :param similarity_function_to_use: An optional callable to use to compare commands :return: The most similar command or None if no one is similar N)MIN_SIMIL_TO_CONSIDERlowerr )rrrproposed_command best_similrequested_command_to_compareeachsimils rsuggest_similarrst&J#4#:#:#<#< !;!R?R$$**4::<<9UVV   J#  rr)VrYrrurrrrrfr subprocessrr0rdifflibrenumrtypingrrrrr r r r r rrrrrargparse_customrrcmd2Popenr.rUrr1rr%r(r*r2r4rrr{rrrrrrrrrrrF_OKrrrrrr#rXrerrrrrrrrrrrrrfloatr rrr#rrr#sM                                 #KKK"3'KK"K WT]]M3M4MMMMcc c c    ,V?V?V?V?V?V?V?V?rCD6 "T"X "$r( " " " "9C9C9999 /HSM /d3i / / / / $c $eCHo $ $ $ $`C`DsCx$9```` 2x} 2c 2 2 2 2 ,$s) ,d3i ,D , , , , 'DI '$s) 'PT ' ' ' 'ss*3$s)33333Xc]B9; Y YS Y# YDI Y Y Y YAC  tCy # DQTI     #$s)Bb4b4b4b4b4b4b4b4J22222222