mirror of
https://github.com/ansible/awx.git
synced 2026-05-06 17:07:36 -02:30
remove python2 support from awxkit
This commit is contained in:
@@ -1,8 +1,6 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import json
|
import json
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
from awxkit.utils import poll_until
|
from awxkit.utils import poll_until
|
||||||
from awxkit.exceptions import WaitUntilTimeout
|
from awxkit.exceptions import WaitUntilTimeout
|
||||||
|
|
||||||
@@ -50,7 +48,7 @@ class HasStatus(object):
|
|||||||
return self.wait_until_status(self.started_statuses, interval=interval, timeout=timeout)
|
return self.wait_until_status(self.started_statuses, interval=interval, timeout=timeout)
|
||||||
|
|
||||||
def assert_status(self, status_list, msg=None):
|
def assert_status(self, status_list, msg=None):
|
||||||
if isinstance(status_list, six.text_type):
|
if isinstance(status_list, str):
|
||||||
status_list = [status_list]
|
status_list = [status_list]
|
||||||
if self.status in status_list:
|
if self.status in status_list:
|
||||||
# include corner cases in is_successful logic
|
# include corner cases in is_successful logic
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from six.moves import http_client as http
|
import http.client as http
|
||||||
|
|
||||||
import awxkit.exceptions as exc
|
import awxkit.exceptions as exc
|
||||||
from awxkit.api.mixins import DSAdapter, HasCopy, HasCreate
|
from awxkit.api.mixins import DSAdapter, HasCopy, HasCreate
|
||||||
@@ -19,10 +19,7 @@ from awxkit.utils import (
|
|||||||
from . import base, page
|
from . import base, page
|
||||||
from .page import exception_from_status_code
|
from .page import exception_from_status_code
|
||||||
|
|
||||||
try:
|
from urllib.parse import urljoin
|
||||||
from urllib.parse import urljoin
|
|
||||||
except ImportError:
|
|
||||||
from urlparse import urljoin
|
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import json
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
from requests import Response
|
from requests import Response
|
||||||
import six
|
import http.client as http
|
||||||
from six.moves import http_client as http
|
|
||||||
|
|
||||||
from awxkit.utils import (
|
from awxkit.utils import (
|
||||||
PseudoNamespace,
|
PseudoNamespace,
|
||||||
@@ -170,10 +169,7 @@ class Page(object):
|
|||||||
def from_json(cls, raw):
|
def from_json(cls, raw):
|
||||||
resp = Response()
|
resp = Response()
|
||||||
data = json.dumps(raw)
|
data = json.dumps(raw)
|
||||||
if six.PY3:
|
resp._content = bytes(data, 'utf-8')
|
||||||
resp._content = bytes(data, 'utf-8')
|
|
||||||
else:
|
|
||||||
resp._content = data
|
|
||||||
resp.encoding = 'utf-8'
|
resp.encoding = 'utf-8'
|
||||||
resp.status_code = 200
|
resp.status_code = 200
|
||||||
return cls(r=resp)
|
return cls(r=resp)
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import pkg_resources
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
from requests.exceptions import RequestException
|
from requests.exceptions import RequestException
|
||||||
import six
|
|
||||||
|
|
||||||
from .custom import handle_custom_actions
|
from .custom import handle_custom_actions
|
||||||
from .format import (add_authentication_arguments,
|
from .format import (add_authentication_arguments,
|
||||||
@@ -203,15 +202,7 @@ class CLI(object):
|
|||||||
if hasattr(response, 'rc'):
|
if hasattr(response, 'rc'):
|
||||||
raise SystemExit(response.rc)
|
raise SystemExit(response.rc)
|
||||||
else:
|
else:
|
||||||
if six.PY3:
|
self.parser.print_help()
|
||||||
self.parser.print_help()
|
|
||||||
elif six.PY2 and not self.help:
|
|
||||||
# Unfortunately, argparse behavior between py2 and py3
|
|
||||||
# changed in a notable way when required subparsers
|
|
||||||
# have invalid (or missing) arguments specified
|
|
||||||
# see: https://github.com/python/cpython/commit/f97c59aaba2d93e48cbc6d25f7ff9f9c87f8d0b2
|
|
||||||
print('\nargument resource: invalid choice')
|
|
||||||
raise SystemExit(2)
|
|
||||||
|
|
||||||
def parse_action(self, page, from_sphinx=False):
|
def parse_action(self, page, from_sphinx=False):
|
||||||
"""Perform an HTTP OPTIONS request
|
"""Perform an HTTP OPTIONS request
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import functools
|
import functools
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from six import with_metaclass, PY3
|
|
||||||
|
|
||||||
from .stdout import monitor, monitor_workflow
|
from .stdout import monitor, monitor_workflow
|
||||||
from .utils import CustomRegistryMeta, color_enabled
|
from .utils import CustomRegistryMeta, color_enabled
|
||||||
from awxkit import api
|
from awxkit import api
|
||||||
@@ -24,7 +22,7 @@ class CustomActionRegistryMeta(CustomRegistryMeta):
|
|||||||
return ' '.join([self.resource, self.action])
|
return ' '.join([self.resource, self.action])
|
||||||
|
|
||||||
|
|
||||||
class CustomAction(with_metaclass(CustomActionRegistryMeta)):
|
class CustomAction(metaclass=CustomActionRegistryMeta):
|
||||||
"""Base class for defining a custom action for a resource."""
|
"""Base class for defining a custom action for a resource."""
|
||||||
|
|
||||||
def __init__(self, page):
|
def __init__(self, page):
|
||||||
@@ -549,11 +547,8 @@ class SettingsModify(CustomAction):
|
|||||||
return resp.from_json({'key': key, 'value': resp[key]})
|
return resp.from_json({'key': key, 'value': resp[key]})
|
||||||
|
|
||||||
def is_json(self, data):
|
def is_json(self, data):
|
||||||
err = ValueError
|
|
||||||
if PY3:
|
|
||||||
err = json.decoder.JSONDecodeError
|
|
||||||
try:
|
try:
|
||||||
json.loads(data)
|
json.loads(data)
|
||||||
except err:
|
except json.decoder.JSONDecodeError:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import locale
|
|||||||
import json
|
import json
|
||||||
from distutils.util import strtobool
|
from distutils.util import strtobool
|
||||||
|
|
||||||
import six
|
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
from awxkit.cli.utils import colored
|
from awxkit.cli.utils import colored
|
||||||
@@ -81,7 +80,7 @@ def add_output_formatting_arguments(parser, env):
|
|||||||
def format_response(response, fmt='json', filter='.', changed=False):
|
def format_response(response, fmt='json', filter='.', changed=False):
|
||||||
if response is None:
|
if response is None:
|
||||||
return # HTTP 204
|
return # HTTP 204
|
||||||
if isinstance(response, six.text_type):
|
if isinstance(response, str):
|
||||||
return response
|
return response
|
||||||
|
|
||||||
if 'results' in response.__dict__:
|
if 'results' in response.__dict__:
|
||||||
@@ -115,7 +114,7 @@ def format_jq(output, fmt):
|
|||||||
results = []
|
results = []
|
||||||
for x in jq.jq(fmt).transform(output, multiple_output=True):
|
for x in jq.jq(fmt).transform(output, multiple_output=True):
|
||||||
if x not in (None, ''):
|
if x not in (None, ''):
|
||||||
if isinstance(x, six.text_type):
|
if isinstance(x, str):
|
||||||
results.append(x)
|
results.append(x)
|
||||||
else:
|
else:
|
||||||
results.append(json.dumps(x))
|
results.append(json.dumps(x))
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import sys
|
|||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
from distutils.util import strtobool
|
from distutils.util import strtobool
|
||||||
import six
|
|
||||||
|
|
||||||
from .custom import CustomAction
|
from .custom import CustomAction
|
||||||
from .format import add_output_formatting_arguments
|
from .format import add_output_formatting_arguments
|
||||||
@@ -182,7 +181,7 @@ class ResourceOptionsParser(object):
|
|||||||
for k, v in parsed.items():
|
for k, v in parsed.items():
|
||||||
# add support for file reading at top-level JSON keys
|
# add support for file reading at top-level JSON keys
|
||||||
# (to make things like SSH key data easier to work with)
|
# (to make things like SSH key data easier to work with)
|
||||||
if isinstance(v, six.text_type) and v.startswith('@'):
|
if isinstance(v, str) and v.startswith('@'):
|
||||||
path = os.path.expanduser(v[1:])
|
path = os.path.expanduser(v[1:])
|
||||||
parsed[k] = open(path).read()
|
parsed[k] = open(path).read()
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
from six import PY3, with_metaclass
|
|
||||||
|
|
||||||
from awxkit import api, config
|
from awxkit import api, config
|
||||||
from awxkit.utils import to_str
|
from awxkit.utils import to_str
|
||||||
from awxkit.api.pages import Page
|
from awxkit.api.pages import Page
|
||||||
@@ -45,7 +43,7 @@ DEPRECATED_RESOURCES_REVERSE = dict(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class CustomCommand(with_metaclass(CustomRegistryMeta)):
|
class CustomCommand(metaclass=CustomRegistryMeta):
|
||||||
"""Base class for implementing custom commands.
|
"""Base class for implementing custom commands.
|
||||||
|
|
||||||
Custom commands represent static code which should run - they are
|
Custom commands represent static code which should run - they are
|
||||||
@@ -153,18 +151,7 @@ def parse_resource(client, skip_deprecated=False):
|
|||||||
k, help='', **kwargs
|
k, help='', **kwargs
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
resource = client.parser.parse_known_args()[0].resource
|
||||||
resource = client.parser.parse_known_args()[0].resource
|
|
||||||
except SystemExit:
|
|
||||||
if PY3:
|
|
||||||
raise
|
|
||||||
else:
|
|
||||||
# Unfortunately, argparse behavior between py2 and py3
|
|
||||||
# changed in a notable way when required subparsers
|
|
||||||
# have invalid (or missing) arguments specified
|
|
||||||
# see: https://github.com/python/cpython/commit/f97c59aaba2d93e48cbc6d25f7ff9f9c87f8d0b2
|
|
||||||
# In py2, this raises a SystemExit; which we want to _ignore_
|
|
||||||
resource = None
|
|
||||||
if resource in DEPRECATED_RESOURCES.values():
|
if resource in DEPRECATED_RESOURCES.values():
|
||||||
client.argv[
|
client.argv[
|
||||||
client.argv.index(resource)
|
client.argv.index(resource)
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
_color = threading.local()
|
_color = threading.local()
|
||||||
_color.enabled = True
|
_color.enabled = True
|
||||||
|
|
||||||
@@ -38,29 +36,6 @@ class CustomRegistryMeta(type):
|
|||||||
|
|
||||||
class HelpfulArgumentParser(ArgumentParser):
|
class HelpfulArgumentParser(ArgumentParser):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super(HelpfulArgumentParser, self).__init__(*args, **kwargs)
|
|
||||||
if six.PY2:
|
|
||||||
# backport parser aliases support to py2
|
|
||||||
# see: https://github.com/python/cpython/commit/fd311a712d5876c3a3efff265978452eea759f85
|
|
||||||
SubParsersAction = self._registries['action']['parsers']
|
|
||||||
|
|
||||||
class _SubParsersAction(SubParsersAction):
|
|
||||||
|
|
||||||
def add_parser(self, name, **kwargs):
|
|
||||||
aliases = kwargs.pop('aliases', [])
|
|
||||||
parser = super(_SubParsersAction, self).add_parser(name, **kwargs)
|
|
||||||
if aliases:
|
|
||||||
self._choices_actions[-1].metavar = ' '.join([
|
|
||||||
name,
|
|
||||||
'({})'.format(', '.join(aliases))
|
|
||||||
])
|
|
||||||
for alias in aliases:
|
|
||||||
self._name_parser_map[alias] = parser
|
|
||||||
return parser
|
|
||||||
|
|
||||||
self._registries['action']['parsers'] = _SubParsersAction
|
|
||||||
|
|
||||||
def error(self, message): # pragma: nocover
|
def error(self, message): # pragma: nocover
|
||||||
"""Prints a usage message incorporating the message to stderr and
|
"""Prints a usage message incorporating the message to stderr and
|
||||||
exits.
|
exits.
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import sys
|
|||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import six
|
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
from awxkit.words import words
|
from awxkit.words import words
|
||||||
@@ -132,7 +131,7 @@ class PseudoNamespace(dict):
|
|||||||
|
|
||||||
|
|
||||||
def is_relative_endpoint(candidate):
|
def is_relative_endpoint(candidate):
|
||||||
return isinstance(candidate, (six.text_type,)) and candidate.startswith('/api/')
|
return isinstance(candidate, (str,)) and candidate.startswith('/api/')
|
||||||
|
|
||||||
|
|
||||||
def is_class_or_instance(obj, cls):
|
def is_class_or_instance(obj, cls):
|
||||||
@@ -321,19 +320,9 @@ def update_payload(payload, fields, kwargs):
|
|||||||
|
|
||||||
|
|
||||||
def to_str(obj):
|
def to_str(obj):
|
||||||
if six.PY3:
|
if isinstance(obj, bytes):
|
||||||
if isinstance(obj, bytes):
|
return obj.decode('utf-8')
|
||||||
return obj.decode('utf-8')
|
return obj
|
||||||
return obj
|
|
||||||
if not isinstance(obj, six.text_type):
|
|
||||||
try:
|
|
||||||
return str(obj)
|
|
||||||
except UnicodeDecodeError:
|
|
||||||
try:
|
|
||||||
obj = six.text_type(obj, 'utf8')
|
|
||||||
except UnicodeDecodeError:
|
|
||||||
obj = obj.decode('latin1')
|
|
||||||
return obj.encode('utf8')
|
|
||||||
|
|
||||||
|
|
||||||
def to_bool(obj):
|
def to_bool(obj):
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import atexit
|
|||||||
import json
|
import json
|
||||||
import ssl
|
import ssl
|
||||||
|
|
||||||
from six.moves.queue import Queue, Empty
|
from queue import Queue, Empty
|
||||||
from six.moves.urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
from awxkit.config import config
|
from awxkit.config import config
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,2 @@
|
|||||||
PyYAML
|
PyYAML
|
||||||
requests
|
requests
|
||||||
six
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ setup(
|
|||||||
},
|
},
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
install_requires=requirements,
|
install_requires=requirements,
|
||||||
python_requires=">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*",
|
python_requires=">=3.6",
|
||||||
extras_require={
|
extras_require={
|
||||||
'formatting': ['jq'],
|
'formatting': ['jq'],
|
||||||
'websockets': ['websocket-client>0.54.0'],
|
'websockets': ['websocket-client>0.54.0'],
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import unittest
|
import unittest
|
||||||
try:
|
from io import StringIO
|
||||||
from StringIO import StringIO
|
|
||||||
except ImportError:
|
|
||||||
from io import StringIO
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from requests import Response
|
from requests import Response
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
try:
|
from unittest.mock import patch
|
||||||
from unittest.mock import patch
|
|
||||||
except ImportError:
|
|
||||||
from mock import patch
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,8 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
try:
|
from unittest import mock
|
||||||
from unittest import mock
|
|
||||||
except ImportError:
|
|
||||||
import mock
|
|
||||||
import pytest
|
import pytest
|
||||||
import six
|
|
||||||
|
|
||||||
from awxkit import utils
|
from awxkit import utils
|
||||||
from awxkit import exceptions as exc
|
from awxkit import exceptions as exc
|
||||||
@@ -83,7 +79,7 @@ def test_load_invalid_json_or_yaml(inp):
|
|||||||
reason='this is only intended to be used in py3, not the CLI'
|
reason='this is only intended to be used in py3, not the CLI'
|
||||||
)
|
)
|
||||||
def test_random_titles_are_unicode(non_ascii):
|
def test_random_titles_are_unicode(non_ascii):
|
||||||
assert isinstance(utils.random_title(non_ascii=non_ascii), six.text_type)
|
assert isinstance(utils.random_title(non_ascii=non_ascii), str)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('non_ascii', [True, False])
|
@pytest.mark.parametrize('non_ascii', [True, False])
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
try:
|
from unittest.mock import patch
|
||||||
from unittest.mock import patch
|
|
||||||
except ImportError:
|
|
||||||
from mock import patch
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from awxkit.ws import WSClient
|
from awxkit.ws import WSClient
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ skip_missing_interpreters = true
|
|||||||
# skipsdist = true
|
# skipsdist = true
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
|
basepython = python3.6
|
||||||
passenv = TRAVIS TRAVIS_JOB_ID TRAVIS_BRANCH
|
passenv = TRAVIS TRAVIS_JOB_ID TRAVIS_BRANCH
|
||||||
setenv =
|
setenv =
|
||||||
PYTHONPATH = {toxinidir}:{env:PYTHONPATH:}:.
|
PYTHONPATH = {toxinidir}:{env:PYTHONPATH:}:.
|
||||||
@@ -21,7 +22,6 @@ deps =
|
|||||||
commands = coverage run --parallel --source awxkit -m pytest --doctest-glob='*.md' --junit-xml=report.xml {posargs}
|
commands = coverage run --parallel --source awxkit -m pytest --doctest-glob='*.md' --junit-xml=report.xml {posargs}
|
||||||
|
|
||||||
[testenv:lint]
|
[testenv:lint]
|
||||||
basepython = python3.6
|
|
||||||
deps =
|
deps =
|
||||||
{[testenv]deps}
|
{[testenv]deps}
|
||||||
flake8
|
flake8
|
||||||
@@ -32,7 +32,6 @@ commands =
|
|||||||
- coverage erase
|
- coverage erase
|
||||||
|
|
||||||
[testenv:coveralls]
|
[testenv:coveralls]
|
||||||
basepython = python3.6
|
|
||||||
commands=
|
commands=
|
||||||
- coverage combine
|
- coverage combine
|
||||||
- coverage report -m
|
- coverage report -m
|
||||||
@@ -43,4 +42,4 @@ max-line-length = 120
|
|||||||
|
|
||||||
[pytest]
|
[pytest]
|
||||||
addopts = -v --tb=native
|
addopts = -v --tb=native
|
||||||
junit_family=xunit2
|
junit_family=xunit2
|
||||||
|
|||||||
Reference in New Issue
Block a user