Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove python2 support from awxkit #6327

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
remove python2 support from awxkit
  • Loading branch information
ryanpetrello committed Mar 19, 2020
commit 06b3e54fb1feb04a7bba870b313d0f36af66a18f
4 changes: 1 addition & 3 deletions awxkit/awxkit/api/mixins/has_status.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
from datetime import datetime
import json

import six

from awxkit.utils import poll_until
from awxkit.exceptions import WaitUntilTimeout

Expand Down Expand Up @@ -50,7 +48,7 @@ def wait_until_started(self, interval=1, timeout=60):
return self.wait_until_status(self.started_statuses, interval=interval, timeout=timeout)

def assert_status(self, status_list, msg=None):
if isinstance(status_list, six.text_type):
if isinstance(status_list, str):
status_list = [status_list]
if self.status in status_list:
# include corner cases in is_successful logic
Expand Down
7 changes: 2 additions & 5 deletions awxkit/awxkit/api/pages/credentials.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging

from six.moves import http_client as http
import http.client as http

import awxkit.exceptions as exc
from awxkit.api.mixins import DSAdapter, HasCopy, HasCreate
Expand All @@ -19,10 +19,7 @@
from . import base, page
from .page import exception_from_status_code

try:
from urllib.parse import urljoin
except ImportError:
from urlparse import urljoin
from urllib.parse import urljoin


log = logging.getLogger(__name__)
Expand Down
8 changes: 2 additions & 6 deletions awxkit/awxkit/api/pages/page.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
import re

from requests import Response
import six
from six.moves import http_client as http
import http.client as http

from awxkit.utils import (
PseudoNamespace,
Expand Down Expand Up @@ -170,10 +169,7 @@ def __item_class__(self):
def from_json(cls, raw):
resp = Response()
data = json.dumps(raw)
if six.PY3:
resp._content = bytes(data, 'utf-8')
else:
resp._content = data
resp._content = bytes(data, 'utf-8')
resp.encoding = 'utf-8'
resp.status_code = 200
return cls(r=resp)
Expand Down
11 changes: 1 addition & 10 deletions awxkit/awxkit/cli/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import sys

from requests.exceptions import RequestException
import six

from .custom import handle_custom_actions
from .format import (add_authentication_arguments,
Expand Down Expand Up @@ -203,15 +202,7 @@ def parse_resource(self, skip_deprecated=False):
if hasattr(response, 'rc'):
raise SystemExit(response.rc)
else:
if six.PY3:
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)
self.parser.print_help()

def parse_action(self, page, from_sphinx=False):
"""Perform an HTTP OPTIONS request
Expand Down
9 changes: 2 additions & 7 deletions awxkit/awxkit/cli/custom.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import functools
import json

from six import with_metaclass, PY3

from .stdout import monitor, monitor_workflow
from .utils import CustomRegistryMeta, color_enabled
from awxkit import api
Expand All @@ -24,7 +22,7 @@ def name(self):
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."""

def __init__(self, page):
Expand Down Expand Up @@ -549,11 +547,8 @@ def perform(self, key, value):
return resp.from_json({'key': key, 'value': resp[key]})

def is_json(self, data):
err = ValueError
if PY3:
err = json.decoder.JSONDecodeError
try:
json.loads(data)
except err:
except json.decoder.JSONDecodeError:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

return False
return True
5 changes: 2 additions & 3 deletions awxkit/awxkit/cli/format.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import json
from distutils.util import strtobool

import six
import yaml

from awxkit.cli.utils import colored
Expand Down Expand Up @@ -81,7 +80,7 @@ def add_output_formatting_arguments(parser, env):
def format_response(response, fmt='json', filter='.', changed=False):
if response is None:
return # HTTP 204
if isinstance(response, six.text_type):
if isinstance(response, str):
return response

if 'results' in response.__dict__:
Expand Down Expand Up @@ -115,7 +114,7 @@ def format_jq(output, fmt):
results = []
for x in jq.jq(fmt).transform(output, multiple_output=True):
if x not in (None, ''):
if isinstance(x, six.text_type):
if isinstance(x, str):
results.append(x)
else:
results.append(json.dumps(x))
Expand Down
3 changes: 1 addition & 2 deletions awxkit/awxkit/cli/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import yaml

from distutils.util import strtobool
import six

from .custom import CustomAction
from .format import add_output_formatting_arguments
Expand Down Expand Up @@ -182,7 +181,7 @@ def json_or_yaml(v):
for k, v in parsed.items():
# add support for file reading at top-level JSON keys
# (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:])
parsed[k] = open(path).read()

Expand Down
17 changes: 2 additions & 15 deletions awxkit/awxkit/cli/resource.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import os

from six import PY3, with_metaclass

from awxkit import api, config
from awxkit.utils import to_str
from awxkit.api.pages import Page
Expand Down Expand Up @@ -45,7 +43,7 @@
)


class CustomCommand(with_metaclass(CustomRegistryMeta)):
class CustomCommand(metaclass=CustomRegistryMeta):
"""Base class for implementing custom commands.

Custom commands represent static code which should run - they are
Expand Down Expand Up @@ -153,18 +151,7 @@ def parse_resource(client, skip_deprecated=False):
k, help='', **kwargs
)

try:
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
resource = client.parser.parse_known_args()[0].resource
if resource in DEPRECATED_RESOURCES.values():
client.argv[
client.argv.index(resource)
Expand Down
25 changes: 0 additions & 25 deletions awxkit/awxkit/cli/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
import sys
import threading

import six

_color = threading.local()
_color.enabled = True

Expand Down Expand Up @@ -38,29 +36,6 @@ def registry(cls):

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
"""Prints a usage message incorporating the message to stderr and
exits.
Expand Down
19 changes: 4 additions & 15 deletions awxkit/awxkit/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import re
import os

import six
import yaml

from awxkit.words import words
Expand Down Expand Up @@ -132,7 +131,7 @@ def update(self, iterable=None, **kw):


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):
Expand Down Expand Up @@ -321,19 +320,9 @@ def update_payload(payload, fields, kwargs):


def to_str(obj):
if six.PY3:
if isinstance(obj, bytes):
return obj.decode('utf-8')
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')
if isinstance(obj, bytes):
return obj.decode('utf-8')
return obj


def to_bool(obj):
Expand Down
4 changes: 2 additions & 2 deletions awxkit/awxkit/ws.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import json
import ssl

from six.moves.queue import Queue, Empty
from six.moves.urllib.parse import urlparse
from queue import Queue, Empty
from urllib.parse import urlparse

from awxkit.config import config

Expand Down
1 change: 0 additions & 1 deletion awxkit/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
PyYAML
requests
six
2 changes: 1 addition & 1 deletion awxkit/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def run(self):
},
include_package_data=True,
install_requires=requirements,
python_requires=">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*",
python_requires=">=3.6",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we start adding Trove classifiers to the setup.py? Are we intending to make awxkit, or at least awx-cli, available on pypi.org?

Copy link
Contributor Author

@ryanpetrello ryanpetrello Mar 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't currently publish to PyPI (and don't have plans to in the near future), but if we did in the future then we should definitely add Trove classifiers 👍

extras_require={
'formatting': ['jq'],
'websockets': ['websocket-client>0.54.0'],
Expand Down
5 changes: 1 addition & 4 deletions awxkit/test/cli/test_options.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import argparse
import json
import unittest
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
from io import StringIO

import pytest
from requests import Response
Expand Down
5 changes: 1 addition & 4 deletions awxkit/test/test_credentials.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
try:
from unittest.mock import patch
except ImportError:
from mock import patch
from unittest.mock import patch
import pytest


Expand Down
8 changes: 2 additions & 6 deletions awxkit/test/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,8 @@
from datetime import datetime
import sys

try:
from unittest import mock
except ImportError:
import mock
from unittest import mock
import pytest
import six

from awxkit import utils
from awxkit import exceptions as exc
Expand Down Expand Up @@ -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'
)
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])
Expand Down
5 changes: 1 addition & 4 deletions awxkit/test/test_ws.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
# -*- coding: utf-8 -*-
from collections import namedtuple

try:
from unittest.mock import patch
except ImportError:
from mock import patch
from unittest.mock import patch
import pytest

from awxkit.ws import WSClient
Expand Down
5 changes: 2 additions & 3 deletions awxkit/tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ skip_missing_interpreters = true
# skipsdist = true

[testenv]
basepython = python3.6
passenv = TRAVIS TRAVIS_JOB_ID TRAVIS_BRANCH
setenv =
PYTHONPATH = {toxinidir}:{env:PYTHONPATH:}:.
Expand All @@ -21,7 +22,6 @@ deps =
commands = coverage run --parallel --source awxkit -m pytest --doctest-glob='*.md' --junit-xml=report.xml {posargs}

[testenv:lint]
basepython = python3.6
deps =
{[testenv]deps}
flake8
Expand All @@ -32,7 +32,6 @@ commands =
- coverage erase

[testenv:coveralls]
basepython = python3.6
commands=
- coverage combine
- coverage report -m
Expand All @@ -43,4 +42,4 @@ max-line-length = 120

[pytest]
addopts = -v --tb=native
junit_family=xunit2
junit_family=xunit2