U
    Sh>                     @  s  d Z ddlm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	m
Z
 ddlmZmZmZmZ ddlmZ ddlZerddlmZ G dd	 d	eZG d
d deZdddddZdddddZdDddddddZddddddZddddddZdZG dd dZejddd d!d"d#d$Z d dd%d&d'd(Z!e
G d)d* d*Z"ddddd+d,ddddd-d.d/d0Z#ddddd+d1ddddd-d.d2d3Z$d4d5ddddd d d6d7d8Z%ddd9d d:d;dd<d=d>Z&dEd?d@dAdBZ'e(dCkre'  dS )Fa  Logic for dealing with sphinx style inventories (e.g. `objects.inv`).

These contain mappings of reference names to ids, scoped by domain and object type.

This is adapted from the Sphinx inventory.py module.
We replicate it here, so that it can be used without Sphinx.
    )annotationsN)asdict	dataclass)IOTYPE_CHECKINGIterator	TypedDict)urlopen)	Inventoryc                   @  s"   e Zd ZU dZded< ded< dS )InventoryItemTypezA single inventory item.strloc
str | NonetextN__name__
__module____qualname____doc____annotations__ r   r   H/root/rtd-docs/venv/lib/python3.8/site-packages/myst_parser/inventory.pyr      s   
r   c                   @  s2   e Zd ZU dZded< ded< ded< ded< d	S )
InventoryTypezInventory data.r   nameversionr   base_urlz2dict[str, dict[str, dict[str, InventoryItemType]]]objectsNr   r   r   r   r   r   %   s   
r   SphinxInventoryType)invreturnc                 C  s   d}d}i }|   D ]z\}}d|kr&q|dd\}}||i |i  |  D ]:\}}	|	\}}}
}|
|rt|dkrxdn|d|| | |< qRq||d|dS )z'Convert from a Sphinx compliant format. :   -Nr   r   r   r   r   r   )itemssplit
setdefault)r   projectr   objsdomain_obj_namedatadomain_nameobj_typerefnamerefdataurir   r   r   r   from_sphinx2   s$    r2   c              	   C  sx   i }| d   D ]b\}}|  D ]P\}}|  D ]>\}}| d | d |d |d pTdf|| d| i |< q0q q|S )z%Convert to a Sphinx compliant format.r   r   r   r   r   r#   r!   )r&   r(   )r   r*   r-   Z	obj_typesr.   refsr/   r0   r   r   r   	to_sphinxL   s    
 r4   r   r   )streamr   r   c                 C  sH   t | }|  }|dkr&t||S |dkr8t||S td| dS )z"Load inventory data from a stream.z# Sphinx inventory version 1z# Sphinx inventory version 2zinvalid inventory header: %sN)InventoryFileReaderreadlinerstrip_load_v1_load_v2
ValueError)r5   r   readerliner   r   r   load[   s    

r>   r6   c           
      C  s   |    dd }|    dd }|||i d}|  D ]v}| dd\}}}d}	|dkrvd}|d| 7 }n|d	| 7 }|d
 |	i |i  |dd|d
 |	 | |< q>|S )z.Load inventory data (format v1) from a stream.   Nr%      pymodmodulez#module-#r   r$   )r7   r8   	readlinesr'   r(   )
r5   r   projnamer   invdatar=   r   objtypelocationdomainr   r   r   r9   g   s"    r9   c                 C  s,  |    dd }|    dd }|||i d}|   }d|krRtd| |  D ]}td| }|stqZ| \}}}	}
}d|krqZ|dkr||d	 kr||d	 | krqZ|
d
r|
dd | }
|dd\}}|d	 	|i 	|i  |r|dkrd}|
|d|d	 | | |< qZ|S )z.Load inventory data (format v2) from a stream.r?   Nr%   zlibz-invalid inventory header (not compressed): %sz+(?x)(.+?)\s+(\S+)\s+(-?\d+)\s+?(\S*)\s+(.*)r!   z	py:moduler   $r"   r#   r$   )
r7   r8   r;   read_compressed_linesrematchgroupsendswithr'   r(   )r5   r   rF   r   rG   r=   mr   type_rI   r   rJ   rH   r   r   r   r:      s@    
	
r:   i @  c                   @  sf   e Zd ZdZdddddZdddd	Zd
dddZddddZddddZddddZ	dS )r6   zjA file reader for an inventory file.

    This reader supports mixture of texts and compressed texts.
    r   None)r5   r   c                 C  s   || _ d| _d| _d S )N    F)r5   buffereof)selfr5   r   r   r   __init__   s    zInventoryFileReader.__init__r   c                 C  s,   | j t}|dkrd| _|  j|7  _d S )NrW   T)r5   read_BUFSIZErY   rX   )rZ   chunkr   r   r   read_buffer   s    zInventoryFileReader.read_bufferr   c                 C  sh   | j d}|dkr<| j d |  }| j |d d  | _ n(| jrT| j  }d| _ n|   |  }|S )N   
rM   r"   rW   )rX   finddecoderY   r`   r7   )rZ   posr=   r   r   r   r7      s    
zInventoryFileReader.readlinezIterator[str]c                 c  s   | j s|  }|r |V  q d S N)rY   r7   )rZ   r=   r   r   r   rE      s    zInventoryFileReader.readlineszIterator[bytes]c                 c  s:   t  }| js,|   || jV  d| _q| V  d S )NrW   )rK   decompressobjrY   r`   
decompressrX   flush)rZ   Zdecompressorr   r   r   read_compressed_chunks   s    z*InventoryFileReader.read_compressed_chunksc                 c  s^   d}|   D ]L}||7 }|d}|dkr|d |  V  ||d d  }|d}q"qd S )NrW   ra   rM   r"   )ri   rb   rc   )rZ   bufr_   rd   r   r   r   rN      s    
z)InventoryFileReader.read_compressed_linesN)
r   r   r   r   r[   r`   r7   rE   ri   rN   r   r   r   r   r6      s      )maxsizer   zre.Pattern[str])patr   c                 C  s   d}d}| D ]h}|r0|dkr0|t |7 }d}q|rB|t d7 }d}|dkrTd}q|dkrf|d7 }q|t |7 }qt |S )zCreate a regex from a pattern, that can include `*` wildcards,
    to match 0 or more characters.

    `\*` is translated as a literal `*`.
    r    F*\Tz.*)rO   escapecompile)rm   regexZbackslash_lastcharr   r   r   _create_regex   s$    rt   bool)r   patternr   c                 C  s"   |dkrdS t |}|| dk	S )zMatch a whole name with a pattern, that can include `*` wildcards,
    to match 0 or more characters.

    To include a literal `*` in the pattern, use `\*`.
    NT)rt   	fullmatch)r   rv   rr   r   r   r   match_with_wildcard  s    rx   c                   @  sh   e Zd ZU dZded< ded< ded< ded< ded< ded< d	ed
< ded< d	ed< ddddZdS )InvMatchzA match from an inventory.r   r   rJ   otyper   r)   r   r   r   r   r   zdict[str, str]r\   c                 C  s   t | S re   )r   )rZ   r   r   r   r      s    zInvMatch.asdictN)r   r   r   r   r   r   r   r   r   r   ry     s   
ry   )invsdomainsotypestargetszdict[str, InventoryType]zIterator[InvMatch])inventoriesr{   r|   r}   r~   r   c                c  s   |   D ]\}}t||sq|d   D ]~\}}t||s<q(|  D ]`\}	}
t|	|sXqD|
  D ]B\}}t||r`t|||	||d |d |d |d |d d	V  q`qDq(qdS )	a  Filter a set of inventories.

    Filters are strings that can include `*` wildcards, to match 0 or more characters.
     To include a literal `*` in the pattern, use `\*`.

    :param inventories: Mapping of inventory name to inventory data
    :param invs: the inventory key filter
    :param domains: the domain name filter
    :param otypes: the object type filter
    :param targets: the target name filter
    r   r   r   r   r   r   	r   rJ   rz   r   r)   r   r   r   r   N)r&   rx   ry   )r   r{   r|   r}   r~   inv_nameinv_datar-   Zdom_datar.   Zobj_datatargetZ	item_datar   r   r   filter_inventories$  s,    



r   zdict[str, SphinxInventoryType]c                c  s   |   D ]\}}t||sq|  D ]\}}d|kr6q$|dd\}	}
t|	|r$t|
|s\q$|D ]J}t||r`|| \}}}}t||	|
|||d||r|dkrdn|d	V  q`q$qdS )a  Filter a set of sphinx style inventories.

    Filters are strings that can include `*` wildcards, to match 0 or more characters.
     To include a literal `*` in the pattern, use `\*`.

    :param inventories: Mapping of inventory name to inventory data
    :param invs: the inventory key filter
    :param domains: the domain name filter
    :param otypes: the object type filter
    :param targets: the target name filter
    r!   r"   Nr#   r   )r&   rx   r'   ry   )r   r{   r|   r}   r~   r   r   r+   r,   r-   r.   r   r)   r   r   r   r   r   r   filter_sphinx_inventoriesO  s6    

r   r!   )	delimiter)r{   r|   rz   r   r   r   c                C  s\   g }| |||fD ]@}|dkr(| d q||krD| d| d q| |  q||S )zGCreate a string representation of the filter, from the given arguments.Nrn   ")appendjoin)r{   r|   rz   r   r   Z	str_itemsitemr   r   r   filter_string  s    	r   )timeoutr   zNone | floatz
None | str)r1   r   r   r   c             
   C  sd   |  dr6t| |d}t||dW  5 Q R  S Q R X t| d}t||dW  5 Q R  S Q R X dS )z,Fetch an inventory from a URL or local path.)http://https://r   )r   rbN)
startswithr	   r>   open)r1   r   r   r5   r   r   r   fetch_inventory  s
    
r   zNone | list[str])inputsc                 C  s  t jdd}|jdddd |jddd	d
dd |jdddd
dd |jdddd
dd |jddddd |jddddgddd |jdtd d!d" || }d#}|jd$s|jd%r>z:t|j|jd&}t	|}W 5 Q R X |j
d'd(d) }W nD tk
r:   t|jd* |jd&}t	|}W 5 Q R X |j}Y nX n t|jd+}t	|}W 5 Q R X |d, |d- |i d.}td/|i|j|j|jd0D ]N}|jrt|j|jsq|j|jd1|d2 |ji |ji |j< q|jdkr ttj|d3d4d5 nttj|d4d6 d#S )7z=Command line interface for fetching and parsing an inventory.zParse an inventory file.)descriptionr1   z
[URL|PATH]zURI of the inventory file)metavarhelpz-dz--domainZDOMAINrn   z/Filter the inventory by domain (`*` = wildcard))r   defaultr   z-oz--object-typeZTYPEz4Filter the inventory by object type (`*` = wildcard)z-nz--nameNAMEz7Filter the inventory by reference name (`*` = wildcard)z-lz--locZLOCz;Filter the inventory by reference location (`*` = wildcard)z-fz--formatyamljsonzOutput format)choicesr   r   z	--timeoutZSECONDSz"Timeout for fetching the inventory)rT   r   r   Nr   r   r   /r"   r   z/objects.invr   r   r   r%   r    )r|   r}   r~   r$   r   r@   F)indent	sort_keys)r   )argparseArgumentParseradd_argumentfloat
parse_argsr1   r   r	   r   r>   rsplit	Exceptionr   r   rJ   Zobject_typer   r   rx   r   r(   rz   formatprintr   dumpsr   dump)r   parserargsr   r5   rG   filteredrP   r   r   r   inventory_cli  s    

r   __main__)N)N))r   
__future__r   r   	functoolsr   rO   rK   dataclassesr   r   typingr   r   r   r   urllib.requestr	   r   Zsphinx.util.typingr
   r   r   r   r2   r4   r>   r9   r:   r^   r6   	lru_cachert   rx   ry   r   r   r   r   r   r   r   r   r   r   <module>   sX   	/8
.7 W
