Skip to content

Commit 10ca314

Browse files
committed
Merge pull request ipython#209 from rmorshea/deprecate_class_traits
deprecate `class_traits` and `class_trait_names` + add event searchers
2 parents a29ed05 + 7c839cf commit 10ca314

File tree

1 file changed

+85
-56
lines changed

1 file changed

+85
-56
lines changed

traitlets/traitlets.py

+85-56
Original file line numberDiff line numberDiff line change
@@ -1286,14 +1286,52 @@ def _register_validator(self, handler, names):
12861286
for name in names:
12871287
self._trait_validators[name] = handler
12881288

1289+
def add_traits(self, **traits):
1290+
"""Dynamically add trait attributes to the HasTraits instance."""
1291+
self.__class__ = type(self.__class__.__name__, (self.__class__,),
1292+
traits)
1293+
for trait in traits.values():
1294+
trait.instance_init(self)
1295+
1296+
def set_trait(self, name, value):
1297+
"""Forcibly sets trait attribute, including read-only attributes."""
1298+
cls = self.__class__
1299+
if not self.has_trait(name):
1300+
raise TraitError("Class %s does not have a trait named %s" %
1301+
(cls.__name__, name))
1302+
else:
1303+
getattr(cls, name).set(self, value)
1304+
1305+
@classmethod
1306+
def class_own_traits(cls, **metadata):
1307+
"""Get a dict of all the traitlets defined on this class, not a parent.
1308+
1309+
Works like ``traits``, except for excluding traits from parents.
1310+
"""
1311+
sup = super(cls, cls)
1312+
return {n: t for (n, t) in cls.traits(**metadata).items()
1313+
if getattr(sup, n, None) is not t}
1314+
1315+
@classmethod
1316+
def has_trait(cls, name):
1317+
"""Returns True if the object has a trait with the specified name."""
1318+
return isinstance(getattr(cls, name, None), TraitType)
1319+
1320+
@classmethod
1321+
def trait_names(cls, **metadata):
1322+
"""Get a list of all the names of this class' traits."""
1323+
return cls.traits(**metadata).keys()
1324+
12891325
@classmethod
12901326
def class_trait_names(cls, **metadata):
12911327
"""Get a list of all the names of this class' traits.
12921328
12931329
This method is just like the :meth:`trait_names` method,
12941330
but is unbound.
12951331
"""
1296-
return cls.class_traits(**metadata).keys()
1332+
warn("``HasTraits.class_trait_names`` is deprecated in favor of ``HasTraits.trait_names``"
1333+
" as a classmethod", DeprecationWarning, stacklevel=2)
1334+
return cls.traits(**metadata).keys()
12971335

12981336
@classmethod
12991337
def class_traits(cls, **metadata):
@@ -1312,43 +1350,12 @@ def class_traits(cls, **metadata):
13121350
the output. If a metadata key doesn't exist, None will be passed
13131351
to the function.
13141352
"""
1315-
traits = dict([memb for memb in getmembers(cls) if
1316-
isinstance(memb[1], TraitType)])
1317-
1318-
if len(metadata) == 0:
1319-
return traits
1320-
1321-
result = {}
1322-
for name, trait in traits.items():
1323-
for meta_name, meta_eval in metadata.items():
1324-
if type(meta_eval) is not types.FunctionType:
1325-
meta_eval = _SimpleTest(meta_eval)
1326-
if not meta_eval(trait.metadata.get(meta_name, None)):
1327-
break
1328-
else:
1329-
result[name] = trait
1330-
1331-
return result
1353+
warn("``HasTraits.class_traits`` is deprecated in favor of ``HasTraits.traits``"
1354+
" as a classmethod", DeprecationWarning, stacklevel=2)
1355+
return cls.traits(**metadata)
13321356

13331357
@classmethod
1334-
def class_own_traits(cls, **metadata):
1335-
"""Get a dict of all the traitlets defined on this class, not a parent.
1336-
1337-
Works like `class_traits`, except for excluding traits from parents.
1338-
"""
1339-
sup = super(cls, cls)
1340-
return {n: t for (n, t) in cls.class_traits(**metadata).items()
1341-
if getattr(sup, n, None) is not t}
1342-
1343-
def has_trait(self, name):
1344-
"""Returns True if the object has a trait with the specified name."""
1345-
return isinstance(getattr(self.__class__, name, None), TraitType)
1346-
1347-
def trait_names(self, **metadata):
1348-
"""Get a list of all the names of this class' traits."""
1349-
return self.traits(**metadata).keys()
1350-
1351-
def traits(self, **metadata):
1358+
def traits(cls, **metadata):
13521359
"""Get a ``dict`` of all the traits of this class. The dictionary
13531360
is keyed on the name and the values are the TraitType objects.
13541361
@@ -1362,49 +1369,71 @@ def traits(self, **metadata):
13621369
the output. If a metadata key doesn't exist, None will be passed
13631370
to the function.
13641371
"""
1365-
traits = dict([memb for memb in getmembers(self.__class__) if
1372+
traits = dict([memb for memb in getmembers(cls) if
13661373
isinstance(memb[1], TraitType)])
13671374

13681375
if len(metadata) == 0:
13691376
return traits
13701377

1378+
for meta_name, meta_eval in metadata.items():
1379+
if type(meta_eval) is not types.FunctionType:
1380+
metadata[meta_name] = _SimpleTest(meta_eval)
1381+
13711382
result = {}
13721383
for name, trait in traits.items():
13731384
for meta_name, meta_eval in metadata.items():
1374-
if type(meta_eval) is not types.FunctionType:
1375-
meta_eval = _SimpleTest(meta_eval)
13761385
if not meta_eval(trait.metadata.get(meta_name, None)):
13771386
break
13781387
else:
13791388
result[name] = trait
13801389

13811390
return result
13821391

1383-
def trait_metadata(self, traitname, key, default=None):
1392+
@classmethod
1393+
def trait_metadata(cls, traitname, key, default=None):
13841394
"""Get metadata values for trait by key."""
13851395
try:
1386-
trait = getattr(self.__class__, traitname)
1396+
trait = getattr(cls, traitname)
13871397
except AttributeError:
13881398
raise TraitError("Class %s does not have a trait named %s" %
1389-
(self.__class__.__name__, traitname))
1399+
(cls.__name__, traitname))
13901400
else:
13911401
return trait.metadata.get(key, default)
13921402

1393-
def add_traits(self, **traits):
1394-
"""Dynamically add trait attributes to the HasTraits instance."""
1395-
self.__class__ = type(self.__class__.__name__, (self.__class__,),
1396-
traits)
1397-
for trait in traits.values():
1398-
trait.instance_init(self)
1403+
@classmethod
1404+
def class_own_trait_events(cls, name):
1405+
"""Get a dict of all event handlers defined on this class, not a parent.
13991406
1400-
def set_trait(self, name, value):
1401-
"""Forcibly sets trait attribute, including read-only attributes."""
1402-
cls = self.__class__
1403-
if not self.has_trait(name):
1404-
raise TraitError("Class %s does not have a trait"
1405-
"named %s" % (cls.__name__, name))
1406-
else:
1407-
getattr(cls, name).set(self, value)
1407+
Works like ``event_handlers``, except for excluding traits from parents.
1408+
"""
1409+
sup = super(cls, cls)
1410+
return {n: e for (n, e) in cls.events(name).items()
1411+
if getattr(sup, n, None) is not e}
1412+
1413+
@classmethod
1414+
def trait_events(cls, name=None):
1415+
"""Get a ``dict`` of all the event handlers of this class.
1416+
1417+
Parameters
1418+
----------
1419+
name: str (default: None)
1420+
The name of a trait of this class. If name is ``None`` then all
1421+
the event handlers of this class will be returned instead.
1422+
1423+
Returns
1424+
-------
1425+
The event handlers associated with a trait name, or all event handlers."""
1426+
events = {}
1427+
for k, v in getmembers(cls):
1428+
if isinstance(v, EventHandler):
1429+
if name is None:
1430+
events[k] = v
1431+
elif name in v.trait_names:
1432+
events[k] = v
1433+
elif hasattr(v, 'tags'):
1434+
if cls.trait_names(**v.tags):
1435+
events[k] = v
1436+
return events
14081437

14091438
#-----------------------------------------------------------------------------
14101439
# Actual TraitTypes implementations/subclasses

0 commit comments

Comments
 (0)