Hello community,
here is the log from the commit of package python-bugzilla for openSUSE:Factory
checked in at 2019-09-18 13:10:18
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-bugzilla (Old)
and /work/SRC/openSUSE:Factory/.python-bugzilla.new.7948 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-bugzilla"
Wed Sep 18 13:10:18 2019 rev:27 rq:731151 version:2.3.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-bugzilla/python-bugzilla.changes
2018-08-24 17:11:59.790634417 +0200
+++
/work/SRC/openSUSE:Factory/.python-bugzilla.new.7948/python-bugzilla.changes
2019-09-18 13:10:42.404699152 +0200
@@ -1,0 +2,9 @@
+Sun Sep 15 13:41:23 UTC 2019 - John Vandenberg <[email protected]>
+
+- Update to v2.3.0
+ * restrict-login support
+ * cli: Add support for private attachments
+ * Fix python3 deprecation warnings
+ * Drop python 3.3 support, minimum python3 is python 3.4 now
+
+-------------------------------------------------------------------
Old:
----
python-bugzilla-2.2.0.tar.gz
New:
----
python-bugzilla-2.3.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-bugzilla.spec ++++++
--- /var/tmp/diff_new_pack.EXSbbO/_old 2019-09-18 13:10:42.976699032 +0200
+++ /var/tmp/diff_new_pack.EXSbbO/_new 2019-09-18 13:10:42.980699031 +0200
@@ -1,7 +1,7 @@
#
# spec file for package python-bugzilla
#
-# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -12,14 +12,14 @@
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
#
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
%define oldpython python
Name: python-bugzilla
-Version: 2.2.0
+Version: 2.3.0
Release: 0
Summary: Python library for Bugzilla
License: GPL-2.0-or-later
@@ -75,6 +75,6 @@
%python_alternative %{_bindir}/bugzilla
%python_alternative %{_mandir}/man1/bugzilla.1%{ext_man}
%{python_sitelib}/bugzilla
-%{python_sitelib}/python_bugzilla-%{version}-py%{py_ver}.egg-info
+%{python_sitelib}/python_bugzilla-%{version}-py*.egg-info
%changelog
++++++ python-bugzilla-2.2.0.tar.gz -> python-bugzilla-2.3.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-bugzilla-2.2.0/NEWS.md
new/python-bugzilla-2.3.0/NEWS.md
--- old/python-bugzilla-2.2.0/NEWS.md 2018-08-11 16:12:39.000000000 +0200
+++ new/python-bugzilla-2.3.0/NEWS.md 2019-08-26 23:31:03.000000000 +0200
@@ -1,5 +1,11 @@
# python-bugzilla release news
+## Release 2.3.0 (August 26, 2019)
+- restrict-login suppot (Viliam Krizan)
+- cli: Add support for private attachments (Brian 'Redbeard' Harrington)
+- Fix python3 deprecation warnings
+- Drop python 3.3 support, minimum python3 is python 3.4 now
+
## Release 2.2.0 (August 11, 2018)
- Port tests to pytest
- cli: --cert Client side certificate support (Tobias Wolter)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-bugzilla-2.2.0/PKG-INFO
new/python-bugzilla-2.3.0/PKG-INFO
--- old/python-bugzilla-2.2.0/PKG-INFO 2018-08-11 16:12:57.000000000 +0200
+++ new/python-bugzilla-2.3.0/PKG-INFO 2019-08-26 23:31:57.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: python-bugzilla
-Version: 2.2.0
+Version: 2.3.0
Summary: Bugzilla XMLRPC access module
Home-page: https://github.com/python-bugzilla/python-bugzilla
Author: Cole Robinson
@@ -16,7 +16,7 @@
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-bugzilla-2.2.0/bugzilla/_cli.py
new/python-bugzilla-2.3.0/bugzilla/_cli.py
--- old/python-bugzilla-2.2.0/bugzilla/_cli.py 2018-08-11 15:13:09.000000000
+0200
+++ new/python-bugzilla-2.3.0/bugzilla/_cli.py 2019-08-20 19:20:32.000000000
+0200
@@ -14,6 +14,7 @@
from __future__ import print_function
+import errno
import locale
from logging import getLogger, DEBUG, INFO, WARN, StreamHandler, Formatter
import argparse
@@ -85,7 +86,7 @@
try:
fd = os.open(name, os.O_CREAT | os.O_EXCL, 0o666)
except OSError as err:
- if err.errno == os.errno.EEXIST:
+ if err.errno == errno.EEXIST:
name = "%s.%i" % (orig_name, count)
count += 1
else:
@@ -152,6 +153,9 @@
'specified command.')
p.add_argument('--username', help="Log in with this username")
p.add_argument('--password', help="Log in with this password")
+ p.add_argument('--restrict-login', action="store_true",
+ help="The session (login token) will be restricted to "
+ "the current IP address.")
p.add_argument('--ensure-logged-in', action="store_true",
help="Raise an error if we aren't logged in to bugzilla. "
@@ -277,7 +281,7 @@
p.add_argument('--field',
metavar="FIELD=VALUE", action="append", dest="fields",
help="Manually specify a bugzilla XMLRPC field. FIELD is "
- "the raw name used by the bugzilla instance. For example if your "
+ "the raw name used by the bugzilla instance. For example, if your "
"bugzilla instance has a custom field cf_my_field, do:\n"
" --field cf_my_field=VALUE")
@@ -418,11 +422,16 @@
default=[], help="Download all attachments on the given bug")
p.add_argument('-l', '--comment', '--long_desc',
help="Add comment with attachment")
+ p.add_argument('--private', action='store_true', default=False,
+ help='Mark new comment as private')
def _setup_action_login_parser(subparsers):
usage = 'bugzilla login [username [password]]'
- description = "Log into bugzilla and save a login cookie or token."
+ description = """Log into bugzilla and save a login cookie or token.
+Note: These tokens are short-lived, and future Bugzilla versions will no
+longer support token authentication at all. Please use a
+~/.config/python-bugzilla/bugzillarc file with an API key instead."""
p = subparsers.add_parser("login", description=description, usage=usage)
p.add_argument("pos_username", nargs="?", help="Optional username",
metavar="username")
@@ -702,7 +711,7 @@
if fieldname == "flag" and rest:
val = b.get_flag_status(rest)
- elif fieldname == "flags" or fieldname == "flags_requestee":
+ elif fieldname in ["flags", "flags_requestee"]:
tmpstr = []
for f in getattr(b, "flags", []):
requestee = f.get('requestee', "")
@@ -976,8 +985,6 @@
data = att.read(4096)
print("Wrote %s" % outfile.name)
- return
-
def _do_set_attach(bz, opt, parser):
if not opt.ids:
@@ -1010,6 +1017,8 @@
kwargs["ispatch"] = True
if opt.comment:
kwargs["comment"] = opt.comment
+ if opt.private:
+ kwargs["is_private"] = True
desc = opt.desc or os.path.basename(fileobj.name)
# Upload attachments
@@ -1031,15 +1040,18 @@
cookiefile = None
tokenfile = None
+ use_creds = False
if opt.cache_credentials:
cookiefile = opt.cookiefile or -1
tokenfile = opt.tokenfile or -1
+ use_creds = True
bz = bugzilla.Bugzilla(
url=opt.bugzilla,
cookiefile=cookiefile,
tokenfile=tokenfile,
sslverify=opt.sslverify,
+ use_creds=use_creds,
cert=opt.cert)
return bz
@@ -1059,7 +1071,8 @@
if do_interactive_login:
if bz.url:
print("Logging into %s" % urlparse(bz.url)[1])
- bz.interactive_login(username, password)
+ bz.interactive_login(username, password,
+ restrict_login=opt.restrict_login)
except bugzilla.BugzillaError as e:
print(str(e))
sys.exit(1)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-bugzilla-2.2.0/bugzilla/apiversion.py
new/python-bugzilla-2.3.0/bugzilla/apiversion.py
--- old/python-bugzilla-2.2.0/bugzilla/apiversion.py 2018-08-11
16:12:39.000000000 +0200
+++ new/python-bugzilla-2.3.0/bugzilla/apiversion.py 2019-08-26
23:31:03.000000000 +0200
@@ -7,5 +7,5 @@
# option) any later version. See http://www.gnu.org/copyleft/gpl.html for
# the full text of the license.
-version = "2.2.0"
+version = "2.3.0"
__version__ = version
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-bugzilla-2.2.0/bugzilla/base.py
new/python-bugzilla-2.3.0/bugzilla/base.py
--- old/python-bugzilla-2.2.0/bugzilla/base.py 2018-08-11 15:13:16.000000000
+0200
+++ new/python-bugzilla-2.3.0/bugzilla/base.py 2019-08-23 01:07:00.000000000
+0200
@@ -9,10 +9,10 @@
# option) any later version. See http://www.gnu.org/copyleft/gpl.html for
# the full text of the license.
-import collections
import getpass
import locale
from logging import getLogger
+import mimetypes
import os
import sys
@@ -21,12 +21,14 @@
# pylint: disable=import-error
if sys.version_info[0] >= 3:
# pylint: disable=no-name-in-module
- from configparser import SafeConfigParser
+ from collections.abc import Mapping
+ from configparser import ConfigParser
from http.cookiejar import LoadError, MozillaCookieJar
from urllib.parse import urlparse, parse_qsl
from xmlrpc.client import Binary, Fault
else:
- from ConfigParser import SafeConfigParser
+ from collections import Mapping
+ from ConfigParser import SafeConfigParser as ConfigParser
from cookielib import LoadError, MozillaCookieJar
from urlparse import urlparse, parse_qsl
from xmlrpclib import Binary, Fault
@@ -40,39 +42,11 @@
log = getLogger(__name__)
-mimemagic = None
-
-
-def _detect_filetype(fname):
- global mimemagic
-
- if mimemagic is None:
- try:
- # pylint: disable=import-error
- import magic
- mimemagic = magic.open(getattr(magic, "MAGIC_MIME_TYPE", 16))
- mimemagic.load()
- except ImportError as e:
- log.debug("Could not load python-magic: %s", e)
- mimemagic = None
- if not mimemagic:
- return None
-
- if not os.path.isabs(fname):
- return None
-
- try:
- return mimemagic.file(fname)
- except Exception as e:
- log.debug("Could not detect content_type: %s", e)
- return None
-
def _nested_update(d, u):
# Helper for nested dict update()
- #
https://stackoverflow.com/questions/3232943/update-value-of-a-nested-dictionary-of-varying-depth
for k, v in list(u.items()):
- if isinstance(v, collections.Mapping):
+ if isinstance(v, Mapping):
d[k] = _nested_update(d.get(k, {}), v)
else:
d[k] = v
@@ -131,7 +105,7 @@
configpaths = [os.path.expanduser(p) for p in
Bugzilla._listify(configpaths)]
# pylint: enable=protected-access
- cfg = SafeConfigParser()
+ cfg = ConfigParser()
read_files = cfg.read(configpaths)
if not read_files:
return
@@ -187,7 +161,7 @@
log in, you can either pass auth options to __init__, or call a login
helper like interactive_login().
- If you are not logged in, you won be able to access restricted data like
+ If you are not logged in, you won't be able to access restricted data like
user email, or perform write actions like bug create/update. But simple
querys will work correctly.
@@ -261,7 +235,7 @@
def __init__(self, url=-1, user=None, password=None, cookiefile=-1,
sslverify=True, tokenfile=-1, use_creds=True, api_key=None,
- cert=None):
+ cert=None, configpaths=-1):
"""
:param url: The bugzilla instance URL, which we will connect
to immediately. Most users will want to specify this at
@@ -288,7 +262,8 @@
:param sslverify: Maps to 'requests' sslverify parameter. Set to
False to disable SSL verification, but it can also be a path
to file or directory for custom certs.
- :param api_key: A bugzilla
+ :param api_key: A bugzilla5+ API key
+ :param configpaths: A list of possible bugzillarc locations.
"""
if url == -1:
raise TypeError("Specify a valid bugzilla url, or pass url=None")
@@ -310,19 +285,22 @@
self._field_aliases = []
self._init_field_aliases()
- self.configpath = _default_configpaths[:]
if not use_creds:
cookiefile = None
tokenfile = None
- self.configpath = []
+ configpaths = []
if cookiefile == -1:
cookiefile = _default_auth_location("bugzillacookies")
if tokenfile == -1:
tokenfile = _default_auth_location("bugzillatoken")
+ if configpaths == -1:
+ configpaths = _default_configpaths[:]
+
log.debug("Using tokenfile=%s", tokenfile)
self.cookiefile = cookiefile
self.tokenfile = tokenfile
+ self.configpath = configpaths
if url:
self.connect(url)
@@ -485,11 +463,25 @@
section = ""
log.debug("bugzillarc: Searching for config section matching %s",
self.url)
- for s in sorted(cfg.sections()):
- # Substring match - prefer the longest match found
- if s in self.url:
- log.debug("bugzillarc: Found matching section: %s", s)
- section = s
+
+ def _parse_hostname(_u):
+ # If http://example.com is passed, netloc=example.com path=""
+ # If just example.com is passed, netloc="" path=example.com
+ parsedbits = urlparse(self.url)
+ return parsedbits.netloc or parsedbits.path
+
+ urlhost = _parse_hostname(self.url)
+ for sectionhost in sorted(cfg.sections()):
+ # If the section is just a hostname, make it match
+ # If the section has a / in it, do a substring match
+ if "/" not in sectionhost:
+ if sectionhost == urlhost:
+ section = sectionhost
+ elif sectionhost in self.url:
+ section = sectionhost
+ if section:
+ log.debug("bugzillarc: Found matching section: %s", section)
+ break
if not section:
log.debug("bugzillarc: No section found")
@@ -570,12 +562,15 @@
self._transport = None
self._cache = _BugzillaAPICache()
-
- def _login(self, user, password):
+ def _login(self, user, password, restrict_login=None):
"""
Backend login method for Bugzilla3
"""
- return self._proxy.User.login({'login': user, 'password': password})
+ payload = {'login': user, 'password': password}
+ if restrict_login:
+ payload['restrict_login'] = True
+
+ return self._proxy.User.login(payload)
def _logout(self):
"""
@@ -583,7 +578,7 @@
"""
return self._proxy.User.logout()
- def login(self, user=None, password=None):
+ def login(self, user=None, password=None, restrict_login=None):
"""
Attempt to log in using the given username and password. Subsequent
method calls will use this username and password. Returns False if
@@ -594,6 +589,9 @@
is not set, ValueError will be raised. If login fails, BugzillaError
will be raised.
+ The login session can be restricted to current user IP address
+ with restrict_login argument. (Bugzilla 4.4+)
+
This method will be called implicitly at the end of connect() if user
and password are both set. So under most circumstances you won't need
to call this yourself.
@@ -611,21 +609,26 @@
if not self.password:
raise ValueError("missing password")
+ if restrict_login:
+ log.info("logging in with restrict_login=True")
+
try:
- ret = self._login(self.user, self.password)
+ ret = self._login(self.user, self.password, restrict_login)
self.password = ''
log.info("login successful for user=%s", self.user)
return ret
except Fault as e:
raise BugzillaError("Login failed: %s" % str(e.faultString))
- def interactive_login(self, user=None, password=None, force=False):
+ def interactive_login(self, user=None, password=None, force=False,
+ restrict_login=None):
"""
Helper method to handle login for this bugzilla instance.
:param user: bugzilla username. If not specified, prompt for it.
:param password: bugzilla password. If not specified, prompt for it.
:param force: Unused
+ :param restrict_login: restricts session to IP address
"""
ignore = force
log.debug('Calling interactive_login')
@@ -638,7 +641,7 @@
password = getpass.getpass('Bugzilla Password: ')
log.info('Logging in... ')
- self.login(user, password)
+ self.login(user, password, restrict_login)
log.info('Authorization cookie received.')
def logout(self):
@@ -876,8 +879,10 @@
product_id is None or
product_id not in self._cache.component_names):
self.refresh_products(names=[product],
- include_fields=["names", "id"])
+ include_fields=["name", "id"])
proddict = self._lookup_product_in_cache(product)
+ if "id" not in proddict:
+ raise BugzillaError("Product '%s' not found" % product)
product_id = proddict["id"]
opts = {'product_id': product_id, 'field': 'component'}
@@ -920,7 +925,7 @@
product: The product to create the component in
component: The name of the component to create
- desription: A one sentence summary of the component
+ description: A one sentence summary of the component
default_assignee: The bugzilla login (email address) of the initial
owner of the component
default_qa_contact (optional): The bugzilla login of the
@@ -1042,7 +1047,7 @@
else:
# Need to map an alias
for valdict in bugdict.values():
- if i in self._listify(valdict.get("alias", None)):
+ if i in self._listify(valdict.get("alias", None) or []):
found = valdict
break
@@ -1144,7 +1149,7 @@
Build a query string from passed arguments. Will handle
query parameter differences between various bugzilla versions.
- Most of the parameters should be self explanatory. However
+ Most of the parameters should be self-explanatory. However,
if you want to perform a complex query, and easy way is to
create it with the bugzilla web UI, copy the entire URL it
generates, and pass it to the static method
@@ -1556,10 +1561,11 @@
if 'file_name' not in kwargs and hasattr(f, "name"):
kwargs['file_name'] = os.path.basename(f.name)
if 'content_type' not in kwargs:
- ctype = _detect_filetype(getattr(f, "name", None))
- if not ctype:
- ctype = 'application/octet-stream'
- kwargs['content_type'] = ctype
+ ctype = None
+ if kwargs['file_name']:
+ ctype = mimetypes.guess_type(
+ kwargs['file_name'], strict=False)[0]
+ kwargs['content_type'] = ctype or 'application/octet-stream'
ret = self._proxy.Bug.add_attachment(kwargs)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-bugzilla-2.2.0/bugzilla/oldclasses.py
new/python-bugzilla-2.3.0/bugzilla/oldclasses.py
--- old/python-bugzilla-2.2.0/bugzilla/oldclasses.py 2018-08-10
22:32:30.000000000 +0200
+++ new/python-bugzilla-2.3.0/bugzilla/oldclasses.py 2019-01-27
00:26:40.000000000 +0100
@@ -7,17 +7,45 @@
from .base import Bugzilla
from .rhbugzilla import RHBugzilla
-
# These are old compat classes. Nothing new should be added here,
# and these should not be altered
-class Bugzilla3(Bugzilla): pass
-class Bugzilla32(Bugzilla): pass
-class Bugzilla34(Bugzilla): pass
-class Bugzilla36(Bugzilla): pass
-class Bugzilla4(Bugzilla): pass
-class Bugzilla42(Bugzilla): pass
-class Bugzilla44(Bugzilla): pass
-class NovellBugzilla(Bugzilla): pass
-class RHBugzilla3(RHBugzilla): pass
-class RHBugzilla4(RHBugzilla): pass
+
+class Bugzilla3(Bugzilla):
+ pass
+
+
+class Bugzilla32(Bugzilla):
+ pass
+
+
+class Bugzilla34(Bugzilla):
+ pass
+
+
+class Bugzilla36(Bugzilla):
+ pass
+
+
+class Bugzilla4(Bugzilla):
+ pass
+
+
+class Bugzilla42(Bugzilla):
+ pass
+
+
+class Bugzilla44(Bugzilla):
+ pass
+
+
+class NovellBugzilla(Bugzilla):
+ pass
+
+
+class RHBugzilla3(RHBugzilla):
+ pass
+
+
+class RHBugzilla4(RHBugzilla):
+ pass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-bugzilla-2.2.0/bugzilla/transport.py
new/python-bugzilla-2.3.0/bugzilla/transport.py
--- old/python-bugzilla-2.2.0/bugzilla/transport.py 2018-08-11
15:13:16.000000000 +0200
+++ new/python-bugzilla-2.3.0/bugzilla/transport.py 2019-01-09
21:17:37.000000000 +0100
@@ -9,11 +9,11 @@
# pylint: disable=import-error
if sys.version_info[0] >= 3:
- from configparser import SafeConfigParser
+ from configparser import ConfigParser
from urllib.parse import urlparse # pylint: disable=no-name-in-module
from xmlrpc.client import Fault, ProtocolError, ServerProxy, Transport
else:
- from ConfigParser import SafeConfigParser
+ from ConfigParser import SafeConfigParser as ConfigParser
from urlparse import urlparse
from xmlrpclib import Fault, ProtocolError, ServerProxy, Transport
# pylint: enable=import-error
@@ -39,7 +39,7 @@
def __init__(self, uri, tokenfilename):
self.tokenfilename = tokenfilename
- self.tokenfile = SafeConfigParser()
+ self.tokenfile = ConfigParser()
self.domain = urlparse(uri)[1]
if self.tokenfilename:
@@ -159,6 +159,7 @@
response.
"""
response = None
+ # pylint: disable=try-except-raise
try:
response = self.session.post(
url, data=request_body, **self.request_defaults)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-bugzilla-2.2.0/bugzilla.1
new/python-bugzilla-2.3.0/bugzilla.1
--- old/python-bugzilla-2.2.0/bugzilla.1 2018-04-16 17:32:40.000000000
+0200
+++ new/python-bugzilla-2.3.0/bugzilla.1 2019-01-27 00:26:40.000000000
+0100
@@ -40,6 +40,8 @@
Log in with this username
.IP "--password=PASSWORD"
Log in with this password
+.IP "--restrict-login"
+The session (login token) will be restricted to the current IP address.
.IP "--ensure-logged-in"
Raise an error if we aren't logged in to bugzilla. Consider using this if you
are depending on cached credentials, to ensure that when they expire the tool
errors, rather than subtly change output.
.IP "--no-cache-credentials"
@@ -223,23 +225,33 @@
Only show active components. Combine with --components*
-.SH AUTHENTICATION COOKIES AND TOKENS
+.SH AUTHENTICATION CACHE AND API KEYS
-Older bugzilla instances use cookie-based authentication, and
-newer bugzilla instances (around 5.0) use a non-cookie token system.
-
-When you log into bugzilla with the "login" subcommand or the "--login"
-argument, we cache the login credentials in ~/.cache/python-bugzilla/
-Previously we cached credentials in ~/.<filename>. If you want to see
-which file the tool is using, check --debug output.
-
-To perform an authenticated bugzilla command on a new machine, run a one time
-"bugzilla login" to cache credentials before running the desired command. You
-can also run "bugzilla --login" and the login process will be initiated before
-invoking the command.
-
-Additionally, the --no-cache-credentials option will tell the bugzilla tool to
-_not_ save any credentials in $HOME, or use any previously cached credentials.
+Some command usage will require an active login to the bugzilla
+instance. For example, if the bugzilla instance has some private
+bugs, those bugs will be missing from 'query' output if you do
+not have an active login.
+
+If you are connecting to a bugzilla 5.0 or later instance, the
+best option is to use bugzilla API keys. From the bugzilla
+web UI, log in, navigate to Preferences->API Keys, and generate
+a key (it will be a long string of characters and numbers).
+Then create a ~/.config/python-bugzilla/bugzillarc like this:
+
+ $ cat ~/.config/python-bugzilla/bugzillarc
+ [bugzilla.example.com]
+ api_key=YOUR_API_KEY
+
+Replace 'bugzilla.example.com' with your bugzilla host name,
+and YOUR_API_KEY with the generated API Key from the Web UI.
+
+For older bugzilla instances, you will need to cache a login
+cookie or token with the "login" subcommand or the "--login"
+argument.
+
+Additionally, the --no-cache-credentials option will tell the
+bugzilla tool to _not_ save or use any authentication cache,
+including the bugzillarc file.
.SH EXAMPLES
.PP
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-bugzilla-2.2.0/python-bugzilla.spec
new/python-bugzilla-2.3.0/python-bugzilla.spec
--- old/python-bugzilla-2.2.0/python-bugzilla.spec 2018-08-11
16:12:39.000000000 +0200
+++ new/python-bugzilla-2.3.0/python-bugzilla.spec 2019-08-26
23:31:03.000000000 +0200
@@ -15,7 +15,7 @@
%endif
Name: python-bugzilla
-Version: 2.2.0
+Version: 2.3.0
Release: 1%{?dist}
Summary: Python library for interacting with Bugzilla
@@ -49,7 +49,6 @@
%package -n python2-bugzilla
Summary: %summary
Requires: python2-requests
-Requires: python2-magic
# This dep is for back compat, so that installing python-bugzilla continues
# to give the cli tool
Requires: python-bugzilla-cli
@@ -64,7 +63,6 @@
%package -n python3-bugzilla
Summary: %summary
Requires: python3-requests
-Requires: python3-magic
%{?python_provide:%python_provide python3-bugzilla}
%if %{without python2}
@@ -144,7 +142,8 @@
%check
%if %{with python2}
-pytest
+# py.test naming is needed for RHEL7 compat, works fine with Fedora
+py.test
%endif # with python2
%if %{with python3}
pytest-3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-bugzilla-2.2.0/python_bugzilla.egg-info/PKG-INFO
new/python-bugzilla-2.3.0/python_bugzilla.egg-info/PKG-INFO
--- old/python-bugzilla-2.2.0/python_bugzilla.egg-info/PKG-INFO 2018-08-11
16:12:57.000000000 +0200
+++ new/python-bugzilla-2.3.0/python_bugzilla.egg-info/PKG-INFO 2019-08-26
23:31:57.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: python-bugzilla
-Version: 2.2.0
+Version: 2.3.0
Summary: Bugzilla XMLRPC access module
Home-page: https://github.com/python-bugzilla/python-bugzilla
Author: Cole Robinson
@@ -16,7 +16,7 @@
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-bugzilla-2.2.0/python_bugzilla.egg-info/SOURCES.txt
new/python-bugzilla-2.3.0/python_bugzilla.egg-info/SOURCES.txt
--- old/python-bugzilla-2.2.0/python_bugzilla.egg-info/SOURCES.txt
2018-08-11 16:12:57.000000000 +0200
+++ new/python-bugzilla-2.3.0/python_bugzilla.egg-info/SOURCES.txt
2019-08-26 23:31:57.000000000 +0200
@@ -32,7 +32,6 @@
tests/__init__.py
tests/conftest.py
tests/pycodestyle.cfg
-tests/pylint.cfg
tests/test_bug.py
tests/test_createbug.py
tests/test_misc.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-bugzilla-2.2.0/setup.py
new/python-bugzilla-2.3.0/setup.py
--- old/python-bugzilla-2.2.0/setup.py 2018-03-12 22:56:02.000000000 +0100
+++ new/python-bugzilla-2.3.0/setup.py 2019-01-27 00:26:40.000000000 +0100
@@ -12,7 +12,7 @@
def unsupported_python_version():
return sys.version_info < (2, 7) \
- or (sys.version_info > (3,) and sys.version_info < (3, 3))
+ or (sys.version_info > (3,) and sys.version_info < (3, 4))
if unsupported_python_version():
@@ -23,7 +23,7 @@
f = open("bugzilla/apiversion.py")
for line in f:
if line.startswith('version = '):
- return eval(line.split('=')[-1])
+ return eval(line.split('=')[-1]) # pylint: disable=eval-used
class TestCommand(Command):
@@ -51,26 +51,24 @@
import pylint.lint
import pycodestyle
- files = (["bugzilla-cli", "bugzilla"] +
+ files = (["bugzilla-cli", "bugzilla", "setup.py"] +
glob.glob("examples/*.py") +
glob.glob("tests/*.py"))
output_format = sys.stdout.isatty() and "colorized" or "text"
print("running pycodestyle")
style_guide = pycodestyle.StyleGuide(
- config_file='tests/pycodestyle.cfg',
+ config_file='tox.ini',
+ format="pylint",
paths=files,
)
- style_guide.options.exclude = pycodestyle.normalize_paths(
- "bugzilla/oldclasses.py",
- )
report = style_guide.check_files()
if style_guide.options.count:
sys.stderr.write(str(report.total_errors) + '\n')
print("running pylint")
pylint_opts = [
- "--rcfile", "tests/pylint.cfg",
+ "--rcfile", "pylintrc",
"--output-format=%s" % output_format,
]
pylint.lint.Run(files + pylint_opts)
@@ -108,37 +106,38 @@
return ret
-setup(name='python-bugzilla',
- version=get_version(),
- description='Bugzilla XMLRPC access module',
- author='Cole Robinson',
- author_email='[email protected]',
- license="GPLv2",
- url='https://github.com/python-bugzilla/python-bugzilla',
- classifiers=[
- 'Topic :: Software Development :: Libraries :: Python Modules',
- 'Intended Audience :: Developers',
- 'License :: OSI Approved :: Apache Software License',
- 'Operating System :: OS Independent',
- 'Programming Language :: Python',
- 'Programming Language :: Python :: 2',
- 'Programming Language :: Python :: 2.7',
- 'Programming Language :: Python :: 3',
- 'Programming Language :: Python :: 3.3',
- 'Programming Language :: Python :: 3.4',
- 'Programming Language :: Python :: 3.5',
- 'Programming Language :: Python :: 3.6',
- ],
- packages = ['bugzilla'],
- entry_points={'console_scripts': ['bugzilla = bugzilla._cli:cli']},
- data_files=[('share/man/man1', ['bugzilla.1'])],
-
- install_requires=_parse_requirements("requirements.txt"),
- tests_require=_parse_requirements("test-requirements.txt"),
-
- cmdclass={
- "pylint" : PylintCommand,
- "rpm" : RPMCommand,
- "test" : TestCommand,
- },
+setup(
+ name='python-bugzilla',
+ version=get_version(),
+ description='Bugzilla XMLRPC access module',
+ author='Cole Robinson',
+ author_email='[email protected]',
+ license="GPLv2",
+ url='https://github.com/python-bugzilla/python-bugzilla',
+ classifiers=[
+ 'Topic :: Software Development :: Libraries :: Python Modules',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: Apache Software License',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python',
+ 'Programming Language :: Python :: 2',
+ 'Programming Language :: Python :: 2.7',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.4',
+ 'Programming Language :: Python :: 3.5',
+ 'Programming Language :: Python :: 3.6',
+ 'Programming Language :: Python :: 3.7',
+ ],
+ packages=['bugzilla'],
+ entry_points={'console_scripts': ['bugzilla = bugzilla._cli:cli']},
+ data_files=[('share/man/man1', ['bugzilla.1'])],
+
+ install_requires=_parse_requirements("requirements.txt"),
+ tests_require=_parse_requirements("test-requirements.txt"),
+
+ cmdclass={
+ "pylint": PylintCommand,
+ "rpm": RPMCommand,
+ "test": TestCommand,
+ },
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-bugzilla-2.2.0/tests/pycodestyle.cfg
new/python-bugzilla-2.3.0/tests/pycodestyle.cfg
--- old/python-bugzilla-2.2.0/tests/pycodestyle.cfg 2018-03-04
21:47:34.000000000 +0100
+++ new/python-bugzilla-2.3.0/tests/pycodestyle.cfg 2019-01-27
00:26:40.000000000 +0100
@@ -1,12 +0,0 @@
-[pycodestyle]
-
-format = pylint
-
-# [E125] Continuation indent isn't different from next block
-# [E128] Not indented for visual style
-# [E129] visually indented line with same indent as next logical line
-# [E303] Too many blank lines
-# [E402] module level import not at top of file
-# [E731] do not assign a lambda expression, use a def
-
-ignore=E125,E128,E129,E303,E402,E731
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-bugzilla-2.2.0/tests/pylint.cfg
new/python-bugzilla-2.3.0/tests/pylint.cfg
--- old/python-bugzilla-2.2.0/tests/pylint.cfg 2018-03-12 22:56:02.000000000
+0100
+++ new/python-bugzilla-2.3.0/tests/pylint.cfg 1970-01-01 01:00:00.000000000
+0100
@@ -1,41 +0,0 @@
-[MASTER]
-persistent=no
-
-
-[MESSAGES CONTROL]
-# Disable the message, report, category or checker with the given id(s). You
-# can either give multiple identifier separated by comma (,) or put this option
-# multiple time (only on the command line, not in the configuration file where
-# it should appear only once).
-disable=Design,Format,Similarities,invalid-name,missing-docstring,locally-disabled,unnecessary-lambda,star-args,fixme,global-statement,broad-except,no-self-use,bare-except,locally-enabled,wrong-import-position,consider-using-ternary,len-as-condition,no-else-return
-enable=fixme
-
-
-[REPORTS]
-# Tells whether to display a full report or only the messages
-reports=no
-score=no
-
-
-[FORMAT]
-# Maximum number of characters on a single line.
-max-line-length=80
-
-# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
-# tab).
-indent-string=' '
-
-
-[MISCELLANEOUS]
-# List of note tags to take in consideration, separated by a comma.
-notes=FIXME,XXX,TODO
-
-
-[VARIABLES]
-# A regular expression matching the beginning of the name of dummy variables
-# (i.e. not used).
-dummy-variables-rgx=ignore.*|.*_ignore
-
-# List of additional names supposed to be defined in builtins. Remember that
-# you should avoid to define new builtins when possible.
-additional-builtins=_
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-bugzilla-2.2.0/tests/test_misc.py
new/python-bugzilla-2.3.0/tests/test_misc.py
--- old/python-bugzilla-2.2.0/tests/test_misc.py 2018-08-11
15:13:09.000000000 +0200
+++ new/python-bugzilla-2.3.0/tests/test_misc.py 2019-01-10
13:52:04.000000000 +0100
@@ -77,7 +77,7 @@
def test_readconfig(self):
# Testing for bugzillarc handling
bzapi = tests.make_bz("4.4.0", rhbz=True)
- bzapi.url = "foo.example.com"
+ bzapi.url = "example.com"
temp = tempfile.NamedTemporaryFile(mode="w")
content = """
@@ -92,6 +92,11 @@
assert bzapi.password == "test2"
assert bzapi.api_key is None
+ bzapi.url = "foo.example.com"
+ bzapi.user = None
+ bzapi.readconfig(temp.name)
+ assert bzapi.user is None
+
content = """
[foo.example.com]
user=test3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-bugzilla-2.2.0/tests/test_ro_functional.py
new/python-bugzilla-2.3.0/tests/test_ro_functional.py
--- old/python-bugzilla-2.2.0/tests/test_ro_functional.py 2018-08-11
15:13:09.000000000 +0200
+++ new/python-bugzilla-2.3.0/tests/test_ro_functional.py 2018-12-11
18:53:15.000000000 +0100
@@ -211,7 +211,7 @@
url = (tests.CLICONFIG.REDHAT_URL or
"https://bugzilla.redhat.com/xmlrpc.cgi")
bzclass = RHBugzilla
- bzversion = (4, 4)
+ bzversion = (5, 0)
test0 = BaseTest._testBZVersion
test01 = lambda s: BaseTest._testInfoProducts(s, 125,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-bugzilla-2.2.0/tests/test_rw_functional.py
new/python-bugzilla-2.3.0/tests/test_rw_functional.py
--- old/python-bugzilla-2.2.0/tests/test_rw_functional.py 2018-08-11
15:13:09.000000000 +0200
+++ new/python-bugzilla-2.3.0/tests/test_rw_functional.py 2019-01-09
20:49:46.000000000 +0100
@@ -525,18 +525,21 @@
setbug.refresh()
assert len(setbug.attachments) == (orignumattach + 2)
- assert setbug.attachments[-2]["summary"] == desc1
- assert (setbug.attachments[-2]["id"] ==
- int(out1.splitlines()[2].split()[2]))
- assert setbug.attachments[-1]["summary"] == desc2
- assert (setbug.attachments[-1]["id"] ==
- int(out2.splitlines()[2].split()[2]))
- attachid = setbug.attachments[-2]["id"]
+
+ att1 = setbug.attachments[-2]
+ attachid = att1["id"]
+ assert att1["summary"] == desc1
+ assert att1["id"] == int(out1.splitlines()[2].split()[2])
+ assert att1["content_type"] == "text/plain"
+
+ att2 = setbug.attachments[-1]
+ assert att2["summary"] == desc2
+ assert att2["id"] == int(out2.splitlines()[2].split()[2])
+ assert att2["content_type"] == "application/octet-stream"
# Set attachment flags
- assert setbug.attachments[-1]["flags"] == []
- bz.updateattachmentflags(setbug.id, setbug.attachments[-1]["id"],
- "review", status="+")
+ assert att1["flags"] == []
+ bz.updateattachmentflags(setbug.id, att2["id"], "review", status="+")
setbug.refresh()
assert len(setbug.attachments[-1]["flags"]) == 1
@@ -646,30 +649,28 @@
getpass.getpass = fakegetpass
try:
+ cmd = "bugzilla --no-cache-credentials --bugzilla %s" % self.url
# Implied login with --username and --password
- ret = tests.clicomm("bugzilla --bugzilla %s "
- "--user [email protected] "
- "--password foobar query -b 123456" % self.url,
+ ret = tests.clicomm("%s --user [email protected] "
+ "--password foobar query -b 123456" % cmd,
None, expectfail=True)
assert "Login failed: " in ret
# 'login' with explicit options
- ret = tests.clicomm("bugzilla --bugzilla %s "
- "--user [email protected] "
- "--password foobar login" % self.url,
+ ret = tests.clicomm("%s --user [email protected] "
+ "--password foobar login" % cmd,
None, expectfail=True)
assert "Login failed: " in ret
# 'login' with positional options
- ret = tests.clicomm("bugzilla --bugzilla %s "
- "login [email protected] foobar" % self.url,
+ ret = tests.clicomm("%s login [email protected] foobar" % cmd,
None, expectfail=True)
assert "Login failed: " in ret
# bare 'login'
stdinstr = StringIO("[email protected]\n\rfoobar\n\r")
- ret = tests.clicomm("bugzilla --bugzilla %s login" % self.url,
+ ret = tests.clicomm("%s login" % cmd,
None, expectfail=True, stdin=stdinstr)
assert "Bugzilla Username:" in ret
assert "Bugzilla Password:" in ret
@@ -812,7 +813,7 @@
def test12SetCookie(self):
bz = self.bzclass(self.url,
- cookiefile=-1, tokenfile=None)
+ cookiefile=-1, tokenfile=None, configpaths=[])
try:
bz.cookiefile = None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-bugzilla-2.2.0/xmlrpc-api-notes.txt
new/python-bugzilla-2.3.0/xmlrpc-api-notes.txt
--- old/python-bugzilla-2.2.0/xmlrpc-api-notes.txt 2018-03-18
15:30:44.000000000 +0100
+++ new/python-bugzilla-2.3.0/xmlrpc-api-notes.txt 2019-01-09
19:44:11.000000000 +0100
@@ -114,7 +114,7 @@
https://bugzilla.readthedocs.io/en/latest/api/index.html
-Redhat Bugzilla: 4.4 based with extensions. Bits on top of 4.4
+Redhat Bugzilla: 5.0 based with extensions
https://bugzilla.redhat.com/docs/en/html/api/
Bug.search has --from-url extension
Bug.update has more hashing support