class_docstr: Base class for Jupyter applications
docstr: Migrate config/data from IPython 3
docstr_tok: ["Migrate","config\/data","from","IPython","3"]
code: def migrate_config(self) -> None:
      """Migrate config/data from IPython 3"""
      try:  # let's see if we can open the marker file
          # for reading and updating (writing)
          f_marker = Path.open(Path(self.config_dir, "migrated"), "r+")
      except FileNotFoundError:  # cannot find the marker file
          pass  # that means we have not migrated yet, so continue
      except OSError:  # not readable and/or writable
          return  # so let's give up migration in such an environment
      else:  # if we got here without raising anything,
          # that means the file exists
          f_marker.close()
          return  # so we must have already migrated -> bail out
  
      from .migrate import get_ipython_dir, migrate
  
      # No IPython dir, nothing to migrate
      if not Path(get_ipython_dir()).exists():
          return
  
      migrate()
  
imports: from __future__ import annotations
  import logging
  import os
  import sys
  import typing
  from copy import deepcopy
  from pathlib import Path
  from shutil import which
  from traitlets import Bool, List, Unicode, observe
  from traitlets.config.application import Application, catch_config_error
  from traitlets.config.loader import ConfigFileNotFound
  from .paths import allow_insecure_writes, issue_insecure_write_warning, jupyter_config_dir, jupyter_config_path, jupyter_data_dir, jupyter_path, jupyter_runtime_dir
  from .utils import ensure_dir_exists, ensure_event_loop
label_desc: Use image node_id 10 for calling the JupyterApp obj's underlying member method code with example usage: obj.migrate_config() without return types