Hello community,

here is the log from the commit of package python-devpi-client for 
openSUSE:Factory checked in at 2020-06-10 00:53:55
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-devpi-client (Old)
 and      /work/SRC/openSUSE:Factory/.python-devpi-client.new.3606 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-devpi-client"

Wed Jun 10 00:53:55 2020 rev:5 rq:813032 version:5.2.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-devpi-client/python-devpi-client.changes  
2020-05-28 09:18:07.545077646 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-devpi-client.new.3606/python-devpi-client.changes
        2020-06-10 00:54:19.555868370 +0200
@@ -1,0 +2,7 @@
+Tue Jun  9 19:25:40 UTC 2020 - Dirk Mueller <[email protected]>
+
+- update to 5.2.0:
+  - fix #799: proper error message for devpi login without prior devpi use
+  - Support for check_manifest>=0.42.
+
+-------------------------------------------------------------------

Old:
----
  devpi-client-5.1.1.tar.gz

New:
----
  devpi-client-5.2.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-devpi-client.spec ++++++
--- /var/tmp/diff_new_pack.BMrzA9/_old  2020-06-10 00:54:20.739871434 +0200
+++ /var/tmp/diff_new_pack.BMrzA9/_new  2020-06-10 00:54:20.743871445 +0200
@@ -18,7 +18,7 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-devpi-client
-Version:        5.1.1
+Version:        5.2.0
 Release:        0
 Summary:        Client for devpi
 License:        MIT

++++++ devpi-client-5.1.1.tar.gz -> devpi-client-5.2.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-5.1.1/CHANGELOG 
new/devpi-client-5.2.0/CHANGELOG
--- old/devpi-client-5.1.1/CHANGELOG    2019-12-18 09:08:44.000000000 +0100
+++ new/devpi-client-5.2.0/CHANGELOG    2020-05-04 11:28:32.000000000 +0200
@@ -2,30 +2,30 @@
 
 .. towncrier release notes start
 
-5.1.1 (2019-12-18)
+5.2.0 (2020-05-04)
 ==================
 
-Bug Fixes
----------
+Features
+--------
 
-- Fix removing a range of versions with index inheritance.
+- fix #140: support ``-f/--force`` option for deletion on non-volatile indexes 
with devpi-server >= 6.0.0.
 
 
-5.1.0 (2019-10-31)
-==================
+Bug Fixes
+---------
 
-Features
---------
+- fix #799: proper error message for devpi login without prior devpi use
+
+- Support for check_manifest>=0.42.
 
-- Add keyring support for ``devpi push`` to external repositories like 
pypi.org. This is compatible with ``twine``, see 
https://twine.readthedocs.io/en/latest/#keyring-support
 
+5.1.1 (2019-12-18)
+==================
 
 Bug Fixes
 ---------
 
-- fix #666: output nicer error message when section couldn't be found in 
pypirc.
-
-- the 410 status for the register action isn't marked as error anymore for 
push to external repository.
+- Fix removing a range of versions with index inheritance.
 
 
 5.1.0 (2019-10-31)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-5.1.1/PKG-INFO 
new/devpi-client-5.2.0/PKG-INFO
--- old/devpi-client-5.1.1/PKG-INFO     2019-12-18 09:08:48.000000000 +0100
+++ new/devpi-client-5.2.0/PKG-INFO     2020-05-04 11:28:35.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: devpi-client
-Version: 5.1.1
+Version: 5.2.0
 Summary: devpi upload/install/... workflow commands for Python developers
 Home-page: https://github.com/devpi/devpi
 Maintainer: Holger Krekel
@@ -39,30 +39,30 @@
         
         .. towncrier release notes start
         
-        5.1.1 (2019-12-18)
+        5.2.0 (2020-05-04)
         ==================
         
-        Bug Fixes
-        ---------
+        Features
+        --------
         
-        - Fix removing a range of versions with index inheritance.
+        - fix #140: support ``-f/--force`` option for deletion on non-volatile 
indexes with devpi-server >= 6.0.0.
         
         
-        5.1.0 (2019-10-31)
-        ==================
+        Bug Fixes
+        ---------
         
-        Features
-        --------
+        - fix #799: proper error message for devpi login without prior devpi 
use
         
-        - Add keyring support for ``devpi push`` to external repositories like 
pypi.org. This is compatible with ``twine``, see 
https://twine.readthedocs.io/en/latest/#keyring-support
+        - Support for check_manifest>=0.42.
         
         
+        5.1.1 (2019-12-18)
+        ==================
+        
         Bug Fixes
         ---------
         
-        - fix #666: output nicer error message when section couldn't be found 
in pypirc.
-        
-        - the 410 status for the register action isn't marked as error anymore 
for push to external repository.
+        - Fix removing a range of versions with index inheritance.
         
         
         5.1.0 (2019-10-31)
@@ -136,3 +136,4 @@
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-5.1.1/devpi/__init__.py 
new/devpi-client-5.2.0/devpi/__init__.py
--- old/devpi-client-5.1.1/devpi/__init__.py    2019-12-18 09:08:44.000000000 
+0100
+++ new/devpi-client-5.2.0/devpi/__init__.py    2020-05-04 11:28:32.000000000 
+0200
@@ -1,2 +1,2 @@
 
-__version__ = '5.1.1'
+__version__ = '5.2.0'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-5.1.1/devpi/list_remove.py 
new/devpi-client-5.2.0/devpi/list_remove.py
--- old/devpi-client-5.1.1/devpi/list_remove.py 2019-12-18 09:08:44.000000000 
+0100
+++ new/devpi-client-5.2.0/devpi/list_remove.py 2020-05-04 11:28:32.000000000 
+0200
@@ -1,5 +1,6 @@
 import json
 from devpi_common.metadata import get_sorted_versions, parse_requirement, 
Version
+from devpi_common.url import URL
 from devpi_common.viewhelp import ViewLinkStore, iter_toxresults
 from functools import partial
 
@@ -121,13 +122,20 @@
         out_index(hub, reply.result["projects"])
 
 
+def add_force_flag(url):
+    return url.replace(query=dict(url.get_query_dict(), force=''))
+
+
 def main_remove(hub, args):
     hub.require_valid_current_with_index()
     args = hub.args
     spec_or_url = args.spec_or_url
     if spec_or_url.startswith(('http://', 'https://')):
         # delete specified file
-        url = spec_or_url
+        url = URL(spec_or_url)
+        if args.force:
+            url = add_force_flag(url)
+        url = url.url
         if confirm_delete_file(hub, url):
             hub.http_api("delete", url)
         return
@@ -139,6 +147,8 @@
     index_url = hub.current.get_index_url(indexname=args.index)
     proj_url = hub.current.get_project_url(
         req.project_name, indexname=args.index)
+    if args.force:
+        proj_url = add_force_flag(proj_url)
     reply = hub.http_api("get", proj_url.replace(query=dict(ignore_bases="")), 
type="projectconfig")
     ver_to_delete = get_versions_to_delete(index_url, reply, req)
     if not ver_to_delete:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-5.1.1/devpi/login.py 
new/devpi-client-5.2.0/devpi/login.py
--- old/devpi-client-5.1.1/devpi/login.py       2019-12-18 09:08:44.000000000 
+0100
+++ new/devpi-client-5.2.0/devpi/login.py       2020-05-04 11:28:32.000000000 
+0200
@@ -3,6 +3,8 @@
 
 
 def main(hub, args):
+    if not hub.current.root_url:
+        hub.fatal("not connected to a server, see 'devpi use'")
     user = args.username
     if user is None:
         user = hub.raw_input("user: ")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-5.1.1/devpi/main.py 
new/devpi-client-5.2.0/devpi/main.py
--- old/devpi-client-5.1.1/devpi/main.py        2019-12-18 09:08:44.000000000 
+0100
+++ new/devpi-client-5.2.0/devpi/main.py        2020-05-04 11:28:32.000000000 
+0200
@@ -682,6 +682,8 @@
     """
     parser.add_argument("--index", default=None,
         help="index to remove from (defaults to current index)")
+    parser.add_argument("-f", "--force", action="store_true", default=False,
+        help="remove even on non-volatile index (with devpi-server >= 6.0.0)")
     parser.add_argument("spec_or_url",
         help="""\
         describes project/version/release file(s) to release from the current 
index. 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-5.1.1/devpi/upload.py 
new/devpi-client-5.2.0/devpi/upload.py
--- old/devpi-client-5.1.1/devpi/upload.py      2019-12-18 09:08:44.000000000 
+0100
+++ new/devpi-client-5.2.0/devpi/upload.py      2020-05-04 11:28:32.000000000 
+0200
@@ -273,13 +273,19 @@
 class Checkout:
     def __init__(self, hub, setupdir, hasvcs=None, setupdir_only=None):
         self.hub = hub
+        self.cm_ui = None
+        if hasattr(check_manifest, 'UI'):
+            self.cm_ui = check_manifest.UI()
         assert setupdir.join("setup.py").check(), setupdir
         hasvcs = not hasvcs and not hub.args.novcs
         setupdir_only = bool(setupdir_only or hub.args.setupdironly)
         if hasvcs:
             with setupdir.as_cwd():
                 try:
-                    hasvcs = check_manifest.detect_vcs().metadata_name
+                    if self.cm_ui:
+                        hasvcs = 
check_manifest.detect_vcs(self.cm_ui).metadata_name
+                    else:
+                        hasvcs = check_manifest.detect_vcs().metadata_name
                 except check_manifest.Failure:
                     hasvcs = None
                 else:
@@ -301,7 +307,10 @@
         if not self.hasvcs:
             return Exported(self.hub, self.setupdir, self.setupdir)
         with self.rootpath.as_cwd():
-            files = check_manifest.get_vcs_files()
+            if self.cm_ui:
+                files = check_manifest.get_vcs_files(self.cm_ui)
+            else:
+                files = check_manifest.get_vcs_files()
         newrepo = basetemp.join(self.rootpath.basename)
         for fn in files:
             source = self.rootpath.join(fn)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-5.1.1/devpi_client.egg-info/PKG-INFO 
new/devpi-client-5.2.0/devpi_client.egg-info/PKG-INFO
--- old/devpi-client-5.1.1/devpi_client.egg-info/PKG-INFO       2019-12-18 
09:08:48.000000000 +0100
+++ new/devpi-client-5.2.0/devpi_client.egg-info/PKG-INFO       2020-05-04 
11:28:35.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: devpi-client
-Version: 5.1.1
+Version: 5.2.0
 Summary: devpi upload/install/... workflow commands for Python developers
 Home-page: https://github.com/devpi/devpi
 Maintainer: Holger Krekel
@@ -39,30 +39,30 @@
         
         .. towncrier release notes start
         
-        5.1.1 (2019-12-18)
+        5.2.0 (2020-05-04)
         ==================
         
-        Bug Fixes
-        ---------
+        Features
+        --------
         
-        - Fix removing a range of versions with index inheritance.
+        - fix #140: support ``-f/--force`` option for deletion on non-volatile 
indexes with devpi-server >= 6.0.0.
         
         
-        5.1.0 (2019-10-31)
-        ==================
+        Bug Fixes
+        ---------
         
-        Features
-        --------
+        - fix #799: proper error message for devpi login without prior devpi 
use
         
-        - Add keyring support for ``devpi push`` to external repositories like 
pypi.org. This is compatible with ``twine``, see 
https://twine.readthedocs.io/en/latest/#keyring-support
+        - Support for check_manifest>=0.42.
         
         
+        5.1.1 (2019-12-18)
+        ==================
+        
         Bug Fixes
         ---------
         
-        - fix #666: output nicer error message when section couldn't be found 
in pypirc.
-        
-        - the 410 status for the register action isn't marked as error anymore 
for push to external repository.
+        - Fix removing a range of versions with index inheritance.
         
         
         5.1.0 (2019-10-31)
@@ -136,3 +136,4 @@
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-5.1.1/devpi_client.egg-info/SOURCES.txt 
new/devpi-client-5.2.0/devpi_client.egg-info/SOURCES.txt
--- old/devpi-client-5.1.1/devpi_client.egg-info/SOURCES.txt    2019-12-18 
09:08:48.000000000 +0100
+++ new/devpi-client-5.2.0/devpi_client.egg-info/SOURCES.txt    2020-05-04 
11:28:35.000000000 +0200
@@ -3,6 +3,7 @@
 LICENSE
 MANIFEST.in
 README.rst
+pyproject.toml
 setup.cfg
 setup.py
 tox.ini
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-5.1.1/pyproject.toml 
new/devpi-client-5.2.0/pyproject.toml
--- old/devpi-client-5.1.1/pyproject.toml       1970-01-01 01:00:00.000000000 
+0100
+++ new/devpi-client-5.2.0/pyproject.toml       2020-05-04 11:28:32.000000000 
+0200
@@ -0,0 +1,26 @@
+[tool.towncrier]
+package = "devpi"
+filename = "CHANGELOG"
+directory = "news/"
+title_format = "{version} ({project_date})"
+template = "news/_template.rst"
+
+  [[tool.towncrier.type]]
+  directory = "removal"
+  name = "Deprecations and Removals"
+  showcontent = true
+
+  [[tool.towncrier.type]]
+  directory = "feature"
+  name = "Features"
+  showcontent = true
+
+  [[tool.towncrier.type]]
+  directory = "bugfix"
+  name = "Bug Fixes"
+  showcontent = true
+
+  [[tool.towncrier.type]]
+  directory = "other"
+  name = "Other Changes"
+  showcontent = true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-5.1.1/setup.py 
new/devpi-client-5.2.0/setup.py
--- old/devpi-client-5.1.1/setup.py     2019-12-18 09:08:44.000000000 +0100
+++ new/devpi-client-5.2.0/setup.py     2020-05-04 11:28:32.000000000 +0200
@@ -40,7 +40,7 @@
       description="devpi upload/install/... workflow commands for Python "
                   "developers",
       long_description="\n\n".join([README, CHANGELOG]),
-      version='5.1.1',
+      version='5.2.0',
       packages=['devpi'],
       install_requires=install_requires,
       extras_require=extras_require,
@@ -57,7 +57,7 @@
         "Programming Language :: Python :: Implementation :: PyPy",
         ] + [
             ("Programming Language :: Python :: %s" % x) for x in
-                "2.7 3.4 3.5 3.6 3.7".split()],
+                "2.7 3.4 3.5 3.6 3.7 3.8".split()],
       entry_points = {
         'console_scripts': [
           "devpi = devpi.main:main"],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-5.1.1/testing/conftest.py 
new/devpi-client-5.2.0/testing/conftest.py
--- old/devpi-client-5.1.1/testing/conftest.py  2019-12-18 09:08:44.000000000 
+0100
+++ new/devpi-client-5.2.0/testing/conftest.py  2020-05-04 11:28:32.000000000 
+0200
@@ -157,7 +157,7 @@
 
 
 @pytest.fixture(scope="session")
-def server_executable(request):
+def server_executable(tmpdir_factory):
     # first try installed devpi-server for quick runs during development
     path = py.path.local.sysfind("devpi-server")
     if path:
@@ -171,7 +171,7 @@
     if sys.platform != "win32":
         env.pop("PATH", None)
     # create a virtualenv with Python 3
-    venv_path = request.config._tmpdirhandler.mktemp("server_venv")
+    venv_path = tmpdir_factory.mktemp("server_venv")
     subprocess.check_call(
         [sys.executable, '-m', 'virtualenv', '-p', python3, str(venv_path)],
         env=env)
@@ -196,7 +196,15 @@
         raise
 
 
-def _liveserver(clientdir, server_executable, server_version):
[email protected](scope="session")
+def indexer_backend_option(server_executable):
+    out = subprocess.check_output([server_executable, '-h'])
+    if b'--indexer-backend' in out:
+        return ['--indexer-backend', 'null']
+    return []
+
+
+def _liveserver(clientdir, indexer_backend_option, server_executable, 
server_version):
     host = 'localhost'
     port = get_open_port(host)
     try:
@@ -215,6 +223,7 @@
             getattr(e, 'output', "Can't get process output on Windows"),
             file=sys.stderr)
         raise
+    args.extend(indexer_backend_option)
     p = subprocess.Popen([server_executable] + args + [
         "--debug", "--host", host, "--port", str(port)])
     wait_for_port(host, port)
@@ -222,14 +231,14 @@
 
 
 @pytest.yield_fixture(scope="session")
-def url_of_liveserver(request, server_executable, server_version):
+def url_of_liveserver(request, indexer_backend_option, server_executable, 
server_version, tmpdir_factory):
     if request.config.option.fast:
         pytest.skip("not running functional tests in --fast mode")
     if request.config.option.live_url:
         yield URL(request.config.option.live_url)
         return
-    clientdir = request.config._tmpdirhandler.mktemp("liveserver")
-    (p, url) = _liveserver(clientdir, server_executable, server_version)
+    clientdir = tmpdir_factory.mktemp("liveserver")
+    (p, url) = _liveserver(clientdir, indexer_backend_option, 
server_executable, server_version)
     try:
         yield url
     finally:
@@ -238,11 +247,11 @@
 
 
 @pytest.yield_fixture(scope="session")
-def url_of_liveserver2(request, server_executable, server_version):
+def url_of_liveserver2(request, indexer_backend_option, server_executable, 
server_version, tmpdir_factory):
     if request.config.option.fast:
         pytest.skip("not running functional tests in --fast mode")
-    clientdir = request.config._tmpdirhandler.mktemp("liveserver2")
-    (p, url) = _liveserver(clientdir, server_executable, server_version)
+    clientdir = tmpdir_factory.mktemp("liveserver2")
+    (p, url) = _liveserver(clientdir, indexer_backend_option, 
server_executable, server_version)
     try:
         yield url
     finally:
@@ -607,20 +616,20 @@
         monkeypatch.setattr(cache.http, "gethtml", newgethtml)
     return mockhtml
 
+
 @pytest.fixture
 def create_venv(request, testdir, tmpdir_factory, monkeypatch):
     monkeypatch.delenv("PYTHONDONTWRITEBYTECODE", raising=False)
-    backupenv = tmpdir_factory.mktemp("venvbackup")
     venvdir = tmpdir_factory.mktemp("venv")
+    venvinstalldir = tmpdir_factory.mktemp("inst")
+
     def do_create_venv():
-        if not venvdir.listdir():
-            assert not backupenv.listdir()
-            result = testdir.run("virtualenv", "--never-download", venvdir)
-            assert result.ret == 0
-            venvdir.copy(backupenv, mode=True)
-        else:
-            venvdir.remove()
-            backupenv.copy(venvdir, mode=True)
+        # we need to change directory, otherwise the path will become
+        # too long on windows
+        venvinstalldir.ensure_dir()
+        os.chdir(venvinstalldir.strpath)
+        subprocess.check_call([
+            "virtualenv", "--never-download", venvdir.strpath])
         # activate
         if sys.platform == "win32":
             bindir = "Scripts"
@@ -628,6 +637,7 @@
             bindir = "bin"
         monkeypatch.setenv("PATH", bindir + os.pathsep + os.environ["PATH"])
         return venvdir
+
     return do_create_venv
 
 
@@ -649,11 +659,10 @@
     return hub
 
 @pytest.fixture(scope="session")
-def makehub(request):
-    handler = request.config._tmpdirhandler
+def makehub(tmpdir_factory):
     def mkhub(arglist):
         arglist = [str(x) for x in arglist]
-        tmp = handler.mktemp("hub")
+        tmp = tmpdir_factory.mktemp("hub")
         for x in arglist:
             if "--clientdir" in x:
                 break
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-5.1.1/testing/reqmock.py 
new/devpi-client-5.2.0/testing/reqmock.py
--- old/devpi-client-5.1.1/testing/reqmock.py   2019-12-18 09:08:44.000000000 
+0100
+++ new/devpi-client-5.2.0/testing/reqmock.py   2020-05-04 11:28:33.000000000 
+0200
@@ -18,6 +18,19 @@
     return mr
 
 
[email protected]
+def patch_reqsessionmock(monkeypatch):
+    def patch_reqsessionmock(session):
+        mr = mocked_request()
+
+        def get_adapter(self, url):
+            return MockAdapter(mr, url)
+
+        monkeypatch.setattr(session, "get_adapter", 
get_adapter.__get__(session))
+        return mr
+    return patch_reqsessionmock
+
+
 class MockAdapter:
     def __init__(self, mock_request, url):
         self.url = url
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-5.1.1/testing/simpypi.py 
new/devpi-client-5.2.0/testing/simpypi.py
--- old/devpi-client-5.1.1/testing/simpypi.py   2019-12-18 09:08:44.000000000 
+0100
+++ new/devpi-client-5.2.0/testing/simpypi.py   2020-05-04 11:28:33.000000000 
+0200
@@ -22,22 +22,23 @@
 
 
 def make_simple_pkg_info(name, text="", pkgver=None, hash_type=None,
-                         pypiserial=None, requires_python=None):
+                         pypiserial=None, requires_python=None, yanked=False):
     class ret:
         hash_spec = ""
+    attribs = ""
     if requires_python:
-        requires_python = ' data-requires-python="%s"' % 
escape(requires_python)
-    else:
-        requires_python = ''
+        attribs = ' data-requires-python="%s"' % escape(requires_python)
+    if yanked:
+        attribs = ' data-yanked=""'
     if pkgver is not None:
         assert not text
         if hash_type and "#" not in pkgver:
             hv = (pkgver + str(pypiserial)).encode("ascii")
             hash_value = getattr(hashlib, hash_type)(hv).hexdigest()
-            ret.hash_spec = "%s=%s" %(hash_type, hash_value)
+            ret.hash_spec = "%s=%s" % (hash_type, hash_value)
             pkgver += "#" + ret.hash_spec
-        text = '<a 
href="../../{name}/{pkgver}"{requires_python}>{pkgver}</a>'.format(
-            name=name, pkgver=pkgver, requires_python=requires_python)
+        text = '<a href="../../{name}/{pkgver}"{attribs}>{pkgver}</a>'.format(
+            name=name, pkgver=pkgver, attribs=attribs)
     elif text and "{md5}" in text:
         text = text.format(md5=getmd5(text))
     elif text and "{sha256}" in text:
@@ -138,11 +139,12 @@
         self.projects.pop(name)
 
     def add_release(self, name, title=None, text="", pkgver=None, 
hash_type=None,
-                    pypiserial=None, requires_python=None, **kw):
+                    pypiserial=None, requires_python=None, yanked=False, **kw):
         project = self.add_project(name, title=title)
         ret, text = make_simple_pkg_info(
             name, text=text, pkgver=pkgver, hash_type=hash_type,
-            pypiserial=pypiserial, requires_python=requires_python)
+            pypiserial=pypiserial, requires_python=requires_python,
+            yanked=yanked)
         assert text
         project['releases'].add(text.encode('utf-8'))
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-5.1.1/testing/test_list_remove.py 
new/devpi-client-5.2.0/testing/test_list_remove.py
--- old/devpi-client-5.1.1/testing/test_list_remove.py  2019-12-18 
09:08:44.000000000 +0100
+++ new/devpi-client-5.2.0/testing/test_list_remove.py  2020-05-04 
11:28:32.000000000 +0200
@@ -1,3 +1,4 @@
+from _pytest.outcomes import Failed
 from devpi_common.metadata import parse_requirement
 from devpi.list_remove import get_versions_to_delete
 from devpi.list_remove import confirm_delete
@@ -202,7 +203,7 @@
         out.stdout.fnmatch_lines_random("*/dev/*/dddttt-0.666.zip")
         out = out_devpi("remove", "dddttt==0.666", code=200)
         out = out_devpi("list", "dddttt", "--all")
-        with pytest.raises(ValueError):
+        with pytest.raises((Failed, ValueError)):
             out.stdout.fnmatch_lines_random("*/dev/*/dddttt-0.666.zip")
 
     def test_delete_version_range_with_inheritance(self, initproj, devpi, 
out_devpi, simpypi):
@@ -238,7 +239,7 @@
         out = out_devpi("remove", "dddttt<2.0", code=200)
         out = out_devpi("list", "dddttt", "--all")
         out.stdout.fnmatch_lines_random("*/dev/*/dddttt-0.666.zip")
-        with pytest.raises(ValueError):
+        with pytest.raises((Failed, ValueError)):
             out.stdout.fnmatch_lines_random("*/dev/*/dddttt-1.0.zip")
         out.stdout.fnmatch_lines_random("*/dev2/*/dddttt-2.0.zip")
 
@@ -253,5 +254,46 @@
         out.stdout.fnmatch_lines_random("*/dev/*/dddttt-0.666.zip")
         out = out_devpi("remove", "dddttt", code=200)
         out = out_devpi("list", "dddttt", "--all")
-        with pytest.raises(ValueError):
+        with pytest.raises((Failed, ValueError)):
+            out.stdout.fnmatch_lines_random("*/dev/*/dddttt-0.666.zip")
+
+    def test_delete_file_non_volatile(self, initproj, devpi, out_devpi, 
server_version):
+        from pkg_resources import parse_version
+        if server_version < parse_version("6dev"):
+            pytest.skip(
+                "devpi-server before 6.0.0 didn't support deleting "
+                "from non-volatile indexes.")
+        devpi("index", "volatile=false")
+        initproj("dddttt-0.666", {"doc": {
+            "conf.py": "",
+            "index.html": "<html/>"}})
+        assert py.path.local("setup.py").check()
+        devpi("upload", "--formats", "sdist.zip")
+        out = out_devpi("list", "dddttt", "--all")
+        out.stdout.fnmatch_lines_random("*/dev/*/dddttt-0.666.zip")
+        url = out.stdout.lines[0]
+        out = out_devpi("remove", url, code=403)
+        out = out_devpi("remove", "-f", url)
+        out = out_devpi("list", "dddttt", "--all")
+        with pytest.raises((Failed, ValueError)):
+            out.stdout.fnmatch_lines_random("*/dev/*/dddttt-0.666.zip")
+
+    def test_delete_project_non_volatile(self, initproj, devpi, out_devpi, 
server_version):
+        from pkg_resources import parse_version
+        if server_version < parse_version("6dev"):
+            pytest.skip(
+                "devpi-server before 6.0.0 didn't support deleting "
+                "from non-volatile indexes.")
+        devpi("index", "volatile=false")
+        initproj("dddttt-0.666", {"doc": {
+            "conf.py": "",
+            "index.html": "<html/>"}})
+        assert py.path.local("setup.py").check()
+        devpi("upload", "--formats", "sdist.zip")
+        out = out_devpi("list", "dddttt", "--all")
+        out.stdout.fnmatch_lines_random("*/dev/*/dddttt-0.666.zip")
+        out = out_devpi("remove", "dddttt", code=403)
+        out = out_devpi("remove", "--force", "dddttt")
+        out = out_devpi("list", "dddttt", "--all")
+        with pytest.raises((Failed, ValueError)):
             out.stdout.fnmatch_lines_random("*/dev/*/dddttt-0.666.zip")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-5.1.1/testing/test_login.py 
new/devpi-client-5.2.0/testing/test_login.py
--- old/devpi-client-5.1.1/testing/test_login.py        2019-12-18 
09:08:44.000000000 +0100
+++ new/devpi-client-5.2.0/testing/test_login.py        2020-05-04 
11:28:32.000000000 +0200
@@ -18,6 +18,7 @@
     class args:
         clientdir = tmpdir.join("client")
         username = "user"
+        password = None
     return args
 
 
@@ -26,7 +27,6 @@
     out = py.io.TextIO()
     hub = Hub(args, file=out)
     hub._out = out
-    hub.current._currentdict["login"] = "http://localhost/";
     return hub
 
 
@@ -36,7 +36,8 @@
     return partial(main, hub, args)
 
 
-def test_login_asks_for_passwd(args, login):
+def test_login_asks_for_passwd(args, hub, login):
+    hub.current._currentdict["login"] = "http://localhost/";
     args.password = None
     with pytest.raises(GetPassException):
         login()
@@ -44,6 +45,7 @@
 
 def test_login(args, hub, login, mock_http_api):
     args.password = "foo"
+    hub.current._currentdict["login"] = "http://localhost/";
     mock_http_api.set(hub.current.login, 200, result={
         "expiration": 36000,
         "password": "token"})
@@ -53,6 +55,13 @@
     assert "credentials valid for 10.00 hours" in out
 
 
+def test_login_without_use(hub, login):
+    with pytest.raises(SystemExit):
+        login()
+    out = hub._out.getvalue()
+    assert "not connected to a server, see 'devpi use'" in out
+
+
 def test_login_plugin(args, hub, login, mock_http_api):
     passwords = ["foo"]
 
@@ -63,6 +72,7 @@
 
     hub.pm.register(Plugin())
     args.password = None
+    hub.current._currentdict["login"] = "http://localhost/";
     mock_http_api.set(hub.current.login, 200, result={
         "expiration": 36000,
         "password": "token"})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-5.1.1/testing/test_upload.py 
new/devpi-client-5.2.0/testing/test_upload.py
--- old/devpi-client-5.1.1/testing/test_upload.py       2019-12-18 
09:08:44.000000000 +0100
+++ new/devpi-client-5.2.0/testing/test_upload.py       2020-05-04 
11:28:32.000000000 +0200
@@ -59,8 +59,8 @@
         return repo.join(setupdir_rel)
 
     @pytest.fixture(scope="class", params=["hg", "git"])
-    def repo(self, request, setupdir_rel):
-        repo = request.config._tmpdirhandler.mktemp("repo", numbered=True)
+    def repo(self, request, setupdir_rel, tmpdir_factory):
+        repo = tmpdir_factory.mktemp("repo", numbered=True)
         setupdir = repo.ensure_dir(setupdir_rel)
         file = setupdir.join("file")
         file.write("hello")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-5.1.1/tox.ini 
new/devpi-client-5.2.0/tox.ini
--- old/devpi-client-5.1.1/tox.ini      2019-12-18 09:08:44.000000000 +0100
+++ new/devpi-client-5.2.0/tox.ini      2020-05-04 11:28:32.000000000 +0200
@@ -4,18 +4,16 @@
 flake8-ignore =
     * E501
     *.py E111 E117 E121 E122 E123 E124 E126 E127 E128 E131 E201 E202 E211 E222 
E225 E226 E231 E251 E265 E271 E301 E302 E303 E305 E306 E401 E501 E711 E712 E722 
E741 W291 W391 W504
-rsyncdirs = devpi testing
-rsyncignore = .tox
 markers =
     nomocking: do not mock anything in fixtures
 
 [tox]
-minversion=1.9.2
-envlist = py27-server4,py27-version,py27,py27-lin,py34,py35,pypy
+envlist = py27-server4,py27-version,py27,py27-lin,py34,py38,pypy,pypy3
 
 [testenv]
 passenv = LANG
 deps = py34: colorama<=0.4.1 ; sys_platform == 'win32'
+       py34: virtualenv!=20.0.19;python_version=="3.4"
        pytest
        pytest-flake8
        pytest-instafail


Reply via email to