
    |h.                      ^   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lmZ d dl	m
Z
  G d de j                        Zede
eef   fd	       Zdde
eef   dedededef
dZefde
eef   defdZefde
eef   defdZde
eef   defdZddedefdZd ed      d
fdededefdZy)    N)contextmanager)datetime)Path)Unionc                   2    e Zd ZdZdeeef   fdZd Zd Z	y)WorkingDirectorya  
    A context manager and decorator for temporarily changing the working directory.

    This class allows for the temporary change of the working directory using a context manager or decorator.
    It ensures that the original working directory is restored after the context or decorated function completes.

    Attributes:
        dir (Path | str): The new directory to switch to.
        cwd (Path): The original current working directory before the switch.

    Methods:
        __enter__: Changes the current directory to the specified directory.
        __exit__: Restores the original working directory on context exit.

    Examples:
        Using as a context manager:
        >>> with WorkingDirectory('/path/to/new/dir'):
        >>> # Perform operations in the new directory
        >>>     pass

        Using as a decorator:
        >>> @WorkingDirectory('/path/to/new/dir')
        >>> def some_function():
        >>> # Perform operations in the new directory
        >>>     pass
    new_dirc                 `    || _         t        j                         j                         | _        y)zJInitialize the WorkingDirectory context manager with the target directory.N)dirr   cwdresolve)selfr	   s     V/var/www/html/test/engine/venv/lib/python3.12/site-packages/ultralytics/utils/files.py__init__zWorkingDirectory.__init__*   s    88:%%'    c                 B    t        j                  | j                         y)zZChange the current working directory to the specified directory upon entering the context.N)oschdirr   )r   s    r   	__enter__zWorkingDirectory.__enter__/       
r   c                 B    t        j                  | j                         y)z@Restore the original working directory when exiting the context.N)r   r   r   )r   exc_typeexc_valexc_tbs       r   __exit__zWorkingDirectory.__exit__3   r   r   N)
__name__
__module____qualname____doc__r   strr   r   r   r    r   r   r   r      s&    6(c4i 0 (
r   r   pathc              #   L  K   dt        |       v r-t        | t               }t        |       } t        j                         5 }t        |      | j
                  j                  dd      z  }| j                         rt        j                  | |       nC| j                         r3|j                  j                  dd       t        j                  | |       	 |rt        |      n| |j                         rt        j                  || d       n'|j                         rt        j                  ||        	 ddd       y|  y# |j                         rt        j                  || d       w |j                         rt        j                  ||        w w xY w# 1 sw Y   yxY ww)a  
    Context manager to handle paths with spaces in their names.

    If a path contains spaces, it replaces them with underscores, copies the file/directory to the new path, executes
    the context code block, then copies the file/directory back to its original location.

    Args:
        path (str | Path): The original path that may contain spaces.

    Yields:
        (Path | str): Temporary path with spaces replaced by underscores if spaces were present, otherwise the
            original path.

    Examples:
        >>> with spaces_in_path('/path/with spaces') as new_path:
        >>> # Your code here
        >>>     pass
     _Tparentsexist_ok)dirs_exist_okN)r    
isinstancer   tempfileTemporaryDirectorynamereplaceis_dirshutilcopytreeis_fileparentmkdircopy2)r"   stringtmp_dirtmp_paths       r   spaces_in_pathr9   8   sE    * c$iD#&Dz ((* 	1gG}tyy'8'8c'BBH {{}h/%%dT%BT8,	1'-c(m8; ??$OOHd$G%%'LL40'	1 	1. 
 ??$OOHd$G%%'LL40 (%	1 	1s8   >F$ BFE%AF5F$AFFF!F$Fr(   sepr4   returnc                 `   t        |       } | j                         r}|s{| j                         r| j                  d      | j                  fn| df\  } }t        dd      D ]-  }|  | | | }t        j                  j                  |      r- n t              } |r| j                  dd       | S )a  
    Increment a file or directory path, i.e., runs/exp --> runs/exp{sep}2, runs/exp{sep}3, ... etc.

    If the path exists and `exist_ok` is not True, the path will be incremented by appending a number and `sep` to
    the end of the path. If the path is a file, the file extension will be preserved. If the path is a directory, the
    number will be appended directly to the end of the path.

    Args:
        path (str | Path): Path to increment.
        exist_ok (bool, optional): If True, the path will not be incremented and returned as-is.
        sep (str, optional): Separator to use between the path and the incrementation number.
        mkdir (bool, optional): Create a directory if it does not exist.

    Returns:
        (Path): Incremented path.

    Examples:
        Increment a directory path:
        >>> from pathlib import Path
        >>> path = Path("runs/exp")
        >>> new_path = increment_path(path)
        >>> print(new_path)
        runs/exp2

        Increment a file path:
        >>> path = Path("runs/exp/results.txt")
        >>> new_path = increment_path(path)
        >>> print(new_path)
        runs/exp/results2.txt
        i'  Tr&   )	r   existsr2   with_suffixsuffixranger   r"   r4   )r"   r(   r:   r4   rA   nps          r   increment_pathrE   l   s    > :D{{}X>Blln((,dkk:SWY[R\f q$ 	A&aS)A77>>!$	 Aw

4$
/Kr   c                     t        j                         t        j                  t        |       j	                         j
                        z
  }|j                  S )z>Return days since the last modification of the specified file.)r   nowfromtimestampr   statst_mtimedays)r"   dts     r   file_agerM      s7    	(00d1B1K1KL	LB77Nr   c                     t        j                  t        |       j                         j                        }|j
                   d|j                   d|j                   S )z7Return the file modification date in 'YYYY-M-D' format.-)r   rH   r   rI   rJ   yearmonthday)r"   ts     r   	file_daterT      sF    tDz099:AffXQqwwiq((r   c                    t        | t        t        f      rnd}t        |       } | j                         r| j	                         j
                  |z  S | j                         r$t        d | j                  d      D              |z  S y)z9Return the size of a file or directory in megabytes (MB).i   c              3   r   K   | ]/  }|j                         s|j                         j                   1 y w)N)r2   rI   st_size).0fs     r   	<genexpr>zfile_size.<locals>.<genexpr>   s$     RAaiikqvvx''Rs   77z**/*g        )	r*   r    r   r2   rI   rW   r/   sumglob)r"   mbs     r   	file_sizer^      sj    $d$Dz<<>99;&&++[[]R61BRRUWWWr   .
search_dirc                     t        j                   |  dd      }|r%t        |t        j                  j                        S dS )zcReturn the path to the most recent 'last.pt' file in the specified directory for resuming training.z/**/last*.ptT)	recursive)keyr=   )r\   maxr   r"   getctime)r`   	last_lists     r   get_latest_runrg      s7    		ZL5FI3<3ybgg../D"Dr   )z
yolo11n.ptmodel_names
source_dirupdate_namesc                 0   ddl m} ddlm} |dz  }|j	                  dd       | D ]m  }||z  }t        d|         ||      }|j                          |r |d      |j                  _        ||z  }	t        d	| d
|	        |j                  |	       o y)ay  
    Update and re-save specified YOLO models in an 'updated_models' subdirectory.

    Args:
        model_names (tuple, optional): Model filenames to update.
        source_dir (Path, optional): Directory containing models and target subdirectory.
        update_names (bool, optional): Update model names from a data YAML.

    Examples:
        Update specified YOLO models and save them in 'updated_models' subdirectory:
        >>> from ultralytics.utils.files import update_models
        >>> model_names = ("yolo11n.pt", "yolov8s.pt")
        >>> update_models(model_names, source_dir=Path("/models"), update_names=True)
    r   )YOLO)default_class_namesupdated_modelsTr&   zLoading model from z
coco8.yamlz
Re-saving z
 model to N)
ultralyticsrl   ultralytics.nn.autobackendrm   r4   printhalfmodelnamessave)
rh   ri   rj   rl   rm   
target_dir
model_name
model_pathrs   	save_paths
             r   update_modelsrz      s     !>..JTD1! 
*,
#J<01 Z 

 3L AEKK +	 	
:,j<=

9r   )Fr=   F)r_   )
contextlibr\   r   r0   r+   r   r   pathlibr   typingr   ContextDecoratorr   r    r9   boolrE   __file__intrM   rT   floatr^   rg   tuplerz   r!   r   r   <module>r      s,     	   %   'z22 'T 0sDy) 0 0f-sDy) -T - -Y] -jn -` '/ 5d# 3  (0 )E#t)$ )C )	E#t)$ 	 	Es ES E (74PS9kp $u $D $dh $r   