o
    bj3                     @  s  d dl m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mZmZmZmZmZmZmZmZmZ d dl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% d dl&m'Z' d dl(m)Z)m*Z*m+Z+ erd dl,m-Z- G dd deZ.d?ddZ/d?ddZ0d@ddZ1dAd#d$Z2dBd)d*Z3dCd.d/Z4G d0d1 d1e5Z6e6d2Z7ed3d4d5Z8eree9e5f Z:neZ:eG d6d4 d4e:Z;eree9ef Z<neZ<ed7d8d5Z=G d9d8 d8e<Z>dDd=d>Z?dS )E    )annotationsN)abstractmethod)MappingMutableMapping)deepcopy)	lru_cache)TYPE_CHECKINGAnyDictIterator
NamedTupleOptionalSequenceSetTypeTypeVarcast)definefield)	unionRect)	Transform)	BoundsPenControlBoundsPen)	UFOReader	UFOWriter)OBJECT_LIBS_KEY)DrawableGlyphSetHasIdentifier)GenConverterc                   @  s2   e Zd ZU dZded< ded< ded< ded< dS )BoundingBoxzARepresents a bounding box as a tuple of (xMin, yMin, xMax, yMax).floatZxMinZyMinZxMaxZyMaxN)__name__
__module____qualname____doc____annotations__ r'   r'   6/usr/lib/python3/dist-packages/ufoLib2/objects/misc.pyr    %   s   
 r    drawabler   layerGlyphSet | NonereturnBoundingBox | Nonec                 C  0   t |}d|_| | |jd u rd S t|j S NF)r   skipMissingComponentsdrawboundsr    r)   r*   Zpenr'   r'   r(   	getBounds.      
r4   c                 C  r.   r/   )r   r0   r1   r2   r    r3   r'   r'   r(   getControlBounds6   r5   r6   bounds1bounds2c                 C  s&   | d u r|S |d u r| S t t| | S N)r    r   )r7   r8   r'   r'   r(   unionBounds>   s
   r:   selfr	   memoc                   sF   t ddrtdr  jdi  fddtjD S )N_lazyTunlazifyc                   sR   i | ]%}|j r|jd dr|jd dkr|jn|jdd tt|j qS )ZcopyableTr   _   N)initmetadatagetnamer   getattr).0ar<   r;   r'   r(   
<dictcomp>L   s    "z,_deepcopy_unlazify_attrs.<locals>.<dictcomp>r'   )rE   hasattrr>   	__class__attrfields)r;   r<   r'   rH   r(   _deepcopy_unlazify_attrsH   s   
rN   
parent_libdict[str, Any]objr   c                 C  sr   |j d u rtt |_ d| vri  }| d< n| d }t|tjjs$J |j |v r0||j  }|S i }|||j < |S )Nzpublic.objectLibs)Z
identifierstruuidZuuid4
isinstancecollectionsabcr   )rO   rQ   object_libsZ
object_liblibr'   r'   r(   _object_libV   s   



rY   identifiersset[str]Nonec                   s2   t | vrdS | t  } fdd| D | t < dS )zPrune non-existing objects and empty libs from a lib's
    public.objectLibs.

    Empty object libs are pruned, but object identifiers stay.
    Nc                   s"   i | ]\}}| v r|r||qS r'   r'   rF   kvrZ   r'   r(   rI   w   s    z&_prune_object_libs.<locals>.<dictcomp>)r   items)rO   rZ   rW   r'   r`   r(   _prune_object_libsl   s   
rb   c                   @  s   e Zd ZdZdS )DataPlaceholderzSRepresents a sentinel value to signal a "lazy" DataSet item hasn't been loaded yet.N)r"   r#   r$   r%   r'   r'   r'   r(   rc   |   s    rc   s   __UFOLIB2_DATA_NOT_LOADED__Tds	DataStore)Zboundc                   @  sT  e Zd ZU dZeedZded< edddddZded	< ed
ddddZ	ded< ee
ddddZded< dQddZdQddZedRdSdd ZeedTd"d#ZeedUd'd(ZeedVd-d.ZeedWd/d0ZdXd1d2ZeZdYd4d5ZdZd7d8Zd[d:d;Zd\d<d=Zd]d>d?Zd^d@dAZd_d`dDdEZe dadFdGZ!dbdKdLZ"edcdOdPZ#d
S )dre   zRepresents the base class for ImageSet and DataSet.

    Both behave like a dictionary that loads its "values" lazily by default and only
    differ in which reader and writer methods they call.
    )factoryzDict[str, bytes]_dataFT)defaultZkw_onlyeqrA   zOptional[bool]r=   N)rh   rA   reprri   zOptional[UFOReader]_reader)rf   rA   rj   ri   zSet[str]_scheduledForDeletionotherobjectr,   boolc                 C  sB   |j | j urtS tt|}| |fD ]	}|jr|  q| j|jkS r9   )rK   NotImplementedr   re   r=   r>   rg   )r;   rm   Z
data_storer'   r'   r(   __eq__   s   
zDataStore.__eq__c                 C  s   |  |}|tu rtS | S r9   )rq   rp   )r;   rm   resultr'   r'   r(   __ne__   s   
zDataStore.__ne__cls	type[Tds]readerr   lazyrd   c                 C  sL   |  }|  |D ]}|rt|j|< q| |||j|< q||_|r$||_|S )zFInstantiate the data store from a :class:`fontTools.ufoLib.UFOReader`.)list_contents_DATA_NOT_LOADEDrg   	read_datar=   rk   )rt   rv   rw   r;   fileNamer'   r'   r(   read   s   zDataStore.read	list[str]c                 C     dS )z;Returns a list of POSIX filename strings in the data store.Nr'   )rv   r'   r'   r(   rx         zDataStore.list_contentsfilenamerR   bytesc                 C  r~   )z.Returns the data at filename within the store.Nr'   )rv   r   r'   r'   r(   rz      r   zDataStore.read_datawriterr   datar\   c                 C  r~   )z-Writes the data to filename within the store.Nr'   )r   r   r   r'   r'   r(   
write_data   r   zDataStore.write_datac                 C  r~   )z-Remove the data at filename within the store.Nr'   )r   r   r'   r'   r(   remove_data   r   zDataStore.remove_datac                 C  s(   | j r| jdur|  D ]}qd| _ dS )zLoad all data into memory.NF)r=   rk   ra   )r;   r?   r'   r'   r(   r>      s   
zDataStore.unlazifyintc                 C  
   t | jS r9   )lenrg   r;   r'   r'   r(   __len__      
zDataStore.__len__Iterator[str]c                 C  r   r9   )iterrg   r   r'   r'   r(   __iter__   r   zDataStore.__iter__r{   c                 C  s.   | j | }|tu r| | j| }| j |< |S r9   )rg   ry   rz   rk   )r;   r{   Zdata_objectr'   r'   r(   __getitem__   s   
zDataStore.__getitem__c                 C  s(   || j |< || jv r| j| d S d S r9   )rg   rl   remove)r;   r{   r   r'   r'   r(   __setitem__   s   

zDataStore.__setitem__c                 C  s   | j |= | j| d S r9   )rg   rl   add)r;   r{   r'   r'   r(   __delitem__   s   zDataStore.__delitem__c              	   C  sJ   t | j}d| jj| jj|dkrdnd||dkrdndtt| S )Nz<{}.{} ({}) at {}>r   emptyz	{} file{}r@   s )r   rg   formatrK   r#   r"   hexid)r;   nr'   r'   r(   __repr__   s   
"
zDataStore.__repr__saveAsbool | Nonec                 C  s   |du r	| j |u}|s| jD ]}| || q| j D ]\}}|tu r4|r3| | j |}|| j|< nq| ||| qt | _|rGd| _ dS dS )z>Write the data store to a :class:`fontTools.ufoLib.UFOWriter`.N)	rk   rl   r   rg   ra   ry   rz   r   set)r;   r   r   r{   r   r'   r'   r(   write  s    


zDataStore.writec                 C  s   t | j S )z.Returns a list of filenames in the data store.)listrg   keysr   r'   r'   r(   	fileNames  s   zDataStore.fileNames	converterr   dict[str, str]c                   sX     d}t|trt| S t|tstt| fdd|  D }| jr*d| _|S )N    c                   s   i | ]
\}}|  |qS r'   )unstructurer]   r   r'   r(   rI   .  s    z*DataStore._unstructure.<locals>.<dictcomp>F)	r   rT   r   dictrR   NotImplementedErrortypera   r=   )r;   r   testr   r'   r   r(   _unstructure#  s   


zDataStore._unstructureMapping[str, Any]Type[DataStore]c                 C  s^   | }|   D ]%\}}t|tr||t||< qt|tr#|||< qtdt|j|S )Nz'Expected (base64) str or bytes, found: )ra   rT   rR   Z	structurer   	TypeErrorr   r"   )r   rt   r   r;   r^   r_   r'   r'   r(   
_structure4  s   


zDataStore._structure)rm   rn   r,   ro   )T)rt   ru   rv   r   rw   ro   r,   rd   )rv   r   r,   r}   )rv   r   r   rR   r,   r   )r   r   r   rR   r   r   r,   r\   )r   r   r   rR   r,   r\   )r,   r\   r,   r   r,   r   )r{   rR   r,   r   )r{   rR   r   r   r,   r\   )r{   rR   r,   r\   )r,   rR   r9   )r   r   r   r   r,   r\   )r,   r}   )r   r   r,   r   )r   r   rt   r   r   r   r,   re   )$r"   r#   r$   r%   r   r   rg   r&   r=   rk   r   rl   rq   rs   classmethodr|   staticmethodr   rx   rz   r   r   r>   rN   __deepcopy__r   r   r   r   r   r   r   propertyr   r   r   r'   r'   r'   r(   re      sL   
 








	
_TAttrDictMixinc                   @  sd   e Zd ZdZeeddd!d"d	d
Zd#ddZd$ddZd%ddZ	ed&ddZ
ed'dd ZdS )(r   zRead attribute values using mapping interface.

    For use with Anchors, Guidelines and WoffMetadata classes, where client code
    expects them to behave as dict.
    N)maxsizeFreversero   r,   r   c                 C  sL   i }t | D ]}|j}|}d|jv r|jd }|r|||< q|||< q|S )NZrename_attr)rL   rM   rD   rB   )rt   r   rr   rG   	attr_namekeyr'   r'   r(   _key_to_attr_mapZ  s   



zAttrDictMixin._key_to_attr_mapr   rR   r	   c              
   C  sR   |   | }zt| |}W n ty } zt||d }~ww |d u r't||S r9   )r   rE   AttributeErrorKeyError)r;   r   r   valueer'   r'   r(   r   i  s   
zAttrDictMixin.__getitem__r   c                 c  s<    | j dd}t| jD ]}t| |d ur|| V  qd S )NT)r   )r   rL   Zfields_dictrK   rE   )r;   Zkey_mapr   r'   r'   r(   r   s  s   
zAttrDictMixin.__iter__r   c                 C  s   t dd | D S )Nc                 s  s    | ]}d V  qdS )r@   Nr'   )rF   r?   r'   r'   r(   	<genexpr>z  s    z(AttrDictMixin.__len__.<locals>.<genexpr>)sumr   r'   r'   r(   r   y  s   zAttrDictMixin.__len__rt   Type[_T]r   _T | Mapping[str, Any]r   c                   s\   t || r|S t |tr |   | di  fdd| D S td| j dt|j )Nc                   s   i | ]	\}} | |qS r'   r'   r]   Zattr_mapr'   r(   rI     s    z2AttrDictMixin.coerce_from_dict.<locals>.<dictcomp>z	Expected z or mapping, found: r'   )rT   r   r   ra   r   r"   r   rt   r   r'   r   r(   coerce_from_dict|  s   

 zAttrDictMixin.coerce_from_dict_T | Mapping[str, Any] | None	_T | Nonec                 C  s   |d u rd S |  |S r9   )r   r   r'   r'   r(   coerce_from_optional_dict  s   
z'AttrDictMixin.coerce_from_optional_dict)F)r   ro   r,   r   )r   rR   r,   r	   r   r   )rt   r   r   r   r,   r   )rt   r   r   r   r,   r   )r"   r#   r$   r%   r   r   r   r   r   r   r   r   r'   r'   r'   r(   r   Q  s    




tTransform | Sequence[float]r   c                 C  s   t | tr| S t|  S )zjReturn a passed-in Transform as is, otherwise convert a sequence of
    numbers to a Transform if need be.)rT   r   )r   r'   r'   r(   _convert_transform  s   r   )r)   r   r*   r+   r,   r-   )r7   r-   r8   r-   r,   r-   )r;   r	   r<   r	   r,   r	   )rO   rP   rQ   r   r,   rP   )rO   rP   rZ   r[   r,   r\   )r   r   r,   r   )@Z
__future__r   Zcollections.abcrU   rS   rV   r   r   r   copyr   	functoolsr   typingr   r	   r
   r   r   r   r   r   r   r   r   rL   r   r   ZfontTools.misc.arrayToolsr   ZfontTools.misc.transformr   ZfontTools.pens.boundsPenr   r   ZfontTools.ufoLibr   r   ZufoLib2.constantsr   ZufoLib2.typingr   r   r   Zcattrr   r    r4   r6   r:   rN   rY   rb   r   rc   ry   rd   rR   ZDataStoreMappingre   ZAttrDictMixinMappingr   r   r   r'   r'   r'   r(   <module>   sP    4
	





 :?