Skip to content

Commit

Permalink
SG-32657 Enable support for Python 3.10 in CI (#920)
Browse files Browse the repository at this point in the history
- Support [deprecation](https://peps.python.org/pep-0632/) of distutils for setuptools > 60.
    - We can't switch to `packaging.version.parse` because many TK components depend of `distutils.version.LooseVersion`. To handle the distutils deprecation, we're switching to the bundled version living on setuptools >= 60. The deprecation warning is still there, so we're suppressing just this one.
- Re-enable commented tests
- Support [deprecation](python/cpython#25174) of `isSet()`
- Upgrade python-api v3.4.0
  • Loading branch information
carlos-villavicencio-adsk authored Sep 25, 2023
1 parent 6766e56 commit 509eca8
Show file tree
Hide file tree
Showing 20 changed files with 3,298 additions and 174 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[![VFX Platform](https://img.shields.io/badge/vfxplatform-2020-yellow.svg)](http://www.vfxplatform.com/)
[![Python 2.7 3.7](https://img.shields.io/badge/python-2.7%20%7C%203.7-blue.svg)](https://www.python.org/)
[![VFX Platform](https://img.shields.io/badge/vfxplatform-2023%202022%202021%202020-blue.svg)](http://www.vfxplatform.com/)
[![Python 3.7 3.9 3.10](https://img.shields.io/badge/python-3.7%20%7C%203.9%20%7C%203.10-blue.svg)](https://www.python.org/)
[![Reference Documentation](http://img.shields.io/badge/doc-reference-blue.svg)](http://developer.shotgridsoftware.com/tk-core)
[![Build Status](https://dev.azure.com/shotgun-ecosystem/Toolkit/_apis/build/status/shotgunsoftware.tk-core?branchName=master)](https://dev.azure.com/shotgun-ecosystem/Toolkit/_build/latest?definitionId=38&branchName=master)
[![codecov](https://codecov.io/gh/shotgunsoftware/tk-core/branch/master/graph/badge.svg)](https://codecov.io/gh/shotgunsoftware/tk-core)
Expand Down
1 change: 1 addition & 0 deletions python/tank/util/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
is_version_newer,
is_version_older_or_equal,
is_version_newer_or_equal,
suppress_known_deprecation,
)

from .shotgun_entity import get_sg_entity_name_field
Expand Down
2 changes: 1 addition & 1 deletion python/tank/util/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ def run(self):
)

# Run until halted
while not self._halt_event.isSet():
while not self._halt_event.is_set():

# get the next available metric and dispatch it
try:
Expand Down
87 changes: 56 additions & 31 deletions python/tank/util/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,19 @@
# By accessing, using, copying or modifying this work you indicate your
# agreement to the Shotgun Pipeline Toolkit Source Code License. All rights
# not expressly granted therein are reserved by Shotgun Software Inc.
import warnings
import contextlib
import sys

if sys.version_info[0:2] >= (3, 10):
from setuptools._distutils.version import LooseVersion
else:
from distutils.version import LooseVersion

from distutils.version import LooseVersion
from . import sgre as re
from ..errors import TankError


GITHUB_HASH_RE = re.compile("^[0-9a-fA-F]{7,40}$")


Expand Down Expand Up @@ -115,6 +123,20 @@ def is_version_number(version):
return False


@contextlib.contextmanager
def suppress_known_deprecation():
"""
Imported function from setuptools.distutils module
"""
with warnings.catch_warnings(record=True) as ctx:
warnings.filterwarnings(
action="default",
category=DeprecationWarning,
message="distutils Version classes are deprecated.",
)
yield ctx


def _compare_versions(a, b):
"""
Tests if version a is newer than version b.
Expand All @@ -124,8 +146,8 @@ def _compare_versions(a, b):
:rtype: bool
"""
if b is None:
# a is always newer than None
if b in [None, "Undefined"]:
# a is always newer than None or `Undefined`
return True

if _is_git_commit(a) and not _is_git_commit(b):
Expand Down Expand Up @@ -157,37 +179,40 @@ def _compare_versions(a, b):
# First, try to use LooseVersion for comparison. This should work in
# most cases.
try:
version_a = LooseVersion(a).version
version_b = LooseVersion(b).version
version_num_a = []
version_num_b = []
# taking only the integers of the version to make comparison
for version in version_a:
if isinstance(version, (int)):
version_num_a.append(version)
elif version == "-":
break
for version in version_b:
if isinstance(version, (int)):
version_num_b.append(version)
elif version == "-":
break

# Comparing equal number versions with with one of them with '-' appended, if a version
# has '-' appended it's older than the same version with '-' at the end
if version_num_a == version_num_b:
if "-" in a and "-" not in b:
return False # False, version a is older than b
elif "-" in b and "-" not in a:
return True # True, version a is older than b
with suppress_known_deprecation():
# Supress `distutils Version classes are deprecated.` for Python 3.10
version_a = LooseVersion(a).version
version_b = LooseVersion(b).version

version_num_a = []
version_num_b = []
# taking only the integers of the version to make comparison
for version in version_a:
if isinstance(version, (int)):
version_num_a.append(version)
elif version == "-":
break
for version in version_b:
if isinstance(version, (int)):
version_num_b.append(version)
elif version == "-":
break

# Comparing equal number versions with with one of them with '-' appended, if a version
# has '-' appended it's older than the same version with '-' at the end
if version_num_a == version_num_b:
if "-" in a and "-" not in b:
return False # False, version a is older than b
elif "-" in b and "-" not in a:
return True # True, version a is older than b
else:
return LooseVersion(a) > LooseVersion(
b
) # If both has '-' compare '-rcx' versions
else:
return LooseVersion(a) > LooseVersion(
b
) # If both has '-' compare '-rcx' versions
else:
return LooseVersion(a) > LooseVersion(
b
) # If they are different numeric versions
) # If they are different numeric versions
except TypeError:
# To mimick the behavior in Python 2.7 as closely as possible, we will
# If LooseVersion comparison didn't work, try to extract a numeric
Expand Down
2 changes: 1 addition & 1 deletion python/tank_vendor/shotgun_api3/commit_id
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1f132f8f495333acc7303996a8151d73b2c204ae
11db780c4a18993130a988d73f9e50bd7d17e53f
69 changes: 69 additions & 0 deletions python/tank_vendor/shotgun_api3/lib/httplib2/auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import base64
import re

from ... import pyparsing as pp

from .error import *


try: # pyparsing>=3.0.0
downcaseTokens = pp.common.downcaseTokens
except AttributeError:
downcaseTokens = pp.downcaseTokens

UNQUOTE_PAIRS = re.compile(r"\\(.)")
unquote = lambda s, l, t: UNQUOTE_PAIRS.sub(r"\1", t[0][1:-1])

# https://tools.ietf.org/html/rfc7235#section-1.2
# https://tools.ietf.org/html/rfc7235#appendix-B
tchar = "!#$%&'*+-.^_`|~" + pp.nums + pp.alphas
token = pp.Word(tchar).setName("token")
token68 = pp.Combine(pp.Word("-._~+/" + pp.nums + pp.alphas) + pp.Optional(pp.Word("=").leaveWhitespace())).setName(
"token68"
)

quoted_string = pp.dblQuotedString.copy().setName("quoted-string").setParseAction(unquote)
auth_param_name = token.copy().setName("auth-param-name").addParseAction(downcaseTokens)
auth_param = auth_param_name + pp.Suppress("=") + (quoted_string | token)
params = pp.Dict(pp.delimitedList(pp.Group(auth_param)))

scheme = token("scheme")
challenge = scheme + (params("params") | token68("token"))

authentication_info = params.copy()
www_authenticate = pp.delimitedList(pp.Group(challenge))


def _parse_authentication_info(headers, headername="authentication-info"):
"""https://tools.ietf.org/html/rfc7615
"""
header = headers.get(headername, "").strip()
if not header:
return {}
try:
parsed = authentication_info.parseString(header)
except pp.ParseException as ex:
# print(ex.explain(ex))
raise MalformedHeader(headername)

return parsed.asDict()


def _parse_www_authenticate(headers, headername="www-authenticate"):
"""Returns a dictionary of dictionaries, one dict per auth_scheme."""
header = headers.get(headername, "").strip()
if not header:
return {}
try:
parsed = www_authenticate.parseString(header)
except pp.ParseException as ex:
# print(ex.explain(ex))
raise MalformedHeader(headername)

retval = {
challenge["scheme"].lower(): challenge["params"].asDict()
if "params" in challenge
else {"token": challenge.get("token")}
for challenge in parsed
}
return retval
Loading

0 comments on commit 509eca8

Please sign in to comment.