???<!-- GIF89;a -->
123123123123
.....................................................................................................................................???<!-- GIF89;a -->
123123123123
.....................................................................................................................................3
u1‘Wô,  ã               @   sì   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ZddlZddlZddl	Z	ddl
Z
ddlmZ ddlmZ d	d
„ Ze
jejƒ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G dd„ deƒZdS )zš
    pyudev.discover
    ===============

    Tools to discover a device given limited information.

    .. moduleauthor::  mulhern <amulhern@redhat.com>
é    )Úabsolute_import)Údivision)Úprint_function)Úunicode_literalsN)ÚDevices)ÚDeviceNotFoundErrorc                s   t jˆ ƒ‡ fdd„ƒ}|S )z\
    Allow Device discovery methods to return None instead of raising an
    exception.
    c                 s$   y
ˆ | |ŽS  t k
r   dS X dS )z‘
        Returns result of calling ``func`` on ``args``, ``kwargs``.
        Returns None if ``func`` raises :exc:`DeviceNotFoundError`.
        N)r   )ÚargsÚkwargs)Úfunc© ú/usr/lib/python3.6/discover.pyÚthe_func1   s    
z wrap_exception.<locals>.the_func)Ú	functoolsÚwraps)r
   r   r   )r
   r   Úwrap_exception+   s    r   c               @   sL   e Zd ZdZeejdd„ ƒƒZeejdd„ ƒƒZedd„ ƒZ	edd	„ ƒZ
d
S )Ú
HypothesiszM
    Represents a hypothesis about the meaning of the device identifier.
    c             C   s
   t ƒ ‚dS )aì  
        Match the given string according to the hypothesis.

        The purpose of this method is to obtain a value corresponding to
        ``value`` if that is possible. It may use a regular expression, but
        in general it should just return ``value`` and let the lookup method
        sort out the rest.

        :param str value: the string to inspect
        :returns: the matched thing or None if unmatched
        :rtype: the type of lookup's key parameter or NoneType
        N)ÚNotImplementedError)ÚclsÚvaluer   r   r   ÚmatchD   s    zHypothesis.matchc             C   s
   t ƒ ‚dS )aN  
        Lookup the given string according to the hypothesis.

        :param Context context: the pyudev context
        :param key: a key with which to lookup the device
        :type key: the type of match's return value if not None
        :returns: a list of Devices obtained
        :rtype: frozenset of :class:`Device`
        N)r   )r   ÚcontextÚkeyr   r   r   ÚlookupU   s    zHypothesis.lookupc             C   s   dS )zé
        A potentially expensive method that may allow an :class:`Hypothesis`
        to find devices more rapidly or to find a device that it would
        otherwise miss.

        :param Context context: the pyudev context
        Nr   )r   r   r   r   r   Úsetupc   s    	zHypothesis.setupc             C   s$   | j |ƒ}|dk	r| j||ƒS tƒ S )a  
        Get any devices that may correspond to the given string.

        :param Context context: the pyudev context
        :param str value: the value to look for
        :returns: a list of devices obtained
        :rtype: set of :class:`Device`
        N)r   r   Ú	frozenset)r   r   r   r   r   r   r   Úget_devicesn   s    

zHypothesis.get_devicesN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚclassmethodÚabcÚabstractmethodr   r   r   r   r   r   r   r   r   >   s   r   c               @   sL   e Zd ZdZedd„ ƒZedd„ ƒZedd„ ƒZedd	„ ƒZed
d„ ƒZ	dS )ÚDeviceNumberHypothesisz—
    Represents the hypothesis that the device is a device number.

    The device may be separated into major/minor number or a composite number.
    c             C   s8   t jdƒ}|j|ƒ}|o6tjt|jdƒƒt|jdƒƒƒS )zÌ
        Match the number under the assumption that it is a major,minor pair.

        :param str value: value to match
        :returns: the device number or None
        :rtype: int or NoneType
        z#^(?P<major>\d+)(\D+)(?P<minor>\d+)$ÚmajorÚminor)ÚreÚcompiler   ÚosÚmakedevÚintÚgroup)r   r   Zmajor_minor_rer   r   r   r   Ú_match_major_minorƒ   s    	
z)DeviceNumberHypothesis._match_major_minorc             C   s&   t jdƒ}|j|ƒ}|o$t|jdƒƒS )zÉ
        Match the number under the assumption that it is a single number.

        :param str value: value to match
        :returns: the device number or None
        :rtype: int or NoneType
        z^(?P<number>\d+)$Znumber)r&   r'   r   r*   r+   )r   r   Z	number_rer   r   r   r   Ú_match_number•   s    	

z$DeviceNumberHypothesis._match_numberc             C   s   | j |ƒp| j|ƒS )z 
        Match the number under the assumption that it is a device number.

        :returns: the device number or None
        :rtype: int or NoneType
        )r,   r-   )r   r   r   r   r   r   ¢   s    zDeviceNumberHypothesis.matchc             C   s   |j }tjtjj|dƒƒS )z§
        Find subsystems in /sys/dev.

        :param Context context: the context
        :returns: a lis of available subsystems
        :rtype: list of str
        Zdev)Úsys_pathr(   ÚlistdirÚpathÚjoin)r   r   r.   r   r   r   Úfind_subsystems¬   s    	z&DeviceNumberHypothesis.find_subsystemsc                s8   t tjƒ‰‡ ‡‡fdd„| jˆ ƒD ƒ}tdd„ |D ƒƒS )zß
        Lookup by the device number.

        :param Context context: the context
        :param int key: the device number
        :returns: a list of matching devices
        :rtype: frozenset of :class:`Device`
        c             3   s   | ]}ˆˆ |ˆƒV  qd S )Nr   )Ú.0Ús)r   r
   r   r   r   ú	<genexpr>Ã   s    z0DeviceNumberHypothesis.lookup.<locals>.<genexpr>c             s   s   | ]}|d k	r|V  qd S )Nr   )r3   Úrr   r   r   r5   Ä   s    )r   r   Zfrom_device_numberr2   r   )r   r   r   Úresr   )r   r
   r   r   r   ¸   s    

zDeviceNumberHypothesis.lookupN)
r   r   r   r   r    r,   r-   r   r2   r   r   r   r   r   r#   |   s   
r#   c               @   s(   e Zd ZdZedd„ ƒZedd„ ƒZdS )ÚDevicePathHypothesiszG
    Discover the device assuming the identifier is a device path.
    c             C   s   |S )z›
        Match ``value`` under the assumption that it is a device path.

        :returns: the device path or None
        :rtype: str or NoneType
        r   )r   r   r   r   r   r   Ì   s    zDevicePathHypothesis.matchc             C   s(   t tjƒ||ƒ}|dk	r"t|fƒS tƒ S )zÔ
        Lookup by the path.

        :param Context context: the context
        :param str key: the device path
        :returns: a list of matching devices
        :rtype: frozenset of :class:`Device`
        N)r   r   Z	from_pathr   )r   r   r   r7   r   r   r   r   Ö   s    
zDevicePathHypothesis.lookupN)r   r   r   r   r    r   r   r   r   r   r   r8   Ç   s   
r8   c               @   s4   e Zd ZdZedd„ ƒZedd„ ƒZedd„ ƒZdS )	ÚDeviceNameHypothesiszf
    Discover the device assuming the input is a device name.

    Try every available subsystem.
    c                s<   |j ‰ d}‡ fdd„|D ƒ}dd„ |D ƒ}tdd„ |D ƒƒS )	zœ
        Find all subsystems in sysfs.

        :param Context context: the context
        :rtype: frozenset
        :returns: subsystems in sysfs
        ÚbusÚclassÚ	subsystemc             3   s   | ]}t jjˆ |ƒV  qd S )N)r(   r0   r1   )r3   Úname)r.   r   r   r5   ö   s    z7DeviceNameHypothesis.find_subsystems.<locals>.<genexpr>c             s   s   | ]}t jj|ƒr|V  qd S )N)r(   r0   Úisdir)r3   Údr   r   r   r5   ÷   s    c             s   s"   | ]}t j|ƒD ]
}|V  qqd S )N)r(   r/   )r3   r?   Únr   r   r   r5   ø   s    )r:   r;   r<   )r.   r   )r   r   ZdirnamesZabsnamesZ	realnamesr   )r.   r   r2   ë   s
    	z$DeviceNameHypothesis.find_subsystemsc             C   s   |S )z›
        Match ``value`` under the assumption that it is a device name.

        :returns: the device path or None
        :rtype: str or NoneType
        r   )r   r   r   r   r   r   ú   s    zDeviceNameHypothesis.matchc                s8   t tjƒ‰‡ ‡‡fdd„| jˆ ƒD ƒ}tdd„ |D ƒƒS )zÔ
        Lookup by the path.

        :param Context context: the context
        :param str key: the device path
        :returns: a list of matching devices
        :rtype: frozenset of :class:`Device`
        c             3   s   | ]}ˆˆ |ˆƒV  qd S )Nr   )r3   r4   )r   r
   r   r   r   r5     s    z.DeviceNameHypothesis.lookup.<locals>.<genexpr>c             s   s   | ]}|d k	r|V  qd S )Nr   )r3   r6   r   r   r   r5     s    )r   r   Ú	from_namer2   r   )r   r   r   r7   r   )r   r
   r   r   r     s    

zDeviceNameHypothesis.lookupN)r   r   r   r   r    r2   r   r   r   r   r   r   r9   ä   s   
r9   c               @   sZ   e Zd ZdZdddddddd	d
ddgZedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZ	dS )ÚDeviceFileHypothesisz‡
    Discover the device assuming the value is some portion of a device file.

    The device file may be a link to a device node.
    z/devz/dev/disk/by-idz/dev/disk/by-labelz/dev/disk/by-partlabelz/dev/disk/by-partuuidz/dev/disk/by-pathz/dev/disk/by-uuidz/dev/input/by-pathz/dev/mapperz/dev/mdz/dev/vgc             C   s:   |j ƒ }dd„ |D ƒ}dd„ |D ƒ}ttdd„ |D ƒƒƒS )a7  
        Get all directories that may contain links to device nodes.

        This method checks the device links of every device, so it is very
        expensive.

        :param Context context: the context
        :returns: a sorted list of directories that contain device links
        :rtype: list
        c             s   s   | ]}t |jƒr|V  qd S )N)ÚlistÚdevice_links)r3   r?   r   r   r   r5   5  s    z5DeviceFileHypothesis.get_link_dirs.<locals>.<genexpr>c             s   s   | ]}|j D ]
}|V  qqd S )N)rD   )r3   r?   Úlr   r   r   r5   6  s    c             s   s   | ]}t jj|ƒV  qd S )N)r(   r0   Údirname)r3   rE   r   r   r   r5   7  s    )Zlist_devicesÚsortedÚset)r   r   ÚdevicesZdevices_with_linksZlinksr   r   r   Úget_link_dirs(  s    z"DeviceFileHypothesis.get_link_dirsc             C   s   | j |ƒ| _dS )z¸
        Set the link directories to be used when discovering by file.

        Uses `get_link_dirs`, so is as expensive as it is.

        :param Context context: the context
        N)rJ   Ú
_LINK_DIRS)r   r   r   r   r   r   9  s    	zDeviceFileHypothesis.setupc             C   s   |S )Nr   )r   r   r   r   r   r   D  s    zDeviceFileHypothesis.matchc                sr   t tjƒ‰dˆkr4ˆˆ ˆƒ}|dk	r.t|fƒS tƒ S ‡fdd„| jD ƒ}‡ ‡fdd„|D ƒ}tdd„ |D ƒƒS dS )a‚  
        Lookup the device under the assumption that the key is part of
        the name of a device file.

        :param Context context: the context
        :param str key: a portion of the device file name

        It is assumed that either it is the whole name of the device file
        or it is the basename.

        A device file may be a device node or a device link.
        ú/Nc             3   s   | ]}t jj|ˆ ƒV  qd S )N)r(   r0   r1   )r3   Zld)r   r   r   r5   [  s    z.DeviceFileHypothesis.lookup.<locals>.<genexpr>c             3   s   | ]}ˆˆ |ƒV  qd S )Nr   )r3   Úf)r   r
   r   r   r5   \  s    c             s   s   | ]}|d k	r|V  qd S )Nr   )r3   r?   r   r   r   r5   ]  s    )r   r   Zfrom_device_filer   rK   )r   r   r   ZdeviceÚfilesrI   r   )r   r
   r   r   r   H  s    

zDeviceFileHypothesis.lookupN)
r   r   r   r   rK   r    rJ   r   r   r   r   r   r   r   rB     s    rB   c               @   s4   e Zd ZdZeeeegZdd„ Z	dd„ Z
dd„ ZdS )	Ú	Discoveryz1
    Provides discovery methods for devices.
    c             C   s   | j | _d S )N)Ú_HYPOTHESESÚ_hypotheses)Úselfr   r   r   Ú__init__m  s    zDiscovery.__init__c             C   s   x| j D ]}|j|ƒ qW dS )z
        Set up individual hypotheses.

        May be an expensive call.

        :param Context context: the context
        N)rQ   r   )rR   r   Zhypr   r   r   r   p  s    zDiscovery.setupc                s   t ‡ ‡fdd„| jD ƒƒS )zý
        Get the devices corresponding to value.

        :param Context context: the context
        :param str value: some identifier of the device
        :returns: a list of corresponding devices
        :rtype: frozenset of :class:`Device`
        c             3   s$   | ]}|j ˆ ˆƒD ]
}|V  qqd S )N)r   )r3   Úhr?   )r   r   r   r   r5   …  s    z(Discovery.get_devices.<locals>.<genexpr>)r   rQ   )rR   r   r   r   )r   r   r   r   {  s    	zDiscovery.get_devicesN)r   r   r   r   rB   r9   r#   r8   rP   rS   r   r   r   r   r   r   rO   `  s   rO   )r   Z
__future__r   r   r   r   r!   r   r(   r&   ZsixZpyudev.devicer   r   r   Zadd_metaclassÚABCMetaÚobjectr   r#   r8   r9   rB   rO   r   r   r   r   Ú<module>   s&   =K/M