diff --git a/setup.py b/setup.py index ce6673f..f315180 100644 --- a/setup.py +++ b/setup.py @@ -39,6 +39,7 @@ setup( install_requires=REQUIREMENTS, extras_require={ 'dev': [ + 'ipython', 'check-manifest', 'pytest', 'pytest-cov', diff --git a/ultralytics/cfg/__init__.py b/ultralytics/cfg/__init__.py index 67f8fb8..eac8174 100644 --- a/ultralytics/cfg/__init__.py +++ b/ultralytics/cfg/__init__.py @@ -252,17 +252,22 @@ def handle_yolo_settings(args: List[str]) -> None: python my_script.py yolo settings reset ``` """ - if any(args): - if args[0] == 'reset': - SETTINGS_YAML.unlink() # delete the settings file - SETTINGS.reset() # create new settings - LOGGER.info('Settings reset successfully') # inform the user that settings have been reset - else: # save a new setting - new = dict(parse_key_value_pair(a) for a in args) - check_dict_alignment(SETTINGS, new) - SETTINGS.update(new) - - yaml_print(SETTINGS_YAML) # print the current settings + url = 'https://docs.ultralytics.com/quickstart/#ultralytics-settings' # help URL + try: + if any(args): + if args[0] == 'reset': + SETTINGS_YAML.unlink() # delete the settings file + SETTINGS.reset() # create new settings + LOGGER.info('Settings reset successfully') # inform the user that settings have been reset + else: # save a new setting + new = dict(parse_key_value_pair(a) for a in args) + check_dict_alignment(SETTINGS, new) + SETTINGS.update(new) + + LOGGER.info(f'💡 Learn about settings at {url}') + yaml_print(SETTINGS_YAML) # print the current settings + except Exception as e: + LOGGER.warning(f"WARNING ⚠️ settings error: '{e}'. Please see {url} for help.") def parse_key_value_pair(pair): diff --git a/ultralytics/utils/callbacks/mlflow.py b/ultralytics/utils/callbacks/mlflow.py index 70ddb73..b3256d6 100644 --- a/ultralytics/utils/callbacks/mlflow.py +++ b/ultralytics/utils/callbacks/mlflow.py @@ -18,7 +18,7 @@ except (ImportError, AssertionError): def on_pretrain_routine_end(trainer): """Logs training parameters to MLflow.""" - global mlflow, run, run_id, experiment_name + global mlflow, run, experiment_name if os.environ.get('MLFLOW_TRACKING_URI') is None: mlflow = None @@ -39,8 +39,7 @@ def on_pretrain_routine_end(trainer): run, active_run = mlflow, mlflow.active_run() if not active_run: active_run = mlflow.start_run(experiment_id=experiment.experiment_id, run_name=run_name) - run_id = active_run.info.run_id - LOGGER.info(f'{prefix}Using run_id({run_id}) at {mlflow_location}') + LOGGER.info(f'{prefix}Using run_id({active_run.info.run_id}) at {mlflow_location}') run.log_params(vars(trainer.model.args)) except Exception as err: LOGGER.error(f'{prefix}Failing init - {repr(err)}') diff --git a/ultralytics/utils/checks.py b/ultralytics/utils/checks.py index d095b60..6b96e57 100644 --- a/ultralytics/utils/checks.py +++ b/ultralytics/utils/checks.py @@ -90,55 +90,61 @@ def check_imgsz(imgsz, stride=32, min_dim=1, max_dim=2, floor=0): def check_version(current: str = '0.0.0', - minimum: str = '0.0.0', - maximum: str = None, + required: str = '0.0.0', name: str = 'version ', - pinned: bool = False, hard: bool = False, verbose: bool = False) -> bool: """ - Check current version against the required minimum and/or maximum version. + Check current version against the required version or range. Args: current (str): Current version. - minimum (str): Required minimum version. - maximum (str, optional): Required maximum version. + required (str): Required version or range (in pip-style format). name (str): Name to be used in warning message. - pinned (bool): If True, versions must match exactly. If False, minimum version must be satisfied. - hard (bool): If True, raise an AssertionError if the minimum or maximum version is not met. - verbose (bool): If True, print warning message if minimum or maximum version is not met. + hard (bool): If True, raise an AssertionError if the requirement is not met. + verbose (bool): If True, print warning message if requirement is not met. Returns: - (bool): True if minimum and maximum versions are met, False otherwise. + (bool): True if requirement is met, False otherwise. Example: - ```python - # Check if current version is exactly 22.04 - check_version(current='22.04', minimum='22.04', pinned=True) + # check if current version is exactly 22.04 + check_version(current='22.04', required='==22.04') - # Check if current version is greater than or equal to 22.04 - check_version(current='22.10', minimum='22.04') + # check if current version is greater than or equal to 22.04 + check_version(current='22.10', required='22.04') # assumes '>=' inequality if none passed - # Check if current version is less than or equal to 22.04 - check_version(current='22.04', maximum='22.04') + # check if current version is less than or equal to 22.04 + check_version(current='22.04', required='<=22.04') - # Check if current version is between 20.04 (inclusive) and 22.04 (exclusive) - check_version(current='21.10', minimum='20.04', maximum='22.04') - ``` + # check if current version is between 20.04 (inclusive) and 22.04 (exclusive) + check_version(current='21.10', required='>20.04,<22.04') """ current = pkg.parse_version(current) - minimum = pkg.parse_version(minimum) - maximum = pkg.parse_version(maximum) if maximum else None - if pinned: - result = (current == minimum) - else: - result = (current >= minimum) and (current <= maximum if maximum else True) - version_message = f'a version between {minimum} and {maximum}' if maximum else f'a minimum version {minimum}' - warning_message = f'WARNING ⚠️ {name} requires {version_message}, but {name}{current} is currently installed.' - if hard: - assert result, emojis(warning_message) # assert version requirements met - if verbose and not result: - LOGGER.warning(warning_message) + constraints = re.findall(r'([<>!=]{1,2}\s*\d+\.\d+)', required) or [f'>={required}'] + + result = True + for constraint in constraints: + op, version = re.match(r'([<>!=]{1,2})\s*(\d+\.\d+)', constraint).groups() + version = pkg.parse_version(version) + if op == '==' and current != version: + result = False + elif op == '!=' and current == version: + result = False + elif op == '>=' and not (current >= version): + result = False + elif op == '<=' and not (current <= version): + result = False + elif op == '>' and not (current > version): + result = False + elif op == '<' and not (current < version): + result = False + if not result: + warning_message = f'WARNING ⚠️ {name}{required} is required, but {name}{current} is currently installed' + if hard: + raise ModuleNotFoundError(emojis(warning_message)) # assert version requirements met + if verbose: + LOGGER.warning(warning_message) return result