From 2203560867154d5aa496e911d78cd99f45c81f43 Mon Sep 17 00:00:00 2001
From: Felix Fontein <felix@fontein.de>
Date: Sat, 28 Dec 2024 22:47:18 +0100
Subject: [PATCH] plugins: replace to_native(), to_text(), str() with str()
 where possible or leave it away in f-string formatting (#9379)

* Replace to_native(), to_text(), str() with str() where possible or leave it away in f-string formatting.

* Improve formulation.

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

* Use more f-strings.

* Remove unicode prefix for strings.

---------

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
---
 changelogs/fragments/9379-refactor.yml | 26 ++++++++++++++++++++++++++
 plugins/action/shutdown.py             |  2 +-
 plugins/cache/redis.py                 |  3 +--
 plugins/callback/counter_enabled.py    | 12 ++++++------
 plugins/callback/dense.py              |  6 +++---
 plugins/callback/logentries.py         | 10 +++++-----
 plugins/callback/slack.py              |  3 +--
 plugins/callback/unixy.py              | 16 ++++++++--------
 plugins/callback/yaml.py               |  2 +-
 plugins/connection/chroot.py           |  4 ++--
 plugins/connection/incus.py            |  2 +-
 plugins/connection/lxd.py              |  2 +-
 plugins/filter/from_csv.py             |  5 ++---
 plugins/filter/from_ini.py             |  4 +---
 plugins/filter/to_ini.py               |  3 +--
 plugins/inventory/cobbler.py           |  3 +--
 plugins/inventory/gitlab_runners.py    |  3 +--
 plugins/inventory/iocage.py            | 16 +++++++---------
 plugins/inventory/lxd.py               | 14 +++++++-------
 plugins/inventory/nmap.py              |  6 +++---
 plugins/inventory/opennebula.py        |  3 +--
 plugins/inventory/proxmox.py           |  3 +--
 plugins/inventory/scaleway.py          |  4 ++--
 plugins/inventory/virtualbox.py        |  4 ++--
 plugins/lookup/cyberarkpassword.py     |  4 ++--
 plugins/lookup/dig.py                  | 17 ++++++++---------
 plugins/lookup/dnstxt.py               |  3 +--
 plugins/lookup/etcd3.py                |  6 +++---
 plugins/lookup/keyring.py              |  2 +-
 plugins/lookup/lmdb_kv.py              |  2 +-
 plugins/lookup/manifold.py             | 10 +++++-----
 plugins/lookup/onepassword.py          |  2 +-
 plugins/lookup/tss.py                  |  6 +++---
 plugins/plugin_utils/unsafe.py         |  2 +-
 34 files changed, 111 insertions(+), 99 deletions(-)
 create mode 100644 changelogs/fragments/9379-refactor.yml

diff --git a/changelogs/fragments/9379-refactor.yml b/changelogs/fragments/9379-refactor.yml
new file mode 100644
index 0000000000..0a87b2d0c1
--- /dev/null
+++ b/changelogs/fragments/9379-refactor.yml
@@ -0,0 +1,26 @@
+minor_changes:
+  - "shutdown action plugin - clean up string conversions (https://github.com/ansible-collections/community.general/pull/9379)."
+  - "redis cache plugin - clean up string conversions (https://github.com/ansible-collections/community.general/pull/9379)."
+  - "logentries callback plugin - clean up string conversions (https://github.com/ansible-collections/community.general/pull/9379)."
+  - "slack callback plugin - clean up string conversions (https://github.com/ansible-collections/community.general/pull/9379)."
+  - "chroot connection plugin - clean up string conversions (https://github.com/ansible-collections/community.general/pull/9379)."
+  - "from_csv filter plugin - clean up string conversions (https://github.com/ansible-collections/community.general/pull/9379)."
+  - "from_ini filter plugin - clean up string conversions (https://github.com/ansible-collections/community.general/pull/9379)."
+  - "to_ini filter plugin - clean up string conversions (https://github.com/ansible-collections/community.general/pull/9379)."
+  - "cobbler inventory plugin - clean up string conversions (https://github.com/ansible-collections/community.general/pull/9379)."
+  - "gitlab_runners inventory plugin - clean up string conversions (https://github.com/ansible-collections/community.general/pull/9379)."
+  - "iocage inventory plugin - clean up string conversions (https://github.com/ansible-collections/community.general/pull/9379)."
+  - "lxd inventory plugin - clean up string conversions (https://github.com/ansible-collections/community.general/pull/9379)."
+  - "nmap inventory plugin - clean up string conversions (https://github.com/ansible-collections/community.general/pull/9379)."
+  - "opennebula inventory plugin - clean up string conversions (https://github.com/ansible-collections/community.general/pull/9379)."
+  - "proxmox inventory plugin - clean up string conversions (https://github.com/ansible-collections/community.general/pull/9379)."
+  - "scaleway inventory plugin - clean up string conversions (https://github.com/ansible-collections/community.general/pull/9379)."
+  - "virtualbox inventory plugin - clean up string conversions (https://github.com/ansible-collections/community.general/pull/9379)."
+  - "cyberarkpassword lookup plugin - clean up string conversions (https://github.com/ansible-collections/community.general/pull/9379)."
+  - "dig lookup plugin - clean up string conversions (https://github.com/ansible-collections/community.general/pull/9379)."
+  - "dnstxt lookup plugin - clean up string conversions (https://github.com/ansible-collections/community.general/pull/9379)."
+  - "etcd3 lookup plugin - clean up string conversions (https://github.com/ansible-collections/community.general/pull/9379)."
+  - "lmdb_kv lookup plugin - clean up string conversions (https://github.com/ansible-collections/community.general/pull/9379)."
+  - "manifold lookup plugin - clean up string conversions (https://github.com/ansible-collections/community.general/pull/9379)."
+  - "onepassword lookup plugin - clean up string conversions (https://github.com/ansible-collections/community.general/pull/9379)."
+  - "tss lookup plugin - clean up string conversions (https://github.com/ansible-collections/community.general/pull/9379)."
diff --git a/plugins/action/shutdown.py b/plugins/action/shutdown.py
index 9505cc2155..e5c2d15a5c 100644
--- a/plugins/action/shutdown.py
+++ b/plugins/action/shutdown.py
@@ -177,7 +177,7 @@ class ActionModule(ActionBase):
         except AnsibleConnectionFailure as e:
             # If the connection is closed too quickly due to the system being shutdown, carry on
             display.debug(
-                f'{self._task.action}: AnsibleConnectionFailure caught and handled: {to_text(e)}')
+                f'{self._task.action}: AnsibleConnectionFailure caught and handled: {e}')
             shutdown_result['rc'] = 0
 
         if shutdown_result['rc'] != 0:
diff --git a/plugins/cache/redis.py b/plugins/cache/redis.py
index aa0243b9dd..63d67c66ef 100644
--- a/plugins/cache/redis.py
+++ b/plugins/cache/redis.py
@@ -73,7 +73,6 @@ import time
 import json
 
 from ansible.errors import AnsibleError
-from ansible.module_utils.common.text.converters import to_native
 from ansible.parsing.ajson import AnsibleJSONEncoder, AnsibleJSONDecoder
 from ansible.plugins.cache import BaseCacheModule
 from ansible.utils.display import Display
@@ -169,7 +168,7 @@ class CacheModule(BaseCacheModule):
         try:
             return scon.master_for(self._sentinel_service_name, socket_timeout=0.2)
         except Exception as exc:
-            raise AnsibleError(f'Could not connect to redis sentinel: {to_native(exc)}')
+            raise AnsibleError(f'Could not connect to redis sentinel: {exc}')
 
     def _make_key(self, key):
         return self._prefix + key
diff --git a/plugins/callback/counter_enabled.py b/plugins/callback/counter_enabled.py
index 9bb1df07d4..a96c8a1a72 100644
--- a/plugins/callback/counter_enabled.py
+++ b/plugins/callback/counter_enabled.py
@@ -92,16 +92,16 @@ class CallbackModule(CallbackBase):
             stat = stats.summarize(host)
 
             self._display.display(
-                f"{hostcolor(host, stat)} : {colorize(u'ok', stat['ok'], C.COLOR_OK)} {colorize(u'changed', stat['changed'], C.COLOR_CHANGED)} "
-                f"{colorize(u'unreachable', stat['unreachable'], C.COLOR_UNREACHABLE)} {colorize(u'failed', stat['failures'], C.COLOR_ERROR)} "
-                f"{colorize(u'rescued', stat['rescued'], C.COLOR_OK)} {colorize(u'ignored', stat['ignored'], C.COLOR_WARN)}",
+                f"{hostcolor(host, stat)} : {colorize('ok', stat['ok'], C.COLOR_OK)} {colorize('changed', stat['changed'], C.COLOR_CHANGED)} "
+                f"{colorize('unreachable', stat['unreachable'], C.COLOR_UNREACHABLE)} {colorize('failed', stat['failures'], C.COLOR_ERROR)} "
+                f"{colorize('rescued', stat['rescued'], C.COLOR_OK)} {colorize('ignored', stat['ignored'], C.COLOR_WARN)}",
                 screen_only=True
             )
 
             self._display.display(
-                f"{hostcolor(host, stat, False)} : {colorize(u'ok', stat['ok'], None)} {colorize(u'changed', stat['changed'], None)} "
-                f"{colorize(u'unreachable', stat['unreachable'], None)} {colorize(u'failed', stat['failures'], None)} "
-                f"{colorize(u'rescued', stat['rescued'], None)} {colorize(u'ignored', stat['ignored'], None)}",
+                f"{hostcolor(host, stat, False)} : {colorize('ok', stat['ok'], None)} {colorize('changed', stat['changed'], None)} "
+                f"{colorize('unreachable', stat['unreachable'], None)} {colorize('failed', stat['failures'], None)} "
+                f"{colorize('rescued', stat['rescued'], None)} {colorize('ignored', stat['ignored'], None)}",
                 log_only=True
             )
 
diff --git a/plugins/callback/dense.py b/plugins/callback/dense.py
index e0419644ef..88a2ff6742 100644
--- a/plugins/callback/dense.py
+++ b/plugins/callback/dense.py
@@ -483,9 +483,9 @@ class CallbackModule(CallbackModule_default):
         for h in hosts:
             t = stats.summarize(h)
             self._display.display(
-                f"{hostcolor(h, t)} : {colorize(u'ok', t['ok'], C.COLOR_OK)} {colorize(u'changed', t['changed'], C.COLOR_CHANGED)} "
-                f"{colorize(u'unreachable', t['unreachable'], C.COLOR_UNREACHABLE)} {colorize(u'failed', t['failures'], C.COLOR_ERROR)} "
-                f"{colorize(u'rescued', t['rescued'], C.COLOR_OK)} {colorize(u'ignored', t['ignored'], C.COLOR_WARN)}",
+                f"{hostcolor(h, t)} : {colorize('ok', t['ok'], C.COLOR_OK)} {colorize('changed', t['changed'], C.COLOR_CHANGED)} "
+                f"{colorize('unreachable', t['unreachable'], C.COLOR_UNREACHABLE)} {colorize('failed', t['failures'], C.COLOR_ERROR)} "
+                f"{colorize('rescued', t['rescued'], C.COLOR_OK)} {colorize('ignored', t['ignored'], C.COLOR_WARN)}",
                 screen_only=True
             )
 
diff --git a/plugins/callback/logentries.py b/plugins/callback/logentries.py
index bc8b1cb5bd..ead49e7dc5 100644
--- a/plugins/callback/logentries.py
+++ b/plugins/callback/logentries.py
@@ -135,7 +135,7 @@ class PlainTextSocketAppender(object):
         # Error message displayed when an incorrect Token has been detected
         self.INVALID_TOKEN = "\n\nIt appears the LOGENTRIES_TOKEN parameter you entered is incorrect!\n\n"
         # Unicode Line separator character   \u2028
-        self.LINE_SEP = u'\u2028'
+        self.LINE_SEP = '\u2028'
 
         self._display = display
         self._conn = None
@@ -153,7 +153,7 @@ class PlainTextSocketAppender(object):
                 self.open_connection()
                 return
             except Exception as e:
-                self._display.vvvv(f"Unable to connect to Logentries: {to_text(e)}")
+                self._display.vvvv(f"Unable to connect to Logentries: {e}")
 
             root_delay *= 2
             if root_delay > self.MAX_DELAY:
@@ -175,8 +175,8 @@ class PlainTextSocketAppender(object):
         # Replace newlines with Unicode line separator
         # for multi-line events
         data = to_text(data, errors='surrogate_or_strict')
-        multiline = data.replace(u'\n', self.LINE_SEP)
-        multiline += u"\n"
+        multiline = data.replace('\n', self.LINE_SEP)
+        multiline += "\n"
         # Send data, reconnect if needed
         while True:
             try:
@@ -249,7 +249,7 @@ class CallbackModule(CallbackBase):
             self.use_tls = self.get_option('use_tls')
             self.flatten = self.get_option('flatten')
         except KeyError as e:
-            self._display.warning(f"Missing option for Logentries callback plugin: {to_text(e)}")
+            self._display.warning(f"Missing option for Logentries callback plugin: {e}")
             self.disabled = True
 
         try:
diff --git a/plugins/callback/slack.py b/plugins/callback/slack.py
index 0e58628c35..08e75affb6 100644
--- a/plugins/callback/slack.py
+++ b/plugins/callback/slack.py
@@ -62,7 +62,6 @@ import os
 import uuid
 
 from ansible import context
-from ansible.module_utils.common.text.converters import to_text
 from ansible.module_utils.urls import open_url
 from ansible.plugins.callback import CallbackBase
 
@@ -138,7 +137,7 @@ class CallbackModule(CallbackBase):
                                 headers=headers)
             return response.read()
         except Exception as e:
-            self._display.warning(f'Could not submit message to Slack: {to_text(e)}')
+            self._display.warning(f'Could not submit message to Slack: {e}')
 
     def v2_playbook_on_start(self, playbook):
         self.playbook_name = os.path.basename(playbook._file_name)
diff --git a/plugins/callback/unixy.py b/plugins/callback/unixy.py
index de0c79088b..cacfb80372 100644
--- a/plugins/callback/unixy.py
+++ b/plugins/callback/unixy.py
@@ -110,12 +110,12 @@ class CallbackModule(CallbackModule_default):
             if name and play.hosts:
                 msg = f"\n- {name} (in check mode) on hosts: {','.join(play.hosts)} -"
             else:
-                msg = u"- check mode -"
+                msg = "- check mode -"
         else:
             if name and play.hosts:
                 msg = f"\n- {name} on hosts: {','.join(play.hosts)} -"
             else:
-                msg = u"---"
+                msg = "---"
 
         self._display.display(msg)
 
@@ -196,16 +196,16 @@ class CallbackModule(CallbackModule_default):
             t = stats.summarize(h)
 
             self._display.display(
-                f"  {hostcolor(h, t)} : {colorize(u'ok', t['ok'], C.COLOR_OK)} {colorize(u'changed', t['changed'], C.COLOR_CHANGED)} "
-                f"{colorize(u'unreachable', t['unreachable'], C.COLOR_UNREACHABLE)} {colorize(u'failed', t['failures'], C.COLOR_ERROR)} "
-                f"{colorize(u'rescued', t['rescued'], C.COLOR_OK)} {colorize(u'ignored', t['ignored'], C.COLOR_WARN)}",
+                f"  {hostcolor(h, t)} : {colorize('ok', t['ok'], C.COLOR_OK)} {colorize('changed', t['changed'], C.COLOR_CHANGED)} "
+                f"{colorize('unreachable', t['unreachable'], C.COLOR_UNREACHABLE)} {colorize('failed', t['failures'], C.COLOR_ERROR)} "
+                f"{colorize('rescued', t['rescued'], C.COLOR_OK)} {colorize('ignored', t['ignored'], C.COLOR_WARN)}",
                 screen_only=True
             )
 
             self._display.display(
-                f"  {hostcolor(h, t, False)} : {colorize(u'ok', t['ok'], None)} {colorize(u'changed', t['changed'], None)} "
-                f"{colorize(u'unreachable', t['unreachable'], None)} {colorize(u'failed', t['failures'], None)} {colorize(u'rescued', t['rescued'], None)} "
-                f"{colorize(u'ignored', t['ignored'], None)}",
+                f"  {hostcolor(h, t, False)} : {colorize('ok', t['ok'], None)} {colorize('changed', t['changed'], None)} "
+                f"{colorize('unreachable', t['unreachable'], None)} {colorize('failed', t['failures'], None)} {colorize('rescued', t['rescued'], None)} "
+                f"{colorize('ignored', t['ignored'], None)}",
                 log_only=True
             )
         if stats.custom and self.get_option('show_custom_stats'):
diff --git a/plugins/callback/yaml.py b/plugins/callback/yaml.py
index 1daf4572d5..d2b8a9cc1b 100644
--- a/plugins/callback/yaml.py
+++ b/plugins/callback/yaml.py
@@ -45,7 +45,7 @@ from ansible.plugins.callback.default import CallbackModule as Default
 # from http://stackoverflow.com/a/15423007/115478
 def should_use_block(value):
     """Returns true if string should be in block format"""
-    for c in u"\u000a\u000d\u001c\u001d\u001e\u0085\u2028\u2029":
+    for c in "\u000a\u000d\u001c\u001d\u001e\u0085\u2028\u2029":
         if c in value:
             return True
     return False
diff --git a/plugins/connection/chroot.py b/plugins/connection/chroot.py
index 2586109669..b0200fdbcb 100644
--- a/plugins/connection/chroot.py
+++ b/plugins/connection/chroot.py
@@ -94,7 +94,7 @@ from ansible.errors import AnsibleError
 from ansible.module_utils.basic import is_executable
 from ansible.module_utils.common.process import get_bin_path
 from ansible.module_utils.six.moves import shlex_quote
-from ansible.module_utils.common.text.converters import to_bytes, to_native
+from ansible.module_utils.common.text.converters import to_bytes
 from ansible.plugins.connection import ConnectionBase, BUFSIZE
 from ansible.utils.display import Display
 
@@ -143,7 +143,7 @@ class Connection(ConnectionBase):
             try:
                 self.chroot_cmd = get_bin_path(self.get_option('chroot_exe'))
             except ValueError as e:
-                raise AnsibleError(to_native(e))
+                raise AnsibleError(str(e))
 
         super(Connection, self)._connect()
         if not self._connected:
diff --git a/plugins/connection/incus.py b/plugins/connection/incus.py
index 097b3b800f..377389312a 100644
--- a/plugins/connection/incus.py
+++ b/plugins/connection/incus.py
@@ -80,7 +80,7 @@ class Connection(ConnectionBase):
         super(Connection, self)._connect()
 
         if not self._connected:
-            self._display.vvv(u"ESTABLISH Incus CONNECTION FOR USER: root",
+            self._display.vvv("ESTABLISH Incus CONNECTION FOR USER: root",
                               host=self._instance())
             self._connected = True
 
diff --git a/plugins/connection/lxd.py b/plugins/connection/lxd.py
index 5fa40c3636..e0782d6284 100644
--- a/plugins/connection/lxd.py
+++ b/plugins/connection/lxd.py
@@ -86,7 +86,7 @@ class Connection(ConnectionBase):
         super(Connection, self)._connect()
 
         if not self._connected:
-            self._display.vvv(u"ESTABLISH LXD CONNECTION FOR USER: root", host=self._host())
+            self._display.vvv("ESTABLISH LXD CONNECTION FOR USER: root", host=self._host())
             self._connected = True
 
     def exec_command(self, cmd, in_data=None, sudoable=True):
diff --git a/plugins/filter/from_csv.py b/plugins/filter/from_csv.py
index 310138d496..617f314794 100644
--- a/plugins/filter/from_csv.py
+++ b/plugins/filter/from_csv.py
@@ -81,7 +81,6 @@ RETURN = '''
 '''
 
 from ansible.errors import AnsibleFilterError
-from ansible.module_utils.common.text.converters import to_native
 
 from ansible_collections.community.general.plugins.module_utils.csv import (initialize_dialect, read_csv, CSVError,
                                                                             DialectNotAvailableError,
@@ -99,7 +98,7 @@ def from_csv(data, dialect='excel', fieldnames=None, delimiter=None, skipinitial
     try:
         dialect = initialize_dialect(dialect, **dialect_params)
     except (CustomDialectFailureError, DialectNotAvailableError) as e:
-        raise AnsibleFilterError(to_native(e))
+        raise AnsibleFilterError(str(e))
 
     reader = read_csv(data, dialect, fieldnames)
 
@@ -109,7 +108,7 @@ def from_csv(data, dialect='excel', fieldnames=None, delimiter=None, skipinitial
         for row in reader:
             data_list.append(row)
     except CSVError as e:
-        raise AnsibleFilterError("Unable to process file: %s" % to_native(e))
+        raise AnsibleFilterError(f"Unable to process file: {e}")
 
     return data_list
 
diff --git a/plugins/filter/from_ini.py b/plugins/filter/from_ini.py
index 6fe83875e6..5b4bd4a3af 100644
--- a/plugins/filter/from_ini.py
+++ b/plugins/filter/from_ini.py
@@ -50,7 +50,6 @@ from ansible.errors import AnsibleFilterError
 from ansible.module_utils.six import string_types
 from ansible.module_utils.six.moves import StringIO
 from ansible.module_utils.six.moves.configparser import ConfigParser
-from ansible.module_utils.common.text.converters import to_native
 
 
 class IniParser(ConfigParser):
@@ -83,8 +82,7 @@ def from_ini(obj):
     try:
         parser.read_file(StringIO(obj))
     except Exception as ex:
-        raise AnsibleFilterError(f'from_ini failed to parse given string: '
-                                 f'{to_native(ex)}', orig_exc=ex)
+        raise AnsibleFilterError(f'from_ini failed to parse given string: {ex}', orig_exc=ex)
 
     return parser.as_dict()
 
diff --git a/plugins/filter/to_ini.py b/plugins/filter/to_ini.py
index bdf2dde270..2bc41f6962 100644
--- a/plugins/filter/to_ini.py
+++ b/plugins/filter/to_ini.py
@@ -56,7 +56,6 @@ from ansible.errors import AnsibleFilterError
 from ansible.module_utils.common._collections_compat import Mapping
 from ansible.module_utils.six.moves import StringIO
 from ansible.module_utils.six.moves.configparser import ConfigParser
-from ansible.module_utils.common.text.converters import to_native
 
 
 class IniParser(ConfigParser):
@@ -79,7 +78,7 @@ def to_ini(obj):
         ini_parser.read_dict(obj)
     except Exception as ex:
         raise AnsibleFilterError('to_ini failed to parse given dict:'
-                                 f'{to_native(ex)}', orig_exc=ex)
+                                 f'{ex}', orig_exc=ex)
 
     # catching empty dicts
     if obj == dict():
diff --git a/plugins/inventory/cobbler.py b/plugins/inventory/cobbler.py
index ef88dae18c..2b056ed9bf 100644
--- a/plugins/inventory/cobbler.py
+++ b/plugins/inventory/cobbler.py
@@ -118,7 +118,6 @@ password: secure
 import socket
 
 from ansible.errors import AnsibleError
-from ansible.module_utils.common.text.converters import to_text
 from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable, to_safe_group_name
 from ansible.module_utils.six import text_type
 
@@ -377,7 +376,7 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
                 try:
                     self.inventory.set_variable(hostname, 'cobbler', make_unsafe(host))
                 except ValueError as e:
-                    self.display.warning(f"Could not set host info for {hostname}: {to_text(e)}")
+                    self.display.warning(f"Could not set host info for {hostname}: {e}")
 
         if self.get_option('want_ip_addresses'):
             self.inventory.set_variable(self.group, 'cobbler_ipv4_addresses', make_unsafe(ip_addresses))
diff --git a/plugins/inventory/gitlab_runners.py b/plugins/inventory/gitlab_runners.py
index a5f53b8b14..302ccad9b7 100644
--- a/plugins/inventory/gitlab_runners.py
+++ b/plugins/inventory/gitlab_runners.py
@@ -81,7 +81,6 @@ keyed_groups:
 '''
 
 from ansible.errors import AnsibleError, AnsibleParserError
-from ansible.module_utils.common.text.converters import to_native
 from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
 
 from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
@@ -124,7 +123,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
                 # Create groups based on variable values and add the corresponding hosts to it
                 self._add_host_to_keyed_groups(self.get_option('keyed_groups'), host_attrs, host, strict=strict)
         except Exception as e:
-            raise AnsibleParserError(f'Unable to fetch hosts from GitLab API, this was the original exception: {to_native(e)}')
+            raise AnsibleParserError(f'Unable to fetch hosts from GitLab API, this was the original exception: {e}')
 
     def verify_file(self, path):
         """Return the possibly of a file being consumable by this plugin."""
diff --git a/plugins/inventory/iocage.py b/plugins/inventory/iocage.py
index 6b51bb346e..5dc18b4710 100644
--- a/plugins/inventory/iocage.py
+++ b/plugins/inventory/iocage.py
@@ -195,17 +195,15 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
             p = Popen(cmd_list, stdout=PIPE, stderr=PIPE, env=my_env)
             stdout, stderr = p.communicate()
             if p.returncode != 0:
-                raise AnsibleError('Failed to run cmd=%s, rc=%s, stderr=%s' %
-                                   (cmd_list, p.returncode, to_native(stderr)))
+                raise AnsibleError(f'Failed to run cmd={cmd_list}, rc={p.returncode}, stderr={to_native(stderr)}')
 
             try:
                 t_stdout = to_text(stdout, errors='surrogate_or_strict')
             except UnicodeError as e:
-                raise AnsibleError('Invalid (non unicode) input returned: %s' % to_native(e)) from e
+                raise AnsibleError(f'Invalid (non unicode) input returned: {e}') from e
 
         except Exception as e:
-            raise AnsibleParserError('Failed to parse %s: %s' %
-                                     (to_native(path), to_native(e))) from e
+            raise AnsibleParserError(f'Failed to parse {to_native(path)}: {e}') from e
 
         results = {'_meta': {'hostvars': {}}}
         self.get_jails(t_stdout, results)
@@ -220,16 +218,16 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
                     p = Popen(cmd_get_properties, stdout=PIPE, stderr=PIPE, env=my_env)
                     stdout, stderr = p.communicate()
                     if p.returncode != 0:
-                        raise AnsibleError('Failed to run cmd=%s, rc=%s, stderr=%s' %
-                                           (cmd_get_properties, p.returncode, to_native(stderr)))
+                        raise AnsibleError(
+                            f'Failed to run cmd={cmd_get_properties}, rc={p.returncode}, stderr={to_native(stderr)}')
 
                     try:
                         t_stdout = to_text(stdout, errors='surrogate_or_strict')
                     except UnicodeError as e:
-                        raise AnsibleError('Invalid (non unicode) input returned: %s' % to_native(e)) from e
+                        raise AnsibleError(f'Invalid (non unicode) input returned: {e}') from e
 
                 except Exception as e:
-                    raise AnsibleError('Failed to get properties: %s' % to_native(e)) from e
+                    raise AnsibleError(f'Failed to get properties: {e}') from e
 
                 self.get_properties(t_stdout, results, hostname)
 
diff --git a/plugins/inventory/lxd.py b/plugins/inventory/lxd.py
index 1e135f7415..d7b942c1f7 100644
--- a/plugins/inventory/lxd.py
+++ b/plugins/inventory/lxd.py
@@ -211,7 +211,7 @@ class InventoryModule(BaseInventoryPlugin):
             with open(path, 'r') as json_file:
                 return json.load(json_file)
         except (IOError, json.decoder.JSONDecodeError) as err:
-            raise AnsibleParserError(f'Could not load the test data from {to_native(path)}: {to_native(err)}')
+            raise AnsibleParserError(f'Could not load the test data from {to_native(path)}: {err}')
 
     def save_json_data(self, path, file_name=None):
         """save data as json
@@ -241,7 +241,7 @@ class InventoryModule(BaseInventoryPlugin):
             with open(os.path.abspath(os.path.join(cwd, *path)), 'w') as json_file:
                 json.dump(self.data, json_file)
         except IOError as err:
-            raise AnsibleParserError(f'Could not save data: {to_native(err)}')
+            raise AnsibleParserError(f'Could not save data: {err}')
 
     def verify_file(self, path):
         """Check the config
@@ -281,7 +281,7 @@ class InventoryModule(BaseInventoryPlugin):
         if not isinstance(url, str):
             return False
         if not url.startswith(('unix:', 'https:')):
-            raise AnsibleError(f'URL is malformed: {to_native(url)}')
+            raise AnsibleError(f'URL is malformed: {url}')
         return True
 
     def _connect_to_socket(self):
@@ -306,7 +306,7 @@ class InventoryModule(BaseInventoryPlugin):
                 return socket_connection
             except LXDClientException as err:
                 error_storage[url] = err
-        raise AnsibleError(f'No connection to the socket: {to_native(error_storage)}')
+        raise AnsibleError(f'No connection to the socket: {error_storage}')
 
     def _get_networks(self):
         """Get Networknames
@@ -579,7 +579,7 @@ class InventoryModule(BaseInventoryPlugin):
             else:
                 path[instance_name][key] = value
         except KeyError as err:
-            raise AnsibleParserError(f"Unable to store Information: {to_native(err)}")
+            raise AnsibleParserError(f"Unable to store Information: {err}")
 
     def extract_information_from_instance_configs(self):
         """Process configuration information
@@ -792,7 +792,7 @@ class InventoryModule(BaseInventoryPlugin):
             network = ipaddress.ip_network(to_text(self.groupby[group_name].get('attribute')))
         except ValueError as err:
             raise AnsibleParserError(
-                f"Error while parsing network range {self.groupby[group_name].get('attribute')}: {to_native(err)}")
+                f"Error while parsing network range {self.groupby[group_name].get('attribute')}: {err}")
 
         for instance_name in self.inventory.hosts:
             if self.data['inventory'][instance_name].get('network_interfaces') is not None:
@@ -1120,6 +1120,6 @@ class InventoryModule(BaseInventoryPlugin):
             self.url = self.get_option('url')
         except Exception as err:
             raise AnsibleParserError(
-                f'All correct options required: {to_native(err)}')
+                f'All correct options required: {err}')
         # Call our internal helper to populate the dynamic inventory
         self._populate()
diff --git a/plugins/inventory/nmap.py b/plugins/inventory/nmap.py
index fbc8a76173..f40f33b972 100644
--- a/plugins/inventory/nmap.py
+++ b/plugins/inventory/nmap.py
@@ -178,7 +178,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
         try:
             self._nmap = get_bin_path('nmap')
         except ValueError as e:
-            raise AnsibleParserError(f'nmap inventory plugin requires the nmap cli tool to work: {to_native(e)}')
+            raise AnsibleParserError(f'nmap inventory plugin requires the nmap cli tool to work: {e}')
 
         super(InventoryModule, self).parse(inventory, loader, path, cache=cache)
 
@@ -259,7 +259,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
                 try:
                     t_stdout = to_text(stdout, errors='surrogate_or_strict')
                 except UnicodeError as e:
-                    raise AnsibleParserError(f'Invalid (non unicode) input returned: {to_native(e)}')
+                    raise AnsibleParserError(f'Invalid (non unicode) input returned: {e}')
 
                 for line in t_stdout.splitlines():
                     hits = self.find_host.match(line)
@@ -300,7 +300,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
                     results[-1]['ports'] = ports
 
             except Exception as e:
-                raise AnsibleParserError(f"failed to parse {to_native(path)}: {to_native(e)} ")
+                raise AnsibleParserError(f"failed to parse {to_native(path)}: {e} ")
 
         if cache_needs_update:
             self._cache[cache_key] = results
diff --git a/plugins/inventory/opennebula.py b/plugins/inventory/opennebula.py
index 2750d4d370..7fc320f326 100644
--- a/plugins/inventory/opennebula.py
+++ b/plugins/inventory/opennebula.py
@@ -96,7 +96,6 @@ except ImportError:
 
 from ansible.errors import AnsibleError
 from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
-from ansible.module_utils.common.text.converters import to_native
 
 from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
 
@@ -172,7 +171,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
         try:
             vm_pool = one_client.vmpool.infoextended(-2, -1, -1, 3)
         except Exception as e:
-            raise AnsibleError(f"Something happened during XML-RPC call: {to_native(e)}")
+            raise AnsibleError(f"Something happened during XML-RPC call: {e}")
 
         return vm_pool
 
diff --git a/plugins/inventory/proxmox.py b/plugins/inventory/proxmox.py
index e4a39df3d7..656304a2d5 100644
--- a/plugins/inventory/proxmox.py
+++ b/plugins/inventory/proxmox.py
@@ -222,7 +222,6 @@ from ansible.module_utils.common._collections_compat import MutableMapping
 
 from ansible.errors import AnsibleError
 from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
-from ansible.module_utils.common.text.converters import to_native
 from ansible.module_utils.six import string_types
 from ansible.module_utils.six.moves.urllib.parse import urlencode
 from ansible.utils.display import Display
@@ -523,7 +522,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
                 if not self._compose(host_filter, properties):
                     return False
             except Exception as e:  # pylint: disable=broad-except
-                message = f"Could not evaluate host filter {host_filter} for host {name} - {to_native(e)}"
+                message = f"Could not evaluate host filter {host_filter} for host {name} - {e}"
                 if self.strict:
                     raise AnsibleError(message)
                 display.warning(message)
diff --git a/plugins/inventory/scaleway.py b/plugins/inventory/scaleway.py
index 7fc5f12c44..9a40243ee7 100644
--- a/plugins/inventory/scaleway.py
+++ b/plugins/inventory/scaleway.py
@@ -125,7 +125,7 @@ from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
 from ansible_collections.community.general.plugins.module_utils.scaleway import SCALEWAY_LOCATION, parse_pagination_link
 from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
 from ansible.module_utils.urls import open_url
-from ansible.module_utils.common.text.converters import to_native, to_text
+from ansible.module_utils.common.text.converters import to_text
 from ansible.module_utils.six import raise_from
 
 import ansible.module_utils.six.moves.urllib.parse as urllib_parse
@@ -140,7 +140,7 @@ def _fetch_information(token, url):
                                 headers={'X-Auth-Token': token,
                                          'Content-type': 'application/json'})
         except Exception as e:
-            raise AnsibleError(f"Error while fetching {url}: {to_native(e)}")
+            raise AnsibleError(f"Error while fetching {url}: {e}")
         try:
             raw_json = json.loads(to_text(response.read()))
         except ValueError:
diff --git a/plugins/inventory/virtualbox.py b/plugins/inventory/virtualbox.py
index e6f401ca86..2ddb1ebb2b 100644
--- a/plugins/inventory/virtualbox.py
+++ b/plugins/inventory/virtualbox.py
@@ -76,7 +76,7 @@ import os
 from subprocess import Popen, PIPE
 
 from ansible.errors import AnsibleParserError
-from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
+from ansible.module_utils.common.text.converters import to_bytes, to_text
 from ansible.module_utils.common._collections_compat import MutableMapping
 from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
 from ansible.module_utils.common.process import get_bin_path
@@ -352,7 +352,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
             try:
                 p = Popen(cmd, stdout=PIPE)
             except Exception as e:
-                raise AnsibleParserError(to_native(e))
+                raise AnsibleParserError(str(e))
 
             source_data = p.stdout.read().splitlines()
 
diff --git a/plugins/lookup/cyberarkpassword.py b/plugins/lookup/cyberarkpassword.py
index e6701c9fb8..4ed040dc6d 100644
--- a/plugins/lookup/cyberarkpassword.py
+++ b/plugins/lookup/cyberarkpassword.py
@@ -84,7 +84,7 @@ from subprocess import Popen
 
 from ansible.errors import AnsibleError
 from ansible.plugins.lookup import LookupBase
-from ansible.module_utils.common.text.converters import to_bytes, to_text, to_native
+from ansible.module_utils.common.text.converters import to_bytes, to_native
 from ansible.utils.display import Display
 
 display = Display()
@@ -164,7 +164,7 @@ class CyberarkPassword:
         except subprocess.CalledProcessError as e:
             raise AnsibleError(e.output)
         except OSError as e:
-            raise AnsibleError(f"ERROR - AIM not installed or clipasswordsdk not in standard location. ERROR=({to_text(e.errno)}) => {e.strerror} ")
+            raise AnsibleError(f"ERROR - AIM not installed or clipasswordsdk not in standard location. ERROR=({e.errno}) => {e.strerror} ")
 
         return [result_dict]
 
diff --git a/plugins/lookup/dig.py b/plugins/lookup/dig.py
index 322cd814d5..cbb597b7b5 100644
--- a/plugins/lookup/dig.py
+++ b/plugins/lookup/dig.py
@@ -220,7 +220,6 @@ RETURN = """
 
 from ansible.errors import AnsibleError
 from ansible.plugins.lookup import LookupBase
-from ansible.module_utils.common.text.converters import to_native
 from ansible.module_utils.parsing.convert_bool import boolean
 from ansible.utils.display import Display
 import socket
@@ -345,7 +344,7 @@ class LookupModule(LookupBase):
         try:
             rdclass = dns.rdataclass.from_text(self.get_option('class'))
         except Exception as e:
-            raise AnsibleError(f"dns lookup illegal CLASS: {to_native(e)}")
+            raise AnsibleError(f"dns lookup illegal CLASS: {e}")
         myres.retry_servfail = self.get_option('retry_servfail')
 
         for t in terms:
@@ -363,7 +362,7 @@ class LookupModule(LookupBase):
                             nsaddr = dns.resolver.query(ns)[0].address
                             nameservers.append(nsaddr)
                         except Exception as e:
-                            raise AnsibleError(f"dns lookup NS: {to_native(e)}")
+                            raise AnsibleError(f"dns lookup NS: {e}")
                 continue
             if '=' in t:
                 try:
@@ -379,7 +378,7 @@ class LookupModule(LookupBase):
                     try:
                         rdclass = dns.rdataclass.from_text(arg)
                     except Exception as e:
-                        raise AnsibleError(f"dns lookup illegal CLASS: {to_native(e)}")
+                        raise AnsibleError(f"dns lookup illegal CLASS: {e}")
                 elif opt == 'retry_servfail':
                     myres.retry_servfail = boolean(arg)
                 elif opt == 'fail_on_error':
@@ -416,7 +415,7 @@ class LookupModule(LookupBase):
                 except dns.exception.SyntaxError:
                     pass
                 except Exception as e:
-                    raise AnsibleError(f"dns.reversename unhandled exception {to_native(e)}")
+                    raise AnsibleError(f"dns.reversename unhandled exception {e}")
             domains = reversed_domains
 
         if len(domains) > 1:
@@ -445,20 +444,20 @@ class LookupModule(LookupBase):
                             ret.append(rd)
                         except Exception as err:
                             if fail_on_error:
-                                raise AnsibleError(f"Lookup failed: {str(err)}")
+                                raise AnsibleError(f"Lookup failed: {err}")
                             ret.append(str(err))
 
             except dns.resolver.NXDOMAIN as err:
                 if fail_on_error:
-                    raise AnsibleError(f"Lookup failed: {str(err)}")
+                    raise AnsibleError(f"Lookup failed: {err}")
                 if not real_empty:
                     ret.append('NXDOMAIN')
             except (dns.resolver.NoAnswer, dns.resolver.Timeout, dns.resolver.NoNameservers) as err:
                 if fail_on_error:
-                    raise AnsibleError(f"Lookup failed: {str(err)}")
+                    raise AnsibleError(f"Lookup failed: {err}")
                 if not real_empty:
                     ret.append("")
             except dns.exception.DNSException as err:
-                raise AnsibleError(f"dns.resolver unhandled exception {to_native(err)}")
+                raise AnsibleError(f"dns.resolver unhandled exception {err}")
 
         return ret
diff --git a/plugins/lookup/dnstxt.py b/plugins/lookup/dnstxt.py
index 296d916368..baaa63aa98 100644
--- a/plugins/lookup/dnstxt.py
+++ b/plugins/lookup/dnstxt.py
@@ -64,7 +64,6 @@ except ImportError:
     pass
 
 from ansible.errors import AnsibleError
-from ansible.module_utils.common.text.converters import to_native
 from ansible.plugins.lookup import LookupBase
 
 # ==============================================================
@@ -108,7 +107,7 @@ class LookupModule(LookupBase):
                     continue
                 string = ''
             except DNSException as e:
-                raise AnsibleError(f"dns.resolver unhandled exception {to_native(e)}")
+                raise AnsibleError(f"dns.resolver unhandled exception {e}")
 
             ret.append(''.join(string))
 
diff --git a/plugins/lookup/etcd3.py b/plugins/lookup/etcd3.py
index 3bbeb06bb3..c67e975b97 100644
--- a/plugins/lookup/etcd3.py
+++ b/plugins/lookup/etcd3.py
@@ -168,7 +168,7 @@ def etcd3_client(client_params):
         etcd = etcd3.client(**client_params)
         etcd.status()
     except Exception as exp:
-        raise AnsibleLookupError(f'Cannot connect to etcd cluster: {to_native(exp)}')
+        raise AnsibleLookupError(f'Cannot connect to etcd cluster: {exp}')
     return etcd
 
 
@@ -218,12 +218,12 @@ class LookupModule(LookupBase):
                         if val and meta:
                             ret.append({'key': to_native(meta.key), 'value': to_native(val)})
                 except Exception as exp:
-                    display.warning(f'Caught except during etcd3.get_prefix: {to_native(exp)}')
+                    display.warning(f'Caught except during etcd3.get_prefix: {exp}')
             else:
                 try:
                     val, meta = etcd.get(term)
                     if val and meta:
                         ret.append({'key': to_native(meta.key), 'value': to_native(val)})
                 except Exception as exp:
-                    display.warning(f'Caught except during etcd3.get: {to_native(exp)}')
+                    display.warning(f'Caught except during etcd3.get: {exp}')
         return ret
diff --git a/plugins/lookup/keyring.py b/plugins/lookup/keyring.py
index 65a3301f2d..ebc35a8ee1 100644
--- a/plugins/lookup/keyring.py
+++ b/plugins/lookup/keyring.py
@@ -57,7 +57,7 @@ class LookupModule(LookupBase):
 
     def run(self, terms, variables=None, **kwargs):
         if not HAS_KEYRING:
-            raise AnsibleError(u"Can't LOOKUP(keyring): missing required python library 'keyring'")
+            raise AnsibleError("Can't LOOKUP(keyring): missing required python library 'keyring'")
 
         self.set_options(var_options=variables, direct=kwargs)
 
diff --git a/plugins/lookup/lmdb_kv.py b/plugins/lookup/lmdb_kv.py
index 7ff3930bed..c09321d081 100644
--- a/plugins/lookup/lmdb_kv.py
+++ b/plugins/lookup/lmdb_kv.py
@@ -96,7 +96,7 @@ class LookupModule(LookupBase):
         try:
             env = lmdb.open(str(db), readonly=True)
         except Exception as e:
-            raise AnsibleError(f"LMDB can't open database {db}: {to_native(e)}")
+            raise AnsibleError(f"LMDB cannot open database {db}: {e}")
 
         ret = []
         if len(terms) == 0:
diff --git a/plugins/lookup/manifold.py b/plugins/lookup/manifold.py
index 0240aa442b..9dbd2e118f 100644
--- a/plugins/lookup/manifold.py
+++ b/plugins/lookup/manifold.py
@@ -121,13 +121,13 @@ class ManifoldApiClient(object):
         except ValueError:
             raise ApiError(f'JSON response can\'t be parsed while requesting {url}:\n{data}')
         except HTTPError as e:
-            raise ApiError(f'Server returned: {str(e)} while requesting {url}:\n{e.read()}')
+            raise ApiError(f'Server returned: {e} while requesting {url}:\n{e.read()}')
         except URLError as e:
-            raise ApiError(f'Failed lookup url for {url} : {str(e)}')
+            raise ApiError(f'Failed lookup url for {url} : {e}')
         except SSLValidationError as e:
-            raise ApiError(f'Error validating the server\'s certificate for {url}: {str(e)}')
+            raise ApiError(f'Error validating the server\'s certificate for {url}: {e}')
         except ConnectionError as e:
-            raise ApiError(f'Error connecting to {url}: {str(e)}')
+            raise ApiError(f'Error connecting to {url}: {e}')
 
     def get_resources(self, team_id=None, project_id=None, label=None):
         """
@@ -270,7 +270,7 @@ class LookupModule(LookupBase):
             ret = [credentials]
             return ret
         except ApiError as e:
-            raise AnsibleError(f'API Error: {str(e)}')
+            raise AnsibleError(f'API Error: {e}')
         except AnsibleError as e:
             raise e
         except Exception:
diff --git a/plugins/lookup/onepassword.py b/plugins/lookup/onepassword.py
index 2d9f01e3de..60e0b2a69c 100644
--- a/plugins/lookup/onepassword.py
+++ b/plugins/lookup/onepassword.py
@@ -169,7 +169,7 @@ class OnePassCLIBase(with_metaclass(abc.ABCMeta, object)):
         rc = p.wait()
 
         if not ignore_errors and rc != expected_rc:
-            raise AnsibleLookupError(to_text(err))
+            raise AnsibleLookupError(str(err))
 
         return rc, out, err
 
diff --git a/plugins/lookup/tss.py b/plugins/lookup/tss.py
index 344fa01678..ffae6bb824 100644
--- a/plugins/lookup/tss.py
+++ b/plugins/lookup/tss.py
@@ -325,12 +325,12 @@ class TSSClient(object):
                     if i['isFile']:
                         try:
                             file_content = i['itemValue'].content
-                            with open(os.path.join(file_download_path, f"{str(obj['id'])}_{i['slug']}"), "wb") as f:
+                            with open(os.path.join(file_download_path, f"{obj['id']}_{i['slug']}"), "wb") as f:
                                 f.write(file_content)
                         except ValueError:
-                            raise AnsibleOptionsError(f"Failed to download {str(i['slug'])}")
+                            raise AnsibleOptionsError(f"Failed to download {i['slug']}")
                         except AttributeError:
-                            display.warning(f"Could not read file content for {str(i['slug'])}")
+                            display.warning(f"Could not read file content for {i['slug']}")
                         finally:
                             i['itemValue'] = "*** Not Valid For Display ***"
                 else:
diff --git a/plugins/plugin_utils/unsafe.py b/plugins/plugin_utils/unsafe.py
index 4fdb8b3d51..49e7a39639 100644
--- a/plugins/plugin_utils/unsafe.py
+++ b/plugins/plugin_utils/unsafe.py
@@ -15,7 +15,7 @@ from ansible.utils.unsafe_proxy import (
     wrap_var as _make_unsafe,
 )
 
-_RE_TEMPLATE_CHARS = re.compile(u'[{}]')
+_RE_TEMPLATE_CHARS = re.compile('[{}]')
 _RE_TEMPLATE_CHARS_BYTES = re.compile(b'[{}]')