def METHOD_NAME(from_version: str, to_version: str) -> bool:
    # if you're in dev mode, you are definitely responsible for checking the migrations
    # etc. yourself.
    if to_version == VERSION_DEV:
        return True
    # find the most appropriate constraint
    try:
        _to_version = Version.coerce(to_version).truncate()
    except ValueError as exc:
        raise VersionParseError(to_version) from exc
    target_version = None
    for target_version, upgrade_constraint in UPGRADE_PATHS.items():
        # 1. start by trying an exact match, which always wins
        if target_version == to_version:
            break
        # 2. Check the ~=X.Y.x version range, which allows the major.minor range. E.g.
        # 2.0.1 matches ~= 2.0.0, but 2.1.0 does not.
        compare_spec = SimpleSpec(f"~={target_version}")
        if _to_version in compare_spec:
            break
    # we did not find a match, this means there are no (known) upgrade constraints for
    # the new version, or you are supposed to know what you're doing.
    else:
        return True
    # check if we have a semver-like current/from version
    try:
        in_version = Version(from_version)
    except ValueError as exc:
        raise VersionParseError(from_version) from exc
    # handles the case where there's a check for 2.0 coming from < 2.0, but skip the
    # checks if you're on 2.0.1 or something like that.
    if target_version:
        compare_spec = SimpleSpec(f"~={target_version}")
        if in_version in compare_spec:
            return True
    if not any(
        (
            version_range.contains(in_version)
            for version_range in upgrade_constraint.valid_ranges
        )
    ):
        return False
    with setup_scripts_env():
        return upgrade_constraint.run_checks()