Skip to content

SG-38306 Python2 Removal - Part 3 - Cleanup imports #400

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

Open
wants to merge 7 commits into
base: ticket/SG-38306-python2-removal-future-wording
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion docs/cookbook/examples/ami_handler.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion shotgun_api3/lib/mockgun/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@
-----------------------------------------------------------------------------
"""

from ..six.moves import cPickle as pickle
import os
import pickle

Check notice on line 34 in shotgun_api3/lib/mockgun/schema.py

View check run for this annotation

ShotGrid Chorus / security/bandit

B403: blacklist

Consider possible security implications associated with pickle module. secure coding id: PYTH-INJC-10.

from .errors import MockgunError

Expand Down
45 changes: 21 additions & 24 deletions shotgun_api3/shotgun.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Check failure on line 54 in shotgun_api3/shotgun.py

View check run for this annotation

ShotGrid Chorus / security/semgrep

app.chorus.semgrep.rules.python.lang.security.use-defused-xmlrpc.use-defused-xmlrpc

Detected use of xmlrpc. xmlrpc is not inherently safe from vulnerabilities. Use defusedxml.xmlrpc instead.

Check failure on line 54 in shotgun_api3/shotgun.py

View check run for this annotation

ShotGrid Chorus / security/bandit

B411: blacklist

Using Error to parse untrusted XML data is known to be vulnerable to XML attacks. Use defusedxml.xmlrpc.monkey_patch() function to monkey-patch xmlrpclib and mitigate XML vulnerabilities.

# 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")
"""
Expand Down Expand Up @@ -708,13 +705,13 @@
# 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:[email protected]:3456
Expand Down Expand Up @@ -3003,8 +3000,8 @@
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,
Expand Down Expand Up @@ -4433,7 +4430,7 @@
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
Expand Down Expand Up @@ -4663,13 +4660,13 @@
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):
"""
Expand Down Expand Up @@ -4761,7 +4758,7 @@
# 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")
Expand Down
19 changes: 4 additions & 15 deletions tests/base.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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):
Expand Down
11 changes: 6 additions & 5 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
import time
import types
import unittest
import urllib.parse
import urllib.request
import urllib.error
import uuid
import warnings

Expand All @@ -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
Expand Down Expand Up @@ -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"""

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
23 changes: 7 additions & 16 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,43 +12,34 @@
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
import shotgun_api3 as api
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):
Expand Down Expand Up @@ -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"
Expand Down
3 changes: 2 additions & 1 deletion tests/test_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down