
    9*bO,                         d 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 Z	 G d de
      Z G d d	e      Z G d
 de      Z G d de      Z G d de      Z G d de
      Zy)z
    pyudev.discover
    ===============

    Tools to discover a device given limited information.

    .. moduleauthor::  mulhern <amulhern@redhat.com>
    NDeviceNotFoundError)Devicesc                 B     t        j                          fd       }|S )z\
    Allow Device discovery methods to return None instead of raising an
    exception.
    c                  4    	  | i |S # t         $ r Y yw xY w)z
        Returns result of calling ``func`` on ``args``, ``kwargs``.
        Returns None if ``func`` raises :exc:`DeviceNotFoundError`.
        Nr   )argskwargsfuncs     1/usr/lib/python3/dist-packages/pyudev/discover.pythe_funcz wrap_exception.<locals>.the_func+   s*    	(((" 		s    	)	functoolswraps)r
   r   s   ` r   wrap_exceptionr   %   s'     __T  O    c                       e Zd ZdZej
                  Zeej                  d               Z	eej                  d               Z
ed        Zed        Zy)
HypothesiszM
    Represents a hypothesis about the meaning of the device identifier.
    c                     t               )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
        NotImplementedErrorclsvalues     r   matchzHypothesis.match@   s     "##r   c                     t               )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`
        r   )r   contextkeys      r   lookupzHypothesis.lookupQ   s     "##r   c                      y)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
        N r   r   s     r   setupzHypothesis.setup_   s     	r   c                 `    | j                  |      }|| 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`
        )r   r   	frozenset)r   r   r   r   s       r   get_deviceszHypothesis.get_devicesj   s.     ii+.?szz'3'K	Kr   N)__name__
__module____qualname____doc__abcABCMeta__metaclass__classmethodabstractmethodr   r   r!   r$   r   r   r   r   r   9   s~     KKM$  $ 
$  
$   
L 
Lr   r   c                   `    e Zd ZdZed        Zed        Zed        Zed        Zed        Z	y)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                     t        j                  d      }|j                  |      }|xrF t        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   major_minor_rer   s       r   _match_major_minorz)DeviceNumberHypothesis._match_major_minor   s\     $JK$$U+ 
G$%s5;;w+?'@
 	
r   c                     t        j                  d      }|j                  |      }|xr 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+)$number)r3   r4   r   r7   r8   )r   r   	number_rer   s       r   _match_numberz$DeviceNumberHypothesis._match_number   s:     JJ34	&3U[[233r   c                 J    | j                  |      xs | 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   s     r   r   zDeviceNumberHypothesis.match   s%     %%e,H0A0A%0HHr   c                     |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
        dev)sys_pathr5   listdirpathjoin)r   r   rB   s      r   find_subsystemsz&DeviceNumberHypothesis.find_subsystems   s-     ##zz"'',,x788r   c                     t        t        j                        fd| j                        D        }t	        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   2   K   | ]  } |        y wNr   .0sr   r
   r   s     r   	<genexpr>z0DeviceNumberHypothesis.lookup.<locals>.<genexpr>        KtGQ$K   c              3   &   K   | ]	  }||  y wrI   r   rK   rs     r   rM   z0DeviceNumberHypothesis.lookup.<locals>.<genexpr>        9q1=9   )r   r   from_device_numberrF   r#   r   r   r   resr
   s    `` @r   r   zDeviceNumberHypothesis.lookup   s;     g889Kc.A.A'.JK9C999r   N)
r%   r&   r'   r(   r,   r:   r>   r   rF   r   r   r   r   r/   r/   x   sm     
 
 
4 
4 I I 	9 	9 : :r   r/   c                   0    e Zd ZdZed        Zed        Zy)DevicePathHypothesiszG
    Discover the device assuming the identifier is a device path.
    c                     |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   s     r   r   zDevicePathHypothesis.match   	     r   c                 r     t        t        j                        ||      }|t        |f      S t               S )
        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`
        )r   r   	from_pathr#   )r   r   r   rW   s       r   r   zDevicePathHypothesis.lookup   s5     0nW../=$'Oy# DDr   N)r%   r&   r'   r(   r,   r   r   r   r   r   rY   rY      s1       
E 
Er   rY   c                   @    e Zd ZdZed        Zed        Zed        Zy)DeviceNameHypothesiszf
    Discover the device assuming the input is a device name.

    Try every available subsystem.
    c                 l    |j                   d}fd|D        }d |D        }t        d |D              S )z
        Find all subsystems in sysfs.

        :param Context context: the context
        :rtype: frozenset
        :returns: subsystems in sysfs
        )busclass	subsystemc              3   ^   K   | ]$  }t         j                  j                  |       & y wrI   r5   rD   rE   )rK   namerB   s     r   rM   z7DeviceNameHypothesis.find_subsystems.<locals>.<genexpr>   s      FTBGGLL40F   *-c              3   `   K   | ]&  }t         j                  j                  |      s#| ( y wrI   )r5   rD   isdirrK   ds     r   rM   z7DeviceNameHypothesis.find_subsystems.<locals>.<genexpr>   s     =1BGGMM!,<Q=s   $..c              3   T   K   | ]   }t        j                  |      D ]  }|  " y wrI   )r5   rC   )rK   rl   ns      r   rM   z7DeviceNameHypothesis.find_subsystems.<locals>.<genexpr>   s$     Eqrzz!}E!EEs   &()rB   r#   )r   r   dirnamesabsnames	realnamesrB   s        @r   rF   z$DeviceNameHypothesis.find_subsystems   s:     ##0FXF==	EIEEEr   c                     |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   s     r   r   zDeviceNameHypothesis.match   r[   r   c                     t        t        j                        fd| j                        D        }t	        d |D              S )r]   c              3   2   K   | ]  } |        y wrI   r   rJ   s     r   rM   z.DeviceNameHypothesis.lookup.<locals>.<genexpr>  rN   rO   c              3   &   K   | ]	  }||  y wrI   r   rQ   s     r   rM   z.DeviceNameHypothesis.lookup.<locals>.<genexpr>	  rS   rT   )r   r   	from_namerF   r#   rV   s    `` @r   r   zDeviceNameHypothesis.lookup   s;     g//0Kc.A.A'.JK9C999r   N)r%   r&   r'   r(   r,   rF   r   r   r   r   r   r`   r`      sE     F F   : :r   r`   c                   X    e Zd ZdZg dZed        Zed        Zed        Zed        Z	y)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                 |    |j                         }d |D        }d |D        }t        t        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              3   L   K   | ]  }t        |j                        s|  y wrI   )listdevice_linksrk   s     r   rM   z5DeviceFileHypothesis.get_link_dirs.<locals>.<genexpr>.  s     IAD4HaIs   $$c              3   B   K   | ]  }|j                   D ]  }|   y wrI   )r|   )rK   rl   ls      r   rM   z5DeviceFileHypothesis.get_link_dirs.<locals>.<genexpr>/  s      GqG1GGs   c              3   Z   K   | ]#  }t         j                  j                  |       % y wrI   )r5   rD   dirname)rK   r~   s     r   rM   z5DeviceFileHypothesis.get_link_dirs.<locals>.<genexpr>0  s     <"''//!,<s   )+)list_devicessortedset)r   r   devicesdevices_with_linkslinkss        r   get_link_dirsz"DeviceFileHypothesis.get_link_dirs!  s>     &&(IIG.Gc<e<<==r   c                 0    | j                  |      | _        y)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)r   
_LINK_DIRSr    s     r   r!   zDeviceFileHypothesis.setup2  s     **73r   c                     |S rI   r   r   s     r   r   zDeviceFileHypothesis.match=  s    r   c                     t        t        j                        dv r!       }|t        |f      S t               S fd| j                  D        }fd|D        }t        d |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.
        /c              3   ^   K   | ]$  }t         j                  j                  |       & y wrI   rf   )rK   ldr   s     r   rM   z.DeviceFileHypothesis.lookup.<locals>.<genexpr>T  s      @2b#&@rh   c              3   0   K   | ]  } |        y wrI   r   )rK   fr   r
   s     r   rM   z.DeviceFileHypothesis.lookup.<locals>.<genexpr>U  s     34#3s   c              3   &   K   | ]	  }||  y wrI   r   rk   s     r   rM   z.DeviceFileHypothesis.lookup.<locals>.<genexpr>V  s     =qq}=rT   )r   r   from_device_filer#   r   )r   r   r   devicefilesr   r
   s    ``   @r   r   zDeviceFileHypothesis.lookupA  sj     g667#:'3'F+1+=9fY'N9;N@@3U3=G===r   N)
r%   r&   r'   r(   r   r,   r   r!   r   r   r   r   r   rx   rx     s^    J > >  4 4   > >r   rx   c                   .    e Zd ZdZeeeegZd Z	d Z
d Zy)	Discoveryz1
    Provides discovery methods for devices.
    c                 &    | j                   | _        y rI   )_HYPOTHESES_hypotheses)selfs    r   __init__zDiscovery.__init__f  s    ++r   c                 H    | j                   D ]  }|j                  |        y)z
        Set up individual hypotheses.

        May be an expensive call.

        :param Context context: the context
        N)r   r!   )r   r   hyps      r   r!   zDiscovery.setupi  s%     ## 	CIIg	r   c                 D    t        f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   P   K   | ]  }|j                        D ]  }|   y wrI   )r$   )rK   hrl   r   r   s      r   rM   z(Discovery.get_devices.<locals>.<genexpr>}  s3      
w1N
,-A

s   #&)r#   r   )r   r   r   s    ``r   r$   zDiscovery.get_devicest  s%      
''
 
 	
r   N)r%   r&   r'   r(   rx   r`   r/   rY   r   r   r!   r$   r   r   r   r   r   Y  s+    
 		K,	
r   r   )r(   r)   r   r5   r3   pyudev._errorsr   pyudev.devicer   r   objectr   r/   rY   r`   rx   r   r   r   r   <module>r      sy   "   	 	 / !(<L <L~E:Z E:PE: E:,:: ,:^J>: J>Z&
 &
r   