dyyyyyyyy/swe-rebench-filtered-1150 huggingface dataset:
task: metadata: install: pip install -e .[dev]
patch: diff --git a/sqlglot/dialects/redshift.py b/sqlglot/dialects/redshift.py
index cd50979e..1ffc41fa 100644
--- a/sqlglot/dialects/redshift.py
+++ b/sqlglot/dialects/redshift.py
@@ -1,6 +1,7 @@
 from __future__ import annotations
 
 from sqlglot import exp, transforms
+from sqlglot.dialects.dialect import rename_func
 from sqlglot.dialects.postgres import Postgres
 from sqlglot.tokens import TokenType
 
@@ -13,6 +14,12 @@ class Redshift(Postgres):
         "HH": "%H",
     }
 
+    class Parser(Postgres.Parser):
+        FUNCTIONS = {
+            **Postgres.Parser.FUNCTIONS,  # type: ignore
+            "DECODE": exp.Matches.from_arg_list,
+        }
+
     class Tokenizer(Postgres.Tokenizer):
         ESCAPES = ["\\"]
 
@@ -50,4 +57,5 @@ class Redshift(Postgres):
             exp.DistKeyProperty: lambda self, e: f"DISTKEY({e.name})",
             exp.SortKeyProperty: lambda self, e: f"{'COMPOUND ' if e.args['compound'] else ''}SORTKEY({self.format_args(*e.this)})",
             exp.DistStyleProperty: lambda self, e: self.naked_property(e),
+            exp.Matches: rename_func("DECODE"),
         }

problem_statement: Redshift DECODE
Current parsing for Redshift DECODE leads to a parsing error: https://docs.aws.amazon.com/redshift/latest/dg/r_DECODE_expression.html
e.g. SELECT DECODE(COL1, 'replace_this', 'with_this', 'replace_that', 'with_that') 

Redshift DECODE is essentially REPLACE but allows unlimited arguments. 

However, mapping DECODE to REPLACE in the tokenizer didn't work and I realised this was the wrong approach. I then tried adding DECODE to FUNC_TOKENS in redshift.py but that still didn't work. Not sure how to override DECODE in expressions.
repo: tobymao/sqlglot
test_cmd: pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
test_patch: diff --git a/tests/dialects/test_redshift.py b/tests/dialects/test_redshift.py
index 1943ee38..4c3d8587 100644
--- a/tests/dialects/test_redshift.py
+++ b/tests/dialects/test_redshift.py
@@ -56,8 +56,19 @@ class TestRedshift(Validator):
                 "redshift": 'SELECT a, b FROM (SELECT a, b, ROW_NUMBER() OVER (PARTITION BY a ORDER BY c DESC) AS "_row_number" FROM x) WHERE "_row_number" = 1',
             },
         )
+        self.validate_all(
+            "DECODE(x, a, b, c, d)",
+            write={
+                "": "MATCHES(x, a, b, c, d)",
+                "oracle": "DECODE(x, a, b, c, d)",
+                "snowflake": "DECODE(x, a, b, c, d)",
+            },
+        )
 
     def test_identity(self):
+        self.validate_identity(
+            "SELECT DECODE(COL1, 'replace_this', 'with_this', 'replace_that', 'with_that')"
+        )
         self.validate_identity("CAST('bla' AS SUPER)")
         self.validate_identity("CREATE TABLE real1 (realcol REAL)")
         self.validate_identity("CAST('foo' AS HLLSKETCH)")
task: metadata: install: pip install -e .[dev]
patch: diff --git a/lineflow/core.py b/lineflow/core.py
index b9d31c7..8bcfb0a 100644
--- a/lineflow/core.py
+++ b/lineflow/core.py
@@ -206,6 +206,12 @@ class IterableDataset(Dataset):
     def __len__(self) -> int:
         return super(IterableDataset, self).__len__()
 
+    def __getitem__(self, index: Union[int, slice]) -> Union[Any, List[Any]]:
+        out = super(IterableDataset, self).__getitem__(index)
+        if isinstance(out, list):
+            out = Dataset(out)
+        return out
+
 
 class ConcatDataset(Dataset):
     def __init__(self, *datasets: List[DatasetMixin]) -> None:

problem_statement: Should slice of IterableDataset return IterableDataset not List?
**Is your feature request related to a problem? Please describe.**

```py
train = lfds.SciTLDR(split="train")  # IterableDataset
train_mini = train[:10]  # Now this is just a python list (List[Any])
```

If I make a subset of a dataset, it loses all the features such as `.map`.

**Describe the solution you'd like**
Return `IterableDataset` in stead of List.
repo: tofunlp/lineflow
test_cmd: pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
test_patch: diff --git a/tests/test_core.py b/tests/test_core.py
index 6171a5a..9e40110 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -158,6 +158,14 @@ class IterableDatasetTestCase(TestCase):
         self.assertEqual(self.data._length, len(self.base))
         self.assertTrue(self.data._computed)
 
+    def test_dunder_slice(self):
+        # Subset of IterableDataset should be Dataset.
+        subset = self.data[:10]
+        self.assertIsInstance(subset, Dataset)
+
+        single_sample = self.data[0]
+        self.assertIsInstance(single_sample, int)
+
 
 class DatasetTestCase(TestCase):
task: metadata: install: pip install -e .
patch: diff --git a/sievelib/commands.py b/sievelib/commands.py
index acb4535..fa133d5 100644
--- a/sievelib/commands.py
+++ b/sievelib/commands.py
@@ -798,7 +798,16 @@ class ExistsCommand(TestCommand):
     ]
 
     def args_as_tuple(self):
+        """FIXME: en fonction de la manière dont la commande a été générée
+        (factory ou parser), le type des arguments est différent :
+        string quand ça vient de la factory ou type normal depuis le
+        parser. Il faut uniformiser tout ça !!
+
+        """
         value = self.arguments["header-names"]
+        if isinstance(value, list):
+            value = "[{}]".format(
+                ",".join('"{}"'.format(item) for item in value))
         if not value.startswith("["):
             return ('exists', value.strip('"'))
         return ("exists", ) + tuple(tools.to_list(value))

problem_statement: factory: problem while exporting exists command
When we try to export an exists command, previously parsed, through the factory module, it fails with the following stack:
```python
>>> c = fs.get_filter_conditions('[test]')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/matteo/src/webmail/be/qbservice/sievelib/factory.py", line 387, in get_filter_conditions
    args = node.args_as_tuple()
  File "/home/matteo/src/webmail/be/qbservice/sievelib/commands.py", line 802, in args_as_tuple
    if not value.startswith("["):
AttributeError: 'list' object has no attribute 'startswith'
```
repo: tonioo/sievelib
test_cmd: pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
test_patch: diff --git a/sievelib/tests/test_factory.py b/sievelib/tests/test_factory.py
index f425363..7787e5c 100644
--- a/sievelib/tests/test_factory.py
+++ b/sievelib/tests/test_factory.py
@@ -5,6 +5,7 @@ import unittest
 import six
 
 from sievelib.factory import FiltersSet
+from .. import parser
 
 
 class FactoryTestCase(unittest.TestCase):
@@ -91,6 +92,21 @@ class FactoryTestCase(unittest.TestCase):
         conditions = self.fs.get_filter_conditions("ruleE")
         self.assertEqual(orig_conditions, conditions)
 
+    def test_get_filter_conditions_from_parser_result(self):
+        res = """require ["fileinto"];
+
+# rule:[test]
+if anyof (exists ["Subject"]) {
+    fileinto "INBOX";
+}
+"""
+        p = parser.Parser()
+        p.parse(res)
+        fs = FiltersSet("test", '# rule:')
+        fs.from_parser_result(p)
+        c = fs.get_filter_conditions('[test]')
+        self.assertEqual(c, [("exists", "Subject")])
+
     def test_get_filter_matchtype(self):
         """Test get_filter_matchtype method."""
         self.fs.addfilter(
task: metadata: install: pip install -e .[dev]
patch: diff --git a/docs/changelog/1095.bugfix.rst b/docs/changelog/1095.bugfix.rst
new file mode 100644
index 00000000..9d0abc24
--- /dev/null
+++ b/docs/changelog/1095.bugfix.rst
@@ -0,0 +1,1 @@
+Don't rewrite ``{posargs}`` substitution for absolute paths.
diff --git a/src/tox/config.py b/src/tox/config.py
index b499a8aa..4d5e02be 100755
--- a/src/tox/config.py
+++ b/src/tox/config.py
@@ -184,10 +184,10 @@ class PosargsOption:
             if value:
                 args = []
                 for arg in config.option.args:
-                    if arg:
-                        origpath = config.invocationcwd.join(arg, abs=True)
-                        if origpath.check():
-                            arg = testenv_config.changedir.bestrelpath(origpath)
+                    if arg and not os.path.isabs(arg):
+                        origpath = os.path.join(config.invocationcwd.strpath, arg)
+                        if os.path.exists(origpath):
+                            arg = os.path.relpath(origpath, testenv_config.changedir.strpath)
                     args.append(arg)
             testenv_config._reader.addsubstitutions(args)
         return value

problem_statement: why the arguments are changed?


When using the *posargs*， the path in the argument is changed with no reason. Why ?

tox.ini
```
[tox]
envlist=py27,py36
skipsdist=True

[testenv]
deps = pytest
commands=pytest -s tests {posargs}
```


![image](https://user-images.githubusercontent.com/1487879/49358412-8dc60300-f70d-11e8-890e-7559e484b4ab.png)

repo: tox-dev/tox
test_cmd: pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
test_patch: diff --git a/tests/unit/test_config.py b/tests/unit/test_config.py
index 86f36319..08a1ced4 100644
--- a/tests/unit/test_config.py
+++ b/tests/unit/test_config.py
@@ -11,6 +11,7 @@ import tox
 from tox.config import (
     CommandParser,
     DepOption,
+    PosargsOption,
     SectionReader,
     get_homedir,
     get_version_info,
@@ -2969,3 +2970,29 @@ def test_config_current_py(newconfig, current_tox_py, cmd, tmpdir, monkeypatch):
     assert config.envconfigs[current_tox_py]
     result = cmd()
     assert result.ret == 0, result.out
+
+
+def test_posargs_relative_changedir(newconfig, tmpdir):
+    dir1 = tmpdir.join("dir1").ensure()
+    tmpdir.join("dir2").ensure()
+    with tmpdir.as_cwd():
+        config = newconfig(
+            """\
+            [tox]
+            [testenv]
+            changedir = dir2
+            commands =
+                echo {posargs}
+            """
+        )
+        config.option.args = ["dir1", dir1.strpath, "dir3"]
+        testenv = config.envconfigs["python"]
+        PosargsOption().postprocess(testenv, config.option.args)
+
+        assert testenv._reader.posargs == [
+            # should have relative-ized
+            os.path.join("..", "dir1"),
+            # should have stayed the same,
+            dir1.strpath,
+            "dir3",
+        ]
task: metadata: install: pip install -e .[testing]
patch: diff --git a/docs/changelog/2343.bugfix.rst b/docs/changelog/2343.bugfix.rst
new file mode 100644
index 00000000..8328e1a5
--- /dev/null
+++ b/docs/changelog/2343.bugfix.rst
@@ -0,0 +1,1 @@
+Fix CLI raises an error for ``-va`` with ``ignored explicit argument 'a'`` - by :user:`gaborbernat`.
diff --git a/src/tox/config/cli/parse.py b/src/tox/config/cli/parse.py
index 51e4c2de..e7868469 100644
--- a/src/tox/config/cli/parse.py
+++ b/src/tox/config/cli/parse.py
@@ -43,7 +43,11 @@ def get_options(*args: str) -> Options:
 def _get_base(args: Sequence[str]) -> tuple[int, ToxHandler, Source]:
     """First just load the base options (verbosity+color) to setup the logging framework."""
     tox_parser = ToxParser.base()
-    parsed, _ = tox_parser.parse_known_args(args)
+    parsed = Parsed()
+    try:
+        tox_parser.parse_known_args(args, namespace=parsed)
+    except SystemExit:
+        ...  # ignore parse errors, such as -va raises ignored explicit argument 'a'
     guess_verbosity = parsed.verbosity
     handler = setup_report(guess_verbosity, parsed.is_colored)
     from tox.plugin.manager import MANAGER  # load the plugin system right after we set up report

problem_statement: tox4: error: argument -q/--quiet: ignored explicit argument 're'
When I try to use the latest tox with merged command-line arguments like `tox4 -qre py310` it gives me the following error:
```
usage: tox4 [--colored {yes,no}] [-v | -q] [-c file] [--workdir dir] [--root dir]
tox4: error: argument -q/--quiet: ignored explicit argument 're'
```
Is that intentional?
repo: tox-dev/tox
test_cmd: pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
test_patch: diff --git a/tests/config/cli/test_parse.py b/tests/config/cli/test_parse.py
index c635ac89..8852bfdb 100644
--- a/tests/config/cli/test_parse.py
+++ b/tests/config/cli/test_parse.py
@@ -38,3 +38,9 @@ def test_verbosity_guess_miss_match(capsys: CaptureFixture) -> None:
 
     out, err = capsys.readouterr()
     assert out == "ROOT: E\nROOT: W\nROOT: I\n"
+
+
+@pytest.mark.parametrize("arg", ["-av", "-va"])
+def test_verbosity(arg: str) -> None:
+    result = get_options(arg)
+    assert result.parsed.verbosity == 3
task: metadata: install: pip install -e .
patch: diff --git a/sourcefinder/image.py b/sourcefinder/image.py
index 48923c7..4f48f44 100644
--- a/sourcefinder/image.py
+++ b/sourcefinder/image.py
@@ -451,7 +451,7 @@ class ImageData(object):
             labelled_data=labelled_data, labels=labels
         )
 
-    def reverse_se(self, det):
+    def reverse_se(self, det, anl):
         """Run source extraction on the negative of this image.
 
         Obviously, there should be no sources in the negative image, so this
@@ -465,7 +465,7 @@ class ImageData(object):
         self.labels.clear()
         self.clip.clear()
         self.data_bgsubbed *= -1
-        results = self.extract(det=det)
+        results = self.extract(det=det, anl=anl)
         self.data_bgsubbed *= -1
         self.labels.clear()
         self.clip.clear()

problem_statement: Missing argument in `ImageData.reverse_se`
### Description

Mypy tells me:
```
sourcefinder/image.py:468: error: Missing positional argument "anl" in call to "extract"  [call-arg]
```

I don't know what should be the correct value of `anl` here, so I
couldn't fix it.

### Remarks

This method is not used anywhere in PySE.  I'm guessing this was
implemented because it might be useful elsewhere in TraP?  If so,
there should be explicit tests for the `ImageData` class testing all
potential downstream API calls.  There are no such tests.

repo: transientskp/pyse
test_cmd: pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
test_patch: diff --git a/test/test_image.py b/test/test_image.py
index 04b9abc..6176d02 100644
--- a/test/test_image.py
+++ b/test/test_image.py
@@ -435,3 +435,28 @@ class TestFailureModes(unittest.TestCase):
                         msg="Data should be flat")
         with self.assertRaises(RuntimeError):
             sfimage.extract(det=5, anl=3)
+
+class TestNegationImage(unittest.TestCase):
+    """
+    Check if we do not detect any sources from the negation of a Stokes I
+    image with many sources.
+    """
+    def setUp(self):
+        fitsfile = sourcefinder.accessors.open(os.path.join(DATAPATH,
+                                                            'deconvolved.fits'))
+        self.img = ImageData(fitsfile.data, fitsfile.beam, fitsfile.wcs)
+
+    @requires_data(os.path.join(DATAPATH, 'deconvolved.fits'))
+    def testReverseSE(self):
+        """
+        We extract with a 5 sigma detection limit on the negation of an
+        artificial 2K * 2K Stokes I image with 3969 bright sources in
+        correlated noise. With this limit one should barely extract a source,
+        since erfc(5/sqrt(2))/2 * 2**22 ~ 1. This simple calculation, however,
+        assumes uncorrelated noise. A 6 sigma detection limit may be needed
+        when this test is applied to other 2K *2K images or to larger images.
+        """
+        extraction_results = self.img.reverse_se(det=5.0, anl=4.0)
+        self.assertTrue(len(extraction_results) == 0,
+                        msg=("Extracting sources from the negation of a Stokes"
+                             " I image should yield only noise peaks."))
task: metadata: install: pip install -e .[tests]
patch: diff --git a/trino/sqlalchemy/dialect.py b/trino/sqlalchemy/dialect.py
index febfac5..9a401d4 100644
--- a/trino/sqlalchemy/dialect.py
+++ b/trino/sqlalchemy/dialect.py
@@ -22,7 +22,12 @@ from sqlalchemy.engine.url import URL
 
 from trino import dbapi as trino_dbapi
 from trino import logging
-from trino.auth import BasicAuthentication, CertificateAuthentication, JWTAuthentication
+from trino.auth import (
+    BasicAuthentication,
+    CertificateAuthentication,
+    JWTAuthentication,
+    OAuth2Authentication,
+)
 from trino.dbapi import Cursor
 from trino.sqlalchemy import compiler, datatype, error
 
@@ -113,6 +118,10 @@ class TrinoDialect(DefaultDialect):
             kwargs["http_scheme"] = "https"
             kwargs["auth"] = CertificateAuthentication(unquote_plus(url.query['cert']), unquote_plus(url.query['key']))
 
+        if "externalAuthentication" in url.query:
+            kwargs["http_scheme"] = "https"
+            kwargs["auth"] = OAuth2Authentication()
+
         if "source" in url.query:
             kwargs["source"] = unquote_plus(url.query["source"])
         else:

problem_statement: SQLAlchemy support for externalAuthentication
### Describe the feature

It'd be great to have SQLAlchemy support for the externalAuthentication query parameter since there are a few libraries that use SQLAlchemy underneath and sometimes passing a Python Class through the connection_args is not possible

### Describe alternatives you've considered

_No response_

### Are you willing to submit PR?

- [X] Yes I am willing to submit a PR!
repo: trinodb/trino-python-client
test_cmd: pytest -sv tests/
test_patch: diff --git a/tests/unit/sqlalchemy/test_dialect.py b/tests/unit/sqlalchemy/test_dialect.py
index c385ab9..413a6bb 100644
--- a/tests/unit/sqlalchemy/test_dialect.py
+++ b/tests/unit/sqlalchemy/test_dialect.py
@@ -4,7 +4,7 @@ from unittest import mock
 import pytest
 from sqlalchemy.engine.url import URL, make_url
 
-from trino.auth import BasicAuthentication
+from trino.auth import BasicAuthentication, OAuth2Authentication
 from trino.dbapi import Connection
 from trino.sqlalchemy import URL as trino_url
 from trino.sqlalchemy.dialect import (
@@ -296,3 +296,12 @@ def test_trino_connection_certificate_auth():
     assert isinstance(cparams['auth'], CertificateAuthentication)
     assert cparams['auth']._cert == cert
     assert cparams['auth']._key == key
+
+
+def test_trino_connection_oauth2_auth():
+    dialect = TrinoDialect()
+    url = make_url('trino://host/?externalAuthentication=true')
+    _, cparams = dialect.create_connect_args(url)
+
+    assert cparams['http_scheme'] == "https"
+    assert isinstance(cparams['auth'], OAuth2Authentication)
task: metadata: install: pip install -e .[dev]
patch: diff --git a/src/uiprotect/data/devices.py b/src/uiprotect/data/devices.py
index d084f24..b52627a 100644
--- a/src/uiprotect/data/devices.py
+++ b/src/uiprotect/data/devices.py
@@ -83,18 +83,7 @@ if TYPE_CHECKING:
     from .nvr import Event, Liveview
 
 PRIVACY_ZONE_NAME = "pyufp_privacy_zone"
-LUX_MAPPING_VALUES = [
-    30,
-    25,
-    20,
-    15,
-    12,
-    10,
-    7,
-    5,
-    3,
-    1,
-]
+LUX_MAPPING_VALUES = [30, 25, 20, 15, 12, 10, 7, 5, 3, 1, 0]
 
 _LOGGER = logging.getLogger(__name__)
 

problem_statement: IndexError: list index out of range if  icr_custom_value set to 0 (under 1 lux)
### Describe the bug

see 

https://github.com/home-assistant/core/issues/122408
https://github.com/home-assistant/core/issues/124093
https://github.com/home-assistant/core/issues/124717

### To Reproduce

set icr_custom_value to 0

### Additional context

_No response_

### Version

v6.6.0

### Platform

all

### Code of Conduct

- [X] I agree to follow this project's Code of Conduct.

### No Duplicate

- [X] I have checked existing issues to avoid duplicates.
repo: uilibs/uiprotect
test_cmd: pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
test_patch: diff --git a/tests/data/test_camera.py b/tests/data/test_camera.py
index 519a544..3268345 100644
--- a/tests/data/test_camera.py
+++ b/tests/data/test_camera.py
@@ -1088,6 +1088,7 @@ async def test_camera_disable_co(camera_obj: Camera | None, status: bool):
 @pytest.mark.parametrize(
     ("value", "lux"),
     [
+        (0, 0),
         (1, 1),
         (2, 3),
         (3, 5),
@@ -1110,7 +1111,12 @@ async def test_camera_set_icr_custom_lux(
         pytest.skip("No camera_obj obj found")
 
     camera_obj.feature_flags.has_led_ir = True
-    camera_obj.isp_settings.icr_custom_value = 0
+    if (
+        value == 0
+    ):  # without this there is no change that gets send if the test value is 0
+        camera_obj.isp_settings.icr_custom_value = 1
+    else:
+        camera_obj.isp_settings.icr_custom_value = 0
 
     camera_obj.api.api_request.reset_mock()
task: metadata: install: pip install -e .
patch: diff --git a/edtf_validate/valid_edtf.py b/edtf_validate/valid_edtf.py
index 6648d02..53dd491 100644
--- a/edtf_validate/valid_edtf.py
+++ b/edtf_validate/valid_edtf.py
@@ -55,11 +55,11 @@ day = oneThru31
 non_negative_date = non_negative_yearMonthDay | non_negative_yearMonth | non_negative_year
 baseTime = hour + ":" + minute + ":" + second | "24:00:00"
 zoneOffsetHour = oneThru13
-zoneOffset = "Z" | (
-    oneOf("+ -") + zoneOffsetHour + Optional(":" + minute)
+zoneOffset = "Z" | (oneOf("+ -") + (
+    zoneOffsetHour + Optional(":" + minute)
     | "14:00"
     | "00:" + oneThru59
-)
+))
 time = baseTime + Optional(zoneOffset)
 dateAndTime = non_negative_date + "T" + time
 L0Interval = non_negative_date + "/" + non_negative_date

problem_statement: Add '+' or '-' to zoneOffset var to indicate timezone being ahead or behind UTC.
repo: unt-libraries/edtf-validate
test_cmd: pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
test_patch: diff --git a/tests/test_valid_edtf.py b/tests/test_valid_edtf.py
index a9b4d84..b74d118 100644
--- a/tests/test_valid_edtf.py
+++ b/tests/test_valid_edtf.py
@@ -122,7 +122,7 @@ Level0 = list(chain([
     '1985-04-12T23:20:30Z',
     '1985-04-12T23:20:30-04',
     '1985-04-12T23:20:30+04:30',
-    pytest.param('2004-01-01T10:10:10+00:59', marks=pytest.mark.xfail),
+    '2004-01-01T10:10:10+00:59',
 ], L0_Intervals))
 
 Level1 = list(chain([
@@ -284,7 +284,7 @@ invalid_edtf_datetimes = [
     '2004-01-01T10:10:40Z00:60',
     '2004-01-01T10:10:10-05:60',
     '2004-01-01T10:10:10+02:00:30',
-    pytest.param('2004-01-01T10:10:1000:59', marks=pytest.mark.xfail),
+    '2004-01-01T10:10:1000:59',
     '-1985-04-12T23:20:30+24',
     '-1985-04-12T23:20:30Z12:00',
 ]
task: metadata: install: pip install -e .[dev]
patch: diff --git a/valohai_cli/commands/execution/run.py b/valohai_cli/commands/execution/run.py
index 643cc5c..9b85f99 100644
--- a/valohai_cli/commands/execution/run.py
+++ b/valohai_cli/commands/execution/run.py
@@ -71,6 +71,7 @@ class RunCommand(click.Command):
         super(RunCommand, self).__init__(
             name=sanitize_name(step.name.lower()),
             callback=self.execute,
+            epilog='Multiple files per input: --my-input=myurl --my-input=myotherurl',
             add_help_option=True,
         )
         for parameter in step.parameters.values():
@@ -107,8 +108,9 @@ class RunCommand(click.Command):
         option = click.Option(
             param_decls=list(generate_sanitized_options(input.name)),
             required=(input.default is None and not input.optional),
-            default=input.default,
+            default=([input.default] if input.default else []),
             metavar='URL',
+            multiple=True,
             help='Input "%s"' % humanize_identifier(input.name),
         )
         option.name = '^%s' % input.name  # Caretize so we can pick these out of kwargs easily

problem_statement: Support multiple files per input
Support for this seems to be lacking in the CLI, even if the web UI and API support it.
repo: valohai/valohai-cli
test_cmd: pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
test_patch: diff --git a/tests/commands/execution/test_run.py b/tests/commands/execution/test_run.py
index fc78001..7e42a90 100644
--- a/tests/commands/execution/test_run.py
+++ b/tests/commands/execution/test_run.py
@@ -83,7 +83,8 @@ def test_run(runner, logged_in_and_linked, monkeypatch, pass_param, pass_input,
 
     if pass_input:
         args.append('--in1=http://url')
-        values['inputs'] = {'in1': 'http://url'}
+        args.append('--in1=http://anotherurl')
+        values['inputs'] = {'in1': ['http://url', 'http://anotherurl']}
 
     if pass_env:
         args.append('--environment=015dbd56-2670-b03e-f37c-dc342714f1b5')
task: metadata: install: pip install -e .[dev]
patch: diff --git a/synapse/models/inet.py b/synapse/models/inet.py
index 624603cd6..f85565170 100644
--- a/synapse/models/inet.py
+++ b/synapse/models/inet.py
@@ -868,6 +868,7 @@ class Url(s_types.Str):
         return cmpr
 
     def _normPyStr(self, valu):
+        valu = valu.strip()
         orig = valu
         subs = {}
         proto = ''

problem_statement: [BUG] inet:url not stripping whitespace at the beg
**Describe the bug**
When adding an inet:url node, whitespace is not stripped from the beginning of the str. I couldn't think of a reason that should be allowed. It would help any accidental spacing added by the user. Maybe this is a feature request then?  


**To Reproduce**
`cli> storm [inet:url=" https://x=msn.com"]
Executing query at 2020/05/22 18:12:49.545
.......
inet:url= https://msn.com
        .created = 2020/05/22 18:12:49.559
        :base =  https://msn.com
        :fqdn = msn.com
        :params =
        :path =
        :proto =  https
complete. 1 nodes in 16 ms (62/sec).
cli> storm [inet:url="  https://msn.com"]
Executing query at 2020/05/22 18:12:55.072
.......
inet:url=  https://msn.com
        .created = 2020/05/22 18:12:55.085
        :base =   https://msn.com
        :fqdn = msn.com
        :params =
        :path =
        :proto =   https
complete. 1 nodes in 14 ms (71/sec).`
A clear and concise description of what you expected to happen.

**Environment (please complete the following information):**
 - OS: macos
 - Synapse Version 0.2.0rc16
 - Python Version: 3.7.3
 - Output of `python -m pip freeze`
aiohttp==3.6.2
async-timeout==3.0.1
attrs==19.3.0
cffi==1.14.0
chardet==3.0.4
cryptography==2.9
fastjsonschema==2.14.4
idna==2.9
lark-parser==0.7.8
lmdb==0.98
msgpack==0.6.2
multidict==4.7.5
packaging==20.3
prompt-toolkit==2.0.10
pycparser==2.20
Pygments==2.3.1
pyOpenSSL==19.1.0
pyparsing==2.4.6
PyYAML==5.3.1
regex==2020.2.20
six==1.14.0
synapse==0.2.0rc16
tornado==6.0.4
wcwidth==0.1.9
xxhash==1.4.3
yarl==1.4.2


repo: vertexproject/synapse
test_cmd: pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
test_patch: diff --git a/synapse/tests/test_model_inet.py b/synapse/tests/test_model_inet.py
index d095983aa..3d484dd61 100644
--- a/synapse/tests/test_model_inet.py
+++ b/synapse/tests/test_model_inet.py
@@ -1414,6 +1414,18 @@ class InetModelTest(s_t_utils.SynTest):
             }})
             self.eq(valu, expected)
 
+            url = '  http://0.0.0.0/index.html?foo=bar  '
+            valu = t.norm(url)
+            expected = (url.strip(), {'subs': {
+                'proto': 'http',
+                'path': '/index.html',
+                'params': '?foo=bar',
+                'ipv4': 0,
+                'port': 80,
+                'base': 'http://0.0.0.0/index.html'
+            }})
+            self.eq(valu, expected)
+
             unc = '\\\\0--1.ipv6-literal.net\\share\\path\\to\\filename.txt'
             url = 'smb://::1/share/path/to/filename.txt'
             valu = t.norm(unc)
task: metadata: install: pip install -e .[dev]
patch: diff --git a/vyper/semantics/analysis/utils.py b/vyper/semantics/analysis/utils.py
index a31ce7ac..8727f375 100644
--- a/vyper/semantics/analysis/utils.py
+++ b/vyper/semantics/analysis/utils.py
@@ -41,7 +41,7 @@ def _validate_op(node, types_list, validation_fn_name):
         try:
             _validate_fn(node)
             ret.append(type_)
-        except InvalidOperation as e:
+        except (InvalidOperation, OverflowException) as e:
             err_list.append(e)
 
     if ret:
diff --git a/vyper/semantics/types/primitives.py b/vyper/semantics/types/primitives.py
index 5c0362e6..dcc4fe8c 100644
--- a/vyper/semantics/types/primitives.py
+++ b/vyper/semantics/types/primitives.py
@@ -173,11 +173,11 @@ class NumericT(_PrimT):
             if isinstance(left, vy_ast.Int):
                 if left.value >= 2**value_bits:
                     raise OverflowException(
-                        "Base is too large, calculation will always overflow", left
+                        f"Base is too large for {self}, calculation will always overflow", left
                     )
                 elif left.value < -(2**value_bits):
                     raise OverflowException(
-                        "Base is too small, calculation will always underflow", left
+                        f"Base is too small for {self}, calculation will always underflow", left
                     )
             elif isinstance(right, vy_ast.Int):
                 if right.value < 0:

problem_statement: incorrectly reported overflow exception
### Version Information

* vyper Version (output of `vyper --version`): 0.4.0

### What's your issue about?
```vyper
@external
def foo() -> uint256:
    return (10**18)**2
```
panics at compilation with the following error, which is clearly wrong given that 10**36 clearly fits in a uint256:
```
vyper.exceptions.OverflowException: Base is too large, calculation will always overflow

  contract "contracts/token.vy:3", function "foo", line 3:12 
       2 def foo() -> uint256:
  ---> 3     return (10**18)**2
  -------------------^
```

repo: vyperlang/vyper
test_cmd: pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
test_patch: diff --git a/tests/functional/codegen/types/numbers/test_exponents.py b/tests/functional/codegen/types/numbers/test_exponents.py
index 702cbcb1..28dba59e 100644
--- a/tests/functional/codegen/types/numbers/test_exponents.py
+++ b/tests/functional/codegen/types/numbers/test_exponents.py
@@ -173,3 +173,17 @@ def foo(b: int128) -> int128:
     c.foo(max_power)
     with tx_failed():
         c.foo(max_power + 1)
+
+
+valid_list = [
+    """
+@external
+def foo() -> uint256:
+    return (10**18)**2
+    """
+]
+
+
+@pytest.mark.parametrize("good_code", valid_list)
+def test_exponent_success(good_code):
+    assert compile_code(good_code) is not None
task: metadata: install: pip install -e .[dev]
patch: diff --git a/vyper/codegen/core.py b/vyper/codegen/core.py
index aaf6f350..789cc775 100644
--- a/vyper/codegen/core.py
+++ b/vyper/codegen/core.py
@@ -560,7 +560,7 @@ def _get_element_ptr_array(parent, key, array_bounds_check):
         return IRnode.from_list("~empty", subtype)
 
     if parent.value == "multi":
-        assert isinstance(key.value, int)
+        assert isinstance(key.value, int), key
         return parent.args[key.value]
 
     ix = unwrap_location(key)
diff --git a/vyper/codegen/stmt.py b/vyper/codegen/stmt.py
index b1e26d7d..b306d833 100644
--- a/vyper/codegen/stmt.py
+++ b/vyper/codegen/stmt.py
@@ -258,7 +258,7 @@ class Stmt:
         ret = ["seq"]
 
         # list literal, force it to memory first
-        if isinstance(self.stmt.iter, vy_ast.List):
+        if iter_list.is_literal:
             tmp_list = self.context.new_internal_variable(iter_list.typ)
             ret.append(make_setter(tmp_list, iter_list))
             iter_list = tmp_list

problem_statement: panic when iterating over static arrays
### Version Information

* vyper Version (output of `vyper --version`): 762eec682450a6631342fad06898471ea2a6aa90

### What's your issue about?
following contract panics when compiling:
```vyper
X: constant(uint24[4]) = [1,2,3,4]

@external
def foo():
    x: uint24 = 0
    for s: uint24 in X:
        x += s
```

error looks like
```
Error compiling: tmp/foo.vy
AssertionError

During handling of the above exception, another exception occurred:

vyper.exceptions.CodegenPanic: unhandled exception , parse_For

  contract "tmp/foo.vy:6", function "foo", line 6:4 
       5     x: uint24 = 0
  ---> 6     for s: uint24 in X:
  -----------^
       7         x += s


This is an unhandled internal compiler error. Please create an issue on Github to notify the developers!
https://github.com/vyperlang/vyper/issues/new?template=bug.md
```

### How can it be fixed?

Fill this in if you know how to fix it.

repo: vyperlang/vyper
test_cmd: pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
test_patch: diff --git a/tests/functional/codegen/features/iteration/test_for_in_list.py b/tests/functional/codegen/features/iteration/test_for_in_list.py
index 036e7c06..4b9eea3c 100644
--- a/tests/functional/codegen/features/iteration/test_for_in_list.py
+++ b/tests/functional/codegen/features/iteration/test_for_in_list.py
@@ -214,6 +214,21 @@ def data() -> int128:
         assert c.data() == sum(xs)
 
 
+def test_constant_list_iter(get_contract):
+    code = """
+MY_LIST: constant(uint24[4]) = [1, 2, 3, 4]
+
+@external
+def foo() -> uint24:
+    x: uint24 = 0
+    for s: uint24 in MY_LIST:
+        x += s
+    return x
+    """
+    c = get_contract(code)
+    assert c.foo() == sum([1, 2, 3, 4])
+
+
 def test_basic_for_list_storage_address(get_contract):
     code = """
 addresses: address[3]
task: metadata: install: pip install -e .[dev]
patch: diff --git a/magnivore/Lexicon.py b/magnivore/Lexicon.py
index 84ae7a2..acf038b 100644
--- a/magnivore/Lexicon.py
+++ b/magnivore/Lexicon.py
@@ -2,6 +2,7 @@
 import re
 from decimal import Decimal
 from functools import reduce
+from math import ceil, floor
 
 from .Tracker import Tracker
 
@@ -40,7 +41,12 @@ class Lexicon:
         """
         value = cls._dot_reduce(rule['from'], target)
         original_type = type(value)
-        return original_type(Decimal(value) * Decimal(rule['factor']))
+        result = Decimal(value) * Decimal(rule['factor'])
+        if 'round' in rule:
+            if rule['round'] == 'up':
+                return original_type(ceil(result))
+            return original_type(floor(result))
+        return original_type(result)
 
     @classmethod
     def format(cls, rule, target):

problem_statement: Add possibility to specify whether to round up or down in factor
repo: wearewhys/magnivore
test_cmd: pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
test_patch: diff --git a/tests/unit/Lexicon.py b/tests/unit/Lexicon.py
index f1c85d6..3af833c 100644
--- a/tests/unit/Lexicon.py
+++ b/tests/unit/Lexicon.py
@@ -65,6 +65,19 @@ def test_lexicon_factor(from_data, target, expected):
     assert type(result) == type(expected)
 
 
+@mark.parametrize('rounding, expected', [
+    ('down', 47),
+    ('up', 48)
+])
+def test_lexicon_factor_round(rounding, expected):
+    rule = {
+        'from': 'value',
+        'round': rounding,
+        'factor': 0.5
+    }
+    assert Lexicon.factor(rule, MagicMock(value=95)) == expected
+
+
 @mark.parametrize('from_data, format, expected', [
     ('birthyear', '{}-0-0', '1992-0-0'),
     (['birthyear', 'birthmonth'], '{}-{}-0', '1992-9-0')
task: metadata: install: pip install -e .
patch: diff --git a/aws_gate/bootstrap.py b/aws_gate/bootstrap.py
index 9e22207..9bf769b 100644
--- a/aws_gate/bootstrap.py
+++ b/aws_gate/bootstrap.py
@@ -68,7 +68,7 @@ class MacPlugin(Plugin):
 
         if not os.path.exists(DEFAULT_GATE_BIN_PATH):
             logger.debug('Creating %s', DEFAULT_GATE_BIN_PATH)
-            os.mkdir(DEFAULT_GATE_BIN_PATH)
+            os.makedirs(DEFAULT_GATE_BIN_PATH)
 
         with open(plugin_src_path, 'rb') as f_src, open(plugin_dst_path, 'wb') as f_dst:
             logger.debug('Copying %s to %s', plugin_src_path, plugin_dst_path)
diff --git a/aws_gate/decorators.py b/aws_gate/decorators.py
index c1d26c8..b153428 100644
--- a/aws_gate/decorators.py
+++ b/aws_gate/decorators.py
@@ -24,7 +24,7 @@ def plugin_version(required_version):
     def _outer_wrapper(wrapped_function):
         @functools.wraps(wrapped_function)
         def _wrapper(*args, **kwargs):
-            version = execute(PLUGIN_INSTALL_PATH, ['--version'])
+            version = execute(PLUGIN_INSTALL_PATH, ['--version'], capture_output=True)
 
             if version and int(version.replace('.', '')) < int(required_version.replace('.', '')):
                 raise ValueError('Invalid plugin version: {}'.format(version))

problem_statement: `aws-gate bootstrap` is broken
I upgraded aws-gate and started to get errors. I guess is because, after #41 got pushed, it no longer accept session-manager-plugin to be provided by the host system. However, most of our users already have it installed by other ways.

```
OSError: session-manager-plugin not found
```

Trying to `aws-gate bootstrap` gives error because the needed folder is not yet created
```
$ aws-gate -v bootstrap
[Errno 2] No such file or directory: '/Users/alanjds/.aws-gate/bin'
```

After creating manually, the installation can succeed:
```
$ mkdir -p /Users/alanjds/.aws-gate/bin
$ aws-gate -v bootstrap
1.1.26.0
session-manager-plugin (version None) installed successfully!
```

After #41, aws-gate no longer accept the plugin to be provided by system.
For curiosity, why is it allowing only owned version to be used?

What about allowing usage of existing one if available, maybe with a deprecation or warning message?

repo: xen0l/aws-gate
test_cmd: pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
test_patch: diff --git a/test/unit/test_bootstrap.py b/test/unit/test_bootstrap.py
index 8ed6a33..b5b4c90 100644
--- a/test/unit/test_bootstrap.py
+++ b/test/unit/test_bootstrap.py
@@ -55,8 +55,8 @@ class TestBootstrap(unittest.TestCase):
                 patch('aws_gate.bootstrap._check_plugin_version', return_value='1.1.23.0'):
             plugin.install()
 
-            self.assertTrue(os_mock.mkdir.called)
-            self.assertEqual(os_mock.mkdir.call_args, call(DEFAULT_GATE_BIN_PATH))
+            self.assertTrue(os_mock.makedirs.called)
+            self.assertEqual(os_mock.makedirs.call_args, call(DEFAULT_GATE_BIN_PATH))
             self.assertTrue(shutil_mock.copyfileobj.called)
             self.assertTrue(os_mock.chmod.called)
task: metadata: install: pip install -e .
patch: diff --git a/pierone/api.py b/pierone/api.py
index 35542be..9b0c76a 100644
--- a/pierone/api.py
+++ b/pierone/api.py
@@ -71,6 +71,9 @@ def docker_login_with_token(url, access_token):
     basic_auth = codecs.encode('oauth2:{}'.format(access_token).encode('utf-8'), 'base64').strip().decode('utf-8')
     if 'auths' not in dockercfg:
         dockercfg['auths'] = {}
+    if 'credsStore' in dockercfg:
+        del dockercfg['credsStore']
+
     dockercfg['auths'][url] = {'auth': basic_auth,
                                'email': 'no-mail-required@example.org'}
     with Action('Storing Docker client configuration in {}..'.format(path)):

problem_statement: no basic auth credentials
Today I had an auth issue. While trying to do `docker push` I was getting the following log:

    ➜ pierone login             
    Getting OAuth2 token "pierone".. OK
    Storing Docker client configuration in /Users/whoever/.docker/config.json.. OK
    ➜ docker push myrepo/...
    The push refers to a repository [myrepo/...]
    a5f591aacc10: Preparing 
    ...
    cb11ba605400: Waiting 
    no basic auth credentials

Recreating `~/config.json` saved me.  
There was `"credsStore": "osxkeychain"` setting In the previous version of the `~/config.json` which was causing me troubles.

BTW 
mac os 10.12.3
pierone cli 1.1.27
docker 17.06.0-ce, build 02c1d87
repo: zalando-stups/pierone-cli
test_cmd: pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
test_patch: diff --git a/tests/test_api.py b/tests/test_api.py
index 62e1f0a..3ee83be 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -21,6 +21,29 @@ def test_docker_login(monkeypatch, tmpdir):
         assert {'auth': 'b2F1dGgyOjEyMzc3',
                 'email': 'no-mail-required@example.org'} == data.get('auths').get('https://pierone.example.org')
 
+def test_docker_login_with_credsstore(monkeypatch, tmpdir):
+    monkeypatch.setattr('os.path.expanduser', lambda x: x.replace('~', str(tmpdir)))
+    monkeypatch.setattr('pierone.api.get_token', MagicMock(return_value='12377'))
+    path = os.path.expanduser('~/.docker/config.json')
+    os.makedirs(os.path.dirname(path))
+    with open(path, 'w') as fd:
+        json.dump({
+            "auths": {
+                "https://pierone.stups.zalan.do": {
+                    "auth": "xxx",
+                    "email": "no-mail-required@example.org"
+                }
+            },
+            "credsStore": "osxkeychain"
+        }, fd)
+    docker_login('https://pierone.example.org', 'services', 'mytok',
+                 'myuser', 'mypass', 'https://token.example.org', use_keyring=False)
+    with open(path) as fd:
+        data = yaml.safe_load(fd)
+        assert {'auth': 'b2F1dGgyOjEyMzc3',
+                'email': 'no-mail-required@example.org'} == data.get('auths').get('https://pierone.example.org')
+        assert 'credsStore' not in data
+
 
 def test_docker_login_service_token(monkeypatch, tmpdir):
     monkeypatch.setattr('os.path.expanduser', lambda x: x.replace('~', str(tmpdir)))
task: metadata: install: pip install -e .[test]
patch: diff --git a/CHANGES.rst b/CHANGES.rst
index 607054e..f794d66 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -4,7 +4,7 @@ Changelog
 4.1 (unreleased)
 ----------------
 
-- Nothing changed yet.
+- Fix generated ``runzeo`` and ``zeoctl`` scripts to run with ZEO 5.
 
 
 4.0 (2017-02-28)
diff --git a/src/zope/mkzeoinstance/__init__.py b/src/zope/mkzeoinstance/__init__.py
index 9b6fe44..8053e92 100644
--- a/src/zope/mkzeoinstance/__init__.py
+++ b/src/zope/mkzeoinstance/__init__.py
@@ -116,9 +116,7 @@ CONFIG_FILE="%(instance_home)s/etc/%(package)s.conf"
 PYTHONPATH="$ZODB3_HOME"
 export PYTHONPATH INSTANCE_HOME
 
-ZEOCTL="$ZODB3_HOME/ZEO/zeoctl.py"
-
-exec "$PYTHON" "$ZEOCTL" -C "$CONFIG_FILE" ${1+"$@"}
+exec "$PYTHON" -m ZEO.zeoctl -C "$CONFIG_FILE" ${1+"$@"}
 """
 
 
@@ -135,9 +133,7 @@ CONFIG_FILE="%(instance_home)s/etc/%(package)s.conf"
 PYTHONPATH="$ZODB3_HOME"
 export PYTHONPATH INSTANCE_HOME
 
-RUNZEO="$ZODB3_HOME/ZEO/runzeo.py"
-
-exec "$PYTHON" "$RUNZEO" -C "$CONFIG_FILE" ${1+"$@"}
+exec "$PYTHON" -m ZEO.runzeo -C "$CONFIG_FILE" ${1+"$@"}
 """
 
 
@@ -197,7 +193,7 @@ class ZEOInstanceBuilder:
             if k in ('-h', '--help'):
                 usage(rc=2)
 
-        if len(args) < 1 or len(args) > 2:  
+        if len(args) < 1 or len(args) > 2:
             usage(rc=1)
 
         instance_home = os.path.abspath(args[0])

problem_statement: Broken with ZEO 5.1.1: runzeo and zeoctl fails.
While investigating zopefoundation/ZEO#87 I figured out, that the scripts running zeoctl and runzeo are no longer working due to usage of relative imports in ZEO.runzeo and ZEO.zeoctl.

It looks like the clean way is to not call the files as scripts, but execute them as modules. 
repo: zopefoundation/zope.mkzeoinstance
test_cmd: pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
test_patch: diff --git a/src/zope/mkzeoinstance/tests/test_unix.py b/src/zope/mkzeoinstance/tests/test_unix.py
index 68c4a2a..89c5c07 100644
--- a/src/zope/mkzeoinstance/tests/test_unix.py
+++ b/src/zope/mkzeoinstance/tests/test_unix.py
@@ -271,9 +271,7 @@ class ZEOInstanceBuilderTests(_WithTempdir, unittest.TestCase):
             'PYTHONPATH="$ZODB3_HOME"',
             'export PYTHONPATH INSTANCE_HOME',
             '',
-            'ZEOCTL="$ZODB3_HOME/ZEO/zeoctl.py"',
-            '',
-            'exec "$PYTHON" "$ZEOCTL" -C "$CONFIG_FILE" ${1+"$@"}',
+            'exec "$PYTHON" -m ZEO.zeoctl -C "$CONFIG_FILE" ${1+"$@"}',
             '',
             ]) % params
task: metadata: install: pip install -e .[test,docs]
patch: diff --git a/CHANGES.rst b/CHANGES.rst
index 5304f54..ea1717a 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -7,6 +7,9 @@
 
 - Add support for Python 3.10.
 
+- Do not try to send queued emails to an empty address
+  (`#45 <https://github.com/zopefoundation/zope.sendmail/issues/45>`_).
+
 
 5.2 (2021-01-18)
 ================
diff --git a/src/zope/sendmail/queue.py b/src/zope/sendmail/queue.py
index cdf17aa..1808189 100644
--- a/src/zope/sendmail/queue.py
+++ b/src/zope/sendmail/queue.py
@@ -163,7 +163,9 @@ class QueueProcessorThread(threading.Thread):
 
         if second.startswith(b"X-Zope-To: "):
             i = len(b"X-Zope-To: ")
-            toaddrs = tuple(addr.decode() for addr in second[i:].split(b", "))
+            toaddrs = tuple(
+                addr.decode() for addr in second[i:].split(b", ") if addr
+            )
 
         return fromaddr, toaddrs, rest
 

problem_statement: The mail queue might get stuck
### What I did:

I am using the mailqueue.
This is what I can read in the message stored in the 'myfolder/new' directory.
```
X-Zope-To: Foo <foo@example.com>, , Bar <bar@example.com>
```
As you can see the application crafted a message with empty recipients.

### What I expect to happen:

I expect the mail to be sent to foo@example.com and bar@example.com.

### What actually happened:

The mail was not sent because the connection with the SMTPServer was lost:
```
smtplib.SMTPServerDisconnected: Connection unexpectedly closed
``` 
and all the others emails and new emails were stuck because there was no connection:
```
smtplib.SMTPServerDisconnected: please run connect() first
```
.

### What version of Python and Zope/Addons I am using:

- Python: 3.8
- Zope: 4.8.2
- Plone: 5.2.9
- zope.sendmail: 5.2

repo: zopefoundation/zope.sendmail
test_cmd: pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
test_patch: diff --git a/src/zope/sendmail/tests/test_queue.py b/src/zope/sendmail/tests/test_queue.py
index 96a4c08..a8e9f10 100644
--- a/src/zope/sendmail/tests/test_queue.py
+++ b/src/zope/sendmail/tests/test_queue.py
@@ -153,6 +153,17 @@ class TestQueueProcessorThread(unittest.TestCase):
         self.assertEqual(t, ('bar@example.com', 'baz@example.com'))
         self.assertEqual(m, msg)
 
+    def test_parseMessage_empty_address(self):
+        hdr = (b'X-Zope-From: foo@example.com\n'
+               b'X-Zope-To: bar@example.com, , baz@example.com\n')
+        msg = (b'Header: value\n'
+               b'\n'
+               b'Body\n')
+        f, t, m = self.thread._parseMessage(hdr + msg)
+        self.assertEqual(f, 'foo@example.com')
+        self.assertEqual(t, ('bar@example.com', 'baz@example.com'))
+        self.assertEqual(m, msg)
+
     def test_parseMessage_error(self):
         msg = b"bad message"
         f, t, m = self.thread._parseMessage(msg)