o
    Rŀg"                     @   s  d Z ddlZddlZddlZddlZddlZddlZddlmZ e	de e
dZeds2J eds9J eddu sBJ ed	du sKJ ed
du sTJ eds[J edsbJ edsiJ g dZdgZG dd dejZG dd dZG dd dZG dd deZG dd deZG dd deZG dd deZG dd deZd d! Zd"d Zed#kre  dS dS )$a7  General mechanisms to access applications in Biopython (DEPRECATED).

This module is not intended for direct use. It provides the basic objects which
are subclassed by our command line wrappers, such as:

 - Bio.Align.Applications
 - Bio.Blast.Applications
 - Bio.Emboss.Applications
 - Bio.Sequencing.Applications

These modules provide wrapper classes for command line tools to help you
construct command line strings by setting the values of each parameter.
The finished command line strings are then normally invoked via the built-in
Python module subprocess.

Due to the on going maintenance burden or keeping command line application
wrappers up to date, we have decided to deprecate and eventually remove them.
We instead now recommend building your command line and invoking it directly
with the subprocess module.
    N)BiopythonDeprecationWarningaX  The Bio.Application modules and modules relying on it have been deprecated.

Due to the on going maintenance burden of keeping command line application
wrappers up to date, we have decided to deprecate and eventually remove these
modules.

We instead now recommend building your command line and invoking it directly
with the subprocess module.z^[a-zA-Z][a-zA-Z0-9_]*$ttest_testz-testz
any-hyphenunderscore_ok	test_nametest2)anddelfromnotwhileaselifglobalorwithassertelseifpassyieldbreakexceptimportprintclassexecinraisecontinuefinallyisreturndefforlambdatryset_parameterc                   @   s*   e Zd ZdZd
ddZdd Zdd Zd	S )ApplicationErroraS  Raised when an application returns a non-zero exit status (OBSOLETE).

    The exit status will be stored in the returncode attribute, similarly
    the command line string used in the cmd attribute, and (if captured)
    stdout and stderr as strings.

    This exception is a subclass of subprocess.CalledProcessError.

    >>> err = ApplicationError(-11, "helloworld", "", "Some error text")
    >>> err.returncode, err.cmd, err.stdout, err.stderr
    (-11, 'helloworld', '', 'Some error text')
    >>> print(err)
    Non-zero return code -11 from 'helloworld', message 'Some error text'

     c                 C   s   || _ || _|| _|| _dS )zInitialize the class.N
returncodecmdstdoutstderr)selfr,   r-   r.   r/    r1   L/var/www/html/myenv/lib/python3.10/site-packages/Bio/Application/__init__.py__init__w   s   
zApplicationError.__init__c                 C   s\   z| j  ddd  }W n ty   d}Y nw |r&d| j| j|f S d| j| jf S )zFormat the error as a string.
   r   r*   z+Non-zero return code %d from %r, message %rzNon-zero return code %d from %r)r/   lstripsplitrstrip	Exceptionr,   r-   )r0   msgr1   r1   r2   __str__~   s   zApplicationError.__str__c                 C   s   d| j | j| j| jf S )z Represent the error as a string.z ApplicationError(%i, %s, %s, %s)r+   r0   r1   r1   r2   __repr__   s   zApplicationError.__repr__N)r*   r*   )__name__
__module____qualname____doc__r3   r;   r=   r1   r1   r1   r2   r)   f   s
    
r)   c                   @   sh   e Zd ZdZdZdd Zdd Zdd Zd	d
 Zdd Z	dd Z
dddZdd Zdd ZdddZdS )AbstractCommandlinea  Generic interface for constructing command line strings (OBSOLETE).

    This class shouldn't be called directly; it should be subclassed to
    provide an implementation for a specific application.

    For a usage example we'll show one of the EMBOSS wrappers.  You can set
    options when creating the wrapper object using keyword arguments - or
    later using their corresponding properties:

    >>> from Bio.Emboss.Applications import WaterCommandline
    >>> cline = WaterCommandline(gapopen=10, gapextend=0.5)
    >>> cline
    WaterCommandline(cmd='water', gapopen=10, gapextend=0.5)

    You can instead manipulate the parameters via their properties, e.g.

    >>> cline.gapopen
    10
    >>> cline.gapopen = 20
    >>> cline
    WaterCommandline(cmd='water', gapopen=20, gapextend=0.5)

    You can clear a parameter you have already added by 'deleting' the
    corresponding property:

    >>> del cline.gapopen
    >>> cline.gapopen
    >>> cline
    WaterCommandline(cmd='water', gapextend=0.5)

    Once you have set the parameters you need, you can turn the object into
    a string (e.g. to log the command):

    >>> str(cline)
    Traceback (most recent call last):
    ...
    ValueError: You must either set outfile (output filename), or enable filter or stdout (output to stdout).

    In this case the wrapper knows certain arguments are required to construct
    a valid command line for the tool.  For a complete example,

    >>> from Bio.Emboss.Applications import WaterCommandline
    >>> water_cmd = WaterCommandline(gapopen=10, gapextend=0.5)
    >>> water_cmd.asequence = "asis:ACCCGGGCGCGGT"
    >>> water_cmd.bsequence = "asis:ACCCGAGCGCGGT"
    >>> water_cmd.outfile = "temp_water.txt"
    >>> print(water_cmd)
    water -outfile=temp_water.txt -asequence=asis:ACCCGGGCGCGGT -bsequence=asis:ACCCGAGCGCGGT -gapopen=10 -gapextend=0.5
    >>> water_cmd
    WaterCommandline(cmd='water', outfile='temp_water.txt', asequence='asis:ACCCGGGCGCGGT', bsequence='asis:ACCCGAGCGCGGT', gapopen=10, gapextend=0.5)

    You would typically run the command line via a standard Python operating
    system call using the subprocess module for full control. For the simple
    case where you just want to run the command and get the output:

    stdout, stderr = water_cmd()

    Note that by default we assume the underlying tool is installed on the
    system $PATH environment variable. This is normal under Linux/Unix, but
    may need to be done manually under Windows. Alternatively, you can specify
    the full path to the binary as the first argument (cmd):

    >>> from Bio.Emboss.Applications import WaterCommandline
    >>> water_cmd = WaterCommandline(r"C:\Program Files\EMBOSS\water.exe",
    ...                              gapopen=10, gapextend=0.5,
    ...                              asequence="asis:ACCCGGGCGCGGT",
    ...                              bsequence="asis:ACCCGAGCGCGGT",
    ...                              outfile="temp_water.txt")
    >>> print(water_cmd)
    "C:\Program Files\EMBOSS\water.exe" -outfile=temp_water.txt -asequence=asis:ACCCGGGCGCGGT -bsequence=asis:ACCCGAGCGCGGT -gapopen=10 -gapextend=0.5

    Notice that since the path name includes a space it has automatically
    been quoted.

    Nc                 K   sn  || _ z| j}W n ty   tddw t }|D ]}|js-t|ts,td|dq|jD ]}||v r>td| d|	| q0|jd }t
|du rVtd| |tv r`td	| |tv rjtd
| dd }dd }dd }	|j}
t|tr|
d|jd  7 }
n	|
d|jd  7 }
t|||||	||
}t| j|| q| D ]
\}}| || qdS )z7Create a new instance of a command line wrapper object.z,Subclass should have defined self.parametersNz	Expected z to be of type _StaticArgumentzParameter alias z multiply definedzPFinal parameter name %r cannot be used as an argument or property name in pythonznFinal parameter name %r cannot be used as an argument or property name because it is a reserved word in pythonzyFinal parameter name %r cannot be used as an argument or property name due to the way the AbstractCommandline class worksc                        fddS )Nc                    
   |   S N)_get_parameterxnamer1   r2   <lambda>&     
 z>AbstractCommandline.__init__.<locals>.getter.<locals>.<lambda>r1   rJ   r1   rJ   r2   getter%     z,AbstractCommandline.__init__.<locals>.getterc                    rD   )Nc                    s   |   |S rF   )r(   )rI   valuerJ   r1   r2   rL   )  s    z>AbstractCommandline.__init__.<locals>.setter.<locals>.<lambda>r1   rJ   r1   rJ   r2   setter(  rO   z,AbstractCommandline.__init__.<locals>.setterc                    rD   )Nc                    rE   rF   )_clear_parameterrH   rJ   r1   r2   rL   ,  rM   z?AbstractCommandline.__init__.<locals>.deleter.<locals>.<lambda>r1   rJ   r1   rJ   r2   deleter+  rO   z-AbstractCommandline.__init__.<locals>.deleterzY

This property controls the addition of the %s switch, treat this property as a boolean.r   z}

This controls the addition of the %s parameter and its associated value.  Set this property to the argument value required.)program_name
parametersAttributeErrorsetnames
isinstance_StaticArgument	TypeError
ValueErroradd_re_prop_namematch_reserved_names_local_reserved_namesdescription_Switchpropertysetattr	__class__itemsr(   )r0   r-   kwargsrU   aliasesprK   rN   rQ   rS   docpropkeyrP   r1   r1   r2   r3      sv   




zAbstractCommandline.__init__c                 C   s2   | j D ]}|jr|jstd|jd  dqdS )zMake sure the required parameters have been set (PRIVATE).

        No return value - it either works or raises a ValueError.

        This is a separate method (called from __str__) so that subclasses may
        override it.
        z
Parameter rC   z is not set.N)rU   is_requiredis_setr\   rX   )r0   rj   r1   r1   r2   	_validate?  s
   
zAbstractCommandline._validatec                 C   s>   |    t| j d}| jD ]}|jr|t|7 }q| S )a  Make the commandline string with the currently set options.

        e.g.

        >>> from Bio.Emboss.Applications import WaterCommandline
        >>> cline = WaterCommandline(gapopen=10, gapextend=0.5)
        >>> cline.asequence = "asis:ACCCGGGCGCGGT"
        >>> cline.bsequence = "asis:ACCCGAGCGCGGT"
        >>> cline.outfile = "temp_water.txt"
        >>> print(cline)
        water -outfile=temp_water.txt -asequence=asis:ACCCGGGCGCGGT -bsequence=asis:ACCCGAGCGCGGT -gapopen=10 -gapextend=0.5
        >>> str(cline)
        'water -outfile=temp_water.txt -asequence=asis:ACCCGGGCGCGGT -bsequence=asis:ACCCGAGCGCGGT -gapopen=10 -gapextend=0.5'
         )rp   _escape_filenamerT   rU   ro   strstrip)r0   commandline	parameterr1   r1   r2   r;   M  s   
zAbstractCommandline.__str__c                 C   sp   | j j d| j}| jD ]$}|jr1t|tr#|d|jd  d7 }q|d|jd  d|j7 }q|d7 }|S )a  Return a representation of the command line object for debugging.

        e.g.

        >>> from Bio.Emboss.Applications import WaterCommandline
        >>> cline = WaterCommandline(gapopen=10, gapextend=0.5)
        >>> cline.asequence = "asis:ACCCGGGCGCGGT"
        >>> cline.bsequence = "asis:ACCCGAGCGCGGT"
        >>> cline.outfile = "temp_water.txt"
        >>> print(cline)
        water -outfile=temp_water.txt -asequence=asis:ACCCGGGCGCGGT -bsequence=asis:ACCCGAGCGCGGT -gapopen=10 -gapextend=0.5
        >>> cline
        WaterCommandline(cmd='water', outfile='temp_water.txt', asequence='asis:ACCCGGGCGCGGT', bsequence='asis:ACCCGAGCGCGGT', gapopen=10, gapextend=0.5)
        z(cmd=z, rC   z=True=))	rf   r>   rT   rU   ro   rY   rc   rX   rP   )r0   answerrv   r1   r1   r2   r=   d  s   

zAbstractCommandline.__repr__c                 C   sD   | j D ]}||jv rt|tr|j  S |j  S qtd| d)z)Get a commandline option value (PRIVATE).Option name  was not found.)rU   rX   rY   rc   ro   rP   r\   )r0   rK   rv   r1   r1   r2   rG   }  s   




z"AbstractCommandline._get_parameterc                 C   sB   d}| j D ]}||jv rd|_d|_d}q|std| ddS )z4Reset or clear a commandline option value (PRIVATE).FNTrz   r{   )rU   rX   rP   ro   r\   )r0   rK   cleared_optionrv   r1   r1   r2   rR     s   

z$AbstractCommandline._clear_parameterc                 C   s   d}| j D ]:}||jv r?t|tr+|du r#ddl}|d|jd   t||_d}q|dur:| |||j	 ||_
d|_d}q|sJtd| ddS )	ac  Set a commandline option for a program (OBSOLETE).

        Every parameter is available via a property and as a named
        keyword when creating the instance. Using either of these is
        preferred to this legacy set_parameter method which is now
        OBSOLETE, and likely to be DEPRECATED and later REMOVED in
        future releases.
        FNr   zSFor a switch type argument like %s, we expect a boolean.  None is treated as FALSE!rC   Trz   r{   )rU   rX   rY   rc   warningswarnboolro   _check_valuechecker_functionrP   r\   )r0   rK   rP   
set_optionrv   r}   r1   r1   r2   r(     s,   	



z!AbstractCommandline.set_parameterc                 C   sH   |dur ||}|dvrt d|d|s"t d|d| dS dS )az  Check whether the given value is valid (PRIVATE).

        No return value - it either works or raises a ValueError.

        This uses the passed function 'check_function', which can either
        return a [0, 1] (bad, good) value or raise an error. Either way
        this function will raise an error if the value is not valid, or
        finish silently otherwise.
        N)r   r5   TFzResult of check_function: z is of an unexpected valuezInvalid parameter value z for parameter )r\   )r0   rP   rK   check_functionis_goodr1   r1   r2   r     s   

z AbstractCommandline._check_valuec                 C   s&   |dv r|| j |< dS | || dS )ad  Set attribute name to value (PRIVATE).

        This code implements a workaround for a user interface issue.
        Without this __setattr__ attribute-based assignment of parameters
        will silently accept invalid parameters, leading to known instances
        of the user assuming that parameters for the application are set,
        when they are not.

        >>> from Bio.Emboss.Applications import WaterCommandline
        >>> cline = WaterCommandline(gapopen=10, gapextend=0.5, stdout=True)
        >>> cline.asequence = "a.fasta"
        >>> cline.bsequence = "b.fasta"
        >>> cline.csequence = "c.fasta"
        Traceback (most recent call last):
        ...
        ValueError: Option name csequence was not found.
        >>> print(cline)
        water -stdout -asequence=a.fasta -bsequence=b.fasta -gapopen=10 -gapextend=0.5

        This workaround uses a whitelist of object attributes, and sets the
        object attribute list as normal, for these.  Other attributes are
        assumed to be parameters, and passed to the self.set_parameter method
        for validation and assignment.
        )rU   rT   N)__dict__r(   )r0   rK   rP   r1   r1   r2   __setattr__  s   zAbstractCommandline.__setattr__Tc              
   C   s>  |s	t tjd}nt|trt |d}ntj}|s t tjd}nt|tr2||kr,|}n	t |d}ntj}tjdkr=d}nt	 d }	|	dv rJd}nd}tj
t| tj||d|||d}
|
|\}}|sk|rkJ ||ss|rsJ ||
j}|r}t|tr|  |rt|tr||kr|  |rt|t| ||||fS )a#  Execute command, wait for it to finish, return (stdout, stderr).

        Runs the command line tool and waits for it to finish. If it returns
        a non-zero error level, an exception is raised. Otherwise two strings
        are returned containing stdout and stderr.

        The optional stdin argument should be a string of data which will be
        passed to the tool as standard input.

        The optional stdout and stderr argument may be filenames (string),
        but otherwise are treated as a booleans, and control if the output
        should be captured as strings (True, default), or ignored by sending
        it to /dev/null to avoid wasting memory (False). If sent to a file
        or ignored, then empty string(s) are returned.

        The optional cwd argument is a string giving the working directory
        to run the command from. See Python's subprocess module documentation
        for more details.

        The optional env argument is a dictionary setting the environment
        variables to be used in the new process. By default the current
        process' environment variables are used. See Python's subprocess
        module documentation for more details.

        Default example usage::

            from Bio.Emboss.Applications import WaterCommandline
            water_cmd = WaterCommandline(gapopen=10, gapextend=0.5,
                                         stdout=True, auto=True,
                                         asequence="a.fasta", bsequence="b.fasta")
            print("About to run: %s" % water_cmd)
            std_output, err_output = water_cmd()

        This functionality is similar to subprocess.check_output(). In general
        if you require more control over running the command, use subprocess
        directly.

        When the program called returns a non-zero error level, a custom
        ApplicationError exception is raised. This includes any stdout and
        stderr strings captured as attributes of the exception object, since
        they may be useful for diagnosing what went wrong.
        wwin32Tr   )78post2012Server10F)stdinr.   r/   universal_newlinescwdenvshell)openosdevnullrY   rs   
subprocessPIPEsysplatform	win32_verPopencommunicater,   closer)   )r0   r   r.   r/   r   r   
stdout_arg
stderr_arg	use_shellwin_verchild_process
stdout_str
stderr_strreturn_coder1   r1   r2   __call__  sR   +


zAbstractCommandline.__call__rF   )NTTNN)r>   r?   r@   rA   rU   r3   rp   r;   r=   rG   rR   r(   r   r   r   r1   r1   r1   r2   rB      s    RR

 rB   c                   @       e Zd ZdZdd Zdd ZdS )_AbstractParameterzA class to hold information about a parameter for a commandline.

    Do not use this directly, instead use one of the subclasses.
    c                 C      t rF   NotImplementedErrorr<   r1   r1   r2   r3   Y     z_AbstractParameter.__init__c                 C   r   rF   r   r<   r1   r1   r2   r;   \  r   z_AbstractParameter.__str__Nr>   r?   r@   rA   r3   r;   r1   r1   r1   r2   r   S  s    r   c                   @   s*   e Zd ZdZ				d	ddZdd ZdS )
_OptionaF  Represent an option that can be set for a program.

    This holds UNIXish options like --append=yes and -a yes,
    where a value (here "yes") is generally expected.

    For UNIXish options like -kimura in clustalw which don't
    take a value, use the _Switch object instead.

    Attributes:
     - names -- a list of string names (typically two entries) by which
       the parameter can be set via the legacy set_parameter method
       (eg ["-a", "--append", "append"]). The first name in list is used
       when building the command line. The last name in the list is a
       "human readable" name describing the option in one word. This
       must be a valid Python identifier as it is used as the property
       name and as a keyword argument, and should therefore follow PEP8
       naming.
     - description -- a description of the option. This is used as
       the property docstring.
     - filename -- True if this argument is a filename (or other argument
       that should be quoted) and should be automatically quoted if it
       contains spaces.
     - checker_function -- a reference to a function that will determine
       if a given value is valid for this parameter. This function can either
       raise an error when given a bad value, or return a [0, 1] decision on
       whether the value is correct.
     - equate -- should an equals sign be inserted if a value is used?
     - is_required -- a flag to indicate if the parameter must be set for
       the program to be run.
     - is_set -- if the parameter has been set
     - value -- the value of a parameter

    FNTc                 C   sV   || _ t|tstd|d|d  || _|| _|| _|| _|| _d| _	d | _
d S NzShould be a string: z for rC   F)rX   rY   rs   r[   is_filenamer   rb   equatern   ro   rP   )r0   rX   rb   filenamer   rn   r   r1   r1   r2   r3     s   	

z_Option.__init__c                 C   sh   | j du r| jd  dS | jrt| j }nt| j }| jr)| jd  d| dS | jd  d| dS )aReturn the value of this option for the commandline.

        Includes a trailing space.
        Nr   rq   rw   )rP   rX   r   rr   rs   r   )r0   vr1   r1   r2   r;     s   
	
z_Option.__str__)FNFTr   r1   r1   r1   r2   r   `  s    &
r   c                   @   r   )rc   a  Represent an optional argument switch for a program.

    This holds UNIXish options like -kimura in clustalw which don't
    take a value, they are either included in the command string
    or omitted.

    Attributes:
     - names -- a list of string names (typically two entries) by which
       the parameter can be set via the legacy set_parameter method
       (eg ["-a", "--append", "append"]). The first name in list is used
       when building the command line. The last name in the list is a
       "human readable" name describing the option in one word. This
       must be a valid Python identifier as it is used as the property
       name and as a keyword argument, and should therefore follow PEP8
       naming.
     - description -- a description of the option. This is used as
       the property docstring.
     - is_set -- if the parameter has been set

    NOTE - There is no value attribute, see is_set instead,

    c                 C   s   || _ || _d| _d| _d S )NF)rX   rb   ro   rn   )r0   rX   rb   r1   r1   r2   r3        
z_Switch.__init__c                 C   s(   t | drJ | jr| jd  dS dS )r   rP   r   rq   r*   )hasattrro   rX   r<   r1   r1   r2   r;     s   z_Switch.__str__Nr   r1   r1   r1   r2   rc     s    rc   c                   @   s(   e Zd ZdZ			dddZdd ZdS )		_Argumenta  Represent an argument on a commandline.

    The names argument should be a list containing one string.
    This must be a valid Python identifier as it is used as the
    property name and as a keyword argument, and should therefore
    follow PEP8 naming.
    FNc                 C   sP   || _ t|tstd|d|d  || _|| _|| _|| _d| _d | _	d S r   )
rX   rY   rs   r[   r   r   rb   rn   ro   rP   )r0   rX   rb   r   r   rn   r1   r1   r2   r3     s   

z_Argument.__init__c                 C   s0   | j d u rdS | jrt| j  dS | j  dS Nrq   )rP   r   rr   r<   r1   r1   r2   r;     s
   
z_Argument.__str__)FNFr   r1   r1   r1   r2   r     s    
r   c                   @   s   e Zd ZdZdd ZdS )_ArgumentListzRRepresent a variable list of arguments on a command line, e.g. multiple filenames.c                 C   sR   t | jts
td| jstd| jr!ddd | jD d S d| jd S )NzArguments should be a listzRequires at least one filenamerq   c                 s   s    | ]}t |V  qd S rF   )rr   ).0r   r1   r1   r2   	<genexpr>  s    z(_ArgumentList.__str__.<locals>.<genexpr>)rY   rP   listr[   r\   r   joinr<   r1   r1   r2   r;     s   z_ArgumentList.__str__N)r>   r?   r@   rA   r;   r1   r1   r1   r2   r      s    r   c                   @   r   )rZ   zRepresent a static (read only) argument on a commandline.

    This is not intended to be exposed as a named argument or
    property of a command line wrapper object.
    c                 C   s   g | _ d| _d| _|| _d S )NFT)rX   rn   ro   rP   )r0   rP   r1   r1   r2   r3     r   z_StaticArgument.__init__c                 C   s   | j  dS r   )rP   r<   r1   r1   r2   r;   !  rO   z_StaticArgument.__str__Nr   r1   r1   r1   r2   rZ     s    rZ   c                 C   s>   t | ts| S d| vr| S | dr| dr| S d|  dS )a  Escape filenames with spaces by adding quotes (PRIVATE).

    Note this will not add quotes if they are already included:

    >>> print((_escape_filename('example with spaces')))
    "example with spaces"
    >>> print((_escape_filename('"example with spaces"')))
    "example with spaces"
    >>> print((_escape_filename(1)))
    1

    Note the function is more generic than the name suggests, since it
    is used to add quotes around any string arguments containing spaces.
    rq   ")rY   rs   
startswithendswith)r   r1   r1   r2   rr   %  s   
rr   c                  C   s   ddl } | jdd dS )z4Run the Bio.Application module's doctests (PRIVATE).r   Nr5   )verbose)doctesttestmod)r   r1   r1   r2   r   N  s   __main__)rA   r   r   rer   r   r}   Bior   r~   compiler^   r_   r`   ra   CalledProcessErrorr)   rB   r   r   rc   r   r   rZ   rr   r   r>   r1   r1   r1   r2   <module>   sN   	
"2   >N*()
