"""simple docstring"""







import gc
import random
import tempfile
import unittest

import numpy as np
import torch
from transformers import CLIPTextConfig, CLIPTextModel, CLIPTokenizer

from diffusers import AutoencoderKL, DDIMScheduler, LMSDiscreteScheduler, PNDMScheduler, UNetaDConditionModel
from diffusers.pipelines.semantic_stable_diffusion import SemanticStableDiffusionPipeline as StableDiffusionPipeline
from diffusers.utils import floats_tensor, nightly, torch_device
from diffusers.utils.testing_utils import enable_full_determinism, require_torch_gpu


enable_full_determinism()


class      _lowercase						(				unittest.TestCase					):

				def     A	(       self    :      Tuple       ):


										'''simple docstring'''
										# clean up the VRAM after each test
										super().tearDown()
										gc.collect()
										torch.cuda.empty_cache()

				@property
				def     A	(       self    :      Tuple       ):


										'''simple docstring'''
										UpperCAmelCase__   		=						1
										UpperCAmelCase__   		=						3
										UpperCAmelCase__   		=						(3_2, 3_2)

										UpperCAmelCase__   		=						floats_tensor((batch_size, num_channels) + sizes    ,      rng=random.Random(0       )       ).to(_lowercase       )
										return image

				@property
				def     A	(       self    :      Optional[int]       ):


										'''simple docstring'''
										torch.manual_seed(0       )
										UpperCAmelCase__   		=						UNetaDConditionModel(
										    block_out_channels=(3_2, 6_4)    ,      layers_per_block=2    ,      sample_size=3_2    ,      in_channels=4    ,      out_channels=4    ,      down_block_types=("""DownBlock2D""", """CrossAttnDownBlock2D""")    ,      up_block_types=("""CrossAttnUpBlock2D""", """UpBlock2D""")    ,      cross_attention_dim=3_2    ,      )
										return model

				@property
				def     A	(       self    :      Dict       ):


										'''simple docstring'''
										torch.manual_seed(0       )
										UpperCAmelCase__   		=						AutoencoderKL(
										    block_out_channels=[3_2, 6_4]    ,      in_channels=3    ,      out_channels=3    ,      down_block_types=["""DownEncoderBlock2D""", """DownEncoderBlock2D"""]    ,      up_block_types=["""UpDecoderBlock2D""", """UpDecoderBlock2D"""]    ,      latent_channels=4    ,      )
										return model

				@property
				def     A	(       self    :      Optional[int]       ):


										'''simple docstring'''
										torch.manual_seed(0       )
										UpperCAmelCase__   		=						CLIPTextConfig(
										    bos_token_id=0    ,      eos_token_id=2    ,      hidden_size=3_2    ,      intermediate_size=3_7    ,      layer_norm_eps=1e-05    ,      num_attention_heads=4    ,      num_hidden_layers=5    ,      pad_token_id=1    ,      vocab_size=1_0_0_0    ,      )
										return CLIPTextModel(_lowercase       )

				@property
				def     A	(       self    :      str       ):


										'''simple docstring'''
										def extract(*_lowercase    :      Optional[int]    ,      **_lowercase    :      int       ):


																class      _lowercase						:

																				def __init__(       self    :      Optional[Any]       ):


																										'''simple docstring'''
																										UpperCAmelCase__   		=						torch.ones([0]       )

																				def     A	(       self    :      int    ,      _lowercase    :      Dict       ):


																										'''simple docstring'''
																										self.pixel_values.to(_lowercase       )
																										return self
																return Out()

										return extract

				def     A	(       self    :      List[Any]       ):


										'''simple docstring'''
										UpperCAmelCase__   		=						"""cpu"""  # ensure determinism for the device-dependent torch.Generator
										UpperCAmelCase__   		=						self.dummy_cond_unet
										UpperCAmelCase__   		=						DDIMScheduler(
										    beta_start=0.0_0085    ,      beta_end=0.012    ,      beta_schedule="""scaled_linear"""    ,      clip_sample=_lowercase    ,      set_alpha_to_one=_lowercase    ,      )

										UpperCAmelCase__   		=						self.dummy_vae
										UpperCAmelCase__   		=						self.dummy_text_encoder
										UpperCAmelCase__   		=						CLIPTokenizer.from_pretrained("""hf-internal-testing/tiny-random-clip"""       )

										# make sure here that pndm scheduler skips prk
										UpperCAmelCase__   		=						StableDiffusionPipeline(
										    unet=_lowercase    ,      scheduler=_lowercase    ,      vae=_lowercase    ,      text_encoder=_lowercase    ,      tokenizer=_lowercase    ,      safety_checker=_lowercase    ,      feature_extractor=self.dummy_extractor    ,      )
										UpperCAmelCase__   		=						sd_pipe.to(_lowercase       )
										sd_pipe.set_progress_bar_config(disable=_lowercase       )

										UpperCAmelCase__   		=						"""A painting of a squirrel eating a burger"""

										UpperCAmelCase__   		=						torch.Generator(device=_lowercase       ).manual_seed(0       )
										UpperCAmelCase__   		=						sd_pipe([prompt]    ,      generator=_lowercase    ,      guidance_scale=6.0    ,      num_inference_steps=2    ,      output_type="""np"""       )
										UpperCAmelCase__   		=						output.images

										UpperCAmelCase__   		=						torch.Generator(device=_lowercase       ).manual_seed(0       )
										UpperCAmelCase__   		=						sd_pipe(
										    [prompt]    ,      generator=_lowercase    ,      guidance_scale=6.0    ,      num_inference_steps=2    ,      output_type="""np"""    ,      return_dict=_lowercase    ,      )[0]

										UpperCAmelCase__   		=						image[0, -3:, -3:, -1]
										UpperCAmelCase__   		=						image_from_tuple[0, -3:, -3:, -1]

										assert image.shape == (1, 6_4, 6_4, 3)
										UpperCAmelCase__   		=						np.array([0.5753, 0.6114, 0.5001, 0.5034, 0.5470, 0.4729, 0.4971, 0.4867, 0.4867]       )

										assert np.abs(image_slice.flatten() - expected_slice       ).max() < 1e-2
										assert np.abs(image_from_tuple_slice.flatten() - expected_slice       ).max() < 1e-2

				def     A	(       self    :      Dict       ):


										'''simple docstring'''
										UpperCAmelCase__   		=						"""cpu"""  # ensure determinism for the device-dependent torch.Generator
										UpperCAmelCase__   		=						self.dummy_cond_unet
										UpperCAmelCase__   		=						PNDMScheduler(skip_prk_steps=_lowercase       )
										UpperCAmelCase__   		=						self.dummy_vae
										UpperCAmelCase__   		=						self.dummy_text_encoder
										UpperCAmelCase__   		=						CLIPTokenizer.from_pretrained("""hf-internal-testing/tiny-random-clip"""       )

										# make sure here that pndm scheduler skips prk
										UpperCAmelCase__   		=						StableDiffusionPipeline(
										    unet=_lowercase    ,      scheduler=_lowercase    ,      vae=_lowercase    ,      text_encoder=_lowercase    ,      tokenizer=_lowercase    ,      safety_checker=_lowercase    ,      feature_extractor=self.dummy_extractor    ,      )
										UpperCAmelCase__   		=						sd_pipe.to(_lowercase       )
										sd_pipe.set_progress_bar_config(disable=_lowercase       )

										UpperCAmelCase__   		=						"""A painting of a squirrel eating a burger"""
										UpperCAmelCase__   		=						torch.Generator(device=_lowercase       ).manual_seed(0       )
										UpperCAmelCase__   		=						sd_pipe([prompt]    ,      generator=_lowercase    ,      guidance_scale=6.0    ,      num_inference_steps=2    ,      output_type="""np"""       )

										UpperCAmelCase__   		=						output.images

										UpperCAmelCase__   		=						torch.Generator(device=_lowercase       ).manual_seed(0       )
										UpperCAmelCase__   		=						sd_pipe(
										    [prompt]    ,      generator=_lowercase    ,      guidance_scale=6.0    ,      num_inference_steps=2    ,      output_type="""np"""    ,      return_dict=_lowercase    ,      )[0]

										UpperCAmelCase__   		=						image[0, -3:, -3:, -1]
										UpperCAmelCase__   		=						image_from_tuple[0, -3:, -3:, -1]

										assert image.shape == (1, 6_4, 6_4, 3)
										UpperCAmelCase__   		=						np.array([0.5122, 0.5712, 0.4825, 0.5053, 0.5646, 0.4769, 0.5179, 0.4894, 0.4994]       )

										assert np.abs(image_slice.flatten() - expected_slice       ).max() < 1e-2
										assert np.abs(image_from_tuple_slice.flatten() - expected_slice       ).max() < 1e-2

				def     A	(       self    :      List[str]       ):


										'''simple docstring'''
										UpperCAmelCase__   		=						StableDiffusionPipeline.from_pretrained(
										    """hf-internal-testing/tiny-stable-diffusion-lms-pipe"""    ,      safety_checker=_lowercase       )
										assert isinstance(_lowercase    ,      _lowercase       )
										assert isinstance(pipe.scheduler    ,      _lowercase       )
										assert pipe.safety_checker is None

										UpperCAmelCase__   		=						pipe("""example prompt"""    ,      num_inference_steps=2       ).images[0]
										assert image is not None

										# check that there's no error when saving a pipeline with one of the models being None
										with tempfile.TemporaryDirectory() as tmpdirname:
																pipe.save_pretrained(_lowercase       )
																UpperCAmelCase__   		=						StableDiffusionPipeline.from_pretrained(_lowercase       )

										# sanity check that the pipeline still works
										assert pipe.safety_checker is None
										UpperCAmelCase__   		=						pipe("""example prompt"""    ,      num_inference_steps=2       ).images[0]
										assert image is not None

				@unittest.skipIf(torch_device != """cuda"""    ,      """This test requires a GPU"""       )
				def     A	(       self    :      int       ):


										'''simple docstring'''
										UpperCAmelCase__   		=						self.dummy_cond_unet
										UpperCAmelCase__   		=						PNDMScheduler(skip_prk_steps=_lowercase       )
										UpperCAmelCase__   		=						self.dummy_vae
										UpperCAmelCase__   		=						self.dummy_text_encoder
										UpperCAmelCase__   		=						CLIPTokenizer.from_pretrained("""hf-internal-testing/tiny-random-clip"""       )

										# put models in fp16
										UpperCAmelCase__   		=						unet.half()
										UpperCAmelCase__   		=						vae.half()
										UpperCAmelCase__   		=						bert.half()

										# make sure here that pndm scheduler skips prk
										UpperCAmelCase__   		=						StableDiffusionPipeline(
										    unet=_lowercase    ,      scheduler=_lowercase    ,      vae=_lowercase    ,      text_encoder=_lowercase    ,      tokenizer=_lowercase    ,      safety_checker=_lowercase    ,      feature_extractor=self.dummy_extractor    ,      )
										UpperCAmelCase__   		=						sd_pipe.to(_lowercase       )
										sd_pipe.set_progress_bar_config(disable=_lowercase       )

										UpperCAmelCase__   		=						"""A painting of a squirrel eating a burger"""
										UpperCAmelCase__   		=						sd_pipe([prompt]    ,      num_inference_steps=2    ,      output_type="""np"""       ).images

										assert image.shape == (1, 6_4, 6_4, 3)


@nightly
@require_torch_gpu
class      _lowercase						(				unittest.TestCase					):

				def     A	(       self    :      Optional[Any]       ):


										'''simple docstring'''
										# clean up the VRAM after each test
										super().tearDown()
										gc.collect()
										torch.cuda.empty_cache()

				def     A	(       self    :      Tuple       ):


										'''simple docstring'''
										UpperCAmelCase__   		=						"""cuda"""
										UpperCAmelCase__   		=						StableDiffusionPipeline.from_pretrained("""runwayml/stable-diffusion-v1-5"""       )
										UpperCAmelCase__   		=						pipe.to(_lowercase       )
										pipe.set_progress_bar_config(disable=_lowercase       )

										UpperCAmelCase__   		=						"""a photo of a cat"""
										UpperCAmelCase__   		=						{
										    """editing_prompt""": ["""sunglasses"""],
										    """reverse_editing_direction""": [False],
										    """edit_warmup_steps""": 1_0,
										    """edit_guidance_scale""": 6,
										    """edit_threshold""": 0.95,
										    """edit_momentum_scale""": 0.5,
										    """edit_mom_beta""": 0.6,
										}

										UpperCAmelCase__   		=						3
										UpperCAmelCase__   		=						7

										# no sega enabled
										UpperCAmelCase__   		=						torch.Generator(_lowercase       )
										generator.manual_seed(_lowercase       )
										UpperCAmelCase__   		=						pipe(
										    [prompt]    ,      generator=_lowercase    ,      guidance_scale=_lowercase    ,      num_inference_steps=5_0    ,      output_type="""np"""    ,      width=5_1_2    ,      height=5_1_2    ,      )

										UpperCAmelCase__   		=						output.images
										UpperCAmelCase__   		=						image[0, -3:, -3:, -1]
										UpperCAmelCase__   		=						[
										    0.3467_3113,
										    0.3849_2733,
										    0.3759_7352,
										    0.3408_6335,
										    0.3565_0748,
										    0.3557_9205,
										    0.338_4763,
										    0.3434_0236,
										    0.357_3271,
										]

										assert image.shape == (1, 5_1_2, 5_1_2, 3)

										assert np.abs(image_slice.flatten() - expected_slice       ).max() < 1e-2

										# with sega enabled
										# generator = torch.manual_seed(seed)
										generator.manual_seed(_lowercase       )
										UpperCAmelCase__   		=						pipe(
										    [prompt]    ,      generator=_lowercase    ,      guidance_scale=_lowercase    ,      num_inference_steps=5_0    ,      output_type="""np"""    ,      width=5_1_2    ,      height=5_1_2    ,      **_lowercase    ,      )

										UpperCAmelCase__   		=						output.images
										UpperCAmelCase__   		=						image[0, -3:, -3:, -1]
										UpperCAmelCase__   		=						[
										    0.4188_7826,
										    0.3772_8766,
										    0.3013_8272,
										    0.4141_6335,
										    0.4166_4985,
										    0.3628_3392,
										    0.3619_1246,
										    0.4336_4465,
										    0.4300_1732,
										]

										assert image.shape == (1, 5_1_2, 5_1_2, 3)

										assert np.abs(image_slice.flatten() - expected_slice       ).max() < 1e-2

				def     A	(       self    :      List[str]       ):


										'''simple docstring'''
										UpperCAmelCase__   		=						"""cuda"""
										UpperCAmelCase__   		=						StableDiffusionPipeline.from_pretrained("""runwayml/stable-diffusion-v1-5"""       )
										UpperCAmelCase__   		=						pipe.to(_lowercase       )
										pipe.set_progress_bar_config(disable=_lowercase       )

										UpperCAmelCase__   		=						"""an image of a crowded boulevard, realistic, 4k"""
										UpperCAmelCase__   		=						{
										    """editing_prompt""": """crowd, crowded, people""",
										    """reverse_editing_direction""": True,
										    """edit_warmup_steps""": 1_0,
										    """edit_guidance_scale""": 8.3,
										    """edit_threshold""": 0.9,
										    """edit_momentum_scale""": 0.5,
										    """edit_mom_beta""": 0.6,
										}

										UpperCAmelCase__   		=						9
										UpperCAmelCase__   		=						7

										# no sega enabled
										UpperCAmelCase__   		=						torch.Generator(_lowercase       )
										generator.manual_seed(_lowercase       )
										UpperCAmelCase__   		=						pipe(
										    [prompt]    ,      generator=_lowercase    ,      guidance_scale=_lowercase    ,      num_inference_steps=5_0    ,      output_type="""np"""    ,      width=5_1_2    ,      height=5_1_2    ,      )

										UpperCAmelCase__   		=						output.images
										UpperCAmelCase__   		=						image[0, -3:, -3:, -1]
										UpperCAmelCase__   		=						[
										    0.4349_7998,
										    0.9181_4065,
										    0.754_0739,
										    0.5558_0205,
										    0.846_7265,
										    0.538_9691,
										    0.6257_4506,
										    0.5889_7763,
										    0.5092_6757,
										]

										assert image.shape == (1, 5_1_2, 5_1_2, 3)

										assert np.abs(image_slice.flatten() - expected_slice       ).max() < 1e-2

										# with sega enabled
										# generator = torch.manual_seed(seed)
										generator.manual_seed(_lowercase       )
										UpperCAmelCase__   		=						pipe(
										    [prompt]    ,      generator=_lowercase    ,      guidance_scale=_lowercase    ,      num_inference_steps=5_0    ,      output_type="""np"""    ,      width=5_1_2    ,      height=5_1_2    ,      **_lowercase    ,      )

										UpperCAmelCase__   		=						output.images
										UpperCAmelCase__   		=						image[0, -3:, -3:, -1]
										UpperCAmelCase__   		=						[
										    0.308_9719,
										    0.3050_0144,
										    0.2901_6042,
										    0.3063_0964,
										    0.32_5687,
										    0.2941_9225,
										    0.290_8091,
										    0.2872_3598,
										    0.2769_6294,
										]

										assert image.shape == (1, 5_1_2, 5_1_2, 3)

										assert np.abs(image_slice.flatten() - expected_slice       ).max() < 1e-2

				def     A	(       self    :      Optional[Any]       ):


										'''simple docstring'''
										UpperCAmelCase__   		=						"""cuda"""
										UpperCAmelCase__   		=						StableDiffusionPipeline.from_pretrained("""runwayml/stable-diffusion-v1-5"""       )
										UpperCAmelCase__   		=						pipe.to(_lowercase       )
										pipe.set_progress_bar_config(disable=_lowercase       )

										UpperCAmelCase__   		=						"""a castle next to a river"""
										UpperCAmelCase__   		=						{
										    """editing_prompt""": ["""boat on a river, boat""", """monet, impression, sunrise"""],
										    """reverse_editing_direction""": False,
										    """edit_warmup_steps""": [1_5, 1_8],
										    """edit_guidance_scale""": 6,
										    """edit_threshold""": [0.9, 0.8],
										    """edit_momentum_scale""": 0.5,
										    """edit_mom_beta""": 0.6,
										}

										UpperCAmelCase__   		=						4_8
										UpperCAmelCase__   		=						7

										# no sega enabled
										UpperCAmelCase__   		=						torch.Generator(_lowercase       )
										generator.manual_seed(_lowercase       )
										UpperCAmelCase__   		=						pipe(
										    [prompt]    ,      generator=_lowercase    ,      guidance_scale=_lowercase    ,      num_inference_steps=5_0    ,      output_type="""np"""    ,      width=5_1_2    ,      height=5_1_2    ,      )

										UpperCAmelCase__   		=						output.images
										UpperCAmelCase__   		=						image[0, -3:, -3:, -1]
										UpperCAmelCase__   		=						[
										    0.7516_3555,
										    0.7603_7145,
										    0.6_1785,
										    0.918_9673,
										    0.862_7701,
										    0.8518_9694,
										    0.851_2813,
										    0.8701_2076,
										    0.831_2857,
										]

										assert image.shape == (1, 5_1_2, 5_1_2, 3)

										assert np.abs(image_slice.flatten() - expected_slice       ).max() < 1e-2

										# with sega enabled
										# generator = torch.manual_seed(seed)
										generator.manual_seed(_lowercase       )
										UpperCAmelCase__   		=						pipe(
										    [prompt]    ,      generator=_lowercase    ,      guidance_scale=_lowercase    ,      num_inference_steps=5_0    ,      output_type="""np"""    ,      width=5_1_2    ,      height=5_1_2    ,      **_lowercase    ,      )

										UpperCAmelCase__   		=						output.images
										UpperCAmelCase__   		=						image[0, -3:, -3:, -1]
										UpperCAmelCase__   		=						[
										    0.7355_3365,
										    0.753_7271,
										    0.7434_1905,
										    0.6648_0356,
										    0.647_2925,
										    0.6303_9416,
										    0.6481_2905,
										    0.674_9717,
										    0.651_7102,
										]

										assert image.shape == (1, 5_1_2, 5_1_2, 3)

										assert np.abs(image_slice.flatten() - expected_slice       ).max() < 1e-2

				def     A	(       self    :      Union[str, Any]       ):


										'''simple docstring'''
										UpperCAmelCase__   		=						"""cuda"""
										UpperCAmelCase__   		=						StableDiffusionPipeline.from_pretrained("""runwayml/stable-diffusion-v1-5"""    ,      torch_dtype=torch.floataa       )
										UpperCAmelCase__   		=						pipe.to(_lowercase       )
										pipe.set_progress_bar_config(disable=_lowercase       )

										UpperCAmelCase__   		=						"""a photo of a cat"""
										UpperCAmelCase__   		=						{
										    """editing_prompt""": ["""sunglasses"""],
										    """reverse_editing_direction""": [False],
										    """edit_warmup_steps""": 1_0,
										    """edit_guidance_scale""": 6,
										    """edit_threshold""": 0.95,
										    """edit_momentum_scale""": 0.5,
										    """edit_mom_beta""": 0.6,
										}

										UpperCAmelCase__   		=						3
										UpperCAmelCase__   		=						7

										# no sega enabled
										UpperCAmelCase__   		=						torch.Generator(_lowercase       )
										generator.manual_seed(_lowercase       )
										UpperCAmelCase__   		=						pipe(
										    [prompt]    ,      generator=_lowercase    ,      guidance_scale=_lowercase    ,      num_inference_steps=5_0    ,      output_type="""np"""    ,      width=5_1_2    ,      height=5_1_2    ,      )

										UpperCAmelCase__   		=						output.images
										UpperCAmelCase__   		=						image[0, -3:, -3:, -1]
										UpperCAmelCase__   		=						[
										    0.3488_7695,
										    0.387_6953,
										    0.375,
										    0.3442_3828,
										    0.358_1543,
										    0.3571_7773,
										    0.338_3789,
										    0.3457_0312,
										    0.35_9375,
										]

										assert image.shape == (1, 5_1_2, 5_1_2, 3)

										assert np.abs(image_slice.flatten() - expected_slice       ).max() < 1e-2

										# with sega enabled
										# generator = torch.manual_seed(seed)
										generator.manual_seed(_lowercase       )
										UpperCAmelCase__   		=						pipe(
										    [prompt]    ,      generator=_lowercase    ,      guidance_scale=_lowercase    ,      num_inference_steps=5_0    ,      output_type="""np"""    ,      width=5_1_2    ,      height=5_1_2    ,      **_lowercase    ,      )

										UpperCAmelCase__   		=						output.images
										UpperCAmelCase__   		=						image[0, -3:, -3:, -1]
										UpperCAmelCase__   		=						[
										    0.4228_5156,
										    0.3691_4062,
										    0.2907_7148,
										    0.4204_1016,
										    0.4191_8945,
										    0.3549_8047,
										    0.361_8164,
										    0.442_3828,
										    0.4311_5234,
										]

										assert image.shape == (1, 5_1_2, 5_1_2, 3)

										assert np.abs(image_slice.flatten() - expected_slice       ).max() < 1e-2


"""simple docstring"""







from collections import namedtuple

UpperCamelCase_    :    Any											=						namedtuple("""from_to""", """from_ to""")

UpperCamelCase_    :    Union[str, Any]											=						{
    """millimeter""": """mm""",
    """centimeter""": """cm""",
    """meter""": """m""",
    """kilometer""": """km""",
    """inch""": """in""",
    """inche""": """in""",  # Trailing 's' has been stripped off
    """feet""": """ft""",
    """foot""": """ft""",
    """yard""": """yd""",
    """mile""": """mi""",
}

UpperCamelCase_    :    str											=						{
    """mm""": from_to(0.001, 1000),
    """cm""": from_to(0.01, 100),
    """m""": from_to(1, 1),
    """km""": from_to(1000, 0.001),
    """in""": from_to(0.0254, 39.3701),
    """ft""": from_to(0.3048, 3.2_8084),
    """yd""": from_to(0.9144, 1.0_9361),
    """mi""": from_to(1609.34, 0.0_0062_1371),
}


def 					a__ (						UpperCAmelCase__    :     float						,     UpperCAmelCase__    :     str						,     UpperCAmelCase__    :     str     )->		float:
						UpperCAmelCase__   		=						from_type.lower().rstrip("""s"""     )
						UpperCAmelCase__   		=						TYPE_CONVERSION.get(UpperCAmelCase__						,     UpperCAmelCase__     )
						UpperCAmelCase__   		=						to_type.lower().rstrip("""s"""     )
						UpperCAmelCase__   		=						TYPE_CONVERSION.get(UpperCAmelCase__						,     UpperCAmelCase__     )
						if new_from not in METRIC_CONVERSION:
												UpperCAmelCase__   		=						(
												    f'Invalid \'from_type\' value: {from_type!r}.\n'
												    f'Conversion abbreviations are: {", ".join(UpperCAmelCase__     )}'
												)
												raise ValueError(UpperCAmelCase__     )
						if new_to not in METRIC_CONVERSION:
												UpperCAmelCase__   		=						(
												    f'Invalid \'to_type\' value: {to_type!r}.\n'
												    f'Conversion abbreviations are: {", ".join(UpperCAmelCase__     )}'
												)
												raise ValueError(UpperCAmelCase__     )
						return value * METRIC_CONVERSION[new_from].from_ * METRIC_CONVERSION[new_to].to


if __name__ == "__main__":
						import doctest

						doctest.testmod()

