code: def canonicalize_version(version: Union[Version, str]) -> str:
      """
      This is very similar to Version.__str__, but has one subtle difference
      with the way it handles the release segment.
      """
      if isinstance(version, str):
          try:
              parsed = Version(version)
          except InvalidVersion:
              # Legacy versions cannot be normalized
              return version
      else:
          parsed = version
  
      parts = []
  
      # Epoch
      if parsed.epoch != 0:
          parts.append(f"{parsed.epoch}!")
  
      # Release segment
      # NB: This strips trailing '.0's to normalize
      parts.append(
          re.sub(
              r"(\.0)+$", "", ".".join(str(x) for x in parsed.release)
          )
      )
  
      # Pre-release
      if parsed.pre is not None:
          parts.append("".join(str(x) for x in parsed.pre))
  
      # Post-release
      if parsed.post is not None:
          parts.append(f".post{parsed.post}")
  
      # Development release
      if parsed.dev is not None:
          parts.append(f".dev{parsed.dev}")
  
      # Local version segment
      if parsed.local is not None:
          parts.append(f"+{parsed.local}")
  
      return "".join(parts)
  
file_path: catboost/contrib/python/packaging/py3/packaging/utils.py
imports: import re
  from typing import FrozenSet, NewType, Tuple, Union, cast
  from .tags import Tag, parse_tag
  from .version import InvalidVersion, Version
label_desc: Use image node_id 2 for calling a global function with example usage: canonicalize_version(version) and returns: str, version