
    %h8                         d Z ddlZddlZddlZ	 ddlZn# e$ r dZY nw xY w	 ddlZn# e$ r ddlZY nw xY wdZde dZ	d Z
d Zd Zd	 Zd
 Zd Zd Z G d de          ZdS )z
Support for detecting various information from python projects metadata.

Metadata can only be loaded from static files (e.g. pyproject.toml, setup.cfg, etc.)
but not from setup.py due to its dynamic nature.
    Nz(===|==|!=|<=|>=|<|>|~=)z^(z?\d+(\.[\d\*]+)*)+$c                     t          |           D ]>\  }}t          |          }	  ||          }n# t          $ r
}Y d}~0d}~ww xY w|r|c S ?dS )zDetect the python version requirement for a project.

    The directory should contain a metadata file such as pyproject.toml,
    setup.cfg, or .python-version.

    Returns the python version requirement as a string or None if not found.
    N)lookup_metadata_file%get_python_version_requirement_parserInvalidVersionConstraintError)	directory_metadata_fileparserversion_constrainterrs         =/Users/aron/dev/rstudio/rsconnect/inst/resources/pyproject.py!detect_python_version_requirementr      s     1;; 	& 	&=6}EE	!'!6!6, 	 	 	HHHH	  	&%%%%	& 4s   1
A Ac                 d     t          j                     fd}t           |                      S )aM  Given the directory of a project return the path of a usable metadata file.

    The returned value is either a list of tuples [(filename, path)] or
    an empty list [] if no metadata file was found.

    The metadata files are returned in the priority they should be processed
    to determine the python version requirements.
    c               3   T   K   dD ]!} | z  }|                                 r| |fV  "d S )N).python-versionpyproject.toml	setup.cfg)is_file)filenamepathr   s     r   	_generatez'lookup_metadata_file.<locals>._generate>   sL      J 	' 	'Hx'D||~~ '&&&&	' 	'    )pathlibPathlist)r   r   s   ` r   r   r   2   sC     Y''I' ' ' ' ' 		r   c                     | j         dk    rt          S | j         dk    rt          S | j         dk    rt          S t	          d| j                    )zGiven the metadata file, return the appropriate parser function.

    The returned function takes a pathlib.Path and returns the parsed value.
    r   r   r   zUnknown metadata file type: )nameparse_pyproject_python_requiresparse_setupcfg_python_requiresparse_pyversion_python_requiresNotImplementedError)r	   s    r   r   r   G   s\     ---..		{	*	*--		0	0	0..!"UAS"U"UVVVr   c                     |                                  }t          j        |          }|                    di                               dd          S )zParse the project.requires-python field from a pyproject.toml file.

    Assumes that the pyproject.toml file exists, is accessible and well formatted.

    Returns None if the field is not found.
    projectzrequires-pythonN)	read_texttomllibloadsget)pyproject_filecontent	pyprojects      r   r   r   W   sI     &&((Gg&&I==B''++,=tDDDr   c                     t          j                    }|                    |            |                    ddd          S )zParse the options.python_requires field from a setup.cfg file.

    Assumes that the setup.cfg file exists, is accessible and well formatted.

    Returns None if the field is not found.
    optionspython_requiresN)fallback)configparserConfigParserreadr'   )setupcfg_fileconfigs     r   r   r   e   s=     &((F
KK::i!2T:BBBr   c                 h    t          |                                                                           S )zParse the python version from a .python-version file.

    Assumes that the .python-version file exists, is accessible and well formatted.

    Returns None if the field is not found.
    )adapt_python_requiresr$   strip)pyversion_files    r   r    r    s   s*     !!9!9!;!;!A!A!C!CDDDr   c                 n    |                      d          }d }d                     ||                    S )zConvert a literal python version to a PEP440 constraint.

    Connect expects a PEP440 format, but the .python-version file can contain
    plain version numbers and other formats.

    We should convert them to the constraints that connect expects.
    ,c              3     K   | D ]}|                                 }d|v sd|v sd|v rt          d|           d|v sd|v sd|v rt          d|           t          j        t          |          t          d	|           t          j        t          |          r|V  d
|v rd| V  d                    |                    d          d d         dgz             }d| V  d S )N@-/z3python specific implementations are not supported: brcaz(pre-release versions are not supported: zInvalid python version: *z==.   0z~=)	r6   r   rematchVALID_VERSION_REQ_REGEXsearchPEP440_OPERATORS_REGEXjoinsplit)constraints
constraints     r   _adapt_contraintz/adapt_python_requires.<locals>._adapt_contraint   sX     % 	, 	,J#))++Jj  C:$5$5
9J9J34vjt4v4vwwwj  DJ$6$6#:K:K34k_i4k4klllx/<<D34[z4[4[\\\y/<< 
,      *$$+z++++++ "%**:*:3*?*?*Cse*K!L!LJ+z+++++++	, 	,r   )rK   rJ   )r-   current_contraintsrN   s      r   r5   r5   ~   sH     )..s33, , ,2 88$$%788999r   c                       e Zd ZdS )r   N)__name__
__module____qualname__ r   r   r   r      s        Dr   r   )__doc__r/   r   rE   typingImportErrorr%   tomlrI   rG   r   r   r   r   r   r    r5   
ValueErrorr   rT   r   r   <module>rZ      sd         				MMMM   FFFNNNN    5 K 6KKK   .  *W W W E E EC C CE E E$: $: $:N	 	 	 	 	J 	 	 	 	 	s    ( 	44