Skip to content

Commit 0b9e12b

Browse files
committed
Revive bugzilla.rhbugzilla.RHBugzilla import path
I've had a few reports about apps breaking without it. We can't easily move RHBugzilla to the existing rhbugzilla.py due to cyclic dependency issues. Rename rhbugzilla.py to _rhconverters.py, and make rhbugzilla.py just import RHBugzilla from oldclasses.py. Add tests to ensure we don't regress in the future Signed-off-by: Cole Robinson <crobinso@redhat.com>
1 parent 68a1dc6 commit 0b9e12b

4 files changed

Lines changed: 140 additions & 125 deletions

File tree

bugzilla/_rhconverters.py

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# rhbugzilla.py - a Python interface to Red Hat Bugzilla using xmlrpclib.
2+
#
3+
# Copyright (C) 2008-2012 Red Hat Inc.
4+
# Author: Will Woods <wwoods@redhat.com>
5+
#
6+
# This work is licensed under the GNU GPLv2 or later.
7+
# See the COPYING file in the top-level directory.
8+
9+
from logging import getLogger
10+
11+
from ._util import listify
12+
13+
log = getLogger(__name__)
14+
15+
16+
class _RHBugzillaConverters(object):
17+
"""
18+
Static class that holds functional Red Hat back compat converters.
19+
Called inline in Bugzilla
20+
"""
21+
@staticmethod
22+
def convert_build_update(
23+
component=None,
24+
fixed_in=None,
25+
qa_whiteboard=None,
26+
devel_whiteboard=None,
27+
internal_whiteboard=None,
28+
sub_component=None):
29+
adddict = {}
30+
31+
def get_alias():
32+
# RHBZ has a custom extension to allow a bug to have multiple
33+
# aliases, so the format of aliases is
34+
# {"add": [...], "remove": [...]}
35+
# But that means in order to approximate upstream, behavior
36+
# which just overwrites the existing alias, we need to read
37+
# the bug's state first to know what string to remove. Which
38+
# we can't do, since we don't know the bug numbers at this point.
39+
# So fail for now.
40+
#
41+
# The API should provide {"set": [...]}
42+
# https://bugzilla.redhat.com/show_bug.cgi?id=1173114
43+
#
44+
# Implementation will go here when it's available
45+
pass
46+
47+
if fixed_in is not None:
48+
adddict["cf_fixed_in"] = fixed_in
49+
if qa_whiteboard is not None:
50+
adddict["cf_qa_whiteboard"] = qa_whiteboard
51+
if devel_whiteboard is not None:
52+
adddict["cf_devel_whiteboard"] = devel_whiteboard
53+
if internal_whiteboard is not None:
54+
adddict["cf_internal_whiteboard"] = internal_whiteboard
55+
56+
if sub_component:
57+
if not isinstance(sub_component, dict):
58+
component = listify(component)
59+
if not component:
60+
raise ValueError("component must be specified if "
61+
"specifying sub_component")
62+
sub_component = {component[0]: sub_component}
63+
adddict["sub_components"] = sub_component
64+
65+
get_alias()
66+
67+
return adddict
68+
69+
70+
#################
71+
# Query methods #
72+
#################
73+
74+
@staticmethod
75+
def pre_translation(query):
76+
"""
77+
Translates the query for possible aliases
78+
"""
79+
old = query.copy()
80+
81+
def split_comma(_v):
82+
if isinstance(_v, list):
83+
return _v
84+
return _v.split(",")
85+
86+
if 'bug_id' in query:
87+
query['id'] = split_comma(query.pop('bug_id'))
88+
89+
if 'component' in query:
90+
query['component'] = split_comma(query['component'])
91+
92+
if 'include_fields' not in query and 'column_list' in query:
93+
query['include_fields'] = query.pop('column_list')
94+
95+
if old != query:
96+
log.debug("RHBugzilla pretranslated query to: %s", query)
97+
98+
@staticmethod
99+
def post_translation(query, bug):
100+
"""
101+
Convert the results of getbug back to the ancient RHBZ value
102+
formats
103+
"""
104+
ignore = query
105+
106+
# RHBZ _still_ returns component and version as lists, which
107+
# deviates from upstream. Copy the list values to components
108+
# and versions respectively.
109+
if 'component' in bug and "components" not in bug:
110+
val = bug['component']
111+
bug['components'] = isinstance(val, list) and val or [val]
112+
bug['component'] = bug['components'][0]
113+
114+
if 'version' in bug and "versions" not in bug:
115+
val = bug['version']
116+
bug['versions'] = isinstance(val, list) and val or [val]
117+
bug['version'] = bug['versions'][0]
118+
119+
# sub_components isn't too friendly of a format, add a simpler
120+
# sub_component value
121+
if 'sub_components' in bug and 'sub_component' not in bug:
122+
val = bug['sub_components']
123+
bug['sub_component'] = ""
124+
if isinstance(val, dict):
125+
values = []
126+
for vallist in val.values():
127+
values += vallist
128+
bug['sub_component'] = " ".join(values)

bugzilla/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from ._compatimports import Mapping, urlparse, urlunparse, parse_qsl
2424
from .bug import Bug, Group, User
2525
from .exceptions import BugzillaError
26-
from .rhbugzilla import _RHBugzillaConverters
26+
from ._rhconverters import _RHBugzillaConverters
2727
from ._session import _BugzillaSession
2828
from ._util import listify
2929

bugzilla/rhbugzilla.py

Lines changed: 3 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -1,128 +1,7 @@
1-
# rhbugzilla.py - a Python interface to Red Hat Bugzilla using xmlrpclib.
2-
#
3-
# Copyright (C) 2008-2012 Red Hat Inc.
4-
# Author: Will Woods <wwoods@redhat.com>
5-
#
61
# This work is licensed under the GNU GPLv2 or later.
72
# See the COPYING file in the top-level directory.
83

9-
from logging import getLogger
4+
# This class needs to live in rhbugzilla.py to preserve historical
5+
# 'bugzilla.rhbugzilla' import compat
106

11-
from ._util import listify
12-
13-
log = getLogger(__name__)
14-
15-
16-
class _RHBugzillaConverters(object):
17-
"""
18-
Static class that holds functional Red Hat back compat converters.
19-
Called inline in Bugzilla
20-
"""
21-
@staticmethod
22-
def convert_build_update(
23-
component=None,
24-
fixed_in=None,
25-
qa_whiteboard=None,
26-
devel_whiteboard=None,
27-
internal_whiteboard=None,
28-
sub_component=None):
29-
adddict = {}
30-
31-
def get_alias():
32-
# RHBZ has a custom extension to allow a bug to have multiple
33-
# aliases, so the format of aliases is
34-
# {"add": [...], "remove": [...]}
35-
# But that means in order to approximate upstream, behavior
36-
# which just overwrites the existing alias, we need to read
37-
# the bug's state first to know what string to remove. Which
38-
# we can't do, since we don't know the bug numbers at this point.
39-
# So fail for now.
40-
#
41-
# The API should provide {"set": [...]}
42-
# https://bugzilla.redhat.com/show_bug.cgi?id=1173114
43-
#
44-
# Implementation will go here when it's available
45-
pass
46-
47-
if fixed_in is not None:
48-
adddict["cf_fixed_in"] = fixed_in
49-
if qa_whiteboard is not None:
50-
adddict["cf_qa_whiteboard"] = qa_whiteboard
51-
if devel_whiteboard is not None:
52-
adddict["cf_devel_whiteboard"] = devel_whiteboard
53-
if internal_whiteboard is not None:
54-
adddict["cf_internal_whiteboard"] = internal_whiteboard
55-
56-
if sub_component:
57-
if not isinstance(sub_component, dict):
58-
component = listify(component)
59-
if not component:
60-
raise ValueError("component must be specified if "
61-
"specifying sub_component")
62-
sub_component = {component[0]: sub_component}
63-
adddict["sub_components"] = sub_component
64-
65-
get_alias()
66-
67-
return adddict
68-
69-
70-
#################
71-
# Query methods #
72-
#################
73-
74-
@staticmethod
75-
def pre_translation(query):
76-
"""
77-
Translates the query for possible aliases
78-
"""
79-
old = query.copy()
80-
81-
def split_comma(_v):
82-
if isinstance(_v, list):
83-
return _v
84-
return _v.split(",")
85-
86-
if 'bug_id' in query:
87-
query['id'] = split_comma(query.pop('bug_id'))
88-
89-
if 'component' in query:
90-
query['component'] = split_comma(query['component'])
91-
92-
if 'include_fields' not in query and 'column_list' in query:
93-
query['include_fields'] = query.pop('column_list')
94-
95-
if old != query:
96-
log.debug("RHBugzilla pretranslated query to: %s", query)
97-
98-
@staticmethod
99-
def post_translation(query, bug):
100-
"""
101-
Convert the results of getbug back to the ancient RHBZ value
102-
formats
103-
"""
104-
ignore = query
105-
106-
# RHBZ _still_ returns component and version as lists, which
107-
# deviates from upstream. Copy the list values to components
108-
# and versions respectively.
109-
if 'component' in bug and "components" not in bug:
110-
val = bug['component']
111-
bug['components'] = isinstance(val, list) and val or [val]
112-
bug['component'] = bug['components'][0]
113-
114-
if 'version' in bug and "versions" not in bug:
115-
val = bug['version']
116-
bug['versions'] = isinstance(val, list) and val or [val]
117-
bug['version'] = bug['versions'][0]
118-
119-
# sub_components isn't too friendly of a format, add a simpler
120-
# sub_component value
121-
if 'sub_components' in bug and 'sub_component' not in bug:
122-
val = bug['sub_components']
123-
bug['sub_component'] = ""
124-
if isinstance(val, dict):
125-
values = []
126-
for vallist in val.values():
127-
values += vallist
128-
bug['sub_component'] = " ".join(values)
7+
from .oldclasses import RHBugzilla # pylint: disable=unused-import

tests/test_api_misc.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ def test_mock_rhbz():
2222
assert fakebz.__class__ == bugzilla.RHBugzilla
2323

2424

25+
def test_file_imports():
26+
# Ensure historically stable import paths continue to work
27+
# pylint: disable=unused-import
28+
from bugzilla.rhbugzilla import RHBugzilla
29+
from bugzilla.bug import Bug
30+
from bugzilla.base import Bugzilla
31+
32+
2533
def testUserAgent():
2634
b3 = tests.mockbackend.make_bz(version="3.0.0")
2735
assert "python-bugzilla" in b3.user_agent

0 commit comments

Comments
 (0)