summaryrefslogtreecommitdiff
path: root/lib/ansible/utils
diff options
context:
space:
mode:
authorMatt Martz <matt@sivel.net>2018-11-20 17:06:51 -0600
committerGitHub <noreply@github.com>2018-11-20 17:06:51 -0600
commit9773a1f2896a914d237cb9926e3b5cdc0f004d1a (patch)
tree50d16f7f19b8fcc81f11ce220b9af22ab19c9709 /lib/ansible/utils
parent54a2f21f93c54c4a10e378e500efcc52999d6408 (diff)
downloadansible-9773a1f2896a914d237cb9926e3b5cdc0f004d1a.tar.gz
Add a Singleton metaclass, use it with Display (#48935)
* Add a Singleton class, use it with Display * update six import * Move remaining failes to display singleton * Fix rebase issues * Singleton improvements * Add code-smell for 'from __main__ import display'. ci_complete * s/self/cls/g * Add docs for no-main-display * Address linting issues * Add changelog fragment. ci_complete * Implement reentrant lock for class instantiation in Singleton * Add Display singleton porting guide
Diffstat (limited to 'lib/ansible/utils')
-rw-r--r--lib/ansible/utils/display.py4
-rw-r--r--lib/ansible/utils/encrypt.py7
-rw-r--r--lib/ansible/utils/jsonrpc.py8
-rw-r--r--lib/ansible/utils/plugin_docs.py7
-rw-r--r--lib/ansible/utils/singleton.py29
5 files changed, 38 insertions, 17 deletions
diff --git a/lib/ansible/utils/display.py b/lib/ansible/utils/display.py
index 2f21646467..51117761e1 100644
--- a/lib/ansible/utils/display.py
+++ b/lib/ansible/utils/display.py
@@ -36,7 +36,9 @@ from termios import TIOCGWINSZ
from ansible import constants as C
from ansible.errors import AnsibleError
from ansible.module_utils._text import to_bytes, to_text
+from ansible.module_utils.six import with_metaclass
from ansible.utils.color import stringc
+from ansible.utils.singleton import Singleton
try:
@@ -77,7 +79,7 @@ b_COW_PATHS = (
)
-class Display:
+class Display(with_metaclass(Singleton, object)):
def __init__(self, verbosity=0):
diff --git a/lib/ansible/utils/encrypt.py b/lib/ansible/utils/encrypt.py
index 4445fb87c8..46029037b8 100644
--- a/lib/ansible/utils/encrypt.py
+++ b/lib/ansible/utils/encrypt.py
@@ -16,6 +16,7 @@ from ansible import constants as C
from ansible.errors import AnsibleError, AnsibleAssertionError
from ansible.module_utils.six import text_type
from ansible.module_utils._text import to_text, to_bytes
+from ansible.utils.display import Display
PASSLIB_AVAILABLE = False
try:
@@ -27,11 +28,7 @@ try:
except:
pass
-try:
- from __main__ import display
-except ImportError:
- from ansible.utils.display import Display
- display = Display()
+display = Display()
__all__ = ['do_encrypt']
diff --git a/lib/ansible/utils/jsonrpc.py b/lib/ansible/utils/jsonrpc.py
index 794f1f4aea..d285cef688 100644
--- a/lib/ansible/utils/jsonrpc.py
+++ b/lib/ansible/utils/jsonrpc.py
@@ -9,13 +9,9 @@ import traceback
from ansible.module_utils._text import to_text
from ansible.module_utils.six import binary_type
+from ansible.utils.display import Display
-
-try:
- from __main__ import display
-except ImportError:
- from ansible.utils.display import Display
- display = Display()
+display = Display()
class JsonRpcServer(object):
diff --git a/lib/ansible/utils/plugin_docs.py b/lib/ansible/utils/plugin_docs.py
index c13c6529bc..30816462db 100644
--- a/lib/ansible/utils/plugin_docs.py
+++ b/lib/ansible/utils/plugin_docs.py
@@ -10,12 +10,9 @@ from ansible.module_utils._text import to_native
from ansible.module_utils.common._collections_compat import MutableMapping, MutableSet, MutableSequence
from ansible.parsing.plugin_docs import read_docstring, read_docstub
from ansible.parsing.yaml.loader import AnsibleLoader
+from ansible.utils.display import Display
-try:
- from __main__ import display
-except ImportError:
- from ansible.utils.display import Display
- display = Display()
+display = Display()
# modules that are ok that they do not have documentation strings
diff --git a/lib/ansible/utils/singleton.py b/lib/ansible/utils/singleton.py
new file mode 100644
index 0000000000..4299403eae
--- /dev/null
+++ b/lib/ansible/utils/singleton.py
@@ -0,0 +1,29 @@
+# Copyright (c) 2017 Ansible Project
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+# Make coding more python3-ish
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+from threading import RLock
+
+
+class Singleton(type):
+ """Metaclass for classes that wish to implement Singleton
+ functionality. If an instance of the class exists, it's returned,
+ otherwise a single instance is instantiated and returned.
+ """
+ def __init__(cls, name, bases, dct):
+ super(Singleton, cls).__init__(name, bases, dct)
+ cls.__instance = None
+ cls.__rlock = RLock()
+
+ def __call__(cls, *args, **kw):
+ if cls.__instance is not None:
+ return cls.__instance
+
+ with cls.__rlock:
+ if cls.__instance is None:
+ cls.__instance = super(Singleton, cls).__call__(*args, **kw)
+
+ return cls.__instance