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 <jay...@gmail.com> + +- 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='python-bugzi...@lists.fedorahosted.org', - 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='python-bugzi...@lists.fedorahosted.org', + 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 foo...@example.com " - "--password foobar query -b 123456" % self.url, + ret = tests.clicomm("%s --user foo...@example.com " + "--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 foo...@example.com " - "--password foobar login" % self.url, + ret = tests.clicomm("%s --user foo...@example.com " + "--password foobar login" % cmd, None, expectfail=True) assert "Login failed: " in ret # 'login' with positional options - ret = tests.clicomm("bugzilla --bugzilla %s " - "login foo...@example.com foobar" % self.url, + ret = tests.clicomm("%s login foo...@example.com foobar" % cmd, None, expectfail=True) assert "Login failed: " in ret # bare 'login' stdinstr = StringIO("foo...@example.com\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