
    M/e:                         d Z ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ dd	lm	Z	 dd
lm
Z
 ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ e
rddlmZ ddlmZ  edd      Z edd      Z edd      Z G d deeef         Z G d deej2                  ej4                  f         Z G d deej8                  ej:                  f         Z G d deej>                  ej@                  f         Z!y )!z  Dual ParserNode implementation     )Any)Generic)Iterable)List)Optional)Set)Tuple)Type)TYPE_CHECKING)TypeVar)apacheparser)
assertions)augeasparser)
interfaces)ApacheParserNode)AugeasParserNodeGenericAugeasParserNoder   )boundGenericApacheParserNoder   GenericDualNodeDualNodeBasec                       e Zd ZdZdededdfdZdeddfdZd	ede	fd
Z
deded    fdZdee   dedede	dee   f
dZy)r   z Dual parser interface for in development testing. This is used as the
    base class for dual parser interface classes. This class handles runtime
    attribute value assertions.primary	secondaryreturnNc                      || _         || _        y )Nr   r   )selfr   r   s      E/usr/lib/python3/dist-packages/certbot_apache/_internal/dualparser.py__init__zDualNodeBase.__init__    s    "    msgc                 p    | j                   j                  |       | j                  j                  |       y)z Call save for both parsers N)r   saver   )r   r"   s     r   r$   zDualNodeBase.save%   s&    #C r!   anamec                     t        | j                  |      }t        | j                  |      }|dk(  t        |      g}t	        |      st        j                  ||       |S )z Attribute value assertion metadata)getattrr   r   callableanyr   assertEqualSimple)r   r%   firstval	secondval
exclusionss        r   __getattr__zDualNodeBase.__getattr__*   sY    4<</DNNE2	 ZX	

 :((9=r!   namec                 0    | j                  t        d|      S )zA Traverses the ancestor tree and returns ancestors matching name find_ancestors_find_helperDualBlockNode)r   r0   s     r   r2   zDualNodeBase.find_ancestors8   s      0@$GGr!   	nodeclassfindfuncsearchkwargsc                 T    t        | j                  |      |fi |} t        | j                  |      |fi |}t        j                  |      }t        j                  |      }g }	|r#|r!|	j                   ||d   |d                |	S |r%|D ]  }
|	j                   ||d   |
               |	S |r%|D ]  }
|	j                   ||
|d                  |	S t        |      t        |      k(  sJ | j                  ||      }|D ]  \  }}|	j                   |||               |	S )a.  A helper for find_* functions. The function specific attributes should
        be passed as keyword arguments.

        :param interfaces.ParserNode nodeclass: The node class for results.
        :param str findfunc: Name of the find function to call
        :param str search: The search term
        r   r   )r(   r   r   r   isPassNodeListappendlen_create_matching_list)r   r6   r7   r8   r9   primary_ressecondary_respass_primarypass_secondary	new_nodescmatchespss                 r   r4   zDualNodeBase._find_helper<   sl    6gdllH5fGG99&KFK
 "00=#22=A	NY{1~1>q1AC D   " 9  ;q>56"8 99    H  15B15E"G HH  {#s='999900mLG D1  1!BCD r!   )__name__
__module____qualname____doc__r   r   r    strr$   r   r/   r   r2   r
   r   r4    r!   r   r   r      s    ## 7 #3#8<#
! ! !
  H3 H4+? H&d?&; &s &TW &"&'+O'<&r!   c                   ,     e Zd ZdZdeddf fdZ xZS )DualCommentNodez5 Dual parser implementation of CommentNode interface r9   r   Nc                    |j                  dd       |j                  dd       |j                  d      }|j                  d      }|s|r|r|sJ t        |   ||       n6t        |   t	        j
                  di |t        j                  di |       t        j                  | j                  | j                         y)a<   This initialization implementation allows ordinary initialization
        of CommentNode objects as well as creating a DualCommentNode object
        using precreated or fetched CommentNode objects if provided as optional
        arguments primary and secondary.

        Parameters other than the following are from interfaces.CommentNode:

        :param CommentNode primary: Primary pre-created CommentNode, mainly
            used when creating new DualParser nodes using add_* methods.
        :param CommentNode secondary: Secondary pre-created CommentNode
        r   Nr   rM   )
setdefaultpopsuperr    r   AugeasCommentNoder   ApacheCommentNoder   assertEqualr   r   r   r9   r   r   	__class__s       r   r    zDualCommentNode.__init__i   s     	)T*+t,**Y'JJ{+	iy((GWi0G\;;EfE);;EfEG 	t||T^^<r!   )rH   rI   rJ   rK   r   r    __classcell__rX   s   @r   rO   rO   e   s    ?= = = =r!   rO   c                   N     e Zd ZU dZeed<   deddf fdZdee   ddfdZ	 xZ
S )DualDirectiveNodez7 Dual parser implementation of DirectiveNode interface 
parametersr9   r   Nc                    |j                  dd       |j                  dd       |j                  d      }|j                  d      }|s|r|r|sJ t        |   ||       n6t        |   t	        j
                  di |t        j                  di |       t        j                  | j                  | j                         y)aL   This initialization implementation allows ordinary initialization
        of DirectiveNode objects as well as creating a DualDirectiveNode object
        using precreated or fetched DirectiveNode objects if provided as optional
        arguments primary and secondary.

        Parameters other than the following are from interfaces.DirectiveNode:

        :param DirectiveNode primary: Primary pre-created DirectiveNode, mainly
            used when creating new DualParser nodes using add_* methods.
        :param DirectiveNode secondary: Secondary pre-created DirectiveNode
        r   Nr   rM   )rQ   rR   rS   r    r   AugeasDirectiveNoder   ApacheDirectiveNoder   rV   r   r   rW   s       r   r    zDualDirectiveNode.__init__   s     	)T*+t,**Y'JJ{+	iy((GWi0G\==GG)==GGI 	t||T^^<r!   c                     | j                   j                  |       | j                  j                  |       t        j                  | j                   | j                         y)zf Sets parameters and asserts that both implementation successfully
        set the parameter sequence N)r   set_parametersr   r   rV   )r   r]   s     r   rb   z DualDirectiveNode.set_parameters   s@     	##J/%%j1t||T^^<r!   )rH   rI   rJ   rK   rL   __annotations__r   r    r   rb   rY   rZ   s   @r   r\   r\      s5    AO= = =6=# =4 =r!   r\   c            	           e Zd ZdZdeddf fdZ	 	 ddedeee      dee	   dd fd	Z
	 	 ddedeee      dee	   defd
Z	 	 ddedee	   defdZdeej"                     deej"                     deeej"                  ej"                  f      fdZddededed    fdZddededee   fdZdedee   fdZddZdee   fdZdee   fdZ xZS )r5   z3 Dual parser implementation of BlockNode interface r9   r   Nc                    |j                  dd       |j                  dd       |j                  d      }|j                  d      }|s|r|r|sJ t        |   ||       n6t        |   t	        j
                  di |t        j                  di |       t        j                  | j                  | j                         y)a,   This initialization implementation allows ordinary initialization
        of BlockNode objects as well as creating a DualBlockNode object
        using precreated or fetched BlockNode objects if provided as optional
        arguments primary and secondary.

        Parameters other than the following are from interfaces.BlockNode:

        :param BlockNode primary: Primary pre-created BlockNode, mainly
            used when creating new DualParser nodes using add_* methods.
        :param BlockNode secondary: Secondary pre-created BlockNode
        r   Nr   rM   )rQ   rR   rS   r    r   AugeasBlockNoder   ApacheBlockNoder   rV   r   r   rW   s       r   r    zDualBlockNode.__init__   s     	)T*+t,:@**Y:O<BJJ{<S	iy((GWi0G\99CFC)99CFCE 	t||T^^<r!   r0   r]   positionc                     | j                   j                  |||      }| j                  j                  |||      }t        j                  ||       t        ||      S )z Creates a new child BlockNode, asserts that both implementations
        did it in a similar way, and returns a newly created DualBlockNode object
        encapsulating both of the newly created objects r   )r   add_child_blockr   r   rV   r5   r   r0   r]   rh   primary_newsecondary_news         r   rj   zDualBlockNode.add_child_block   sQ     ll224XN66tZR{M:[MJJr!   c                     | j                   j                  |||      }| j                  j                  |||      }t        j                  ||       t        ||      S )z Creates a new child DirectiveNode, asserts that both implementations
        did it in a similar way, and returns a newly created DualDirectiveNode
        object encapsulating both of the newly created objects r   )r   add_child_directiver   r   rV   r\   rk   s         r   ro   z!DualBlockNode.add_child_directive   sQ     ll66tZR::4XV{M: NNr!   commentc                     | j                   j                  ||      }| j                  j                  ||      }t        j                  ||       t        ||      S )z Creates a new child CommentNode, asserts that both implementations
        did it in a similar way, and returns a newly created DualCommentNode
        object encapsulating both of the newly created objects )rp   rh   )r0   rh   r   )r   add_child_commentr   r   rV   rO   )r   rp   rh   rl   rm   s        r   rr   zDualBlockNode.add_child_comment   sT     ll44Wx4X88gPX8Y{M:{mLLr!   primary_listsecondary_listc                     g }|D ]E  }d}|D ]  }	 t        j                  ||       |} n |r|j                  ||f       <t        d       |S # t        $ r Y Nw xY w)a   Matches the list of primary_list to a list of secondary_list and
        returns a list of tuples. This is used to create results for find_
        methods.

        This helper function exists, because we cannot ensure that the list of
        search results returned by primary.find_* and secondary.find_* are ordered
        in a same way. The function pairs the same search results from both
        implementations to a list of tuples.
        NzCould not find a matching node.)r   rV   AssertionErrorr<   )r   rs   rt   matchedrF   matchrG   s          r   r>   z#DualBlockNode._create_matching_list   s      	HAE# **1a0E	 5z*$%FGG	H  & s   A	AAexcludec                 4    | j                  t        d||      S )a  
        Performs a search for BlockNodes using both implementations and does simple
        checks for results. This is built upon the assumption that unimplemented
        find_* methods return a list with a single assertion passing object.
        After the assertion, it creates a list of newly created DualBlockNode
        instances that encapsulate the pairs of returned BlockNode objects.
        find_blocksry   r3   r   r0   ry   s      r   r{   zDualBlockNode.find_blocks  s%       t)0 ! 2 	2r!   c                 4    | j                  t        d||      S )a  
        Performs a search for DirectiveNodes using both implementations and
        checks the results. This is built upon the assumption that unimplemented
        find_* methods return a list with a single assertion passing object.
        After the assertion, it creates a list of newly created DualDirectiveNode
        instances that encapsulate the pairs of returned DirectiveNode objects.
        find_directivesr|   )r4   r\   r}   s      r   r   zDualBlockNode.find_directives  s'       !24Et)0 ! 2 	2r!   c                 0    | j                  t        d|      S )a  
        Performs a search for CommentNodes using both implementations and
        checks the results. This is built upon the assumption that unimplemented
        find_* methods return a list with a single assertion passing object.
        After the assertion, it creates a list of newly created DualCommentNode
        instances that encapsulate the pairs of returned CommentNode objects.
        find_comments)r4   rO   )r   rp   s     r   r   zDualBlockNode.find_comments$  s       /7KKr!   c                     | j                   j                  |j                          | j                  j                  |j                         y)zDeletes a child from the ParserNode implementations. The actual
        ParserNode implementations are used here directly in order to be able
        to match a child to the list of children.N)r   delete_childr   )r   childs     r   r   zDualBlockNode.delete_child/  s0    
 	!!%--0##EOO4r!   c                     | j                   j                         }| j                  j                         }t        j                  ||       |S )zQ Fetches the list of unsaved file paths and asserts that the lists
        match )r   unsaved_filesr   r   r+   )r   primary_filessecondary_filess      r   r   zDualBlockNode.unsaved_files7  s>     224..668$$]ODr!   c                     | j                   j                         }| j                  j                         }t        j                  ||       |S )an  
        Returns a list of file paths that have currently been parsed into the parser
        tree. The returned list may include paths with wildcard characters, for
        example: ['/etc/apache2/conf.d/*.load']

        This is typically called on the root node of the ParserNode tree.

        :returns: list of file paths of files that have been parsed
        )r   parsed_pathsr   r   assertEqualPathsList)r   primary_pathssecondary_pathss      r   r   zDualBlockNode.parsed_paths@  s>     113..557''Gr!   )NN) N)T)r   r5   r   N)rH   rI   rJ   rK   r   r    rL   r   r   intrj   r\   ro   rO   rr   r   r   
ParserNoder	   r>   boolr{   r   r   r   r   r   r   rY   rZ   s   @r   r5   r5      s   == = =6 LP26	KC 	KXd3i5H 	K"*3-	K;J	K PT6:	O 	O$s)9L 	O&.sm	O?P	O 0248	M 	M$,SM	M=L	M(:;P;P2Q .6z7L7L.M#'j.C.CZEZEZ.Z([#\:
2 
2d 
2d?>S 
2
2C 
2$ 
2$GXBY 
2	LS 	LT/-B 	L5s3x d3i r!   r5   N)"rK   typingr   r   r   r   r   r   r	   r
   r   r   certbot_apache._internalr   r   r   r   %certbot_apache._internal.apacheparserr   %certbot_apache._internal.augeasparserr   r   r   r   r   rT   rU   rO   r_   r`   r\   rf   rg   r5   rM   r!   r   <module>r      s    &            1 / 1 /FF!";CUV !";CUV +>BG724KKL GT=l<#A#A#/#A#A$B C =@'=\%E%E%1%E%E&F G '=T_L!=!=!-!=!="> ? _r!   