a
    yf                     @   s  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
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 d dlZd dlmZ d dlZd dlZd dlZd dlmZ  d dl!m"Z" e#e$dd	Z%e#e$d
d	Z&ej'pddgZ(ee)* Z+e+j,d Z-e-d Z.e-d Z/e0de1de2 d Z3e4e$dd5 dkZ6e4e$dd5 dkZ7e7rdndZ8dZ9dd dD \Z:Z;Z<e= dv Z>e? Z@ej"ZAejBCdZDejEFdddkZGdZHejIdd d!d" ejIdd#d$jJid% eKd  e4e3ejEd&< d'ejEd(< d)ejEd*< d+ejEd,< d-ejEd.< G d/d0 d0e ZLG d1d2 d2ZMG d3d4 d4eZNdd6d7ZOdd9d:ZPePe9e7d;ZQd<D ]ZReSeRTejUd  qdd=d>ZVG d?d@ d@ZWddBdCZXddDdEZYee4eeZf ddFdGdHZ[eYe/Z\e\] D ],\Z^Z_e`e_e4re_5 dIkrde\e^< qe\a ZbeNf i e\Zce4dJdKdLZdeedJdMdNZfdOdP ZgdQdR ZhdSdT ZieedJdUdVZjeedJdWdXZkeedJdYdZZleedJd[d\Zmenfe4eed]d^d_Zoee4ef eed`dadbZpdcdd ZqeedJdedfZrdgdh Zsdidj Ztdkdl Zudmdn Zvdodp Zwdqdr ZxddtduZyed Zzem Z{eg Z|ej Z}el Z~ei Zeh Zeo Zek Zes Zet Zee$dvpey Zedw Zdxdy Zdzd{ ZG d|d} d}e jZG d~d de jZdd Zdd ZG dd deZZG dd deZdd Zdd Zdd Zde4dJddZedZe Zeed Zeed Zeed Zeed Ze|rndn$erxdnerdne}rdne Zeq per Ze  d dlmZmZmZmZmZ ee_ee_e<reee  e_e_e_dS )    N)Path)Lock)SimpleNamespace)Union)tqdm)__version__RANK
LOCAL_RANK    Zassetszcfg/default.yaml   ZYOLO_AUTOINSTALLTtrueZYOLO_VERBOSEz{l_bar}{bar:10}{r_bar}ultralyticsc                 c   s   | ]}t  |kV  qd S N)platformsystem.0x r   V/var/www/html/django/DPS/env/lib/python3.9/site-packages/ultralytics/utils/__init__.py	<genexpr>.       r   )DarwinLinuxWindows>   arm64aarch64ZtorchvisionZTERM_PROGRAMFZvscodea  
    Examples for running Ultralytics:

    1. Install the ultralytics package:

        pip install ultralytics

    2. Use the Python SDK:

        from ultralytics import YOLO

        # Load a model
        model = YOLO("yolov8n.yaml")  # build a new model from scratch
        model = YOLO("yolov8n.pt")  # load a pretrained model (recommended for training)

        # Use the model
        results = model.train(data="coco8.yaml", epochs=3)  # train the model
        results = model.val()  # evaluate model performance on the validation set
        results = model("https://ultralytics.com/images/bus.jpg")  # predict on an image
        success = model.export(format="onnx")  # export the model to ONNX format

    3. Use the command line interface (CLI):

        Ultralytics 'yolo' CLI commands use the following syntax:

            yolo TASK MODE ARGS

            Where   TASK (optional) is one of [detect, segment, classify, pose, obb]
                    MODE (required) is one of [train, val, predict, export, benchmark]
                    ARGS (optional) are any number of custom "arg=value" pairs like "imgsz=320" that override defaults.
                        See all ARGS at https://docs.ultralytics.com/usage/cfg or with "yolo cfg"

        - Train a detection model for 10 epochs with an initial learning_rate of 0.01
            yolo detect train data=coco8.yaml model=yolov8n.pt epochs=10 lr0=0.01

        - Predict a YouTube video using a pretrained segmentation model at image size 320:
            yolo segment predict model=yolov8n-seg.pt source='https://youtu.be/LNwODJXcvt4' imgsz=320

        - Val a pretrained detection model at batch-size 1 and image size 640:
            yolo detect val model=yolov8n.pt data=coco8.yaml batch=1 imgsz=640

        - Export a YOLOv8n classification model to ONNX format at image size 224 by 128 (no TASK required)
            yolo export model=yolov8n-cls.pt format=onnx imgsz=224,128

        - Run special commands:
            yolo help
            yolo checks
            yolo version
            yolo settings
            yolo copy-cfg
            yolo cfg

    Docs: https://docs.ultralytics.com
    Community: https://community.ultralytics.com
    GitHub: https://github.com/ultralytics/ultralytics
    i@     default)	linewidth	precisionZprofileZ
float_kindz{:11.5g})r!   	formatterZNUMEXPR_MAX_THREADSz:4096:8ZCUBLAS_WORKSPACE_CONFIG3ZTF_CPP_MIN_LOG_LEVELERRORZTORCH_CPP_LOG_LEVEL5ZKINETO_LOG_LEVELc                       s    e Zd ZdZ fddZ  ZS )TQDMa  
    A custom TQDM progress bar class that extends the original tqdm functionality.

    This class modifies the behavior of the original tqdm progress bar based on global settings and provides
    additional customization options.

    Attributes:
        disable (bool): Whether to disable the progress bar. Determined by the global VERBOSE setting and
            any passed 'disable' argument.
        bar_format (str): The format string for the progress bar. Uses the global TQDM_BAR_FORMAT if not
            explicitly set.

    Methods:
        __init__: Initializes the TQDM object with custom settings.

    Examples:
        >>> from ultralytics.utils import TQDM
        >>> for i in TQDM(range(100)):
        ...     # Your processing code here
        ...     pass
    c                    s8   t  p|dd|d< |dt t j|i | dS )a  
        Initializes a custom TQDM progress bar.

        This class extends the original tqdm class to provide customized behavior for Ultralytics projects.

        Args:
            *args (Any): Variable length argument list to be passed to the original tqdm constructor.
            **kwargs (Any): Arbitrary keyword arguments to be passed to the original tqdm constructor.

        Notes:
            - The progress bar is disabled if VERBOSE is False or if 'disable' is explicitly set to True in kwargs.
            - The default bar format is set to TQDM_BAR_FORMAT unless overridden in kwargs.

        Examples:
            >>> from ultralytics.utils import TQDM
            >>> for i in TQDM(range(100)):
            ...     # Your code here
            ...     pass
        disableFZ
bar_formatN)VERBOSEget
setdefaultTQDM_BAR_FORMATsuper__init__selfargskwargs	__class__r   r   r.      s    zTQDM.__init__)__name__
__module____qualname____doc__r.   __classcell__r   r   r3   r   r'   x   s   r'   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	SimpleClassa  
    A simple base class for creating objects with string representations of their attributes.

    This class provides a foundation for creating objects that can be easily printed or represented as strings,
    showing all their non-callable attributes. It's useful for debugging and introspection of object states.

    Methods:
        __str__: Returns a human-readable string representation of the object.
        __repr__: Returns a machine-readable string representation of the object.
        __getattr__: Provides a custom attribute access error message with helpful information.

    Examples:
        >>> class MyClass(SimpleClass):
        ...     def __init__(self):
        ...         self.x = 10
        ...         self.y = "hello"
        >>> obj = MyClass()
        >>> print(obj)
        __main__.MyClass object with attributes:

        x: 10
        y: 'hello'

    Notes:
        - This class is designed to be subclassed. It provides a convenient way to inspect object attributes.
        - The string representation includes the module and class name of the object.
        - Callable attributes and attributes starting with an underscore are excluded from the string representation.
    c                 C   s   g }t | D ]d}t| |}t|s|dst|trT| d|j d|jj d}n| dt	| }|
| q| j d| jj dd| S )<Return a human-readable string representation of the object._: .z objectz object with attributes:


)dirgetattrcallable
startswith
isinstancer:   r6   r4   r5   reprappendjoin)r0   attravsr   r   r   __str__   s    

zSimpleClass.__str__c                 C   s   |   S )z>Return a machine-readable string representation of the object.)rL   r0   r   r   r   __repr__   s    zSimpleClass.__repr__c                 C   s(   | j j}td| d| d| j dS )?Custom attribute access error message with helpful information.'' object has no attribute 'z'. See valid attributes below.
N)r4   r5   AttributeErrorr8   r0   rH   namer   r   r   __getattr__   s    zSimpleClass.__getattr__N)r5   r6   r7   r8   rL   rN   rU   r   r   r   r   r:      s   r:   c                   @   s2   e Zd ZdZdd Zdd Zdd Zdd	d
ZdS )IterableSimpleNamespacea  
    An iterable SimpleNamespace class that provides enhanced functionality for attribute access and iteration.

    This class extends the SimpleNamespace class with additional methods for iteration, string representation,
    and attribute access. It is designed to be used as a convenient container for storing and accessing
    configuration parameters.

    Methods:
        __iter__: Returns an iterator of key-value pairs from the namespace's attributes.
        __str__: Returns a human-readable string representation of the object.
        __getattr__: Provides a custom attribute access error message with helpful information.
        get: Retrieves the value of a specified key, or a default value if the key doesn't exist.

    Examples:
        >>> cfg = IterableSimpleNamespace(a=1, b=2, c=3)
        >>> for k, v in cfg:
        ...     print(f"{k}: {v}")
        a: 1
        b: 2
        c: 3
        >>> print(cfg)
        a=1
        b=2
        c=3
        >>> cfg.get("b")
        2
        >>> cfg.get("d", "default")
        'default'

    Notes:
        This class is particularly useful for storing configuration parameters in a more accessible
        and iterable format compared to a standard dictionary.
    c                 C   s   t t|  S )zFReturn an iterator of key-value pairs from the namespace's attributes.)itervarsitemsrM   r   r   r   __iter__  s    z IterableSimpleNamespace.__iter__c                 C   s   d dd t|  D S )r;   r?   c                 s   s    | ]\}}| d | V  qdS )=Nr   r   krJ   r   r   r   r     r   z2IterableSimpleNamespace.__str__.<locals>.<genexpr>)rG   rX   rY   rM   r   r   r   rL     s    zIterableSimpleNamespace.__str__c                 C   s(   | j j}td| d| dt ddS )rO   z
            'rQ   z'. This may be caused by a modified or out of date ultralytics
            'default.yaml' file.
Please update your code with 'pip install -U ultralytics' and if necessary replace
            z with the latest version from
            https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/default.yaml
            N)r4   r5   rR   DEFAULT_CFG_PATHrS   r   r   r   rU   	  s    z#IterableSimpleNamespace.__getattr__Nc                 C   s   t | ||S )zXReturn the value of the specified key if it exists; otherwise, return the default value.)rA   )r0   keyr    r   r   r   r*     s    zIterableSimpleNamespace.get)N)r5   r6   r7   r8   rZ   rL   rU   r*   r   r   r   r   rV      s
   "rV   Aggc                    s"   du rddi fdd}|S )ai  
    Decorator to temporarily set rc parameters and the backend for a plotting function.

    Example:
        decorator: @plt_settings({"font.size": 12})
        context manager: with plt_settings({"font.size": 12}):

    Args:
        rcparams (dict): Dictionary of rc parameters to set.
        backend (str, optional): Name of the backend to use. Defaults to 'Agg'.

    Returns:
        (Callable): Decorated function with temporarily set rc parameters and backend. This decorator can be
            applied to any function that needs to have specific matplotlib rc parameters and backend for its execution.
    Nz	font.size   c                    s    fdd}|S )zEDecorator to apply temporary rc parameters and backend to a function.c               	      s   t  }  | k}|r0t d t   zTt  | i |}W d   n1 s`0    Y  W |rt d t | n|rt d t | 0 |S )zWSets rc parameters and backend, calls the original function, and restores the settings.allN)pltget_backendlowercloseZswitch_backendZ
rc_context)r1   r2   Zoriginal_backendswitchresult)backendfuncrcparamsr   r   wrapper0  s    

.

z0plt_settings.<locals>.decorator.<locals>.wrapperr   rj   rl   ri   rk   rj   r   	decorator-  s    zplt_settings.<locals>.decoratorr   )rk   ri   rp   r   rn   r   plt_settings  s    rq   LOGGING_NAMEc           	   
   C   s&  |rt dv rtjntj}td}trttjdrtjj	dkrG dd dtj}zRttjdrntjj
dd n2ttjd	rd
dl}|jtjjddt_n|d}W n: ty } z"td|  |d}W Y d}~n
d}~0 0 ttj}|| || t| }|| || d|_|S )ar  
    Sets up logging with UTF-8 encoding and configurable verbosity.

    This function configures logging for the Ultralytics library, setting the appropriate logging level and
    formatter based on the verbosity flag and the current process rank. It handles special cases for Windows
    environments where UTF-8 encoding might not be the default.

    Args:
        name (str): Name of the logger. Defaults to "LOGGING_NAME".
        verbose (bool): Flag to set logging level to INFO if True, ERROR otherwise. Defaults to True.

    Examples:
        >>> set_logging(name="ultralytics", verbose=True)
        >>> logger = logging.getLogger("ultralytics")
        >>> logger.info("This is an info message")

    Notes:
        - On Windows, this function attempts to reconfigure stdout to use UTF-8 encoding if possible.
        - If reconfiguration is not possible, it falls back to a custom formatter that handles non-UTF-8 environments.
        - The function sets up a StreamHandler with the appropriate formatter and level.
        - The logger's propagate flag is set to False to prevent duplicate logging in parent loggers.
       r   r	   z%(message)sencodingutf-8c                       s   e Zd Z fddZ  ZS )z$set_logging.<locals>.CustomFormatterc                    s   t t |S )z?Sets up logging with UTF-8 encoding and configurable verbosity.)emojisr-   format)r0   recordr3   r   r   rw   e  s    z+set_logging.<locals>.CustomFormatter.format)r5   r6   r7   rw   r9   r   r   r3   r   CustomFormatterd  s   ry   reconfigure)rt   bufferr   Nz<Creating custom formatter for non UTF-8 environments due to F)r   loggingINFOr%   	FormatterWINDOWShasattrsysstdoutrt   rz   ioTextIOWrapperr{   	ExceptionprintStreamHandlersetFormattersetLevel	getLogger
addHandler	propagate)	rT   verboselevelr#   ry   r   eZstream_handlerloggerr   r   r   set_loggingG  s,    





r   )r   )
sentry_sdkzurllib3.connectionpoolc                 C   s   t r|  ddS | S )z7Return platform-dependent emoji-safe version of string.asciiignore)r   encodedecode)stringr   r   r   rv     s    rv   c                   @   s    e Zd ZdZdd Zdd ZdS )ThreadingLockeda7  
    A decorator class for ensuring thread-safe execution of a function or method. This class can be used as a decorator
    to make sure that if the decorated function is called from multiple threads, only one thread at a time will be able
    to execute the function.

    Attributes:
        lock (threading.Lock): A lock object used to manage access to the decorated function.

    Example:
        ```python
        from ultralytics.utils import ThreadingLocked

        @ThreadingLocked()
        def my_function():
            # Your code here
        ```
    c                 C   s   t  | _dS )zRInitializes the decorator class for thread-safe execution of a function or method.N)	threadingr   lockrM   r   r   r   r.     s    zThreadingLocked.__init__c                    s&   ddl m} |  fdd}|S )z0Run thread-safe execution of function or method.r   )wrapsc                     s8   j   | i |W  d   S 1 s*0    Y  dS )z:Applies thread-safety to the decorated function or method.N)r   )r1   r2   fr0   r   r   	decorated  s    z+ThreadingLocked.__call__.<locals>.decorated)	functoolsr   )r0   r   r   r   r   r   r   __call__  s    zThreadingLocked.__call__Nr5   r6   r7   r8   r.   r   r   r   r   r   r     s   r   	data.yamlc              	   C   s   |du ri }t | } | j s.| jjddd tttttt	t
tdf}| D ]\}}t||sNt|||< qNt| dddd0}|r|| tj||ddd	 W d   n1 s0    Y  dS )
a  
    Save YAML data to a file.

    Args:
        file (str, optional): File name. Default is 'data.yaml'.
        data (dict): Data to save in YAML format.
        header (str, optional): YAML header to add.

    Returns:
        (None): Data is saved to the specified file.
    NTparentsexist_okwr   ru   errorsrt   F)	sort_keysallow_unicode)r   parentexistsmkdirintfloatstrboollisttupledicttyperY   rD   openwriteyamlZ	safe_dump)filedataheaderZvalid_typesr]   rJ   r   r   r   r   	yaml_save  s    


r   c                 C   s   t | jdv sJ d|  dt| dddP}| }| sLtdd|}t|pXi }|rjt	| |d	< |W  d
   S 1 s0    Y  d
S )a  
    Load YAML data from a file.

    Args:
        file (str, optional): File name. Default is 'data.yaml'.
        append_filename (bool): Add the YAML filename to the YAML dictionary. Default is False.

    Returns:
        (dict): YAML data and file name.
    >   z.ymlz.yamlz!Attempting to load non-YAML file z with yaml_load()r   ru   r   zJ[^\x09\x0A\x0D\x20-\x7E\x85\xA0-\uD7FF\uE000-\uFFFD\U00010000-\U0010ffff]+r   	yaml_fileN)
r   suffixr   readisprintableresubr   Z	safe_loadr   )r   Zappend_filenamer   rK   r   r   r   r   	yaml_load  s    r   )r   returnc                 C   sR   t | ttfrt| n| }tj|ddtdd}tdt	dd|  d|  d	S )
z
    Pretty prints a YAML file or a YAML-formatted dictionary.

    Args:
        yaml_file: The file path of the YAML file or a YAML-formatted dictionary.

    Returns:
        (None)
    FTinf)r   r   widthz
Printing 'boldblackz'

N)
rD   r   r   r   r   dumpr   LOGGERinfocolorstr)r   Z	yaml_dictr   r   r   r   
yaml_print  s    
r   none)r   c               	   C   sl   t tN td&} |  W  d   W  d   S 1 s@0    Y  W d   n1 s^0    Y  dS )z
    Reads the device model information from the system and caches it for quick access. Used by is_jetson() and
    is_raspberrypi().

    Returns:
        (str): Model file contents if read successfully or empty string otherwise.
    z/proc/device-tree/modelNr   
contextlibsuppressr   r   r   r   r   r   r   read_device_model  s    
Rr   c               	   C   sp   t tR td*} d|  v W  d   W  d   S 1 sD0    Y  W d   n1 sb0    Y  dS )zi
    Check if the OS is Ubuntu.

    Returns:
        (bool): True if OS is Ubuntu, False otherwise.
    /etc/os-releasez	ID=ubuntuNF)r   r   FileNotFoundErrorr   r   r   r   r   r   	is_ubuntu  s    
Vr   c                   C   s   dt jv pdt jv S )z
    Check if the current script is running inside a Google Colab notebook.

    Returns:
        (bool): True if running inside a Colab notebook, False otherwise.
    ZCOLAB_RELEASE_TAGZCOLAB_BACKEND_VERSIONosenvironr   r   r   r   is_colab!  s    r   c                   C   s    t jddkot jddkS )z
    Check if the current script is running inside a Kaggle kernel.

    Returns:
        (bool): True if running inside a Kaggle kernel, False otherwise.
    ZPWDz/kaggle/workingZKAGGLE_URL_BASEzhttps://www.kaggle.com)r   r   r*   r   r   r   r   	is_kaggle+  s    r   c                  C   sD   t t& ddlm}  |  duW  d   S 1 s60    Y  dS )z
    Check if the current script is running inside a Jupyter Notebook. Verified on Colab, Jupyterlab, Kaggle, Paperspace.

    Returns:
        (bool): True if running inside a Jupyter Notebook, False otherwise.
    r   get_ipythonNF)r   r   r   ZIPythonr   r   r   r   r   
is_jupyter5  s    (r   c               	   C   sp   t tR td*} d|  v W  d   W  d   S 1 sD0    Y  W d   n1 sb0    Y  dS )z
    Determine if the script is running inside a Docker container.

    Returns:
        (bool): True if the script is running inside a Docker container, False otherwise.
    z/proc/self/cgroupdockerNFr   r   r   r   r   	is_dockerC  s    
Vr   c                   C   s   dt v S )z
    Determines if the Python environment is running on a Raspberry Pi by checking the device model information.

    Returns:
        (bool): True if running on a Raspberry Pi, False otherwise.
    zRaspberry PiPROC_DEVICE_MODELr   r   r   r   is_raspberrypiP  s    r   c                   C   s   dt v S )z
    Determines if the Python environment is running on a Jetson Nano or Jetson Orin device by checking the device model
    information.

    Returns:
        (bool): True if running on a Jetson Nano or Jetson Orin, False otherwise.
    ZNVIDIAr   r   r   r   r   	is_jetsonZ  s    r   c                  C   s   t td ttdd dks(J ddl} dD ]*}| j|dfdd		   W d   d
S W d   n1 st0    Y  dS )z
    Check internet connectivity by attempting to connect to a known online host.

    Returns:
        (bool): True if connection is successful, False otherwise.
    ZYOLO_OFFLINEr   r   r   N)z1.1.1.1z8.8.8.8P   g       @)addresstimeoutTF)
r   r   r   r   r   getenvre   socketcreate_connectionrf   )r   Zdnsr   r   r   	is_onlinee  s    0r   )filepathr   c                 C   s&   ddl }|j| }|duo$|jduS )z
    Determines if the file at the given filepath is part of a pip package.

    Args:
        filepath (str): The filepath to check.

    Returns:
        (bool): True if the file is part of a pip package, False otherwise.
    r   N)importlib.utilutil	find_specorigin)r   	importlibspecr   r   r   is_pip_packagev  s    
r   )dir_pathr   c                 C   s   t t| t jS )z
    Check if a directory is writeable.

    Args:
        dir_path (str | Path): The path to the directory.

    Returns:
        (bool): True if the directory is writeable, False otherwise.
    )r   accessr   W_OK)r   r   r   r   is_dir_writeable  s    
r   c                   C   s&   dt jv p$dtjv p$dttd jv S )z
    Determines whether pytest is currently running or not.

    Returns:
        (bool): True if pytest is running, False otherwise.
    ZPYTEST_CURRENT_TESTZpytestr   )r   r   r   modulesr   ARGVstemr   r   r   r   is_pytest_running  s    r   c                   C   s   dt jv odt jv odt jv S )z
    Determine if the current environment is a GitHub Actions runner.

    Returns:
        (bool): True if the current environment is a GitHub Actions runner, False otherwise.
    ZGITHUB_ACTIONSZGITHUB_WORKFLOWZ	RUNNER_OSr   r   r   r   r   is_github_action_running  s    r   c                  C   s(   t tjD ]} | d  r
|   S q
dS )a  
    Determines whether the current file is part of a git repository and if so, returns the repository root directory. If
    the current file is not part of a git repository, returns None.

    Returns:
        (Path | None): Git root directory if found or None if not found.
    z.gitN)r   __file__r   is_dir)dr   r   r   get_git_dir  s    r   c                   C   s   t duS )z
    Determines whether the current file is part of a git repository. If the current file is not part of a git
    repository, returns None.

    Returns:
        (bool): True if current file is part of a git repository.
    N)GIT_DIRr   r   r   r   
is_git_dir  s    r  c                  C   sN   t rJttj* tg d} |   W  d   S 1 s@0    Y  dS )z
    Retrieves the origin URL of a git repository.

    Returns:
        (str | None): The origin URL of the git repository or None if not git directory.
    )gitconfigz--getzremote.origin.urlN
IS_GIT_DIRr   r   
subprocessCalledProcessErrorcheck_outputr   stripr   r   r   r   get_git_origin_url  s    r  c                  C   sN   t rJttj* tg d} |   W  d   S 1 s@0    Y  dS )z
    Returns the current git branch name. If not in a git repository, returns None.

    Returns:
        (str | None): The current git branch name or None if not a git directory.
    )r  z	rev-parsez--abbrev-refHEADNr  r  r   r   r   get_git_branch  s    r  c                 C   s   t | }dd |j D S )a  
    Returns a dictionary of default arguments for a function.

    Args:
        func (callable): The function to inspect.

    Returns:
        (dict): A dictionary where each key is a parameter name, and each value is the default value of that parameter.
    c                 S   s&   i | ]\}}|j tjjur||j qS r   )r    inspect	Parameteremptyr\   r   r   r   
<dictcomp>  r   z$get_default_args.<locals>.<dictcomp>)r  	signature
parametersrY   )rj   r  r   r   r   get_default_args  s    

r  c               	   C   s   t  r|tttZ td2} td|  d W  d   W  d   S 1 sT0    Y  W d   n1 sr0    Y  dS )z
    Retrieve the Ubuntu version if the OS is Ubuntu.

    Returns:
        (str): Ubuntu version or None if not an Ubuntu OS.
    r   zVERSION_ID="(\d+\.\d+)"r   N)	r   r   r   r   rR   r   r   searchr   r   r   r   r   get_ubuntu_version  s    
r  Ultralyticsc                 C   s   t rt d d |  }nBtr4t d d |  }n(trJt d |  }ntdt  t|j	st
d| d td	rtd	|  nt  |  }|jd
d
d |S )z
    Return the appropriate config directory based on the environment operating system.

    Args:
        sub_dir (str): The name of the subdirectory to create.

    Returns:
        (Path): The path to the user config directory.
    ZAppDataZRoamingLibraryzApplication Supportz.configzUnsupported operating system: u&   WARNING ⚠️ user config directory 'z' is not writeable, defaulting to '/tmp' or CWD.Alternatively you can define a YOLO_CONFIG_DIR environment variable for this path.z/tmpTr   )r   r   homeMACOSLINUX
ValueErrorr   r   r   r   r   warningcwdr   )Zsub_dirpathr   r   r   get_user_config_dir  s    


"r!  ZYOLO_CONFIG_DIRzsettings.jsonc                     sv   t | dkr| ndd| d f^ }}ddddd	d
dddddddddddddd d fdd|D |   d  S )am  
    Colors a string based on the provided color and style arguments. Utilizes ANSI escape codes.
    See https://en.wikipedia.org/wiki/ANSI_escape_code for more details.

    This function can be called in two ways:
        - colorstr('color', 'style', 'your string')
        - colorstr('your string')

    In the second form, 'blue' and 'bold' will be applied by default.

    Args:
        *input (str | Path): A sequence of strings where the first n-1 strings are color and style arguments,
                      and the last string is the one to be colored.

    Supported Colors and Styles:
        Basic Colors: 'black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'
        Bright Colors: 'bright_black', 'bright_red', 'bright_green', 'bright_yellow',
                       'bright_blue', 'bright_magenta', 'bright_cyan', 'bright_white'
        Misc: 'end', 'bold', 'underline'

    Returns:
        (str): The input string wrapped with ANSI escape codes for the specified color and style.

    Examples:
        >>> colorstr("blue", "bold", "hello world")
        >>> "\033[34m\033[1mhello world\033[0m"
    r   bluer   r   z[30mz[31mz[32mz[33mz[34mz[35mz[36mz[37mz[90mz[91mz[92mz[93mz[94mz[95mz[96mz[97mz[0mz[1mz[4m)r   redgreenyellowr"  magentacyanwhitebright_black
bright_redbright_greenbright_yellowbright_bluebright_magentabright_cyanbright_whiteendr   	underliner   c                 3   s   | ]} | V  qd S r   r   r   colorsr   r   r   Z  r   zcolorstr.<locals>.<genexpr>r1  )lenrG   )inputr1   r   r   r3  r   r   (  s,    $r   c                 C   s   t d}|d| S )a\  
    Removes ANSI escape codes from a string, effectively un-coloring it.

    Args:
        input_string (str): The string to remove color and style from.

    Returns:
        (str): A new string with all ANSI escape codes removed.

    Examples:
        >>> remove_colorstr(colorstr("blue", "bold", "hello world"))
        >>> "hello world"
    z\x1B\[[0-9;]*[A-Za-z]r   )r   compiler   )Zinput_stringZansi_escaper   r   r   remove_colorstr]  s    
r8  c                   @   s*   e Zd ZdZdddZdd Zdd	 Zd
S )	TryExcepta  
    Ultralytics TryExcept class. Use as @TryExcept() decorator or 'with TryExcept():' context manager.

    Examples:
        As a decorator:
        >>> @TryExcept(msg="Error occurred in func", verbose=True)
        >>> def func():
        >>> # Function logic here
        >>>     pass

        As a context manager:
        >>> with TryExcept(msg="Error occurred in block", verbose=True):
        >>> # Code block here
        >>>     pass
    r   Tc                 C   s   || _ || _dS )zHInitialize TryExcept class with optional message and verbosity settings.N)msgr   )r0   r:  r   r   r   r   r.     s    zTryExcept.__init__c                 C   s   dS )z?Executes when entering TryExcept context, initializes instance.Nr   rM   r   r   r   	__enter__  s    zTryExcept.__enter__c                 C   s2   | j r.|r.tt| j | jrdnd |  dS )zPDefines behavior when exiting a 'with' block, prints error message if necessary.r=   r   T)r   r   rv   r:  )r0   exc_typevalue	tracebackr   r   r   __exit__  s    
$zTryExcept.__exit__N)r   T)r5   r6   r7   r8   r.   r;  r?  r   r   r   r   r9  o  s   
r9  c                   @   s"   e Zd ZdZd	ddZdd ZdS )
Retrya  
    Retry class for function execution with exponential backoff.

    Can be used as a decorator to retry a function on exceptions, up to a specified number of times with an
    exponentially increasing delay between retries.

    Examples:
        Example usage as a decorator:
        >>> @Retry(times=3, delay=2)
        >>> def test_func():
        >>> # Replace with function logic that may raise exceptions
        >>>     return True
          c                 C   s   || _ || _d| _dS )zBInitialize Retry class with specified number of retries and delay.r   N)timesdelay	_attempts)r0   rC  rD  r   r   r   r.     s    zRetry.__init__c                    s    fdd}|S )z<Decorator implementation for Retry with exponential backoff.c               
      s   d_ j jk rz | i |W S  ty } z^ j d7  _ tdj  dj d|  j jkrn|tjdj    W Y d}~qd}~0 0 qdS )z4Applies retries to the decorated function or method.r   r   zRetry /z	 failed: rB  N)rE  rC  r   r   timesleeprD  )r1   r2   r   rj   r0   r   r   wrapped_func  s    z$Retry.__call__.<locals>.wrapped_funcr   )r0   rj   rJ  r   rI  r   r     s    zRetry.__call__N)rA  rB  r   r   r   r   r   r@    s   
r@  c                    s    fdd}|S )z
    Multi-threads a target function by default and returns the thread or function result.

    Use as @threaded decorator. The function runs in a separate thread unless 'threaded=False' is passed.
    c                     s<   | ddr*tj | |dd}|  |S  | i |S dS )zcMulti-threads a given function based on 'threaded' kwarg and returns the thread or function result.threadedT)targetr1   r2   daemonN)popr   Threadstart)r1   r2   threadro   r   r   rl     s
    zthreaded.<locals>.wrapperr   rm   r   ro   r   rK    s    	rK  c               
   C   s   t d rtdv rttd jdkrtstrtrtszddl	} W n t
yR   Y dS 0 dd }| jdd	d	d
td|ttgd | dt d i dS )a  
    Initialize the Sentry SDK for error tracking and reporting. Only used if sentry_sdk package is installed and
    sync=True in settings. Run 'yolo settings' to see and update settings.

    Conditions required to send errors (ALL conditions must be met or no errors will be reported):
        - sentry_sdk package is installed
        - sync=True in YOLO settings
        - pytest is not running
        - running in a pip package installation
        - running in a non-git directory
        - running with rank -1 or 0
        - online environment
        - CLI used to run package (checked with 'yolo' as the name of the main CLI command)

    The function also configures Sentry SDK to ignore KeyboardInterrupt and FileNotFoundError exceptions and to exclude
    events with 'out of memory' in their exception message.

    Additionally, the function sets custom tags and user information for Sentry events.
    syncrs   r   ZyoloNc                 S   sf   d|v r2|d \}}}|t thv s.dt|v r2dS td ttd jtrLdn
trTdndtd| d	< | S )
a  
            Modify the event before sending it to Sentry based on specific exception types and messages.

            Args:
                event (dict): The event dictionary containing information about the error.
                hint (dict): A dictionary containing additional information about the error.

            Returns:
                dict: The modified event or None if the event should not be sent to Sentry.
            exc_infozout of memoryNr   r  pipother)Zsys_argvZsys_argv_nameinstallr   tags)	KeyboardInterruptr   r   r   r   rT   r  IS_PIP_PACKAGEENVIRONMENT)eventhintr<  	exc_valuer<   r   r   r   before_send  s    
zset_sentry.<locals>.before_sendz_https://888e5a0778212e1d0314c37d4b9aae5d@o4504521589325824.ingest.us.sentry.io/4504521592406016Fg      ?
production)ZdsndebugZauto_enabling_integrationsZtraces_sample_ratereleaseenvironmentr^  ignore_errorsiduuid)SETTINGSr   r   r   rT   TESTS_RUNNINGONLINErY  r  r   ImportErrorinitr   rX  r   Zset_user)r   r^  r   r   r   
set_sentry  s<    

rk  c                       s   e Zd ZdZdeeef d fddZdd Zdd	 Z	e
d
d Z fddZ fddZdd Z fddZ fddZ  ZS )JSONDictak  
    A dictionary-like class that provides JSON persistence for its contents.

    This class extends the built-in dictionary to automatically save its contents to a JSON file whenever they are
    modified. It ensures thread-safe operations using a lock.

    Attributes:
        file_path (Path): The path to the JSON file used for persistence.
        lock (threading.Lock): A lock object to ensure thread-safe operations.

    Methods:
        _load: Loads the data from the JSON file into the dictionary.
        _save: Saves the current state of the dictionary to the JSON file.
        __setitem__: Stores a key-value pair and persists it to disk.
        __delitem__: Removes an item and updates the persistent storage.
        update: Updates the dictionary and persists changes.
        clear: Clears all entries and updates the persistent storage.

    Examples:
        >>> json_dict = JSONDict("data.json")
        >>> json_dict["key"] = "value"
        >>> print(json_dict["key"])
        value
        >>> del json_dict["key"]
        >>> json_dict.update({"new_key": "new_value"})
        >>> json_dict.clear()
    	data.json)	file_pathc                    s(   t    t|| _t | _|   dS )zMInitialize a JSONDict object with a specified file path for JSON persistence.N)r-   r.   r   rn  r   r   _load)r0   rn  r3   r   r   r.   0  s    

zJSONDict.__init__c              
   C   s   zH| j  rFt| j  }| t| W d   n1 s<0    Y  W n^ tjyn   td| j  d Y n: ty } z"td| j  d|  W Y d}~n
d}~0 0 dS )z5Load the data from the JSON file into the dictionary.NzError decoding JSON from z$. Starting with an empty dictionary.zError reading from r=   )	rn  r   r   updatejsonloadJSONDecodeErrorr   r   r0   r   r   r   r   r   ro  7  s    
2zJSONDict._loadc              
   C   s   zZ| j jjddd t| j d(}tjt| |d| jd W d   n1 sN0    Y  W n: ty } z"t	d| j  d|  W Y d}~n
d}~0 0 dS )	z:Save the current state of the dictionary to the JSON file.Tr   r   rB  )indentr    NzError writing to r=   )
rn  r   r   r   rq  r   r   _json_defaultr   r   rt  r   r   r   _saveB  s    :zJSONDict._savec                 C   s,   t | trt| S tdt| j ddS )z*Handle JSON serialization of Path objects.zObject of type z is not JSON serializableN)rD   r   r   	TypeErrorr   r5   )objr   r   r   rv  K  s    
zJSONDict._json_defaultc                    s@   | j & t || |   W d   n1 s20    Y  dS )z+Store a key-value pair and persist to disk.N)r   r-   __setitem__rw  )r0   r_   r=  r3   r   r   rz  R  s    zJSONDict.__setitem__c                    s>   | j $ t | |   W d   n1 s00    Y  dS )z1Remove an item and update the persistent storage.N)r   r-   __delitem__rw  )r0   r_   r3   r   r   r{  X  s    zJSONDict.__delitem__c              	   C   s&   d| j  dtjt| dd| jd S )zEReturn a pretty-printed JSON string representation of the dictionary.z
JSONDict("z"):
rB  F)ru  ensure_asciir    )rn  rq  dumpsr   rv  rM   r   r   r   rL   ^  s    zJSONDict.__str__c                    sD   | j * t j|i | |   W d   n1 s60    Y  dS )z*Update the dictionary and persist changes.N)r   r-   rp  rw  r/   r3   r   r   rp  b  s    zJSONDict.updatec                    s<   | j " t   |   W d   n1 s.0    Y  dS )z4Clear all entries and update the persistent storage.N)r   r-   clearrw  rM   r3   r   r   r~  h  s    
zJSONDict.clear)rm  )r5   r6   r7   r8   r   r   r   r.   ro  rw  staticmethodrv  rz  r{  rL   rp  r~  r9   r   r   r3   r   rl    s   	
rl  c                       sB   e Zd ZdZedf fdd	Zdd Z fddZd	d
 Z  Z	S )SettingsManagera  
    SettingsManager class for managing and persisting Ultralytics settings.

    This class extends JSONDict to provide JSON persistence for settings, ensuring thread-safe operations and default
    values. It validates settings on initialization and provides methods to update or reset settings.

    Attributes:
        file (Path): The path to the JSON file used for persistence.
        version (str): The version of the settings schema.
        defaults (Dict): A dictionary containing default settings.
        help_msg (str): A help message for users on how to view and update settings.

    Methods:
        _validate_settings: Validates the current settings and resets if necessary.
        update: Updates settings, validating keys and types.
        reset: Resets the settings to default and saves them.

    Examples:
        Initialize and update settings:
        >>> settings = SettingsManager()
        >>> settings.update(runs_dir="/new/runs/dir")
        >>> print(settings["runs_dir"])
        /new/runs/dir
    z0.0.6c                    s&  ddl }ddlm} tpt }tr2t|jr2|jn| }t|| _|| _	|t
|d t
|d t
|d |t
t   dddddddddddddd	| _d
| j d| _|tT t | j | j r| std| d| j  |   |   W d   n1 s0    Y  dS )zNInitializes the SettingsManager with default settings and loads user settings.r   N)torch_distributed_zero_firstZdatasetsweightsrunsTr   )settings_versiondatasets_dirweights_dirruns_dirre  rR  Zapi_keyZopenai_api_keyZclearmlcometZdvcZhubZmlflowZneptuneZraytuneZtensorboardZwandb
vscode_msgz7
View Ultralytics Settings with 'yolo settings' or at 'z'
Update Settings with 'yolo settings key=value', i.e. 'yolo settings runs_dir=path/to/dir'. For help see https://docs.ultralytics.com/quickstart/#ultralytics-settings.z#Creating new Ultralytics Settings vu
    file ✅ )hashlibZultralytics.utils.torch_utilsr  r  r   r   r   resolver   versionr   sha256re  getnoder   	hexdigestdefaultshelp_msgr   r-   r.   r   r   r   reset_validate_settings)r0   r   r  r  r  rootZdatasets_rootr3   r   r   r.     sB    





zSettingsManager.__init__c                    s   t   t  j k}t fdd j D } dd jk}|rT|rT|sntd j	   
   d dkrtd d d	 d d
 j	  dS )z5Validate the current settings and reset if necessary.c                 3   s&   | ]\}}t  |t|V  qd S r   )rD   r*   r   r\   rM   r   r   r     r   z5SettingsManager._validate_settings.<locals>.<genexpr>r  r   u   WARNING ⚠️ Ultralytics settings reset to default values. This may be due to a possible problem with your settings or a recent ultralytics package update. r  r  u2   WARNING ⚠️ Ultralytics setting 'datasets_dir: z$' must be different than 'runs_dir: z?'. Please change one to avoid possible issues during training. N)setkeysr  rb   rY   r*   r  r   r  r  r  )r0   Zcorrect_keysZcorrect_typesZcorrect_versionr   rM   r   r    s$    z"SettingsManager._validate_settingsc              
      s   |  D ]f\}}|| jvr0td| d| j t| j| }t||std| d| dt| d| j qt j|i | dS )z,Updates settings, validating keys and types.zNo Ultralytics setting 'z'. zUltralytics setting 'z' must be of type 'z', not 'N)	rY   r  KeyErrorr  r   rD   rx  r-   rp  )r0   r1   r2   r]   rJ   tr3   r   r   rp    s    

(zSettingsManager.updatec                 C   s   |    | | j dS )z.Resets the settings to default and saves them.N)r~  rp  r  rM   r   r   r   r    s    zSettingsManager.reset)
r5   r6   r7   r8   SETTINGS_FILEr.   r  rp  r  r9   r   r   r3   r   r  o  s
   /
r  c                 C   s   t d|  d| d dS )z_Issue a deprecation warning when a deprecated argument is used, suggesting an updated argument.u   WARNING ⚠️ 'z;' is deprecated and will be removed in in the future. Use 'z
' instead.N)r   r  )argZnew_argr   r   r   deprecation_warn  s    r  c                 C   s*   t |  dd} tj| dd S )zTStrip auth from URL, i.e. https://url.com/file.txt?auth -> https://url.com/file.txt.z:/z://?r   )r   as_posixreplaceurllibparseunquotespliturlr   r   r   	clean_url  s    r  c                 C   s   t t| jS )zHConvert URL to filename, i.e. https://url.com/file.txt?auth -> file.txt.)r   r  rT   r  r   r   r   url2file  s    r   ultralytics.ultralytics-snippetsc                 C   sp   t rtjd ntjd d }|d }t||  doP| | rL|dndv}d}|r^dS td	 d
| S )zWDisplay a message to install Ultralytics-Snippets for VS Code if not already installed.rB  r   z.vscode/extensionsz	.obsolete*ru   r   z0https://docs.ultralytics.com/integrations/vscodezVS Code:u+    view Ultralytics VS Code Extension ⚡ at )r   USER_CONFIG_DIRr   anyglobr   	read_textr   )extr   Zobs_file	installedr  r   r   r   r    s
    .r  zUltralytics: zpersistent_cache.jsonr  r  r  ZColabZKaggleZJupyterDocker)imreadimshowimwrite
torch_load
torch_save)Nr`   )rr   T)r   )r   Nr   )r   F)r  )r  )r   importlib.metadatar   r  rq  logging.configr|   r   r   r   r  r   r   rG  r  re  pathlibr   r   typesr   typingr   Zcv2Zmatplotlib.pyplotZpyplotrc   numpynpZtorchr   r   Ztqdm_originalr   r   r   r   r   r
   argvr   r   r  FILEr   ROOTZASSETSr^   minmax	cpu_countZNUM_THREADSr   re   ZAUTOINSTALLr)   r,   rr   r  r  r   machineZARM64python_versionPYTHON_VERSIONZTORCH_VERSIONmetadatar  ZTORCHVISION_VERSIONr   r*   Z	IS_VSCODEZHELP_MSGZset_printoptionsrw   ZsetNumThreadsr'   r:   rV   rq   r   r   r   r   r   CRITICALrv   r   r   r   r   r   ZDEFAULT_CFG_DICTrY   r]   rJ   rD   r  ZDEFAULT_CFG_KEYSZDEFAULT_CFGr   r   r   r   r   r   r   r   r   r   r5   r   r   r   r   r   r  r  r  r  r  r!  r   rh  ZIS_COLABZ	IS_DOCKERZ	IS_JETSONZ
IS_JUPYTERZ	IS_KAGGLErY  ZIS_RASPBERRYPIr  r  r  r  r   r8  ContextDecoratorr9  r@  rK  rk  rl  r  r  r  r  r  PREFIXrf  ZPERSISTENT_CACHEZDATASETS_DIRZWEIGHTS_DIRZRUNS_DIRr   rZ  rg  Zultralytics.utils.patchesr  r  r  r  r  rr  saver   r   r   r   <module>   s  
:




06<
-
?
$
 






"5!(H\m