class_docstr: Thread-safe cache of Python script bytecode.
class_docstr_tok: ["Thread-safe","cache","of","Python","script","bytecode","."]
docstr: Return the bytecode for the Python script at the given path.
  
  If the bytecode is not already in the cache, the script will be
  compiled first.
  
  Raises
  ------
  Any Exception raised while reading or compiling the script.
  
  Notes
  -----
  Threading: SAFE. May be called on any thread.
docstr_tok: ["Return","the","bytecode","for","the","Python","script","at","the","given","path",".","If","the","bytecode","is","not","already","in","the","cache",",","the","script","will","be","compiled","first",".","Raises","--","--","--","Any","Exception","raised","while","reading","or","compiling","the","script",".","Notes","--","--","-","Threading",":","SAFE",".","May","be","called","on","any","thread","."]
code: def get_bytecode(self, script_path: str) -> Any:
      """Return the bytecode for the Python script at the given path.
  
      If the bytecode is not already in the cache, the script will be
      compiled first.
  
      Raises
      ------
      Any Exception raised while reading or compiling the script.
  
      Notes
      -----
      Threading: SAFE. May be called on any thread.
      """
  
      script_path = os.path.abspath(script_path)
  
      with self._lock:
          bytecode = self._cache.get(script_path, None)
          if bytecode is not None:
              # Fast path: the code is already cached.
              return bytecode
  
          # Populate the cache
          with open_python_file(script_path) as f:
              filebody = f.read()
  
          if config.get_option("runner.magicEnabled"):
              filebody = magic.add_magic(filebody, script_path)
  
          bytecode = compile(  # type: ignore
              filebody,
              # Pass in the file path so it can show up in exceptions.
              script_path,
              # We're compiling entire blocks of Python, so we need "exec"
              # mode (as opposed to "eval" or "single").
              mode="exec",
              # Don't inherit any flags or "future" statements.
              flags=0,
              dont_inherit=1,
              # Use the default optimization options.
              optimize=-1,
          )
  
          self._cache[script_path] = bytecode
          return bytecode
  
file_path: streamlit/lib/streamlit/runtime/scriptrunner/script_cache.py
imports: from __future__ import annotations
  import os.path
  import threading
  from typing import Any
  from streamlit import config
  from streamlit.runtime.scriptrunner import magic
  from streamlit.source_util import open_python_file
label_desc: Use image node_id 3 for calling the ScriptCache obj's underlying member method code with example usage: obj.get_bytecode(script_path) and returns: bytecode, bytecode