+
    O(iLE              	         a  R t60 t R t^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RIH	t	H
t
 ^ RIHt ^ RIHtHt ^RIHtHtHtHt ^RIHtHtHtHtHt ^RIHtHtHt ^R	IHtH t  ^R
I!H"t"H#t#H$t$H%t% ^RI&H't'H(t( ^t)] ^ k ]PT                  ! R]PV                  ! ]PX                  4      R R2]PZ                  4      t.] ^k ]PT                  ! R]PV                  ! ]P^                  4      R R2]PZ                  4      t0] ^k  ! R R]4      t1 ! R R]4      t2R]])RRR3R R llt3R]RRRR3R R llt4RR])RRRRRR3	R R llt5R# )zA
.. codeauthor:: Tsuyoshi Hombashi <tsuyoshi.hombashi@gmail.com>
N)Sequence)PathPurePath)Pattern)FinalOptional)AbstractSanitizerAbstractValidatorBaseFileBaseValidator)findall_to_stris_nt_abspathto_strtruncate_strvalidate_pathtype)DEFAULT_MIN_LENINVALID_CHAR_ERR_MSG_TMPLPlatform)PathTypePlatformType)ErrorAttrKeyErrorReasonInvalidCharErrorValidationError)ReservedNameHandlerValidationErrorHandler[s]c                   z   a a ] tR t^t o]RRRRRRR3V3R lV 3R llltR
V3R lR lltV3R lR ltR	tVt	V ;t
# )FileNameSanitizerNFc                   < V ^8  d   QhRS[ RS[S[,          RS[S[,          RS[S[,          RS[S[,          RS[S[S[,          ,          RS[RS[S[,          R	R
/	# )   max_lenfs_encodingplatformnull_value_handlerreserved_name_handleradditional_reserved_namesvalidate_after_sanitize	validatorreturnN)intr   strr   r   r   boolr	   )format__classdict__s   "\/Users/agent/.openclaw/workspace/venv/lib/python3.14/site-packages/pathvalidate/_filename.py__annotate__FileNameSanitizer.__annotate__    s     "< "<"< c]"< <(	"<
 %%;<"<  ((>?"< $,HSM#:"< "&"< -."< 
"<    c	                   < V'       d   Tp	M\        \        VVR VVR7      p	\        S
V `  VVVVVVVV	R7       V P	                  4       V n        R# )Tmin_lenr#   r$   check_reservedr(   r%   )r#   r$   r&   r'   r(   r%   r)   r*   N)FileNameValidatorr   super__init___get_sanitize_regexp_sanitize_regexp)selfr#   r$   r%   r&   r'   r(   r)   r*   fname_validator	__class__s   &&&&&&&&& r1   r;   FileNameSanitizer.__init__    sh     'O/''#*C!O 	#1"7&?$;% 	 		
 !% 9 9 ;r4   c                ,   < V ^8  d   QhRS[ RS[RS[ /# )r"   valuereplacement_textr+   )r   r-   )r/   r0   s   "r1   r2   r3   D   s"     1" 1"h 1"# 1"x 1"r4   c                h    \        WP                  R R7      '       * R7       T P                  P                  T\        T4      4      p\        Y@P                  T P                  4      p T P                  P!                  T4       T P2                  '       d    T P                  P!                  T4       \        T\        4      '       d   \9        T4      # T#   \         dS   pTP                  \        P
                  8X  d.   \        T\        4      '       d   h T P                  T4      u Rp?# h Rp?ii ; i  \         Ed/   pTP                  \        P"                  8X  d^   T P%                  T4      pTP&                  T8w  d6   \(        P                  ! \(        P*                  ! TP&                  4      YT4      p Rp?EL9TP                  \        P,                  8X  dY   T P                  R R7      '       dA   TP/                  R4      pTP1                  R4      pTR9  d   TP1                  R4      p Rp?ELTP                  \        P
                  8X  d   T P                  T4      p Rp?ELRp?ii ; i  \         d5   p\        \        T4      \        P4                  T P6                  R7      hRp?ii ; i)Tinclude_universalallow_whitespacesN z .)descriptionreasonr%   .z..)r   _is_windowsr   rL   r   	NULL_NAME
isinstancer   _null_value_handlerr=   subr-   r   _fs_encodingr#   
_validatorvalidateRESERVED_NAME_reserved_name_handlerreserved_namereescapeINVALID_CHARACTERlstriprstrip_validate_after_sanitizeINVALID_AFTER_SANITIZEr%   r   )r>   rC   rD   esanitized_filenamereplacement_words   &&&   r1   sanitizeFileNameSanitizer.sanitizeD   s6   	e;K;K^b;K;c7cd "22667GUT)*<>O>OQUQ]Q]^	AOO$$%78* ((((();< eX&&*++!!]  	xx;000eX..//22	  	Axx;444#'#>#>q#A ??&66)+		!//24D*& [:::t?O?O"& @P @ @ &8%>%>s%C" &8%>%>s%C"%[8);)B)B4)H&[222%)%=%=a%@"%	A. # % #A&==!]] sg   !C )D5 I2 D2 AD-&D2,D--D25I/A6I*=6I*4:I*40I**I/2J1=/J,,J1c                0   < V ^8  d   QhRS[ S[,          /# )r"   r+   )r   r-   )r/   r0   s   "r1   r2   r3   w   s     $ $gcl $r4   c                J    V P                  R R7      '       d   \        # \        # )TrF   )rO   _RE_INVALID_WIN_FILENAME_RE_INVALID_FILENAME)r>   s   &r1   r<   &FileNameSanitizer._get_sanitize_regexpw   s"    d33++##r4   )r=   ) )__name__
__module____qualname____firstlineno___DEFAULT_MAX_FILENAME_LENr;   rd   r<   __static_attributes____classdictcell____classcell__r@   r0   s   @@r1   r    r       sD      1%)+/?CBF=A(-15"< "<H1" 1"f$ $ $r4   r    c                   $  a a ] tR t^~t oR];QJ d,    . R ]P                  ! R]! ^ ^
4      4       4       F  NK  	  5M%! R ]P                  ! R]! ^ ^
4      4       4       4      ,           ];QJ d%    . R ]P                  ! RR4       4       F  NK  	  5M! R ]P                  ! RR4       4       4      ,           tRt	]
V3R lV 3R ll4       t]]RRRR3V3R lV 3R llltV3R	 lR
 ltV3R lR ltV3R lR ltV3R lR ltV3R ltRtVtV ;t# )r9   c              #  6   "   T F  w  rVR  VR 2x  K  	  R# 5i)r   dN ).0namenums   &  r1   	<genexpr>FileNameValidator.<genexpr>   s!     d4cyt4(3q'"4c   c              #  6   "   T F  w  rVR  VR  2x  K  	  R# 5i)r   Nrx   )ry   rz   ssds   &  r1   r|   r}      s*      
	 Ahs1gr~   c                4   < V ^8  d   QhRS[ S[R3,          /# )r"   r+   .)tupler-   )r/   r0   s   "r1   r2   FileNameValidator.__annotate__   s     ' '5c? 'r4   c                  < \         SV `  pV P                  4       '       d/   \        VV P                  ,           V P
                  ,           4      pMV P                  4       '       d   \        WP                  ,           4      pMSV P                  4       '       g   V P                  4       '       d   \        WP
                  ,           4      pM\        V4      p\        \        V4      4      # )N)r:   reserved_keywords_is_universalset_WINDOWS_RESERVED_FILE_NAMES_MACOS_RESERVED_FILE_NAMESrO   	_is_posix	_is_macosr   sorted)r>   common_keywordsword_setr@   s   &  r1   r   #FileNameValidator.reserved_keywords   s    '3334112H
 ?-N-NNOH^^!1!1?-L-LLMH?+HVH%&&r4   NTc                   < V ^8  d   QhRS[ RS[ RS[S[,          RS[S[,          RS[RS[S[S[,          ,          RR/# )	r"   r7   r#   r$   r%   r8   r(   r+   N)r,   r   r-   r   r.   r   )r/   r0   s   "r1   r2   r      sc     
 

 
 c]	

 <(
 
 $,HSM#:
 

r4   c           	     2   < \         SV `  VVVVVVR 7       R# )r6   N)r:   r;   )r>   r7   r#   r$   r%   r8   r(   r@   s   &&&&&&&r1   r;   FileNameValidator.__init__   s)     	#)&? 	 	
r4   c                $   < V ^8  d   QhRS[ RR/# r"   rC   r+   N)r   )r/   r0   s   "r1   r2   r      s     "; ";h ";4 ";r4   c           
     
   \        WP                  R R7      '       * R7       \        V4      p\        VP	                  V P
                  4      4      pV P                  V4       \        P                  \        P                  \        P                  V P                  \        P                  V P
                  \        P                  V\        P                  V/pW0P                   8  d!   \#        RV P                   R RVR R2.3/ VB hW0P$                  8  d!   \#        RV P$                  R RVR R2.3/ VB hV P'                  V4       V P)                  V4       V P                  R R7      '       d   V P+                  V4       R# R# )	TrF   rH   z filename is too long: expected<=rw   z bytes, actual=z bytesz!filename is too short: expected>=N)r   rO   r   lenencoderT   validate_abspathr   REASONr   INVALID_LENGTHPLATFORMr%   FS_ENCODING
BYTE_COUNTVALUEr#   r   r7   _validate_reserved_keywords/_FileNameValidator__validate_universal_filename)_FileNameValidator__validate_win_filename)r>   rC   unicode_filenamebyte_ct
err_kwargss   &&   r1   rV   FileNameValidator.validate   sx   %7G7GZ^7G7_3_`!%=&--d.?.?@A./ !;!;!!4==$$d&7&7##W 0

 \\!!6t||A6FoV]^_U``fg 	  \\!!7Q7GW^_`Vaagh 	  	(()9:**+;<d33(()9: 4r4   c                $   < V ^8  d   QhRS[ RR/# r   r-   )r/   r0   s   "r1   r2   r      s      c d r4   c                    \        R V: R2V P                  \        P                  R7      pV P	                  RR7      '       d   \        V4      '       d   Vh\        P                  ! V4      '       d   VhR# )zfound an absolute path (z), expected a filename)rK   r%   rL   TrF   N)r   r%   r   FOUND_ABS_PATHrO   r   	posixpathisabs)r>   rC   errs   && r1   r   "FileNameValidator.validate_abspath   sh    25);QR]]--
 d33U##	??5!!I "r4   c                $   < V ^8  d   QhRS[ RR/# r"   r   r+   Nr   )r/   r0   s   "r1   r2   r      s     	 	c 	d 	r4   c                    \         P                  V4      pV'       d;   \        \        P                  ! \        V4      R 7      \        P                  VR7      hR# )invalidr%   rC   N)ri   findallr   r   r/   r   r   	UNIVERSAL)r>   r   matchs   && r1   __validate_universal_filename/FileNameValidator.__validate_universal_filename   sL    $,,-=>")00*51 "++&  r4   c                $   < V ^8  d   QhRS[ RR/# r   r   )r/   r0   s   "r1   r2   r      s     $ $ $ $r4   c                   \         P                  V4      pV'       d;   \        \        P                  ! \        V4      R 7      \        P                  VR7      hVR9   d   R# Rp\        P                  \        P                  \        P                  V/pVR	,          R
9   dN   \        \        P                  ! \        P                  ! VR	,          4      R 7      3RVP	                  R4      /VB hV^ ,          R9   dN   \        \        P                  ! \        P                  ! V^ ,          4      R 7      3RVP	                  R4      /VB hR# )r   r   Nz{}. Refer: https://learn.microsoft.com/en-us/troubleshoot/windows-client/shell-experience/file-folder-name-whitespace-charactersrJ   rK   z<Do not end a file or directory name with a space or a periodz2Do not start a file or directory name with a spacerM   )rJ   rN   )rh   r   r   r   r/   r   r   WINDOWSr   r   r   rZ   r[   )r>   r   r   KB2829981_err_tmplr   s   &&   r1   __validate_win_filename)FileNameValidator.__validate_win_filename   s:   (001AB")00*51 "))&  {* `!!8#3#3 0


 B:-")00CSTVCW9XY.55R
   A3'")00CSTUCV9WX.55H
   (r4   c                2   < V ^8  d   Qh/ S[ ;R&   S[ ;R&   # )r"   r   r   )r   )r/   r0   s   "r1   r2   r   ~   s     "' 
  !&. r4   rx   )CONPRNAUXzCLOCK$NUL)COMLPT)   ¹   ²   ³):)rl   rm   rn   ro   r   	itertoolsproductranger   r   propertyr   r   rp   r;   rV   r   r   r   __annotate_func__rq   rr   rs   rt   s   @@r1   r9   r9   ~   s    .
%dI4E4EnV[\]_aVb4cd%%dI4E4EnV[\]_aVb4cd
d	e
% 
&..W
%% 
&..W
 
	
 ! )/' ' '( '0%)+/#=A
 
$"; ";H 	 	$ $a  r4   r9   Tc                    V ^8  d   QhR\         R\        \        ,          R\        R\        R\        \        ,          R\
        R\        \        \        ,          ,          RR	/# )
r"   filenamer%   r7   r#   r$   r8   r(   r+   Nr   r   r   r,   r-   r.   r   )r/   s   "r1   r2   r2     st     C CC|$C C 	C
 #C C  (6C 
Cr4   c           	     F    \        VVVVVVR7      P                  V 4       R# )a  Verifying whether the ``filename`` is a valid file name or not.

Args:
    filename:
        Filename to validate.
    platform:
        Target platform name of the filename.

        .. include:: platform.txt
    min_len:
        Minimum byte length of the ``filename``. The value must be greater or equal to one.
        Defaults to ``1``.
    max_len:
        Maximum byte length of the ``filename``. The value must be lower than:

            - ``Linux``: 4096
            - ``macOS``: 1024
            - ``Windows``: 260
            - ``universal``: 260

        Defaults to ``255``.
    fs_encoding:
        Filesystem encoding that is used to calculate the byte length of the filename.
        If |None|, get the encoding from the execution environment.
    check_reserved:
        If |True|, check the reserved names of the ``platform``.
    additional_reserved_names:
        Additional reserved names to check.
        Case insensitive.

Raises:
    ValidationError (ErrorReason.INVALID_LENGTH):
        If the ``filename`` is longer than ``max_len`` characters.
    ValidationError (ErrorReason.INVALID_CHARACTER):
        If the ``filename`` includes invalid character(s) for a filename:
        |invalid_filename_chars|.
        The following characters are also invalid for Windows platforms:
        |invalid_win_filename_chars|.
    ValidationError (ErrorReason.RESERVED_NAME):
        If the ``filename`` equals the reserved name by OS.
        Windows reserved name is as follows:
        ``"CON"``, ``"PRN"``, ``"AUX"``, ``"NUL"``, ``"COM[1-9]"``, ``"LPT[1-9]"``.

Example:
    :ref:`example-validate-filename`

See Also:
    `Naming Files, Paths, and Namespaces - Win32 apps | Microsoft Docs
    <https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file>`__
r%   r7   r#   r$   r8   r(   N)r9   rV   r   r%   r7   r#   r$   r8   r(   s   &&&&&&&r1   validate_filenamer     s+    x %"; hxr4   c                    V ^8  d   QhR\         R\        \        ,          R\        R\        \        ,          R\        \        ,          R\
        R\        \        \        ,          ,          R\
        /# )	r"   r   r%   r7   r#   r$   r8   r(   r+   r   )r/   s   "r1   r2   r2   [  sn      |$  c]	
 #   (6 
r4   c           	     N    \        TTVf   RMTVVVR7      P                  V 4      # )a  Check whether the ``filename`` is a valid name or not.

Args:
    filename:
        A filename to be checked.
    platform:
        Target platform name of the filename.

Example:
    :ref:`example-is-valid-filename`

See Also:
    :py:func:`.validate_filename()`
r   r   )r9   is_validr   s   &&&&&&&r1   is_valid_filenamer   [  s5    0 o7%"; hxr4   rk   Fc                L   V ^8  d   QhR\         R\        R\        \        ,          R\        \        ,          R\        \        ,          R\        \
        ,          R\        \        ,          R\        \        ,          R	\        \        \        ,          ,          R
\
        R\         /# )r"   r   rD   r%   r#   r$   r8   r&   r'   r(   r)   r+   )r   r-   r   r   r,   r.   r   r   )r/   s   "r1   r2   r2   }  s     a+ a+a+a+ |$a+ c]	a+
 #a+ TNa+ !!78a+ $$:;a+  (6a+ "a+ a+r4   c
           
         Ve2   \         P                  ! R\        4       VRJ d   \        P                  p\        TVf   RMTVVVVV	R7      P                  W4      # )a	  Make a valid filename from a string.

To make a valid filename, the function does the following:

    - Replace invalid characters as file names included in the ``filename``
      with the ``replacement_text``. Invalid characters are:

        - unprintable characters
        - |invalid_filename_chars|
        - for Windows (or universal) only: |invalid_win_filename_chars|

    - Replace a value if a sanitized value is a reserved name by operating systems
      with a specified handler by ``reserved_name_handler``.

Args:
    filename: Filename to sanitize.
    replacement_text:
        Replacement text for invalid characters. Defaults to ``""``.
    platform:
        Target platform name of the filename.

        .. include:: platform.txt
    max_len:
        Maximum byte length of the ``filename``.
        Truncate the name length if the ``filename`` length exceeds this value.
        Defaults to ``255``.
    fs_encoding:
        Filesystem encoding that is used to calculate the byte length of the filename.
        If |None|, get the encoding from the execution environment.
    check_reserved:
        [Deprecated] Use 'reserved_name_handler' instead.
    null_value_handler:
        Function called when a value after sanitization is an empty string.
        You can specify predefined handlers:

            - :py:func:`~.handler.NullValueHandler.return_null_string`
            - :py:func:`~.handler.NullValueHandler.return_timestamp`
            - :py:func:`~.handler.raise_error`

        Defaults to :py:func:`.handler.NullValueHandler.return_null_string` that just return ``""``.
    reserved_name_handler:
        Function called when a value after sanitization is a reserved name.
        You can specify predefined handlers:

            - :py:meth:`~.handler.ReservedNameHandler.add_leading_underscore`
            - :py:meth:`~.handler.ReservedNameHandler.add_trailing_underscore`
            - :py:meth:`~.handler.ReservedNameHandler.as_is`
            - :py:func:`~.handler.raise_error`

        Defaults to :py:func:`.handler.add_trailing_underscore`.
    additional_reserved_names:
        Additional reserved names to sanitize.
        Case insensitive.
    validate_after_sanitize:
        Execute validation after sanitization to the file name.

Returns:
    Same type as the ``filename`` (str or PathLike object):
        Sanitized filename.

Raises:
    ValueError:
        If the ``filename`` is an invalid filename.

Example:
    :ref:`example-sanitize-filename`
zD'check_reserved' is deprecated. Use 'reserved_name_handler' instead.F)r%   r#   r$   r&   r'   r(   r)   r   )warningswarnDeprecationWarningr   as_isr    rd   )
r   rD   r%   r#   r$   r8   r&   r'   r(   r)   s
   &&&&&&&&&&r1   sanitize_filenamer   }  sg    ` !R	

 U"$7$=$=!o7-3"; 7 hx*+r4   c                    V ^8  d   Qh/ ^ \         9   d
   \        ;R&   ^\         9   d
   \        ;R&   ^\         9   d
   \        ;R&   # )r"   rp   ri   rh   )__conditional_annotations__r   )r/   s   "r1   r2   r2      sJ      * ' &5 &+, e -2 % 3r4   )7r   __doc__r   r   rZ   r   collections.abcr   pathlibr   r   r   typingr   r   _baser   r	   r
   r   _commonr   r   r   r   r   _constr   r   r   _typesr   r   errorr   r   r   r   handlerr   r   rp   compiler[   _INVALID_FILENAME_CHARSUNICODEri   _INVALID_WIN_FILENAME_CHARSrh   r    r9   r   r   r   r2   )r   s   @r1   <module>r      s=     	  $ "  " P P [ [ H H * O O @ $'  & jj		(223A6a8"**   #%**		(667:!<bjj#  
\$) \$~T Tr (,",!%9=CP (,"!!%9=H '+6!%%);?>B9=$)a+ a+r4   