Skip to content

Commit

Permalink
use new hub_version session property if available (#176)
Browse files Browse the repository at this point in the history
* use new hub_version session property if available

* new properties in stubs

* mention the new hub_version compatibility
  • Loading branch information
obriencj authored May 14, 2024
1 parent f7fe3ff commit 45dfe81
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 30 deletions.
6 changes: 6 additions & 0 deletions docs/release_notes/v2.2.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ API
* introduced a new `kojismokydingo.users.get_group_members` function
* introduced a new `kojismokydingo.users.get_user_groups` function
* fixed some missing ``__all__`` exports in `kojismokydingo.types`
* the `kojismokydingo.hub_version` function will work with the new
`koji.hub_version_str` property, which is populated from a new value
in http headers on responses from the hub. This potentially saves us
the explicit ``getKojiVersion`` call on newer deployments


Meta Plugin
Expand Down Expand Up @@ -54,6 +58,8 @@ Other
* migrated away from the ``build_sphinx`` setuptools command
* introduced nightly CI that runs against the upstream git version of
koji, in order to catch any additional API changes early on
* added more static analysis checking and a special proxytype plugin,
and moved from the ``stubs`` directory to the ``mypy`` directory


Issues
Expand Down
47 changes: 31 additions & 16 deletions kojismokydingo/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -837,17 +837,17 @@ def bulk_load_users(
# whether there's already a cached answer as to which API is
# available
session_vars = vars(session)
new_get_user = session_vars.get("__new_get_user")
new_get_user = session_vars.get("__ksd_new_get_user")

if new_get_user is None:
# there wasn't already an answer, so we'll have to find out
# ourselves. In this case we'll load the first user in the
# list of users separately, outside of a multicall, and using
# the as_userinfo function. This function will first try the
# newer signature. If successful, it will record
# __new_get_user as True, and we'll know to use the newer
# __ksd_new_get_user as True, and we'll know to use the newer
# signature. If not, the function will retry with the older
# signature and set __new_get_user to False.
# signature and set __ksd_new_get_user to False.

key = users[0]
users = users[1:]
Expand All @@ -860,9 +860,10 @@ def bulk_load_users(
else:
results[key] = None

# the use of as_userinfo will have updated the __new_get_user
# sentinel attribute to either True or False
new_get_user = session_vars.get("__new_get_user")
# the use of as_userinfo will have updated the
# __ksd_new_get_user sentinel attribute to either True or
# False
new_get_user = session_vars.get("__ksd_new_get_user")

if new_get_user:
fn = lambda u: session.getUser(u, False, True)
Expand Down Expand Up @@ -1268,7 +1269,7 @@ def as_userinfo(

if isinstance(user, (str, int)):
session_vars = vars(session)
new_get_user = session_vars.get("__new_get_user")
new_get_user = session_vars.get("__ksd_new_get_user")

if new_get_user:
# we've tried the new way and it worked, so keep doing it.
Expand All @@ -1282,11 +1283,11 @@ def as_userinfo(
# cannot use the version_check function to gate this.
try:
info = session.getUser(user, False, True)
session_vars["__new_get_user"] = True
session_vars["__ksd_new_get_user"] = True

except ParameterError:
info = session.getUser(user)
session_vars["__new_get_user"] = False
session_vars["__ksd_new_get_user"] = False

else:
# we've already tried the new way once and it didn't work.
Expand Down Expand Up @@ -1342,7 +1343,7 @@ def _int(val):


def hub_version(
session: ClientSession) -> Tuple[int]:
session: ClientSession) -> Tuple[int, ...]:
"""
Wrapper for ``session.getKojiVersion`` which caches the results on
the session and splits the value into a tuple of ints for easy
Expand All @@ -1352,6 +1353,10 @@ def hub_version(
presume that we're version 1.22 ``(1, 22)`` which is the last
version before the getKojiVersion API was added.
If used with koji hub and client >= 1.35 then this value is farmed
from the Koji-Version header of XMLRPC responses, rather than
directly calling getKojiVersion.
:param session: active koji session
:since: 1.0
Expand All @@ -1362,20 +1367,30 @@ def hub_version(
# remote hub method.
session_vars = vars(session)

hub_ver = session_vars.get("__hub_version", None)
hub_ver = session_vars.get("__ksd_hub_version", None)
if hub_ver is None:
try:
hub_ver = session.getKojiVersion()
except GenericError:
pass

if "hub_version_str" in session_vars:
# introduced in koji 1.34, koji client can determine the
# hub version via a header that is available in every
# response (including the login response). That saves us
# an explicit getKojiVersion call, so use it if possible.

hub_ver = session.hub_version_str

else:
try:
hub_ver = session.getKojiVersion()
except GenericError:
pass

if hub_ver is None:
hub_ver = (1, 22)

elif isinstance(hub_ver, str):
hub_ver = tuple(map(_int, hub_ver.split(".")))

session_vars["__hub_version"] = hub_ver
session_vars["__ksd_hub_version"] = hub_ver

return hub_ver

Expand Down
14 changes: 14 additions & 0 deletions mypy/koji/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,20 @@ class ClientSession:
multicall: "MultiCallHack"
opts: Dict[str, Any]

@property
def hub_version(self) -> Tuple[int, ...]:
"""
:since: koji 1.35
"""
...

@property
def hub_version_str(self) -> str:
"""
:since: koji 1.35
"""
...

def __init__(
self,
baseurl: str,
Expand Down
28 changes: 14 additions & 14 deletions tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,13 +214,13 @@ def test_bad_version_check(self):
self.assertFalse(version_check(sess, "1.26"))
self.assertFalse(version_check(sess, (1, 26)))
self.assertFalse(version_check(sess, (1, 27)))
self.assertEqual(vars(sess)["__hub_version"], (1, 25))
self.assertEqual(vars(sess)["__ksd_hub_version"], (1, 25))
self.assertEqual(send.call_count, 1)

sess, send = self.session([self.ge()])
self.assertFalse(version_check(sess, (1, 23)))
self.assertFalse(version_check(sess, (1, 24)))
self.assertEqual(vars(sess)["__hub_version"], (1, 22))
self.assertEqual(vars(sess)["__ksd_hub_version"], (1, 22))
self.assertEqual(send.call_count, 1)


Expand All @@ -230,19 +230,19 @@ def test_good_version_check(self):
self.assertTrue(version_check(sess, "1.23"))
self.assertTrue(version_check(sess, (1, 23)))
self.assertTrue(version_check(sess, (1, 24)))
self.assertEqual(vars(sess)["__hub_version"], (1, 24))
self.assertEqual(vars(sess)["__ksd_hub_version"], (1, 24))
self.assertEqual(send.call_count, 1)

sess, send = self.session(["1.25"])
self.assertTrue(version_check(sess, (1, 24)))
self.assertTrue(version_check(sess, (1, 25)))
self.assertEqual(vars(sess)["__hub_version"], (1, 25))
self.assertEqual(vars(sess)["__ksd_hub_version"], (1, 25))
self.assertEqual(send.call_count, 1)

sess, send = self.session([self.ge()])
self.assertTrue(version_check(sess, (1, 22)))
self.assertTrue(version_check(sess, (1, 22)))
self.assertEqual(vars(sess)["__hub_version"], (1, 22))
self.assertEqual(vars(sess)["__ksd_hub_version"], (1, 22))
self.assertEqual(send.call_count, 1)


Expand All @@ -251,13 +251,13 @@ def test_bad_version_require(self):
sess, send = self.session(["1.25"])
self.assertRaises(FeatureUnavailable, version_require, sess, (1, 26))
self.assertRaises(FeatureUnavailable, version_require, sess, (1, 27))
self.assertEqual(vars(sess)["__hub_version"], (1, 25))
self.assertEqual(vars(sess)["__ksd_hub_version"], (1, 25))
self.assertEqual(send.call_count, 1)

sess, send = self.session([self.ge()])
self.assertRaises(FeatureUnavailable, version_require, sess, (1, 23))
self.assertRaises(FeatureUnavailable, version_require, sess, (1, 24))
self.assertEqual(vars(sess)["__hub_version"], (1, 22))
self.assertEqual(vars(sess)["__ksd_hub_version"], (1, 22))
self.assertEqual(send.call_count, 1)


Expand All @@ -266,19 +266,19 @@ def test_good_version_require(self):
sess, send = self.session(["1.24"])
self.assertTrue(version_require(sess, (1, 23)))
self.assertTrue(version_require(sess, (1, 24)))
self.assertEqual(vars(sess)["__hub_version"], (1, 24))
self.assertEqual(vars(sess)["__ksd_hub_version"], (1, 24))
self.assertEqual(send.call_count, 1)

sess, send = self.session(["1.25"])
self.assertTrue(version_require(sess, (1, 24)))
self.assertTrue(version_require(sess, (1, 25)))
self.assertEqual(vars(sess)["__hub_version"], (1, 25))
self.assertEqual(vars(sess)["__ksd_hub_version"], (1, 25))
self.assertEqual(send.call_count, 1)

sess, send = self.session([self.ge()])
self.assertTrue(version_require(sess, (1, 22)))
self.assertTrue(version_require(sess, (1, 22)))
self.assertEqual(vars(sess)["__hub_version"], (1, 22))
self.assertEqual(vars(sess)["__ksd_hub_version"], (1, 22))
self.assertEqual(send.call_count, 1)


Expand Down Expand Up @@ -514,8 +514,8 @@ def test_as_userinfo_name(self):
self.assertEqual(send.call_args_list[0][0], (key, False, True))

sess_vars = vars(sess)
self.assertTrue("__new_get_user" in sess_vars)
self.assertTrue(sess_vars["__new_get_user"])
self.assertTrue("__ksd_new_get_user" in sess_vars)
self.assertTrue(sess_vars["__ksd_new_get_user"])

res = as_userinfo(sess, key)
self.assertEqual(res, self.DATA)
Expand All @@ -530,8 +530,8 @@ def test_as_userinfo_name(self):
self.assertEqual(send.call_args_list[1][0], (key,))

sess_vars = vars(sess)
self.assertTrue("__new_get_user" in sess_vars)
self.assertFalse(sess_vars["__new_get_user"])
self.assertTrue("__ksd_new_get_user" in sess_vars)
self.assertFalse(sess_vars["__ksd_new_get_user"])

res = as_userinfo(sess, key)
self.assertEqual(res, self.DATA)
Expand Down

0 comments on commit 45dfe81

Please sign in to comment.