diff --git a/docs/cookbook/examples/ami_handler.rst b/docs/cookbook/examples/ami_handler.rst index 3fb5e357..6b8f3384 100644 --- a/docs/cookbook/examples/ami_handler.rst +++ b/docs/cookbook/examples/ami_handler.rst @@ -218,7 +218,7 @@ via ``POST``. If you're using a custom protocol the data is sent via ``GET``. params = params.split("&") p = {"column_display_names": [], "cols": []} for arg in params: - key, value = map(six.moves.urllib.parse.unquote, arg.split("=", 1)) + key, value = map(urllib.parse.unquote, arg.split("=", 1)) if key == "column_display_names" or key == "cols": p[key].append(value) else: diff --git a/shotgun_api3/lib/mockgun/schema.py b/shotgun_api3/lib/mockgun/schema.py index 5d5019df..ab671629 100644 --- a/shotgun_api3/lib/mockgun/schema.py +++ b/shotgun_api3/lib/mockgun/schema.py @@ -30,8 +30,8 @@ ----------------------------------------------------------------------------- """ -from ..six.moves import cPickle as pickle import os +import pickle from .errors import MockgunError diff --git a/shotgun_api3/shotgun.py b/shotgun_api3/shotgun.py index 2bede5da..c7ab8a50 100644 --- a/shotgun_api3/shotgun.py +++ b/shotgun_api3/shotgun.py @@ -29,9 +29,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """ +import base64 import copy import datetime import json +import http.client # Used for secure file upload +import http.cookiejar # used for attachment upload +import io # used for attachment upload import logging import os import re @@ -40,29 +44,22 @@ import stat # used for attachment upload import sys import time +import urllib.error +import urllib.parse +import urllib.request import uuid # used for attachment upload +# Import Error and ResponseError (even though they're unused in this file) since they need +# to be exposed as part of the API. +from xmlrpc.client import Error, ProtocolError, ResponseError # noqa + # Python 2/3 compatibility from .lib import six from .lib import sgsix from .lib import sgutils -from .lib.six import BytesIO # used for attachment upload -from .lib.six.moves import map -from .lib.six.moves import http_cookiejar # used for attachment upload -from .lib.six.moves import urllib -from .lib.six.moves import http_client # Used for secure file upload. from .lib.httplib2 import Http, ProxyInfo, socks, ssl_error_classes from .lib.sgtimezone import SgTimezone -# Import Error and ResponseError (even though they're unused in this file) since they need -# to be exposed as part of the API. -from .lib.six.moves.xmlrpc_client import Error, ProtocolError, ResponseError # noqa - -if six.PY3: - from base64 import encodebytes as base64encode -else: - from base64 import encodestring as base64encode - LOG = logging.getLogger("shotgun_api3") """ @@ -708,13 +705,13 @@ def __init__( # and auth header # Do NOT self._split_url(self.base_url) here, as it contains the lower - # case version of the base_url argument. Doing so would base64encode + # case version of the base_url argument. Doing so would base64.encodebytes # the lowercase version of the credentials. auth, self.config.server = self._split_url(base_url) if auth: - auth = base64encode(urllib.parse.unquote(auth).encode("utf-8")).decode( - "utf-8" - ) + auth = base64.encodebytes( + urllib.parse.unquote(auth).encode("utf-8") + ).decode("utf-8") self.config.authorization = "Basic " + auth.strip() # foo:bar@123.456.789.012:3456 @@ -3003,8 +3000,8 @@ def get_auth_cookie_handler(self): This is used internally for downloading attachments from FPTR. """ sid = self.get_session_token() - cj = http_cookiejar.LWPCookieJar() - c = http_cookiejar.Cookie( + cj = http.cookiejar.LWPCookieJar() + c = http.cookiejar.Cookie( "0", "_session_id", sid, @@ -4433,7 +4430,7 @@ def _multipart_upload_file_to_storage(self, path, upload_info): data_size = len(data) # keep data as a stream so that we don't need to worry how it was # encoded. - data = BytesIO(data) + data = io.BytesIO(data) bytes_read += data_size part_url = self._get_upload_part_link( upload_info, filename, part_number @@ -4663,13 +4660,13 @@ def _send_form(self, url, params): raise ShotgunError("Max attemps limit reached.") -class CACertsHTTPSConnection(http_client.HTTPConnection): +class CACertsHTTPSConnection(http.client.HTTPConnection): """ " This class allows to create an HTTPS connection that uses the custom certificates passed in. """ - default_port = http_client.HTTPS_PORT + default_port = http.client.HTTPS_PORT def __init__(self, *args, **kwargs): """ @@ -4761,7 +4758,7 @@ def encode(self, params, files, boundary=None, buffer=None): # We'll do this across both python 2/3 rather than add more branching. boundary = uuid.uuid4() if buffer is None: - buffer = BytesIO() + buffer = io.BytesIO() for key, value in params: if isinstance(key, bytes): key = key.decode("utf-8") diff --git a/tests/base.py b/tests/base.py index cc863499..e30ec01a 100644 --- a/tests/base.py +++ b/tests/base.py @@ -1,31 +1,20 @@ """Base class for Flow Production Tracking API tests.""" +import configparser import contextlib +import json import os import random import re import time import unittest +import urllib.error from . import mock import shotgun_api3 as api -from shotgun_api3.shotgun import json from shotgun_api3.shotgun import ServerCapabilities from shotgun_api3.lib import six -from shotgun_api3.lib.six.moves import urllib -from shotgun_api3.lib.six.moves.configparser import ConfigParser - -try: - # Attempt to import skip from unittest. Since this was added in Python 2.7 - # in the case that we're running on Python 2.6 we'll need a decorator to - # provide some equivalent functionality. - from unittest import skip -except ImportError: - # On Python 2.6 we'll just have to ignore tests that are skipped -- we won't - # mark them as skipped, but we will not fail on them. - def skip(f): - return lambda self: None THUMBNAIL_MAX_ATTEMPTS = 30 @@ -456,7 +445,7 @@ def config_keys(self): ] def read_config(self, config_path): - config_parser = ConfigParser() + config_parser = configparser.ConfigParser() config_parser.read(config_path) for section in config_parser.sections(): for option in config_parser.options(section): diff --git a/tests/test_api.py b/tests/test_api.py index 751ace79..5c618d7a 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -22,6 +22,9 @@ import time import types import unittest +import urllib.parse +import urllib.request +import urllib.error import uuid import warnings @@ -33,8 +36,6 @@ # class for the current Python version. from shotgun_api3.lib.sgsix import ShotgunSSLError -from shotgun_api3.lib.six.moves import range, urllib - import shotgun_api3 from . import base @@ -629,7 +630,7 @@ def test_linked_thumbnail_url(self): # For now skip tests that are erroneously failling on some sites to # allow CI to pass until the known issue causing this is resolved. - @base.skip("Skipping test that erroneously fails on some sites.") + @unittest.skip("Skipping test that erroneously fails on some sites.") def test_share_thumbnail(self): """share thumbnail between two entities""" @@ -2933,7 +2934,7 @@ def _check_attachment(self, data, attachment_id, additional_fields): # For now skip tests that are erroneously failling on some sites to # allow CI to pass until the known issue causing this is resolved. - @base.skip("Skipping test that erroneously fails on some sites.") + @unittest.skip("Skipping test that erroneously fails on some sites.") def test_simple(self): """ Test note reply thread API call @@ -3012,7 +3013,7 @@ def test_simple(self): # For now skip tests that are erroneously failling on some sites to # allow CI to pass until the known issue causing this is resolved. - @base.skip("Skipping test that erroneously fails on some sites.") + @unittest.skip("Skipping test that erroneously fails on some sites.") def test_complex(self): """ Test note reply thread API call with additional params diff --git a/tests/test_client.py b/tests/test_client.py index 9cb50a16..27e384b1 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -12,25 +12,21 @@ CRUD functions. These tests always use a mock http connection so not not need a live server to run against.""" +import configparser +import base64 import datetime +import json import os import platform import re import sys import time import unittest +import urllib.parse +import urllib.error -from shotgun_api3.lib.six.moves import urllib from shotgun_api3.lib import six, sgutils -try: - import simplejson as json -except ImportError: - try: - import json as json - except ImportError: - import shotgun_api3.lib.simplejson as json - from . import mock import shotgun_api3.lib.httplib2 as httplib2 @@ -38,17 +34,12 @@ from shotgun_api3.shotgun import ServerCapabilities, SG_TIMEZONE from . import base -if six.PY3: - from base64 import encodebytes as base64encode -else: - from base64 import encodestring as base64encode - def b64encode(val): if isinstance(val, str): val = val.encode("utf-8") - return base64encode(val).decode("utf-8") + return base64.encodebytes(val).decode("utf-8") class TestShotgunClient(base.MockTestBase): @@ -190,7 +181,7 @@ def test_read_config(self): """Validate that config values are properly coerced.""" this_dir = os.path.dirname(os.path.realpath(__file__)) config_path = os.path.join(this_dir, "test_config_file") - config = base.ConfigParser() + config = configparser.ConfigParser() config.read(config_path) result = config.get("SERVER_INFO", "api_key") expected = "%abce" diff --git a/tests/test_unit.py b/tests/test_unit.py index ff78253c..d2853e5d 100644 --- a/tests/test_unit.py +++ b/tests/test_unit.py @@ -13,11 +13,12 @@ import os import unittest from unittest import mock +import urllib.request +import urllib.error from .mock import patch import shotgun_api3 as api from shotgun_api3.shotgun import _is_mimetypes_broken -from shotgun_api3.lib.six.moves import range, urllib from shotgun_api3.lib.httplib2 import Http, ssl_error_classes