code: def get_environment(self, step):
      environment = {}
      for decorator in step.decorators:
          # @conda decorator is guaranteed to exist thanks to self.decospecs
          if decorator.name in ["conda", "pypi"]:
              # handle @conda/@pypi(disabled=True)
              disabled = decorator.attributes["disabled"]
              if not disabled or str(disabled).lower() == "false":
                  environment[decorator.name] = {
                      k: decorator.attributes[k]
                      for k in decorator.attributes
                      if k != "disabled"
                  }
              else:
                  return {}
      # Resolve conda environment for @pypi's Python, falling back on @conda's
      # Python
      env_python = (
          environment.get("pypi", environment["conda"]).get("python")
          or environment["conda"]["python"]
      )
      # TODO: Support dependencies for `--metadata`.
      # TODO: Introduce support for `--telemetry` as a follow up.
      # Certain packages are required for metaflow runtime to function correctly.
      # Ensure these packages are available both in Conda channels and PyPI
      # repostories.
      pinned_packages = get_pinned_conda_libs(
          env_python, self.datastore_type
      )
  
      # PyPI dependencies are prioritized over Conda dependencies.
      environment.get("pypi", environment["conda"])["packages"] = {
          **pinned_packages,
          **environment.get("pypi", environment["conda"])["packages"],
      }
      # Disallow specifying both @conda and @pypi together for now. Mixing Conda
      # and PyPI packages comes with a lot of operational pain that we can handle
      # as follow-up work in the future.
      if all(
          map(
              lambda key: environment.get(key, {}).get("packages"),
              ["pypi", "conda"],
          )
      ):
          msg = "Mixing and matching PyPI packages and Conda packages within a\n"
          msg += "step is not yet supported. Use one of @pypi or @conda only."
          raise CondaEnvironmentException(msg)
  
      # To support cross-platform environments, these invariants are maintained
      # 1. Conda packages are resolved for target platforms
      # 2. Conda packages are resolved for local platform only for PyPI packages
      # 3. Conda environments are created only for local platform
      # 4. PyPI packages are resolved for target platform within Conda environments
      #    created for local platform
      # 5. All resolved packages (Conda or PyPI) are cached
      # 6. PyPI packages are only installed for local platform
  
      # Resolve `linux-64` Conda environments if @batch or @kubernetes are in play
      target_platform = conda_platform()
      for decorator in step.decorators:
          if decorator.name in ["batch", "kubernetes"]:
              # TODO: Support arm architectures
              target_platform = "linux-64"
              break
  
      environment["conda"]["platforms"] = [target_platform]
      if "pypi" in environment:
          # For PyPI packages, resolve conda environment for local platform in
          # addition to target platform
          environment["conda"]["platforms"] = list(
              {target_platform, conda_platform()}
          )
          environment["pypi"]["platforms"] = [target_platform]
          # Match PyPI and Conda python versions with the resolved environment Python.
          environment["pypi"]["python"] = environment["conda"][
              "python"
          ] = env_python
  
      # Z combinator for a recursive lambda
      deep_sort = (lambda f: f(f))(
          lambda f: lambda obj: (
              {k: f(f)(v) for k, v in sorted(obj.items())}
              if isinstance(obj, dict)
              else sorted([f(f)(e) for e in obj])
              if isinstance(obj, list)
              else obj
          )
      )
  
      return {
          **environment,
          # Create a stable unique id for the environment.
          # Add packageroot to the id so that packageroot modifications can
          # invalidate existing environments.
          "id_": sha256(
              json.dumps(
                  deep_sort(
                      {
                          **environment,
                          **{
                              "package_root": _datastore_packageroot(
                                  self.datastore, self.echo
                              )
                          },
                      }
                  )
              ).encode()
          ).hexdigest()[:15],
      }
  
imports: import copy
  import errno
  import fcntl
  import functools
  import io
  import json
  import os
  import sys
  import time
  from concurrent.futures import ThreadPoolExecutor
  from hashlib import sha256
  from io import BufferedIOBase
  from itertools import chain
  from urllib.parse import unquote, urlparse
  import requests
  from metaflow.exception import MetaflowException
  from metaflow.metaflow_config import get_pinned_conda_libs
  from metaflow.metaflow_environment import MetaflowEnvironment
  from metaflow.metaflow_profile import profile
  from .None import MAGIC_FILE, _datastore_packageroot
  from .utils import conda_platform
label_desc: Use image node_id 9 for calling the CondaEnvironment obj's underlying member method code with example usage: obj.get_environment(step) and returns: dict, dict