Comments (9)
@ssanderson, just to gauge the sort of design changes you're looking for:
- With respect to overriding the built-in default handling behavior, is a default validation behavior associated with
@default
/@validate
preferable to new under the hood heuristics forTraitType
? - Concerning
Container
andInstance
, I'll look into what's going on in their__init__
constructor to see if things can be made more uniform. As for themake_dynamic_default
issue, I think that could be solved if we choose to make changes to@default
or@validate
like I mentioned above, but maybe that's not what's best?
from traitlets.
In what sense, for example, is an empty string an appropriate default for all Unicode instances, or an empty list appropriate as a default for all List instances?
I would say: In the sense that it's the only logical default value for all of them. I take your point on more complex things that may or may not be instantiated (e.g. Instance), but for all of the str/list/tuple/dict, I would be very surprised if the default were anything other than the default value for the given type. I disagree that it would be an improvement for it to be otherwise.
But providing a nice API for specifying "A value must explicitly be provided to me, I have no default" is sensible, and seems to solve the actual problem here regardless of the 'default default' issue.
from traitlets.
Tuple just does a metadata.pop('default_value'))
This one could be considered a bug IMO.
from traitlets.
The tuple case is a laziness of signature, allowing default_value to be passed positionally or as a kwarg. e.g.
Tuple((1,2,3))
and
Tuple(default_value=(1,2,3))
are equivalent. It's a bit of a sloppy implementation of what should be
Tuple(default_value=..., **deprecated_metadata)
which allows the same positional-or-kwarg specification like any normal Python function.
from traitlets.
Yeah, it is just that the **metadata
argument name is bad since we decided that passing metadata as keyword arguments was deprecated in favor of .tag
.
from traitlets.
I realize that removing many of the "default defaults" would represent a pretty serious API breakage (though I'd argue it would be a breakage for the better that would be straightforward for downstream consumers to fix, likely surfacing latent bugs in the process).
We did change the API in a backward incompatible way when we decided that allow_none
should default to False
for all trait types by default.
However, I would be 👎 for removing the "default defaults", with the exception of Instance
. In this case, the current behavior is that a trait type with a foo = Instance(Foo)
attribute will fail to instantiate if the constructor is not passed a keyword argument foo=some instance of Foo
(which makes sense).
On the other hand, in the case where allow_none
is True
, it will succeed by initializing foo
as None
. I am not sure it is a good idea and if we should not rather encourage people to specify the None
default value.
from traitlets.
@rmorshea in my ideal world where the API was being designed from scratch, doing something like:
class MyClass(HasTraits):
x = Integer() # Note that no default_value was set.
MyClass().x
would raise an error indicating that no default value was specified for x
.
My argument for this behavior is that there is no value appropriate for use as a default value for a type that represents an integer field of an arbitrary object. I agree with @minrk's sentiment that 0 is the only sane choice _if we have to choose a default_. I just don't think 0 is universal enough to be imposed on every usage of Integer
. I'd rather have an API that asks me to clarify my intent than one that tries to guess what I mean without enough information to do so reliably.
In my experience, liberal default values tend to create bugs that manifest far away from their root causes, which at best wastes developer time tracking down where the bad value actually entered the system, and at worst encourages band-aid solutions that try to handle malformed values where they cause issues rather than where they're introduced.
In the case of traitlets specifically, the failure-at-a-distance problem is made worse by the fact that HasTraits
accepts arbitrary keyword arguments. On more than one occasion, I've had the frustrating experience of tracing an unexpected 0 or False value in a trait to having made a typo in a traited object's constructor or config file.
from traitlets.
@ssanderson I see what you're saying. I wasn't sure if you were also unhappy with validation of defaults, since default values don't pass through handlers registered with @validate
, which IMO seems off (though I understand @validate
is supposed to be meant for "cross-validation" and not all validation).
from traitlets.
@ssanderson given how much time has passed and the increased need for backwards compatibility in Traitlets I don't think we will be able to change how default values are handled. Closing for now...
from traitlets.
Related Issues (20)
- pull request blocked by "Enforce PR label / enforce-label (pull_request)" HOT 1
- Issues with trait typing HOT 12
- Consider using mypyc HOT 1
- Promise not to remove Sentinel?
- One test fails HOT 3
- Singletons configurable allow multiple instances HOT 2
- `__doc__` no longer contains the traitlets help string for reference type traitlets (Dict, List, ...) HOT 2
- Fix License metadata in PyPi package
- More typing edge cases
- Uncaught Exception `TypeError: 'ExtendedCompletionFinder' object is not callable` caused by orphaned pyc in site-packages HOT 5
- execution order of trait observers HOT 2
- Traitlets documentation incorrectly shows `__version__`
- Upgrade from traitlets `5.11.2` to `5.12.0` broke script HOT 1
- 5.13.0: pytest is failing with error in tests/test_typing.py HOT 1
- Changed behaviour since v5.12.0 of `traitlets.Set.set` if value is a string HOT 1
- Obeserve not works when showing result in widgets.Output()
- 26 tests fail
- test_complete_custom_completers failing HOT 4
- in get_type_hints(Appliction), TypeError: <class 'traitlets.traitlets.Dict'> is not a generic class HOT 1
- unobserve is not listed in the API in read the docs
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from traitlets.