# Path: detectron/utils/collections.py
# class AttrDict(dict):
# 
#     IMMUTABLE = '__immutable__'
# 
#     def __init__(self, *args, **kwargs):
#         super(AttrDict, self).__init__(*args, **kwargs)
#         self.__dict__[AttrDict.IMMUTABLE] = False
# 
#     def __getattr__(self, name):
#         if name in self.__dict__:
#             return self.__dict__[name]
#         elif name in self:
#             return self[name]
#         else:
#             raise AttributeError(name)
# 
#     def __setattr__(self, name, value):
#         if not self.__dict__[AttrDict.IMMUTABLE]:
#             if name in self.__dict__:
#                 self.__dict__[name] = value
#             else:
#                 self[name] = value
#         else:
#             raise AttributeError(
#                 'Attempted to set "{}" to "{}", but AttrDict is immutable'.
#                 format(name, value)
#             )
# 
#     def immutable(self, is_immutable):
#         """Set immutability to is_immutable and recursively apply the setting
#         to all nested AttrDicts.
#         """
#         self.__dict__[AttrDict.IMMUTABLE] = is_immutable
#         # Recursively set immutable state
#         for v in self.__dict__.values():
#             if isinstance(v, AttrDict):
#                 v.immutable(is_immutable)
#         for v in self.values():
#             if isinstance(v, AttrDict):
#                 v.immutable(is_immutable)
# 
#     def is_immutable(self):
#         return self.__dict__[AttrDict.IMMUTABLE]
# 
# Path: detectron/utils/io.py
# def cache_url(url_or_file, cache_dir):
#     """Download the file specified by the URL to the cache_dir and return the
#     path to the cached file. If the argument is not a URL, simply return it as
#     is.
#     """
#     is_url = re.match(
#         r'^(?:http)s?://', url_or_file, re.IGNORECASE
#     ) is not None
# 
#     if not is_url:
#         return url_or_file
# 
#     url = url_or_file
#     assert url.startswith(_DETECTRON_S3_BASE_URL), \
#         ('Detectron only automatically caches URLs in the Detectron S3 '
#          'bucket: {}').format(_DETECTRON_S3_BASE_URL)
# 
#     cache_file_path = url.replace(_DETECTRON_S3_BASE_URL, cache_dir)
#     if os.path.exists(cache_file_path):
#         assert_cache_file_is_ok(url, cache_file_path)
#         return cache_file_path
# 
#     cache_file_dir = os.path.dirname(cache_file_path)
#     if not os.path.exists(cache_file_dir):
#         os.makedirs(cache_file_dir)
# 
#     logger.info('Downloading remote file {} to {}'.format(url, cache_file_path))
#     download_url(url, cache_file_path)
#     assert_cache_file_is_ok(url, cache_file_path)
#     return cache_file_path


from ast import literal_eval
from future.utils import iteritems
from detectron.utils.collections import AttrDict
from detectron.utils.io import cache_url
import copy
import io
import logging
import numpy as np
import os
import os.path as osp
import six
    import detectron.utils.env as envu
# is renamed/moved and you don't want to break loading of existing yaml configs
# (e.g. from weights files) you can specify the renamed module below.
# ---------------------------------------------------------------------------- #
_RENAMED_MODULES = {
    'utils.collections': 'detectron.utils.collections',
}


def assert_and_infer_cfg(cache_urls=True, make_immutable=True):
    """Call this function in your script after you have finished setting all cfg
    values that are necessary (e.g., merging a config from a file, merging
    command line config options, etc.). By default, this function will also
    mark the global cfg as immutable to prevent changing the global cfg settings
    during script execution (which can lead to hard to debug errors or code
    that's harder to understand than is necessary).
    """
    if __C.MODEL.RPN_ONLY or __C.MODEL.FASTER_RCNN:
        __C.RPN.RPN_ON = True
    if __C.RPN.RPN_ON or __C.RETINANET.RETINANET_ON:
        __C.TEST.PRECOMPUTED_PROPOSALS = False
    if cache_urls:
        cache_cfg_urls()
    if make_immutable:
        cfg.immutable(True)


def cache_cfg_urls():
    """Download URLs in the config, cache them locally, and rewrite cfg to make
    use of the locally cached file.
    """

# Path: detectron/utils/collections.py
# class AttrDict(dict):
# 
#     IMMUTABLE = '__immutable__'
# 
#     def __init__(self, *args, **kwargs):
#         super(AttrDict, self).__init__(*args, **kwargs)
#         self.__dict__[AttrDict.IMMUTABLE] = False
# 
#     def __getattr__(self, name):
#         if name in self.__dict__:
#             return self.__dict__[name]
#         elif name in self:
#             return self[name]
#         else:
#             raise AttributeError(name)
# 
#     def __setattr__(self, name, value):
#         if not self.__dict__[AttrDict.IMMUTABLE]:
#             if name in self.__dict__:
#                 self.__dict__[name] = value
#             else:
#                 self[name] = value
#         else:
#             raise AttributeError(
#                 'Attempted to set "{}" to "{}", but AttrDict is immutable'.
#                 format(name, value)
#             )
# 
#     def immutable(self, is_immutable):
#         """Set immutability to is_immutable and recursively apply the setting
#         to all nested AttrDicts.
#         """
#         self.__dict__[AttrDict.IMMUTABLE] = is_immutable
#         # Recursively set immutable state
#         for v in self.__dict__.values():
#             if isinstance(v, AttrDict):
#                 v.immutable(is_immutable)
#         for v in self.values():
#             if isinstance(v, AttrDict):
#                 v.immutable(is_immutable)
# 
#     def is_immutable(self):
#         return self.__dict__[AttrDict.IMMUTABLE]
# 
# Path: detectron/utils/io.py
# def cache_url(url_or_file, cache_dir):
#     """Download the file specified by the URL to the cache_dir and return the
#     path to the cached file. If the argument is not a URL, simply return it as
#     is.
#     """
#     is_url = re.match(
#         r'^(?:http)s?://', url_or_file, re.IGNORECASE
#     ) is not None
# 
#     if not is_url:
#         return url_or_file
# 
#     url = url_or_file
#     assert url.startswith(_DETECTRON_S3_BASE_URL), \
#         ('Detectron only automatically caches URLs in the Detectron S3 '
#          'bucket: {}').format(_DETECTRON_S3_BASE_URL)
# 
#     cache_file_path = url.replace(_DETECTRON_S3_BASE_URL, cache_dir)
#     if os.path.exists(cache_file_path):
#         assert_cache_file_is_ok(url, cache_file_path)
#         return cache_file_path
# 
#     cache_file_dir = os.path.dirname(cache_file_path)
#     if not os.path.exists(cache_file_dir):
#         os.makedirs(cache_file_dir)
# 
#     logger.info('Downloading remote file {} to {}'.format(url, cache_file_path))
#     download_url(url, cache_file_path)
#     assert_cache_file_is_ok(url, cache_file_path)
#     return cache_file_path


# Path: detectron/core/config.py
from ast import literal_eval
from future.utils import iteritems
from detectron.utils.collections import AttrDict
from detectron.utils.io import cache_url
import copy
import io
import logging
import numpy as np
import os
import os.path as osp
import six
    import detectron.utils.env as envu

# is renamed/moved and you don't want to break loading of existing yaml configs
# (e.g. from weights files) you can specify the renamed module below.
# ---------------------------------------------------------------------------- #
_RENAMED_MODULES = {
    'utils.collections': 'detectron.utils.collections',
}


def assert_and_infer_cfg(cache_urls=True, make_immutable=True):
    """Call this function in your script after you have finished setting all cfg
    values that are necessary (e.g., merging a config from a file, merging
    command line config options, etc.). By default, this function will also
    mark the global cfg as immutable to prevent changing the global cfg settings
    during script execution (which can lead to hard to debug errors or code
    that's harder to understand than is necessary).
    """
    if __C.MODEL.RPN_ONLY or __C.MODEL.FASTER_RCNN:
        __C.RPN.RPN_ON = True
    if __C.RPN.RPN_ON or __C.RETINANET.RETINANET_ON:
        __C.TEST.PRECOMPUTED_PROPOSALS = False
    if cache_urls:
        cache_cfg_urls()
    if make_immutable:
        cfg.immutable(True)


def cache_cfg_urls():
    """Download URLs in the config, cache them locally, and rewrite cfg to make
    use of the locally cached file.
    """

    __C.TRAIN.WEIGHTS = cache_url(__C.TRAIN.WEIGHTS, __C.DOWNLOAD_CACHE)