diff --git a/luigi/parameter.py b/luigi/parameter.py index 7978e520ec..b2b242c1fb 100644 --- a/luigi/parameter.py +++ b/luigi/parameter.py @@ -853,6 +853,15 @@ def run(self): $ luigi --module my_tasks MyTask --grades '[100,70]' """ + def normalize(self, x): + """ + Ensure that list parameter is converted to a tuple so it can be hashed. + + :param str x: the value to parse. + :return: the normalized (hashable/immutable) value. + """ + return tuple(x) + def parse(self, x): """ Parse an individual value from the input. diff --git a/test/parameter_test.py b/test/parameter_test.py index 7dd5dbfa25..b21cb911fa 100644 --- a/test/parameter_test.py +++ b/test/parameter_test.py @@ -347,6 +347,13 @@ class Foo(luigi.Task): p = luigi.parameter.DictParameter() self.assertEqual(hash(Foo(args=dict(foo=1, bar="hello")).args), hash(p.parse('{"foo":1,"bar":"hello"}'))) + def test_list(self): + class Foo(luigi.Task): + args = luigi.parameter.ListParameter() + + p = luigi.parameter.ListParameter() + self.assertEqual(hash(Foo(args=[1, "hello"]).args), hash(p.normalize(p.parse('[1,"hello"]')))) + def test_tuple(self): class Foo(luigi.Task): args = luigi.parameter.TupleParameter()