Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-devpi-client for 
openSUSE:Factory checked in at 2023-04-20 15:14:14
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-devpi-client (Old)
 and      /work/SRC/openSUSE:Factory/.python-devpi-client.new.2023 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-devpi-client"

Thu Apr 20 15:14:14 2023 rev:8 rq:1080284 version:6.0.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-devpi-client/python-devpi-client.changes  
2023-04-10 21:24:49.540743825 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-devpi-client.new.2023/python-devpi-client.changes
        2023-04-20 15:15:13.730169163 +0200
@@ -1,0 +2,14 @@
+Wed Apr 19 09:33:04 UTC 2023 - Dirk Müller <dmuel...@suse.com>
+
+- update to 6.0.4:
+  * Fix precedence of URL from command line over DEVPI_INDEX
+    environment variable for ``devpi use``.
+  * Fix relative DEVPI_INDEX environment variable with user and
+    index causing an invalid URL in some cases.
+  * Fix persistence of username when DEVPI_INDEX environment
+    variable is used with ``devpi login``.
+  * Fix precedence of ``--sdist`` and ``--wheel`` over
+    ``formats`` setting from setup.cfg ``[devpi:upload]``
+    section.
+
+-------------------------------------------------------------------

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

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

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

Other differences:
------------------
++++++ python-devpi-client.spec ++++++
--- /var/tmp/diff_new_pack.cStjZO/_old  2023-04-20 15:15:14.286172936 +0200
+++ /var/tmp/diff_new_pack.cStjZO/_new  2023-04-20 15:15:14.290172963 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           python-devpi-client
-Version:        6.0.3
+Version:        6.0.4
 Release:        0
 Summary:        Client for devpi
 License:        MIT

++++++ devpi-client-6.0.3.tar.gz -> devpi-client-6.0.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-6.0.3/CHANGELOG 
new/devpi-client-6.0.4/CHANGELOG
--- old/devpi-client-6.0.3/CHANGELOG    2023-02-20 10:11:07.000000000 +0100
+++ new/devpi-client-6.0.4/CHANGELOG    2023-04-13 07:14:01.000000000 +0200
@@ -2,6 +2,21 @@
 
 .. towncrier release notes start
 
+6.0.4 (2023-04-13)
+==================
+
+Bug Fixes
+---------
+
+- Fix precedence of URL from command line over DEVPI_INDEX environment 
variable for ``devpi use``.
+
+- Fix relative DEVPI_INDEX environment variable with user and index causing an 
invalid URL in some cases.
+
+- Fix persistence of username when DEVPI_INDEX environment variable is used 
with ``devpi login``.
+
+- Fix precedence of ``--sdist`` and ``--wheel`` over ``formats`` setting from 
setup.cfg ``[devpi:upload]`` section.
+
+
 6.0.3 (2023-02-20)
 ==================
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-6.0.3/PKG-INFO 
new/devpi-client-6.0.4/PKG-INFO
--- old/devpi-client-6.0.3/PKG-INFO     2023-02-20 10:11:16.122493500 +0100
+++ new/devpi-client-6.0.4/PKG-INFO     2023-04-13 07:14:10.173057600 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: devpi-client
-Version: 6.0.3
+Version: 6.0.4
 Summary: devpi upload/install/... workflow commands for Python developers
 Home-page: https://devpi.net
 Maintainer: Florian Schulze
@@ -61,6 +61,21 @@
 
 .. towncrier release notes start
 
+6.0.4 (2023-04-13)
+==================
+
+Bug Fixes
+---------
+
+- Fix precedence of URL from command line over DEVPI_INDEX environment 
variable for ``devpi use``.
+
+- Fix relative DEVPI_INDEX environment variable with user and index causing an 
invalid URL in some cases.
+
+- Fix persistence of username when DEVPI_INDEX environment variable is used 
with ``devpi login``.
+
+- Fix precedence of ``--sdist`` and ``--wheel`` over ``formats`` setting from 
setup.cfg ``[devpi:upload]`` section.
+
+
 6.0.3 (2023-02-20)
 ==================
 
@@ -166,12 +181,3 @@
 
 - When there is no json error message only the HTML error code and reason is 
printed now, to get the full HTML output use the ``--debug`` flag.
 
-
-5.2.3 (2021-11-15)
-==================
-
-Bug Fixes
----------
-
-- Bump upper version limit on pluggy to <2.0.
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-6.0.3/devpi/__init__.py 
new/devpi-client-6.0.4/devpi/__init__.py
--- old/devpi-client-6.0.3/devpi/__init__.py    2023-02-20 10:11:07.000000000 
+0100
+++ new/devpi-client-6.0.4/devpi/__init__.py    2023-04-13 07:14:01.000000000 
+0200
@@ -1,2 +1,2 @@
 
-__version__ = '6.0.3'
+__version__ = '6.0.4'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-6.0.3/devpi/main.py 
new/devpi-client-6.0.4/devpi/main.py
--- old/devpi-client-6.0.3/devpi/main.py        2023-02-20 10:11:07.000000000 
+0100
+++ new/devpi-client-6.0.4/devpi/main.py        2023-04-13 07:14:01.000000000 
+0200
@@ -258,30 +258,65 @@
         finally:
             rmtree(workdir.strpath, onerror=remove_readonly)
 
-    @cached_property
-    def current(self):
+    def get_current(self, args_url=None):
         self.clientdir.ensure(dir=1)
         current = PersistentCurrent(self.auth_path, self.current_path)
-        url = getattr(self.args, "index", None)
+        index_url = getattr(self.args, "index", None)
         if "DEVPI_INDEX" in os.environ:
-            if url is None:
-                if current.index is None:
+            devpi_index = os.environ["DEVPI_INDEX"]
+            self.debug("Got DEVPI_INDEX from environment: %s", devpi_index)
+            if args_url is not None:
+                self.info(
+                    "Using index URL from command line instead of "
+                    "DEVPI_INDEX (%s) from environment." % devpi_index)
+                # cache in case get_current was called directly
+                self.__dict__['current'] = current
+                return current
+            if URL(devpi_index).is_valid_http_url():
+                # switch to full DEVPI_INDEX URL, so possible relative
+                # --index switches work
+                current.persist_index = False
+                current.configure_fromurl(self, devpi_index)
+            if index_url is None:
+                if current.index is None or '/' in devpi_index:
                     url = current.root_url
                 else:
                     url = current.index_url
+                url = url.joinpath(devpi_index)
+                if not current.root_url.is_valid_http_url() and not 
url.is_valid_http_url():
+                    self.fatal(
+                        "No server set and DEVPI_INDEX from environment is not 
a "
+                        "full valid URL: %s" % devpi_index)
+                self.info("Using DEVPI_INDEX from environment: %s" % 
devpi_index)
             else:
-                url = URL(url)
-            devpi_index = os.environ["DEVPI_INDEX"]
-            url = url.joinpath(devpi_index)
-            if not current.root_url.is_valid_http_url() and not 
url.is_valid_http_url():
-                self.fatal(
-                    "No server set and DEVPI_INDEX from environment is not a "
-                    "full valid URL: %s" % devpi_index)
-            self.info("Using DEVPI_INDEX from environment: %s" % devpi_index)
+                url = URL(index_url)
+                if not url.is_valid_http_url():
+                    if not current.root_url.is_valid_http_url():
+                        if not URL(devpi_index).is_valid_http_url():
+                            self.fatal(
+                                "No server set and neither the --index URL 
(%s) "
+                                "nor the DEVPI_INDEX from environment (%s) is 
a "
+                                "full valid URL." % (index_url, devpi_index))
+                        url = URL(devpi_index)
+                        self.info("Using DEVPI_INDEX from environment: %s" % 
devpi_index)
+                    elif current.index is None or '/' in index_url:
+                        url = current.root_url
+                    else:
+                        url = current.index_url
+                    url = url.joinpath(index_url)
+        else:
+            url = index_url
         if url is not None:
-            current = current.switch_to_local(self, URL(url).url, None)
+            current.persist_index = False
+            current.configure_fromurl(self, URL(url).url)
+        # cache in case get_current was called directly
+        self.__dict__['current'] = current
         return current
 
+    @cached_property
+    def current(self):
+        return self.get_current()
+
     def get_existing_file(self, arg):
         p = py.path.local(arg, expanduser=True)
         if not p.exists():
@@ -1151,7 +1186,7 @@
         help="Install from the given requirements file.")
     parser.add_argument("pkgspecs", metavar="pkg", type=str,
         action="store", default=None, nargs="*",
-        help="uri or package file for installation from current index. """)
+        help="uri or package file for installation from current index. ")
 
 
 @subcommand("devpi.refresh")
@@ -1165,7 +1200,7 @@
         help="index to refresh (defaults to current index)")
     parser.add_argument(
         "pkgnames", metavar="pkg", type=str, action="store", nargs="+",
-        help="package name to refresh.""")
+        help="package name to refresh.")
 
 
 def verify_reply_version(hub, reply):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-6.0.3/devpi/upload.py 
new/devpi-client-6.0.4/devpi/upload.py
--- old/devpi-client-6.0.3/devpi/upload.py      2023-02-20 10:11:07.000000000 
+0100
+++ new/devpi-client-6.0.4/devpi/upload.py      2023-04-13 07:14:01.000000000 
+0200
@@ -139,7 +139,7 @@
         dic = meta.copy()
         pypi_action = action
         dic[":action"] = pypi_action
-        dic["protocol_version"] = "1",
+        dic["protocol_version"] = "1"
         headers = {}
         auth = hub.current.get_auth()
         if auth:
@@ -405,10 +405,12 @@
 
     def setup_build(self, default_formats=None):
         deprecated_formats = []
+        sdist = self.args.sdist
+        wheel = self.args.wheel
         formats = self.args.formats
         if formats is None:
             formats = default_formats
-        if formats:
+        if formats and not sdist and not wheel:
             sdist = None
             wheel = None
             for format in formats.split(","):
@@ -447,9 +449,6 @@
                     "The --formats option is deprecated, "
                     "you can remove it to get the default sdist and wheel "
                     "releases you get with your currently specified formats.")
-        else:
-            sdist = self.args.sdist
-            wheel = self.args.wheel
 
         cmds = []
         if sdist is not None or wheel is not None:
@@ -559,6 +558,7 @@
     setup_cfg = path.join("setup.cfg")
     if setup_cfg.exists():
         cfg = iniconfig.IniConfig(setup_cfg)
-        hub.line("detected devpi:upload section in %s" % setup_cfg, bold=True)
-        return cfg.sections.get("devpi:upload", {})
+        if 'devpi:upload' in cfg.sections:
+            hub.line("detected devpi:upload section in %s" % setup_cfg, 
bold=True)
+            return cfg.sections["devpi:upload"]
     return {}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-6.0.3/devpi/use.py 
new/devpi-client-6.0.4/devpi/use.py
--- old/devpi-client-6.0.3/devpi/use.py 2023-02-20 10:11:07.000000000 +0100
+++ new/devpi-client-6.0.4/devpi/use.py 2023-04-13 07:14:01.000000000 +0200
@@ -19,31 +19,36 @@
 devpi_data_keys = ["features"]
 
 
-def currentproperty(name):
-    def propget(self):
-        return self._currentdict.get(name, None)
+class baseproperty(object):
+    def __init__(self, name):
+        self.name = name
 
-    def propset(self, val):
-        self._currentdict[name] = val
+    def __get__(self, inst, owner=None):
+        if inst is None:
+            return self
+        return getattr(inst, self.dict_name).get(self.name)
 
-    return property(propget, propset)
+    def __set__(self, inst, value):
+        getattr(inst, self.dict_name)[self.name] = value
 
 
-def authproperty(name):
-    def propget(self):
-        return self._authdict.get(name, None)
+class authproperty(baseproperty):
+    dict_name = '_authdict'
 
-    def propset(self, val):
-        self._authdict[name] = val
 
-    return property(propget, propset)
+class currentproperty(baseproperty):
+    dict_name = '_currentdict'
+
+
+class indexproperty(baseproperty):
+    dict_name = '_currentdict'
 
 
 class Current(object):
-    index = currentproperty("index")
-    simpleindex = currentproperty("simpleindex")
-    pypisubmit = currentproperty("pypisubmit")
-    login = currentproperty("login")
+    index = indexproperty("index")
+    simpleindex = indexproperty("simpleindex")
+    pypisubmit = indexproperty("pypisubmit")
+    login = indexproperty("login")
     username = currentproperty("username")
     venvdir = currentproperty("venvdir")
     _auth = authproperty("auth")
@@ -381,19 +386,29 @@
             indexname=indexname).addpath(name, asdir=1)
 
 
+def _load_json(path, dest):
+    if path is None:
+        return
+    if not path.check():
+        return
+    raw = path.read().strip()
+    if not raw:
+        return
+    data = json.loads(raw)
+    if not isinstance(data, dict):
+        return
+    dest.update(data)
+
+
 class PersistentCurrent(Current):
+    persist_index = True
+
     def __init__(self, auth_path, current_path):
         Current.__init__(self)
         self.auth_path = auth_path
         self.current_path = current_path
-        if self.auth_path.check():
-            auth_data = self.auth_path.read().strip()
-            if auth_data:
-                self._authdict.update(json.loads(auth_data))
-        if self.current_path and self.current_path.check():
-            current_data = self.current_path.read().strip()
-            if current_data:
-                self._currentdict.update(json.loads(current_data))
+        _load_json(self.auth_path, self._authdict)
+        _load_json(self.current_path, self._currentdict)
 
     def exists(self):
         return self.current_path and self.current_path.check()
@@ -416,9 +431,16 @@
     def reconfigure(self, data, force_write=False):
         Current.reconfigure(self, data)
         self._persist(self._authdict, self.auth_path, force_write=force_write)
+        currentdict = {}
+        _load_json(self.current_path, currentdict)
+        for key, value in self._currentdict.items():
+            prop = getattr(self.__class__, key)
+            if isinstance(prop, indexproperty) and not self.persist_index:
+                continue
+            currentdict[key] = value
         # we make sure to remove legacy auth data
-        self._currentdict.pop("auth", None)
-        self._persist(self._currentdict, self.current_path, 
force_write=force_write)
+        currentdict.pop("auth", None)
+        self._persist(currentdict, self.current_path, force_write=force_write)
 
 
 def out_index_list(hub, data):
@@ -445,7 +467,7 @@
                 hub, current.index, hub.local_current_path)
             # now store existing data in new location
             current.reconfigure({}, force_write=True)
-    current = hub.current
+    current = hub.get_current(args.url)
 
     if args.delete:
         if not hub.current.exists():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-6.0.3/devpi_client.egg-info/PKG-INFO 
new/devpi-client-6.0.4/devpi_client.egg-info/PKG-INFO
--- old/devpi-client-6.0.3/devpi_client.egg-info/PKG-INFO       2023-02-20 
10:11:16.000000000 +0100
+++ new/devpi-client-6.0.4/devpi_client.egg-info/PKG-INFO       2023-04-13 
07:14:10.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: devpi-client
-Version: 6.0.3
+Version: 6.0.4
 Summary: devpi upload/install/... workflow commands for Python developers
 Home-page: https://devpi.net
 Maintainer: Florian Schulze
@@ -61,6 +61,21 @@
 
 .. towncrier release notes start
 
+6.0.4 (2023-04-13)
+==================
+
+Bug Fixes
+---------
+
+- Fix precedence of URL from command line over DEVPI_INDEX environment 
variable for ``devpi use``.
+
+- Fix relative DEVPI_INDEX environment variable with user and index causing an 
invalid URL in some cases.
+
+- Fix persistence of username when DEVPI_INDEX environment variable is used 
with ``devpi login``.
+
+- Fix precedence of ``--sdist`` and ``--wheel`` over ``formats`` setting from 
setup.cfg ``[devpi:upload]`` section.
+
+
 6.0.3 (2023-02-20)
 ==================
 
@@ -166,12 +181,3 @@
 
 - When there is no json error message only the HTML error code and reason is 
printed now, to get the full HTML output use the ``--debug`` flag.
 
-
-5.2.3 (2021-11-15)
-==================
-
-Bug Fixes
----------
-
-- Bump upper version limit on pluggy to <2.0.
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-6.0.3/pyproject.toml 
new/devpi-client-6.0.4/pyproject.toml
--- old/devpi-client-6.0.3/pyproject.toml       2023-02-20 10:11:07.000000000 
+0100
+++ new/devpi-client-6.0.4/pyproject.toml       2023-04-13 07:14:01.000000000 
+0200
@@ -3,7 +3,6 @@
 filename = "CHANGELOG"
 directory = "news/"
 title_format = "{version} ({project_date})"
-template = "news/_template.rst"
 
   [[tool.towncrier.type]]
   directory = "removal"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-6.0.3/setup.py 
new/devpi-client-6.0.4/setup.py
--- old/devpi-client-6.0.3/setup.py     2023-02-20 10:11:07.000000000 +0100
+++ new/devpi-client-6.0.4/setup.py     2023-04-13 07:14:01.000000000 +0200
@@ -44,7 +44,7 @@
       description="devpi upload/install/... workflow commands for Python "
                   "developers",
       long_description="\n\n".join([README, CHANGELOG]),
-      version='6.0.3',
+      version='6.0.4',
       packages=['devpi'],
       install_requires=install_requires,
       extras_require=extras_require,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-6.0.3/testing/conftest.py 
new/devpi-client-6.0.4/testing/conftest.py
--- old/devpi-client-6.0.3/testing/conftest.py  2023-02-20 10:11:07.000000000 
+0100
+++ new/devpi-client-6.0.4/testing/conftest.py  2023-04-13 07:14:01.000000000 
+0200
@@ -742,12 +742,10 @@
 
 
 @pytest.fixture
-def mock_http_api(monkeypatch):
+def mock_http_api(monkeypatch, reqmock):  # noqa
     """ mock out all Hub.http_api calls and return an object
     offering 'set' and 'add' to fake replies. """
     from devpi import main
-    from requests.sessions import Session
-    monkeypatch.setattr(Session, "request", None)
 
     class MockHTTPAPI:
         def __init__(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-6.0.3/testing/functional.py 
new/devpi-client-6.0.4/testing/functional.py
--- old/devpi-client-6.0.3/testing/functional.py        2023-02-20 
10:11:07.000000000 +0100
+++ new/devpi-client-6.0.4/testing/functional.py        2023-04-13 
07:14:01.000000000 +0200
@@ -13,6 +13,12 @@
     def __init__(self, d):
         self.__dict__ = d
 
+    def __repr__(self):
+        cls = self.__class__
+        name = "%s.%s" % (cls.__module__, cls.__name__)
+        return "<%s %r>" % (
+            name, self.__dict__.get('stagename', 'uninitialized'))
+
 
 class MappMixin:
     _usercount = 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-6.0.3/testing/reqmock.py 
new/devpi-client-6.0.4/testing/reqmock.py
--- old/devpi-client-6.0.3/testing/reqmock.py   2023-02-20 10:11:07.000000000 
+0100
+++ new/devpi-client-6.0.4/testing/reqmock.py   2023-04-13 07:14:01.000000000 
+0200
@@ -55,7 +55,7 @@
                         if fnmatch.fnmatch(request.url, name):
                             break
                 else:
-                    raise Exception("not mocked call to %s" % url)
+                    raise Exception("not mocked call to %s" % url)  # noqa: 
TRY002
         response.add_request(request)
         r = HTTPAdapter().build_response(request, response)
         return r
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-6.0.3/testing/simpypi.py 
new/devpi-client-6.0.4/testing/simpypi.py
--- old/devpi-client-6.0.3/testing/simpypi.py   2023-02-20 10:11:07.000000000 
+0100
+++ new/devpi-client-6.0.4/testing/simpypi.py   2023-04-13 07:14:01.000000000 
+0200
@@ -116,6 +116,9 @@
         self.simpleurl = "%s/simple" % self.baseurl
         self.projects = {}
         self.files = {}
+        self.clear()
+
+    def clear(self):
         self.clear_log()
         self.clear_requests()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-6.0.3/testing/test_login.py 
new/devpi-client-6.0.4/testing/test_login.py
--- old/devpi-client-6.0.3/testing/test_login.py        2023-02-20 
10:11:07.000000000 +0100
+++ new/devpi-client-6.0.4/testing/test_login.py        2023-04-13 
07:14:01.000000000 +0200
@@ -87,3 +87,45 @@
     out = hub._out.getvalue()
     assert "logged in 'user'" in out
     assert "credentials valid for 10.00 hours" in out
+
+
+@pytest.mark.skipif("config.option.fast")
+def test_login_with_index_environment(capfd, devpi, devpi_username, 
monkeypatch, tmpdir, url_of_liveserver):
+    # remove persisted client for fresh start
+    clientdir = tmpdir.join("client")
+    clientdir.remove()
+    monkeypatch.setenv("DEVPI_INDEX", url_of_liveserver.url)
+    devpi("use")
+    (out, err) = capfd.readouterr()
+    assert "using server: %s/ (not logged in)" % url_of_liveserver.url in out
+    devpi("login", devpi_username, "--password", "123")
+    (out, err) = capfd.readouterr()
+    assert 'credentials valid for' in out
+    devpi("use")
+    (out, err) = capfd.readouterr()
+    msg = "using server: %s/ (logged in as %s)" % (
+        url_of_liveserver.url,
+        devpi_username)
+    assert msg in out
+
+
+@pytest.mark.skipif("config.option.fast")
+def test_login_with_relative_index_environment(capfd, devpi, devpi_username, 
monkeypatch, tmpdir, url_of_liveserver):
+    # remove persisted client for fresh start
+    clientdir = tmpdir.join("client")
+    clientdir.remove()
+    devpi_index = "%s/dev" % devpi_username
+    monkeypatch.setenv("DEVPI_INDEX", devpi_index)
+    devpi("use", url_of_liveserver.url)
+    (out, err) = capfd.readouterr()
+    assert "using server: %s/ (not logged in)" % url_of_liveserver.url in out
+    devpi("login", devpi_username, "--password", "123")
+    (out, err) = capfd.readouterr()
+    assert 'credentials valid for' in out
+    devpi("use")
+    (out, err) = capfd.readouterr()
+    url = url_of_liveserver.joinpath(devpi_index).url
+    msg = "current devpi index: %s (logged in as %s)" % (
+        url,
+        devpi_username)
+    assert msg in out
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-6.0.3/testing/test_main.py 
new/devpi-client-6.0.4/testing/test_main.py
--- old/devpi-client-6.0.3/testing/test_main.py 2023-02-20 10:11:07.000000000 
+0100
+++ new/devpi-client-6.0.4/testing/test_main.py 2023-04-13 07:14:01.000000000 
+0200
@@ -84,7 +84,7 @@
     try:
         import importlib.metadata as importlib_metadata
     except ImportError:
-        import importlib_metadata as importlib_metadata
+        import importlib_metadata
     ver = devpi.__version__
     assert importlib_metadata.version("devpi-client") == ver
 
@@ -112,3 +112,88 @@
     names = [x.strip().split()[0] for x in lines]
     assert 'devpi-client' in names
     assert 'devpi-server' in names
+
+
+@pytest.mark.parametrize("devpi_index", ["user/dev", "/user/dev"])
+def test_index_option_with_environment_relative_root_current(
+        capfd, cmd_devpi, devpi_index, initproj,
+        mock_http_api, monkeypatch, reqmock):
+    mock_http_api.set(
+        "http://devpi/+api";, 200, result=dict(
+            login="http://devpi/+login";,
+            authstatus=["noauth", "", []]))
+    cmd_devpi("use", "http://devpi";)
+    monkeypatch.setenv("DEVPI_INDEX", "foo/bar")
+    initproj("hello1.1")
+    mock_http_api.set(
+        "http://devpi/user/dev/+api";, 200, result=dict(
+            pypisubmit="http://devpi/user/dev/";,
+            simpleindex="http://devpi/user/dev/+simple/";,
+            index="http://devpi/user/dev";,
+            login="http://devpi/+login";,
+            authstatus=["noauth", "", []]))
+    (out, err) = capfd.readouterr()
+    reqmock.mockresponse("http://devpi/user/dev/";, 200)
+    cmd_devpi("upload", "--no-isolation", "--index", devpi_index)
+    (out, err) = capfd.readouterr()
+    assert "DEVPI_INDEX" not in out
+    assert "foo/bar" not in out
+    assert "file_upload of hello1.1-0.1.tar.gz to http://devpi/user/dev/"; in 
out.splitlines()
+
+
+@pytest.mark.parametrize("devpi_index", ["user/dev", "/user/dev"])
+def test_index_option_with_environment_relative_user_current(
+        capfd, cmd_devpi, devpi_index, initproj,
+        mock_http_api, monkeypatch, reqmock):
+    mock_http_api.set(
+        "http://devpi/user/+api";, 200, result=dict(
+            login="http://devpi/+login";,
+            authstatus=["noauth", "", []]))
+    cmd_devpi("use", "http://devpi/user";)
+    monkeypatch.setenv("DEVPI_INDEX", "foo/bar")
+    initproj("hello1.1")
+    mock_http_api.set(
+        "http://devpi/user/dev/+api";, 200, result=dict(
+            pypisubmit="http://devpi/user/dev/";,
+            simpleindex="http://devpi/user/dev/+simple/";,
+            index="http://devpi/user/dev";,
+            login="http://devpi/+login";,
+            authstatus=["noauth", "", []]))
+    (out, err) = capfd.readouterr()
+    reqmock.mockresponse("http://devpi/user/dev/";, 200)
+    cmd_devpi("upload", "--no-isolation", "--index", devpi_index)
+    (out, err) = capfd.readouterr()
+    assert "DEVPI_INDEX" not in out
+    assert "foo/bar" not in out
+    assert "file_upload of hello1.1-0.1.tar.gz to http://devpi/user/dev/"; in 
out.splitlines()
+
+
+@pytest.mark.parametrize("devpi_index", ["user/dev", "/user/dev"])
+def test_index_option_with_environment_relative(
+        capfd, cmd_devpi, devpi_index, initproj,
+        mock_http_api, monkeypatch, reqmock):
+    mock_http_api.set(
+        "http://devpi/user/foo/+api";, 200, result=dict(
+            pypisubmit="http://devpi/user/foo/";,
+            simpleindex="http://devpi/user/foo/+simple/";,
+            index="http://devpi/user/foo";,
+            login="http://devpi/+login";,
+            authstatus=["noauth", "", []]))
+    mock_http_api.set("http://devpi/user/foo?no_projects=";, 200, result=dict())
+    cmd_devpi("use", "http://devpi/user/foo";)
+    monkeypatch.setenv("DEVPI_INDEX", "foo/bar")
+    initproj("hello1.1")
+    mock_http_api.set(
+        "http://devpi/user/dev/+api";, 200, result=dict(
+            pypisubmit="http://devpi/user/dev/";,
+            simpleindex="http://devpi/user/dev/+simple/";,
+            index="http://devpi/user/dev";,
+            login="http://devpi/+login";,
+            authstatus=["noauth", "", []]))
+    (out, err) = capfd.readouterr()
+    reqmock.mockresponse("http://devpi/user/dev/";, 200)
+    cmd_devpi("upload", "--no-isolation", "--index", devpi_index)
+    (out, err) = capfd.readouterr()
+    assert "DEVPI_INDEX" not in out
+    assert "foo/bar" not in out
+    assert "file_upload of hello1.1-0.1.tar.gz to http://devpi/user/dev/"; in 
out.splitlines()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-6.0.3/testing/test_push.py 
new/devpi-client-6.0.4/testing/test_push.py
--- old/devpi-client-6.0.3/testing/test_push.py 2023-02-20 10:11:07.000000000 
+0100
+++ new/devpi-client-6.0.4/testing/test_push.py 2023-04-13 07:14:01.000000000 
+0200
@@ -90,6 +90,31 @@
     assert len(mock_http_api.called) == 1
 
 
+def test_push_devpi_index_option_with_environment(loghub, monkeypatch, 
mock_http_api):
+    loghub.args.target = "user/name"
+    loghub.args.index = "src/dev"
+    monkeypatch.setenv("DEVPI_INDEX", "http://devpi/user/dev";)
+    mock_http_api.set(
+        "http://devpi/user/dev/+api";, 200, result=dict(
+            pypisubmit="http://devpi/user/dev/";,
+            simpleindex="http://devpi/user/dev/+simple/";,
+            index="http://devpi/user/dev";,
+            login="http://devpi/+login";,
+            authstatus=["noauth", "", []]))
+    mock_http_api.set(
+        "http://devpi/src/dev/+api";, 200, result=dict(
+            pypisubmit="http://devpi/src/dev/";,
+            simpleindex="http://devpi/src/dev/+simple/";,
+            index="http://devpi/src/dev";,
+            login="http://devpi/+login";,
+            authstatus=["noauth", "", []]))
+    pusher = parse_target(loghub, loghub.args)
+    mock_http_api.set("http://devpi/src/dev";, 200, result={})
+    pusher.execute(loghub, "pytest", "2.3.5")
+    dict(name="pytest", version="2.3.5", targetindex="user/name")
+    assert len(mock_http_api.called) == 3
+
+
 @pytest.mark.parametrize("spec", ("pkg==1.0", "pkg-1.0"))
 def test_main_push_pypi(capsys, monkeypatch, tmpdir, spec):
     from devpi.push import main
@@ -244,7 +269,7 @@
             msgs.append(msg)
     hub = MockHub()
     hub.derive_token = Hub.derive_token.__get__(hub)
-    hub.derive_token("%s-foo" % prefix, None) == "%s-foo" % prefix
+    assert hub.derive_token("%s-foo" % prefix, None) == "%s-foo" % prefix
     (msg,) = msgs
     assert "can not parse it" in msg
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-6.0.3/testing/test_upload.py 
new/devpi-client-6.0.4/testing/test_upload.py
--- old/devpi-client-6.0.3/testing/test_upload.py       2023-02-20 
10:11:07.000000000 +0100
+++ new/devpi-client-6.0.4/testing/test_upload.py       2023-04-13 
07:14:01.000000000 +0200
@@ -96,7 +96,7 @@
             runproc("git commit -m message")
         return repo
 
-    def test_vcs_export(self, uploadhub, repo, setupdir, tmpdir, monkeypatch):
+    def test_vcs_export(self, uploadhub, repo, setupdir, tmpdir):
         checkout = Checkout(uploadhub, uploadhub.args, setupdir)
         assert checkout.rootpath == repo
         newrepo = tmpdir.mkdir("newrepo")
@@ -145,8 +145,7 @@
         exported = checkout.export(tmpdir)
         assert exported.rootpath == checkout.setupdir
 
-    def test_vcs_export_verify_setup(self, uploadhub, setupdir,
-                                          tmpdir, monkeypatch):
+    def test_vcs_export_verify_setup(self, uploadhub, setupdir, tmpdir):
         subdir = setupdir.mkdir("subdir")
         subdir.ensure("setup.py")
         checkout = Checkout(uploadhub, uploadhub.args, subdir)
@@ -154,7 +153,7 @@
         exported = checkout.export(wc)
         assert not exported.rootpath.join("setup.py").check()
 
-    def test_export_attributes(self, uploadhub, setupdir, tmpdir, monkeypatch):
+    def test_export_attributes(self, uploadhub, setupdir, tmpdir):
         checkout = Checkout(uploadhub, uploadhub.args, setupdir)
         setupdir.join("setup.py").write(dedent("""
             from setuptools import setup
@@ -167,7 +166,7 @@
         assert name == "xyz"
         assert version == "1.2.3"
 
-    def test_setup_build_docs(self, uploadhub, setupdir, tmpdir, monkeypatch):
+    def test_setup_build_docs(self, uploadhub, setupdir, tmpdir):
         checkout = Checkout(uploadhub, uploadhub.args, setupdir)
         setupdir.join("setup.py").write(dedent("""
             from setuptools import setup
@@ -229,7 +228,7 @@
 
 
 @pytest.mark.skipif("config.option.fast")
-def test_post_includes_auth_info(initproj, monkeypatch, uploadhub):
+def test_post_includes_auth_info(initproj, uploadhub):
     class Session:
         posts = []
 
@@ -241,7 +240,9 @@
 
     class args:
         dryrun = None
-        formats = "sdist,bdist_wheel"
+        sdist = False
+        wheel = False
+        formats = None
         index = None
         no_isolation = True
         novcs = None
@@ -277,9 +278,63 @@
     assert "X-Devpi-Auth" in upload2[1]["headers"]
 
 
+@pytest.mark.skipif("sys.version_info < (3,)")
+@pytest.mark.skipif("config.option.fast")
+def test_post_data(initproj, monkeypatch, reqmock, uploadhub):
+    import email
+
+    class args:
+        dryrun = None
+        sdist = False
+        wheel = False
+        formats = None
+        index = None
+        no_isolation = True
+        novcs = None
+        only_latest = None
+        onlydocs = None
+        path = None
+        python = None
+        setupdironly = None
+        verbose = 0
+        withdocs = None
+
+    class Response:
+        status_code = 200
+
+    sent = []
+
+    def send(req, **kw):
+        sent.append((req, kw))
+        return Response()
+
+    initproj("pkg-1.0")
+    tmpdir = py.path.local()
+    uploadhub.cwd = tmpdir
+    uploadhub.current.reconfigure(dict(
+        index="http://devpi/foo/bar";,
+        login="http://devpi/+login";,
+        pypisubmit="http://devpi/foo/bar";))
+    monkeypatch.setattr(uploadhub.http, "send", send)
+    main(uploadhub, args)
+    # convert POST data to Message
+    msg = email.message_from_bytes(
+        b"MIME-Version: 1.0\nContent-Type: %s\n\n%s" % (
+            sent[0][0].headers['Content-Type'].encode('ascii'),
+            sent[0][0].body))
+    # get the data
+    data = {
+        x.get_param("name", header="Content-Disposition"): x.get_payload()
+        for x in msg.get_payload()}
+    assert data[":action"] == "file_upload"
+    assert data["name"] == "pkg"
+    assert data["protocol_version"] == "1"
+    assert data["version"] == "1.0"
+
+
 @pytest.mark.skipif("sys.version_info < (3, 7)")
 @pytest.mark.skipif("config.option.fast")
-def test_post_derived_devpi_token(initproj, monkeypatch, uploadhub):
+def test_post_derived_devpi_token(initproj, uploadhub):
     from base64 import b64decode
     import pypitoken
 
@@ -587,6 +642,27 @@
         out = out_devpi("upload", "--no-isolation", "--index", "%s/dev" % 
user, "--dry-run")
         out.stdout.fnmatch_lines_random("skipped: file_upload*to*/%s/dev*" % 
user)
 
+    @pytest.mark.parametrize("other_index", ["root/pypi", "/"])
+    def test_index_option_with_environment_relative(
+            self, devpi, initproj, monkeypatch, out_devpi,
+            other_index, projname_version):
+        initproj(projname_version.rsplit("-", 1), {"doc": {
+            "conf.py": "#nothing",
+            "contents.rst": "",
+            "index.html": "<html/>"}})
+        assert py.path.local("setup.py").check()
+        # remember username
+        out = out_devpi("use")
+        user = re.search(r'\(logged in as (.+?)\)', out.stdout.str()).group(1)
+
+        # go to other index
+        out = out_devpi("use", other_index)
+
+        monkeypatch.setenv("DEVPI_INDEX", "user/dev")
+        # --index option
+        out = out_devpi("upload", "--no-isolation", "--index", "%s/dev" % 
user, "--dry-run")
+        out.stdout.fnmatch_lines_random("skipped: file_upload*to*/%s/dev*" % 
user)
+
     def test_logout(self, capfd, devpi, out_devpi, projname_version):
         # logoff then upload
         out = out_devpi("logoff")
@@ -601,7 +677,7 @@
         assert isinstance(res.sysex, SystemExit)
         assert res.sysex.args == (1,)
 
-    def test_fromdir(self, initproj, devpi, out_devpi, runproc, monkeypatch):
+    def test_fromdir(self, initproj, devpi, out_devpi, runproc):
         initproj("hello-1.1", {"doc": {
             "conf.py": "",
             "index.html": "<html/>"}})
@@ -653,6 +729,36 @@
         assert links["releasefile"] == "%s.zip" % name_version_str
         assert links["doczip"] == "%s.doc.zip" % name_version_str
 
+    def test_cli_sdist_precedence(self, initproj, devpi, out_devpi):
+        initproj("pkg-1.0")
+        tmpdir = py.path.local()
+        tmpdir.join("setup.cfg").write(dedent("""
+            [devpi:upload]
+            formats=bdist_wheel,sdist.zip"""))
+        hub = devpi("upload", "--sdist", "--no-isolation")
+        url = hub.current.get_index_url().url + 'pkg/1.0/'
+        out = out_devpi("getjson", url)
+        data = json.loads(out.stdout.str())
+        vv = ViewLinkStore(url, data["result"])
+        assert len(vv.get_links()) == 1
+        assert vv.get_links()[0].basename in ('pkg-1.0.tar.gz', 'pkg-1.0.zip')
+
+    def test_cli_wheel_precedence(self, initproj, devpi, out_devpi):
+        initproj("pkg-1.0")
+        tmpdir = py.path.local()
+        tmpdir.join("setup.cfg").write(dedent("""
+            [devpi:upload]
+            formats=bdist_wheel,sdist.zip"""))
+        hub = devpi("upload", "--wheel", "--no-isolation")
+        url = hub.current.get_index_url().url + 'pkg/1.0/'
+        out = out_devpi("getjson", url)
+        data = json.loads(out.stdout.str())
+        vv = ViewLinkStore(url, data["result"])
+        assert len(vv.get_links()) == 1
+        assert vv.get_links()[0].basename in (
+            'pkg-1.0-py2-none-any.whl',
+            'pkg-1.0-py3-none-any.whl')
+
 
 def test_getpkginfo(datadir):
     info = get_pkginfo(datadir.join("dddttt-0.1.dev45-py27-none-any.whl"))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-6.0.3/testing/test_use.py 
new/devpi-client-6.0.4/testing/test_use.py
--- old/devpi-client-6.0.3/testing/test_use.py  2023-02-20 10:11:07.000000000 
+0100
+++ new/devpi-client-6.0.4/testing/test_use.py  2023-04-13 07:14:01.000000000 
+0200
@@ -802,6 +802,70 @@
         assert "login: http://devpi/+login"; in out
 
     @pytest.mark.parametrize("devpi_index", ["user/dev", "/user/dev"])
+    def test_environment_relative_with_current(
+            self, capfd, cmd_devpi, devpi_index, mock_http_api, monkeypatch):
+        mock_http_api.set(
+            "http://world/user/dev/+api";, 200, result=dict(
+                pypisubmit="http://world/user/dev/";,
+                simpleindex="http://world/user/dev/+simple/";,
+                index="http://world/user/dev";,
+                login="http://world/+login";,
+                authstatus=["noauth", "", []]))
+        mock_http_api.set("http://world/user/dev?no_projects=";, 200, 
result=dict())
+        cmd_devpi("use", "http://world/user/dev";)
+        (out, err) = capfd.readouterr()
+        cmd_devpi("use", "--urls")
+        (out, err) = capfd.readouterr()
+        assert "index: http://world/user/dev"; in out
+        assert "simpleindex: http://world/user/dev/+simple/"; in out
+        assert "pypisubmit: http://world/user/dev/"; in out
+        assert "login: http://world/+login"; in out
+        monkeypatch.setenv("DEVPI_INDEX", devpi_index)
+        mock_http_api.set(
+            "http://world/user/dev/+api";, 200, result=dict(
+                pypisubmit="http://world/user/dev/";,
+                simpleindex="http://world/user/dev/+simple/";,
+                index="http://world/user/dev";,
+                login="http://world/+login";,
+                authstatus=["noauth", "", []]))
+        mock_http_api.set("http://world/user/dev?no_projects=";, 200, 
result=dict())
+        cmd_devpi("use", "--urls")
+        (out, err) = capfd.readouterr()
+        assert "Using DEVPI_INDEX from environment: %s\n" % devpi_index in out
+        assert "index: http://world/user/dev"; in out
+        assert "simpleindex: http://world/user/dev/+simple/"; in out
+        assert "pypisubmit: http://world/user/dev/"; in out
+        assert "login: http://world/+login"; in out
+
+    def test_environment_with_root_current(self, capfd, cmd_devpi, 
mock_http_api, monkeypatch):
+        mock_http_api.set(
+            "http://world/+api";, 200, result=dict(
+                login="http://world/+login";,
+                authstatus=["noauth", "", []]))
+        cmd_devpi("use", "http://world/";)
+        (out, err) = capfd.readouterr()
+        cmd_devpi("use", "--urls")
+        (out, err) = capfd.readouterr()
+        assert "using server: http://world/ (not logged in)" in out
+        assert "no current index" in out
+        monkeypatch.setenv("DEVPI_INDEX", "http://devpi/user/dev";)
+        mock_http_api.set(
+            "http://devpi/user/dev/+api";, 200, result=dict(
+                pypisubmit="http://devpi/user/dev/";,
+                simpleindex="http://devpi/user/dev/+simple/";,
+                index="http://devpi/user/dev";,
+                login="http://devpi/+login";,
+                authstatus=["noauth", "", []]))
+        mock_http_api.set("http://devpi/user/dev?no_projects=";, 200, 
result=dict())
+        cmd_devpi("use", "--urls")
+        (out, err) = capfd.readouterr()
+        assert "Using DEVPI_INDEX from environment: http://devpi/user/dev\n"; 
in out
+        assert "index: http://devpi/user/dev"; in out
+        assert "simpleindex: http://devpi/user/dev/+simple/"; in out
+        assert "pypisubmit: http://devpi/user/dev/"; in out
+        assert "login: http://devpi/+login"; in out
+
+    @pytest.mark.parametrize("devpi_index", ["user/dev", "/user/dev"])
     def test_environment_relative_with_root_current(
             self, capfd, cmd_devpi, devpi_index, mock_http_api, monkeypatch):
         mock_http_api.set(
@@ -831,6 +895,81 @@
         assert "pypisubmit: http://world/user/dev/"; in out
         assert "login: http://world/+login"; in out
 
+    def test_environment_with_url_from_commandline(
+            self, capfd, cmd_devpi, mock_http_api, monkeypatch):
+        monkeypatch.setenv("DEVPI_INDEX", "http://devpi/user/dev";)
+        mock_http_api.set(
+            "http://world/user/foo/+api";, 200, result=dict(
+                pypisubmit="http://world/user/foo/";,
+                simpleindex="http://world/user/foo/+simple/";,
+                index="http://world/user/foo";,
+                login="http://world/+login";,
+                authstatus=["noauth", "", []]))
+        mock_http_api.set("http://world/user/foo?no_projects=";, 200, 
result=dict())
+        cmd_devpi("use", "http://world/user/foo";)
+        (out, err) = capfd.readouterr()
+        assert "Using index URL from command line" in out
+        mock_http_api.set(
+            "http://devpi/user/dev/+api";, 200, result=dict(
+                pypisubmit="http://devpi/user/dev/";,
+                simpleindex="http://devpi/user/dev/+simple/";,
+                index="http://devpi/user/dev";,
+                login="http://devpi/+login";,
+                authstatus=["noauth", "", []]))
+        mock_http_api.set("http://devpi/user/dev?no_projects=";, 200, 
result=dict())
+        cmd_devpi("use", "--urls")
+        (out, err) = capfd.readouterr()
+        assert "Using DEVPI_INDEX from environment: http://devpi/user/dev\n"; 
in out
+        assert "index: http://devpi/user/dev"; in out
+        assert "simpleindex: http://devpi/user/dev/+simple/"; in out
+        assert "pypisubmit: http://devpi/user/dev/"; in out
+        assert "login: http://devpi/+login"; in out
+        cmd_devpi("use", "http://world/user/foo";, "--urls")
+        (out, err) = capfd.readouterr()
+        assert "Using index URL from command line" in out
+        assert "index: http://world/user/foo"; in out
+        assert "simpleindex: http://world/user/foo/+simple/"; in out
+        assert "pypisubmit: http://world/user/foo/"; in out
+        assert "login: http://world/+login"; in out
+
+    @pytest.mark.parametrize("devpi_index", ["user/dev", "/user/dev"])
+    def test_environment_relative_with_url_from_commandline(
+            self, capfd, cmd_devpi, devpi_index, mock_http_api, monkeypatch):
+        monkeypatch.setenv("DEVPI_INDEX", devpi_index)
+        mock_http_api.set(
+            "http://world/user/foo/+api";, 200, result=dict(
+                pypisubmit="http://world/user/foo/";,
+                simpleindex="http://world/user/foo/+simple/";,
+                index="http://world/user/foo";,
+                login="http://world/+login";,
+                authstatus=["noauth", "", []]))
+        mock_http_api.set("http://world/user/foo?no_projects=";, 200, 
result=dict())
+        cmd_devpi("use", "http://world/user/foo";)
+        (out, err) = capfd.readouterr()
+        assert "Using index URL from command line" in out
+        mock_http_api.set(
+            "http://world/user/dev/+api";, 200, result=dict(
+                pypisubmit="http://world/user/dev/";,
+                simpleindex="http://world/user/dev/+simple/";,
+                index="http://world/user/dev";,
+                login="http://world/+login";,
+                authstatus=["noauth", "", []]))
+        mock_http_api.set("http://world/user/dev?no_projects=";, 200, 
result=dict())
+        cmd_devpi("use", "--urls")
+        (out, err) = capfd.readouterr()
+        assert "Using DEVPI_INDEX from environment: %s\n" % devpi_index in out
+        assert "index: http://world/user/dev"; in out
+        assert "simpleindex: http://world/user/dev/+simple/"; in out
+        assert "pypisubmit: http://world/user/dev/"; in out
+        assert "login: http://world/+login"; in out
+        cmd_devpi("use", "http://world/user/foo";, "--urls")
+        (out, err) = capfd.readouterr()
+        assert "Using index URL from command line" in out
+        assert "index: http://world/user/foo"; in out
+        assert "simpleindex: http://world/user/foo/+simple/"; in out
+        assert "pypisubmit: http://world/user/foo/"; in out
+        assert "login: http://world/+login"; in out
+
 
 def test_getparse_keyvalues_invalid():
     with pytest.raises(ValueError):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/devpi-client-6.0.3/tox.ini 
new/devpi-client-6.0.4/tox.ini
--- old/devpi-client-6.0.3/tox.ini      2023-02-20 10:11:07.000000000 +0100
+++ new/devpi-client-6.0.4/tox.ini      2023-04-13 07:14:01.000000000 +0200
@@ -15,12 +15,13 @@
 envlist = py27-server520,py27-version,py27,py35,py38,pypy,pypy3
 
 [testenv]
-passenv = LANG, PIP_INDEX_URL
+passenv = GITHUB_ACTIONS, LANG, PIP_INDEX_URL
 deps =
        pytest
        pytest-flake8 < 1.1.0;python_version=="2.7"
        pytest-flake8;python_version!="2.7"
        flake8<5
+       pytest-github-actions-annotate-failures
        pytest-instafail
        pytest-timeout
        devpi-server;python_version!="2.7"

Reply via email to