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 <[email protected]>
+
+- 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
+
+
[email protected]("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
+
+
[email protected]("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
+
+
[email protected]("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()
+
+
[email protected]("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()
+
+
[email protected]("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"]
[email protected]("sys.version_info < (3,)")
[email protected]("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"