File: C:/Users/fred/anaconda3/Lib/site-packages/anaconda_project/internal/keyring.py
# -*- coding: utf-8 -*-
# -----------------------------------------------------------------------------
# Copyright (c) 2016, Anaconda, Inc. All rights reserved.
#
# Licensed under the terms of the BSD 3-Clause License.
# The full license is in the file LICENSE.txt, distributed with this software.
# -----------------------------------------------------------------------------
"""OS keychain/keyring abstraction."""
from __future__ import absolute_import, print_function
import sys
try:
from urllib.parse import quote_plus
except ImportError: # pragma: no cover (py2 only)
from urllib import quote_plus # pragma: no cover (py2 only)
_fallback_keyring = 0
_fake_in_memory_keyring = dict()
def enable_fallback_keyring():
global _fallback_keyring
_fallback_keyring = _fallback_keyring + 1
def disable_fallback_keyring():
global _fallback_keyring
global _fake_in_memory_keyring
assert _fallback_keyring > 0
_fallback_keyring = _fallback_keyring - 1
if _fallback_keyring == 0:
# forget everything whenever the fallback gets disabled
_fake_in_memory_keyring = dict()
def _use_fallback_keyring():
global _fallback_keyring
return _fallback_keyring > 0
def _onetime_keyring_complain_and_disable(complaint):
if not _use_fallback_keyring():
# Printing to console here is a hack; we may be running in a
# GUI. But let's live with it for now until we see how often
# this happens.
print("Unable to use system keyring to store passwords.", file=sys.stderr)
print(" (%s)" % complaint, file=sys.stderr)
enable_fallback_keyring()
def reset_keyring_module():
global _fake_in_memory_keyring
global _fallback_keyring
_fake_in_memory_keyring = dict()
_fallback_keyring = 0
def fallback_data():
return _fake_in_memory_keyring
try:
import keyring
except ImportError: # pragma: no cover
keyring = None # pragma: no cover
_onetime_keyring_complain_and_disable("Module 'keyring' not available, try installing the 'keyring' package.")
def _make_username(env_prefix, variable):
assert env_prefix is not None
assert variable is not None
return "%s/%s" % (quote_plus(env_prefix), quote_plus(variable))
def get(env_prefix, variable):
name = _make_username(env_prefix, variable)
if not _use_fallback_keyring():
try:
got = keyring.get_password("anaconda", name)
return got
except Exception as e:
# keyring throws a bare "RuntimeError" if it has no working backend;
# not sure what else it can throw.
_onetime_keyring_complain_and_disable("Exception getting a password: " + str(e))
# on either exception, or disabled
return _fake_in_memory_keyring.get(name, None)
def set(env_prefix, variable, value):
assert value is not None
name = _make_username(env_prefix, variable)
if not _use_fallback_keyring():
try:
keyring.set_password("anaconda", name, value)
return
except Exception as e:
# keyring throws a bare "RuntimeError" if it has no working backend;
# not sure what else it can throw.
_onetime_keyring_complain_and_disable("Exception setting a password: " + str(e))
# on either exception, or disabled
_fake_in_memory_keyring[name] = value
def unset(env_prefix, variable):
name = _make_username(env_prefix, variable)
if not _use_fallback_keyring():
try:
keyring.delete_password("anaconda", name)
return
except Exception as e:
# keyring throws a bare "RuntimeError" if it has no working backend;
# not sure what else it can throw.
_onetime_keyring_complain_and_disable("Exception deleting a password: " + str(e))
# on either exception, or disabled
if name in _fake_in_memory_keyring:
del _fake_in_memory_keyring[name]