code: def _str_to_version(
      version_str: str, allow_wildcard=False
  ) -> Tuple[Union[int, str], Union[int, str], Union[int, str]]:
      """Return the tuple (major, minor, patch) version extracted from the str."""
      if not isinstance(version_str, str):
          raise TypeError(
              "Can only convert strings to versions. "
              f"Got: {type(version_str)} with value {version_str}."
          )
      reg = (
          _VERSION_WILDCARD_REG
          if allow_wildcard
          else _VERSION_RESOLVED_REG
      )
      res = reg.match(version_str)
      if not res:
          msg = "Invalid version '{}'. Format should be x.y.z".format(
              version_str
          )
          if allow_wildcard:
              msg += " with {x,y,z} being digits or wildcard."
          else:
              msg += " with {x,y,z} being digits."
          raise ValueError(msg)
      return tuple(
          v
          if v == "*"
          else int(v)  # pylint:disable=g-complex-comprehension
          for v in [
              res.group("major"),
              res.group("minor"),
              res.group("patch"),
          ]
      )
  
imports: from __future__ import annotations
  import enum
  import re
  from typing import List, Tuple, Union
  from etils import epath
label_desc: Use image node_id 1 for calling a global function with example usage: _str_to_version(version_str, allow_wildcard) and returns: tuple