Observable typed attributes for Python classes
This is a bugfix release that fixes test failures with Sphinx 7.2 and later, and adds support for Python 3.12.
pathlib.Path
instead of sphinx.testing.path.path
for Sphinx
7.2 and later. (#1755)datetime.utcnow
method. (#1758)This is a bugfix release that fixes wheel builds on Python 3.11 and fixes some distribution and testing issues with typing stubs.
Fixes
* Update `cibuildwheel` to the latest version so that we get wheels for
Python 3.11. (#1711)
* Rename `requires_numpy_testing` decorator to `requires_numpy_typing`,
and have it check for `numpy.typing`, not `numpy.testing`. (#1710)
* Fix missing `numpy_examples` directory in traits-stubs package data.
(#1709)
Traits 6.4 is a minor feature release of Traits, which focuses mainly on typing stub and documentation updates.
Traits 6.4 should be largely backwards compatible with Traits 6.3, but there are a couple of things to watch out for.
Either
and Trait
trait types are not yet formally
deprecated, the intention is to eventually deprecate and remove them.
Projects are encouraged to update their code to use Union
instead.Unicode
trait type in your project should
be replaced with Str
.foos = List(MyTraitType)
)
now always matches the validation used for the item trait at top level (e.g.,
foo = MyTraitType
). Previously, the validation methods used could differ,
thanks to a bug in the container implementations. For most trait types this
will make no difference, but for the Tuple
trait type this change has the
consequence that lists will no longer be accepted as valid for Tuple
traits inside list items. See issue #1619 and PR #1625 for more information.Tuple()
trait declaration currently
accepts Python list
objects, while a Tuple
declaration with explicit
item types (for example Tuple(Int(), Int())
) does not. The support for
list
objects in plain Tuple()
is deprecated, and will be removed in a
future version of Traits. See PR #1627 for more information.The following people contributed code changes for this release:
ETSConfig
attributes now support deletion. This makes it easier to make
temporary changes to ETSConfig
attributes during unit testing. (#1670,
#1686)Complex
trait type validation is now more lenient: any type that
implements __complex__
will be accepted. (#1594)BaseFloat
validation is now more lenient, and matches Float
validation: BaseFloat
now also accepts objects whose type has an
__index__
method. (#1595)enumerate
alias has been removed from traits.trait_base
. In the
unlikely event of code that imports enumerate
from traits.trait_base
,
use the built-in enumerate
instead. (#1681)int_fast_validate
, float_fast_validate
and
complex_fast_validate
have been removed from the traits.trait_types
module. (#1601)TraitListObject
, TraitDict
object and TraitSetObject
now use the
validate
method of the appropriate CTrait
instances to validate
items, keys and values. Previously the handler's validate
method was
used; this gave buggy behaviour in cases where the handler's validate
method differed from the actual validation in use. (#1625)default_value
that incorrectly disregarded
default_value_type
. (#1631)clone_traits
applied to List
, Dict
and Set
traits. (#1624)find_resource
and store_resource
tests are now skipped
if the pkg_resources
module is not present in the environment. (#1679)ETSConfig
test has been renamed so that it's properly picked up
by the test runner. (#1671)ETSConfig
tests that assume unittest as the test runner. (#1683)List
or other collection trait in a subclass
now works as expected. Previously, the behaviour was unusably buggy. (#1645)Tuple
traits currently accept Python list
objects in some (but
not all) circumstances. That feature is deprecated, and will be removed
in a future version of Traits. (#1627)Array
, ArrayOrNone
, and CArray
. (#1682)traits.trait_types
; add stubs for
traits.ctraits
. (#1661)TraitError
stubs weren't exposed at traits.api
level.
(#1658)Int
and Float
type stubs more accurate. (#1656)Dict
trait type. (#1655)ETSConfig
class documentation visible in the API docs. (#1688)Date
, Datetime
and Time
trait types. (#1641)Set
in notification docs. (#1618)'some_trait.-'
pattern for on_trait_change
. (#1592)Either
should not be used in new code. (#1699)TraitPrefixMap
and TraitPrefixList
are deprecated.
(#1702)etstool.py
for Python 3.8 support. Python 3.8 is now the
default Python version for builds. (#1694)pyproject.toml
files for both Traits and traits-stubs. (#1689, #1676)build
directory in flake8 configuration. (#1635).gitignore
cleanup and updates. (#1678, #1687)PyErr_Format
calls in traits/ctraits.c
. (#1640)ci-src-requirements.txt
file isn't used; remove it. (#1602)Traits 6.3 is the latest feature release in the Traits 6 series, with several improvements and fixes over Traits 6.2.
on_trait_change
and observe
machinery. These may improve
startup time for some Traits-using applications.observe
mini-language now has in-language support for listening
to all traits, using the *
character.Traits 6.3 is intended to be fully backwards compatible with Traits 6.2, and most projects should have no difficulties upgrading. However, you may see some new deprecation warnings for existing code, warning about behaviour that will be changed in Traits 7.0. There are two particular sets of changes to look out for:
Starting with Traits 7.0, the Any
trait type will treat a default
value of type list
or dict
differently. Currently, instances of
list
and dict
are special-cased, and a per-instance copy of the
default is provided to each HasTraits
instance. In Traits 7.0, this
special-casing will be removed, and the default value will be shared between
all instances. For the 6.3 release of Traits, a deprecation warning is issued
whenever a trait definition of the form Any([1, 2, 3])
or Any({})
is encountered. Users can retain the existing behaviour and suppress the
warning by changing their code to use the new factory
argument to the
Any
trait type, for example replacing a trait declaration foo = Any({})
with foo = Any(factory=dict)
, and a trait declaration foo = Any([1, 2, 3])
with foo = Any(factory=list, args=([1, 2, 3],))
.
Starting with Traits 7.0, the Date
trait type will no longer accept
datetime
instances by default. Traits 6.3 will issue a deprecation
warning whenever a datetime
instance is assigned as a value for
a Date
trait. The existing behaviour can be preserved and the warning
silenced by using Date(allow_datetime=True)
; alternatively, you can
use Date(allow_datetime=False)
to adopt the Traits 7.0 behaviour
right now.
Over 80 pull requests went into this release. The following people contributed to the release:
Thank you to all who contributed!
observe
mini-language now supports use of "*"
for listening to
all traits on a HasTraits
object. Currently this support is limited to
cases where the "*"
appears in a terminal position. For example,
observe("foo:*")
is supported, but observe("*:foo")
is not.
(#1496, #1525)Any
trait type now supports a factory
argument (with accompanying
args
and kw
arguments). This can be used to specify a per-instance
default, for example with Any(factory=dict)
. (#1557, #1558)DefaultValue
enumeration has a new member DefaultValue.disallow
intended to be used for trait types that don't have a meaningful default. For
traits using this default value type, an attempt to retrieve the
corresponding default using default_value_for
will raise ValueError
.
(#1546)observe
decorator, the method
signature is now checked, and a warning issued if it doesn't match the
expected signature. This should catch the common error of forgetting to
provide the event
parameter. (#1529)ETSToolkit
, the "qt"
toolkit name is now supported as a synonym
for "qt4"
. (#1436)Date
, Datetime
and Time
trait types have a new argument
allow_none
. In the future, these trait types will not accept None
unless allow_none=True
is specified. (#1432)Date
trait type has a new argument allow_datetime
. In the future,
datetime
instances will not be valid values for a Date
trait unless
allow_datetime=True
is specified. (#1429)ObserverGraph
instances that result from compiling
ObserverExpression
objects and observe mini-language strings are now
cached. This should speed up creation and instantiation of HasTraits
subclasses that involve listening for the same pattern in multiple places.
(#1516, #1528)ObserverExpression
has been simplified.
(#1517)ObserverExpression
, ObserverGraph
and related
classes now use __slots__
to improve speed and memory use. (#1513, #1515)on_trait_change
method has been sped up by almost a factor of two,
by removing unnecessary internal usage of Traits in the parsing and listener
functionality. (#1490, #1491, #1492, #1493)PrefixList
or PrefixMap
trait
declaration now raises ValueError
rather than TraitError
. (#1564)PrefixList
and PrefixMap
no longer cache completions. (#1564)observe
mini-language string now raises
ValueError
rather than LarkError
. (#1507)NotifierNotFound
exception is now published in
traits.observation.api
. (#1498)CTrait
instance will now raise
AttributeError
. Previously, it would return None
. (#1469, #1474,
#1477)Any
trait type currently implicitly makes a per-HasTraits
-instance
copy of the default value if that value is an instance of either list
or
dict
. This behaviour is deprecated, and will be removed in Traits 7.0.
For a per-instance default, use the new factory
argument to Any
instead. (#1548, #1532)Date
, Datetime
and Time
trait types will no longer accept
None
as a valid trait value in the future. To keep the existing
behaviour, use the new allow_none
keyword argument to these trait types.
(#1444)Date
trait type will no longer accept datetime
instances by
default in the future. To keep the existing behaviour, use the new
allow_datetime
keyword argument. (#1441)Symbol
trait type is deprecated. For resolution of a string
representing a package/module/object combination, use import_symbol
instead. (#1542)MetaHasTraits.add_listener
and MetaHasTraits.remove_listener
methods are deprecated. (#1550)clean_filename
and clean_timestamp
utilities are deprecated. If
you need these utilities in your own project, you're advised to copy the
code directly into your project. (#1527)find_resource
and store_resource
functions are deprecated. New
code should use importlib.resources
or importlib_resources
instead
of either of these functions. (#1501)PrefixList
and PrefixMap
traits produced
an unnecessarily nested exception. This has been fixed. (#1564)observe
-decorated listener method whose name has the special form
"_traitname_changed"
will no longer be triggered both as as result
of the observe
decorator and the special naming: it will only be
triggered via the observe
decorator. (#1560)delegate
parameter was mistyped in the typing stubs for the
Delegate
trait type. This has been fixed. (#1556)Function
and Method
trait types will no longer fail when
arguments are passed. Note that these trait types are already deprecated, and
should not be used in new code. (#1543)Union
trait are now validated properly. Previously, in
trait declarations like foo = Union(List(Int), Str)
, the list entries
would not be validated. (#1522, #1534)Tuple
trait are now validated properly. (#1521)ListenerHandler
has been fixed. The
race condition is hard to exercise and has not been witnessed in the wild.
(#1495)add_class_trait
to add a List
trait was broken in the presence
of subclasses. This has been fixed. (#1461)distutils
library has been replaced with
sysconfig
. (#1452)_instance_handler_factory
used by the TraitsUI TableEditor
. (#1446, #1450)File
and Directory
traits have been fixed to avoid giving a misleading error message when
exists=True
. (#1440)BaseInstance
traits didn't correctly respect the allow_none
parameter. This is now fixed. (#1433)Any(some_list)
in docs have been replaced. (#1547)sync_trait
has been updated to note that it only
synchronises items for List
traits, not for Dict
and Set
traits.
(#1519)DeprecationWarning
arising from an unnecessary override of the
add_content
method in the TraitDocumenter
has been fixed. (#1475)HasTraits.set
have been replaced with
HasTraits.trait_set
. (#1451)trait_added
and trait_modified
traits on HasTraits
now
have proper trait type declarations. (#1552)unittest.main blocks
have been removed. (#1545)trait_types.pyi
. (#1523)ObserverExpression
and other key observation classes now have more
debug-friendly repr
implementations. (#1514)observer
parsing internals have been reworked to make
ObserverGraph
the key "compiled" object that the rest of Traits cares
about, rather than ObserverExpression
. (#1512)noqa
markers have been removed. (#1499)property
callable has been replaced with a property
decorator. (#1470)workflow_dispatch
trigger. (#1480)Traits 6.2 is the latest feature release in the Traits 6 series, with several improvements and fixes over Traits 6.1.
etsdemo
application. (The latter can be
installed from PyPI with pip install etsdemo
.)observe
framework has been significantly improved.ComparisonMode.identity
when using observe
to observe items
in a List
, Dict
or Set
.api
modules (for example, traits.api
, traits.adaptation.api
, etc.) This
recommendation has now been made explicit in the documentation. If you find
something you need that's not available from one of the api
modules,
please let the Traits developers know.More than 60 PRs went into this release. The following people contributed to this release:
Property
trait type now supports the observe
keyword. (#1175,
#1400)|=
support to TraitDict for Python 3.9 and later. (#1306)etsdemo
. (#1275)observe
string was previously a performance bottleneck.
This has been fixed, by removing some redundant parsing calls and by caching
parsing results. (#1343, #1344, #1345)NoDefaultSpecified
constant (used as a default value for
the TraitType
default_value
argument) is now public, made
available from traits.api
. (#1384, #1380, #1378)TraitMap
trait type has been reversed, because
there are existing uses of TraitMap
that are hard to replace.
Nevertheless, it is still not recommended to use TraitMap
in new code.
Use Map
instead. (#1365)PrefixList
with an empty list, or PrefixMap
or
Map
with an empty dictionary, now raises ValueError
. As a result,
the default default value (which used to be None
) is always valid.
(#1351)TraitListEvent
arguments are now keyword only. (#1346)ComparisonMode.identity
when using observe
to observe items
in a List
, Dict
or Set
. (#1165, #1328, #1240)Function
and Method
trait types are deprecated. Use
Callable
or Instance
instead. (#1399, #1397)edit
parameter to configure_traits
has been deprecated. (#1311)UnittestTools._catch_warnings
function has been deprecated. (#1310)CHECK_INTERFACES
global variable for automated
interface checking has been deprecated. (#1231)TraitError
exceptions raised during Tuple
validation are now
propagated. Previously they were converted into TraitError
. (#1393)Range
and Enum
traits are now properly validated
when inside a container (for example Tuple
or List
). Previously
no validation was performed. (#1388, #1392)traits.has_traits.EmptyList
.
(#1366)__repr__
implementations of
TraitListEvent
, TraitSetEvent
and TraitDictEvent
. (#1335)update
\ s of Dict
traits. (#1308)List
trait. (#1278)logger.warn
function. (#1283)Instance
trait declaration for a private trait in
the _TraitChangeCollector
class. (#1411)traits.examples
tutorial content. (#1374)api
modules should be used for imports. (#1387)image_LICENSE.txt
. (#1362)adapts
and implements
from
the examples and tutorial. (#1367)index.rst
. (#1358)trait_documenter
extension to be less fragile. (#1247)Instance
trait type. (#1395)List
, Dict
and Set
trait types copy on
assignment. (#1402)super
usage to the usual Python 3 argument-less pattern. (#1280)# noqa
comments in api
modules in favour of
per-file ignores in the flake8
configuration. (#1269)_i_observable
module to i_observable
. (#1296)pkg_resources
are skipped if setuptools
is not
installed. (#1301)test_subclasses_weakref
regression
test. (#1290)traits.examples
into a package. (#1348)flake8
-clean. (#1353)-h
for getting help in etstool.py
. (#1347)shell
command to etstool.py
. (#1293)flake8_ets
package in place of the local copyright_header
package.
The copyright_header
package has been removed. (#1341)check_observe_timing.py
to benchmark performance of
observe
to compare with on_trait_change
. (#1331)mypy
an optional dependency. (#1289)pip
directory
(now redundant). (#1241)Traits 6.1.1 is a bugfix release fixing a handful of minor documentation and test-related issues with the Traits 6.1.0 release. There are no API-breaking changes in this release. It's recommended that all users of Traits 6.1.0 upgrade to Traits 6.1.1.
Released: 2020-06-05
The Traits library is a foundational component of the Enthought Tool Suite. It provides observable, typed attributes for Python classes, making those classes suitable for event-driven dataflow programming and for immediate use as models for graphical user interfaces, like those provided by the TraitsUI library.
Traits 6.1 is the latest feature release in the Traits 6 series, and contains several major improvements.
A new observation
framework for observing traited
attributes and other observable objects has been introduced. This is intended
to provide a full replacement for the existing on_trait_change
mechanism, and aims to fix a number of fundamental flaws and limitations of
that mechanism. See the observe-notification
section of
the user manual for an introduction to this framework.
New TraitList
, TraitDict
and TraitSet
classes have been added,
subclassing Python's built-in list
, dict
and
set
(respectively). Instances of these classes are observable
objects in their own right, and it's possible to attach observers to them
directly. These classes were primarily introduced to support the new
observation framework, and are not expected to be used directly. The API for
these objects and their notification system is provisional, and may change in
a future Traits release.
A new Union
trait type has been added. This is intended as a
simpler replacement for the existing Either
trait type, which
will eventually be deprecated.
New PrefixList
, PrefixMap
and Map
trait types
have been added. These replace the existing TraitPrefixList
,
TraitPrefixMap
and TraitMap
subclasses of
TraitHandler
, which are deprecated.
Typing stubs for the Traits library have been added in a
traits-stubs
package, which will be released separately to PyPI. This
should help support Traits-using projects that want to make use of type
annotations and type checkers like mypy
.
As far as possible, Traits 6.1 is backwards compatible with Traits 6.0. However, there are a few things to be aware of when upgrading.
Traits 6.1 is not compatible with TraitsUI versions older than TraitsUI 7.0.
A combination of Traits 6.1 or later with TraitsUI 6.x or earlier will fail
to properly recognise View
class variables as
TraitsUI views, and an error will be raised if you attempt to create a
TraitsUI view.
Traits now does no logging configuration at all, leaving all such configuration to the application.
In more detail: trait notification handlers should not raise exceptions in normal use, so an exception is logged whenever a trait notification handler raises. This part of the behaviour has not changed. What has changed is the way that logged exception is handled under default exception handling.
Previously, Traits added a logging.StreamHandler
to the
top-level "traits"
logger, so that trait notification exceptions would
always be visible. Traits also added a logging.NullHandler
to that
logger. Both of those handlers have now been removed. We now rely on
Python's "handler of last resort", which will continue to make notification
exceptions to the user visible in the absence of any application-level
log configuration.
When listening for changes to the items of a List
trait, an index
or slice set operation no longer performs an equality check between the
replaced elements and the replacement elements when deciding whether to issue
a notification; instead, a notification is always issued if at least one
element was replaced. For example, consider the following class:
class Selection(HasTraits):
indices = List(Int)
@on_trait_change("indices_items")
def report_change(self, event):
print("Indices changed: ", event)
When replacing the 8
with the same integer, we get this behavior:
>>> selection = Selection(indices=[2, 5, 8])
>>> selection.indices[2] = 8
Indices changed: TraitListEvent(index=2, removed=[8], added=[8])
Previously, no notification would have been issued.
The Color
, RGBColor
and Font
trait factories
have moved to TraitsUI, and should be imported from there rather than from
Traits. For backwards compatibility, the factories are still
available in Traits, but they are deprecated and will eventually
be removed.
As a reminder, the Unicode
and Long
trait types are
deprecated since Traits 6.0. Please replace uses with Str
and
Int
respectively. To avoid excessive noise in Traits-using
projects, Traits does not yet issue deprecation warnings for existing uses of
Unicode
and Long
. Those warnings will be introduced in a
future Traits release, prior to the removal of these trait types.
In addition to the deprecations listed in the changelog below, some parts of the Traits library are not yet formally deprecated, but are likely to be deprecated before Traits 7.0. Users should be aware of the following possible future changes:
The Either
trait type will eventually be deprecated. Where
possible, use Union
instead. When replacing uses of
Either
with Union
, note that there are some significant
API and behavioral differences between the two trait types, particularly with
respect to handling of defaults. See the user manual for
more details.
The trait_modified
event trait that's present on all HasTraits
subclasses will eventually be removed. Users should not rely on it being
present in an object's class_traits
dictionary.
Trait names starting with trait
, traits
, _trait
or
_traits
may become reserved for use by ETS at some point in the future.
Avoid using these names for your own traits.
More than 160 PRs went into this release. The following people contributed code changes for this release:
os.PathLike
support for Directory
traits. (#867)Union
trait type. (#779, #1103, #1107, #1116, #1115)PrefixList
trait type. (#871, #1142, #1144, #1147)allow_none
flag for Callable
trait. (#885)Constant
trait. (#929)Map
and PrefixMap
trait types. (#886, #953, #956, #970, #1139,
#1189)TraitList
as the base list object that can perform validation
and emit change notifications. (#912, #981, #984, #989, #999, #1003, #1011,
#1026, #1009, #1040, #1172, #1173)TraitDict
as the base dict object that can perform validation and
emit change notifications. (#913)TraitSet
as the base set object that can perform validation and
emit change notifications. (#922, #1043)observe
to supersede on_trait_change
for observing trait
changes. (#976, #1000, #1007, #1065, #1023, #1066, #1070, #1069, #1067,
#1080, #1082, #1079, #1071, #1072, #1075, #1085, #1089, #1078, #1093, #1086,
#1077, #1095, #1102, #1108, #1110, #1112, #1117, #1118, #1123, #1125, #1126,
#1128, #1129, #1135, #1156)TraitSetEvent
and TraitDictEvent
initialization arguments are now
keyword-only. (#1036)TraitListObject
will no longer skip notifications even if mutations
result in content that compares equally to the old values. (#1026)TraitListEvent.index
reported by mutations to a list is now normalized.
(#1009)NullHandler
log handler has been removed.
(#1161)CTrait.post_setattr
. (#833)HasTraits
introspection with dir()
. (#927)DatetimeEditor
. (#937)TraitNotificationError
on trailing comma in on_trait_change
.
(#926)Enum
trait. (#889)TraitError
when mutating a list/dict/set inside another container.
(#1018)Map
, Expression
, PrefixMap
.
(#1091, #1188)Expression
and AdaptsTo
. (#1088, #1119, #1152)traits.testing.nose_tools
is deprecated. (#880)SingletonHasTraits
, SingletonHasStrictTraits
and
SingletonHasPrivateTraits
are deprecated. (#887)TraitMap
is deprecated, use Map
instead. (#974)TraitPrefixMap
is deprecated, use PrefixMap
instead. (#974)TraitPrefixList
is deprecated, use PrefixList
. (#974)Color
, RBGColor
and Font
are now deprecated. Use the ones from
TraitsUI instead. (#1022)traits_super
is removed. (#1015)OddInt
. (#973)observe
notification system. (#1060,
#1140, #1143)Union
trait type and how to migrate from
Either
(#779, #1153, #1162)extras_require
entry for testing. (#879)on_trait_change
mini-language. (#921)Enum.create_editor
. (#988)DeprecationWarning
messages. (#1157)etstool.py
. (#1051)setup.py
package metadata fields. (#1185)traits_inited
method. (#842)ctraits.c
. (#862)cTrait
getattr
, setattr
handlers in tp_new
. (#875)trait_change_notify
early in call_notifiers
. (#917)ctraits.c
for calling trait and object notifiers. (#918)BaseEnum
and Enum
fixes and cleanup. (#968)ctraits
property api to _set_property
and _get_property
.
(#967)__deepcopy__
implementation. (#992)__repr__
implementation for TraitListEvent
, TraitDictEvent
and TraitSetEvent
. (#1006, #1148, #1149)tutor.py
. (#1034)Enum
default traitsui editor. (#1012)NULL
for zero-argument PyObject_CallMethod
format. (#1100)