+
     h?,  c                   s    R t ^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RIHt R t	 ! R R4      t
 ! R R]
4      t ! R	 R
]
4      t ! R R]
4      t ! R R]
4      t ! R R4      tR# )z
pyudev.discover
===============

Tools to discover a device given limited information.

.. moduleauthor::  mulhern <amulhern@redhat.com>
NDeviceNotFoundError)Devicesc                sF   a  \         P                  ! S 4      V 3R l4       pV# )zP
Allow Device discovery methods to return None instead of raising an
exception.
c                 s:   <  S! V / VB #   \          d     R# i ; i)zy
Returns result of calling ``func`` on ``args``, ``kwargs``.
Returns None if ``func`` raises :exc:`DeviceNotFoundError`.
Nr    )ZargsZkwargsfuncs   *,4/usr/lib/python3.14/site-packages/pyudev/discover.pythe_funcZ wrap_exception.<locals>.the_func+   s*    	(((" 		s    )	functoolsZwraps)r   r   s   f r   wrap_exceptionr   %   s'     __T  O    c                   s   a  ] tR t^9t o Rt]P                  t]]P                  R 4       4       t
]]P                  R 4       4       t]R 4       t]R 4       tRtV tR# )
HypothesiszE
Represents a hypothesis about the meaning of the device identifier.
c                    \        4       h)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
ZNotImplementedErrorclsvalue   &&r   matchZHypothesis.match@   s     "##r   c                r
   )a  
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                s    R# )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   r   r   setupZHypothesis.setup_   s     	r   c                sb    V P                  V4      pVe   V P                  W4      # \        4       # )z
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      &&& r   get_devicesZHypothesis.get_devicesj   s,     ii+.?szz''K	Kr   r   N)__name__
__module____qualname____firstlineno____doc__abcZABCMetaZ__metaclass__classmethodZabstractmethodr   r   r   r   __static_attributes____classdictcell__Z__classdict__   @r   r	   r	   9   s      KKM$  $ 
$  
$   
L 
Lr   r	   c                   st   a  ] tR t^xt o Rt]R 4       t]R 4       t]R 4       t]R 4       t	]R 4       t
RtV tR# )	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                s    \         P                  ! R4      pVP                  V4      pT;'       dH    \        P                  ! \        VP                  R4      4      \        VP                  R4      4      4      # )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+)$ZmajorZminor)recompiler   osZmakedevintgroup)r   r   Zmajor_minor_rer      &&  r   _match_major_minorZ)DeviceNumberHypothesis._match_major_minor   sa     $JK$$U+ 
 
G$%s5;;w+?'@
 	
r   c                s    \         P                  ! R4      pVP                  V4      pT;'       d    \        VP	                  R4      4      # )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   _match_numberZ$DeviceNumberHypothesis._match_number   s=     JJ34	&33U[[233r   c                sV    V P                  V4      ;'       g    V P                  V4      # )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   ZDeviceNumberHypothesis.match   s(     %%e,HH0A0A%0HHr   c                s    VP                   p\        P                  ! \        P                  P	                  VR4      4      # )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   find_subsystemsZ&DeviceNumberHypothesis.find_subsystems   s-     ##zz"'',,x788r   c                   aaa \        \        P                  4      oVVV3R lV P                  S4       4       p\	        R V 4       4      # )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   8   <"   T F  pS! SVS4      x  K  	  R # 5iNr   .0Zsr   r   r      & r   	<genexpr>0DeviceNumberHypothesis.lookup.<locals>.<genexpr>        K.JtGQ$$.J   c              3   0   "   T F  qf   K  Vx  K  	  R # 5ir6   r   r8   Zr   & r   r:   r;           9CqC   
)r   r   Zfrom_device_numberr3   r   r   r   r   resr      &ff @r   r   ZDeviceNumberHypothesis.lookup   s;     g889Kc.A.A'.JK9C999r   r   N)r   r   r   r   r   r    r,   r-   r   r3   r   r!   r"   r#   r$   r   r%   r%   x   sp      
 
 
4 
4 I I 	9 	9 : :r   r%   c                   sD   a  ] tR t^t o Rt]R 4       t]R 4       tRtV t	R# )DevicePathHypothesisz?
Discover the device assuming the identifier is a device path.
c                    V# )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   ZDevicePathHypothesis.match   	     r   c                st    \        \        P                  4      ! W4      pVe   \        V34      # \        4       # )
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   Z	from_pathr   )r   r   r   rD   r   r   r   ZDevicePathHypothesis.lookup   s1     W../=$'Oy# DDr   r   N)
r   r   r   r   r   r    r   r   r!   r"   r#   r$   r   rF   rF      s4        
E 
Er   rF   c                   sT   a  ] tR t^t o Rt]R 4       t]R 4       t]R 4       tRt	V t
R# )DeviceNameHypothesiszZ
Discover the device assuming the input is a device name.

Try every available subsystem.
c                sn   a VP                   oRpV3R lV 4       pR V 4       p\        R V 4       4      # )zt
Find all subsystems in sysfs.

:param Context context: the context
:rtype: frozenset
:returns: subsystems in sysfs
c              3   sd   <"   T F%  p\         P                  P                  SV4      x  K'  	  R # 5ir6   r(   r0   r1   )r8   Znamer.      & r   r:   7DeviceNameHypothesis.find_subsystems.<locals>.<genexpr>   s#     FXTBGGLL400X   -0c              3   st   "   T F.  p\         P                  P                  V4      '       g   K*  Vx  K0  	  R # 5ir6   )r(   r0   Zisdirr8   dr@   r   r:   rM      s!     =1BGGMM!,<QQs   '8
8c              3   s^   "   T F#  p\         P                  ! V4       F  q"x  K  	  K%  	  R # 5ir6   )r(   r/   )r8   rP   Zn   &  r   r:   rM      s      EIqrzz!}!}Is   +-)ZbusZclassZ	subsystem)r.   r   )r   r   ZdirnamesZabsnamesZ	realnamesr.   s   &&   @r   r3   Z$DeviceNameHypothesis.find_subsystems   s:     ##0FXF==	EIEEEr   c                rG   )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   ZDeviceNameHypothesis.match   rH   r   c                r4   )rI   c              3   r5   r6   r   r7   r9   r   r:   .DeviceNameHypothesis.lookup.<locals>.<genexpr>  r<   r=   c              3   r>   r6   r   r?   r@   r   r:   rR   	  rA   rB   )r   r   Z	from_namer3   r   rC   rE   r   r   ZDeviceNameHypothesis.lookup   s;     g//0Kc.A.A'.JK9C999r   r   N)r   r   r   r   r   r    r3   r   r   r!   r"   r#   r$   r   rJ   rJ      sH      F F   : :r   rJ   c                   sl   a  ] tR tRt o Rt. R	Ot]R 4       t]R 4       t]R 4       t	]R 4       t
RtV tR# )
DeviceFileHypothesisi  z{
Discover the device assuming the value is some portion of a device file.

The device file may be a link to a device node.
c                s|    VP                  4       pR V 4       pR V 4       p\        \        R V 4       4      4      # )z
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   s`   "   T F$  p\        VP                  4      '       g   K   Vx  K&  	  R # 5ir6   )Zlistdevice_linksrO   r@   r   r:   5DeviceFileHypothesis.get_link_dirs.<locals>.<genexpr>.  s     IAD4Haas   .
.c              3   sH   "   T F  qP                    F  q"x  K  	  K  	  R # 5ir6   )rT   )r8   rP   lrQ   r   r:   rU   /  s     G.q1.s    "c              3   s`   "   T F$  p\         P                  P                  V4      x  K&  	  R # 5ir6   )r(   r0   Zdirname)r8   rV   r@   r   r:   rU   0  s      <e"''//!,,es   ,.)Zlist_devicesZsortedZset)r   r   devicesZdevices_with_linksZlinkss   &&   r   get_link_dirsZ"DeviceFileHypothesis.get_link_dirs!  s>     &&(IIG.Gc<e<<==r   c                s2    V P                  V4      V n        R# )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)rX   
_LINK_DIRSr   r   r   r   ZDeviceFileHypothesis.setup2  s     **73r   c                rG   r6   r   r   r   r   r   ZDeviceFileHypothesis.match=  s    r   c                s   aaa \        \        P                  4      oRS9   d$   S! SS4      pVe   \        V34      # \        4       # V3R lV P                   4       pVV3R lV 4       p\        R V 4       4      # )aB  
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.
Z/c              3   sd   <"   T F%  p\         P                  P                  VS4      x  K'  	  R # 5ir6   rK   )r8   Zldr   rL   r   r:   .DeviceFileHypothesis.lookup.<locals>.<genexpr>T  s#     @2b#&&rN   c              3   s6   <"   T F  pS! SV4      x  K  	  R # 5ir6   r   )r8   Zfr   r   s   & r   r:   rZ   U  s     3U4##Us   c              3   r>   r6   r   rO   r@   r   r:   rZ   V  s     =GqGrB   )r   r   Zfrom_device_filer   rY   )r   r   r   ZdeviceZfilesrW   r   s   &ff   @r   r   ZDeviceFileHypothesis.lookupA  sj     g667#:'3'F+1+=9fY'N9;N@@3U3=G===r   r   N)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/vg)r   r   r   r   r   rY   r    rX   r   r   r   r!   r"   r#   r$   r   rS   rS     sa     J > >  4 4   > >r   rS   c                   sB   a  ] tR tRt o Rt]]]].t	R t
R tR tRtV tR# )	DiscoveryiY  z)
Provides discovery methods for devices.
c                s(    V P                   V n        R # r6   )_HYPOTHESES_hypotheses)selfs   &r   __init__ZDiscovery.__init__f  s    ++r   c                sN    V P                    F  pVP                  V4       K  	  R# )z_
Set up individual hypotheses.

May be an expensive call.

:param Context context: the context
N)r]   r   )r^   r   Zhypr2   r   r   ZDiscovery.setupi  s      ##CIIg $r   c                sF   aa \        VV3R lV P                   4       4      # )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   sV   <"   T F  qP                  SS4       F  q"x  K  	  K   	  R # 5ir6   )r   )r8   ZhrP   r   r   s   &  r   r:   Z(Discovery.get_devices.<locals>.<genexpr>}  s'      
'!w1NAA1NA's   &))r   r]   )r^   r   r   s   &ffr   r   ZDiscovery.get_devicest  s%      
''
 
 	
r   )r]   N)r   r   r   r   r   rS   rJ   r%   rF   r\   r_   r   r   r!   r"   r#   r$   r   r[   r[   Y  s3     
 		K,	
 
r   r[   )r   r   r   r(   r&   Zpyudev._errorsr   Zpyudev.devicer   r   r	   r%   rF   rJ   rS   r[   r   r   r   <module>r`      su   "   	 	 / !(<L <L~E:Z E:PE: E:,:: ,:^J>: J>Z&
 &
r   