def __init__(self, parent=None, active_project_callback=None): """ Configuration manager to provide access to user/site/project config. """ path = self.get_user_config_path() if not osp.isdir(path): os.makedirs(path) # Site configuration defines the system defaults if a file # is found in the site location conf_paths = get_conf_paths() site_defaults = DEFAULTS for conf_path in reversed(conf_paths): conf_fpath = os.path.join(conf_path, 'spyder.ini') if os.path.isfile(conf_fpath): site_config = UserConfig( 'spyder', path=conf_path, defaults=site_defaults, load=False, version=CONF_VERSION, backup=False, raw_mode=True, remove_obsolete=False, ) site_defaults = site_config.to_list() self._parent = parent self._active_project_callback = active_project_callback self._user_config = MultiUserConfig( NAME_MAP, path=path, defaults=site_defaults, load=True, version=CONF_VERSION, backup=True, raw_mode=True, remove_obsolete=False, ) # Store plugin configurations when CONF_FILE = True self._plugin_configs = {} # TODO: To be implemented in following PR self._project_configs = {} # Cache project configurations # Setup self.remove_deprecated_config_locations()
def test_site_config_load(): """ Test that the site/system config preferences are loaded with correct precedence. """ clear_site_config() for i, path in enumerate(reversed(get_conf_paths())): exp_value = 100 * (1 + i) content = '[main]\nmemory_usage/timeout = ' + str(exp_value) + '\n' conf_fpath = os.path.join(path, 'spyder.ini') with open(conf_fpath, 'w') as fh: fh.write(content) config = ConfigurationManager() config.reset_to_defaults() value = config.get('main', 'memory_usage/timeout') print(path, value, exp_value) assert value == exp_value clear_site_config()
def clear_site_config(): """Delete all test site config folders.""" for path in get_conf_paths(): shutil.rmtree(path)
def __init__(self, parent=None, active_project_callback=None): """ Configuration manager to provide access to user/site/project config. """ path = self.get_user_config_path() if not osp.isdir(path): os.makedirs(path) # Site configuration defines the system defaults if a file # is found in the site location conf_paths = get_conf_paths() site_defaults = DEFAULTS for conf_path in reversed(conf_paths): conf_fpath = os.path.join(conf_path, 'spyder.ini') if os.path.isfile(conf_fpath): site_config = UserConfig( 'spyder', path=conf_path, defaults=site_defaults, load=False, version=CONF_VERSION, backup=False, raw_mode=True, remove_obsolete=False, ) site_defaults = site_config.to_list() self._parent = parent self._active_project_callback = active_project_callback self._user_config = MultiUserConfig( NAME_MAP, path=path, defaults=site_defaults, load=True, version=CONF_VERSION, backup=True, raw_mode=True, remove_obsolete=False, ) # Store plugin configurations when CONF_FILE = True self._plugin_configs = {} # TODO: To be implemented in following PR self._project_configs = {} # Cache project configurations # Object observer map # This dict maps from a configuration key (str/tuple) to a set # of objects that should be notified on changes to the corresponding # subscription key per section. The observer objects must be hashable. # # type: Dict[ConfigurationKey, Dict[str, Set[ConfigurationObserver]]] self._observers = {} # Set of suscription keys per observer object # This dict maps from a observer object to the set of configuration # keys that the object is subscribed to per section. # # type: Dict[ConfigurationObserver, Dict[str, Set[ConfigurationKey]]] self._observer_map_keys = weakref.WeakKeyDictionary() # Setup self.remove_deprecated_config_locations()
def main(): """ Start Spyder application. If single instance mode is turned on (default behavior) and an instance of Spyder is already running, this will just parse and send command line options to the application. """ # Parse command line options options, args = (CLI_OPTIONS, CLI_ARGS) # This is to allow reset without reading our conf file if options.reset_config_files: # <!> Remove all configuration files! reset_config_files() return from spyder.config.manager import CONF # Store variable to be used in self.restart (restart spyder instance) os.environ['SPYDER_ARGS'] = str(sys.argv[1:]) #========================================================================== # Proper high DPI scaling is available in Qt >= 5.6.0. This attribute must # be set before creating the application. #========================================================================== if CONF.get('main', 'high_dpi_custom_scale_factor'): factors = str(CONF.get('main', 'high_dpi_custom_scale_factors')) f = list(filter(None, factors.split(';'))) if len(f) == 1: os.environ['QT_SCALE_FACTOR'] = f[0] else: os.environ['QT_SCREEN_SCALE_FACTORS'] = factors else: os.environ['QT_SCALE_FACTOR'] = '' os.environ['QT_SCREEN_SCALE_FACTORS'] = '' if sys.platform == 'darwin': # Fixes launching issues with Big Sur (spyder-ide/spyder#14222) os.environ['QT_MAC_WANTS_LAYER'] = '1' # Prevent Spyder from crashing in macOS if locale is not defined LANG = os.environ.get('LANG') LC_ALL = os.environ.get('LC_ALL') if bool(LANG) and not bool(LC_ALL): LC_ALL = LANG elif not bool(LANG) and bool(LC_ALL): LANG = LC_ALL else: LANG = LC_ALL = 'en_US.UTF-8' os.environ['LANG'] = LANG os.environ['LC_ALL'] = LC_ALL # Don't show useless warning in the terminal where Spyder # was started. # See spyder-ide/spyder#3730. os.environ['EVENT_NOKQUEUE'] = '1' else: # Prevent our kernels to crash when Python fails to identify # the system locale. # Fixes spyder-ide/spyder#7051. try: from locale import getlocale getlocale() except ValueError: # This can fail on Windows. See spyder-ide/spyder#6886. try: os.environ['LANG'] = 'C' os.environ['LC_ALL'] = 'C' except Exception: pass if options.debug_info: levels = {'minimal': '2', 'verbose': '3'} os.environ['SPYDER_DEBUG'] = levels[options.debug_info] if options.paths: from spyder.config.base import get_conf_paths sys.stdout.write('\nconfig:' + '\n') for path in reversed(get_conf_paths()): sys.stdout.write('\t' + path + '\n') sys.stdout.write('\n' ) return if (CONF.get('main', 'single_instance') and not options.new_instance and not options.reset_config_files and not running_in_mac_app()): # Minimal delay (0.1-0.2 secs) to avoid that several # instances started at the same time step in their # own foots while trying to create the lock file time.sleep(random.randrange(1000, 2000, 90)/10000.) # Lock file creation lock_file = get_conf_path('spyder.lock') lock = lockfile.FilesystemLock(lock_file) # Try to lock spyder.lock. If it's *possible* to do it, then # there is no previous instance running and we can start a # new one. If *not*, then there is an instance already # running, which is locking that file try: lock_created = lock.lock() except: # If locking fails because of errors in the lockfile # module, try to remove a possibly stale spyder.lock. # This is reported to solve all problems with lockfile. # See spyder-ide/spyder#2363. try: if os.name == 'nt': if osp.isdir(lock_file): import shutil shutil.rmtree(lock_file, ignore_errors=True) else: if osp.islink(lock_file): os.unlink(lock_file) except: pass # Then start Spyder as usual and *don't* continue # executing this script because it doesn't make # sense from spyder.app import mainwindow if running_under_pytest(): return mainwindow.main(options, args) else: mainwindow.main(options, args) return if lock_created: # Start a new instance from spyder.app import mainwindow if running_under_pytest(): return mainwindow.main(options, args) else: mainwindow.main(options, args) else: # Pass args to Spyder or print an informative # message if args: send_args_to_spyder(args) else: print("Spyder is already running. If you want to open a new \n" "instance, please pass to it the --new-instance option") else: from spyder.app import mainwindow if running_under_pytest(): return mainwindow.main(options, args) else: mainwindow.main(options, args)