
    c                        U d Z dZdZddlZddlZddlZddlmZ ddlm	Z	m
Z
 ddlmZ ddlmZ dd	lmZmZ dd
lmZmZmZmZmZmZmZmZ ddlmZ ddlZddlmZm Z m!Z! ddl"m#Z$ ddl%m&Z& ddl'm(Z(m)Z) ddl*m+Z+ e+jX                  Z,g Z-ee.d<    G d de/      Z0dee1   deeef   de1fdZ2eee1   ee1df   e1f   Z3dee1ef   de1de1de1fdZ4dee1ef   de1de3de3fdZ5dee1ef   de1de3de3fdZ6dee1ef   de1dee7e1f   de7fdZ8dee1ef   de1deee1e1f   e1f   dee1e1f   fd Z9d! Z:d" Z;d# Z<d$ Z=d% Z>dee1e1f   de1dee?e1f   de?fd&Z@i d'e)d(e?d)eAd*e:d+e)d,e;d-ej                  d.e6d/e8d0e8d1e9d2e<d3e=d4e>d5e@d6e4d7e5ZCee1ef   e.d8<   d9e1dee1ef   d:e1deee1   e?e1f   deee1   e?e1f   f
d;ZDd\d<ZEd= ZFd> ZGeFeEd?ZHee1ef   e.d@<   eCj                         D ]  ZJeHj                  eJ eGeJ              dA ZL	 d]deee1   e?e1f   dee1ef   de1deee1   e?e1f   fdBZM  e&dC      eM      ZNdD ZOdE ZPde?de1fdFZQdee1ef   dedede?e1f   fdGZR	 	 d^deeef   dHe1dIede1dJee   ddfdKZSdeeef   dIede1ddfdLZTeSZUd^dMZV G dN dOeW      ZX G dP dQeW      ZY G dR dSeW      ZZ G dT dUeXeZ      Z[ G dV dWe[      Z\ G dX dYeW      Z]dZ Z^d_d[Z_y)`a>  Classes to handle advanced configuration in simple to complex applications.

Allows to load the configuration from a file or from command line
options, to generate a sample configuration file or to display
program's usage. Fills the gap between optik/optparse and ConfigParser
by adding data types (which are also available as a standalone optik
extension in the `optik_ext` module).


Quick start: simplest usage
---------------------------

.. ::

  >>> import sys
  >>> from logilab.common.configuration import Configuration
  >>> options = [('dothis', {'type':'yn', 'default': True, 'metavar': '<y or n>'}),
  ...            ('value', {'type': 'string', 'metavar': '<string>'}),
  ...            ('multiple', {'type': 'csv', 'default': ('yop',),
  ...                          'metavar': '<comma separated values>',
  ...                          'help': 'you can also document the option'}),
  ...            ('number', {'type': 'int', 'default':2, 'metavar':'<int>'}),
  ...           ]
  >>> config = Configuration(options=options, name='My config')
  >>> print config['dothis']
  True
  >>> print config['value']
  None
  >>> print config['multiple']
  ('yop',)
  >>> print config['number']
  2
  >>> print config.help()
  Usage:  [options]

  Options:
    -h, --help            show this help message and exit
    --dothis=<y or n>
    --value=<string>
    --multiple=<comma separated values>
                          you can also document the option [current: none]
    --number=<int>

  >>> f = open('myconfig.ini', 'w')
  >>> f.write('''[MY CONFIG]
  ... number = 3
  ... dothis = no
  ... multiple = 1,2,3
  ... ''')
  >>> f.close()
  >>> config.load_file_configuration('myconfig.ini')
  >>> print config['dothis']
  False
  >>> print config['value']
  None
  >>> print config['multiple']
  ['1', '2', '3']
  >>> print config['number']
  3
  >>> sys.argv = ['mon prog', '--value', 'bacon', '--multiple', '4,5,6',
  ...             'nonoptionargument']
  >>> print config.load_command_line_configuration()
  ['nonoptionargument']
  >>> print config['value']
  bacon
  >>> config.generate_config()
  # class for simple configurations which don't need the
  # manager / providers model and prefer delegation to inheritance
  #
  # configuration values are accessible through a dict like interface
  #
  [MY CONFIG]

  dothis=no

  value=bacon

  # you can also document the option
  multiple=4,5,6

  number=3

  Note : starting with Python 2.7 ConfigParser is able to take into
  account the order of occurrences of the options into a file (by
  using an OrderedDict). If you have two options changing some common
  state, like a 'disable-all-stuff' and a 'enable-some-stuff-a', their
  order of appearance will be significant : the last specified in the
  file wins. For earlier version of python and logilab.common newer
  than 0.61 the behaviour is unspecified.

zrestructuredtext en)OptionsManagerMixInOptionsProviderMixInConfigurationMixInConfiguration#OptionsManager2ConfigurationAdapter    N)get_close_matches)exists
expanduser)OptionGroup)copy)StringIOTextIOWrapper)AnyOptionalUnionDictListTupleIteratorCallable)warn)OptionParserOptionattrdict)
str_encode)callable_deprecated)normalize_textunquote)	optik_extREQUIREDc                       e Zd ZdZy)UnsupportedActionzBraised by set_option when it doesn't know what to do for an actionN)__name__
__module____qualname____doc__     >/usr/lib/python3/dist-packages/logilab/common/configuration.pyr"   r"      s    Lr(   r"   encodingstreamreturnc                 T    | xs t        |dd       } | sdd l}|j                         } | S )Nr*   r   )getattrlocalegetpreferredencoding)r*   r+   r/   s      r)   _get_encodingr1      s.    <76:t<H..0Or(   .optdictnamevaluec                 T    || d   vr d}t        j                  |||| d   fz        |S )Avalidate and return a converted value for option of type 'choice'choices-option %s: invalid value: %r, should be in %s)r   OptionValueError)r2   r3   r4   msgs       r)   choice_validatorr;      s;    GI&&=((eWY=O/P)PQQLr(   c                     | d   }t        j                  d||      }|D ]#  }||vsd}t        j                  ||||fz         |S )r6   r7   Nr8   )r   	check_csvr9   )r2   r3   r4   r7   valuesr:   s         r)   multiple_choice_validatorr?      sb    i G  tU3F KAC,,SD%3I-IJJK Mr(   c                 0    t        j                  d||      S )z>validate and return a converted value for option of type 'csv'N)r   r=   r2   r3   r4   s      r)   csv_validatorrB      s    tT511r(   c                 0    t        j                  d||      S )z=validate and return a converted value for option of type 'yn'N)r   check_ynrA   s      r)   yn_validatorrE      s    dD%00r(   c                 0    t        j                  d||      S )z@validate and return a converted value for option of type 'named'N)r   check_namedrA   s      r)   named_validatorrH      s       tU33r(   c                 0    t        j                  d||      S )z8validate and return a filepath for option of type 'file'N)r   
check_filerA   s      r)   file_validatorrK          dE22r(   c                 0    t        j                  d||      S )z<validate and return a valid color for option of type 'color'N)r   check_colorrA   s      r)   color_validatorrO            tU33r(   c                 0    t        j                  d||      S )z:validate and return a string for option of type 'password'N)r   check_passwordrA   s      r)   password_validatorrS      s    ##D$66r(   c                 0    t        j                  d||      S )zBvalidate and return a mx DateTime object for option of type 'date'N)r   
check_daterA   s      r)   date_validatorrV      rL   r(   c                 0    t        j                  d||      S )z;validate and return a time object for option of type 'time'N)r   
check_timerA   s      r)   time_validatorrY      rL   r(   c                 0    t        j                  d||      S )z9validate and return an integer for option of type 'bytes'N)r   check_bytesrA   s      r)   bytes_validatorr\      rP   r(   stringintfloatfilefontcolorregexpcsvynboolnamedpassworddatetimebyteschoicemultiple_choice
VALIDATORSopttypeoptionc           	      d   | t         vr=dj                  t        t         j                                     }t	        d|  d|       	 t        |    |||      S # t
        $ rO 	 t        |    |      cY S # t        j                  $ r  t        $ r t        j                  |d|d|       w xY ww xY w)Nz
 - zUnsupported type "z", supported types are:
 - z value (z) should be of type )rn   joinsortedkeys	Exception	TypeErrorr   r9   )ro   r2   rp   r4   all_validatorss        r)   _call_validatorrx      s     j  fZ__->&?@,WI5QR`Qabcc
'"7FE:: 	g&u--)) 	 	,,8>wO 	s$   A 	B/!A1.B/1:B++B/c                 V    ddl m } 	  ||      } |d      }||k(  r|S t        d       #)Nr   )getpassz	confirm: zpassword mismatch, try again)rz   print)r2   questionrz   r4   value2s        r)   input_passwordr~     s6    
!%F?L,- r(   c                 @    t        |      j                         }|xs d S N)inputstrip)r2   r|   r4   s      r)   input_stringr   #  s    (O!!#E=Dr(   c                       fd}|S )Nc                    	 t        |      }|j                         sy 	 t        | d |      S # t        j                  $ rD}t        |      j                  dd      d   j                         }t        d|z         Y d }~nd }~ww xY w)N:   zbad value: %s)r   r   rx   r   r9   strsplitr{   )r2   r|   r4   exr:   ro   s        r)   input_validatorz-_make_input_function.<locals>.input_validator)  s~    (OE;;=-&wuEE-- -"gmmC+B/557o+,,- s   . B:B  Br'   )ro   r   s   ` r)   _make_input_functionr   (  s    	- r(   )r]   rh   INPUT_FUNCTIONSc                    | j                   | j                  s|j                  S |j                  d   dd }	 | j                   j                  j
                  |   }|j                  |      }|j                  ||      }t        |j                  ||      }t        ||      }|t        j                  u s|s| j                  }|j                  j                  | j                  t!        |            S # t        $ r d}Y \w xY w)zmonkey patch OptionParser.expand_default since we have a particular
    way to handle defaults to avoid overriding values in the configuration
    file
    Nr      )parserdefault_taghelp
_long_optsoptions_manager_all_optionsget_option_defoption_attrnamer.   configformat_option_valueKeyErrorr   
NO_DEFAULTNO_DEFAULT_VALUEreplacer   )selfrp   optnameproviderr2   r4   s         r)   expand_defaultr   B  s    
 {{$"2"2{{"12&G4;;..;;GD ))'2**7G<':#GU3	$$$E%%;;t//U<<  s   #C0 0C>=C>c                 L    	 |d   }t        ||||       S # t         $ r | cY S w xY w)zreturn a validated value for an option according to its type

    optional argument name is only used for error message formatting
    type)r   rx   )r4   r2   r3   _types       r)   	_validater   X  s9     5'477  s    ##z([0.60] convert() was renamed _validate()c                     | j                         D cg c]  }|j                          }}ddt        j                  z  j	                  |      z   S c c}w )zreturn string as a comment# z%s# )
splitlinesr   oslineseprr   )r]   lineliness      r)   commentr   l  sH    &,&7&7&9:dTZZ\:E:6BJJ&,,U333 ;s   Ac                     | sy| t        |       k7  rd| z  S t        |       } t        | d      \  }}|rd| z  S t        |d      \  }}|rd|z  S t        |d      \  }}|rd|z  S d|z  S )	N0z%.2fs<   z%ssz%smin   z%shz%sdr^   divmod)r4   nbminnbsecnbhournbmin_nbdaynbhour_s          r)   format_timer   r  s    E
JE%$LE5u}E2&NFFFB'NE7v~5=r(   c                     | sy| t        |       k7  rd| z  S t        |       } d}dD ]  }t        | d      \  }}|r| |c S |}|} ! | S )Nr   z%.2fBB)KBMBGBTBi   r   )r4   prevunitunitnextremains        r)   format_bytesr     sp    E
JEH( eT*f"H-- D!!r(   c           	      |   t        |t        t        f      rdj                  |      }|S t        |t              r9dj                  |j                         D cg c]  \  }}|d| c}}      }|S t        |d      r|j                  }|S | j                  d      dk(  r|xr dxs d}|S t        |t              r|j                         rd|z  }|S | j                  d      d	k(  r#t        |t        t        f      rt        |      }|S | j                  d      d
k(  rt        |d      rt        |      }|S c c}}w )z5return the user input's value from a 'compiled' value,r   matchr   re   yesnoz'%s'rj   rk   __int__)
isinstancelisttuplerr   dictitemshasattrpatterngetr   isspacer_   r^   r   r   )r2   r4   kvs       r)   r   r     s)   %$' L 
E4	 u{{}Etq!Q*EF L 
	  L 
V		$%'4 L 
E3	EMMO
 L	 
V		&:eeS\+JE" L 
V		'GE9,EU#L Fs   D8
sectionoptionsdocc                     t        ||       }|r t        t        t        |      |      |        t        d|z  |        t	        | ||       y)z.format an options section using the INI formatr`   z[%s]N)r1   r{   _encoder   
ini_format)r+   r   r   r*   r   s        r)   ini_format_sectionr     sC     Xv.H
ggclH-F;	&7
(vw)r(   c                    |D ]  \  }}}t        ||      }|j                  d      }|r2t        |dd      }t        |        t        t	        ||      |        nt        |        |t        d|z  |        wt	        ||      j                         }|j                  d      d	k(  r)d
|v r%d}||j                  |j                  d
            z   }t        |d||         y)z#format options using the INI formatr   O   r   line_lenindentr   Nz#%s=r   r]   
z
    =)r   r   r   r{   r   r   rr   r   )r+   r   r*   r   r2   r4   r   prefixs           r)   r   r     s    #* ;%#GU3{{6"!$DADv'$)7v=&7"0E8,224E{{6"h.45=!U[[->!??We,6:!;r(   c           	         t        ||       }|rt        |ddt        |      z  |        |r/t        t        t	        |dd      |      |        t        |        |D ]  \  }}}|j                  d      }t        d|z  |        |r%t	        |dd	      }t        t        ||      |        |sRt        t        ||      |      }t        |        t        d
|j                  dd      z  |         y)z8format an options section using as ReST formatted outputr   'r   r    r   r   :%s:z  z  Default: ``%s``z`` z```` ``N)r1   r{   lenr   r   r   r   r   )	r+   r   r   r*   r   r   r2   r4   r   s	            r)   rest_format_sectionr     s    Xv.H'3W#56VD
gnS2bA8LSYZ6#* 	V%{{6"fwV,!$DAD'$)7/?JEv%eY(GGfU	Vr(   c                      e Zd ZdZ	 	 	 d7dee   dee   dee   deddf
dZd8dee   dee   ddfd	Z		 d9d
dde
ddfdZdedee   deeeeeeef   f      eeeeeef   f      f   d
dddf
dZd
ddeeef   dedeeef   ddf
dZd
ddedeeef   deee   eeef   f   fdZdddedeee   eef   ddddf
dZdedeee   eef   ddfdZ	 	 	 	 d:deeef   d ed   d!ee   d"ee   ddf
d#Z	 d;d$ed%ededdfd&Zd<d'Zd=deddfd(Zd=deddfd)Zd>d*Zd<d+Z d,eddfd-Z!d=d.ee   dee   fd/Z"d?d0ed1ed2eddfd3Z#d<d4Z$d<d5Z%d?d2edefd6Z&y)@r   z`MixIn to handle a configuration from both a configuration file and
    command line options
    Nusageconfig_fileversionquietr,   c                     || _         | j                  ||       g | _        i | _        i | _        i | _        i | _        || _        d| _        y )N)r   r   )	r   reset_parsersoptions_providersr   _short_options_nocallback_options	_mygroupsr   	_maxlevel)r   r   r   r   r   s        r)   __init__zOptionsManagerMixIn.__init__  sT     '5'2;=;=.0BD ;=
r(   c                     t        j                         | _        t        j                  ||      | _        | | j
                  _        t        | j
                  j                  j                        | _
        y )N)r   r   )cpConfigParsercfgfile_parserr   r   cmdline_parserr   setoption_classATTRS_optik_option_attrs)r   r   r   s      r)   r   z!OptionsManagerMixIn.reset_parsers  sU     oo/'445'R /3+#&t':':'G'G'M'M#N r(   r   r   	own_groupc                 D   |j                   dk  sJ d       t        t        | j                              D ]F  }|j                   | j                  |   j                   kD  s*| j                  j	                  ||        n | j                  j                  |       |j                  D cg c]  }d|d   vs| }}t        |dd      }|r9|r7| j                  |j                  j                         |j                  ||       n(|D ]#  \  }}| j                  || j                  ||       % |D ]h  \  }	}
|	j                         }	|j                  D cg c]*  }|d   j                  dd      j                         |	k(  r|, }}| j                  |	|
||       j yc c}w c c}w )	zregister an options providerr   z!provider's priority can't be >= 0groupr   option_groupsr'   r   N)priorityranger   r   insertappendr   r.   add_option_groupr3   upperr&   add_optik_optionr   r   )r   r   r  irp   non_group_spec_optionsgroupsoptr2   gnamegdocgoptionss               r)   register_options_providerz-OptionsManagerMixIn.register_options_provider	  s      A%J'JJ%s41123 	4A  4#9#9!#<#E#EE&&--a:	4
 ""))(3
 "*!1!1(
WF1I5MF(
 (
 ?B7/!!##%x'7'79OQY !7 SW%%h0C0CS'RS! 
	CKE4KKME '..!9=="-335> H 
 !!%xB
	C(
"s   'F4F/F
group_namer   r   c                    |sJ || j                   v r| j                   |   }nt        j                  | j                  |j	                               }| j                  j                  |       |j                  |_        || j                   |<   |dk7  r| j                  j                  |       |D ]  \  }}| j                  ||||        y)z0add an option group including the listed options)titleDEFAULTN)
r   r   r   r   
capitalizer  levelr   add_sectionr  )r   r  r   r   r   r  r  r2   s           r)   r  z$OptionsManagerMixIn.add_option_group/  s     w'NN:.E))$*=*=ZEZEZE\]E007 #..EK).DNN:&Y&##//
;# 	ALC!!(E3@	Ar(   optikcontainerr  r2   c                    d|v r't        d|z  t               |j                  d      |d<   | j                  |||      \  }} |j                  |i |}|| j
                  |<   t        | j                  |j                  xs d      | _        y )N
inputlevelzJ[0.50] "inputlevel" in option dictionary for %s is deprecated, use "level"r  r   )	r   DeprecationWarningpopoptik_option
add_optionr   maxr   r  )r   r   r  r  r2   argsrp   s          r)   r  z$OptionsManagerMixIn.add_optik_optionI  s     7"!$%"
  '{{<8GG))(CAg***D<G<!)#T^^V\\->Q?r(   c                    t        |      }d|v r|| j                  |<   nd|d<   | j                  |d<   d|v r,d|v r%|j                  d      |d   dvr|dxx   dz  cc<   |d= dt	        |      z   g}d|v r,|| j
                  |d   <   |j                  d	|d   z          |d= t        |j                               D ]"  }|| j                  vs|j                  |       $ ||fS )
zjget our personal option definition and return a suitable form for
        use with optik/optparse
        actioncallbackdefaultr   )
store_truestore_falsez [current: %default]--short-)r   r   cb_set_provider_optionr   r   r   r  r   rt   r  r"  )r   r   r  r2   r&  keys         r)   r#  z OptionsManagerMixIn.optik_option\  s    w-w14D$$X. *GH"&"="=GJ '!KK	*6)-JJ#99	"s3x g47D 01KKgg../ ' 	!C$222C 	! W}r(   rp   r   r4   r   r   c                     |j                  d      r|dd }n| j                  |dd    }|d}| j                  ||       y)z!optik callback for option settingr-  r   Nr   )
startswithr   global_set_option)r   rp   r  r4   r   s        r)   r0  z*OptionsManagerMixIn.cb_set_provider_option}  sM     >>$ab'C %%c!"g.C=EsE*r(   c                 B    | j                   |   j                  ||       y)z)set option on the correct option providerN)r   
set_option)r   r  r4   s      r)   r4  z%OptionsManagerMixIn.global_set_option  s    #))#u5r(   r'   r+   skipsectionsr*   header_messagec           
         i }g }| j                   D ]  }|j                         D ]s  \  }}	||j                  }||v r|	D 
cg c]  \  }
}}|j                  d      |
||f }	}}
}|	sH||vr|j	                  |       |j                  |g       }||	z  }u  |xs t        j                  }t        ||      }d}|Ct        j                  dt        j                        }|j                  d|      }t        ||       |D ]2  }|rt        d|       t        ||j                         ||   |       d}4 yc c}}}
w )	zrwrite a configuration file according to the current configuration
        into the given stream or stdout
        Nr   Fz^\s*(?=[^#])r   r   r   T)r   options_by_sectionr3   r   r  
setdefaultsysstdoutr1   recompile	MULTILINEsubr{   format_sectionr  )r   r+   r7  r*   r8  r:  sectionsr   r   r   ndr   
alloptionsprintedexpcommented_headers                    r)   generate_configz#OptionsManagerMixIn.generate_config  sZ    /1.. 	&H$,$?$?$A & ?&mmGl*6=[[!QvAZAq!9[[(*OOG,/::7BG
g%
&	& %3:: 62% **_bll;C"wwt^<"0 	Gd(67==?4Fw4OQYZG		% \s   D;D;pkginfor   c                     | j                          	 t        j                  | j                  |||xs t        j
                  | j                         | j                          y# | j                          w xY w)z_write a man page for the current configuration into the given
        stream or stdout
        )r+   r  N)_monkeypatch_expand_defaultr   generate_manpager   r<  r=  r   _unmonkeypatch_expand_default)r   rK  r   r+   s       r)   rN  z$OptionsManagerMixIn.generate_manpage  s`     	((*		1&&##+nn ..0D..0s   A A# #A5c                 F    | j                   D ]  }|j                           y)z-initialize configuration using default valuesN)r   load_defaultsr   r   s     r)   load_provider_defaultsz*OptionsManagerMixIn.load_provider_defaults  s#    .. 	%H""$	%r(   c                 F    | j                  |       | j                          y)z load the configuration from fileN)read_config_fileload_config_file)r   r   s     r)   load_file_configurationz+OptionsManagerMixIn.load_file_configuration  s    k*r(   c                     d}| j                   k  rdj                  dg|z        dz   }| j                  v rn|f fd	}ddj                  dg|z        z  }d	||d
} j                  d   } j	                  | j
                  ||       |xj                  ||ffz  c_        |dz  }| j                   k  r| j                  }|t        |      }|rt        |      r{ j                  }|j                  |g       t        |j                  j                               D ]6  \  }	}
|	j                         r|
s|
|j                  |	j!                         <   8 y j"                  sd}t%        |t&        j(                         yy)zrread the configuration file but do not load it (i.e. dispatching
        values to each options provider)
        r   r/  longz-helpc                 d    t        j                  |             t        j                  d       y )Nr   )r{   r   r<  exit)rp   r  valpr  r   s        r)   helpfuncz6OptionsManagerMixIn.read_config_file.<locals>.helpfunc  s    dii&'r(   z%s verbose help. morer)  )r(  r)  r   r   Nz1No config file found, using default configurationr   )r   rr   r   r   r  r   r   r   r
   r	   r   readr   	_sectionsr   isupperr  r   r{   r<  stderr)r   r   	helplevelr  r^  helpmsgr2   r   r   sectr>   r:   s   `           r)   rU  z$OptionsManagerMixIn.read_config_file  s~    	4>>)((F8i/07:Cd'''4=  )388VHy4H+IIG!+7SG--a0H!!(D,?,?gN#w 11NI 4>>) **K"$[1K6+.((FKK& !%V%5%5%;%;%= > <f||~&5;F$$TZZ\2< EC#CJJ' r(   c                     ||j                         }| j                  D ];  }|j                         D ]&  \  }}}|||k7  rd|vr|j                  |||       ( = || j	                  |       yy)zointeractively get configuration values by asking to the user and generate
        a configuration file
        Nr   )r  r   all_optionsinput_optionrJ  )r   onlysectionr   r+   r   r   rp   r2   s           r)   input_configz OptionsManagerMixIn.input_config  s     "%++-K.. 	CH,4,@,@,B C(*w+/E(%%fgzBC	C   ( r(   c                     | j                   }|j                         D ].  }|j                  |      D ]  \  }}	 | j                  ||        0 y# t        t
        f$ r Y /w xY w)zddispatch values previously read from a configuration file to each
        options provider)
        N)r   rC  r   r4  r   OptionError)r   r   r   rp   r4   s        r)   rV  z$OptionsManagerMixIn.load_config_file  so     $$( 	G!'g!6 **659	 !+. s   AA! A!kwargsc                     |j                         D ]8  \  }}|j                  dd      }| j                  |   }|j                  ||       : y)z4override configuration according to given parameters_r/  N)r   r   r   r6  )r   ro  r  	opt_valuer   s        r)   load_configurationz&OptionsManagerMixIn.load_configuration  sK    $lln 	0NC++c3'C((-HY/	0r(   r&  c                    | j                          	 |t        j                  dd }nt        |      }| j                  j                  |      \  }}| j                  j                         D ]J  }|j                  }|j                  j                         D ]  }t        ||d      }|t        |||       ! L || j                          S # | j                          w xY w)zioverride configuration according to command line parameters

        return additional arguments
        Nr   )r&  )rM  r<  argvr   r   
parse_argsr   rt   r   __dict__r.   setattrrO  )r   r&  r   r   r   attrr4   s          r)   load_command_line_configurationz3OptionsManagerMixIn.load_command_line_configuration%  s    
 	((*	1|xx|Dz"11<<$<GOWd 4499; 1!"OO002 1D#GT48E} FD%0	11 ..0D..0s   B(C Cr  descriptionr  c                     t        j                  | j                  |j                         |      }||_        t        | j                  |      | _        | j                  j                  |       y)z+add a dummy option section for help purpose)r  r{  N)r   r   r   r  r  r%  r   r  )r   r  r{  r  r  s        r)   add_help_sectionz$OptionsManagerMixIn.add_help_section?  sW    %%u'7'7'9{

 T^^U3,,U3r(   c                     	 t         j                  j                  | _        t        t         j                  _        y # t        $ r Y y w xY wr   )r   HelpFormatterr   +_OptionsManagerMixIn__expand_default_backupAttributeErrorr   s    r)   rM  z/OptionsManagerMixIn._monkeypatch_expand_defaultJ  s>    	+4+B+B+Q+QD( 6DI##2 		s   8; 	AAc                 x    t        t        j                  d      r | j                  t        j                  _        y y )Nr   )r   r   r  r  r   r  s    r)   rO  z1OptionsManagerMixIn._unmonkeypatch_expand_defaultU  s.    9**,<=
 6:5Q5QI##2 >r(   c                     || j                   j                  _        | j                          	 | j                   j	                         | j                          S # | j                          w xY w)z-return the usage string for available options)r   	formatteroutput_levelrM  format_helprO  )r   r  s     r)   r   zOptionsManagerMixIn.help^  sT     6;%%2((*	1&&224..0D..0s   A A))NNr   )r   N)T)Nr'   NN)r   Nr,   Nr   )Nr   N)r   )'r#   r$   r%   r&   r   r   r   r^   r   r   rf   r  r   r   r   r   r  r   r   r  r#  r0  r4  r   r   rJ  r   rN  rS  rW  rU  rl  rV  rs  rz  r}  rM  rO  r   r'   r(   r)   r   r     s>    &*!%} c] #	
  
(O8C= O OY] O AE$C,$C9=$C	$CLAA c]A tE#tCH~"567eCcSVhDW>X9YYZ	A
 'A 
A4@&@ lK78@ 	@
 c3h@ 
@&,36AEc3h	tCy$sCx.(	)B++%(+16tCy#s7J1K+Uc+	+6S 6tCy#s7J1K 6PT 6 26"$"&(,)h-.) Bi) 3-	)
 !) 
)X GK11*-1;C1	1(%
 3  $  
$C $4 $L)$03 04 01DI 1c 14	4c 	4 	4C 	4PT 	4	R	1# 	1c 	1r(   r   c                   <    e Zd ZdZd Zd	dZdededeeef   fdZ	y)
Methodzused to ease late binding of default method (so you can define options
    on the class using default methods on the configuration instance)
    c                      || _         d | _        y r   )method_inst)r   methnames     r)   r   zMethod.__init__o  s    
r(   r,   Nc                 ,    | j                   || _         yy)zbind the method to its instanceN)r  )r   instances     r)   bindzMethod.binds  s    ::!DJ r(   r&  ro  c                 t    | j                   sJ d        t        | j                   | j                        |i |S )Nzunbound method)r  r.   r  )r   r&  ro  s      r)   __call__zMethod.__call__x  s5    zz+++z/wtzz4;;/@@@r(   )r  r   r,   N)
r#   r$   r%   r&   r   r  r   r   r   r  r'   r(   r)   r  r  j  s7    "
Ac AS AT#s(^ Ar(   r  c                       e Zd ZU dZdZdZdZeed<   dZ	dd	Z
dd
ZddZddZ  ed      e      Zd ZddZddZd Zd Zdee   fdZddZy)r   z-Mixin to provide options to an OptionsManagerr   r*  r'   r   r   r,   Nc                    t        j                         | _        | j                  D ]p  }	 |\  }}t        |j                  d      t              r|d   j                  |        =t        |j                  d      t              s]|d   j                  |        r | j                          y # t        $ r t        dt        |      z        w xY w)NzBad option: %sr*  r)  )r   Valuesr   r   
ValueErrorru   r   r   r   r  r  rQ  )r   option_tuplerp   r2   s       r)   r   zOptionsProviderMixIn.__init__  s    &&( LL 	/LF". '++i0&9	"''-GKK
3V<
#((.	/ 	  F 03|3D DEEFs   B**!Cc                     | j                   D ]K  \  }}|j                  d      }|dk7  s| j                  ||      }|t        u r8| j	                  ||||       M y)z,initialize the provider using default valuesr(  r)  N)r   r   option_defaultr    r6  )r   r  r2   r(  r*  s        r)   rQ  z"OptionsProviderMixIn.load_defaults  s^     LL 	?LC[[*F#--c7;h&Wfg>	?r(   c                 r    || j                  |      }|j                  d      }t        |      r |       }|S )z&return the default value for an optionr*  )r   r   callable)r   r  r2   r*  s       r)   r  z#OptionsProviderMixIn.option_default  s9    ?))#.G++i(GiGr(   c                 l    || j                  |      }|j                  d|j                  dd            S )z-get the config attribute corresponding to optdestr/  rq  )r   r   r   )r   r  r2   s      r)   r   z$OptionsProviderMixIn.option_attrname  s3    ?))#.G{{63;;sC#899r(   zJ[0.60] OptionsProviderMixIn.option_name() was renamed to option_attrname()c                 N    t        | j                  | j                  |      d      S )z*get the current value for the given optionN)r.   r   r   )r   r  s     r)   option_valuez!OptionsProviderMixIn.option_value  s     t{{D$8$8$=tDDr(   c                    || j                  |      }|t        |||      }||j                  dd      }|j                  d      dk(  r>| j                  ||      }t	        | j
                  |d      }|r|j                  |       |}|dk(  r(t        | j
                  | j                  ||      |       y|dv r(t        | j
                  | j                  ||      d       y|dk(  r(t        | j
                  | j                  ||      d	       y|d
k(  r| j                  ||      }t	        | j
                  |d      }|Ft        |t        t        f      r|}n|g }|j                  |       t        | j
                  ||       yt        |t              rt        | j
                  |||fz          y|j                  |       y|dk(  r |d   d||d       yt        |      )z?method called to set an option (registered in the options list)Nr(  storer   rg   )r+  countr   r,  r   r  r)  )r   r   r   r   r.   r   updaterx  r   r   r   r  r"   )r   r  r4   r(  r2   r   currentvalue_lists           r)   r6  zOptionsProviderMixIn.set_option  s   ?))#.GeWc2E>[[73F;;v')**38G"4;;>L##E*$WDKK!5!5c7!CUK..DKK!5!5c7!CQG}$DKK!5!5c7!CQGx&&sG4CDKKd3E}edE]3!E&ELL'S%0E5)S%5(*:;U#z!GJc5$7#F++r(   c                    | j                  ||      }|t        u rd}n2|j                  dd      |kD  ry |d   dk(  s|d}ndt        ||      z  }t	        d|z         t	        |j                  d	      xs |       t
        |d      } |||      }|t        u r$|s"t	        d
        ||d|z        }|t        u r|s"|||}| j                  |||       y )Nz(required): r  r   r   rh   z: z(default: %s): r   r   zplease specify a valuez%s: r2   )r  r    r   r   r{   r   r6  )r   rp   r2   r   r*  
defaultstr	inputfuncr4   s           r)   rj  z!OptionsProviderMixIn.input_option  s    %%fg6h'J[[!$z1V_
*goJ*-@'-RRJfvogkk&!+V,#GFO4	':.!%*+gv7E !% =W0Ew7r(   c                 z   | j                   sJ | j                   D ]  }|d   |k(  s|d   c S  t        |d | j                   D        d      }|r.t        d|d| j                  dd	j	                  |      |      t        d|d| j                  d
d	j	                  d | j                   D              |      )z8return the dictionary defining an option given it's namer   r   c              3   8   K   | ]  }t        |d            ywr   Nr   .0xs     r)   	<genexpr>z6OptionsProviderMixIn.get_option_def.<locals>.<genexpr>  s     1R#ad)1R   
   )rD  zno such option z in section z'.

Options with a similar name are:
 * z
 * z<.

No option with a similar name, all available options:
 * c              3   8   K   | ]  }t        |d            ywr  r  r  s     r)   r  z6OptionsProviderMixIn.get_option_def.<locals>.<genexpr>  s     /PaAaD	/Pr  )r   r   rn  r3   rr   )r   r  rp   similar_optionss       r)   r   z#OptionsProviderMixIn.get_option_def  s    |||ll 	!FayCay 	!
 ,C1RT\\1RVXY		7<<#@B   		7<</P4<</P#PR 	 r(   c              #      K   | j                         D ]@  \  }}|'| j                  | j                  j                         }|D ]  \  }}}|||f  B yw)zreturn an iterator on available options for this provider
        option are actually described by a 3-uple:
        (section, option name, option dictionary)
        N)r:  r3   r  )r   r   r   rp   
optiondictr4   s         r)   ri  z OptionsProviderMixIn.all_options  sj     
 !% 7 7 9 	2GW99$))//+-4 2)
Evz112	2s   AAc              #   X  K   i }| j                   D ]G  \  }}|j                  |j                  d      g       j                  ||| j	                  |      f       I d|v rd|j                  d      f t        |j                               D ]  \  }}|j                         |f  yw)ztreturn an iterator on options grouped by section

        (section, [list of (optname, optdict, optvalue)])
        r  N)	r   r;  r   r  r  r"  rs   r   r  )r   rC  r   r2   r   r   s         r)   r:  z'OptionsProviderMixIn.options_by_section  s     
 FH $ 	GWG 4b9@@'4#4#4W#=>	 8 T*** &x~~'7 8 	+GW--/7**	+s   B(B*c              #   h   K   || j                   }|D ]  \  }}||| j                  |      f  y wr   )r   r  )r   r   r   r2   s       r)   options_and_valuesz'OptionsProviderMixIn.options_and_values)  sB     ?llG ' 	AGWGT%6%6w%?@@	As   02r  r   NN)c   )r#   r$   r%   r&   r  r3   r   r   __annotations__r  r   rQ  r  r   r   option_namer  r6  rj  r   ri  r   r   r:  r  r'   r(   r)   r   r     s    7 HDGUE	?:%TKE%,N8*.2+HSM +"Ar(   r   c                   J    e Zd ZdZdededdfdZd Zd Zd	 Zd
 Z	d Z
ddZy)r   z]basic mixin for simple configurations which don't need the
    manager / providers model
    r&  ro  r,   Nc                    |s|j                  dd       |j                  dd       t        j                  | g|i | t        j                  |        t	        | dd       s[g | _        | j                  D ]E  \  }}	 |d   j                         df}|| j
                  vs+| j
                  j                  |       G | j                  | d       y # t        $ r Y gw xY w)	Nr   r   r   r   r  r  F)r  )r;  r   r   r   r.   r  r   r  r   r  r  )r   r&  ro  rp   r2   gdefs         r)   r   zConfigurationMixIn.__init__8  s    gr*'1%$$T;D;F;%%d+t_d38:D#'<< 4#G,224b9D t111&&--d34 	&&tu&=	   s   <C	CCc                 F   i }|D ]P  \  }}|j                  |j                  d| j                  j                               g       j	                  ||f       R |j                         D ]  \  }}| j                  |d||         | xj                  t        |      z  c_        y)z%add some options to the configurationr  N)	r;  r   r3   r  r  r   r  r   r   )r   r   options_by_groupr   r2   r  group_optionss          r)   register_optionsz#ConfigurationMixIn.register_optionsI  s     ' 	GW''GTYY__=N(OQST[['"	 %5$:$:$< 	D E=!!%}dC	Dg&r(   c                 .    t         j                  |        y r   )r   rQ  r  s    r)   rQ  z ConfigurationMixIn.load_defaultsT  s    **40r(   c                 \    t        | j                  j                  j                               S r   )iterr   rw  r   r  s    r)   __iter__zConfigurationMixIn.__iter__W  s     DKK((..011r(   c                     	 t        | j                  | j                  |            S # t        j                  t
        f$ r t        |      w xY wr   )r.   r   r   r   r9   r  r   r   r1  s     r)   __getitem__zConfigurationMixIn.__getitem__Z  sG    	 4;;(<(<S(ABB**N; 	 3-	 s	   $' %Ac                 (    | j                  ||       y r   )r6  r   r1  r4   s      r)   __setitem__zConfigurationMixIn.__setitem__`  s    U#r(   c                 <    	 | |   S # t         t        f$ r |cY S w xY wr   )rn  r   r   r1  r*  s      r)   r   zConfigurationMixIn.getc  s*    	9X& 	N	s    r   )r#   r$   r%   r&   r   r   r  rQ  r  r  r  r   r'   r(   r)   r   r   3  s?    >c >S >T >"	'12 $r(   r   c                   &     e Zd ZdZ	 d fd	Z xZS )r   zclass for simple configurations which don't need the
    manager / providers model and prefer delegation to inheritance

    configuration values are accessible through a dict like interface
    c                 h    ||| _         ||| _        ||| _        t        t        |   |||       y )N)r   r   r   )r   r3   r&   superr   r   )r   r   r   r3   r   r   r   	__class__s          r)   r   zConfiguration.__init__q  sB     "DLDI?DLmT+5Za+br(   )NNNNNN)r#   r$   r%   r&   r   __classcell__)r  s   @r)   r   r   j  s     X\	c 	cr(   r   c                   0    e Zd ZdZd Zd Zd Zd ZddZy)	r   zgAdapt an option manager to behave like a
    `logilab.common.configuration.Configuration` instance
    c                     || _         y r   )r   rR  s     r)   r   z,OptionsManager2ConfigurationAdapter.__init__  s	    r(   c                 .    t        | j                  |      S r   )r.   r   r  s     r)   __getattr__z/OptionsManager2ConfigurationAdapter.__getattr__  s    t{{C((r(   c                     | j                   j                  |   }	 t        |j                   |j                  |            S # t        $ r t        |      w xY wr   )r   r   r.   r   r  r   )r   r1  r   s      r)   r  z/OptionsManager2ConfigurationAdapter.__getitem__  sP    ;;++C0	 8??H,D,DS,IJJ 	 3-	 s   $A   Ac                 n    | j                   j                  | j                   j                  |      |       y r   )r   r4  r   r  s      r)   r  z/OptionsManager2ConfigurationAdapter.__setitem__  s%    %%dkk&A&A#&FNr(   Nc                 0    	 | |   S # t         $ r |cY S w xY wr   )r   r  s      r)   r   z'OptionsManager2ConfigurationAdapter.get  s%    	9 	N	s    r   )	r#   r$   r%   r&   r   r  r  r  r   r'   r(   r)   r   r   }  s!    ) Or(   r   c                    i }|D ]  }|d   dk(  r1|dd \  }}}|j                  |g       j                  |d   ||f       <|d   dk(  r/|dd \  }}	|j                  |	g       j                  |d   |f       s|d   dk(  r1|dd \  }}
}|j                  |g       j                  |d   |
|f       |d   dv rt        d|d   z         g }| j                  D ]  \  }}|j	                  |d	      D ]Y  }|d   dk(  r|dd \  }}|j                         }||d
<   )|d   dk(  r|d   }7|d   dk(  s@|d   }
|j                         }|
|d<   [ |j                  ||f        |rt        d|z        t        || j                        }|j                  |       |j                          t               }|D ]T  }|d   dk(  r"|dd \  }}	||   | |	<   |j                  |	       -|d   dk(  s6|dd \  }}
}|| |<   |j                  |       V | j                  D ]3  \  }}|j                  d      s||vs| j                  |||   |       5 y)zinitialize newconfig from a deprecated configuration file

    possible changes:
    * ('renamed', oldname, newname)
    * ('moved', option, oldgroup, newgroup)
    * ('typechanged', option, oldtype, newvalue)
    r   movedr   Nrenamedtypechanged)addedremovedzunknown change %sr'   r  r   zunapplied changes: %s)r   r3   r  )r;  r  ru   r   r"  r   r   r3   rW  reverser   addr   r6  )	newconfigchanges
configfilechangesindexr(  rp   oldgroupnewgroupoldnamenewnameoldtypenewvaluer   r   optdef	oldconfigdones                    r)   read_old_configr    s    L 9!9)/&FHh##FB/66q	8X7VW!9	!%abzGW##GR077G8LM!9%(.qr
%FGX##FB/66q	7H7UV!9,,+fQi7889" G$,, *"&&w3 
	)FayG#%+ABZ"("*wi' )m+ )!(v
	) 	()* /,>??gINNCI%%j1OO5D !9	!%abzGW!*7!3IgHHWAY-')/&GWh!)IgHHW %,, N::f'"5  )G*<f MNr(   c                     i }t        |       } t        t        |       dz
  dd      D ][  }| |   \  }}||v r&| j                  |       ||   j	                  |       n|j                         }||f| |<   |||<   |T|||   d<   ] t        |       S )a	  preprocess a list of options and remove duplicates, returning a new list
    (tuple actually) of options.

    Options dictionaries are copied to avoid later side-effect. Also, if
    `otpgroup` argument is specified, ensure all options are in the given group.
    r   r   r  )r   r	  r   r"  r  r   r   )r   optgrouprF  r  r   r2   s         r)   merge_optionsr    s     J7mG3w<!#R, 
4"1:j KKNw&&w/llnG!7+GAJ")Jw+3Jw(
4 >r(   )z	password:)r   r  r   )`r&   __docformat____all__r   r<  r>  difflibr   os.pathr	   r
   optparser   r   _ior   r   typingr   r   r   r   r   r   r   r   warningsr   configparserr   logilab.common.typesr   r   r   logilab.common.compatr   r   logilab.common.deprecationr   logilab.common.textutilsr   r   logilab.commonr   rn  r    r  ru   r"   r   r1   
_ValueTyper;   r?   rB   rf   rE   rH   rK   rO   rS   rV   rY   r^   r\   r_   r?  rn   rx   r~   r   r   r   rt   ro   r;  r   r   convertr   r   r   r   r   r   rB  r   objectr   r  r   r   r   r   r  r  r'   r(   r)   <module>r	     sJ  $Zz & 
 
 	 % &    ' N N N   ? ? 7 : < $ ##$ M	 MHSM 5=9P3Q VY  49eCHos23
d38n C   tCH~ S  Xb 24S> 2 2Z 2J 2
1$sCx. 1 1E$)<L 1QU 1
4#s(^4#&4/4T#s(^S5H/I4	#s(^43
4
7
3
3
4T#s(^ 43 4uS#X 4SV 4
#g#	3# U# N	#
 G# _# bjj# 
=# 	,# L# _# "# N# N# _#  !#" 0##
Dh *S>36?DT#YPSUXEX?Y
49c34.
  (c8m$ 
   GGw(<W(EFG=. MO8cC$%804S#X8FI8
49c38 J
H
I)
T
4$" " " c3h  dCQTn@U 0 *(M)*** * 	*
 
#* 
*;uX}45 ; ;s ;W[ ;* $V.A1& A1HAV A,mA6 mAf4,.B 4nc& c&& ><N~r(   