K ii_dZddlmZddlZddlZddlZddlZddlZddlZddl m Z ddl m Z ddl mZmZmZmZmZmZmZmZmZmZmZmZddlmZmZmZmZddlm Z dd l!m"Z"e rdd l#m$Z$dd l m%Z%dd l m&Z&dd lm'Z'm(Z(dZ)dZ*e jVre*nejXejZzZ.ej^Z0ejbejdzejfzZ4ejjejlzejnzejpzejrzejtzejvzZddZ?ddZ@ddZAGddZBGddZCGddeZDGddeZEy)u:module: watchdog.observers.kqueue :synopsis: ``kqueue(2)`` based emitter implementation. :author: yesudeep@google.com (Yesudeep Mangalapilly) :author: contact@tiger-222.fr (Mickaël Schoentgen) :platforms: macOS and BSD with kqueue(2). .. WARNING:: kqueue is a very heavyweight way to monitor file systems. Each kqueue-detected directory modification triggers a full directory scan. Traversing the entire directory tree and opening file descriptors for all files will create performance problems. We need to find a way to re-scan only those directories which report changes and do a diff between two sub-DirectorySnapshots perhaps. .. ADMONITION:: About OS X performance guidelines Quote from the `macOS File System Performance Guidelines`_: "When you only want to track changes on a file or directory, be sure to open it using the ``O_EVTONLY`` flag. This flag prevents the file or directory from being marked as open or in use. This is important if you are tracking files on a removable volume and the user tries to unmount the volume. With this flag in place, the system knows it can dismiss the volume. If you had opened the files or directories without this flag, the volume would be marked as busy and would not be unmounted." ``O_EVTONLY`` is defined as ``0x8000`` in the OS X header files. More information here: http://www.mlsite.net/blog/?p=2312 Classes ------- .. autoclass:: KqueueEmitter :members: :show-inheritance: Collections and Utility Classes ------------------------------- .. autoclass:: KeventDescriptor :members: :show-inheritance: .. autoclass:: KeventDescriptorSet :members: :show-inheritance: .. _macOS File System Performance Guidelines: http://developer.apple.com/library/ios/#documentation/Performance/Conceptual/FileSystem/Articles/TrackingChanges.html#//apple_ref/doc/uid/20001993-CJBJFIDD ) annotationsN)S_ISDIR) TYPE_CHECKING) EVENT_TYPE_CREATEDEVENT_TYPE_DELETEDEVENT_TYPE_MOVEDDirCreatedEventDirDeletedEventDirModifiedEvent DirMovedEventFileCreatedEventFileDeletedEventFileModifiedEventFileMovedEventgenerate_sub_moved_events)DEFAULT_EMITTER_TIMEOUTDEFAULT_OBSERVER_TIMEOUT BaseObserver EventEmitter)platform)DirectorySnapshot) Generator)Callable)FileSystemEvent) EventQueue ObservedWatchiicztjjtjj|SN)ospathabspathnormpath)r s _/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/watchdog/observers/kqueue.py absolute_pathr$ss$ 77??277++D1 22cB|jtjzdkDS)z8Determines whether the given kevent represents deletion.r)fflagsselectKQ_NOTE_DELETEkevs r# is_deletedr,z ::-- - 11r%cv|j}|tjzdkDxs|tjzdkDS)z)rDfds r# get_for_fdzKeventDescriptorSet.get_for_fds.ZZ /**2. / / /s&/c~|j5t|}|j|cdddS#1swYyxYw)zObtains a :class:`KeventDescriptor` object for the specified path. :param path: Path for which the descriptor will be obtained. N)rBr$_getrDr s r#getzKeventDescriptorSet.gets5 ZZ # &D99T? # # #3<c~|j5t|}|j|cdddS#1swYyxYw)zDetermines whether a :class:`KeventDescriptor has been registered for the specified path. :param path: Path for which the descriptor will be obtained. N)rBr$ _has_pathrQs r# __contains__z KeventDescriptorSet.__contains__s6ZZ ( &D>>$' ( ( (rSc|j5t|}|j|s|jt ||dddy#1swYyxYw)aeAdds a :class:`KeventDescriptor` to the collection for the given path. :param path: The path for which a :class:`KeventDescriptor` object will be added. :param is_directory: ``True`` if the path refers to a directory; ``False`` otherwise. :type is_directory: ``bool``  is_directoryN)rBr$rU_add_descriptorKeventDescriptorrDr rYs r#addzKeventDescriptorSet.addsPZZ X &D>>$'$$%5d%VW X X Xs 9AAc|j5t|}|j|r |j|j |dddy#1swYyxYw)zRemoves the :class:`KeventDescriptor` object for the given path if it already exists. :param path: Path for which the :class:`KeventDescriptor` object will be removed. N)rBr$rU_remove_descriptorrPrQs r#removezKeventDescriptorSet.removesLZZ 9 &D~~d#'' $8 9 9 9s =AAc2|j5|jD]}|j|jj|jj|j jg|_dddy#1swYyxYw)z6Clears the collection and closes all open descriptors.N)rBr<closeclearr>r=r?rD descriptors r#rczKeventDescriptorSet.clears| ZZ "// #   " #    # # %  # # ) ) +  % % + + -DM    s A7B  Bc |j|S)z-Returns a kevent descriptor for a given path.r=rQs r#rPzKeventDescriptorSet._gets((..r%c||jvS)zxDetermines whether a :class:`KeventDescriptor` for the specified path exists already in the collection. rgrQs r#rUzKeventDescriptorSet._has_pathst0000r%c|jj||jj|j||j |j <||j|j<y)zAdds a descriptor to the collection. :param descriptor: An instance of :class:`KeventDescriptor` to be added. N) r<r]r?appendkeventr=r r>rMrds r#rZz#KeventDescriptorSet._add_descriptorsX j) Z../5?!!*//21; .r%c|jj||j|j=|j|j =|j j|j|jy)zRemoves a descriptor from the collection. :param descriptor: An instance of :class:`KeventDescriptor` to be removed. N) r<r`r>rMr=r r?rkrbrds r#r_z&KeventDescriptorSet._remove_descriptors`   ,  # #JMM 2  % %joo 6 Z../r%NreturnNone)rnlist[select.kevent])rnzlist[bytes | str])rMintrnr[)r bytes | strrnr[)r rrrnboolr rrrYrsrnror rrrnro)rer[rnro)__name__ __module__ __qualname____doc__rEpropertyrGrKrNrRrVr]r`rcrPrUrZr_r%r#r9r9se3&!! :: /# (X" 9/1 < r%r9ceZdZdZddZeddZeddZeddZeddZ ddZ eddZ dd Z dd Z dd Zdd Zy )r[a{A kevent descriptor convenience data structure to keep together: * kevent * directory status * path * file descriptor :param path: Path string for which a kevent descriptor will be created. :param is_directory: ``True`` if the path refers to a directory; ``False`` otherwise. :type is_directory: ``bool`` ct||_||_tj|t |_tj|j ttt|_ y)N)filterflagsr') r$_path _is_directoryropenWATCHDOG_OS_OPEN_FLAGS_fdr(rkWATCHDOG_KQ_FILTERWATCHDOG_KQ_EV_FLAGSWATCHDOG_KQ_FFLAGS_kevr\s r#rEzKeventDescriptor.__init__#sI"4( )774!78MM HH%&%   r%c|jS)z-OS file descriptor for the kevent descriptor.)rrCs r#rMzKeventDescriptor.fd.s xxr%c|jS)z/The path associated with the kevent descriptor.)rrCs r#r zKeventDescriptor.path3szzr%c|jS)z8The kevent object associated with the kevent descriptor.)rrCs r#rkzKeventDescriptor.kevent8syyr%c|jS)z}Determines whether the kevent descriptor refers to a directory. :returns: ``True`` or ``False`` )rrCs r#rYzKeventDescriptor.is_directory=s!!!r%ctjt5tj|j dddy#1swYyxYw)z?Closes the file descriptor associated with a kevent descriptor.N) contextlibsuppressOSErrorrrbrMrCs r#rbzKeventDescriptor.closeFs5   )  HHTWW    s AA c2|j|jfSr)r rYrCs r#keyzKeventDescriptor.keyKs 4,,--r%c`t|tstS|j|jk(Sr isinstancer[NotImplementedrrds r#__eq__zKeventDescriptor.__eq__O&*&67! !xx:>>))r%c`t|tstS|j|jk7Srrrds r#__ne__zKeventDescriptor.__ne__Trr%c,t|jSr)hashrrCs r#__hash__zKeventDescriptor.__hash__YsDHH~r%chdt|jd|jd|jdS)N)typervr rYrCs r#__repr__zKeventDescriptor.__repr__\s44:&&'wtyym?4K\K\J]]^__r%Nrt)rnrq)rnrr)rn select.kevent)rnrsrm)rnztuple[bytes | str, bool])reobjectrnrs)rnstr)rvrwrxryrErzrMr rkrYrbrrrrrr{r%r#r[r[s   "" ..* * `r%r[ceZdZdZedej d dfdZddZddZ ddZ ddZ dd Z dd Z dd Zdd Zdd ZxZS) KqueueEmittera}kqueue(2)-based event emitter. .. ADMONITION:: About ``kqueue(2)`` behavior and this implementation ``kqueue(2)`` monitors file system events only for open descriptors, which means, this emitter does a lot of book-keeping behind the scenes to keep track of open descriptors for every entry in the monitored directory tree. This also means the number of maximum open file descriptors on your system must be increased **manually**. Usually, issuing a call to ``ulimit`` should suffice:: ulimit -n 1024 Ensure that you pick a number that is larger than the number of files you expect to be monitored. ``kqueue(2)`` does not provide enough information about the following things: * The destination path of a file or directory that is renamed. * Creation of a file or directory within a directory; in this case, ``kqueue(2)`` only indicates a modified event on the parent directory. Therefore, this emitter takes a snapshot of the directory tree when ``kqueue(2)`` detects a change on the file system to be able to determine the above information. :param event_queue: The event queue to fill with events. :param watch: A watch object representing the directory to monitor. :type watch: :class:`watchdog.observers.api.ObservedWatch` :param timeout: Read events blocking timeout (in seconds). :type timeout: ``float`` :param event_filter: Collection of event types to emit, or None for no filtering (default). :type event_filter: Iterable[:class:`watchdog.events.FileSystemEvent`] | None :param stat: stat function. See ``os.stat`` for details. N)timeout event_filterstatct|||||tj|_t j |_t|_ |fdfd }t|j|j||_ y)N)rrcd|}|j|t|j|S)NrX)_register_keventrst_mode)r cls stat_infors r# custom_statz+KqueueEmitter.__init__..custom_stats0T I  GI ZZ     # # % HHNN    s 5A  A) rrrrrfloatrz"list[type[FileSystemEvent]] | NonerzCallable[[str], os.stat_result]rnrortru)rrrnro)r+rrrrrrnGenerator[FileSystemEvent])rrrrnr ) rrrrrrrrYrsrnr)rrrnrprrrnrorm)rvrwrxryrrrrErrrrrrrrr __classcell__rs@r#rr`s-h1;?02ggg  g 9 g.g g0!F'4(,1 ,10A,1Qb,1 #,1\;5656(56( 56  56 $56n P$Lr%rc*eZdZdZeddfdZxZS)KqueueObserverzdObserver thread that schedules watching directories and dispatches calls to event handlers. rc0t|t|y)Nr)rrEr)rDrrs r#rEzKqueueObserver.__init__s 8r%r)rvrwrxryrrErrs@r#rrs,D99r%r)r rrrnrr)r+rrnrs)Fry __future__rrrros.pathr(r@rrtypingrwatchdog.eventsrrrr r r r r rrrrwatchdog.observers.apirrrrwatchdog.utilsrwatchdog.utils.dirsnapshotrcollections.abcrrrrrr O_EVTONLY is_darwinO_RDONLY O_NONBLOCKrKQ_FILTER_VNODEr KQ_EV_ADD KQ_EV_ENABLE KQ_EV_CLEARrr)r0r/r3 KQ_NOTE_LINKr6KQ_NOTE_REVOKErr$r,r1r4r7r9r[rrr{r%r#rsu1r#       qp#8)/@   '9h&8&8&: bmm@[++''&*=*==@R@RR            32 W 2 2 AAHJ`J`ZfLfR 9\9r%