openSUSE Commits
Threads by month
- ----- 2025 -----
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
June 2024
- 2 participants
- 1220 discussions
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package go1.22 for openSUSE:Factory checked in at 2024-06-05 17:42:32
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/go1.22 (Old)
and /work/SRC/openSUSE:Factory/.go1.22.new.24587 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "go1.22"
Wed Jun 5 17:42:32 2024 rev:10 rq:1178641 version:1.22.4
Changes:
--------
--- /work/SRC/openSUSE:Factory/go1.22/go1.22.changes 2024-05-08 11:42:32.282909494 +0200
+++ /work/SRC/openSUSE:Factory/.go1.22.new.24587/go1.22.changes 2024-06-05 17:43:15.871994095 +0200
@@ -1,0 +2,23 @@
+Tue Jun 4 18:08:59 UTC 2024 - Jeff Kowalczyk <jkowalczyk(a)suse.com>
+
+- go1.22.4 (released 2024-06-04) includes security fixes to the
+ archive/zip and net/netip packages, as well as bug fixes to the
+ compiler, the go command, the linker, the runtime, and the os
+ package.
+ Refs boo#1218424 go1.22 release tracking
+ CVE-2024-24789 CVE-2024-24790
+ * go#67554 go#66869 boo#1225973 security: fix CVE-2024-24789 archive/zip: EOCDR comment length handling is inconsistent with other ZIP implementations
+ * go#67682 go#67680 boo#1225974 security: fix CVE-2024-24790 net/netip: unexpected behavior from Is methods for IPv4-mapped IPv6 addresses
+ * go#67188 runtime/metrics: /memory/classes/heap/unused:bytes spikes
+ * go#67212 cmd/compile: SIGBUS unaligned access on mips64 via qemu-mips64
+ * go#67236 cmd/go: mod tidy reports toolchain not available with 'go 1.21'
+ * go#67258 runtime: unexpected fault address 0
+ * go#67311 cmd/go: TestScript/gotoolchain_issue66175 fails on tip locally
+ * go#67314 cmd/go,cmd/link: TestScript/build_issue48319 and TestScript/build_plugin_reproducible failing on LUCI gotip-darwin-amd64-longtest builder due to non-reproducible LC_UUID
+ * go#67352 crypto/x509: TestPlatformVerifier failures on Windows due to broken connections
+ * go#67460 cmd/compile: internal compiler error: panic with range over integer value
+ * go#67527 cmd/link: panic: machorelocsect: size mismatch
+ * go#67650 runtime: SIGSEGV after performing clone(CLONE_PARENT) via C constructor prior to runtime start
+ * go#67696 os: RemoveAll susceptible to symlink race
+
+-------------------------------------------------------------------
Old:
----
go1.22.3.src.tar.gz
New:
----
go1.22.4.src.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ go1.22.spec ++++++
--- /var/tmp/diff_new_pack.b8w15q/_old 2024-06-05 17:43:16.652022501 +0200
+++ /var/tmp/diff_new_pack.b8w15q/_new 2024-06-05 17:43:16.656022647 +0200
@@ -122,7 +122,7 @@
%endif
Name: go1.22
-Version: 1.22.3
+Version: 1.22.4
Release: 0
Summary: A compiled, garbage-collected, concurrent programming language
License: BSD-3-Clause
++++++ go1.22.3.src.tar.gz -> go1.22.4.src.tar.gz ++++++
/work/SRC/openSUSE:Factory/go1.22/go1.22.3.src.tar.gz /work/SRC/openSUSE:Factory/.go1.22.new.24587/go1.22.4.src.tar.gz differ: char 111, line 2
1
0
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package votca for openSUSE:Factory checked in at 2024-06-05 17:42:29
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/votca (Old)
and /work/SRC/openSUSE:Factory/.votca.new.24587 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "votca"
Wed Jun 5 17:42:29 2024 rev:11 rq:1178635 version:2024
Changes:
--------
--- /work/SRC/openSUSE:Factory/votca/votca.changes 2024-02-04 19:07:47.733568632 +0100
+++ /work/SRC/openSUSE:Factory/.votca.new.24587/votca.changes 2024-06-05 17:43:13.655913390 +0200
@@ -1,0 +2,5 @@
+Mon Jun 3 21:40:05 UTC 2024 - Christoph Junghans <junghans(a)votca.org>
+
+- Add upsteam patch, 1032.patch, to fix build with newer boost
+
+-------------------------------------------------------------------
New:
----
1032.patch
BETA DEBUG BEGIN:
New:
- Add upsteam patch, 1032.patch, to fix build with newer boost
BETA DEBUG END:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ votca.spec ++++++
--- /var/tmp/diff_new_pack.eivxwe/_old 2024-06-05 17:43:14.511944565 +0200
+++ /var/tmp/diff_new_pack.eivxwe/_new 2024-06-05 17:43:14.515944710 +0200
@@ -34,6 +34,8 @@
Group: Productivity/Scientific/Chemistry
URL: https://www.votca.org
Source0: https://github.com/votca/votca/archive/v%{uversion}.tar.gz#/%{name}-%{uvers…
+# PATCH-FIX-UPSTREAM 1032.patch -- fix build with newer boost votca/votca#1032
+Patch0: 1032.patch
BuildRequires: cmake >= 3.13
BuildRequires: eigen3-devel
@@ -175,7 +177,7 @@
This package contains the bash completion support for votca.
%prep
-%autosetup -n %{name}-%{uversion}
+%autosetup -p1 -n %{name}-%{uversion}
%build
%setup_openmpi
++++++ 1032.patch ++++++
From 9a29a3a82ea23c5159d43b0f25218601e12085b4 Mon Sep 17 00:00:00 2001
From: Michael Cho <michael(a)michaelcho.dev>
Date: Thu, 25 Apr 2024 14:14:54 -0400
Subject: [PATCH] Fix build with Boost 1.85.0
Signed-off-by: Michael Cho <michael(a)michaelcho.dev>
---
csg/src/libcsg/modules/io/pdbreader.cc | 1 -
xtp/src/libxtp/calculators/kmcmultiple.cc | 1 +
2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/csg/src/libcsg/modules/io/pdbreader.cc b/csg/src/libcsg/modules/io/pdbreader.cc
index 14b259ee8b..3686806e9d 100644
--- a/csg/src/libcsg/modules/io/pdbreader.cc
+++ b/csg/src/libcsg/modules/io/pdbreader.cc
@@ -22,7 +22,6 @@
// Third party includes
#include <boost/algorithm/string.hpp>
-#include <boost/filesystem/convenience.hpp>
#include <boost/lexical_cast.hpp>
// VOTCA includes
diff --git a/xtp/src/libxtp/calculators/kmcmultiple.cc b/xtp/src/libxtp/calculators/kmcmultiple.cc
index 1627950277..fa515e78eb 100644
--- a/xtp/src/libxtp/calculators/kmcmultiple.cc
+++ b/xtp/src/libxtp/calculators/kmcmultiple.cc
@@ -20,6 +20,7 @@
// Third party includes
#include <boost/format.hpp>
+#include <boost/numeric/conversion/cast.hpp>
// VOTCA includes
#include <votca/tools/constants.h>
1
0
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package ansible-lint for openSUSE:Factory checked in at 2024-06-05 17:42:24
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ansible-lint (Old)
and /work/SRC/openSUSE:Factory/.ansible-lint.new.24587 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ansible-lint"
Wed Jun 5 17:42:24 2024 rev:47 rq:1178622 version:24.6.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/ansible-lint/ansible-lint.changes 2024-05-29 19:37:09.527327380 +0200
+++ /work/SRC/openSUSE:Factory/.ansible-lint.new.24587/ansible-lint.changes 2024-06-05 17:43:08.387721536 +0200
@@ -1,0 +2,34 @@
+Tue Jun 4 19:22:21 UTC 2024 - Johannes Kastl <opensuse_buildservice(a)ojkastl.de>
+
+- update to 24.6.0:
+ * Enhancements
+ - Adding logic for configuring supported ansible versions
+ (#4203) @alisonlhart
+ * Bugfixes
+ - Revert notify related checks, errors, transforms for listen
+ and tests (#4205) @audgirka
+ - Improve logic of find_children (#4161) @ssbarnea
+ - Pickup correct path component w/ANSIBLE_ROLES_PATH (#4176)
+ @cavcrosby
+ - Respect yamllint 'document_start' rule when autofixing yaml
+ (#4184) @elara-leitstellentechnik
+ - Avoid displaying upgrade warning when installation is not pip
+ (#4204) @ssbarnea
+ - Correctly recognize path with spaces with tokenize (#4198)
+ @ssbarnea
+ - Fix false positive reports in is_handler function (#4170)
+ @MalKeshar
+ - Avoid exception with conflicting action statements (#4195)
+ @ssbarnea
+ - Don't raise name[casing] on handlers with special role syntax
+ (#4196) @Qalthos
+ - Refactor tokenize function (#4191) @ssbarnea
+ - Avoid stacktrace with unsupported import_playbook syntax
+ (#4190) @ssbarnea
+ - Support for 2.15...updating linter. (#4144) @epacific1
+ - Don't quote strings that start with 0 when running
+ ansible-lint --fix. (#4167) @kousu
+ - Allow inventory to be used for playbook order key (#4182)
+ @ssbarnea
+
+-------------------------------------------------------------------
Old:
----
ansible-lint-24.5.0.tar.gz
New:
----
ansible-lint-24.6.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ ansible-lint.spec ++++++
--- /var/tmp/diff_new_pack.9nO2kf/_old 2024-06-05 17:43:09.543763636 +0200
+++ /var/tmp/diff_new_pack.9nO2kf/_new 2024-06-05 17:43:09.543763636 +0200
@@ -40,7 +40,7 @@
%global lib_name ansiblelint
%{?python_enable_dependency_generator}
Name: ansible-lint
-Version: 24.5.0
+Version: 24.6.0
Release: 0%{?dist}
Summary: Best practices checker for Ansible
License: MIT
++++++ ansible-lint-24.5.0.tar.gz -> ansible-lint-24.6.0.tar.gz ++++++
++++ 2550 lines of diff (skipped)
1
0
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-pep8-naming for openSUSE:Factory checked in at 2024-06-05 17:42:22
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pep8-naming (Old)
and /work/SRC/openSUSE:Factory/.python-pep8-naming.new.24587 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pep8-naming"
Wed Jun 5 17:42:22 2024 rev:13 rq:1178618 version:0.14.1
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pep8-naming/python-pep8-naming.changes 2023-01-02 15:02:32.049474292 +0100
+++ /work/SRC/openSUSE:Factory/.python-pep8-naming.new.24587/python-pep8-naming.changes 2024-06-05 17:43:06.535654088 +0200
@@ -1,0 +2,11 @@
+Tue Jun 4 20:46:22 UTC 2024 - Dirk Müller <dmueller(a)suse.com>
+
+- update to 0.14.1:
+ * Require Python 3.8 or later.
+ * Drop support for Python 3.7.
+ * Add support for Python 3.12.
+ * Ignore methods decorated by @typing.override.
+ * Perform case-sensitive ignore-names globbing on all
+ platforms.
+
+-------------------------------------------------------------------
Old:
----
pep8-naming-0.13.3.tar.gz
New:
----
pep8-naming-0.14.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-pep8-naming.spec ++++++
--- /var/tmp/diff_new_pack.8cQsCv/_old 2024-06-05 17:43:07.251680164 +0200
+++ /var/tmp/diff_new_pack.8cQsCv/_new 2024-06-05 17:43:07.251680164 +0200
@@ -1,7 +1,7 @@
#
# spec file for package python-pep8-naming
#
-# Copyright (c) 2023 SUSE LLC
+# Copyright (c) 2024 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -18,23 +18,21 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-pep8-naming
-Version: 0.13.3
+Version: 0.14.1
Release: 0
Summary: Flake8 plugin for checking PEP-8 naming conventions
License: MIT
URL: https://github.com/PyCQA/pep8-naming
Source: https://files.pythonhosted.org/packages/source/p/pep8-naming/pep8-naming-%{…
-BuildRequires: %{python_module base >= 3.7}
-BuildRequires: %{python_module setuptools}
+BuildRequires: %{python_module base >= 3.8}
+BuildRequires: %{python_module pip}
+BuildRequires: %{python_module wheel}
BuildRequires: fdupes
BuildRequires: python-rpm-macros
Requires: python-flake8 >= 5.0.0
-Requires: python-flake8-polyfill >= 1.0.2
-Requires: python-setuptools
BuildArch: noarch
# SECTION test requirements
BuildRequires: %{python_module flake8 >= 5.0.0}
-BuildRequires: %{python_module flake8-polyfill >= 1.0.2}
# /SECTION
%python_subpackages
@@ -49,10 +47,10 @@
%autosetup -p1 -n pep8-naming-%{version}
%build
-%python_build
+%pyproject_wheel
%install
-%python_install
+%pyproject_install
%python_expand %fdupes %{buildroot}%{$python_sitelib}
%check
@@ -65,5 +63,5 @@
%license LICENSE
%{python_sitelib}/pep8ext_naming.py*
%pycache_only %{python_sitelib}/__pycache__/pep8ext_naming.*.py*
-%{python_sitelib}/pep8_naming-%{version}*-info
+%{python_sitelib}/pep8_naming-%{version}.dist-info
++++++ pep8-naming-0.13.3.tar.gz -> pep8-naming-0.14.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pep8-naming-0.13.3/CHANGELOG.rst new/pep8-naming-0.14.1/CHANGELOG.rst
--- old/pep8-naming-0.13.3/CHANGELOG.rst 2022-12-19 21:43:16.000000000 +0100
+++ new/pep8-naming-0.14.1/CHANGELOG.rst 2024-05-17 16:07:14.000000000 +0200
@@ -1,6 +1,19 @@
Changes
=======
+0.14.1 - 2024-05-17
+-------------------
+
+* Require Python 3.8 or later.
+
+0.14.0 - 2024-05-16
+-------------------
+
+* Drop support for Python 3.7.
+* Add support for Python 3.12.
+* Ignore methods decorated by ``(a)typing.override``.
+* Perform case-sensitive ``ignore-names`` globbing on all platforms.
+
0.13.3 - 2022-12-19
-------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pep8-naming-0.13.3/PKG-INFO new/pep8-naming-0.14.1/PKG-INFO
--- old/pep8-naming-0.13.3/PKG-INFO 2022-12-19 21:43:50.878376200 +0100
+++ new/pep8-naming-0.14.1/PKG-INFO 2024-05-17 16:08:18.518595000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: pep8-naming
-Version: 0.13.3
+Version: 0.14.1
Summary: Check PEP-8 naming conventions, plugin for flake8
Home-page: https://github.com/PyCQA/pep8-naming
Author: Florent Xicluna
@@ -18,16 +18,17 @@
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Quality Assurance
-Requires-Python: >=3.7
+Requires-Python: >=3.8
License-File: LICENSE
+Requires-Dist: flake8>=5.0.0
PEP 8 Naming Conventions
========================
@@ -134,3 +135,19 @@
Used to prevent false N805 errors.
Default: ``staticmethod``.
+
+FAQ
+---
+
+How do I configure ``classmethod_decorators`` to recognize `SQLAlchemy`_ class methods?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ classmethod_decorators =
+ classmethod
+ declared_attr
+ expression
+ comparator
+
+.. _SQLAlchemy: https://www.sqlalchemy.org/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pep8-naming-0.13.3/README.rst new/pep8-naming-0.14.1/README.rst
--- old/pep8-naming-0.13.3/README.rst 2022-08-18 02:19:39.000000000 +0200
+++ new/pep8-naming-0.14.1/README.rst 2023-04-11 18:36:59.000000000 +0200
@@ -103,3 +103,19 @@
Used to prevent false N805 errors.
Default: ``staticmethod``.
+
+FAQ
+---
+
+How do I configure ``classmethod_decorators`` to recognize `SQLAlchemy`_ class methods?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ classmethod_decorators =
+ classmethod
+ declared_attr
+ expression
+ comparator
+
+.. _SQLAlchemy: https://www.sqlalchemy.org/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pep8-naming-0.13.3/setup.py new/pep8-naming-0.14.1/setup.py
--- old/pep8-naming-0.13.3/setup.py 2022-12-19 21:43:16.000000000 +0100
+++ new/pep8-naming-0.14.1/setup.py 2024-05-17 16:06:23.000000000 +0200
@@ -44,7 +44,7 @@
py_modules=['pep8ext_naming'],
install_requires=['flake8>=5.0.0'],
zip_safe=False,
- python_requires='>=3.7',
+ python_requires='>=3.8',
entry_points={
'flake8.extension': [
'N8 = pep8ext_naming:NamingChecker',
@@ -59,11 +59,11 @@
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
- 'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
+ 'Programming Language :: Python :: 3.12',
'Programming Language :: Python :: 3 :: Only',
'Topic :: Software Development :: Libraries :: Python Modules',
'Topic :: Software Development :: Quality Assurance',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pep8-naming-0.13.3/src/pep8_naming.egg-info/PKG-INFO new/pep8-naming-0.14.1/src/pep8_naming.egg-info/PKG-INFO
--- old/pep8-naming-0.13.3/src/pep8_naming.egg-info/PKG-INFO 2022-12-19 21:43:50.000000000 +0100
+++ new/pep8-naming-0.14.1/src/pep8_naming.egg-info/PKG-INFO 2024-05-17 16:08:18.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: pep8-naming
-Version: 0.13.3
+Version: 0.14.1
Summary: Check PEP-8 naming conventions, plugin for flake8
Home-page: https://github.com/PyCQA/pep8-naming
Author: Florent Xicluna
@@ -18,16 +18,17 @@
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Quality Assurance
-Requires-Python: >=3.7
+Requires-Python: >=3.8
License-File: LICENSE
+Requires-Dist: flake8>=5.0.0
PEP 8 Naming Conventions
========================
@@ -134,3 +135,19 @@
Used to prevent false N805 errors.
Default: ``staticmethod``.
+
+FAQ
+---
+
+How do I configure ``classmethod_decorators`` to recognize `SQLAlchemy`_ class methods?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ classmethod_decorators =
+ classmethod
+ declared_attr
+ expression
+ comparator
+
+.. _SQLAlchemy: https://www.sqlalchemy.org/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pep8-naming-0.13.3/src/pep8_naming.egg-info/SOURCES.txt new/pep8-naming-0.14.1/src/pep8_naming.egg-info/SOURCES.txt
--- old/pep8-naming-0.13.3/src/pep8_naming.egg-info/SOURCES.txt 2022-12-19 21:43:50.000000000 +0100
+++ new/pep8-naming-0.14.1/src/pep8_naming.egg-info/SOURCES.txt 2024-05-17 16:08:18.000000000 +0200
@@ -18,14 +18,11 @@
testsuite/N803.py
testsuite/N804.py
testsuite/N805.py
-testsuite/N805_py38.py
testsuite/N806.py
-testsuite/N806_py38.py
testsuite/N807.py
testsuite/N80x.py
testsuite/N815.py
testsuite/N816.py
-testsuite/N816_py38.py
testsuite/N818.py
testsuite/N81x.py
testsuite/N8xx.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pep8-naming-0.13.3/src/pep8ext_naming.py new/pep8-naming-0.14.1/src/pep8ext_naming.py
--- old/pep8-naming-0.13.3/src/pep8ext_naming.py 2022-12-19 21:43:16.000000000 +0100
+++ new/pep8-naming-0.14.1/src/pep8ext_naming.py 2024-05-17 16:07:20.000000000 +0200
@@ -1,17 +1,15 @@
"""Checker of PEP-8 Naming Conventions."""
import ast
-import sys
from ast import iter_child_nodes
from collections import deque
-from fnmatch import fnmatch
+from collections.abc import Iterable
+from fnmatch import fnmatchcase
from functools import partial
from itertools import chain
from flake8 import style_guide
-__version__ = '0.13.3'
-
-PYTHON_VERSION = sys.version_info[:3]
+__version__ = '0.14.1'
CLASS_METHODS = frozenset((
'__new__',
@@ -32,15 +30,6 @@
}
FUNC_NODES = (ast.FunctionDef, ast.AsyncFunctionDef)
-if PYTHON_VERSION < (3, 8):
- def get_arg_name_tuples(node):
- groups = (node.args.args, node.args.kwonlyargs)
- return [(arg, arg.arg) for args in groups for arg in args]
-else:
- def get_arg_name_tuples(node):
- groups = (node.args.posonlyargs, node.args.args, node.args.kwonlyargs)
- return [(arg, arg.arg) for args in groups for arg in args]
-
class _ASTCheckMeta(type):
def __init__(cls, class_name, bases, namespace):
@@ -54,12 +43,8 @@
def _err(self, node, code, **kwargs):
lineno, col_offset = node.lineno, node.col_offset
if isinstance(node, ast.ClassDef):
- if PYTHON_VERSION < (3, 8):
- lineno += len(node.decorator_list)
col_offset += 6
elif isinstance(node, FUNC_NODES):
- if PYTHON_VERSION < (3, 8):
- lineno += len(node.decorator_list)
col_offset += 4
code_str = getattr(self, code)
if kwargs:
@@ -68,7 +53,7 @@
def _ignored(name, ignore):
- return any(fnmatch(name, i) for i in ignore)
+ return any(fnmatchcase(name, i) for i in ignore)
BaseASTCheck = _ASTCheckMeta('BaseASTCheck', (object,),
@@ -118,8 +103,7 @@
ignore_names = frozenset(_default_ignore_names)
def __init__(self, tree, filename):
- self.parents = deque()
- self._node = tree
+ self.tree = tree
@classmethod
def add_options(cls, parser):
@@ -168,23 +152,22 @@
)
def run(self):
- return self.visit_tree(self._node) if self._node else ()
+ return self.visit_tree(self.tree, deque()) if self.tree else ()
- def visit_tree(self, node):
- yield from self.visit_node(node)
- self.parents.append(node)
+ def visit_tree(self, node, parents: deque):
+ yield from self.visit_node(node, parents)
+ parents.append(node)
for child in iter_child_nodes(node):
- yield from self.visit_tree(child)
- self.parents.pop()
+ yield from self.visit_tree(child, parents)
+ parents.pop()
- def visit_node(self, node):
+ def visit_node(self, node, parents: Iterable):
if isinstance(node, ast.ClassDef):
self.tag_class_functions(node)
elif isinstance(node, FUNC_NODES):
self.find_global_defs(node)
method = 'visit_' + node.__class__.__name__.lower()
- parents = self.parents
ignore_names = self.ignore_names
for visitor in self.visitors:
visitor_method = getattr(visitor, method, None)
@@ -274,14 +257,14 @@
N818 = "exception name '{name}' should be named with an Error suffix"
@classmethod
- def get_classdef(cls, name, parents):
+ def get_classdef(cls, name, parents: Iterable):
for parent in parents:
for node in parent.body:
if isinstance(node, ast.ClassDef) and node.name == name:
return node
@classmethod
- def superclass_names(cls, name, parents, _names=None):
+ def superclass_names(cls, name, parents: Iterable, _names=None):
names = _names or set()
classdef = cls.get_classdef(name, parents)
if not classdef:
@@ -292,7 +275,7 @@
names.update(cls.superclass_names(base.id, parents, names))
return names
- def visit_classdef(self, node, parents, ignore=None):
+ def visit_classdef(self, node, parents: Iterable, ignore=None):
name = node.name
if _ignored(name, ignore):
return
@@ -317,13 +300,26 @@
N802 = "function name '{name}' should be lowercase"
N807 = "function name '{name}' should not start and end with '__'"
- def visit_functiondef(self, node, parents, ignore=None):
+ @staticmethod
+ def has_override_decorator(node):
+ for d in node.decorator_list:
+ if isinstance(d, ast.Name) and d.id == 'override':
+ return True
+ if (isinstance(d, ast.Attribute) and isinstance(d.value, ast.Name)
+ and d.value.id == 'typing' and d.attr == 'override'):
+ return True
+ return False
+
+ def visit_functiondef(self, node, parents: Iterable, ignore=None):
function_type = getattr(node, 'function_type', _FunctionType.FUNCTION)
name = node.name
if _ignored(name, ignore):
return
if name in ('__dir__', '__getattr__'):
return
+ if (function_type != _FunctionType.FUNCTION
+ and self.has_override_decorator(node)):
+ return
if name.lower() != name:
yield self.err(node, 'N802', name=name)
if (function_type == _FunctionType.FUNCTION
@@ -345,34 +341,37 @@
N804 = "first argument of a classmethod should be named 'cls'"
N805 = "first argument of a method should be named 'self'"
- def visit_functiondef(self, node, parents, ignore=None):
+ def visit_functiondef(self, node, parents: Iterable, ignore=None):
+ args = node.args.posonlyargs + node.args.args + node.args.kwonlyargs
- def arg_name(arg):
- return (arg, arg.arg) if arg else (node, arg)
-
- for arg, name in arg_name(node.args.vararg), arg_name(node.args.kwarg):
- if name is None or _ignored(name, ignore):
- continue
- if name.lower() != name:
- yield self.err(arg, 'N803', name=name)
- return
-
- arg_name_tuples = get_arg_name_tuples(node)
- if not arg_name_tuples:
- return
- arg0, name0 = arg_name_tuples[0]
- function_type = getattr(node, 'function_type', _FunctionType.FUNCTION)
+ # Start by applying checks that are specific to the first argument.
+ #
+ # Note: The `ignore` check shouldn't be necessary here because we'd
+ # expect users to explicitly ignore N804/N805 when using names
+ # other than `self` and `cls` rather than ignoring names like
+ # `klass` to get around these checks. However, a previous
+ # implementation allowed for that, so we retain that behavior
+ # for backwards compatibility.
+ if args and (name := args[0].arg) and not _ignored(name, ignore):
+ function_type = getattr(node, 'function_type', None)
+ if function_type == _FunctionType.METHOD and name != 'self':
+ yield self.err(args[0], 'N805')
+ elif function_type == _FunctionType.CLASSMETHOD and name != 'cls':
+ yield self.err(args[0], 'N804')
+
+ # Also add the special *arg and **kwarg arguments for the rest of the
+ # checks when they're present. We didn't include them above because
+ # the "first argument" naming checks shouldn't be applied to them
+ # when they're the function's only argument(s).
+ if node.args.vararg:
+ args.append(node.args.vararg)
+ if node.args.kwarg:
+ args.append(node.args.kwarg)
- if function_type == _FunctionType.METHOD:
- if name0 != 'self' and not _ignored(name0, ignore):
- yield self.err(arg0, 'N805')
- elif function_type == _FunctionType.CLASSMETHOD:
- if name0 != 'cls' and not _ignored(name0, ignore):
- yield self.err(arg0, 'N804')
- for arg, name in arg_name_tuples:
+ for arg in args:
+ name = arg.arg
if name.lower() != name and not _ignored(name, ignore):
yield self.err(arg, 'N803', name=name)
- return
visit_asyncfunctiondef = visit_functiondef
@@ -387,7 +386,7 @@
N814 = "camelcase '{name}' imported as constant '{asname}'"
N817 = "camelcase '{name}' imported as acronym '{asname}'"
- def visit_importfrom(self, node, parents, ignore=None):
+ def visit_importfrom(self, node, parents: Iterable, ignore=None):
for name in node.names:
asname = name.asname
if not asname:
@@ -419,7 +418,7 @@
N815 = "variable '{name}' in class scope should not be mixedCase"
N816 = "variable '{name}' in global scope should not be mixedCase"
- def _find_errors(self, assignment_target, parents, ignore):
+ def _find_errors(self, assignment_target, parents: Iterable, ignore):
for parent_func in reversed(parents):
if isinstance(parent_func, ast.ClassDef):
checker = self.class_variable_check
@@ -447,36 +446,36 @@
return True
return False
- def visit_assign(self, node, parents, ignore=None):
+ def visit_assign(self, node, parents: Iterable, ignore=None):
if self.is_namedtupe(node.value):
return
for target in node.targets:
yield from self._find_errors(target, parents, ignore)
- def visit_namedexpr(self, node, parents, ignore):
+ def visit_namedexpr(self, node, parents: Iterable, ignore):
if self.is_namedtupe(node.value):
return
yield from self._find_errors(node.target, parents, ignore)
visit_annassign = visit_namedexpr
- def visit_with(self, node, parents, ignore):
+ def visit_with(self, node, parents: Iterable, ignore):
for item in node.items:
yield from self._find_errors(
item.optional_vars, parents, ignore)
visit_asyncwith = visit_with
- def visit_for(self, node, parents, ignore):
+ def visit_for(self, node, parents: Iterable, ignore):
yield from self._find_errors(node.target, parents, ignore)
visit_asyncfor = visit_for
- def visit_excepthandler(self, node, parents, ignore):
+ def visit_excepthandler(self, node, parents: Iterable, ignore):
if node.name:
yield from self._find_errors(node, parents, ignore)
- def visit_generatorexp(self, node, parents, ignore):
+ def visit_generatorexp(self, node, parents: Iterable, ignore):
for gen in node.generators:
yield from self._find_errors(gen.target, parents, ignore)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pep8-naming-0.13.3/testsuite/N801.py new/pep8-naming-0.14.1/testsuite/N801.py
--- old/pep8-naming-0.13.3/testsuite/N801.py 2022-08-18 02:19:39.000000000 +0200
+++ new/pep8-naming-0.14.1/testsuite/N801.py 2023-10-21 04:24:52.000000000 +0200
@@ -7,6 +7,9 @@
#: Okay(--ignore-names=*ok)
class notok:
pass
+#: N801:1:7(--ignore-names=*OK)
+class notok:
+ pass
#: N801
class Good:
class notok:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pep8-naming-0.13.3/testsuite/N802.py new/pep8-naming-0.14.1/testsuite/N802.py
--- old/pep8-naming-0.13.3/testsuite/N802.py 2022-08-18 02:19:39.000000000 +0200
+++ new/pep8-naming-0.14.1/testsuite/N802.py 2023-10-21 04:24:52.000000000 +0200
@@ -25,6 +25,9 @@
#: Okay(--ignore-names=*OK)
def NotOK():
pass
+#: N802:1:5(--ignore-names=*ok)
+def NotOK():
+ pass
#: Okay
def _():
pass
@@ -53,6 +56,14 @@
def notOk(self):
pass
#: Okay
+class ClassName:
+ @override
+ def notOk(self):
+ pass
+ @typing.override
+ def alsoNotOk(self):
+ pass
+#: Okay
def setUp():
pass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pep8-naming-0.13.3/testsuite/N803.py new/pep8-naming-0.14.1/testsuite/N803.py
--- old/pep8-naming-0.13.3/testsuite/N803.py 2022-08-18 02:19:39.000000000 +0200
+++ new/pep8-naming-0.14.1/testsuite/N803.py 2023-10-21 04:24:52.000000000 +0200
@@ -40,6 +40,9 @@
#: Okay(--ignore-names=*BAD)
def b13(BAD, *VERYBAD, **EXTRABAD):
pass
+#: N803:1:9(--ignore-names=*bad)
+def b13(BAD):
+ pass
#: N803:1:9
def b14(BAD):
pass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pep8-naming-0.13.3/testsuite/N804.py new/pep8-naming-0.14.1/testsuite/N804.py
--- old/pep8-naming-0.13.3/testsuite/N804.py 2022-08-18 02:19:39.000000000 +0200
+++ new/pep8-naming-0.14.1/testsuite/N804.py 2023-10-21 04:24:52.000000000 +0200
@@ -21,6 +21,11 @@
@classmethod
def prepare_meta(klass, root):
pass
+#: N804(--ignore-names=KLASS)
+class SpecialConventionCase:
+ @classmethod
+ def prepare_meta(klass, root):
+ pass
#: Okay(--ignore-names=_*)
class SpecialConventionCase:
@classmethod
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pep8-naming-0.13.3/testsuite/N805.py new/pep8-naming-0.14.1/testsuite/N805.py
--- old/pep8-naming-0.13.3/testsuite/N805.py 2022-08-18 02:19:39.000000000 +0200
+++ new/pep8-naming-0.14.1/testsuite/N805.py 2023-10-22 03:19:02.000000000 +0200
@@ -26,6 +26,10 @@
class GraphQLNode:
def resolve_foo(source, info):
pass
+#: N805(--ignore-names=SOURCE)
+class GraphQLNode:
+ def resolve_foo(source, info):
+ pass
#: Okay
class Foo:
def __new__(cls):
@@ -175,3 +179,11 @@
async def test(so, exciting):
pass
test = staticmethod(test)
+#: Okay
+class C:
+ def __init__(self, a, /, b=None):
+ pass
+#: N805:2:18
+class C:
+ def __init__(this, a, /, b=None):
+ pass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pep8-naming-0.13.3/testsuite/N805_py38.py new/pep8-naming-0.14.1/testsuite/N805_py38.py
--- old/pep8-naming-0.13.3/testsuite/N805_py38.py 2020-04-12 00:57:21.000000000 +0200
+++ new/pep8-naming-0.14.1/testsuite/N805_py38.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,9 +0,0 @@
-# python_version >= '3.8'
-#: Okay
-class C:
- def __init__(self, a, /, b=None):
- pass
-#: N805:2:18
-class C:
- def __init__(this, a, /, b=None):
- pass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pep8-naming-0.13.3/testsuite/N806.py new/pep8-naming-0.14.1/testsuite/N806.py
--- old/pep8-naming-0.13.3/testsuite/N806.py 2022-08-18 02:19:39.000000000 +0200
+++ new/pep8-naming-0.14.1/testsuite/N806.py 2023-10-22 03:19:02.000000000 +0200
@@ -31,6 +31,9 @@
#: Okay(--ignore-names=B*)
def test():
Bad = 1
+#: N806(--ignore-names=b*)
+def test():
+ Bad = 1
#: Okay
def good():
global Bad
@@ -219,3 +222,21 @@
async def f():
async with expr as ASYNC_VAR:
pass
+#: Okay
+def f1(values):
+ total = 0
+ partial_sums = [total := total + v for v in values]
+ return partial_sums, total
+#: Okay
+GLOBAL_VAR = 0
+def f2(values):
+ global GLOBAL_VAR
+ partial_sums = [GLOBAL_VAR := GLOBAL_VAR + v for v in values]
+ return partial_sums, GLOBAL_VAR
+#: N806:2:16
+def f():
+ return 1, (BaD_WalRuS := 1), BaD_WalRuS + 1
+#: Okay
+def f():
+ (NamedTuple := namedtuple('NamedTuple', 'f1 f2'))
+ return NamedTuple
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pep8-naming-0.13.3/testsuite/N806_py38.py new/pep8-naming-0.14.1/testsuite/N806_py38.py
--- old/pep8-naming-0.13.3/testsuite/N806_py38.py 2020-04-12 00:57:21.000000000 +0200
+++ new/pep8-naming-0.14.1/testsuite/N806_py38.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,19 +0,0 @@
-# python_version >= '3.8'
-#: Okay
-def f1(values):
- total = 0
- partial_sums = [total := total + v for v in values]
- return partial_sums, total
-#: Okay
-GLOBAL_VAR = 0
-def f2(values):
- global GLOBAL_VAR
- partial_sums = [GLOBAL_VAR := GLOBAL_VAR + v for v in values]
- return partial_sums, GLOBAL_VAR
-#: N806:2:16
-def f():
- return 1, (BaD_WalRuS := 1), BaD_WalRuS + 1
-#: Okay
-def f():
- (NamedTuple := namedtuple('NamedTuple', 'f1 f2'))
- return NamedTuple
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pep8-naming-0.13.3/testsuite/N807.py new/pep8-naming-0.14.1/testsuite/N807.py
--- old/pep8-naming-0.13.3/testsuite/N807.py 2022-08-18 02:19:39.000000000 +0200
+++ new/pep8-naming-0.14.1/testsuite/N807.py 2023-10-21 04:24:52.000000000 +0200
@@ -46,11 +46,14 @@
def method(self):
def __bad__():
pass
-#: Okay(--ignore-names=__bad)
-def __bad():
+#: Okay(--ignore-names=__bad__)
+def __bad__():
pass
#: Okay(--ignore-names=__*)
-def __bad():
+def __bad__():
+ pass
+#: N807(--ignore-names=__B*)
+def __bad__():
pass
#: Okay
def __dir__():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pep8-naming-0.13.3/testsuite/N815.py new/pep8-naming-0.14.1/testsuite/N815.py
--- old/pep8-naming-0.13.3/testsuite/N815.py 2020-04-12 00:57:21.000000000 +0200
+++ new/pep8-naming-0.14.1/testsuite/N815.py 2023-10-21 04:24:52.000000000 +0200
@@ -25,3 +25,6 @@
#: Okay(--ignore-names=*Case)
class C:
mixed_Case = 0
+#: N815(--ignore-names=*case)
+class C:
+ mixed_Case = 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pep8-naming-0.13.3/testsuite/N816.py new/pep8-naming-0.14.1/testsuite/N816.py
--- old/pep8-naming-0.13.3/testsuite/N816.py 2022-08-18 02:19:39.000000000 +0200
+++ new/pep8-naming-0.14.1/testsuite/N816.py 2023-10-22 03:19:02.000000000 +0200
@@ -22,6 +22,8 @@
mixedCase = 0
#: Okay(--ignore-names=*Case)
mixedCase = 0
+#: N816(--ignore-names=*case)
+mixedCase = 0
#: Okay
Γ = 1
#: N816
@@ -51,3 +53,7 @@
#: N816
async for γΓ1 in iterator:
pass
+#: Okay
+lambda f: (TheName := namedtuple('TheName', 'a b c')), TheName
+#: N816:1:15:
+lambda line: (BaD_WaLRuS := re.match(pattern, line)) and BaD_WaLRuS.group(1)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pep8-naming-0.13.3/testsuite/N816_py38.py new/pep8-naming-0.14.1/testsuite/N816_py38.py
--- old/pep8-naming-0.13.3/testsuite/N816_py38.py 2020-04-12 00:57:21.000000000 +0200
+++ new/pep8-naming-0.14.1/testsuite/N816_py38.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,5 +0,0 @@
-# python_version >= '3.8'
-#: Okay
-lambda f: (TheName := namedtuple('TheName', 'a b c')), TheName
-#: N816:1:15:
-lambda line: (BaD_WaLRuS := re.match(pattern, line)) and BaD_WaLRuS.group(1)
1
0
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-nose2 for openSUSE:Factory checked in at 2024-06-05 17:42:20
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-nose2 (Old)
and /work/SRC/openSUSE:Factory/.python-nose2.new.24587 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-nose2"
Wed Jun 5 17:42:20 2024 rev:15 rq:1178617 version:0.15.1
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-nose2/python-nose2.changes 2024-05-08 11:42:32.318910815 +0200
+++ /work/SRC/openSUSE:Factory/.python-nose2.new.24587/python-nose2.changes 2024-06-05 17:43:04.387575860 +0200
@@ -1,0 +2,24 @@
+Tue Jun 4 20:42:07 UTC 2024 - Dirk Müller <dmueller(a)suse.com>
+
+- update to 0.15.1:
+ * Fix a bug with config loading which caused custom ini configs
+ not to load if they were not named with a .cfg extension.
+ Thanks :user:`grhwalls` for the bug report!
+ * Official support for python3.13 betas. nose2 now tests itself
+ against Python 3.13.
+ * Official support for python3.13 betas. nose2 now tests itself
+ against Python 3.13.
+ * nose2 now supports loading configuration data from the
+ tool.nose2 table in pyproject.toml. Thanks to :user:`qequ`
+ for the PR! (:pr:`596`, :pr:`606`) On python 3.11+, tomllib
+ is used to parse TOML data. On python 3.10 and lower, tomli
+ must be installed to enable TOML support. Simply pip install
+ tomli as necessary.
+ * nose2 now supports loading configuration data from the
+ tool.nose2 table in pyproject.toml. Thanks to :user:`qequ`
+ for the PR! (:pr:`596`, :pr:`606`)
+ * On python 3.11+, tomllib is used to parse TOML data. On
+ python 3.10 and lower, tomli must be installed to enable TOML
+ support. Simply pip install tomli as necessary.
+
+-------------------------------------------------------------------
Old:
----
nose2-0.14.2.tar.gz
New:
----
nose2-0.15.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-nose2.spec ++++++
--- /var/tmp/diff_new_pack.AWtKDH/_old 2024-06-05 17:43:05.187604996 +0200
+++ /var/tmp/diff_new_pack.AWtKDH/_new 2024-06-05 17:43:05.191605141 +0200
@@ -18,7 +18,7 @@
%{?sle15_python_module_pythons}
Name: python-nose2
-Version: 0.14.2
+Version: 0.15.1
Release: 0
Summary: The successor to the Python testing framework nose, based on unittest
License: BSD-2-Clause AND Python-2.0
++++++ nose2-0.14.2.tar.gz -> nose2-0.15.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/MANIFEST.in new/nose2-0.15.1/MANIFEST.in
--- old/nose2-0.14.2/MANIFEST.in 2023-04-29 20:18:18.000000000 +0200
+++ new/nose2-0.15.1/MANIFEST.in 2024-05-31 03:06:08.000000000 +0200
@@ -3,7 +3,7 @@
include unittest.cfg
include README.rst
include license.txt
-recursive-include nose2/tests/functional/support *.py *.txt *.cfg *.rst *.json *.egg .coveragerc
+recursive-include nose2/tests/functional/support *.py *.txt *.toml *.cfg *.rst *.json *.egg .coveragerc
recursive-include docs *.inc *.py *.rst Makefile
global-exclude __pycache__
global-exclude *~
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/PKG-INFO new/nose2-0.15.1/PKG-INFO
--- old/nose2-0.14.2/PKG-INFO 2024-05-07 16:49:53.142876000 +0200
+++ new/nose2-0.15.1/PKG-INFO 2024-06-01 05:20:00.930882000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: nose2
-Version: 0.14.2
+Version: 0.15.1
Summary: unittest with plugins
Author-email: Stephen Rosen <dev(a)nose2.io>
License: BSD-2-Clause
@@ -32,9 +32,9 @@
Provides-Extra: coverage-plugin
Requires-Dist: coverage; extra == "coverage-plugin"
Provides-Extra: dev
-Requires-Dist: Sphinx; extra == "dev"
+Requires-Dist: sphinx; extra == "dev"
Requires-Dist: sphinx-issues; extra == "dev"
-Requires-Dist: sphinx_rtd_theme; extra == "dev"
+Requires-Dist: sphinx-rtd-theme; extra == "dev"
.. image:: https://results.pre-commit.ci/badge/github/nose-devs/nose2/main.svg
:target: https://results.pre-commit.ci/latest/github/nose-devs/nose2/main
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/docs/changelog.rst new/nose2-0.15.1/docs/changelog.rst
--- old/nose2-0.14.2/docs/changelog.rst 2024-05-07 16:49:26.000000000 +0200
+++ new/nose2-0.15.1/docs/changelog.rst 2024-06-01 05:19:28.000000000 +0200
@@ -13,9 +13,39 @@
Unreleased
----------
+0.15.1 (2024-05-31)
+-------------------
+
+Fixed
+~~~~~
+
+* Fix a bug with config loading which caused custom ini configs not to load if
+ they were not named with a ``.cfg`` extension. Thanks :user:`grhwalls` for
+ the bug report!
+
+0.15.0 (2024-05-30)
+-------------------
+
+Added
+~~~~~
+
+* Official support for ``python3.13`` betas. ``nose2`` now tests itself against
+ Python 3.13.
+
+* ``nose2`` now supports loading configuration data from the ``tool.nose2``
+ table in ``pyproject.toml``. Thanks to :user:`qequ` for the PR! (:pr:`596`,
+ :pr:`606`)
+
+ On python 3.11+, ``tomllib`` is used to parse TOML data. On python 3.10 and
+ lower, ``tomli`` must be installed to enable TOML support. Simply
+ ``pip install tomli`` as necessary.
+
0.14.2 (2024-05-07)
-------------------
+Added
+~~~~~
+
* For the coverage plugin, add a config option, ``coverage-combine``, which
defaults to ``False``. When set, this config invokes a ``coverage combine``
step before reporting results, regardless of whether or not multiprocessing
@@ -26,6 +56,9 @@
0.14.1 (2024-01-28)
-------------------
+Fixed
+~~~~~
+
* Fix the reporting of skipped tests in verbose mode on newer pythons (3.12.1+),
in which a skipped test is no longer treated as "started".
@@ -35,26 +68,42 @@
0.14.0 (2023-10-04)
-------------------
+Added
+~~~~~
+
* Add official support for ``python3.12``
+
+Removed
+~~~~~~~
+
* Remove support for ``python3.6`` and ``python3.7``
0.13.0 (2023-04-29)
-------------------
-* Remove support for python2 and older python3 versions
-
-* Fix support for python3.12 to avoid warnings about ``addDuration``.
- Thanks to :user:`cclauss` for the fix!
+Changed
+~~~~~~~
* ``nose2`` package metadata is converted to pyproject.toml format, using
``setuptools``. Building ``nose2`` packages from source now requires
``setuptools>=61.0.0`` or a PEP 517 compatible build frontend
(e.g. ``build``).
+Fixed
+~~~~~
+
+* Fix support for python3.12 to avoid warnings about ``addDuration``.
+ Thanks to :user:`cclauss` for the fix!
+
* ``nose2`` license metadata has been corrected in format and content to be
distributed in the sdist and wheel distributions correctly. Thanks
:user:`musicinmybrain` for helping research this issue!
+Removed
+~~~~~~~
+
+* Remove support for python2 and older python3 versions
+
0.12.0 (2022-07-16)
-------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/nose2/__init__.py new/nose2-0.15.1/nose2/__init__.py
--- old/nose2-0.14.2/nose2/__init__.py 2024-05-07 16:49:26.000000000 +0200
+++ new/nose2-0.15.1/nose2/__init__.py 2024-06-01 05:18:52.000000000 +0200
@@ -1,5 +1,5 @@
from nose2.main import discover, main
-__version__ = "0.14.2"
+__version__ = "0.15.1"
__all__ = ("__version__", "discover", "main")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/nose2/_toml.py new/nose2-0.15.1/nose2/_toml.py
--- old/nose2-0.14.2/nose2/_toml.py 1970-01-01 01:00:00.000000000 +0100
+++ new/nose2-0.15.1/nose2/_toml.py 2024-06-01 04:04:39.000000000 +0200
@@ -0,0 +1,26 @@
+from __future__ import annotations
+
+import types
+
+TOML_ENABLED: bool = False
+toml: types.ModuleType | None = None
+
+try:
+ import tomllib as toml
+
+ TOML_ENABLED = True
+except ImportError:
+ try:
+ import tomli as toml
+
+ TOML_ENABLED = True
+ except ImportError:
+ toml = None
+ TOML_ENABLED = False
+
+
+def load_toml(file: str) -> dict:
+ if toml is None:
+ raise RuntimeError("toml library not found. Please install 'tomli'.")
+ with open(file, "rb") as fp:
+ return toml.load(fp)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/nose2/events.py new/nose2-0.15.1/nose2/events.py
--- old/nose2-0.14.2/nose2/events.py 2024-04-28 01:10:38.000000000 +0200
+++ new/nose2-0.15.1/nose2/events.py 2024-06-01 04:04:39.000000000 +0200
@@ -3,9 +3,11 @@
# code developed in reference to that module and others within unittest2.
# unittest2 is Copyright (c) 2001-2010 Python Software Foundation; All
# Rights Reserved. See: http://docs.python.org/license.html
+from __future__ import annotations
import argparse
import logging
+import typing as t
import unittest
from nose2 import config, util
@@ -315,7 +317,7 @@
"handleDir",
# ... etc?
)
- hookClass = Hook
+ hookClass: type[Hook] = Hook
def __init__(self):
self.hooks = {}
@@ -362,7 +364,7 @@
"""
- _attrs = ("handled",)
+ _attrs: t.ClassVar[tuple[str, ...]] = ("handled",)
version = "0.4"
def __init__(self, **metadata):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/nose2/main.py new/nose2-0.15.1/nose2/main.py
--- old/nose2-0.14.2/nose2/main.py 2024-04-28 06:23:35.000000000 +0200
+++ new/nose2-0.15.1/nose2/main.py 2024-05-31 03:06:08.000000000 +0200
@@ -4,6 +4,7 @@
import unittest
from nose2 import events, loader, plugins, runner, session, util
+from nose2._toml import TOML_ENABLED
log = logging.getLogger(__name__)
__unittest = True
@@ -242,6 +243,8 @@
"""Find available config files"""
filenames = cfg_args.config[:]
proj_opts = ("unittest.cfg", "nose2.cfg")
+ if TOML_ENABLED:
+ proj_opts += ("pyproject.toml",)
for fn in proj_opts:
if cfg_args.top_level_directory:
fn = os.path.abspath(os.path.join(cfg_args.top_level_directory, fn))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/nose2/plugins/loader/eggdiscovery.py new/nose2-0.15.1/nose2/plugins/loader/eggdiscovery.py
--- old/nose2-0.14.2/nose2/plugins/loader/eggdiscovery.py 2024-04-28 01:10:38.000000000 +0200
+++ new/nose2-0.15.1/nose2/plugins/loader/eggdiscovery.py 2024-06-01 04:04:39.000000000 +0200
@@ -13,6 +13,8 @@
"""
+from __future__ import annotations
+
import logging
import os
@@ -24,8 +26,10 @@
try:
import pkg_resources
+
+ _has_pkg_resources = True
except ImportError:
- pkg_resources = None
+ _has_pkg_resources = False
class EggDiscoveryLoader(events.Plugin, discovery.Discoverer):
@@ -80,7 +84,7 @@
def _find_tests_in_dir(self, event, full_path, top_level):
if os.path.exists(full_path):
return
- elif pkg_resources and full_path.find(".egg") != -1:
+ elif _has_pkg_resources and full_path.find(".egg") != -1:
egg_path = full_path.split(".egg")[0] + ".egg"
for dist in pkg_resources.find_distributions(egg_path):
for modname in dist._get_metadata("top_level.txt"):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/nose2/plugins/printhooks.py new/nose2-0.15.1/nose2/plugins/printhooks.py
--- old/nose2-0.14.2/nose2/plugins/printhooks.py 2024-04-28 01:10:38.000000000 +0200
+++ new/nose2-0.15.1/nose2/plugins/printhooks.py 2024-06-01 04:04:39.000000000 +0200
@@ -12,11 +12,13 @@
each call.
"""
+from __future__ import annotations
+
import sys
from nose2 import events
-INDENT = []
+INDENT: list[str] = []
__unittest = True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/nose2/session.py new/nose2-0.15.1/nose2/session.py
--- old/nose2-0.14.2/nose2/session.py 2024-04-28 01:10:38.000000000 +0200
+++ new/nose2-0.15.1/nose2/session.py 2024-06-01 05:18:40.000000000 +0200
@@ -1,11 +1,11 @@
import argparse
import logging
import os
-
-# py2/py3 compatible load of SafeConfigParser/ConfigParser
+import pathlib
from configparser import ConfigParser
from nose2 import config, events, util
+from nose2._toml import load_toml
log = logging.getLogger(__name__)
__unittest = True
@@ -118,7 +118,24 @@
Loads all names files that exist into ``self.config``.
"""
- self.config.read(filenames)
+ for filename in filenames:
+ path = pathlib.Path(filename)
+ if not path.exists():
+ continue
+
+ # handle pyproject.toml case
+ if path.name == "pyproject.toml":
+ toml_config = load_toml(filename)
+ if not isinstance(toml_config.get("tool"), dict):
+ continue
+ tool_table = toml_config["tool"]
+ if not isinstance(tool_table.get("nose2"), dict):
+ continue
+ self.config.read_dict(tool_table["nose2"])
+
+ # else, use the config parser to read config data
+ else:
+ self.config.read(path)
def loadPlugins(self, modules=None, exclude=None):
"""Load plugins.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/nose2/tests/_common.py new/nose2-0.15.1/nose2/tests/_common.py
--- old/nose2-0.14.2/nose2/tests/_common.py 2024-05-07 16:39:24.000000000 +0200
+++ new/nose2-0.15.1/nose2/tests/_common.py 2024-06-01 04:04:39.000000000 +0200
@@ -210,13 +210,13 @@
self.cwd = os.getcwd()
if self.chdir:
os.chdir(self.chdir)
- self.stdout = sys.stdout = sys.__stdout__ = io.StringIO()
- self.stderr = sys.stderr = sys.__stderr__ = io.StringIO()
+ self.stdout = sys.stdout = sys.__stdout__ = io.StringIO() # type: ignore[misc]
+ self.stderr = sys.stderr = sys.__stderr__ = io.StringIO() # type: ignore[misc]
return self
def __exit__(self, exc_type, exc_val, exc_tb):
- sys.stdout = sys.__stdout__ = self._stdout
- sys.stderr = sys.__stderr__ = self._stderr
+ sys.stdout = sys.__stdout__ = self._stdout # type: ignore[misc]
+ sys.stderr = sys.__stderr__ = self._stderr # type: ignore[misc]
if self.chdir:
os.chdir(self.cwd)
return False
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/nose2/tests/functional/support/scenario/module_fixtures/test_mf_param_func.py new/nose2-0.15.1/nose2/tests/functional/support/scenario/module_fixtures/test_mf_param_func.py
--- old/nose2-0.14.2/nose2/tests/functional/support/scenario/module_fixtures/test_mf_param_func.py 2023-04-25 23:28:20.000000000 +0200
+++ new/nose2-0.15.1/nose2/tests/functional/support/scenario/module_fixtures/test_mf_param_func.py 2024-06-01 04:04:39.000000000 +0200
@@ -14,4 +14,4 @@
assert THINGS, "setup didn't run I think"
-test.paramList = (1,)
+test.paramList = (1,) # type: ignore[attr-defined]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/nose2/tests/functional/support/scenario/test_classes/test_classes.py new/nose2-0.15.1/nose2/tests/functional/support/scenario/test_classes/test_classes.py
--- old/nose2-0.14.2/nose2/tests/functional/support/scenario/test_classes/test_classes.py 2023-04-29 20:18:18.000000000 +0200
+++ new/nose2-0.15.1/nose2/tests/functional/support/scenario/test_classes/test_classes.py 2024-06-01 04:04:39.000000000 +0200
@@ -12,4 +12,4 @@
def test_params(self, a):
pass
- test_params.paramList = (1, 2)
+ test_params.paramList = (1, 2) # type: ignore[attr-defined]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/nose2/tests/functional/support/scenario/test_classes/test_fixtures.py new/nose2-0.15.1/nose2/tests/functional/support/scenario/test_classes/test_fixtures.py
--- old/nose2-0.14.2/nose2/tests/functional/support/scenario/test_classes/test_fixtures.py 2023-04-29 20:18:18.000000000 +0200
+++ new/nose2-0.15.1/nose2/tests/functional/support/scenario/test_classes/test_fixtures.py 2024-06-01 04:04:39.000000000 +0200
@@ -29,4 +29,4 @@
assert self.test_setup
assert self.setup
- test_params.paramList = (1, 2)
+ test_params.paramList = (1, 2) # type: ignore[attr-defined]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/nose2/tests/functional/support/scenario/test_classes_mp/test_classes_mp.py new/nose2-0.15.1/nose2/tests/functional/support/scenario/test_classes_mp/test_classes_mp.py
--- old/nose2-0.14.2/nose2/tests/functional/support/scenario/test_classes_mp/test_classes_mp.py 2023-04-29 20:18:18.000000000 +0200
+++ new/nose2-0.15.1/nose2/tests/functional/support/scenario/test_classes_mp/test_classes_mp.py 2024-06-01 04:04:39.000000000 +0200
@@ -12,4 +12,4 @@
def test_params(self, a):
pass
- test_params.paramList = (1, 2)
+ test_params.paramList = (1, 2) # type: ignore[attr-defined]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/nose2/tests/functional/support/scenario/test_classes_mp/test_fixtures_mp.py new/nose2-0.15.1/nose2/tests/functional/support/scenario/test_classes_mp/test_fixtures_mp.py
--- old/nose2-0.14.2/nose2/tests/functional/support/scenario/test_classes_mp/test_fixtures_mp.py 2023-04-29 20:18:18.000000000 +0200
+++ new/nose2-0.15.1/nose2/tests/functional/support/scenario/test_classes_mp/test_fixtures_mp.py 2024-06-01 04:04:39.000000000 +0200
@@ -29,4 +29,4 @@
assert self.test_setup
assert self.setup
- test_params.paramList = (1, 2)
+ test_params.paramList = (1, 2) # type: ignore[attr-defined]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/nose2/tests/functional/support/scenario/tests_in_package/pkg1/test/test_things.py new/nose2-0.15.1/nose2/tests/functional/support/scenario/tests_in_package/pkg1/test/test_things.py
--- old/nose2-0.14.2/nose2/tests/functional/support/scenario/tests_in_package/pkg1/test/test_things.py 2023-04-25 23:28:20.000000000 +0200
+++ new/nose2-0.15.1/nose2/tests/functional/support/scenario/tests_in_package/pkg1/test/test_things.py 2024-06-01 04:04:39.000000000 +0200
@@ -7,65 +7,65 @@
def test_ok(self):
pass
- test_ok.tags = ["method", "pass"]
- test_ok.a = 0
- test_ok.b = 1
+ test_ok.tags = ["method", "pass"] # type: ignore[attr-defined]
+ test_ok.a = 0 # type: ignore[attr-defined]
+ test_ok.b = 1 # type: ignore[attr-defined]
def test_typeerr(self):
raise TypeError("oops")
- test_typeerr.tags = ["method"]
+ test_typeerr.tags = ["method"] # type: ignore[attr-defined]
def test_failed(self):
print("Hello stdout")
assert False, "I failed"
- test_failed.tags = ["method"]
+ test_failed.tags = ["method"] # type: ignore[attr-defined]
def test_skippy(self):
raise unittest.SkipTest("I wanted to skip")
- test_skippy.a = 1
- test_skippy.b = 1
+ test_skippy.a = 1 # type: ignore[attr-defined]
+ test_skippy.b = 1 # type: ignore[attr-defined]
def test_gen_method(self):
def check(x):
assert x == 1
- check.b = 2
+ check.b = 2 # type: ignore[attr-defined]
yield check, 1
yield check, 2
- test_gen_method.a = 1
- test_gen_method.b = 1
+ test_gen_method.a = 1 # type: ignore[attr-defined]
+ test_gen_method.b = 1 # type: ignore[attr-defined]
def test_params_method(self, a):
self.assertEqual(a, 1)
- test_params_method.paramList = (1, 2)
- test_params_method.a = 1
+ test_params_method.paramList = (1, 2) # type: ignore[attr-defined]
+ test_params_method.a = 1 # type: ignore[attr-defined]
def test_func():
assert 1 == 1
-test_func.a = 1
-test_func.b = 0
-test_func.tags = ["func", "pass"]
+test_func.a = 1 # type: ignore[attr-defined]
+test_func.b = 0 # type: ignore[attr-defined]
+test_func.tags = ["func", "pass"] # type: ignore[attr-defined]
def test_gen():
def check(a, b):
assert a == b
- check.tags = ["func"]
+ check.tags = ["func"] # type: ignore[attr-defined]
for i in range(0, 5):
yield check, (i, i)
-test_gen.testGenerator = True
-test_gen.tags = ["func"]
+test_gen.testGenerator = True # type: ignore[attr-defined]
+test_gen.tags = ["func"] # type: ignore[attr-defined]
def test_gen_nose_style():
@@ -88,19 +88,19 @@
assert did_setup
-test_fixt.setup = setup
+test_fixt.setup = setup # type: ignore[attr-defined]
def test_params_func(a):
assert a == 1
-test_params_func.paramList = (1, 2)
-test_params_func.tags = ["func"]
+test_params_func.paramList = (1, 2) # type: ignore[attr-defined]
+test_params_func.tags = ["func"] # type: ignore[attr-defined]
def test_params_func_multi_arg(a, b):
assert a == b
-test_params_func_multi_arg.paramList = ((1, 1), (1, 2), (2, 2))
+test_params_func_multi_arg.paramList = ((1, 1), (1, 2), (2, 2)) # type: ignore[attr-defined] # noqa: E501
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/nose2/tests/functional/support/scenario/tests_in_unzipped_eggs/pkgunegg-0.0.0-py2.7.egg/pkgunegg/test/test_things.py new/nose2-0.15.1/nose2/tests/functional/support/scenario/tests_in_unzipped_eggs/pkgunegg-0.0.0-py2.7.egg/pkgunegg/test/test_things.py
--- old/nose2-0.14.2/nose2/tests/functional/support/scenario/tests_in_unzipped_eggs/pkgunegg-0.0.0-py2.7.egg/pkgunegg/test/test_things.py 2023-04-25 23:28:20.000000000 +0200
+++ new/nose2-0.15.1/nose2/tests/functional/support/scenario/tests_in_unzipped_eggs/pkgunegg-0.0.0-py2.7.egg/pkgunegg/test/test_things.py 2024-06-01 04:04:39.000000000 +0200
@@ -7,65 +7,65 @@
def test_ok(self):
pass
- test_ok.tags = ["method", "pass"]
- test_ok.a = 0
- test_ok.b = 1
+ test_ok.tags = ["method", "pass"] # type: ignore[attr-defined]
+ test_ok.a = 0 # type: ignore[attr-defined]
+ test_ok.b = 1 # type: ignore[attr-defined]
def test_typeerr(self):
raise TypeError("oops")
- test_typeerr.tags = ["method"]
+ test_typeerr.tags = ["method"] # type: ignore[attr-defined]
def test_failed(self):
print("Hello stdout")
assert False, "I failed"
- test_failed.tags = ["method"]
+ test_failed.tags = ["method"] # type: ignore[attr-defined]
def test_skippy(self):
raise unittest.SkipTest("I wanted to skip")
- test_skippy.a = 1
- test_skippy.b = 1
+ test_skippy.a = 1 # type: ignore[attr-defined]
+ test_skippy.b = 1 # type: ignore[attr-defined]
def test_gen_method(self):
def check(x):
assert x == 1
- check.b = 2
+ check.b = 2 # type: ignore[attr-defined]
yield check, 1
yield check, 2
- test_gen_method.a = 1
- test_gen_method.b = 1
+ test_gen_method.a = 1 # type: ignore[attr-defined]
+ test_gen_method.b = 1 # type: ignore[attr-defined]
def test_params_method(self, a):
self.assertEqual(a, 1)
- test_params_method.paramList = (1, 2)
- test_params_method.a = 1
+ test_params_method.paramList = (1, 2) # type: ignore[attr-defined]
+ test_params_method.a = 1 # type: ignore[attr-defined]
def test_func():
assert 1 == 1
-test_func.a = 1
-test_func.b = 0
-test_func.tags = ["func", "pass"]
+test_func.a = 1 # type: ignore[attr-defined]
+test_func.b = 0 # type: ignore[attr-defined]
+test_func.tags = ["func", "pass"] # type: ignore[attr-defined]
def test_gen():
def check(a, b):
assert a == b
- check.tags = ["func"]
+ check.tags = ["func"] # type: ignore[attr-defined]
for i in range(0, 5):
yield check, (i, i)
-test_gen.testGenerator = True
-test_gen.tags = ["func"]
+test_gen.testGenerator = True # type: ignore[attr-defined]
+test_gen.tags = ["func"] # type: ignore[attr-defined]
def test_gen_nose_style():
@@ -88,19 +88,19 @@
assert did_setup
-test_fixt.setup = setup
+test_fixt.setup = setup # type: ignore[attr-defined]
def test_params_func(a):
assert a == 1
-test_params_func.paramList = (1, 2)
-test_params_func.tags = ["func"]
+test_params_func.paramList = (1, 2) # type: ignore[attr-defined]
+test_params_func.tags = ["func"] # type: ignore[attr-defined]
def test_params_func_multi_arg(a, b):
assert a == b
-test_params_func_multi_arg.paramList = ((1, 1), (1, 2), (2, 2))
+test_params_func_multi_arg.paramList = ((1, 1), (1, 2), (2, 2)) # type: ignore[attr-defined] # noqa: E501
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/nose2/tests/functional/support/such/test_such.py new/nose2-0.15.1/nose2/tests/functional/support/such/test_such.py
--- old/nose2-0.14.2/nose2/tests/functional/support/such/test_such.py 2023-04-29 20:18:18.000000000 +0200
+++ new/nose2-0.15.1/nose2/tests/functional/support/such/test_such.py 2024-06-01 04:04:39.000000000 +0200
@@ -51,7 +51,7 @@
#
with it.having("an expensive fixture"):
- @it.has_setup # noqa: F811
+ @it.has_setup
def setup(): # noqa: F811
it.things.append(2)
@@ -61,7 +61,7 @@
# them. Tests can call any and all TestCase methods on this
# instance.
#
- @it.should("do more things") # noqa: F811
+ @it.should("do more things")
def test(case): # noqa: F811
case.assertEqual(it.things[-1], 2)
@@ -70,15 +70,15 @@
#
with it.having("another precondition"):
- @it.has_setup # noqa: F811
+ @it.has_setup
def setup(): # noqa: F811
it.things.append(3)
- @it.has_teardown # noqa: F811
+ @it.has_teardown
def teardown(): # noqa: F811
it.things.pop()
- @it.should("do that not this") # noqa: F811
+ @it.should("do that not this") # type: ignore[no-redef]
def test(case): # noqa: F811
it.things.append(4)
#
@@ -87,7 +87,7 @@
case.addCleanup(it.things.pop)
case.assertEqual(it.things[-1], 4, it.things)
- @it.should("do this not that") # noqa: F811
+ @it.should("do this not that") # type: ignore[no-redef]
def test(case): # noqa: F811
case.assertEqual(it.things[-1], 3, it.things[:])
@@ -104,11 +104,11 @@
#
it.uses(SomeLayer)
- @it.has_setup # noqa: F811
+ @it.has_setup
def setup(): # noqa: F811
it.things.append(99)
- @it.has_teardown # noqa: F811
+ @it.has_teardown
def teardown(): # noqa: F811
it.things.pop()
@@ -127,24 +127,24 @@
delattr(it, "is_funny")
delattr(case, "is_funny")
- @it.should("do something else") # noqa: F811
+ @it.should("do something else") # type: ignore[no-redef]
def test(case): # noqa: F811
assert it.things[-1] == 99
assert it.is_funny
assert case.is_funny
- @it.should("have another test") # noqa: F811
+ @it.should("have another test") # type: ignore[no-redef]
def test(case): # noqa: F811
assert it.is_funny
assert case.is_funny
- @it.should("have access to an external fixture") # noqa: F811
+ @it.should("have access to an external fixture") # type: ignore[no-redef]
def test(case): # noqa: F811
assert it.somelayer
with it.having("a case inside the external fixture"):
- @it.should("still have access to that fixture") # noqa: F811
+ @it.should("still have access to that fixture") # type: ignore[no-redef] # noqa: E501
def test(case): # noqa: F811
assert it.somelayer
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/nose2/tests/functional/support/toml/a/pyproject.toml new/nose2-0.15.1/nose2/tests/functional/support/toml/a/pyproject.toml
--- old/nose2-0.14.2/nose2/tests/functional/support/toml/a/pyproject.toml 1970-01-01 01:00:00.000000000 +0100
+++ new/nose2-0.15.1/nose2/tests/functional/support/toml/a/pyproject.toml 2024-05-31 03:06:08.000000000 +0200
@@ -0,0 +1,5 @@
+[tool.nose2.a]
+a = 1
+
+[tool.nose2.unittest]
+plugins = "plugin_a"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/nose2/tests/functional/support/toml/b/pyproject.toml new/nose2-0.15.1/nose2/tests/functional/support/toml/b/pyproject.toml
--- old/nose2-0.14.2/nose2/tests/functional/support/toml/b/pyproject.toml 1970-01-01 01:00:00.000000000 +0100
+++ new/nose2-0.15.1/nose2/tests/functional/support/toml/b/pyproject.toml 2024-05-31 03:06:08.000000000 +0200
@@ -0,0 +1,5 @@
+[tool.nose2.b]
+b = """
+4
+5
+"""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/nose2/tests/functional/test_eggdiscovery_loader.py new/nose2-0.15.1/nose2/tests/functional/test_eggdiscovery_loader.py
--- old/nose2-0.14.2/nose2/tests/functional/test_eggdiscovery_loader.py 2023-04-25 23:28:20.000000000 +0200
+++ new/nose2-0.15.1/nose2/tests/functional/test_eggdiscovery_loader.py 2024-06-01 04:04:39.000000000 +0200
@@ -6,11 +6,9 @@
from nose2.tests._common import FunctionalTestCase, support_file
try:
- import pkg_resources
-
+ import pkg_resources # noqa: F401
except ImportError:
- pkg_resources = None
-
+ pass
else:
class EggDiscoveryFunctionalTest(FunctionalTestCase):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/nose2/tests/functional/test_prettyassert.py new/nose2-0.15.1/nose2/tests/functional/test_prettyassert.py
--- old/nose2-0.14.2/nose2/tests/functional/test_prettyassert.py 2024-05-07 16:39:24.000000000 +0200
+++ new/nose2-0.15.1/nose2/tests/functional/test_prettyassert.py 2024-05-29 21:47:44.000000000 +0200
@@ -167,7 +167,7 @@
"scenario/pretty_asserts/unittest_assertion", "-v", "--pretty-assert"
)
# look for typical unittest output
- expected = "self.assertTrue\\(x\\)\nAssertionError: False is not true"
+ expected = "self.assertTrue\\(x\\)\n(\\W+\n)?AssertionError: False is not true"
stderr = self.assertProcOutputPattern(proc, expected)
# the assertion line wasn't reprinted by prettyassert
self.assertNotIn(">>> self.assertTrue", stderr)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/nose2/tests/functional/test_session.py new/nose2-0.15.1/nose2/tests/functional/test_session.py
--- old/nose2-0.14.2/nose2/tests/functional/test_session.py 2023-04-25 23:28:20.000000000 +0200
+++ new/nose2-0.15.1/nose2/tests/functional/test_session.py 2024-06-01 05:18:40.000000000 +0200
@@ -1,9 +1,32 @@
+import pathlib
import sys
+import tempfile
+import unittest
from nose2 import session
+from nose2._toml import TOML_ENABLED
from nose2.tests._common import FunctionalTestCase, support_file
+def test_loading_config_from_ini_file_without_cfg_suffix():
+ """
+ Regression test for https://github.com/nose-devs/nose2/issues/614
+
+ It is possible to have nose2 config embedded in any ini config file, and it might
+ not have a recognizable name.
+ It is not guaranteed that filenames used for config will end in `.cfg`.
+ """
+ sess = session.Session()
+ with tempfile.TemporaryDirectory() as tmpdirname:
+ tmpdir = pathlib.Path(tmpdirname)
+
+ foo_ini = tmpdir / "foo.ini"
+ foo_ini.write_text("""[alpha]\na = 1""")
+
+ sess.loadConfigFiles(str(foo_ini))
+ assert sess.config.has_section("alpha")
+
+
class SessionFunctionalTests(FunctionalTestCase):
def setUp(self):
self.s = session.Session()
@@ -41,6 +64,58 @@
# Hack cached Config object internals to make the stored value
# something different
cache_sess.configCache["a"]._mvd["a"] = "0"
+ newitems = []
+ for item in cache_sess.configCache["a"]._items:
+ if item != ("a", "1"):
+ newitems.append(item)
+ else:
+ newitems.append(("a", "0"))
+ cache_sess.configCache["a"]._items = newitems
+
+ # Second access to given section, confirm returns cached value
+ # rather than parsing config file again
+ secondaccess = cache_sess.get("a")
+ assert secondaccess.as_int("a") == 0
+
+
+class SessionTomlFunctionalTests(FunctionalTestCase):
+ def setUp(self):
+ if not TOML_ENABLED:
+ raise unittest.SkipTest("toml module not available")
+ self.s = session.Session()
+ self.s.loadConfigFiles(
+ support_file("toml", "a", "pyproject.toml"),
+ support_file("toml", "b", "pyproject.toml"),
+ )
+
+ def test_session_can_load_config_files(self):
+ assert self.s.config.has_section("a")
+ assert self.s.config.has_section("b")
+
+ def test_session_holds_plugin_config(self):
+ plug_config = self.s.get("a")
+ assert plug_config
+
+ def test_session_can_load_toml_plugins_from_modules(self):
+ self.s.loadPlugins()
+ assert self.s.plugins
+ plug = self.s.plugins[0]
+ self.assertEqual(plug.a, 1)
+
+ def test_session_config_cacheing(self):
+ """Test caching of config sections works"""
+
+ # Create new session (generic one likely already cached
+ # depending on test order)
+ cache_sess = session.Session()
+ cache_sess.loadConfigFiles(support_file("toml", "a", "pyproject.toml"))
+
+ # First access to given section, should read from config file
+ firstaccess = cache_sess.get("a")
+ assert firstaccess.as_int("a") == 1
+ # Hack cached Config object internals to make the stored value
+ # something different
+ cache_sess.configCache["a"]._mvd["a"] = "0"
newitems = []
for item in cache_sess.configCache["a"]._items:
if item != ("a", "1"):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/nose2/tests/unit/test_prof_plugin.py new/nose2-0.15.1/nose2/tests/unit/test_prof_plugin.py
--- old/nose2-0.14.2/nose2/tests/unit/test_prof_plugin.py 2023-04-25 23:28:20.000000000 +0200
+++ new/nose2-0.15.1/nose2/tests/unit/test_prof_plugin.py 2024-06-01 04:04:39.000000000 +0200
@@ -22,7 +22,11 @@
def test_startTestRun_sets_executeTests(self):
_prof = Stub()
_prof.runcall = object()
- prof.cProfile.Profile = lambda: _prof
+
+ def _profile_call() -> Stub:
+ return _prof
+
+ prof.cProfile.Profile = _profile_call
event = StartTestRunEvent(
runner=None, suite=None, result=None, startTime=None, executeTests=None
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/nose2.egg-info/PKG-INFO new/nose2-0.15.1/nose2.egg-info/PKG-INFO
--- old/nose2-0.14.2/nose2.egg-info/PKG-INFO 2024-05-07 16:49:53.000000000 +0200
+++ new/nose2-0.15.1/nose2.egg-info/PKG-INFO 2024-06-01 05:20:00.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: nose2
-Version: 0.14.2
+Version: 0.15.1
Summary: unittest with plugins
Author-email: Stephen Rosen <dev(a)nose2.io>
License: BSD-2-Clause
@@ -32,9 +32,9 @@
Provides-Extra: coverage-plugin
Requires-Dist: coverage; extra == "coverage-plugin"
Provides-Extra: dev
-Requires-Dist: Sphinx; extra == "dev"
+Requires-Dist: sphinx; extra == "dev"
Requires-Dist: sphinx-issues; extra == "dev"
-Requires-Dist: sphinx_rtd_theme; extra == "dev"
+Requires-Dist: sphinx-rtd-theme; extra == "dev"
.. image:: https://results.pre-commit.ci/badge/github/nose-devs/nose2/main.svg
:target: https://results.pre-commit.ci/latest/github/nose-devs/nose2/main
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/nose2.egg-info/SOURCES.txt new/nose2-0.15.1/nose2.egg-info/SOURCES.txt
--- old/nose2-0.14.2/nose2.egg-info/SOURCES.txt 2024-05-07 16:49:53.000000000 +0200
+++ new/nose2-0.15.1/nose2.egg-info/SOURCES.txt 2024-06-01 05:20:00.000000000 +0200
@@ -63,6 +63,7 @@
docs/plugins/testid.rst
nose2/__init__.py
nose2/__main__.py
+nose2/_toml.py
nose2/collector.py
nose2/config.py
nose2/events.py
@@ -297,6 +298,8 @@
nose2/tests/functional/support/such/test_such.py
nose2/tests/functional/support/such/test_such_timing.py
nose2/tests/functional/support/such/test_such_without_layers.py
+nose2/tests/functional/support/toml/a/pyproject.toml
+nose2/tests/functional/support/toml/b/pyproject.toml
nose2/tests/unit/__init__.py
nose2/tests/unit/test_attrib_plugin.py
nose2/tests/unit/test_buffer_plugin.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/nose2.egg-info/requires.txt new/nose2-0.15.1/nose2.egg-info/requires.txt
--- old/nose2-0.14.2/nose2.egg-info/requires.txt 2024-05-07 16:49:53.000000000 +0200
+++ new/nose2-0.15.1/nose2.egg-info/requires.txt 2024-06-01 05:20:00.000000000 +0200
@@ -3,6 +3,6 @@
coverage
[dev]
-Sphinx
+sphinx
sphinx-issues
-sphinx_rtd_theme
+sphinx-rtd-theme
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/pyproject.toml new/nose2-0.15.1/pyproject.toml
--- old/nose2-0.14.2/pyproject.toml 2024-04-28 01:10:38.000000000 +0200
+++ new/nose2-0.15.1/pyproject.toml 2024-06-01 04:04:39.000000000 +0200
@@ -8,17 +8,17 @@
name = "nose2"
description = "unittest with plugins"
readme = "README.rst"
-keywords= [
+keywords = [
"testing",
"tests",
"unittest",
]
-license = {text = "BSD-2-Clause"}
+license = { text = "BSD-2-Clause" }
authors = [
{ name = "Stephen Rosen", email = "dev(a)nose2.io" },
]
requires-python = ">=3.8"
-classifiers=[
+classifiers = [
"Development Status :: 4 - Beta",
"Environment :: Console",
"Intended Audience :: Developers",
@@ -40,25 +40,34 @@
dynamic = [
"version",
]
-[project.optional-dependencies]
-coverage_plugin = [
+optional-dependencies.coverage_plugin = [
"coverage",
]
-dev = [
- "Sphinx",
+optional-dependencies.dev = [
+ "sphinx",
"sphinx-issues",
- "sphinx_rtd_theme",
+ "sphinx-rtd-theme",
]
-[project.urls]
-changelog = "https://docs.nose2.io/en/latest/changelog.html"
-documentation = "https://docs.nose2.io/"
-repository = "https://github.com/nose-devs/nose2"
-[project.scripts]
-nose2 = "nose2:discover"
+urls.changelog = "https://docs.nose2.io/en/latest/changelog.html"
+urls.documentation = "https://docs.nose2.io/"
+urls.repository = "https://github.com/nose-devs/nose2"
+scripts.nose2 = "nose2:discover"
[tool.setuptools.dynamic]
-version = {attr = "nose2.__version__"}
+version = { attr = "nose2.__version__" }
[tool.isort]
profile = "black"
-known_third_party = ["coverage", "mock"]
+known_third_party = [
+ "coverage",
+ "mock",
+]
+
+[tool.mypy]
+# strict = true
+sqlite_cache = true
+ignore_missing_imports = true
+disallow_subclassing_any = false
+files = [
+ "nose2",
+]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nose2-0.14.2/tox.ini new/nose2-0.15.1/tox.ini
--- old/nose2-0.14.2/tox.ini 2023-08-30 03:22:49.000000000 +0200
+++ new/nose2-0.15.1/tox.ini 2024-06-01 05:18:36.000000000 +0200
@@ -1,10 +1,12 @@
[tox]
-envlist=py{38,39,310,311,312}{,-nocov},pypy,docs,lint
+envlist=py{38,39,310,311,312,313}{,-nocov},pypy,docs,lint
[testenv]
passenv = CI
extras = dev
-deps = !nocov: coverage
+deps =
+ !nocov: coverage
+ py{38,39,310}-toml: tomli
setenv = PYTHONPATH={toxinidir}
commands =
nocov: nose2 -v --pretty-assert {posargs}
@@ -20,9 +22,11 @@
[testenv:mypy]
extras = dev
deps =
- mypy
+ mypy==1.10.0
types-setuptools
types-docutils
+ tomli
+ coverage
commands =
mypy nose2/ {posargs}
1
0
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-itemloaders for openSUSE:Factory checked in at 2024-06-05 17:42:16
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-itemloaders (Old)
and /work/SRC/openSUSE:Factory/.python-itemloaders.new.24587 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-itemloaders"
Wed Jun 5 17:42:16 2024 rev:6 rq:1178615 version:1.3.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-itemloaders/python-itemloaders.changes 2024-04-21 20:29:29.514789591 +0200
+++ /work/SRC/openSUSE:Factory/.python-itemloaders.new.24587/python-itemloaders.changes 2024-06-05 17:43:00.175422463 +0200
@@ -1,0 +2,9 @@
+Tue Jun 4 20:38:34 UTC 2024 - Dirk Müller <dmueller(a)suse.com>
+
+- update to 1.3.0:
+ * Added support for method chaining to the `add_*` and
+ `replace_*` methods
+ * Added type hints and `py.typed`
+ * Made the docs builds reproducible
+
+-------------------------------------------------------------------
Old:
----
itemloaders-1.2.0-gh.tar.gz
New:
----
itemloaders-1.3.0-gh.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-itemloaders.spec ++++++
--- /var/tmp/diff_new_pack.FztGX7/_old 2024-06-05 17:43:00.863447520 +0200
+++ /var/tmp/diff_new_pack.FztGX7/_new 2024-06-05 17:43:00.863447520 +0200
@@ -18,7 +18,7 @@
%{?sle15_python_module_pythons}
Name: python-itemloaders
-Version: 1.2.0
+Version: 1.3.0
Release: 0
Summary: Base library for scrapy's ItemLoader
License: BSD-3-Clause
++++++ itemloaders-1.2.0-gh.tar.gz -> itemloaders-1.3.0-gh.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/itemloaders-1.2.0/.bumpversion.cfg new/itemloaders-1.3.0/.bumpversion.cfg
--- old/itemloaders-1.2.0/.bumpversion.cfg 2024-04-18 11:51:35.000000000 +0200
+++ new/itemloaders-1.3.0/.bumpversion.cfg 2024-05-30 13:05:17.000000000 +0200
@@ -1,5 +1,5 @@
[bumpversion]
-current_version = 1.2.0
+current_version = 1.3.0
commit = True
tag = True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/itemloaders-1.2.0/docs/conf.py new/itemloaders-1.3.0/docs/conf.py
--- old/itemloaders-1.2.0/docs/conf.py 2024-04-18 11:51:35.000000000 +0200
+++ new/itemloaders-1.3.0/docs/conf.py 2024-05-30 13:05:17.000000000 +0200
@@ -12,7 +12,6 @@
# serve to show the default.
import sys
-from datetime import datetime
from os import path
import sphinx_rtd_theme
@@ -50,7 +49,7 @@
# General information about the project.
project = "itemloaders"
-copyright = "2020–{}, Zyte Group Ltd".format(datetime.now().year)
+copyright = "Zyte Group Ltd"
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/itemloaders-1.2.0/docs/release-notes.rst new/itemloaders-1.3.0/docs/release-notes.rst
--- old/itemloaders-1.2.0/docs/release-notes.rst 2024-04-18 11:51:35.000000000 +0200
+++ new/itemloaders-1.3.0/docs/release-notes.rst 2024-05-30 13:05:17.000000000 +0200
@@ -5,6 +5,20 @@
Release notes
=============
+.. _release-1.3.0:
+
+itemloaders 1.3.0 (2024-05-30)
+------------------------------
+
+- Added support for method chaining to the ``add_*`` and ``replace_*``
+ methods, so you can now write code such as
+ ``loader.add_xpath("name", "//body/text()").add_value("url", "http://example.com")``
+ (:gh:`81`)
+
+- Added type hints and ``py.typed`` (:gh:`80`, :gh:`83`)
+
+- Made the docs builds reproducible (:gh:`82`)
+
.. _release-1.2.0:
itemloaders 1.2.0 (2024-04-18)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/itemloaders-1.2.0/itemloaders/__init__.py new/itemloaders-1.3.0/itemloaders/__init__.py
--- old/itemloaders-1.2.0/itemloaders/__init__.py 2024-04-18 11:51:35.000000000 +0200
+++ new/itemloaders-1.3.0/itemloaders/__init__.py 2024-05-30 13:05:17.000000000 +0200
@@ -4,24 +4,43 @@
See documentation in docs/topics/loaders.rst
"""
+from __future__ import annotations
+
from contextlib import suppress
+from typing import (
+ TYPE_CHECKING,
+ Any,
+ Callable,
+ Dict,
+ Iterable,
+ List,
+ MutableMapping,
+ Optional,
+ Pattern,
+ Union,
+)
from itemadapter import ItemAdapter
+from parsel import Selector
from parsel.utils import extract_regex, flatten
from itemloaders.common import wrap_loader_context
from itemloaders.processors import Identity
from itemloaders.utils import arg_to_iter
+if TYPE_CHECKING:
+ # typing.Self requires Python 3.11
+ from typing_extensions import Self
+
-def unbound_method(method):
+def unbound_method(method: Callable[..., Any]) -> Callable[..., Any]:
"""
Allow to use single-argument functions as input or output processors
(no need to define an unused first 'self' argument)
"""
with suppress(AttributeError):
if "." not in method.__qualname__:
- return method.__func__
+ return method.__func__ # type: ignore[attr-defined, no-any-return]
return method
@@ -96,40 +115,46 @@
.. _parsel: https://parsel.readthedocs.io/en/latest/
"""
- default_item_class = dict
- default_input_processor = Identity()
- default_output_processor = Identity()
-
- def __init__(self, item=None, selector=None, parent=None, **context):
- self.selector = selector
+ default_item_class: type = dict
+ default_input_processor: Callable[..., Any] = Identity()
+ default_output_processor: Callable[..., Any] = Identity()
+
+ def __init__(
+ self,
+ item: Any = None,
+ selector: Optional[Selector] = None,
+ parent: Optional[ItemLoader] = None,
+ **context: Any,
+ ):
+ self.selector: Optional[Selector] = selector
context.update(selector=selector)
if item is None:
item = self.default_item_class()
self._local_item = item
context["item"] = item
- self.context = context
- self.parent = parent
- self._local_values = {}
+ self.context: MutableMapping[str, Any] = context
+ self.parent: Optional[ItemLoader] = parent
+ self._local_values: Dict[str, List[Any]] = {}
# values from initial item
for field_name, value in ItemAdapter(item).items():
self._values.setdefault(field_name, [])
self._values[field_name] += arg_to_iter(value)
@property
- def _values(self):
+ def _values(self) -> Dict[str, List[Any]]:
if self.parent is not None:
return self.parent._values
else:
return self._local_values
@property
- def item(self):
+ def item(self) -> Any:
if self.parent is not None:
return self.parent.item
else:
return self._local_item
- def nested_xpath(self, xpath, **context):
+ def nested_xpath(self, xpath: str, **context: Any) -> Self:
"""
Create a nested loader with an xpath selector.
The supplied selector is applied relative to selector associated
@@ -137,12 +162,14 @@
with the parent :class:`ItemLoader` so calls to :meth:`add_xpath`,
:meth:`add_value`, :meth:`replace_value`, etc. will behave as expected.
"""
+ self._check_selector_method()
+ assert self.selector
selector = self.selector.xpath(xpath)
context.update(selector=selector)
subloader = self.__class__(item=self.item, parent=self, **context)
return subloader
- def nested_css(self, css, **context):
+ def nested_css(self, css: str, **context: Any) -> Self:
"""
Create a nested loader with a css selector.
The supplied selector is applied relative to selector associated
@@ -150,12 +177,21 @@
with the parent :class:`ItemLoader` so calls to :meth:`add_xpath`,
:meth:`add_value`, :meth:`replace_value`, etc. will behave as expected.
"""
+ self._check_selector_method()
+ assert self.selector
selector = self.selector.css(css)
context.update(selector=selector)
subloader = self.__class__(item=self.item, parent=self, **context)
return subloader
- def add_value(self, field_name, value, *processors, re=None, **kw):
+ def add_value(
+ self,
+ field_name: Optional[str],
+ value: Any,
+ *processors: Callable[..., Any],
+ re: Union[str, Pattern[str], None] = None,
+ **kw: Any,
+ ) -> Self:
"""
Process and then add the given ``value`` for the given field.
@@ -169,6 +205,9 @@
multiple fields may be added. And the processed value should be a dict
with field_name mapped to values.
+ :returns: The current ItemLoader instance for method chaining.
+ :rtype: ItemLoader
+
Examples::
loader.add_value('name', 'Color TV')
@@ -176,6 +215,7 @@
loader.add_value('length', '100')
loader.add_value('name', 'name: foo', TakeFirst(), re='name: (.+)')
loader.add_value(None, {'name': 'foo', 'sex': 'male'})
+
"""
value = self.get_value(value, *processors, re=re, **kw)
if value is None:
@@ -185,11 +225,22 @@
self._add_value(k, v)
else:
self._add_value(field_name, value)
+ return self
- def replace_value(self, field_name, value, *processors, re=None, **kw):
+ def replace_value(
+ self,
+ field_name: Optional[str],
+ value: Any,
+ *processors: Callable[..., Any],
+ re: Union[str, Pattern[str], None] = None,
+ **kw: Any,
+ ) -> Self:
"""
Similar to :meth:`add_value` but replaces the collected data with the
new value instead of adding it.
+
+ :returns: The current ItemLoader instance for method chaining.
+ :rtype: ItemLoader
"""
value = self.get_value(value, *processors, re=re, **kw)
if value is None:
@@ -199,19 +250,26 @@
self._replace_value(k, v)
else:
self._replace_value(field_name, value)
+ return self
- def _add_value(self, field_name, value):
+ def _add_value(self, field_name: str, value: Any) -> None:
value = arg_to_iter(value)
processed_value = self._process_input_value(field_name, value)
if processed_value:
self._values.setdefault(field_name, [])
self._values[field_name] += arg_to_iter(processed_value)
- def _replace_value(self, field_name, value):
+ def _replace_value(self, field_name: str, value: Any) -> None:
self._values.pop(field_name, None)
self._add_value(field_name, value)
- def get_value(self, value, *processors, re=None, **kw):
+ def get_value(
+ self,
+ value: Any,
+ *processors: Callable[..., Any],
+ re: Union[str, Pattern[str], None] = None,
+ **kw: Any,
+ ) -> Any:
"""
Process the given ``value`` by the given ``processors`` and keyword
arguments.
@@ -221,7 +279,7 @@
:param re: a regular expression to use for extracting data from the
given value using :func:`~parsel.utils.extract_regex` method,
applied before processors
- :type re: str or typing.Pattern
+ :type re: str or typing.Pattern[str]
Examples:
@@ -249,7 +307,7 @@
) from e
return value
- def load_item(self):
+ def load_item(self) -> Any:
"""
Populate the item with the data collected so far, and return it. The
data collected is first passed through the :ref:`output processors
@@ -263,7 +321,7 @@
return adapter.item
- def get_output_value(self, field_name):
+ def get_output_value(self, field_name: str) -> Any:
"""
Return the collected values parsed using the output processor, for the
given field. This method doesn't populate or modify the item at all.
@@ -279,11 +337,11 @@
% (field_name, value, type(e).__name__, str(e))
) from e
- def get_collected_values(self, field_name):
+ def get_collected_values(self, field_name: str) -> List[Any]:
"""Return the collected values for the given field."""
return self._values.get(field_name, [])
- def get_input_processor(self, field_name):
+ def get_input_processor(self, field_name: str) -> Callable[..., Any]:
proc = getattr(self, "%s_in" % field_name, None)
if not proc:
proc = self._get_item_field_attr(
@@ -291,7 +349,7 @@
)
return unbound_method(proc)
- def get_output_processor(self, field_name):
+ def get_output_processor(self, field_name: str) -> Callable[..., Any]:
proc = getattr(self, "%s_out" % field_name, None)
if not proc:
proc = self._get_item_field_attr(
@@ -299,11 +357,13 @@
)
return unbound_method(proc)
- def _get_item_field_attr(self, field_name, key, default=None):
+ def _get_item_field_attr(
+ self, field_name: str, key: Any, default: Any = None
+ ) -> Any:
field_meta = ItemAdapter(self.item).get_field_meta(field_name)
return field_meta.get(key, default)
- def _process_input_value(self, field_name, value):
+ def _process_input_value(self, field_name: str, value: Any) -> Any:
proc = self.get_input_processor(field_name)
_proc = proc
proc = wrap_loader_context(proc, self.context)
@@ -322,14 +382,21 @@
)
) from e
- def _check_selector_method(self):
+ def _check_selector_method(self) -> None:
if self.selector is None:
raise RuntimeError(
"To use XPath or CSS selectors, %s "
"must be instantiated with a selector" % self.__class__.__name__
)
- def add_xpath(self, field_name, xpath, *processors, re=None, **kw):
+ def add_xpath(
+ self,
+ field_name: Optional[str],
+ xpath: Union[str, Iterable[str]],
+ *processors: Callable[..., Any],
+ re: Union[str, Pattern[str], None] = None,
+ **kw: Any,
+ ) -> Self:
"""
Similar to :meth:`ItemLoader.add_value` but receives an XPath instead of a
value, which is used to extract a list of strings from the
@@ -340,6 +407,9 @@
:param xpath: the XPath to extract data from
:type xpath: str
+ :returns: The current ItemLoader instance for method chaining.
+ :rtype: ItemLoader
+
Examples::
# HTML snippet: <p class="product-name">Color TV</p>
@@ -349,16 +419,33 @@
"""
values = self._get_xpathvalues(xpath, **kw)
- self.add_value(field_name, values, *processors, re=re, **kw)
+ return self.add_value(field_name, values, *processors, re=re, **kw)
- def replace_xpath(self, field_name, xpath, *processors, re=None, **kw):
+ def replace_xpath(
+ self,
+ field_name: Optional[str],
+ xpath: Union[str, Iterable[str]],
+ *processors: Callable[..., Any],
+ re: Union[str, Pattern[str], None] = None,
+ **kw: Any,
+ ) -> Self:
"""
Similar to :meth:`add_xpath` but replaces collected data instead of adding it.
+
+ :returns: The current ItemLoader instance for method chaining.
+ :rtype: ItemLoader
+
"""
values = self._get_xpathvalues(xpath, **kw)
- self.replace_value(field_name, values, *processors, re=re, **kw)
+ return self.replace_value(field_name, values, *processors, re=re, **kw)
- def get_xpath(self, xpath, *processors, re=None, **kw):
+ def get_xpath(
+ self,
+ xpath: Union[str, Iterable[str]],
+ *processors: Callable[..., Any],
+ re: Union[str, Pattern[str], None] = None,
+ **kw: Any,
+ ) -> Any:
"""
Similar to :meth:`ItemLoader.get_value` but receives an XPath instead of a
value, which is used to extract a list of unicode strings from the
@@ -369,7 +456,7 @@
:param re: a regular expression to use for extracting data from the
selected XPath region
- :type re: str or typing.Pattern
+ :type re: str or typing.Pattern[str]
Examples::
@@ -382,12 +469,22 @@
values = self._get_xpathvalues(xpath, **kw)
return self.get_value(values, *processors, re=re, **kw)
- def _get_xpathvalues(self, xpaths, **kw):
+ def _get_xpathvalues(
+ self, xpaths: Union[str, Iterable[str]], **kw: Any
+ ) -> List[Any]:
self._check_selector_method()
+ assert self.selector
xpaths = arg_to_iter(xpaths)
return flatten(self.selector.xpath(xpath, **kw).getall() for xpath in xpaths)
- def add_css(self, field_name, css, *processors, re=None, **kw):
+ def add_css(
+ self,
+ field_name: Optional[str],
+ css: Union[str, Iterable[str]],
+ *processors: Callable[..., Any],
+ re: Union[str, Pattern[str], None] = None,
+ **kw: Any,
+ ) -> Self:
"""
Similar to :meth:`ItemLoader.add_value` but receives a CSS selector
instead of a value, which is used to extract a list of unicode strings
@@ -398,24 +495,45 @@
:param css: the CSS selector to extract data from
:type css: str
+ :returns: The current ItemLoader instance for method chaining.
+ :rtype: ItemLoader
+
Examples::
# HTML snippet: <p class="product-name">Color TV</p>
loader.add_css('name', 'p.product-name')
# HTML snippet: <p id="price">the price is $1200</p>
loader.add_css('price', 'p#price', re='the price is (.*)')
+
"""
values = self._get_cssvalues(css)
- self.add_value(field_name, values, *processors, re=re, **kw)
+ return self.add_value(field_name, values, *processors, re=re, **kw)
- def replace_css(self, field_name, css, *processors, re=None, **kw):
+ def replace_css(
+ self,
+ field_name: Optional[str],
+ css: Union[str, Iterable[str]],
+ *processors: Callable[..., Any],
+ re: Union[str, Pattern[str], None] = None,
+ **kw: Any,
+ ) -> Self:
"""
Similar to :meth:`add_css` but replaces collected data instead of adding it.
+
+ :returns: The current ItemLoader instance for method chaining.
+ :rtype: ItemLoader
+
"""
values = self._get_cssvalues(css)
- self.replace_value(field_name, values, *processors, re=re, **kw)
+ return self.replace_value(field_name, values, *processors, re=re, **kw)
- def get_css(self, css, *processors, re=None, **kw):
+ def get_css(
+ self,
+ css: Union[str, Iterable[str]],
+ *processors: Callable[..., Any],
+ re: Union[str, Pattern[str], None] = None,
+ **kw: Any,
+ ) -> Any:
"""
Similar to :meth:`ItemLoader.get_value` but receives a CSS selector
instead of a value, which is used to extract a list of unicode strings
@@ -426,7 +544,7 @@
:param re: a regular expression to use for extracting data from the
selected CSS region
- :type re: str or typing.Pattern
+ :type re: str or typing.Pattern[str]
Examples::
@@ -438,12 +556,20 @@
values = self._get_cssvalues(css)
return self.get_value(values, *processors, re=re, **kw)
- def _get_cssvalues(self, csss):
+ def _get_cssvalues(self, csss: Union[str, Iterable[str]]) -> List[Any]:
self._check_selector_method()
+ assert self.selector
csss = arg_to_iter(csss)
return flatten(self.selector.css(css).getall() for css in csss)
- def add_jmes(self, field_name, jmes, *processors, re=None, **kw):
+ def add_jmes(
+ self,
+ field_name: Optional[str],
+ jmes: str,
+ *processors: Callable[..., Any],
+ re: Union[str, Pattern[str], None] = None,
+ **kw: Any,
+ ) -> Self:
"""
Similar to :meth:`ItemLoader.add_value` but receives a JMESPath selector
instead of a value, which is used to extract a list of unicode strings
@@ -454,6 +580,9 @@
:param jmes: the JMESPath selector to extract data from
:type jmes: str
+ :returns: The current ItemLoader instance for method chaining.
+ :rtype: ItemLoader
+
Examples::
# HTML snippet: {"name": "Color TV"}
@@ -462,16 +591,32 @@
loader.add_jmes('price', TakeFirst(), re='the price is (.*)')
"""
values = self._get_jmesvalues(jmes)
- self.add_value(field_name, values, *processors, re=re, **kw)
+ return self.add_value(field_name, values, *processors, re=re, **kw)
- def replace_jmes(self, field_name, jmes, *processors, re=None, **kw):
+ def replace_jmes(
+ self,
+ field_name: Optional[str],
+ jmes: Union[str, Iterable[str]],
+ *processors: Callable[..., Any],
+ re: Union[str, Pattern[str], None] = None,
+ **kw: Any,
+ ) -> Self:
"""
Similar to :meth:`add_jmes` but replaces collected data instead of adding it.
+
+ :returns: The current ItemLoader instance for method chaining.
+ :rtype: ItemLoader
"""
values = self._get_jmesvalues(jmes)
- self.replace_value(field_name, values, *processors, re=re, **kw)
+ return self.replace_value(field_name, values, *processors, re=re, **kw)
- def get_jmes(self, jmes, *processors, re=None, **kw):
+ def get_jmes(
+ self,
+ jmes: Union[str, Iterable[str]],
+ *processors: Callable[..., Any],
+ re: Union[str, Pattern[str], None] = None,
+ **kw: Any,
+ ) -> Any:
"""
Similar to :meth:`ItemLoader.get_value` but receives a JMESPath selector
instead of a value, which is used to extract a list of unicode strings
@@ -494,8 +639,9 @@
values = self._get_jmesvalues(jmes)
return self.get_value(values, *processors, re=re, **kw)
- def _get_jmesvalues(self, jmess):
+ def _get_jmesvalues(self, jmess: Union[str, Iterable[str]]) -> List[Any]:
self._check_selector_method()
+ assert self.selector
jmess = arg_to_iter(jmess)
if not hasattr(self.selector, "jmespath"):
raise AttributeError(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/itemloaders-1.2.0/itemloaders/common.py new/itemloaders-1.3.0/itemloaders/common.py
--- old/itemloaders-1.2.0/itemloaders/common.py 2024-04-18 11:51:35.000000000 +0200
+++ new/itemloaders-1.3.0/itemloaders/common.py 2024-05-30 13:05:17.000000000 +0200
@@ -1,11 +1,14 @@
"""Common functions used in Item Loaders code"""
from functools import partial
+from typing import Any, Callable, MutableMapping
from itemloaders.utils import get_func_args
-def wrap_loader_context(function, context):
+def wrap_loader_context(
+ function: Callable[..., Any], context: MutableMapping[str, Any]
+) -> Callable[..., Any]:
"""Wrap functions that receive loader_context to contain the context
"pre-loaded" and expose a interface that receives only one argument
"""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/itemloaders-1.2.0/itemloaders/processors.py new/itemloaders-1.3.0/itemloaders/processors.py
--- old/itemloaders-1.2.0/itemloaders/processors.py 2024-04-18 11:51:35.000000000 +0200
+++ new/itemloaders-1.3.0/itemloaders/processors.py 2024-05-30 13:05:17.000000000 +0200
@@ -5,6 +5,7 @@
"""
from collections import ChainMap
+from typing import Any, Callable, Iterable, List, MutableMapping, Optional
from itemloaders.common import wrap_loader_context
from itemloaders.utils import arg_to_iter
@@ -54,19 +55,22 @@
.. _`parsel selectors`: https://parsel.readthedocs.io/en/latest/parsel.html#parsel.selector.Selecto…
""" # noqa
- def __init__(self, *functions, **default_loader_context):
+ def __init__(self, *functions: Callable[..., Any], **default_loader_context: Any):
self.functions = functions
self.default_loader_context = default_loader_context
- def __call__(self, value, loader_context=None):
+ def __call__(
+ self, value: Any, loader_context: Optional[MutableMapping[str, Any]] = None
+ ) -> Iterable[Any]:
values = arg_to_iter(value)
+ context: MutableMapping[str, Any]
if loader_context:
context = ChainMap(loader_context, self.default_loader_context)
else:
context = self.default_loader_context
wrapped_funcs = [wrap_loader_context(f, context) for f in self.functions]
for func in wrapped_funcs:
- next_values = []
+ next_values: List[Any] = []
for v in values:
try:
next_values += arg_to_iter(func(v))
@@ -109,12 +113,15 @@
<itemloaders.ItemLoader.context>` attribute.
"""
- def __init__(self, *functions, **default_loader_context):
+ def __init__(self, *functions: Callable[..., Any], **default_loader_context: Any):
self.functions = functions
self.stop_on_none = default_loader_context.get("stop_on_none", True)
self.default_loader_context = default_loader_context
- def __call__(self, value, loader_context=None):
+ def __call__(
+ self, value: Any, loader_context: Optional[MutableMapping[str, Any]] = None
+ ) -> Any:
+ context: MutableMapping[str, Any]
if loader_context:
context = ChainMap(loader_context, self.default_loader_context)
else:
@@ -148,7 +155,7 @@
'one'
"""
- def __call__(self, values):
+ def __call__(self, values: Any) -> Any:
for value in values:
if value is not None and value != "":
return value
@@ -168,7 +175,7 @@
['one', 'two', 'three']
"""
- def __call__(self, values):
+ def __call__(self, values: Any) -> Any:
return values
@@ -198,13 +205,15 @@
['bar']
"""
- def __init__(self, json_path):
- self.json_path = json_path
- import jmespath
+ def __init__(self, json_path: str):
+ self.json_path: str = json_path
+ import jmespath.parser
+
+ self.compiled_path: jmespath.parser.ParsedResult = jmespath.compile(
+ self.json_path
+ )
- self.compiled_path = jmespath.compile(self.json_path)
-
- def __call__(self, value):
+ def __call__(self, value: Any) -> Any:
"""Query value for the jmespath query and return answer
:param value: a data structure (dict, list) to extract from
:return: Element extracted according to jmespath query
@@ -231,8 +240,8 @@
'one<br>two<br>three'
"""
- def __init__(self, separator=" "):
+ def __init__(self, separator: str = " "):
self.separator = separator
- def __call__(self, values):
+ def __call__(self, values: Any) -> str:
return self.separator.join(values)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/itemloaders-1.2.0/itemloaders/utils.py new/itemloaders-1.3.0/itemloaders/utils.py
--- old/itemloaders-1.2.0/itemloaders/utils.py 2024-04-18 11:51:35.000000000 +0200
+++ new/itemloaders-1.3.0/itemloaders/utils.py 2024-05-30 13:05:17.000000000 +0200
@@ -5,10 +5,10 @@
import inspect
from functools import partial
-from typing import Generator
+from typing import Any, Callable, Generator, Iterable, List
-def arg_to_iter(arg):
+def arg_to_iter(arg: Any) -> Iterable[Any]:
"""Return an iterable based on *arg*.
If *arg* is a list, a tuple or a generator, it will be returned as is.
@@ -25,12 +25,12 @@
return [arg]
-def get_func_args(func, stripself=False):
+def get_func_args(func: Callable[..., Any], stripself: bool = False) -> List[str]:
"""Return the argument name list of a callable object"""
if not callable(func):
raise TypeError(f"func must be callable, got {type(func).__name__!r}")
- args = []
+ args: List[str] = []
try:
sig = inspect.signature(func)
except ValueError:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/itemloaders-1.2.0/setup.cfg new/itemloaders-1.3.0/setup.cfg
--- old/itemloaders-1.2.0/setup.cfg 2024-04-18 11:51:35.000000000 +0200
+++ new/itemloaders-1.3.0/setup.cfg 2024-05-30 13:05:17.000000000 +0200
@@ -1,8 +1,15 @@
[flake8]
-ignore = E266, E501, W503
+ignore = E266, E501, E704, W503
max-line-length = 100
select = B,C,E,F,W,T4,B9
exclude = .git,__pycache__,.venv
[isort]
profile = black
+
+[mypy]
+
+[mypy-tests.*]
+# Allow test functions to be untyped
+allow_untyped_defs = true
+check_untyped_defs = true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/itemloaders-1.2.0/setup.py new/itemloaders-1.3.0/setup.py
--- old/itemloaders-1.2.0/setup.py 2024-04-18 11:51:35.000000000 +0200
+++ new/itemloaders-1.3.0/setup.py 2024-05-30 13:05:17.000000000 +0200
@@ -5,7 +5,7 @@
setup(
name="itemloaders",
- version="1.2.0",
+ version="1.3.0",
url="https://github.com/scrapy/itemloaders",
project_urls={
"Documentation": "https://itemloaders.readthedocs.io/",
@@ -18,6 +18,9 @@
author_email="opensource(a)zyte.com",
license="BSD",
packages=find_packages(exclude=("tests", "tests.*")),
+ package_data={
+ "itemadapter": ["py.typed"],
+ },
include_package_data=True,
zip_safe=False,
classifiers=[
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/itemloaders-1.2.0/tests/test_base_loader.py new/itemloaders-1.3.0/tests/test_base_loader.py
--- old/itemloaders-1.2.0/tests/test_base_loader.py 2024-04-18 11:51:35.000000000 +0200
+++ new/itemloaders-1.3.0/tests/test_base_loader.py 2024-05-30 13:05:17.000000000 +0200
@@ -300,17 +300,17 @@
il.add_value("name", ["mar", "ta"])
self.assertEqual(il.get_output_value("name"), ["Mar", "Ta"])
- class TakeFirstItemLoader(CustomItemLoader):
+ class TakeFirstItemLoader1(CustomItemLoader):
name_out = Join()
- il = TakeFirstItemLoader()
+ il = TakeFirstItemLoader1()
il.add_value("name", ["mar", "ta"])
self.assertEqual(il.get_output_value("name"), "Mar Ta")
- class TakeFirstItemLoader(CustomItemLoader):
+ class TakeFirstItemLoader2(CustomItemLoader):
name_out = Join("<br>")
- il = TakeFirstItemLoader()
+ il = TakeFirstItemLoader2()
il.add_value("name", ["mar", "ta"])
self.assertEqual(il.get_output_value("name"), "Mar<br>Ta")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/itemloaders-1.2.0/tests/test_loader_initialization.py new/itemloaders-1.3.0/tests/test_loader_initialization.py
--- old/itemloaders-1.2.0/tests/test_loader_initialization.py 2024-04-18 11:51:35.000000000 +0200
+++ new/itemloaders-1.3.0/tests/test_loader_initialization.py 2024-05-30 13:05:17.000000000 +0200
@@ -1,12 +1,21 @@
import unittest
+from typing import Any, Protocol
from itemloaders import ItemLoader
+class InitializationTestProtocol(Protocol):
+ item_class: Any
+
+ def assertEqual(self, first: Any, second: Any, msg: Any = ...) -> None: ...
+
+ def assertIsInstance(self, obj: object, cls: type, msg: Any = None) -> None: ...
+
+
class InitializationTestMixin:
- item_class = None
+ item_class: Any = None
- def test_keep_single_value(self):
+ def test_keep_single_value(self: InitializationTestProtocol) -> None:
"""Loaded item should contain values from the initial item"""
input_item = self.item_class(name="foo")
il = ItemLoader(item=input_item)
@@ -14,7 +23,7 @@
self.assertIsInstance(loaded_item, self.item_class)
self.assertEqual(dict(loaded_item), {"name": ["foo"]})
- def test_keep_list(self):
+ def test_keep_list(self: InitializationTestProtocol) -> None:
"""Loaded item should contain values from the initial item"""
input_item = self.item_class(name=["foo", "bar"])
il = ItemLoader(item=input_item)
@@ -22,7 +31,9 @@
self.assertIsInstance(loaded_item, self.item_class)
self.assertEqual(dict(loaded_item), {"name": ["foo", "bar"]})
- def test_add_value_singlevalue_singlevalue(self):
+ def test_add_value_singlevalue_singlevalue(
+ self: InitializationTestProtocol,
+ ) -> None:
"""Values added after initialization should be appended"""
input_item = self.item_class(name="foo")
il = ItemLoader(item=input_item)
@@ -31,7 +42,7 @@
self.assertIsInstance(loaded_item, self.item_class)
self.assertEqual(dict(loaded_item), {"name": ["foo", "bar"]})
- def test_add_value_singlevalue_list(self):
+ def test_add_value_singlevalue_list(self: InitializationTestProtocol) -> None:
"""Values added after initialization should be appended"""
input_item = self.item_class(name="foo")
il = ItemLoader(item=input_item)
@@ -40,7 +51,7 @@
self.assertIsInstance(loaded_item, self.item_class)
self.assertEqual(dict(loaded_item), {"name": ["foo", "item", "loader"]})
- def test_add_value_list_singlevalue(self):
+ def test_add_value_list_singlevalue(self: InitializationTestProtocol) -> None:
"""Values added after initialization should be appended"""
input_item = self.item_class(name=["foo", "bar"])
il = ItemLoader(item=input_item)
@@ -49,7 +60,7 @@
self.assertIsInstance(loaded_item, self.item_class)
self.assertEqual(dict(loaded_item), {"name": ["foo", "bar", "qwerty"]})
- def test_add_value_list_list(self):
+ def test_add_value_list_list(self: InitializationTestProtocol) -> None:
"""Values added after initialization should be appended"""
input_item = self.item_class(name=["foo", "bar"])
il = ItemLoader(item=input_item)
@@ -58,7 +69,7 @@
self.assertIsInstance(loaded_item, self.item_class)
self.assertEqual(dict(loaded_item), {"name": ["foo", "bar", "item", "loader"]})
- def test_get_output_value_singlevalue(self):
+ def test_get_output_value_singlevalue(self: InitializationTestProtocol) -> None:
"""Getting output value must not remove value from item"""
input_item = self.item_class(name="foo")
il = ItemLoader(item=input_item)
@@ -67,7 +78,7 @@
self.assertIsInstance(loaded_item, self.item_class)
self.assertEqual(loaded_item, {"name": ["foo"]})
- def test_get_output_value_list(self):
+ def test_get_output_value_list(self: InitializationTestProtocol) -> None:
"""Getting output value must not remove value from item"""
input_item = self.item_class(name=["foo", "bar"])
il = ItemLoader(item=input_item)
@@ -76,13 +87,13 @@
self.assertIsInstance(loaded_item, self.item_class)
self.assertEqual(loaded_item, {"name": ["foo", "bar"]})
- def test_values_single(self):
+ def test_values_single(self: InitializationTestProtocol) -> None:
"""Values from initial item must be added to loader._values"""
input_item = self.item_class(name="foo")
il = ItemLoader(item=input_item)
self.assertEqual(il._values.get("name"), ["foo"])
- def test_values_list(self):
+ def test_values_list(self: InitializationTestProtocol) -> None:
"""Values from initial item must be added to loader._values"""
input_item = self.item_class(name=["foo", "bar"])
il = ItemLoader(item=input_item)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/itemloaders-1.2.0/tests/test_nested_items.py new/itemloaders-1.3.0/tests/test_nested_items.py
--- old/itemloaders-1.2.0/tests/test_nested_items.py 2024-04-18 11:51:35.000000000 +0200
+++ new/itemloaders-1.3.0/tests/test_nested_items.py 2024-05-30 13:05:17.000000000 +0200
@@ -1,4 +1,5 @@
import unittest
+from typing import Any
from itemloaders import ItemLoader
@@ -6,7 +7,7 @@
class NestedItemTest(unittest.TestCase):
"""Test that adding items as values works as expected."""
- def _test_item(self, item):
+ def _test_item(self, item: Any) -> None:
il = ItemLoader()
il.add_value("item_list", item)
self.assertEqual(il.load_item(), {"item_list": [item]})
@@ -44,7 +45,8 @@
except ImportError:
self.skipTest("Cannot import Field or Item from scrapy")
- class TestItem(Item):
+ # needs py.typed in Scrapy
+ class TestItem(Item): # type: ignore[misc]
foo = Field()
self._test_item(TestItem(foo="bar"))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/itemloaders-1.2.0/tests/test_nested_loader.py new/itemloaders-1.3.0/tests/test_nested_loader.py
--- old/itemloaders-1.2.0/tests/test_nested_loader.py 2024-04-18 11:51:35.000000000 +0200
+++ new/itemloaders-1.3.0/tests/test_nested_loader.py 2024-05-30 13:05:17.000000000 +0200
@@ -28,6 +28,7 @@
nl = loader.nested_xpath("//header")
nl.add_xpath("name", "div/text()")
nl.add_css("name_div", "#id")
+ assert nl.selector
nl.add_value("name_value", nl.selector.xpath('div[@id = "id"]/text()').getall())
self.assertEqual(loader.get_output_value("name"), ["marta"])
@@ -49,6 +50,7 @@
nl = loader.nested_css("header")
nl.add_xpath("name", "div/text()")
nl.add_css("name_div", "#id")
+ assert nl.selector
nl.add_value("name_value", nl.selector.xpath('div[@id = "id"]/text()').getall())
self.assertEqual(loader.get_output_value("name"), ["marta"])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/itemloaders-1.2.0/tests/test_output_processor.py new/itemloaders-1.3.0/tests/test_output_processor.py
--- old/itemloaders-1.2.0/tests/test_output_processor.py 2024-04-18 11:51:35.000000000 +0200
+++ new/itemloaders-1.3.0/tests/test_output_processor.py 2024-05-30 13:05:17.000000000 +0200
@@ -1,4 +1,5 @@
import unittest
+from typing import Any, Dict
from itemloaders import ItemLoader
from itemloaders.processors import Compose, Identity, TakeFirst
@@ -6,7 +7,7 @@
class TestOutputProcessorDict(unittest.TestCase):
def test_output_processor(self):
- class TempDict(dict):
+ class TempDict(Dict[str, Any]):
def __init__(self, *args, **kwargs):
super(TempDict, self).__init__(self, *args, **kwargs)
self.setdefault("temp", 0.3)
@@ -28,7 +29,7 @@
default_input_processor = Identity()
default_output_processor = Compose(TakeFirst())
- item = {}
+ item: Dict[str, Any] = {}
item.setdefault("temp", 0.3)
loader = TempLoader(item=item)
item = loader.load_item()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/itemloaders-1.2.0/tests/test_selector_loader.py new/itemloaders-1.3.0/tests/test_selector_loader.py
--- old/itemloaders-1.2.0/tests/test_selector_loader.py 2024-04-18 11:51:35.000000000 +0200
+++ new/itemloaders-1.3.0/tests/test_selector_loader.py 2024-05-30 13:05:17.000000000 +0200
@@ -273,3 +273,19 @@
self.assertEqual(loader.get_output_value("url"), ["http://www.scrapy.org"])
loader.replace_jmes("url", "website.url", re=r"http://www\.(.+)")
self.assertEqual(loader.get_output_value("url"), ["scrapy.org"])
+
+ def test_fluent_interface(self):
+ loader = ItemLoader(selector=self.selector)
+ item = (
+ loader.add_xpath("name", "//body/text()")
+ .replace_xpath("name", "//div/text()")
+ .add_css("description", "div::text")
+ .replace_css("description", "p::text")
+ .add_value("url", "http://example.com")
+ .replace_value("url", "http://foo")
+ .load_item()
+ )
+ self.assertEqual(
+ item,
+ {"name": ["marta"], "description": ["paragraph"], "url": ["http://foo"]},
+ )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/itemloaders-1.2.0/tests/test_utils_python.py new/itemloaders-1.3.0/tests/test_utils_python.py
--- old/itemloaders-1.2.0/tests/test_utils_python.py 2024-04-18 11:51:35.000000000 +0200
+++ new/itemloaders-1.3.0/tests/test_utils_python.py 2024-05-30 13:05:17.000000000 +0200
@@ -2,6 +2,7 @@
import operator
import platform
import unittest
+from typing import Any
from itemloaders.utils import get_func_args
@@ -18,7 +19,7 @@
pass
class A:
- def __init__(self, a, b, c):
+ def __init__(self, a: Any, b: Any, c: Any):
pass
def method(self, a, b, c):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/itemloaders-1.2.0/tox.ini new/itemloaders-1.3.0/tox.ini
--- old/itemloaders-1.2.0/tox.ini 2024-04-18 11:51:35.000000000 +0200
+++ new/itemloaders-1.3.0/tox.ini 2024-05-30 13:05:17.000000000 +0200
@@ -45,3 +45,12 @@
commands =
python -m build --sdist
twine check dist/*
+
+[testenv:typing]
+basepython = python3
+deps =
+ mypy==1.10.0
+ types-attrs==19.1.0
+ types-jmespath==1.0.2.20240106
+commands =
+ mypy --strict --ignore-missing-imports --implicit-reexport {posargs:itemloaders tests}
1
0
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-sushy for openSUSE:Factory checked in at 2024-06-05 17:42:12
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-sushy (Old)
and /work/SRC/openSUSE:Factory/.python-sushy.new.24587 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-sushy"
Wed Jun 5 17:42:12 2024 rev:17 rq:1178612 version:5.1.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-sushy/python-sushy.changes 2024-05-10 12:07:12.794016802 +0200
+++ /work/SRC/openSUSE:Factory/.python-sushy.new.24587/python-sushy.changes 2024-06-05 17:42:51.875120186 +0200
@@ -1,0 +2,12 @@
+Tue Jun 4 20:09:08 UTC 2024 - cloud-devel(a)suse.de
+
+- update to version 5.1.0
+ - Update master for stable/2024.1
+ - refectoring: Fix parameter and annotation mismatch
+ - reno: Update master for unmaintained/victoria
+ - reno: Update master for unmaintained/zed
+ - Handle NotAcceptable when Accept-Encoding: identity is not allowed
+ - reno: Update master for unmaintained/wallaby
+ - reno: Update master for unmaintained/xena
+
+-------------------------------------------------------------------
Old:
----
sushy-5.0.0.tar.gz
New:
----
sushy-5.1.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-sushy.spec ++++++
--- /var/tmp/diff_new_pack.uxDUPU/_old 2024-06-05 17:42:53.875193025 +0200
+++ /var/tmp/diff_new_pack.uxDUPU/_new 2024-06-05 17:42:53.887193461 +0200
@@ -17,13 +17,13 @@
Name: python-sushy
-Version: 5.0.0
+Version: 5.1.0
Release: 0
Summary: Python library to communicate with Redfish based systems
License: Apache-2.0
Group: Development/Languages/Python
URL: https://docs.openstack.org/sushy
-Source0: https://files.pythonhosted.org/packages/source/s/sushy/sushy-5.0.0.tar.gz
+Source0: https://files.pythonhosted.org/packages/source/s/sushy/sushy-5.1.0.tar.gz
BuildRequires: openstack-macros
BuildRequires: python3-oslotest
BuildRequires: python3-pbr >= 2.0.0
@@ -62,7 +62,7 @@
This package contains the documentation.
%prep
-%autosetup -p1 -n sushy-5.0.0
+%autosetup -p1 -n sushy-5.1.0
%py_req_cleanup
%build
++++++ sushy-5.0.0.tar.gz -> sushy-5.1.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.0.0/AUTHORS new/sushy-5.1.0/AUTHORS
--- old/sushy-5.0.0/AUTHORS 2024-02-22 16:01:13.000000000 +0100
+++ new/sushy-5.1.0/AUTHORS 2024-05-23 09:55:12.000000000 +0200
@@ -59,6 +59,7 @@
Varsha <varsha.verma.eee15(a)itbhu.ac.in>
Vu Cong Tuan <tuanvc(a)vn.fujitsu.com>
Winicius Silva <winiciusab12(a)gmail.com>
+Youngjun <yj.yoo(a)okestro.com>
Yusef Shaban <yshaban(a)godaddy.com>
ajya <mail(a)clusums.eu>
ankit <ankit.dhn31(a)gmail.com>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.0.0/ChangeLog new/sushy-5.1.0/ChangeLog
--- old/sushy-5.0.0/ChangeLog 2024-02-22 16:01:13.000000000 +0100
+++ new/sushy-5.1.0/ChangeLog 2024-05-23 09:55:12.000000000 +0200
@@ -1,6 +1,17 @@
CHANGES
=======
+5.1.0
+-----
+
+* reno: Update master for unmaintained/zed
+* Handle NotAcceptable when Accept-Encoding: identity is not allowed
+* reno: Update master for unmaintained/xena
+* reno: Update master for unmaintained/wallaby
+* reno: Update master for unmaintained/victoria
+* refectoring: Fix parameter and annotation mismatch
+* Update master for stable/2024.1
+
5.0.0
-----
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.0.0/PKG-INFO new/sushy-5.1.0/PKG-INFO
--- old/sushy-5.0.0/PKG-INFO 2024-02-22 16:01:13.680539100 +0100
+++ new/sushy-5.1.0/PKG-INFO 2024-05-23 09:55:13.139894000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.2
Name: sushy
-Version: 5.0.0
+Version: 5.1.0
Summary: Sushy is a small Python library to communicate with Redfish based systems
Home-page: https://docs.openstack.org/sushy/latest/
Author: OpenStack
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.0.0/releasenotes/notes/accept-encoding-4646ea43998f80bd.yaml new/sushy-5.1.0/releasenotes/notes/accept-encoding-4646ea43998f80bd.yaml
--- old/sushy-5.0.0/releasenotes/notes/accept-encoding-4646ea43998f80bd.yaml 1970-01-01 01:00:00.000000000 +0100
+++ new/sushy-5.1.0/releasenotes/notes/accept-encoding-4646ea43998f80bd.yaml 2024-05-23 09:54:08.000000000 +0200
@@ -0,0 +1,5 @@
+---
+fixes:
+ - |
+ Adds a work-around for cases where ``Accept-Encoding: identity`` is not
+ accepted.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.0.0/releasenotes/source/2024.1.rst new/sushy-5.1.0/releasenotes/source/2024.1.rst
--- old/sushy-5.0.0/releasenotes/source/2024.1.rst 1970-01-01 01:00:00.000000000 +0100
+++ new/sushy-5.1.0/releasenotes/source/2024.1.rst 2024-05-23 09:54:08.000000000 +0200
@@ -0,0 +1,6 @@
+===========================
+2024.1 Series Release Notes
+===========================
+
+.. release-notes::
+ :branch: stable/2024.1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.0.0/releasenotes/source/index.rst new/sushy-5.1.0/releasenotes/source/index.rst
--- old/sushy-5.0.0/releasenotes/source/index.rst 2024-02-22 16:00:44.000000000 +0100
+++ new/sushy-5.1.0/releasenotes/source/index.rst 2024-05-23 09:54:08.000000000 +0200
@@ -6,6 +6,7 @@
:maxdepth: 1
unreleased
+ 2024.1
2023.2
2023.1
zed
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.0.0/releasenotes/source/victoria.rst new/sushy-5.1.0/releasenotes/source/victoria.rst
--- old/sushy-5.0.0/releasenotes/source/victoria.rst 2024-02-22 16:00:44.000000000 +0100
+++ new/sushy-5.1.0/releasenotes/source/victoria.rst 2024-05-23 09:54:08.000000000 +0200
@@ -3,4 +3,4 @@
=============================================
.. release-notes::
- :branch: stable/victoria
+ :branch: unmaintained/victoria
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.0.0/releasenotes/source/wallaby.rst new/sushy-5.1.0/releasenotes/source/wallaby.rst
--- old/sushy-5.0.0/releasenotes/source/wallaby.rst 2024-02-22 16:00:44.000000000 +0100
+++ new/sushy-5.1.0/releasenotes/source/wallaby.rst 2024-05-23 09:54:08.000000000 +0200
@@ -3,4 +3,4 @@
============================================
.. release-notes::
- :branch: stable/wallaby
+ :branch: unmaintained/wallaby
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.0.0/releasenotes/source/xena.rst new/sushy-5.1.0/releasenotes/source/xena.rst
--- old/sushy-5.0.0/releasenotes/source/xena.rst 2024-02-22 16:00:44.000000000 +0100
+++ new/sushy-5.1.0/releasenotes/source/xena.rst 2024-05-23 09:54:08.000000000 +0200
@@ -3,4 +3,4 @@
==========================================
.. release-notes::
- :branch: stable/xena
+ :branch: unmaintained/xena
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.0.0/releasenotes/source/zed.rst new/sushy-5.1.0/releasenotes/source/zed.rst
--- old/sushy-5.0.0/releasenotes/source/zed.rst 2024-02-22 16:00:44.000000000 +0100
+++ new/sushy-5.1.0/releasenotes/source/zed.rst 2024-05-23 09:54:08.000000000 +0200
@@ -3,4 +3,4 @@
========================================
.. release-notes::
- :branch: stable/zed
+ :branch: unmaintained/zed
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.0.0/sushy/connector.py new/sushy-5.1.0/sushy/connector.py
--- old/sushy-5.0.0/sushy/connector.py 2024-02-22 16:00:44.000000000 +0100
+++ new/sushy-5.1.0/sushy/connector.py 2024-05-23 09:54:08.000000000 +0200
@@ -51,15 +51,6 @@
# By default, we ask HTTP server to shut down HTTP connection we've
# just used.
self._session.headers['Connection'] = 'close'
- # NOTE(TheJulia): Depending on the BMC, offering compression as an
- # acceptable response changes the ETag behavior to offering an
- # automatic "weak" ETag response, which is appropriate because the
- # body content *may* not be a byte for byte match given compression.
- # Overall, the value of compression is less than the value of concise
- # interaction with the BMC. Setting to identity basically means
- # "without modification or compression". By default, python-requests
- # indicates responses can be compressed.
- self._session.headers['Accept-Encoding'] = 'identity'
if username or password:
LOG.warning('Passing username and password to Connector is '
@@ -115,7 +106,8 @@
PUT, PATCH, etc...
:param path: The sub-URI or absolute URL path to the resource.
:param data: Optional JSON data.
- :param headers: Optional dictionary of headers.
+ :param headers: Optional dictionary of headers. Use None value
+ to remove a default header.
:param blocking: Whether to block for asynchronous operations.
:param timeout: Max time in seconds to wait for blocking async call or
for requests library to connect and read. If a custom
@@ -138,12 +130,25 @@
url = path if urlparse.urlparse(path).netloc else urlparse.urljoin(
self._url, path)
- headers = headers or {}
+ headers = (headers or {}).copy()
lc_headers = [k.lower() for k in headers]
if data is not None and 'content-type' not in lc_headers:
headers['Content-Type'] = 'application/json'
if 'odata-version' not in lc_headers:
headers['OData-Version'] = '4.0'
+ # NOTE(TheJulia): Depending on the BMC, offering compression as an
+ # acceptable response changes the ETag behavior to offering an
+ # automatic "weak" ETag response, which is appropriate because the
+ # body content *may* not be a byte for byte match given compression.
+ # Overall, the value of compression is less than the value of concise
+ # interaction with the BMC. Setting to identity basically means
+ # "without modification or compression". By default, python-requests
+ # indicates responses can be compressed.
+ if 'accept-encoding' not in lc_headers:
+ headers['Accept-Encoding'] = 'identity'
+ # Allow removing default headers
+ headers = {k: v for k, v in headers.items() if v is not None}
+
# TODO(lucasagomes): We should mask the data to remove sensitive
# information
LOG.debug('HTTP request: %(method)s %(url)s; headers: %(headers)s; '
@@ -264,6 +269,21 @@
return self._op(
method, path, data=data, headers=headers,
blocking=blocking, timeout=timeout,
+ server_side_retries_left=server_side_retries_left,
+ **extra_session_req_kwargs)
+ else:
+ raise
+ except exceptions.NotAcceptableError as e:
+ # NOTE(dtantsur): some HPE Gen 10 Plus machines do not allow
+ # identity encoding when fetching registries.
+ if (method.lower() == 'get'
+ and headers.get('Accept-Encoding') == 'identity'):
+ LOG.warning('Server has indicated a NotAcceptable for %s, '
+ 'retrying without identity encoding', e)
+ headers = dict(headers, **{'Accept-Encoding': None})
+ return self._op(
+ method, path, data=data, headers=headers,
+ blocking=blocking, timeout=timeout,
server_side_retries_left=server_side_retries_left,
**extra_session_req_kwargs)
else:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.0.0/sushy/exceptions.py new/sushy-5.1.0/sushy/exceptions.py
--- old/sushy-5.0.0/sushy/exceptions.py 2024-02-22 16:00:44.000000000 +0100
+++ new/sushy-5.1.0/sushy/exceptions.py 2024-05-23 09:54:08.000000000 +0200
@@ -160,6 +160,10 @@
pass
+class NotAcceptableError(HTTPError):
+ pass
+
+
class MissingXAuthToken(HTTPError):
message = ('No X-Auth-Token returned from remote host when '
'attempting to establish a session. Error: %(error)s')
@@ -176,6 +180,8 @@
elif response.status_code in (http_client.UNAUTHORIZED,
http_client.FORBIDDEN):
raise AccessError(method, url, response)
+ elif response.status_code == http_client.NOT_ACCEPTABLE:
+ raise NotAcceptableError(method, url, response)
elif response.status_code >= http_client.INTERNAL_SERVER_ERROR:
raise ServerSideError(method, url, response)
else:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.0.0/sushy/resources/registry/message_registry.py new/sushy-5.1.0/sushy/resources/registry/message_registry.py
--- old/sushy-5.0.0/sushy/resources/registry/message_registry.py 2024-02-22 16:00:44.000000000 +0100
+++ new/sushy-5.1.0/sushy/resources/registry/message_registry.py 2024-05-23 09:54:08.000000000 +0200
@@ -93,7 +93,7 @@
Check only registries that support messages.
- :param registries: dict of Message Registries
+ :param message_registries: dict of Message Registries
:param message_field: settings.MessageListField to parse
:returns: parsed settings.MessageListField with missing attributes filled
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.0.0/sushy/tests/unit/test_connector.py new/sushy-5.1.0/sushy/tests/unit/test_connector.py
--- old/sushy-5.0.0/sushy/tests/unit/test_connector.py 2024-02-22 16:00:44.000000000 +0100
+++ new/sushy-5.1.0/sushy/tests/unit/test_connector.py 2024-05-23 09:54:08.000000000 +0200
@@ -168,18 +168,25 @@
server_side_retries=10, server_side_retries_delay=3)
self.conn._auth = mock_auth
self.data = {'fake': 'data'}
- self.headers = {'X-Fake': 'header'}
+ self.headers = {'Accept-Encoding': 'identity', 'OData-Version': '4.0'}
self.session = mock.Mock(spec=requests.Session)
self.conn._session = self.session
self.request = self.session.request
self.request.return_value.status_code = http_client.OK
def test_ok_get(self):
- self.conn._op('GET', path='fake/path', headers=self.headers)
+ self.conn._op('GET', path='fake/path')
self.request.assert_called_once_with(
'GET', 'http://foo.bar:1234/fake/path',
headers=self.headers, json=None, verify=True, timeout=60)
+ def test_ok_get_with_headers(self):
+ self.conn._op('GET', path='fake/path', headers={'answer': '42'})
+ self.request.assert_called_once_with(
+ 'GET', 'http://foo.bar:1234/fake/path',
+ headers=dict(self.headers, answer='42'),
+ json=None, verify=True, timeout=60)
+
def test_response_callback(self):
mock_response_callback = mock.MagicMock()
self.conn._response_callback = mock_response_callback
@@ -188,34 +195,42 @@
self.assertEqual(1, mock_response_callback.call_count)
def test_ok_get_url_redirect_false(self):
- self.conn._op('GET', path='fake/path', headers=self.headers,
- allow_redirects=False)
+ self.conn._op('GET', path='fake/path', allow_redirects=False)
self.request.assert_called_once_with(
'GET', 'http://foo.bar:1234/fake/path',
headers=self.headers, json=None, allow_redirects=False,
verify=True, timeout=60)
def test_ok_post(self):
+ self.conn._op('POST', path='fake/path', data=self.data.copy())
+ self.request.assert_called_once_with(
+ 'POST', 'http://foo.bar:1234/fake/path',
+ json=self.data,
+ headers=dict(self.headers, **{'Content-Type': 'application/json'}),
+ verify=True, timeout=60)
+
+ def test_ok_post_with_headers(self):
self.conn._op('POST', path='fake/path', data=self.data.copy(),
- headers=self.headers)
+ headers={'answer': 42})
self.request.assert_called_once_with(
'POST', 'http://foo.bar:1234/fake/path',
- json=self.data, headers=self.headers, verify=True, timeout=60)
+ json=self.data,
+ headers=dict(self.headers, **{'Content-Type': 'application/json',
+ 'answer': 42}),
+ verify=True, timeout=60)
def test_ok_put(self):
- self.conn._op('PUT', path='fake/path', data=self.data.copy(),
- headers=self.headers)
+ self.conn._op('PUT', path='fake/path', data=self.data.copy())
self.request.assert_called_once_with(
'PUT', 'http://foo.bar:1234/fake/path',
- json=self.data, headers=self.headers, verify=True, timeout=60)
+ headers=dict(self.headers, **{'Content-Type': 'application/json'}),
+ json=self.data, verify=True, timeout=60)
def test_ok_delete(self):
- expected_headers = self.headers.copy()
- expected_headers['OData-Version'] = '4.0'
- self.conn._op('DELETE', path='fake/path', headers=self.headers.copy())
+ self.conn._op('DELETE', path='fake/path')
self.request.assert_called_once_with(
'DELETE', 'http://foo.bar:1234/fake/path',
- headers=expected_headers, json=None, verify=True, timeout=60)
+ headers=self.headers, json=None, verify=True, timeout=60)
def test_ok_post_with_session(self):
self.conn._session.headers = {}
@@ -242,22 +257,23 @@
'GET', 'http://foo.bar:1234' + path,
headers=expected_headers, json=None, verify=True, timeout=60)
- def test_odata_version_header_redfish_no_headers(self):
- path = '/redfish/v1/bar'
- expected_headers = {'OData-Version': '4.0'}
- self.conn._op('GET', path=path)
+ def test_odata_version_header_redfish_existing_header(self):
+ path = '/redfish/v1/foo'
+ headers = {'OData-Version': '3.0'}
+ expected_headers = dict(self.headers, **headers)
+ self.conn._op('GET', path=path, headers=headers)
self.request.assert_called_once_with(
'GET', 'http://foo.bar:1234' + path,
headers=expected_headers, json=None, verify=True, timeout=60)
- def test_odata_version_header_redfish_existing_header(self):
+ def test_remove_header_accept_encoding(self):
path = '/redfish/v1/foo'
- headers = {'OData-Version': '3.0'}
- expected_headers = dict(headers)
+ headers = {'Accept-Encoding': None}
+ self.headers.pop('Accept-Encoding')
self.conn._op('GET', path=path, headers=headers)
self.request.assert_called_once_with(
'GET', 'http://foo.bar:1234' + path,
- headers=expected_headers, json=None, verify=True, timeout=60)
+ headers=self.headers, json=None, verify=True, timeout=60)
def test_timed_out_session_unable_to_create_session(self):
self.conn._auth.can_refresh_session.return_value = False
@@ -522,6 +538,29 @@
self.assertEqual(0, mock_sleep.call_count)
self.assertEqual(1, self.request.call_count)
+ def test_op_retry_without_identity(self):
+ self.request.side_effect = [
+ mock.Mock(status_code=http_client.NOT_ACCEPTABLE),
+ mock.Mock(status_code=http_client.OK),
+ ]
+ self.conn._op('GET', 'http://foo.bar')
+
+ self.assertEqual(2, self.request.call_count)
+ headers_no_accept = self.headers.copy()
+ headers_no_accept.pop('Accept-Encoding')
+ self.request.assert_has_calls([
+ mock.call('GET', 'http://foo.bar', headers=self.headers,
+ json=None, verify=True, timeout=60),
+ mock.call('GET', 'http://foo.bar', headers=headers_no_accept,
+ json=None, verify=True, timeout=60),
+ ])
+
+ def test_op_retry_without_identity_fails(self):
+ self.request.return_value.status_code = http_client.NOT_ACCEPTABLE
+ self.assertRaises(exceptions.NotAcceptableError, self.conn._op,
+ 'GET', 'http://foo.bar')
+ self.assertEqual(2, self.request.call_count)
+
def test_access_error(self):
self.conn._auth = None
@@ -715,8 +754,7 @@
'/redfish/v1/Systems/1',
data={'Boot': {'BootSourceOverrideTarget': 'Cd',
'BootSourceOverrideEnabled': 'Once'}},
- headers={'X-Fake': 'header',
- 'If-Match': '"3d7b8a7360bf2941d"'},
+ headers=dict(self.headers, **{'If-Match': '"3d7b8a7360bf2941d"'}),
blocking=False,
timeout=60)
@@ -738,8 +776,8 @@
'/redfish/v1/Systems/1',
data={'Boot': {'BootSourceOverrideTarget': 'Cd',
'BootSourceOverrideEnabled': 'Once'}},
- headers={'X-Fake': 'header',
- 'If-Match': 'W/"3d7b8a7360bf2941d"'},
+ headers=dict(self.headers,
+ **{'If-Match': 'W/"3d7b8a7360bf2941d"'}),
blocking=False,
timeout=60)
@@ -759,7 +797,7 @@
'/redfish/v1/Systems/1',
data={'Boot': {'BootSourceOverrideTarget': 'Cd',
'BootSourceOverrideEnabled': 'Once'}},
- headers={'X-Fake': 'header'},
+ headers=self.headers,
blocking=False,
timeout=60)
@@ -787,8 +825,7 @@
'/redfish/v1/Systems/1',
data={'Boot': {'BootSourceOverrideTarget': 'Cd',
'BootSourceOverrideEnabled': 'Once'}},
- headers={'X-Fake': 'header',
- 'If-Match': '"3d7b8a7360bf2941d"'},
+ headers=dict(self.headers, **{'If-Match': '"3d7b8a7360bf2941d"'}),
blocking=False,
timeout=60)
@@ -818,7 +855,7 @@
'/redfish/v1/Systems/1',
data={'Boot': {'BootSourceOverrideTarget': 'Cd',
'BootSourceOverrideEnabled': 'Once'}},
- headers={'X-Fake': 'header'},
+ headers=self.headers,
blocking=False,
timeout=60)
@@ -846,7 +883,7 @@
'/redfish/v1/Systems/1',
data={'Boot': {'BootSourceOverrideTarget': 'Cd',
'BootSourceOverrideEnabled': 'Once'}},
- headers={'X-Fake': 'header'},
+ headers=self.headers,
blocking=False,
timeout=60)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.0.0/sushy.egg-info/PKG-INFO new/sushy-5.1.0/sushy.egg-info/PKG-INFO
--- old/sushy-5.0.0/sushy.egg-info/PKG-INFO 2024-02-22 16:01:13.000000000 +0100
+++ new/sushy-5.1.0/sushy.egg-info/PKG-INFO 2024-05-23 09:55:12.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.2
Name: sushy
-Version: 5.0.0
+Version: 5.1.0
Summary: Sushy is a small Python library to communicate with Redfish based systems
Home-page: https://docs.openstack.org/sushy/latest/
Author: OpenStack
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.0.0/sushy.egg-info/SOURCES.txt new/sushy-5.1.0/sushy.egg-info/SOURCES.txt
--- old/sushy-5.0.0/sushy.egg-info/SOURCES.txt 2024-02-22 16:01:13.000000000 +0100
+++ new/sushy-5.1.0/sushy.egg-info/SOURCES.txt 2024-05-23 09:55:13.000000000 +0200
@@ -21,6 +21,7 @@
doc/source/reference/index.rst
doc/source/reference/usage.rst
releasenotes/notes/.placeholder
+releasenotes/notes/accept-encoding-4646ea43998f80bd.yaml
releasenotes/notes/action-parameter-missing-7d234b96b5b1d81a.yaml
releasenotes/notes/add-apply-time-support-to-bios-315ebad429dcab3d.yaml
releasenotes/notes/add-bios-bf69ac56c4ae8f50.yaml
@@ -151,6 +152,7 @@
releasenotes/notes/workaround-sushy-requests-verify-handling-6879c273b651246f.yaml
releasenotes/source/2023.1.rst
releasenotes/source/2023.2.rst
+releasenotes/source/2024.1.rst
releasenotes/source/conf.py
releasenotes/source/index.rst
releasenotes/source/pike.rst
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.0.0/sushy.egg-info/pbr.json new/sushy-5.1.0/sushy.egg-info/pbr.json
--- old/sushy-5.0.0/sushy.egg-info/pbr.json 2024-02-22 16:01:13.000000000 +0100
+++ new/sushy-5.1.0/sushy.egg-info/pbr.json 2024-05-23 09:55:12.000000000 +0200
@@ -1 +1 @@
-{"git_version": "8929cce", "is_release": true}
\ No newline at end of file
+{"git_version": "0cec13b", "is_release": true}
\ No newline at end of file
1
0
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-swiftclient for openSUSE:Factory checked in at 2024-06-05 17:42:10
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-swiftclient (Old)
and /work/SRC/openSUSE:Factory/.python-swiftclient.new.24587 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-swiftclient"
Wed Jun 5 17:42:10 2024 rev:35 rq:1178611 version:4.6.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-swiftclient/python-swiftclient.changes 2024-01-15 22:19:28.383382146 +0100
+++ /work/SRC/openSUSE:Factory/.python-swiftclient.new.24587/python-swiftclient.changes 2024-06-05 17:42:48.134983980 +0200
@@ -1,0 +2,27 @@
+Tue Jun 4 20:08:29 UTC 2024 - cloud-devel(a)suse.de
+
+- update to version 4.6.0
+ - make setup dependencies discoverable
+ - tests: Fix call assertion
+ - Fix swiftclient output regression
+ - Add transaction id to errors
+ - reno: Update master for unmaintained/zed
+ - reno: Update master for unmaintained/victoria
+ - CI: constrain deps for tests
+ - Mark py312 job as voting and update classifiers
+ - Update master for stable/2023.2
+ - CI: skip func tests on irrelevant changes
+ - CI: add py39 and py310 to experimental pipeline
+ - Bring back (experimental) py38 job
+ - tests: Skip keystoneauth tests if not available
+ - Update master for stable/2024.1
+ - shell: Print friendly account byte quotas
+ - Authors / changelog for 4.5.0
+ - reno: Update master for unmaintained/yoga
+ - lint: Up-rev hacking
+ - CI: Fix py36 and py37 jobs
+ - Remove duplicate script entry leading to broken wheel build
+ - reno: Update master for unmaintained/xena
+ - reno: Update master for unmaintained/wallaby
+
+-------------------------------------------------------------------
Old:
----
python-swiftclient-4.4.0.tar.gz
New:
----
python-swiftclient-4.6.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-swiftclient.spec ++++++
--- /var/tmp/diff_new_pack.SzPt7N/_old 2024-06-05 17:42:50.543071676 +0200
+++ /var/tmp/diff_new_pack.SzPt7N/_new 2024-06-05 17:42:50.547071823 +0200
@@ -17,13 +17,13 @@
Name: python-swiftclient
-Version: 4.4.0
+Version: 4.6.0
Release: 0
Summary: OpenStack Object Storage API Client Library
License: Apache-2.0
Group: Development/Languages/Python
URL: https://docs.openstack.org/python-swiftclient
-Source0: https://files.pythonhosted.org/packages/source/p/python-swiftclient/python-…
+Source0: https://files.pythonhosted.org/packages/source/p/python-swiftclient/python-…
BuildRequires: openstack-macros
BuildRequires: python3-keystoneclient
BuildRequires: python3-pbr
@@ -37,7 +37,7 @@
%package -n python3-swiftclient
Summary: OpenStack Object Storage API Client Library
-Requires: python3-requests >= 1.1.0
+Requires: python3-requests >= 2.4.0
%if 0%{?suse_version}
Obsoletes: python2-swiftclient < 3.9.0
%endif
@@ -61,7 +61,7 @@
This package contains documentation files for %{name}.
%prep
-%autosetup -p1 -n python-swiftclient-4.4.0
+%autosetup -p1 -n python-swiftclient-4.6.0
%py_req_cleanup
%build
++++++ _service ++++++
--- /var/tmp/diff_new_pack.SzPt7N/_old 2024-06-05 17:42:50.591073424 +0200
+++ /var/tmp/diff_new_pack.SzPt7N/_new 2024-06-05 17:42:50.595073571 +0200
@@ -2,7 +2,7 @@
<service mode="manual" name="renderspec">
<param name="input-template">https://opendev.org/openstack/rpm-packaging/raw/master/openstack/python-swi…</param>
<param name="output-name">python-swiftclient.spec</param>
- <param name="requirements">https://opendev.org/openstack/python-swiftclient/raw/branch/stable/xena/req…</param>
+ <param name="requirements">https://opendev.org/openstack/python-swiftclient/raw/master/requirements.txt</param>
<param name="changelog-email">cloud-devel(a)suse.de</param>
<param name="changelog-provider">gh,openstack,python-swiftclient</param>
</service>
++++++ python-swiftclient-4.4.0.tar.gz -> python-swiftclient-4.6.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/.mailmap new/python-swiftclient-4.6.0/.mailmap
--- old/python-swiftclient-4.4.0/.mailmap 2023-09-01 15:38:49.000000000 +0200
+++ new/python-swiftclient-4.6.0/.mailmap 2024-05-23 10:01:23.000000000 +0200
@@ -97,3 +97,4 @@
Flavio Percoco <flaper87(a)gmail.com>
Timur Alperovich <timuralp(a)swiftstack.com> <timur(a)timuralp.com>
Thiago da Silva <thiagodasilva(a)gmail.com> <thiago(a)redhat.com>
+DavHau <hsngrmpf(a)gmail.com> <hsngrmpf+github(a)gmail.com>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/.zuul.yaml new/python-swiftclient-4.6.0/.zuul.yaml
--- old/python-swiftclient-4.4.0/.zuul.yaml 2023-09-01 15:38:49.000000000 +0200
+++ new/python-swiftclient-4.6.0/.zuul.yaml 2024-05-23 10:01:23.000000000 +0200
@@ -37,21 +37,33 @@
- publish-openstack-docs-pti
- release-notes-jobs-python3
experimental:
- # on-demand pipeline used to test older (but still supported) versions of python
+ # on-demand pipeline used to test older (but still supported) versions of python,
+ # as well as intermediate releases that the openstack-python3-jobs might skip
jobs:
- openstack-tox-py36
- openstack-tox-py37
+ - openstack-tox-py38
+ - openstack-tox-py310
check:
jobs:
- - swiftclient-swift-functional
- - swiftclient-functional
- - openstack-tox-py311:
+ - swiftclient-functional:
+ irrelevant-files: &functest-irrelevant-files
+ - ^(doc|releasenotes)/.*$
+ - ^test/unit/.*$
+ - ^(.gitreview|.mailmap|AUTHORS|ChangeLog|.*\.rst)$
+ - swiftclient-swift-functional:
+ irrelevant-files: *functest-irrelevant-files
+ - tempest-full-py3:
+ irrelevant-files: *functest-irrelevant-files
+ - openstack-tox-py311
+ - openstack-tox-py312:
voting: true
gate:
jobs:
- swiftclient-swift-functional
- swiftclient-functional
- - openstack-tox-py311:
+ - openstack-tox-py311
+ - openstack-tox-py312:
voting: true
post:
jobs:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/AUTHORS new/python-swiftclient-4.6.0/AUTHORS
--- old/python-swiftclient-4.4.0/AUTHORS 2023-09-01 15:38:49.000000000 +0200
+++ new/python-swiftclient-4.6.0/AUTHORS 2024-05-23 10:01:23.000000000 +0200
@@ -30,6 +30,7 @@
Dan Prince (dprince(a)redhat.com)
Daniel Wakefield (daniel.wakefield(a)hp.com)
Darrell Bishop (darrell(a)swiftstack.com)
+DavHau (hsngrmpf(a)gmail.com)
David Goetz (david.goetz(a)rackspace.com)
David Kranz (david.kranz(a)qrclab.com)
David Shrewsbury (shrewsbury.dave(a)gmail.com)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/ChangeLog new/python-swiftclient-4.6.0/ChangeLog
--- old/python-swiftclient-4.4.0/ChangeLog 2023-09-01 15:38:49.000000000 +0200
+++ new/python-swiftclient-4.6.0/ChangeLog 2024-05-23 10:01:23.000000000 +0200
@@ -1,3 +1,15 @@
+4.5.0
+-----
+
+* `swift stat --lh` now prints account quotas (including per-policy quotas)
+ in human-readable units, similar to account usage values.
+
+* Modernized some aspects of packaging, allowing wheels to be built with more
+ (and more recent) tools.
+
+* Various other minor bug fixes and improvements.
+
+
4.4.0
-----
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/PKG-INFO new/python-swiftclient-4.6.0/PKG-INFO
--- old/python-swiftclient-4.4.0/PKG-INFO 2023-09-01 15:39:15.668769100 +0200
+++ new/python-swiftclient-4.6.0/PKG-INFO 2024-05-23 10:01:55.497597500 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: python-swiftclient
-Version: 4.4.0
+Version: 4.6.0
Summary: OpenStack Object Storage API Client Library
Home-page: https://docs.openstack.org/python-swiftclient/latest/
Author: OpenStack
@@ -76,6 +76,7 @@
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3 :: Only
Requires-Python: >=3.6
Description-Content-Type: text/x-rst
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/pyproject.toml new/python-swiftclient-4.6.0/pyproject.toml
--- old/python-swiftclient-4.4.0/pyproject.toml 1970-01-01 01:00:00.000000000 +0100
+++ new/python-swiftclient-4.6.0/pyproject.toml 2024-05-23 10:01:23.000000000 +0200
@@ -0,0 +1,3 @@
+[build-system]
+requires = ["setuptools", "pbr"]
+build-backend = "setuptools.build_meta"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/python_swiftclient.egg-info/PKG-INFO new/python-swiftclient-4.6.0/python_swiftclient.egg-info/PKG-INFO
--- old/python-swiftclient-4.4.0/python_swiftclient.egg-info/PKG-INFO 2023-09-01 15:39:15.000000000 +0200
+++ new/python-swiftclient-4.6.0/python_swiftclient.egg-info/PKG-INFO 2024-05-23 10:01:55.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: python-swiftclient
-Version: 4.4.0
+Version: 4.6.0
Summary: OpenStack Object Storage API Client Library
Home-page: https://docs.openstack.org/python-swiftclient/latest/
Author: OpenStack
@@ -76,6 +76,7 @@
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3 :: Only
Requires-Python: >=3.6
Description-Content-Type: text/x-rst
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/python_swiftclient.egg-info/SOURCES.txt new/python-swiftclient-4.6.0/python_swiftclient.egg-info/SOURCES.txt
--- old/python-swiftclient-4.4.0/python_swiftclient.egg-info/SOURCES.txt 2023-09-01 15:39:15.000000000 +0200
+++ new/python-swiftclient-4.6.0/python_swiftclient.egg-info/SOURCES.txt 2024-05-23 10:01:55.000000000 +0200
@@ -11,6 +11,7 @@
LICENSE
MANIFEST.in
README.rst
+pyproject.toml
requirements.txt
run_tests.sh
setup.cfg
@@ -58,7 +59,10 @@
releasenotes/notes/3_9_0_release-3c293d277f14ec22.yaml
releasenotes/notes/4_3_0_release.yaml
releasenotes/notes/4_4_0_release-d731bab5982c160b.yaml
+releasenotes/notes/4_5_0_release-b315d25b889293f2.yaml
releasenotes/source/2023.1.rst
+releasenotes/source/2023.2.rst
+releasenotes/source/2024.1.rst
releasenotes/source/conf.py
releasenotes/source/current.rst
releasenotes/source/index.rst
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/python_swiftclient.egg-info/pbr.json new/python-swiftclient-4.6.0/python_swiftclient.egg-info/pbr.json
--- old/python-swiftclient-4.4.0/python_swiftclient.egg-info/pbr.json 2023-09-01 15:39:15.000000000 +0200
+++ new/python-swiftclient-4.6.0/python_swiftclient.egg-info/pbr.json 2024-05-23 10:01:55.000000000 +0200
@@ -1 +1 @@
-{"git_version": "54fbfa8", "is_release": true}
\ No newline at end of file
+{"git_version": "e7061db", "is_release": true}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/python_swiftclient.egg-info/requires.txt new/python-swiftclient-4.6.0/python_swiftclient.egg-info/requires.txt
--- old/python-swiftclient-4.4.0/python_swiftclient.egg-info/requires.txt 2023-09-01 15:39:15.000000000 +0200
+++ new/python-swiftclient-4.6.0/python_swiftclient.egg-info/requires.txt 2024-05-23 10:01:55.000000000 +0200
@@ -5,7 +5,8 @@
[test]
coverage!=4.4,>=4.0
-hacking<3.3.0,>=3.2.0
+hacking<6.2.0,>=3.2.0
keystoneauth1>=3.4.0
openstacksdk>=0.11.0
+python-keystoneclient>=0.7.0
stestr!=3.0.0,>=2.0.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/releasenotes/notes/4_5_0_release-b315d25b889293f2.yaml new/python-swiftclient-4.6.0/releasenotes/notes/4_5_0_release-b315d25b889293f2.yaml
--- old/python-swiftclient-4.4.0/releasenotes/notes/4_5_0_release-b315d25b889293f2.yaml 1970-01-01 01:00:00.000000000 +0100
+++ new/python-swiftclient-4.6.0/releasenotes/notes/4_5_0_release-b315d25b889293f2.yaml 2024-05-23 10:01:23.000000000 +0200
@@ -0,0 +1,12 @@
+---
+features:
+ - |
+ ``swift stat --lh`` now prints account quotas (including per-policy quotas)
+ in human-readable units, similar to account usage values.
+
+ - |
+ Modernized some aspects of packaging, allowing wheels to be built with more
+ (and more recent) tools.
+fixes:
+ - |
+ Various other minor bug fixes and improvements.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/releasenotes/source/2023.2.rst new/python-swiftclient-4.6.0/releasenotes/source/2023.2.rst
--- old/python-swiftclient-4.4.0/releasenotes/source/2023.2.rst 1970-01-01 01:00:00.000000000 +0100
+++ new/python-swiftclient-4.6.0/releasenotes/source/2023.2.rst 2024-05-23 10:01:23.000000000 +0200
@@ -0,0 +1,6 @@
+===========================
+2023.2 Series Release Notes
+===========================
+
+.. release-notes::
+ :branch: stable/2023.2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/releasenotes/source/2024.1.rst new/python-swiftclient-4.6.0/releasenotes/source/2024.1.rst
--- old/python-swiftclient-4.4.0/releasenotes/source/2024.1.rst 1970-01-01 01:00:00.000000000 +0100
+++ new/python-swiftclient-4.6.0/releasenotes/source/2024.1.rst 2024-05-23 10:01:23.000000000 +0200
@@ -0,0 +1,6 @@
+===========================
+2024.1 Series Release Notes
+===========================
+
+.. release-notes::
+ :branch: stable/2024.1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/releasenotes/source/index.rst new/python-swiftclient-4.6.0/releasenotes/source/index.rst
--- old/python-swiftclient-4.4.0/releasenotes/source/index.rst 2023-09-01 15:38:49.000000000 +0200
+++ new/python-swiftclient-4.6.0/releasenotes/source/index.rst 2024-05-23 10:01:23.000000000 +0200
@@ -6,6 +6,8 @@
:maxdepth: 1
current
+ 2024.1
+ 2023.2
2023.1
zed
yoga
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/releasenotes/source/victoria.rst new/python-swiftclient-4.6.0/releasenotes/source/victoria.rst
--- old/python-swiftclient-4.4.0/releasenotes/source/victoria.rst 2023-09-01 15:38:49.000000000 +0200
+++ new/python-swiftclient-4.6.0/releasenotes/source/victoria.rst 2024-05-23 10:01:23.000000000 +0200
@@ -3,4 +3,4 @@
=============================
.. release-notes::
- :branch: stable/victoria
+ :branch: unmaintained/victoria
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/releasenotes/source/wallaby.rst new/python-swiftclient-4.6.0/releasenotes/source/wallaby.rst
--- old/python-swiftclient-4.4.0/releasenotes/source/wallaby.rst 2023-09-01 15:38:49.000000000 +0200
+++ new/python-swiftclient-4.6.0/releasenotes/source/wallaby.rst 2024-05-23 10:01:23.000000000 +0200
@@ -3,4 +3,4 @@
============================
.. release-notes::
- :branch: stable/wallaby
+ :branch: unmaintained/wallaby
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/releasenotes/source/xena.rst new/python-swiftclient-4.6.0/releasenotes/source/xena.rst
--- old/python-swiftclient-4.4.0/releasenotes/source/xena.rst 2023-09-01 15:38:49.000000000 +0200
+++ new/python-swiftclient-4.6.0/releasenotes/source/xena.rst 2024-05-23 10:01:23.000000000 +0200
@@ -3,4 +3,4 @@
=========================
.. release-notes::
- :branch: stable/xena
+ :branch: unmaintained/xena
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/releasenotes/source/yoga.rst new/python-swiftclient-4.6.0/releasenotes/source/yoga.rst
--- old/python-swiftclient-4.4.0/releasenotes/source/yoga.rst 2023-09-01 15:38:49.000000000 +0200
+++ new/python-swiftclient-4.6.0/releasenotes/source/yoga.rst 2024-05-23 10:01:23.000000000 +0200
@@ -3,4 +3,4 @@
=========================
.. release-notes::
- :branch: stable/yoga
+ :branch: unmaintained/yoga
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/releasenotes/source/zed.rst new/python-swiftclient-4.6.0/releasenotes/source/zed.rst
--- old/python-swiftclient-4.4.0/releasenotes/source/zed.rst 2023-09-01 15:38:49.000000000 +0200
+++ new/python-swiftclient-4.6.0/releasenotes/source/zed.rst 2024-05-23 10:01:23.000000000 +0200
@@ -3,4 +3,4 @@
========================
.. release-notes::
- :branch: stable/zed
+ :branch: unmaintained/zed
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/setup.cfg new/python-swiftclient-4.6.0/setup.cfg
--- old/python-swiftclient-4.4.0/setup.cfg 2023-09-01 15:39:15.668769100 +0200
+++ new/python-swiftclient-4.6.0/setup.cfg 2024-05-23 10:01:55.497597500 +0200
@@ -29,13 +29,12 @@
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
+ Programming Language :: Python :: 3.12
Programming Language :: Python :: 3 :: Only
[files]
packages =
swiftclient
-scripts =
- bin/swift
data_files =
share/man/man1 = doc/manpages/swift.1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/swiftclient/client.py new/python-swiftclient-4.6.0/swiftclient/client.py
--- old/python-swiftclient-4.4.0/swiftclient/client.py 2023-09-01 15:38:49.000000000 +0200
+++ new/python-swiftclient-4.6.0/swiftclient/client.py 2024-05-23 10:01:23.000000000 +0200
@@ -19,10 +19,13 @@
import socket
import re
import logging
+from urllib3.exceptions import HTTPError as urllib_http_error
+
import warnings
from requests.exceptions import RequestException, SSLError
import http.client as http_client
+from requests.structures import CaseInsensitiveDict
from urllib.parse import quote, unquote
from urllib.parse import urljoin, urlparse, urlunparse
from time import sleep, time
@@ -209,6 +212,15 @@
return ret
+class LowerKeyCaseInsensitiveDict(CaseInsensitiveDict):
+ """
+ CaseInsensitiveDict returning lower case keys for items()
+ """
+
+ def __iter__(self):
+ return iter(self._store.keys())
+
+
class _ObjectBody:
"""
Readable and iterable object body response wrapper.
@@ -287,7 +299,7 @@
try:
buf = self.resp.read(length)
self.bytes_read += len(buf)
- except (socket.error, RequestException):
+ except (socket.error, urllib_http_error, RequestException):
if self.conn.attempts > self.conn.retries:
raise
if (not buf and self.bytes_read < self.expected_length and
@@ -735,9 +747,9 @@
def resp_header_dict(resp):
- resp_headers = {}
+ resp_headers = LowerKeyCaseInsensitiveDict()
for header, value in resp.getheaders():
- header = parse_header_string(header).lower()
+ header = parse_header_string(header)
resp_headers[header] = parse_header_string(value)
return resp_headers
@@ -1926,6 +1938,7 @@
is_not_range_request and resp_chunk_size and
self.attempts <= self.retries and
rheaders.get('transfer-encoding') is None)
+
if retry_is_possible:
body = _RetryBody(body.resp, self, container, obj,
resp_chunk_size=resp_chunk_size,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/swiftclient/command_helpers.py new/python-swiftclient-4.6.0/swiftclient/command_helpers.py
--- old/python-swiftclient-4.4.0/swiftclient/command_helpers.py 2023-09-01 15:38:49.000000000 +0200
+++ new/python-swiftclient-4.6.0/swiftclient/command_helpers.py 2024-05-23 10:01:23.000000000 +0200
@@ -15,6 +15,7 @@
POLICY_HEADER_PREFIX = 'x-account-storage-policy-'
+PER_POLICY_QUOTA_HEADER_PREFIX = 'x-account-quota-bytes-policy-'
def stat_account(conn, options):
@@ -38,6 +39,10 @@
('Objects', object_count),
('Bytes', bytes_used),
])
+ if headers.get('x-account-meta-quota-bytes'):
+ quota_bytes = prt_bytes(headers.get('x-account-meta-quota-bytes'),
+ options['human']).lstrip()
+ items.append(('Quota Bytes', quota_bytes))
policies = set()
for header_key, header_value in headers.items():
@@ -68,6 +73,10 @@
options['human']
).lstrip()),
))
+ policy_quota = headers.get(PER_POLICY_QUOTA_HEADER_PREFIX + policy)
+ if policy_quota:
+ items.append(('Quota Bytes for policy "' + policy + '"',
+ prt_bytes(policy_quota, options['human']).lstrip()))
return items, headers
@@ -75,7 +84,10 @@
def print_account_stats(items, headers, output_manager):
exclude_policy_headers = []
for header_key, header_value in headers.items():
- if header_key.lower().startswith(POLICY_HEADER_PREFIX):
+ if header_key.lower().startswith((
+ POLICY_HEADER_PREFIX,
+ PER_POLICY_QUOTA_HEADER_PREFIX,
+ )):
exclude_policy_headers.append(header_key)
items.extend(headers_to_items(
@@ -84,7 +96,8 @@
'content-length', 'date',
'x-account-container-count',
'x-account-object-count',
- 'x-account-bytes-used'] + exclude_policy_headers)))
+ 'x-account-bytes-used',
+ 'x-account-meta-quota-bytes'] + exclude_policy_headers)))
# line up the items nicely
offset = max(len(item) for item, value in items)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/swiftclient/multithreading.py new/python-swiftclient-4.6.0/swiftclient/multithreading.py
--- old/python-swiftclient-4.4.0/swiftclient/multithreading.py 2023-09-01 15:38:49.000000000 +0200
+++ new/python-swiftclient-4.6.0/swiftclient/multithreading.py 2024-05-23 10:01:23.000000000 +0200
@@ -89,6 +89,10 @@
msg = msg % fmt_args
self.error_print_pool.submit(self._print_error, msg)
+ def error_with_txn_id(self, swift_err):
+ self.error("{}\nFailed Transaction ID: {}".format(
+ swift_err.value, swift_err.transaction_id or 'unknown'))
+
def get_error_count(self):
return self.error_count
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/swiftclient/service.py new/python-swiftclient-4.6.0/swiftclient/service.py
--- old/python-swiftclient-4.4.0/swiftclient/service.py 2023-09-01 15:38:49.000000000 +0200
+++ new/python-swiftclient-4.6.0/swiftclient/service.py 2024-05-23 10:01:23.000000000 +0200
@@ -32,6 +32,9 @@
from threading import Thread
from queue import Queue
from queue import Empty as QueueEmpty
+from requests.exceptions import RequestException
+from socket import error as socket_error
+from urllib3.exceptions import HTTPError as urllib_http_error
from urllib.parse import quote
import json
@@ -68,12 +71,16 @@
class SwiftError(Exception):
def __init__(self, value, container=None, obj=None,
- segment=None, exc=None):
+ segment=None, exc=None, transaction_id=None):
self.value = value
self.container = container
self.obj = obj
self.segment = segment
self.exception = exc
+ if transaction_id is None:
+ self.transaction_id = getattr(exc, 'transaction_id', None)
+ else:
+ self.transaction_id = transaction_id
def __str__(self):
value = repr(self.value)
@@ -459,7 +466,9 @@
try:
self._content_length = int(headers.get('content-length'))
except ValueError:
- raise SwiftError('content-length header must be an integer')
+ raise SwiftError(
+ 'content-length header must be an integer',
+ transaction_id=self._txn_id)
def __iter__(self):
for chunk in self._body:
@@ -1306,9 +1315,15 @@
else:
pseudodir = True
- for chunk in obj_body:
- if fp is not None:
- fp.write(chunk)
+ try:
+ for chunk in obj_body:
+ if fp is not None:
+ fp.write(chunk)
+ except (socket_error,
+ urllib_http_error,
+ RequestException) as err:
+ raise ClientException(
+ str(err), http_response_headers=headers)
finish_time = time()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/swiftclient/shell.py new/python-swiftclient-4.6.0/swiftclient/shell.py
--- old/python-swiftclient-4.4.0/swiftclient/shell.py 2023-09-01 15:38:49.000000000 +0200
+++ new/python-swiftclient-4.6.0/swiftclient/shell.py 2024-05-23 10:01:23.000000000 +0200
@@ -227,7 +227,7 @@
output_manager.error('Error Deleting: {0}: {1}'
.format(p, r['error']))
except SwiftError as err:
- output_manager.error(err.value)
+ output_manager.error_with_txn_id(err)
st_download_options = '''[--all] [--marker <marker>] [--prefix <prefix>]
@@ -484,11 +484,13 @@
"Object '%s/%s' not found", container, obj)
continue
output_manager.error(
- "Error downloading object '%s/%s': %s",
- container, obj, error)
+ "Error downloading object '%s/%s': %s\n"
+ "Failed Transaction ID: %s",
+ container, obj, error,
+ getattr(error, 'transaction_id', 'unknown'))
except SwiftError as e:
- output_manager.error(e.value)
+ output_manager.error_with_txn_id(e)
except Exception as e:
output_manager.error(e)
@@ -670,7 +672,7 @@
prt_bytes(totals['bytes'], human))
except SwiftError as e:
- output_manager.error(e.value)
+ output_manager.error_with_txn_id(e)
st_stat_options = '''[--lh] [--header <header:value>]
@@ -754,21 +756,21 @@
items, headers, output_manager
)
else:
- raise(stat_result["error"])
+ raise stat_result["error"]
else:
output_manager.error(
'Usage: %s stat %s\n%s', BASENAME,
st_stat_options, st_stat_help)
except SwiftError as e:
- output_manager.error(e.value)
+ output_manager.error_with_txn_id(e)
st_post_options = '''[--read-acl <acl>] [--write-acl <acl>] [--sync-to <sync-to>]
[--sync-key <sync-key>] [--meta <name:value>]
[--header <header>]
[<container> [<object>]]
-'''
+''' # noqa
st_post_help = '''
Updates meta information for the account, container, or object.
@@ -864,10 +866,10 @@
else:
result = swift.post(container=container)
if not result["success"]:
- raise(result["error"])
+ raise result["error"]
except SwiftError as e:
- output_manager.error(e.value)
+ output_manager.error_with_txn_id(e)
st_copy_options = '''[--destination </container/object>] [--fresh-metadata]
@@ -972,7 +974,7 @@
return
except SwiftError as e:
- output_manager.error(e.value)
+ output_manager.error_with_txn_id(e)
st_upload_options = '''[--changed] [--skip-identical] [--segment-size <size>]
@@ -1270,7 +1272,7 @@
"to chunk the object")
except SwiftError as e:
- output_manager.error(e.value)
+ output_manager.error_with_txn_id(e)
st_capabilities_options = '''[--json] [<proxy_url>]
@@ -1332,7 +1334,7 @@
del capabilities['swift']
_print_compo_cap('Additional middleware', capabilities)
except SwiftError as e:
- output_manager.error(e.value)
+ output_manager.error_with_txn_id(e)
st_info = st_capabilities
@@ -1520,7 +1522,7 @@
Optional positional arguments:
<command> Swift client command to filter the flags by.
-'''.strip('\n')
+'''.strip('\n') # noqa
st_bash_completion_options = '''[command]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/test/unit/test_authv1.py new/python-swiftclient-4.6.0/test/unit/test_authv1.py
--- old/python-swiftclient-4.4.0/test/unit/test_authv1.py 2023-09-01 15:38:49.000000000 +0200
+++ new/python-swiftclient-4.6.0/test/unit/test_authv1.py 2024-05-23 10:01:23.000000000 +0200
@@ -16,10 +16,13 @@
import json
import unittest
from unittest import mock
-from keystoneauth1 import plugin
-from keystoneauth1 import loading
-from keystoneauth1 import exceptions
-from swiftclient import authv1
+try:
+ from keystoneauth1 import plugin
+ from keystoneauth1 import loading
+ from keystoneauth1 import exceptions
+ from swiftclient import authv1
+except ImportError:
+ plugin = loading = exceptions = authv1 = None
class TestDataNoAccount:
@@ -44,6 +47,10 @@
class TestPluginLoading(TestDataNoAccount, unittest.TestCase):
+ def setUp(self):
+ if authv1 is None:
+ raise unittest.SkipTest('keystoneauth1 is not available')
+
def test_can_load(self):
loader = loading.get_plugin_loader('v1password')
self.assertIsInstance(loader, authv1.PasswordLoader)
@@ -120,6 +127,8 @@
class TestPlugin(TestDataNoAccount, unittest.TestCase):
def setUp(self):
+ if authv1 is None:
+ raise unittest.SkipTest('keystoneauth1 is not available')
self.mock_session = mock.MagicMock()
self.mock_response = self.mock_session.get.return_value
self.mock_response.status_code = 200
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/test/unit/test_command_helpers.py new/python-swiftclient-4.6.0/test/unit/test_command_helpers.py
--- old/python-swiftclient-4.4.0/test/unit/test_command_helpers.py 2023-09-01 15:38:49.000000000 +0200
+++ new/python-swiftclient-4.6.0/test/unit/test_command_helpers.py 2024-05-23 10:01:23.000000000 +0200
@@ -18,6 +18,7 @@
from unittest import mock
from swiftclient import command_helpers as h
+from swiftclient.client import LowerKeyCaseInsensitiveDict
from swiftclient.multithreading import OutputManager
@@ -233,6 +234,33 @@
self.conn.head_object.return_value = stub_headers
args = ('c', 'o')
with self.output_manager as output_manager:
+ items, headers = h.stat_object(self.conn, self.options, *args)
+ h.print_object_stats(items, headers, output_manager)
+ expected = """
+ URL: http://storage/v1/a/c/o
+ Auth Token: tk12345
+ Account: a
+ Container: c
+ Object: o
+ Content Length: 1048576
+ ETag: 68b329da9893e34099c7d8ad5cb9c940
+ Meta Color: blue
+Content-Encoding: gzip
+"""
+ self.assertOut(expected)
+
+ def test_stat_object_case_insensitive_headers(self):
+ self.options['verbose'] += 1
+ # stub head object request
+ stub_headers = LowerKeyCaseInsensitiveDict({
+ 'content-length': 2 ** 20,
+ 'x-object-meta-color': 'blue',
+ 'ETag': '68b329da9893e34099c7d8ad5cb9c940',
+ 'content-encoding': 'gzip',
+ })
+ self.conn.head_object.return_value = stub_headers
+ args = ('c', 'o')
+ with self.output_manager as output_manager:
items, headers = h.stat_object(self.conn, self.options, *args)
h.print_object_stats(items, headers, output_manager)
expected = """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/test/unit/test_service.py new/python-swiftclient-4.6.0/test/unit/test_service.py
--- old/python-swiftclient-4.4.0/test/unit/test_service.py 2023-09-01 15:38:49.000000000 +0200
+++ new/python-swiftclient-4.6.0/test/unit/test_service.py 2024-05-23 10:01:23.000000000 +0200
@@ -31,7 +31,9 @@
import swiftclient
import swiftclient.utils as utils
-from swiftclient.client import Connection, ClientException
+from swiftclient.client import (
+ Connection, ClientException, LowerKeyCaseInsensitiveDict
+)
from swiftclient.service import (
SwiftService, SwiftError, SwiftUploadObject, SwiftDeleteObject
)
@@ -167,8 +169,10 @@
self.assertIsNone(sr._actual_md5)
# Check Contentlength raises error if it isn't an integer
- self.assertRaises(SwiftError, self.sr, 'path', 'body',
- {'content-length': 'notanint'})
+ with self.assertRaises(SwiftError) as cm:
+ self.sr('path', 'body', {'content-length': 'notanint'})
+ self.assertEqual("'content-length header must be an integer'",
+ str(cm.exception))
def test_iterator_usage(self):
def _consume(sr):
@@ -239,6 +243,26 @@
self.assertEqual(sr._actual_md5.hexdigest(),
md5('abc'.encode() * 3).hexdigest())
+ def test_swift_reader_knows_slo_etag_is_not_md5(self):
+ segment_bodies = [b'abc', b'def', b'ghi']
+ # slo etag is md5 of the sum of md5 of segments
+ slo_etag = md5(b''.join(
+ md5(b).hexdigest().encode()
+ for b in segment_bodies
+ )).hexdigest()
+ headers = LowerKeyCaseInsensitiveDict({
+ 'Content-Length': len(b''.join(segment_bodies)),
+ 'X-Static-Large-Object': 'true',
+ 'ETag': '"%s"' % slo_etag
+ })
+ sr = self.sr('path', segment_bodies, headers)
+ # x-static-large-object; so no exception is raised!
+ actual_md5 = md5(b''.join(sr)).hexdigest()
+ self.assertEqual(sr._actual_read, 9)
+ self.assertIsNone(sr._actual_md5)
+ self.assertEqual(actual_md5,
+ md5(b''.join(segment_bodies)).hexdigest())
+
class _TestServiceBase(unittest.TestCase):
def _get_mock_connection(self, attempts=2):
@@ -653,6 +677,7 @@
self.assertIsNone(se.exception)
self.assertEqual(str(se), '5')
+ self.assertNotIn(str(se), 'Transaction ID')
def test_swifterror_creation(self):
test_exc = Exception('test exc')
@@ -665,6 +690,25 @@
self.assertEqual(se.exception, test_exc)
self.assertEqual(str(se), '5 container:con object:obj segment:seg')
+ self.assertNotIn(str(se), 'Transaction ID')
+
+ def test_swifterror_clientexception_creation(self):
+ test_exc = ClientException(
+ Exception('test exc'),
+ http_response_headers=LowerKeyCaseInsensitiveDict({
+ 'x-trans-id': 'someTransId'})
+ )
+ se = SwiftError(5, 'con', 'obj', 'seg', test_exc)
+
+ self.assertEqual(se.value, 5)
+ self.assertEqual(se.container, 'con')
+ self.assertEqual(se.obj, 'obj')
+ self.assertEqual(se.segment, 'seg')
+ self.assertEqual(se.exception, test_exc)
+
+ self.assertEqual('someTransId', se.transaction_id)
+ self.assertNotIn('someTransId', str(se))
+ self.assertIn('5 container:con object:obj segment:seg', str(se))
class TestServiceUtils(unittest.TestCase):
@@ -1330,7 +1374,7 @@
options)
responses = [x for x in resp_iter]
for resp in responses:
- self.assertFalse('error' in resp)
+ self.assertNotIn('error', resp)
self.assertTrue(resp['success'])
self.assertEqual(5, len(responses))
container_resp, segment_container_resp = responses[0:2]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/test/unit/test_shell.py new/python-swiftclient-4.6.0/test/unit/test_shell.py
--- old/python-swiftclient-4.4.0/test/unit/test_shell.py 2023-09-01 15:38:49.000000000 +0200
+++ new/python-swiftclient-4.6.0/test/unit/test_shell.py 2024-05-23 10:01:23.000000000 +0200
@@ -15,6 +15,7 @@
import io
import contextlib
+import socket
from genericpath import getmtime
import getpass
import hashlib
@@ -26,8 +27,11 @@
from unittest import mock
import textwrap
from time import localtime, mktime, strftime, strptime
+from requests.exceptions import RequestException
+from urllib3.exceptions import HTTPError
import swiftclient
+from swiftclient.client import LowerKeyCaseInsensitiveDict
from swiftclient.service import SwiftError
import swiftclient.shell
import swiftclient.utils
@@ -160,6 +164,34 @@
' Bytes: 3\n')
@mock.patch('swiftclient.service.Connection')
+ def test_stat_account_with_quota(self, connection):
+ argv = ["", "stat", "--lh"]
+ return_headers = {
+ 'x-account-container-count': '2000',
+ 'x-account-object-count': '3000',
+ 'x-account-bytes-used': '4000000',
+ 'x-account-storage-policy-gold-bytes-used': '4000',
+ 'x-account-meta-quota-bytes': '5000000',
+ 'x-account-quota-bytes-policy-gold': '5000',
+ 'content-length': 0,
+ 'date': ''}
+ connection.return_value.head_account.return_value = return_headers
+ connection.return_value.url = 'http://127.0.0.1/v1/AUTH_account'
+ with CaptureOutput() as output:
+ swiftclient.shell.main(argv)
+
+ self.assertEqual(
+ output.out,
+ ' Account: AUTH_account\n'
+ ' Containers: 2000\n'
+ ' Objects: 2.9K\n'
+ ' Bytes: 3.8M\n'
+ ' Quota Bytes: 4.8M\n'
+ ' Objects in policy "gold": 0\n'
+ ' Bytes in policy "gold": 3.9K\n'
+ 'Quota Bytes for policy "gold": 4.9K\n')
+
+ @mock.patch('swiftclient.service.Connection')
def test_stat_account_with_headers(self, connection):
argv = ["", "stat", "-H", "Skip-Middleware: Test"]
return_headers = {
@@ -208,6 +240,28 @@
' Sync Key: secret\n')
@mock.patch('swiftclient.service.Connection')
+ def test_stat_container_not_found(self, connection):
+ connection.return_value.head_container.side_effect = \
+ swiftclient.ClientException(
+ 'test',
+ http_status=404,
+ http_response_headers=LowerKeyCaseInsensitiveDict({
+ 'x-trans-id': 'someTransId'})
+ )
+ argv = ["", "stat", "container"]
+
+ with CaptureOutput() as output:
+ with self.assertRaises(SystemExit):
+ swiftclient.shell.main(argv)
+ connection.return_value.head_container.assert_called_with(
+ 'container', headers={}, resp_chunk_size=65536,
+ response_dict={})
+
+ self.assertIn('Container \'container\' not found\n'
+ 'Failed Transaction ID: someTransId',
+ output.err)
+
+ @mock.patch('swiftclient.service.Connection')
def test_stat_container_with_headers(self, connection):
return_headers = {
'x-container-object-count': '1',
@@ -286,6 +340,27 @@
' Manifest: manifest\n')
@mock.patch('swiftclient.service.Connection')
+ def test_stat_object_not_found(self, connection):
+ connection.return_value.head_object.side_effect = \
+ swiftclient.ClientException(
+ 'test', http_status=404,
+ http_response_headers=LowerKeyCaseInsensitiveDict({
+ 'x-trans-id': 'someTransId'})
+ )
+ argv = ["", "stat", "container", "object"]
+
+ with CaptureOutput() as output:
+ with self.assertRaises(SystemExit):
+ swiftclient.shell.main(argv)
+ connection.return_value.head_object.assert_called_with(
+ 'container', 'object', headers={}, resp_chunk_size=65536,
+ response_dict={})
+
+ self.assertIn('test: 404\n'
+ 'Failed Transaction ID: someTransId',
+ output.err)
+
+ @mock.patch('swiftclient.service.Connection')
def test_stat_object_with_headers(self, connection):
return_headers = {
'x-object-manifest': 'manifest',
@@ -707,11 +782,122 @@
swiftclient.shell.main(argv)
self.assertEqual('objcontent', output.out)
+ def _do_test_download_clientexception(self, exc):
+ retry_calls = []
+
+ def _fake_retry(conn, *args, **kwargs):
+ retry_calls.append((args, kwargs))
+ conn.attempts += 1
+
+ body = mock.MagicMock()
+ body.resp.read.side_effect = RequestException('test_exc')
+ return (LowerKeyCaseInsensitiveDict({
+ 'content-type': 'text/plain',
+ 'etag': '2cbbfe139a744d6abbe695e17f3c1991',
+ 'x-trans-id': 'someTransId'}),
+ body)
+
+ argv = ["", "download", "container", "object", "--retries", "1"]
+ with CaptureOutput() as output:
+ with mock.patch(BUILTIN_OPEN) as mock_open:
+ with mock.patch("swiftclient.service.Connection._retry",
+ _fake_retry):
+ with self.assertRaises(SystemExit):
+ swiftclient.shell.main(argv)
+ mock_open.assert_called_with('object', 'wb', 65536)
+ self.assertEqual([
+ ((None, swiftclient.client.get_object, 'container', 'object'),
+ {'headers': {},
+ 'query_string': None,
+ 'resp_chunk_size': 65536,
+ 'response_dict': {}}),
+ ((None, swiftclient.client.get_object, 'container', 'object'),
+ {'attempts': 1,
+ 'headers': {'If-Match': mock.ANY, 'Range': 'bytes=0-'},
+ 'query_string': None,
+ 'resp_chunk_size': 65536,
+ 'response_dict': {}})],
+ retry_calls)
+ self.assertIn('Error downloading object \'container/object\': '
+ 'test_exc',
+ str(output.err))
+ self.assertIn('someTransId', str(output.err))
+
+ def test_download_request_exception(self):
+ self._do_test_download_clientexception(RequestException('text_exc'))
+
+ def test_download_socket_error(self):
+ self._do_test_download_clientexception(socket.error())
+
+ def test_download_http_error(self):
+ self._do_test_download_clientexception(HTTPError)
+
+ def test_download_request_exception_retries_0(self):
+ retry_calls = []
+
+ def _fake_retry(conn, *args, **kwargs):
+ retry_calls.append((args, kwargs))
+ conn.attempts += 1
+
+ body = mock.MagicMock()
+ body.__iter__.side_effect = RequestException('test_exc')
+ return (LowerKeyCaseInsensitiveDict({
+ 'content-type': 'text/plain',
+ 'etag': '2cbbfe139a744d6abbe695e17f3c1991',
+ 'x-trans-id': 'someTransId'}),
+ body)
+
+ argv = ["", "download", "container", "object", "--retries", "0"]
+ with CaptureOutput() as output:
+ with mock.patch(BUILTIN_OPEN) as mock_open:
+ with mock.patch("swiftclient.service.Connection._retry",
+ _fake_retry):
+ with self.assertRaises(SystemExit):
+ swiftclient.shell.main(argv)
+ mock_open.assert_called_with('object', 'wb', 65536)
+ self.assertEqual([
+ ((None, swiftclient.client.get_object, 'container', 'object'),
+ {'headers': {},
+ 'query_string': None,
+ 'resp_chunk_size': 65536,
+ 'response_dict': {}}), ],
+ retry_calls)
+ self.assertIn('Error downloading object \'container/object\': '
+ 'test_exc',
+ str(output.err))
+ self.assertIn('someTransId', str(output.err))
+
+ @mock.patch('swiftclient.service.Connection')
+ def test_download_bad_content_length(self, connection):
+ objcontent = io.BytesIO(b'objcontent')
+ connection.return_value.get_object.side_effect = [
+ (LowerKeyCaseInsensitiveDict({
+ 'content-type': 'text/plain',
+ 'content-length': 'BAD',
+ 'etag': '2cbbfe139a744d6abbe695e17f3c1991',
+ 'x-trans-id': 'someTransId'}),
+ objcontent)
+ ]
+ with CaptureOutput() as output:
+ with self.assertRaises(SystemExit):
+ with mock.patch(BUILTIN_OPEN) as mock_open:
+ argv = ["", "download", "container", "object"]
+ swiftclient.shell.main(argv)
+ connection.return_value.get_object.assert_called_with(
+ 'container', 'object', headers={}, resp_chunk_size=65536,
+ response_dict={})
+ mock_open.assert_called_with('object', 'wb', 65536)
+
+ self.assertIn("Error downloading object \'container/object\': "
+ "'content-length header must be an integer'"
+ "\nFailed Transaction ID: someTransId",
+ str(output.err))
+
@mock.patch('swiftclient.service.shuffle')
@mock.patch('swiftclient.service.Connection')
def test_download_shuffle(self, connection, mock_shuffle):
# Test that the container and object lists are shuffled
- mock_shuffle.side_effect = lambda l: l
+ mock_shuffle.side_effect = lambda to_shuffle: to_shuffle
connection.return_value.get_object.return_value = [
{'content-type': 'text/plain',
'etag': EMPTY_ETAG},
@@ -867,12 +1053,13 @@
fh.write(b'12345678901234567890')
swiftclient.shell.main(argv)
expected_calls = [mock.call('container',
- {'X-Storage-Policy': mock.ANY},
+ {'X-Storage-Policy': 'one'},
response_dict={}),
mock.call('container_segments',
- {'X-Storage-Policy': mock.ANY},
+ {'X-Storage-Policy': 'one'},
response_dict={})]
- connection.return_value.put_container.has_calls(expected_calls)
+ connection.return_value.put_container.assert_has_calls(expected_calls,
+ any_order=True)
connection.return_value.put_object.assert_called_with(
'container',
self.tmpfile.lstrip('/'),
@@ -1901,7 +2088,9 @@
with self.assertRaises(SystemExit):
swiftclient.shell.main(argv)
- self.assertEqual(output.err, 'Account not found\n')
+ self.assertEqual(
+ output.err,
+ 'Account not found\nFailed Transaction ID: unknown\n')
@mock.patch('swiftclient.service.Connection')
def test_post_container(self, connection):
@@ -2093,7 +2282,8 @@
self.assertEqual(
output.err,
'Combination of multiple objects and destination '
- 'including object is invalid\n')
+ 'including object is invalid\n'
+ 'Failed Transaction ID: unknown\n')
@mock.patch('swiftclient.service.Connection')
def test_copy_object_bad_auth(self, connection):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/test/unit/test_swiftclient.py new/python-swiftclient-4.6.0/test/unit/test_swiftclient.py
--- old/python-swiftclient-4.4.0/test/unit/test_swiftclient.py 2023-09-01 15:38:49.000000000 +0200
+++ new/python-swiftclient-4.6.0/test/unit/test_swiftclient.py 2024-05-23 10:01:23.000000000 +0200
@@ -579,7 +579,10 @@
self.assertTrue(token)
def test_auth_v3applicationcredential(self):
- from keystoneauth1 import exceptions as ksauthexceptions
+ try:
+ from keystoneauth1 import exceptions as ksauthexceptions
+ except ImportError:
+ raise unittest.SkipTest('keystoneauth1 is not available')
os_options = {
"auth_type": "v3applicationcredential",
@@ -1114,6 +1117,25 @@
self.assertEqual('t\xe9st', headers.get('x-utf-8-header', ''))
self.assertEqual('%ff', headers.get('x-non-utf-8-header', ''))
self.assertEqual('%FF', headers.get('x-binary-header', ''))
+ for k, v in headers.items():
+ # N.B. k is always lower case!
+ self.assertTrue(k.islower())
+ for k in headers.keys():
+ # N.B. k is always lower case!
+ self.assertTrue(k.islower())
+ self.assertTrue(set([
+ 'x-utf-8-header',
+ 'x-non-utf-8-header',
+ 'x-binary-header',
+ ]).intersection(headers))
+
+ self.assertEqual('t\xe9st', headers.get('X-Utf-8-Header', ''))
+ self.assertEqual('%ff', headers.get('X-Non-Utf-8-Header', ''))
+ self.assertEqual('%FF', headers.get('X-Binary-Header', ''))
+
+ self.assertEqual('t\xe9st', headers.get('X-UTF-8-HEADER', ''))
+ self.assertEqual('%ff', headers.get('X-NON-UTF-8-HEADER', ''))
+ self.assertEqual('%FF', headers.get('X-BINARY-HEADER', ''))
def test_chunk_size_read_method(self):
conn = c.Connection('http://auth.url/', 'some_user', 'some_key')
@@ -1997,7 +2019,7 @@
'authurl': 'http://www.test.com',
'tenant_name': 'atenant'}
conn = c.Connection(**args)
- self.assertEqual(type(conn), c.Connection)
+ self.assertIsInstance(conn, c.Connection)
def test_instance_kwargs_token(self):
args = {'preauthtoken': 'atoken123',
@@ -3053,7 +3075,7 @@
conn = c.Connection(url, 'asdf', 'asdf')
self.assertIsNone(conn.http_conn)
conn.http_conn = c.http_connection(url)
- self.assertEqual(type(conn.http_conn), tuple)
+ self.assertIsInstance(conn.http_conn, tuple)
self.assertEqual(len(conn.http_conn), 2)
http_conn_obj = conn.http_conn[1]
self.assertIsInstance(http_conn_obj, c.HTTPConnection)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/test-requirements.txt new/python-swiftclient-4.6.0/test-requirements.txt
--- old/python-swiftclient-4.4.0/test-requirements.txt 2023-09-01 15:38:49.000000000 +0200
+++ new/python-swiftclient-4.6.0/test-requirements.txt 2024-05-23 10:01:23.000000000 +0200
@@ -1,6 +1,7 @@
-hacking>=3.2.0,<3.3.0 # Apache-2.0
+hacking>=3.2.0,<6.2.0 # Apache-2.0
coverage!=4.4,>=4.0 # Apache-2.0
+python-keystoneclient>=0.7.0
keystoneauth1>=3.4.0 # Apache-2.0
stestr>=2.0.0,!=3.0.0 # Apache-2.0
openstacksdk>=0.11.0 # Apache-2.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-swiftclient-4.4.0/tox.ini new/python-swiftclient-4.6.0/tox.ini
--- old/python-swiftclient-4.4.0/tox.ini 2023-09-01 15:38:49.000000000 +0200
+++ new/python-swiftclient-4.6.0/tox.ini 2024-05-23 10:01:23.000000000 +0200
@@ -1,18 +1,18 @@
[tox]
envlist = py3,pep8
minversion = 3.18.0
-skipsdist = True
[testenv]
+skipsdist = True
usedevelop = True
list_dependencies_command = python -m pip freeze
setenv =
LANG=en_US.utf-8
VIRTUAL_ENV={envdir}
-deps = -r{toxinidir}/requirements.txt
+deps = -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
+ -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
- .[keystone]
commands = sh -c '(find . -not \( -type d -name .?\* -prune \) \
\( -type d -name "__pycache__" -or -type f -name "*.py[co]" \) \
-print0) | xargs -0 rm -rf'
@@ -24,6 +24,12 @@
commands =
python -m flake8 swiftclient test
+[testenv:{py36,py37}]
+# Drop the use of constraints; most dependencies have dropped support for
+# these versions already, and have updated their metadata to reflect that
+deps = -r{toxinidir}/requirements.txt
+ -r{toxinidir}/test-requirements.txt
+
[testenv:venv]
commands = {posargs}
@@ -69,7 +75,8 @@
# H404: multi line docstring should start without a leading new line
# H405: multi line docstring summary not separated with an empty line
# W504: line break after binary operator
-ignore = H101,H301,H306,H401,H403,H404,H405,W504
+# F811: Redefinition of unused name from line n
+ignore = H101,H301,H306,H401,H403,H404,H405,W504,F811
# H106: Don’t put vim configuration in source files
# H203: Use assertIs(Not)None to check for None
enable-extensions=H106,H203
@@ -87,8 +94,7 @@
[testenv:releasenotes]
usedevelop = False
-deps = -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
- -r{toxinidir}/doc/requirements.txt
+deps = {[testenv:docs]deps}
commands = sphinx-build -a -W -E -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html
[testenv:pdf-docs]
1
0
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-manilaclient for openSUSE:Factory checked in at 2024-06-05 17:42:08
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-manilaclient (Old)
and /work/SRC/openSUSE:Factory/.python-manilaclient.new.24587 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-manilaclient"
Wed Jun 5 17:42:08 2024 rev:25 rq:1178610 version:4.9.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-manilaclient/python-manilaclient.changes 2024-03-25 21:18:05.455214338 +0100
+++ /work/SRC/openSUSE:Factory/.python-manilaclient.new.24587/python-manilaclient.changes 2024-06-05 17:42:46.270916096 +0200
@@ -1,0 +2,15 @@
+Tue Jun 4 20:07:23 UTC 2024 - cloud-devel(a)suse.de
+
+- update to version 4.9.0
+ - Update master for stable/2024.1
+ - [OSC] Fix output format for osc share subnet create
+ - reno: Update master for unmaintained/xena
+ - Human readable export location CLI changes
+ - Add new-note tox environment
+ - "--wait" option added for snapshot create/revert/delete commands
+ - "--wait" option added for managing/unmanaging a share snapshot
+ - adds bandit testing and Zuul CI job.
+ - reno: Update master for unmaintained/wallaby
+ - Remove --nova-net-id option
+
+-------------------------------------------------------------------
Old:
----
python-manilaclient-4.8.0.tar.gz
New:
----
python-manilaclient-4.9.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-manilaclient.spec ++++++
--- /var/tmp/diff_new_pack.Xjl5jA/_old 2024-06-05 17:42:46.962941297 +0200
+++ /var/tmp/diff_new_pack.Xjl5jA/_new 2024-06-05 17:42:46.962941297 +0200
@@ -17,13 +17,13 @@
Name: python-manilaclient
-Version: 4.8.0
+Version: 4.9.0
Release: 0
Summary: Client Library for OpenStack Share API
License: Apache-2.0
Group: Development/Languages/Python
URL: https://docs.openstack.org/python-manilaclient
-Source0: https://files.pythonhosted.org/packages/source/p/python-manilaclient/python…
+Source0: https://files.pythonhosted.org/packages/source/p/python-manilaclient/python…
BuildRequires: openstack-macros
BuildRequires: python3-ddt
BuildRequires: python3-fixtures
@@ -31,7 +31,7 @@
BuildRequires: python3-osc-lib >= 1.10.0
BuildRequires: python3-oslo.config >= 5.2.0
BuildRequires: python3-oslo.log >= 3.36.0
-BuildRequires: python3-oslo.serialization >= 2.18.0
+BuildRequires: python3-oslo.serialization >= 2.20.0
BuildRequires: python3-oslo.utils >= 3.33.0
BuildRequires: python3-stestr
BuildRequires: python3-testrepository
@@ -44,14 +44,14 @@
%package -n python3-manilaclient
Summary: Client Library for OpenStack Share API
-Requires: python3-Babel >= 2.3.4
+Requires: python3-Babel >= 2.5.0
Requires: python3-PrettyTable >= 0.7.1
Requires: python3-debtcollector >= 1.2.0
Requires: python3-keystoneclient >= 3.8.0
Requires: python3-osc-lib >= 1.10.0
Requires: python3-oslo.config >= 5.2.0
Requires: python3-oslo.log >= 3.36.0
-Requires: python3-oslo.serialization >= 2.18.0
+Requires: python3-oslo.serialization >= 2.20.0
Requires: python3-oslo.utils >= 3.33.0
Requires: python3-requests >= 2.14.2
Requires: python3-simplejson >= 3.5.1
@@ -76,13 +76,13 @@
This package contains auto-generated documentation.
%prep
-%autosetup -p1 -n python-manilaclient-4.8.0
+%autosetup -p1 -n python-manilaclient-4.9.0
%py_req_cleanup
%build
%{py3_build}
-PBR_VERSION=4.8.0 %sphinx_build -b html doc/source doc/build/html
+PBR_VERSION=4.9.0 %sphinx_build -b html doc/source doc/build/html
# remove the sphinx-build leftovers
rm -rf doc/build/html/.{doctrees,buildinfo}
++++++ python-manilaclient-4.8.0.tar.gz -> python-manilaclient-4.9.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/AUTHORS new/python-manilaclient-4.9.0/AUTHORS
--- old/python-manilaclient-4.8.0/AUTHORS 2024-03-01 10:55:55.000000000 +0100
+++ new/python-manilaclient-4.9.0/AUTHORS 2024-05-16 15:02:55.000000000 +0200
@@ -22,6 +22,7 @@
Chris MacNaughton <chris.macnaughton(a)canonical.com>
Christian Berendt <berendt(a)b1-systems.de>
Chuck Fouts <fchuck(a)netapp.com>
+Clifford Emeka <emclidon(a)gmail.com>
Clinton Knight <cknight(a)netapp.com>
Cloud User <stack(a)devstack-maari.novalocal>
Corey Bryant <corey.bryant(a)canonical.com>
@@ -118,6 +119,7 @@
Yulia Portnova <yportnova(a)mirantis.com>
altanai <tara181989(a)gmail.com>
andrebeltrami <andreluizbeltrami(a)hotmail.com>
+annwesha.das <annwesha.das(a)ndsu.edu>
archanaserver <ak31960466(a)gmail.com>
ashrod98 <ashrod98(a)gmail.com>
binean <ting.wang(a)easystack.cn>
@@ -143,6 +145,7 @@
howardlee <lihongweibj(a)inspur.com>
iswarya_vakati <v.iswarya(a)nectechnologies.in>
jacky06 <zhang.min(a)99cloud.net>
+jayaanand.borra(a)netapp.com <jayaanand.borra(a)netapp.com>
ji-xuepeng <ji.xuepeng(a)zte.com.cn>
junboli <junbo85.li(a)gmail.com>
kafilat-adeleke <adelekekafilatadenike(a)gmail.com>
@@ -159,6 +162,7 @@
luke.li <lilu7189(a)fiberhome.com>
maaoyu <maaoyu(a)inspur.com>
mark.sturdevant <mark.sturdevant(a)hpe.com>
+melakualehegn <melakualehegn34(a)gmail.com>
melissaml <ma.lei(a)99cloud.net>
namrata <namrata.sitlani(a)citynetwork.eu>
nidhimittalhada <nidhimittal19(a)gmail.com>
@@ -175,6 +179,7 @@
sunjia <sunjia(a)inspur.com>
ting.wang <ting.wang(a)easystack.cn>
tpsilva <tiago.pasqualini(a)gmail.com>
+tspyderboy <tspyderboy(a)gmail.com>
venkatamahesh <venkatamaheshkotha(a)gmail.com>
vik <vik(a)ubuntu.(none)>
vkmc <victoria(a)redhat.com>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/ChangeLog new/python-manilaclient-4.9.0/ChangeLog
--- old/python-manilaclient-4.8.0/ChangeLog 2024-03-01 10:55:55.000000000 +0100
+++ new/python-manilaclient-4.9.0/ChangeLog 2024-05-16 15:02:55.000000000 +0200
@@ -1,9 +1,22 @@
CHANGES
=======
+4.9.0
+-----
+
+* adds bandit testing and Zuul CI job
+* Remove --nova-net-id option
+* "--wait" option added for snapshot create/revert/delete commands
+* "--wait" option added for managing/unmanaging a share snapshot
+* Human readable export location CLI changes
+* Update master for stable/2024.1
+* reno: Update master for unmaintained/xena
+* reno: Update master for unmaintained/wallaby
+
4.8.0
-----
+* Add new-note tox environment
* CLI for disable service reason
* reno: Update master for unmaintained/yoga
* Fix share force delete case
@@ -42,6 +55,7 @@
-----
* Metadata for Share Network Subnets
+* [OSC] Fix output format for osc share subnet create
* Use suitable api version for OSC
* Fix share network create command with the AZ option
* Add defaultadsite to security service
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/PKG-INFO new/python-manilaclient-4.9.0/PKG-INFO
--- old/python-manilaclient-4.8.0/PKG-INFO 2024-03-01 10:55:55.633288000 +0100
+++ new/python-manilaclient-4.9.0/PKG-INFO 2024-05-16 15:02:55.670791100 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.2
Name: python-manilaclient
-Version: 4.8.0
+Version: 4.9.0
Summary: Client library for OpenStack Manila API.
Home-page: https://docs.openstack.org/python-manilaclient/latest/
Author: OpenStack
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/doc/source/contributor/adding_release_notes.rst new/python-manilaclient-4.9.0/doc/source/contributor/adding_release_notes.rst
--- old/python-manilaclient-4.8.0/doc/source/contributor/adding_release_notes.rst 1970-01-01 01:00:00.000000000 +0100
+++ new/python-manilaclient-4.9.0/doc/source/contributor/adding_release_notes.rst 2024-05-16 15:02:24.000000000 +0200
@@ -0,0 +1,160 @@
+.. _adding_release_notes:
+
+Release Notes
+=============
+
+What are release notes?
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Release notes are important for change management within manila. Since manila
+follows a release cycle with milestones, release notes provide a way for the
+community and users to quickly grasp what changes occurred within a development
+milestone. To the OpenStack release management and documentation teams,
+release notes are a way to compile changes per milestone. These notes are
+published on the `OpenStack Releases website <http://releases.openstack.org>`_.
+Automated tooling is built around ``releasenotes`` and they get appropriately
+handled per release milestone, including any back-ports to stable releases.
+
+What needs a release note?
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+* Changes that impact an upgrade, most importantly, those that require a
+ deployer to take some action while upgrading
+
+* A new feature is implemented
+* An existing feature is deprecated
+* An existing feature is removed
+* Behavior of an existing feature has changed in a discernible way to an end
+ user or administrator
+* A security bug is fixed
+* New configuration option is added
+
+What does not need a release note?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+* A code change that doesn't change the general behavior of any
+ feature such as code refactor or logging changes. One case of this could be
+ the removal of the python 2.x compatibility layer, i.e., the "six" library
+ from code.
+* Functional or unit test coverage enhancement
+* Any change submitted with a justified TrivialFix flag added in the commit
+ message
+* Adding or changing documentation within in-tree documentation guides
+
+How do I add a release note?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We use `Reno <https://docs.openstack.org/reno/latest/>`_ to create and manage
+release notes. The new subcommand combines a random suffix with a "slug" value
+to make the new file with a unique name that is easy to identify again later.
+To create a release note for your change, use:
+
+.. code-block:: console
+
+ $ reno new slug-goes-here
+
+If reno is not installed globally on your system, you can use a tox
+environment in manila:
+
+.. code-block:: console
+
+ $ tox -e newnote -- slug-goes-here
+
+.. note::
+
+ When you are adding a bug-fix reno, name your file using the template:
+ "bug-<launchpad-bug-id>-slug-goes-here".
+
+Then add the notes in ``yaml`` format in the file created. Pay attention to the
+type of section. The following are general sections to use:
+
+prelude
+
+ General comments about the change. The prelude from all notes in a
+ release are combined, in note order, to produce a single prelude
+ introducing the release.
+
+features
+
+ New features introduced
+
+issues
+
+ A list of known issues with respect to the change being introduced. For
+ example, if the new feature in the change is experimental or known to not
+ work in some cases, it should be mentioned here.
+
+upgrade
+
+ A list of upgrade notes in the release. Any removals that affect upgrades are
+ to be noted here.
+
+deprecations
+
+ Any features, APIs, configuration options that the change has deprecated.
+ Deprecations are not removals. Deprecations suggest that there will be
+ support for a certain timeline. Deprecation should allow time for users
+ to make necessary changes for the removal to happen in a future release.
+ It is important to note the timeline of deprecation in this section.
+
+critical
+
+ A list of *fixed* critical bugs (descriptions only).
+
+security
+
+ A list of *fixed* security issues (descriptions only).
+
+fixes
+
+ A list of other *fixed* bugs (descriptions only).
+
+other
+
+ Other notes that are important but do not fall into any of the given
+ categories.
+
+::
+
+ ---
+ prelude: >
+ Replace this text with content to appear at the
+ top of the section for this change.
+ features:
+ - List new features here, or remove this section.
+ issues:
+ - List known issues here, or remove this section.
+ upgrade:
+ - List upgrade notes here, or remove this section.
+ deprecations:
+ - List deprecation notes here, or remove this section
+ critical:
+ - Add critical notes here, or remove this section.
+ security:
+ - Add security notes here, or remove this section.
+ fixes:
+ - Add normal bug fixes here, or remove this section.
+ other:
+ - Add other notes here, or remove this section.
+
+
+Dos and Don'ts
+~~~~~~~~~~~~~~
+* Release notes need to be succinct. Short and unambiguous descriptions are
+ preferred
+* Write in past tense, unless you are writing an imperative statement
+* Do not have blank sections in the file
+* Do not include code or links
+* Avoid special rst formatting unless absolutely necessary
+* Always prefer including a release note in the same patch
+* Release notes are not a replacement for developer/user/admin documentation
+* Release notes are not a way of conveying behavior of any features or usage of
+ any APIs
+* Limit a release note to fewer than 2-3 lines per change per section
+* OpenStack prefers atomic changes. So remember that your change may need the
+ fewest sections possible
+* General writing guidelines can be found
+ `here <https://docs.openstack
+ .org/doc-contrib-guide/writing-style/general-writing-guidelines.html>`_
+* Proofread your note. Pretend you are a user or a deployer who is reading
+ the note after a milestone or a release has been cut
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/doc/source/contributor/index.rst new/python-manilaclient-4.9.0/doc/source/contributor/index.rst
--- old/python-manilaclient-4.8.0/doc/source/contributor/index.rst 2024-03-01 10:55:26.000000000 +0100
+++ new/python-manilaclient-4.9.0/doc/source/contributor/index.rst 2024-05-16 15:02:24.000000000 +0200
@@ -9,6 +9,13 @@
contributing
+Programming HowTos and Tutorials
+--------------------------------
+.. toctree::
+ :maxdepth: 3
+
+ adding_release_notes
+
Testing
-------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/manilaclient/api_versions.py new/python-manilaclient-4.9.0/manilaclient/api_versions.py
--- old/python-manilaclient-4.8.0/manilaclient/api_versions.py 2024-03-01 10:55:26.000000000 +0100
+++ new/python-manilaclient-4.9.0/manilaclient/api_versions.py 2024-05-16 15:02:24.000000000 +0200
@@ -27,7 +27,7 @@
LOG = logging.getLogger(__name__)
-MAX_VERSION = '2.83'
+MAX_VERSION = '2.84'
MIN_VERSION = '2.0'
DEPRECATED_VERSION = '1.0'
_VERSIONED_METHOD_MAP = {}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/manilaclient/base.py new/python-manilaclient-4.9.0/manilaclient/base.py
--- old/python-manilaclient-4.8.0/manilaclient/base.py 2024-03-01 10:55:26.000000000 +0100
+++ new/python-manilaclient-4.9.0/manilaclient/base.py 2024-05-16 15:02:24.000000000 +0200
@@ -129,8 +129,8 @@
# pair
username = cliutils.env('OS_USERNAME', 'MANILA_USERNAME')
url = cliutils.env('OS_URL', 'MANILA_URL')
- uniqifier = hashlib.sha1(username.encode('utf-8') +
- url.encode('utf-8')).hexdigest()
+ uniqifier = hashlib.sha256(username.encode('utf-8') +
+ url.encode('utf-8')).hexdigest()
cache_dir = os.path.expanduser(os.path.join(base_dir, uniqifier))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/manilaclient/osc/v2/share.py new/python-manilaclient-4.9.0/manilaclient/osc/v2/share.py
--- old/python-manilaclient-4.8.0/manilaclient/osc/v2/share.py 2024-03-01 10:55:26.000000000 +0100
+++ new/python-manilaclient-4.9.0/manilaclient/osc/v2/share.py 2024-05-16 15:02:24.000000000 +0200
@@ -188,6 +188,13 @@
"possible keys are same_host, different_host."
"(repeat option to set multiple hints)"),
)
+ parser.add_argument(
+ '--mount-point-name',
+ metavar="<mount_point_name>",
+ default=None,
+ help=_('Optional custom export location. Available for '
+ 'microversion >= 2.84')
+ )
return parser
@@ -232,6 +239,15 @@
snapshot_id = snapshot.id
size = max(size or 0, snapshot.size)
+ mount_point_name = None
+ if parsed_args.mount_point_name:
+ if share_client.api_version < api_versions.APIVersion('2.84'):
+ raise exceptions.CommandError(
+ 'Setting share mount point name is '
+ 'available only for API microversion >= 2.84')
+ else:
+ mount_point_name = parsed_args.mount_point_name
+
scheduler_hints = {}
if parsed_args.scheduler_hint:
if share_client.api_version < api_versions.APIVersion('2.65'):
@@ -271,7 +287,8 @@
'is_public': parsed_args.public,
'availability_zone': parsed_args.availability_zone,
'share_group_id': share_group,
- 'scheduler_hints': scheduler_hints
+ 'scheduler_hints': scheduler_hints,
+ 'mount_point_name': mount_point_name,
}
share = share_client.shares.create(**body)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/manilaclient/osc/v2/share_network_subnets.py new/python-manilaclient-4.9.0/manilaclient/osc/v2/share_network_subnets.py
--- old/python-manilaclient-4.8.0/manilaclient/osc/v2/share_network_subnets.py 2024-03-01 10:55:26.000000000 +0100
+++ new/python-manilaclient-4.9.0/manilaclient/osc/v2/share_network_subnets.py 2024-05-16 15:02:24.000000000 +0200
@@ -21,6 +21,7 @@
from manilaclient import api_versions
from manilaclient.common._i18n import _
+from manilaclient.common import cliutils
LOG = logging.getLogger(__name__)
@@ -135,6 +136,15 @@
share_network_id=share_network_id)
)
subnet_data = subnet_create_check[1]
+ if subnet_data:
+ if parsed_args.formatter == 'table':
+ for k, v in subnet_data.items():
+ if isinstance(v, dict):
+ capabilities_list = [v]
+ dict_values = cliutils.convert_dict_list_to_string(
+ capabilities_list
+ )
+ subnet_data[k] = dict_values
else:
share_network_subnet = share_client.share_network_subnets.create(
neutron_net_id=parsed_args.neutron_net_id,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/manilaclient/tests/functional/client.py new/python-manilaclient-4.9.0/manilaclient/tests/functional/client.py
--- old/python-manilaclient-4.8.0/manilaclient/tests/functional/client.py 2024-03-01 10:55:26.000000000 +0100
+++ new/python-manilaclient-4.9.0/manilaclient/tests/functional/client.py 2024-05-16 15:02:24.000000000 +0200
@@ -453,24 +453,19 @@
# Share networks
def create_share_network(self, name=None, description=None,
- nova_net_id=None, neutron_net_id=None,
- neutron_subnet_id=None, availability_zone=None,
+ neutron_net_id=None, neutron_subnet_id=None,
+ availability_zone=None,
microversion=None):
"""Creates share network.
:param name: text -- desired name of new share network
:param description: text -- desired description of new share network
- :param nova_net_id: text -- ID of Nova network
:param neutron_net_id: text -- ID of Neutron network
:param neutron_subnet_id: text -- ID of Neutron subnet
-
- NOTE: 'nova_net_id' and 'neutron_net_id'/'neutron_subnet_id' are
- mutually exclusive.
"""
params = self._combine_share_network_data(
name=name,
description=description,
- nova_net_id=nova_net_id,
neutron_net_id=neutron_net_id,
neutron_subnet_id=neutron_subnet_id,
availability_zone=availability_zone
@@ -481,7 +476,7 @@
return share_network
def _combine_share_network_data(self, name=None, description=None,
- nova_net_id=None, neutron_net_id=None,
+ neutron_net_id=None,
neutron_subnet_id=None,
availability_zone=None):
"""Combines params for share network operations 'create' and 'update'.
@@ -493,8 +488,6 @@
data['--name'] = name
if description is not None:
data['--description'] = description
- if nova_net_id is not None:
- data['--nova_net_id'] = nova_net_id
if neutron_net_id is not None:
data['--neutron_net_id'] = neutron_net_id
if neutron_subnet_id is not None:
@@ -516,23 +509,18 @@
@not_found_wrapper
def update_share_network(self, share_network, name=None, description=None,
- nova_net_id=None, neutron_net_id=None,
+ neutron_net_id=None,
neutron_subnet_id=None, microversion=None):
"""Updates share-network by its name or ID.
:param name: text -- new name for share network
:param description: text -- new description for share network
- :param nova_net_id: text -- ID of some Nova network
:param neutron_net_id: text -- ID of some Neutron network
:param neutron_subnet_id: text -- ID of some Neutron subnet
-
- NOTE: 'nova_net_id' and 'neutron_net_id'/'neutron_subnet_id' are
- mutually exclusive.
"""
sn_params = self._combine_share_network_data(
name=name,
description=description,
- nova_net_id=nova_net_id,
neutron_net_id=neutron_net_id,
neutron_subnet_id=neutron_subnet_id)
share_network_raw = self.manila(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/manilaclient/tests/functional/osc/test_share_network_subnets.py new/python-manilaclient-4.9.0/manilaclient/tests/functional/osc/test_share_network_subnets.py
--- old/python-manilaclient-4.8.0/manilaclient/tests/functional/osc/test_share_network_subnets.py 2024-03-01 10:55:26.000000000 +0100
+++ new/python-manilaclient-4.9.0/manilaclient/tests/functional/osc/test_share_network_subnets.py 2024-05-16 15:02:24.000000000 +0200
@@ -25,7 +25,7 @@
share_network['id'])
self.assertEqual('True', check_result['compatible'])
- self.assertEqual('{}', check_result['hosts_check_result'])
+ self.assertEqual('', check_result['hosts_check_result'])
def test_openstack_share_network_create_check_restart(self):
share_network = self.create_share_network()
@@ -34,4 +34,4 @@
share_network['id'], restart_check=True)
self.assertEqual('True', check_result['compatible'])
- self.assertEqual('{}', check_result['hosts_check_result'])
+ self.assertEqual('', check_result['hosts_check_result'])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/manilaclient/tests/unit/osc/v2/fakes.py new/python-manilaclient-4.9.0/manilaclient/tests/unit/osc/v2/fakes.py
--- old/python-manilaclient-4.8.0/manilaclient/tests/unit/osc/v2/fakes.py 2024-03-01 10:55:26.000000000 +0100
+++ new/python-manilaclient-4.9.0/manilaclient/tests/unit/osc/v2/fakes.py 2024-05-16 15:02:24.000000000 +0200
@@ -139,6 +139,7 @@
"revert_to_snapshot_support": False,
"source_share_group_snapshot_member_id": None,
"scheduler_hints": {},
+ "mount_point_name": None,
}
# Overwrite default attributes.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/manilaclient/tests/unit/osc/v2/test_share.py new/python-manilaclient-4.9.0/manilaclient/tests/unit/osc/v2/test_share.py
--- old/python-manilaclient-4.8.0/manilaclient/tests/unit/osc/v2/test_share.py 2024-03-01 10:55:26.000000000 +0100
+++ new/python-manilaclient-4.9.0/manilaclient/tests/unit/osc/v2/test_share.py 2024-05-16 15:02:24.000000000 +0200
@@ -132,7 +132,8 @@
share_type=self.share_type.id,
size=self.new_share.size,
snapshot_id=None,
- scheduler_hints={}
+ scheduler_hints={},
+ mount_point_name=None,
)
self.assertCountEqual(self.columns, columns)
@@ -180,7 +181,8 @@
share_type=self.share_type.id,
size=self.new_share.size,
snapshot_id=None,
- scheduler_hints={}
+ scheduler_hints={},
+ mount_point_name=None,
)
self.assertCountEqual(self.columns, columns)
@@ -227,6 +229,49 @@
snapshot_id=None,
scheduler_hints={'same_host': shares[0].id,
'different_host': shares[1].id},
+ mount_point_name=None,
+ )
+
+ self.assertCountEqual(self.columns, columns)
+ self.assertCountEqual(self.datalist, data)
+
+ def test_share_create_mount_point_name(self):
+ """Verifies that the mount point name has been passed correctly."""
+ self.app.client_manager.share.api_version = api_versions.APIVersion(
+ "2.84")
+
+ mount_point_name = "fake_mp"
+
+ arglist = [
+ self.new_share.share_proto,
+ str(self.new_share.size),
+ '--share-type', self.share_type.id,
+ '--mount-point-name', mount_point_name,
+ ]
+ verifylist = [
+ ('share_proto', self.new_share.share_proto),
+ ('size', self.new_share.size),
+ ('mount_point_name', mount_point_name),
+ ('share_type', self.share_type.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.shares_mock.create.assert_called_with(
+ availability_zone=None,
+ description=None,
+ is_public=False,
+ metadata={},
+ name=None,
+ share_group_id=None,
+ share_network=None,
+ share_proto=self.new_share.share_proto,
+ share_type=self.share_type.id,
+ size=self.new_share.size,
+ snapshot_id=None,
+ scheduler_hints={},
+ mount_point_name='fake_mp',
)
self.assertCountEqual(self.columns, columns)
@@ -269,7 +314,8 @@
share_type=None,
size=self.new_share.size,
snapshot_id=self.share_snapshot.id,
- scheduler_hints={}
+ scheduler_hints={},
+ mount_point_name=None,
)
self.assertCountEqual(self.columns, columns)
self.assertCountEqual(self.datalist, data)
@@ -305,7 +351,8 @@
share_type=self.share_type.id,
size=self.new_share.size,
snapshot_id=None,
- scheduler_hints={}
+ scheduler_hints={},
+ mount_point_name=None,
)
self.shares_mock.get.assert_called_with(self.new_share.id)
@@ -345,7 +392,8 @@
share_type=self.share_type.id,
size=self.new_share.size,
snapshot_id=None,
- scheduler_hints={}
+ scheduler_hints={},
+ mount_point_name=None,
)
mock_logger.error.assert_called_with(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/manilaclient/tests/unit/v2/fakes.py new/python-manilaclient-4.9.0/manilaclient/tests/unit/v2/fakes.py
--- old/python-manilaclient-4.8.0/manilaclient/tests/unit/v2/fakes.py 2024-03-01 10:55:26.000000000 +0100
+++ new/python-manilaclient-4.9.0/manilaclient/tests/unit/v2/fakes.py 2024-05-16 15:02:24.000000000 +0200
@@ -250,7 +250,8 @@
return (200, {}, shares)
def get_snapshots_1234(self, **kw):
- snapshot = {'snapshot': {'id': 1234, 'name': 'sharename'}}
+ snapshot = {'snapshot': {'id': 1234, 'name': 'sharename',
+ 'status': 'available'}}
return (200, {}, snapshot)
def get_share_servers(self, **kw):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/manilaclient/tests/unit/v2/test_shares.py new/python-manilaclient-4.9.0/manilaclient/tests/unit/v2/test_shares.py
--- old/python-manilaclient-4.8.0/manilaclient/tests/unit/v2/test_shares.py 2024-03-01 10:55:26.000000000 +0100
+++ new/python-manilaclient-4.9.0/manilaclient/tests/unit/v2/test_shares.py 2024-05-16 15:02:24.000000000 +0200
@@ -140,6 +140,29 @@
availability_zone=availability_zone)
cs.assert_called('POST', '/shares', body)
+ @ddt.data({'mount_point_name': 'fake_mount_pt1'},
+ {'mount_point_name': 'fake_mount_pt2'})
+ @ddt.unpack
+ def test_create_share_with_mount_point_name(self, mount_point_name):
+ body = {
+ 'share': {
+ 'is_public': False,
+ 'share_type': None,
+ 'name': None,
+ 'snapshot_id': None,
+ 'description': None,
+ 'metadata': {},
+ 'share_proto': 'nfs',
+ 'share_network_id': None,
+ 'size': 1,
+ 'availability_zone': None,
+ 'scheduler_hints': {},
+ 'mount_point_name': mount_point_name,
+ }
+ }
+ cs.shares.create('nfs', 1, mount_point_name=mount_point_name)
+ cs.assert_called('POST', '/shares', body)
+
@ddt.data(
type('ShareUUID', (object, ), {'uuid': '1234'}),
type('ShareID', (object, ), {'id': '1234'}),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/manilaclient/tests/unit/v2/test_shell.py new/python-manilaclient-4.9.0/manilaclient/tests/unit/v2/test_shell.py
--- old/python-manilaclient-4.8.0/manilaclient/tests/unit/v2/test_shell.py 2024-03-01 10:55:26.000000000 +0100
+++ new/python-manilaclient-4.9.0/manilaclient/tests/unit/v2/test_shell.py 2024-05-16 15:02:24.000000000 +0200
@@ -981,13 +981,15 @@
)
@ddt.unpack
@mock.patch.object(shell_v2, '_find_share', mock.Mock())
+ @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock())
def test_snapshot_manage(self, cmd_args, valid_params):
- shell_v2._find_share.return_value = 'fake_share'
+ share_containing_snapshot = shares.Share('fake_share', {'id': '1234'})
+ shell_v2._find_share.return_value = share_containing_snapshot
self.run_command('snapshot-manage fake_share fake_provider_location '
+ cmd_args)
expected = {
'snapshot': {
- 'share_id': 'fake_share',
+ 'share_id': '1234',
'provider_location': 'fake_provider_location',
'name': None,
'description': None,
@@ -995,12 +997,64 @@
}
expected['snapshot'].update(valid_params)
self.assert_called('POST', '/snapshots/manage', body=expected)
+ # _wait_for_resource_status should not be triggered
+ self.assertEqual(0, shell_v2._wait_for_resource_status.call_count)
+ @mock.patch.object(shell_v2, '_find_share', mock.Mock())
+ @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock())
+ def test_snapshot_manage_with_wait(self):
+ share_containing_snapshot = shares.Share('fake_share', {'id': '1234'})
+ shell_v2._find_share.return_value = share_containing_snapshot
+ cmd_args = '--wait --driver_options opt1=opt1 opt2=opt2'
+ self.run_command('snapshot-manage fake_share fake_provider_location '
+ + cmd_args)
+ expected = {
+ 'snapshot': {
+ 'share_id': '1234',
+ 'provider_location': 'fake_provider_location',
+ 'name': None,
+ 'description': None,
+ }
+ }
+ valid_params = {'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}}
+ expected['snapshot'].update(valid_params)
+ self.assert_called('POST', '/snapshots/manage', body=expected)
+
+ shell_v2._find_share.assert_has_calls(
+ [mock.call(self.shell.cs, 'fake_share')])
+ self.assertEqual(1, shell_v2._find_share.call_count)
+ # _wait_for_resource_status should be triggered once
+ shell_v2._wait_for_resource_status.assert_called_once_with(
+ self.shell.cs, mock.ANY, 'available', resource_type='snapshot')
+
+ @mock.patch.object(shell_v2, '_find_share', mock.Mock())
+ @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock())
def test_snapshot_unmanage(self):
+ share_containing_snapshot = shares.Share('fake_share', {'id': '1234'})
+ shell_v2._find_share.return_value = share_containing_snapshot
self.run_command('snapshot-unmanage 1234')
+
self.assert_called('POST', '/snapshots/1234/action',
body={'unmanage': None})
+ self.assertEqual(0, shell_v2._wait_for_resource_status.call_count)
+ @mock.patch.object(shell_v2, '_find_share', mock.Mock())
+ @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock())
+ def test_snapshot_unmanage_with_wait(self):
+ share_containing_snapshot = shares.Share('fake_share', {'id': '1234'})
+ shell_v2._find_share.return_value = share_containing_snapshot
+ self.run_command('snapshot-unmanage 1234 --wait')
+
+ self.assert_called('POST', '/snapshots/1234/action',
+ body={'unmanage': None})
+ expected_snapshot = shell_v2._find_share_snapshot(
+ self.shell.cs, '1234')
+ # _wait_for_resource_status should be trigerred once
+ shell_v2._wait_for_resource_status.assert_called_once_with(
+ self.shell.cs, expected_snapshot, 'deleted',
+ resource_type='snapshot')
+
+ @mock.patch.object(shell_v2, '_wait_for_share_status', mock.Mock())
def test_revert_to_snapshot(self):
fake_share_snapshot = type(
@@ -1013,6 +1067,25 @@
self.assert_called('POST', '/shares/1234/action',
body={'revert': {'snapshot_id': '5678'}})
+ # _wait_for_share_status should not be trigerred
+ self.assertEqual(0, shell_v2._wait_for_share_status.call_count)
+
+ @mock.patch.object(shell_v2, '_wait_for_share_status', mock.Mock())
+ def test_revert_to_snapshot_with_wait(self):
+
+ fake_share_snapshot = type(
+ 'FakeShareSnapshot', (object,), {'id': '5678', 'share_id': '1234'})
+ self.mock_object(
+ shell_v2, '_find_share_snapshot',
+ mock.Mock(return_value=fake_share_snapshot))
+
+ self.run_command('revert-to-snapshot 5678 --wait')
+
+ self.assert_called('POST', '/shares/1234/action',
+ body={'revert': {'snapshot_id': '5678'}})
+ # _wait_for_share_status should be trigerred once
+ shell_v2._wait_for_share_status.assert_called_once_with(
+ self.shell.cs, mock.ANY)
def test_delete(self):
self.run_command('delete 1234')
@@ -3640,6 +3713,39 @@
'DELETE', '/share-networks/%s' % sn.id,
clear_callstack=False)
+ @mock.patch.object(shell_v2, '_find_share', mock.Mock())
+ @mock.patch.object(shell_v2, '_wait_for_snapshot_status', mock.Mock())
+ def test_snapshot_create(self):
+ share_to_create_snapshot = shares.Share('fake_share', {'id': '1234'})
+ shell_v2._find_share.return_value = share_to_create_snapshot
+
+ self.run_command(
+ 'snapshot-create fake_share --name testshare1snapshot')
+
+ shell_v2._find_share.assert_has_calls([
+ mock.call(self.shell.cs, 'fake_share')])
+ self.assert_called_anytime(
+ 'POST', '/snapshots', clear_callstack=False)
+ # _wait_for_snapshot_status should not be trigerred
+ self.assertEqual(0, shell_v2._wait_for_snapshot_status.call_count)
+
+ @mock.patch.object(shell_v2, '_find_share', mock.Mock())
+ @mock.patch.object(shell_v2, '_wait_for_snapshot_status', mock.Mock())
+ def test_snapshot_create_with_wait(self):
+ share_to_create_snapshot = shares.Share('fake_share', {'id': '1234'})
+ shell_v2._find_share.return_value = share_to_create_snapshot
+
+ self.run_command(
+ 'snapshot-create fake_share --name testshare1snapshot --wait')
+
+ shell_v2._find_share.assert_has_calls([
+ mock.call(self.shell.cs, 'fake_share')])
+ self.assert_called_anytime(
+ 'POST', '/snapshots', clear_callstack=False)
+ # _wait_for_snapshot_status should be trigerred once
+ shell_v2._wait_for_snapshot_status.assert_called_once_with(
+ self.shell.cs, mock.ANY, expected_status='available')
+
@ddt.data(('fake_snapshot1', ), ('fake_snapshot1', 'fake_snapshot2'))
def test_snapshot_delete(self, snapshot_ids):
fake_snapshots = [
@@ -3660,6 +3766,23 @@
'DELETE', '/snapshots/%s' % snapshot.id,
clear_callstack=False)
+ @mock.patch.object(shell_v2, '_find_share_snapshot', mock.Mock())
+ @mock.patch.object(shell_v2, '_wait_for_snapshot_status', mock.Mock())
+ def test_snapshot_delete_with_wait(self):
+ fake_snapshot = share_snapshots.ShareSnapshot(
+ 'fake', {'id': 'fake_snapshot1'}, True)
+ shell_v2._find_share_snapshot.return_value = fake_snapshot
+
+ self.run_command('snapshot-delete fake_snapshot1 --wait')
+
+ shell_v2._find_share_snapshot.assert_has_calls([
+ mock.call(self.shell.cs, 'fake_snapshot1')])
+ self.assert_called_anytime(
+ 'DELETE', '/snapshots/fake_snapshot1', clear_callstack=False)
+ # _wait_for_resource_status should be trigerred once
+ shell_v2._wait_for_snapshot_status.assert_called_once_with(
+ self.shell.cs, 'fake_snapshot1', expected_status='deleted')
+
@ddt.data(('snapshot_xyz', ), ('snapshot_abc', 'snapshot_xyz'))
def test_snapshot_force_delete_wait(self, snapshots_to_delete):
fake_manager = mock.Mock()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/manilaclient/v2/shares.py new/python-manilaclient-4.9.0/manilaclient/v2/shares.py
--- old/python-manilaclient-4.8.0/manilaclient/v2/shares.py 2024-03-01 10:55:26.000000000 +0100
+++ new/python-manilaclient-4.9.0/manilaclient/v2/shares.py 2024-05-16 15:02:24.000000000 +0200
@@ -124,7 +124,8 @@
def create(self, share_proto, size, snapshot_id=None, name=None,
description=None, metadata=None, share_network=None,
share_type=None, is_public=False, availability_zone=None,
- share_group_id=None, scheduler_hints=None, return_raw=False):
+ share_group_id=None, scheduler_hints=None, return_raw=False,
+ mount_point_name=None):
"""Create a share.
:param share_proto: text - share protocol for new share available
@@ -142,6 +143,9 @@
:param scheduler_hints: dict - hints for the scheduler to place share
on most appropriate host e.g. keys are same_host for affinity and
different_host for anti-affinity
+ :param mount_point_name: text - share human-readable mount point name.
+ This name will be reflected in export location once
+ share is created.
:rtype: :class:`Share`
"""
share_metadata = metadata if metadata is not None else dict()
@@ -163,6 +167,9 @@
if share_group_id:
body['share_group_id'] = share_group_id
+ if mount_point_name:
+ body['mount_point_name'] = mount_point_name
+
return self._create('/shares', {'share': body}, 'share',
return_raw=return_raw)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/manilaclient/v2/shell.py new/python-manilaclient-4.9.0/manilaclient/v2/shell.py
--- old/python-manilaclient-4.8.0/manilaclient/v2/shell.py 2024-03-01 10:55:26.000000000 +0100
+++ new/python-manilaclient-4.9.0/manilaclient/v2/shell.py 2024-05-16 15:02:24.000000000 +0200
@@ -326,6 +326,11 @@
cliutils.print_dict(info.get('members', {}))
+def _wait_for_snapshot_status(cs, snapshot, expected_status='available'):
+ return _wait_for_resource_status(
+ cs, snapshot, expected_status, resource_type='snapshot')
+
+
def _find_share_snapshot(cs, snapshot):
"""Get a snapshot by ID."""
return apiclient_utils.find_resource(cs.share_snapshots, snapshot)
@@ -1704,10 +1709,14 @@
action='single_alias',
help='Optional driver options as key=value pairs (Default=None).',
default=None)
+(a)cliutils.arg(
+ '--wait',
+ action='store_true',
+ default=False,
+ help='Wait for share snapshot to be managed')
def do_snapshot_manage(cs, args):
"""Manage share snapshot not handled by Manila (Admin only)."""
share_ref = _find_share(cs, args.share)
-
driver_options = _extract_key_value_options(args, 'driver_options')
share_snapshot = cs.share_snapshots.manage(
@@ -1716,6 +1725,12 @@
name=args.name, description=args.description
)
+ if args.wait:
+ try:
+ _wait_for_snapshot_status(cs, share_snapshot,
+ expected_status='available')
+ except exceptions.CommandError as e:
+ print(e, file=sys.stderr)
_print_share_snapshot(cs, share_snapshot)
@@ -1771,6 +1786,11 @@
metavar='<snapshot>',
nargs='+',
help='Name or ID of the snapshot(s).')
+(a)cliutils.arg(
+ '--wait',
+ action='store_true',
+ default=False,
+ help='Wait for share snapshot to be unmanaged')
def do_snapshot_unmanage(cs, args):
"""Unmanage one or more share snapshots (Admin only)."""
failure_count = 0
@@ -1778,6 +1798,9 @@
try:
snapshot_ref = _find_share_snapshot(cs, snapshot)
snapshot_ref.unmanage_snapshot()
+ if args.wait:
+ _wait_for_snapshot_status(cs, snapshot_ref,
+ expected_status='deleted')
except Exception as e:
failure_count += 1
print("Unmanage for share snapshot %s failed: %s" % (snapshot, e),
@@ -1794,11 +1817,18 @@
metavar='<snapshot>',
help='Name or ID of the snapshot to restore. The snapshot must be the '
'most recent one known to manila.')
+(a)cliutils.arg(
+ '--wait',
+ action='store_true',
+ default=False,
+ help='Wait for share to be reverted from snapshot.')
def do_revert_to_snapshot(cs, args):
"""Revert a share to the specified snapshot."""
snapshot = _find_share_snapshot(cs, args.snapshot)
share = _find_share(cs, snapshot.share_id)
share.revert_to_snapshot(snapshot)
+ if args.wait:
+ _wait_for_share_status(cs, share)
@cliutils.arg(
@@ -3038,6 +3068,11 @@
metavar='<description>',
default=None,
help='Optional snapshot description. (Default=None)')
+(a)cliutils.arg(
+ '--wait',
+ action='store_true',
+ default=False,
+ help='Wait for snapshot to be created.')
def do_snapshot_create(cs, args):
"""Add a new snapshot."""
share = _find_share(cs, args.share)
@@ -3045,6 +3080,12 @@
args.force,
args.name,
args.description)
+ if args.wait:
+ try:
+ _wait_for_snapshot_status(cs, snapshot,
+ expected_status='available')
+ except exceptions.CommandError as e:
+ print(e, file=sys.stderr)
_print_share_snapshot(cs, snapshot)
@@ -3120,6 +3161,11 @@
metavar='<snapshot>',
nargs='+',
help='Name or ID of the snapshot(s) to delete.')
+(a)cliutils.arg(
+ '--wait',
+ action='store_true',
+ default=False,
+ help='Wait for snapshot to be deleted')
def do_snapshot_delete(cs, args):
"""Remove one or more snapshots."""
failure_count = 0
@@ -3129,6 +3175,9 @@
snapshot_ref = _find_share_snapshot(
cs, snapshot)
cs.share_snapshots.delete(snapshot_ref)
+ if args.wait:
+ _wait_for_snapshot_status(cs, snapshot,
+ expected_status='deleted')
except Exception as e:
failure_count += 1
print("Delete for snapshot %s failed: %s" % (
@@ -3291,15 +3340,6 @@
@api_versions.wraps("1.0", "2.25")
@cliutils.arg(
- '--nova-net-id',
- '--nova-net_id', '--nova_net_id', '--nova_net-id', # aliases
- metavar='<nova-net-id>',
- default=None,
- action='single_alias',
- help="Nova net ID. Used to set up network for share servers. This "
- "option is deprecated and will be rejected in newer releases "
- "of OpenStack Manila.")
-(a)cliutils.arg(
'--neutron-net-id',
'--neutron-net_id', '--neutron_net_id', '--neutron_net-id',
metavar='<neutron-net-id>',
@@ -3329,7 +3369,6 @@
values = {
'neutron_net_id': args.neutron_net_id,
'neutron_subnet_id': args.neutron_subnet_id,
- 'nova_net_id': args.nova_net_id,
'name': args.name,
'description': args.description,
}
@@ -3399,15 +3438,6 @@
metavar='<share-network>',
help='Name or ID of share network to update.')
@cliutils.arg(
- '--nova-net-id',
- '--nova-net_id', '--nova_net_id', '--nova_net-id', # aliases
- metavar='<nova-net-id>',
- default=None,
- action='single_alias',
- help="Nova net ID. Used to set up network for share servers. This "
- "option is deprecated and will be rejected in newer releases "
- "of OpenStack Manila.")
-(a)cliutils.arg(
'--neutron-net-id',
'--neutron-net_id', '--neutron_net_id', '--neutron_net-id',
metavar='<neutron-net-id>',
@@ -3437,7 +3467,6 @@
values = {
'neutron_net_id': args.neutron_net_id,
'neutron_subnet_id': args.neutron_subnet_id,
- 'nova_net_id': args.nova_net_id,
'name': args.name,
'description': args.description,
}
@@ -3552,14 +3581,6 @@
default=None,
help='Filter results by attached security service.')
@cliutils.arg(
- '--nova-net-id',
- '--nova_net_id', '--nova_net-id', '--nova-net_id', # aliases
- metavar='<nova_net_id>',
- action='single_alias',
- default=None,
- help='Filter results by Nova net ID. This option is deprecated and will '
- 'be rejected in newer releases of OpenStack Manila.')
-(a)cliutils.arg(
'--neutron-net-id',
'--neutron_net_id', '--neutron_net-id', '--neutron-net_id', # aliases
metavar='<neutron_net_id>',
@@ -3634,7 +3655,6 @@
'name': args.name,
'created_since': args.created_since,
'created_before': args.created_before,
- 'nova_net_id': args.nova_net_id,
'neutron_net_id': args.neutron_net_id,
'neutron_subnet_id': args.neutron_subnet_id,
'network_type': args.network_type,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/python_manilaclient.egg-info/PKG-INFO new/python-manilaclient-4.9.0/python_manilaclient.egg-info/PKG-INFO
--- old/python-manilaclient-4.8.0/python_manilaclient.egg-info/PKG-INFO 2024-03-01 10:55:55.000000000 +0100
+++ new/python-manilaclient-4.9.0/python_manilaclient.egg-info/PKG-INFO 2024-05-16 15:02:55.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.2
Name: python-manilaclient
-Version: 4.8.0
+Version: 4.9.0
Summary: Client library for OpenStack Manila API.
Home-page: https://docs.openstack.org/python-manilaclient/latest/
Author: OpenStack
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/python_manilaclient.egg-info/SOURCES.txt new/python-manilaclient-4.9.0/python_manilaclient.egg-info/SOURCES.txt
--- old/python-manilaclient-4.8.0/python_manilaclient.egg-info/SOURCES.txt 2024-03-01 10:55:55.000000000 +0100
+++ new/python-manilaclient-4.9.0/python_manilaclient.egg-info/SOURCES.txt 2024-05-16 15:02:55.000000000 +0200
@@ -21,6 +21,7 @@
doc/source/cli/osc_plugin_cli.rst
doc/source/cli/osc/manila.csv
doc/source/cli/osc/v2/index.rst
+doc/source/contributor/adding_release_notes.rst
doc/source/contributor/contributing.rst
doc/source/contributor/functional-tests.rst
doc/source/contributor/index.rst
@@ -343,6 +344,7 @@
releasenotes/notes/bug-1855391-support-force-extend-share-6b5ebcfe1de0ca7b.yaml
releasenotes/notes/bug-1871252-update-default-quotas-via-quota-class-share-groups-share-group-snapshots-20ec1dfcc0a7e81c.yaml
releasenotes/notes/bug-1898304-add-wait-to-share-create-delete-f121073f2f4402ff.yaml
+releasenotes/notes/bug-1898307-add-wait-to-create-revert-delete-a-snapshot-20271b8ebb60ade5.yaml
releasenotes/notes/bug-1898308-add-wait-to-share-extend-shrink-c9cc413c50d9832a.yaml
releasenotes/notes/bug-1898309-add-wait-to-share-manage-unmanage-d2060c61cc295bfd.yaml
releasenotes/notes/bug-1898315-add-wait-flag-to-manage-share-server-operation-be6488c2a57536e1.yaml
@@ -362,10 +364,12 @@
releasenotes/notes/bug-1962288-fixed-share-network-create-command-879dc3deca131ef9.yaml
releasenotes/notes/bug-1975488-skip-force-kwarg-if-unspecified-f98c717df1d6e364.yaml
releasenotes/notes/bug-1980985-dont-use-share-type-with-snapshot-ref-de0331c640afbbd3.yaml
+releasenotes/notes/bug-1989818-fix-share-network-output-format-93d997f0f4a33fab.yaml
releasenotes/notes/bug-1999775-add-os-key-0cfc95c7b480df05.yaml
releasenotes/notes/bug-2030686-fix-default-share-lookup-cc7e592a0dc855e1.yaml
releasenotes/notes/bug-2047249-fix-osc-quota-set-per-share-gigabytes-fcff7f8ce2cc3c75.yaml
releasenotes/notes/bug-2051737-fix-share-force-delete-request-6d2578fb7da61e3f.yaml
+releasenotes/notes/bug-913201-add-wait-to-manage-unmanage-snapshot-9cc017a15733120f.yaml
releasenotes/notes/bug-share-access-list-3cf3114doe40k599.yaml
releasenotes/notes/bug_1570085_fix-905786b797379309.yaml
releasenotes/notes/bug_1603387_fix_env_variable_8ed5450aab41aa5f.yaml
@@ -382,6 +386,7 @@
releasenotes/notes/fix-is-default-empty-557844001e0401e2.yaml
releasenotes/notes/graduate-share-replication-feature-49770e921b4338fb.yaml
releasenotes/notes/handle-missing-api-minor-version-5a6d242f28883442.yaml
+releasenotes/notes/human-readable-export-location-share-support-d156f23669e458fa.yaml
releasenotes/notes/manage-unmanage-share-servers-8c7b27a1fe80e5fa.yaml
releasenotes/notes/manila-client-support-recycle-bin-4ecb5de770bd525f.yaml
releasenotes/notes/manila-openstackclient-bf61ceb270d3afb7.yaml
@@ -389,6 +394,7 @@
releasenotes/notes/mountable_snapshot-ced01da7dffc6d7e.yaml
releasenotes/notes/newton-migration-improvements-166a03472948bdef.yaml
releasenotes/notes/remove-experimental-flag-from-share-groups-feature-dcf2b0b67fe4cac4.yaml
+releasenotes/notes/remove-nova-net-id-arg-5b01f0077be171ed.yaml
releasenotes/notes/remove-nova-net-id-option-for-share-nets-82e424b75221528b.yaml
releasenotes/notes/share-backup-98e11c6a28897e94.yaml
releasenotes/notes/share-network-multiple-subnets-732309abfbf5987c.yaml
@@ -404,6 +410,7 @@
releasenotes/notes/v2-0-0-deprecated-opts-removal-863565618535733d.yaml
releasenotes/source/2023.1.rst
releasenotes/source/2023.2.rst
+releasenotes/source/2024.1.rst
releasenotes/source/conf.py
releasenotes/source/index.rst
releasenotes/source/newton.rst
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/python_manilaclient.egg-info/pbr.json new/python-manilaclient-4.9.0/python_manilaclient.egg-info/pbr.json
--- old/python-manilaclient-4.8.0/python_manilaclient.egg-info/pbr.json 2024-03-01 10:55:55.000000000 +0100
+++ new/python-manilaclient-4.9.0/python_manilaclient.egg-info/pbr.json 2024-05-16 15:02:55.000000000 +0200
@@ -1 +1 @@
-{"git_version": "06e96b7", "is_release": true}
\ No newline at end of file
+{"git_version": "56ba694", "is_release": true}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/releasenotes/notes/bug-1898307-add-wait-to-create-revert-delete-a-snapshot-20271b8ebb60ade5.yaml new/python-manilaclient-4.9.0/releasenotes/notes/bug-1898307-add-wait-to-create-revert-delete-a-snapshot-20271b8ebb60ade5.yaml
--- old/python-manilaclient-4.8.0/releasenotes/notes/bug-1898307-add-wait-to-create-revert-delete-a-snapshot-20271b8ebb60ade5.yaml 1970-01-01 01:00:00.000000000 +0100
+++ new/python-manilaclient-4.9.0/releasenotes/notes/bug-1898307-add-wait-to-create-revert-delete-a-snapshot-20271b8ebb60ade5.yaml 2024-05-16 15:02:24.000000000 +0200
@@ -0,0 +1,6 @@
+---
+features:
+ - |
+ The commands "snapshot-create", "snapshot-delete" and "revert-to-snapshot"
+ now accept an optional "--wait" option that allows users to let the
+ client poll for the completion of the operation.
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/releasenotes/notes/bug-1989818-fix-share-network-output-format-93d997f0f4a33fab.yaml new/python-manilaclient-4.9.0/releasenotes/notes/bug-1989818-fix-share-network-output-format-93d997f0f4a33fab.yaml
--- old/python-manilaclient-4.8.0/releasenotes/notes/bug-1989818-fix-share-network-output-format-93d997f0f4a33fab.yaml 1970-01-01 01:00:00.000000000 +0100
+++ new/python-manilaclient-4.9.0/releasenotes/notes/bug-1989818-fix-share-network-output-format-93d997f0f4a33fab.yaml 2024-05-16 15:02:24.000000000 +0200
@@ -0,0 +1,6 @@
+---
+fixes:
+ - |
+ The format of the osc share network subnet create command output has been
+ updated to return a list of hosts instead of a dictionary, as we do for
+ other commands in the client.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/releasenotes/notes/bug-913201-add-wait-to-manage-unmanage-snapshot-9cc017a15733120f.yaml new/python-manilaclient-4.9.0/releasenotes/notes/bug-913201-add-wait-to-manage-unmanage-snapshot-9cc017a15733120f.yaml
--- old/python-manilaclient-4.8.0/releasenotes/notes/bug-913201-add-wait-to-manage-unmanage-snapshot-9cc017a15733120f.yaml 1970-01-01 01:00:00.000000000 +0100
+++ new/python-manilaclient-4.9.0/releasenotes/notes/bug-913201-add-wait-to-manage-unmanage-snapshot-9cc017a15733120f.yaml 2024-05-16 15:02:24.000000000 +0200
@@ -0,0 +1,6 @@
+---
+features:
+ - |
+ The commands "snapshot-manage" and "snapshot-unmanage" now accept
+ an optional "--wait" option that allows users to let the client
+ poll for the completion of the operation.
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/releasenotes/notes/human-readable-export-location-share-support-d156f23669e458fa.yaml new/python-manilaclient-4.9.0/releasenotes/notes/human-readable-export-location-share-support-d156f23669e458fa.yaml
--- old/python-manilaclient-4.8.0/releasenotes/notes/human-readable-export-location-share-support-d156f23669e458fa.yaml 1970-01-01 01:00:00.000000000 +0100
+++ new/python-manilaclient-4.9.0/releasenotes/notes/human-readable-export-location-share-support-d156f23669e458fa.yaml 2024-05-16 15:02:24.000000000 +0200
@@ -0,0 +1,19 @@
+---
+features:
+ - In the 2.84 API version, a new option, ``mount_point_name``, has been
+ introduced to the share creation command. This option allow users
+ to specify a more intuitive ``mount_point_name`` that will be reflected
+ in the share's export location. However, for this feature to be available
+ to users, administrators must first enable an extra-spec in the
+ share type. In addition, administrators need to set an extra-spec named
+ ``provisioning:mount_point_prefix``. The Manila service will combine
+ this prefix with the mount point name that user provides during share
+ creation. If the ``provisioning:mount_point_prefix`` is not set for
+ a share type, but ``mount_point_name_support`` is enabled, the share's
+ export location will default to using the project_id as a prefix.
+ Please note that shares created with a project_id prefix cannot be
+ transferred. To move these shares to a different project,
+ an admin must manually unmount them from the current project and mount
+ them to the target project. A new capability, ``mount_point_name_support``,
+ allows the driver to inform the scheduler about its support for the
+ mount_point_name feature.
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/releasenotes/notes/remove-nova-net-id-arg-5b01f0077be171ed.yaml new/python-manilaclient-4.9.0/releasenotes/notes/remove-nova-net-id-arg-5b01f0077be171ed.yaml
--- old/python-manilaclient-4.8.0/releasenotes/notes/remove-nova-net-id-arg-5b01f0077be171ed.yaml 1970-01-01 01:00:00.000000000 +0100
+++ new/python-manilaclient-4.9.0/releasenotes/notes/remove-nova-net-id-arg-5b01f0077be171ed.yaml 2024-05-16 15:02:24.000000000 +0200
@@ -0,0 +1,4 @@
+---
+upgrade:
+ - |
+ The ``--nova-net-id`` option has been removed from the ``manila`` CLI.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/releasenotes/source/2024.1.rst new/python-manilaclient-4.9.0/releasenotes/source/2024.1.rst
--- old/python-manilaclient-4.8.0/releasenotes/source/2024.1.rst 1970-01-01 01:00:00.000000000 +0100
+++ new/python-manilaclient-4.9.0/releasenotes/source/2024.1.rst 2024-05-16 15:02:24.000000000 +0200
@@ -0,0 +1,6 @@
+===========================
+2024.1 Series Release Notes
+===========================
+
+.. release-notes::
+ :branch: stable/2024.1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/releasenotes/source/index.rst new/python-manilaclient-4.9.0/releasenotes/source/index.rst
--- old/python-manilaclient-4.8.0/releasenotes/source/index.rst 2024-03-01 10:55:26.000000000 +0100
+++ new/python-manilaclient-4.9.0/releasenotes/source/index.rst 2024-05-16 15:02:24.000000000 +0200
@@ -7,6 +7,7 @@
:maxdepth: 1
unreleased
+ 2024.1
2023.2
2023.1
zed
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/releasenotes/source/wallaby.rst new/python-manilaclient-4.9.0/releasenotes/source/wallaby.rst
--- old/python-manilaclient-4.8.0/releasenotes/source/wallaby.rst 2024-03-01 10:55:26.000000000 +0100
+++ new/python-manilaclient-4.9.0/releasenotes/source/wallaby.rst 2024-05-16 15:02:24.000000000 +0200
@@ -3,4 +3,4 @@
============================
.. release-notes::
- :branch: stable/wallaby
+ :branch: unmaintained/wallaby
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/releasenotes/source/xena.rst new/python-manilaclient-4.9.0/releasenotes/source/xena.rst
--- old/python-manilaclient-4.8.0/releasenotes/source/xena.rst 2024-03-01 10:55:26.000000000 +0100
+++ new/python-manilaclient-4.9.0/releasenotes/source/xena.rst 2024-05-16 15:02:24.000000000 +0200
@@ -3,4 +3,4 @@
=========================
.. release-notes::
- :branch: stable/xena
+ :branch: unmaintained/xena
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/tox.ini new/python-manilaclient-4.9.0/tox.ini
--- old/python-manilaclient-4.8.0/tox.ini 2024-03-01 10:55:26.000000000 +0100
+++ new/python-manilaclient-4.9.0/tox.ini 2024-05-16 15:02:24.000000000 +0200
@@ -24,6 +24,12 @@
[testenv:debug]
commands = oslo_debug_helper -t manilaclient/tests {posargs}
+[testenv:newnote]
+deps =
+ -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
+ -r{toxinidir}/doc/requirements.txt
+commands = reno new {posargs}
+
[testenv:pep8]
commands =
flake8
@@ -84,6 +90,10 @@
coverage xml -o cover/coverage.xml
coverage report
+[testenv:bandit]
+deps = bandit
+commands = bandit -r manilaclient -x manilaclient/tests/* -n5 -ll
+
[flake8]
# F821: undefined name
# W503 line break before binary operator
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/zuul.d/project.yaml new/python-manilaclient-4.9.0/zuul.d/project.yaml
--- old/python-manilaclient-4.8.0/zuul.d/project.yaml 2024-03-01 10:55:26.000000000 +0100
+++ new/python-manilaclient-4.9.0/zuul.d/project.yaml 2024-05-16 15:02:24.000000000 +0200
@@ -8,6 +8,7 @@
check:
jobs:
- python-manilaclient-functional
+ - python-manilaclient-tox-bandit
- manila-rally-ss:
voting: false
- python-manilaclient-functional-fips:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-manilaclient-4.8.0/zuul.d/python-manilaclient-jobs.yaml new/python-manilaclient-4.9.0/zuul.d/python-manilaclient-jobs.yaml
--- old/python-manilaclient-4.8.0/zuul.d/python-manilaclient-jobs.yaml 2024-03-01 10:55:26.000000000 +0100
+++ new/python-manilaclient-4.9.0/zuul.d/python-manilaclient-jobs.yaml 2024-05-16 15:02:24.000000000 +0200
@@ -92,3 +92,10 @@
vars:
configure_swap_size: 4096
nslookup_target: 'opendev.org'
+
+- job:
+ name: python-manilaclient-tox-bandit
+ parent: openstack-tox
+ timeout: 2400
+ vars:
+ tox_envlist: bandit
1
0
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-magnumclient for openSUSE:Factory checked in at 2024-06-05 17:42:07
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-magnumclient (Old)
and /work/SRC/openSUSE:Factory/.python-magnumclient.new.24587 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-magnumclient"
Wed Jun 5 17:42:07 2024 rev:15 rq:1178609 version:4.5.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-magnumclient/python-magnumclient.changes 2024-05-03 10:42:23.148545813 +0200
+++ /work/SRC/openSUSE:Factory/.python-magnumclient.new.24587/python-magnumclient.changes 2024-06-05 17:42:44.886865692 +0200
@@ -1,0 +2,10 @@
+Tue Jun 4 20:06:44 UTC 2024 - cloud-devel(a)suse.de
+
+- update to version 4.5.0
+ - Update master for stable/2024.1
+ - Replace deprecated inspector.getargspec
+ - Display project_id for cluster template
+ - Always use io module
+ - reno: Update master for unmaintained/zed
+
+-------------------------------------------------------------------
Old:
----
python-magnumclient-4.4.0.tar.gz
New:
----
python-magnumclient-4.5.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-magnumclient.spec ++++++
--- /var/tmp/diff_new_pack.R9EKut/_old 2024-06-05 17:42:45.470886960 +0200
+++ /var/tmp/diff_new_pack.R9EKut/_new 2024-06-05 17:42:45.474887106 +0200
@@ -17,13 +17,13 @@
Name: python-magnumclient
-Version: 4.4.0
+Version: 4.5.0
Release: 0
Summary: Python API and CLI for OpenStack Magnum
License: Apache-2.0
Group: Development/Languages/Python
URL: https://docs.openstack.org/python-magnumclient
-Source0: https://files.pythonhosted.org/packages/source/p/python-magnumclient/python…
+Source0: https://files.pythonhosted.org/packages/source/p/python-magnumclient/python…
BuildRequires: openstack-macros
BuildRequires: python3-PrettyTable >= 0.7.2
BuildRequires: python3-cryptography >= 3.0
@@ -86,15 +86,15 @@
This package contains the documentation.
%prep
-%autosetup -p1 -n python-magnumclient-4.4.0
+%autosetup -p1 -n python-magnumclient-4.5.0
%py_req_cleanup
%build
%{py3_build}
# Build HTML docs and man page
-PBR_VERSION=4.4.0 %sphinx_build -b html doc/source doc/build/html
-PBR_VERSION=4.4.0 %sphinx_build -b man doc/source doc/build/man
+PBR_VERSION=4.5.0 %sphinx_build -b html doc/source doc/build/html
+PBR_VERSION=4.5.0 %sphinx_build -b man doc/source doc/build/man
rm -r doc/build/html/.{doctrees,buildinfo}
%install
++++++ python-magnumclient-4.4.0.tar.gz -> python-magnumclient-4.5.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-magnumclient-4.4.0/AUTHORS new/python-magnumclient-4.5.0/AUTHORS
--- old/python-magnumclient-4.4.0/AUTHORS 2024-03-01 14:53:30.000000000 +0100
+++ new/python-magnumclient-4.5.0/AUTHORS 2024-05-23 10:01:02.000000000 +0200
@@ -29,6 +29,7 @@
David Rabel <rabel(a)b1-systems.de>
Diogo Guerra <diogo.filipe.tomas.guerra(a)cern.ch>
Diogo Guerra <dy090.guerra(a)gmail.com>
+Dmitriy Rabotyagov <dmitriy.rabotyagov(a)citynetwork.eu>
Doug Hellmann <doug(a)doughellmann.com>
Eli Qiao <liyong.qiao(a)intel.com>
Eric Brown <browne(a)vmware.com>
@@ -100,6 +101,7 @@
Steven Dake <stdake(a)cisco.com>
Surojit Pathak <suro(a)yahoo-inc.com>
Swapnil Kulkarni (coolsvap) <me(a)coolsvap.net>
+Takashi Kajinami <kajinamit(a)oss.nttdata.com>
Theodoros Tsioutsias <theodoros.tsioutsias(a)cern.ch>
Tobias Urdin <tobias.urdin(a)binero.se>
Tom Cammann <tom.cammann(a)hp.com>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-magnumclient-4.4.0/ChangeLog new/python-magnumclient-4.5.0/ChangeLog
--- old/python-magnumclient-4.4.0/ChangeLog 2024-03-01 14:53:30.000000000 +0100
+++ new/python-magnumclient-4.5.0/ChangeLog 2024-05-23 10:01:02.000000000 +0200
@@ -1,6 +1,15 @@
CHANGES
=======
+4.5.0
+-----
+
+* Display project\_id for cluster template
+* Replace deprecated inspector.getargspec
+* Always use io module
+* reno: Update master for unmaintained/zed
+* Update master for stable/2024.1
+
4.4.0
-----
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-magnumclient-4.4.0/PKG-INFO new/python-magnumclient-4.5.0/PKG-INFO
--- old/python-magnumclient-4.4.0/PKG-INFO 2024-03-01 14:53:30.683074000 +0100
+++ new/python-magnumclient-4.5.0/PKG-INFO 2024-05-23 10:01:02.220143300 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.2
Name: python-magnumclient
-Version: 4.4.0
+Version: 4.5.0
Summary: Client library for Magnum API
Home-page: https://docs.openstack.org/python-magnumclient/latest/
Author: OpenStack
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-magnumclient-4.4.0/magnumclient/common/cliutils.py new/python-magnumclient-4.5.0/magnumclient/common/cliutils.py
--- old/python-magnumclient-4.4.0/magnumclient/common/cliutils.py 2024-03-01 14:53:06.000000000 +0100
+++ new/python-magnumclient-4.5.0/magnumclient/common/cliutils.py 2024-05-23 10:00:32.000000000 +0200
@@ -89,7 +89,7 @@
:param arg: the positional arguments supplied
:param kwargs: the keyword arguments supplied
"""
- argspec = inspect.getargspec(fn)
+ argspec = inspect.getfullargspec(fn)
num_defaults = len(argspec.defaults or [])
required_args = argspec.args[:len(argspec.args) - num_defaults]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-magnumclient-4.4.0/magnumclient/osc/v1/cluster_templates.py new/python-magnumclient-4.5.0/magnumclient/osc/v1/cluster_templates.py
--- old/python-magnumclient-4.4.0/magnumclient/osc/v1/cluster_templates.py 2024-03-01 14:53:06.000000000 +0100
+++ new/python-magnumclient-4.5.0/magnumclient/osc/v1/cluster_templates.py 2024-05-23 10:00:32.000000000 +0200
@@ -52,6 +52,7 @@
'flavor_id',
'master_lb_enabled',
'dns_nameserver',
+ 'project_id',
'hidden',
'tags',
]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-magnumclient-4.4.0/magnumclient/tests/osc/unit/v1/fakes.py new/python-magnumclient-4.5.0/magnumclient/tests/osc/unit/v1/fakes.py
--- old/python-magnumclient-4.4.0/magnumclient/tests/osc/unit/v1/fakes.py 2024-03-01 14:53:06.000000000 +0100
+++ new/python-magnumclient-4.5.0/magnumclient/tests/osc/unit/v1/fakes.py 2024-05-23 10:00:32.000000000 +0200
@@ -185,6 +185,7 @@
'flavor_id': 'm1.medium',
'master_lb_enabled': False,
'dns_nameserver': '8.8.8.8',
+ 'project_id': uuid.uuid4().hex,
'hidden': False,
'tags': "",
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-magnumclient-4.4.0/magnumclient/tests/osc/unit/v1/test_clusters.py new/python-magnumclient-4.5.0/magnumclient/tests/osc/unit/v1/test_clusters.py
--- old/python-magnumclient-4.4.0/magnumclient/tests/osc/unit/v1/test_clusters.py 2024-03-01 14:53:06.000000000 +0100
+++ new/python-magnumclient-4.5.0/magnumclient/tests/osc/unit/v1/test_clusters.py 2024-05-23 10:00:32.000000000 +0200
@@ -14,16 +14,13 @@
#
import copy
+from io import StringIO
import os
import sys
import tempfile
from unittest import mock
from contextlib import contextmanager
-try:
- from StringIO import StringIO
-except ImportError:
- from io import StringIO
from unittest.mock import call
from magnumclient import exceptions
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-magnumclient-4.4.0/python_magnumclient.egg-info/PKG-INFO new/python-magnumclient-4.5.0/python_magnumclient.egg-info/PKG-INFO
--- old/python-magnumclient-4.4.0/python_magnumclient.egg-info/PKG-INFO 2024-03-01 14:53:30.000000000 +0100
+++ new/python-magnumclient-4.5.0/python_magnumclient.egg-info/PKG-INFO 2024-05-23 10:01:02.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.2
Name: python-magnumclient
-Version: 4.4.0
+Version: 4.5.0
Summary: Client library for Magnum API
Home-page: https://docs.openstack.org/python-magnumclient/latest/
Author: OpenStack
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-magnumclient-4.4.0/python_magnumclient.egg-info/SOURCES.txt new/python-magnumclient-4.5.0/python_magnumclient.egg-info/SOURCES.txt
--- old/python-magnumclient-4.4.0/python_magnumclient.egg-info/SOURCES.txt 2024-03-01 14:53:30.000000000 +0100
+++ new/python-magnumclient-4.5.0/python_magnumclient.egg-info/SOURCES.txt 2024-05-23 10:01:02.000000000 +0200
@@ -113,6 +113,7 @@
releasenotes/notes/partial_osc_implementation_for_quotas-33f44c0496d721f8.yaml
releasenotes/source/2023.1.rst
releasenotes/source/2023.2.rst
+releasenotes/source/2024.1.rst
releasenotes/source/conf.py
releasenotes/source/index.rst
releasenotes/source/rocky.rst
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-magnumclient-4.4.0/python_magnumclient.egg-info/pbr.json new/python-magnumclient-4.5.0/python_magnumclient.egg-info/pbr.json
--- old/python-magnumclient-4.4.0/python_magnumclient.egg-info/pbr.json 2024-03-01 14:53:30.000000000 +0100
+++ new/python-magnumclient-4.5.0/python_magnumclient.egg-info/pbr.json 2024-05-23 10:01:02.000000000 +0200
@@ -1 +1 @@
-{"git_version": "5e478d4", "is_release": true}
\ No newline at end of file
+{"git_version": "feb8cbb", "is_release": true}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-magnumclient-4.4.0/releasenotes/source/2024.1.rst new/python-magnumclient-4.5.0/releasenotes/source/2024.1.rst
--- old/python-magnumclient-4.4.0/releasenotes/source/2024.1.rst 1970-01-01 01:00:00.000000000 +0100
+++ new/python-magnumclient-4.5.0/releasenotes/source/2024.1.rst 2024-05-23 10:00:32.000000000 +0200
@@ -0,0 +1,6 @@
+===========================
+2024.1 Series Release Notes
+===========================
+
+.. release-notes::
+ :branch: stable/2024.1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-magnumclient-4.4.0/releasenotes/source/index.rst new/python-magnumclient-4.5.0/releasenotes/source/index.rst
--- old/python-magnumclient-4.4.0/releasenotes/source/index.rst 2024-03-01 14:53:06.000000000 +0100
+++ new/python-magnumclient-4.5.0/releasenotes/source/index.rst 2024-05-23 10:00:32.000000000 +0200
@@ -6,6 +6,7 @@
:maxdepth: 1
unreleased
+ 2024.1
2023.2
2023.1
zed
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-magnumclient-4.4.0/releasenotes/source/zed.rst new/python-magnumclient-4.5.0/releasenotes/source/zed.rst
--- old/python-magnumclient-4.4.0/releasenotes/source/zed.rst 2024-03-01 14:53:06.000000000 +0100
+++ new/python-magnumclient-4.5.0/releasenotes/source/zed.rst 2024-05-23 10:00:32.000000000 +0200
@@ -3,4 +3,4 @@
========================
.. release-notes::
- :branch: stable/zed
+ :branch: unmaintained/zed
1
0