Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Collections in valid values for Enum trait #889

Merged
merged 19 commits into from
Mar 27, 2020

Conversation

midhun-pm
Copy link
Contributor

@midhun-pm midhun-pm commented Feb 6, 2020

Fixes #835
PR modifies the Enum trait to allow values that are of type Collection

@codecov-io
Copy link

codecov-io commented Feb 7, 2020

Codecov Report

Merging #889 into master will increase coverage by 0.18%.
The diff coverage is 94.73%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #889      +/-   ##
==========================================
+ Coverage   73.05%   73.24%   +0.18%     
==========================================
  Files          51       51              
  Lines        6514     6521       +7     
  Branches     1309     1311       +2     
==========================================
+ Hits         4759     4776      +17     
+ Misses       1363     1352      -11     
- Partials      392      393       +1     
Impacted Files Coverage Δ
traits/has_traits.py 71.24% <ø> (ø)
traits/trait_handlers.py 61.11% <ø> (ø)
traits/trait_types.py 71.63% <93.75%> (-0.02%) ⬇️
traits/trait_base.py 64.59% <100.00%> (+1.01%) ⬆️
traits/editor_factories.py 79.59% <0.00%> (-9.19%) ⬇️
traits/ctrait.py 57.79% <0.00%> (-0.77%) ⬇️
traits/traits.py 76.92% <0.00%> (+4.04%) ⬆️
traits/etsconfig/etsconfig.py 63.46% <0.00%> (+6.41%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 26548b0...ada61f7. Read the comment docs.

@midhun-pm midhun-pm changed the title WIP: Allow Collections in valid values for Enum trait Allow Collections in valid values for Enum trait Feb 25, 2020
Copy link
Member

@mdickinson mdickinson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't reviewed the code in detail, but there are still a couple of things missing relative to the original issue:

  • As described in the original issue, we should have documentation warning users about the arbitrary selection of a default when using something like a set as a collection
  • Please include a test for the case Enum(1, {1, 2}), whose behaviour changes as a result of this PR.
  • In addition to strings, we want to exclude bytestrings and bytearrays as collections, since in behaves oddly for those:
>>> from traits.api import *
>>> class A(HasTraits):
...     foo = Enum(b"abc")
... 
>>> a = A()
>>> a.foo
97
>>> a.foo = 98
>>> a.foo
98
>>> a.foo = 100  # Error message says 97, 98 and 99 are the only valid values
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mdickinson/Enthought/ETS/traits/traits/base_trait_handler.py", line 76, in error
    raise TraitError(
traits.trait_errors.TraitError: The 'foo' trait of an A instance must be 97 or 98 or 99, but a value of 100 <class 'int'> was specified.
>>> a.foo = b"bc"  # But b"bc" is accepted as valid, too.
>>> a.foo
b'bc'

@mdickinson
Copy link
Member

Please also update docstrings for BaseEnum and Enum to reflect the new behaviour.

@mdickinson mdickinson assigned mdickinson and unassigned midhun-pm Mar 23, 2020
Copy link
Member

@mdickinson mdickinson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few comments. I think there may be some opportunities to make the __init__ code a bit clearer and more consistent.

traits/ctraits.c Outdated Show resolved Hide resolved
traits/tests/test_enum.py Outdated Show resolved Hide resolved
traits/trait_base.py Outdated Show resolved Hide resolved
traits/trait_base.py Outdated Show resolved Hide resolved
traits/trait_base.py Outdated Show resolved Hide resolved
traits/trait_base.py Outdated Show resolved Hide resolved
traits/trait_types.py Outdated Show resolved Hide resolved
@mdickinson
Copy link
Member

@midhun-pm When you've finished making changes, please could you click the "Re-request review" button? That way I'll be alerted that the PR is ready for re-review.

Copy link
Member

@mdickinson mdickinson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're getting there. Please update enum_default: currently it accepts either a collection or a single string (or bytes or bytestring) object, which then gets treated as a single-element collection. That's a cruel and unusual API, and it also doesn't match the enum_default docstring. This is a somewhat general purpose utility function, and we should have a clean API for it.

I think it should be easy to rework the caller of enum_default so that it's always the collection that's being passed.

traits/trait_base.py Outdated Show resolved Hide resolved
traits/trait_base.py Outdated Show resolved Hide resolved
traits/trait_types.py Outdated Show resolved Hide resolved
traits/trait_types.py Outdated Show resolved Hide resolved
traits/trait_types.py Show resolved Hide resolved
traits/trait_types.py Outdated Show resolved Hide resolved
Copy link
Member

@mdickinson mdickinson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few more comments: it looks as though we may be able to get rid of is_collection entirely.

As part of this PR, there should be an update to the user documentation warning about the perils of using an unordered structure like set as the collections type.

self.values = tuple(args)
else:
default_value = args[0]
self.values = tuple(args)

if isinstance(args, enum.EnumMeta):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@corranwebster Do you know what this branch is for? As far as I can tell, args will always be a tuple here, so this branch is never exercised, and can be removed. (Possibly it ended up here as a result of a bad merge?)

traits/trait_types.py Show resolved Hide resolved
Copy link
Member

@mdickinson mdickinson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good; I think this is the last round of changes.

traits/tests/test_enum.py Outdated Show resolved Hide resolved
traits/trait_types.py Outdated Show resolved Hide resolved
traits/trait_types.py Outdated Show resolved Hide resolved
traits/trait_types.py Show resolved Hide resolved
Copy link
Member

@mdickinson mdickinson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates! Merging.

@mdickinson mdickinson merged commit 637bcce into master Mar 27, 2020
@mdickinson mdickinson deleted the feature/allow_collections_for_enum_valid_values branch March 27, 2020 17:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow Enum traits to use Collections for valid values
3 participants