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
December 2020
- 1 participants
- 2154 discussions
01 Dec '20
Hello community,
here is the log from the commit of package python-iminuit for openSUSE:Factory checked in at 2020-12-01 14:23:13
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-iminuit (Old)
and /work/SRC/openSUSE:Factory/.python-iminuit.new.5913 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-iminuit"
Tue Dec 1 14:23:13 2020 rev:6 rq:851910 version:1.5.4
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-iminuit/python-iminuit.changes 2020-11-03 15:16:43.216048969 +0100
+++ /work/SRC/openSUSE:Factory/.python-iminuit.new.5913/python-iminuit.changes 2020-12-01 14:23:25.237634471 +0100
@@ -1,0 +2,26 @@
+Sun Nov 29 17:18:42 UTC 2020 - Atri Bhattacharya <badshah400(a)gmail.com>
+
+- Update to version 1.5.4:
+ Fixed broken sdist package in 1.5.3
+- Changes from version 1.5.3:
+ * Fixed a crash when throw_nan=True is used and the throw is
+ triggered.
+ * Add python_requires (gh#scikit-hep/iminuit#496) by @henryiii.
+ * Fixed buggy display of text matrix if npar != 2
+ (gh#scikit-hep/iminuit#493).
+ * Switch extern Minuit2 repo to official root repo
+ (gh#scikit-hep/iminuit#500), ROOT state: a5d880a434.
+ * Add ngrad and ngrad_total to FMin display, rename ncalls to
+ nfcn_total (gh#scikit-hep/iminuit#489).
+ * Use __getattr__ to hide deprecated interface from Python
+ help() (gh#scikit-hep/iminuit#491).
+ * Improvements to tutorials by @giammi56.
+ * Show number of gradient calls in FMin display (if nonzero)
+ instead of errordef value.
+ * Deprecated:
+ - Minuit.ncalls, use Minuit.nfcn instead
+ - Minuit.ngrads, use Minuit.ngrad instead
+
+
+
+-------------------------------------------------------------------
Old:
----
iminuit-1.5.2.tar.gz
New:
----
iminuit-1.5.4.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-iminuit.spec ++++++
--- /var/tmp/diff_new_pack.2r1z3l/_old 2020-12-01 14:23:25.877635163 +0100
+++ /var/tmp/diff_new_pack.2r1z3l/_new 2020-12-01 14:23:25.881635168 +0100
@@ -20,7 +20,7 @@
# Python2 support dropped since version 1.4.0
%define skip_python2 1
Name: python-iminuit
-Version: 1.5.2
+Version: 1.5.4
Release: 0
Summary: Python bindings for MINUIT2
License: MIT
++++++ iminuit-1.5.2.tar.gz -> iminuit-1.5.4.tar.gz ++++++
++++ 79608 lines of diff (skipped)
1
0
01 Dec '20
Hello community,
here is the log from the commit of package python-httmock for openSUSE:Factory checked in at 2020-12-01 14:23:11
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-httmock (Old)
and /work/SRC/openSUSE:Factory/.python-httmock.new.5913 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-httmock"
Tue Dec 1 14:23:11 2020 rev:4 rq:851912 version:1.4.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-httmock/python-httmock.changes 2019-03-05 12:23:31.792874220 +0100
+++ /work/SRC/openSUSE:Factory/.python-httmock.new.5913/python-httmock.changes 2020-12-01 14:23:24.365633527 +0100
@@ -1,0 +2,6 @@
+Sun Nov 29 19:33:50 UTC 2020 - ecsos <ecsos(a)opensuse.org>
+
+- Update to 1.4.0:
+ - No changelog from upstream.
+
+-------------------------------------------------------------------
Old:
----
1.3.0.tar.gz
New:
----
1.4.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-httmock.spec ++++++
--- /var/tmp/diff_new_pack.psB8XH/_old 2020-12-01 14:23:24.917634125 +0100
+++ /var/tmp/diff_new_pack.psB8XH/_new 2020-12-01 14:23:24.917634125 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-httmock
#
-# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2020 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -18,12 +18,12 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-httmock
-Version: 1.3.0
+Version: 1.4.0
Release: 0
Summary: A mocking library for requests
License: Apache-2.0
Group: Development/Languages/Python
-Url: https://github.com/patrys/httmock
+URL: https://github.com/patrys/httmock
Source: https://github.com/patrys/httmock/archive/%{version}.tar.gz
BuildRequires: %{python_module setuptools}
BuildRequires: fdupes
++++++ 1.3.0.tar.gz -> 1.4.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httmock-1.3.0/.travis.yml new/httmock-1.4.0/.travis.yml
--- old/httmock-1.3.0/.travis.yml 2019-01-28 18:19:10.000000000 +0100
+++ new/httmock-1.4.0/.travis.yml 2020-10-28 13:00:08.000000000 +0100
@@ -1,3 +1,7 @@
+os: linux
+arch:
+ - amd64
+ - ppc64le
language: python
python:
- 2.7
@@ -5,6 +9,12 @@
- 3.4
- 3.5
- 3.6
+ - 3.7
+ - 3.8
+jobs:
+ exclude:
+ - arch: ppc64le
+ python: pypy
install:
- "pip install requests"
script: nosetests
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httmock-1.3.0/httmock.py new/httmock-1.4.0/httmock.py
--- old/httmock-1.3.0/httmock.py 2019-01-28 18:19:10.000000000 +0100
+++ new/httmock-1.4.0/httmock.py 2020-10-28 13:00:08.000000000 +0100
@@ -14,10 +14,7 @@
if sys.version_info >= (3, 0, 0):
from io import BytesIO
else:
- try:
- from cStringIO import StringIO as BytesIO
- except ImportError:
- from StringIO import StringIO as BytesIO
+ from StringIO import StringIO as BytesIO
binary_type = bytes
@@ -39,7 +36,7 @@
def response(status_code=200, content='', headers=None, reason=None, elapsed=0,
- request=None, stream=False):
+ request=None, stream=False, http_vsn=11):
res = requests.Response()
res.status_code = status_code
if isinstance(content, (dict, list)):
@@ -64,6 +61,7 @@
res.raw = BytesIO(content)
else:
res.raw = BytesIO(b'')
+ res.raw.version = http_vsn
# normally this closes the underlying connection,
# but we have nothing to free.
@@ -194,7 +192,7 @@
response = history.pop()
response.history = tuple(history)
- session.cookies = response.cookies
+ session.cookies.update(response.cookies)
return response
@@ -231,7 +229,8 @@
res.get('reason'),
res.get('elapsed', 0),
request,
- stream=kwargs.get('stream', False))
+ stream=kwargs.get('stream', False),
+ http_vsn=res.get('http_vsn', 11))
elif isinstance(res, (text_type, binary_type)):
return response(content=res, stream=kwargs.get('stream', False))
elif res is None:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httmock-1.3.0/setup.py new/httmock-1.4.0/setup.py
--- old/httmock-1.3.0/setup.py 2019-01-28 18:19:10.000000000 +0100
+++ new/httmock-1.4.0/setup.py 2020-10-28 13:00:08.000000000 +0100
@@ -3,15 +3,12 @@
from setuptools import setup
import os
-LICENSE = open(
- os.path.join(os.path.dirname(__file__), 'LICENSE')).read().strip()
-
DESCRIPTION = open(
os.path.join(os.path.dirname(__file__), 'README.md')).read().strip()
setup(
name='httmock',
- version='1.3.0',
+ version='1.4.0',
description='A mocking library for requests.',
author='Patryk Zawadzki',
author_email='patrys(a)room-303.com',
@@ -22,9 +19,11 @@
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 3',
'Intended Audience :: Developers',
+ 'License :: OSI Approved :: Apache Software License',
'Topic :: Software Development :: Testing',
'Operating System :: OS Independent'],
install_requires=['requests >= 1.0.0'],
- license=LICENSE,
+ license='Apache-2.0',
long_description=DESCRIPTION,
+ long_description_content_type='text/markdown',
test_suite='tests')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/httmock-1.3.0/tests.py new/httmock-1.4.0/tests.py
--- old/httmock-1.3.0/tests.py 2019-01-28 18:19:10.000000000 +0100
+++ new/httmock-1.4.0/tests.py 2020-10-28 13:00:08.000000000 +0100
@@ -66,7 +66,8 @@
def dict_any_mock(url, request):
return {
'content': 'Hello from %s' % (url.netloc,),
- 'status_code': 200
+ 'status_code': 200,
+ 'http_vsn': 10,
}
@@ -136,6 +137,13 @@
self.assertEqual(r.text, u'Motörhead')
self.assertEqual(r.content, r.text.encode('utf-8'))
+ def test_has_raw_version(self):
+ with HTTMock(any_mock):
+ r = requests.get('http://example.com')
+ self.assertEqual(r.raw.version, 11)
+ with HTTMock(dict_any_mock):
+ r = requests.get('http://example.com')
+ self.assertEqual(r.raw.version, 10)
class DecoratorTest(unittest.TestCase):
@@ -242,6 +250,11 @@
r = response(200, None, {'Content-Type': 'application/json'})
self.assertEqual(r.headers['content-type'], 'application/json')
+ def test_response_raw_version(self):
+ r = response(200, None, {'Content-Type': 'application/json'},
+ http_vsn=10)
+ self.assertEqual(r.raw.version, 10)
+
def test_response_cookies(self):
@all_requests
def response_content(url, request):
@@ -268,6 +281,18 @@
self.assertTrue('foo' in session.cookies)
self.assertEqual(session.cookies['foo'], 'bar')
+ def test_session_persistent_cookies(self):
+ session = requests.Session()
+ with HTTMock(lambda u, r: response(200, 'Foo', {'Set-Cookie': 'foo=bar;'}, request=r)):
+ session.get('https://foo_bar')
+ with HTTMock(lambda u, r: response(200, 'Baz', {'Set-Cookie': 'baz=qux;'}, request=r)):
+ session.get('https://baz_qux')
+ self.assertEqual(len(session.cookies), 2)
+ self.assertTrue('foo' in session.cookies)
+ self.assertEqual(session.cookies['foo'], 'bar')
+ self.assertTrue('baz' in session.cookies)
+ self.assertEqual(session.cookies['baz'], 'qux')
+
def test_python_version_encoding_differences(self):
# Previous behavior would result in this test failing in Python3 due
# to how requests checks for utf-8 JSON content in requests.utils with:
@@ -341,7 +366,7 @@
results = self.several_calls(
1, requests.get, 'http://facebook.com/')
- self.assertEquals(facebook_mock_count.call['count'], 1)
+ self.assertEqual(facebook_mock_count.call['count'], 1)
@with_httmock(google_mock_count, facebook_mock_count)
def test_several_call_decorated(self):
@@ -357,7 +382,7 @@
self.assertEqual(r.content, b'Hello from Facebook')
self.several_calls(1, requests.get, 'http://facebook.com/')
- self.assertEquals(facebook_mock_count.call['count'], 4)
+ self.assertEqual(facebook_mock_count.call['count'], 4)
def test_store_several_requests(self):
with HTTMock(google_mock_store_requests):
1
0
01 Dec '20
Hello community,
here is the log from the commit of package python-uvicorn for openSUSE:Factory checked in at 2020-12-01 14:23:10
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-uvicorn (Old)
and /work/SRC/openSUSE:Factory/.python-uvicorn.new.5913 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-uvicorn"
Tue Dec 1 14:23:10 2020 rev:3 rq:851909 version:0.12.3
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-uvicorn/python-uvicorn.changes 2020-10-20 16:23:40.994386903 +0200
+++ /work/SRC/openSUSE:Factory/.python-uvicorn.new.5913/python-uvicorn.changes 2020-12-01 14:23:23.321632398 +0100
@@ -1,0 +2,20 @@
+Sun Nov 29 09:56:12 UTC 2020 - John Vandenberg <jayvdb(a)gmail.com>
+
+- Skip three tests due to minor change introduced in wsproto 1.0.0
+- Add some missing minimum versions to Requires and BuildRequires
+- Update to v0.12.3
+ * Fix race condition that leads Quart to hang
+ * Use latin1 when decoding X-Forwarded-* headers
+ * Rework IPv6 support
+ * Cancel old keepalive-trigger before setting new one
+- from v0.12.2
+ * Adding ability to decrypt ssl key file
+ * Support .yml log config files
+ * Added python 3.9 support
+ * Fixes watchgod with common prefixes
+ * Fix reload with ipv6 host
+ * Added cli support for headers containing colon
+ * Sharing socket across workers on windows
+ * Note the need to configure trusted "ips" when using unix sockets
+
+-------------------------------------------------------------------
Old:
----
uvicorn-0.12.1.tar.gz
New:
----
uvicorn-0.12.3.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-uvicorn.spec ++++++
--- /var/tmp/diff_new_pack.Vj2tRw/_old 2020-12-01 14:23:23.889633012 +0100
+++ /var/tmp/diff_new_pack.Vj2tRw/_new 2020-12-01 14:23:23.893633017 +0100
@@ -19,7 +19,7 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
%define skip_python2 1
Name: python-uvicorn
-Version: 0.12.1
+Version: 0.12.3
Release: 0
Summary: An Asynchronous Server Gateway Interface server
License: BSD-3-Clause
@@ -31,29 +31,30 @@
BuildRequires: python-rpm-macros
Requires: python-click >= 7.0
Requires: python-h11 >= 0.8.0
-Requires: python-httptools >= 0.0.13
+Requires: python-httptools >= 0.1.0
Requires: python-typing_extensions
Requires: python-websockets >= 8.0
-Recommends: python-PyYAML
+Recommends: python-PyYAML >= 5.1
Suggests: python-uvloop >= 0.14.0
-Suggests: python-watchgod
-Suggests: python-wsproto
+Suggests: python-watchgod >= 0.6
+Suggests: python-wsproto >= 0.15.0
Requires(post): update-alternatives
Requires(postun): update-alternatives
BuildArch: noarch
# SECTION test requirements
-BuildRequires: %{python_module PyYAML}
+BuildRequires: %{python_module PyYAML >= 5.1}
BuildRequires: %{python_module click >= 7.0}
BuildRequires: %{python_module h11 >= 0.8.0}
-BuildRequires: %{python_module httptools >= 0.0.13}
+BuildRequires: %{python_module httptools >= 0.1.0}
BuildRequires: %{python_module pytest-mock}
BuildRequires: %{python_module pytest}
BuildRequires: %{python_module requests}
+BuildRequires: %{python_module trustme}
BuildRequires: %{python_module typing_extensions}
BuildRequires: %{python_module uvloop >= 0.14.0}
BuildRequires: %{python_module watchgod >= 0.6}
BuildRequires: %{python_module websockets >= 8.0}
-BuildRequires: %{python_module wsproto >= 0.13.0}
+BuildRequires: %{python_module wsproto >= 0.15.0}
# /SECTION
%python_subpackages
@@ -80,7 +81,11 @@
%python_uninstall_alternative uvicorn
%check
-%pytest
+# Required for reporting bugs
+%python_exec -m uvicorn --version
+# Three wsproto upgrade related tests
+# https://github.com/encode/uvicorn/issues/868
+%pytest -rs -k 'not (test_supported_upgrade_request or test_invalid_upgrade)'
%files %{python_files}
%doc README.md
++++++ uvicorn-0.12.1.tar.gz -> uvicorn-0.12.3.tar.gz ++++++
++++ 2000 lines of diff (skipped)
1
0
01 Dec '20
Hello community,
here is the log from the commit of package python-aiosmtplib for openSUSE:Factory checked in at 2020-12-01 14:23:07
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-aiosmtplib (Old)
and /work/SRC/openSUSE:Factory/.python-aiosmtplib.new.5913 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-aiosmtplib"
Tue Dec 1 14:23:07 2020 rev:4 rq:851905 version:1.1.4
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-aiosmtplib/python-aiosmtplib.changes 2020-03-24 22:34:15.009145040 +0100
+++ /work/SRC/openSUSE:Factory/.python-aiosmtplib.new.5913/python-aiosmtplib.changes 2020-12-01 14:23:20.941629823 +0100
@@ -1,0 +2,13 @@
+Sun Nov 29 07:16:07 UTC 2020 - John Vandenberg <jayvdb(a)gmail.com>
+
+- Add docs/*.rst to %doc
+- Remove a test skip that has been resolved upstream
+- Update to v1.1.4
+ * Bugfix: parsing comma separated addresses in to header
+- from v1.1.3
+ * Feature: add pause and resume writing methods to SMTPProcotol,
+ via asyncio.streams.FlowControlMixin
+ * Bugfix: allow an empty sender
+ * Cleanup: more useful error message when login called without TLS
+
+-------------------------------------------------------------------
Old:
----
aiosmtplib-1.1.2.tar.gz
New:
----
aiosmtplib-1.1.4.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-aiosmtplib.spec ++++++
--- /var/tmp/diff_new_pack.QRkP7t/_old 2020-12-01 14:23:21.581630516 +0100
+++ /var/tmp/diff_new_pack.QRkP7t/_new 2020-12-01 14:23:21.585630520 +0100
@@ -19,21 +19,23 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
%define skip_python2 1
Name: python-aiosmtplib
-Version: 1.1.2
+Version: 1.1.4
Release: 0
Summary: Python asyncio SMTP client
License: MIT
Group: Development/Languages/Python
URL: https://github.com/cole/aiosmtplib
Source: https://files.pythonhosted.org/packages/source/a/aiosmtplib/aiosmtplib-%{ve…
-BuildRequires: %{python_module aiosmtpd}
-BuildRequires: %{python_module hypothesis}
-BuildRequires: %{python_module pytest-asyncio}
BuildRequires: %{python_module setuptools}
BuildRequires: fdupes
BuildRequires: python-rpm-macros
Suggests: python-aiosmtpd
BuildArch: noarch
+# SECTION test requirements
+BuildRequires: %{python_module aiosmtpd}
+BuildRequires: %{python_module hypothesis}
+BuildRequires: %{python_module pytest-asyncio}
+# /SECTION
%python_subpackages
%description
@@ -52,11 +54,10 @@
%check
# test_qq_login or test_starttls_gmail are online
-# https://github.com/cole/aiosmtplib/issues/79 for test_send_message_smtputf8_sender
-%pytest -k 'not (test_qq_login or test_starttls_gmail or test_send_message_smtputf8_sender)'
+%pytest -rs -k 'not (test_qq_login or test_starttls_gmail)'
%files %{python_files}
-%doc README.rst
+%doc README.rst docs/*.rst
%license LICENSE.txt
%{python_sitelib}/*
++++++ aiosmtplib-1.1.2.tar.gz -> aiosmtplib-1.1.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiosmtplib-1.1.2/LICENSE.txt new/aiosmtplib-1.1.4/LICENSE.txt
--- old/aiosmtplib-1.1.2/LICENSE.txt 2019-07-30 06:11:42.416175400 +0200
+++ new/aiosmtplib-1.1.4/LICENSE.txt 2020-09-12 19:19:34.795263800 +0200
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2019 Cole Maclean
+Copyright (c) 2020 Cole Maclean
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiosmtplib-1.1.2/PKG-INFO new/aiosmtplib-1.1.4/PKG-INFO
--- old/aiosmtplib-1.1.2/PKG-INFO 1970-01-01 01:00:00.000000000 +0100
+++ new/aiosmtplib-1.1.4/PKG-INFO 2020-09-12 19:20:12.445738000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: aiosmtplib
-Version: 1.1.2
+Version: 1.1.4
Summary: asyncio SMTP client
Home-page: https://github.com/cole/aiosmtplib
License: MIT
@@ -26,7 +26,7 @@
Classifier: Typing :: Typed
Provides-Extra: docs
Provides-Extra: uvloop
-Requires-Dist: sphinx (>=2.0.0,<3.0.0); extra == "docs"
+Requires-Dist: sphinx (>=2,<4); extra == "docs"
Requires-Dist: sphinx_autodoc_typehints (>=1.7.0,<2.0.0); extra == "docs"
Requires-Dist: uvloop (>=0.13,<0.15); extra == "uvloop"
Project-URL: Documentation, https://aiosmtplib.readthedocs.io/en/stable/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiosmtplib-1.1.2/aiosmtplib/__init__.py new/aiosmtplib-1.1.4/aiosmtplib/__init__.py
--- old/aiosmtplib-1.1.2/aiosmtplib/__init__.py 2019-11-12 04:01:21.198798200 +0100
+++ new/aiosmtplib-1.1.4/aiosmtplib/__init__.py 2020-09-12 19:19:34.803263700 +0200
@@ -32,10 +32,10 @@
__title__ = "aiosmtplib"
-__version__ = "1.1.2"
+__version__ = "1.1.4"
__author__ = "Cole Maclean"
__license__ = "MIT"
-__copyright__ = "Copyright 2019 Cole Maclean"
+__copyright__ = "Copyright 2020 Cole Maclean"
__all__ = (
"send",
"SMTP",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiosmtplib-1.1.2/aiosmtplib/api.py new/aiosmtplib-1.1.4/aiosmtplib/api.py
--- old/aiosmtplib-1.1.2/aiosmtplib/api.py 2019-11-12 04:01:21.154114700 +0100
+++ new/aiosmtplib-1.1.4/aiosmtplib/api.py 2020-09-12 19:19:34.807263600 +0200
@@ -1,11 +1,11 @@
"""
Main public API.
"""
+import email.message
import os
import socket
import ssl
import sys
-from email.message import Message
from typing import Dict, List, Optional, Sequence, Tuple, Union, overload
from .response import SMTPResponse
@@ -20,15 +20,17 @@
else:
SocketPathType = Union[str, bytes]
+# flake8: noqa F811
+
# overloaded matrix is split by:
# * message type (Message, str/bytes)
# * connection type (hostname/socket/socket path)
# * cert info (client_cert/tls_context)
-@overload # noqa: F811
+@overload
async def send(
- message: Message,
+ message: Union[email.message.EmailMessage, email.message.Message],
sender: Optional[str] = ...,
recipients: Optional[Union[str, Sequence[str]]] = ...,
hostname: str = ...,
@@ -52,7 +54,7 @@
...
-@overload # noqa: F811
+@overload
async def send(
message: Union[str, bytes],
sender: str = ...,
@@ -78,9 +80,9 @@
...
-@overload # noqa: F811
+@overload
async def send(
- message: Message,
+ message: Union[email.message.EmailMessage, email.message.Message],
sender: Optional[str] = ...,
recipients: Optional[Union[str, Sequence[str]]] = ...,
hostname: str = ...,
@@ -104,7 +106,7 @@
...
-@overload # noqa: F811
+@overload
async def send(
message: Union[str, bytes],
sender: str = ...,
@@ -130,9 +132,9 @@
...
-@overload # noqa: F811
+@overload
async def send(
- message: Message,
+ message: Union[email.message.EmailMessage, email.message.Message],
sender: Optional[str] = ...,
recipients: Optional[Union[str, Sequence[str]]] = ...,
hostname: None = ...,
@@ -156,7 +158,7 @@
...
-@overload # noqa: F811
+@overload
async def send(
message: Union[str, bytes],
sender: str = ...,
@@ -182,9 +184,9 @@
...
-@overload # noqa: F811
+@overload
async def send(
- message: Message,
+ message: Union[email.message.EmailMessage, email.message.Message],
sender: Optional[str] = ...,
recipients: Optional[Union[str, Sequence[str]]] = ...,
hostname: None = ...,
@@ -208,7 +210,7 @@
...
-@overload # noqa: F811
+@overload
async def send(
message: Union[str, bytes],
sender: str = ...,
@@ -234,9 +236,9 @@
...
-@overload # noqa: F811
+@overload
async def send(
- message: Message,
+ message: Union[email.message.EmailMessage, email.message.Message],
sender: Optional[str] = ...,
recipients: Optional[Union[str, Sequence[str]]] = ...,
hostname: None = ...,
@@ -260,7 +262,7 @@
...
-@overload # noqa: F811
+@overload
async def send(
message: Union[str, bytes],
sender: str = ...,
@@ -286,9 +288,9 @@
...
-@overload # noqa: F811
+@overload
async def send(
- message: Message,
+ message: Union[email.message.EmailMessage, email.message.Message],
sender: Optional[str] = ...,
recipients: Optional[Union[str, Sequence[str]]] = ...,
hostname: None = ...,
@@ -312,7 +314,7 @@
...
-@overload # noqa: F811
+@overload
async def send(
message: Union[str, bytes],
sender: str = ...,
@@ -338,7 +340,7 @@
...
-async def send(message, sender=None, recipients=None, **kwargs): # noqa: F811
+async def send(message, sender=None, recipients=None, **kwargs):
"""
Send an email message. On await, connects to the SMTP server using the details
provided, sends the message, then disconnects.
@@ -383,7 +385,7 @@
:raises ValueError: required arguments missing or mutually exclusive options
provided
"""
- if not isinstance(message, Message):
+ if not isinstance(message, (email.message.EmailMessage, email.message.Message)):
if not recipients:
raise ValueError("Recipients must be provided with raw messages.")
if not sender:
@@ -392,7 +394,7 @@
client = SMTP(**kwargs)
async with client:
- if isinstance(message, Message):
+ if isinstance(message, (email.message.EmailMessage, email.message.Message)):
result = await client.send_message(
message, sender=sender, recipients=recipients
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiosmtplib-1.1.2/aiosmtplib/auth.py new/aiosmtplib-1.1.4/aiosmtplib/auth.py
--- old/aiosmtplib-1.1.2/aiosmtplib/auth.py 2019-11-12 04:01:21.156599000 +0100
+++ new/aiosmtplib-1.1.4/aiosmtplib/auth.py 2020-09-12 19:19:34.807263600 +0200
@@ -56,7 +56,14 @@
await self._ehlo_or_helo_if_needed()
if not self.supports_extension("auth"):
- raise SMTPException("SMTP AUTH extension not supported by server.")
+ if self.is_connected and self.get_transport_info("sslcontext") is None:
+ raise SMTPException(
+ "The SMTP AUTH extension is not supported by this server. Try "
+ "connecting via TLS (or STARTTLS)."
+ )
+ raise SMTPException(
+ "The SMTP AUTH extension is not supported by this server."
+ )
response = None # type: Optional[SMTPResponse]
exception = None # type: Optional[SMTPAuthenticationError]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiosmtplib-1.1.2/aiosmtplib/connection.py new/aiosmtplib-1.1.4/aiosmtplib/connection.py
--- old/aiosmtplib-1.1.2/aiosmtplib/connection.py 2019-11-12 04:01:21.157382000 +0100
+++ new/aiosmtplib-1.1.4/aiosmtplib/connection.py 2020-09-12 19:19:34.815263700 +0200
@@ -7,7 +7,7 @@
import ssl
import sys
import warnings
-from typing import Any, Optional, Type, Union, cast
+from typing import Any, Optional, Type, Union
from .compat import create_connection, create_unix_connection, get_running_loop
from .default import Default, _default
@@ -194,7 +194,7 @@
This method can be called multiple times.
"""
if hostname is not _default:
- self.hostname = cast(Optional[str], hostname)
+ self.hostname = hostname
if loop is not _default:
if loop is not None:
warnings.warn(
@@ -203,7 +203,7 @@
DeprecationWarning,
stacklevel=3,
)
- self.loop = cast(Optional[asyncio.AbstractEventLoop], loop)
+ self.loop = loop
if use_tls is not None:
self.use_tls = use_tls
if start_tls is not None:
@@ -211,28 +211,28 @@
if validate_certs is not None:
self.validate_certs = validate_certs
if port is not _default:
- self.port = cast(Optional[int], port)
+ self.port = port
if username is not _default:
- self._login_username = cast(Optional[str], username)
+ self._login_username = username
if password is not _default:
- self._login_password = cast(Optional[str], password)
+ self._login_password = password
if timeout is not _default:
- self.timeout = cast(Optional[float], timeout)
+ self.timeout = timeout
if source_address is not _default:
- self._source_address = cast(Optional[str], source_address)
+ self._source_address = source_address
if client_cert is not _default:
- self.client_cert = cast(Optional[str], client_cert)
+ self.client_cert = client_cert
if client_key is not _default:
- self.client_key = cast(Optional[str], client_key)
+ self.client_key = client_key
if tls_context is not _default:
- self.tls_context = cast(Optional[ssl.SSLContext], tls_context)
+ self.tls_context = tls_context
if cert_bundle is not _default:
- self.cert_bundle = cast(Optional[str], cert_bundle)
+ self.cert_bundle = cert_bundle
if socket_path is not _default:
- self.socket_path = cast(Optional[SocketPathType], socket_path)
+ self.socket_path = socket_path
if sock is not _default:
- self.sock = cast(Optional[socket.socket], sock)
+ self.sock = sock
def _validate_config(self) -> None:
if self._start_tls_on_connect and self.use_tls:
@@ -364,7 +364,7 @@
try:
transport, _ = await asyncio.wait_for(connect_coro, timeout=self.timeout)
- except (ConnectionRefusedError, OSError) as exc:
+ except OSError as exc:
raise SMTPConnectError(
"Error connecting to {host} on port {port}: {err}".format(
host=self.hostname, port=self.port, err=exc
@@ -416,7 +416,6 @@
if timeout is _default:
timeout = self.timeout
- timeout = cast(Optional[float], timeout)
response = await self.protocol.execute_command(*args, timeout=timeout)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiosmtplib-1.1.2/aiosmtplib/email.py new/aiosmtplib-1.1.4/aiosmtplib/email.py
--- old/aiosmtplib-1.1.2/aiosmtplib/email.py 2019-11-12 04:01:21.160953000 +0100
+++ new/aiosmtplib-1.1.4/aiosmtplib/email.py 2020-09-12 19:19:34.819263700 +0200
@@ -72,7 +72,9 @@
def flatten_message(
- message: email.message.Message, utf8: bool = False, cte_type: str = "8bit"
+ message: Union[email.message.EmailMessage, email.message.Message],
+ utf8: bool = False,
+ cte_type: str = "8bit",
) -> bytes:
# Make a local copy so we can delete the bcc headers.
message_copy = copy.copy(message)
@@ -119,12 +121,14 @@
charset = "ascii"
addresses.append(parse_address(str(address_bytes, encoding=charset)))
else:
- addresses.append(parse_address(header))
+ addresses.extend(addr for _, addr in email.utils.getaddresses([header]))
return addresses
-def extract_sender(message: email.message.Message) -> Optional[str]:
+def extract_sender(
+ message: Union[email.message.EmailMessage, email.message.Message]
+) -> Optional[str]:
"""
Extract the sender from the message object given.
"""
@@ -151,7 +155,9 @@
return extract_addresses(sender_header)[0]
-def extract_recipients(message: email.message.Message) -> List[str]:
+def extract_recipients(
+ message: Union[email.message.EmailMessage, email.message.Message]
+) -> List[str]:
"""
Extract the recipients from the message object given.
"""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiosmtplib-1.1.2/aiosmtplib/esmtp.py new/aiosmtplib-1.1.4/aiosmtplib/esmtp.py
--- old/aiosmtplib-1.1.2/aiosmtplib/esmtp.py 2019-11-12 04:01:21.162656800 +0100
+++ new/aiosmtplib-1.1.4/aiosmtplib/esmtp.py 2020-09-12 19:19:34.823263600 +0200
@@ -3,7 +3,7 @@
"""
import re
import ssl
-from typing import Dict, Iterable, List, Optional, Tuple, Union, cast
+from typing import Dict, Iterable, List, Optional, Tuple, Union
from .connection import SMTPConnection
from .default import Default, _default
@@ -324,7 +324,6 @@
if timeout is _default:
timeout = self.timeout
- timeout = cast(Optional[float], timeout)
if isinstance(message, str):
message = message.encode("ascii")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiosmtplib-1.1.2/aiosmtplib/protocol.py new/aiosmtplib-1.1.4/aiosmtplib/protocol.py
--- old/aiosmtplib-1.1.2/aiosmtplib/protocol.py 2019-11-12 04:01:21.163550400 +0100
+++ new/aiosmtplib-1.1.4/aiosmtplib/protocol.py 2020-09-12 19:19:34.823263600 +0200
@@ -26,13 +26,76 @@
PERIOD_REGEX = re.compile(rb"(?m)^\.")
-class SMTPProtocol(asyncio.Protocol):
+class FlowControlMixin(asyncio.Protocol):
+ """
+ Reusable flow control logic for StreamWriter.drain().
+ This implements the protocol methods pause_writing(),
+ resume_writing() and connection_lost(). If the subclass overrides
+ these it must call the super methods.
+ StreamWriter.drain() must wait for _drain_helper() coroutine.
+
+ Copied from stdlib as per recommendation: https://bugs.python.org/msg343685.
+ Logging and asserts removed, type annotations added.
+ """
+
+ def __init__(self, loop: Optional[asyncio.AbstractEventLoop] = None):
+ if loop is None:
+ self._loop = asyncio.get_event_loop()
+ else:
+ self._loop = loop
+ self._paused = False
+ self._drain_waiter = None # type: Optional[asyncio.Future[None]]
+ self._connection_lost = False
+
+ def pause_writing(self) -> None:
+ self._paused = True
+
+ def resume_writing(self) -> None:
+ self._paused = False
+
+ waiter = self._drain_waiter
+ if waiter is not None:
+ self._drain_waiter = None
+ if not waiter.done():
+ waiter.set_result(None)
+
+ def connection_lost(self, exc) -> None:
+ self._connection_lost = True
+ # Wake up the writer if currently paused.
+ if not self._paused:
+ return
+ waiter = self._drain_waiter
+ if waiter is None:
+ return
+ self._drain_waiter = None
+ if waiter.done():
+ return
+ if exc is None:
+ waiter.set_result(None)
+ else:
+ waiter.set_exception(exc)
+
+ async def _drain_helper(self) -> None:
+ if self._connection_lost:
+ raise ConnectionResetError("Connection lost")
+ if not self._paused:
+ return
+ waiter = self._drain_waiter
+ waiter = self._loop.create_future()
+ self._drain_waiter = waiter
+ await waiter
+
+ def _get_close_waiter(self, stream: asyncio.StreamWriter) -> asyncio.Future:
+ raise NotImplementedError
+
+
+class SMTPProtocol(FlowControlMixin, asyncio.Protocol):
def __init__(
self,
loop: Optional[asyncio.AbstractEventLoop] = None,
connection_lost_callback: Optional[Callable] = None,
) -> None:
- self._loop = loop or asyncio.get_event_loop()
+ super().__init__(loop=loop)
self._over_ssl = False
self._buffer = bytearray()
self._response_waiter = None # type: Optional[asyncio.Future[SMTPResponse]]
@@ -41,6 +104,7 @@
self.transport = None # type: Optional[asyncio.Transport]
self._command_lock = None # type: Optional[asyncio.Lock]
+ self._closed = self._loop.create_future() # type: asyncio.Future[None]
def __del__(self):
waiters = (self._response_waiter, self._connection_lost_waiter)
@@ -49,6 +113,9 @@
# Avoid 'Future exception was never retrieved' warnings
waiter.exception()
+ def _get_close_waiter(self, stream: asyncio.StreamWriter) -> asyncio.Future:
+ return self._closed
+
@property
def is_connected(self) -> bool:
"""
@@ -69,6 +136,8 @@
)
def connection_lost(self, exc: Optional[Exception]) -> None:
+ super().connection_lost(exc)
+
if exc:
smtp_exc = SMTPServerDisconnected("Connection lost")
smtp_exc.__cause__ = exc
@@ -172,7 +241,7 @@
async def read_response(self, timeout: Optional[float] = None) -> SMTPResponse:
"""
- Get a status reponse from the server.
+ Get a status response from the server.
This method must be awaited once per command sent; if multiple commands
are written to the transport without awaiting, response data will be lost.
@@ -186,7 +255,9 @@
raise SMTPServerDisconnected("Connection lost")
try:
- result = await asyncio.wait_for(self._response_waiter, timeout)
+ result = await asyncio.wait_for(
+ self._response_waiter, timeout
+ ) # type: SMTPResponse
except asyncio.TimeoutError as exc:
raise SMTPReadTimeoutError("Timed out waiting for server response") from exc
finally:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiosmtplib-1.1.2/aiosmtplib/py.typed new/aiosmtplib-1.1.4/aiosmtplib/py.typed
--- old/aiosmtplib-1.1.2/aiosmtplib/py.typed 1970-01-01 01:00:00.000000000 +0100
+++ new/aiosmtplib-1.1.4/aiosmtplib/py.typed 2020-09-12 19:19:34.827263600 +0200
@@ -0,0 +1 @@
+This file exists to help mypy (and other tools) find inline type hints. See PR #141 and PEP 561.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiosmtplib-1.1.2/aiosmtplib/smtp.py new/aiosmtplib-1.1.4/aiosmtplib/smtp.py
--- old/aiosmtplib-1.1.2/aiosmtplib/smtp.py 2019-11-12 04:01:21.164341700 +0100
+++ new/aiosmtplib-1.1.4/aiosmtplib/smtp.py 2020-09-12 19:19:34.831263500 +0200
@@ -8,7 +8,7 @@
* :class:`.connection.SMTPConnection` - connection handling
"""
import asyncio
-from email.message import Message
+import email.message
from typing import Dict, Iterable, Optional, Sequence, Tuple, Union
from .auth import SMTPAuth
@@ -35,7 +35,7 @@
Basic usage:
>>> loop = asyncio.get_event_loop()
- >>> smtp = aiosmtplib.SMTP(hostname="127.0.0.1", port=1025, loop=loop)
+ >>> smtp = aiosmtplib.SMTP(hostname="127.0.0.1", port=1025)
>>> loop.run_until_complete(smtp.connect())
(220, ...)
>>> sender = "root@localhost"
@@ -212,7 +212,7 @@
async def send_message(
self,
- message: Message,
+ message: Union[email.message.EmailMessage, email.message.Message],
sender: Optional[str] = None,
recipients: Optional[Union[str, Sequence[str]]] = None,
mail_options: Optional[Iterable[str]] = None,
@@ -251,7 +251,7 @@
if sender is None:
sender = extract_sender(message)
- if not sender:
+ if sender is None:
raise ValueError("No From header provided in message")
if isinstance(recipients, str):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiosmtplib-1.1.2/docs/conf.py new/aiosmtplib-1.1.4/docs/conf.py
--- old/aiosmtplib-1.1.2/docs/conf.py 2019-11-12 04:01:21.165280000 +0100
+++ new/aiosmtplib-1.1.4/docs/conf.py 2020-09-12 19:19:34.843263600 +0200
@@ -17,17 +17,11 @@
# documentation root, use os.path.abspath to make it absolute, like shown here.
import datetime
-import os
import pathlib
import re
-import sys
from typing import Dict, List
-sys.path.insert(0, os.path.abspath("../src"))
-sys.path.insert(0, os.path.abspath("."))
-
-
VERSION_REGEX = r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]'
@@ -182,7 +176,7 @@
)
]
-intersphinx_mapping = {"python": ("https://docs.python.org/3.7", None)}
+intersphinx_mapping = {"python": ("https://docs.python.org/3.8", None)}
html_sidebars = {
"**": ["globaltoc.html", "relations.html", "sourcelink.html", "searchbox.html"]
@@ -191,6 +185,7 @@
nitpick_ignore = [
("py:class", "typing.Tuple"),
("py:class", "concurrent.futures._base.TimeoutError"),
+ ("py:class", "asyncio.exceptions.TimeoutError"),
]
doctest_global_setup = """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiosmtplib-1.1.2/docs/usage.rst new/aiosmtplib-1.1.4/docs/usage.rst
--- old/aiosmtplib-1.1.2/docs/usage.rst 2019-11-07 03:31:35.193945400 +0100
+++ new/aiosmtplib-1.1.4/docs/usage.rst 2020-09-12 19:19:34.855263500 +0200
@@ -16,7 +16,7 @@
For details on creating :py:class:`email.message.EmailMessage` objects, see
`the stdlib documentation examples
-<https://docs.python.org/3.7/library/email.examples.html>`_.
+<https://docs.python.org/3.8/library/email.examples.html>`_.
.. note:: Confusingly, :py:class:`email.message.Message` objects are part of the
legacy email API (prior to Python 3.3), while :py:class:`email.message.EmailMessage`
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiosmtplib-1.1.2/pyproject.toml new/aiosmtplib-1.1.4/pyproject.toml
--- old/aiosmtplib-1.1.2/pyproject.toml 2019-11-12 04:01:21.199175600 +0100
+++ new/aiosmtplib-1.1.4/pyproject.toml 2020-09-12 19:19:34.859263700 +0200
@@ -1,10 +1,10 @@
[build-system]
-requires = ["poetry>=1.0.0b4"]
+requires = ["poetry>=1.0.0"]
build-backend = "poetry.masonry.api"
[tool.poetry]
name = "aiosmtplib"
-version = "1.1.2"
+version = "1.1.4"
description = "asyncio SMTP client"
authors = ["Cole Maclean <hi(a)colemaclean.dev>"]
license = "MIT"
@@ -42,16 +42,17 @@
python = "^3.5.2"
uvloop = { version = ">=0.13,<0.15", optional = true }
-sphinx = { version = "^2.0.0", optional = true }
+sphinx = { version = ">=2,<4", optional = true }
sphinx_autodoc_typehints = { version = "^1.7.0", optional = true }
[tool.poetry.dev-dependencies]
-pytest = "^5.2.2"
-pytest-asyncio = "^0.10.0"
-pytest-cov = "^2.8.1"
-coverage = "^4.5.4"
-hypothesis = "^4.43.8"
+pytest = "^5.4.3"
+pytest-asyncio = "^0.12.0"
+pytest-cov = "^2.9.0"
+coverage = "^5.1"
+hypothesis = "~4.57"
aiosmtpd = "1.2"
+pytest-xdist = "^1.32.0"
[tool.poetry.extras]
docs = ["sphinx", "sphinx_autodoc_typehints"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiosmtplib-1.1.2/setup.py new/aiosmtplib-1.1.4/setup.py
--- old/aiosmtplib-1.1.2/setup.py 1970-01-01 01:00:00.000000000 +0100
+++ new/aiosmtplib-1.1.4/setup.py 2020-09-12 19:20:12.445069300 +0200
@@ -8,12 +8,12 @@
{'': ['*'], 'tests': ['certs/*']}
extras_require = \
-{'docs': ['sphinx>=2.0.0,<3.0.0', 'sphinx_autodoc_typehints>=1.7.0,<2.0.0'],
+{'docs': ['sphinx>=2,<4', 'sphinx_autodoc_typehints>=1.7.0,<2.0.0'],
'uvloop': ['uvloop>=0.13,<0.15']}
setup_kwargs = {
'name': 'aiosmtplib',
- 'version': '1.1.2',
+ 'version': '1.1.4',
'description': 'asyncio SMTP client',
'long_description': 'aiosmtplib\n==========\n\n|circleci| |codecov| |pypi-version| |pypi-python-versions| |pypi-status|\n|pypi-license| |black|\n\n------------\n\naiosmtplib is an asynchronous SMTP client for use with asyncio.\n\nFor documentation, see `Read The Docs`_.\n\nQuickstart\n----------\n\n.. code-block:: python\n\n import asyncio\n from email.message import EmailMessage\n\n import aiosmtplib\n\n message = EmailMessage()\n message["From"] = "root@localhost"\n message["To"] = "somebody(a)example.com"\n message["Subject"] = "Hello World!"\n message.set_content("Sent via aiosmtplib")\n\n loop = asyncio.get_event_loop()\n loop.run_until_complete(aiosmtplib.send(message, hostname="127.0.0.1", port=25))\n\n\nRequirements\n------------\nPython 3.5.2+, compiled with SSL support, is required.\n\n\nBug reporting\n-------------\nBug reports (and feature requests) are welcome via Github issues.\n\n\n\n.. |circleci| image:: https://circleci.com/gh/cole/aiosmtplib/tree/master.svg?style=shield\n :target: https://circleci.com/gh/cole/aiosmtplib/tree/master\n :alt: "aiosmtplib CircleCI build status"\n.. |pypi-version| image:: https://img.shields.io/pypi/v/aiosmtplib.svg\n :target: https://pypi.python.org/pypi/aiosmtplib\n :alt: "aiosmtplib on the Python Package Index"\n.. |pypi-python-versions| image:: https://img.shields.io/pypi/pyversions/aiosmtplib.svg\n.. |pypi-status| image:: https://img.shields.io/pypi/status/aiosmtplib.svg\n.. |pypi-license| image:: https://img.shields.io/pypi/l/aiosmtplib.svg\n.. |codecov| image:: https://codecov.io/gh/cole/aiosmtplib/branch/master/graph/badge.svg\n :target: https://codecov.io/gh/cole/aiosmtplib\n.. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/ambv/black\n :alt: "Code style: black"\n.. _Read The Docs: https://aiosmtplib.readthedocs.io/en/stable/overview.html\n',
'author': 'Cole Maclean',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiosmtplib-1.1.2/tests/conftest.py new/aiosmtplib-1.1.4/tests/conftest.py
--- old/aiosmtplib-1.1.2/tests/conftest.py 2019-11-09 22:05:06.226744000 +0100
+++ new/aiosmtplib-1.1.4/tests/conftest.py 2020-09-12 19:19:34.879263400 +0200
@@ -9,6 +9,7 @@
import socket
import ssl
import sys
+import traceback
from pathlib import Path
import hypothesis
@@ -40,6 +41,10 @@
hypothesis.settings.register_profile("ci", parent=base_settings, max_examples=100)
+class AsyncPytestWarning(pytest.PytestWarning):
+ pass
+
+
def pytest_addoption(parser):
parser.addoption(
"--event-loop",
@@ -72,13 +77,20 @@
@pytest.fixture(scope="function")
def event_loop(request, event_loop_policy):
+ verbosity = request.config.getoption("verbose", default=0)
old_loop = event_loop_policy.get_event_loop()
loop = event_loop_policy.new_event_loop()
event_loop_policy.set_event_loop(loop)
def handle_async_exception(loop, context):
- """Fail on exceptions by default"""
- pytest.fail("{}: {}".format(context["message"], repr(context["exception"])))
+ message = "{}: {}".format(context["message"], repr(context["exception"]))
+ if verbosity > 1:
+ message += "\n"
+ message += "Future: {}".format(repr(context["future"]))
+ message += "\nTraceback:\n"
+ message += "".join(traceback.format_list(context["source_traceback"]))
+
+ request.node.warn(AsyncPytestWarning(message))
loop.set_exception_handler(handle_async_exception)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiosmtplib-1.1.2/tests/smtpd.py new/aiosmtplib-1.1.4/tests/smtpd.py
--- old/aiosmtplib-1.1.2/tests/smtpd.py 2019-09-03 04:09:27.761034500 +0200
+++ new/aiosmtplib-1.1.4/tests/smtpd.py 2020-09-12 19:19:34.879263400 +0200
@@ -38,7 +38,10 @@
async def handle_EHLO(self, server, session, envelope, hostname):
"""Advertise auth login support."""
session.host_name = hostname
- return "250-AUTH LOGIN\r\n250 HELP"
+ if server._tls_protocol:
+ return "250-AUTH LOGIN\r\n250 HELP"
+ else:
+ return "250 HELP"
class TestSMTPD(SMTPD):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiosmtplib-1.1.2/tests/test_auth.py new/aiosmtplib-1.1.4/tests/test_auth.py
--- old/aiosmtplib-1.1.2/tests/test_auth.py 2019-09-03 04:09:27.762322400 +0200
+++ new/aiosmtplib-1.1.4/tests/test_auth.py 2020-09-12 19:19:34.887263500 +0200
@@ -48,9 +48,11 @@
async def test_login_without_extension_raises_error(mock_auth):
mock_auth.esmtp_extensions = {}
- with pytest.raises(SMTPException):
+ with pytest.raises(SMTPException) as excinfo:
await mock_auth.login("username", "bogus")
+ assert "Try connecting via TLS" not in excinfo.value.args[0]
+
async def test_login_unknown_method_raises_error(mock_auth):
mock_auth.AUTH_METHODS = ("fakeauth",)
@@ -179,3 +181,11 @@
with pytest.raises(SMTPAuthenticationError):
await mock_auth.auth_crammd5("username", "bogus")
+
+
+async def test_login_without_starttls_exception(smtp_client, smtpd_server):
+ async with smtp_client:
+ with pytest.raises(SMTPException) as excinfo:
+ await smtp_client.login("test", "test")
+
+ assert "Try connecting via TLS" in excinfo.value.args[0]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiosmtplib-1.1.2/tests/test_email_utils.py new/aiosmtplib-1.1.4/tests/test_email_utils.py
--- old/aiosmtplib-1.1.2/tests/test_email_utils.py 2019-11-07 04:19:54.547639000 +0100
+++ new/aiosmtplib-1.1.4/tests/test_email_utils.py 2020-09-12 19:19:34.899263400 +0200
@@ -155,11 +155,11 @@
"compat32_cc_header,expected_recipients",
(
(
- "Alice Smith <alice(a)example.com>",
+ "Alice Smith <alice(a)example.com>, hackerman(a)email.com",
"Bob <Bob(a)example.com>",
- "Alice Smith <alice(a)example.com>",
+ "Alice Smith <alice(a)example.com>, hackerman(a)email.com",
"Bob <Bob(a)example.com>",
- ["alice(a)example.com", "Bob(a)example.com"],
+ ["alice(a)example.com", "hackerman(a)email.com", "Bob(a)example.com"],
),
(
Address(display_name="Alice Smith", username="alice", domain="example.com"),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiosmtplib-1.1.2/tests/test_live.py new/aiosmtplib-1.1.4/tests/test_live.py
--- old/aiosmtplib-1.1.2/tests/test_live.py 2019-10-16 06:21:56.106305100 +0200
+++ new/aiosmtplib-1.1.4/tests/test_live.py 2020-09-12 19:19:34.907263500 +0200
@@ -4,10 +4,11 @@
These aren't generally run as part of the test suite.
"""
import os
+from email.message import EmailMessage
import pytest
-from aiosmtplib import SMTP, SMTPAuthenticationError, SMTPStatus
+from aiosmtplib import SMTP, SMTPAuthenticationError, SMTPStatus, send
pytestmark = [
@@ -28,6 +29,8 @@
assert response.code == SMTPStatus.completed
assert "smtp.gmail.com at your service" in response.message
+ assert client.server_auth_methods
+
with pytest.raises(SMTPAuthenticationError):
await client.login("test", "test")
@@ -41,3 +44,21 @@
with pytest.raises(SMTPAuthenticationError):
await client.login("test", "test")
+
+
+async def test_office365_auth_send():
+ message = EmailMessage()
+ message["From"] = "user(a)mydomain.com"
+ message["To"] = "somebody(a)example.com"
+ message["Subject"] = "Hello World!"
+ message.set_content("Sent via aiosmtplib")
+
+ with pytest.raises(SMTPAuthenticationError):
+ await send(
+ message,
+ hostname="smtp.office365.com",
+ port=587,
+ start_tls=True,
+ password="test",
+ username="test",
+ )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aiosmtplib-1.1.2/tests/test_sendmail.py new/aiosmtplib-1.1.4/tests/test_sendmail.py
--- old/aiosmtplib-1.1.2/tests/test_sendmail.py 2019-11-03 21:59:55.923034400 +0100
+++ new/aiosmtplib-1.1.4/tests/test_sendmail.py 2020-09-12 19:19:34.915263400 +0200
@@ -13,7 +13,7 @@
SMTPResponseException,
SMTPStatus,
)
-
+from aiosmtplib.email import formataddr
pytestmark = pytest.mark.asyncio()
@@ -370,6 +370,16 @@
await smtp_client.send_message(message)
+async def test_send_message_with_formataddr(smtp_client, smtpd_server, message):
+ message["To"] = formataddr(("æøå", "someotheruser(a)example.com"))
+
+ async with smtp_client:
+ errors, response = await smtp_client.send_message(message)
+
+ assert not errors
+ assert response != ""
+
+
async def test_send_compat32_message_utf8_text_without_smtputf8(
smtp_client, smtpd_server, compat32_message, received_commands, received_messages
):
@@ -422,3 +432,14 @@
"recipient(a)example.com",
"=?utf-8?b?cmXDp2lww6/DqW50IDxyZWNpcGllbnQyQGV4YW1wbGUuY29tPg==?=",
]
+
+
+async def test_sendmail_empty_sender(
+ smtp_client, smtpd_server, recipient_str, message_str
+):
+ async with smtp_client:
+ errors, response = await smtp_client.sendmail("", [recipient_str], message_str)
+
+ assert not errors
+ assert isinstance(errors, dict)
+ assert response != ""
1
0
01 Dec '20
Hello community,
here is the log from the commit of package python-websockets for openSUSE:Factory checked in at 2020-12-01 14:22:57
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-websockets (Old)
and /work/SRC/openSUSE:Factory/.python-websockets.new.5913 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-websockets"
Tue Dec 1 14:22:57 2020 rev:11 rq:851871 version:8.1
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-websockets/python-websockets.changes 2020-02-07 15:55:50.995556956 +0100
+++ /work/SRC/openSUSE:Factory/.python-websockets.new.5913/python-websockets.changes 2020-12-01 14:23:11.505619615 +0100
@@ -1,0 +2,5 @@
+Sat Nov 28 10:59:12 UTC 2020 - John Vandenberg <jayvdb(a)gmail.com>
+
+- Remove Suggest python-asyncio, which is in Python 3 stdlib
+
+-------------------------------------------------------------------
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-websockets.spec ++++++
--- /var/tmp/diff_new_pack.uemIw7/_old 2020-12-01 14:23:13.025621260 +0100
+++ /var/tmp/diff_new_pack.uemIw7/_new 2020-12-01 14:23:13.025621260 +0100
@@ -30,7 +30,6 @@
BuildRequires: %{python_module setuptools}
BuildRequires: fdupes
BuildRequires: python-rpm-macros
-Suggests: python-asyncio
%python_subpackages
%description
@@ -56,6 +55,8 @@
%check
# Test execution speed depends on BS load and architecture, relax
export WEBSOCKETS_TESTS_TIMEOUT_FACTOR=5
+# https://github.com/aaugustin/websockets/issues/855 is an intermittent failure
+# for test_keepalive_ping_does_not_crash_when_connection_lost on s390x
%python_expand PYTHONPATH=%{buildroot}%{$python_sitearch} $python -m unittest
%files %{python_files}
1
0
01 Dec '20
Hello community,
here is the log from the commit of package virt-manager for openSUSE:Factory checked in at 2020-12-01 14:22:55
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/virt-manager (Old)
and /work/SRC/openSUSE:Factory/.virt-manager.new.5913 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "virt-manager"
Tue Dec 1 14:22:55 2020 rev:216 rq:851950 version:3.2.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/virt-manager/virt-manager.changes 2020-11-17 21:26:11.233431480 +0100
+++ /work/SRC/openSUSE:Factory/.virt-manager.new.5913/virt-manager.changes 2020-12-01 14:23:09.773617742 +0100
@@ -1,0 +2,23 @@
+Mon Nov 30 13:39:10 MST 2020 - carnold(a)suse.com
+
+- bsc#1179236 - L3: virt-install: "Error validating install
+ location: invalid literal for int() with base 10" reported by
+ virt-install ref:_00D1igLOd._5001iTe00n:ref
+ virtinst-sap-detection.patch
+
+-------------------------------------------------------------------
+Wed Nov 25 19:00:46 UTC 2020 - Bruce Rogers <brogers(a)suse.com>
+
+- boo#1178141 - Accomodate qemu modularization with respect to v5.2
+ qemu changes, where 3 additional modular shared objects need to
+ be present for spice support. This change simply augments what
+ was done before, adding the additional code to the same patch
+
+-------------------------------------------------------------------
+Fri Nov 20 13:52:33 MST 2020 - carnold(a)suse.com
+
+- bsc#1172340 - Several YaST modules can be started by typing
+ "yast2 $module <tab><tab>"
+ virt-install.rb
+
+-------------------------------------------------------------------
New:
----
virtinst-sap-detection.patch
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ virt-manager.spec ++++++
--- /var/tmp/diff_new_pack.KxQ9dq/_old 2020-12-01 14:23:10.865618922 +0100
+++ /var/tmp/diff_new_pack.KxQ9dq/_new 2020-12-01 14:23:10.869618927 +0100
@@ -72,6 +72,7 @@
Patch175: virtinst-keep-install-iso-attached.patch
Patch176: virtinst-dont-use-special-copy-cpu-features.patch
Patch177: virtinst-set-default-nic.patch
+Patch178: virtinst-sap-detection.patch
BuildArch: noarch
BuildRoot: %{_tmppath}/%{name}-%{version}-build
@@ -196,6 +197,7 @@
%patch175 -p1
%patch176 -p1
%patch177 -p1
+%patch178 -p1
%build
%if %{default_hvs}
++++++ virt-install.rb ++++++
--- /var/tmp/diff_new_pack.KxQ9dq/_old 2020-12-01 14:23:11.009619079 +0100
+++ /var/tmp/diff_new_pack.KxQ9dq/_new 2020-12-01 14:23:11.013619083 +0100
@@ -43,6 +43,11 @@
@details = {}
Builtins.y2milestone("START HERE.")
+ if WFM.Args == ["help"]
+ # Ignore yast help request
+ return :next
+ end
+
if UI.TextMode()
Builtins.y2milestone("Running virt-install in text mode is not supported. Running vm-install instead in command line mode.")
status = UI.RunInTerminal("/usr/bin/vm-install")
++++++ virtinst-graphics-add-check-for-qemu-modules-in-spice-graphic.patch ++++++
--- /var/tmp/diff_new_pack.KxQ9dq/_old 2020-12-01 14:23:11.077619152 +0100
+++ /var/tmp/diff_new_pack.KxQ9dq/_new 2020-12-01 14:23:11.081619156 +0100
@@ -1,6 +1,6 @@
-From 2919f40ac931dce5dedf326f84e83e8c04e1fabe Mon Sep 17 00:00:00 2001
+From dc5e834199e19ad09de17ac13e9834d3f17bd112 Mon Sep 17 00:00:00 2001
From: Bruce Rogers <brogers(a)suse.com>
-Date: Sat, 24 Oct 2020 08:10:29 -0600
+Date: Wed, 25 Nov 2020 10:34:56 -0700
Subject: [PATCH] graphics: add check for qemu modules in spice graphics
detection
@@ -13,30 +13,43 @@
our own detection of whether the qemu modules needed to support the
default guest install using spice, usb redirection, and qxl video are
present.
+With v5.2, some additional qemu modules are also required, so we add
+a separate detection for that version, and add corresponding additional
+module checks.
Signed-off-by: Bruce Rogers <brogers(a)suse.com>
---
- virtinst/devices/graphics.py | 9 +++++++++
- virtinst/support.py | 1 +
- 2 files changed, 10 insertions(+)
+ virtinst/devices/graphics.py | 19 +++++++++++++++++++
+ virtinst/support.py | 2 ++
+ 2 files changed, 21 insertions(+)
Index: virt-manager-3.1.0/virtinst/devices/graphics.py
===================================================================
--- virt-manager-3.1.0.orig/virtinst/devices/graphics.py
+++ virt-manager-3.1.0/virtinst/devices/graphics.py
-@@ -135,6 +135,15 @@ class DeviceGraphics(Device):
+@@ -135,6 +135,25 @@ class DeviceGraphics(Device):
# Spice has issues on some host arches, like ppc, so allow it
if self.conn.caps.host.cpu.arch not in ["i686", "x86_64"]:
return False
-+ if self.conn.support.conn_spice_modular():
++ if self.conn.support.conn_spice_modular1():
+ if self.conn.caps.host.cpu.arch in ["x86_64"]:
+ if not (os.path.exists("/usr/lib64/qemu/hw-usb-redirect.so") and
+ os.path.exists("/usr/lib64/qemu/hw-display-qxl.so")):
+ return False
++ if self.conn.support.conn_spice_modular2():
++ if not (os.path.exists("/usr/lib64/qemu/chardev-spice.so") and
++ os.path.exists("/usr/lib64/qemu/ui-spice-core.so") and
++ os.path.exists("/usr/lib64/qemu/ui-opengl.so")):
++ return False
+ else:
+ if not (os.path.exists("/usr/lib/qemu/hw-usb-redirect.so") and
+ os.path.exists("/usr/lib/qemu/hw-display-qxl.so")):
+ return False
++ if self.conn.support.conn_spice_modular2():
++ if not (os.path.exists("/usr/lib/qemu/chardev-spice.so") and
++ os.path.exists("/usr/lib/qemu/ui-spice-core.so") and
++ os.path.exists("/usr/lib/qemu/ui-opengl.so")):
++ return False
return True
def _listen_need_port(self):
@@ -44,11 +57,12 @@
===================================================================
--- virt-manager-3.1.0.orig/virtinst/support.py
+++ virt-manager-3.1.0/virtinst/support.py
-@@ -282,6 +282,7 @@ class SupportCache:
+@@ -282,6 +282,8 @@ class SupportCache:
conn_disk_driver_name_qemu = _make(
hv_version={"qemu": 0, "xen": "4.2.0"},
hv_libvirt_version={"qemu": 0, "xen": "1.1.0"})
-+ conn_spice_modular = _make(hv_version={"qemu": "5.1.0", "test": 0})
++ conn_spice_modular1 = _make(hv_version={"qemu": "5.1.0", "test": 0})
++ conn_spice_modular2 = _make(hv_version={"qemu": "5.2.0", "test": 0})
# Domain checks
domain_xml_inactive = _make(function="virDomain.XMLDesc", run_args=(),
++++++ virtinst-sap-detection.patch ++++++
Index: virt-manager-3.2.0/virtinst/install/urldetect.py
===================================================================
--- virt-manager-3.2.0.orig/virtinst/install/urldetect.py
+++ virt-manager-3.2.0/virtinst/install/urldetect.py
@@ -271,9 +271,16 @@ class _SUSEContent(object):
distro_version = distro_version.strip()
if "Enterprise" in self.product_name or "SLES" in self.product_name:
- sle_version = self.product_name.strip().rsplit(' ')[4]
+ if " SAP " in self.product_name:
+ sle_version = self.product_name.strip().rsplit(' ')[7]
+ else:
+ sle_version = self.product_name.strip().rsplit(' ')[4]
if len(self.product_name.strip().rsplit(' ')) > 5:
- sle_version = (sle_version + '.' +
+ if " SAP " in self.product_name:
+ sle_version = (sle_version + '.' +
+ self.product_name.strip().rsplit(' ')[8][2])
+ else:
+ sle_version = (sle_version + '.' +
self.product_name.strip().rsplit(' ')[5][2])
distro_version = sle_version
1
0
01 Dec '20
Hello community,
here is the log from the commit of package i18nspector for openSUSE:Factory checked in at 2020-12-01 14:22:54
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/i18nspector (Old)
and /work/SRC/openSUSE:Factory/.i18nspector.new.5913 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "i18nspector"
Tue Dec 1 14:22:54 2020 rev:31 rq:851928 version:0.26
Changes:
--------
--- /work/SRC/openSUSE:Factory/i18nspector/i18nspector.changes 2020-08-19 18:59:10.219922002 +0200
+++ /work/SRC/openSUSE:Factory/.i18nspector.new.5913/i18nspector.changes 2020-12-01 14:23:08.333616184 +0100
@@ -1,0 +2,11 @@
+Sun Nov 29 16:15:12 UTC 2020 - Kyrill Detinov <lazy.kent(a)opensuse.org>
+
+- Update to 0.26.
+ * Summary of tag changes:
+ + Added:
+ - perl-brace-format-string-error
+ - perl-brace-format-string-missing-argument
+ - perl-brace-format-string-unknown-argument
+ * Check for errors in Perl brace format strings.
+
+-------------------------------------------------------------------
Old:
----
i18nspector-0.25.9.tar.gz
i18nspector-0.25.9.tar.gz.asc
New:
----
i18nspector-0.26.tar.gz
i18nspector-0.26.tar.gz.asc
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ i18nspector.spec ++++++
--- /var/tmp/diff_new_pack.77yQNq/_old 2020-12-01 14:23:09.017616924 +0100
+++ /var/tmp/diff_new_pack.77yQNq/_new 2020-12-01 14:23:09.021616928 +0100
@@ -17,7 +17,7 @@
Name: i18nspector
-Version: 0.25.9
+Version: 0.26
Release: 0
Summary: Tool for Checking gettext POT/PO/MO Files
License: MIT
++++++ i18nspector-0.25.9.tar.gz -> i18nspector-0.26.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/.pylintrc new/i18nspector-0.26/.pylintrc
--- old/i18nspector-0.25.9/.pylintrc 2020-08-06 10:23:02.000000000 +0200
+++ new/i18nspector-0.26/.pylintrc 2020-09-26 18:25:15.000000000 +0200
@@ -18,6 +18,7 @@
no-else-raise,
no-else-return,
no-self-use,
+ raise-missing-from,
redefined-variable-type,
subprocess-popen-preexec-fn,
superfluous-parens,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/data/tags new/i18nspector-0.26/data/tags
--- old/i18nspector-0.25.9/data/tags 2020-08-06 10:23:02.000000000 +0200
+++ new/i18nspector-0.26/data/tags 2020-09-26 18:25:15.000000000 +0200
@@ -709,6 +709,62 @@
description =
Translation is missing for some plural forms of a message.
+[perl-brace-format-string-error]
+severity = serious
+certainty = possible
+description =
+ A Perl format string could not be parsed.
+references =
+ https://www.gnu.org/software/gettext/manual/html_node/perl_002dformat.html
+
+[perl-brace-format-string-missing-argument]
+severity = serious
+certainty = possible
+description =
+ A Perl format string for ``msgid`` doesn't use a named argument that is used in ``msgid_plural``;
+ or ``msgstr`` doesn't use a named argument that is used in ``msgid``;
+ or ``msgstr[``\ *N*\ ``]`` doesn't use a named argument that is used in corresponding ``msgid`` or ``msgid_plural``.
+ .
+ Note that in some languages,
+ the commonly used Plural-Forms expression evaluates to the same value for n=1 and n=21, n=31, and so on.
+ Take this Serbian translation for example::
+ .
+ . Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;
+ . ...
+ . msgid "one byte"
+ . msgid_plural "{n} bytes"
+ . msgstr[0] "{n} bajt"
+ . msgstr[1] "{n} bajta"
+ . msgstr[2] "{n} bajtova"
+ .
+ Here ``{n}`` should not be replaced with the spelled-out form ``jedan``.
+ Either ``{n}`` should be kept, or the Plural-Forms expression should be amended,
+ so that there is a special case for n=1::
+ .
+ . Plural-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2
+ . ...
+ . msgid "one byte"
+ . msgid_plural "{n} bytes"
+ . msgstr[0] "{n} bajt"
+ . msgstr[1] "{n} bajta"
+ . msgstr[2] "{n} bajtova"
+ . msgstr[3] "jedan bajt"
+references =
+ https://www.gnu.org/software/gettext/manual/html_node/perl_002dformat.html
+ https://www.gnu.org/software/gettext/manual/html_node/Translating-plural-fo…
+
+[perl-brace-format-string-unknown-argument]
+severity = serious
+certainty = possible
+description =
+ A Perl format string for ``msgid`` uses a named argument that isn't used in ``msgid_plural``;
+ or ``msgstr`` uses a named argument that isn't used in ``msgid``;
+ or ``msgstr[``\ *N*\ ``]`` uses a named argument that isn't used in corresponding ``msgid`` or ``msgid_plural``.
+ This indicates that the conversion would try to consume an argument that weren't supplied.
+references =
+ https://www.gnu.org/software/gettext/manual/html_node/perl_002dformat.html
+ https://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html
+
[python-brace-format-string-argument-type-mismatch]
severity = serious
certainty = possible
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/doc/changelog new/i18nspector-0.26/doc/changelog
--- old/i18nspector-0.25.9/doc/changelog 2020-08-06 10:23:02.000000000 +0200
+++ new/i18nspector-0.26/doc/changelog 2020-09-26 18:25:15.000000000 +0200
@@ -1,3 +1,16 @@
+i18nspector (0.26) unstable; urgency=low
+
+ * Summary of tag changes:
+ + Added:
+ - perl-brace-format-string-error
+ - perl-brace-format-string-missing-argument
+ - perl-brace-format-string-unknown-argument
+
+ * Check for errors in Perl brace format strings.
+ https://github.com/jwilk/i18nspector/issues/6
+
+ -- Jakub Wilk <jwilk(a)jwilk.net> Sat, 26 Sep 2020 18:25:06 +0200
+
i18nspector (0.25.9) unstable; urgency=low
* Drop support for Python < 3.4.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/doc/i18nspector.1 new/i18nspector-0.26/doc/i18nspector.1
--- old/i18nspector-0.25.9/doc/i18nspector.1 2020-08-06 10:23:04.000000000 +0200
+++ new/i18nspector-0.26/doc/i18nspector.1 2020-09-26 18:25:18.000000000 +0200
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH I18NSPECTOR 1 "2020-08-06" "i18nspector 0.25.9" ""
+.TH I18NSPECTOR 1 "2020-09-26" "i18nspector 0.26" ""
.SH NAME
i18nspector \- checking tool for gettext POT, PO and MO files
.
@@ -1542,6 +1542,114 @@
.sp
Severity, certainty:
.INDENT 0.0
+.INDENT 3.5
+serious, possible
+.UNINDENT
+.UNINDENT
+.SS perl\-brace\-format\-string\-error
+.sp
+A Perl format string could not be parsed.
+.sp
+References:
+.INDENT 0.0
+.INDENT 3.5
+.nf
+\fI\%https://www.gnu.org/software/gettext/manual/html_node/perl_002dformat.html\fP
+.fi
+.sp
+.UNINDENT
+.UNINDENT
+.sp
+Severity, certainty:
+.INDENT 0.0
+.INDENT 3.5
+serious, possible
+.UNINDENT
+.UNINDENT
+.SS perl\-brace\-format\-string\-missing\-argument
+.sp
+A Perl format string for \fBmsgid\fP doesn't use a named argument that is used in \fBmsgid_plural\fP;
+or \fBmsgstr\fP doesn't use a named argument that is used in \fBmsgid\fP;
+or \fBmsgstr[\fP\fIN\fP\fB]\fP doesn't use a named argument that is used in corresponding \fBmsgid\fP or \fBmsgid_plural\fP\&.
+.sp
+Note that in some languages,
+the commonly used Plural\-Forms expression evaluates to the same value for n=1 and n=21, n=31, and so on.
+Take this Serbian translation for example:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+Plural\-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;
+\&...
+msgid "one byte"
+msgid_plural "{n} bytes"
+msgstr[0] "{n} bajt"
+msgstr[1] "{n} bajta"
+msgstr[2] "{n} bajtova"
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+Here \fB{n}\fP should not be replaced with the spelled\-out form \fBjedan\fP\&.
+Either \fB{n}\fP should be kept, or the Plural\-Forms expression should be amended,
+so that there is a special case for n=1:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+Plural\-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2
+\&...
+msgid "one byte"
+msgid_plural "{n} bytes"
+msgstr[0] "{n} bajt"
+msgstr[1] "{n} bajta"
+msgstr[2] "{n} bajtova"
+msgstr[3] "jedan bajt"
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+References:
+.INDENT 0.0
+.INDENT 3.5
+.nf
+\fI\%https://www.gnu.org/software/gettext/manual/html_node/perl_002dformat.html\fP
+\fI\%https://www.gnu.org/software/gettext/manual/html_node/Translating\-plural\-forms.html\fP
+.fi
+.sp
+.UNINDENT
+.UNINDENT
+.sp
+Severity, certainty:
+.INDENT 0.0
+.INDENT 3.5
+serious, possible
+.UNINDENT
+.UNINDENT
+.SS perl\-brace\-format\-string\-unknown\-argument
+.sp
+A Perl format string for \fBmsgid\fP uses a named argument that isn't used in \fBmsgid_plural\fP;
+or \fBmsgstr\fP uses a named argument that isn't used in \fBmsgid\fP;
+or \fBmsgstr[\fP\fIN\fP\fB]\fP uses a named argument that isn't used in corresponding \fBmsgid\fP or \fBmsgid_plural\fP\&.
+This indicates that the conversion would try to consume an argument that weren't supplied.
+.sp
+References:
+.INDENT 0.0
+.INDENT 3.5
+.nf
+\fI\%https://www.gnu.org/software/gettext/manual/html_node/perl_002dformat.html\fP
+\fI\%https://www.gnu.org/software/gettext/manual/html_node/Plural\-forms.html\fP
+.fi
+.sp
+.UNINDENT
+.UNINDENT
+.sp
+Severity, certainty:
+.INDENT 0.0
.INDENT 3.5
serious, possible
.UNINDENT
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/doc/manpage.rst new/i18nspector-0.26/doc/manpage.rst
--- old/i18nspector-0.25.9/doc/manpage.rst 2020-08-06 10:23:02.000000000 +0200
+++ new/i18nspector-0.26/doc/manpage.rst 2020-09-26 18:25:15.000000000 +0200
@@ -7,7 +7,7 @@
----------------------------------------------
:manual section: 1
-:version: i18nspector 0.25.9
+:version: i18nspector 0.26
:date: |date|
Synopsis
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/doc/tags.rst new/i18nspector-0.26/doc/tags.rst
--- old/i18nspector-0.25.9/doc/tags.rst 2020-08-06 10:23:04.000000000 +0200
+++ new/i18nspector-0.26/doc/tags.rst 2020-09-26 18:25:17.000000000 +0200
@@ -974,6 +974,74 @@
serious, possible
+perl-brace-format-string-error
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+A Perl format string could not be parsed.
+
+References:
+
+ | https://www.gnu.org/software/gettext/manual/html_node/perl_002dformat.html
+
+Severity, certainty:
+
+ serious, possible
+
+perl-brace-format-string-missing-argument
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+A Perl format string for ``msgid`` doesn't use a named argument that is used in ``msgid_plural``;
+or ``msgstr`` doesn't use a named argument that is used in ``msgid``;
+or ``msgstr[``\ *N*\ ``]`` doesn't use a named argument that is used in corresponding ``msgid`` or ``msgid_plural``.
+
+Note that in some languages,
+the commonly used Plural-Forms expression evaluates to the same value for n=1 and n=21, n=31, and so on.
+Take this Serbian translation for example::
+
+ Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;
+ ...
+ msgid "one byte"
+ msgid_plural "{n} bytes"
+ msgstr[0] "{n} bajt"
+ msgstr[1] "{n} bajta"
+ msgstr[2] "{n} bajtova"
+
+Here ``{n}`` should not be replaced with the spelled-out form ``jedan``.
+Either ``{n}`` should be kept, or the Plural-Forms expression should be amended,
+so that there is a special case for n=1::
+
+ Plural-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2
+ ...
+ msgid "one byte"
+ msgid_plural "{n} bytes"
+ msgstr[0] "{n} bajt"
+ msgstr[1] "{n} bajta"
+ msgstr[2] "{n} bajtova"
+ msgstr[3] "jedan bajt"
+
+References:
+
+ | https://www.gnu.org/software/gettext/manual/html_node/perl_002dformat.html
+ | https://www.gnu.org/software/gettext/manual/html_node/Translating-plural-fo…
+
+Severity, certainty:
+
+ serious, possible
+
+perl-brace-format-string-unknown-argument
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+A Perl format string for ``msgid`` uses a named argument that isn't used in ``msgid_plural``;
+or ``msgstr`` uses a named argument that isn't used in ``msgid``;
+or ``msgstr[``\ *N*\ ``]`` uses a named argument that isn't used in corresponding ``msgid`` or ``msgid_plural``.
+This indicates that the conversion would try to consume an argument that weren't supplied.
+
+References:
+
+ | https://www.gnu.org/software/gettext/manual/html_node/perl_002dformat.html
+ | https://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html
+
+Severity, certainty:
+
+ serious, possible
+
python-brace-format-string-argument-type-mismatch
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
There's a type mismatch between a Python format argument in ``msgid`` and the corresponding format argument in ``msgid_plural``;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/lib/check/__init__.py new/i18nspector-0.26/lib/check/__init__.py
--- old/i18nspector-0.25.9/lib/check/__init__.py 2020-08-06 10:23:02.000000000 +0200
+++ new/i18nspector-0.26/lib/check/__init__.py 2020-09-26 18:25:15.000000000 +0200
@@ -44,6 +44,7 @@
from lib import xml
from lib.check.msgformat import c as msgformat_c
+from lib.check.msgformat import perlbrace as msgformat_perlbrace
from lib.check.msgformat import pybrace as msgformat_pybrace
from lib.check.msgformat import python as msgformat_python
from lib.check.msgrepr import message_repr
@@ -101,6 +102,7 @@
self.options = options
self._message_format_checkers = {
'c': msgformat_c.Checker(self),
+ 'perl-brace': msgformat_perlbrace.Checker(self),
'python': msgformat_python.Checker(self),
'python-brace': msgformat_pybrace.Checker(self),
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/lib/check/msgformat/perlbrace.py new/i18nspector-0.26/lib/check/msgformat/perlbrace.py
--- old/i18nspector-0.25.9/lib/check/msgformat/perlbrace.py 1970-01-01 01:00:00.000000000 +0100
+++ new/i18nspector-0.26/lib/check/msgformat/perlbrace.py 2020-09-26 18:25:15.000000000 +0200
@@ -0,0 +1,70 @@
+# Copyright © 2016-2020 Jakub Wilk <jwilk(a)jwilk.net>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the “Software”), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+'''
+message format checks: Perl Locale::TextDomain
+'''
+
+from lib import tags
+
+from lib.check.msgformat import Checker as CheckerBase
+from lib.check.msgrepr import message_repr
+
+from lib.strformat import perlbrace as backend
+
+class Checker(CheckerBase):
+
+ backend = backend # pylint: disable=self-assigning-variable
+
+ def check_string(self, ctx, message, s):
+ prefix = message_repr(message, template='{}:')
+ fmt = None
+ try:
+ fmt = backend.FormatString(s)
+ except backend.Error as exc:
+ self.tag('perl-brace-format-string-error',
+ prefix,
+ tags.safestr(exc.message),
+ *exc.args[:1]
+ )
+ else:
+ return fmt
+
+ def check_args(self, message, src_loc, src_fmt, dst_loc, dst_fmt, *, omitted_int_conv_ok=False):
+ def sort_key(item):
+ return (isinstance(item, str), item)
+ prefix = message_repr(message, template='{}:')
+ src_args = src_fmt.arguments
+ dst_args = dst_fmt.arguments
+ for key in sorted(dst_args - src_args, key=sort_key):
+ self.tag('perl-brace-format-string-unknown-argument', prefix, key,
+ tags.safestr('in'), tags.safestr(dst_loc),
+ tags.safestr('but not in'), tags.safestr(src_loc),
+ )
+ missing_keys = src_args - dst_args
+ if len(missing_keys) == 1 and omitted_int_conv_ok:
+ missing_keys = ()
+ for key in sorted(missing_keys):
+ self.tag('perl-brace-format-string-missing-argument', prefix, key,
+ tags.safestr('not in'), tags.safestr(dst_loc),
+ tags.safestr('while in'), tags.safestr(src_loc),
+ )
+
+# vim:ts=4 sts=4 sw=4 et
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/lib/cli.py new/i18nspector-0.26/lib/cli.py
--- old/i18nspector-0.25.9/lib/cli.py 2020-08-06 10:23:02.000000000 +0200
+++ new/i18nspector-0.26/lib/cli.py 2020-09-26 18:25:15.000000000 +0200
@@ -39,7 +39,7 @@
from lib import tags
from lib import terminal
-__version__ = '0.25.9'
+__version__ = '0.26'
def initialize_terminal():
if sys.stdout.isatty():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/lib/strformat/perlbrace.py new/i18nspector-0.26/lib/strformat/perlbrace.py
--- old/i18nspector-0.25.9/lib/strformat/perlbrace.py 1970-01-01 01:00:00.000000000 +0100
+++ new/i18nspector-0.26/lib/strformat/perlbrace.py 2020-09-26 18:25:15.000000000 +0200
@@ -0,0 +1,70 @@
+# Copyright © 2016-2020 Jakub Wilk <jwilk(a)jwilk.net>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the “Software”), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+'''
+Perl format checks: Locale::TextDomain
+'''
+
+import re
+
+_field_re = re.compile(r'''
+ (?P<literal> [^{]+ ) |
+ (?:
+ [{]
+ (?P<name> [^\W\d]\w* )
+ [}]
+ )
+''', re.VERBOSE)
+
+def _printable_prefix(s, r=re.compile('[ -\x7E]+')):
+ return r.match(s).group()
+
+class Error(Exception):
+ message = 'invalid placeholder specification'
+
+class FormatString():
+
+ def __init__(self, s):
+ self._items = items = []
+ arguments = set()
+ last_pos = 0
+ for match in _field_re.finditer(s):
+ if match.start() != last_pos:
+ raise Error(
+ _printable_prefix(s[last_pos:])
+ )
+ items += [match.group()]
+ argname = match.group('name')
+ if argname is not None:
+ arguments.add(argname)
+ last_pos = match.end()
+ if last_pos != len(s):
+ raise Error(
+ _printable_prefix(s[last_pos:])
+ )
+ self.arguments = frozenset(arguments)
+
+ def __iter__(self):
+ return iter(self._items)
+
+ def __len__(self):
+ return len(self._items)
+
+# vim:ts=4 sts=4 sw=4 et
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/lib/strformat/pybrace.py new/i18nspector-0.26/lib/strformat/pybrace.py
--- old/i18nspector-0.25.9/lib/strformat/pybrace.py 2020-08-06 10:23:02.000000000 +0200
+++ new/i18nspector-0.26/lib/strformat/pybrace.py 2020-09-26 18:25:15.000000000 +0200
@@ -1,4 +1,4 @@
-# Copyright © 2016-2018 Jakub Wilk <jwilk(a)jwilk.net>
+# Copyright © 2016-2020 Jakub Wilk <jwilk(a)jwilk.net>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the “Software”), to deal
@@ -40,7 +40,7 @@
_field_re = re.compile(r'''
(?P<literal> (?: [^{}] | [{]{2} | [}]{2} )+ ) |
- (
+ (?:
[{]
(?:
(?P<name>''' + _field_name_pattern + r''') ?
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/private/online-build-po-corpus new/i18nspector-0.26/private/online-build-po-corpus
--- old/i18nspector-0.25.9/private/online-build-po-corpus 2020-08-06 10:23:02.000000000 +0200
+++ new/i18nspector-0.26/private/online-build-po-corpus 2020-09-26 18:25:15.000000000 +0200
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
-# Copyright © 2012-2019 Jakub Wilk <jwilk(a)jwilk.net>
+# Copyright © 2012-2020 Jakub Wilk <jwilk(a)jwilk.net>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the “Software”), to deal
@@ -46,8 +46,10 @@
self._files = []
self._tmpdir = tempfile.TemporaryDirectory(prefix='i18nspector.private.')
- def add(self, url, name):
- url = urllib.parse.urljoin(self._urlbase, url)
+ def add(self, url, name, urlbase=None):
+ if urlbase is None:
+ urlbase = self._urlbase
+ url = urllib.parse.urljoin(urlbase, url)
self._files += [apt_pkg.AcquireFile(
self._acquire,
uri=url,
@@ -99,6 +101,9 @@
ap.add_argument('--mirror', metavar='URL', default=default_mirror,
help='Debian mirror to use (default: {mirror})'.format(mirror=default_mirror)
)
+ ap.add_argument('--contents-mirror', metavar='URL', default=None,
+ help='Debian mirror of Contents-* files to use (default: same as --mirror)'
+ )
ap.add_argument('--distribution', metavar='DIST', default=default_dist,
help='Debian distribution to use (default: {dist})'.format(dist=default_dist)
)
@@ -117,6 +122,9 @@
break
tar = tarfile.open(output, mode=tarmode)
mirror = options.mirror
+ cnts_mirror = options.contents_mirror
+ if cnts_mirror is None:
+ cnts_mirror = mirror
dist = options.distribution
areas = options.areas.split(',')
def tarfilter(tarinfo):
@@ -126,13 +134,17 @@
tarinfo.mode |= 0o644
if tarinfo.mode & 0o100:
tarinfo.mode |= 0o111
- tarinfo.name = 'po-corpus-{dist}/{name}'.format(dist=dist, name=tarinfo.name)
+ prefix = 'po-corpus-{dist}/'.format(dist=dist)
+ tarinfo.name = prefix + tarinfo.name
+ if tarinfo.linkname:
+ tarinfo.linkname = prefix + tarinfo.linkname
return tarinfo
subprocess.check_call(['dpkg-source', '--version'], stdout=subprocess.DEVNULL)
for area in areas:
urlbase = '{mirror}/dists/{dist}/{area}/'.format(mirror=mirror, dist=dist, area=area)
+ cnts_urlbase = '{mirror}/dists/{dist}/{area}/'.format(mirror=cnts_mirror, dist=dist, area=area)
with Fetcher(urlbase=urlbase) as fetcher:
- fetcher.add('Contents-source.gz', 'Contents.gz')
+ fetcher.add('Contents-source.gz', 'Contents.gz', urlbase=cnts_urlbase)
fetcher.add('source/Sources.xz', 'Sources.xz')
[contents_path, sources_path] = fetcher.run()
interesting_packages = set()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/private/tags-as-rst new/i18nspector-0.26/private/tags-as-rst
--- old/i18nspector-0.25.9/private/tags-as-rst 2020-08-06 10:23:02.000000000 +0200
+++ new/i18nspector-0.26/private/tags-as-rst 2020-09-26 18:25:15.000000000 +0200
@@ -44,7 +44,7 @@
for ref in tag.references:
match = re.match(r'\A(?P<name>[\w-]+)[(](?P<section>[0-9])[)]\Z', ref)
if match is not None:
- ref = r'**{name}**\ ({section})'.format(**match.groupdict())
+ ref = r'**{name}**\ ({section})'.format_map(match.groupdict())
print(' |', ref)
print()
print('Severity, certainty:', end='\n\n')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-error.po new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-error.po
--- old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-error.po 1970-01-01 01:00:00.000000000 +0100
+++ new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-error.po 2020-09-26 18:25:15.000000000 +0200
@@ -0,0 +1,18 @@
+# E: perl-brace-format-string-error msgid 'A quick brown fox jumps over the lazy dog.': invalid placeholder specification '{'
+
+msgid ""
+msgstr ""
+"Project-Id-Version: Gizmo Enhancer 1.0\n"
+"Report-Msgid-Bugs-To: gizmoenhancer(a)jwilk.net\n"
+"POT-Creation-Date: 2012-11-01 14:42+0100\n"
+"PO-Revision-Date: 2012-11-01 14:42+0100\n"
+"Last-Translator: Jakub Wilk <jwilk(a)jwilk.net>\n"
+"Language-Team: Latin <la(a)li.org>\n"
+"Language: la\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#, perl-brace-format
+msgid "A quick brown fox jumps over the lazy dog."
+msgstr "Sic fugiens, dux, zelotypos, quam Karus haberis{"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-missing-argument.po new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-missing-argument.po
--- old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-missing-argument.po 1970-01-01 01:00:00.000000000 +0100
+++ new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-missing-argument.po 2020-09-26 18:25:15.000000000 +0200
@@ -0,0 +1,18 @@
+# E: perl-brace-format-string-missing-argument msgid 'A quick brown {A} jumps over the lazy {B}': A not in msgstr while in msgid
+
+msgid ""
+msgstr ""
+"Project-Id-Version: Gizmo Enhancer 1.0\n"
+"Report-Msgid-Bugs-To: gizmoenhancer(a)jwilk.net\n"
+"POT-Creation-Date: 2012-11-01 14:42+0100\n"
+"PO-Revision-Date: 2012-11-01 14:42+0100\n"
+"Last-Translator: Jakub Wilk <jwilk(a)jwilk.net>\n"
+"Language-Team: Latin <la(a)li.org>\n"
+"Language: la\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#, perl-brace-format
+msgid "A quick brown {A} jumps over the lazy {B}"
+msgstr "Sic fugiens, dux, zelotypos, quam {B} haberis."
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-missing-arguments.pot new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-missing-arguments.pot
--- old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-missing-arguments.pot 1970-01-01 01:00:00.000000000 +0100
+++ new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-missing-arguments.pot 2020-09-26 18:25:15.000000000 +0200
@@ -0,0 +1,23 @@
+# E: perl-brace-format-string-missing-argument msgid 'A quick brown fox jumps over the lazy dog.': N not in msgid while in msgid_plural
+# E: perl-brace-format-string-missing-argument msgid 'A quick brown fox jumps over the lazy dog.': X not in msgid while in msgid_plural
+
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Gizmo Enhancer 1.0\n"
+"Report-Msgid-Bugs-To: gizmoenhancer(a)jwilk.net\n"
+"POT-Creation-Date: 2012-11-01 14:42+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL(a)li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+
+#, perl-brace-format
+msgid "A quick brown fox jumps over the lazy dog."
+msgid_plural "{N} quick brown foxes jump over the lazy {X}."
+msgstr[0] ""
+msgstr[1] ""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-missing-numeral.po new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-missing-numeral.po
--- old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-missing-numeral.po 1970-01-01 01:00:00.000000000 +0100
+++ new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-missing-numeral.po 2020-09-26 18:25:15.000000000 +0200
@@ -0,0 +1,22 @@
+# E: perl-brace-format-string-missing-argument msgid once: N not in msgstr[0] while in msgid_plural
+
+msgid ""
+msgstr ""
+"Project-Id-Version: Gizmo Enhancer 1.0\n"
+"Report-Msgid-Bugs-To: gizmoenhancer(a)jwilk.net\n"
+"POT-Creation-Date: 2012-11-01 14:42+0100\n"
+"PO-Revision-Date: 2012-11-01 14:42+0100\n"
+"Last-Translator: Jakub Wilk <jwilk(a)jwilk.net>\n"
+"Language-Team: Russian <ru(a)li.org>\n"
+"Language: ru\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2\n"
+
+#, perl-brace-format
+msgid "once"
+msgid_plural "{N} times"
+msgstr[0] "paз"
+msgstr[1] "{N} paзи"
+msgstr[2] "{N} paзiв"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-msgid-error.po new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-msgid-error.po
--- old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-msgid-error.po 1970-01-01 01:00:00.000000000 +0100
+++ new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-msgid-error.po 2020-09-26 18:25:15.000000000 +0200
@@ -0,0 +1,16 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: Gizmo Enhancer 1.0\n"
+"Report-Msgid-Bugs-To: gizmoenhancer(a)jwilk.net\n"
+"POT-Creation-Date: 2012-11-01 14:42+0100\n"
+"PO-Revision-Date: 2012-11-01 14:42+0100\n"
+"Last-Translator: Jakub Wilk <jwilk(a)jwilk.net>\n"
+"Language-Team: Latin <la(a)li.org>\n"
+"Language: la\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#, perl-brace-format
+msgid "A quick brown fox jumps over the lazy dog{"
+msgstr "Sic fugiens, dux, zelotypos, quam Karus haberis{"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-msgid-error.pot new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-msgid-error.pot
--- old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-msgid-error.pot 1970-01-01 01:00:00.000000000 +0100
+++ new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-msgid-error.pot 2020-09-26 18:25:15.000000000 +0200
@@ -0,0 +1,19 @@
+# E: perl-brace-format-string-error msgid 'A quick brown fox jumps over the lazy dog{': invalid placeholder specification '{'
+
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Gizmo Enhancer 1.0\n"
+"Report-Msgid-Bugs-To: gizmoenhancer(a)jwilk.net\n"
+"POT-Creation-Date: 2012-11-01 14:42+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL(a)li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#, perl-brace-format
+msgid "A quick brown fox jumps over the lazy dog{"
+msgstr ""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-no-excess-arguments.po new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-no-excess-arguments.po
--- old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-no-excess-arguments.po 1970-01-01 01:00:00.000000000 +0100
+++ new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-no-excess-arguments.po 2020-09-26 18:25:15.000000000 +0200
@@ -0,0 +1,20 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: Gizmo Enhancer 1.0\n"
+"Report-Msgid-Bugs-To: gizmoenhancer(a)jwilk.net\n"
+"POT-Creation-Date: 2012-11-01 14:42+0100\n"
+"PO-Revision-Date: 2012-11-01 14:42+0100\n"
+"Last-Translator: Jakub Wilk <jwilk(a)jwilk.net>\n"
+"Language-Team: Russian <ru(a)li.org>\n"
+"Language: ru\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2\n"
+
+#, perl-brace-format
+msgid "once"
+msgid_plural "{N} times"
+msgstr[0] "{N} paз"
+msgstr[1] "{N} paзи"
+msgstr[2] "{N} paзiв"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-okay.po new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-okay.po
--- old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-okay.po 1970-01-01 01:00:00.000000000 +0100
+++ new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-okay.po 2020-09-26 18:25:15.000000000 +0200
@@ -0,0 +1,16 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: Gizmo Enhancer 1.0\n"
+"Report-Msgid-Bugs-To: gizmoenhancer(a)jwilk.net\n"
+"POT-Creation-Date: 2012-11-01 14:42+0100\n"
+"PO-Revision-Date: 2012-11-01 14:42+0100\n"
+"Last-Translator: Jakub Wilk <jwilk(a)jwilk.net>\n"
+"Language-Team: Latin <la(a)li.org>\n"
+"Language: la\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#, perl-brace-format
+msgid "A quick brown {X} jumps over the lazy dog."
+msgstr "Sic fugiens, {X}, zelotypos, quam Karus haberis."
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-okay.pot new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-okay.pot
--- old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-okay.pot 1970-01-01 01:00:00.000000000 +0100
+++ new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-okay.pot 2020-09-26 18:25:15.000000000 +0200
@@ -0,0 +1,17 @@
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Gizmo Enhancer 1.0\n"
+"Report-Msgid-Bugs-To: gizmoenhancer(a)jwilk.net\n"
+"POT-Creation-Date: 2012-11-01 14:42+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL(a)li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#, perl-brace-format
+msgid "A quick brown {X} jumps over the lazy dog."
+msgstr ""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-omitted-numeral-1.po new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-omitted-numeral-1.po
--- old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-omitted-numeral-1.po 1970-01-01 01:00:00.000000000 +0100
+++ new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-omitted-numeral-1.po 2020-09-26 18:25:15.000000000 +0200
@@ -0,0 +1,20 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: Gizmo Enhancer 1.0\n"
+"Report-Msgid-Bugs-To: gizmoenhancer(a)jwilk.net\n"
+"POT-Creation-Date: 2012-11-01 14:42+0100\n"
+"PO-Revision-Date: 2012-11-01 14:42+0100\n"
+"Last-Translator: Jakub Wilk <jwilk(a)jwilk.net>\n"
+"Language-Team: Polish <pl(a)li.org>\n"
+"Language: pl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+
+#, perl-brace-format
+msgid "{N} quick brown fox jumps over the lazy dog."
+msgid_plural "{N} quick brown foxes jump over the lazy dog."
+msgstr[0] "Mężny bądź, chroń pułk twój i jedną flagę."
+msgstr[1] "Mężny bądź, chroń pułk twój i {N} flagi."
+msgstr[2] "Mężny bądź, chroń pułk twój i {N} flag."
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-omitted-numeral-2.po new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-omitted-numeral-2.po
--- old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-omitted-numeral-2.po 1970-01-01 01:00:00.000000000 +0100
+++ new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-omitted-numeral-2.po 2020-09-26 18:25:15.000000000 +0200
@@ -0,0 +1,20 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: Gizmo Enhancer 1.0\n"
+"Report-Msgid-Bugs-To: gizmoenhancer(a)jwilk.net\n"
+"POT-Creation-Date: 2012-11-01 14:42+0100\n"
+"PO-Revision-Date: 2012-11-01 14:42+0100\n"
+"Last-Translator: Jakub Wilk <jwilk(a)jwilk.net>\n"
+"Language-Team: Polish <pl(a)li.org>\n"
+"Language: pl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+
+#, perl-brace-format
+msgid "A quick brown fox jumps over the lazy dog."
+msgid_plural "{N} quick brown foxes jump over the lazy dog."
+msgstr[0] "Mężny bądź, chroń pułk twój i jedną flagę."
+msgstr[1] "Mężny bądź, chroń pułk twój i {N} flagi."
+msgstr[2] "Mężny bądź, chroń pułk twój i {N} flag."
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-omitted-numeral-5.po new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-omitted-numeral-5.po
--- old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-omitted-numeral-5.po 1970-01-01 01:00:00.000000000 +0100
+++ new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-omitted-numeral-5.po 2020-09-26 18:25:15.000000000 +0200
@@ -0,0 +1,37 @@
+# E: perl-brace-format-string-missing-argument msgid 'A quick brown fox jumps over the lazy dog.' msgctxt 'max 6': N not in msgstr[2] while in msgid_plural
+
+msgid ""
+msgstr ""
+"Project-Id-Version: Gizmo Enhancer 1.0\n"
+"Report-Msgid-Bugs-To: gizmoenhancer(a)jwilk.net\n"
+"POT-Creation-Date: 2012-11-01 14:42+0100\n"
+"PO-Revision-Date: 2012-11-01 14:42+0100\n"
+"Last-Translator: Jakub Wilk <jwilk(a)jwilk.net>\n"
+"Language-Team: Polish <pl(a)li.org>\n"
+"Language: pl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+
+# {N} doesn't have to be included in msgstr[2], because according to the range
+# flag, it applies only to n=5.
+
+#, perl-brace-format, range: 1..5
+msgctxt "max 5"
+msgid "A quick brown fox jumps over the lazy dog."
+msgid_plural "{N} quick brown foxes jump over the lazy dog."
+msgstr[0] "Mężny bądź, chroń pułk twój i jedną flagę."
+msgstr[1] "Mężny bądź, chroń pułk twój i {N} flagi."
+msgstr[2] "Mężny bądź, chroń pułk twój i pięć flag."
+
+# {N} cannot be omitted in msgstr[2], because it applies not only to n=5 but
+# also n=6.
+
+#, perl-brace-format, range: 1..6
+msgctxt "max 6"
+msgid "A quick brown fox jumps over the lazy dog."
+msgid_plural "{N} quick brown foxes jump over the lazy dog."
+msgstr[0] "Mężny bądź, chroń pułk twój i jedną flagę."
+msgstr[1] "Mężny bądź, chroń pułk twój i {N} flagi."
+msgstr[2] "Mężny bądź, chroń pułk twój i pięć flag."
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-omitted-numeral.pot new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-omitted-numeral.pot
--- old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-omitted-numeral.pot 1970-01-01 01:00:00.000000000 +0100
+++ new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-omitted-numeral.pot 2020-09-26 18:25:15.000000000 +0200
@@ -0,0 +1,20 @@
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Gizmo Enhancer 1.0\n"
+"Report-Msgid-Bugs-To: gizmoenhancer(a)jwilk.net\n"
+"POT-Creation-Date: 2012-11-01 14:42+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL(a)li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+
+#, perl-brace-format
+msgid "A quick brown fox jumps over the lazy dog."
+msgid_plural "{N} quick brown foxes jump over the lazy dog."
+msgstr[0] ""
+msgstr[1] ""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-plural-okay.po new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-plural-okay.po
--- old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-plural-okay.po 1970-01-01 01:00:00.000000000 +0100
+++ new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-plural-okay.po 2020-09-26 18:25:15.000000000 +0200
@@ -0,0 +1,20 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: Gizmo Enhancer 1.0\n"
+"Report-Msgid-Bugs-To: gizmoenhancer(a)jwilk.net\n"
+"POT-Creation-Date: 2012-11-01 14:42+0100\n"
+"PO-Revision-Date: 2012-11-01 14:42+0100\n"
+"Last-Translator: Jakub Wilk <jwilk(a)jwilk.net>\n"
+"Language-Team: Polish <pl(a)li.org>\n"
+"Language: pl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+
+#, perl-brace-format
+msgid "{N} quick brown fox jumps over the lazy dog."
+msgid_plural "{N} quick brown foxes jump over the lazy dog."
+msgstr[0] "Mężny bądź, chroń pułk twój i {N} flagę."
+msgstr[1] "Mężny bądź, chroń pułk twój i {N} flagi."
+msgstr[2] "Mężny bądź, chroń pułk twój i {N} flag."
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-plural-okay.pot new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-plural-okay.pot
--- old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-plural-okay.pot 1970-01-01 01:00:00.000000000 +0100
+++ new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-plural-okay.pot 2020-09-26 18:25:15.000000000 +0200
@@ -0,0 +1,20 @@
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Gizmo Enhancer 1.0\n"
+"Report-Msgid-Bugs-To: gizmoenhancer(a)jwilk.net\n"
+"POT-Creation-Date: 2012-11-01 14:42+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL(a)li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+
+#, perl-brace-format
+msgid "{N} quick brown fox jumps over the lazy dog."
+msgid_plural "{N} quick brown foxes jump over the lazy dog."
+msgstr[0] ""
+msgstr[1] ""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-unknown-argument-1.po new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-unknown-argument-1.po
--- old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-unknown-argument-1.po 1970-01-01 01:00:00.000000000 +0100
+++ new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-unknown-argument-1.po 2020-09-26 18:25:15.000000000 +0200
@@ -0,0 +1,18 @@
+# E: perl-brace-format-string-unknown-argument msgid 'A quick brown {A} jumps over the lazy dog.': B in msgstr but not in msgid
+
+msgid ""
+msgstr ""
+"Project-Id-Version: Gizmo Enhancer 1.0\n"
+"Report-Msgid-Bugs-To: gizmoenhancer(a)jwilk.net\n"
+"POT-Creation-Date: 2012-11-01 14:42+0100\n"
+"PO-Revision-Date: 2012-11-01 14:42+0100\n"
+"Last-Translator: Jakub Wilk <jwilk(a)jwilk.net>\n"
+"Language-Team: Latin <la(a)li.org>\n"
+"Language: la\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#, perl-brace-format
+msgid "A quick brown {A} jumps over the lazy dog."
+msgstr "Sic fugiens, {A}, zelotypos, quam {B} haberis."
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-unknown-argument-2.po new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-unknown-argument-2.po
--- old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-unknown-argument-2.po 1970-01-01 01:00:00.000000000 +0100
+++ new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-unknown-argument-2.po 2020-09-26 18:25:15.000000000 +0200
@@ -0,0 +1,23 @@
+# E: perl-brace-format-string-unknown-argument msgid '{N} quick brown fox jumps over the lazy dog.': O in msgstr[0] but not in msgid
+# E: perl-brace-format-string-unknown-argument msgid '{N} quick brown fox jumps over the lazy dog.': O in msgstr[2] but not in msgid_plural
+
+msgid ""
+msgstr ""
+"Project-Id-Version: Gizmo Enhancer 1.0\n"
+"Report-Msgid-Bugs-To: gizmoenhancer(a)jwilk.net\n"
+"POT-Creation-Date: 2012-11-01 14:42+0100\n"
+"PO-Revision-Date: 2012-11-01 14:42+0100\n"
+"Last-Translator: Jakub Wilk <jwilk(a)jwilk.net>\n"
+"Language-Team: Polish <pl(a)li.org>\n"
+"Language: pl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+
+#, perl-brace-format
+msgid "{N} quick brown fox jumps over the lazy dog."
+msgid_plural "{N} quick brown foxes jump over the lazy dog."
+msgstr[0] "Mężny bądź, chroń {O} twój i {N} flagę."
+msgstr[1] "Mężny bądź, chroń pułk twój i {N} flagi."
+msgstr[2] "Mężny bądź, chroń {O} twój i {N} flag."
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-unknown-argument.pot new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-unknown-argument.pot
--- old/i18nspector-0.25.9/tests/blackbox_tests/perl-brace-format-string-unknown-argument.pot 1970-01-01 01:00:00.000000000 +0100
+++ new/i18nspector-0.26/tests/blackbox_tests/perl-brace-format-string-unknown-argument.pot 2020-09-26 18:25:15.000000000 +0200
@@ -0,0 +1,22 @@
+# E: perl-brace-format-string-unknown-argument msgid '{N} quick brown fox jumps over the lazy dog.': N in msgid but not in msgid_plural
+
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Gizmo Enhancer 1.0\n"
+"Report-Msgid-Bugs-To: gizmoenhancer(a)jwilk.net\n"
+"POT-Creation-Date: 2012-11-01 14:42+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL(a)li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+
+#, perl-brace-format
+msgid "{N} quick brown fox jumps over the lazy dog."
+msgid_plural "Quick brown foxes jump over the lazy dog."
+msgstr[0] ""
+msgstr[1] ""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/tests/blackbox_tests/python-brace-format-string-missing-non-numeral.pot new/i18nspector-0.26/tests/blackbox_tests/python-brace-format-string-missing-non-numeral.pot
--- old/i18nspector-0.25.9/tests/blackbox_tests/python-brace-format-string-missing-non-numeral.pot 2020-08-06 10:23:02.000000000 +0200
+++ new/i18nspector-0.26/tests/blackbox_tests/python-brace-format-string-missing-non-numeral.pot 2020-09-26 18:25:15.000000000 +0200
@@ -20,4 +20,3 @@
msgid_plural "{N:s} quick brown foxes jump over the lazy dog."
msgstr[0] ""
msgstr[1] ""
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/tests/coverage new/i18nspector-0.26/tests/coverage
--- old/i18nspector-0.25.9/tests/coverage 2020-08-06 10:23:02.000000000 +0200
+++ new/i18nspector-0.26/tests/coverage 2020-09-26 18:25:15.000000000 +0200
@@ -1,31 +1,33 @@
Generated automatically by private/update-branch-coverage. Do not edit.
-Name Stmts Miss Branch BrPart Cover Missing
------------------------------------------------------------------------------
-lib/__init__.py 1 0 0 0 100%
-lib/check/__init__.py 809 749 515 0 5% 82-86, 89-102, 116-201, 204-220, 224-356, 360-504, 508-580, 584-627, 632-667, 672-716, 719-797, 800-880, 883-997, 1000-1007, 1010-1026, 1031
-lib/check/msgformat/__init__.py 83 68 36 0 13% 31, 38, 41-151
-lib/check/msgformat/c.py 67 56 36 0 11% 37-44, 47-105, 108-129
-lib/check/msgformat/pybrace.py 35 26 13 0 19% 37-48, 51-75
-lib/check/msgformat/python.py 77 67 47 0 8% 37-109, 112-149
-lib/check/msgrepr.py 11 7 2 0 31% 28-34
-lib/cli.py 161 125 46 0 17% 45-49, 58-67, 70-71, 74-76, 82-111, 114-119, 125-131, 134-142, 145-153, 159, 168-186, 189-195, 198-232
-lib/domains.py 15 0 0 0 100%
-lib/encodings.py 132 38 36 2 73% 50-66, 78-86, 134->138, 138-140, 191->193, 193, 207-220, 224-228
-lib/gettext.py 105 0 36 0 100%
-lib/iconv.py 156 49 58 19 64% 41-42, 55-57, 63->64, 64, 65->66, 66, 67->68, 68, 69->70, 70, 82->83, 83-84, 96->97, 97-98, 105->110, 110->111, 111-123, 129->130, 129->exit, 130-131, 134-145, 150->151, 151, 152->153, 153, 154->155, 155, 156->157, 157, 165->166, 166-167, 179->180, 180-181, 198->213, 200->203, 203-204, 213, 221->222, 222-223, 226-237
-lib/intexpr.py 420 0 126 0 100%
-lib/ling.py 243 2 98 3 99% 159->162, 179->181, 181, 277->283, 281
-lib/misc.py 42 0 16 0 100%
-lib/moparser.py 138 92 56 3 28% 56->58, 68, 74->76, 76, 91-109, 112-178, 183-192, 194->195, 195
-lib/paths.py 7 2 0 0 71% 36-37
-lib/polib4us.py 120 75 26 0 31% 41-42, 56, 72, 75-96, 100, 110-112, 133-145, 149, 161, 170-175, 186-194, 205, 208, 212-216, 228-235, 243-252
-lib/strformat/__init__.py 0 0 0 0 100%
-lib/strformat/c.py 285 0 168 0 100%
-lib/strformat/pybrace.py 156 0 74 0 100%
-lib/strformat/python.py 204 0 94 0 100%
-lib/tags.py 117 29 34 4 75% 81->82, 82, 83->84, 84, 86->87, 87, 106-107, 118-120, 125-127, 139->140, 140, 151-158, 164-168, 178-191, 210, 216
-lib/terminal.py 48 17 6 1 59% 37-38, 63->64, 64, 80-93
-lib/xml.py 21 0 2 0 100%
------------------------------------------------------------------------------
-TOTAL 3453 1402 1525 32 55%
+Name Stmts Miss Branch BrPart Cover Missing
+------------------------------------------------------------------------------
+lib/__init__.py 1 0 0 0 100%
+lib/check/__init__.py 810 749 515 0 5% 83-87, 90-103, 118-203, 206-222, 226-358, 362-506, 510-582, 586-629, 634-669, 674-718, 721-799, 802-882, 885-999, 1002-1009, 1012-1028, 1033
+lib/check/msgformat/__init__.py 83 68 36 0 13% 31, 38, 41-151
+lib/check/msgformat/c.py 67 56 36 0 11% 37-44, 47-105, 108-129
+lib/check/msgformat/perlbrace.py 28 19 6 0 26% 37-48, 51-65
+lib/check/msgformat/pybrace.py 35 26 13 0 19% 37-48, 51-75
+lib/check/msgformat/python.py 77 67 47 0 8% 37-109, 112-149
+lib/check/msgrepr.py 11 7 2 0 31% 28-34
+lib/cli.py 161 125 46 0 17% 45-49, 58-67, 70-71, 74-76, 82-111, 114-119, 125-131, 134-142, 145-153, 159, 168-186, 189-195, 198-232
+lib/domains.py 15 0 0 0 100%
+lib/encodings.py 134 40 36 2 72% 50-66, 78-86, 134->138, 138-142, 193->195, 195, 209-222, 226-230
+lib/gettext.py 105 0 36 0 100%
+lib/iconv.py 156 49 58 19 64% 41-42, 55-57, 63->64, 64, 65->66, 66, 67->68, 68, 69->70, 70, 82->83, 83-84, 96->97, 97-98, 105->110, 110->111, 111-123, 129->130, 129->exit, 130-131, 134-145, 150->151, 151, 152->153, 153, 154->155, 155, 156->157, 157, 165->166, 166-167, 179->180, 180-181, 198->213, 200->203, 203-204, 213, 221->222, 222-223, 226-237
+lib/intexpr.py 420 0 126 0 100%
+lib/ling.py 243 2 98 3 99% 159->162, 179->181, 181, 277->283, 281
+lib/misc.py 42 0 16 0 100%
+lib/moparser.py 138 92 56 3 28% 56->58, 68, 74->76, 76, 91-109, 112-178, 183-192, 194->195, 195
+lib/paths.py 7 2 0 0 71% 36-37
+lib/polib4us.py 120 75 26 0 31% 41-42, 56, 72, 75-96, 100, 110-112, 133-145, 149, 161, 170-175, 186-194, 205, 208, 212-216, 228-235, 243-252
+lib/strformat/__init__.py 0 0 0 0 100%
+lib/strformat/c.py 285 0 168 0 100%
+lib/strformat/perlbrace.py 27 0 8 0 100%
+lib/strformat/pybrace.py 156 0 74 0 100%
+lib/strformat/python.py 204 0 94 0 100%
+lib/tags.py 117 29 34 4 75% 81->82, 82, 83->84, 84, 86->87, 87, 106-107, 118-120, 125-127, 139->140, 140, 151-158, 164-168, 178-191, 210, 216
+lib/terminal.py 48 17 6 1 59% 37-38, 63->64, 64, 80-93
+lib/xml.py 21 0 2 0 100%
+------------------------------------------------------------------------------
+TOTAL 3511 1423 1539 32 55%
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i18nspector-0.25.9/tests/test_strformat_perlbrace.py new/i18nspector-0.26/tests/test_strformat_perlbrace.py
--- old/i18nspector-0.25.9/tests/test_strformat_perlbrace.py 1970-01-01 01:00:00.000000000 +0100
+++ new/i18nspector-0.26/tests/test_strformat_perlbrace.py 2020-09-26 18:25:15.000000000 +0200
@@ -0,0 +1,57 @@
+# Copyright © 2016-2020 Jakub Wilk <jwilk(a)jwilk.net>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the “Software”), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+from nose.tools import (
+ assert_equal,
+ assert_raises,
+)
+
+import lib.strformat.perlbrace as M
+
+def test_lone_lcb():
+ with assert_raises(M.Error):
+ M.FormatString('{')
+
+def test_lone_rcb():
+ M.FormatString('}')
+
+def test_invalid_field():
+ with assert_raises(M.Error):
+ M.FormatString('{@}')
+
+def test_text():
+ fmt = M.FormatString('bacon')
+ assert_equal(len(fmt), 1)
+ [fld] = fmt
+ assert_equal(fld, 'bacon')
+
+class test_named_arguments:
+
+ def test_good(self):
+ fmt = M.FormatString('{spam}')
+ assert_equal(len(fmt), 1)
+ [fld] = fmt
+ assert_equal(fld, '{spam}')
+
+ def test_bad(self):
+ with assert_raises(M.Error):
+ M.FormatString('{3ggs}')
+
+# vim:ts=4 sts=4 sw=4 et
1
0
Hello community,
here is the log from the commit of package musique for openSUSE:Factory checked in at 2020-12-01 14:22:53
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/musique (Old)
and /work/SRC/openSUSE:Factory/.musique.new.5913 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "musique"
Tue Dec 1 14:22:53 2020 rev:2 rq:851873 version:1.10.1
Changes:
--------
--- /work/SRC/openSUSE:Factory/musique/musique.changes 2020-10-26 16:15:24.494887141 +0100
+++ /work/SRC/openSUSE:Factory/.musique.new.5913/musique.changes 2020-12-01 14:23:07.173614929 +0100
@@ -1,0 +2,6 @@
+Mon Nov 30 14:46:54 UTC 2020 - Cor Blom <cornelis(a)solcon.nl>
+
+- Update to 1.10.1
+ * No upstream changelog
+
+-------------------------------------------------------------------
Old:
----
musique-1.10.tar.xz
New:
----
musique-1.10.1.tar.xz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ musique.spec ++++++
--- /var/tmp/diff_new_pack.oiiAme/_old 2020-12-01 14:23:07.797615604 +0100
+++ /var/tmp/diff_new_pack.oiiAme/_new 2020-12-01 14:23:07.801615608 +0100
@@ -17,7 +17,7 @@
Name: musique
-Version: 1.10
+Version: 1.10.1
Release: 0
Summary: A different take on the music player
License: GPL-3.0-only AND LGPL-2.1-only
++++++ _service ++++++
--- /var/tmp/diff_new_pack.oiiAme/_old 2020-12-01 14:23:07.833615643 +0100
+++ /var/tmp/diff_new_pack.oiiAme/_new 2020-12-01 14:23:07.837615647 +0100
@@ -4,7 +4,7 @@
<param name="url">https://github.com/flaviotordini/musique.git</param>
<param name="filename">musique</param>
<param name="versionformat">@PARENT_TAG@</param>
- <param name="revision">1.10</param>
+ <param name="revision">1.10.1</param>
</service>
<service mode="disabled" name="recompress">
<param name="file">*.tar</param>
++++++ musique-1.10.tar.xz -> musique-1.10.1.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/.github/FUNDING.yml new/musique-1.10.1/.github/FUNDING.yml
--- old/musique-1.10/.github/FUNDING.yml 1970-01-01 01:00:00.000000000 +0100
+++ new/musique-1.10.1/.github/FUNDING.yml 2020-11-30 10:20:50.000000000 +0100
@@ -0,0 +1,2 @@
+github: flaviotordini
+custom: https://flavio.tordini.org/donate
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/lib/http/.github/FUNDING.yml new/musique-1.10.1/lib/http/.github/FUNDING.yml
--- old/musique-1.10/lib/http/.github/FUNDING.yml 1970-01-01 01:00:00.000000000 +0100
+++ new/musique-1.10.1/lib/http/.github/FUNDING.yml 2020-11-30 10:20:50.000000000 +0100
@@ -0,0 +1,2 @@
+github: flaviotordini
+custom: https://flavio.tordini.org/donate
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/lib/http/README.md new/musique-1.10.1/lib/http/README.md
--- old/musique-1.10/lib/http/README.md 2020-10-07 11:09:32.000000000 +0200
+++ new/musique-1.10.1/lib/http/README.md 2020-11-30 10:20:50.000000000 +0100
@@ -9,6 +9,7 @@
- Easier POST requests
- Read timeouts (don't let your requests get stuck forever). (now supported by Qt >= 5.15)
- Redirection support (now supported by Qt >= 5.6)
+- Disk-based cache implementation similar to Qt's but not strictly a HTTP cache, i.e. it ignores HTTP headers. This is good if want to cache successful requests irrespective of what the origin server says you should do. The cache also fallbacks to stale content when the server returns an error.
## Design
@@ -98,6 +99,19 @@
});
```
+Or using two separate signals for success and failure:
+```
+#include "http.h"
+
+auto reply = Http::instance().get("https://google.com/");
+connect(reply, &HttpReply::data, this, [](auto &bytes) {
+ qDebug() << "Feel the bytes!" << bytes;
+});
+connect(reply, &HttpReply::error, this, [](auto &msg) {
+ qDebug() << "Something's wrong here" << msg;
+});
+```
+
This is a real-world example of building a Http object with more complex features. It throttles requests, uses a custom user agent and caches results:
```
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/lib/http/src/cachedhttp.cpp new/musique-1.10.1/lib/http/src/cachedhttp.cpp
--- old/musique-1.10/lib/http/src/cachedhttp.cpp 2020-10-07 11:09:32.000000000 +0200
+++ new/musique-1.10.1/lib/http/src/cachedhttp.cpp 2020-11-30 10:20:50.000000000 +0100
@@ -97,7 +97,7 @@
qDebug() << "HIT" << key << req.url;
return new CachedHttpReply(value, req.url);
}
- qDebug() << "MISS" << key << req.url;
+ // qDebug() << "MISS" << key << req.url;
return new WrappedHttpReply(*this, cache, key, http.request(req));
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/lib/http/src/httpreply.h new/musique-1.10.1/lib/http/src/httpreply.h
--- old/musique-1.10/lib/http/src/httpreply.h 2020-10-07 11:09:32.000000000 +0200
+++ new/musique-1.10.1/lib/http/src/httpreply.h 2020-11-30 10:20:50.000000000 +0100
@@ -16,6 +16,19 @@
virtual QByteArray header(const QByteArray &headerName) const;
virtual QByteArray body() const = 0;
+ template <typename Functor> HttpReply &onData(Functor lambda) {
+ connect(this, &HttpReply::data, this, lambda);
+ return *this;
+ }
+ template <typename Functor> HttpReply &onError(Functor lambda) {
+ connect(this, &HttpReply::error, this, lambda);
+ return *this;
+ }
+ template <typename Functor> HttpReply &onFinished(Functor lambda) {
+ connect(this, &HttpReply::finished, this, lambda);
+ return *this;
+ }
+
signals:
void data(const QByteArray &bytes);
void error(const QString &message);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/lib/js/js.cpp new/musique-1.10.1/lib/js/js.cpp
--- old/musique-1.10/lib/js/js.cpp 2020-10-07 11:09:32.000000000 +0200
+++ new/musique-1.10.1/lib/js/js.cpp 2020-11-30 10:20:50.000000000 +0100
@@ -1,14 +1,12 @@
#include "js.h"
-#include "jsnamfactory.h"
-
#include "cachedhttp.h"
namespace {
Http &cachedHttp() {
static Http *h = [] {
CachedHttp *cachedHttp = new CachedHttp(Http::instance(), "js");
- cachedHttp->setMaxSeconds(3600 * 6);
+ cachedHttp->setMaxSeconds(3600);
// Avoid expiring the cached js
cachedHttp->setMaxSize(0);
@@ -85,12 +83,18 @@
if (engine) engine->deleteLater();
engine = new QQmlEngine(this);
- engine->setNetworkAccessManagerFactory(new JSNAMFactory);
+ engine->setNetworkAccessManagerFactory(&namFactory);
engine->globalObject().setProperty("global", engine->globalObject());
QJSValue timer = engine->newQObject(new JSTimer(engine));
+ engine->globalObject().setProperty("setTimeoutQt", timer.property("setTimeout"));
+ QJSValue setTimeoutWrapperFunction =
+ engine->evaluate("function setTimeout(cb, delay) {"
+ "const args = Array.prototype.slice.call(arguments, 2);"
+ "return setTimeoutQt(cb, delay, args);"
+ "}");
+ checkError(setTimeoutWrapperFunction);
engine->globalObject().setProperty("clearTimeout", timer.property("clearTimeout"));
- engine->globalObject().setProperty("setTimeout", timer.property("setTimeout"));
connect(cachedHttp().get(url), &HttpReply::finished, this, [this](auto &reply) {
if (!reply.isSuccessful()) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/lib/js/js.h new/musique-1.10.1/lib/js/js.h
--- old/musique-1.10/lib/js/js.h 2020-10-07 11:09:32.000000000 +0200
+++ new/musique-1.10.1/lib/js/js.h 2020-11-30 10:20:50.000000000 +0100
@@ -3,6 +3,7 @@
#include <QtQml>
+#include "jsnamfactory.h"
#include "jsresult.h"
class JSTimer : public QTimer {
@@ -24,14 +25,26 @@
return QJSValue();
}
// This should be static but cannot bind static functions to QJSEngine
- Q_INVOKABLE QJSValue setTimeout(QJSValue callback, QJSValue delayTime) {
- // qDebug() << callback.toString() << delayTime.toInt();
+ Q_INVOKABLE QJSValue setTimeout(QJSValue callback, QJSValue delayTime, QJSValue args) {
+ // qDebug() << callback.toString() << delayTime.toInt() << args.toString();
+
+ QJSValueList valueArgs;
+ if (args.isArray()) {
+ const int argsLength = args.property("length").toInt();
+ for (int i = 0; i < argsLength; ++i) {
+ auto arg = args.property(i);
+ qDebug() << "Adding arg" << arg.toString();
+ valueArgs << arg;
+ }
+ }
+
auto timer = new JSTimer();
timer->setInterval(delayTime.toInt());
- connect(timer, &JSTimer::timeout, this, [callback]() mutable {
+
+ connect(timer, &JSTimer::timeout, timer, [callback, valueArgs]() mutable {
qDebug() << "Calling" << callback.toString();
if (!callback.isCallable()) qDebug() << callback.toString() << "is not callable";
- auto value = callback.call();
+ auto value = callback.call(valueArgs);
if (value.isError()) {
qWarning() << "Error" << value.toString();
qDebug() << value.property("stack").toString().splitRef('\n');
@@ -62,6 +75,8 @@
static JS &instance();
explicit JS(QObject *parent = nullptr);
+ JSNAMFactory &getNamFactory() { return namFactory; };
+
void initialize(const QUrl &url);
bool checkError(const QJSValue &value);
@@ -78,6 +93,7 @@
void initialize();
QQmlEngine *engine;
+ JSNAMFactory namFactory;
bool initializing = false;
bool ready = false;
QUrl url;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/lib/js/jsnamfactory.cpp new/musique-1.10.1/lib/js/jsnamfactory.cpp
--- old/musique-1.10/lib/js/jsnamfactory.cpp 2020-10-07 11:09:32.000000000 +0200
+++ new/musique-1.10.1/lib/js/jsnamfactory.cpp 2020-11-30 10:20:50.000000000 +0100
@@ -24,16 +24,19 @@
auto headers = meta2.rawHeaders();
for (auto i = headers.begin(); i != headers.end(); ++i) {
// qDebug() << i->first << i->second;
- if (i->first == "Cache-Control" || i->first == "Expires") {
+ static const QVector<QByteArray> headersToRemove{"Cache-Control", "Expires", "Pragma"};
+ if (headersToRemove.contains(i->first)) {
qDebug() << "Removing" << i->first << i->second;
headers.erase(i);
}
}
+ meta2.setRawHeaders(headers);
return meta2;
}
-JSNAM::JSNAM(QObject *parent) : QNetworkAccessManager(parent) {
+JSNAM::JSNAM(QObject *parent, const JSNAMFactory &factory)
+ : QNetworkAccessManager(parent), factory(factory) {
auto cache = new JSDiskCache(this);
cache->setCacheDirectory(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) +
"/js");
@@ -50,13 +53,20 @@
auto req2 = request;
req2.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
- // TODO maybe set user agent
+ auto end = factory.getRequestHeaders().cend();
+ for (auto i = factory.getRequestHeaders().cbegin(); i != end; ++i) {
+ if (!req2.hasRawHeader(i.key()))
+ req2.setRawHeader(i.key(), i.value());
+ else
+ qDebug() << "Request for" << req2.url() << "already contains header" << i.key()
+ << req2.rawHeader(i.key());
+ }
- qDebug() << req2.url();
+ qDebug() << req2.url() << req2.rawHeaderList();
return QNetworkAccessManager::createRequest(op, req2, outgoingData);
}
QNetworkAccessManager *JSNAMFactory::create(QObject *parent) {
qDebug() << "Creating NAM";
- return new JSNAM(parent);
+ return new JSNAM(parent, *this);
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/lib/js/jsnamfactory.h new/musique-1.10.1/lib/js/jsnamfactory.h
--- old/musique-1.10/lib/js/jsnamfactory.h 2020-10-07 11:09:32.000000000 +0200
+++ new/musique-1.10.1/lib/js/jsnamfactory.h 2020-11-30 10:20:50.000000000 +0100
@@ -3,30 +3,39 @@
#include <QtQml>
-class JSDiskCache : public QNetworkDiskCache {
+class JSNAMFactory : public QQmlNetworkAccessManagerFactory {
public:
- JSDiskCache(QObject *parent);
- void updateMetaData(const QNetworkCacheMetaData &meta);
- QIODevice *prepare(const QNetworkCacheMetaData &meta);
+ QNetworkAccessManager *create(QObject *parent);
+
+ void setRequestHeaders(QMap<QByteArray, QByteArray> value) { requestHeaders = value; };
+ const QMap<QByteArray, QByteArray> &getRequestHeaders() const { return requestHeaders; }
private:
- QNetworkCacheMetaData fixMetadata(const QNetworkCacheMetaData &meta);
+ QMap<QByteArray, QByteArray> requestHeaders;
};
class JSNAM : public QNetworkAccessManager {
Q_OBJECT
public:
- JSNAM(QObject *parent);
+ JSNAM(QObject *parent, const JSNAMFactory &factory);
protected:
QNetworkReply *
createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData);
+
+private:
+ const JSNAMFactory &factory;
};
-class JSNAMFactory : public QQmlNetworkAccessManagerFactory {
+class JSDiskCache : public QNetworkDiskCache {
public:
- QNetworkAccessManager *create(QObject *parent);
+ JSDiskCache(QObject *parent);
+ void updateMetaData(const QNetworkCacheMetaData &meta);
+ QIODevice *prepare(const QNetworkCacheMetaData &meta);
+
+private:
+ QNetworkCacheMetaData fixMetadata(const QNetworkCacheMetaData &meta);
};
#endif // YTJSNAMFACTORY_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/lib/media/.github/FUNDING.yml new/musique-1.10.1/lib/media/.github/FUNDING.yml
--- old/musique-1.10/lib/media/.github/FUNDING.yml 1970-01-01 01:00:00.000000000 +0100
+++ new/musique-1.10.1/lib/media/.github/FUNDING.yml 2020-11-30 10:20:50.000000000 +0100
@@ -0,0 +1,2 @@
+github: flaviotordini
+custom: https://flavio.tordini.org/donate
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/lib/media/src/mpv/mediampv.cpp new/musique-1.10.1/lib/media/src/mpv/mediampv.cpp
--- old/musique-1.10/lib/media/src/mpv/mediampv.cpp 2020-10-07 11:09:32.000000000 +0200
+++ new/musique-1.10.1/lib/media/src/mpv/mediampv.cpp 2020-11-30 10:20:50.000000000 +0100
@@ -360,8 +360,9 @@
}
QString MediaMPV::file() const {
- char *path;
+ char *path = nullptr;
mpv_get_property(mpv, "path", MPV_FORMAT_STRING, &path);
+ if (!path) return QString();
return QString::fromUtf8(path);
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/lib/updater/.github/FUNDING.yml new/musique-1.10.1/lib/updater/.github/FUNDING.yml
--- old/musique-1.10/lib/updater/.github/FUNDING.yml 1970-01-01 01:00:00.000000000 +0100
+++ new/musique-1.10.1/lib/updater/.github/FUNDING.yml 2020-11-30 10:20:50.000000000 +0100
@@ -0,0 +1,2 @@
+github: flaviotordini
+custom: https://flavio.tordini.org/donate
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/lib/updater/README.md new/musique-1.10.1/lib/updater/README.md
--- old/musique-1.10/lib/updater/README.md 2020-10-07 11:09:32.000000000 +0200
+++ new/musique-1.10.1/lib/updater/README.md 2020-11-30 10:20:50.000000000 +0100
@@ -1,6 +1,6 @@
# An updater for Qt apps
-This is an extensible updater for Qt apps. It can wrap Sparkle on macOS and use its own implementation on Windows and Linux. I use it in my apps at https://flavio.tordini.org .
+This is an extensible updater for Qt apps. It can wrap [Sparkle](https://sparkle-project.org/) on macOS and use its own implementation on Windows and Linux. I use it in my apps at https://flavio.tordini.org .
## Design
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/lib/updater/marketplace.json new/musique-1.10.1/lib/updater/marketplace.json
--- old/musique-1.10/lib/updater/marketplace.json 1970-01-01 01:00:00.000000000 +0100
+++ new/musique-1.10.1/lib/updater/marketplace.json 2020-11-30 10:20:50.000000000 +0100
@@ -0,0 +1,48 @@
+{
+ "$schema": "http://qt.io/schema/extension-schema-v1#",
+ "title": "Updater",
+ "extensionType": [
+ "library"
+ ],
+ "version": "1",
+ "vendor": {
+ "name": "Flavio Tordini",
+ "url": "https://flavio.tordini.org"
+ },
+ "contact": "Flavio Tordini <flavio.tordini(a)gmail.com>",
+ "copyright": [
+ "Flavio Tordini"
+ ],
+ "author": "Flavio Tordini",
+ "icon": "https://flavio.tordini.org/favicon-196x196.png",
+ "licenses": [
+ {
+ "licenseType": "GPLv3",
+ "licenseUrl": "https://opensource.org/licenses/GPL-3.0"
+ }
+ ],
+ "created": "2020-07-03",
+ "platforms": [
+ "Windows",
+ "Linux",
+ "macOS"
+ ],
+ "qtVersions": [
+ "5.10.0-or-later"
+ ],
+ "tags": [
+ "updater,update,deploy,release,tools,utility"
+ ],
+ "price": {
+ "listprice": 0
+ },
+ "support": "flavio.tordini(a)gmail.com",
+ "bugUrl": "https://github.com/flaviotordini/updater/issues",
+ "sourceRepoUrl": "https://github.com/flaviotordini/updater",
+ "userManuals": [
+ "https://github.com/flaviotordini/updater/blob/master/README.md"
+ ],
+ "dependencies": [
+ "Network"
+ ]
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/lib/updater/src/impl/defaultupdater.cpp new/musique-1.10.1/lib/updater/src/impl/defaultupdater.cpp
--- old/musique-1.10/lib/updater/src/impl/defaultupdater.cpp 2020-10-07 11:09:32.000000000 +0200
+++ new/musique-1.10.1/lib/updater/src/impl/defaultupdater.cpp 2020-11-30 10:20:50.000000000 +0100
@@ -4,8 +4,8 @@
#include "dialog.h"
#include "downloader.h"
#include "installer.h"
+#include "openinstaller.h"
#include "parser.h"
-#include "runinstaller.h"
namespace updater {
@@ -89,7 +89,7 @@
void DefaultUpdater::update() {
if (!installer) {
- installer = new RunInstaller();
+ installer = new OpenInstaller();
installer->setUpdater(this);
}
connect(installer, &Installer::error, this, [](auto message) { qWarning() << message; });
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/lib/updater/src/impl/openinstaller.cpp new/musique-1.10.1/lib/updater/src/impl/openinstaller.cpp
--- old/musique-1.10/lib/updater/src/impl/openinstaller.cpp 1970-01-01 01:00:00.000000000 +0100
+++ new/musique-1.10.1/lib/updater/src/impl/openinstaller.cpp 2020-11-30 10:20:50.000000000 +0100
@@ -0,0 +1,13 @@
+#include "openinstaller.h"
+
+#include <QDesktopServices>
+
+namespace updater {
+
+OpenInstaller::OpenInstaller() {}
+
+void updater::OpenInstaller::start(const QString &filename) {
+ if (!QDesktopServices::openUrl(QUrl("file:///" + filename))) emit error("Cannot start update");
+}
+
+} // namespace updater
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/lib/updater/src/impl/openinstaller.h new/musique-1.10.1/lib/updater/src/impl/openinstaller.h
--- old/musique-1.10/lib/updater/src/impl/openinstaller.h 1970-01-01 01:00:00.000000000 +0100
+++ new/musique-1.10.1/lib/updater/src/impl/openinstaller.h 2020-11-30 10:20:50.000000000 +0100
@@ -0,0 +1,20 @@
+#ifndef OPENINSTALLER_H
+#define OPENINSTALLER_H
+
+#include <QtCore>
+
+#include "installer.h"
+
+namespace updater {
+
+/// Installer implementation that opens the downloaded update
+class OpenInstaller : public Installer {
+ Q_OBJECT
+
+public:
+ OpenInstaller();
+ void start(const QString &filename);
+};
+
+} // namespace updater
+#endif // OPENINSTALLER_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/lib/updater/src/impl/runinstaller.cpp new/musique-1.10.1/lib/updater/src/impl/runinstaller.cpp
--- old/musique-1.10/lib/updater/src/impl/runinstaller.cpp 2020-10-07 11:09:32.000000000 +0200
+++ new/musique-1.10.1/lib/updater/src/impl/runinstaller.cpp 2020-11-30 10:20:50.000000000 +0100
@@ -2,20 +2,58 @@
#include <QDesktopServices>
+#include "defaultupdater.h"
+
namespace updater {
RunInstaller::RunInstaller() : Installer() {}
void RunInstaller::start(const QString &filename) {
- if (arguments.isEmpty()) {
- if (!QDesktopServices::openUrl(QUrl("file:///" + filename)))
- emit error("Cannot start update");
+ auto processedArguments = arguments;
+ processedArguments << autoRestartArguments;
+
+ if (command.isEmpty()) {
+ command = filename;
+ } else {
+ // replace markers
+ for (auto &arg : processedArguments)
+ arg.replace("%filename%", filename);
+#ifdef Q_OS_LINUX
+ if (runAsAdmin) {
+ processedArguments.prepend(command);
+ command = "pkexec";
+ }
+#endif
+ }
+
+ QProcess *process = new QProcess();
+ QObject::connect(process, &QProcess::errorOccurred, this, [this](auto error) {
+ this->emit error("Update error: " + QVariant::fromValue(error).toString());
+ });
+
+ if (autoRestart && updater->getRelaunchAfterInstall()) {
+ auto thread = new QThread;
+ process->moveToThread(thread);
+ connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this,
+ [this](int exitCode, QProcess::ExitStatus exitStatus) {
+ qDebug() << "finished" << exitCode << exitStatus;
+ if (exitCode == 0 && exitStatus == QProcess::NormalExit) {
+ qDebug() << "Restarting" << qApp->applicationFilePath();
+ QProcess *restartProcess = new QProcess(this);
+ restartProcess->startDetached(qApp->applicationFilePath(), {});
+ }
+ });
+ qDebug() << "Executing" << command << processedArguments;
+ process->start(command, processedArguments);
+ process->waitForFinished(60000);
} else {
- QProcess *process = new QProcess(this);
- QObject::connect(process, &QProcess::errorOccurred, this, [this](auto error) {
- this->emit error("Update error: " + QVariant::fromValue(error).toString());
- });
- process->startDetached(filename, arguments);
+ qDebug() << "Forking" << command << processedArguments;
+ if (!process->startDetached(command, processedArguments)) {
+ qWarning() << "Cannot execute" << command << processedArguments
+ << process->errorString();
+ // Fallback to opening the downloaded payload
+ QDesktopServices::openUrl(QUrl("file:///" + filename));
+ }
}
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/lib/updater/src/impl/runinstaller.h new/musique-1.10.1/lib/updater/src/impl/runinstaller.h
--- old/musique-1.10/lib/updater/src/impl/runinstaller.h 2020-10-07 11:09:32.000000000 +0200
+++ new/musique-1.10.1/lib/updater/src/impl/runinstaller.h 2020-11-30 10:20:50.000000000 +0100
@@ -1,25 +1,42 @@
#ifndef UPDATER_IMPL_RUNINSTALLER_H
#define UPDATER_IMPL_RUNINSTALLER_H
-#include <QObject>
+#include <QtCore>
#include "installer.h"
namespace updater {
/**
- * Installer implementation that simply runs the downloaded update
+ * Installer implementation that executes a command with arguments
*/
class RunInstaller : public Installer {
Q_OBJECT
public:
RunInstaller();
+ void setCommand(const QString &value) { command = value; }
void setArguments(const QStringList &value) { arguments = value; };
+ /**
+ * Currently supported on Linux only using PackageKit (pkexec)
+ */
+ void setRunAsAdmin(bool value) { runAsAdmin = value; }
+ /**
+ * This will cause the update process to run while the app is still running. Then the app will
+ * self-restart.
+ */
+ void setAutoRestart(bool value) { autoRestart = value; }
+
+ void setRelaunchArguments(const QStringList &value) { autoRestartArguments = value; }
+
void start(const QString &filename);
private:
+ QString command;
QStringList arguments;
+ bool runAsAdmin = false;
+ bool autoRestart = false;
+ QStringList autoRestartArguments;
};
} // namespace updater
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/lib/updater/src/updater.cpp new/musique-1.10.1/lib/updater/src/updater.cpp
--- old/musique-1.10/lib/updater/src/updater.cpp 2020-10-07 11:09:32.000000000 +0200
+++ new/musique-1.10.1/lib/updater/src/updater.cpp 2020-11-30 10:20:50.000000000 +0100
@@ -124,6 +124,8 @@
void Updater::onUserAction() {
if (status == Updater::Status::UpdateDownloaded) {
+ // tell Installer we want the app to be restarted
+ setRelaunchAfterInstall(true);
// update will be installed on quit
qApp->quit();
return;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/lib/updater/src/updater.h new/musique-1.10.1/lib/updater/src/updater.h
--- old/musique-1.10/lib/updater/src/updater.h 2020-10-07 11:09:32.000000000 +0200
+++ new/musique-1.10.1/lib/updater/src/updater.h 2020-11-30 10:20:50.000000000 +0100
@@ -40,9 +40,15 @@
// This should be protected
void setDisplayVersion(const QString &value) { displayVersion = value; }
+ /// true if the app can be stopped and relaunched without user interaction
virtual bool getImmediateInstallAndRelaunch() const { return immediateInstallAndRelaunch; }
virtual void setImmediateInstallAndRelaunch(bool value) { immediateInstallAndRelaunch = value; }
+ /// true if the app has to be relaunched after the update has completed
+ virtual bool getRelaunchAfterInstall() const { return relaunchAfterInstall; }
+ virtual void setRelaunchAfterInstall(bool value) { relaunchAfterInstall = value; }
+
+ /// when true an available update will be downloaded without user interaction
virtual bool getAutomaticDownload() const { return automaticDownload; }
virtual void setAutomaticDownload(bool value) { automaticDownload = value; }
@@ -65,6 +71,7 @@
bool automaticDownload = true;
bool immediateInstallAndRelaunch = false;
+ bool relaunchAfterInstall = false;
Status status = Status::UpToDate;
QString version;
QString displayVersion;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/lib/updater/updater.pri new/musique-1.10.1/lib/updater/updater.pri
--- old/musique-1.10/lib/updater/updater.pri 2020-10-07 11:09:32.000000000 +0200
+++ new/musique-1.10.1/lib/updater/updater.pri 2020-11-30 10:20:50.000000000 +0100
@@ -16,7 +16,7 @@
OBJECTIVE_SOURCES += $$PWD/src/sparkle/sparkleupdater.mm
} else {
DEFINES += UPDATER_DEFAULT
- QT *= network
+ QT *= network widgets
INCLUDEPATH += $$PWD/src/impl
DEPENDPATH += $$PWD/src/impl
@@ -29,7 +29,8 @@
$$PWD/src/impl/parser.h \
$$PWD/src/impl/runinstaller.h \
$$PWD/src/impl/simplexmlparser.h \
- $$PWD/src/impl/appcastparser.h
+ $$PWD/src/impl/appcastparser.h \
+ $$PWD/src/impl/openinstaller.h
SOURCES += \
$$PWD/src/impl/checker.cpp \
@@ -38,5 +39,6 @@
$$PWD/src/impl/downloader.cpp \
$$PWD/src/impl/runinstaller.cpp \
$$PWD/src/impl/simplexmlparser.cpp \
- $$PWD/src/impl/appcastparser.cpp
+ $$PWD/src/impl/appcastparser.cpp \
+ $$PWD/src/impl/openinstaller.cpp
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/locale/ms_MY.ts new/musique-1.10.1/locale/ms_MY.ts
--- old/musique-1.10/locale/ms_MY.ts 2020-10-07 11:09:32.000000000 +0200
+++ new/musique-1.10.1/locale/ms_MY.ts 2020-11-30 10:20:50.000000000 +0100
@@ -210,7 +210,7 @@
</message>
<message>
<source>Use %1 library</source>
- <translation type="unfinished"/>
+ <translation>Guna pustaka %1</translation>
</message>
</context>
<context>
@@ -664,15 +664,15 @@
</message>
<message>
<source>Thanks for updating %1 to version %2!</source>
- <translation type="unfinished"/>
+ <translation>Terima kasih kerana mengemas kini %1 ke versi %2!</translation>
</message>
<message>
<source>If you enjoy %1, perhaps having installed it months or even years ago, please consider becoming one of the people willing to support something you enjoy.</source>
- <translation type="unfinished"/>
+ <translation>Jika anda menyukai %1, mungkin telah memasangnya beberapa bulan atau tahun yang lalu, dialu-alukan menyokong hasil kerja yang anda nikmati ini.</translation>
</message>
<message>
<source>Donate</source>
- <translation type="unfinished"/>
+ <translation>Beri Sumbangan</translation>
</message>
</context>
<context>
@@ -767,31 +767,31 @@
<name>Updater</name>
<message>
<source>Check for Updates...</source>
- <translation type="unfinished"/>
+ <translation>Periksa Kemas Kini...</translation>
</message>
<message>
<source>Version %1 is available...</source>
- <translation type="unfinished"/>
+ <translation>Versi %1 sudah tersedia...</translation>
</message>
<message>
<source>Downloading version %1...</source>
- <translation type="unfinished"/>
+ <translation>Memuat turun versi %1...</translation>
</message>
<message>
<source>Restart to Update</source>
- <translation type="unfinished"/>
+ <translation>Mula Semula untuk Kemas Kini</translation>
</message>
<message>
<source>Version %1 download failed</source>
- <translation type="unfinished"/>
+ <translation>Gagal memuat turun versi %1</translation>
</message>
<message>
<source>Check for Updates</source>
- <translation type="unfinished"/>
+ <translation>Periksa Kemas Kini</translation>
</message>
<message>
<source>Download Update</source>
- <translation type="unfinished"/>
+ <translation>Muat Turun Kemas Kini</translation>
</message>
<message>
<source>Downloading update...</source>
@@ -799,37 +799,37 @@
</message>
<message>
<source>Retry Update Download</source>
- <translation type="unfinished"/>
+ <translation>Cuba Lagi Muat Turun Kemas Kini</translation>
</message>
<message>
<source>You have the latest version.</source>
- <translation type="unfinished"/>
+ <translation>Anda sudah memiliki versi terkini.</translation>
</message>
<message>
<source>Version %1 is available.</source>
- <translation type="unfinished"/>
+ <translation>Versi %1 sudah tersedia.</translation>
</message>
<message>
<source>An update has been downloaded and is ready to be installed.</source>
- <translation type="unfinished"/>
+ <translation>Satu kemas kini telah dimuat turun dan sedia dipasang.</translation>
</message>
</context>
<context>
<name>updater::DefaultUpdater</name>
<message>
<source>There are currently no updates available.</source>
- <translation type="unfinished"/>
+ <translation>Tiada kemas kini buat masa ini.</translation>
</message>
</context>
<context>
<name>updater::Dialog</name>
<message>
<source>You already have the latest version</source>
- <translation type="unfinished"/>
+ <translation>Anda sudah memiliki versi terkini</translation>
</message>
<message>
<source>Downloading %1 %2...</source>
- <translation type="unfinished"/>
+ <translation>Memuat turun %1 %2...</translation>
</message>
<message>
<source>A new version of %1 is available!</source>
@@ -849,7 +849,7 @@
</message>
<message>
<source>Download Update</source>
- <translation type="unfinished"/>
+ <translation>Muat Turun Kemas Kini</translation>
</message>
</context>
</TS>
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/locale/pt_BR.ts new/musique-1.10.1/locale/pt_BR.ts
--- old/musique-1.10/locale/pt_BR.ts 2020-10-07 11:09:32.000000000 +0200
+++ new/musique-1.10.1/locale/pt_BR.ts 2020-11-30 10:20:50.000000000 +0100
@@ -767,15 +767,15 @@
<name>Updater</name>
<message>
<source>Check for Updates...</source>
- <translation type="unfinished"/>
+ <translation>Verificar se há atualizações...</translation>
</message>
<message>
<source>Version %1 is available...</source>
- <translation type="unfinished"/>
+ <translation>A Versão %1 está disponível...</translation>
</message>
<message>
<source>Downloading version %1...</source>
- <translation type="unfinished"/>
+ <translation>Baixando a versão %1...</translation>
</message>
<message>
<source>Restart to Update</source>
@@ -791,7 +791,7 @@
</message>
<message>
<source>Download Update</source>
- <translation type="unfinished"/>
+ <translation>Baixar Atualização</translation>
</message>
<message>
<source>Downloading update...</source>
@@ -807,7 +807,7 @@
</message>
<message>
<source>Version %1 is available.</source>
- <translation type="unfinished"/>
+ <translation>A Versão %1 já está disponível.</translation>
</message>
<message>
<source>An update has been downloaded and is ready to be installed.</source>
@@ -829,7 +829,7 @@
</message>
<message>
<source>Downloading %1 %2...</source>
- <translation type="unfinished"/>
+ <translation>Baixando %1 %2...</translation>
</message>
<message>
<source>A new version of %1 is available!</source>
@@ -849,7 +849,7 @@
</message>
<message>
<source>Download Update</source>
- <translation type="unfinished"/>
+ <translation>Baixar Atualização</translation>
</message>
</context>
</TS>
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/musique.pro new/musique-1.10.1/musique.pro
--- old/musique-1.10/musique.pro 2020-10-07 11:09:32.000000000 +0200
+++ new/musique-1.10.1/musique.pro 2020-11-30 10:20:50.000000000 +0100
@@ -1,7 +1,7 @@
CONFIG += c++17 exceptions_off rtti_off optimize_full object_parallel_to_source
TEMPLATE = app
-VERSION = 1.10
+VERSION = 1.10.1
DEFINES += APP_VERSION="$$VERSION"
APP_NAME = Musique
@@ -254,10 +254,6 @@
}
mac|win32|contains(DEFINES, APP_UBUNTU):include(local/local.pri)
-!contains(DEFINES, APP_MAC_STORE) {
- include(lib/updater/updater.pri)
-}
-
message(QT: $$QT)
message(CONFIG: $$CONFIG)
message(DEFINES: $$DEFINES)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/src/httputils.cpp new/musique-1.10.1/src/httputils.cpp
--- old/musique-1.10/src/httputils.cpp 2020-10-07 11:09:32.000000000 +0200
+++ new/musique-1.10.1/src/httputils.cpp 2020-11-30 10:20:50.000000000 +0100
@@ -72,3 +72,10 @@
}();
return ua;
}
+
+const QByteArray &HttpUtils::stealthUserAgent() {
+ static const QByteArray ua =
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like "
+ "Gecko) Chrome/84.0.4147.105 Safari/537.36";
+ return ua;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/src/httputils.h new/musique-1.10.1/src/httputils.h
--- old/musique-1.10/src/httputils.h 2020-10-07 11:09:32.000000000 +0200
+++ new/musique-1.10.1/src/httputils.h 2020-11-30 10:20:50.000000000 +0100
@@ -12,6 +12,7 @@
static Http &cached();
static Http ¬Cached();
static const QByteArray &userAgent();
+ static const QByteArray &stealthUserAgent();
private:
HttpUtils() {}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/musique-1.10/src/mainwindow.cpp new/musique-1.10.1/src/mainwindow.cpp
--- old/musique-1.10/src/mainwindow.cpp 2020-10-07 11:09:32.000000000 +0200
+++ new/musique-1.10.1/src/mainwindow.cpp 2020-11-30 10:20:50.000000000 +0100
@@ -131,7 +131,9 @@
}
void MainWindow::lazyInit() {
- JS::instance().initialize(QUrl(QLatin1String(Constants::WEBSITE) + "-ws/bundle.js"));
+ JS::instance().getNamFactory().setRequestHeaders(
+ {{"User-Agent", HttpUtils::stealthUserAgent()}});
+ JS::instance().initialize(QUrl(QLatin1String(Constants::WEBSITE) + "-ws/bundle2.js"));
GlobalShortcuts &shortcuts = GlobalShortcuts::instance();
#ifdef APP_MAC
1
0
01 Dec '20
Hello community,
here is the log from the commit of package python-model-bakery for openSUSE:Factory checked in at 2020-12-01 14:22:52
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-model-bakery (Old)
and /work/SRC/openSUSE:Factory/.python-model-bakery.new.5913 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-model-bakery"
Tue Dec 1 14:22:52 2020 rev:2 rq:851869 version:1.2.1
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-model-bakery/python-model-bakery.changes 2020-09-06 00:03:01.931272763 +0200
+++ /work/SRC/openSUSE:Factory/.python-model-bakery.new.5913/python-model-bakery.changes 2020-12-01 14:23:05.705613341 +0100
@@ -1,0 +2,20 @@
+Fri Nov 27 06:23:38 UTC 2020 - John Vandenberg <jayvdb(a)gmail.com>
+
+- Add changelog and docs
+- Enable Leap builds by disabling Python 2
+- Update to v1.2.1
+ * Add ability to pass `str` values to `foreign_key` for recipes
+ from other modules
+ * Add new parameter `_using` to support multi database applications
+ * Fixed _model parameter annotations
+ * Fixed bug when field has callable `default`
+ * Drop Python 3.5 support as it is retired
+ * Remove support for Django<2.2
+- from v1.2.0
+ * Support to Django 3.1 `JSONField`
+ * Added type annotations
+ * Support for Python 3.9
+ * Support for `prefix` in `seq` values
+ * Adjust imports for Django 3.1 compatibility
+
+-------------------------------------------------------------------
Old:
----
model_bakery-1.1.1.tar.gz
New:
----
model_bakery-1.2.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-model-bakery.spec ++++++
--- /var/tmp/diff_new_pack.ziXNgw/_old 2020-12-01 14:23:06.365614055 +0100
+++ /var/tmp/diff_new_pack.ziXNgw/_new 2020-12-01 14:23:06.369614059 +0100
@@ -13,25 +13,27 @@
# published by the Open Source Initiative.
# Please submit bugfixes or comments via https://bugs.opensuse.org/
+#
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
+%define skip_python2 1
Name: python-model-bakery
-Version: 1.1.1
+Version: 1.2.1
Release: 0
-License: Apache-2.0
Summary: Smart object creation facility for Django
-Url: http://github.com/model-bakers/model_bakery
+License: Apache-2.0
Group: Development/Languages/Python
+Url: http://github.com/model-bakers/model_bakery
Source: https://files.pythonhosted.org/packages/source/m/model-bakery/model_bakery-…
-BuildRequires: python-rpm-macros
BuildRequires: %{python_module setuptools}
+BuildRequires: python-rpm-macros
# SECTION test requirements
-BuildRequires: %{python_module django >= 1.11.0}
+BuildRequires: %{python_module Django >= 2.2}
BuildRequires: %{python_module pytest-django}
# /SECTION
BuildRequires: fdupes
-Requires: python-django >= 1.11.0
+Requires: python-Django >= 2.2
BuildArch: noarch
%python_subpackages
@@ -50,11 +52,11 @@
%python_expand %fdupes %{buildroot}%{$python_sitelib}
%check
-export PYTHONPATH=.
+export PYTHONPATH=${PWD}
%pytest
%files %{python_files}
-%doc README.md
+%doc CHANGELOG.md README.md docs/source/*.rst
%license LICENSE
%{python_sitelib}/*
++++++ model_bakery-1.1.1.tar.gz -> model_bakery-1.2.1.tar.gz ++++++
++++ 3377 lines of diff (skipped)
1
0
Hello community,
here is the log from the commit of package neomutt for openSUSE:Factory checked in at 2020-12-01 14:22:50
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/neomutt (Old)
and /work/SRC/openSUSE:Factory/.neomutt.new.5913 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "neomutt"
Tue Dec 1 14:22:50 2020 rev:17 rq:851847 version:20201127
Changes:
--------
--- /work/SRC/openSUSE:Factory/neomutt/neomutt.changes 2020-11-26 23:13:08.388965988 +0100
+++ /work/SRC/openSUSE:Factory/.neomutt.new.5913/neomutt.changes 2020-12-01 14:23:04.341611865 +0100
@@ -1,0 +2,11 @@
+Fri Nov 27 15:50:29 UTC 2020 - Kai Liu <kai.liu(a)suse.com>
+
+- Update to version 20201127:
+ * Bug Fixes
+ - Fix crash when saving an alias
+ * Translations
+ - 70% Russian
+ * Code
+ - Remove redundant function call
+
+-------------------------------------------------------------------
Old:
----
20201120.tar.gz
20201120.tar.gz.sig
New:
----
20201127.tar.gz
20201127.tar.gz.sig
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ neomutt.spec ++++++
--- /var/tmp/diff_new_pack.P4e1QA/_old 2020-12-01 14:23:04.997612574 +0100
+++ /var/tmp/diff_new_pack.P4e1QA/_new 2020-12-01 14:23:05.001612579 +0100
@@ -17,7 +17,7 @@
Name: neomutt
-Version: 20201120
+Version: 20201127
Release: 0
Summary: A command line mail reader (or MUA), a fork of Mutt with added features
License: GPL-2.0-or-later
++++++ 20201120.tar.gz -> 20201127.tar.gz ++++++
++++ 1759 lines of diff (skipped)
1
0