traitlets icon indicating copy to clipboard operation
traitlets copied to clipboard

changing default value of containers to None

Open djarecka opened this issue 8 years ago • 5 comments

Hi,

I wanted to create my own trait types, so all have the same default_value, e.g. None, and call tag automatically, but I'm having problems with default_value for containers. I will use List as an example, I'm defining a new class:

class List(traitlets.List):
    allow_none = True
    default_value = None 
    info_text = "a list with default_value = None"

    def __init__(self, trait=None, default_value=None, minlen=0, maxlen=sys.maxsize, kw=None,
                 read_only=None, help=None, config=None, **kwargs):
        super(List, self).__init__(trait=trait, default_value=default_value, minlen=0, maxlen=maxlen,
                                   kw=kw, read_only=read_only, help=help, config=config)
        self.tag(**kwargs)

and I'd like my new class to pass those test:

def test_list_default_1():
    class HasTr(traitlets.HasTraits):
        foo = List()
    ht = HasTr()
    assert ht.foo is None

def test_list_default_2():
    class HasTr(traitlets.HasTraits):
        foo = List(default_value=[1])
    ht = HasTr()
    assert ht.foo == [1]

I'm passing the first test, but not the second (in both cases ht.foo is None). From quick reading of your code, it looks like the method make_dynamic_default is not called when I define my List class with class attribute default_value = None. Is this on purpose? Do you have any other suggestions how I can write my class (for all traits) that I'm able to pass both tests?

system Info {'commit_hash': 'd86648c5d', 'commit_source': 'installation', 'default_encoding': 'UTF-8', 'ipython_path': '/Users/dorota/anaconda/envs/py35_trlets/lib/python3.5/site-packages/IPython', 'ipython_version': '6.1.0', 'os_name': 'posix', 'platform': 'Darwin-16.1.0-x86_64-i386-64bit', 'sys_executable': '/Users/dorota/anaconda/envs/py35_trlets/bin/python', 'sys_platform': 'darwin', 'sys_version': '3.5.3 | packaged by conda-forge | (default, May 12 2017, ' '15:35:12) \n' '[GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.53)]'}

I'm using the current master.

djarecka avatar Oct 08 '17 18:10 djarecka

@djarecka I think that https://github.com/ipython/traitlets/pull/403 might fix this problem for you. If so, I can invest the time to try and get that into the 5.0 release. Otherwise it may be relegated to an as yet, unplanned, 6.0 release.

rmorshea avatar Oct 08 '17 20:10 rmorshea

@rmorshea thanks for your answer. Unfortunately, when I try your branch (after merging with current master), the test test_list_default_2 still doesn't work. Actually, it doesn't even work without the attribute default_value = None in my new class.

djarecka avatar Oct 08 '17 21:10 djarecka

@djarecka, I have confirmed that the issue is (in my branch) just bad argument handling.

For example this works:

class X(HasTraits):
    l = List([1, 2, 3])

x = X()
assert x.l == [1, 2, 3]

However this does not:

class X(HasTraits):
    l = List(default_value=[1, 2, 3])

x = X()
assert x.l == [] # passes
assert x.l == [1, 2, 3] # fails

We failed to identify this issue because we actually don't have a test in our suite for it. Feel free to add one if you have the time.

rmorshea avatar Oct 08 '17 23:10 rmorshea

master probably fails for the same reason, though I have not checked that myself.

rmorshea avatar Oct 08 '17 23:10 rmorshea

@rmorshea I created a small PR, added examples of tests, but two fail with master (and some extra fail with your pr). Let me know if this what you had in mind as new tests, can add more.

djarecka avatar Oct 09 '17 01:10 djarecka