traits-4.1.0/0000755000175100001440000000000011674464647014026 5ustar ischnellusers00000000000000traits-4.1.0/TODO.txt0000644000175100001440000000016011674463323015317 0ustar ischnellusers00000000000000* Remove the dependency on AppTools project (caused by imports of pyface.resource in traits/ui/image.py.) traits-4.1.0/integrationtests/0000755000175100001440000000000011674463323017422 5ustar ischnellusers00000000000000traits-4.1.0/integrationtests/ui/0000755000175100001440000000000011674463323020037 5ustar ischnellusers00000000000000traits-4.1.0/integrationtests/ui/table_editor_test.py0000644000175100001440000002036211674463323024110 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # TableEditor test case for Traits UI # # Written by: David C. Morrill # # Date: 07/05/2005 # # (c) Copyright 2005 by Enthought, Inc. # Copyright (c) 2007, Enthought, Inc. # License: BSD Style. # #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from traits.api \ import HasStrictTraits, Str, Int, Regex, List, Instance from traitsui.api \ import View, Group, Item, TableEditor, EnumEditor from traitsui.table_column \ import ObjectColumn from traitsui.table_filter \ import TableFilter, RuleTableFilter, RuleFilterTemplate, \ MenuFilterTemplate, EvalFilterTemplate #------------------------------------------------------------------------------- # 'Person' class: #------------------------------------------------------------------------------- class Person ( HasStrictTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- name = Str age = Int phone = Regex( value = '000-0000', regex = '\d\d\d[-]\d\d\d\d' ) state = Str #--------------------------------------------------------------------------- # Traits view definition: #--------------------------------------------------------------------------- traits_view = View( 'name', 'age', 'phone', 'state', title = 'Create new person', width = 0.18, buttons = [ 'OK', 'Cancel' ] ) #------------------------------------------------------------------------------- # Sample data: #------------------------------------------------------------------------------- people = [ Person( name = 'Dave', age = 39, phone = '555-1212' ), Person( name = 'Mike', age = 28, phone = '555-3526' ), Person( name = 'Joe', age = 34, phone = '555-6943' ), Person( name = 'Tom', age = 22, phone = '555-7586' ), Person( name = 'Dick', age = 63, phone = '555-3895' ), Person( name = 'Harry', age = 46, phone = '555-3285' ), Person( name = 'Sally', age = 43, phone = '555-8797' ), Person( name = 'Fields', age = 31, phone = '555-3547' ) ] #------------------------------------------------------------------------------- # 'AgeFilter' class: #------------------------------------------------------------------------------- class AgeFilter ( TableFilter ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- name = "Age filter" _name = "Age filter" age = Int( 0 ) #--------------------------------------------------------------------------- # Traits view definitions: #--------------------------------------------------------------------------- #filter_view = Group( 'age{Age >=}' ) #--------------------------------------------------------------------------- # Returns whether an object passes the filter or not: #--------------------------------------------------------------------------- def filter ( self, person ): """ Returns whether an object passes the filter or not. """ return (person.age >= self.age) #--------------------------------------------------------------------------- # Returns a user readable description of what the filter does: #--------------------------------------------------------------------------- def description ( self ): """ Returns a user readable description of what the filter does. """ return 'Age >= %d' % self.age def _age_changed(self, old, new): self.name = self.description() print 'AgeFilter _age_changed', self.name #------------------------------------------------------------------------------- # 'NameFilter' class: #------------------------------------------------------------------------------- class NameFilter ( TableFilter ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- mname = Str #--------------------------------------------------------------------------- # Traits view definitions: #--------------------------------------------------------------------------- filter_view = Group( 'mname{Name contains}' ) #--------------------------------------------------------------------------- # Returns whether an object passes the filter or not: #--------------------------------------------------------------------------- def filter ( self, person ): """ Returns whether an object passes the filter or not. """ return (person.name.lower().find( self.mname.lower() ) >= 0) #--------------------------------------------------------------------------- # Returns a user readable description of what the filter does: #--------------------------------------------------------------------------- def description ( self ): """ Returns a user readable description of what the filter does. """ return "Name contains '%s'" % self.mname #------------------------------------------------------------------------------- # Table editor definition: #------------------------------------------------------------------------------- filters = [ AgeFilter( age = 30 ), NameFilter( mname = 'd' ), EvalFilterTemplate, MenuFilterTemplate, RuleFilterTemplate, ] def evaluate_value(v): print 'evaluate_value', v return str(v) #------------------------------------------------------------------------------- # 'TableTest' class: #------------------------------------------------------------------------------- class TableTest ( HasStrictTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- #people = Instance( Person ) people = List( Person ) #--------------------------------------------------------------------------- # Traits view definitions: #--------------------------------------------------------------------------- _valid_states = List(["AL", "AR", "AZ", "AK"]) _state_editor = EnumEditor( name = "_valid_states", evaluate = evaluate_value, object = 'table_editor_object' ) table_editor = TableEditor( columns = [ ObjectColumn( name = 'name' ), ObjectColumn( name = 'age' ), ObjectColumn( name = 'phone' ), ObjectColumn( name = 'state', editor=_state_editor), ], editable = True, deletable = True, sortable = True, sort_model = True, show_lines = True, orientation = 'vertical', show_column_labels = True, edit_view = View( [ 'name', 'age', 'phone', 'state', '|[]' ], resizable = True ), filter = None, filters = filters, row_factory = Person ) traits_view = View( [ Item( 'people', id = 'people', editor = table_editor ), '|[]<>' ], title = 'Table Editor Test', id = 'traitsui.tests.table_editor_test', dock = 'horizontal', width = .4, height = .3, resizable = True, kind = 'live' ) #------------------------------------------------------------------------------- # Run the tests: #------------------------------------------------------------------------------- if __name__ == '__main__': tt = TableTest( people = people ) tt.configure_traits() for p in tt.people: p.print_traits() print '--------------' traits-4.1.0/integrationtests/ui/test_ui.py0000644000175100001440000002345011674463323022071 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # Copyright (c) 2005, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # Thanks for using Enthought open source! # # Author: David C. Morrill Date: 11/02/2004 Description: Test case for Traits # User Interface # ------------------------------------------------------------------------------ #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- import wx from traits.api \ import Trait, HasTraits, Str, Int, Range, List, Event, File, Directory, \ Bool, Color, Font, Enum from traitsui.api \ import View, Handler, Item, CheckListEditor, ButtonEditor, FileEditor, \ DirectoryEditor, ImageEnumEditor #------------------------------------------------------------------------------- # Constants: #------------------------------------------------------------------------------- origin_values = [ 'top left', 'top right', 'bottom left', 'bottom right' ] #------------------------------------------------------------------------------- # 'Instance' class: #------------------------------------------------------------------------------- class Instance ( HasTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- integer_text = Int( 1 ) enumeration = Enum( 'one', 'two', 'three', 'four', 'five', 'six', cols = 3 ) float_range = Range( 0.0, 10.0, 10.0 ) int_range = Range( 1, 5 ) boolean = Bool( True ) view = View( 'integer_text', 'enumeration', 'float_range', 'int_range', 'boolean' ) #------------------------------------------------------------------------------- # 'TraitsTest' class #------------------------------------------------------------------------------- class TraitsTest ( HasTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- integer_text = Int( 1 ) enumeration = Enum( 'one', 'two', 'three', 'four', 'five', 'six', cols = 3 ) float_range = Range( 0.0, 10.0, 10.0 ) int_range = Range( 1, 6 ) int_range2 = Range( 1, 50 ) compound = Trait( 1, Range( 1, 6 ), 'one', 'two', 'three', 'four', 'five', 'six' ) boolean = Bool( True ) instance = Trait( Instance() ) color = Color font = Font check_list = List( editor = CheckListEditor( values = [ 'one', 'two', 'three', 'four' ], cols = 4 ) ) list = List( Str, [ 'East of Eden', 'The Grapes of Wrath', 'Of Mice and Men' ] ) button = Event( 0, editor = ButtonEditor( label = 'Click' ) ) file = File directory = Directory image_enum = Trait( editor = ImageEnumEditor( values = origin_values, suffix = '_origin', cols = 4, klass = Instance ), *origin_values ) #--------------------------------------------------------------------------- # View definitions: #--------------------------------------------------------------------------- view = View( ( '|{Enum}', ( '|<[Enumeration]', 'enumeration[Simple]', '_', 'enumeration[Custom]@', '_', 'enumeration[Text]*', '_', 'enumeration[Readonly]~' ), ( '|<[Check List]', 'check_list[Simple]', '_', 'check_list[Custom]@', '_', 'check_list[Text]*', '_', 'check_list[Readonly]~' ) ), ( '|{Range}', ( '|<[Float Range]', 'float_range[Simple]', '_', 'float_range[Custom]@', '_', 'float_range[Text]*', '_', 'float_range[Readonly]~' ), ( '|<[Int Range]', 'int_range[Simple]', '_', 'int_range[Custom]@', '_', 'int_range[Text]*', '_', 'int_range[Readonly]~' ), ( '|<[Int Range 2]', 'int_range2[Simple]', '_', 'int_range2[Custom]@', '_', 'int_range2[Text]*', '_', 'int_range2[Readonly]~' ) ), ( '|{Misc}', ( '|<[Integer Text]', 'integer_text[Simple]', '_', 'integer_text[Custom]@', '_', 'integer_text[Text]*', '_', 'integer_text[Readonly]~' ), ( '|<[Compound]', 'compound[Simple]', '_', 'compound[Custom]@', '_', 'compound[Text]*', '_', 'compound[Readonly]~' ), ( '|<[Boolean]', 'boolean[Simple]', '_', 'boolean[Custom]@', '_', 'boolean[Text]*', '_', 'boolean[Readonly]~' ) ), ( '|{Color/Font}', ( '|<[Color]', 'color[Simple]', '_', 'color[Custom]@', '_', 'color[Text]*', '_', 'color[Readonly]~' ), ( '|<[Font]', 'font[Simple]', '_', 'font[Custom]@', '_', 'font[Text]*', '_', 'font[Readonly]~' ) ), ( '|{List}', ( '|<[List]', 'list[Simple]', '_', 'list[Custom]@', '_', 'list[Text]*', '_', 'list[Readonly]~' ) ), ( '|{Button}', ( '|<[Button]', 'button[Simple]', '_', 'button[Custom]@' ), # 'button[Text]*', # 'button[Readonly]~' ), ( '|<[Image Enum]', 'image_enum[Simple]', '_', 'image_enum[Custom]@', '_', 'image_enum[Text]*', '_', 'image_enum[Readonly]~' ), ( '|<[Instance]', 'instance[Simple]', '_', 'instance[Custom]@', '_', 'instance[Text]*', '_', 'instance[Readonly]~' ), ), ( '|{File}', ( '|<[File]', 'file[Simple]', '_', 'file[Custom]@', '_', 'file[Text]*', '_', 'file[Readonly]~', ), ( '|<[Directory]', 'directory[Simple]', '_', 'directory[Custom]@', '_', 'directory[Text]*', '_', 'directory[Readonly]~' ) ), buttons = [ 'Apply', 'Revert', 'Undo', 'OK' ] ) #------------------------------------------------------------------------------- # 'TraitSheetApp' class: #------------------------------------------------------------------------------- class TraitSheetApp ( wx.App ): #--------------------------------------------------------------------------- # Initialize the object: #--------------------------------------------------------------------------- def __init__ ( self, object ): self.object = object wx.InitAllImageHandlers() wx.App.__init__( self, 1, 'debug.log' ) self.MainLoop() #--------------------------------------------------------------------------- # Handle application initialization: #--------------------------------------------------------------------------- def OnInit ( self ): ui = self.object.edit_traits( kind = 'modal' ) ui = self.object.edit_traits( kind = 'wizard' ) ui = self.object.edit_traits( kind = 'nonmodal' ) ui = self.object.edit_traits( kind = 'live' ) self.SetTopWindow( ui.control ) return True #------------------------------------------------------------------------------- # Main program: #------------------------------------------------------------------------------- if __name__ == '__main__': TraitSheetApp( TraitsTest() ) traits-4.1.0/integrationtests/ui/table_editor_color_test.py0000644000175100001440000000502311674463323025303 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # TableEditor test case for Traits UI # # Written by: David C. Morrill # # Date: 07/05/2005 # # (c) Copyright 2005 by Enthought, Inc. # License: BSD Style. # #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from traits.api \ import HasTraits, List from traitsui.api \ import View, Item, TableEditor from traitsui.wx.color_column \ import ColorColumn from enable.api \ import ColorTrait class Thingy ( HasTraits ): color = ColorTrait( 'black' ) #------------------------------------------------------------------------------- # Sample data: #------------------------------------------------------------------------------- colors = [ Thingy( color = 'red'), Thingy( color = 'orange'), Thingy( color = 'yellow'), Thingy( color = 'green'), Thingy( color = 'blue'), Thingy( color = 'indigo'), Thingy( color = 'violet'), Thingy( color = 'black'), Thingy( color = 'white'), ] class TableTest ( HasTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- colors = List( Thingy ) table_editor = TableEditor( columns = [ ColorColumn( name = 'color' ), ], editable = True, deletable = True, sortable = True, # sort_model = True, show_lines = True, # orientation = 'vertical', show_column_labels = True, # row_factory = Thingy ) traits_view = View( [ Item( 'colors', id = 'colors', editor = table_editor ), '|[]<>' ], title = 'Table Editor Test', id = 'traitsui.tests.table_editor_color_test', dock = 'horizontal', width = .4, height = .3, resizable = True, kind = 'live' ) #------------------------------------------------------------------------------- # Run the tests: #------------------------------------------------------------------------------- if __name__ == '__main__': tt = TableTest( colors = colors ) tt.configure_traits() traits-4.1.0/integrationtests/ui/large_range_editor.py0000644000175100001440000000271311674463323024230 0ustar ischnellusers00000000000000# Copyright (c) 2007, Enthought, Inc. # License: BSD Style. from traits.api import HasTraits, Float, List from traitsui.api import View, Item, RangeEditor # Tests the Large Range Slider editor. It also tests the case where the # editor is embedded in a list. class TestRangeEditor(HasTraits): x = Float low = Float(123.123) high = Float(1123.123) list = List(Float( editor = RangeEditor(low_name='low', high_name = 'high', # These force the large range # slider to be used. low=100.0, high=10000.123) ) ) view = View(Item(name='x', editor = RangeEditor(low_name='low', high_name = 'high', # These force the large range # slider to be used. low=100.0, high=10000.123) ), Item('list'), resizable=True ) def test(): a = TestRangeEditor() a.x = 500 a.list.append(500) a.edit_traits() # Just close the resulting dialog. assert a.x == 500 assert a.list[0] == 500 test() traits-4.1.0/integrationtests/ui/instance_editor_test.py0000644000175100001440000000537211674463323024631 0ustar ischnellusers00000000000000# Copyright (c) 2007, Enthought, Inc. # License: BSD Style. from traits.api import * from traitsui.api import * from traitsui.instance_choice import InstanceChoice #------------------------------------------------------------------------------- # 'Person' class: #------------------------------------------------------------------------------- class Person ( HasStrictTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- name = Str age = Int phone = Regex( value = '000-0000', regex = '\d\d\d[-]\d\d\d\d' ) #--------------------------------------------------------------------------- # Traits view definition: #--------------------------------------------------------------------------- traits_view = View( 'name', 'age', 'phone' ) #------------------------------------------------------------------------------- # Sample data: #------------------------------------------------------------------------------- people = [ Person( name = 'Dave', age = 39, phone = '555-1212' ), Person( name = 'Mike', age = 28, phone = '555-3526' ), Person( name = 'Joe', age = 34, phone = '555-6943' ), Person( name = 'Tom', age = 22, phone = '555-7586' ), Person( name = 'Dick', age = 63, phone = '555-3895' ), Person( name = 'Harry', age = 46, phone = '555-3285' ), Person( name = 'Sally', age = 43, phone = '555-8797' ), Person( name = 'Fields', age = 31, phone = '555-3547' ) ] #------------------------------------------------------------------------------- # 'Team' class: #------------------------------------------------------------------------------- class Team ( HasStrictTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- name = Str captain = Instance( Person ) roster = List( Person ) #--------------------------------------------------------------------------- # Traits view definitions: #--------------------------------------------------------------------------- traits_view = View( 'name', '_', Item( 'captain@', editor = InstanceEditor( name = 'roster' ) ), buttons = [ 'Undo', 'OK', 'Cancel' ] ) #------------------------------------------------------------------------------- # Run the test: #------------------------------------------------------------------------------- if __name__ == '__main__': Team( name = 'Vultures', captain = people[0], roster = people ).configure_traits() traits-4.1.0/integrationtests/ui/html_editor_test.py0000644000175100001440000000450611674463323023767 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # Test case for the HTMLEditor. # # Written by: David C. Morrill # # Date: 09/22/2005 # # (c) Copyright 2005 by Enthought, Inc. # License: BSD Style. # #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from traits.api \ import HasPrivateTraits, Code from traitsui.api \ import View, Group, Item, HTMLEditor #------------------------------------------------------------------------------- # Constants: #------------------------------------------------------------------------------- sample = """This is a code block: def foo ( bar ): print 'bar:', bar This is an unordered list: - An - unordered - list This is an ordered list: * One * Two * Three Lists can be nested: * One * 1.1 * 1.2 * Two * 2.1 * 2.2 """ #------------------------------------------------------------------------------- # 'TestHTML' class: #------------------------------------------------------------------------------- class TestHTML ( HasPrivateTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- # Text string to display as HTML: html = Code( sample ) #--------------------------------------------------------------------------- # Traits view definitions: #--------------------------------------------------------------------------- view = View( Group( [ Item( 'html#@', editor = HTMLEditor() ), '|<>' ], [ '{Enter formatted text and/or HTML below:}@', 'html#@', '|<>' ], '|<>', layout = 'split' ), title = 'HTML Editor Test', resizable = True, width = 0.4, height = 0.6 ) #------------------------------------------------------------------------------- # Run the test: #------------------------------------------------------------------------------- if __name__ == '__main__': TestHTML().configure_traits() traits-4.1.0/integrationtests/ui/images/0000755000175100001440000000000011674463323021304 5ustar ischnellusers00000000000000traits-4.1.0/integrationtests/ui/images/bottom_left_origin.gif0000644000175100001440000000125011674463323025656 0ustar ischnellusers00000000000000GIF89a< ccc]]]KKKqqqVVVzyy~~~bbbƆuu>xRR((GG飣dd[["""쟟ZZZUUhUUooo׻XXaa,<      ɂʿҶ  !"#$$%&'b*Np - ,2j܈F bX$!c&8F y 8q2". 9TL=|@) ,H!=5 !-@B@3B (|G@* ;traits-4.1.0/integrationtests/ui/images/bottom_right_origin.gif0000644000175100001440000000125011674463323026041 0ustar ischnellusers00000000000000GIF89a< bbb]]]KKKqqqVVVyyy\\\~~~Ɔuu>xRR((kkkLLhhh !!!wwwWW..Ӿ??||˴SSaa,<       ņ  ׻߲!"#$%L8B>B R|RA nVBA*_Pq@16*Xi &fHP@4Ԩa?m#GMtCNq GmC V!!5@H[ v'* ;traits-4.1.0/integrationtests/ui/images/top_right_origin.gif0000644000175100001440000000123411674463323025341 0ustar ischnellusers00000000000000GIF89a<JJkkk ddޝ!!!wwwWW&&Ӿ?? lYYkEEZc$$KKK~~~^^^555oooaaaWWW ===,<   ± "#$%&'('&)&$+,-(./.'0//023456&u@ IN5G 9^ X5 E  nH1cG;>`dH%[D SD7`ƴKY)^, %ʩ0~bCH!@׃ ?@ؕ<@ݔ#Eo;traits-4.1.0/integrationtests/ui/images/top_left_origin.gif0000644000175100001440000000125011674463323025154 0ustar ischnellusers00000000000000GIF89a<JJ]]dd[[ """쟟[[[tttaaa]]]UU `MMnnn¸oIIZe&&JIIyyy555~~~WWWfff===Ǔ,<   ȶ !"#$$%&Я'()*+,-,,./%01 234567H5G&bIAtqP++&X#ǓxLA*0Uf̕4_(3Γ=].VZ- %ʁ-,L2 Ä?nH0Z @48AnxÞ^ m'BN ;traits-4.1.0/integrationtests/ui/instance_editor_test6.py0000644000175100001440000000636511674463323024722 0ustar ischnellusers00000000000000# Copyright (c) 2007, Enthought, Inc. # License: BSD Style. from traits.api import * from traitsui.api import * from traitsui.instance_choice \ import InstanceChoice, InstanceFactoryChoice #------------------------------------------------------------------------------- # 'Person' class: #------------------------------------------------------------------------------- class Person ( HasStrictTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- name = Str age = Int phone = Regex( value = '000-0000', regex = '\d\d\d[-]\d\d\d\d' ) #--------------------------------------------------------------------------- # Traits view definition: #--------------------------------------------------------------------------- traits_view = View( 'name', 'age', 'phone', buttons = [ 'OK', 'Cancel' ] ) #------------------------------------------------------------------------------- # Sample data: #------------------------------------------------------------------------------- people = [ Person( name = 'Dave', age = 39, phone = '555-1212' ), Person( name = 'Mike', age = 28, phone = '555-3526' ), Person( name = 'Joe', age = 34, phone = '555-6943' ), Person( name = 'Tom', age = 22, phone = '555-7586' ), Person( name = 'Dick', age = 63, phone = '555-3895' ), Person( name = 'Harry', age = 46, phone = '555-3285' ), Person( name = 'Sally', age = 43, phone = '555-8797' ), Person( name = 'Fields', age = 31, phone = '555-3547' ) ] #------------------------------------------------------------------------------- # 'Team' class: #------------------------------------------------------------------------------- class Team ( HasStrictTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- name = Str captain = Instance( Person ) roster = List( Person ) #--------------------------------------------------------------------------- # Traits view definitions: #--------------------------------------------------------------------------- traits_view = View( [ 'name', '_', Item( 'captain', editor = InstanceEditor( name = 'roster', label = 'Edit...', values = [ InstanceFactoryChoice( klass = Person, name = 'Non player', view = 'edit_view' ) ] ) ) ], buttons = [ 'OK', 'Cancel' ] ) #------------------------------------------------------------------------------- # Run the test: #------------------------------------------------------------------------------- if __name__ == '__main__': Team( name = 'Vultures', captain = people[0], roster = people ).configure_traits() traits-4.1.0/integrationtests/ui/instance_drag_test.py0000644000175100001440000002034111674463323024251 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # Copyright (c) 2005, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # Thanks for using Enthought open source! # # Author: David C. Morrill # Date: 12/04/2004 # Description: Test case for the traits tree editor. #------------------------------------------------------------------------------ #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from traits.api \ import HasTraits, Str, Regex, List, Instance from traitsui.api \ import TreeEditor, TreeNode, View, Group, Item, Handler, InstanceEditor from traitsui.instance_choice \ import InstanceDropChoice from traitsui.menu \ import Menu, Action, Separator from traitsui.wx.tree_editor \ import NewAction, CopyAction, CutAction, PasteAction, DeleteAction, \ RenameAction #------------------------------------------------------------------------------- # 'Employee' class: #------------------------------------------------------------------------------- class Employee ( HasTraits ): name = Str( '' ) title = Str phone = Regex( regex = r'\d\d\d-\d\d\d\d' ) view = View( 'title', 'phone' ) def default_title ( self ): self.title = 'Senior Engineer' #------------------------------------------------------------------------------- # 'Department' class: #------------------------------------------------------------------------------- class Department ( HasTraits ): name = Str( '' ) employees = List( Employee ) view = View( [ 'employees', '|<>' ] ) #------------------------------------------------------------------------------- # 'Company' class: #------------------------------------------------------------------------------- class Company ( HasTraits ): name = Str( '' ) departments = List( Department ) employees = List( Employee ) #------------------------------------------------------------------------------- # 'Partner' class: #------------------------------------------------------------------------------- class Partner ( HasTraits ): name = Str( '' ) company = Instance( Company ) eom = Instance( Employee ) dom = Instance( Department ) #------------------------------------------------------------------------------- # Create a hierarchy: #------------------------------------------------------------------------------- jason = Employee( name = 'Jason', title = 'Sr. Engineer', phone = '536-1057' ) mike = Employee( name = 'Mike', title = 'Sr. Engineer', phone = '536-1057' ) dave = Employee( name = 'Dave', title = 'Sr. Engineer', phone = '536-1057' ) martin = Employee( name = 'Martin', title = 'Sr. Engineer', phone = '536-1057' ) duncan = Employee( name = 'Duncan', title = 'Sr. Engineer' ) partner = Partner( name = 'eric', company = Company( name = 'Enthought, Inc.', departments = [ Department( name = 'Business', employees = [ jason, mike ] ), Department( name = 'Scientific', employees = [ dave, martin, duncan ] ) ], employees = [ dave, martin, mike, duncan, jason ] ) ) #------------------------------------------------------------------------------- # Define the tree trait editor: #------------------------------------------------------------------------------- no_view = View() tree_editor = TreeEditor( editable = False, nodes = [ TreeNode( node_for = [ Company ], auto_open = True, children = '', label = 'name', view = View( [ 'name', '|<' ] ) ), TreeNode( node_for = [ Company ], auto_open = True, children = 'departments', label = '=Departments', view = no_view, add = [ Department ] ), TreeNode( node_for = [ Company ], auto_open = True, children = 'employees', label = '=Employees', view = no_view, add = [ Employee ] ), TreeNode( node_for = [ Department ], auto_open = True, children = 'employees', label = 'name', menu = Menu( NewAction, Separator(), DeleteAction, Separator(), RenameAction, Separator(), CopyAction, CutAction, PasteAction ), view = View( [ 'name', '|<' ] ), add = [ Employee ] ), TreeNode( node_for = [ Employee ], auto_open = True, label = 'name', menu = Menu( NewAction, Separator(), Action( name = 'Default title', action = 'object.default_title' ), Action( name = 'Department', action = 'handler.employee_department(editor,object)' ), Separator(), CopyAction, CutAction, PasteAction, Separator(), DeleteAction, Separator(), RenameAction ), view = View( [ 'name', 'title', 'phone', '|<' ] ) ) ] ) #------------------------------------------------------------------------------- # 'TreeHandler' class: #------------------------------------------------------------------------------- class TreeHandler ( Handler ): def employee_department ( self, editor, object ): dept = editor.get_parent( object ) print '%s works in the %s department.' % ( object.name, dept.name ) #------------------------------------------------------------------------------- # Define the View to use: #------------------------------------------------------------------------------- view = View( Group( [ Item( 'company', editor = tree_editor, resizable = True ), '|<>' ], Group( [ '{Employee of the Month}@', Item( 'eom@', editor = InstanceEditor( values = [ InstanceDropChoice( klass = Employee, selectable = True ) ] ), resizable = True ), '|<>' ], [ '{Department of the Month}@', Item( 'dom@', editor = InstanceEditor( values = [ InstanceDropChoice( klass = Department ) ] ), resizable = True ), '|<>' ], show_labels = False, layout = 'split' ), orientation = 'horizontal', show_labels = False, layout = 'split' ), title = 'Company Structure', handler = TreeHandler(), buttons = [ 'OK', 'Cancel' ], resizable = True, width = .5, height = .5 ) #------------------------------------------------------------------------------- # Edit it: #------------------------------------------------------------------------------- if __name__ == '__main__': partner.configure_traits( view = view ) traits-4.1.0/integrationtests/ui/code_editor_test.py0000644000175100001440000000545111674463323023735 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # Test using a KeyBindings object with the traits Codeditor # # Written by: David C. Morrill # # Date: 09/22/2005 # # (c) Copyright 2005 by Enthought, Inc. # License: BSD Style. # #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from traits.api \ import HasPrivateTraits, Code, Str from traitsui.api \ import View, Item, Handler, CodeEditor from traitsui.key_bindings \ import KeyBinding, KeyBindings #------------------------------------------------------------------------------- # Define a KeyBindings object: #------------------------------------------------------------------------------- key_bindings = KeyBindings( KeyBinding( binding1 = 'Ctrl-s', description = 'Save to a file', method_name = 'save_file' ), KeyBinding( binding1 = 'Ctrl-r', description = 'Run script', method_name = 'run_script' ), KeyBinding( binding1 = 'Ctrl-q', description = 'Edit key bindings', method_name = 'edit_bindings' ) ) #------------------------------------------------------------------------------- # 'CodeHandler' class: #------------------------------------------------------------------------------- class CodeHandler ( Handler ): def save_file ( self, info ): info.object.status = "save file" def run_script ( self, info ): info.object.status = "run script" def edit_bindings ( self, info ): info.object.status = "edit bindings" key_bindings.edit_traits() #------------------------------------------------------------------------------- # 'TestCode' class: #------------------------------------------------------------------------------- class TestCode ( HasPrivateTraits ): code = Code status = Str view = View( [ Item( 'code', style = 'custom', resizable = True, editor = CodeEditor( key_bindings = key_bindings ) ), 'status~', '|<>' ], id = 'traitsui.tests.test_code_editor.TestCode', title = 'Sample Code Editor', width = 0.4, height = 0.4, resizable = True, handler = CodeHandler() ) #------------------------------------------------------------------------------- # Run the test: #------------------------------------------------------------------------------- if __name__ == '__main__': TestCode().configure_traits() traits-4.1.0/integrationtests/ui/check_list_editor_test2.py0000644000175100001440000000471111674463323025213 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # CheckListEditor test case for Traits UI # # Written by: David C. Morrill # # Date: 06/29/2005 # # (c) Copyright 2005 by Enthought, Inc. # License: BSD Style. # #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from traits.api \ import Enum, List, Str from traitsui.api \ import Handler, View, Item, CheckListEditor #------------------------------------------------------------------------------- # 'CheckListTest' class: #------------------------------------------------------------------------------- class CheckListTest ( Handler ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- value = List( editor = CheckListEditor( name = 'values', cols = 5 ) ) values = List( Str ) values_text = Str( 'red orange yellow green blue indigo violet' ) #--------------------------------------------------------------------------- # Traits view definitions: #--------------------------------------------------------------------------- simple_view = View( 'value', 'values_text@' ) custom_view = View( 'value@', 'values_text@' ) #--------------------------------------------------------------------------- # 'Initializes the object: #--------------------------------------------------------------------------- def __init__ ( self, **traits ): super( CheckListTest, self ).__init__( **traits ) self._values_text_changed() #--------------------------------------------------------------------------- # Event handlers: #--------------------------------------------------------------------------- def _values_text_changed ( self ): self.values = self.values_text.split() #------------------------------------------------------------------------------- # Run the tests: #------------------------------------------------------------------------------- if __name__ == '__main__': clt = CheckListTest() clt.configure_traits( view = 'simple_view' ) print 'value:', clt.value clt.configure_traits( view = 'custom_view' ) print 'value:', clt.value traits-4.1.0/integrationtests/ui/tree_editor_test.py0000644000175100001440000001747011674463323023766 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # Copyright (c) 2005, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # Thanks for using Enthought open source! # # Author: David C. Morrill # Date: 12/04/2004 # Description: Test case for the traits tree editor. #------------------------------------------------------------------------------ #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from traits.api import HasTraits, Str, Regex, List, Instance from traitsui.api import TreeEditor, TreeNode, View, Item, VSplit, \ HGroup, Handler from traitsui.menu import Menu, Action, Separator from traitsui.wx.tree_editor import NewAction, CopyAction, \ CutAction, PasteAction, DeleteAction, RenameAction #------------------------------------------------------------------------------- # 'Employee' class: #------------------------------------------------------------------------------- class Employee ( HasTraits ): name = Str( '' ) title = Str phone = Regex( regex = r'\d\d\d-\d\d\d\d' ) def default_title ( self ): self.title = 'Senior Engineer' #------------------------------------------------------------------------------- # 'Department' class: #------------------------------------------------------------------------------- class Department ( HasTraits ): name = Str( '' ) employees = List( Employee ) #------------------------------------------------------------------------------- # 'Company' class: #------------------------------------------------------------------------------- class Company ( HasTraits ): name = Str( '' ) departments = List( Department ) employees = List( Employee ) #------------------------------------------------------------------------------- # 'Partner' class: #------------------------------------------------------------------------------- class Partner ( HasTraits ): name = Str( '' ) company = Instance( Company ) #------------------------------------------------------------------------------- # Create a hierarchy: #------------------------------------------------------------------------------- jason = Employee( name = 'Jason', title = 'Sr. Engineer', phone = '536-1057' ) mike = Employee( name = 'Mike', title = 'Sr. Engineer', phone = '536-1057' ) dave = Employee( name = 'Dave', title = 'Sr. Engineer', phone = '536-1057' ) martin = Employee( name = 'Martin', title = 'Sr. Engineer', phone = '536-1057' ) duncan = Employee( name = 'Duncan', title = 'Sr. Engineer' ) partner = Partner( name = 'eric', company = Company( name = 'Enthought, Inc.', departments = [ Department( name = 'Business', employees = [ jason, mike ] ), Department( name = 'Scientific', employees = [ dave, martin, duncan ] ) ], employees = [ dave, martin, mike, duncan, jason ] ) ) #------------------------------------------------------------------------------- # Define the tree trait editor: #------------------------------------------------------------------------------- no_view = View() tree_editor = TreeEditor( nodes = [ TreeNode( node_for = [ Company ], auto_open = True, children = '', label = 'name', view = View( [ 'name', '|<' ] ) ), TreeNode( node_for = [ Company ], auto_open = True, children = 'departments', label = '=Departments', view = no_view, add = [ Department ] ), TreeNode( node_for = [ Company ], auto_open = True, children = 'employees', label = '=Employees', view = no_view, add = [ Employee ] ), TreeNode( node_for = [ Department ], auto_open = True, children = 'employees', label = 'name', menu = Menu( NewAction, Separator(), DeleteAction, Separator(), RenameAction, Separator(), CopyAction, CutAction, PasteAction ), view = View( [ 'name', '|<' ] ), add = [ Employee ] ), TreeNode( node_for = [ Employee ], auto_open = True, label = 'name', menu = Menu( NewAction, Separator(), Action( name = 'Default title', action = 'object.default_title' ), Action( name = 'Department', action = 'handler.employee_department(editor,object)' ), Separator(), CopyAction, CutAction, PasteAction, Separator(), DeleteAction, Separator(), RenameAction ), view = View( VSplit( HGroup( '3', 'name' ), HGroup( '9', 'title' ), HGroup( 'phone' ), id = 'vsplit' ), id = 'traitsui.test.tree_editor_test.employee', dock = 'vertical' ) ) ] ) #------------------------------------------------------------------------------- # 'TreeHandler' class: #------------------------------------------------------------------------------- class TreeHandler ( Handler ): def employee_department ( self, editor, object ): dept = editor.get_parent( object ) print '%s works in the %s department.' % ( object.name, dept.name ) #------------------------------------------------------------------------------- # Define the View to use: #------------------------------------------------------------------------------- view = View( [ Item( name = 'company', id = 'company', editor = tree_editor, resizable = True ), '|<>' ], title = 'Company Structure', id = 'traitsui.tests.tree_editor_test', dock = 'horizontal', drop_class = HasTraits, handler = TreeHandler(), buttons = [ 'Undo', 'OK', 'Cancel' ], resizable = True, width = .3, height = .3 ) #------------------------------------------------------------------------------- # Edit it: #------------------------------------------------------------------------------- if __name__ == '__main__': partner.configure_traits( view = view ) traits-4.1.0/integrationtests/ui/enum_dynamic_test.py0000644000175100001440000000116411674463323024122 0ustar ischnellusers00000000000000# Copyright (c) 2007, Enthought, Inc. # License: BSD Style. from traits.api import * from traitsui.api import * def evaluate_value(v): print 'evaluate_value', v return str(v) class Team ( HasTraits ): captain = Str( 'Dick' ) players = List( [ 'Tom', 'Dick', 'Harry', 'Sally' ], Str ) captain_editor = EnumEditor( name = 'players', evaluate=evaluate_value ) view = View( Item( 'captain', editor = captain_editor), '_', 'players@', height=200 ) if __name__ == '__main__': team = Team() team.configure_traits() team.print_traits() traits-4.1.0/integrationtests/ui/set_dynamic_test.py0000644000175100001440000000106111674463323023745 0ustar ischnellusers00000000000000# Copyright (c) 2007, Enthought, Inc. # License: BSD Style. from traits.api import * from traitsui.api import * class Team ( HasTraits ): batting_order = List( Str ) roster = List( [ 'Tom', 'Dick', 'Harry', 'Sally' ], Str ) view = View( Item( 'batting_order', editor = SetEditor( name = 'roster', ordered = True ) ), '_', 'roster@', height=500, resizable=True) if __name__ == '__main__': Team().configure_traits() traits-4.1.0/integrationtests/ui/table_list_editor_test.py0000644000175100001440000000613511674463323025145 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # TableEditor test case for Traits UI which tests editing of lists instead of # editing of objects. # # Written by: David C. Morrill # # Date: 07/06/2005 # # (c) Copyright 2005 by Enthought, Inc. # Copyright (c) 2007, Enthought, Inc. # License: BSD Style. # #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from traits.api \ import HasStrictTraits, List from traitsui.api \ import View, Item, TableEditor from traitsui.table_column \ import ListColumn from traitsui.table_filter \ import TableFilter #------------------------------------------------------------------------------- # Sample data: #------------------------------------------------------------------------------- people = [ [ 'Dave', 39, '555-1212' ], [ 'Mike', 28, '555-3526' ], [ 'Joe', 34, '555-6943' ], [ 'Tom', 22, '555-7586' ], [ 'Dick', 63, '555-3895' ], [ 'Harry', 46, '555-3285' ], [ 'Sally', 43, '555-8797' ], [ 'Fields', 31, '555-3547' ] ] #------------------------------------------------------------------------------- # Table editor definition: #------------------------------------------------------------------------------- table_editor = TableEditor( columns = [ ListColumn( index = 0, label = 'Name' ), ListColumn( index = 1, label = 'Age' ), ListColumn( index = 2, label = 'Phone' ) ], editable = False, show_column_labels = True, # ) #------------------------------------------------------------------------------- # 'TableTest' class: #------------------------------------------------------------------------------- class TableTest ( HasStrictTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- people = List #--------------------------------------------------------------------------- # Traits view definitions: #--------------------------------------------------------------------------- traits_view = View( [ Item( 'people', editor = table_editor, resizable = True ), '|[]<>' ], title = 'Table Editor Test', width = .17, height = .23, buttons = [ 'OK', 'Cancel' ], kind = 'live' ) #------------------------------------------------------------------------------- # Run the tests: #------------------------------------------------------------------------------- if __name__ == '__main__': tt = TableTest( people = people ) tt.configure_traits() for p in tt.people: print p print '--------------' traits-4.1.0/integrationtests/ui/instance_editor_test5.py0000644000175100001440000000644711674463323024722 0ustar ischnellusers00000000000000# Copyright (c) 2007, Enthought, Inc. # License: BSD Style. from traits.api import * from traitsui.api import * from traitsui.instance_choice \ import InstanceChoice, InstanceFactoryChoice #------------------------------------------------------------------------------- # 'Person' class: #------------------------------------------------------------------------------- class Person ( HasStrictTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- name = Str age = Int phone = Regex( value = '000-0000', regex = '\d\d\d[-]\d\d\d\d' ) #--------------------------------------------------------------------------- # Traits view definition: #--------------------------------------------------------------------------- traits_view = View( 'name~', 'age~', 'phone~' ) edit_view = View( 'name', 'age', 'phone' ) #------------------------------------------------------------------------------- # Sample data: #------------------------------------------------------------------------------- people = [ Person( name = 'Dave', age = 39, phone = '555-1212' ), Person( name = 'Mike', age = 28, phone = '555-3526' ), Person( name = 'Joe', age = 34, phone = '555-6943' ), Person( name = 'Tom', age = 22, phone = '555-7586' ), Person( name = 'Dick', age = 63, phone = '555-3895' ), Person( name = 'Harry', age = 46, phone = '555-3285' ), Person( name = 'Sally', age = 43, phone = '555-8797' ), Person( name = 'Fields', age = 31, phone = '555-3547' ) ] #------------------------------------------------------------------------------- # 'Team' class: #------------------------------------------------------------------------------- class Team ( HasStrictTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- name = Str captain = Instance( Person ) roster = List( Person ) #--------------------------------------------------------------------------- # Traits view definitions: #--------------------------------------------------------------------------- traits_view = View( [ [ 'name', '_', Item( 'captain@', editor = InstanceEditor( name = 'roster', editable = False, values = [ InstanceFactoryChoice( klass = Person, name = 'Non player', view = 'edit_view' ) ] ) ), '_' ], [ 'captain@', '|<>' ] ] ) #------------------------------------------------------------------------------- # Run the test: #------------------------------------------------------------------------------- if __name__ == '__main__': Team( name = 'Vultures', captain = people[0], roster = people ).configure_traits() traits-4.1.0/integrationtests/ui/numeric_editor_test.py0000644000175100001440000001135511674463323024465 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # NumericEditor test case for Traits UI # # Written by: David C. Morrill # # Date: 11/29/2005 # # (c) Copyright 2005 by Enthought, Inc. # License: BSD Style. # #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from traits.api \ import HasPrivateTraits, Array, Instance from traitsui.api \ import View, Item, HGroup from traitsui.table_column \ import NumericColumn from traitsui.wx.numeric_editor \ import ToolkitEditorFactory as NumericEditor from blockcanvas.model.api \ import ANumericModel, NumericArrayModel, ReductionModel, SelectionModel, \ NumericItem, ExpressionFilter, IndexFilter from numpy \ import array, sin, arange #------------------------------------------------------------------------------- # Defines the numeric editor: #------------------------------------------------------------------------------- number_editor = NumericEditor( extendable = True, new_columns = 'last', configurable = True, columns = [ NumericColumn( name = 'model_indices', label = 'i' ), NumericColumn( name = 'x', label = 'x', format = '%.2f' ), NumericColumn( name = 'sinx', label = 'sin(x)', format = '%.3f' ), NumericColumn( name = 'xsinx', label = 'x*sin(x)', format = '%.3f' ) ], other_columns = [], choose_selection_filter = True, edit_selection_filter = True, edit_selection_colors = False, selection_filter = None, selection_filter_name = '', user_selection_filter = IndexFilter(), choose_reduction_filter = True, edit_reduction_filter = True, reduction_filter = None, reduction_filter_name = '', deletable = True, sortable = True, sort_model = False, editable = True, auto_size = False, show_lines = True, menu = None, show_column_labels = True, #line_color = 0xC4C0A9, #cell_font = Font, #cell_color = Color( 'black' ) #cell_bg_color = Color( 'white' ) #cell_read_only_bg_color = Color( 0xF8F7F1 ) #label_font = Font #label_color = Color( 'black' ) #label_bg_color = Color( 0xD7D2BF ) #selection_bg_color = Color( 0x0D22DF ) #selection_color = Color( 'white' ) #column_label_height = Int( 25 ) #row_label_width = Int( 82 ) #on_select = Callable #on_dclick = Callable ) #------------------------------------------------------------------------------- # 'BunchANumbersApp' class: #------------------------------------------------------------------------------- class BunchANumbersApp ( HasPrivateTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- model = Instance( ANumericModel ) #--------------------------------------------------------------------------- # Traits view definitions: #--------------------------------------------------------------------------- view = View( HGroup( Item( 'model', editor = number_editor, id = 'model' ), # Item( 'model', editor = number_editor ), show_labels = False ), title = 'Numeric Editor Test', id = 'traitsui.tests.numeric_editor_test', width = 0.28, height = 0.6, resizable = True ) #------------------------------------------------------------------------------- # Run the test: #------------------------------------------------------------------------------- if __name__ == '__main__': x = arange( 0.0, 20.005, 0.1 ) model = NumericArrayModel( x = x, sinx = sin( x ), xsinx = x * sin( x ) ) BunchANumbersApp( model = model ).configure_traits() traits-4.1.0/integrationtests/ui/table_editor_test2.py0000644000175100001440000001003211674463323024163 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # TableEditor test case for Traits UI # # Written by: David C. Morrill # # Date: 07/05/2005 # # (c) Copyright 2005 by Enthought, Inc. # License: BSD Style. # #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from traits.api \ import HasStrictTraits, Str, Int, Regex, List from traitsui.api \ import View #------------------------------------------------------------------------------- # 'Person' class: #------------------------------------------------------------------------------- class Person ( HasStrictTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- name = Str age = Int phone = Regex( value = '000-0000', regex = '\d\d\d[-]\d\d\d\d' ) #--------------------------------------------------------------------------- # Traits view definition: #--------------------------------------------------------------------------- traits_view = View( 'name', 'age', 'phone', title = 'Create new person', width = 0.18, buttons = [ 'OK', 'Cancel' ] ) #------------------------------------------------------------------------------- # 'WorkingPerson' class #------------------------------------------------------------------------------- class WorkingPerson ( Person ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- job = Str #--------------------------------------------------------------------------- # Traits view definition: #--------------------------------------------------------------------------- traits_view = View( 'name', 'age', 'phone', 'job', title = 'Create new working person.........', width = 0.18, buttons = [ 'OK', 'Cancel' ] ) #------------------------------------------------------------------------------- # Sample data: #------------------------------------------------------------------------------- people = [ Person( name = 'Dave', age = 39, phone = '555-1212' ), Person( name = 'Mike', age = 28, phone = '555-3526' ), WorkingPerson( name = 'Joe', age = 34, phone = '555-6943', job = 'Fireman' ), Person( name = 'Tom', age = 22, phone = '555-7586' ), Person( name = 'Dick', age = 63, phone = '555-3895' ), Person( name = 'Harry', age = 46, phone = '555-3285' ), WorkingPerson( name = 'Sally', age = 43, phone = '555-8797', job = 'Soldier' ), Person( name = 'Fields', age = 31, phone = '555-3547' ) ] #------------------------------------------------------------------------------- # 'TableTest' class: #------------------------------------------------------------------------------- class TableTest ( HasStrictTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- people = List( Person ) #--------------------------------------------------------------------------- # Traits view definitions: #--------------------------------------------------------------------------- traits_view = View( [ 'people#', '|<>' ], resizable = True ) #------------------------------------------------------------------------------- # Run the tests: #------------------------------------------------------------------------------- if __name__ == '__main__': tt = TableTest( people = people ) tt.configure_traits() for p in tt.people: p.print_traits() print '--------------' traits-4.1.0/integrationtests/ui/instance_editor_test2.py0000644000175100001440000000574711674463323024721 0ustar ischnellusers00000000000000# Copyright (c) 2007, Enthought, Inc. # License: BSD Style. from traits.api import * from traitsui.api import * from traitsui.instance_choice \ import InstanceChoice, InstanceFactoryChoice #------------------------------------------------------------------------------- # 'Person' class: #------------------------------------------------------------------------------- class Person ( HasStrictTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- name = Str age = Int phone = Regex( value = '000-0000', regex = '\d\d\d[-]\d\d\d\d' ) #--------------------------------------------------------------------------- # Traits view definition: #--------------------------------------------------------------------------- traits_view = View( 'name', 'age', 'phone' ) #------------------------------------------------------------------------------- # Sample data: #------------------------------------------------------------------------------- people = [ Person( name = 'Dave', age = 39, phone = '555-1212' ), Person( name = 'Mike', age = 28, phone = '555-3526' ), Person( name = 'Joe', age = 34, phone = '555-6943' ), Person( name = 'Tom', age = 22, phone = '555-7586' ), Person( name = 'Dick', age = 63, phone = '555-3895' ), Person( name = 'Harry', age = 46, phone = '555-3285' ), Person( name = 'Sally', age = 43, phone = '555-8797' ), Person( name = 'Fields', age = 31, phone = '555-3547' ) ] #------------------------------------------------------------------------------- # 'Team' class: #------------------------------------------------------------------------------- class Team ( HasStrictTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- name = Str captain = Instance( Person ) roster = List( Person ) #--------------------------------------------------------------------------- # Traits view definitions: #--------------------------------------------------------------------------- traits_view = View( 'name', '_', Item( 'captain@', editor = InstanceEditor( name = 'roster', values = [ InstanceFactoryChoice( klass = Person, name = 'Non player' ) ] ) ) ) #------------------------------------------------------------------------------- # Run the test: #------------------------------------------------------------------------------- if __name__ == '__main__': Team( name = 'Vultures', captain = people[0], roster = people ).configure_traits() traits-4.1.0/integrationtests/ui/instance_editor_test4.py0000644000175100001440000000546011674463323024713 0ustar ischnellusers00000000000000# Copyright (c) 2007, Enthought, Inc. # License: BSD Style. from traits.api import * from traitsui.api import * from traitsui.instance_choice import InstanceChoice #------------------------------------------------------------------------------- # 'Person' class: #------------------------------------------------------------------------------- class Person ( HasStrictTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- name = Str age = Int phone = Regex( value = '000-0000', regex = '\d\d\d[-]\d\d\d\d' ) #--------------------------------------------------------------------------- # Traits view definition: #--------------------------------------------------------------------------- traits_view = View( 'name', 'age', 'phone' ) #------------------------------------------------------------------------------- # Sample data: #------------------------------------------------------------------------------- people = [ Person( name = 'Dave', age = 39, phone = '555-1212' ), Person( name = 'Mike', age = 28, phone = '555-3526' ), Person( name = 'Joe', age = 34, phone = '555-6943' ), Person( name = 'Tom', age = 22, phone = '555-7586' ), Person( name = 'Dick', age = 63, phone = '555-3895' ), Person( name = 'Harry', age = 46, phone = '555-3285' ), Person( name = 'Sally', age = 43, phone = '555-8797' ), Person( name = 'Fields', age = 31, phone = '555-3547' ) ] #------------------------------------------------------------------------------- # 'Team' class: #------------------------------------------------------------------------------- class Team ( HasStrictTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- name = Str captain = Instance( Person ) roster = List( Person ) #--------------------------------------------------------------------------- # Traits view definitions: #--------------------------------------------------------------------------- traits_view = View( 'name', '_', Item( 'captain@', editor = InstanceEditor( name = 'roster', editable = False ) ), '_', 'roster' ) #------------------------------------------------------------------------------- # Run the test: #------------------------------------------------------------------------------- if __name__ == '__main__': Team( name = 'Vultures', captain = people[0], roster = people ).configure_traits() traits-4.1.0/integrationtests/ui/test_ui3.py0000644000175100001440000000570211674463323022154 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # Copyright (c) 2005, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # Thanks for using Enthought open source! # # Author: David C. Morrill # Date: 11/02/2004 # Description: Test case for Traits User Interface #------------------------------------------------------------------------------ #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- import wx from traits.api import Trait, HasTraits, Str, Int from traitsui.api import View, Group from traits.api import Color #------------------------------------------------------------------------------- # Model/View classes: #------------------------------------------------------------------------------- class Employer ( HasTraits ): company = Str boss = Str view = View( 'company', 'boss' ) class Person ( HasTraits ): name = Str( 'David Morrill' ) age = Int( 39 ) view = View( 'name', '', 'age', kind = 'modal' ) class ExtraPerson ( Person ): sex = Trait( 'Male', 'Female' ) eye_color = Color extra = Group( 'sex', 'eye_color' ) class LocatedPerson ( Person ): street = Str city = Str state = Str zip = Int( 78663 ) extra = Group( 'street', 'city', 'state', 'zip' ) class EmployedPerson ( LocatedPerson ): employer = Trait( Employer( company = 'Enthought, Inc.', boss = 'eric' ) ) extra = Group( 'employer', '' ) #------------------------------------------------------------------------------- # 'TraitSheetApp' class: #------------------------------------------------------------------------------- class TraitSheetApp ( wx.App ): #--------------------------------------------------------------------------- # Initialize the object: #--------------------------------------------------------------------------- def __init__ ( self ): wx.InitAllImageHandlers() wx.App.__init__( self, 1, 'debug.log' ) self.MainLoop() #--------------------------------------------------------------------------- # Handle application initialization: #--------------------------------------------------------------------------- def OnInit ( self ): Person().edit_traits() ExtraPerson().edit_traits() LocatedPerson().edit_traits() EmployedPerson().edit_traits() return True #------------------------------------------------------------------------------- # Main program: #------------------------------------------------------------------------------- TraitSheetApp() traits-4.1.0/integrationtests/ui/buttons_test.py0000644000175100001440000000663211674463323023155 0ustar ischnellusers00000000000000# Copyright (c) 2007, Enthought, Inc. # License: BSD Style. from traits.api \ import * from traitsui.api \ import * from traitsui.menu \ import * #------------------------------------------------------------------------------- # 'Person' class: #------------------------------------------------------------------------------- class Person ( Handler ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- name = Str age = Int phone = Regex( value = '000-0000', regex = '\d\d\d[-]\d\d\d\d' ) notes = Str #--------------------------------------------------------------------------- # Handles the 'Annoy' button being clicked: #--------------------------------------------------------------------------- def _annoy_clicked ( self, info ): self.edit_traits( view = View( title = 'Annoying', kind = 'modal', buttons = [ 'OK' ] ) ) #------------------------------------------------------------------------------- # Run the tests: #------------------------------------------------------------------------------- if __name__ == '__main__': AnnoyButton = Action( name = 'Annoy', tooltip = 'Click me to be annoyed', enabled_when = 'age >= 40' ) person = Person( name = 'Bill', age = 42, phone = '555-1212' ) fields = Group( 'name', 'age', 'phone', 'notes~' ) person.notes = ("Should have 6 standard 'live' buttons: Undo, Redo, " "Revert, OK, Cancel, Help") person.configure_traits( view = View( fields, kind = 'livemodal', buttons = LiveButtons ) ) person.notes = ("Should have 5 standard 'modal' buttons: Apply, Revert, " "OK, Cancel, Help") person.configure_traits( view = View( fields, buttons = ModalButtons ) ) person.notes = "Should have 2 standard buttons: OK, Cancel" person.configure_traits( view = View( fields, buttons = [ OKButton, CancelButton ] ) ) person.notes = "Should have 1 standard button: OK (enabled when age >= 40)" person.configure_traits( view = View( fields, buttons = [ Action( name = 'OK', enabled_when = 'age >= 40' ) ] ) ) person.notes = "Should have 1 standard button: OK (visible when age >= 40)" person.configure_traits( view = View( fields, buttons = [ Action( name = 'OK', visible_when = 'age >= 40' ) ] ) ) person.notes = ("Should have 2 standard buttons: OK, Help (defined when " "age >= 50)") person.configure_traits( view = View( fields, buttons = [ 'OK', Action( name = 'Help', defined_when = 'age >= 50' ) ] ) ) person.notes = ("Should have 1 user and 5 standard buttons: Annoy (enabled " "when age >= 40), Apply, Revert, OK, Cancel, Help") person.configure_traits( view = View( fields, buttons = [ AnnoyButton ] + ModalButtons ) ) traits-4.1.0/integrationtests/ui/test_ui2.py0000644000175100001440000001675511674463323022165 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # Copyright (c) 2005, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # Thanks for using Enthought open source! # # Author: David C. Morrill Date: 11/02/2004 Description: Test case for Traits # User Interface # ------------------------------------------------------------------------------ #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- import wx from kiva.traits.kiva_font_trait \ import KivaFont from enable.traits.api \ import RGBAColor from traits.api \ import Trait, HasTraits, Str, Int, Range, List, Event, Bool from traitsui.api \ import View, Handler, Item, CheckListEditor, ButtonEditor, FileEditor, \ DirectoryEditor, ImageEnumEditor #------------------------------------------------------------------------------- # Constants: #------------------------------------------------------------------------------- origin_values = [ 'top left', 'top right', 'bottom left', 'bottom right' ] #------------------------------------------------------------------------------- # 'PersonHandler' class: #------------------------------------------------------------------------------- class PersonHandler ( Handler ): def object_zip_changed ( self, info ): obj = info.object enabled = (obj.zip >= 10000) info.street.enabled = enabled info.city.enabled = enabled info.state.enabled = enabled if obj.zip == 78664: obj.street = '901 Morning View Place' obj.city = 'Round Rock' obj.state = 'Texas' def object_call_changed ( self, info ): print 'You called?' #------------------------------------------------------------------------------- # 'WizardHandler' class: #------------------------------------------------------------------------------- class WizardHandler ( Handler ): def object_sex_changed ( self, info ): if info.object.sex == 'Female': info.p1.next = 'p3' else: info.p1.next = 'p2' info.p2.next = None def object_name_changed ( self, info ): info.p2.enabled = info.p3.enabled = (info.object.name != '') if not info.p2.enabled: info.p2.msg = info.p3.msg = 'You must enter a valid name.' #------------------------------------------------------------------------------- # 'Employer' class: #------------------------------------------------------------------------------- class Employer ( HasTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- company = Str boss = Str view = View( 'company', 'boss' ) #------------------------------------------------------------------------------- # 'Person' class #------------------------------------------------------------------------------- class Person ( HasTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- name = Str( 'David Morrill' ) age = Int( 39 ) sex = Trait( 'Male', 'Female' ) coolness = Range( 0.0, 10.0, 10.0 ) number = Trait( 1, Range( 1, 6 ), 'one', 'two', 'three', 'four', 'five', 'six' ) human = Bool( True ) employer = Trait( Employer( company = 'Enthought, Inc.', boss = 'eric' ) ) eye_color = RGBAColor set = List( editor = CheckListEditor( values = [ 'one', 'two', 'three', 'four' ], cols = 4 ) ) font = KivaFont street = Str city = Str state = Str zip = Int( 78663 ) password = Str books = List( Str, [ 'East of Eden', 'The Grapes of Wrath', 'Of Mice and Men' ] ) call = Event( 0, editor = ButtonEditor( label = 'Click to call' ) ) info = Str( editor = FileEditor() ) location = Str( editor = DirectoryEditor() ) origin = Trait( editor = ImageEnumEditor( values = origin_values, suffix = '_origin', cols = 4, klass = Employer ), *origin_values ) nm = Item( 'name', enabled_when = 'object.age >= 21' ) pw = Item( 'password', defined_when = 'object.zip == 78664' ) view = View( ( ( nm, 'age', 'coolness', '_', 'eye_color', 'eye_color@', 'eye_color*', 'eye_color~', '_', 'font', 'font@', 'font*', 'font~', '_', 'set', 'set@', 'set*', 'set~', '_', 'sex', 'sex@', 'sex*', 'sex~', '_', 'human', 'human@', 'human*', 'human~', '_', 'number', 'number@', 'number*', 'number~', '_', 'books', '_', 'books@', '_', 'books*', '_', 'books~', '_', 'info', 'location', 'origin', 'origin@', 'call', 'employer', 'employer[]@', 'employer*', 'employer~', pw, '|<[Person:]' ), ( ' ', 'street', 'city', 'state', 'zip', '|<[Address:]' ), ( nm, nm, nm, nm, nm, nm, nm, nm, nm, nm, nm, nm, nm, nm, '|<[Names:]' ), '|' ), title = 'Traits 2 User Interface Test', handler = PersonHandler(), buttons = [ 'Apply', 'Revert', 'Undo', 'OK' ], height = 0.5 ) wizard = View( ( '|p1:', 'name', 'age', 'sex' ), ( '|p2:', 'street', 'city', 'state', 'zip' ), ( '|p3:', 'eye_color', 'origin', 'human' ), handler = WizardHandler() ) #------------------------------------------------------------------------------- # 'TraitSheetApp' class: #------------------------------------------------------------------------------- class TraitSheetApp ( wx.App ): #--------------------------------------------------------------------------- # Initialize the object: #--------------------------------------------------------------------------- def __init__ ( self, object ): self.object = object wx.InitAllImageHandlers() wx.App.__init__( self, 1, 'debug.log' ) self.MainLoop() object.print_traits() #--------------------------------------------------------------------------- # Handle application initialization: #--------------------------------------------------------------------------- def OnInit ( self ): #ui = self.object.edit_traits( 'view', kind = 'live' ) ui = self.object.edit_traits( 'wizard', kind = 'wizard' ) self.SetTopWindow( ui.control ) return True #------------------------------------------------------------------------------- # Main program: #------------------------------------------------------------------------------- TraitSheetApp( Person() ) traits-4.1.0/integrationtests/ui/array_editor_test.py0000644000175100001440000000331611674463323024137 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # ArrayEditor test case # # Written by: David C. Morrill # # Date: 01/10/2006 # # (c) Copyright 2006 by Enthought, Inc. # License: BSD Style. # #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from traits.api \ import HasPrivateTraits, Array from traitsui.api \ import View, ArrayEditor #------------------------------------------------------------------------------- # 'Test' class: #------------------------------------------------------------------------------- class Test ( HasPrivateTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- three = Array( int, (3,3) ) four = Array( float, (4,4), editor = ArrayEditor( width = -50 ) ) #--------------------------------------------------------------------------- # Traits view definitions: #--------------------------------------------------------------------------- view = View( 'three', '_', 'three', '_', 'three~', '_', 'four', '_', 'four', '_', 'four~', title = 'ArrayEditor Test Case', resizable = True ) #------------------------------------------------------------------------------- # Run the test case: #------------------------------------------------------------------------------- if __name__ == '__main__': Test().configure_traits() traits-4.1.0/integrationtests/ui/check_list_editor_test.py0000644000175100001440000000447311674463323025136 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # CheckListEditor test case for Traits UI # # Written by: David C. Morrill # # Date: 06/29/2005 # # (c) Copyright 2005 by Enthought, Inc. # License: BSD Style. # #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from traits.api \ import Enum, List from traitsui.api \ import Handler, View, Item, CheckListEditor #------------------------------------------------------------------------------- # Constants: #------------------------------------------------------------------------------- colors = [ 'red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet' ] numbers = [ 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten' ] #------------------------------------------------------------------------------- # 'CheckListTest' class: #------------------------------------------------------------------------------- class CheckListTest ( Handler ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- case = Enum( 'Colors', 'Numbers' ) value = List( editor = CheckListEditor( values = colors, cols = 5 ) ) #--------------------------------------------------------------------------- # Event handlers: #--------------------------------------------------------------------------- def object_case_changed ( self, info ): if self.case == 'Colors': info.value.factory.values = colors else: info.value.factory.values = numbers #------------------------------------------------------------------------------- # Run the tests: #------------------------------------------------------------------------------- if __name__ == '__main__': clt = CheckListTest() clt.configure_traits( view = View( 'case', '_', Item( 'value', id = 'value' ) ) ) print 'value:', clt.value clt.configure_traits( view = View( 'case', '_', Item( 'value@', id = 'value' ) ) ) print 'value:', clt.value traits-4.1.0/integrationtests/ui/table_editor_focus_bug.py0000644000175100001440000000372711674463323025113 0ustar ischnellusers00000000000000# Copyright (c) 2007, Enthought, Inc. # License: BSD Style. from traits.api import HasTraits, Str, List from traitsui.api import Group, Item, TableEditor, View from traitsui.table_column \ import ObjectColumn class Word(HasTraits): word = Str class Foo(HasTraits): # arbitrary string containing spaces input = Str # input split on space parsed = List def _input_changed(self): words = self.input.split() for word in self.parsed[:]: if word.word in words: words.remove(word.word) else: self.parsed.remove(word) for word in words: self.parsed.append(Word(word=word)) return table_editor = TableEditor( columns = [ ObjectColumn( name='word') ], editable=True ) help = Str("""Type in the 'input' box before clicking the Parsed tab. The first non-whitespace character will cause changes to the parsed trait and therefore changes to the table rows. That is expected. BUG: the table grabs the focus from 'input' and thus subsequent typing goes into one of the table cells. If you click the 'Parsed' tab, to view the table, and then the 'Inputs' tab the focus will stay with the 'input' box. """) traits_view = View( Group( Item( 'help', style='readonly'), Item( 'input' ), label='Input'), Group( Item( 'parsed', editor=table_editor), label='Parsed' ), dock = 'tab', resizable=True, width=320, height=240 ) if __name__ == '__main__': # simple test of the model foo = Foo() foo.input = 'these words in the list' assert( [word.word for word in foo.parsed] == ['these', 'words', 'in', 'the', 'list'] ) foo.input = 'these dudes in the bar' assert( [word.word for word in foo.parsed] == ['these', 'in', 'the', 'dudes', 'bar'] ) foo.configure_traits( kind='modal' ) print foo.input, [word.word for word in foo.parsed] traits-4.1.0/integrationtests/ui/shell_editor_test.py0000644000175100001440000000324711674463323024133 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # Traits UI Python ShellEditor test. # # Written by: David C. Morrill # # Date: 10/13/2005 # # (c) Copyright 2005 by Enthought, Inc. # License: BSD Style. # #------------------------------------------------------------------------------- from traits.api import * from traitsui.api import * from traitsui.menu import * #------------------------------------------------------------------------------- # 'ShellTest' class: #------------------------------------------------------------------------------- class ShellTest ( HasPrivateTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- name = Str age = Int weight = Float shell_1 = Str shell_2 = Dict #--------------------------------------------------------------------------- # Traits view definitions: #--------------------------------------------------------------------------- view = View( 'name', 'age', 'weight', '_', Item( 'shell_1', editor = ShellEditor() ), Item( 'shell_2', editor = ShellEditor() ), id = 'traitsui.tests.shell_editor_test', resizable = True, width = 0.3, height = 0.3 ) #------------------------------------------------------------------------------- # Run the test: #------------------------------------------------------------------------------- if __name__ == '__main__': ShellTest().configure_traits() traits-4.1.0/integrationtests/ui/test_ui4.py0000644000175100001440000000655611674463323022165 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # Copyright (c) 2005, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # Thanks for using Enthought open source! # # Author: David C. Morrill # Date: 11/02/2004 # Description: Test case for Traits User Interface #------------------------------------------------------------------------------ #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- import wx from traits.api import Trait, HasTraits, Str, Int from traitsui.api import View, Group from traits.api import Color #------------------------------------------------------------------------------- # Model classes: #------------------------------------------------------------------------------- class Employer ( HasTraits ): company = Str( 'Enthought, Inc.' ) boss = Str( 'eric' ) view = View( 'company', 'boss' ) class Person ( HasTraits ): name = Str( 'David Morrill' ) age = Int( 39 ) class ExtraPerson ( Person ): sex = Trait( 'Male', 'Female' ) eye_color = Color class LocatedPerson ( Person ): street = Str city = Str state = Str zip = Int( 78663 ) class EmployedPerson ( LocatedPerson ): employer = Trait( Employer() ) #------------------------------------------------------------------------------- # View classes: #------------------------------------------------------------------------------- class PersonView ( HasTraits ): view = View( 'name', '', 'age', kind = 'modal' ) class ExtraPersonView ( PersonView ): extra = Group( 'sex', 'eye_color' ) class LocatedPersonView ( PersonView ): extra = Group( 'street', 'city', 'state', 'zip' ) class EmployedPersonView ( LocatedPersonView ): extra = Group( 'employer', '' ) #------------------------------------------------------------------------------- # 'TraitSheetApp' class: #------------------------------------------------------------------------------- class TraitSheetApp ( wx.App ): #--------------------------------------------------------------------------- # Initialize the object: #--------------------------------------------------------------------------- def __init__ ( self ): wx.InitAllImageHandlers() wx.App.__init__( self, 1, 'debug.log' ) self.MainLoop() #--------------------------------------------------------------------------- # Handle application initialization: #--------------------------------------------------------------------------- def OnInit ( self ): PersonView().edit_traits( context = Person() ) ExtraPersonView().edit_traits( context = ExtraPerson() ) LocatedPersonView().edit_traits( context = LocatedPerson() ) EmployedPersonView().edit_traits( context = EmployedPerson() ) return True #------------------------------------------------------------------------------- # Main program: #------------------------------------------------------------------------------- TraitSheetApp() traits-4.1.0/integrationtests/ui/test_ui5.py0000644000175100001440000002503111674463323022153 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # # Copyright (c) 2005, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # # Author: David C. Morrill # Date: 11/02/2004 # # ------------------------------------------------------------------------------ """ Traits Test case """ #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- import wx from traits.api \ import Trait, HasTraits, Str, Int, Range, List, Event, File, Directory, Bool from traitsui.api \ import View, Handler, Item, CheckListEditor, ButtonEditor, FileEditor, \ DirectoryEditor, ImageEnumEditor from traits.api \ import Color, Font #------------------------------------------------------------------------------- # Constants: #------------------------------------------------------------------------------- origin_values = [ 'top left', 'top right', 'bottom left', 'bottom right' ] #------------------------------------------------------------------------------- # 'Instance' class: #------------------------------------------------------------------------------- class Instance ( HasTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- integer_text = Int( 1 ) enumeration = Trait( 'one', 'two', 'three', 'four', 'five', 'six', cols = 3 ) float_range = Range( 0.0, 10.0, 10.0 ) int_range = Range( 1, 5 ) boolean = Bool( True ) view = View( 'integer_text', 'enumeration', 'float_range', 'int_range', 'boolean' ) #------------------------------------------------------------------------------- # 'TraitsTestHandler' class: #------------------------------------------------------------------------------- class TraitsTestHandler ( Handler ): def object_enabled_changed ( self, info ): enabled = info.object.enabled for i in range( 1, 63 ): getattr( info, 'f%d' % i ).enabled = enabled #------------------------------------------------------------------------------- # 'TraitsTest' class #------------------------------------------------------------------------------- class TraitsTest ( HasTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- enabled = Bool( True ) integer_text = Int( 1 ) enumeration = Trait( 'one', 'two', 'three', 'four', 'five', 'six', cols = 3 ) float_range = Range( 0.0, 10.0, 10.0 ) int_range = Range( 1, 6 ) int_range2 = Range( 1, 50 ) compound = Trait( 1, Range( 1, 6 ), 'one', 'two', 'three', 'four', 'five', 'six' ) boolean = Bool( True ) instance = Trait( Instance() ) color = Color( 'cyan' ) font = Font() check_list = List( editor = CheckListEditor( values = [ 'one', 'two', 'three', 'four' ], cols = 4 ) ) list = List( Str, [ 'East of Eden', 'The Grapes of Wrath', 'Of Mice and Men' ] ) button = Event( 0, editor = ButtonEditor( label = 'Click' ) ) file = File() directory = Directory() image_enum = Trait( editor = ImageEnumEditor( values = origin_values, suffix = '_origin', cols = 4, klass = Instance ), *origin_values ) #--------------------------------------------------------------------------- # View definitions: #--------------------------------------------------------------------------- view = View( ( '|{Enum}', ( 'enabled', ), ( '|<[Enumeration]', 'f1:enumeration[Simple]', '_', 'f2:enumeration[Custom]@', '_', 'f3:enumeration[Text]*', '_', 'f4:enumeration[Readonly]~' ), ( '|<[Check List]', 'f5:check_list[Simple]', '_', 'f6:check_list[Custom]@', '_', 'f7:check_list[Text]*', '_', 'f8:check_list[Readonly]~' ) ), ( '|{Range}', ( '|<[Float Range]', 'f9:float_range[Simple]', '_', 'f10:float_range[Custom]@', '_', 'f11:float_range[Text]*', '_', 'f12:float_range[Readonly]~' ), ( '|<[Int Range]', 'f13:int_range[Simple]', '_', 'f14:int_range[Custom]@', '_', 'f15:int_range[Text]*', '_', 'f16:int_range[Readonly]~' ), ( '|<[Int Range 2]', 'f17:int_range2[Simple]', '_', 'f18:int_range2[Custom]@', '_', 'f19:int_range2[Text]*', '_', 'f20:int_range2[Readonly]~' ) ), ( '|{Misc}', ( '|<[Integer Text]', 'f21:integer_text[Simple]', '_', 'f22:integer_text[Custom]@', '_', 'f23:integer_text[Text]*', '_', 'f24:integer_text[Readonly]~' ), ( '|<[Compound]', 'f25:compound[Simple]', '_', 'f26:compound[Custom]@', '_', 'f27:compound[Text]*', '_', 'f28:compound[Readonly]~' ), ( '|<[Boolean]', 'f29:boolean[Simple]', '_', 'f30:boolean[Custom]@', '_', 'f31:boolean[Text]*', '_', 'f32:boolean[Readonly]~' ) ), ( '|{Color/Font}', ( '|<[Color]', 'f33:color[Simple]', '_', 'f34:color[Custom]@', '_', 'f35:color[Text]*', '_', 'f36:color[Readonly]~' ), ( '|<[Font]', 'f37:font[Simple]', '_', 'f38:font[Custom]@', '_', 'f39:font[Text]*', '_', 'f40:font[Readonly]~' ) ), ( '|{List}', ( '|<[List]', 'f41:list[Simple]', '_', 'f42:list[Custom]@', '_', 'f43:list[Text]*', '_', 'f44:list[Readonly]~' ) ), ( '|{Button}', ( '|<[Button]', 'f45:button[Simple]', '_', 'f46:button[Custom]@' ), # 'button[Text]*', # 'button[Readonly]~' ), ( '|<[Image Enum]', 'f47:image_enum[Simple]', '_', 'f48:image_enum[Custom]@', '_', 'f49:image_enum[Text]*', '_', 'f50:image_enum[Readonly]~' ), ( '|<[Instance]', 'f51:instance[Simple]', '_', 'f52:instance[Custom]@', '_', 'f53:instance[Text]*', '_', 'f54:instance[Readonly]~' ), ), ( '|{File}', ( '|<[File]', 'f55:file[Simple]', '_', 'f56:file[Custom]@', '_', 'f57:file[Text]*', '_', 'f58:file[Readonly]~', ), ( '|<[Directory]', 'f59:directory[Simple]', '_', 'f60:directory[Custom]@', '_', 'f61:directory[Text]*', '_', 'f62:directory[Readonly]~' ) ), buttons = [ 'Apply', 'Revert', 'Undo', 'OK' ], handler = TraitsTestHandler() ) #------------------------------------------------------------------------------- # 'TraitSheetApp' class: #------------------------------------------------------------------------------- class TraitSheetApp ( wx.App ): #--------------------------------------------------------------------------- # Initialize the object: #--------------------------------------------------------------------------- def __init__ ( self, object ): self.object = object wx.InitAllImageHandlers() wx.App.__init__( self, 1, 'debug.log' ) self.MainLoop() #--------------------------------------------------------------------------- # Handle application initialization: #--------------------------------------------------------------------------- def OnInit ( self ): ui = self.object.edit_traits( kind = 'live' ) ui = self.object.edit_traits( kind = 'modal' ) ui = self.object.edit_traits( kind = 'nonmodal' ) ui = self.object.edit_traits( kind = 'wizard' ) self.SetTopWindow( ui.control ) return True #------------------------------------------------------------------------------- # Main program: #------------------------------------------------------------------------------- TraitSheetApp( TraitsTest() ) traits-4.1.0/integrationtests/ui/list_traits_ui_test.py0000644000175100001440000001143011674463323024505 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # TableEditor test case for Traits UI # # Written by: David C. Morrill # # Date: 11/11/2005 # # (c) Copyright 2005 by Enthought, Inc. # License: BSD Style. # #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from traits.api \ import HasStrictTraits, Str, Int, Regex, List, Instance from traitsui.api \ import View, Item, VSplit, TableEditor, ListEditor from traitsui.table_column \ import ObjectColumn from traitsui.table_filter \ import TableFilter, RuleTableFilter, RuleFilterTemplate, \ MenuFilterTemplate, EvalFilterTemplate #------------------------------------------------------------------------------- # 'Person' class: #------------------------------------------------------------------------------- class Person ( HasStrictTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- name = Str age = Int phone = Regex( value = '000-0000', regex = '\d\d\d[-]\d\d\d\d' ) #--------------------------------------------------------------------------- # Traits view definition: #--------------------------------------------------------------------------- traits_view = View( 'name', 'age', 'phone', width = 0.18, buttons = [ 'OK', 'Cancel' ] ) #------------------------------------------------------------------------------- # Sample data: #------------------------------------------------------------------------------- people = [ Person( name = 'Dave', age = 39, phone = '555-1212' ), Person( name = 'Mike', age = 28, phone = '555-3526' ), Person( name = 'Joe', age = 34, phone = '555-6943' ), Person( name = 'Tom', age = 22, phone = '555-7586' ), Person( name = 'Dick', age = 63, phone = '555-3895' ), Person( name = 'Harry', age = 46, phone = '555-3285' ), Person( name = 'Sally', age = 43, phone = '555-8797' ), Person( name = 'Fields', age = 31, phone = '555-3547' ) ] #------------------------------------------------------------------------------- # Table editor definition: #------------------------------------------------------------------------------- filters = [ EvalFilterTemplate, MenuFilterTemplate, RuleFilterTemplate ] table_editor = TableEditor( columns = [ ObjectColumn( name = 'name' ), ObjectColumn( name = 'age' ), ObjectColumn( name = 'phone' ) ], editable = True, deletable = True, sortable = True, sort_model = True, filters = filters, search = RuleTableFilter(), row_factory = Person ) #------------------------------------------------------------------------------- # 'ListTraitTest' class: #------------------------------------------------------------------------------- class ListTraitTest ( HasStrictTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- people = List( Person ) #--------------------------------------------------------------------------- # Traits view definitions: #--------------------------------------------------------------------------- traits_view = View( VSplit( Item( 'people', id = 'table', editor = table_editor ), Item( 'people@', id = 'list', editor = ListEditor( style = 'custom', rows = 5 ) ), Item( 'people@', id = 'notebook', editor = ListEditor( use_notebook = True, deletable = True, export = 'DockShellWindow', page_name = '.name' ) ), id = 'splitter', show_labels = False ), title = 'List Trait Editor Test', id = 'traitsui.tests.list_traits_ui_test', dock = 'horizontal', width = .4, height = .6, resizable = True, kind = 'live' ) #------------------------------------------------------------------------------- # Run the tests: #------------------------------------------------------------------------------- if __name__ == '__main__': ListTraitTest( people = people ).configure_traits() traits-4.1.0/integrationtests/ui/instance_editor_test3.py0000644000175100001440000000534311674463323024712 0ustar ischnellusers00000000000000# Copyright (c) 2007, Enthought, Inc. # License: BSD Style. from traits.api import * from traitsui.api import * from traitsui.instance_choice import InstanceChoice #------------------------------------------------------------------------------- # 'Person' class: #------------------------------------------------------------------------------- class Person ( HasStrictTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- name = Str age = Int phone = Regex( value = '000-0000', regex = '\d\d\d[-]\d\d\d\d' ) #--------------------------------------------------------------------------- # Traits view definition: #--------------------------------------------------------------------------- traits_view = View( 'name', 'age', 'phone' ) #------------------------------------------------------------------------------- # Sample data: #------------------------------------------------------------------------------- people = [ Person( name = 'Dave', age = 39, phone = '555-1212' ), Person( name = 'Mike', age = 28, phone = '555-3526' ), Person( name = 'Joe', age = 34, phone = '555-6943' ), Person( name = 'Tom', age = 22, phone = '555-7586' ), Person( name = 'Dick', age = 63, phone = '555-3895' ), Person( name = 'Harry', age = 46, phone = '555-3285' ), Person( name = 'Sally', age = 43, phone = '555-8797' ), Person( name = 'Fields', age = 31, phone = '555-3547' ) ] #------------------------------------------------------------------------------- # 'Team' class: #------------------------------------------------------------------------------- class Team ( HasStrictTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- name = Str captain = Instance( Person ) roster = List( Person ) #--------------------------------------------------------------------------- # Traits view definitions: #--------------------------------------------------------------------------- traits_view = View( 'name', '_', Item( 'captain@', editor = InstanceEditor( name = 'roster' ) ), '_', 'roster' ) #------------------------------------------------------------------------------- # Run the test: #------------------------------------------------------------------------------- if __name__ == '__main__': Team( name = 'Vultures', captain = people[0], roster = people ).configure_traits() traits-4.1.0/integrationtests/ui/enum_editor_test.py0000644000175100001440000000401611674463323023763 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # Copyright (c) 2005, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # Thanks for using Enthought open source! # # Author: David C. Morrill # Date: 04/06/2005 # Description: Test the EnumEditor trait editor. #------------------------------------------------------------------------------ #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from traits.api \ import HasTraits, Trait, Enum, Range from traitsui.api \ import EnumEditor #------------------------------------------------------------------------------- # Trait definitions: #------------------------------------------------------------------------------- values = [ 'one', 'two', 'three', 'four' ] enum = Enum( *values ) range = Range( 1, 4 ) #------------------------------------------------------------------------------- # 'TestEnumEditor' class: #------------------------------------------------------------------------------- class TestEnumEditor ( HasTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- value = Trait( 1, enum, range, editor = EnumEditor( values = values, evaluate = int ) ) #------------------------------------------------------------------------------- # Run the test: #------------------------------------------------------------------------------- if __name__ == '__main__': test = TestEnumEditor() test.configure_traits() test.print_traits() traits-4.1.0/LICENSE.txt0000644000175100001440000000352711674463323015646 0ustar ischnellusers00000000000000This software is OSI Certified Open Source Software. OSI Certified is a certification mark of the Open Source Initiative. Copyright (c) 2006, Enthought, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Enthought, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The software contained in the traits/protocols/ directory is the pyprotocols project (http://peak.telecommunity.com/PyProtocols.html), it is originaly licensed under the terms of the Python Software Foundation License, which is compatible with the above terms. traits-4.1.0/image_LICENSE_Eclipse.txt0000644000175100001440000002604311674463323020452 0ustar ischnellusers00000000000000Eclipse Public License - v 1.0 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENTS ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i)changes to the Program, and ii)additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributors behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipients responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributors responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipients patent(s), then such Recipients rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipients rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipients rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipients obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. traits-4.1.0/traits/0000755000175100001440000000000011674463323015322 5ustar ischnellusers00000000000000traits-4.1.0/traits/trait_handlers.py0000644000175100001440000035716211674463323020715 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # # Copyright (c) 2005, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in enthought/LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # # Author: David C. Morrill # Date: 06/21/2002 # # Refactored into a separate module: 07/04/2003 # #------------------------------------------------------------------------------ """ Defines the BaseTraitHandler class and a standard set of BaseTraitHandler subclasses for use with the Traits package. A trait handler mediates the assignment of values to object traits. It verifies (via its validate() method) that a specified value is consistent with the object trait, and generates a TraitError exception if it is not consistent. """ #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from __future__ import absolute_import import sys import re import copy import copy_reg from types import InstanceType, TypeType, FunctionType, MethodType from weakref import ref from .protocols.api import adapt from .ctraits import CTraitMethod from .trait_base import (strx, SequenceTypes, Undefined, TypeTypes, ClassTypes, CoercableTypes, TraitsCache, class_of, enumerate, Missing) from .trait_errors import TraitError, repr_type # Patched by 'traits.py' once class is defined! Trait = Event = None # Set up a logger: import logging logger = logging.getLogger( __name__ ) #------------------------------------------------------------------------------- # Constants: #------------------------------------------------------------------------------- # Trait 'comparison_mode' enum values: NO_COMPARE = 0 OBJECT_IDENTITY_COMPARE = 1 RICH_COMPARE = 2 RangeTypes = ( int, long, float ) CallableTypes = ( FunctionType, MethodType, CTraitMethod ) # Mapping from trait metadata 'type' to CTrait 'type': trait_types = { 'python': 1, 'event': 2 } #------------------------------------------------------------------------------- # Forward references: #------------------------------------------------------------------------------- trait_from = None # Patched by 'traits.py' when real 'trait_from' is defined #------------------------------------------------------------------------------- # Returns the correct argument count for a specified function or method: #------------------------------------------------------------------------------- def _arg_count ( func ): """ Returns the correct argument count for a specified function or method. """ if (type( func ) is MethodType) and (func.im_self is not None): return func.func_code.co_argcount - 1 return func.func_code.co_argcount #------------------------------------------------------------------------------- # Property error handling functions: #------------------------------------------------------------------------------- def _write_only ( object, name ): raise TraitError, "The '%s' trait of %s instance is 'write only'." % ( name, class_of( object ) ) def _read_only ( object, name, value ): raise TraitError, "The '%s' trait of %s instance is 'read only'." % ( name, class_of( object ) ) def _undefined_get ( object, name ): raise TraitError, ("The '%s' trait of %s instance is a property that has " "no 'get' or 'set' method") % ( name, class_of( object ) ) def _undefined_set ( object, name, value ): _undefined_get( object, name ) #------------------------------------------------------------------------------- # 'BaseTraitHandler' class (base class for all user defined traits and trait # handlers): #------------------------------------------------------------------------------- class BaseTraitHandler ( object ): """ The task of this class and its subclasses is to verify the correctness of values assigned to object trait attributes. This class is an alternative to trait validator functions. A trait handler has several advantages over a trait validator function, due to being an object: * Trait handlers have constructors and state. Therefore, you can use them to create *parameterized types*. * Trait handlers can have multiple methods, whereas validator functions can have only one callable interface. This feature allows more flexibility in their implementation, and allows them to handle a wider range of cases, such as interactions with other components. """ default_value_type = -1 has_items = False is_mapped = False editor = None info_text = 'a legal value' def is_valid ( self, object, name, value ): try: validate = self.validate try: validate( object, name, value ) return True except: return False except: return True def error ( self, object, name, value ): """Raises a TraitError exception. Parameters ---------- object : object The object whose attribute is being assigned name : string The name of the attribute being assigned value : object The proposed new value for the attribute Description ----------- This method is called by the validate() method when an assigned value is not valid. Raising a TraitError exception either notifies the user of the problem, or, in the case of compound traits, provides a chance for another trait handler to handle to validate the value. """ raise TraitError( object, name, self.full_info( object, name, value ), value ) def arg_error ( self, method, arg_num, object, name, value ): """ Raises a TraitError exception to notify the user that a method on an instance received a positional argument of an incorrect type. Parameters ---------- method : function The method that encountered the error arg_num : integer The position of the incorrect argument in the argument list object : object The object whose method was called name : string The name of the parameter corresponding to the incorrect argument value : object The value passed to the argument Description ----------- This method can be called when type-checking a method. """ raise TraitError, ("The '%s' parameter (argument %d) of the %s method " "of %s instance must be %s, but a value of %s was " "specified." % (name, arg_num, method.tm_name, class_of(object), self.full_info(object, name, value), repr_type(value))) def keyword_error ( self, method, object, name, value ): """ Raises a TraitError exception to notify the user that a method on an instance received a keyword argument of an incorrect type. Parameters ---------- method : function The method that encountered the error object : object The object whose method was called name : string The name of the parameter corresponding to the incorrect argument value The value passed to the argument Description ----------- This method can be called when type-checking a method. """ raise TraitError, ("The '%s' keyword argument of the %s method of " "%s instance must be %s, but a value of %s was " "specified." % (name, method.tm_name, class_of(object), self.info(object, name, value), repr_type(value))) def missing_arg_error ( self, method, arg_num, object, name ): """ Raises a TraitError exception to notify the user that a method on an instance failed to receive a required positional argument. Parameters ---------- method : function The method that encountered the error arg_num : integer The position of the incorrect argument in the argument list object : object The object whose method was called name : string The name of the parameter corresponding to the incorrect argument Description ----------- This method can be called when type-checking a method. """ raise TraitError, ("The '%s' parameter (argument %d) of the %s method " "of %s instance must be specified, but was omitted." % ( name, arg_num, method.tm_name, class_of( object ) ) ) def dup_arg_error ( self, method, arg_num, object, name ): """ Raises a TraitError exception to notify the user that a method on an instance received an argument as both a keyword argument and a positional argument. Parameters ---------- method : function The method that encountered the error arg_num : integer The position of the incorrect argument in the argument list object : object The object whose method was called name : string The name of the parameter corresponding to the incorrect argument Description ----------- This method can be called when type-checking a method. """ raise TraitError, ("The '%s' parameter (argument %d) of the %s method " "of %s instance was specified as both a positional " "and keyword value." % ( name, arg_num, method.tm_name, class_of( object ) ) ) def return_error ( self, method, object, value ): """ Raises a TraitError exception to notify the user that a method on an instance returned a value of incorrect type. Parameters ---------- method : function The method that encountered the error object : object The object whose method was called value The value returned by the method Description ----------- This method can be called when type-checking a method. """ raise TraitError, ("The result of the %s method of %s instance must " "be %s, but a value of %s was returned." % ( method.tm_name, class_of(object), self.info(), repr_type(value))) def full_info ( self, object, name, value ): """Returns a string describing the type of value accepted by the trait handler. Parameters ---------- object : object The object whose attribute is being assigned name : string The name of the attribute being assigned value The proposed new value for the attribute Description ----------- The string should be a phrase describing the type defined by the TraitHandler subclass, rather than a complete sentence. For example, use the phrase, "a square sprocket" instead of the sentence, "The value must be a square sprocket." The value returned by full_info() is combined with other information whenever an error occurs and therefore makes more sense to the user if the result is a phrase. The full_info() method is similar in purpose and use to the **info** attribute of a validator function. Note that the result can include information specific to the particular trait handler instance. For example, TraitRange instances return a string indicating the range of values acceptable to the handler (e.g., "an integer in the range from 1 to 9"). If the full_info() method is not overridden, the default method returns the value of calling the info() method. """ return self.info() def info ( self ): """Must return a string describing the type of value accepted by the trait handler. The string should be a phrase describing the type defined by the TraitHandler subclass, rather than a complete sentence. For example, use the phrase, "a square sprocket" instead of the sentence, "The value must be a square sprocket." The value returned by info() is combined with other information whenever an error occurs and therefore makes more sense to the user if the result is a phrase. The info() method is similar in purpose and use to the **info** attribute of a validator function. Note that the result can include information specific to the particular trait handler instance. For example, TraitRange instances return a string indicating the range of values acceptable to the handler (e.g., "an integer in the range from 1 to 9"). If the info() method is not overridden, the default method returns the value of the 'info_text' attribute. """ return self.info_text def repr ( self, value ): """ Returns a printable representation of a value along with its type. DEPRECATED: This functionality was only used to provide readable error messages. This functionality has been incorporated into TraitError itself. Parameters ---------- value : object The value to be printed. """ import warnings warnings.warn("this functionality has been merged into TraitError; " "just pass the raw value", DeprecationWarning) return repr_type(value) def get_editor ( self, trait = None ): """ Returns a trait editor that allows the user to modify the *trait* trait. Parameters ---------- trait : trait The trait to be edited Description ----------- This method only needs to be specified if traits defined using this trait handler require a non-default trait editor in trait user interfaces. The default implementation of this method returns a trait editor that allows the user to type an arbitrary string as the value. For more information on trait user interfaces, refer to the *Traits UI User Guide*. """ if self.editor is None: self.editor = self.create_editor() return self.editor def create_editor ( self ): """ Returns the default traits UI editor to use for a trait. """ from traitsui.api import TextEditor return TextEditor() def inner_traits ( self ): """ Returns a tuple containing the *inner traits* for this trait. Most trait handlers do not have any inner traits, and so will return an empty tuple. The exceptions are **List** and **Dict** trait types, which have inner traits used to validate the values assigned to the trait. For example, in *List( Int )*, the *inner traits* for **List** are ( **Int**, ). """ return () #------------------------------------------------------------------------------- # 'TraitType' (base class for class-based trait definitions: #------------------------------------------------------------------------------- # Create a singleton object for use in the TraitType constructor: class NoDefaultSpecified ( object ): pass NoDefaultSpecified = NoDefaultSpecified() class TraitType ( BaseTraitHandler ): """ Base class for new trait types. This class enables you to define new traits using a class-based approach, instead of by calling the Trait() factory function with an instance of a TraitHandler derived object. When subclassing this class, you can implement one or more of the method signatures below. Note that these methods are defined only as comments, because the absence of method definitions in the subclass definition implicitly provides information about how the trait should operate. The optional methods are as follows: * **get ( self, object, name ):** This is the getter method of a trait that behaves like a property. *Parameters* object : an object The object that the property applies to. name : string The name of the property on *object* property. *Description* If neither this method nor the set() method is defined, the value of the trait is handled like a normal object attribute. If this method is not defined, but the set() method is defined, the trait behaves like a write-only property. This method should return the value of the *name* property for the *object* object. * **set ( self, object, name, value )** This is the setter method of a trait that behaves like a property. *Parameters* object : instance The object that the property applies to. name : string The name of the property on *object*. value : any The value being assigned as the value of the property. *Description* If neither this method nor the get() method is implemented, the trait behaves like a normal trait attribute. If this method is not defined, but the get() method is defined, the trait behaves like a read-only property. This method does not need to return a value, but it should raise a TraitError exception if the specified *value* is not valid and cannot be coerced or adapted to a valid value. * **validate ( self, object, name, value )** This method validates, coerces, or adapts the specified *value* as the value of the *name* trait of the *object* object. This method is called when a value is assigned to an object trait that is based on this subclass of *TraitType* and the class does not contain a definition for either the get() or set() methods. This method must return the original *value* or any suitably coerced or adapted value that is a legal value for the trait. If *value* is not a legal value for the trait, and cannot be coerced or adapted to a legal value, the method should either raise a **TraitError** or call the **error** method to raise the **TraitError** on its behalf. * **is_valid_for ( self, value )** As an alternative to implementing the **validate** method, you can instead implement the **is_valid_for** method, which receives only the *value* being assigned. It should return **True** if the value is valid, and **False** otherwise. * **value_for ( self, value )** As another alternative to implementing the **validate** method, you can instead implement the **value_for** method, which receives only the *value* being assigned. It should return the validated form of *value* if it is valid, or raise a **TraitError** if the value is not valid. * **post_setattr ( self, object, name, value )** This method allows the trait to do additional processing after *value* has been successfully assigned to the *name* trait of the *object* object. For most traits there is no additional processing that needs to be done, and this method need not be defined. It is normally used for creating "shadow" (i.e., "mapped" traits), but other uses may arise as well. This method does not need to return a value, and should normally not raise any exceptions. """ default_value = Undefined metadata = {} def __init__ ( self, default_value = NoDefaultSpecified, **metadata ): """ This constructor method is the only method normally called directly by client code. It defines the trait. The default implementation accepts an optional, untype-checked default value, and caller-supplied trait metadata. Override this method whenever a different method signature or a type-checked default value is needed. """ if default_value is not NoDefaultSpecified: self.default_value = default_value if len( metadata ) > 0: if len( self.metadata ) > 0: self._metadata = self.metadata.copy() self._metadata.update( metadata ) else: self._metadata = metadata else: self._metadata = self.metadata self.init() def init ( self ): """ Allows the trait to perform any additional initialization needed. """ pass def get_default_value ( self ): """ Returns a tuple of the form: (*default_value_type*, *default_value*) which describes the default value for this trait. The default implementation analyzes the value of the trait's **default_value** attribute and determines an appropriate *default_value_type* for *default_value*. If you need to override this method to provide a different result tuple, the following values are valid values for *default_value_type*: - 0, 1: The *default_value* item of the tuple is the default value. - 2: The object containing the trait is the default value. - 3: A new copy of the list specified by *default_value* is the default value. - 4: A new copy of the dictionary specified by *default_value* is the default value. - 5: A new instance of TraitListObject constructed using the *default_value* list is the default value. - 6: A new instance of TraitDictObject constructed using the *default_value* dictionary is the default value. - 7: *default_value* is a tuple of the form: (*callable*, *args*, *kw*), where *callable* is a callable, *args* is a tuple, and *kw* is either a dictionary or None. The default value is the result obtained by invoking callable(\*args, \*\*kw). - 8: *default_value* is a callable. The default value is the result obtained by invoking *default_value*(*object*), where *object* is the object containing the trait. If the trait has a validate() method, the validate() method is also called to validate the result. - 9: A new instance of TraitSetObject constructed using the *default_value* set is the default value. """ dv = self.default_value dvt = self.default_value_type if dvt < 0: dvt = 0 if isinstance( dv, TraitListObject ): dvt = 5 elif isinstance( dv, list ): dvt = 3 elif isinstance( dv, TraitDictObject ): dvt = 6 elif isinstance( dv, dict ): dvt = 4 elif isinstance( dv, TraitSetObject ): dvt = 9 self.default_value_type = dvt return ( dvt, dv ) def clone ( self, default_value = Missing, **metadata ): """ Clones the contents of this object into a new instance of the same class, and then modifies the cloned copy using the specified *default_value* and *metadata*. Returns the cloned object as the result. Note that subclasses can change the signature of this method if needed, but should always call the 'super' method if possible. """ if 'parent' not in metadata: metadata[ 'parent' ] = self new = self.__class__.__new__( self.__class__ ) new_dict = new.__dict__ new_dict.update( self.__dict__ ) if 'editor' in new_dict: del new_dict[ 'editor' ] if '_metadata' in new_dict: new._metadata = new._metadata.copy() else: new._metadata = {} new._metadata.update( metadata ) if default_value is not Missing: new.default_value = default_value if self.validate is not None: try: new.default_value = self.validate( None, None, default_value ) except: pass return new def get_value ( self, object, name, trait = None ): """ Returns the current value of a property-based trait. """ cname = TraitsCache + name value = object.__dict__.get( cname, Undefined ) if value is Undefined: if trait is None: trait = object.trait( name ) object.__dict__[ cname ] = value = \ trait.default_value_for( object, name ) return value def set_value ( self, object, name, value ): """ Sets the cached value of a property-based trait and fires the appropriate trait change event. """ cname = TraitsCache + name old = object.__dict__.get( cname, Undefined ) if value != old: object.__dict__[ cname ] = value object.trait_property_changed( name, old, value ) #-- Private Methods -------------------------------------------------------- def __call__ ( self, *args, **kw ): """ Allows a derivative trait to be defined from this one. """ return self.clone( *args, **kw ).as_ctrait() def _is_valid_for ( self, object, name, value ): """ Handles a simplified validator that only returns whether or not the original value is valid. """ if self.is_valid_for( value ): return value self.error( object, name, value ) def _value_for ( self, object, name, value ): """ Handles a simplified validator that only receives the value argument. """ try: return self.value_for( value ) except TraitError: self.error( object, name, value ) def as_ctrait ( self ): """ Returns a CTrait corresponding to the trait defined by this class. """ from .traits import CTrait metadata = getattr( self, '_metadata', {} ) getter = getattr( self, 'get', None ) setter = getattr( self, 'set', None ) if (getter is not None) or (setter is not None): if getter is None: getter = _write_only metadata.setdefault( 'transient', True ) elif setter is None: setter = _read_only metadata.setdefault( 'transient', True ) trait = CTrait( 4 ) n = 0 validate = getattr( self, 'validate', None ) if validate is not None: n = _arg_count( validate ) trait.property( getter, _arg_count( getter ), setter, _arg_count( setter ), validate, n ) metadata.setdefault( 'type', 'property' ) else: type = getattr( self, 'ctrait_type', None ) if type is None: type = trait_types.get( metadata.get( 'type' ), 0 ) trait = CTrait( type ) validate = getattr( self, 'fast_validate', None ) if validate is None: validate = getattr( self, 'validate', None ) if validate is None: validate = getattr( self, 'is_valid_for', None ) if validate is not None: validate = self._is_valid_for else: validate = getattr( self, 'value_for', None ) if validate is not None: validate = self._value_for if validate is not None: trait.set_validate( validate ) post_setattr = getattr( self, 'post_setattr', None ) if post_setattr is not None: trait.post_setattr = post_setattr trait.is_mapped( self.is_mapped ) # Note: The use of 'rich_compare' metadata is deprecated; use # 'comparison_mode' metadata instead: rich_compare = metadata.get( 'rich_compare' ) if rich_compare is not None: trait.rich_comparison( rich_compare is True ) comparison_mode = metadata.get( 'comparison_mode' ) if comparison_mode is not None: trait.comparison_mode( comparison_mode ) metadata.setdefault( 'type', 'trait' ) trait.default_value( *self.get_default_value() ) trait.value_allowed( metadata.get( 'trait_value', False ) is True ) trait.handler = self trait.__dict__ = metadata.copy() return trait def __getattr__ ( self, name ): if (name[:2] == '__') and (name[-2:] == '__'): raise AttributeError( "'%s' object has no attribute '%s'" % ( self.__class__.__name__, name ) ) return getattr( self, '_metadata', {} ).get( name, None ) #------------------------------------------------------------------------------- # 'TraitHandler' class (base class for all trait handlers): #------------------------------------------------------------------------------- class TraitHandler ( BaseTraitHandler ): """ The task of this class and its subclasses is to verify the correctness of values assigned to object trait attributes. This class is an alternative to trait validator functions. A trait handler has several advantages over a trait validator function, due to being an object: * Trait handlers have constructors and state. Therefore, you can use them to create *parameterized types*. * Trait handlers can have multiple methods, whereas validator functions can have only one callable interface. This feature allows more flexibility in their implementation, and allows them to handle a wider range of cases, such as interactions with other components. The only method of TraitHandler that *must* be implemented by subclasses is validate(). """ def validate ( self, object, name, value ): """ Verifies whether a new value assigned to a trait attribute is valid. Parameters ---------- object : object The object whose attribute is being assigned name : string The name of the attribute being assigned value The proposed new value for the attribute Returns ------- If the new value is valid, this method must return either the original value passed to it, or an alternate value to be assigned in place of the original value. Whatever value this method returns is the actual value assigned to *object.name*. Description ----------- This method *must* be implemented by subclasses of TraitHandler. It is called whenever a new value is assigned to a trait attribute defined using this trait handler. If the value received by validate() is not valid for the trait attribute, the method must called the predefined error() method to raise a TraitError exception """ raise TraitError, ( "The '%s' trait of %s instance has an unknown type. " "Contact the developer to correct the problem." % ( name, class_of( object ) ) ) #------------------------------------------------------------------------------- # 'TraitRange' class: #------------------------------------------------------------------------------- class TraitRange ( TraitHandler ): """Ensures that a trait attribute lies within a specified numeric range. TraitRange is the underlying handler for the predefined Range() trait factory. Any value assigned to a trait containing a TraitRange handler must be of the correct type and in the numeric range defined by the TraitRange instance. No automatic coercion takes place. For example:: class Person(HasTraits): age = Trait(0, TraitRange(0, 150)) weight = Trait(0.0, TraitRange(0.0, None)) This example defines a Person class, which has an **age** trait attribute, which must be an integer/long in the range from 0 to 150, and a **weight** trait attribute, which must be a non-negative float value. """ def __init__ ( self, low = None, high = None, exclude_low = False, exclude_high = False ): """ Creates a TraitRange handler. Parameters ---------- low : number The minimum value that the trait can accept high : number The maximum value that the trait can accept exclude_low : Boolean Should the *low* value be exclusive (or inclusive) exclude_high : Boolean Should the *high* value be exclusive (or inclusive) Description ----------- The *low* and *high* values must be of the same Python numeric type, either ``int``, ``long`` or ``float``. Alternatively, one of the values may be None, to indicate that that portion of the range is unbounded. The *exclude_low* and *exclude_high* values can be used to specify whether the *low* and *high* values should be exclusive (or inclusive). """ vtype = type( high ) if (low is not None) and (vtype is not float): vtype = type( low ) if vtype not in RangeTypes: raise TraitError, ("TraitRange can only be use for int, long or " "float values, but a value of type %s was " "specified." % vtype) if vtype is float: self.validate = self.float_validate kind = 4 self._type_desc = 'a floating point number' if low is not None: low = float( low ) if high is not None: high = float( high ) elif vtype is long: self.validate = self.long_validate self._type_desc = 'a long integer' if low is not None: low = long( low ) if high is not None: high = long( high ) else: self.validate = self.int_validate kind = 3 self._type_desc = 'an integer' if low is not None: low = int( low ) if high is not None: high = int( high ) exclude_mask = 0 if exclude_low: exclude_mask |= 1 if exclude_high: exclude_mask |= 2 if vtype is not long: self.fast_validate = ( kind, low, high, exclude_mask ) # Assign type-corrected arguments to handler attributes self._low = low self._high = high self._exclude_low = exclude_low self._exclude_high = exclude_high def float_validate ( self, object, name, value ): try: if (isinstance( value, RangeTypes ) and ((self._low is None) or (self._exclude_low and (self._low < value)) or ((not self._exclude_low) and (self._low <= value))) and ((self._high is None) or (self._exclude_high and (self._high > value)) or ((not self._exclude_high) and (self._high >= value)))): return float( value ) except: pass self.error( object, name, value ) def int_validate ( self, object, name, value ): try: if (isinstance( value, int ) and ((self._low is None) or (self._exclude_low and (self._low < value)) or ((not self._exclude_low) and (self._low <= value))) and ((self._high is None) or (self._exclude_high and (self._high > value)) or ((not self._exclude_high) and (self._high >= value)))): return value except: pass self.error( object, name, value ) def long_validate ( self, object, name, value ): try: if (isinstance( value, long ) and ((self._low is None) or (self._exclude_low and (self._low < value)) or ((not self._exclude_low) and (self._low <= value))) and ((self._high is None) or (self._exclude_high and (self._high > value)) or ((not self._exclude_high) and (self._high >= value)))): return value except: pass self.error( object, name, value ) def info ( self ): if self._low is None: if self._high is None: return self._type_desc return '%s <%s %s' % ( self._type_desc, '='[ self._exclude_high: ], self._high ) elif self._high is None: return '%s >%s %s' % ( self._type_desc, '='[ self._exclude_low: ], self._low ) return '%s <%s %s <%s %s' % ( self._low, '='[ self._exclude_low: ], self._type_desc, '='[ self._exclude_high: ], self._high ) def get_editor ( self, trait ): from traitsui.api import RangeEditor auto_set = trait.auto_set if auto_set is None: auto_set = True return RangeEditor( self, mode = trait.mode or 'auto', cols = trait.cols or 3, auto_set = auto_set, enter_set = trait.enter_set or False, low_label = trait.low or '', high_label = trait.high or '' ) #------------------------------------------------------------------------------- # 'TraitString' class: #------------------------------------------------------------------------------- class TraitString ( TraitHandler ): """ Ensures that a trait attribute value is a string that satisfied some additional, optional constraints. The optional constraints include minimum and maximum lengths, and a regular expression that the string must match. If the value assigned to the trait attribute is a Python numeric type, the TraitString handler first coerces the value to a string. Values of other non-string types result in a TraitError being raised. The handler then makes sure that the resulting string is within the specified length range and that it matches the regular expression. Example ------- :: class Person(HasTraits): name = Trait('', TraitString(maxlen=50, regex=r'^[A-Za-z]*$')) This example defines a **Person** class with a **name** attribute, which must be a string of between 0 and 50 characters that consist of only upper and lower case letters. """ def __init__ ( self, minlen = 0, maxlen = sys.maxint, regex = '' ): """ Creates a TraitString handler. Parameters ---------- minlen : integer The minimum length allowed for the string maxlen : integer The maximum length allowed for the string regex : string A Python regular expression that the string must match """ self.minlen = max( 0, minlen ) self.maxlen = max( self.minlen, maxlen ) self.regex = regex self._init() def _init ( self ): if self.regex != '': self.match = re.compile( self.regex ).match if (self.minlen == 0) and (self.maxlen == sys.maxint): self.validate = self.validate_regex elif (self.minlen == 0) and (self.maxlen == sys.maxint): self.validate = self.validate_str else: self.validate = self.validate_len def validate ( self, object, name, value ): try: value = strx( value ) if ((self.minlen <= len( value ) <= self.maxlen) and (self.match( value ) is not None)): return value except: pass self.error( object, name, value ) def validate_str ( self, object, name, value ): try: return strx( value ) except: pass self.error( object, name, value ) def validate_len ( self, object, name, value ): try: value = strx( value ) if self.minlen <= len( value ) <= self.maxlen: return value except: pass self.error( object, name, value ) def validate_regex ( self, object, name, value ): try: value = strx( value ) if self.match( value ) is not None: return value except: pass self.error( object, name, value ) def info ( self ): msg = '' if (self.minlen != 0) and (self.maxlen != sys.maxint): msg = ' between %d and %d characters long' % ( self.minlen, self.maxlen ) elif self.maxlen != sys.maxint: msg = ' <= %d characters long' % self.maxlen elif self.minlen != 0: msg = ' >= %d characters long' % self.minlen if self.regex != '': if msg != '': msg += ' and' msg += (" matching the pattern '%s'" % self.regex) return 'a string' + msg def __getstate__ ( self ): result = self.__dict__.copy() for name in [ 'validate', 'match' ]: if name in result: del result[ name ] return result def __setstate__ ( self, state ): self.__dict__.update( state ) self._init() #------------------------------------------------------------------------------- # 'TraitCoerceType' class: #------------------------------------------------------------------------------- class TraitCoerceType ( TraitHandler ): """Ensures that a value assigned to a trait attribute is of a specified Python type, or can be coerced to the specified type. TraitCoerceType is the underlying handler for the predefined traits and factories for Python simple types. The TraitCoerceType class is also an example of a parameterized type, because the single TraitCoerceType class allows creating instances that check for totally different sets of values. For example:: class Person(HasTraits): name = Trait('', TraitCoerceType('')) weight = Trait(0.0, TraitCoerceType(float)) In this example, the **name** attribute must be of type ``str`` (string), while the **weight** attribute must be of type ``float``, although both are based on instances of the TraitCoerceType class. Note that this example is essentially the same as writing:: class Person(HasTraits): name = Trait('') weight = Trait(0.0) This simpler form is automatically changed by the Trait() function into the first form, based on TraitCoerceType instances, when the trait attributes are defined. For attributes based on TraitCoerceType instances, if a value that is assigned is not of the type defined for the trait, a TraitError exception is raised. However, in certain cases, if the value can be coerced to the required type, then the coerced value is assigned to the attribute. Only *widening* coercions are allowed, to avoid any possible loss of precision. The following table lists the allowed coercions. ============ ================= Trait Type Coercible Types ============ ================= complex float, int float int long int unicode str ============ ================= """ def __init__ ( self, aType ): """ Creates a TraitCoerceType handler. Parameters ---------- aType : type Either a Python type (e.g., ``str`` or types.StringType) or a Python value (e.g., 'cat') Description ----------- If *aType* is a value, it is mapped to its corresponding type. For example, the string 'cat' is automatically mapped to ``str`` (i.e., types.StringType). """ if not isinstance( aType, TypeType ): aType = type( aType ) self.aType = aType try: self.fast_validate = CoercableTypes[ aType ] except: self.fast_validate = ( 11, aType ) def validate ( self, object, name, value ): fv = self.fast_validate tv = type( value ) # If the value is already the desired type, then return it: if tv is fv[1]: return value # Else see if it is one of the coercable types: for typei in fv[2:]: if tv is typei: # Return the coerced value: return fv[1]( value ) # Otherwise, raise an exception: self.error( object, name, value ) def info ( self ): return 'a value of %s' % str( self.aType )[1:-1] def get_editor ( self, trait ): # Make the special case of a 'bool' type use the boolean editor: if self.aType is bool: if self.editor is None: from traitsui.api import BooleanEditor self.editor = BooleanEditor() return self.editor # Otherwise, map all other types to a text editor: auto_set = trait.auto_set if auto_set is None: auto_set = True from traitsui.api import TextEditor return TextEditor( auto_set = auto_set, enter_set = trait.enter_set or False, evaluate = self.fast_validate[1] ) #------------------------------------------------------------------------------- # 'TraitCastType' class: #------------------------------------------------------------------------------- class TraitCastType ( TraitCoerceType ): """Ensures that a value assigned to a trait attribute is of a specified Python type, or can be cast to the specified type. This class is similar to TraitCoerceType, but uses casting rather than coercion. Values are cast by calling the type with the value to be assigned as an argument. When casting is performed, the result of the cast is the value assigned to the trait attribute. Any trait that uses a TraitCastType instance in its definition ensures that its value is of the type associated with the TraitCastType instance. For example:: class Person(HasTraits): name = Trait('', TraitCastType('')) weight = Trait(0.0, TraitCastType(float)) In this example, the **name** trait must be of type ``str`` (string), while the **weight** trait must be of type ``float``. Note that this example is essentially the same as writing:: class Person(HasTraits): name = CStr weight = CFloat To understand the difference between TraitCoerceType and TraitCastType (and also between Float and CFloat), consider the following example:: >>>class Person(HasTraits): ... weight = Float ... cweight = CFloat >>> >>>bill = Person() >>>bill.weight = 180 # OK, coerced to 180.0 >>>bill.cweight = 180 # OK, cast to 180.0 >>>bill.weight = '180' # Error, invalid coercion >>>bill.cweight = '180' # OK, cast to float('180') """ def __init__ ( self, aType ): """ Creates a TraitCastType handler. Parameters ---------- aType : type Either a Python type (e.g., ``str`` or types.StringType) or a Python value (e.g., ``'cat``) Description ----------- If *aType* is a Python value, it is automatically mapped to its corresponding Python type. For example, the string 'cat' is automatically mapped to ``str`` (i.e., types.StringType). """ if not isinstance( aType, TypeType ): aType = type( aType ) self.aType = aType self.fast_validate = ( 12, aType ) def validate ( self, object, name, value ): # If the value is already the desired type, then return it: if type( value ) is self.aType: return value # Else try to cast it to the specified type: try: return self.aType( value ) except: self.error( object, name, value ) #------------------------------------------------------------------------------- # 'ThisClass' class: #------------------------------------------------------------------------------- class ThisClass ( TraitHandler ): """Ensures that the trait attribute values belong to the same class (or a subclass) as the object containing the trait attribute. ThisClass is the underlying handler for the predefined traits **This** and **self**, and the elements of ListThis. """ def __init__ ( self, allow_none = False ): """Creates a ThisClass handler. Parameters ---------- allow_none : Boolean Flag indicating whether None is accepted as a valid value (True or non-zero) or not (False or 0) """ if allow_none: self.validate = self.validate_none self.info = self.info_none self.fast_validate = ( 2, None ) else: self.fast_validate = ( 2, ) def validate ( self, object, name, value ): if isinstance( value, object.__class__ ): return value self.validate_failed( object, name, value ) def validate_none ( self, object, name, value ): if isinstance( value, object.__class__ ) or (value is None): return value self.validate_failed( object, name, value ) def info ( self ): return 'an instance of the same type as the receiver' def info_none ( self ): return 'an instance of the same type as the receiver or None' def validate_failed ( self, object, name, value ): self.error( object, name, value ) def get_editor ( self, trait ): if self.editor is None: from traitsui.api import InstanceEditor self.editor = InstanceEditor( label = trait.label or '', view = trait.view or '', kind = trait.kind or 'live' ) return self.editor #------------------------------------------------------------------------------- # 'TraitInstance' class: #------------------------------------------------------------------------------- # Mapping from 'adapt' parameter values to 'fast validate' values AdaptMap = { 'no': -1, 'yes': 0, 'default': 1 } class TraitInstance ( ThisClass ): """Ensures that trait attribute values belong to a specified Python class or type. TraitInstance is the underlying handler for the predefined trait **Instance** and the elements of List( Instance ). Any trait that uses a TraitInstance handler ensures that its values belong to the specified type or class (or one of its subclasses). For example:: class Employee(HasTraits): manager = Trait(None, TraitInstance(Employee, True)) This example defines a class Employee, which has a **manager** trait attribute, which accepts either None or an instance of Employee as its value. TraitInstance ensures that assigned values are exactly of the type specified (i.e., no coercion is performed). """ def __init__ ( self, aClass, allow_none = True, adapt = 'yes', module = '' ): """Creates a TraitInstance handler. Parameters ---------- aClass : class or type A Python class, an instance of a Python class, or a Python type allow_none : boolean Flag indicating whether None is accepted as a valid value (True or non-zero) or not (False or 0) adapt : string Value indicating how adaptation should be handled: - 'no' (-1): Adaptation is not allowed. - 'yes' (0): Adaptation is allowed and should raise an exception if adaptation fails. - 'default' (1): Adaption is allowed and should return the default value if adaptation fails. module : module The module that the class belongs to. Description ----------- If *aClass* is an instance, it is mapped to the class it is an instance of. """ self._allow_none = allow_none self.adapt = AdaptMap[ adapt ] self.module = module if isinstance( aClass, basestring ): self.aClass = aClass else: if not isinstance( aClass, ClassTypes ): aClass = aClass.__class__ self.aClass = aClass self.set_fast_validate() def allow_none ( self ): self._allow_none = True if hasattr( self, 'fast_validate' ): self.set_fast_validate() def set_fast_validate ( self ): if self.adapt < 0: fast_validate = [ 1, self.aClass ] if self._allow_none: fast_validate = [ 1, None, self.aClass ] if self.aClass in TypeTypes: fast_validate[0] = 0 self.fast_validate = tuple( fast_validate ) else: self.fast_validate = ( 19, self.aClass, self.adapt, self._allow_none ) def validate ( self, object, name, value ): if value is None: if self._allow_none: return value else: self.validate_failed( object, name, value ) if isinstance( self.aClass, basestring ): self.resolve_class( object, name, value ) if self.adapt < 0: if isinstance( value, self.aClass ): return value elif self.adapt == 0: try: return adapt( value, self.aClass ) except: pass else: # fixme: The 'None' value is not really correct. It should return # the default value for the trait, but the handler does not have # any way to know this currently. Since the 'fast validate' code # does the correct thing, this should not normally be a problem. return adapt( value, self.aClass, None ) self.validate_failed( object, name, value ) def info ( self ): aClass = self.aClass if type( aClass ) is not str: aClass = aClass.__name__ if self.adapt < 0: result = class_of( aClass ) else: result = ('an implementor of, or can be adapted to implement, %s' % aClass) if self._allow_none: return result + ' or None' return result def resolve_class ( self, object, name, value ): aClass = self.validate_class( self.find_class( self.aClass ) ) if aClass is None: self.validate_failed( object, name, value ) self.aClass = aClass # fixme: The following is quite ugly, because it wants to try and fix # the trait referencing this handler to use the 'fast path' now that the # actual class has been resolved. The problem is finding the trait, # especially in the case of List(Instance('foo')), where the # object.base_trait(...) value is the List trait, not the Instance # trait, so we need to check for this and pull out the List # 'item_trait'. Obviously this does not extend well to other traits # containing nested trait references (Dict?)... self.set_fast_validate() trait = object.base_trait( name ) handler = trait.handler if (handler is not self) and hasattr( handler, 'item_trait' ): trait = handler.item_trait trait.set_validate( self.fast_validate ) def find_class ( self, aClass ): module = self.module col = aClass.rfind( '.' ) if col >= 0: module = aClass[ : col ] aClass = aClass[ col + 1: ] theClass = getattr( sys.modules.get( module ), aClass, None ) if (theClass is None) and (col >= 0): try: mod = __import__( module , globals=globals(), level=1) for component in module.split( '.' )[1:]: mod = getattr( mod, component ) theClass = getattr( mod, aClass, None ) except: pass return theClass def validate_class ( self, aClass ): return aClass def create_default_value ( self, *args, **kw ): aClass = args[0] if isinstance( aClass, basestring ): aClass = self.validate_class( self.find_class( aClass ) ) if aClass is None: raise TraitError, 'Unable to locate class: ' + args[0] return aClass( *args[1:], **kw ) #------------------------------------------------------------------------------- # 'TraitWeakRef' class: #------------------------------------------------------------------------------- class TraitWeakRef ( TraitInstance ): def _get ( self, object, name ): value = getattr( object, name + '_', None ) if value is not None: return value.value() return None def _set ( self, object, name, value ): if value is not None: value = HandleWeakRef( object, name, value ) object.__dict__[ name + '_' ] = value def resolve_class ( self, object, name, value ): # fixme: We have to override this method to prevent the 'fast validate' # from being set up, since the trait using this is a 'property' style # trait which is not currently compatible with the 'fast_validate' # style (causes internal Python SystemError messages). aClass = self.find_class( self.aClass ) if aClass is None: self.validate_failed( object, name, value ) self.aClass = aClass class HandleWeakRef ( object ): def __init__ ( self, object, name, value ): self.object = ref( object ) self.name = name self.value = ref( value, self._value_freed ) def _value_freed ( self, ref ): object = self.object() if object is not None: object.trait_property_changed( self.name, Undefined, None ) #------------------------------------------------------------------------------- # 'TraitClass' class: #------------------------------------------------------------------------------- class TraitClass ( TraitHandler ): """Ensures that trait attribute values are subclasses of a specified class (or the class itself). A value is valid if it is a subclass of the specified class (including the class itself), or it is a string that is equivalent to the name of a valid class. """ def __init__ ( self, aClass ): """Creates a TraitClass handler. Parameters ---------- aClass : class A Python class Description ----------- If *aClass* is an instance, it is mapped to the class it is an instance of. """ if type( aClass ) is InstanceType: aClass = aClass.__class__ self.aClass = aClass def validate ( self, object, name, value ): try: if isinstance( value, basestring ): value = value.strip() col = value.rfind( '.' ) if col >= 0: module_name = value[:col] class_name = value[col + 1:] module = sys.modules.get( module_name ) if module is None: exec( 'import ' + module_name ) module = sys.modules[ module_name ] value = getattr( module, class_name ) else: value = globals().get( value ) if issubclass( value, self.aClass ): return value except: pass self.error( object, name, value ) def info ( self ): return 'a subclass of ' + self.aClass.__name__ #------------------------------------------------------------------------------- # 'TraitFunction' class: #------------------------------------------------------------------------------- class TraitFunction ( TraitHandler ): """Ensures that assigned trait attribute values are acceptable to a specified validator function. TraitFunction is the underlying handler for the predefined trait **Function**, and for the use of function references as arguments to the Trait() function. """ def __init__ ( self, aFunc ): """ Creates a TraitFunction handler. Parameters ---------- aFunc : function A function to validate trait attribute values Description ----------- The signature of the function passed as an argument must be of the form *function* ( *object*, *name*, *value* ). The function must verify that *value* is a legal value for the *name* trait attribute of *object*. If it is, the value returned by the fucntion is the actual value assigned to the trait attribute. If it is not, the function must raise a TraitError exception. """ if not isinstance( aFunc, CallableTypes ): raise TraitError, "Argument must be callable." self.aFunc = aFunc self.fast_validate = ( 13, aFunc ) def validate ( self, object, name, value ): try: return self.aFunc( object, name, value ) except TraitError: self.error( object, name, value ) def info ( self ): try: return self.aFunc.info except: if self.aFunc.__doc__: return self.aFunc.__doc__ return 'a legal value' #------------------------------------------------------------------------------- # 'TraitEnum' class: #------------------------------------------------------------------------------- class TraitEnum ( TraitHandler ): """ Ensures that a value assigned to a trait attribute is a member of a specified list of values. TraitEnum is the underlying handler for the forms of the Trait() function that take a list of possible values """ def __init__ ( self, *values ): """ Creates a TraitEnum handler. Parameters ---------- values : list or tuple Enumeration of all legal values for a trait Description ----------- The list of legal values can be provided as a list of values. That is, ``TraitEnum([1, 2, 3])`` and ``TraitEnum(1, 2, 3)`` are equivalent. For example:: class Flower(HasTraits): color = Trait('white', TraitEnum(['white', 'yellow', 'red'])) kind = Trait('annual', TraitEnum('annual', 'perennial')) This example defines a Flower class, which has a **color** trait attribute, which can have as its value, one of the three strings, 'white', 'yellow', or 'red', and a **kind** trait attribute, which can have as its value, either of the strings 'annual' or 'perennial'. This is equivalent to the following class definition:: class Flower(HasTraits): color = Trait(['white', 'yellow', 'red']) kind = Trait('annual', 'perennial') The Trait() function automatically maps traits of the form shown in this example to the form shown in the preceding example whenever it encounters them in a trait definition. """ if (len( values ) == 1) and (type( values[0] ) in SequenceTypes): values = values[0] self.values = tuple( values ) self.fast_validate = ( 5, self.values ) def validate ( self, object, name, value ): if value in self.values: return value self.error( object, name, value ) def info ( self ): return ' or '.join( [ repr( x ) for x in self.values ] ) def get_editor ( self, trait ): from traitsui.api import EnumEditor return EnumEditor( values = self, cols = trait.cols or 3, evaluate = trait.evaluate, mode = trait.mode or 'radio' ) #------------------------------------------------------------------------------- # 'TraitPrefixList' class: #------------------------------------------------------------------------------- class TraitPrefixList ( TraitHandler ): """Ensures that a value assigned to a trait attribute is a member of a list of specified string values, or is a unique prefix of one of those values. TraitPrefixList is a variation on TraitEnum. The values that can be assigned to a trait attribute defined using a TraitPrefixList handler is the set of all strings supplied to the TraitPrefixList constructor, as well as any unique prefix of those strings. That is, if the set of strings supplied to the constructor is described by [*s*\ :sub:`1`\ , *s*\ :sub:`2`\ , ..., *s*\ :sub:`n`\ ], then the string *v* is a valid value for the trait if *v* == *s*\ :sub:`i[:j]` for one and only one pair of values (i, j). If *v* is a valid value, then the actual value assigned to the trait attribute is the corresponding *s*\ :sub:`i` value that *v* matched. For example:: class Person(HasTraits): married = Trait('no', TraitPrefixList('yes', 'no') The Person class has a **married** trait that accepts any of the strings 'y', 'ye', 'yes', 'n', or 'no' as valid values. However, the actual values assigned as the value of the trait attribute are limited to either 'yes' or 'no'. That is, if the value 'y' is assigned to the **married** attribute, the actual value assigned will be 'yes'. Note that the algorithm used by TraitPrefixList in determining whether a string is a valid value is fairly efficient in terms of both time and space, and is not based on a brute force set of comparisons. """ def __init__ ( self, *values ): """ Creates a TraitPrefixList handler. Parameters ---------- values : list or tuple of strings Enumeration of all legal values for a trait Description ----------- As with TraitEnum, the list of legal values can be provided as a list of values. That is, ``TraitPrefixList(['one', 'two', 'three'])`` and ``TraitPrefixList('one', 'two', 'three')`` are equivalent. """ if (len( values ) == 1) and (type( values[0] ) in SequenceTypes): values = values[0] self.values = values[:] self.values_ = values_ = {} for key in values: values_[ key ] = key self.fast_validate = ( 10, values_, self.validate ) def validate ( self, object, name, value ): try: if not self.values_.has_key( value ): match = None n = len( value ) for key in self.values: if value == key[:n]: if match is not None: match = None break match = key if match is None: self.error( object, name, value ) self.values_[ value ] = match return self.values_[ value ] except: self.error( object, name, value ) def info ( self ): return (' or '.join( [ repr( x ) for x in self.values ] ) + ' (or any unique prefix)') def get_editor ( self, trait ): from traitsui.api import EnumEditor return EnumEditor( values = self, cols = trait.cols or 3 ) def __getstate__ ( self ): result = self.__dict__.copy() if 'fast_validate' in result: del result[ 'fast_validate' ] return result #------------------------------------------------------------------------------- # 'TraitMap' class: #------------------------------------------------------------------------------- class TraitMap ( TraitHandler ): """Checks that the value assigned to a trait attribute is a key of a specified dictionary, and also assigns the dictionary value corresponding to that key to a *shadow* attribute. A trait attribute that uses a TraitMap handler is called *mapped* trait attribute. In practice, this means that the resulting object actually contains two attributes: one whose value is a key of the TraitMap dictionary, and the other whose value is the corresponding value of the TraitMap dictionary. The name of the shadow attribute is simply the base attribute name with an underscore ('_') appended. Mapped trait attributes can be used to allow a variety of user-friendly input values to be mapped to a set of internal, program-friendly values. For example:: >>>class Person(HasTraits): ... married = Trait('yes', TraitMap({'yes': 1, 'no': 0 }) >>> >>>bob = Person() >>>print bob.married yes >>>print bob.married_ 1 In this example, the default value of the **married** attribute of the Person class is 'yes'. Because this attribute is defined using TraitPrefixList, instances of Person have another attribute, **married_**, whose default value is 1, the dictionary value corresponding to the key 'yes'. """ is_mapped = True def __init__ ( self, map ): """ Creates a TraitMap handler. Parameters ---------- map : dictionary A dictionary whose keys are valid values for the trait attribute, and whose corresponding values are the values for the shadow trait attribute. """ self.map = map self.fast_validate = ( 6, map ) def validate ( self, object, name, value ): try: if self.map.has_key( value ): return value except: pass self.error( object, name, value ) def mapped_value ( self, value ): return self.map[ value ] def post_setattr ( self, object, name, value ): try: setattr( object, name + '_', self.mapped_value( value ) ) except: # We don't need a fancy error message, because this exception # should always be caught by a TraitCompound handler: raise TraitError, 'Unmappable' def info ( self ): keys = [ repr( x ) for x in self.map.keys() ] keys.sort() return ' or '.join( keys ) def get_editor ( self, trait ): from traitsui.api import EnumEditor return EnumEditor( values = self, cols = trait.cols or 3 ) #------------------------------------------------------------------------------- # 'TraitPrefixMap' class: #------------------------------------------------------------------------------- class TraitPrefixMap ( TraitMap ): """A cross between the TraitPrefixList and TraitMap classes. Like TraitMap, TraitPrefixMap is created using a dictionary, but in this case, the keys of the dictionary must be strings. Like TraitPrefixList, a string *v* is a valid value for the trait attribute if it is a prefix of one and only one key *k* in the dictionary. The actual values assigned to the trait attribute is *k*, and its corresponding mapped attribute is *map*[*k*]. Example ------- :: boolean_map = Trait('true', TraitPrefixMap( { 'true': 1, 'yes': 1, 'false': 0, 'no': 0 } )) This example defines a Boolean trait that accepts any prefix of 'true', 'yes', 'false', or 'no', and maps them to 1 or 0. """ def __init__ ( self, map ): """Creates a TraitPrefixMap handler. Parameters ---------- map : dictionary A dictionary whose keys are strings that are valid values for the trait attribute, and whose corresponding values are the values for the shadow trait attribute. """ self.map = map self._map = _map = {} for key in map.keys(): _map[ key ] = key self.fast_validate = ( 10, _map, self.validate ) def validate ( self, object, name, value ): try: if not self._map.has_key( value ): match = None n = len( value ) for key in self.map.keys(): if value == key[:n]: if match is not None: match = None break match = key if match is None: self.error( object, name, value ) self._map[ value ] = match return self._map[ value ] except: self.error( object, name, value ) def info ( self ): return super( TraitPrefixMap, self ).info() + ' (or any unique prefix)' #------------------------------------------------------------------------------- # 'TraitExpression' class: #------------------------------------------------------------------------------- class TraitExpression ( TraitHandler ): """ Ensures that a value assigned to a trait attribute is a valid Python expression. The compiled form of a valid expression is stored as the mapped value of the trait. """ is_mapped = True def validate ( self, object, name, value ): try: compile( value, '', 'eval' ) return value except: self.error( object, name, value ) def post_setattr ( self, object, name, value ): object.__dict__[ name + '_' ] = self.mapped_value( value ) def info ( self ): return 'a valid Python expression' def mapped_value ( self, value ): return compile( value, '', 'eval' ) #------------------------------------------------------------------------------- # 'TraitCompound' class: #------------------------------------------------------------------------------- class TraitCompound ( TraitHandler ): """ Provides a logical-OR combination of other trait handlers. This class provides a means of creating complex trait definitions by combining several simpler trait definitions. TraitCompound is the underlying handler for the general forms of the Trait() function. A value is a valid value for a trait attribute based on a TraitCompound instance if the value is valid for at least one of the TraitHandler or trait objects supplied to the constructor. In addition, if at least one of the TraitHandler or trait objects is mapped (e.g., based on a TraitMap or TraitPrefixMap instance), then the TraitCompound is also mapped. In this case, any non-mapped traits or trait handlers use identity mapping. """ def __init__ ( self, *handlers ): """ Creates a TraitCompound handler. Parameters ---------- handlers : list or tuple of TraitHandler or trait objects The trait handlers to be combined Description ----------- The TraitHandler or trait objects can be provided directly as arguments to the constructor. """ if (len( handlers ) == 1) and (type( handlers[0] ) in SequenceTypes): handlers = handlers[0] self.handlers = handlers self.set_validate() def set_validate ( self ): self.is_mapped = False self.has_items = False self.reversable = True post_setattrs = [] mapped_handlers = [] validates = [] fast_validates = [] slow_validates = [] for handler in self.handlers: fv = getattr( handler, 'fast_validate', None ) if fv is not None: validates.append( handler.validate ) if fv[0] == 7: # If this is a nested complex fast validator, expand its # contents and adds its list to our list: fast_validates.extend( fv[1] ) else: # Else just add the entire validator to the list: fast_validates.append( fv ) else: slow_validates.append( handler.validate ) post_setattr = getattr( handler, 'post_setattr', None ) if post_setattr is not None: post_setattrs.append( post_setattr ) if handler.is_mapped: self.is_mapped = True mapped_handlers.append( handler ) else: self.reversable = False if handler.has_items: self.has_items = True self.validates = validates self.slow_validates = slow_validates if self.is_mapped: self.mapped_handlers = mapped_handlers elif hasattr( self, 'mapped_handlers' ): del self.mapped_handlers # If there are any fast validators, then we create a 'complex' fast # validator that composites them: if len( fast_validates ) > 0: # If there are any 'slow' validators, add a special handler at # the end of the fast validator list to handle them: if len( slow_validates ) > 0: fast_validates.append( ( 8, self ) ) # Create the 'complex' fast validator: self.fast_validate = ( 7, tuple( fast_validates ) ) elif hasattr( self, 'fast_validate' ): del self.fast_validate if len( post_setattrs ) > 0: self.post_setattrs = post_setattrs self.post_setattr = self._post_setattr elif hasattr( self, 'post_setattr' ): del self.post_setattr def validate ( self, object, name, value ): for validate in self.validates: try: return validate( object, name, value ) except TraitError: pass return self.slow_validate( object, name, value ) def slow_validate ( self, object, name, value ): for validate in self.slow_validates: try: return validate( object, name, value ) except TraitError: pass self.error( object, name, value ) def full_info ( self, object, name, value ): return ' or '.join( [ x.full_info( object, name, value ) for x in self.handlers ] ) def info ( self ): return ' or '.join( [ x.info() for x in self.handlers ] ) def mapped_value ( self, value ): for handler in self.mapped_handlers: try: return handler.mapped_value( value ) except: pass return value def _post_setattr ( self, object, name, value ): for post_setattr in self.post_setattrs: try: post_setattr( object, name, value ) return except TraitError: pass setattr( object, name + '_', value ) def get_editor ( self, trait ): from traitsui.api import TextEditor, CompoundEditor the_editors = [ x.get_editor( trait ) for x in self.handlers ] text_editor = TextEditor() count = 0 editors = [] for editor in the_editors: if isinstance( text_editor, editor.__class__ ): count += 1 if count > 1: continue editors.append( editor ) return CompoundEditor( editors = editors ) def items_event ( self ): return items_event() #------------------------------------------------------------------------------- # 'TraitTuple' class: #------------------------------------------------------------------------------- class TraitTuple ( TraitHandler ): """ Ensures that values assigned to a trait attribute are tuples of a specified length, with elements that are of specified types. TraitTuple is the underlying handler for the predefined trait **Tuple**, and the trait factory Tuple(). For example:: rank = Range(1, 13) suit = Trait('Hearts', 'Diamonds', 'Spades', 'Clubs') class Card(HasTraits): value = Trait(TraitTuple(rank, suit)) This example defines a Card class, which has a **value** trait attribute, which must be a tuple of two elments. The first element must be an integer in the range from 1 to 13, and the second element must be one of the four strings, 'Hearts', 'Diamonds', 'Spades', or 'Clubs'. """ def __init__ ( self, *args ): """ Creates a TraitTuple handler. Parameters ---------- args : list of traits Each *trait*\ :sub:`i` specifies the type that the *i*\ th element of a tuple must be. Description ----------- Each *trait*\ :sub:`i` must be either a trait, or a value that can be converted to a trait using the Trait() function. The resulting trait handler accepts values that are tuples of the same length as *args*, and whose *i*\ th element is of the type specified by *trait*\ :sub:`i`. """ self.types = tuple( [ trait_from( arg ) for arg in args ] ) self.fast_validate = ( 9, self.types ) def validate ( self, object, name, value ): try: if isinstance( value, tuple ): types = self.types if len( value ) == len( types ): values = [] for i, type in enumerate( types ): values.append( type.handler.validate( object, name, value[i] ) ) return tuple( values ) except: pass self.error( object, name, value ) def full_info ( self, object, name, value ): return 'a tuple of the form: (%s)' % (', '.join( [ self._trait_info( type, object, name, value ) for type in self.types ] )) def _trait_info ( self, type, object, name, value ): handler = type.handler if handler is None: return 'any value' return handler.full_info( object, name, value ) def get_editor ( self, trait ): from traitsui.api import TupleEditor return TupleEditor( types = self.types, labels = trait.labels or [], cols = trait.cols or 1 ) #------------------------------------------------------------------------------- # 'TraitCallable' class: #------------------------------------------------------------------------------- class TraitCallable ( TraitHandler ): """Ensures that the value of a trait attribute is a callable Python object (usually a function or method). """ def validate ( self, object, name, value ): if (value is None) or callable( value ): return value self.error( object, name, value ) def info ( self ): return 'a callable value' #------------------------------------------------------------------------------- # 'TraitListEvent' class: #------------------------------------------------------------------------------- class TraitListEvent ( object ): #--------------------------------------------------------------------------- # Initialize the object: #--------------------------------------------------------------------------- def __init__ ( self, index = 0, removed = None, added = None ): self.index = index if removed is None: removed = [] self.removed = removed if added is None: added = [] self.added = added #------------------------------------------------------------------------------- # 'TraitList' class: #------------------------------------------------------------------------------- class TraitList ( TraitHandler ): """ Ensures that a value assigned to a trait attribute is a list containing elements of a specified type, and that the length of the list is also within a specified range. TraitList also makes sure that any changes made to the list after it is assigned to the trait attribute do not violate the list's type and length constraints. TraitList is the underlying handler for the predefined list-based traits. For example:: class Card(HasTraits): pass class Hand(HasTraits): cards = Trait([], TraitList(Trait(Card), maxlen=52)) This example defines a Hand class, which has a **cards** trait attribute, which is a list of Card objects and can have from 0 to 52 items in the list. """ info_trait = None default_value_type = 5 _items_event = None def __init__ ( self, trait = None, minlen = 0, maxlen = sys.maxint, has_items = True ): """ Creates a TraitList handler. Parameters ---------- trait : trait The type of items the list can contain minlen : integer The minimum length of the list maxlen : integer The maximum length of the list has_items : boolean Flag indicating whether the list contains elements Description ----------- If *trait* is None or omitted, then no type checking is performed on any items in the list; otherwise, *trait* must be either a trait, or a value that can be converted to a trait using the Trait() function. """ self.item_trait = trait_from( trait ) self.minlen = max( 0, minlen ) self.maxlen = max( minlen, maxlen ) self.has_items = has_items def clone ( self ): return TraitList( self.item_trait, self.minlen, self.maxlen, self.has_items ) def validate ( self, object, name, value ): if (isinstance( value, list ) and (self.minlen <= len( value ) <= self.maxlen)): return TraitListObject( self, object, name, value ) self.error( object, name, value ) def full_info ( self, object, name, value ): if self.minlen == 0: if self.maxlen == sys.maxint: size = 'items' else: size = 'at most %d items' % self.maxlen else: if self.maxlen == sys.maxint: size = 'at least %d items' % self.minlen else: size = 'from %s to %s items' % ( self.minlen, self.maxlen ) handler = self.item_trait.handler if handler is None: info = '' else: info = ' which are %s' % handler.full_info( object, name, value ) return 'a list of %s%s' % ( size, info ) def get_editor ( self, trait ): handler = self.item_trait.handler if isinstance( handler, TraitInstance ) and (trait.mode != 'list'): from .api import HasTraits if issubclass( handler.aClass, HasTraits ): try: object = handler.aClass() from traitsui.table_column import ObjectColumn from traitsui.table_filter import (EvalFilterTemplate, RuleFilterTemplate, MenuFilterTemplate, EvalTableFilter) from traitsui.api import TableEditor return TableEditor( columns = [ ObjectColumn( name = name ) for name in object.editable_traits() ], filters = [ RuleFilterTemplate, MenuFilterTemplate, EvalFilterTemplate ], edit_view = '', orientation = 'vertical', search = EvalTableFilter(), deletable = True, row_factory = handler.aClass ) except: pass from traitsui.api import ListEditor return ListEditor( trait_handler = self, rows = trait.rows or 5, use_notebook = trait.use_notebook is True, page_name = trait.page_name or '' ) def items_event ( self ): return items_event() def items_event ( ): if TraitList._items_event is None: TraitList._items_event = \ Event( TraitListEvent, is_base = False ).as_ctrait() return TraitList._items_event #------------------------------------------------------------------------------- # 'TraitListObject' class: #------------------------------------------------------------------------------- class TraitListObject ( list ): def __init__ ( self, trait, object, name, value ): self.trait = trait self.object = ref( object ) self.name = name self.name_items = None if trait.has_items: self.name_items = name + '_items' # Do the validated 'setslice' assignment without raising an # 'items_changed' event: if trait.minlen <= len( value ) <= trait.maxlen: try: validate = trait.item_trait.handler.validate if validate is not None: value = [ validate( object, name, val ) for val in value ] list.__setslice__( self, 0, 0, value ) return except TraitError, excp: excp.set_prefix( 'Each element of the' ) raise excp self.len_error( len( value ) ) def _send_trait_items_event(self, name, event, items_event=None): """ Send a TraitListEvent to the owning object if there is one. """ object = self.object() if object is not None: if items_event is None and hasattr(self, 'trait'): items_event = self.trait.items_event() object.trait_items_event(name, event, items_event) def __deepcopy__ ( self, memo ): id_self = id( self ) if id_self in memo: return memo[ id_self ] memo[ id_self ] = result = TraitListObject( self.trait, lambda: None, self.name, [ copy.deepcopy( x, memo ) for x in self ] ) return result def __setitem__ ( self, key, value ): self_trait = getattr(self, 'trait', None) if self_trait is None: return list.__setitem__(self, key, value) try: removed = self[ key ] except: pass try: validate = self.trait.item_trait.handler.validate object = self.object() if validate is not None: value = validate( object, self.name, value ) list.__setitem__( self, key, value ) if self.name_items is not None: if key < 0: key = len( self ) + key try: if removed == value: return except: # Treat incomparable values as unequal: pass self._send_trait_items_event( self.name_items, TraitListEvent( key, [ removed ], [ value ] )) except TraitError, excp: excp.set_prefix( 'Each element of the' ) raise excp def __setslice__ ( self, i, j, values ): try: delta = len( values ) - (min( j, len( self ) ) - max( 0, i )) except: raise TypeError, 'must assign sequence (not "%s") to slice' % ( values.__class__.__name__ ) self_trait = getattr(self, 'trait', None) if self_trait is None: return list.__setslice__(self, i, j, values) if self_trait.minlen <= (len(self) + delta) <= self_trait.maxlen: try: object = self.object() name = self.name trait = self_trait.item_trait removed = self[ i: j ] validate = trait.handler.validate if validate is not None: values = [ validate( object, name, value ) for value in values ] list.__setslice__( self, i, j, values ) if self.name_items is not None: if delta == 0: try: if removed == values: return except: # Treat incomparable values as equal: pass self._send_trait_items_event( self.name_items, TraitListEvent( max( 0, i ), removed, values ) ) return except TraitError, excp: excp.set_prefix( 'Each element of the' ) raise excp self.len_error( len( self ) + delta ) def __delitem__ ( self, key ): trait = getattr(self, 'trait', None) if trait is None: return list.__delitem__(self, key) if self.trait.minlen <= (len( self ) - 1): try: removed = [ self[ key ] ] except: pass list.__delitem__( self, key ) if self.name_items is not None: if key < 0: key = len( self ) + key + 1 self._send_trait_items_event( self.name_items, TraitListEvent( key, removed ) ) return self.len_error( len( self ) - 1 ) def __delslice__ ( self, i, j ): trait = getattr(self, 'trait', None) if trait is None: return list.__delslice__(self, i, j) delta = min( j, len( self ) ) - max( 0, i ) if self.trait.minlen <= (len( self ) - delta): removed = self[ i: j ] list.__delslice__( self, i, j ) if (self.name_items is not None) and (len( removed ) != 0): self._send_trait_items_event( self.name_items, TraitListEvent( max( 0, i ), removed ) ) return self.len_error( len( self ) - delta ) def append ( self, value ): trait = getattr( self, 'trait', None ) if trait is None: list.append( self, value ) return if trait.minlen <= (len( self ) + 1) <= trait.maxlen: try: validate = trait.item_trait.handler.validate object = self.object() if validate is not None: value = validate( object, self.name, value ) list.append( self, value ) if self.name_items is not None: self._send_trait_items_event( self.name_items, TraitListEvent( len( self ) - 1, None, [ value ] ), trait.items_event() ) return except TraitError, excp: excp.set_prefix( 'Each element of the' ) raise excp self.len_error( len( self ) + 1 ) def insert ( self, index, value ): trait = getattr( self, 'trait', None ) if trait is None: return list.insert(self, index, value) if trait.minlen <= (len( self ) + 1) <= trait.maxlen: try: validate = trait.item_trait.handler.validate object = self.object() if validate is not None: value = validate( object, self.name, value ) list.insert( self, index, value ) if self.name_items is not None: if index < 0: index = len( self ) + index - 1 self._send_trait_items_event( self.name_items, TraitListEvent( index, None, [ value ] ), trait.items_event() ) return except TraitError, excp: excp.set_prefix( 'Each element of the' ) raise excp self.len_error( len( self ) + 1 ) def extend ( self, xlist ): trait = getattr( self, 'trait', None ) if trait is None: list.extend( self, xlist ) return try: len_xlist = len( xlist ) except: raise TypeError, "list.extend() argument must be iterable" if (trait.minlen <= (len( self ) + len_xlist) <= trait.maxlen): object = self.object() name = self.name validate = trait.item_trait.handler.validate try: if validate is not None: xlist = [ validate( object, name, value ) for value in xlist ] list.extend( self, xlist ) if (self.name_items is not None) and (len( xlist ) != 0): self._send_trait_items_event( self.name_items, TraitListEvent( len( self ) - len( xlist ), None, xlist ), trait.items_event() ) return except TraitError, excp: excp.set_prefix( 'The elements of the' ) raise excp self.len_error( len( self ) + len( xlist ) ) def remove ( self, value ): trait = getattr(self, 'trait', None) if trait is None: list.remove(self, value) return if trait.minlen < len( self ): try: index = self.index( value ) removed = [ self[ index ] ] except: pass list.remove( self, value ) if self.name_items is not None: self._send_trait_items_event( self.name_items, TraitListEvent( index, removed ) ) else: self.len_error( len( self ) - 1 ) def sort ( self, cmp = None, key = None, reverse = False ): removed = self[:] list.sort( self, cmp = cmp, key = key, reverse = reverse ) if (getattr(self, 'name_items', None) is not None and getattr(self, 'trait', None) is not None): self._send_trait_items_event( self.name_items, TraitListEvent( 0, removed, self[:] ) ) def reverse ( self ): removed = self[:] if len( self ) > 1: list.reverse( self ) if self.name_items is not None: self._send_trait_items_event( self.name_items, TraitListEvent( 0, removed, self[:] ) ) def pop ( self, *args ): if not hasattr(self, 'trait'): return list.pop(self, *args) if self.trait.minlen < len( self ): if len( args ) > 0: index = args[0] else: index = -1 try: removed = [ self[ index ] ] except: pass result = list.pop( self, *args ) if self.name_items is not None: if index < 0: index = len( self ) + index + 1 self._send_trait_items_event( self.name_items, TraitListEvent( index, removed ) ) return result else: self.len_error( len( self ) - 1 ) def rename ( self, name ): trait = self.object()._trait( name, 0 ) if trait is not None: self.name = name self.trait = trait.handler def len_error ( self, len ): raise TraitError( "The '%s' trait of %s instance must be %s, " "but you attempted to change its length to %d element%s." % ( self.name, class_of( self.object() ), self.trait.full_info( self.object(), self.name, Undefined ), len, 's'[ len == 1: ] ) ) def __getstate__ ( self ): result = self.__dict__.copy() result.pop('object', None) result.pop('trait', None) return result def __setstate__ ( self, state ): name = state.setdefault('name', '') object = state.pop( 'object', None ) if object is not None: self.object = ref( object ) self.rename( name ) else: self.object = lambda: None self.__dict__.update( state ) #------------------------------------------------------------------------------- # 'TraitSetEvent' class: #------------------------------------------------------------------------------- class TraitSetEvent ( object ): #--------------------------------------------------------------------------- # Initialize the object: #--------------------------------------------------------------------------- def __init__ ( self, removed = None, added = None ): if removed is None: removed = set() self.removed = removed if added is None: added = set() self.added = added #------------------------------------------------------------------------------- # 'TraitSetObject' class: #------------------------------------------------------------------------------- class TraitSetObject ( set ): def __init__ ( self, trait, object, name, value ): self.trait = trait self.object = ref( object ) self.name = name self.name_items = None if trait.has_items: self.name_items = name + '_items' # Validate and assign the initial set value: try: validate = trait.item_trait.handler.validate if validate is not None: value = [ validate( object, name, val ) for val in value ] super( TraitSetObject, self ).__init__( value ) return except TraitError, excp: excp.set_prefix( 'Each element of the' ) raise excp def _send_trait_items_event(self, name, event, items_event=None): """ Send a TraitDictEvent to the owning object if there is one. """ object = self.object() if object is not None: if items_event is None and hasattr(self, 'trait'): items_event = self.trait.items_event() object.trait_items_event(name, event, items_event) def __deepcopy__ ( self, memo ): id_self = id( self ) if id_self in memo: return memo[ id_self ] memo[ id_self ] = result = TraitSetObject( self.trait, lambda: None, self.name, [ copy.deepcopy( x, memo ) for x in self ] ) return result def update ( self, value ): if not hasattr(self, 'trait'): return set.update(self, value) try: added = value.difference( self ) if len( added ) > 0: object = self.object() validate = self.trait.item_trait.handler.validate if validate is not None: name = self.name added = set( [ validate( object, name, item ) for item in added ] ) set.update( self, added ) if self.name_items is not None: self._send_trait_items_event( self.name_items, TraitSetEvent( None, added ) ) except TraitError, excp: excp.set_prefix( 'Each element of the' ) raise excp def intersection_update ( self, value ): removed = self.difference( value ) if len( removed ) > 0: set.difference_update( self, removed ) if self.name_items is not None: self._send_trait_items_event( self.name_items, TraitSetEvent( removed ) ) def difference_update ( self, value ): removed = self.intersection( value ) if len( removed ) > 0: set.difference_update( self, removed ) if self.name_items is not None: self._send_trait_items_event( self.name_items, TraitSetEvent( removed ) ) def symmetric_difference_update ( self, value ): if not hasattr(self, 'trait'): return set.symmetric_difference_update(self, value) removed = self.intersection( value ) added = value.difference( self ) if (len( removed ) > 0) or (len( added ) > 0): object = self.object() set.difference_update( self, removed ) if len( added ) > 0: validate = self.trait.item_trait.handler.validate if validate is not None: name = self.name added = set( [ validate( object, name, item ) for item in added ] ) set.update( self, added ) if self.name_items is not None: self._send_trait_items_event( self.name_items, TraitSetEvent( removed, added ) ) def add ( self, value ): if not hasattr(self, 'trait'): return set.add(self, value) if value not in self: try: object = self.object() validate = self.trait.item_trait.handler.validate if validate is not None: value = validate( object, self.name, value ) set.add( self, value ) if self.name_items is not None: self._send_trait_items_event( self.name_items, TraitSetEvent( None, set( [ value ] ) ) ) except TraitError, excp: excp.set_prefix( 'Each element of the' ) raise excp def remove ( self, value ): set.remove( self, value ) if self.name_items is not None: self._send_trait_items_event( self.name_items, TraitSetEvent( set( [ value ] ) ) ) def discard ( self, value ): if value in self: self.remove( value ) def pop ( self ): value = set.pop( self ) if self.name_items is not None: self._send_trait_items_event( self.name_items, TraitSetEvent( set( [ value ] ) ) ) return value def clear ( self ): removed = set( self ) set.clear( self ) if self.name_items is not None: self._send_trait_items_event( self.name_items, TraitSetEvent( removed ) ) def __reduce_ex__(self, protocol=None): """ Overridden to make sure we call our custom __getstate__. """ return (copy_reg._reconstructor, (type(self), set, list(self)), self.__getstate__()) def __getstate__ ( self ): result = self.__dict__.copy() result.pop('object', None) result.pop('trait', None) return result def __setstate__ ( self, state ): name = state.setdefault('name', '') object = state.pop( 'object', None ) if object is not None: self.object = ref( object ) self.rename( name ) else: self.object = lambda: None self.__dict__.update( state ) #------------------------------------------------------------------------------- # 'TraitDictEvent' class: #------------------------------------------------------------------------------- class TraitDictEvent ( object ): def __init__ ( self, added = None, changed = None, removed = None ): """ Parameters ---------- added : dictionary New keys and values changed : dictionary Updated keys and their previous values removed : dictionary Old keys and values that were just removed """ # Construct new empty dicts every time instead of using a default value # in the method argument, just in case someone gets the bright idea of # modifying the dict they get in-place. if added is None: added = {} self.added = added if changed is None: changed = {} self.changed = changed if removed is None: removed = {} self.removed = removed #------------------------------------------------------------------------------- # 'TraitDict' class: #------------------------------------------------------------------------------- class TraitDict ( TraitHandler ): """ Ensures that values assigned to a trait attribute are dictionaries whose keys and values are of specified types. TraitDict also makes sure that any changes to keys or values made that are made after the dictionary is assigned to the trait attribute satisfy the type constraints. TraitDict is the underlying handler for the dictionary-based predefined traits, and the Dict() trait factory. For example:: class WorkoutClass(HasTraits): member_weights = Trait({}, TraitDict(str, float)) This example defines a WorkoutClass class containing a *member_weights* trait attribute whose value must be a dictionary containing keys that are strings (i.e., the members' names) and whose associated values must be floats (i.e., their most recently recorded weight). """ info_trait = None default_value_type = 6 _items_event = None def __init__ ( self, key_trait = None, value_trait = None, has_items = True ): """ Creates a TraitDict handler. Parameters ---------- key_trait : trait The type for the dictionary keys value_trait : trait The type for the dictionary values has_items : boolean Flag indicating whether the dictionary contains entries Description ----------- If *key_trait* is None or omitted, the keys in the dictionary can be of any type. Otherwise, *key_trait* must be either a trait, or a value that can be converted to a trait using the Trait() function. In this case, all dictionary keys are checked to ensure that they are of the type specified by *key_trait*. If *value_trait* is None or omitted, the values in the dictionary can be of any type. Otherwise, *value_trait* must be either a trait, or a value that can be converted to a trait using the Trait() function. In this case, all dictionary values are checked to ensure that they are of the type specified by *value_trait*. """ self.key_trait = trait_from( key_trait ) self.value_trait = trait_from( value_trait ) self.has_items = has_items handler = self.value_trait.handler if handler.has_items: handler = handler.clone() handler.has_items = False self.value_handler = handler def clone ( self ): return TraitDict( self.key_trait, self.value_trait, self.has_items ) def validate ( self, object, name, value ): if isinstance( value, dict ): return TraitDictObject( self, object, name, value ) self.error( object, name, value ) def full_info ( self, object, name, value ): extra = '' handler = self.key_trait.handler if handler is not None: extra = (' with keys which are %s' % handler.full_info( object, name, value)) handler = self.value_handler if handler is not None: if extra == '': extra = ' with' else: extra += ' and' extra += (' values which are %s' % handler.full_info( object, name, value )) return 'a dictionary%s' % extra def get_editor ( self, trait ): if self.editor is None: from traitsui.api import TextEditor self.editor = TextEditor( evaluate = eval ) return self.editor def items_event ( self ): if TraitDict._items_event is None: TraitDict._items_event = \ Event( TraitDictEvent, is_base = False ).as_ctrait() return TraitDict._items_event #------------------------------------------------------------------------------- # 'TraitDictObject' class: #------------------------------------------------------------------------------- class TraitDictObject ( dict ): def __init__ ( self, trait, object, name, value ): self.trait = trait self.object = ref( object ) self.name = name self.name_items = None if trait.has_items: self.name_items = name + '_items' if len( value ) > 0: dict.update( self, self._validate_dic( value ) ) def _send_trait_items_event(self, name, event, items_event=None): """ Send a TraitDictEvent to the owning object if there is one. """ object = self.object() if object is not None: if items_event is None and hasattr(self, 'trait'): items_event = self.trait.items_event() object.trait_items_event(name, event, items_event) def __deepcopy__ ( self, memo ): id_self = id( self ) if id_self in memo: return memo[ id_self ] memo[ id_self ] = result = TraitDictObject( self.trait, lambda: None, self.name, dict([ copy.deepcopy( x, memo ) for x in self.iteritems() ]) ) return result def __setitem__ ( self, key, value ): trait = getattr( self, 'trait', None ) if trait is None: dict.__setitem__( self, key, value ) return object = self.object() try: validate = trait.key_trait.handler.validate if validate is not None: key = validate( object, self.name, key ) except TraitError, excp: excp.set_prefix( 'Each key of the' ) raise excp try: validate = trait.value_handler.validate if validate is not None: value = validate( object, self.name, value ) if self.name_items is not None: if dict.has_key( self, key ): added = None old = self[ key ] changed = { key: old } else: added = { key: value } changed = None dict.__setitem__( self, key, value ) if self.name_items is not None: if added is None: try: if old == value: return except: # Treat incomparable objects as unequal: pass self._send_trait_items_event( self.name_items, TraitDictEvent( added, changed ), trait.items_event() ) except TraitError, excp: excp.set_prefix( 'Each value of the' ) raise excp def __delitem__ ( self, key ): if self.name_items is not None: removed = { key: self[ key ] } dict.__delitem__( self, key ) if self.name_items is not None: self._send_trait_items_event( self.name_items, TraitDictEvent( removed = removed ) ) def clear ( self ): if len( self ) > 0: if self.name_items is not None: removed = self.copy() dict.clear( self ) if self.name_items is not None: self._send_trait_items_event( self.name_items, TraitDictEvent( removed = removed ) ) def update ( self, dic ): trait = getattr( self, 'trait', None ) if trait is None: dict.update( self, dic ) return if len( dic ) > 0: new_dic = self._validate_dic( dic ) if self.name_items is not None: added = {} changed = {} for key, value in new_dic.iteritems(): if key in self: changed[ key ] = self[ key ] else: added[ key ] = value dict.update( self, new_dic ) self._send_trait_items_event( self.name_items, TraitDictEvent( added = added, changed = changed ) ) else: dict.update( self, new_dic ) def setdefault ( self, key, value = None ): if self.has_key( key ): return self[ key ] self[ key ] = value result = self[ key ] if self.name_items is not None: self._send_trait_items_event( self.name_items, TraitDictEvent( added = { key: result } ) ) return result def pop ( self, key, value = Undefined ): if (value is Undefined) or self.has_key( key ): result = dict.pop( self, key ) if self.name_items is not None: self._send_trait_items_event( self.name_items, TraitDictEvent( removed = { key: result } ) ) return result return value def popitem ( self ): result = dict.popitem( self ) if self.name_items is not None: self._send_trait_items_event( self.name_items, TraitDictEvent( removed = { result[0]: result[1] } ) ) return result def rename ( self, name ): trait = self.object()._trait( name, 0 ) if trait is not None: self.name = name self.trait = trait.handler else: logger.debug( "rename: No 'trait' in %s for '%s'" % ( self.object(), name ) ) def __getstate__ ( self ): result = self.__dict__.copy() result.pop('object', None) result.pop('trait', None) return result def __setstate__ ( self, state ): name = state.setdefault('name', '') object = state.pop( 'object', None ) if object is not None: self.object = ref( object ) self.rename( name ) else: self.object = lambda: None self.__dict__.update( state ) #-- Private Methods ------------------------------------------------------------ def _validate_dic ( self, dic ): name = self.name new_dic = {} key_validate = self.trait.key_trait.handler.validate if key_validate is None: key_validate = lambda object, name, key: key value_validate = self.trait.value_trait.handler.validate if value_validate is None: value_validate = lambda object, name, value: value object = self.object() for key, value in dic.iteritems(): try: key = key_validate( object, name, key ) except TraitError, excp: excp.set_prefix( 'Each key of the' ) raise excp try: value = value_validate( object, name, value ) except TraitError, excp: excp.set_prefix( 'Each value of the' ) raise excp new_dic[ key ] = value return new_dic #------------------------------------------------------------------------------- # Tell the C-based traits module about 'TraitListObject', 'TraitSetObject and # 'TraitDictObject', and the PyProtocols 'adapt' function: #------------------------------------------------------------------------------- from . import ctraits ctraits._list_classes( TraitListObject, TraitSetObject, TraitDictObject ) ctraits._adapt( adapt ) traits-4.1.0/traits/tests/0000755000175100001440000000000011674463323016464 5ustar ischnellusers00000000000000traits-4.1.0/traits/tests/array_test_case.py0000644000175100001440000000263211674463323022211 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # Copyright (c) 2005, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # Thanks for using Enthought open source! #------------------------------------------------------------------------------ from __future__ import absolute_import import unittest from numpy import array, concatenate, zeros from ..api import Array, Bool, HasTraits class Foo( HasTraits ): a = Array() event_fired = Bool(False) def _a_changed(self): self.event_fired = True class ArrayTestCase( unittest.TestCase ): """ Test cases for delegated traits. """ def test_zero_to_one_element(self): """ Test that an event fires when an Array trait changes from zero to one element. """ f = Foo() f.a = zeros((2,), float) f.event_fired = False # Change the array. f.a = concatenate((f.a, array([100]))) # Confirm that the static trait handler was invoked. self.assertEqual( f.event_fired, True ) return #### EOF ###################################################################### traits-4.1.0/traits/tests/test_listeners.py0000644000175100001440000001066511674463323022115 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # Test the 'add_trait_listener', 'remove_trait_listener' interface to # the HasTraits class. # # Written by: David C. Morrill # # Date: 09/07/2005 # # (c) Copyright 2005 by Enthought, Inc. # # Copyright (c) 2007, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # ListenEventsicense included in /LICENSE.txt and may be redistributed # only under the conditions described in the aforementioned license. The # license is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from __future__ import absolute_import import unittest from ..api import HasTraits, Str, Int, Float #------------------------------------------------------------------------------- # 'GenerateEvents' class: #------------------------------------------------------------------------------- class GenerateEvents ( HasTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- name = Str age = Int weight = Float #------------------------------------------------------------------------------- # 'ListenEvents' class: #------------------------------------------------------------------------------- events = {} # dict of events class ListenEvents ( HasTraits ): #--------------------------------------------------------------------------- # 'GenerateEvents' event interface: # the events are stored in the dict 'events' #--------------------------------------------------------------------------- def _name_changed ( self, object, name, old, new ): events["_name_changed"] = (name, old, new) def _age_changed ( self, object, name, old, new ): events["_age_changed"] = (name, old, new) def _weight_changed ( self, object, name, old, new ): events["_weight_changed"] = (name, old, new) def alt_name_changed ( self, object, name, old, new ): events["alt_name_changed"] = (name, old, new) def alt_weight_changed ( self, object, name, old, new ): events["alt_weight_changed"] = (name, old, new) #------------------------------------------------------------------------------- # unit test class: #------------------------------------------------------------------------------- class Test_Listeners ( unittest.TestCase ): def test(self): global events # FIXME: comparing floats ge = GenerateEvents() le = ListenEvents() # Starting test: No Listeners ge.set( name = 'Joe', age = 22, weight = 152.0 ) # Adding default listener ge.add_trait_listener( le ) events = {} ge.set( name = 'Mike', age = 34, weight = 178.0 ) self.assertEqual(events, { '_age_changed': ('age', 22, 34), '_weight_changed': ('weight', 152.0, 178.0), '_name_changed': ('name', 'Joe', 'Mike'), }) # Adding alternate listener ge.add_trait_listener( le, 'alt' ) events = {} ge.set( name = 'Gertrude', age = 39, weight = 108.0 ) self.assertEqual(events, { '_age_changed': ('age', 34, 39), '_name_changed': ('name', 'Mike', 'Gertrude'), '_weight_changed': ('weight', 178.0, 108.0), 'alt_name_changed': ('name', 'Mike', 'Gertrude'), 'alt_weight_changed': ('weight', 178.0, 108.0), }) # Removing default listener ge.remove_trait_listener( le ) events = {} ge.set( name = 'Sally', age = 46, weight = 118.0 ) self.assertEqual(events, { 'alt_name_changed': ('name', 'Gertrude', 'Sally'), 'alt_weight_changed': ('weight', 108.0, 118.0), }) # Removing alternate listener ge.remove_trait_listener( le, 'alt' ) events = {} ge.set( name = 'Ralph', age = 29, weight = 198.0 ) self.assertEqual(events, {}) # Run the unit tests (if invoked from the command line): if __name__ == '__main__': unittest.main() traits-4.1.0/traits/tests/rich_compare_test_case.py0000644000175100001440000001336311674463323023531 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # Copyright (c) 2007, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # #------------------------------------------------------------------------------- from __future__ import absolute_import import unittest from ..api import HasTraits, Any, Str class IdentityCompare(HasTraits): bar = Any(rich_compare=False) class RichCompare(HasTraits): bar = Any(rich_compare=True) class RichCompareTests: def bar_changed(self, object, trait, old, new): self.changed_object = object self.changed_trait = trait self.changed_old = old self.changed_new = new self.changed_count += 1 def reset_change_tracker(self): self.changed_object = None self.changed_trait = None self.changed_old = None self.changed_new = None self.changed_count = 0 def check_tracker(self, object, trait, old, new, count): self.failUnlessEqual( count, self.changed_count ) self.failUnless( object is self.changed_object ) self.failUnlessEqual( trait, self.changed_trait ) self.failUnless( old is self.changed_old ) self.failUnless( new is self.changed_new ) return def test_id_first_assignment(self): ic = IdentityCompare() ic.on_trait_change( self.bar_changed, 'bar' ) self.reset_change_tracker() default_value = ic.bar ic.bar = self.a self.check_tracker( ic, 'bar', default_value, self.a, 1 ) return def test_rich_first_assignment(self): rich = RichCompare() rich.on_trait_change( self.bar_changed, 'bar' ) self.reset_change_tracker() default_value = rich.bar rich.bar = self.a self.check_tracker( rich, 'bar', default_value, self.a, 1 ) return def test_id_same_object(self): ic = IdentityCompare() ic.on_trait_change( self.bar_changed, 'bar' ) self.reset_change_tracker() default_value = ic.bar ic.bar = self.a self.check_tracker( ic, 'bar', default_value, self.a, 1 ) ic.bar = self.a self.check_tracker( ic, 'bar', default_value, self.a, 1 ) return def test_rich_same_object(self): rich = RichCompare() rich.on_trait_change( self.bar_changed, 'bar' ) self.reset_change_tracker() default_value = rich.bar rich.bar = self.a self.check_tracker( rich, 'bar', default_value, self.a, 1 ) rich.bar = self.a self.check_tracker( rich, 'bar', default_value, self.a, 1 ) return def test_id_different_object(self): ic = IdentityCompare() ic.on_trait_change( self.bar_changed, 'bar' ) self.reset_change_tracker() default_value = ic.bar ic.bar = self.a self.check_tracker( ic, 'bar', default_value, self.a, 1 ) ic.bar = self.different_from_a self.check_tracker( ic, 'bar', self.a, self.different_from_a, 2 ) return def test_rich_different_object(self): rich = RichCompare() rich.on_trait_change( self.bar_changed, 'bar' ) self.reset_change_tracker() default_value = rich.bar rich.bar = self.a self.check_tracker( rich, 'bar', default_value, self.a, 1 ) rich.bar = self.different_from_a self.check_tracker( rich, 'bar', self.a, self.different_from_a, 2 ) return def test_id_different_object_same_as(self): ic = IdentityCompare() ic.on_trait_change( self.bar_changed, 'bar' ) self.reset_change_tracker() default_value = ic.bar ic.bar = self.a self.check_tracker( ic, 'bar', default_value, self.a, 1 ) ic.bar = self.same_as_a self.check_tracker( ic, 'bar', self.a, self.same_as_a, 2 ) return def test_rich_different_object_same_as(self): rich = RichCompare() rich.on_trait_change( self.bar_changed, 'bar' ) self.reset_change_tracker() default_value = rich.bar rich.bar = self.a self.check_tracker( rich, 'bar', default_value, self.a, 1 ) # Values of a and same_as_a are the same and should therefore not # be considered a change. rich.bar = self.same_as_a self.check_tracker( rich, 'bar', default_value, self.a, 1 ) return class Foo(HasTraits): name = Str def __ne__(self, other): # Traits uses != to do the rich compare. The default implementation # of __ne__ is to compare the object identities. return self.name != other.name def __eq__(self, other): # Not required, but a good idea to make __eq__ and __ne__ compatible return self.name == other.name class RichCompareHasTraitsTestCase(unittest.TestCase, RichCompareTests): def setUp(self): self.a = Foo(name='a') self.same_as_a = Foo(name='a') self.different_from_a = Foo(name='not a') # print '\na' # self.a.print_traits() # print '\nsame_as_a' # self.same_as_a.print_traits() # print '\ndifferent_from_a' # self.different_from_a.print_traits() return def test_assumptions(self): self.failIf( self.a is self.same_as_a ) self.failIf( self.a is self.different_from_a ) self.failUnless( self.a.name == self.same_as_a.name ) self.failIf( self.a.name == self.different_from_a.name ) return ### EOF traits-4.1.0/traits/tests/container_events_test_case.py0000644000175100001440000001206211674463323024437 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # Copyright (c) 2007, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # #------------------------------------------------------------------------------- """ Tests for Dict and List items_changed events """ from __future__ import absolute_import import unittest from ..api import HasTraits, Dict, List class ListEventTestCase(unittest.TestCase): # TODO: Implement this! pass class MyClass(HasTraits): """ A dummy HasTraits class with a Dict """ d = Dict({"a": "apple", "b": "banana", "c": "cherry", "d": "durian" }) def __init__(self, callback): "The callback is called with the TraitDictEvent instance" self.callback = callback return def _d_items_changed(self, event): if self.callback: self.callback(event) return class MyOtherClass(HasTraits): """ A dummy HasTraits class with a Dict """ d = Dict({"a": "apple", "b": "banana", "c": "cherry", "d": "durian" }) class Callback: """ A stateful callback that gets initialized with the values to check for """ def __init__(self, obj, added={}, changed={}, removed={}): self.obj = obj self.added = added self.changed = changed self.removed = removed self.called = False return def __call__(self, event): if event.added != self.added: print "\n\n******Error\nevent.added:", event.added else: self.obj.assert_(event.added == self.added) self.obj.assert_(event.changed == self.changed) self.obj.assert_(event.removed == self.removed) self.called = True return class DictEventTestCase(unittest.TestCase): def test_setitem(self): # overwriting an existing item cb = Callback(self, changed={"c":"cherry"}) foo = MyClass(cb) foo.d["c"] = "coconut" self.assert_(cb.called) # adding a new item cb = Callback(self, added={"g":"guava"}) bar = MyClass(cb) bar.d["g"] = "guava" self.assert_(cb.called) return def test_delitem(self): cb = Callback(self, removed={"b":"banana"}) foo = MyClass(cb) del foo.d["b"] self.assert_(cb.called) return def test_clear(self): removed = MyClass(None).d.copy() cb = Callback(self, removed=removed) foo = MyClass(cb) foo.d.clear() self.assert_(cb.called) return def test_update(self): update_dict = {"a":"artichoke", "f": "fig"} cb = Callback(self, changed={"a":"apple"}, added={"f":"fig"}) foo = MyClass(cb) foo.d.update(update_dict) self.assert_(cb.called) return def test_setdefault(self): # Test retrieving an existing value cb = Callback(self) foo = MyClass(cb) self.assert_(foo.d.setdefault("a", "dummy") == "apple") self.assert_(not cb.called) # Test adding a new value cb = Callback(self, added={"f":"fig"}) bar = MyClass(cb) self.assert_(bar.d.setdefault("f", "fig") == "fig") self.assert_(cb.called) return def test_pop(self): # Test popping a non-existent key cb = Callback(self) foo = MyClass(cb) self.assert_(foo.d.pop("x", "dummy") == "dummy") self.assert_(not cb.called) # Test popping a regular item cb = Callback(self, removed={"c": "cherry"}) bar = MyClass(cb) self.assert_(bar.d.pop("c") == "cherry") self.assert_(cb.called) return def test_popitem(self): foo = MyClass(None) foo.d.clear() foo.d["x"] = "xylophone" cb = Callback(self, removed={"x":"xylophone"}) foo.callback = cb self.assert_(foo.d.popitem() == ("x", "xylophone")) self.assert_(cb.called) return def test_dynamic_listener(self): foo = MyOtherClass() # Test adding func = Callback(self, added={"g":"guava"}) foo.on_trait_change(func.__call__, "d_items") foo.d["g"] = "guava" foo.on_trait_change(func.__call__, "d_items", remove=True) self.assert_(func.called) # Test removing func2 = Callback(self, removed={"a":"apple"}) foo.on_trait_change(func2.__call__, "d_items") del foo.d["a"] foo.on_trait_change(func2.__call__, "d_items", remove=True) self.assert_(func2.called) # Test changing func3 = Callback(self, changed={"b":"banana"}) foo.on_trait_change(func3.__call__, "d_items") foo.d["b"] = "broccoli" foo.on_trait_change(func3.__call__, "d_items", remove=True) self.assert_(func3.called) return traits-4.1.0/traits/tests/test_interfaces.py0000644000175100001440000002146111674463323022224 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # Unit test case for testing interfaces and adaptation. # # Written by: David C. Morrill # # Date: 4/10/2007 # # Copyright (c) 2007, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # #------------------------------------------------------------------------------- """ Unit test case for testing interfaces and adaptation. """ #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from __future__ import absolute_import import unittest from ..api import (HasTraits, Interface, Adapter, Instance, Int, List, TraitError, AdaptedTo, adapts, implements) #------------------------------------------------------------------------------- # Test 'Interface' definitions: #------------------------------------------------------------------------------- class IFoo(Interface): def get_foo(self): """ Returns the current foo. """ class IFooPlus(IFoo): def get_foo_plus(self): """ Returns even more foo. """ class IAverage(Interface): def get_average(self): """ Returns the average value for the object. """ class IList(Interface): def get_list(self): """ Returns the list value for the object. """ #------------------------------------------------------------------------------- # Test 'model' classes: #------------------------------------------------------------------------------- class Sample ( HasTraits ): s1 = Int( 1, sample = True ) s2 = Int( 2, sample = True ) s3 = Int( 3, sample = True ) i1 = Int( 4 ) i2 = Int( 5 ) i3 = Int( 6 ) class SampleList ( HasTraits ): implements( IList ) data = List( Int, [ 10, 20, 30 ] ) def get_list ( self ): return self.data class SampleAverage ( HasTraits ): implements( IList, IAverage ) data = List( Int, [ 100, 200, 300 ] ) def get_list ( self ): return self.data def get_average ( self ): value = self.get_list() if len( value ) == 0: return 0.0 average = 0.0 for item in value: average += item return (average / len( value )) class SampleBad ( HasTraits ): pass #------------------------------------------------------------------------------- # Test interfaces class: #------------------------------------------------------------------------------- class TraitsHolder ( HasTraits ): a_no = Instance( IAverage, adapt = 'no' ) a_yes = Instance( IAverage, adapt = 'yes' ) a_default = Instance( IAverage, adapt = 'default' ) l_yes = AdaptedTo( IList ) f_yes = AdaptedTo( IFoo ) fp_yes = AdaptedTo( IFooPlus ) #------------------------------------------------------------------------------- # Test 'adapter' definitions: #------------------------------------------------------------------------------- class SampleListAdapter ( Adapter ): adapts( Sample, IList ) def get_list ( self ): obj = self.adaptee return [ getattr( obj, name ) for name in obj.trait_names( sample = True ) ] class ListAverageAdapter ( Adapter ): adapts( IList, IAverage ) def get_average ( self ): value = self.adaptee.get_list() if len( value ) == 0: return 0.0 average = 0.0 for item in value: average += item return (average / len( value )) class SampleFooAdapter ( HasTraits ): adapts( Sample, IFoo ) object = Instance( Sample ) def __init__ ( self, object ): self.object = object def get_foo ( self ): object = self.object return (object.s1 + object.s2 + object.s3) class FooPlusAdapter ( object ): def __init__ ( self, obj ): self.obj = obj def get_foo ( self ): return self.obj.get_foo() def get_foo_plus ( self ): return (self.obj.get_foo() + 1) adapts( FooPlusAdapter, IFoo, IFooPlus ) #------------------------------------------------------------------------------- # 'InterfacesTest' unit test class: #------------------------------------------------------------------------------- class InterfacesTest ( unittest.TestCase ): #--------------------------------------------------------------------------- # Individual unit test methods: #--------------------------------------------------------------------------- def test_implements_none ( self ): class Test ( HasTraits ): implements() def test_implements_one ( self ): class Test ( HasTraits ): implements( IFoo ) def test_implements_multi ( self ): class Test ( HasTraits ): implements( IFoo, IAverage, IList ) def test_implements_extended ( self ): """ Ensure that subclasses of Interfaces imply the superinterface. """ class Test ( HasTraits ): implements( IFooPlus ) ta = TraitsHolder() ta.f_yes = Test() def test_implements_bad ( self ): self.assertRaises( TraitError, self.implements_bad ) def test_instance_adapt_no ( self ): ta = TraitsHolder() # Verify that SampleAverage() does not raise an error (it is an instance # of the IAverage interface). try: ta.a_no = SampleAverage() except TraitError: self.fail("Setting instance of interface should not require " \ "adaptation") # These are not instances of the IAverage interface, and therefore # cannot be set to the trait. self.assertRaises( TraitError, ta.set, a_no = SampleList() ) self.assertRaises( TraitError, ta.set, a_no = Sample() ) self.assertRaises( TraitError, ta.set, a_no = SampleBad() ) def test_instance_adapt_yes ( self ): ta = TraitsHolder() ta.a_yes = object = SampleAverage() self.assertEqual( ta.a_yes.get_average(), 200.0 ) self.assert_( isinstance( ta.a_yes, SampleAverage ) ) self.assertFalse( hasattr(ta, 'a_yes_') ) ta.a_yes = object = SampleList() self.assertEqual( ta.a_yes.get_average(), 20.0 ) self.assert_( isinstance( ta.a_yes, ListAverageAdapter ) ) self.assertFalse( hasattr(ta, 'a_yes_') ) ta.l_yes = object = Sample() result = ta.l_yes.get_list() self.assertEqual( len( result ), 3 ) for n in [ 1, 2, 3 ]: self.assert_( n in result ) self.assert_( isinstance( ta.l_yes, SampleListAdapter ) ) self.assertEqual( ta.l_yes_, object ) ta.a_yes = object = Sample() self.assertEqual( ta.a_yes.get_average(), 2.0 ) self.assert_( isinstance( ta.a_yes, ListAverageAdapter ) ) self.assertFalse( hasattr(ta, 'a_yes_') ) self.assertRaises( TraitError, ta.set, a_yes = SampleBad() ) ta.f_yes = object = Sample() self.assertEqual( ta.f_yes.get_foo(), 6 ) self.assert_( isinstance( ta.f_yes, SampleFooAdapter ) ) self.assertEqual( ta.f_yes_, object ) ta.fp_yes = object = Sample( s1 = 5, s2 = 10, s3 = 15 ) self.assertEqual( ta.fp_yes.get_foo(), 30 ) self.assertEqual( ta.fp_yes.get_foo_plus(), 31 ) self.assert_( isinstance( ta.fp_yes, FooPlusAdapter ) ) self.assertEqual( ta.fp_yes_, object ) def test_instance_adapt_default ( self ): ta = TraitsHolder() ta.a_default = object = SampleAverage() self.assertEqual( ta.a_default.get_average(), 200.0 ) self.assert_( isinstance( ta.a_default, SampleAverage ) ) self.assertFalse( hasattr(ta, 'a_default_') ) ta.a_default = object = SampleList() self.assertEqual( ta.a_default.get_average(), 20.0 ) self.assert_( isinstance( ta.a_default, ListAverageAdapter ) ) self.assertFalse( hasattr(ta, 'a_default_') ) ta.a_default = object = Sample() self.assertEqual( ta.a_default.get_average(), 2.0 ) self.assert_( isinstance( ta.a_default, ListAverageAdapter ) ) self.assertFalse( hasattr(ta, 'a_default_') ) ta.a_default = object = SampleBad() self.assertEqual( ta.a_default, None ) self.assertFalse( hasattr(ta, 'a_default_') ) #-- Helper Methods --------------------------------------------------------- def implements_bad ( self ): class Test ( HasTraits ): implements( Sample ) # Run the unit tests (if invoked from the command line): if __name__ == '__main__': unittest.main() traits-4.1.0/traits/tests/test_copyable_trait_names.py0000644000175100001440000000665711674463323024277 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # Copyright (c) 2007, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # #------------------------------------------------------------------------------- from __future__ import absolute_import import unittest from ..api import HasTraits, Any, Bool, Delegate, Event, Instance, Property, Str class Foo(HasTraits): a = Any b = Bool s = Str i = Instance(HasTraits) e = Event d = Delegate( 'i' ) p = Property def _get_p(self): return self._p def _set_p(self, p): self._p = p # Read Only Property p_ro = Property def _get_p_ro(self): return id(self) # Write-only property p_wo = Property def _set_p_wo(self, p_wo): self._p_wo = p_wo class TestCopyableTraitNames(unittest.TestCase): """ Validate that copyable_trait_names returns the appropriate result. """ def setUp(self): foo = Foo() self.names = foo.copyable_trait_names() def test_events_not_copyable(self): self.failIf('e' in self.names) def test_read_only_property_not_copyable(self): self.failIf('p_ro' in self.names) def test_write_only_property_not_copyable(self): self.failIf('p_wo' in self.names) def test_any_copyable(self): self.assert_('a' in self.names) def test_bool_copyable(self): self.assert_('b' in self.names) def test_str_copyable(self): self.assert_('s' in self.names) def test_instance_copyable(self): self.assert_('i' in self.names) def test_delegate_copyable(self): self.assert_('d' in self.names) def test_property_copyable(self): self.assert_('p' in self.names) class TestCopyableTraitNameQueries(unittest.TestCase): def setUp(self): self.foo = Foo() def test_type_query(self): names = self.foo.copyable_trait_names(**{ 'type': 'trait' }) self.failUnlessEqual(['a', 'i', 's', 'b'], names) names = self.foo.copyable_trait_names(**{ 'type': lambda t: t in ('trait', 'property',) }) self.failUnlessEqual(['a', 'p', 's', 'b', 'i'], names) def test_property_query(self): names = self.foo.copyable_trait_names(**{ 'property': lambda p: p() and p()[1].__name__ == '_set_p', }) self.assertEquals(['p'], names) def test_unmodified_query(self): names = self.foo.copyable_trait_names(**{ 'is_trait_type': lambda f: f(Str) }) self.assertEquals(['s'], names) def test_queries_not_combined(self): """ Verify that metadata is not merged with metadata to find the copyable traits. """ eval_true = lambda x: True names = self.foo.copyable_trait_names(property=eval_true, type=eval_true, transient=eval_true) self.assertEquals(['a', 'b', 'e', 'd', 'i', 'trait_added', 'p', 's', 'trait_modified', 'p_ro', 'p_wo'], names) ### EOF traits-4.1.0/traits/tests/test_trait_list_dict.py0000644000175100001440000000467611674463323023273 0ustar ischnellusers00000000000000""" Test the persistence behavior of TraitListObjects, TraitDictObjects and TraitSetObjects. """ from __future__ import absolute_import import copy from cPickle import dumps, loads from ..has_traits import HasTraits, on_trait_change from ..trait_types import Dict, List, Set, Str, Int, Instance class A(HasTraits): list = List(Int, range(5)) dict = Dict(Str, Int, dict(a=1, b=2)) set = Set(Int, range(5)) events = List() @on_trait_change('list_items,dict_items,set_items') def _receive_events(self, object, name, old, new): self.events.append((name, new)) class B(HasTraits): dict = Dict(Str, Instance(A)) def test_trait_list_object_persists(): a = A() list = loads(dumps(a.list)) assert list.object() is None list.append(10) assert len(a.events) == 0 a.list.append(20) assert len(a.events) == 1 list2 = loads(dumps(list)) assert list2.object() is None def test_trait_dict_object_persists(): a = A() dict = loads(dumps(a.dict)) assert dict.object() is None dict['key'] = 10 assert len(a.events) == 0 a.dict['key'] = 10 assert len(a.events) == 1 dict2 = loads(dumps(dict)) assert dict2.object() is None def test_trait_set_object_persists(): a = A() set = loads(dumps(a.set)) assert set.object() is None set.add(10) assert len(a.events) == 0 a.set.add(20) assert len(a.events) == 1 set2 = loads(dumps(set)) assert set2.object() is None def test_trait_list_object_copies(): a = A() list = copy.deepcopy(a.list) assert list.object() is None list.append(10) assert len(a.events) == 0 a.list.append(20) assert len(a.events) == 1 list2 = copy.deepcopy(list) list2.append(30) assert list2.object() is None def test_trait_dict_object_copies(): a = A() dict = copy.deepcopy(a.dict) assert dict.object() is None dict['key'] = 10 assert len(a.events) == 0 a.dict['key'] = 10 assert len(a.events) == 1 dict2 = copy.deepcopy(dict) dict2['key2'] = 20 assert dict2.object() is None def test_trait_set_object_copies(): a = A() set = copy.deepcopy(a.set) assert set.object() is None set.add(10) assert len(a.events) == 0 a.set.add(20) assert len(a.events) == 1 set2 = copy.deepcopy(set) set2.add(30) assert set2.object() is None def test_pickle_whole(): a = A() loads(dumps(a)) b = B(dict=dict(a=a)) loads(dumps(b)) traits-4.1.0/traits/tests/test_extended_trait_change.py0000644000175100001440000006317711674463323024423 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # Unit test case for testing HasTraits 'on_trait_change' support. # # Written by: David C. Morrill # # Date: 4/10/2007 # # (c) Copyright 2007 by Enthought, Inc. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- """ Unit test case for testing HasTraits 'on_trait_change' support. """ #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from __future__ import absolute_import import unittest from nose import SkipTest from ..api import (HasTraits, List, Dict, Int, Str, Any, Instance, Undefined, TraitError, TraitListEvent, TraitDictEvent, push_exception_handler, on_trait_change, Property, cached_property) from ..trait_handlers import TraitListObject, TraitDictObject #------------------------------------------------------------------------------- # Test support classes: #------------------------------------------------------------------------------- class ArgCheckBase ( HasTraits ): value = Int( 0 ) int1 = Int( 0, test = True ) int2 = Int( 0 ) int3 = Int( 0, test = True ) tint1 = Int( 0 ) tint2 = Int( 0, test = True ) tint3 = Int( 0 ) calls = Int( 0 ) tc = Any class ArgCheckSimple ( ArgCheckBase ): def arg_check0 ( self ): self.calls += 1 def arg_check1 ( self, new ): self.calls += 1 self.tc.assertEqual( new, self.value ) def arg_check2 ( self, name, new ): self.calls += 1 self.tc.assertEqual( name, 'value' ) self.tc.assertEqual( new, self.value ) def arg_check3 ( self, object, name, new ): self.calls += 1 self.tc.assert_( object is self ) self.tc.assertEqual( name, 'value' ) self.tc.assertEqual( new, self.value ) def arg_check4 ( self, object, name, old, new ): self.calls += 1 self.tc.assert_( object is self ) self.tc.assertEqual( name, 'value' ) self.tc.assertEqual( old, (self.value - 1) ) self.tc.assertEqual( new, self.value ) class ArgCheckDecorator ( ArgCheckBase ): @on_trait_change( 'value' ) def arg_check0 ( self ): self.calls += 1 @on_trait_change( 'value' ) def arg_check1 ( self, new ): self.calls += 1 self.tc.assertEqual( new, self.value ) @on_trait_change( 'value' ) def arg_check2 ( self, name, new ): self.calls += 1 self.tc.assertEqual( name, 'value' ) self.tc.assertEqual( new, self.value ) @on_trait_change( 'value' ) def arg_check3 ( self, object, name, new ): self.calls += 1 self.tc.assert_( object is self ) self.tc.assertEqual( name, 'value' ) self.tc.assertEqual( new, self.value ) @on_trait_change( 'value' ) def arg_check4 ( self, object, name, old, new ): self.calls += 1 self.tc.assert_( object is self ) self.tc.assertEqual( name, 'value' ) self.tc.assertEqual( old, (self.value - 1) ) self.tc.assertEqual( new, self.value ) class Instance1 ( HasTraits ): ref = Instance( ArgCheckBase, () ) calls = Int( 0 ) exp_object = Any exp_name = Any dst_name = Any exp_old = Any exp_new = Any dst_new = Any tc = Any @on_trait_change( 'ref.value' ) def arg_check0 ( self ): self.calls += 1 @on_trait_change( 'ref.value' ) def arg_check1 ( self, new ): self.calls += 1 self.tc.assertEqual( new, self.dst_new ) @on_trait_change( 'ref.value' ) def arg_check2 ( self, name, new ): self.calls += 1 self.tc.assertEqual( name, self.dst_name ) self.tc.assertEqual( new, self.dst_new ) @on_trait_change( 'ref.value' ) def arg_check3 ( self, object, name, new ): self.calls += 1 self.tc.assert_( object is self.exp_object ) self.tc.assertEqual( name, self.exp_name ) self.tc.assertEqual( new, self.exp_new ) @on_trait_change( 'ref.value' ) def arg_check4 ( self, object, name, old, new ): self.calls += 1 self.tc.assert_( object is self.exp_object ) self.tc.assertEqual( name, self.exp_name ) self.tc.assertEqual( old, self.exp_old ) self.tc.assertEqual( new, self.exp_new ) class List1 ( HasTraits ): refs = List( ArgCheckBase ) calls = Int( 0 ) exp_object = Any exp_name = Any type_old = Any exp_old = Any type_new = Any exp_new = Any tc = Any @on_trait_change( 'refs.value' ) def arg_check0 ( self ): self.calls += 1 @on_trait_change( 'refs.value' ) def arg_check3 ( self, object, name, new ): self.calls += 1 self.tc.assert_( object is self.exp_object ) self.tc.assertEqual( name, self.exp_name ) if self.type_new is None: self.tc.assertEqual( new, self.exp_new ) else: self.tc.assert_( isinstance( new, self.type_new ) ) @on_trait_change( 'refs.value' ) def arg_check4 ( self, object, name, old, new ): self.calls += 1 self.tc.assert_( object is self.exp_object ) self.tc.assertEqual( name, self.exp_name ) if self.type_old is None: self.tc.assertEqual( old, self.exp_old ) else: self.tc.assert_( isinstance( old, self.type_old ) ) if self.type_new is None: self.tc.assertEqual( new, self.exp_new ) else: self.tc.assert_( isinstance( new, self.type_new ) ) class List2 ( HasTraits ): refs = List( ArgCheckBase ) calls = Int( 0 ) exp_new = Any tc = Any @on_trait_change( 'refs.value' ) def arg_check1 ( self, new ): self.calls += 1 self.tc.assertEqual( new, self.exp_new ) class List3 ( HasTraits ): refs = List( ArgCheckBase ) calls = Int( 0 ) exp_name = Any exp_new = Any tc = Any @on_trait_change( 'refs.value' ) def arg_check2 ( self, name, new ): self.calls += 1 self.tc.assertEqual( name, self.exp_name ) self.tc.assertEqual( new, self.exp_new ) class Dict1 ( List1 ): refs = Dict( Int, ArgCheckBase ) class Dict2 ( HasTraits ): refs = Dict( Int, ArgCheckBase ) calls = Int( 0 ) exp_new = Any tc = Any @on_trait_change( 'refs.value' ) def arg_check1 ( self, new ): self.calls += 1 self.tc.assertEqual( new, self.exp_new ) class Dict3 ( HasTraits ): refs = Dict( Int, ArgCheckBase ) calls = Int( 0 ) exp_name = Any exp_new = Any tc = Any @on_trait_change( 'refs.value' ) def arg_check2 ( self, name, new ): self.calls += 1 self.tc.assertEqual( name, self.exp_name ) self.tc.assertEqual( new, self.exp_new ) class Complex ( HasTraits ): int1 = Int( 0, test = True ) int2 = Int( 0 ) int3 = Int( 0, test = True ) tint1 = Int( 0 ) tint2 = Int( 0, test = True ) tint3 = Int( 0 ) ref = Instance( ArgCheckBase, () ) calls = Int( 0 ) exp_object = Any exp_name = Any dst_name = Any exp_old = Any exp_new = Any dst_new = Any tc = Any def arg_check0 ( self ): self.calls += 1 def arg_check1 ( self, new ): self.calls += 1 self.tc.assertEqual( new, self.exp_new ) def arg_check2 ( self, name, new ): self.calls += 1 self.tc.assertEqual( name, self.exp_name ) self.tc.assertEqual( new, self.exp_new ) def arg_check3 ( self, object, name, new ): self.calls += 1 self.tc.assert_( object is self.exp_object ) self.tc.assertEqual( name, self.exp_name ) self.tc.assertEqual( new, self.exp_new ) def arg_check4 ( self, object, name, old, new ): self.calls += 1 self.tc.assert_( object is self.exp_object ) self.tc.assertEqual( name, self.exp_name ) self.tc.assertEqual( old, self.exp_old ) self.tc.assertEqual( new, self.exp_new ) class Link ( HasTraits ): next = Any prev = Any value = Int( 0 ) class LinkTest ( HasTraits ): head = Instance( Link ) calls = Int( 0 ) exp_object = Any exp_name = Any dst_name = Any exp_old = Any exp_new = Any dst_new = Any tc = Any def arg_check0 ( self ): self.calls += 1 def arg_check1 ( self, new ): self.calls += 1 self.tc.assertEqual( new, self.exp_new ) def arg_check2 ( self, name, new ): self.calls += 1 self.tc.assertEqual( name, self.exp_name ) self.tc.assertEqual( new, self.exp_new ) def arg_check3 ( self, object, name, new ): self.calls += 1 self.tc.assert_( object is self.exp_object ) self.tc.assertEqual( name, self.exp_name ) self.tc.assertEqual( new, self.exp_new ) def arg_check4 ( self, object, name, old, new ): self.calls += 1 self.tc.assert_( object is self.exp_object ) self.tc.assertEqual( name, self.exp_name ) self.tc.assertEqual( old, self.exp_old ) self.tc.assertEqual( new, self.exp_new ) class PropertyDependsOn ( HasTraits ): sum = Property( depends_on = 'ref.[int1,int2,int3]' ) ref = Instance( ArgCheckBase, () ) pcalls = Int( 0 ) calls = Int( 0 ) exp_old = Any exp_new = Any tc = Any @cached_property def _get_sum ( self ): self.pcalls += 1 r = self.ref return (r.int1 + r.int2 + r.int3) def _sum_changed ( self, old, new ): self.calls += 1 self.tc.assertEqual( old, self.exp_old ) self.tc.assertEqual( new, self.exp_new ) #------------------------------------------------------------------------------- # 'OnTraitChangeTest' unit test class: #------------------------------------------------------------------------------- class OnTraitChangeTest ( unittest.TestCase ): #-- Unit Test Methods ------------------------------------------------------ def test_arg_check_simple ( self ): ac = ArgCheckSimple( tc = self ) ac.on_trait_change( ac.arg_check0, 'value' ) ac.on_trait_change( ac.arg_check1, 'value' ) ac.on_trait_change( ac.arg_check2, 'value' ) ac.on_trait_change( ac.arg_check3, 'value' ) ac.on_trait_change( ac.arg_check4, 'value' ) for i in range( 3 ): ac.value += 1 self.assert_( ac.calls == (3 * 5) ) ac.on_trait_change( ac.arg_check0, 'value', remove = True ) ac.on_trait_change( ac.arg_check1, 'value', remove = True ) ac.on_trait_change( ac.arg_check2, 'value', remove = True ) ac.on_trait_change( ac.arg_check3, 'value', remove = True ) ac.on_trait_change( ac.arg_check4, 'value', remove = True ) for i in range( 3 ): ac.value += 1 self.assertEqual( ac.calls, (3 * 5) ) self.assertEqual( ac.value, (2 * 3) ) def test_arg_check_decorator ( self ): ac = ArgCheckDecorator( tc = self ) for i in range( 3 ): ac.value += 1 self.assertEqual( ac.calls, (3 * 5) ) self.assertEqual( ac.value, 3 ) def test_instance1 ( self ): i1 = Instance1( tc = self ) for i in range( 3 ): i1.set( exp_object = i1.ref, exp_name = 'value', dst_name = 'value', exp_old = i, exp_new = (i + 1), dst_new = (i + 1) ) i1.ref.value = (i + 1) self.assertEqual( i1.calls, (3 * 5) ) self.assertEqual( i1.ref.value, 3 ) ref = ArgCheckBase() i1.set( exp_object = i1, exp_name = 'ref', dst_name = 'value', exp_old = i1.ref, exp_new = ref, dst_new = 0 ) i1.ref = ref self.assertEqual( i1.calls, (4 * 5) ) self.assertEqual( i1.ref.value, 0 ) for i in range( 3 ): i1.set( exp_object = i1.ref, exp_name = 'value', dst_name = 'value', exp_old = i, exp_new = (i + 1), dst_new = (i + 1) ) i1.ref.value = (i + 1) self.assertEqual( i1.calls, (7 * 5) ) self.assertEqual( i1.ref.value, 3 ) def test_list1 ( self ): l1 = List1( tc = self ) for i in range( 3 ): ac = ArgCheckBase() l1.set( exp_object = l1, exp_name = 'refs_items', type_old = None, exp_old = Undefined, type_new = TraitListEvent ) l1.refs.append( ac ) #self.assertEqual( l1.calls, (3 * 3) ) # FIXME for i in range( 3 ): self.assertEqual( l1.refs[i].value, 0 ) refs = [ ArgCheckBase(), ArgCheckBase(), ArgCheckBase() ] l1.set( exp_object = l1, exp_name = 'refs', type_old = None, exp_old = l1.refs, type_new = TraitListObject ) l1.refs = refs #self.assertEqual( l1.calls, (4 * 3) ) for i in range( 3 ): self.assertEqual( l1.refs[i].value, 0 ) for i in range( 3 ): for j in range( 3 ): l1.set( exp_object = l1.refs[j], exp_name = 'value', type_old = None, exp_old = i, type_new = None, exp_new = (i + 1) ) l1.refs[j].value = (i + 1) #self.assertEqual( l1.calls, (13 * 3) ) for i in range( 3 ): self.assertEqual( l1.refs[i].value, 3 ) def test_list2 ( self ): self.check_list( List2( tc = self ) ) def test_list3 ( self ): self.check_list( List3( tc = self ) ) def test_dict1 ( self ): d1 = Dict1( tc = self ) for i in range( 3 ): ac = ArgCheckBase() d1.set( exp_object = d1, exp_name = 'refs_items', type_old = None, exp_old = Undefined, type_new = TraitDictEvent ) d1.refs[i] = ac #self.assertEqual( d1.calls, (3 * 3) ) # FIXME for i in range( 3 ): self.assertEqual( d1.refs[i].value, 0 ) refs = { 0: ArgCheckBase(), 1: ArgCheckBase(), 2: ArgCheckBase() } d1.set( exp_object = d1, exp_name = 'refs', type_old = None, exp_old = d1.refs, type_new = TraitDictObject ) d1.refs = refs #self.assertEqual( d1.calls, (4 * 3) ) for i in range( 3 ): self.assertEqual( d1.refs[i].value, 0 ) for i in range( 3 ): for j in range( 3 ): d1.set( exp_object = d1.refs[j], exp_name = 'value', type_old = None, exp_old = i, type_new = None, exp_new = (i + 1) ) d1.refs[j].value = (i + 1) #self.assertEqual( d1.calls, (13 * 3) ) for i in range( 3 ): self.assertEqual( d1.refs[i].value, 3 ) def test_dict2 ( self ): self.check_dict( Dict2( tc = self ) ) def test_dict3 ( self ): self.check_dict( Dict3( tc = self ) ) def test_pattern_list1 ( self ): c = Complex( tc = self ) self.check_complex( c, c, 'int1, int2, int3', [ 'int1', 'int2', 'int3' ], [ 'tint1', 'tint2', 'tint3' ] ) def test_pattern_list2 ( self ): c = Complex( tc = self ) self.check_complex( c, c, [ 'int1', 'int2', 'int3' ], [ 'int1', 'int2', 'int3' ], [ 'tint1', 'tint2', 'tint3' ] ) def test_pattern_list3 ( self ): c = Complex( tc = self ) self.check_complex( c, c.ref, 'ref.[int1, int2, int3]', [ 'int1', 'int2', 'int3' ], [ 'tint1', 'tint2', 'tint3' ] ) def test_pattern_list4 ( self ): c = Complex( tc = self ) handlers = [ c.arg_check0, c.arg_check3, c.arg_check4 ] n = len( handlers ) pattern = 'ref.[int1,int2,int3]' self.multi_register( c, handlers, pattern ) r0 = c.ref r1 = ArgCheckBase() c.set( exp_object = c, exp_name = 'ref', exp_old = r0, exp_new = r1 ) c.ref = r1 c.set( exp_old = r1, exp_new = r0 ) c.ref = r0 self.assertEqual( c.calls, 2 * n ) self.multi_register( c, handlers, pattern, remove = True ) c.ref = r1 c.ref = r0 self.assertEqual( c.calls, 2 * n ) def test_pattern_list5 ( self ): c = Complex( tc = self ) c.on_trait_change( c.arg_check1, 'ref.[int1,int2,int3]' ) self.assertRaises( TraitError, c.set, ref = ArgCheckBase() ) def test_pattern_list6 ( self ): c = Complex( tc = self ) c.on_trait_change( c.arg_check2, 'ref.[int1,int2,int3]' ) self.assertRaises( TraitError, c.set, ref = ArgCheckBase() ) def test_pattern_list7 ( self ): c = Complex( tc = self ) self.check_complex( c, c, '+test', [ 'int1', 'int3', 'tint2' ], [ 'int2', 'tint1', 'tint3' ] ) def test_pattern_list8 ( self ): c = Complex( tc = self ) self.check_complex( c, c, 'int+test', [ 'int1', 'int3' ], [ 'int2', 'tint1', 'tint2', 'tint3' ] ) def test_pattern_list9 ( self ): c = Complex( tc = self ) self.check_complex( c, c, 'int-test', [ 'int2' ], [ 'int1', 'int3', 'tint4', 'tint5', 'tint6' ] ) def test_pattern_list10 ( self ): c = Complex( tc = self ) self.check_complex( c, c, 'int+', [ 'int1', 'int2', 'int3' ], [ 'tint1', 'tint2', 'tint3' ] ) def test_pattern_list11 ( self ): c = Complex( tc = self ) self.check_complex( c, c, 'int-', [ 'int1', 'int2', 'int3' ], [ 'tint1', 'tint2', 'tint3' ] ) def test_pattern_list12 ( self ): c = Complex( tc = self ) self.check_complex( c, c, 'int+test,tint-test', [ 'int1', 'int3', 'tint1', 'tint3' ], [ 'int2', 'tint2' ] ) def test_pattern_list13 ( self ): c = Complex( tc = self ) self.check_complex( c, c.ref, 'ref.[int+test,tint-test]', [ 'int1', 'int3', 'tint1', 'tint3' ], [ 'int2', 'tint2' ] ) def test_cycle1 ( self ): lt = LinkTest( tc = self, head = self.build_list() ) handlers = [ lt.arg_check0, lt.arg_check1, lt.arg_check2, lt.arg_check3, lt.arg_check4 ] nh = len( handlers ) self.multi_register( lt, handlers, 'head.next*.value' ) cur = lt.head for i in range( 4 ): lt.set( exp_object = cur, exp_name = 'value', exp_old = 10 * i, exp_new = (10 * i) + 1 ) cur.value = (10 * i) + 1 cur = cur.next self.assertEqual( lt.calls, 4 * nh ) self.multi_register( lt, handlers, 'head.next*.value', remove = True ) cur = lt.head for i in range( 4 ): cur.value = (10 * i) + 2 cur = cur.next self.assertEqual( lt.calls, 4 * nh ) def test_cycle2 ( self ): lt = LinkTest( tc = self, head = self.build_list() ) handlers = [ lt.arg_check0, lt.arg_check1, lt.arg_check2, lt.arg_check3, lt.arg_check4 ] nh = len( handlers ) self.multi_register( lt, handlers, 'head.[next,prev]*.value' ) cur = lt.head for i in range( 4 ): lt.set( exp_object = cur, exp_name = 'value', exp_old = 10 * i, exp_new = (10 * i) + 1 ) cur.value = (10 * i) + 1 cur = cur.next self.assertEqual( lt.calls, 4 * nh ) self.multi_register( lt, handlers, 'head.[next,prev]*.value', remove = True ) cur = lt.head for i in range( 4 ): cur.value = (10 * i) + 2 cur = cur.next self.assertEqual( lt.calls, 4 * nh ) def test_cycle3 ( self ): lt = LinkTest( tc = self, head = self.build_list() ) handlers = [ lt.arg_check0, lt.arg_check3, lt.arg_check4 ] nh = len( handlers ) self.multi_register( lt, handlers, 'head.next*.value' ) link = self.new_link( lt, lt.head, 1 ) self.assertEqual( lt.calls, nh ) link = self.new_link( lt, link, 2 ) self.assertEqual( lt.calls, 2 * nh ) self.multi_register( lt, handlers, 'head.next*.value', remove = True ) link = self.new_link( lt, link, 3 ) self.assertEqual( lt.calls, 2 * nh ) def test_property ( self ): pdo = PropertyDependsOn( tc = self ) sum = pdo.sum self.assertEqual( sum, 0 ) for n in [ 'int1', 'int2', 'int3' ]: for i in range( 3 ): pdo.set( exp_old = sum, exp_new = sum + 1 ) setattr( pdo.ref, n, i + 1 ) sum += 1 self.assertEqual( pdo.pcalls, (3 * 3) + 1 ) self.assertEqual( pdo.calls, 3 * 3 ) for i in range( 10 ): x = pdo.sum self.assertEqual( pdo.pcalls, (3 * 3) + 1 ) pdo.set( exp_old = sum, exp_new = 60 ) old_ref = pdo.ref pdo.ref = ArgCheckBase( int1 = 10, int2 = 20, int3 = 30 ) self.assertEqual( pdo.pcalls, (3 * 3) + 2 ) self.assertEqual( pdo.calls, (3 * 3) + 1 ) sum = 60 for n in [ 'int1', 'int2', 'int3' ]: for i in range( 3 ): pdo.set( exp_old = sum, exp_new = sum + 1 ) setattr( pdo.ref, n, getattr( pdo.ref, n ) + 1 ) sum += 1 self.assertEqual( pdo.pcalls, (2 * 3 * 3) + 2 ) self.assertEqual( pdo.calls, (2 * 3 * 3) + 1 ) for n in [ 'int1', 'int2', 'int3' ]: for i in range( 3 ): setattr( old_ref, n, getattr( old_ref, n ) + 1 ) self.assertEqual( pdo.pcalls, (2 * 3 * 3) + 2 ) self.assertEqual( pdo.calls, (2 * 3 * 3) + 1 ) self.assertEqual( pdo.sum, sum ) self.assertEqual( pdo.pcalls, (2 * 3 * 3) + 2 ) #-- Helper methods --------------------------------------------------------- def check_list ( self, l ): for i in range( 3 ): ac = ArgCheckBase() self.assertRaises( TraitError, l.refs.append, ac) self.assertEqual( l.calls, 0 ) for i in range( 3 ): self.assertEqual( l.refs[i].value, 0 ) refs = [ ArgCheckBase(), ArgCheckBase(), ArgCheckBase() ] self.assertRaises( TraitError, l.set, refs = refs ) self.assertEqual( l.calls, 0 ) for i in range( 3 ): self.assertEqual( l.refs[i].value, 0 ) for i in range( 3 ): for j in range( 3 ): l.exp_new = (i + 1) l.refs[j].value = (i + 1) self.assertEqual( l.calls, 0 ) for i in range( 3 ): self.assertEqual( l.refs[i].value, 3 ) def check_dict ( self, d ): for i in range( 3 ): ac = ArgCheckBase() self.assertRaises( TraitError, d.refs.setdefault, i, ac ) self.assertEqual( d.calls, 0 ) for i in range( 3 ): self.assertEqual( d.refs[i].value, 0 ) refs = { 0: ArgCheckBase(), 1: ArgCheckBase(), 2: ArgCheckBase() } self.assertRaises( TraitError, d.set, refs = refs ) self.assertEqual( d.calls, 0 ) for i in range( 3 ): self.assertEqual( d.refs[i].value, 0 ) for i in range( 3 ): for j in range( 3 ): d.exp_new = (i + 1) d.refs[j].value = (i + 1) self.assertEqual( d.calls, 0 ) for i in range( 3 ): self.assertEqual( d.refs[i].value, 3 ) def check_complex ( self, c, r, pattern, names, other = [] ): handlers = [ c.arg_check0, c.arg_check1, c.arg_check2, c.arg_check3, c.arg_check4 ] nh = len( handlers ) nn = len( names ) self.multi_register( c, handlers, pattern ) for i in range( 3 ): for n in names: c.set( exp_object = r, exp_name = n, exp_old = i, exp_new = (i + 1) ) setattr( r, n, i + 1 ) for n in other: c.set( exp_object = r, exp_name = n, exp_old = i, exp_new = (i + 1) ) setattr( r, n, i + 1 ) self.assertEqual( c.calls, 3 * nn * nh ) self.multi_register( c, handlers, pattern, remove = True ) for i in range( 3 ): for n in names: setattr( r, n, i + 1 ) for n in other: setattr( r, n, i + 1 ) self.assertEqual( c.calls, 3 * nn * nh ) def multi_register ( self, object, handlers, pattern, remove = False ): for handler in handlers: print object, handler, pattern, remove object.on_trait_change( handler, pattern, remove = remove ) def build_list ( self ): l1 = Link( value = 00 ) l2 = Link( value = 10 ) l3 = Link( value = 20 ) l4 = Link( value = 30 ) l1.set( next = l2, prev = l4 ) l2.set( next = l3, prev = l1 ) l3.set( next = l4, prev = l2 ) l4.set( next = l1, prev = l3 ) return l1 def new_link ( self, lt, cur, value ): link = Link( value = value, next = cur.next, prev = cur ) cur.next.prev = link lt.set( exp_object = cur, exp_name = 'next', exp_old = cur.next, exp_new = link ) cur.next = link return link # Run the unit tests (if invoked from the command line): def ignore ( *args ): pass push_exception_handler( handler = ignore, reraise_exceptions = True ) if __name__ == '__main__': unittest.main() traits-4.1.0/traits/tests/delegate_test_case.py0000644000175100001440000002416511674463323022652 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # Copyright (c) 2005, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in enthought/LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # Thanks for using Enthought open source! #------------------------------------------------------------------------------ from __future__ import absolute_import import unittest from ..api import Delegate, HasTraits, Instance, Str # global because event handlers are being called with wrong value for self baz_s_handler_self = None baz_sd_handler_self = None baz_u_handler_self = None baz_t_handler_self = None foo_s_handler_self = None foo_t_handler_self = None class Foo( HasTraits ): s = Str( 'foo' ) t = Str( 'foo.t' ) u = Str( 'foo.u' ) def _s_changed(self, name, old, new): print 'Foo._s_changed( %s, %s, %s, %s)' % (self, name, old, new) global foo_s_handler_self foo_s_handler_self = self return def _t_changed(self, name, old, new): print 'Foo._t_changed( %s, %s, %s, %s)' % (self, name, old, new) global foo_t_handler_self foo_t_handler_self = self return class Bar( HasTraits ): foo = Instance( Foo, () ) s = Delegate( 'foo' ) class BazModify( HasTraits ): foo = Instance( Foo, () ) sd = Delegate( 'foo', prefix='s', modify=True ) t = Delegate( 'foo', modify=True ) u = Delegate( 'foo', listenable=False, modify=True ) def _s_changed(self, name, old, new): # should never be called print 'BazModify._s_changed( %s, %s, %s, %s)' % (self, name, old, new) global baz_s_handler_self baz_s_handler_self = self return def _sd_changed(self, name, old, new): print 'BazModify._sd_changed( %s, %s, %s, %s)' % (self, name, old, new) global baz_sd_handler_self baz_sd_handler_self = self return def _t_changed(self, name, old, new): print 'BazModify._t_changed( %s, %s, %s, %s)' % (self, name, old, new) global baz_t_handler_self baz_t_handler_self = self return def _u_changed(self, name, old, new): print 'BazModify._u_changed( %s, %s, %s, %s)' % (self, name, old, new) global baz_u_handler_self baz_u_handler_self = self return class BazNoModify( HasTraits ): foo = Instance( Foo, () ) sd = Delegate( 'foo', prefix='s' ) t = Delegate( 'foo' ) u = Delegate( 'foo', listenable=False ) def _s_changed(self, name, old, new): print 'BazNoModify._s_changed( %s, %s, %s, %s)' % (self, name, old, new) global baz_s_handler_self baz_s_handler_self = self return def _sd_changed(self, name, old, new): print 'BazNoModify._sd_changed( %s, %s, %s, %s)' % (self, name, old, new) global baz_sd_handler_self baz_sd_handler_self = self return def _t_changed(self, name, old, new): print 'BazNoModify._t_changed( %s, %s, %s, %s)' % (self, name, old, new) global baz_t_handler_self baz_t_handler_self = self return def _u_changed(self, name, old, new): print 'BazNoModify._u_changed( %s, %s, %s, %s)' % (self, name, old, new) global baz_u_handler_self baz_u_handler_self = self return class DelegateTestCase( unittest.TestCase ): """ Test cases for delegated traits. """ def setUp(self): """ Reset all of the globals. """ global baz_s_handler_self, baz_sd_handler_self, baz_u_handler_self global baz_t_handler_self, foo_s_handler_self, foo_t_handler_self baz_s_handler_self = None baz_sd_handler_self = None baz_u_handler_self = None baz_t_handler_self = None foo_s_handler_self = None foo_t_handler_self = None def test_reset(self): """ Test that a delegated trait may be reset. Deleting the attribute should reset the trait back to its initial delegation behavior. """ f = Foo() b = Bar(foo=f) # Check initial delegation. self.assertEqual( f.s, b.s ) # Check that an override works. b.s = 'bar' self.assertNotEqual( f.s, b.s ) # Check that we can reset back to delegation. This is what we are # really testing for. del b.s self.assertEqual( f.s, b.s ) return # Below are 8 tests to check the calling of change notification handlers. # There are 8 cases for the 2x2x2 matrix with axes: # Delegate with prefix or not # Delegate with modify write through or not # Handler in the delegator and delegatee # def test_modify_prefix_handler_on_delegator(self): f = Foo() b = BazModify(foo=f) self.assertEqual( f.s, b.sd ) b.sd = 'changed' self.assertEqual( f.s, b.sd ) # Don't expect _s_changed to be called because from Baz's perspective # the trait is named 'sd' self.assertEqual( baz_s_handler_self, None ) # Do expect '_sd_changed' to be called with b as self self.assertEqual( baz_sd_handler_self, b ) return def test_modify_prefix_handler_on_delegatee(self): f = Foo() b = BazModify(foo=f) self.assertEqual( f.s, b.sd ) b.sd = 'changed' self.assertEqual( f.s, b.sd ) # Foo expects its '_s_changed' handler to be called with f as self self.assertEqual( foo_s_handler_self, f ) return def test_no_modify_prefix_handler_on_delegator(self): f = Foo() b = BazNoModify(foo=f) self.assertEqual( f.s, b.sd ) b.sd = 'changed' self.assertNotEqual( f.s, b.sd ) # Don't expect _s_changed to be called because from Baz's perspective # the triat is named 'sd' self.assertEqual( baz_s_handler_self, None ) # Do expect '_sd_changed' to be called with b as self self.assertEqual( baz_sd_handler_self, b ) return def test_no_modify_prefix_handler_on_delegatee_not_called(self): f = Foo() b = BazNoModify(foo=f) self.assertEqual( f.s, b.sd ) b.sd = 'changed' self.assertNotEqual( f.s, b.sd ) # Foo expects its '_s_changed' handler to be called with f as self self.assertEqual( foo_s_handler_self, None ) return def test_modify_handler_on_delegator(self): f = Foo() b = BazModify(foo=f) self.assertEqual( f.t, b.t ) b.t = 'changed' self.assertEqual( f.t, b.t ) # Do expect '_t_changed' to be called with b as self self.assertEqual( baz_t_handler_self, b ) return def test_modify_handler_on_delegatee(self): f = Foo() b = BazModify(foo=f) self.assertEqual( f.t, b.t ) b.t = 'changed' self.assertEqual( f.t, b.t ) # Foo t did change so '_t_changed' handler should be called self.assertEqual( foo_t_handler_self, f) return def test_no_modify_handler_on_delegator(self): f = Foo() b = BazNoModify(foo=f) self.assertEqual( f.t, b.t ) b.t = 'changed' self.assertNotEqual( f.t, b.t ) # Do expect '_t_changed' to be called with b as self self.assertEqual( baz_t_handler_self, b ) return def test_no_modify_handler_on_delegatee_not_called(self): f = Foo() b = BazNoModify(foo=f) self.assertEqual( f.t, b.t ) b.t = 'changed' self.assertNotEqual( f.t, b.t ) # Foo t did not change so '_t_changed' handler should not be called self.assertEqual( foo_t_handler_self, None) return # Below are 4 tests for notification when the delegated trait is changed # directly rather than through the delegator. def test_no_modify_handler_on_delegatee_direct_change(self): f = Foo() b = BazNoModify(foo=f) self.assertEqual( f.t, b.t ) f.t = 'changed' self.assertEqual( f.t, b.t ) # Foo t did change so '_t_changed' handler should be called self.assertEqual( foo_t_handler_self, f) return def test_no_modify_handler_on_delegator_direct_change(self): f = Foo() b = BazNoModify(foo=f) self.assertEqual( f.t, b.t ) f.t = 'changed' self.assertEqual( f.t, b.t ) # Do expect '_t_changed' to be called with b as self self.assertEqual( baz_t_handler_self, b ) return def test_modify_handler_on_delegatee_direct_change(self): f = Foo() b = BazModify(foo=f) self.assertEqual( f.t, b.t ) f.t = 'changed' self.assertEqual( f.t, b.t ) # Foo t did change so '_t_changed' handler should be called self.assertEqual( foo_t_handler_self, f) return def test_modify_handler_on_delegator_direct_change(self): f = Foo() b = BazModify(foo=f) self.assertEqual( f.t, b.t ) f.t = 'changed' self.assertEqual( f.t, b.t ) # Do expect '_t_changed' to be called with b as self self.assertEqual( baz_t_handler_self, b ) return # Below are tests which check that we can turn off listenableness. def test_modify_handler_not_listenable(self): f = Foo() b = BazModify(foo=f) self.assertEqual( f.u, b.u ) f.u = 'changed' self.assertEqual( f.u, b.u ) # Do not expect '_u_changed' to be called. self.assertEqual( baz_u_handler_self, None ) return def test_no_modify_handler_not_listenable(self): f = Foo() b = BazNoModify(foo=f) self.assertEqual( f.u, b.u ) f.u = 'changed' self.assertEqual( f.u, b.u ) # Do not expect '_u_changed' to be called. self.assertEqual( baz_u_handler_self, None ) return if __name__ == '__main__': unittest.main() #### EOF ###################################################################### traits-4.1.0/traits/tests/test_traits.py0000644000175100001440000007142711674463323021416 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # Copyright (c) 2005, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in enthought/LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # Thanks for using Enthought open source! # # Author: David C. Morrill Date: 03/20/2003 Description: Unit Test Case for the # Traits Package # ------------------------------------------------------------------------------ #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from __future__ import absolute_import import unittest from ..api import (Any, CFloat, CInt, CLong, Delegate, Float, HasTraits, Instance, Int, List, Long, Str, Trait, TraitError, TraitList, TraitPrefixList, TraitPrefixMap, TraitRange, Tuple) #------------------------------------------------------------------------------- # Base unit test classes: #------------------------------------------------------------------------------- class BaseTest(object): def assign(self, value): self.obj.value = value def coerce(self, value): return value def test_assignment(self): obj = self.obj # Validate default value value = self._default_value self.assertEqual(obj.value, value) # Validate all legal values for i, value in enumerate(self._good_values): obj.value = value self.assertEqual(obj.value, self.coerce(value)) # If there's a defined if i < len(self._mapped_values): self.assertEqual(obj.value_, self._mapped_values[i]) # NOTE: # There is/was some intercation between nosetests and coverage # which causes problems with raising exceptions in Traits # with Python 2.4. However, I am no longer able to reproduce # the behavior, see: # # https://svn.enthought.com/enthought/ticket/1620 # #if 'coverage' in sys.modules: # raise nose.SkipTest("Skipped because coverage module is loaded") # Validate correct behavior for illegal values for value in self._bad_values: self.assertRaises(TraitError, self.assign, value) class test_base2(unittest.TestCase): def indexed_assign(self, list, index, value): list[ index ] = value def indexed_range_assign(self, list, index1, index2, value): list[ index1: index2 ] = value # This avoids using a method name that contains 'test' so that this is not # called by the tester directly, as nose looks for all tests, regardless of # the handler at the bottom of this file. def check_values(self, name, default_value, good_values, bad_values, actual_values = None, mapped_values = None): obj = self.obj try: # Make sure the default value is correct: msg = 'default value' value = default_value self.assertEqual(getattr(obj, name), value) # Iterate over all legal values being tested: if actual_values is None: actual_values = good_values msg = 'legal values' i = 0 for value in good_values: setattr(obj, name, value) self.assertEqual(getattr(obj, name), actual_values[i]) if mapped_values is not None: self.assertEqual(getattr(obj, name + '_'), mapped_values[i]) i += 1 # Iterate over all illegal values being tested: msg = 'illegal values' for value in bad_values: self.assertRaises(TraitError, setattr, obj, name, value) except: print 'Failed while testing %s for value: %s(%s) in %s' % ( msg, value, value.__class__.__name__, self.__class__.__name__) raise #------------------------------------------------------------------------------- # Trait that can have any value: #------------------------------------------------------------------------------- class AnyTrait(HasTraits): # Trait definitions: value = Any class AnyTraitTest(BaseTest, unittest.TestCase): obj = AnyTrait() _default_value = None _good_values = [10.0, 'ten', u'ten', [10], {'ten': 10},(10,), None, 1j] _mapped_values = [] _bad_values = [] #------------------------------------------------------------------------------- # Trait that can only have 'int' values: #------------------------------------------------------------------------------- class CoercibleIntTrait(HasTraits): # Trait definitions: value = CInt(99) class IntTrait(HasTraits): # Trait definitions: value = Int(99) class CoercibleIntTest(AnyTraitTest): obj = CoercibleIntTrait() _default_value = 99 _good_values = [10, -10, 10L, -10L, 10.1, -10.1, '10', '-10', u'10', u'-10'] _bad_values = ['10L', '-10L', '10.1', '-10.1', u'10L', u'-10L', u'10.1', u'-10.1', 'ten', u'ten', [10], {'ten': 10},(10,), None, 1j] def coerce(self, value): try: return int(value) except: try: return int(float(value)) except: return int(long(value)) class IntTest(AnyTraitTest): obj = IntTrait() _default_value = 99 _good_values = [10, -10] _bad_values = ['ten', u'ten', [10], {'ten': 10},(10,), None, 1j, 10L, -10L, 10.1, -10.1, '10L', '-10L', '10.1', '-10.1', u'10L', u'-10L', u'10.1', u'-10.1', '10', '-10', u'10', u'-10'] def coerce(self, value): try: return int(value) except: try: return int(float(value)) except: return int(long(value)) #------------------------------------------------------------------------------- # Trait that can only have 'long' values: #------------------------------------------------------------------------------- class CoercibleLongTrait(HasTraits): # Trait definitions: value = CLong(99L) class LongTrait(HasTraits): # Trait definitions: value = Long(99L) class CoercibleLongTest(AnyTraitTest): obj = CoercibleLongTrait() _default_value = 99L _good_values = [10, -10, 10L, -10L, 10.1, -10.1, '10', '-10', '10L', '-10L', u'10', u'-10', u'10L', u'-10L'] _bad_values = ['10.1', '-10.1', u'10.1', u'-10.1', 'ten', u'ten', [10], [10l], {'ten': 10},(10,),(10L,), None, 1j] def coerce(self, value): try: return long(value) except: return long(float(value)) class LongTest(AnyTraitTest): obj = LongTrait() _default_value = 99L _good_values = [10, -10, 10L, -10L] _bad_values = ['ten', u'ten', [10], [10l], {'ten': 10},(10,),(10L,), None, 1j, 10.1, -10.1, '10', '-10', '10L', '-10L', '10.1', '-10.1', u'10', u'-10', u'10L', u'-10L', u'10.1', u'-10.1'] def coerce(self, value): try: return long(value) except: return long(float(value)) #------------------------------------------------------------------------------- # Trait that can only have 'float' values: #------------------------------------------------------------------------------- class CoercibleFloatTrait(HasTraits): # Trait definitions: value = CFloat(99.0) class FloatTrait(HasTraits): # Trait definitions: value = Float(99.0) class CoercibleFloatTest(AnyTraitTest): obj = CoercibleFloatTrait() _default_value = 99.0 _good_values = [10, -10, 10L, -10L, 10.1, -10.1, '10', '-10', '10.1', '-10.1', u'10', u'-10', u'10.1', u'-10.1'] _bad_values = ['10L', '-10L', u'10L', u'-10L', 'ten', u'ten', [10], {'ten': 10},(10,), None, 1j] def coerce(self, value): try: return float(value) except: return float(long(value)) class FloatTest(AnyTraitTest): obj = FloatTrait() _default_value = 99.0 _good_values = [10, -10, 10.1, -10.1] _bad_values = [10L, -10L, 'ten', u'ten', [10], {'ten': 10},(10,), None, 1j, '10', '-10', '10L', '-10L', '10.1', '-10.1', u'10', u'-10', u'10L', u'-10L', u'10.1', u'-10.1'] def coerce(self, value): try: return float(value) except: return float(long(value)) #------------------------------------------------------------------------------- # Trait that can only have 'complex'(i.e. imaginary) values: #------------------------------------------------------------------------------- class ImaginaryValueTrait(HasTraits): # Trait definitions: value = Trait(99.0-99.0j) class ImaginaryValueTest(AnyTraitTest): obj = ImaginaryValueTrait() _default_value = 99.0-99.0j _good_values = [10, -10, 10L, -10L, 10.1, -10.1, '10', '-10', '10.1', '-10.1', 10j, 10+10j, 10-10j, 10.1j, 10.1+10.1j, 10.1-10.1j, '10j', '10+10j', '10-10j'] _bad_values = [u'10L', u'-10L', 'ten', [10], {'ten': 10},(10,), None] def coerce(self, value): try: return complex(value) except: return complex(long(value)) #------------------------------------------------------------------------------- # Trait that can only have 'string' values: #------------------------------------------------------------------------------- class StringTrait(HasTraits): # Trait definitions: value = Trait('string') class StringTest(AnyTraitTest): obj = StringTrait() _default_value = 'string' _good_values = [10, -10, 10L, -10L, 10.1, -10.1, '10', '-10', '10L', '-10L', '10.1', '-10.1', 'string', u'string', 1j, [10], ['ten'],{'ten': 10},(10,), None] _bad_values = [] def coerce(self, value): return str(value) #------------------------------------------------------------------------------- # Trait that can only have 'unicode' values: #------------------------------------------------------------------------------- class UnicodeTrait(HasTraits): # Trait definitions: value = Trait(u'unicode') class UnicodeTest(StringTest): obj = UnicodeTrait() _default_value = u'unicode' _good_values = [10, -10, 10L, -10L, 10.1, -10.1, '10', '-10', '10L', '-10L', '10.1', '-10.1', '', u'', 'string', u'string', 1j, [10], ['ten'], [u'ten'], {'ten': 10},(10,), None] _bad_values = [] def coerce(self, value): return str(value) #------------------------------------------------------------------------------- # Trait that can only have an 'enumerated list' values: #------------------------------------------------------------------------------- class EnumTrait(HasTraits): # Trait definitions: value = Trait([1, 'one', 2, 'two', 3, 'three', 4.4, u'four.four']) class EnumTest(AnyTraitTest): obj = EnumTrait() _default_value = 1 _good_values = [1, 'one', 2, 'two', 3, 'three', 4.4, u'four.four'] _bad_values = [0, 'zero', 4, None] #------------------------------------------------------------------------------- # Trait that can only have a 'mapped' values: #------------------------------------------------------------------------------- class MappedTrait(HasTraits): # Trait definitions: value = Trait('one', {'one': 1, 'two': 2, 'three': 3}) class MappedTest(AnyTraitTest): obj = MappedTrait() _default_value = 'one' _good_values = ['one', 'two', 'three'] _mapped_values = [1, 2, 3] _bad_values = ['four', 1, 2, 3, [1],(1,), {1: 1}, None] #------------------------------------------------------------------------------- # Trait that must be a unique prefix of an enumerated list of values: #------------------------------------------------------------------------------- class PrefixListTrait(HasTraits): # Trait definitions: value = Trait('one', TraitPrefixList('one', 'two', 'three')) class PrefixListTest(AnyTraitTest): obj = PrefixListTrait() _default_value = 'one' _good_values = ['o', 'on', 'one', 'tw', 'two', 'th', 'thr', 'thre', 'three'] _bad_values = ['t', 'one ', ' two', 1, None] def coerce(self, value): return {'o': 'one', 'on': 'one', 'tw': 'two', 'th': 'three'}[value[:2]] #------------------------------------------------------------------------------- # Trait that must be a unique prefix of a mapped set of values: #------------------------------------------------------------------------------- class PrefixMapTrait(HasTraits): # Trait definitions: value = Trait('one', TraitPrefixMap({'one': 1, 'two': 2, 'three': 3})) class PrefixMapTest(AnyTraitTest): obj = PrefixMapTrait() _default_value = 'one' _good_values = ['o', 'on', 'one', 'tw', 'two', 'th', 'thr', 'thre', 'three'] _mapped_values = [1, 1, 1, 2, 2, 3, 3, 3] _bad_values = ['t', 'one ', ' two', 1, None] def coerce(self, value): return {'o': 'one', 'on': 'one', 'tw': 'two', 'th': 'three'}[value[:2]] #------------------------------------------------------------------------------- # Trait that must be within a specified integer range: #------------------------------------------------------------------------------- class IntRangeTrait(HasTraits): # Trait definitions: value = Trait(3, TraitRange(2, 5)) class IntRangeTest(AnyTraitTest): obj = IntRangeTrait() _default_value = 3 _good_values = [2, 3, 4, 5] _bad_values = [0, 1, 6, 0.999, 6.01, 'two', '0.999', '6.01', None] def coerce(self, value): try: return int(value) except: try: return int(float(value)) except: return int(long(value)) #------------------------------------------------------------------------------- # Trait that must be within a specified float range: #------------------------------------------------------------------------------- class FloatRangeTrait(HasTraits): # Trait definitions: value = Trait(3.0, TraitRange(2.0, 5.0)) class FloatRangeTest(AnyTraitTest): obj = FloatRangeTrait() _default_value = 3.0 _good_values = [2.0, 3.0, 4.0, 5.0, 2.001, 4.999] _bad_values = [0, 1, 6, 0L, 1L, 6L, 1.999, 6.01, 'two', '0.999', '6.01', None] def coerce(self, value): try: return float(value) except: return float(long(value)) #------------------------------------------------------------------------------- # Trait that must be an instance of a particular class(or subclass): #------------------------------------------------------------------------------- # Old style class version: class OTraitTest1: pass class OTraitTest2(OTraitTest1): pass class OTraitTest3(OTraitTest2): pass class OBadTraitTest: pass otrait_test1 = OTraitTest1() class OldInstanceTrait(HasTraits): # Trait definitions: value = Trait(otrait_test1) class OldInstanceTest(AnyTraitTest): # Trait definitions: obj = OldInstanceTrait() _default_value = otrait_test1 _good_values = [otrait_test1, OTraitTest1(), OTraitTest2(), OTraitTest3(), None] _bad_values = [0, 0L, 0.0, 0j, OTraitTest1, OTraitTest2, OBadTraitTest(), 'string', u'string', [otrait_test1],(otrait_test1,), {'data': otrait_test1}] # New style class version: class NTraitTest1(object): pass class NTraitTest2(NTraitTest1): pass class NTraitTest3(NTraitTest2): pass class NBadTraitTest: pass ntrait_test1 = NTraitTest1() class NewInstanceTrait(HasTraits): # Trait definitions: value = Trait(ntrait_test1) class NewInstanceTest(AnyTraitTest): obj = NewInstanceTrait() _default_value = ntrait_test1 _good_values = [ntrait_test1, NTraitTest1(), NTraitTest2(), NTraitTest3(), None] _bad_values = [0, 0L, 0.0, 0j, NTraitTest1, NTraitTest2, NBadTraitTest(), 'string', u'string', [ntrait_test1],(ntrait_test1,), {'data': ntrait_test1}] class FactoryClass(HasTraits): pass class ConsumerClass(HasTraits): x = Instance(FactoryClass, ()) class ConsumerSubclass(ConsumerClass): x = FactoryClass() embedded_instance_trait = Trait('', Str, Instance('traits.has_traits.HasTraits')) class Dummy(HasTraits): x = embedded_instance_trait xl = List(embedded_instance_trait) class RegressionTest(unittest.TestCase): """ Check that fixed bugs stay fixed. """ def test_factory_subclass_no_segfault(self): """ Test that we can provide an instance as a default in the definition of a subclass. """ # There used to be a bug where this would segfault. obj = ConsumerSubclass() obj.x def test_trait_compound_instance(self): """ Test that a deferred Instance() embedded in a TraitCompound handler and then a list will not replace the validate method for the outermost trait. """ # Pass through an instance in order to make the instance trait resolve the class. d = Dummy() d.xl = [HasTraits()] d.x = 'OK' #------------------------------------------------------------------------------- # Trait(using a function) that must be an odd integer: #------------------------------------------------------------------------------- def odd_integer(object, name, value): try: float(value) if(value % 2) == 1: return int(value) except: pass raise TraitError class OddIntegerTrait(HasTraits): # Trait definitions: value = Trait(99, odd_integer) class OddIntegerTest(AnyTraitTest): obj = OddIntegerTrait() _default_value = 99 _good_values = [ 1, 3, 5, 7, 9, 999999999, 1L, 3L, 5L, 7L, 9L, 999999999L, 1.0, 3.0, 5.0, 7.0, 9.0, 999999999.0, -1, -3, -5, -7, -9, -999999999, -1L, -3L, -5L, -7L, -9L, -999999999L, -1.0, -3.0, -5.0, -7.0, -9.0, -999999999.0 ] _bad_values = [0, 2, -2, 1j, None, '1', [1],(1,), {1: 1}] #------------------------------------------------------------------------------- # Trait that has various notifiers attached: #------------------------------------------------------------------------------- class NotifierTraits(HasTraits): # Trait definitions: value1 = Int value2 = Int value1_count = Int value2_count = Int def _anytrait_changed(self, trait_name, old, new): if trait_name == 'value1': self.value1_count += 1 elif trait_name == 'value2': self.value2_count += 1 def _value1_changed(self, old, new): self.value1_count += 1 def _value2_changed(self, old, new): self.value2_count += 1 class NotifierTests(unittest.TestCase): obj = NotifierTraits() def __init__(self, value): unittest.TestCase.__init__(self, value) def setUp(self): obj = self.obj obj.value1 = 0 obj.value2 = 0 obj.value1_count = 0 obj.value2_count = 0 def tearDown(self): obj = self.obj obj.on_trait_change(self.on_value1_changed, 'value1', remove = True) obj.on_trait_change(self.on_value2_changed, 'value2', remove = True) obj.on_trait_change(self.on_anytrait_changed, remove = True) def on_anytrait_changed(self, object, trait_name, old, new): if trait_name == 'value1': self.obj.value1_count += 1 elif trait_name == 'value2': self.obj.value2_count += 1 def on_value1_changed(self): self.obj.value1_count += 1 def on_value2_changed(self): self.obj.value2_count += 1 def test_simple(self): obj = self.obj obj.value1 = 1 self.assertEqual(obj.value1_count, 2) self.assertEqual(obj.value2_count, 0) obj.value2 = 1 self.assertEqual(obj.value1_count, 2) self.assertEqual(obj.value2_count, 2) def test_complex(self): obj = self.obj obj.on_trait_change(self.on_value1_changed, 'value1') obj.value1 = 1 self.assertEqual(obj.value1_count, 3) self.assertEqual(obj.value2_count, 0) obj.on_trait_change(self.on_value2_changed, 'value2') obj.value2 = 1 self.assertEqual(obj.value1_count, 3) self.assertEqual(obj.value2_count, 3) obj.on_trait_change(self.on_anytrait_changed) obj.value1 = 2 self.assertEqual(obj.value1_count, 7) self.assertEqual(obj.value2_count, 3) obj.value1 = 2 self.assertEqual(obj.value1_count, 7) self.assertEqual(obj.value2_count, 3) obj.value2 = 2 self.assertEqual(obj.value1_count, 7) self.assertEqual(obj.value2_count, 7) obj.on_trait_change(self.on_value1_changed, 'value1', remove = True) obj.value1 = 3 self.assertEqual(obj.value1_count, 10) self.assertEqual(obj.value2_count, 7) obj.on_trait_change(self.on_value2_changed, 'value2', remove = True) obj.value2 = 3 self.assertEqual(obj.value1_count, 10) self.assertEqual(obj.value2_count, 10) obj.on_trait_change(self.on_anytrait_changed, remove = True) obj.value1 = 4 self.assertEqual(obj.value1_count, 12) self.assertEqual(obj.value2_count, 10) obj.value2 = 4 self.assertEqual(obj.value1_count, 12) self.assertEqual(obj.value2_count, 12) #------------------------------------------------------------------------------- # Trait that uses delegation: #------------------------------------------------------------------------------- class DelegatedFloatTrait(HasTraits): # Trait definitions: value = Trait(99.0) class DelegateTrait(HasTraits): # Trait definitions: value = Delegate('delegate') delegate = Trait(DelegatedFloatTrait()) class DelegateTrait2(DelegateTrait): # Trait definitions: delegate = Trait(DelegateTrait()) class DelegateTrait3(DelegateTrait): # Trait definitions: delegate = Trait(DelegateTrait2()) class DelegateTests(unittest.TestCase): def test_delegation(self): obj = DelegateTrait3() self.assertEqual(obj.value, 99.0) parent1 = obj.delegate parent2 = parent1.delegate parent3 = parent2.delegate parent3.value = 3.0 self.assertEqual(obj.value, 3.0) parent2.value = 2.0 self.assertEqual(obj.value, 2.0) self.assertEqual(parent3.value, 3.0) parent1.value = 1.0 self.assertEqual(obj.value, 1.0) self.assertEqual(parent2.value, 2.0) self.assertEqual(parent3.value, 3.0) obj.value = 0.0 self.assertEqual(obj.value, 0.0) self.assertEqual(parent1.value, 1.0) self.assertEqual(parent2.value, 2.0) self.assertEqual(parent3.value, 3.0) del obj.value self.assertEqual(obj.value, 1.0) del parent1.value self.assertEqual(obj.value, 2.0) self.assertEqual(parent1.value, 2.0) del parent2.value self.assertEqual(obj.value, 3.0) self.assertEqual(parent1.value, 3.0) self.assertEqual(parent2.value, 3.0) del parent3.value # Uncommenting the following line allows # the last assertions to pass. However, this # may not be intended behavior, so keeping # the line commented. #del parent2.value self.assertEqual(obj.value, 99.0) self.assertEqual(parent1.value, 99.0) self.assertEqual(parent2.value, 99.0) self.assertEqual(parent3.value, 99.0) #------------------------------------------------------------------------------- # Complex(i.e. 'composite') Traits tests: #------------------------------------------------------------------------------- # Make a TraitCompound handler that does not have a fast_validate so we can # check for a particular regression. slow = Trait(1, TraitRange(1, 3), TraitRange(-3, -1)) del slow.handler.fast_validate class complex_value(HasTraits): # Trait definitions: num1 = Trait(1, TraitRange(1, 5), TraitRange(-5, -1)) num2 = Trait(1, TraitRange(1, 5), TraitPrefixList('one', 'two', 'three', 'four', 'five')) num3 = Trait(1, TraitRange(1, 5), TraitPrefixMap({ 'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5 })) num4 = Trait(1, Trait(1, Tuple, slow), 10) num5 = Trait(1, 10, Trait(1, Tuple, slow)) class test_complex_value(test_base2): # Trait definitions: obj = complex_value() def test_num1(self): self.check_values('num1', 1, [ 1, 2, 3, 4, 5, -1, -2, -3, -4, -5 ], [ 0, 6, -6, '0', '6', '-6', 0.0, 6.0, -6.0, [ 1 ],(1,), { 1: 1 }, None ], [ 1, 2, 3, 4, 5, -1, -2, -3, -4, -5 ]) def test_enum_exceptions(self): """ Check that enumerated values can be combined with nested TraitCompound handlers. """ self.check_values('num4', 1, [1,2,3,-3,-2,-1, 10, ()], [0, 4, 5, -5, -4, 11], ) self.check_values('num5', 1, [1,2,3,-3,-2,-1, 10, ()], [0, 4, 5, -5, -4, 11], ) ## def check_num2(self): ## self.check_values('num2', 1, ## [ 1, 2, 3, 4, 5, ## 'one', 'two', 'three', 'four', 'five', 'o', 'on', 'tw', ## 'th', 'thr', 'thre', 'fo', 'fou', 'fi', 'fiv' ], ## [ 0, 6, '0', '6', 0.0, 6.0, 't', 'f', 'six', [ 1 ],(1,), ## { 1: 1 }, None ], ## [ 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 'one', 'two', ## 'three', 'four', 'five', 'one', 'one', 'two', 'three', 'three', ## 'three', 'four', 'four', 'five', 'five' ]) ## def check_num3(self): ## self.check_values('num3', 1, ## [ 1, 2, 3, 4, 5, ## 'one', 'two', 'three', 'four', 'five', 'o', 'on', 'tw', ## 'th', 'thr', 'thre', 'fo', 'fou', 'fi', 'fiv' ], ## [ 0, 6, '0', '6', 0.0, 6.0, 't', 'f', 'six', [ 1 ],(1,), ## { 1: 1 }, None ], ## [ 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 'one', 'two', ## 'three', 'four', 'five', 'one', 'one', 'two', 'three', 'three', ## 'three', 'four', 'four', 'five', 'five' ], ## [ 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, ## 1, 1, 2, 3, 3, 3, 4, 4, 5, 5 ]) #------------------------------------------------------------------------------- # Test traits which are lists: #------------------------------------------------------------------------------- class list_value(HasTraits): # Trait definitions: list1 = Trait([ 2 ], TraitList(Trait([ 1, 2, 3, 4 ]), maxlen = 4)) list2 = Trait([ 2 ], TraitList(Trait([ 1, 2, 3, 4 ]), minlen = 1, maxlen = 4)) class test_list_value(test_base2): obj = list_value() def del_range(self, list, index1, index2): del list[ index1: index2 ] def check_list(self, list): self.assertEqual(list, [ 2 ]) self.assertEqual(len(list), 1) list.append(3) self.assertEqual(len(list), 2) list[1] = 2 self.assertEqual(list[1], 2) self.assertEqual(len(list), 2) list[0] = 1 self.assertEqual(list[0], 1) self.assertEqual(len(list), 2) self.assertRaises(TraitError, self.indexed_assign, list, 0, 5) self.assertRaises(TraitError, list.append, 5) self.assertRaises(TraitError, list.extend, [ 1, 2, 3 ]) list.extend([ 3, 4 ]) self.assertEqual(list, [ 1 ,2, 3, 4 ]) self.assertRaises(TraitError, list.append, 1) del list[1] self.assertEqual(list, [ 1, 3, 4 ]) del list[0] self.assertEqual(list, [ 3, 4 ]) list[:0] = [ 1, 2 ] self.assertEqual(list, [ 1 ,2, 3, 4 ]) self.assertRaises(TraitError, self.indexed_range_assign, list, 0, 0, [ 1 ]) del list[0:3] self.assertEqual(list, [ 4 ]) self.assertRaises(TraitError, self.indexed_range_assign, list, 0, 0, [ 4, 5 ]) def test_list1(self): self.check_list(self.obj.list1) def test_list2(self): self.check_list(self.obj.list2) self.assertRaises(TraitError, self.del_range, self.obj.list2, 0, 1) traits-4.1.0/traits/tests/test_events.py0000644000175100001440000001053411674463323021404 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # Copyright (c) 2005, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in enthought/LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # Thanks for using Enthought open source! # # Author: David C. Morrill Date: 10/22/2003 Description: Unit test case for # Traits event notification handling. # ------------------------------------------------------------------------------ from __future__ import absolute_import from ..api import HasTraits #------------------------------------------------------------------------------ class TestBase ( HasTraits ): __traits__ = { 't1': 0, 't2': 0 } def test ( self ): print '---------- Begin %s test ----------' % self.__class__.__name__ print 'normal changes' self.t1 = 1 self.t2 = 2 print '---------- End %s test ----------\n' % self.__class__.__name__ #------------------------------------------------------------------------------ class Test1 ( TestBase ): def t1_changed ( self, old, new ): print 't1 changed:', old, new def t2_changed ( self, old, new ): print 't2 changed:', old, new #------------------------------------------------------------------------------ class Test2 ( Test1 ): def anytrait_changed ( self, name, old, new ): print 'anytrait changed:', name, old, new #------------------------------------------------------------------------------ class Test3 ( TestBase ): def anytrait_changed ( self, name, old, new ): print 'anytrait changed:', name, old, new #------------------------------------------------------------------------------ class Test4 ( TestBase ): def __init__ ( self, **traits ): TestBase.__init__( self, **traits ) self.on_trait_change( self.on_anytrait ) def on_anytrait ( self, object, name, old, new ): print 'on anytrait changed:', name, old, new #------------------------------------------------------------------------------ class Test5 ( TestBase ): def __init__ ( self, **traits ): TestBase.__init__( self, **traits ) self.on_trait_change( self.t1_trait, 't1' ) self.on_trait_change( self.t2_trait, 't2' ) def t1_trait ( self, object, name, old, new ): print 'on t1 changed:', old, new def t2_trait ( self, object, name, old, new ): print 'on t2 changed:', old, new #------------------------------------------------------------------------------ class Test6 ( Test5 ): def __init__ ( self, **traits ): Test5.__init__( self, **traits ) self.on_trait_change( self.on_anytrait ) def on_anytrait ( self, object, name, old, new ): print 'on anytrait changed:', name, old, new #------------------------------------------------------------------------------ class Test7 ( Test1 ): def __init__ ( self, **traits ): Test1.__init__( self, **traits ) self.on_trait_change( self.t1_trait, 't1' ) self.on_trait_change( self.t2_trait, 't2' ) def t1_trait ( self, object, name, old, new ): print 'on t1 changed:', old, new def t2_trait ( self, object, name, old, new ): print 'on t2 changed:', old, new #------------------------------------------------------------------------------ class Test8 ( Test2 ): def __init__ ( self, **traits ): Test1.__init__( self, **traits ) self.on_trait_change( self.t1_trait, 't1' ) self.on_trait_change( self.t2_trait, 't2' ) self.on_trait_change( self.on_anytrait ) def on_anytrait ( self, object, name, old, new ): print 'on anytrait changed:', name, old, new def t1_trait ( self, object, name, old, new ): print 'on t1 changed:', old, new def t2_trait ( self, object, name, old, new ): print 'on t2 changed:', old, new #------------------------------------------------------------------------------ test1 = Test1() test1.test() test2 = Test2() test2.test() test3 = Test3() test3.test() test4 = Test4() test4.test() test5 = Test5() test5.test() test6 = Test6() test6.test() test7 = Test7() test7.test() test8 = Test8() test8.test() traits-4.1.0/traits/tests/keyword_args_test_case.py0000644000175100001440000000174211674463323023574 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # Copyright (c) 2007, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # #------------------------------------------------------------------------------- from __future__ import absolute_import from ..api import HasTraits, Instance, Int import unittest class Bar(HasTraits): b = Int(3) class Foo(HasTraits): bar = Instance(Bar) class KeyWordArgsTest(unittest.TestCase): def test_using_kw(self): bar = Bar(b=5) foo = Foo(bar=bar) self.assertEqual(foo.bar.b, 5) def test_not_using_kw(self): foo = Foo() self.assertEqual(foo.bar, None) traits-4.1.0/traits/tests/test_property_notifications.py0000644000175100001440000000431411674463323024714 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # Copyright (c) 2005, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in enthought/LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # Thanks for using Enthought open source! # # Author: David C. Morrill # Description: #------------------------------------------------------------------------------ from __future__ import absolute_import from ..api import HasTraits, Property class Test ( HasTraits ): __traits__ = { } def __value_get ( self ): return self.__dict__.get( '_value', 0 ) def __value_set ( self, value ): old_value = self.__dict__.get( '_value', 0 ) if value != old_value: self._value = value self.trait_property_changed( 'value', old_value, value ) __traits__[ 'value' ] = Property( __value_get, __value_set ) class Test_1 ( Test ): def value_changed ( self, value ): print 'value_changed:', value class Test_2 ( Test ): def anytrait_changed ( self, name, value ): print 'anytrait_changed for %s: %s' % ( name, value ) class Test_3 ( Test_2 ): def value_changed ( self, value ): print 'value_changed:', value def on_value_changed ( value ): print 'on_value_changed:', value def on_anyvalue_changed ( value ): print 'on_anyvalue_changed:', value def test_property_notifications(): Test_1().value = 'test 1' Test_2().value = 'test 2' Test_3().value = 'test 3' test_4 = Test() test_4.on_trait_change( on_value_changed, 'value' ) test_4.value = 'test 4' test_5 = Test() test_5.on_trait_change( on_anyvalue_changed ) test_5.value = 'test 5' test_6 = Test() test_6.on_trait_change( on_value_changed, 'value' ) test_6.on_trait_change( on_anyvalue_changed ) test_6.value = 'test 6' test_7 = Test_3() test_7.on_trait_change( on_value_changed, 'value' ) test_7.on_trait_change( on_anyvalue_changed ) test_7.value = 'test 7' traits-4.1.0/traits/tests/pickle_validated_dict_test_case.py0000644000175100001440000000227511674463323025365 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # Copyright (c) 2007, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # #------------------------------------------------------------------------------- from __future__ import absolute_import from cPickle import dumps, loads import unittest from ..api import Dict, HasTraits, Int, List class C(HasTraits): # A dict trait containing a list trait a = Dict(Int, List(Int)) # And we must initialize it to something non-trivial def __init__(self): super(C, self).__init__() self.a = {1 : [2,3]} class PickleValidatedDictTestCase(unittest.TestCase): def test(self): # And we must unpickle one x = dumps(C()) try: loads(x) except AttributeError, e: self.fail('Unpickling raised an AttributeError: %s' % e) traits-4.1.0/traits/tests/interface_checker_test_case.py0000644000175100001440000002406111674463323024517 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # Copyright (c) 2007, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # #------------------------------------------------------------------------------- """ Tests to help find out if we can do type-safe casting. """ from __future__ import absolute_import # Standard library imports. import unittest # Enthought library imports. from ..api import Adapter, HasTraits, Instance, Int, Interface, adapts, implements # Local imports. from ..interface_checker import InterfaceError, check_implements # Make sure implicit interface checking is turned off, so that we can make the # checks explicitly: from .. import has_traits has_traits.CHECK_INTERFACES = 0 class InterfaceCheckerTestCase(unittest.TestCase): """ Tests to help find out if we can do type-safe casting. """ ########################################################################### # 'TestCase' interface. ########################################################################### def setUp(self): """ Prepares the test fixture before each test method is called. """ return def tearDown(self): """ Called immediately after each test method has been called. """ return ########################################################################### # Tests. ########################################################################### def test_non_traits_class(self): """ non-traits class """ class IFoo(Interface): def foo(self): pass # A class that *does* implement the interface. class Foo(object): implements(IFoo) def foo(self): pass # The checker will raise an exception if the class does not implement # the interface. check_implements(Foo, IFoo, 2) return def test_single_interface(self): """ single interface """ class IFoo(Interface): x = Int # A class that *does* implement the interface. class Foo(HasTraits): implements(IFoo) x = Int # The checker will raise an exception if the class does not implement # the interface. check_implements(Foo, IFoo, 2) return def test_single_interface_with_invalid_method_signature(self): """ single interface with invalid method signature """ class IFoo(Interface): def foo(self): pass # A class that does *not* implement the interface. class Foo(HasTraits): implements(IFoo) # Extra argument! def foo(self, x): pass self.failUnlessRaises(InterfaceError, check_implements, Foo, IFoo, 2) return def test_single_interface_with_missing_trait(self): """ single interface with missing trait """ class IFoo(Interface): x = Int # A class that does *not* implement the interface. class Foo(HasTraits): implements(IFoo) self.failUnlessRaises(InterfaceError, check_implements, Foo, IFoo, 2) return def test_single_interface_with_missing_method(self): """ single interface with missing method """ class IFoo(Interface): def method(self): pass # A class that does *not* implement the interface. class Foo(HasTraits): implements(IFoo) self.failUnlessRaises(InterfaceError, check_implements, Foo, IFoo, 2) return def test_multiple_interfaces(self): """ multiple interfaces """ class IFoo(Interface): x = Int class IBar(Interface): y = Int class IBaz(Interface): z = Int # A class that *does* implement the interface. class Foo(HasTraits): implements(IFoo, IBar, IBaz) x = Int y = Int z = Int # The checker will raise an exception if the class does not implement # the interface. check_implements(Foo, [IFoo, IBar, IBaz], 2) return def test_multiple_interfaces_with_invalid_method_signature(self): """ multiple interfaces with invalid method signature """ class IFoo(Interface): def foo(self): pass class IBar(Interface): def bar(self): pass class IBaz(Interface): def baz(self): pass # A class that does *not* implement the interface. class Foo(HasTraits): implements(IFoo, IBar, IBaz) def foo(self): pass def bar(self): pass # Extra argument! def baz(self, x): pass self.failUnlessRaises( InterfaceError, check_implements, Foo, [IFoo, IBar, IBaz], 2 ) return def test_multiple_interfaces_with_missing_trait(self): """ multiple interfaces with missing trait """ class IFoo(Interface): x = Int class IBar(Interface): y = Int class IBaz(Interface): z = Int # A class that does *not* implement the interface. class Foo(HasTraits): implements(IFoo, IBar, IBaz) x = Int y = Int self.failUnlessRaises( InterfaceError, check_implements, Foo, [IFoo, IBar, IBaz], 2 ) return def test_multiple_interfaces_with_missing_method(self): """ multiple interfaces with missing method """ class IFoo(Interface): def foo(self): pass class IBar(Interface): def bar(self): pass class IBaz(Interface): def baz(self): pass # A class that does *not* implement the interface. class Foo(HasTraits): implements(IFoo, IBar, IBaz) def foo(self): pass def bar(self): pass self.failUnlessRaises( InterfaceError, check_implements, Foo, [IFoo, IBar, IBaz], 2 ) return def test_inherited_interfaces(self): """ inherited interfaces """ class IFoo(Interface): x = Int class IBar(IFoo): y = Int class IBaz(IBar): z = Int # A class that *does* implement the interface. class Foo(HasTraits): implements(IBaz) x = Int y = Int z = Int # The checker will raise an exception if the class does not implement # the interface. check_implements(Foo, IBaz, 2) return def test_inherited_interfaces_with_invalid_method_signature(self): """ inherited with invalid method signature """ class IFoo(Interface): def foo(self): pass class IBar(IFoo): def bar(self): pass class IBaz(IBar): def baz(self): pass # A class that does *not* implement the interface. class Foo(HasTraits): implements(IBaz) def foo(self): pass def bar(self): pass # Extra argument! def baz(self, x): pass self.failUnlessRaises(InterfaceError, check_implements, Foo, IBaz, 2) return def test_inherited_interfaces_with_missing_trait(self): """ inherited interfaces with missing trait """ class IFoo(Interface): x = Int class IBar(IFoo): y = Int class IBaz(IBar): z = Int # A class that does *not* implement the interface. class Foo(HasTraits): implements(IBaz) x = Int y = Int self.failUnlessRaises(InterfaceError, check_implements, Foo, IBaz, 2) return def test_inherited_interfaces_with_missing_method(self): """ inherited interfaces with missing method """ class IFoo(Interface): def foo(self): pass class IBar(IFoo): def bar(self): pass class IBaz(IBar): def baz(self): pass # A class that does *not* implement the interface. class Foo(HasTraits): implements(IBaz) def foo(self): pass def bar(self): pass self.failUnlessRaises(InterfaceError, check_implements, Foo, IBaz, 2) return # Make sure interfaces and adaptation etc still work with the 'HasTraits' # version of 'Interface'! def test_instance(self): """ instance """ class IFoo(Interface): pass class Foo(HasTraits): implements(IFoo) class Bar(HasTraits): foo = Instance(IFoo) b = Bar(foo=Foo()) return def test_callable(self): """ callable """ class IFoo(Interface): pass class Foo(HasTraits): implements(IFoo) f = Foo() self.assertEqual(f, IFoo(f)) return def test_adaptation(self): """ adaptation """ class IFoo(Interface): pass class Foo(HasTraits): pass class FooToIFooAdapter(Adapter): adapts(Foo, IFoo) f = Foo() # Make sure adaptation works. i_foo = IFoo(f) self.assertNotEqual(None, i_foo) self.assertEqual(FooToIFooAdapter, type(i_foo)) return # Entry point for stand-alone testing. if __name__ == '__main__': unittest.main() traits-4.1.0/traits/tests/undefined_test_case.py0000644000175100001440000000411211674463323023027 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # Copyright (c) 2007, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # #------------------------------------------------------------------------------- from __future__ import absolute_import import unittest from ..api import HasTraits, Str, Undefined, ReadOnly, Float class Foo(HasTraits): name = Str() original_name = ReadOnly bar = Str baz = Float def _name_changed(self): if self.original_name is Undefined: self.original_name = self.name class Bar(HasTraits): name = Str(Undefined) class UndefinedTestCase(unittest.TestCase): def test_initial_value(self): b = Bar() self.failUnlessEqual( b.name, Undefined ) return def test_name_change(self): b = Bar() b.name = 'first' self.failUnlessEqual( b.name, 'first' ) return def test_read_only_write_once(self): f = Foo() self.failUnlessEqual(f.name, '') self.failUnless(f.original_name is Undefined) f.name = 'first' self.failUnlessEqual(f.name, 'first') self.failUnlessEqual(f.original_name, 'first') f.name = 'second' self.failUnlessEqual(f.name, 'second') self.failUnlessEqual(f.original_name, 'first') return def test_read_only_write_once_from_constructor(self): f = Foo(name='first') f.name = 'first' self.failUnlessEqual(f.name, 'first') self.failUnlessEqual(f.original_name, 'first') f.name = 'second' self.failUnlessEqual(f.name, 'second') self.failUnlessEqual(f.original_name, 'first') return ### EOF ####################################################################### traits-4.1.0/traits/tests/test_target.py0000644000175100001440000000433011674463323021363 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # Copyright (c) 2010, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # #------------------------------------------------------------------------------- """ Test whether HasTraits objects with cycles can be garbage collected. """ # Standard library imports import unittest # Enthought library imports from traits.api import HasTraits, Instance, Int class TestCase(unittest.TestCase): """ Tests the 'target' argument for on_traits_change. """ def test_simple(self): """ Tests a simple dynamic trait change handler. """ class Test(HasTraits): i = Int # Create objects obj = Test() target = HasTraits() # Set up to count changes in i self.count = 0 def count_notifies(): self.count += 1 obj.on_trait_change(count_notifies, "i", target=target) # Change the trait obj.i = 10 # Delete the target and change it again del target obj.i = 0 # The count should be 1 self.assertEqual(self.count, 1) def test_extended(self): """ Tests a dynamic trait change handler using extended names. """ class Child(HasTraits): i = Int class Parent(HasTraits): child = Instance(Child) # Create objects parent = Parent(child=Child()) target = HasTraits() # Set up to count changes in i self.count = 0 def count_notifies(): self.count += 1 parent.on_trait_change(count_notifies, "child:i", target=target) # Change the trait parent.child.i = 10 # Delete the target and change it again del target parent.child.i = 0 # The count should be 1 self.assertEqual(self.count, 1) if __name__ == '__main__': unittest.main() traits-4.1.0/traits/tests/test_copy_traits.py0000644000175100001440000002646511674463323022452 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # Copyright (c) 2007, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # # #------------------------------------------------------------------------------- from __future__ import absolute_import import unittest from ..api import HasTraits, Instance, Str class Shared(HasTraits): s = Str('new instance of Shared') class Foo(HasTraits): s = Str('new instance of Foo') shared = Instance(Shared) class Bar(HasTraits): s = Str('new instance of Bar') foo = Instance(Foo) shared = Instance(Shared) class Baz(HasTraits): s = Str('new instance of Baz') bar = Instance(Bar) shared = Instance(Shared) class CopyTraitsBase( unittest.TestCase ): """ Validate that copy_traits """ __test__ = False def setUp(self): print '\n**CopyTraitsBase.setUp ', super(CopyTraitsBase,self).setUp() self.shared = Shared(s='shared') self.foo = Foo(shared=self.shared, s='foo') self.bar = Bar(shared=self.shared, foo=self.foo, s='bar') self.baz = Baz(shared=self.shared, bar=self.bar, s='baz') self.shared2 = Shared( s='shared2' ) self.foo2 = Foo( shared=self.shared2, s='foo2' ) self.bar2 = Bar( shared=self.shared2, foo=self.foo2, s='bar2' ) self.baz2 = Baz( shared=self.shared2, bar=self.bar2, s='baz2' ) return def print_copy(self): print '\nfoo.copy:', self.foo.base_trait('shared').copy print 'bar.copy:', self.bar.base_trait('shared').copy print 'baz.copy:', self.baz.base_trait('shared').copy print 'foo2.copy:', self.foo2.base_trait('shared').copy print 'bar2.copy:', self.bar2.base_trait('shared').copy print 'baz2.copy:', self.baz2.base_trait('shared').copy def set_shared_copy(self, value): """ Change the copy style for the 'shared' traits. """ #self.print_copy() self.foo.base_trait('shared').copy = value self.bar.base_trait('shared').copy = value self.baz.base_trait('shared').copy = value # copy is metadata and therefore a shared a class attribute # self.foo2.base_trait('shared').copy = value # self.bar2.base_trait('shared').copy = value # self.baz2.base_trait('shared').copy = value #self.print_copy() class TestCopyTraitsSetup( CopyTraitsBase ): __test__ = True def setUp(self): super(TestCopyTraitsSetup,self).setUp() print '\nshared', self.shared print 'foo', self.foo print 'bar', self.bar print 'baz', self.baz print '\nshared2', self.shared2 print 'foo2', self.foo2 print 'bar2', self.bar2 print 'baz2', self.baz2 return def test_setup(self): self.failUnless( self.foo is self.bar.foo ) self.failUnless( self.bar is self.baz.bar ) self.failUnless( self.foo.shared is self.shared ) self.failUnless( self.bar.shared is self.shared ) self.failUnless( self.baz.shared is self.shared ) self.failUnless( self.foo2 is self.bar2.foo ) self.failUnless( self.bar2 is self.baz2.bar ) self.failUnless( self.foo2.shared is self.shared2 ) self.failUnless( self.bar2.shared is self.shared2 ) self.failUnless( self.baz2.shared is self.shared2 ) return class CopyTraits: def test_baz2_s(self): self.failUnlessEqual(self.baz2.s, 'baz') self.failUnlessEqual(self.baz2.s, self.baz.s) def test_baz2_bar_s(self): self.failUnlessEqual(self.baz2.bar.s, 'bar') self.failUnlessEqual(self.baz2.bar.s, self.baz.bar.s) def test_baz2_bar_foo_s(self): self.failUnlessEqual(self.baz2.bar.foo.s, 'foo') self.failUnlessEqual(self.baz2.bar.foo.s, self.baz.bar.foo.s) def test_baz2_shared_s(self): self.failUnlessEqual(self.baz2.shared.s, 'shared') self.failUnlessEqual(self.baz2.bar.shared.s, 'shared') self.failUnlessEqual(self.baz2.bar.foo.shared.s, 'shared') def test_baz2_bar(self): # First hand Instance trait is different and # is not the same object as the source. self.failIf( self.baz2.bar is None) self.failIf( self.baz2.bar is self.bar2 ) self.failIf( self.baz2.bar is self.baz.bar ) def test_baz2_bar_foo(self): # Second hand Instance trait is a different object and # is not the same object as the source. self.failIf( self.baz2.bar.foo is None) self.failIf( self.baz2.bar.foo is self.foo2 ) self.failIf( self.baz2.bar.foo is self.baz.bar.foo ) class CopyTraitsSharedCopyNone: def test_baz2_shared(self): # First hand Instance trait is a different object and # is not the same object as the source. self.failIf( self.baz2.shared is None) self.failIf( self.baz2.shared is self.shared2) self.failIf( self.baz2.shared is self.shared) def test_baz2_bar_shared(self): # Second hand Instance that was shared is a different object and # not the same object as the source and # not the same object as the new first hand instance that was the same. # I.e. There are now (at least) two copies of one orginal object. self.failIf( self.baz2.bar.shared is None ) self.failIf( self.baz2.bar.shared is self.shared2 ) self.failIf( self.baz2.bar.shared is self.shared ) self.failIf( self.baz2.bar.shared is self.baz2.shared ) def test_baz2_bar_foo_shared(self): # Third hand Instance that was shared is a different object and # not the same object as the source and # not the same object as the new first hand instance that was the same. # I.e. There are now (at least) two copies of one orginal object. self.failIf( self.baz2.bar.foo.shared is None ) self.failIf( self.baz2.bar.foo.shared is self.shared2 ) self.failIf( self.baz2.bar.foo.shared is self.shared ) self.failIf( self.baz2.bar.foo.shared is self.baz2.shared ) def test_baz2_bar_and_foo_shared(self): # # THE BEHAVIOR DEMONSTRATED BY THIS TEST CASE DOES NOT SEEM TO BE CORRECT. # # Second and Third hand Instance object that was shared with first hand # instance are the same as each other but # Every reference to the same original object has been replace by # a reference to the same copy of the same source object except the # first hand reference which is a different copy. # I.e. The shared relationship has been fubarred by copy_traits: it's # not maintained, but not completely destroyed. self.failUnless( self.baz2.bar.shared is self.baz2.bar.foo.shared ) self.failIf( self.baz2.shared is self.baz2.bar.foo.shared ) class TestCopyTraitsSharedCopyNone( CopyTraits, CopyTraitsSharedCopyNone ): __test__ = False def setUp(self): print '\n***TestCopyTraitsSharedCopyNone', #super(TestCopyTraitsSharedCopyNone,self).setUp() # deep is the default value for Instance trait copy self.set_shared_copy('deep') return class TestCopyTraitsCopyNotSpecified( CopyTraitsBase, TestCopyTraitsSharedCopyNone ): __test__ = True def setUp(self): print '\n*TestCopyTraitsCopyNotSpecified', # super(TestCopyTraitsCopyNotSpecified,self).setUp() CopyTraitsBase.setUp(self) TestCopyTraitsSharedCopyNone.setUp(self) self.baz2.copy_traits( self.baz ) return class TestCopyTraitsCopyShallow( CopyTraitsBase, TestCopyTraitsSharedCopyNone ): __test__ = True def setUp(self): print '\n*TestCopyTraitsCopyShallow', # super(TestCopyTraitsCopyShallow,self).setUp() CopyTraitsBase.setUp(self) TestCopyTraitsSharedCopyNone.setUp(self) self.baz2.copy_traits( self.baz, copy='shallow' ) return class TestCopyTraitsCopyDeep( CopyTraitsBase, TestCopyTraitsSharedCopyNone ): __test__ = True def setUp(self): print '\n*TestCopyTraitsCopyDeep', # super(TestCopyTraitsCopyDeep,self).setUp() CopyTraitsBase.setUp(self) TestCopyTraitsSharedCopyNone.setUp(self) self.baz2.copy_traits( self.baz, copy='deep' ) return class CopyTraitsSharedCopyRef: def test_baz2_shared(self): # First hand Instance trait is a different object and # is the same object as the source. self.failIf( self.baz2.shared is None) self.failIf( self.baz2.shared is self.shared2) self.failUnless( self.baz2.shared is self.shared) def test_baz2_bar_shared(self): self.failIf( self.baz2.bar.shared is None ) self.failIf( self.baz2.bar.shared is self.shared2 ) self.failUnless( self.baz2.bar.shared is self.shared ) self.failUnless( self.baz2.bar.shared is self.baz2.shared ) def test_baz2_bar_foo_shared(self): self.failIf( self.baz2.bar.foo.shared is None ) self.failIf( self.baz2.bar.foo.shared is self.shared2 ) self.failUnless( self.baz2.bar.foo.shared is self.shared ) self.failUnless( self.baz2.bar.foo.shared is self.baz2.shared ) def test_baz2_bar_and_foo_shared(self): self.failUnless( self.baz2.bar.shared is self.baz2.bar.foo.shared ) self.failUnless( self.baz2.shared is self.baz2.bar.foo.shared ) class TestCopyTraitsSharedCopyRef( CopyTraits, CopyTraitsSharedCopyRef ): __test__ = False def setUp(self): print '\n***TestCopyTraitsSharedCopyRef.setUp ', #super(TestCopyTraitsSharedCopyRef,self).setUp() self.set_shared_copy('ref') return # The next three tests demostrate that a 'ref' trait is always copied as a # reference regardless of the copy argument to copy_traits. That is, shallow # and deep are indistinguishable. class TestCopyTraitsCopyNotSpecifiedSharedRef( CopyTraitsBase, TestCopyTraitsSharedCopyRef): __test__ = True def setUp(self): print '\n*TestCopyTraitsCopyNotSpecifiedSharedRef.setUp', # super(TestCopyTraitsCopyNotSpecifiedSharedRef,self).setUp() CopyTraitsBase.setUp(self) TestCopyTraitsSharedCopyRef.setUp(self) self.baz2.copy_traits( self.baz ) return class TestCopyTraitsCopyShallowSharedRef( CopyTraitsBase, TestCopyTraitsSharedCopyRef ): __test__ = True def setUp(self): print '\n*TestCopyTraitsCopyShallowSharedRef.setUp', # super(TestCopyTraitsCopyShallowSharedRef,self).setUp() CopyTraitsBase.setUp(self) TestCopyTraitsSharedCopyRef.setUp(self) self.baz2.copy_traits( self.baz, copy='shallow' ) return class TestCopyTraitsCopyDeepSharedRef( CopyTraitsBase, TestCopyTraitsSharedCopyRef ): __test__ = True def setUp(self): print '\n*TestCopyTraitsCopyDeepSharedRef.setUp', # super(TestCopyTraitsCopyDeepSharedRef,self).setUp() CopyTraitsBase.setUp(self) TestCopyTraitsSharedCopyRef.setUp(self) self.baz2.copy_traits( self.baz, copy='deep' ) return ### EOF traits-4.1.0/traits/tests/check_timing.py0000644000175100001440000001664511674463323021476 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # Copyright (c) 2005, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # Thanks for using Enthought open source! # # Author: David C. Morrill # Date: 03/03/2003 # Description: Perform timing tests on various trait styles to determine the # amount of overhead that traits add. #------------------------------------------------------------------------------ #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from __future__ import absolute_import from time import time from ..api import Any, Delegate, HasTraits, Int, Range print 'OK!' #------------------------------------------------------------------------------- # Constants: #------------------------------------------------------------------------------- # Number of iterations to perform: n = 1000000 # Loop overhead time (actual value determined first time a measurement is made): t0 = -1.0 #------------------------------------------------------------------------------- # Measure how long it takes to execute a specified function: #------------------------------------------------------------------------------- def measure ( func ): now = time() func() return time() - now #------------------------------------------------------------------------------- # 'Old style' Python attribute get/set: #------------------------------------------------------------------------------- class old_style_value: def measure ( self ): global t0 self.init() if t0 < 0.0: t0 = measure( self.null ) t1 = measure( self.do_get ) t2 = measure( self.do_set ) scale = 1.0e6 / n print self.__class__.__name__ + ':' print ' get: %.2f usec' % (max( t1 - t0, 0.0 ) * scale) print ' set: %.2f usec' % (max( t2 - t0, 0.0 ) * scale) print def null ( self ): for i in range(n): pass def init ( self ): self.value = -1 def do_set ( self ): for i in range(n): self.value = i def do_get ( self ): for i in range(n): self.value #------------------------------------------------------------------------------- # 'New style' Python attribute get/set: #------------------------------------------------------------------------------- class new_style_value ( object ): def measure ( self ): global t0 self.init() if t0 < 0.0: t0 = measure( self.null ) t1 = measure( self.do_get ) t2 = measure( self.do_set ) scale = 1.0e6 / n print self.__class__.__name__ + ':' print ' get: %.2f usec' % (max( t1 - t0, 0.0 ) * scale) print ' set: %.2f usec' % (max( t2 - t0, 0.0 ) * scale) print def null ( self ): for i in range(n): pass def init ( self ): self.value = -1 def do_set ( self ): for i in range(n): self.value = i def do_get ( self ): for i in range(n): self.value #------------------------------------------------------------------------------- # Python 'property' get/set: #------------------------------------------------------------------------------- class property_value ( new_style_value ): def get_value ( self ): return self._value def set_value ( self, value ): self._value = value value = property( get_value, set_value ) #------------------------------------------------------------------------------- # Python 'global' get/set: #------------------------------------------------------------------------------- class global_value ( new_style_value ): def init ( self ): global gvalue gvalue = -1 def do_set ( self ): global gvalue for i in range(n): gvalue = i def do_get ( self ): global gvalue for i in range(n): gvalue #------------------------------------------------------------------------------- # Trait that can have any value: #------------------------------------------------------------------------------- class any_value ( HasTraits, new_style_value ): value = Any #------------------------------------------------------------------------------- # Trait that can only have 'float' values: #------------------------------------------------------------------------------- class int_value ( any_value ): value = Int #------------------------------------------------------------------------------- # Trait that can only have 'range' values: #------------------------------------------------------------------------------- class range_value ( any_value ): value = Range( -1, 2000000000 ) #------------------------------------------------------------------------------- # Executes method when float trait is changed: #------------------------------------------------------------------------------- class change_value ( int_value ): def _value_changed ( self, old, new ): pass #------------------------------------------------------------------------------- # Notifies handler when float trait is changed: #------------------------------------------------------------------------------- class monitor_value ( int_value ): def init ( self ): self.on_trait_change( self.on_value_change, 'value' ) def on_value_change ( self, object, trait_name, old, new ): pass #------------------------------------------------------------------------------- # Float trait is delegated to another object: #------------------------------------------------------------------------------- class delegate_value ( HasTraits, new_style_value ): value = Delegate( 'delegate' ) delegate = Any def init ( self ): self.delegate = int_value() #------------------------------------------------------------------------------- # Float trait is delegated through one object to another object: #------------------------------------------------------------------------------- class delegate_2_value ( delegate_value ): def init ( self ): self.delegate = delegate_value() self.delegate.init() #------------------------------------------------------------------------------- # Float trait is delegated through two objects to another object: #------------------------------------------------------------------------------- class delegate_3_value ( delegate_value ): def init ( self ): self.delegate = delegate_2_value() self.delegate.init() #------------------------------------------------------------------------------- # Run the timing measurements: #------------------------------------------------------------------------------- if __name__ == '__main__': old_style_value().measure() new_style_value().measure() property_value().measure() global_value().measure() any_value().measure() int_value().measure() range_value().measure() change_value().measure() monitor_value().measure() delegate_value().measure() delegate_2_value().measure() delegate_3_value().measure() traits-4.1.0/traits/tests/test_trait_types.py0000644000175100001440000000410711674463323022446 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # Unit test case for testing trait types created by subclassing TraitType. # # Written by: David C. Morrill # # Date: 4/10/2007 # # Copyright (c) 2007, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # #------------------------------------------------------------------------------- """ Unit test case for testing trait types created by subclassing TraitType. """ #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- import unittest #------------------------------------------------------------------------------- # 'TraitTypesTest' unit test class: #------------------------------------------------------------------------------- class TraitTypesTest ( unittest.TestCase ): #--------------------------------------------------------------------------- # Test fixture set-up: #--------------------------------------------------------------------------- def setUp ( self ): """ Test fixture set-up. """ pass #--------------------------------------------------------------------------- # Test fixture tear-down: #--------------------------------------------------------------------------- def tearDown ( self ): """ Test fixture tear-down. """ pass #--------------------------------------------------------------------------- # Individual unit test methods: #--------------------------------------------------------------------------- def test_ ( self ): pass # Run the unit tests (if invoked from the command line): if __name__ == '__main__': unittest.main() traits-4.1.0/traits/tests/test_trait_cycle.py0000644000175100001440000001014411674463323022377 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # Copyright (c) 2007, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # #------------------------------------------------------------------------------- """ Test whether HasTraits objects with cycles can be garbage collected. """ from __future__ import absolute_import import gc import time import unittest # Enthought library imports from ..api import HasTraits, Any, DelegatesTo, Instance, Int class TestCase(unittest.TestCase): def _simple_cycle_helper(self, foo_class): """ Can the garbage collector clean up a cycle with traits objects? """ # Create two Foo objects that refer to each other. first = foo_class() second = foo_class(child=first) first.child=second # get their ids foo_ids = [id(first), id(second)] # delete the items so that they can be garbage collected del first, second # tell the garbage collector to pick up the litter. gc.collect() # Now grab all objects in the process and ask for their ids all_ids = [id(obj) for obj in gc.get_objects()] # Ensure that neither of the Foo object ids are in this list for foo_id in foo_ids: self.assertTrue(foo_id not in all_ids) def test_simple_cycle_oldstyle_class(self): """ Can the garbage collector clean up a cycle with old style class? """ class Foo: def __init__(self,child=None): self.child = child self._simple_cycle_helper(Foo) def test_simple_cycle_newstyle_class(self): """ Can the garbage collector clean up a cycle with new style class? """ class Foo(object): def __init__(self,child=None): self.child = child self._simple_cycle_helper(Foo) def test_simple_cycle_hastraits(self): """ Can the garbage collector clean up a cycle with traits objects? """ class Foo(HasTraits): child = Any self._simple_cycle_helper(Foo) def test_reference_to_trait_dict(self): """ Does a HasTraits object refer to its __dict__ object? This test may point to why the previous one fails. Even if it doesn't, the functionality is needed for detecting problems with memory in debug.memory_tracker """ class Foo(HasTraits): child = Any foo = Foo() # It seems like foo sometimes has not finished construction yet, so the # frame found by referrers is not _exactly_ the same as Foo(). For more # information, see the gc doc: http://docs.python.org/lib/module-gc.html # # The documentation says that this (get_referrers) should be used for no # purpose other than debugging, so this is really not a good way to test # the code. time.sleep(0.1) referrers = gc.get_referrers(foo.__dict__) self.assertTrue(len(referrers) > 0) self.assertTrue(foo in referrers) def test_delegates_to(self): """ Tests if an object that delegates to another is freed. """ class Base(HasTraits): """ Object we are delegating to. """ i = Int class Delegates(HasTraits): """ Object that delegates. """ b = Instance(Base) i = DelegatesTo('b') # Make a pair of object b = Base() d = Delegates(b=b) # Delete d and thoroughly collect garbage del d for i in range(3): gc.collect(2) # See if we still have a Delegates ds = [ obj for obj in gc.get_objects() if isinstance(obj, Delegates) ] self.assert_(ds == []) if __name__ == '__main__': unittest.main() traits-4.1.0/traits/tests/test_getstate_setstate.py0000644000175100001440000000412111674463323023627 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # Unit test case for testing HasTraits __getstate__/__setstate__ support. # # Written by: David C. Morrill # # Date: 4/10/2007 # # Copyright (c) 2007, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # #------------------------------------------------------------------------------- """ Unit test case for testing HasTraits __getstate__/__setstate__ support. """ #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- import unittest #------------------------------------------------------------------------------- # 'GetstateSetstateTest' unit test class: #------------------------------------------------------------------------------- class GetstateSetstateTest ( unittest.TestCase ): #--------------------------------------------------------------------------- # Test fixture set-up: #--------------------------------------------------------------------------- def setUp ( self ): """ Test fixture set-up. """ pass #--------------------------------------------------------------------------- # Test fixture tear-down: #--------------------------------------------------------------------------- def tearDown ( self ): """ Test fixture tear-down. """ pass #--------------------------------------------------------------------------- # Individual unit test methods: #--------------------------------------------------------------------------- def test_ ( self ): pass # Run the unit tests (if invoked from the command line): if __name__ == '__main__': unittest.main() traits-4.1.0/traits/tests/list_test_case.py0000644000175100001440000001600311674463323022043 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # Copyright (c) 2007, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # #------------------------------------------------------------------------------- from __future__ import absolute_import import unittest from ..api import CList, HasTraits, Instance, Int, List, Str, TraitError class Foo(HasTraits): l = List(Str) class Bar(HasTraits): name = Str class Baz(HasTraits): bars = List(Bar) class BazRef(HasTraits): bars = List(Bar, copy='ref') class DeepBaz(HasTraits): baz = Instance(Baz) class DeepBazBazRef(HasTraits): baz = Instance(BazRef) class CFoo(HasTraits): ints = CList(Int) strs = CList(Str) class ListTestCase(unittest.TestCase): def test_initialized(self): f = Foo() self.failIfEqual( f.l, None ) self.failUnlessEqual( len(f.l), 0 ) return def test_initializer(self): f = Foo( l=['a', 'list']) self.failIfEqual( f.l, None ) self.failUnlessEqual( f.l, ['a', 'list'] ) return def test_type_check(self): f = Foo() f.l.append('string') self.failUnlessRaises( TraitError, f.l.append, 123.456 ) return def test_append(self): f = Foo() f.l.append('bar') self.failUnlessEqual(f.l, ['bar']) return def test_remove(self): f = Foo() f.l.append('bar') f.l.remove('bar') self.failUnlessEqual(f.l, []) return def test_slice(self): f = Foo( l=['zero', 'one', 'two', 'three'] ) self.failUnlessEqual( f.l[0], 'zero') self.failUnlessEqual( f.l[:0], []) self.failUnlessEqual( f.l[:1], ['zero']) self.failUnlessEqual( f.l[0:1], ['zero']) self.failUnlessEqual( f.l[1:], ['one','two','three']) self.failUnlessEqual( f.l[-1], 'three') self.failUnlessEqual( f.l[-2], 'two') self.failUnlessEqual( f.l[:-1], ['zero', 'one', 'two']) return def test_retrieve_reference(self): f = Foo( l=['initial', 'value'] ) l = f.l self.failUnless( l is f.l ) # no copy on change behavior, l is always a reference l.append('change') self.failUnlessEqual( f.l, ['initial', 'value', 'change']) f.l.append('more change') self.failUnlessEqual( l, ['initial', 'value', 'change', 'more change']) return def test_assignment_makes_copy(self): f = Foo( l=['initial', 'value'] ) l = ['new'] f.l = l # same content self.failUnlessEqual( l, f.l) # different objects self.failIf( l is f.l ) # which means behaviorally... l.append('l change') self.failIf( 'l change' in f.l ) f.l.append('f.l change') self.failIf( 'f.l change' in l ) return def test_should_not_allow_none(self): f = Foo( l=['initial', 'value'] ) try: f.l = None self.fail('None assigned to List trait.') except TraitError: pass def test_clone(self): baz = Baz() for name in ['a', 'b', 'c', 'd']: baz.bars.append( Bar(name=name) ) # Clone will clone baz, the bars list, and the objects in the list baz_copy = baz.clone_traits() self.failIf( baz_copy is baz) self.failIf( baz_copy.bars is baz.bars) self.failUnlessEqual( len(baz_copy.bars), len(baz.bars) ) for bar in baz.bars: self.failIf( bar in baz_copy.bars ) baz_bar_names = [ bar.name for bar in baz.bars ] baz_copy_bar_names = [ bar.name for bar in baz_copy.bars ] baz_bar_names.sort() baz_copy_bar_names.sort() self.failUnlessEqual( baz_copy_bar_names, baz_bar_names ) return def test_clone_ref(self): baz = BazRef() for name in ['a', 'b', 'c', 'd']: baz.bars.append( Bar(name=name) ) # Clone will clone baz, the bars list, but the objects in the list # will not be cloned because the copy metatrait of the List is 'ref' baz_copy = baz.clone_traits() self.failIf( baz_copy is baz) self.failIf( baz_copy.bars is baz.bars) self.failUnlessEqual( len(baz_copy.bars), len(baz.bars) ) for bar in baz.bars: self.failUnless( bar in baz_copy.bars ) return def test_clone_deep_baz(self): baz = Baz() for name in ['a', 'b', 'c', 'd']: baz.bars.append( Bar(name=name) ) deep_baz = DeepBaz( baz=baz ) # Clone will clone deep_baz, deep_baz.baz, the bars list, # and the objects in the list deep_baz_copy = deep_baz.clone_traits() self.failIf( deep_baz_copy is deep_baz) self.failIf( deep_baz_copy.baz is deep_baz.baz) baz_copy = deep_baz_copy.baz self.failIf( baz_copy is baz) self.failIf( baz_copy.bars is baz.bars) self.failUnlessEqual( len(baz_copy.bars), len(baz.bars) ) for bar in baz.bars: self.failIf( bar in baz_copy.bars ) baz_bar_names = [ bar.name for bar in baz.bars ] baz_copy_bar_names = [ bar.name for bar in baz_copy.bars ] baz_bar_names.sort() baz_copy_bar_names.sort() self.failUnlessEqual( baz_copy_bar_names, baz_bar_names ) return def test_clone_deep_baz_ref(self): baz = BazRef() for name in ['a', 'b', 'c', 'd']: baz.bars.append( Bar(name=name) ) deep_baz = DeepBazBazRef( baz=baz ) deep_baz_copy = deep_baz.clone_traits() self.failIf( deep_baz_copy is deep_baz) self.failIf( deep_baz_copy.baz is deep_baz.baz) baz_copy = deep_baz_copy.baz self.failIf( baz_copy is baz) self.failIf( baz_copy.bars is baz.bars) self.failUnlessEqual( len(baz_copy.bars), len(baz.bars) ) for bar in baz.bars: self.failUnless( bar in baz_copy.bars ) return def test_coercion(self): f = CFoo() # Test coercion from basic built-in types f.ints = [1,2,3] desired = [1,2,3] self.failUnlessEqual( f.ints, desired ) f.ints = (1,2,3) self.failUnlessEqual( f.ints, desired ) f.strs = ("abc", "def", "ghi") self.failUnlessEqual( f.strs, ["abc", "def", "ghi"] ) f.strs = "abcdef" self.failUnlessEqual( f.strs, list("abcdef") ) try: from numpy import array f.ints = array([1,2,3]) self.failUnlessEqual( f.ints, [1,2,3] ) f.strs = array( ("abc", "def", "ghi") ) self.failUnlessEqual( f.strs, ["abc", "def", "ghi"] ) except ImportError: pass ### EOF traits-4.1.0/traits/tests/range_test_case.py0000644000175100001440000000775711674463323022204 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # Copyright (c) 2007, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # #------------------------------------------------------------------------------- from __future__ import absolute_import import unittest from ..api import HasTraits, Int, Range, Str class WithFloatRange(HasTraits): r = Range(0.0, 100.0) r_copied_on_change = Str _changed_handler_calls = Int def _r_changed(self, old, new): self._changed_handler_calls += 1 self.r_copied_on_change = str(self.r) if (self.r % 10) > 0: self.r += 10-(self.r % 10) class WithLargeIntRange(HasTraits): r = Range(0, 1000) r_copied_on_change = Str _changed_handler_calls = Int def _r_changed(self, old, new): self._changed_handler_calls += 1 self.r_copied_on_change = str(self.r) if self.r > 100: self.r = 0 class RangeTestCase(unittest.TestCase): def test_non_ui_events(self): obj = WithFloatRange() obj._changed_handler_calls = 0 obj.r = 10 self.failUnlessEqual(1, obj._changed_handler_calls) obj._changed_handler_calls = 0 obj.r = 34.56 self.failUnlessEqual(2, obj._changed_handler_calls) self.failUnlessEqual(40, obj.r) return def test_non_ui_int_events(self): # Even thou the range is configured for 0..1000, the handler resets # the value to 0 when it exceeds 100. obj = WithLargeIntRange() obj._changed_handler_calls = 0 obj.r = 10 self.failUnlessEqual(1, obj._changed_handler_calls) self.failUnlessEqual(10, obj.r) obj.r = 100 self.failUnlessEqual(2, obj._changed_handler_calls) self.failUnlessEqual(100, obj.r) obj.r = 101 self.failUnlessEqual(4, obj._changed_handler_calls) self.failUnlessEqual(0, obj.r) return def ui_test_events(self): import nose raise nose.SkipTest('Requires GUI') print print 'enter the value 34.56 in the range text box and tab out or enter.' print 'Notice that the changed handler call count is 2.' print 'Notice the slider is at 34.56 and the text box still shows 34.56' print 'Notice that r_copied_on_change shows 40.0' print 'Click OK to close the window.' print 'The test will not fail, because the range value was rounded by the event handler.' print 'However, the range widget did not show that change.' obj = WithFloatRange() obj._changed_handler_calls = 0 obj.edit_traits(kind='livemodal', ) self.failUnlessEqual( obj.r%10, 0 ) return def ui_test_int_events(self): import nose raise nose.SkipTest('Requires GUI') print print 'enter the value 95 in the range text box.' print 'Notice that the changed handler call count is 2.' print 'Notice that r_copied_on_change shows 95' print 'Click the up arrow 5 times. Each time the handler call count will increment by one.' print 'The R value is now 100 and the change handler call count is 7.' print 'Click the up array 1 time. The call count is 11, R is 101 (wrong), and R copied on change is 0 (correct)' print 'Click OK to close the window.' print 'The test will not fail, because the range value kept below 101 by the event handler.' print 'However, the range widget did not show that change.' obj = WithLargeIntRange() obj._changed_handler_calls = 0 obj.edit_traits(kind='livemodal', ) self.failUnless( obj.r <= 100 ) return ### EOF traits-4.1.0/traits/tests/protocols_usage_test_case.py0000644000175100001440000002271311674463323024305 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # Copyright (c) 2007, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # #------------------------------------------------------------------------------- """ Tests for protocols usage. """ from __future__ import absolute_import # Standard library imports. import pickle, unittest, os # Enthought library imports. from ..api import (Bool, HasTraits, Int, Interface, Str, Adapter, adapts, Property) # NOTE: There is a File class in apptools.io module, but since we want to # eliminate dependencies of Traits on other modules, we create another # minimal File class here to test the adapter implementation. # Test class class File(HasTraits): # The path name of this file/folder. path = Str # Is this an existing file? is_file = Property(Bool) # Is this an existing folder? is_folder = Property(Bool) def _get_is_file(self): """ Returns True if the path exists and is a file. """ return os.path.exists(self.path) and os.path.isfile(self.path) def _get_is_folder(self): """ Returns True if the path exists and is a folder. """ return os.path.exists(self.path) and os.path.isdir(self.path) # Test class. class Person(HasTraits): """ A person! """ name = Str age = Int class ProtocolsUsageTestCase(unittest.TestCase): """ Tests for protocols usage. """ def test_adapts(self): """ adapts """ class IFoo(Interface): """ A simple interface. """ def foo(self): """ The only method for the IFoo interface. """ class Bar(HasTraits): """ A type that *doesn't* implement 'IFoo'. """ class BarToIFooAdapter(Adapter): """ Adapts from Bar to IFoo. """ adapts(Bar, to=IFoo) def foo(self): """ An implementation of the single method in the interface.""" return 'foo' b = Bar() # Make sure that the Bar instance can be adapted to 'IFoo'. self.assertNotEqual(None, IFoo(b)) self.assertEqual('foo', IFoo(b).foo()) def test_factory(self): """ factory """ class IInputStream(Interface): """ Fake interface for input stream. """ def get_input_stream(self): """ Get an input stream. """ def factory(obj): """ A factory for File to IInputStream adapters. """ if not obj.is_folder: adapter = FileToIInputStreamAdapter(adaptee=obj) else: adapter = None return adapter class FileToIInputStreamAdapter(Adapter): """ An adapter from 'File' to 'IInputStream'. """ adapts(File, to=IInputStream, factory=factory) ################################################################### # 'IInputStream' interface. ################################################################### def get_input_stream(self): """ Get an input stream. """ return file(self.adaptee.path, 'r') # Create a reference to this file cwd = os.path.dirname(os.path.abspath(__file__)) f = File(path=os.path.join(cwd, 'protocols_usage_test_case.py')) self.assert_(f.is_file) # A reference to the parent folder g = File(path='..') self.assert_(g.is_folder) # We should be able to adapt the file to an input stream... self.assertNotEqual(None, IInputStream(f, None)) # ... but not the folder. self.assertEqual(None, IInputStream(g, None)) # Make sure we can use the stream (this reads this module and makes # sure that it contains the right doc string). stream = IInputStream(f).get_input_stream() self.assert_('"""' + __doc__ in stream.read()) return def test_when_expression(self): """ when expression """ class IInputStream(Interface): """ Fake interface for input stream. """ def get_input_stream(self): """ Get an input stream. """ class FileToIInputStreamAdapter(Adapter): """ An adapter from 'File' to 'IInputStream'. """ adapts(File, to=IInputStream, when='not adaptee.is_folder') ################################################################### # 'IInputStream' interface. ################################################################### def get_input_stream(self): """ Get an input stream. """ return file(self.adaptee.path, 'r') # Create a reference to this file cwd = os.path.dirname(os.path.abspath(__file__)) f = File(path=os.path.join(cwd, 'protocols_usage_test_case.py')) self.assert_(f.is_file) # A reference to the parent folder g = File(path='..') self.assert_(g.is_folder) # We should be able to adapt the file to an input stream... self.assertNotEqual(None, IInputStream(f, None)) # ... but not the folder. self.assertEqual(None, IInputStream(g, None)) # Make sure we can use the stream (this reads this module and makes # sure that it contains the right doc string). stream = IInputStream(f).get_input_stream() self.assert_('"""' + __doc__ in stream.read()) return def test_cached(self): """ cached """ class ISaveable(Interface): """ Fake interface for saveable. """ # Is the object 'dirty'? dirty = Bool(False) def save(self, output_stream): """ Save the object to an output stream. """ class HasTraitsToISaveableAdapter(Adapter): """ An adapter from 'HasTraits' to 'ISaveable'. """ adapts(HasTraits, to=ISaveable, cached=True) #### 'ISaveable' interface ######################################## # Is the object 'dirty'? dirty = Bool(False) def save(self, output_stream): """ Save the object to an output stream. """ pickle.dump(self.adaptee, output_stream) self.dirty = False return #### Private interface ############################################ def _adaptee_changed(self, old, new): """ Static trait change handler. """ if old is not None: old.on_trait_change(self._set_dirty, remove=True) if new is not None: new.on_trait_change(self._set_dirty) self._set_dirty() return def _set_dirty(self): """ Sets the dirty flag to True. """ self.dirty = True return # Create some people! fred = Person(name='fred', age=42) wilma = Person(name='wilma', age=35) fred_saveable = ISaveable(fred) self.assertEqual(True, fred_saveable.dirty) wilma_saveable = ISaveable(wilma) self.assertEqual(True, wilma_saveable.dirty) # Make sure that Fred and Wilma have got their own saveable. self.assertNotEqual(id(fred_saveable), id(wilma_saveable)) # But make sure that their saveable's are cached. self.assertEqual(id(ISaveable(fred)), id(fred_saveable)) self.assertEqual(id(ISaveable(wilma)), id(wilma_saveable)) # Save Fred and Wilma and make sure that the dirty flag is cleared. fred_saveable.save(file('fred.pickle', 'w')) self.assertEqual(False, ISaveable(fred).dirty) wilma_saveable.save(file('wilma.pickle', 'w')) self.assertEqual(False, ISaveable(wilma).dirty) # Clean up. for path in ['fred.pickle', 'wilma.pickle']: if os.access(path, os.W_OK): os.remove(path) return def test_multiple_factories_for_type(self): """ multiple factories for type """ # There was a bug that prevented more than one adapter factory being # registered for the same class. class IFoo(Interface): pass class HasTraitsToIFooAdapter(Adapter): adapts(HasTraits, to=IFoo, cached=True) class IBar(Interface): pass class HasTraitsToIBarAdapter(Adapter): adapts(HasTraits, to=IBar, cached=True) return def test_multiple_factories_for_interface(self): """ multiple factories for interfaces """ # There was a bug that prevented more than one adapter factory being # registered for the same class. This test just makes sure that it # still works for interfaces too! class IBaz(Interface): pass class IFoo(Interface): pass class IBazToIFooAdapter(Adapter): adapts(IBaz, to=IFoo, cached=True) class IBar(Interface): pass class IBazToIBarAdapter(Adapter): adapts(IBaz, to=IBar, cached=True) return # Run the unit tests (if invoked from the command line): if __name__ == '__main__': unittest.main() traits-4.1.0/traits/tests/test_int_range_long.py0000644000175100001440000000266111674463323023067 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # Copyright (c) 2007, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # #------------------------------------------------------------------------------- from __future__ import absolute_import import unittest from ..api import HasTraits, Int, Range, Long, TraitError class A(HasTraits): i = Int l = Long r = Range(2L, 9223372036854775807L) class TraitIntRangeLong(unittest.TestCase): def test_int(self): "Test to make sure it is illegal to set an Int trait to a long value" a = A() a.i = 1 self.assertRaises(TraitError, a.set, i=10L) def test_long(self): "Test if it is legal to set a Long trait to an int value" a = A() a.l = 10 a.l = 100L def test_range(self): "Test a range trait with longs being set to an int value" a = A() a.r = 256 a.r = 20L self.assertRaises(TraitError, a.set, r=1L) self.assertRaises(TraitError, a.set, r=9223372036854775808L) if __name__ == '__main__': unittest.main() traits-4.1.0/traits/tests/__init__.py0000644000175100001440000000007011674463323020572 0ustar ischnellusers00000000000000#required by simple_test_case.py so it can do an import traits-4.1.0/traits/tests/test_enum.py0000644000175100001440000000121711674463323021042 0ustar ischnellusers00000000000000import unittest from traits.api import Enum, HasTraits, List, Property, TraitError class ExampleModel(HasTraits): valid_models = Property(List) root = Enum(values='valid_models') def _get_valid_models(self): return ['model1', 'model2', 'model3'] class EnumTestCase(unittest.TestCase): def test_valid_enum(self): example_model = ExampleModel(root='model1') example_model.root = 'model2' def test_invalid_enum(self): example_model = ExampleModel(root='model1') def assign_invalid(): example_model.root = 'not_valid_model' self.assertRaises(TraitError, assign_invalid) traits-4.1.0/traits/tests/dict_test_case.py0000644000175100001440000000700311674463323022013 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # # Copyright (c) 2007, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # #------------------------------------------------------------------------------ """ Test cases for dictionary (Dict) traits. """ from __future__ import absolute_import import unittest from ..api import on_trait_change, Dict, Event, HasTraits, Str # fixme: We'd like to use a callable instance for the listener so that we # can maintain state, but traits barfs trying to determine the signature 8^() def create_listener(): """ Create a listener for testing trait notifications. """ def listener(obj, trait_name, old, new): listener.obj = obj listener.trait_name = trait_name listener.new = new listener.old = old listener.called += 1 return listener.initialize = lambda : initialize_listener(listener) return initialize_listener(listener) def initialize_listener(listener): """ Initialize a listener so it looks like it hasn't been called. This allows us to re-use the listener without having to create and wire-up a new one. """ listener.obj = None listener.trait_name = None listener.old = None listener.new = None listener.called = 0 return listener # For convenience class DictTestCase(unittest.TestCase): """ Test cases for dictionary (Dict) traits. """ def test_modified_event(self): class Foo(HasTraits): name = Str modified = Event @on_trait_change('name') def _fire_modified_event(self): self.modified = True return class Bar(HasTraits): foos = Dict(Str, Foo) modified = Event @on_trait_change('foos_items,foos.modified') def _fire_modified_event(self, obj, trait_name, old, new): self.modified = True return bar = Bar() listener = create_listener() bar.on_trait_change(listener, 'modified') # Assign a completely new dictionary. bar.foos = {'dino' : Foo(name='dino')} self.assertEqual(1, listener.called) self.assertEqual('modified', listener.trait_name) # Add an item to an existing disctionary. listener.initialize() fred = Foo(name='fred') bar.foos['fred'] = fred self.assertEqual(1, listener.called) self.assertEqual('modified', listener.trait_name) # Modify an item already in the dictionary. listener.initialize() fred.name = 'barney' self.assertEqual(1, listener.called) self.assertEqual('modified', listener.trait_name) # Overwrite an item in the dictionary. This is the one that fails! listener.initialize() bar.foos['fred'] = Foo(name='wilma') self.assertEqual(1, listener.called) self.assertEqual('modified', listener.trait_name) return if __name__ == '__main__': unittest.main() #### EOF ###################################################################### traits-4.1.0/traits/tests/test_str_handler.py0000644000175100001440000000424411674463323022406 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # Copyright (c) 2007, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # #------------------------------------------------------------------------------- from __future__ import absolute_import import unittest from ..api import HasTraits, Trait, TraitError, TraitHandler from ..trait_base import strx # Validation via function def validator(object, name, value): if isinstance(value, basestring): # abitrary rule for testing if value.find('fail') < 0: return value else: raise TraitError else: raise TraitError # Validation via Handler class MyHandler(TraitHandler): def validate ( self, object, name, value ): #print 'myvalidate "%s" %s' % (value, type(value)) try: value = strx( value ) if value.find('fail') < 0: return value except: pass self.error( object, name, value ) return def info(self): msg = "a string not contining the character sequence 'fail'" return msg class Foo(HasTraits): s = Trait('', validator) class Bar(HasTraits): s = Trait('', MyHandler() ) class StrHandlerCase(unittest.TestCase): def test_validator_function(self): f = Foo() self.failUnlessEqual( f.s, '' ) f.s = 'ok' self.failUnlessEqual( f.s, 'ok' ) self.failUnlessRaises( TraitError, setattr, f, 's', 'should fail.') self.failUnlessEqual( f.s, 'ok' ) return def test_validator_handler(self): b = Bar() self.failUnlessEqual(b.s, '') b.s = 'ok' self.failUnlessEqual(b.s, 'ok') self.failUnlessRaises( TraitError, setattr, b, 's', 'should fail.') self.failUnlessEqual( b.s, 'ok') return ### EOF traits-4.1.0/traits/tests/test_event_order.py0000644000175100001440000000601011674463323022406 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # Copyright (c) 2007, Enthought, Inc. # All rights reserved. # # This Str()oftware is provided without warranty under the terms of the # BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The # license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # #------------------------------------------------------------------------------- from __future__ import absolute_import import unittest from ..api import HasTraits, Str, Instance, Any class TestEventOrder( unittest.TestCase ): """ Tests that demonstrate that trait events are delivered in LIFO order rather than FIFO order. Baz receives the "effect" event before it receives the "cause" event. """ def setUp(self): foo = Foo( cause='ORIGINAL') bar = Bar( foo=foo, test=self ) baz = Baz( bar=bar, test=self ) self.events_delivered = [] foo.cause = 'CHANGE' return def test_lifo_order(self): lifo = ['Bar._caused_changed', 'Baz._effect_changed', 'Baz._caused_changed'] self.failUnlessEqual( self.events_delivered, lifo) return def test_not_fifo_order(self): fifo = ['Bar._caused_changed', 'Baz._caused_changed', 'Baz._effect_changed'] self.failIfEqual( self.events_delivered, fifo) return class Foo(HasTraits): cause = Str class Bar(HasTraits): foo = Instance(Foo) effect = Str test = Any def _foo_changed(self, obj, old, new): if old is not None and old is not new: old.on_trait_change( self._cause_changed, name='cause', remove=True) if new is not None: new.on_trait_change( self._cause_changed, name='cause') return def _cause_changed(self, obj, name, old, new): self.test.events_delivered.append( 'Bar._caused_changed' ) self.effect = new.lower() return class Baz(HasTraits): bar = Instance(Bar) test = Any def _bar_changed(self, obj, old, new): if old is not None and old is not new: old.on_trait_change( self._effect_changed, name='effect', remove=True) old.foo.on_trait_change( self._cause_changed, name='cause', remove=True) if new is not None: new.foo.on_trait_change( self._cause_changed, name='cause') new.on_trait_change( self._effect_changed, name='effect') return def _cause_changed(self, obj, name, old, new): self.test.events_delivered.append( 'Baz._caused_changed' ) return def _effect_changed(self, obj, name, old, new): self.test.events_delivered.append( 'Baz._effect_changed' ) return ### EOF ####################################################################### traits-4.1.0/traits/tests/clone_test_case.py0000644000175100001440000002160111674463323022170 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # Copyright (c) 2005, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # Thanks for using Enthought open source! # # Author: David C. Morrill # Description: #------------------------------------------------------------------------------ from __future__ import absolute_import import unittest from ..api import HasTraits, Instance, Str, Any, Property class Foo(HasTraits): s = Str class ClassWithAny(HasTraits): x = Property _x = Any def _get_x(self): return self._x def _set_x(self,x): self._x = x class ClassWithInstance(HasTraits): x = Property _x = Instance(Foo) def _get_x(self): return self._x def _set_x(self,x): self._x = x class ClassWithClassAttribute(HasTraits): name = 'class defined name' foo = Str class BazAny(HasTraits): other = Any class BarAny(HasTraits): other = Any class BazInstance(HasTraits): # A BarInstance owned by this object. other = Instance('BarInstance') # A Foo owned by this object and not referenced by others. unique = Instance(Foo) # A Foo owned by this object and referenced by others. shared = Instance(Foo) # A Foo not owned by this object, may or may not be shared with other # objects found via owned references (e.g. other.ref). For the tests, # ref will always reference a Foo that is not owned by any of the objects # reachable via owned references, and therefore, that Foo object should # not be cloned. ref = Instance(Foo, copy='ref') class BarInstance(HasTraits): # used as circular reference back to owning BazInstance # NOTE: Setting copy to 'ref' will mean that when BarInstance is cloned, # the 'other' trait will not be copied, and will still point to the # 'other' attribute of the original BarInstance. other = Instance('BazInstance', copy='ref') # A Foo owned by this object and not referenced by others. unique = Instance(Foo) # A Foo owned by the 'other' object and referenced by this object. shared = Instance(Foo) # A Foo not owned by this object, may or may not be shared with other # objects found via owned references (e.g. other.ref). For the tests, # ref will always reference a Foo that is not owned by any of the objects # reachable via owned references, and therefore, that Foo object should # not be cloned. ref = Instance(Foo, copy='ref') class CloneTestCase( unittest.TestCase ) : """ Test cases for traits clone """ def test_any(self) : b = ClassWithAny() f = Foo() f.s = 'the f' b.x = f bc = b.clone_traits( traits='all', copy='deep') self.assertNotEqual( id(bc.x), id(f), 'Foo x not cloned') return def test_instance(self) : b = ClassWithInstance() f = Foo() f.s = 'the f' b.x = f bc = b.clone_traits(traits='all', copy='deep') self.assertNotEqual( id(bc.x), id(f), 'Foo x not cloned') return def test_class_attribute_missing(self): """ This test demonstrates a problem with Traits objects with class attributes. A change to the value of a class attribute via one instance causes the attribute to be removed from other instances. AttributeError: 'ClassWithClassAttribute' object has no attribute 'name' """ s = 'class defined name' c = ClassWithClassAttribute() self.assertEqual( s, c.name ) c2 = ClassWithClassAttribute() self.assertEqual( s, c.name ) self.assertEqual( s, c2.name ) s2 = 'name class attribute changed via clone' c2.name = s2 self.assertEqual( s2, c2.name ) # this is failing with # AttributeError: 'ClassWithClassAttribute' object has no attribute 'name' self.assertEqual( s, c.name ) return def test_Any_circular_references(self): # Demonstrates that Any traits default to copy='ref' bar = BarAny() baz = BazAny() bar.other = baz baz.other = bar bar_copy = bar.clone_traits() self.failIf( bar_copy is bar ) self.failUnless( bar_copy.other is baz) self.failUnless( bar_copy.other.other is bar) def test_Any_circular_references_deep(self): # Demonstrates that Any traits can be forced to deep copy. bar = BarAny() baz = BazAny() bar.other = baz baz.other = bar bar_copy = bar.clone_traits(copy='deep') self.failIf( bar_copy is bar ) self.failIf( bar_copy.other is baz) self.failIf( bar_copy.other.other is bar) self.failUnless( bar_copy.other.other is bar_copy) def test_Instance_circular_references(self): ref = Foo(s='ref') bar_unique = Foo(s='bar.foo') shared = Foo(s='shared') baz_unique = Foo(s='baz.unique') baz = BazInstance() baz.unique = baz_unique baz.shared = shared baz.ref = ref bar = BarInstance() bar.unique = bar_unique bar.shared = shared bar.ref = ref bar.other = baz baz.other = bar baz_copy = baz.clone_traits() # Check Baz and Baz attributes.... self.failIf( baz_copy is baz ) self.failIf( baz_copy.other is bar) self.failIf( baz_copy.unique is baz.unique ) self.failIf( baz_copy.shared is baz.shared ) self.failUnless( baz_copy.ref is ref ) # Check Bar and Bar attributes.... bar_copy = baz_copy.other # Check the Bar owned object self.failIf( bar_copy.unique is bar.unique ) # Check the Bar reference to an object 'outside' the cloned graph. self.failUnless( bar_copy.ref is ref ) # Check references to objects that where cloned, they should reference # the new clones not the original objects, except when copy is set # to 'ref' (as in the case of the 'other' trait). # When copy is set to ref, the trait does not get cloned. Therefore, # baz_copy.other.other is baz (and not baz_copy). self.failIf( bar_copy.other is baz_copy ) self.failUnless( bar_copy.other is baz ) # 'shared' does not have copy set to 'ref', and so bar_copy.shared # should reference the new clone. # should reference the new clones self.failIf( bar_copy.shared is baz.shared ) self.failUnless( bar_copy.shared is baz_copy.shared ) def test_Instance_circular_references_deep(self): ref = Foo(s='ref') bar_unique = Foo(s='bar.foo') shared = Foo(s='shared') baz_unique = Foo(s='baz.unique') baz = BazInstance() baz.unique = baz_unique baz.shared = shared baz.ref = ref bar = BarInstance() bar.unique = bar_unique bar.shared = shared bar.ref = ref bar.other = baz baz.other = bar baz_copy = baz.clone_traits(copy='deep') # Check Baz and Baz attributes.... self.failIf( baz_copy is baz ) self.failIf( baz_copy.other is bar ) self.failIf( baz_copy.unique is baz.unique ) self.failIf( baz_copy.shared is baz.shared ) # baz_copy.ref is checked below with bar_copy.ref. # Check Bar and Bar attributes.... bar_copy = baz_copy.other # Chedk the Bar owned object self.failIf( bar_copy.unique is bar.unique ) # Since the two original 'ref' links were to a shared object, # the cloned links should be to a shared object. Also, the shared # object should be the original 'ref' object, since copy was set to # 'ref'. self.failUnless( baz_copy.ref is bar_copy.ref ) self.failUnless( bar_copy.ref is ref ) # Check references to objects that where cloned, they should reference # the new clones not the original objects, except when copy is set # to 'ref' (as in the case of the 'other' trait). That is, the 'deep' # flag on clone_traits should not override the 'copy' metadata on # the trait. self.failIf( bar_copy.other is baz_copy ) self.failUnless( bar_copy.other is baz ) # 'shared' does not have copy set to 'ref', and so bar_copy.shared # should reference the new clone. self.failIf( bar_copy.shared is baz.shared ) self.failUnless( bar_copy.shared is baz_copy.shared ) # # support running this test individually, from the command-line as a script # if __name__ == '__main__': unittest.main() #### EOF ###################################################################### traits-4.1.0/traits/tests/category_test_case.py0000644000175100001440000000704411674463323022712 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # Copyright (c) 2005, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # Thanks for using Enthought open source! # # Author: David C. Morrill # Description: #------------------------------------------------------------------------------ from __future__ import absolute_import import unittest from ..api import HasTraits, Category, Str class Base( HasTraits ) : y = Str("Base y") z = Str("Base z") class BaseExtra( Category, Base ) : x = Str("BaseExtra x") class BasePlus( Category, Base ) : p = Str("BasePlus p") # z = Str("BasePlus z") overrides not allowed. class BasePlusPlus( BasePlus ) : pp = Str("BasePlusPlus pp") class CategoryTestCase( unittest.TestCase ) : """ Test cases for traits category """ def setUp( self ) : self.base = Base() return def test_base_category(self) : """ Base class with traits """ self.assertEqual( self.base.y, "Base y", msg="y != 'Base y'" ) self.assertEqual( self.base.z, "Base z", msg="z != 'Base z'" ) return def test_extra_extension_category(self) : """ Base class extended with a category subclass """ self.assertEqual( self.base.x, "BaseExtra x", msg="x != 'BaseExtra x'" ) return def test_plus_extension_category(self) : """ Base class extended with two category subclasses """ self.assertEqual( self.base.x, "BaseExtra x", msg="x != 'BaseExtra x'" ) self.assertEqual( self.base.p, "BasePlus p", msg="p != 'BasePlus p'" ) return def test_subclass_extension_category(self) : """ Category subclass does not extend base class. This test demonstrates that traits allows subclassing of a category class, but that the traits from the subclass are not actually added to the base class of the Category. Seems like the declaration of the subclass (BasePlusPlus) should fail. """ try : x = self.base.pp self.fail( msg="base.pp should have thrown AttributeError " "as Category subclassing is not supported." ) except AttributeError : pass basepp = BasePlusPlus() return def test_subclass_instance_category(self) : """ Category subclass instantiation not supportted. This test demonstrates that traits allows subclassing of a category class, that subclass can be instantiated, but the traits of the parent class are not inherited. Seems like the declaration of the subclass (BasePlusPlus) should fail. """ bpp = BasePlusPlus() self.assertEqual( bpp.pp, "BasePlusPlus pp", msg="pp != 'BasePlusPlus pp'" ) try : self.assertEqual( bpp.p, "BasePlus p", msg="p != 'BasePlus p'" ) self.fail( msg="bpp.p should have thrown SystemError as " "instantiating a subclass of a category is not supported." ) except SystemError : pass return # # support running this test individually, from the command-line as a script # if __name__ == '__main__': unittest.main() #### EOF ###################################################################### traits-4.1.0/traits/MANIFEST.in0000644000175100001440000000002411674463323017054 0ustar ischnellusers00000000000000exclude *_test*.py traits-4.1.0/traits/protocols/0000755000175100001440000000000011674463323017346 5ustar ischnellusers00000000000000traits-4.1.0/traits/protocols/interfaces.py0000644000175100001440000000054611674463323022050 0ustar ischnellusers00000000000000"""Implement Interfaces and define the interfaces used by the package""" from __future__ import absolute_import from .protocols import (Protocol, InterfaceClass, Interface, AbstractBase, AbstractBaseMeta, IAdapterFactory, IProtocol, IAdaptingProtocol, IOpenProtocol, IOpenProvider, IOpenImplementor, IImplicationListener, Attribute, Variation) traits-4.1.0/traits/protocols/_speedups.c0000644000175100001440000066130011674463323021507 0ustar ischnellusers00000000000000/* Generated by Cython 0.14.1 on Mon Apr 25 10:26:50 2011 */ #define PY_SSIZE_T_CLEAN #include "Python.h" #ifndef Py_PYTHON_H #error Python headers needed to compile C extensions, please install development version of Python. #else #include /* For offsetof */ #ifndef offsetof #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) #endif #if !defined(WIN32) && !defined(MS_WINDOWS) #ifndef __stdcall #define __stdcall #endif #ifndef __cdecl #define __cdecl #endif #ifndef __fastcall #define __fastcall #endif #endif #ifndef DL_IMPORT #define DL_IMPORT(t) t #endif #ifndef DL_EXPORT #define DL_EXPORT(t) t #endif #ifndef PY_LONG_LONG #define PY_LONG_LONG LONG_LONG #endif #if PY_VERSION_HEX < 0x02040000 #define METH_COEXIST 0 #define PyDict_CheckExact(op) (Py_TYPE(op) == &PyDict_Type) #define PyDict_Contains(d,o) PySequence_Contains(d,o) #endif #if PY_VERSION_HEX < 0x02050000 typedef int Py_ssize_t; #define PY_SSIZE_T_MAX INT_MAX #define PY_SSIZE_T_MIN INT_MIN #define PY_FORMAT_SIZE_T "" #define PyInt_FromSsize_t(z) PyInt_FromLong(z) #define PyInt_AsSsize_t(o) PyInt_AsLong(o) #define PyNumber_Index(o) PyNumber_Int(o) #define PyIndex_Check(o) PyNumber_Check(o) #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message) #endif #if PY_VERSION_HEX < 0x02060000 #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt) #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) #define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size) #define PyVarObject_HEAD_INIT(type, size) \ PyObject_HEAD_INIT(type) size, #define PyType_Modified(t) typedef struct { void *buf; PyObject *obj; Py_ssize_t len; Py_ssize_t itemsize; int readonly; int ndim; char *format; Py_ssize_t *shape; Py_ssize_t *strides; Py_ssize_t *suboffsets; void *internal; } Py_buffer; #define PyBUF_SIMPLE 0 #define PyBUF_WRITABLE 0x0001 #define PyBUF_FORMAT 0x0004 #define PyBUF_ND 0x0008 #define PyBUF_STRIDES (0x0010 | PyBUF_ND) #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES) #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES) #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES) #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES) #endif #if PY_MAJOR_VERSION < 3 #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" #else #define __Pyx_BUILTIN_MODULE_NAME "builtins" #endif #if PY_MAJOR_VERSION >= 3 #define Py_TPFLAGS_CHECKTYPES 0 #define Py_TPFLAGS_HAVE_INDEX 0 #endif #if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3) #define Py_TPFLAGS_HAVE_NEWBUFFER 0 #endif #if PY_MAJOR_VERSION >= 3 #define PyBaseString_Type PyUnicode_Type #define PyStringObject PyUnicodeObject #define PyString_Type PyUnicode_Type #define PyString_Check PyUnicode_Check #define PyString_CheckExact PyUnicode_CheckExact #endif #if PY_VERSION_HEX < 0x02060000 #define PyBytesObject PyStringObject #define PyBytes_Type PyString_Type #define PyBytes_Check PyString_Check #define PyBytes_CheckExact PyString_CheckExact #define PyBytes_FromString PyString_FromString #define PyBytes_FromStringAndSize PyString_FromStringAndSize #define PyBytes_FromFormat PyString_FromFormat #define PyBytes_DecodeEscape PyString_DecodeEscape #define PyBytes_AsString PyString_AsString #define PyBytes_AsStringAndSize PyString_AsStringAndSize #define PyBytes_Size PyString_Size #define PyBytes_AS_STRING PyString_AS_STRING #define PyBytes_GET_SIZE PyString_GET_SIZE #define PyBytes_Repr PyString_Repr #define PyBytes_Concat PyString_Concat #define PyBytes_ConcatAndDel PyString_ConcatAndDel #endif #if PY_VERSION_HEX < 0x02060000 #define PySet_Check(obj) PyObject_TypeCheck(obj, &PySet_Type) #define PyFrozenSet_Check(obj) PyObject_TypeCheck(obj, &PyFrozenSet_Type) #endif #ifndef PySet_CheckExact #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) #endif #define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) #if PY_MAJOR_VERSION >= 3 #define PyIntObject PyLongObject #define PyInt_Type PyLong_Type #define PyInt_Check(op) PyLong_Check(op) #define PyInt_CheckExact(op) PyLong_CheckExact(op) #define PyInt_FromString PyLong_FromString #define PyInt_FromUnicode PyLong_FromUnicode #define PyInt_FromLong PyLong_FromLong #define PyInt_FromSize_t PyLong_FromSize_t #define PyInt_FromSsize_t PyLong_FromSsize_t #define PyInt_AsLong PyLong_AsLong #define PyInt_AS_LONG PyLong_AS_LONG #define PyInt_AsSsize_t PyLong_AsSsize_t #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask #endif #if PY_MAJOR_VERSION >= 3 #define PyBoolObject PyLongObject #endif #if PY_MAJOR_VERSION >= 3 #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) #else #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) #endif #if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300) #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b) #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value) #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b) #else #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \ (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \ (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \ (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0))) #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \ (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \ (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \ (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1))) #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \ (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \ (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \ (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1))) #endif #if PY_MAJOR_VERSION >= 3 #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func)) #endif #if PY_VERSION_HEX < 0x02050000 #define __Pyx_GetAttrString(o,n) PyObject_GetAttrString((o),((char *)(n))) #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a)) #define __Pyx_DelAttrString(o,n) PyObject_DelAttrString((o),((char *)(n))) #else #define __Pyx_GetAttrString(o,n) PyObject_GetAttrString((o),(n)) #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a)) #define __Pyx_DelAttrString(o,n) PyObject_DelAttrString((o),(n)) #endif #if PY_VERSION_HEX < 0x02050000 #define __Pyx_NAMESTR(n) ((char *)(n)) #define __Pyx_DOCSTR(n) ((char *)(n)) #else #define __Pyx_NAMESTR(n) (n) #define __Pyx_DOCSTR(n) (n) #endif #ifdef __cplusplus #define __PYX_EXTERN_C extern "C" #else #define __PYX_EXTERN_C extern #endif #if defined(WIN32) || defined(MS_WINDOWS) #define _USE_MATH_DEFINES #endif #include #define __PYX_HAVE_API__enthought__traits__protocols___speedups #ifdef PYREX_WITHOUT_ASSERTIONS #define CYTHON_WITHOUT_ASSERTIONS #endif /* inline attribute */ #ifndef CYTHON_INLINE #if defined(__GNUC__) #define CYTHON_INLINE __inline__ #elif defined(_MSC_VER) #define CYTHON_INLINE __inline #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define CYTHON_INLINE inline #else #define CYTHON_INLINE #endif #endif /* unused attribute */ #ifndef CYTHON_UNUSED # if defined(__GNUC__) # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) # define CYTHON_UNUSED __attribute__ ((__unused__)) # else # define CYTHON_UNUSED # endif # elif defined(__ICC) || defined(__INTEL_COMPILER) # define CYTHON_UNUSED __attribute__ ((__unused__)) # else # define CYTHON_UNUSED # endif #endif typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/ /* Type Conversion Predeclarations */ #define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s) #define __Pyx_PyBytes_AsUString(s) ((unsigned char*) PyBytes_AsString(s)) #define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False)) static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x); static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*); #define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) #ifdef __GNUC__ /* Test for GCC > 2.95 */ #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)) #define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) #else /* __GNUC__ > 2 ... */ #define likely(x) (x) #define unlikely(x) (x) #endif /* __GNUC__ > 2 ... */ #else /* __GNUC__ */ #define likely(x) (x) #define unlikely(x) (x) #endif /* __GNUC__ */ static PyObject *__pyx_m; static PyObject *__pyx_b; static PyObject *__pyx_empty_tuple; static PyObject *__pyx_empty_bytes; static int __pyx_lineno; static int __pyx_clineno = 0; static const char * __pyx_cfilenm= __FILE__; static const char *__pyx_filename; static const char *__pyx_f[] = { "_speedups.pyx", }; /* Type declarations */ /* "traits/protocols/_speedups.pyx":101 * * * cdef class metamethod: # <<<<<<<<<<<<<< * """Wrapper for metaclass method that might be confused w/instance method""" * */ struct __pyx_obj_9enthought_6traits_9protocols_9_speedups_metamethod { PyObject_HEAD PyObject *func; }; #ifndef CYTHON_REFNANNY #define CYTHON_REFNANNY 0 #endif #if CYTHON_REFNANNY typedef struct { void (*INCREF)(void*, PyObject*, int); void (*DECREF)(void*, PyObject*, int); void (*GOTREF)(void*, PyObject*, int); void (*GIVEREF)(void*, PyObject*, int); void* (*SetupContext)(const char*, int, const char*); void (*FinishContext)(void**); } __Pyx_RefNannyAPIStruct; static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; static __Pyx_RefNannyAPIStruct * __Pyx_RefNannyImportAPI(const char *modname) { PyObject *m = NULL, *p = NULL; void *r = NULL; m = PyImport_ImportModule((char *)modname); if (!m) goto end; p = PyObject_GetAttrString(m, (char *)"RefNannyAPI"); if (!p) goto end; r = PyLong_AsVoidPtr(p); end: Py_XDECREF(p); Py_XDECREF(m); return (__Pyx_RefNannyAPIStruct *)r; } #define __Pyx_RefNannySetupContext(name) void *__pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) #define __Pyx_RefNannyFinishContext() __Pyx_RefNanny->FinishContext(&__pyx_refnanny) #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r);} } while(0) #else #define __Pyx_RefNannySetupContext(name) #define __Pyx_RefNannyFinishContext() #define __Pyx_INCREF(r) Py_INCREF(r) #define __Pyx_DECREF(r) Py_DECREF(r) #define __Pyx_GOTREF(r) #define __Pyx_GIVEREF(r) #define __Pyx_XDECREF(r) Py_XDECREF(r) #endif /* CYTHON_REFNANNY */ #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);} } while(0) #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r);} } while(0) static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/ static void __Pyx_RaiseDoubleKeywordsError( const char* func_name, PyObject* kw_name); /*proto*/ static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, const char* function_name); /*proto*/ static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/ static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/ static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/ static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/ static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { PyObject *r; if (!j) return NULL; r = PyObject_GetItem(o, j); Py_DECREF(j); return r; } #define __Pyx_GetItemInt_List(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \ __Pyx_GetItemInt_List_Fast(o, i) : \ __Pyx_GetItemInt_Generic(o, to_py_func(i))) static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i) { if (likely(o != Py_None)) { if (likely((0 <= i) & (i < PyList_GET_SIZE(o)))) { PyObject *r = PyList_GET_ITEM(o, i); Py_INCREF(r); return r; } else if ((-PyList_GET_SIZE(o) <= i) & (i < 0)) { PyObject *r = PyList_GET_ITEM(o, PyList_GET_SIZE(o) + i); Py_INCREF(r); return r; } } return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); } #define __Pyx_GetItemInt_Tuple(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \ __Pyx_GetItemInt_Tuple_Fast(o, i) : \ __Pyx_GetItemInt_Generic(o, to_py_func(i))) static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i) { if (likely(o != Py_None)) { if (likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) { PyObject *r = PyTuple_GET_ITEM(o, i); Py_INCREF(r); return r; } else if ((-PyTuple_GET_SIZE(o) <= i) & (i < 0)) { PyObject *r = PyTuple_GET_ITEM(o, PyTuple_GET_SIZE(o) + i); Py_INCREF(r); return r; } } return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); } #define __Pyx_GetItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \ __Pyx_GetItemInt_Fast(o, i) : \ __Pyx_GetItemInt_Generic(o, to_py_func(i))) static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i) { PyObject *r; if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) { r = PyList_GET_ITEM(o, i); Py_INCREF(r); } else if (PyTuple_CheckExact(o) && ((0 <= i) & (i < PyTuple_GET_SIZE(o)))) { r = PyTuple_GET_ITEM(o, i); Py_INCREF(r); } else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_item && (likely(i >= 0))) { r = PySequence_GetItem(o, i); } else { r = __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); } return r; } static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/ static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/ static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/ static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); /*proto*/ static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject *); static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject *); static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject *); static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject *); static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject *); static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject *); static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject *); static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject *); static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject *); static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject *); static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject *); static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject *); static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject *); static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject *); static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject *); static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject *); static void __Pyx_AddTraceback(const char *funcname); /*proto*/ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/ /* Module declarations from traits.protocols._speedups */ static PyTypeObject *__pyx_ptype_9enthought_6traits_9protocols_9_speedups_metamethod = 0; static PyObject *__pyx_v_9enthought_6traits_9protocols_9_speedups__marker = 0; static PyObject *__pyx_v_9enthought_6traits_9protocols_9_speedups___conform = 0; static PyObject *__pyx_v_9enthought_6traits_9protocols_9_speedups___adapt = 0; static PyObject *__pyx_v_9enthought_6traits_9protocols_9_speedups___mro = 0; static PyObject *__pyx_v_9enthought_6traits_9protocols_9_speedups___ECType = 0; static PyObject *__pyx_f_9enthought_6traits_9protocols_9_speedups__adapt(PyObject *, PyObject *, PyObject *, PyObject *); /*proto*/ static PyObject *__pyx_f_9enthought_6traits_9protocols_9_speedups_buildClassicMRO(PyClassObject *, PyListObject *); /*proto*/ static PyObject *__pyx_f_9enthought_6traits_9protocols_9_speedups_buildECMRO(PyObject *, PyListObject *); /*proto*/ #define __Pyx_MODULE_NAME "traits.protocols._speedups" static int __pyx_module_is_main_enthought__traits__protocols___speedups = 0; /* Implementation of traits.protocols._speedups */ static PyObject *__pyx_builtin___import__; static PyObject *__pyx_builtin_ImportError; static PyObject *__pyx_builtin_object; static PyObject *__pyx_builtin_AttributeError; static PyObject *__pyx_builtin_TypeError; static PyObject *__pyx_builtin_DeprecationWarning; static PyObject *__pyx_builtin_Exception; static char __pyx_k_1[] = "Read-only attribute"; static char __pyx_k_4[] = "The 'factory' argument to 'adapt()' will be removed in 1.0"; static char __pyx_k_5[] = "Can't adapt"; static char __pyx_k_10[] = "Not a classic class"; static char __pyx_k_13[] = "C Speedups for commonly-used operations"; static char __pyx_k_15[] = "traits.protocols._speedups"; static char __pyx_k__ob[] = "ob"; static char __pyx_k__get[] = "get"; static char __pyx_k__obj[] = "obj"; static char __pyx_k__sys[] = "sys"; static char __pyx_k__func[] = "func"; static char __pyx_k__self[] = "self"; static char __pyx_k__warn[] = "warn"; static char __pyx_k__adapt[] = "adapt"; static char __pyx_k__level[] = "level"; static char __pyx_k__getMRO[] = "getMRO"; static char __pyx_k__object[] = "object"; static char __pyx_k__tp_mro[] = "tp_mro"; static char __pyx_k____all__[] = "__all__"; static char __pyx_k____class[] = "__class"; static char __pyx_k____mro__[] = "__mro__"; static char __pyx_k__default[] = "default"; static char __pyx_k__factory[] = "factory"; static char __pyx_k__globals[] = "globals"; static char __pyx_k__ob_type[] = "ob_type"; static char __pyx_k__tb_next[] = "tb_next"; static char __pyx_k____main__[] = "__main__"; static char __pyx_k____name__[] = "__name__"; static char __pyx_k____test__[] = "__test__"; static char __pyx_k__cl_bases[] = "cl_bases"; static char __pyx_k__exc_info[] = "exc_info"; static char __pyx_k__fromlist[] = "fromlist"; static char __pyx_k__in_class[] = "in_class"; static char __pyx_k__protocol[] = "protocol"; static char __pyx_k__warnings[] = "warnings"; static char __pyx_k__Exception[] = "Exception"; static char __pyx_k__TypeError[] = "TypeError"; static char __pyx_k____adapt__[] = "__adapt__"; static char __pyx_k____bases__[] = "__bases__"; static char __pyx_k____class__[] = "__class__"; static char __pyx_k__exc_clear[] = "exc_clear"; static char __pyx_k__protocols[] = "protocols"; static char __pyx_k____import__[] = "__import__"; static char __pyx_k__classicMRO[] = "classicMRO"; static char __pyx_k__metamethod[] = "metamethod"; static char __pyx_k__ImportError[] = "ImportError"; static char __pyx_k____conform__[] = "__conform__"; static char __pyx_k__extClassMRO[] = "extClassMRO"; static char __pyx_k__AttributeError[] = "AttributeError"; static char __pyx_k__ExtensionClass[] = "ExtensionClass"; static char __pyx_k__extendedClassic[] = "extendedClassic"; static char __pyx_k__DOES_NOT_SUPPORT[] = "DOES_NOT_SUPPORT"; static char __pyx_k__Protocol__call__[] = "Protocol__call__"; static char __pyx_k__AdaptationFailure[] = "AdaptationFailure"; static char __pyx_k__NO_ADAPTER_NEEDED[] = "NO_ADAPTER_NEEDED"; static char __pyx_k__Protocol__adapt__[] = "Protocol__adapt__"; static char __pyx_k__DeprecationWarning[] = "DeprecationWarning"; static char __pyx_k___Protocol__adapters[] = "_Protocol__adapters"; static PyObject *__pyx_kp_s_1; static PyObject *__pyx_kp_s_10; static PyObject *__pyx_n_s_15; static PyObject *__pyx_kp_s_4; static PyObject *__pyx_kp_s_5; static PyObject *__pyx_n_s__AdaptationFailure; static PyObject *__pyx_n_s__AttributeError; static PyObject *__pyx_n_s__DOES_NOT_SUPPORT; static PyObject *__pyx_n_s__DeprecationWarning; static PyObject *__pyx_n_s__Exception; static PyObject *__pyx_n_s__ExtensionClass; static PyObject *__pyx_n_s__ImportError; static PyObject *__pyx_n_s__NO_ADAPTER_NEEDED; static PyObject *__pyx_n_s__Protocol__adapt__; static PyObject *__pyx_n_s__Protocol__call__; static PyObject *__pyx_n_s__TypeError; static PyObject *__pyx_n_s___Protocol__adapters; static PyObject *__pyx_n_s____all__; static PyObject *__pyx_n_s____bases__; static PyObject *__pyx_n_s____class; static PyObject *__pyx_n_s____import__; static PyObject *__pyx_n_s____main__; static PyObject *__pyx_n_s____mro__; static PyObject *__pyx_n_s____name__; static PyObject *__pyx_n_s____test__; static PyObject *__pyx_n_s__adapt; static PyObject *__pyx_n_s__cl_bases; static PyObject *__pyx_n_s__classicMRO; static PyObject *__pyx_n_s__default; static PyObject *__pyx_n_s__exc_clear; static PyObject *__pyx_n_s__exc_info; static PyObject *__pyx_n_s__extClassMRO; static PyObject *__pyx_n_s__extendedClassic; static PyObject *__pyx_n_s__factory; static PyObject *__pyx_n_s__fromlist; static PyObject *__pyx_n_s__func; static PyObject *__pyx_n_s__get; static PyObject *__pyx_n_s__getMRO; static PyObject *__pyx_n_s__globals; static PyObject *__pyx_n_s__in_class; static PyObject *__pyx_n_s__level; static PyObject *__pyx_n_s__metamethod; static PyObject *__pyx_n_s__ob; static PyObject *__pyx_n_s__ob_type; static PyObject *__pyx_n_s__obj; static PyObject *__pyx_n_s__object; static PyObject *__pyx_n_s__protocol; static PyObject *__pyx_n_s__protocols; static PyObject *__pyx_n_s__self; static PyObject *__pyx_n_s__sys; static PyObject *__pyx_n_s__tb_next; static PyObject *__pyx_n_s__tp_mro; static PyObject *__pyx_n_s__warn; static PyObject *__pyx_n_s__warnings; static PyObject *__pyx_int_1; static PyObject *__pyx_k_6; static PyObject *__pyx_k_7; static PyObject *__pyx_k_8; static PyObject *__pyx_k_9; static PyObject *__pyx_k_11; static PyObject *__pyx_k_12; static PyObject *__pyx_k_tuple_2; static PyObject *__pyx_k_tuple_3; static PyObject *__pyx_k_tuple_14; /* "traits/protocols/_speedups.pyx":92 * # Fundamental Adapters * * def NO_ADAPTER_NEEDED(obj, protocol=None): # <<<<<<<<<<<<<< * """Assume 'obj' implements 'protocol' directly""" * return obj */ static PyObject *__pyx_pf_9enthought_6traits_9protocols_9_speedups_NO_ADAPTER_NEEDED(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static char __pyx_doc_9enthought_6traits_9protocols_9_speedups_NO_ADAPTER_NEEDED[] = "Assume 'obj' implements 'protocol' directly"; static PyMethodDef __pyx_mdef_9enthought_6traits_9protocols_9_speedups_NO_ADAPTER_NEEDED = {__Pyx_NAMESTR("NO_ADAPTER_NEEDED"), (PyCFunction)__pyx_pf_9enthought_6traits_9protocols_9_speedups_NO_ADAPTER_NEEDED, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_9enthought_6traits_9protocols_9_speedups_NO_ADAPTER_NEEDED)}; static PyObject *__pyx_pf_9enthought_6traits_9protocols_9_speedups_NO_ADAPTER_NEEDED(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_obj = 0; PyObject *__pyx_v_protocol = 0; PyObject *__pyx_r = NULL; static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__obj,&__pyx_n_s__protocol,0}; __Pyx_RefNannySetupContext("NO_ADAPTER_NEEDED"); __pyx_self = __pyx_self; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args = PyDict_Size(__pyx_kwds); PyObject* values[2] = {0,0}; values[1] = ((PyObject *)Py_None); switch (PyTuple_GET_SIZE(__pyx_args)) { case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } switch (PyTuple_GET_SIZE(__pyx_args)) { case 0: values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__obj); if (likely(values[0])) kw_args--; else goto __pyx_L5_argtuple_error; case 1: if (kw_args > 0) { PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__protocol); if (value) { values[1] = value; kw_args--; } } } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "NO_ADAPTER_NEEDED") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } __pyx_v_obj = values[0]; __pyx_v_protocol = values[1]; } else { __pyx_v_protocol = ((PyObject *)Py_None); switch (PyTuple_GET_SIZE(__pyx_args)) { case 2: __pyx_v_protocol = PyTuple_GET_ITEM(__pyx_args, 1); case 1: __pyx_v_obj = PyTuple_GET_ITEM(__pyx_args, 0); break; default: goto __pyx_L5_argtuple_error; } } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("NO_ADAPTER_NEEDED", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("traits.protocols._speedups.NO_ADAPTER_NEEDED"); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; /* "traits/protocols/_speedups.pyx":94 * def NO_ADAPTER_NEEDED(obj, protocol=None): * """Assume 'obj' implements 'protocol' directly""" * return obj # <<<<<<<<<<<<<< * * def DOES_NOT_SUPPORT(obj, protocol=None): */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_v_obj); __pyx_r = __pyx_v_obj; goto __pyx_L0; __pyx_r = Py_None; __Pyx_INCREF(Py_None); __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "traits/protocols/_speedups.pyx":96 * return obj * * def DOES_NOT_SUPPORT(obj, protocol=None): # <<<<<<<<<<<<<< * """Prevent 'obj' from supporting 'protocol'""" * return None */ static PyObject *__pyx_pf_9enthought_6traits_9protocols_9_speedups_1DOES_NOT_SUPPORT(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static char __pyx_doc_9enthought_6traits_9protocols_9_speedups_1DOES_NOT_SUPPORT[] = "Prevent 'obj' from supporting 'protocol'"; static PyMethodDef __pyx_mdef_9enthought_6traits_9protocols_9_speedups_1DOES_NOT_SUPPORT = {__Pyx_NAMESTR("DOES_NOT_SUPPORT"), (PyCFunction)__pyx_pf_9enthought_6traits_9protocols_9_speedups_1DOES_NOT_SUPPORT, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_9enthought_6traits_9protocols_9_speedups_1DOES_NOT_SUPPORT)}; static PyObject *__pyx_pf_9enthought_6traits_9protocols_9_speedups_1DOES_NOT_SUPPORT(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_obj = 0; PyObject *__pyx_v_protocol = 0; PyObject *__pyx_r = NULL; static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__obj,&__pyx_n_s__protocol,0}; __Pyx_RefNannySetupContext("DOES_NOT_SUPPORT"); __pyx_self = __pyx_self; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args = PyDict_Size(__pyx_kwds); PyObject* values[2] = {0,0}; values[1] = ((PyObject *)Py_None); switch (PyTuple_GET_SIZE(__pyx_args)) { case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } switch (PyTuple_GET_SIZE(__pyx_args)) { case 0: values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__obj); if (likely(values[0])) kw_args--; else goto __pyx_L5_argtuple_error; case 1: if (kw_args > 0) { PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__protocol); if (value) { values[1] = value; kw_args--; } } } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "DOES_NOT_SUPPORT") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } __pyx_v_obj = values[0]; __pyx_v_protocol = values[1]; } else { __pyx_v_protocol = ((PyObject *)Py_None); switch (PyTuple_GET_SIZE(__pyx_args)) { case 2: __pyx_v_protocol = PyTuple_GET_ITEM(__pyx_args, 1); case 1: __pyx_v_obj = PyTuple_GET_ITEM(__pyx_args, 0); break; default: goto __pyx_L5_argtuple_error; } } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("DOES_NOT_SUPPORT", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("traits.protocols._speedups.DOES_NOT_SUPPORT"); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; /* "traits/protocols/_speedups.pyx":98 * def DOES_NOT_SUPPORT(obj, protocol=None): * """Prevent 'obj' from supporting 'protocol'""" * return None # <<<<<<<<<<<<<< * * */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(Py_None); __pyx_r = Py_None; goto __pyx_L0; __pyx_r = Py_None; __Pyx_INCREF(Py_None); __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "traits/protocols/_speedups.pyx":106 * cdef object func * * def __init__(self, func): # <<<<<<<<<<<<<< * self.func = func * */ static int __pyx_pf_9enthought_6traits_9protocols_9_speedups_10metamethod___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static int __pyx_pf_9enthought_6traits_9protocols_9_speedups_10metamethod___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_func = 0; int __pyx_r; static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__func,0}; __Pyx_RefNannySetupContext("__init__"); if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args = PyDict_Size(__pyx_kwds); PyObject* values[1] = {0}; switch (PyTuple_GET_SIZE(__pyx_args)) { case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } switch (PyTuple_GET_SIZE(__pyx_args)) { case 0: values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__func); if (likely(values[0])) kw_args--; else goto __pyx_L5_argtuple_error; } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } __pyx_v_func = values[0]; } else if (PyTuple_GET_SIZE(__pyx_args) != 1) { goto __pyx_L5_argtuple_error; } else { __pyx_v_func = PyTuple_GET_ITEM(__pyx_args, 0); } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("traits.protocols._speedups.metamethod.__init__"); __Pyx_RefNannyFinishContext(); return -1; __pyx_L4_argument_unpacking_done:; /* "traits/protocols/_speedups.pyx":107 * * def __init__(self, func): * self.func = func # <<<<<<<<<<<<<< * * def __get__(self, ob, typ): */ __Pyx_INCREF(__pyx_v_func); __Pyx_GIVEREF(__pyx_v_func); __Pyx_GOTREF(((struct __pyx_obj_9enthought_6traits_9protocols_9_speedups_metamethod *)__pyx_v_self)->func); __Pyx_DECREF(((struct __pyx_obj_9enthought_6traits_9protocols_9_speedups_metamethod *)__pyx_v_self)->func); ((struct __pyx_obj_9enthought_6traits_9protocols_9_speedups_metamethod *)__pyx_v_self)->func = __pyx_v_func; __pyx_r = 0; __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "traits/protocols/_speedups.pyx":109 * self.func = func * * def __get__(self, ob, typ): # <<<<<<<<<<<<<< * if ob is None: * return self */ static PyObject *__pyx_pf_9enthought_6traits_9protocols_9_speedups_10metamethod_1__get__(PyObject *__pyx_v_self, PyObject *__pyx_v_ob, PyObject *__pyx_v_typ); /*proto*/ static PyObject *__pyx_pf_9enthought_6traits_9protocols_9_speedups_10metamethod_1__get__(PyObject *__pyx_v_self, PyObject *__pyx_v_ob, PyObject *__pyx_v_typ) { PyObject *__pyx_r = NULL; int __pyx_t_1; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; __Pyx_RefNannySetupContext("__get__"); /* "traits/protocols/_speedups.pyx":110 * * def __get__(self, ob, typ): * if ob is None: # <<<<<<<<<<<<<< * return self * return PyMethod_New(self.func, ob, typ) */ __pyx_t_1 = (__pyx_v_ob == Py_None); if (__pyx_t_1) { /* "traits/protocols/_speedups.pyx":111 * def __get__(self, ob, typ): * if ob is None: * return self # <<<<<<<<<<<<<< * return PyMethod_New(self.func, ob, typ) * */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_v_self); __pyx_r = __pyx_v_self; goto __pyx_L0; goto __pyx_L5; } __pyx_L5:; /* "traits/protocols/_speedups.pyx":112 * if ob is None: * return self * return PyMethod_New(self.func, ob, typ) # <<<<<<<<<<<<<< * * def __set__(self, ob, value): */ __Pyx_XDECREF(__pyx_r); __pyx_t_2 = ((struct __pyx_obj_9enthought_6traits_9protocols_9_speedups_metamethod *)__pyx_v_self)->func; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = __pyx_v_ob; __Pyx_INCREF(__pyx_t_3); __pyx_t_4 = __pyx_v_typ; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = PyMethod_New(__pyx_t_2, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_5); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_r = __pyx_t_5; __pyx_t_5 = 0; goto __pyx_L0; __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __Pyx_AddTraceback("traits.protocols._speedups.metamethod.__get__"); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "traits/protocols/_speedups.pyx":114 * return PyMethod_New(self.func, ob, typ) * * def __set__(self, ob, value): # <<<<<<<<<<<<<< * raise AttributeError("Read-only attribute") * */ static int __pyx_pf_9enthought_6traits_9protocols_9_speedups_10metamethod_2__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_ob, PyObject *__pyx_v_value); /*proto*/ static int __pyx_pf_9enthought_6traits_9protocols_9_speedups_10metamethod_2__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_ob, PyObject *__pyx_v_value) { int __pyx_r; PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("__set__"); /* "traits/protocols/_speedups.pyx":115 * * def __set__(self, ob, value): * raise AttributeError("Read-only attribute") # <<<<<<<<<<<<<< * * def __delete__(self, ob): */ __pyx_t_1 = PyObject_Call(__pyx_builtin_AttributeError, ((PyObject *)__pyx_k_tuple_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_Raise(__pyx_t_1, 0, 0); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_r = 0; goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("traits.protocols._speedups.metamethod.__set__"); __pyx_r = -1; __pyx_L0:; __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "traits/protocols/_speedups.pyx":117 * raise AttributeError("Read-only attribute") * * def __delete__(self, ob): # <<<<<<<<<<<<<< * raise AttributeError("Read-only attribute") * */ static int __pyx_pf_9enthought_6traits_9protocols_9_speedups_10metamethod_3__delete__(PyObject *__pyx_v_self, PyObject *__pyx_v_ob); /*proto*/ static int __pyx_pf_9enthought_6traits_9protocols_9_speedups_10metamethod_3__delete__(PyObject *__pyx_v_self, PyObject *__pyx_v_ob) { int __pyx_r; PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("__delete__"); /* "traits/protocols/_speedups.pyx":118 * * def __delete__(self, ob): * raise AttributeError("Read-only attribute") # <<<<<<<<<<<<<< * * */ __pyx_t_1 = PyObject_Call(__pyx_builtin_AttributeError, ((PyObject *)__pyx_k_tuple_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_Raise(__pyx_t_1, 0, 0); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_r = 0; goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("traits.protocols._speedups.metamethod.__delete__"); __pyx_r = -1; __pyx_L0:; __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "traits/protocols/_speedups.pyx":131 * * * cdef object _adapt(obj, protocol, default, factory): # <<<<<<<<<<<<<< * * # We use nested 'if' blocks here because using 'and' causes Pyrex to */ static PyObject *__pyx_f_9enthought_6traits_9protocols_9_speedups__adapt(PyObject *__pyx_v_obj, PyObject *__pyx_v_protocol, PyObject *__pyx_v_default, PyObject *__pyx_v_factory) { PyObject *__pyx_v_meth; PyObject *__pyx_v_result; PyObject *__pyx_v_e; PyObject *__pyx_v_warn; PyObject *__pyx_r = NULL; PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; int __pyx_t_3; PyObject *__pyx_t_4 = NULL; int __pyx_t_5; PyObject *__pyx_t_6 = NULL; PyObject *__pyx_t_7 = NULL; __Pyx_RefNannySetupContext("_adapt"); __pyx_v_meth = Py_None; __Pyx_INCREF(Py_None); __pyx_v_result = Py_None; __Pyx_INCREF(Py_None); __pyx_v_e = Py_None; __Pyx_INCREF(Py_None); __pyx_v_warn = Py_None; __Pyx_INCREF(Py_None); /* "traits/protocols/_speedups.pyx":149 * ### return obj * * if PyObject_IsInstance(obj,protocol): # <<<<<<<<<<<<<< * return obj * */ __pyx_t_1 = __pyx_v_obj; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = __pyx_v_protocol; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = PyObject_IsInstance(__pyx_t_1, __pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; if (__pyx_t_3) { /* "traits/protocols/_speedups.pyx":150 * * if PyObject_IsInstance(obj,protocol): * return obj # <<<<<<<<<<<<<< * * try: */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_v_obj); __pyx_r = __pyx_v_obj; goto __pyx_L0; goto __pyx_L3; } __pyx_L3:; /* "traits/protocols/_speedups.pyx":152 * return obj * * try: # <<<<<<<<<<<<<< * meth = getattr(obj, __conform) * try: */ { PyObject *__pyx_save_exc_type, *__pyx_save_exc_value, *__pyx_save_exc_tb; __Pyx_ExceptionSave(&__pyx_save_exc_type, &__pyx_save_exc_value, &__pyx_save_exc_tb); __Pyx_XGOTREF(__pyx_save_exc_type); __Pyx_XGOTREF(__pyx_save_exc_value); __Pyx_XGOTREF(__pyx_save_exc_tb); /*try:*/ { /* "traits/protocols/_speedups.pyx":153 * * try: * meth = getattr(obj, __conform) # <<<<<<<<<<<<<< * try: * result = meth(protocol) */ __pyx_t_2 = __pyx_v_obj; __Pyx_INCREF(__pyx_t_2); __pyx_t_1 = __pyx_v_9enthought_6traits_9protocols_9_speedups___conform; __Pyx_INCREF(__pyx_t_1); __pyx_t_4 = PyObject_GetAttr(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L4_error;} __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_v_meth); __pyx_v_meth = __pyx_t_4; __pyx_t_4 = 0; /* "traits/protocols/_speedups.pyx":154 * try: * meth = getattr(obj, __conform) * try: # <<<<<<<<<<<<<< * result = meth(protocol) * if result is not None: */ { PyObject *__pyx_save_exc_type, *__pyx_save_exc_value, *__pyx_save_exc_tb; __Pyx_ExceptionSave(&__pyx_save_exc_type, &__pyx_save_exc_value, &__pyx_save_exc_tb); __Pyx_XGOTREF(__pyx_save_exc_type); __Pyx_XGOTREF(__pyx_save_exc_value); __Pyx_XGOTREF(__pyx_save_exc_tb); /*try:*/ { /* "traits/protocols/_speedups.pyx":155 * meth = getattr(obj, __conform) * try: * result = meth(protocol) # <<<<<<<<<<<<<< * if result is not None: * return result */ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L12_error;} __Pyx_GOTREF(((PyObject *)__pyx_t_4)); __Pyx_INCREF(__pyx_v_protocol); PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_protocol); __Pyx_GIVEREF(__pyx_v_protocol); __pyx_t_1 = PyObject_Call(__pyx_v_meth, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L12_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0; __Pyx_DECREF(__pyx_v_result); __pyx_v_result = __pyx_t_1; __pyx_t_1 = 0; /* "traits/protocols/_speedups.pyx":156 * try: * result = meth(protocol) * if result is not None: # <<<<<<<<<<<<<< * return result * except TypeError, e: */ __pyx_t_5 = (__pyx_v_result != Py_None); if (__pyx_t_5) { /* "traits/protocols/_speedups.pyx":157 * result = meth(protocol) * if result is not None: * return result # <<<<<<<<<<<<<< * except TypeError, e: * if exc_info()[2].tb_next is not None: */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_v_result); __pyx_r = __pyx_v_result; goto __pyx_L16_try_return; goto __pyx_L20; } __pyx_L20:; } __Pyx_XDECREF(__pyx_save_exc_type); __pyx_save_exc_type = 0; __Pyx_XDECREF(__pyx_save_exc_value); __pyx_save_exc_value = 0; __Pyx_XDECREF(__pyx_save_exc_tb); __pyx_save_exc_tb = 0; goto __pyx_L19_try_end; __pyx_L16_try_return:; __Pyx_XGIVEREF(__pyx_save_exc_type); __Pyx_XGIVEREF(__pyx_save_exc_value); __Pyx_XGIVEREF(__pyx_save_exc_tb); __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb); goto __pyx_L8_try_return; __pyx_L12_error:; __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; /* "traits/protocols/_speedups.pyx":158 * if result is not None: * return result * except TypeError, e: # <<<<<<<<<<<<<< * if exc_info()[2].tb_next is not None: * raise */ __pyx_t_3 = PyErr_ExceptionMatches(__pyx_builtin_TypeError); if (__pyx_t_3) { __Pyx_AddTraceback("traits.protocols._speedups._adapt"); if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_4, &__pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L14_except_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_GOTREF(__pyx_t_4); __Pyx_GOTREF(__pyx_t_2); __Pyx_INCREF(__pyx_t_4); __Pyx_DECREF(__pyx_v_e); __pyx_v_e = __pyx_t_4; /* "traits/protocols/_speedups.pyx":159 * return result * except TypeError, e: * if exc_info()[2].tb_next is not None: # <<<<<<<<<<<<<< * raise * except AttributeError, e: */ __pyx_t_6 = __Pyx_GetName(__pyx_m, __pyx_n_s__exc_info); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L14_except_error;} __Pyx_GOTREF(__pyx_t_6); __pyx_t_7 = PyObject_Call(__pyx_t_6, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L14_except_error;} __Pyx_GOTREF(__pyx_t_7); __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; __pyx_t_6 = __Pyx_GetItemInt(__pyx_t_7, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L14_except_error;} __Pyx_GOTREF(__pyx_t_6); __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; __pyx_t_7 = PyObject_GetAttr(__pyx_t_6, __pyx_n_s__tb_next); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L14_except_error;} __Pyx_GOTREF(__pyx_t_7); __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; __pyx_t_5 = (__pyx_t_7 != Py_None); __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; if (__pyx_t_5) { /* "traits/protocols/_speedups.pyx":160 * except TypeError, e: * if exc_info()[2].tb_next is not None: * raise # <<<<<<<<<<<<<< * except AttributeError, e: * # Call exc_clear() instead of PyErr_Clear to make sure that the */ __Pyx_GIVEREF(__pyx_t_1); __Pyx_GIVEREF(__pyx_t_4); __Pyx_GIVEREF(__pyx_t_2); __Pyx_ErrRestore(__pyx_t_1, __pyx_t_4, __pyx_t_2); __pyx_t_1 = 0; __pyx_t_4 = 0; __pyx_t_2 = 0; {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L14_except_error;} goto __pyx_L23; } __pyx_L23:; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; goto __pyx_L13_exception_handled; } __pyx_L14_except_error:; __Pyx_XGIVEREF(__pyx_save_exc_type); __Pyx_XGIVEREF(__pyx_save_exc_value); __Pyx_XGIVEREF(__pyx_save_exc_tb); __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb); goto __pyx_L4_error; __pyx_L13_exception_handled:; __Pyx_XGIVEREF(__pyx_save_exc_type); __Pyx_XGIVEREF(__pyx_save_exc_value); __Pyx_XGIVEREF(__pyx_save_exc_tb); __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb); __pyx_L19_try_end:; } } __Pyx_XDECREF(__pyx_save_exc_type); __pyx_save_exc_type = 0; __Pyx_XDECREF(__pyx_save_exc_value); __pyx_save_exc_value = 0; __Pyx_XDECREF(__pyx_save_exc_tb); __pyx_save_exc_tb = 0; goto __pyx_L11_try_end; __pyx_L8_try_return:; __Pyx_XGIVEREF(__pyx_save_exc_type); __Pyx_XGIVEREF(__pyx_save_exc_value); __Pyx_XGIVEREF(__pyx_save_exc_tb); __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb); goto __pyx_L0; __pyx_L4_error:; __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; /* "traits/protocols/_speedups.pyx":161 * if exc_info()[2].tb_next is not None: * raise * except AttributeError, e: # <<<<<<<<<<<<<< * # Call exc_clear() instead of PyErr_Clear to make sure that the * # sys.exc_* objects are also removed. This has caused some frames to */ __pyx_t_3 = PyErr_ExceptionMatches(__pyx_builtin_AttributeError); if (__pyx_t_3) { __Pyx_AddTraceback("traits.protocols._speedups._adapt"); if (__Pyx_GetException(&__pyx_t_2, &__pyx_t_4, &__pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_GOTREF(__pyx_t_4); __Pyx_GOTREF(__pyx_t_1); __Pyx_INCREF(__pyx_t_4); __Pyx_DECREF(__pyx_v_e); __pyx_v_e = __pyx_t_4; /* "traits/protocols/_speedups.pyx":165 * # sys.exc_* objects are also removed. This has caused some frames to * # live too long. * exc_clear() # <<<<<<<<<<<<<< * * try: */ __pyx_t_7 = __Pyx_GetName(__pyx_m, __pyx_n_s__exc_clear); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;} __Pyx_GOTREF(__pyx_t_7); __pyx_t_6 = PyObject_Call(__pyx_t_7, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;} __Pyx_GOTREF(__pyx_t_6); __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; goto __pyx_L5_exception_handled; } __pyx_L6_except_error:; __Pyx_XGIVEREF(__pyx_save_exc_type); __Pyx_XGIVEREF(__pyx_save_exc_value); __Pyx_XGIVEREF(__pyx_save_exc_tb); __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb); goto __pyx_L1_error; __pyx_L5_exception_handled:; __Pyx_XGIVEREF(__pyx_save_exc_type); __Pyx_XGIVEREF(__pyx_save_exc_value); __Pyx_XGIVEREF(__pyx_save_exc_tb); __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb); __pyx_L11_try_end:; } /* "traits/protocols/_speedups.pyx":167 * exc_clear() * * try: # <<<<<<<<<<<<<< * meth = getattr(protocol, __adapt) * try: */ { PyObject *__pyx_save_exc_type, *__pyx_save_exc_value, *__pyx_save_exc_tb; __Pyx_ExceptionSave(&__pyx_save_exc_type, &__pyx_save_exc_value, &__pyx_save_exc_tb); __Pyx_XGOTREF(__pyx_save_exc_type); __Pyx_XGOTREF(__pyx_save_exc_value); __Pyx_XGOTREF(__pyx_save_exc_tb); /*try:*/ { /* "traits/protocols/_speedups.pyx":168 * * try: * meth = getattr(protocol, __adapt) # <<<<<<<<<<<<<< * try: * result = meth(obj) */ __pyx_t_1 = __pyx_v_protocol; __Pyx_INCREF(__pyx_t_1); __pyx_t_4 = __pyx_v_9enthought_6traits_9protocols_9_speedups___adapt; __Pyx_INCREF(__pyx_t_4); __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L26_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF(__pyx_v_meth); __pyx_v_meth = __pyx_t_2; __pyx_t_2 = 0; /* "traits/protocols/_speedups.pyx":169 * try: * meth = getattr(protocol, __adapt) * try: # <<<<<<<<<<<<<< * result = meth(obj) * if result is not None: */ { PyObject *__pyx_save_exc_type, *__pyx_save_exc_value, *__pyx_save_exc_tb; __Pyx_ExceptionSave(&__pyx_save_exc_type, &__pyx_save_exc_value, &__pyx_save_exc_tb); __Pyx_XGOTREF(__pyx_save_exc_type); __Pyx_XGOTREF(__pyx_save_exc_value); __Pyx_XGOTREF(__pyx_save_exc_tb); /*try:*/ { /* "traits/protocols/_speedups.pyx":170 * meth = getattr(protocol, __adapt) * try: * result = meth(obj) # <<<<<<<<<<<<<< * if result is not None: * return result */ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L34_error;} __Pyx_GOTREF(((PyObject *)__pyx_t_2)); __Pyx_INCREF(__pyx_v_obj); PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_obj); __Pyx_GIVEREF(__pyx_v_obj); __pyx_t_4 = PyObject_Call(__pyx_v_meth, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L34_error;} __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_v_result); __pyx_v_result = __pyx_t_4; __pyx_t_4 = 0; /* "traits/protocols/_speedups.pyx":171 * try: * result = meth(obj) * if result is not None: # <<<<<<<<<<<<<< * return result * except TypeError: */ __pyx_t_5 = (__pyx_v_result != Py_None); if (__pyx_t_5) { /* "traits/protocols/_speedups.pyx":172 * result = meth(obj) * if result is not None: * return result # <<<<<<<<<<<<<< * except TypeError: * if exc_info()[2].tb_next is not None: */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_v_result); __pyx_r = __pyx_v_result; goto __pyx_L38_try_return; goto __pyx_L42; } __pyx_L42:; } __Pyx_XDECREF(__pyx_save_exc_type); __pyx_save_exc_type = 0; __Pyx_XDECREF(__pyx_save_exc_value); __pyx_save_exc_value = 0; __Pyx_XDECREF(__pyx_save_exc_tb); __pyx_save_exc_tb = 0; goto __pyx_L41_try_end; __pyx_L38_try_return:; __Pyx_XGIVEREF(__pyx_save_exc_type); __Pyx_XGIVEREF(__pyx_save_exc_value); __Pyx_XGIVEREF(__pyx_save_exc_tb); __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb); goto __pyx_L30_try_return; __pyx_L34_error:; __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; /* "traits/protocols/_speedups.pyx":173 * if result is not None: * return result * except TypeError: # <<<<<<<<<<<<<< * if exc_info()[2].tb_next is not None: * raise */ __pyx_t_3 = PyErr_ExceptionMatches(__pyx_builtin_TypeError); if (__pyx_t_3) { __Pyx_AddTraceback("traits.protocols._speedups._adapt"); if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_2, &__pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L36_except_error;} __Pyx_GOTREF(__pyx_t_4); __Pyx_GOTREF(__pyx_t_2); __Pyx_GOTREF(__pyx_t_1); /* "traits/protocols/_speedups.pyx":174 * return result * except TypeError: * if exc_info()[2].tb_next is not None: # <<<<<<<<<<<<<< * raise * except AttributeError, e: */ __pyx_t_6 = __Pyx_GetName(__pyx_m, __pyx_n_s__exc_info); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L36_except_error;} __Pyx_GOTREF(__pyx_t_6); __pyx_t_7 = PyObject_Call(__pyx_t_6, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L36_except_error;} __Pyx_GOTREF(__pyx_t_7); __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; __pyx_t_6 = __Pyx_GetItemInt(__pyx_t_7, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L36_except_error;} __Pyx_GOTREF(__pyx_t_6); __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; __pyx_t_7 = PyObject_GetAttr(__pyx_t_6, __pyx_n_s__tb_next); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L36_except_error;} __Pyx_GOTREF(__pyx_t_7); __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; __pyx_t_5 = (__pyx_t_7 != Py_None); __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; if (__pyx_t_5) { /* "traits/protocols/_speedups.pyx":175 * except TypeError: * if exc_info()[2].tb_next is not None: * raise # <<<<<<<<<<<<<< * except AttributeError, e: * exc_clear() */ __Pyx_GIVEREF(__pyx_t_4); __Pyx_GIVEREF(__pyx_t_2); __Pyx_GIVEREF(__pyx_t_1); __Pyx_ErrRestore(__pyx_t_4, __pyx_t_2, __pyx_t_1); __pyx_t_4 = 0; __pyx_t_2 = 0; __pyx_t_1 = 0; {__pyx_filename = __pyx_f[0]; __pyx_lineno = 175; __pyx_clineno = __LINE__; goto __pyx_L36_except_error;} goto __pyx_L45; } __pyx_L45:; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; goto __pyx_L35_exception_handled; } __pyx_L36_except_error:; __Pyx_XGIVEREF(__pyx_save_exc_type); __Pyx_XGIVEREF(__pyx_save_exc_value); __Pyx_XGIVEREF(__pyx_save_exc_tb); __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb); goto __pyx_L26_error; __pyx_L35_exception_handled:; __Pyx_XGIVEREF(__pyx_save_exc_type); __Pyx_XGIVEREF(__pyx_save_exc_value); __Pyx_XGIVEREF(__pyx_save_exc_tb); __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb); __pyx_L41_try_end:; } } __Pyx_XDECREF(__pyx_save_exc_type); __pyx_save_exc_type = 0; __Pyx_XDECREF(__pyx_save_exc_value); __pyx_save_exc_value = 0; __Pyx_XDECREF(__pyx_save_exc_tb); __pyx_save_exc_tb = 0; goto __pyx_L33_try_end; __pyx_L30_try_return:; __Pyx_XGIVEREF(__pyx_save_exc_type); __Pyx_XGIVEREF(__pyx_save_exc_value); __Pyx_XGIVEREF(__pyx_save_exc_tb); __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb); goto __pyx_L0; __pyx_L26_error:; __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; /* "traits/protocols/_speedups.pyx":176 * if exc_info()[2].tb_next is not None: * raise * except AttributeError, e: # <<<<<<<<<<<<<< * exc_clear() * */ __pyx_t_3 = PyErr_ExceptionMatches(__pyx_builtin_AttributeError); if (__pyx_t_3) { __Pyx_AddTraceback("traits.protocols._speedups._adapt"); if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_2, &__pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L28_except_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_GOTREF(__pyx_t_2); __Pyx_GOTREF(__pyx_t_4); __Pyx_INCREF(__pyx_t_2); __Pyx_DECREF(__pyx_v_e); __pyx_v_e = __pyx_t_2; /* "traits/protocols/_speedups.pyx":177 * raise * except AttributeError, e: * exc_clear() # <<<<<<<<<<<<<< * * if default is _marker: */ __pyx_t_7 = __Pyx_GetName(__pyx_m, __pyx_n_s__exc_clear); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 177; __pyx_clineno = __LINE__; goto __pyx_L28_except_error;} __Pyx_GOTREF(__pyx_t_7); __pyx_t_6 = PyObject_Call(__pyx_t_7, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 177; __pyx_clineno = __LINE__; goto __pyx_L28_except_error;} __Pyx_GOTREF(__pyx_t_6); __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; goto __pyx_L27_exception_handled; } __pyx_L28_except_error:; __Pyx_XGIVEREF(__pyx_save_exc_type); __Pyx_XGIVEREF(__pyx_save_exc_value); __Pyx_XGIVEREF(__pyx_save_exc_tb); __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb); goto __pyx_L1_error; __pyx_L27_exception_handled:; __Pyx_XGIVEREF(__pyx_save_exc_type); __Pyx_XGIVEREF(__pyx_save_exc_value); __Pyx_XGIVEREF(__pyx_save_exc_tb); __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb); __pyx_L33_try_end:; } /* "traits/protocols/_speedups.pyx":179 * exc_clear() * * if default is _marker: # <<<<<<<<<<<<<< * if factory is not _marker: * from warnings import warn */ __pyx_t_5 = (__pyx_v_default == __pyx_v_9enthought_6traits_9protocols_9_speedups__marker); if (__pyx_t_5) { /* "traits/protocols/_speedups.pyx":180 * * if default is _marker: * if factory is not _marker: # <<<<<<<<<<<<<< * from warnings import warn * warn("The 'factory' argument to 'adapt()' will be removed in 1.0", */ __pyx_t_5 = (__pyx_v_factory != __pyx_v_9enthought_6traits_9protocols_9_speedups__marker); if (__pyx_t_5) { /* "traits/protocols/_speedups.pyx":181 * if default is _marker: * if factory is not _marker: * from warnings import warn # <<<<<<<<<<<<<< * warn("The 'factory' argument to 'adapt()' will be removed in 1.0", * DeprecationWarning, 1) */ __pyx_t_4 = PyList_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(((PyObject *)__pyx_t_4)); __Pyx_INCREF(((PyObject *)__pyx_n_s__warn)); PyList_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_n_s__warn)); __Pyx_GIVEREF(((PyObject *)__pyx_n_s__warn)); __pyx_t_2 = __Pyx_Import(((PyObject *)__pyx_n_s__warnings), ((PyObject *)__pyx_t_4)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0; __pyx_t_4 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__warn); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __Pyx_INCREF(__pyx_t_4); __Pyx_DECREF(__pyx_v_warn); __pyx_v_warn = __pyx_t_4; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "traits/protocols/_speedups.pyx":183 * from warnings import warn * warn("The 'factory' argument to 'adapt()' will be removed in 1.0", * DeprecationWarning, 1) # <<<<<<<<<<<<<< * return factory(obj, protocol) * raise AdaptationFailure("Can't adapt", obj, protocol) */ __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(((PyObject *)__pyx_t_2)); __Pyx_INCREF(((PyObject *)__pyx_kp_s_4)); PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_kp_s_4)); __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_4)); __Pyx_INCREF(__pyx_builtin_DeprecationWarning); PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_builtin_DeprecationWarning); __Pyx_GIVEREF(__pyx_builtin_DeprecationWarning); __Pyx_INCREF(__pyx_int_1); PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_int_1); __Pyx_GIVEREF(__pyx_int_1); __pyx_t_4 = PyObject_Call(__pyx_v_warn, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; /* "traits/protocols/_speedups.pyx":184 * warn("The 'factory' argument to 'adapt()' will be removed in 1.0", * DeprecationWarning, 1) * return factory(obj, protocol) # <<<<<<<<<<<<<< * raise AdaptationFailure("Can't adapt", obj, protocol) * */ __Pyx_XDECREF(__pyx_r); __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 184; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(((PyObject *)__pyx_t_4)); __Pyx_INCREF(__pyx_v_obj); PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_obj); __Pyx_GIVEREF(__pyx_v_obj); __Pyx_INCREF(__pyx_v_protocol); PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_v_protocol); __Pyx_GIVEREF(__pyx_v_protocol); __pyx_t_2 = PyObject_Call(__pyx_v_factory, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 184; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0; __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; goto __pyx_L49; } __pyx_L49:; /* "traits/protocols/_speedups.pyx":185 * DeprecationWarning, 1) * return factory(obj, protocol) * raise AdaptationFailure("Can't adapt", obj, protocol) # <<<<<<<<<<<<<< * * return default */ __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__AdaptationFailure); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(((PyObject *)__pyx_t_4)); __Pyx_INCREF(((PyObject *)__pyx_kp_s_5)); PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_kp_s_5)); __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_5)); __Pyx_INCREF(__pyx_v_obj); PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_v_obj); __Pyx_GIVEREF(__pyx_v_obj); __Pyx_INCREF(__pyx_v_protocol); PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_protocol); __Pyx_GIVEREF(__pyx_v_protocol); __pyx_t_1 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0; __Pyx_Raise(__pyx_t_1, 0, 0); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;} goto __pyx_L48; } __pyx_L48:; /* "traits/protocols/_speedups.pyx":187 * raise AdaptationFailure("Can't adapt", obj, protocol) * * return default # <<<<<<<<<<<<<< * * */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_v_default); __pyx_r = __pyx_v_default; goto __pyx_L0; __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_6); __Pyx_XDECREF(__pyx_t_7); __Pyx_AddTraceback("traits.protocols._speedups._adapt"); __pyx_r = 0; __pyx_L0:; __Pyx_DECREF(__pyx_v_meth); __Pyx_DECREF(__pyx_v_result); __Pyx_DECREF(__pyx_v_e); __Pyx_DECREF(__pyx_v_warn); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "traits/protocols/_speedups.pyx":190 * * * def adapt(obj, protocol, default=_marker, factory=_marker): # <<<<<<<<<<<<<< * """PEP 246-alike: Adapt 'obj' to 'protocol', return 'default' * */ static PyObject *__pyx_pf_9enthought_6traits_9protocols_9_speedups_2adapt(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static char __pyx_doc_9enthought_6traits_9protocols_9_speedups_2adapt[] = "PEP 246-alike: Adapt 'obj' to 'protocol', return 'default'\n\n If 'default' is not supplied and no implementation is found,\n raise 'AdaptationFailure'."; static PyMethodDef __pyx_mdef_9enthought_6traits_9protocols_9_speedups_2adapt = {__Pyx_NAMESTR("adapt"), (PyCFunction)__pyx_pf_9enthought_6traits_9protocols_9_speedups_2adapt, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_9enthought_6traits_9protocols_9_speedups_2adapt)}; static PyObject *__pyx_pf_9enthought_6traits_9protocols_9_speedups_2adapt(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_obj = 0; PyObject *__pyx_v_protocol = 0; PyObject *__pyx_v_default = 0; PyObject *__pyx_v_factory = 0; PyObject *__pyx_r = NULL; PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__obj,&__pyx_n_s__protocol,&__pyx_n_s__default,&__pyx_n_s__factory,0}; __Pyx_RefNannySetupContext("adapt"); __pyx_self = __pyx_self; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args = PyDict_Size(__pyx_kwds); PyObject* values[4] = {0,0,0,0}; values[2] = __pyx_k_6; values[3] = __pyx_k_7; switch (PyTuple_GET_SIZE(__pyx_args)) { case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } switch (PyTuple_GET_SIZE(__pyx_args)) { case 0: values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__obj); if (likely(values[0])) kw_args--; else goto __pyx_L5_argtuple_error; case 1: values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__protocol); if (likely(values[1])) kw_args--; else { __Pyx_RaiseArgtupleInvalid("adapt", 0, 2, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 2: if (kw_args > 0) { PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__default); if (value) { values[2] = value; kw_args--; } } case 3: if (kw_args > 0) { PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__factory); if (value) { values[3] = value; kw_args--; } } } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "adapt") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } __pyx_v_obj = values[0]; __pyx_v_protocol = values[1]; __pyx_v_default = values[2]; __pyx_v_factory = values[3]; } else { __pyx_v_default = __pyx_k_6; __pyx_v_factory = __pyx_k_7; switch (PyTuple_GET_SIZE(__pyx_args)) { case 4: __pyx_v_factory = PyTuple_GET_ITEM(__pyx_args, 3); case 3: __pyx_v_default = PyTuple_GET_ITEM(__pyx_args, 2); case 2: __pyx_v_protocol = PyTuple_GET_ITEM(__pyx_args, 1); __pyx_v_obj = PyTuple_GET_ITEM(__pyx_args, 0); break; default: goto __pyx_L5_argtuple_error; } } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("adapt", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("traits.protocols._speedups.adapt"); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; /* "traits/protocols/_speedups.pyx":196 * raise 'AdaptationFailure'.""" * * return _adapt(obj,protocol,default,factory) # <<<<<<<<<<<<<< * * def Protocol__call__(self, ob, default=_marker): */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = __pyx_v_obj; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = __pyx_v_protocol; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = __pyx_v_default; __Pyx_INCREF(__pyx_t_3); __pyx_t_4 = __pyx_v_factory; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = __pyx_f_9enthought_6traits_9protocols_9_speedups__adapt(__pyx_t_1, __pyx_t_2, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_5); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_r = __pyx_t_5; __pyx_t_5 = 0; goto __pyx_L0; __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __Pyx_AddTraceback("traits.protocols._speedups.adapt"); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "traits/protocols/_speedups.pyx":198 * return _adapt(obj,protocol,default,factory) * * def Protocol__call__(self, ob, default=_marker): # <<<<<<<<<<<<<< * """Adapt to this protocol""" * return _adapt(ob,self,default,_marker) */ static PyObject *__pyx_pf_9enthought_6traits_9protocols_9_speedups_3Protocol__call__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static char __pyx_doc_9enthought_6traits_9protocols_9_speedups_3Protocol__call__[] = "Adapt to this protocol"; static PyMethodDef __pyx_mdef_9enthought_6traits_9protocols_9_speedups_3Protocol__call__ = {__Pyx_NAMESTR("Protocol__call__"), (PyCFunction)__pyx_pf_9enthought_6traits_9protocols_9_speedups_3Protocol__call__, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_9enthought_6traits_9protocols_9_speedups_3Protocol__call__)}; static PyObject *__pyx_pf_9enthought_6traits_9protocols_9_speedups_3Protocol__call__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_self = 0; PyObject *__pyx_v_ob = 0; PyObject *__pyx_v_default = 0; PyObject *__pyx_r = NULL; PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__self,&__pyx_n_s__ob,&__pyx_n_s__default,0}; __Pyx_RefNannySetupContext("Protocol__call__"); __pyx_self = __pyx_self; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args = PyDict_Size(__pyx_kwds); PyObject* values[3] = {0,0,0}; values[2] = __pyx_k_8; switch (PyTuple_GET_SIZE(__pyx_args)) { case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } switch (PyTuple_GET_SIZE(__pyx_args)) { case 0: values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__self); if (likely(values[0])) kw_args--; else goto __pyx_L5_argtuple_error; case 1: values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__ob); if (likely(values[1])) kw_args--; else { __Pyx_RaiseArgtupleInvalid("Protocol__call__", 0, 2, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 198; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 2: if (kw_args > 0) { PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__default); if (value) { values[2] = value; kw_args--; } } } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "Protocol__call__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 198; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } __pyx_v_self = values[0]; __pyx_v_ob = values[1]; __pyx_v_default = values[2]; } else { __pyx_v_default = __pyx_k_8; switch (PyTuple_GET_SIZE(__pyx_args)) { case 3: __pyx_v_default = PyTuple_GET_ITEM(__pyx_args, 2); case 2: __pyx_v_ob = PyTuple_GET_ITEM(__pyx_args, 1); __pyx_v_self = PyTuple_GET_ITEM(__pyx_args, 0); break; default: goto __pyx_L5_argtuple_error; } } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("Protocol__call__", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 198; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("traits.protocols._speedups.Protocol__call__"); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; /* "traits/protocols/_speedups.pyx":200 * def Protocol__call__(self, ob, default=_marker): * """Adapt to this protocol""" * return _adapt(ob,self,default,_marker) # <<<<<<<<<<<<<< * * */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = __pyx_v_ob; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = __pyx_v_self; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = __pyx_v_default; __Pyx_INCREF(__pyx_t_3); __pyx_t_4 = __pyx_v_9enthought_6traits_9protocols_9_speedups__marker; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = __pyx_f_9enthought_6traits_9protocols_9_speedups__adapt(__pyx_t_1, __pyx_t_2, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_5); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_r = __pyx_t_5; __pyx_t_5 = 0; goto __pyx_L0; __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __Pyx_AddTraceback("traits.protocols._speedups.Protocol__call__"); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "traits/protocols/_speedups.pyx":203 * * * cdef buildClassicMRO(PyClassObject *cls, PyListObject *list): # <<<<<<<<<<<<<< * * cdef PyTupleObject *bases */ static PyObject *__pyx_f_9enthought_6traits_9protocols_9_speedups_buildClassicMRO(PyClassObject *__pyx_v_cls, PyListObject *__pyx_v_list) { PyTupleObject *__pyx_v_bases; int __pyx_v_i; PyObject *__pyx_v_tmp; PyObject *__pyx_r = NULL; PyListObject *__pyx_t_1; PyObject *__pyx_t_2 = NULL; int __pyx_t_3; int __pyx_t_4; void *__pyx_t_5; __Pyx_RefNannySetupContext("buildClassicMRO"); __pyx_v_tmp = Py_None; __Pyx_INCREF(Py_None); /* "traits/protocols/_speedups.pyx":208 * cdef int i * * PyList_Append(list, cls) # <<<<<<<<<<<<<< * bases = cls.cl_bases * */ __pyx_t_1 = __pyx_v_list; __pyx_t_2 = ((PyObject *)__pyx_v_cls); __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = PyList_Append(__pyx_t_1, __pyx_t_2); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "traits/protocols/_speedups.pyx":209 * * PyList_Append(list, cls) * bases = cls.cl_bases # <<<<<<<<<<<<<< * * if bases: */ __pyx_v_bases = __pyx_v_cls->cl_bases; /* "traits/protocols/_speedups.pyx":211 * bases = cls.cl_bases * * if bases: # <<<<<<<<<<<<<< * for i from 0 <= i < PyTuple_GET_SIZE(bases): * tmp = PyTuple_GET_ITEM(bases, i) */ __pyx_t_4 = (__pyx_v_bases != 0); if (__pyx_t_4) { /* "traits/protocols/_speedups.pyx":212 * * if bases: * for i from 0 <= i < PyTuple_GET_SIZE(bases): # <<<<<<<<<<<<<< * tmp = PyTuple_GET_ITEM(bases, i) * buildClassicMRO(tmp, list) */ __pyx_t_3 = PyTuple_GET_SIZE(__pyx_v_bases); for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_3; __pyx_v_i++) { /* "traits/protocols/_speedups.pyx":213 * if bases: * for i from 0 <= i < PyTuple_GET_SIZE(bases): * tmp = PyTuple_GET_ITEM(bases, i) # <<<<<<<<<<<<<< * buildClassicMRO(tmp, list) * */ __pyx_t_5 = PyTuple_GET_ITEM(__pyx_v_bases, __pyx_v_i); __Pyx_INCREF(((PyObject *)__pyx_t_5)); __Pyx_DECREF(__pyx_v_tmp); __pyx_v_tmp = ((PyObject *)__pyx_t_5); /* "traits/protocols/_speedups.pyx":214 * for i from 0 <= i < PyTuple_GET_SIZE(bases): * tmp = PyTuple_GET_ITEM(bases, i) * buildClassicMRO(tmp, list) # <<<<<<<<<<<<<< * * */ __pyx_t_2 = __pyx_f_9enthought_6traits_9protocols_9_speedups_buildClassicMRO(((PyClassObject *)__pyx_v_tmp), __pyx_v_list); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 214; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; } goto __pyx_L3; } __pyx_L3:; __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("traits.protocols._speedups.buildClassicMRO"); __pyx_r = 0; __pyx_L0:; __Pyx_DECREF(__pyx_v_tmp); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "traits/protocols/_speedups.pyx":217 * * * def classicMRO(ob, extendedClassic=False): # <<<<<<<<<<<<<< * * if PyClass_Check(ob): */ static PyObject *__pyx_pf_9enthought_6traits_9protocols_9_speedups_4classicMRO(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static PyMethodDef __pyx_mdef_9enthought_6traits_9protocols_9_speedups_4classicMRO = {__Pyx_NAMESTR("classicMRO"), (PyCFunction)__pyx_pf_9enthought_6traits_9protocols_9_speedups_4classicMRO, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)}; static PyObject *__pyx_pf_9enthought_6traits_9protocols_9_speedups_4classicMRO(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_ob = 0; PyObject *__pyx_v_extendedClassic = 0; PyObject *__pyx_v_mro; PyObject *__pyx_r = NULL; PyObject *__pyx_t_1 = NULL; int __pyx_t_2; int __pyx_t_3; PyListObject *__pyx_t_4; PyTypeObject *__pyx_t_5; PyListObject *__pyx_t_6; PyTypeObject *__pyx_t_7; PyObject *__pyx_t_8 = NULL; static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__ob,&__pyx_n_s__extendedClassic,0}; __Pyx_RefNannySetupContext("classicMRO"); __pyx_self = __pyx_self; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args = PyDict_Size(__pyx_kwds); PyObject* values[2] = {0,0}; values[1] = __pyx_k_9; switch (PyTuple_GET_SIZE(__pyx_args)) { case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } switch (PyTuple_GET_SIZE(__pyx_args)) { case 0: values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__ob); if (likely(values[0])) kw_args--; else goto __pyx_L5_argtuple_error; case 1: if (kw_args > 0) { PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__extendedClassic); if (value) { values[1] = value; kw_args--; } } } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "classicMRO") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } __pyx_v_ob = values[0]; __pyx_v_extendedClassic = values[1]; } else { __pyx_v_extendedClassic = __pyx_k_9; switch (PyTuple_GET_SIZE(__pyx_args)) { case 2: __pyx_v_extendedClassic = PyTuple_GET_ITEM(__pyx_args, 1); case 1: __pyx_v_ob = PyTuple_GET_ITEM(__pyx_args, 0); break; default: goto __pyx_L5_argtuple_error; } } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("classicMRO", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("traits.protocols._speedups.classicMRO"); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; __pyx_v_mro = ((PyObject*)Py_None); __Pyx_INCREF(Py_None); /* "traits/protocols/_speedups.pyx":219 * def classicMRO(ob, extendedClassic=False): * * if PyClass_Check(ob): # <<<<<<<<<<<<<< * mro = [] * buildClassicMRO(ob, mro) */ __pyx_t_1 = __pyx_v_ob; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = PyClass_Check(__pyx_t_1); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; if (__pyx_t_2) { /* "traits/protocols/_speedups.pyx":220 * * if PyClass_Check(ob): * mro = [] # <<<<<<<<<<<<<< * buildClassicMRO(ob, mro) * if extendedClassic: */ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(((PyObject *)__pyx_t_1)); __Pyx_DECREF(((PyObject *)__pyx_v_mro)); __pyx_v_mro = __pyx_t_1; __pyx_t_1 = 0; /* "traits/protocols/_speedups.pyx":221 * if PyClass_Check(ob): * mro = [] * buildClassicMRO(ob, mro) # <<<<<<<<<<<<<< * if extendedClassic: * PyList_Append(mro, &PyInstance_Type) */ __pyx_t_1 = __pyx_f_9enthought_6traits_9protocols_9_speedups_buildClassicMRO(((PyClassObject *)__pyx_v_ob), ((PyListObject *)__pyx_v_mro)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 221; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "traits/protocols/_speedups.pyx":222 * mro = [] * buildClassicMRO(ob, mro) * if extendedClassic: # <<<<<<<<<<<<<< * PyList_Append(mro, &PyInstance_Type) * PyList_Append(mro, &PyBaseObject_Type) */ __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_extendedClassic); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;} if (__pyx_t_3) { /* "traits/protocols/_speedups.pyx":223 * buildClassicMRO(ob, mro) * if extendedClassic: * PyList_Append(mro, &PyInstance_Type) # <<<<<<<<<<<<<< * PyList_Append(mro, &PyBaseObject_Type) * return mro */ __pyx_t_4 = ((PyListObject *)__pyx_v_mro); __pyx_t_5 = (&PyInstance_Type); __pyx_t_1 = ((PyObject *)__pyx_t_5); __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = PyList_Append(__pyx_t_4, __pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "traits/protocols/_speedups.pyx":224 * if extendedClassic: * PyList_Append(mro, &PyInstance_Type) * PyList_Append(mro, &PyBaseObject_Type) # <<<<<<<<<<<<<< * return mro * */ __pyx_t_6 = ((PyListObject *)__pyx_v_mro); __pyx_t_7 = (&PyBaseObject_Type); __pyx_t_1 = ((PyObject *)__pyx_t_7); __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = PyList_Append(__pyx_t_6, __pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; goto __pyx_L7; } __pyx_L7:; /* "traits/protocols/_speedups.pyx":225 * PyList_Append(mro, &PyInstance_Type) * PyList_Append(mro, &PyBaseObject_Type) * return mro # <<<<<<<<<<<<<< * * raise TypeError("Not a classic class", ob) */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(((PyObject *)__pyx_v_mro)); __pyx_r = ((PyObject *)__pyx_v_mro); goto __pyx_L0; goto __pyx_L6; } __pyx_L6:; /* "traits/protocols/_speedups.pyx":227 * return mro * * raise TypeError("Not a classic class", ob) # <<<<<<<<<<<<<< * * */ __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(((PyObject *)__pyx_t_1)); __Pyx_INCREF(((PyObject *)__pyx_kp_s_10)); PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_kp_s_10)); __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_10)); __Pyx_INCREF(__pyx_v_ob); PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_ob); __Pyx_GIVEREF(__pyx_v_ob); __pyx_t_8 = PyObject_Call(__pyx_builtin_TypeError, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_8); __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0; __Pyx_Raise(__pyx_t_8, 0, 0); __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_8); __Pyx_AddTraceback("traits.protocols._speedups.classicMRO"); __pyx_r = NULL; __pyx_L0:; __Pyx_DECREF(__pyx_v_mro); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "traits/protocols/_speedups.pyx":244 * * * cdef buildECMRO(object cls, PyListObject *list): # <<<<<<<<<<<<<< * PyList_Append(list, cls) * for i in cls.__bases__: */ static PyObject *__pyx_f_9enthought_6traits_9protocols_9_speedups_buildECMRO(PyObject *__pyx_v_cls, PyListObject *__pyx_v_list) { PyObject *__pyx_v_i; PyObject *__pyx_r = NULL; PyListObject *__pyx_t_1; PyObject *__pyx_t_2 = NULL; int __pyx_t_3; Py_ssize_t __pyx_t_4; PyObject *__pyx_t_5 = NULL; __Pyx_RefNannySetupContext("buildECMRO"); __pyx_v_i = Py_None; __Pyx_INCREF(Py_None); /* "traits/protocols/_speedups.pyx":245 * * cdef buildECMRO(object cls, PyListObject *list): * PyList_Append(list, cls) # <<<<<<<<<<<<<< * for i in cls.__bases__: * buildECMRO(i, list) */ __pyx_t_1 = __pyx_v_list; __pyx_t_2 = __pyx_v_cls; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = PyList_Append(__pyx_t_1, __pyx_t_2); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 245; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "traits/protocols/_speedups.pyx":246 * cdef buildECMRO(object cls, PyListObject *list): * PyList_Append(list, cls) * for i in cls.__bases__: # <<<<<<<<<<<<<< * buildECMRO(i, list) * */ __pyx_t_2 = PyObject_GetAttr(__pyx_v_cls, __pyx_n_s____bases__); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 246; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); if (PyList_CheckExact(__pyx_t_2) || PyTuple_CheckExact(__pyx_t_2)) { __pyx_t_4 = 0; __pyx_t_5 = __pyx_t_2; __Pyx_INCREF(__pyx_t_5); } else { __pyx_t_4 = -1; __pyx_t_5 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 246; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_5); } __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; for (;;) { if (likely(PyList_CheckExact(__pyx_t_5))) { if (__pyx_t_4 >= PyList_GET_SIZE(__pyx_t_5)) break; __pyx_t_2 = PyList_GET_ITEM(__pyx_t_5, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; } else if (likely(PyTuple_CheckExact(__pyx_t_5))) { if (__pyx_t_4 >= PyTuple_GET_SIZE(__pyx_t_5)) break; __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_5, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; } else { __pyx_t_2 = PyIter_Next(__pyx_t_5); if (!__pyx_t_2) { if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 246; __pyx_clineno = __LINE__; goto __pyx_L1_error;} break; } __Pyx_GOTREF(__pyx_t_2); } __Pyx_DECREF(__pyx_v_i); __pyx_v_i = __pyx_t_2; __pyx_t_2 = 0; /* "traits/protocols/_speedups.pyx":247 * PyList_Append(list, cls) * for i in cls.__bases__: * buildECMRO(i, list) # <<<<<<<<<<<<<< * * */ __pyx_t_2 = __pyx_f_9enthought_6traits_9protocols_9_speedups_buildECMRO(__pyx_v_i, __pyx_v_list); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 247; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; } __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_5); __Pyx_AddTraceback("traits.protocols._speedups.buildECMRO"); __pyx_r = 0; __pyx_L0:; __Pyx_DECREF(__pyx_v_i); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "traits/protocols/_speedups.pyx":250 * * * def extClassMRO(ob, extendedClassic=False): # <<<<<<<<<<<<<< * mro = [] * buildECMRO(ob, mro) */ static PyObject *__pyx_pf_9enthought_6traits_9protocols_9_speedups_5extClassMRO(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static PyMethodDef __pyx_mdef_9enthought_6traits_9protocols_9_speedups_5extClassMRO = {__Pyx_NAMESTR("extClassMRO"), (PyCFunction)__pyx_pf_9enthought_6traits_9protocols_9_speedups_5extClassMRO, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)}; static PyObject *__pyx_pf_9enthought_6traits_9protocols_9_speedups_5extClassMRO(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_ob = 0; PyObject *__pyx_v_extendedClassic = 0; PyObject *__pyx_v_mro; PyObject *__pyx_r = NULL; PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; int __pyx_t_3; PyListObject *__pyx_t_4; PyTypeObject *__pyx_t_5; int __pyx_t_6; PyListObject *__pyx_t_7; PyTypeObject *__pyx_t_8; static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__ob,&__pyx_n_s__extendedClassic,0}; __Pyx_RefNannySetupContext("extClassMRO"); __pyx_self = __pyx_self; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args = PyDict_Size(__pyx_kwds); PyObject* values[2] = {0,0}; values[1] = __pyx_k_11; switch (PyTuple_GET_SIZE(__pyx_args)) { case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } switch (PyTuple_GET_SIZE(__pyx_args)) { case 0: values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__ob); if (likely(values[0])) kw_args--; else goto __pyx_L5_argtuple_error; case 1: if (kw_args > 0) { PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__extendedClassic); if (value) { values[1] = value; kw_args--; } } } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "extClassMRO") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } __pyx_v_ob = values[0]; __pyx_v_extendedClassic = values[1]; } else { __pyx_v_extendedClassic = __pyx_k_11; switch (PyTuple_GET_SIZE(__pyx_args)) { case 2: __pyx_v_extendedClassic = PyTuple_GET_ITEM(__pyx_args, 1); case 1: __pyx_v_ob = PyTuple_GET_ITEM(__pyx_args, 0); break; default: goto __pyx_L5_argtuple_error; } } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("extClassMRO", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("traits.protocols._speedups.extClassMRO"); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; __pyx_v_mro = ((PyObject*)Py_None); __Pyx_INCREF(Py_None); /* "traits/protocols/_speedups.pyx":251 * * def extClassMRO(ob, extendedClassic=False): * mro = [] # <<<<<<<<<<<<<< * buildECMRO(ob, mro) * if extendedClassic: */ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(((PyObject *)__pyx_t_1)); __Pyx_DECREF(((PyObject *)__pyx_v_mro)); __pyx_v_mro = __pyx_t_1; __pyx_t_1 = 0; /* "traits/protocols/_speedups.pyx":252 * def extClassMRO(ob, extendedClassic=False): * mro = [] * buildECMRO(ob, mro) # <<<<<<<<<<<<<< * if extendedClassic: * PyList_Append(mro, &PyInstance_Type) */ __pyx_t_1 = __pyx_v_ob; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = __pyx_f_9enthought_6traits_9protocols_9_speedups_buildECMRO(__pyx_t_1, ((PyListObject *)__pyx_v_mro)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "traits/protocols/_speedups.pyx":253 * mro = [] * buildECMRO(ob, mro) * if extendedClassic: # <<<<<<<<<<<<<< * PyList_Append(mro, &PyInstance_Type) * PyList_Append(mro, &PyBaseObject_Type) */ __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_extendedClassic); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; __pyx_clineno = __LINE__; goto __pyx_L1_error;} if (__pyx_t_3) { /* "traits/protocols/_speedups.pyx":254 * buildECMRO(ob, mro) * if extendedClassic: * PyList_Append(mro, &PyInstance_Type) # <<<<<<<<<<<<<< * PyList_Append(mro, &PyBaseObject_Type) * return mro */ __pyx_t_4 = ((PyListObject *)__pyx_v_mro); __pyx_t_5 = (&PyInstance_Type); __pyx_t_2 = ((PyObject *)__pyx_t_5); __Pyx_INCREF(__pyx_t_2); __pyx_t_6 = PyList_Append(__pyx_t_4, __pyx_t_2); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 254; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "traits/protocols/_speedups.pyx":255 * if extendedClassic: * PyList_Append(mro, &PyInstance_Type) * PyList_Append(mro, &PyBaseObject_Type) # <<<<<<<<<<<<<< * return mro * */ __pyx_t_7 = ((PyListObject *)__pyx_v_mro); __pyx_t_8 = (&PyBaseObject_Type); __pyx_t_2 = ((PyObject *)__pyx_t_8); __Pyx_INCREF(__pyx_t_2); __pyx_t_6 = PyList_Append(__pyx_t_7, __pyx_t_2); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; goto __pyx_L6; } __pyx_L6:; /* "traits/protocols/_speedups.pyx":256 * PyList_Append(mro, &PyInstance_Type) * PyList_Append(mro, &PyBaseObject_Type) * return mro # <<<<<<<<<<<<<< * * */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(((PyObject *)__pyx_v_mro)); __pyx_r = ((PyObject *)__pyx_v_mro); goto __pyx_L0; __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("traits.protocols._speedups.extClassMRO"); __pyx_r = NULL; __pyx_L0:; __Pyx_DECREF(__pyx_v_mro); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "traits/protocols/_speedups.pyx":260 * * * def getMRO(ob, extendedClassic=False): # <<<<<<<<<<<<<< * * if PyClass_Check(ob): */ static PyObject *__pyx_pf_9enthought_6traits_9protocols_9_speedups_6getMRO(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static PyMethodDef __pyx_mdef_9enthought_6traits_9protocols_9_speedups_6getMRO = {__Pyx_NAMESTR("getMRO"), (PyCFunction)__pyx_pf_9enthought_6traits_9protocols_9_speedups_6getMRO, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)}; static PyObject *__pyx_pf_9enthought_6traits_9protocols_9_speedups_6getMRO(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_ob = 0; PyObject *__pyx_v_extendedClassic = 0; PyObject *__pyx_r = NULL; PyObject *__pyx_t_1 = NULL; int __pyx_t_2; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__ob,&__pyx_n_s__extendedClassic,0}; __Pyx_RefNannySetupContext("getMRO"); __pyx_self = __pyx_self; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args = PyDict_Size(__pyx_kwds); PyObject* values[2] = {0,0}; values[1] = __pyx_k_12; switch (PyTuple_GET_SIZE(__pyx_args)) { case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } switch (PyTuple_GET_SIZE(__pyx_args)) { case 0: values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__ob); if (likely(values[0])) kw_args--; else goto __pyx_L5_argtuple_error; case 1: if (kw_args > 0) { PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__extendedClassic); if (value) { values[1] = value; kw_args--; } } } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "getMRO") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } __pyx_v_ob = values[0]; __pyx_v_extendedClassic = values[1]; } else { __pyx_v_extendedClassic = __pyx_k_12; switch (PyTuple_GET_SIZE(__pyx_args)) { case 2: __pyx_v_extendedClassic = PyTuple_GET_ITEM(__pyx_args, 1); case 1: __pyx_v_ob = PyTuple_GET_ITEM(__pyx_args, 0); break; default: goto __pyx_L5_argtuple_error; } } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("getMRO", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("traits.protocols._speedups.getMRO"); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; /* "traits/protocols/_speedups.pyx":262 * def getMRO(ob, extendedClassic=False): * * if PyClass_Check(ob): # <<<<<<<<<<<<<< * return classicMRO(ob,extendedClassic) * */ __pyx_t_1 = __pyx_v_ob; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = PyClass_Check(__pyx_t_1); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; if (__pyx_t_2) { /* "traits/protocols/_speedups.pyx":263 * * if PyClass_Check(ob): * return classicMRO(ob,extendedClassic) # <<<<<<<<<<<<<< * * elif PyType_Check(ob): */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__classicMRO); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(((PyObject *)__pyx_t_3)); __Pyx_INCREF(__pyx_v_ob); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_ob); __Pyx_GIVEREF(__pyx_v_ob); __Pyx_INCREF(__pyx_v_extendedClassic); PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_extendedClassic); __Pyx_GIVEREF(__pyx_v_extendedClassic); __pyx_t_4 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0; __pyx_r = __pyx_t_4; __pyx_t_4 = 0; goto __pyx_L0; goto __pyx_L6; } /* "traits/protocols/_speedups.pyx":265 * return classicMRO(ob,extendedClassic) * * elif PyType_Check(ob): # <<<<<<<<<<<<<< * return ob.__mro__ * */ __pyx_t_4 = __pyx_v_ob; __Pyx_INCREF(__pyx_t_4); __pyx_t_2 = PyType_Check(__pyx_t_4); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; if (__pyx_t_2) { /* "traits/protocols/_speedups.pyx":266 * * elif PyType_Check(ob): * return ob.__mro__ # <<<<<<<<<<<<<< * * elif PyObject_TypeCheck(ob,__ECType): */ __Pyx_XDECREF(__pyx_r); __pyx_t_4 = PyObject_GetAttr(__pyx_v_ob, __pyx_n_s____mro__); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 266; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __pyx_r = __pyx_t_4; __pyx_t_4 = 0; goto __pyx_L0; goto __pyx_L6; } /* "traits/protocols/_speedups.pyx":268 * return ob.__mro__ * * elif PyObject_TypeCheck(ob,__ECType): # <<<<<<<<<<<<<< * return extClassMRO(ob, extendedClassic) * */ __pyx_t_4 = __pyx_v_ob; __Pyx_INCREF(__pyx_t_4); __pyx_t_3 = __pyx_v_9enthought_6traits_9protocols_9_speedups___ECType; __Pyx_INCREF(__pyx_t_3); __pyx_t_2 = PyObject_TypeCheck(__pyx_t_4, __pyx_t_3); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; if (__pyx_t_2) { /* "traits/protocols/_speedups.pyx":269 * * elif PyObject_TypeCheck(ob,__ECType): * return extClassMRO(ob, extendedClassic) # <<<<<<<<<<<<<< * * return ob, */ __Pyx_XDECREF(__pyx_r); __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s__extClassMRO); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(((PyObject *)__pyx_t_4)); __Pyx_INCREF(__pyx_v_ob); PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_ob); __Pyx_GIVEREF(__pyx_v_ob); __Pyx_INCREF(__pyx_v_extendedClassic); PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_v_extendedClassic); __Pyx_GIVEREF(__pyx_v_extendedClassic); __pyx_t_1 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0; __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; goto __pyx_L6; } __pyx_L6:; /* "traits/protocols/_speedups.pyx":271 * return extClassMRO(ob, extendedClassic) * * return ob, # <<<<<<<<<<<<<< * * */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(((PyObject *)__pyx_t_1)); __Pyx_INCREF(__pyx_v_ob); PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_ob); __Pyx_GIVEREF(__pyx_v_ob); __pyx_r = ((PyObject *)__pyx_t_1); __pyx_t_1 = 0; goto __pyx_L0; __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_AddTraceback("traits.protocols._speedups.getMRO"); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "traits/protocols/_speedups.pyx":285 * * * def Protocol__adapt__(self, obj): # <<<<<<<<<<<<<< * * cdef void *tmp */ static PyObject *__pyx_pf_9enthought_6traits_9protocols_9_speedups_7Protocol__adapt__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static PyMethodDef __pyx_mdef_9enthought_6traits_9protocols_9_speedups_7Protocol__adapt__ = {__Pyx_NAMESTR("Protocol__adapt__"), (PyCFunction)__pyx_pf_9enthought_6traits_9protocols_9_speedups_7Protocol__adapt__, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)}; static PyObject *__pyx_pf_9enthought_6traits_9protocols_9_speedups_7Protocol__adapt__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_self = 0; PyObject *__pyx_v_obj = 0; void *__pyx_v_tmp; int __pyx_v_i; PyObject *__pyx_v_cls; PyObject *__pyx_v_mro; PyObject *__pyx_v_get; PyObject *__pyx_v_factory; PyObject *__pyx_r = NULL; PyObject *__pyx_t_1 = NULL; int __pyx_t_2; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; int __pyx_t_5; PyListObject *__pyx_t_6; PyTypeObject *__pyx_t_7; PyListObject *__pyx_t_8; PyTypeObject *__pyx_t_9; PyObject *__pyx_t_10 = NULL; PyObject *__pyx_t_11 = NULL; PyObject *__pyx_t_12 = NULL; void *__pyx_t_13; void *__pyx_t_14; Py_ssize_t __pyx_t_15; static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__self,&__pyx_n_s__obj,0}; __Pyx_RefNannySetupContext("Protocol__adapt__"); __pyx_self = __pyx_self; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args = PyDict_Size(__pyx_kwds); PyObject* values[2] = {0,0}; switch (PyTuple_GET_SIZE(__pyx_args)) { case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } switch (PyTuple_GET_SIZE(__pyx_args)) { case 0: values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__self); if (likely(values[0])) kw_args--; else goto __pyx_L5_argtuple_error; case 1: values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__obj); if (likely(values[1])) kw_args--; else { __Pyx_RaiseArgtupleInvalid("Protocol__adapt__", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "Protocol__adapt__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } __pyx_v_self = values[0]; __pyx_v_obj = values[1]; } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { goto __pyx_L5_argtuple_error; } else { __pyx_v_self = PyTuple_GET_ITEM(__pyx_args, 0); __pyx_v_obj = PyTuple_GET_ITEM(__pyx_args, 1); } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("Protocol__adapt__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("traits.protocols._speedups.Protocol__adapt__"); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; __pyx_v_cls = Py_None; __Pyx_INCREF(Py_None); __pyx_v_mro = Py_None; __Pyx_INCREF(Py_None); __pyx_v_get = Py_None; __Pyx_INCREF(Py_None); __pyx_v_factory = Py_None; __Pyx_INCREF(Py_None); /* "traits/protocols/_speedups.pyx":290 * cdef int i * * if PyInstance_Check(obj): # <<<<<<<<<<<<<< * cls = ((obj).in_class) * else: */ __pyx_t_1 = __pyx_v_obj; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = PyInstance_Check(__pyx_t_1); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; if (__pyx_t_2) { /* "traits/protocols/_speedups.pyx":291 * * if PyInstance_Check(obj): * cls = ((obj).in_class) # <<<<<<<<<<<<<< * else: * # We use __class__ instead of type to support proxies */ __Pyx_INCREF(((PyObject *)((PyInstanceObject *)__pyx_v_obj)->in_class)); __Pyx_DECREF(__pyx_v_cls); __pyx_v_cls = ((PyObject *)((PyInstanceObject *)__pyx_v_obj)->in_class); goto __pyx_L6; } /*else*/ { /* "traits/protocols/_speedups.pyx":294 * else: * # We use __class__ instead of type to support proxies * try: # <<<<<<<<<<<<<< * cls = getattr(obj, __class) * except AttributeError: */ { PyObject *__pyx_save_exc_type, *__pyx_save_exc_value, *__pyx_save_exc_tb; __Pyx_ExceptionSave(&__pyx_save_exc_type, &__pyx_save_exc_value, &__pyx_save_exc_tb); __Pyx_XGOTREF(__pyx_save_exc_type); __Pyx_XGOTREF(__pyx_save_exc_value); __Pyx_XGOTREF(__pyx_save_exc_tb); /*try:*/ { /* "traits/protocols/_speedups.pyx":295 * # We use __class__ instead of type to support proxies * try: * cls = getattr(obj, __class) # <<<<<<<<<<<<<< * except AttributeError: * # Some object have no __class__; use their type */ __pyx_t_1 = __pyx_v_obj; __Pyx_INCREF(__pyx_t_1); __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s____class); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 295; __pyx_clineno = __LINE__; goto __pyx_L7_error;} __Pyx_GOTREF(__pyx_t_3); __pyx_t_4 = PyObject_GetAttr(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 295; __pyx_clineno = __LINE__; goto __pyx_L7_error;} __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_v_cls); __pyx_v_cls = __pyx_t_4; __pyx_t_4 = 0; } __Pyx_XDECREF(__pyx_save_exc_type); __pyx_save_exc_type = 0; __Pyx_XDECREF(__pyx_save_exc_value); __pyx_save_exc_value = 0; __Pyx_XDECREF(__pyx_save_exc_tb); __pyx_save_exc_tb = 0; goto __pyx_L14_try_end; __pyx_L7_error:; __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; /* "traits/protocols/_speedups.pyx":296 * try: * cls = getattr(obj, __class) * except AttributeError: # <<<<<<<<<<<<<< * # Some object have no __class__; use their type * cls = (obj).ob_type */ __pyx_t_2 = PyErr_ExceptionMatches(__pyx_builtin_AttributeError); if (__pyx_t_2) { __Pyx_AddTraceback("traits.protocols._speedups.Protocol__adapt__"); if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_3, &__pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; __pyx_clineno = __LINE__; goto __pyx_L9_except_error;} __Pyx_GOTREF(__pyx_t_4); __Pyx_GOTREF(__pyx_t_3); __Pyx_GOTREF(__pyx_t_1); /* "traits/protocols/_speedups.pyx":298 * except AttributeError: * # Some object have no __class__; use their type * cls = (obj).ob_type # <<<<<<<<<<<<<< * * mro = None */ __Pyx_INCREF(((PyObject *)((PyObject *)__pyx_v_obj)->ob_type)); __Pyx_DECREF(__pyx_v_cls); __pyx_v_cls = ((PyObject *)((PyObject *)__pyx_v_obj)->ob_type); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; goto __pyx_L8_exception_handled; } __pyx_L9_except_error:; __Pyx_XGIVEREF(__pyx_save_exc_type); __Pyx_XGIVEREF(__pyx_save_exc_value); __Pyx_XGIVEREF(__pyx_save_exc_tb); __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb); goto __pyx_L1_error; __pyx_L8_exception_handled:; __Pyx_XGIVEREF(__pyx_save_exc_type); __Pyx_XGIVEREF(__pyx_save_exc_value); __Pyx_XGIVEREF(__pyx_save_exc_tb); __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb); __pyx_L14_try_end:; } } __pyx_L6:; /* "traits/protocols/_speedups.pyx":300 * cls = (obj).ob_type * * mro = None # <<<<<<<<<<<<<< * if PyType_Check(cls): * # It's a type, we can use its mro directly */ __Pyx_INCREF(Py_None); __Pyx_DECREF(__pyx_v_mro); __pyx_v_mro = Py_None; /* "traits/protocols/_speedups.pyx":301 * * mro = None * if PyType_Check(cls): # <<<<<<<<<<<<<< * # It's a type, we can use its mro directly * tmp = ((cls).tp_mro) */ __pyx_t_2 = PyType_Check(__pyx_v_cls); if (__pyx_t_2) { /* "traits/protocols/_speedups.pyx":303 * if PyType_Check(cls): * # It's a type, we can use its mro directly * tmp = ((cls).tp_mro) # <<<<<<<<<<<<<< * if tmp != NULL: * mro = tmp */ __pyx_v_tmp = ((void *)((PyTypeObject *)__pyx_v_cls)->tp_mro); /* "traits/protocols/_speedups.pyx":304 * # It's a type, we can use its mro directly * tmp = ((cls).tp_mro) * if tmp != NULL: # <<<<<<<<<<<<<< * mro = tmp * */ __pyx_t_5 = (__pyx_v_tmp != NULL); if (__pyx_t_5) { /* "traits/protocols/_speedups.pyx":305 * tmp = ((cls).tp_mro) * if tmp != NULL: * mro = tmp # <<<<<<<<<<<<<< * * if mro is None: */ __Pyx_INCREF(((PyObject *)__pyx_v_tmp)); __Pyx_DECREF(__pyx_v_mro); __pyx_v_mro = ((PyObject *)__pyx_v_tmp); goto __pyx_L18; } __pyx_L18:; goto __pyx_L17; } __pyx_L17:; /* "traits/protocols/_speedups.pyx":307 * mro = tmp * * if mro is None: # <<<<<<<<<<<<<< * if PyClass_Check(cls): * # It's a classic class, build up its MRO */ __pyx_t_5 = (__pyx_v_mro == Py_None); if (__pyx_t_5) { /* "traits/protocols/_speedups.pyx":308 * * if mro is None: * if PyClass_Check(cls): # <<<<<<<<<<<<<< * # It's a classic class, build up its MRO * mro = [] */ __pyx_t_2 = PyClass_Check(__pyx_v_cls); if (__pyx_t_2) { /* "traits/protocols/_speedups.pyx":310 * if PyClass_Check(cls): * # It's a classic class, build up its MRO * mro = [] # <<<<<<<<<<<<<< * buildClassicMRO(cls, mro) * PyList_Append(mro, &PyInstance_Type) */ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 310; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(((PyObject *)__pyx_t_1)); __Pyx_DECREF(__pyx_v_mro); __pyx_v_mro = ((PyObject *)__pyx_t_1); __pyx_t_1 = 0; /* "traits/protocols/_speedups.pyx":311 * # It's a classic class, build up its MRO * mro = [] * buildClassicMRO(cls, mro) # <<<<<<<<<<<<<< * PyList_Append(mro, &PyInstance_Type) * PyList_Append(mro, &PyBaseObject_Type) */ __pyx_t_1 = __pyx_f_9enthought_6traits_9protocols_9_speedups_buildClassicMRO(((PyClassObject *)__pyx_v_cls), ((PyListObject *)__pyx_v_mro)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "traits/protocols/_speedups.pyx":312 * mro = [] * buildClassicMRO(cls, mro) * PyList_Append(mro, &PyInstance_Type) # <<<<<<<<<<<<<< * PyList_Append(mro, &PyBaseObject_Type) * */ __pyx_t_6 = ((PyListObject *)__pyx_v_mro); __pyx_t_7 = (&PyInstance_Type); __pyx_t_1 = ((PyObject *)__pyx_t_7); __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = PyList_Append(__pyx_t_6, __pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 312; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "traits/protocols/_speedups.pyx":313 * buildClassicMRO(cls, mro) * PyList_Append(mro, &PyInstance_Type) * PyList_Append(mro, &PyBaseObject_Type) # <<<<<<<<<<<<<< * * else: */ __pyx_t_8 = ((PyListObject *)__pyx_v_mro); __pyx_t_9 = (&PyBaseObject_Type); __pyx_t_1 = ((PyObject *)__pyx_t_9); __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = PyList_Append(__pyx_t_8, __pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 313; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; goto __pyx_L20; } /*else*/ { /* "traits/protocols/_speedups.pyx":317 * else: * # Fallback to getting __mro__ (for e.g. security proxies/ExtensionClass) * try: # <<<<<<<<<<<<<< * mro = getattr(cls, __mro) * except Exception: */ { PyObject *__pyx_save_exc_type, *__pyx_save_exc_value, *__pyx_save_exc_tb; __Pyx_ExceptionSave(&__pyx_save_exc_type, &__pyx_save_exc_value, &__pyx_save_exc_tb); __Pyx_XGOTREF(__pyx_save_exc_type); __Pyx_XGOTREF(__pyx_save_exc_value); __Pyx_XGOTREF(__pyx_save_exc_tb); /*try:*/ { /* "traits/protocols/_speedups.pyx":318 * # Fallback to getting __mro__ (for e.g. security proxies/ExtensionClass) * try: * mro = getattr(cls, __mro) # <<<<<<<<<<<<<< * except Exception: * # No __mro__? Is it an ExtensionClass? */ __pyx_t_1 = __pyx_v_9enthought_6traits_9protocols_9_speedups___mro; __Pyx_INCREF(__pyx_t_1); __pyx_t_3 = PyObject_GetAttr(__pyx_v_cls, __pyx_t_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L21_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_v_mro); __pyx_v_mro = __pyx_t_3; __pyx_t_3 = 0; } __Pyx_XDECREF(__pyx_save_exc_type); __pyx_save_exc_type = 0; __Pyx_XDECREF(__pyx_save_exc_value); __pyx_save_exc_value = 0; __Pyx_XDECREF(__pyx_save_exc_tb); __pyx_save_exc_tb = 0; goto __pyx_L28_try_end; __pyx_L21_error:; __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; /* "traits/protocols/_speedups.pyx":319 * try: * mro = getattr(cls, __mro) * except Exception: # <<<<<<<<<<<<<< * # No __mro__? Is it an ExtensionClass? * if PyObject_TypeCheck(cls,__ECType): */ __pyx_t_2 = PyErr_ExceptionMatches(__pyx_builtin_Exception); if (__pyx_t_2) { __Pyx_AddTraceback("traits.protocols._speedups.Protocol__adapt__"); if (__Pyx_GetException(&__pyx_t_3, &__pyx_t_1, &__pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 319; __pyx_clineno = __LINE__; goto __pyx_L23_except_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_GOTREF(__pyx_t_1); __Pyx_GOTREF(__pyx_t_4); /* "traits/protocols/_speedups.pyx":321 * except Exception: * # No __mro__? Is it an ExtensionClass? * if PyObject_TypeCheck(cls,__ECType): # <<<<<<<<<<<<<< * # Yep, toss out the error and compute a reasonable MRO * mro = extClassMRO(cls, 1) */ __pyx_t_10 = __pyx_v_9enthought_6traits_9protocols_9_speedups___ECType; __Pyx_INCREF(__pyx_t_10); __pyx_t_2 = PyObject_TypeCheck(__pyx_v_cls, __pyx_t_10); __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; if (__pyx_t_2) { /* "traits/protocols/_speedups.pyx":323 * if PyObject_TypeCheck(cls,__ECType): * # Yep, toss out the error and compute a reasonable MRO * mro = extClassMRO(cls, 1) # <<<<<<<<<<<<<< * else: * raise */ __pyx_t_10 = __Pyx_GetName(__pyx_m, __pyx_n_s__extClassMRO); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L23_except_error;} __Pyx_GOTREF(__pyx_t_10); __pyx_t_11 = PyTuple_New(2); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L23_except_error;} __Pyx_GOTREF(((PyObject *)__pyx_t_11)); __Pyx_INCREF(__pyx_v_cls); PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_v_cls); __Pyx_GIVEREF(__pyx_v_cls); __Pyx_INCREF(__pyx_int_1); PyTuple_SET_ITEM(__pyx_t_11, 1, __pyx_int_1); __Pyx_GIVEREF(__pyx_int_1); __pyx_t_12 = PyObject_Call(__pyx_t_10, ((PyObject *)__pyx_t_11), NULL); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L23_except_error;} __Pyx_GOTREF(__pyx_t_12); __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; __Pyx_DECREF(((PyObject *)__pyx_t_11)); __pyx_t_11 = 0; __Pyx_DECREF(__pyx_v_mro); __pyx_v_mro = __pyx_t_12; __pyx_t_12 = 0; goto __pyx_L31; } /*else*/ { /* "traits/protocols/_speedups.pyx":325 * mro = extClassMRO(cls, 1) * else: * raise # <<<<<<<<<<<<<< * * */ __Pyx_GIVEREF(__pyx_t_3); __Pyx_GIVEREF(__pyx_t_1); __Pyx_GIVEREF(__pyx_t_4); __Pyx_ErrRestore(__pyx_t_3, __pyx_t_1, __pyx_t_4); __pyx_t_3 = 0; __pyx_t_1 = 0; __pyx_t_4 = 0; {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L23_except_error;} } __pyx_L31:; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; goto __pyx_L22_exception_handled; } __pyx_L23_except_error:; __Pyx_XGIVEREF(__pyx_save_exc_type); __Pyx_XGIVEREF(__pyx_save_exc_value); __Pyx_XGIVEREF(__pyx_save_exc_tb); __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb); goto __pyx_L1_error; __pyx_L22_exception_handled:; __Pyx_XGIVEREF(__pyx_save_exc_type); __Pyx_XGIVEREF(__pyx_save_exc_value); __Pyx_XGIVEREF(__pyx_save_exc_tb); __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb); __pyx_L28_try_end:; } } __pyx_L20:; goto __pyx_L19; } __pyx_L19:; /* "traits/protocols/_speedups.pyx":336 * * * get = self._Protocol__adapters.get # <<<<<<<<<<<<<< * * if PyTuple_Check(mro): */ __pyx_t_4 = PyObject_GetAttr(__pyx_v_self, __pyx_n_s___Protocol__adapters); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 336; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __pyx_t_1 = PyObject_GetAttr(__pyx_t_4, __pyx_n_s__get); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 336; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF(__pyx_v_get); __pyx_v_get = __pyx_t_1; __pyx_t_1 = 0; /* "traits/protocols/_speedups.pyx":338 * get = self._Protocol__adapters.get * * if PyTuple_Check(mro): # <<<<<<<<<<<<<< * #print "tuple",mro * for i from 0 <= i < PyTuple_GET_SIZE(mro): */ __pyx_t_2 = PyTuple_Check(__pyx_v_mro); if (__pyx_t_2) { /* "traits/protocols/_speedups.pyx":340 * if PyTuple_Check(mro): * #print "tuple",mro * for i from 0 <= i < PyTuple_GET_SIZE(mro): # <<<<<<<<<<<<<< * cls = PyTuple_GET_ITEM(mro, i) * factory=get(cls) */ __pyx_t_2 = PyTuple_GET_SIZE(((PyTupleObject *)__pyx_v_mro)); for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_2; __pyx_v_i++) { /* "traits/protocols/_speedups.pyx":341 * #print "tuple",mro * for i from 0 <= i < PyTuple_GET_SIZE(mro): * cls = PyTuple_GET_ITEM(mro, i) # <<<<<<<<<<<<<< * factory=get(cls) * if factory is not None: */ __pyx_t_13 = PyTuple_GET_ITEM(((PyTupleObject *)__pyx_v_mro), __pyx_v_i); __Pyx_INCREF(((PyObject *)__pyx_t_13)); __Pyx_DECREF(__pyx_v_cls); __pyx_v_cls = ((PyObject *)__pyx_t_13); /* "traits/protocols/_speedups.pyx":342 * for i from 0 <= i < PyTuple_GET_SIZE(mro): * cls = PyTuple_GET_ITEM(mro, i) * factory=get(cls) # <<<<<<<<<<<<<< * if factory is not None: * return factory[0](obj) */ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 342; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(((PyObject *)__pyx_t_1)); __Pyx_INCREF(__pyx_v_cls); PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_cls); __Pyx_GIVEREF(__pyx_v_cls); __pyx_t_4 = PyObject_Call(__pyx_v_get, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 342; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_v_factory); __pyx_v_factory = __pyx_t_4; __pyx_t_4 = 0; /* "traits/protocols/_speedups.pyx":343 * cls = PyTuple_GET_ITEM(mro, i) * factory=get(cls) * if factory is not None: # <<<<<<<<<<<<<< * return factory[0](obj) * */ __pyx_t_5 = (__pyx_v_factory != Py_None); if (__pyx_t_5) { /* "traits/protocols/_speedups.pyx":344 * factory=get(cls) * if factory is not None: * return factory[0](obj) # <<<<<<<<<<<<<< * * elif PyList_Check(mro): */ __Pyx_XDECREF(__pyx_r); __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_factory, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 344; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 344; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(((PyObject *)__pyx_t_1)); __Pyx_INCREF(__pyx_v_obj); PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_obj); __Pyx_GIVEREF(__pyx_v_obj); __pyx_t_3 = PyObject_Call(__pyx_t_4, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 344; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0; __pyx_r = __pyx_t_3; __pyx_t_3 = 0; goto __pyx_L0; goto __pyx_L35; } __pyx_L35:; } goto __pyx_L32; } /* "traits/protocols/_speedups.pyx":346 * return factory[0](obj) * * elif PyList_Check(mro): # <<<<<<<<<<<<<< * #print "list",mro * for i from 0 <= i < PyList_GET_SIZE(mro): */ __pyx_t_2 = PyList_Check(__pyx_v_mro); if (__pyx_t_2) { /* "traits/protocols/_speedups.pyx":348 * elif PyList_Check(mro): * #print "list",mro * for i from 0 <= i < PyList_GET_SIZE(mro): # <<<<<<<<<<<<<< * cls = PyList_GET_ITEM(mro, i) * factory=get(cls) */ __pyx_t_2 = PyList_GET_SIZE(((PyListObject *)__pyx_v_mro)); for (__pyx_v_i = 0; __pyx_v_i < __pyx_t_2; __pyx_v_i++) { /* "traits/protocols/_speedups.pyx":349 * #print "list",mro * for i from 0 <= i < PyList_GET_SIZE(mro): * cls = PyList_GET_ITEM(mro, i) # <<<<<<<<<<<<<< * factory=get(cls) * if factory is not None: */ __pyx_t_14 = PyList_GET_ITEM(((PyListObject *)__pyx_v_mro), __pyx_v_i); __Pyx_INCREF(((PyObject *)__pyx_t_14)); __Pyx_DECREF(__pyx_v_cls); __pyx_v_cls = ((PyObject *)__pyx_t_14); /* "traits/protocols/_speedups.pyx":350 * for i from 0 <= i < PyList_GET_SIZE(mro): * cls = PyList_GET_ITEM(mro, i) * factory=get(cls) # <<<<<<<<<<<<<< * if factory is not None: * return factory[0](obj) */ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(((PyObject *)__pyx_t_3)); __Pyx_INCREF(__pyx_v_cls); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_cls); __Pyx_GIVEREF(__pyx_v_cls); __pyx_t_1 = PyObject_Call(__pyx_v_get, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_v_factory); __pyx_v_factory = __pyx_t_1; __pyx_t_1 = 0; /* "traits/protocols/_speedups.pyx":351 * cls = PyList_GET_ITEM(mro, i) * factory=get(cls) * if factory is not None: # <<<<<<<<<<<<<< * return factory[0](obj) * */ __pyx_t_5 = (__pyx_v_factory != Py_None); if (__pyx_t_5) { /* "traits/protocols/_speedups.pyx":352 * factory=get(cls) * if factory is not None: * return factory[0](obj) # <<<<<<<<<<<<<< * * else: */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_factory, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(((PyObject *)__pyx_t_3)); __Pyx_INCREF(__pyx_v_obj); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_obj); __Pyx_GIVEREF(__pyx_v_obj); __pyx_t_4 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0; __pyx_r = __pyx_t_4; __pyx_t_4 = 0; goto __pyx_L0; goto __pyx_L38; } __pyx_L38:; } goto __pyx_L32; } /*else*/ { /* "traits/protocols/_speedups.pyx":357 * #print "other",mro * * for cls in mro: # <<<<<<<<<<<<<< * factory=get(cls) * if factory is not None: */ if (PyList_CheckExact(__pyx_v_mro) || PyTuple_CheckExact(__pyx_v_mro)) { __pyx_t_15 = 0; __pyx_t_4 = __pyx_v_mro; __Pyx_INCREF(__pyx_t_4); } else { __pyx_t_15 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_v_mro); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_4); } for (;;) { if (likely(PyList_CheckExact(__pyx_t_4))) { if (__pyx_t_15 >= PyList_GET_SIZE(__pyx_t_4)) break; __pyx_t_3 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_15); __Pyx_INCREF(__pyx_t_3); __pyx_t_15++; } else if (likely(PyTuple_CheckExact(__pyx_t_4))) { if (__pyx_t_15 >= PyTuple_GET_SIZE(__pyx_t_4)) break; __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_15); __Pyx_INCREF(__pyx_t_3); __pyx_t_15++; } else { __pyx_t_3 = PyIter_Next(__pyx_t_4); if (!__pyx_t_3) { if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;} break; } __Pyx_GOTREF(__pyx_t_3); } __Pyx_DECREF(__pyx_v_cls); __pyx_v_cls = __pyx_t_3; __pyx_t_3 = 0; /* "traits/protocols/_speedups.pyx":358 * * for cls in mro: * factory=get(cls) # <<<<<<<<<<<<<< * if factory is not None: * return factory[0](obj) */ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 358; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(((PyObject *)__pyx_t_3)); __Pyx_INCREF(__pyx_v_cls); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_cls); __Pyx_GIVEREF(__pyx_v_cls); __pyx_t_1 = PyObject_Call(__pyx_v_get, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 358; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_v_factory); __pyx_v_factory = __pyx_t_1; __pyx_t_1 = 0; /* "traits/protocols/_speedups.pyx":359 * for cls in mro: * factory=get(cls) * if factory is not None: # <<<<<<<<<<<<<< * return factory[0](obj) * */ __pyx_t_5 = (__pyx_v_factory != Py_None); if (__pyx_t_5) { /* "traits/protocols/_speedups.pyx":360 * factory=get(cls) * if factory is not None: * return factory[0](obj) # <<<<<<<<<<<<<< * * */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_factory, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(((PyObject *)__pyx_t_3)); __Pyx_INCREF(__pyx_v_obj); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_obj); __Pyx_GIVEREF(__pyx_v_obj); __pyx_t_12 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_12); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0; __pyx_r = __pyx_t_12; __pyx_t_12 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; goto __pyx_L0; goto __pyx_L41; } __pyx_L41:; } __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; } __pyx_L32:; __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_10); __Pyx_XDECREF(__pyx_t_11); __Pyx_XDECREF(__pyx_t_12); __Pyx_AddTraceback("traits.protocols._speedups.Protocol__adapt__"); __pyx_r = NULL; __pyx_L0:; __Pyx_DECREF(__pyx_v_cls); __Pyx_DECREF(__pyx_v_mro); __Pyx_DECREF(__pyx_v_get); __Pyx_DECREF(__pyx_v_factory); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_tp_new_9enthought_6traits_9protocols_9_speedups_metamethod(PyTypeObject *t, PyObject *a, PyObject *k) { struct __pyx_obj_9enthought_6traits_9protocols_9_speedups_metamethod *p; PyObject *o = (*t->tp_alloc)(t, 0); if (!o) return 0; p = ((struct __pyx_obj_9enthought_6traits_9protocols_9_speedups_metamethod *)o); p->func = Py_None; Py_INCREF(Py_None); return o; } static void __pyx_tp_dealloc_9enthought_6traits_9protocols_9_speedups_metamethod(PyObject *o) { struct __pyx_obj_9enthought_6traits_9protocols_9_speedups_metamethod *p = (struct __pyx_obj_9enthought_6traits_9protocols_9_speedups_metamethod *)o; Py_XDECREF(p->func); (*Py_TYPE(o)->tp_free)(o); } static int __pyx_tp_traverse_9enthought_6traits_9protocols_9_speedups_metamethod(PyObject *o, visitproc v, void *a) { int e; struct __pyx_obj_9enthought_6traits_9protocols_9_speedups_metamethod *p = (struct __pyx_obj_9enthought_6traits_9protocols_9_speedups_metamethod *)o; if (p->func) { e = (*v)(p->func, a); if (e) return e; } return 0; } static int __pyx_tp_clear_9enthought_6traits_9protocols_9_speedups_metamethod(PyObject *o) { struct __pyx_obj_9enthought_6traits_9protocols_9_speedups_metamethod *p = (struct __pyx_obj_9enthought_6traits_9protocols_9_speedups_metamethod *)o; PyObject* tmp; tmp = ((PyObject*)p->func); p->func = Py_None; Py_INCREF(Py_None); Py_XDECREF(tmp); return 0; } static PyObject *__pyx_tp_descr_get_9enthought_6traits_9protocols_9_speedups_metamethod(PyObject *o, PyObject *i, PyObject *c) { PyObject *r = 0; if (!i) i = Py_None; if (!c) c = Py_None; r = __pyx_pf_9enthought_6traits_9protocols_9_speedups_10metamethod_1__get__(o, i, c); return r; } static int __pyx_tp_descr_set_9enthought_6traits_9protocols_9_speedups_metamethod(PyObject *o, PyObject *i, PyObject *v) { if (v) { return __pyx_pf_9enthought_6traits_9protocols_9_speedups_10metamethod_2__set__(o, i, v); } else { return __pyx_pf_9enthought_6traits_9protocols_9_speedups_10metamethod_3__delete__(o, i); } } static PyMethodDef __pyx_methods_9enthought_6traits_9protocols_9_speedups_metamethod[] = { {0, 0, 0, 0} }; static PyNumberMethods __pyx_tp_as_number_metamethod = { 0, /*nb_add*/ 0, /*nb_subtract*/ 0, /*nb_multiply*/ #if PY_MAJOR_VERSION < 3 0, /*nb_divide*/ #endif 0, /*nb_remainder*/ 0, /*nb_divmod*/ 0, /*nb_power*/ 0, /*nb_negative*/ 0, /*nb_positive*/ 0, /*nb_absolute*/ 0, /*nb_nonzero*/ 0, /*nb_invert*/ 0, /*nb_lshift*/ 0, /*nb_rshift*/ 0, /*nb_and*/ 0, /*nb_xor*/ 0, /*nb_or*/ #if PY_MAJOR_VERSION < 3 0, /*nb_coerce*/ #endif 0, /*nb_int*/ #if PY_MAJOR_VERSION < 3 0, /*nb_long*/ #else 0, /*reserved*/ #endif 0, /*nb_float*/ #if PY_MAJOR_VERSION < 3 0, /*nb_oct*/ #endif #if PY_MAJOR_VERSION < 3 0, /*nb_hex*/ #endif 0, /*nb_inplace_add*/ 0, /*nb_inplace_subtract*/ 0, /*nb_inplace_multiply*/ #if PY_MAJOR_VERSION < 3 0, /*nb_inplace_divide*/ #endif 0, /*nb_inplace_remainder*/ 0, /*nb_inplace_power*/ 0, /*nb_inplace_lshift*/ 0, /*nb_inplace_rshift*/ 0, /*nb_inplace_and*/ 0, /*nb_inplace_xor*/ 0, /*nb_inplace_or*/ 0, /*nb_floor_divide*/ 0, /*nb_true_divide*/ 0, /*nb_inplace_floor_divide*/ 0, /*nb_inplace_true_divide*/ #if PY_VERSION_HEX >= 0x02050000 0, /*nb_index*/ #endif }; static PySequenceMethods __pyx_tp_as_sequence_metamethod = { 0, /*sq_length*/ 0, /*sq_concat*/ 0, /*sq_repeat*/ 0, /*sq_item*/ 0, /*sq_slice*/ 0, /*sq_ass_item*/ 0, /*sq_ass_slice*/ 0, /*sq_contains*/ 0, /*sq_inplace_concat*/ 0, /*sq_inplace_repeat*/ }; static PyMappingMethods __pyx_tp_as_mapping_metamethod = { 0, /*mp_length*/ 0, /*mp_subscript*/ 0, /*mp_ass_subscript*/ }; static PyBufferProcs __pyx_tp_as_buffer_metamethod = { #if PY_MAJOR_VERSION < 3 0, /*bf_getreadbuffer*/ #endif #if PY_MAJOR_VERSION < 3 0, /*bf_getwritebuffer*/ #endif #if PY_MAJOR_VERSION < 3 0, /*bf_getsegcount*/ #endif #if PY_MAJOR_VERSION < 3 0, /*bf_getcharbuffer*/ #endif #if PY_VERSION_HEX >= 0x02060000 0, /*bf_getbuffer*/ #endif #if PY_VERSION_HEX >= 0x02060000 0, /*bf_releasebuffer*/ #endif }; static PyTypeObject __pyx_type_9enthought_6traits_9protocols_9_speedups_metamethod = { PyVarObject_HEAD_INIT(0, 0) __Pyx_NAMESTR("traits.protocols._speedups.metamethod"), /*tp_name*/ sizeof(struct __pyx_obj_9enthought_6traits_9protocols_9_speedups_metamethod), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc_9enthought_6traits_9protocols_9_speedups_metamethod, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 0, /*tp_compare*/ #else 0, /*reserved*/ #endif 0, /*tp_repr*/ &__pyx_tp_as_number_metamethod, /*tp_as_number*/ &__pyx_tp_as_sequence_metamethod, /*tp_as_sequence*/ &__pyx_tp_as_mapping_metamethod, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ &__pyx_tp_as_buffer_metamethod, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ __Pyx_DOCSTR("Wrapper for metaclass method that might be confused w/instance method"), /*tp_doc*/ __pyx_tp_traverse_9enthought_6traits_9protocols_9_speedups_metamethod, /*tp_traverse*/ __pyx_tp_clear_9enthought_6traits_9protocols_9_speedups_metamethod, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ 0, /*tp_iter*/ 0, /*tp_iternext*/ __pyx_methods_9enthought_6traits_9protocols_9_speedups_metamethod, /*tp_methods*/ 0, /*tp_members*/ 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ __pyx_tp_descr_get_9enthought_6traits_9protocols_9_speedups_metamethod, /*tp_descr_get*/ __pyx_tp_descr_set_9enthought_6traits_9protocols_9_speedups_metamethod, /*tp_descr_set*/ 0, /*tp_dictoffset*/ __pyx_pf_9enthought_6traits_9protocols_9_speedups_10metamethod___init__, /*tp_init*/ 0, /*tp_alloc*/ __pyx_tp_new_9enthought_6traits_9protocols_9_speedups_metamethod, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ 0, /*tp_bases*/ 0, /*tp_mro*/ 0, /*tp_cache*/ 0, /*tp_subclasses*/ 0, /*tp_weaklist*/ 0, /*tp_del*/ #if PY_VERSION_HEX >= 0x02060000 0, /*tp_version_tag*/ #endif }; static PyMethodDef __pyx_methods[] = { {0, 0, 0, 0} }; #if PY_MAJOR_VERSION >= 3 static struct PyModuleDef __pyx_moduledef = { PyModuleDef_HEAD_INIT, __Pyx_NAMESTR("_speedups"), __Pyx_DOCSTR(__pyx_k_13), /* m_doc */ -1, /* m_size */ __pyx_methods /* m_methods */, NULL, /* m_reload */ NULL, /* m_traverse */ NULL, /* m_clear */ NULL /* m_free */ }; #endif static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_kp_s_1, __pyx_k_1, sizeof(__pyx_k_1), 0, 0, 1, 0}, {&__pyx_kp_s_10, __pyx_k_10, sizeof(__pyx_k_10), 0, 0, 1, 0}, {&__pyx_n_s_15, __pyx_k_15, sizeof(__pyx_k_15), 0, 0, 1, 1}, {&__pyx_kp_s_4, __pyx_k_4, sizeof(__pyx_k_4), 0, 0, 1, 0}, {&__pyx_kp_s_5, __pyx_k_5, sizeof(__pyx_k_5), 0, 0, 1, 0}, {&__pyx_n_s__AdaptationFailure, __pyx_k__AdaptationFailure, sizeof(__pyx_k__AdaptationFailure), 0, 0, 1, 1}, {&__pyx_n_s__AttributeError, __pyx_k__AttributeError, sizeof(__pyx_k__AttributeError), 0, 0, 1, 1}, {&__pyx_n_s__DOES_NOT_SUPPORT, __pyx_k__DOES_NOT_SUPPORT, sizeof(__pyx_k__DOES_NOT_SUPPORT), 0, 0, 1, 1}, {&__pyx_n_s__DeprecationWarning, __pyx_k__DeprecationWarning, sizeof(__pyx_k__DeprecationWarning), 0, 0, 1, 1}, {&__pyx_n_s__Exception, __pyx_k__Exception, sizeof(__pyx_k__Exception), 0, 0, 1, 1}, {&__pyx_n_s__ExtensionClass, __pyx_k__ExtensionClass, sizeof(__pyx_k__ExtensionClass), 0, 0, 1, 1}, {&__pyx_n_s__ImportError, __pyx_k__ImportError, sizeof(__pyx_k__ImportError), 0, 0, 1, 1}, {&__pyx_n_s__NO_ADAPTER_NEEDED, __pyx_k__NO_ADAPTER_NEEDED, sizeof(__pyx_k__NO_ADAPTER_NEEDED), 0, 0, 1, 1}, {&__pyx_n_s__Protocol__adapt__, __pyx_k__Protocol__adapt__, sizeof(__pyx_k__Protocol__adapt__), 0, 0, 1, 1}, {&__pyx_n_s__Protocol__call__, __pyx_k__Protocol__call__, sizeof(__pyx_k__Protocol__call__), 0, 0, 1, 1}, {&__pyx_n_s__TypeError, __pyx_k__TypeError, sizeof(__pyx_k__TypeError), 0, 0, 1, 1}, {&__pyx_n_s___Protocol__adapters, __pyx_k___Protocol__adapters, sizeof(__pyx_k___Protocol__adapters), 0, 0, 1, 1}, {&__pyx_n_s____all__, __pyx_k____all__, sizeof(__pyx_k____all__), 0, 0, 1, 1}, {&__pyx_n_s____bases__, __pyx_k____bases__, sizeof(__pyx_k____bases__), 0, 0, 1, 1}, {&__pyx_n_s____class, __pyx_k____class, sizeof(__pyx_k____class), 0, 0, 1, 1}, {&__pyx_n_s____import__, __pyx_k____import__, sizeof(__pyx_k____import__), 0, 0, 1, 1}, {&__pyx_n_s____main__, __pyx_k____main__, sizeof(__pyx_k____main__), 0, 0, 1, 1}, {&__pyx_n_s____mro__, __pyx_k____mro__, sizeof(__pyx_k____mro__), 0, 0, 1, 1}, {&__pyx_n_s____name__, __pyx_k____name__, sizeof(__pyx_k____name__), 0, 0, 1, 1}, {&__pyx_n_s____test__, __pyx_k____test__, sizeof(__pyx_k____test__), 0, 0, 1, 1}, {&__pyx_n_s__adapt, __pyx_k__adapt, sizeof(__pyx_k__adapt), 0, 0, 1, 1}, {&__pyx_n_s__cl_bases, __pyx_k__cl_bases, sizeof(__pyx_k__cl_bases), 0, 0, 1, 1}, {&__pyx_n_s__classicMRO, __pyx_k__classicMRO, sizeof(__pyx_k__classicMRO), 0, 0, 1, 1}, {&__pyx_n_s__default, __pyx_k__default, sizeof(__pyx_k__default), 0, 0, 1, 1}, {&__pyx_n_s__exc_clear, __pyx_k__exc_clear, sizeof(__pyx_k__exc_clear), 0, 0, 1, 1}, {&__pyx_n_s__exc_info, __pyx_k__exc_info, sizeof(__pyx_k__exc_info), 0, 0, 1, 1}, {&__pyx_n_s__extClassMRO, __pyx_k__extClassMRO, sizeof(__pyx_k__extClassMRO), 0, 0, 1, 1}, {&__pyx_n_s__extendedClassic, __pyx_k__extendedClassic, sizeof(__pyx_k__extendedClassic), 0, 0, 1, 1}, {&__pyx_n_s__factory, __pyx_k__factory, sizeof(__pyx_k__factory), 0, 0, 1, 1}, {&__pyx_n_s__fromlist, __pyx_k__fromlist, sizeof(__pyx_k__fromlist), 0, 0, 1, 1}, {&__pyx_n_s__func, __pyx_k__func, sizeof(__pyx_k__func), 0, 0, 1, 1}, {&__pyx_n_s__get, __pyx_k__get, sizeof(__pyx_k__get), 0, 0, 1, 1}, {&__pyx_n_s__getMRO, __pyx_k__getMRO, sizeof(__pyx_k__getMRO), 0, 0, 1, 1}, {&__pyx_n_s__globals, __pyx_k__globals, sizeof(__pyx_k__globals), 0, 0, 1, 1}, {&__pyx_n_s__in_class, __pyx_k__in_class, sizeof(__pyx_k__in_class), 0, 0, 1, 1}, {&__pyx_n_s__level, __pyx_k__level, sizeof(__pyx_k__level), 0, 0, 1, 1}, {&__pyx_n_s__metamethod, __pyx_k__metamethod, sizeof(__pyx_k__metamethod), 0, 0, 1, 1}, {&__pyx_n_s__ob, __pyx_k__ob, sizeof(__pyx_k__ob), 0, 0, 1, 1}, {&__pyx_n_s__ob_type, __pyx_k__ob_type, sizeof(__pyx_k__ob_type), 0, 0, 1, 1}, {&__pyx_n_s__obj, __pyx_k__obj, sizeof(__pyx_k__obj), 0, 0, 1, 1}, {&__pyx_n_s__object, __pyx_k__object, sizeof(__pyx_k__object), 0, 0, 1, 1}, {&__pyx_n_s__protocol, __pyx_k__protocol, sizeof(__pyx_k__protocol), 0, 0, 1, 1}, {&__pyx_n_s__protocols, __pyx_k__protocols, sizeof(__pyx_k__protocols), 0, 0, 1, 1}, {&__pyx_n_s__self, __pyx_k__self, sizeof(__pyx_k__self), 0, 0, 1, 1}, {&__pyx_n_s__sys, __pyx_k__sys, sizeof(__pyx_k__sys), 0, 0, 1, 1}, {&__pyx_n_s__tb_next, __pyx_k__tb_next, sizeof(__pyx_k__tb_next), 0, 0, 1, 1}, {&__pyx_n_s__tp_mro, __pyx_k__tp_mro, sizeof(__pyx_k__tp_mro), 0, 0, 1, 1}, {&__pyx_n_s__warn, __pyx_k__warn, sizeof(__pyx_k__warn), 0, 0, 1, 1}, {&__pyx_n_s__warnings, __pyx_k__warnings, sizeof(__pyx_k__warnings), 0, 0, 1, 1}, {0, 0, 0, 0, 0, 0, 0} }; static int __Pyx_InitCachedBuiltins(void) { __pyx_builtin___import__ = __Pyx_GetName(__pyx_b, __pyx_n_s____import__); if (!__pyx_builtin___import__) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_builtin_ImportError = __Pyx_GetName(__pyx_b, __pyx_n_s__ImportError); if (!__pyx_builtin_ImportError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_builtin_object = __Pyx_GetName(__pyx_b, __pyx_n_s__object); if (!__pyx_builtin_object) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_builtin_AttributeError = __Pyx_GetName(__pyx_b, __pyx_n_s__AttributeError); if (!__pyx_builtin_AttributeError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_builtin_TypeError = __Pyx_GetName(__pyx_b, __pyx_n_s__TypeError); if (!__pyx_builtin_TypeError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_builtin_DeprecationWarning = __Pyx_GetName(__pyx_b, __pyx_n_s__DeprecationWarning); if (!__pyx_builtin_DeprecationWarning) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 183; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_builtin_Exception = __Pyx_GetName(__pyx_b, __pyx_n_s__Exception); if (!__pyx_builtin_Exception) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 319; __pyx_clineno = __LINE__; goto __pyx_L1_error;} return 0; __pyx_L1_error:; return -1; } static int __Pyx_InitCachedConstants(void) { __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants"); /* "traits/protocols/_speedups.pyx":115 * * def __set__(self, ob, value): * raise AttributeError("Read-only attribute") # <<<<<<<<<<<<<< * * def __delete__(self, ob): */ __pyx_k_tuple_2 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(((PyObject *)__pyx_k_tuple_2)); __Pyx_INCREF(((PyObject *)__pyx_kp_s_1)); PyTuple_SET_ITEM(__pyx_k_tuple_2, 0, ((PyObject *)__pyx_kp_s_1)); __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_1)); __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_2)); /* "traits/protocols/_speedups.pyx":118 * * def __delete__(self, ob): * raise AttributeError("Read-only attribute") # <<<<<<<<<<<<<< * * */ __pyx_k_tuple_3 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(((PyObject *)__pyx_k_tuple_3)); __Pyx_INCREF(((PyObject *)__pyx_kp_s_1)); PyTuple_SET_ITEM(__pyx_k_tuple_3, 0, ((PyObject *)__pyx_kp_s_1)); __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_1)); __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_3)); /* "traits/protocols/_speedups.pyx":66 * # an extension module, globals() returns the globals dictionary of the last * # pure Python module that was executing. * AdaptationFailure = __import__( # <<<<<<<<<<<<<< * 'protocols', globals=dict(__name__=__name__), * fromlist=['AdaptationFailure'], level=1 */ __pyx_k_tuple_14 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(((PyObject *)__pyx_k_tuple_14)); __Pyx_INCREF(((PyObject *)__pyx_n_s__protocols)); PyTuple_SET_ITEM(__pyx_k_tuple_14, 0, ((PyObject *)__pyx_n_s__protocols)); __Pyx_GIVEREF(((PyObject *)__pyx_n_s__protocols)); __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_14)); __Pyx_RefNannyFinishContext(); return 0; __pyx_L1_error:; __Pyx_RefNannyFinishContext(); return -1; } static int __Pyx_InitGlobals(void) { if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; return 0; __pyx_L1_error:; return -1; } #if PY_MAJOR_VERSION < 3 PyMODINIT_FUNC init_speedups(void); /*proto*/ PyMODINIT_FUNC init_speedups(void) #else PyMODINIT_FUNC PyInit__speedups(void); /*proto*/ PyMODINIT_FUNC PyInit__speedups(void) #endif { PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; int __pyx_t_4; #if CYTHON_REFNANNY void* __pyx_refnanny = NULL; __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); if (!__Pyx_RefNanny) { PyErr_Clear(); __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); if (!__Pyx_RefNanny) Py_FatalError("failed to import 'refnanny' module"); } __pyx_refnanny = __Pyx_RefNanny->SetupContext("PyMODINIT_FUNC PyInit__speedups(void)", __LINE__, __FILE__); #endif __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #ifdef __pyx_binding_PyCFunctionType_USED if (__pyx_binding_PyCFunctionType_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} #endif /*--- Library function declarations ---*/ /*--- Threads initialization code ---*/ #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS #ifdef WITH_THREAD /* Python build with threading support? */ PyEval_InitThreads(); #endif #endif /*--- Module creation code ---*/ #if PY_MAJOR_VERSION < 3 __pyx_m = Py_InitModule4(__Pyx_NAMESTR("_speedups"), __pyx_methods, __Pyx_DOCSTR(__pyx_k_13), 0, PYTHON_API_VERSION); #else __pyx_m = PyModule_Create(&__pyx_moduledef); #endif if (!__pyx_m) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; #if PY_MAJOR_VERSION < 3 Py_INCREF(__pyx_m); #endif __pyx_b = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); if (!__pyx_b) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; if (__Pyx_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; /*--- Initialize various global constants etc. ---*/ if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} if (__pyx_module_is_main_enthought__traits__protocols___speedups) { if (__Pyx_SetAttrString(__pyx_m, "__name__", __pyx_n_s____main__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; } /*--- Builtin init code ---*/ if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /*--- Constants init code ---*/ if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /*--- Global init code ---*/ __pyx_v_9enthought_6traits_9protocols_9_speedups__marker = Py_None; Py_INCREF(Py_None); __pyx_v_9enthought_6traits_9protocols_9_speedups___conform = Py_None; Py_INCREF(Py_None); __pyx_v_9enthought_6traits_9protocols_9_speedups___adapt = Py_None; Py_INCREF(Py_None); __pyx_v_9enthought_6traits_9protocols_9_speedups___mro = Py_None; Py_INCREF(Py_None); __pyx_v_9enthought_6traits_9protocols_9_speedups___ECType = Py_None; Py_INCREF(Py_None); /*--- Function export code ---*/ /*--- Type init code ---*/ if (PyType_Ready(&__pyx_type_9enthought_6traits_9protocols_9_speedups_metamethod) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;} if (__Pyx_SetAttrString(__pyx_m, "metamethod", (PyObject *)&__pyx_type_9enthought_6traits_9protocols_9_speedups_metamethod) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_ptype_9enthought_6traits_9protocols_9_speedups_metamethod = &__pyx_type_9enthought_6traits_9protocols_9_speedups_metamethod; /*--- Type import code ---*/ /*--- Function import code ---*/ /*--- Execution code ---*/ /* "traits/protocols/_speedups.pyx":3 * """C Speedups for commonly-used operations""" * * __all__ = [ # <<<<<<<<<<<<<< * 'NO_ADAPTER_NEEDED', 'DOES_NOT_SUPPORT', * 'adapt', 'Protocol__adapt__', 'metamethod', 'classicMRO', 'getMRO', */ __pyx_t_1 = PyList_New(8); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(((PyObject *)__pyx_t_1)); __Pyx_INCREF(((PyObject *)__pyx_n_s__NO_ADAPTER_NEEDED)); PyList_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_n_s__NO_ADAPTER_NEEDED)); __Pyx_GIVEREF(((PyObject *)__pyx_n_s__NO_ADAPTER_NEEDED)); __Pyx_INCREF(((PyObject *)__pyx_n_s__DOES_NOT_SUPPORT)); PyList_SET_ITEM(__pyx_t_1, 1, ((PyObject *)__pyx_n_s__DOES_NOT_SUPPORT)); __Pyx_GIVEREF(((PyObject *)__pyx_n_s__DOES_NOT_SUPPORT)); __Pyx_INCREF(((PyObject *)__pyx_n_s__adapt)); PyList_SET_ITEM(__pyx_t_1, 2, ((PyObject *)__pyx_n_s__adapt)); __Pyx_GIVEREF(((PyObject *)__pyx_n_s__adapt)); __Pyx_INCREF(((PyObject *)__pyx_n_s__Protocol__adapt__)); PyList_SET_ITEM(__pyx_t_1, 3, ((PyObject *)__pyx_n_s__Protocol__adapt__)); __Pyx_GIVEREF(((PyObject *)__pyx_n_s__Protocol__adapt__)); __Pyx_INCREF(((PyObject *)__pyx_n_s__metamethod)); PyList_SET_ITEM(__pyx_t_1, 4, ((PyObject *)__pyx_n_s__metamethod)); __Pyx_GIVEREF(((PyObject *)__pyx_n_s__metamethod)); __Pyx_INCREF(((PyObject *)__pyx_n_s__classicMRO)); PyList_SET_ITEM(__pyx_t_1, 5, ((PyObject *)__pyx_n_s__classicMRO)); __Pyx_GIVEREF(((PyObject *)__pyx_n_s__classicMRO)); __Pyx_INCREF(((PyObject *)__pyx_n_s__getMRO)); PyList_SET_ITEM(__pyx_t_1, 6, ((PyObject *)__pyx_n_s__getMRO)); __Pyx_GIVEREF(((PyObject *)__pyx_n_s__getMRO)); __Pyx_INCREF(((PyObject *)__pyx_n_s__Protocol__call__)); PyList_SET_ITEM(__pyx_t_1, 7, ((PyObject *)__pyx_n_s__Protocol__call__)); __Pyx_GIVEREF(((PyObject *)__pyx_n_s__Protocol__call__)); if (PyObject_SetAttr(__pyx_m, __pyx_n_s____all__, ((PyObject *)__pyx_t_1)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0; /* "traits/protocols/_speedups.pyx":61 * * cdef object _marker, __conform, __adapt, __mro, __ECType * from sys import exc_info, exc_clear # <<<<<<<<<<<<<< * # Since we can't do "from future import absolute_import", we use __import__ * # directly. Fake the globals dictionary with just the relevant information. In */ __pyx_t_1 = PyList_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(((PyObject *)__pyx_t_1)); __Pyx_INCREF(((PyObject *)__pyx_n_s__exc_info)); PyList_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_n_s__exc_info)); __Pyx_GIVEREF(((PyObject *)__pyx_n_s__exc_info)); __Pyx_INCREF(((PyObject *)__pyx_n_s__exc_clear)); PyList_SET_ITEM(__pyx_t_1, 1, ((PyObject *)__pyx_n_s__exc_clear)); __Pyx_GIVEREF(((PyObject *)__pyx_n_s__exc_clear)); __pyx_t_2 = __Pyx_Import(((PyObject *)__pyx_n_s__sys), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0; __pyx_t_1 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__exc_info); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); if (PyObject_SetAttr(__pyx_m, __pyx_n_s__exc_info, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_1 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__exc_clear); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); if (PyObject_SetAttr(__pyx_m, __pyx_n_s__exc_clear, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "traits/protocols/_speedups.pyx":66 * # an extension module, globals() returns the globals dictionary of the last * # pure Python module that was executing. * AdaptationFailure = __import__( # <<<<<<<<<<<<<< * 'protocols', globals=dict(__name__=__name__), * fromlist=['AdaptationFailure'], level=1 */ __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(((PyObject *)__pyx_t_2)); /* "traits/protocols/_speedups.pyx":67 * # pure Python module that was executing. * AdaptationFailure = __import__( * 'protocols', globals=dict(__name__=__name__), # <<<<<<<<<<<<<< * fromlist=['AdaptationFailure'], level=1 * ).AdaptationFailure */ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(((PyObject *)__pyx_t_1)); __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s____name__); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s____name__), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__globals), ((PyObject *)__pyx_t_1)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0; /* "traits/protocols/_speedups.pyx":68 * AdaptationFailure = __import__( * 'protocols', globals=dict(__name__=__name__), * fromlist=['AdaptationFailure'], level=1 # <<<<<<<<<<<<<< * ).AdaptationFailure * */ __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(((PyObject *)__pyx_t_1)); __Pyx_INCREF(((PyObject *)__pyx_n_s__AdaptationFailure)); PyList_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_n_s__AdaptationFailure)); __Pyx_GIVEREF(((PyObject *)__pyx_n_s__AdaptationFailure)); if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__fromlist), ((PyObject *)__pyx_t_1)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0; if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_n_s__level), __pyx_int_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_t_1 = PyEval_CallObjectWithKeywords(__pyx_builtin___import__, ((PyObject *)__pyx_k_tuple_14), ((PyObject *)__pyx_t_2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0; __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__AdaptationFailure); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; if (PyObject_SetAttr(__pyx_m, __pyx_n_s__AdaptationFailure, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "traits/protocols/_speedups.pyx":71 * ).AdaptationFailure * * try: # <<<<<<<<<<<<<< * from ExtensionClass import ExtensionClass * __ECType = ExtensionClass */ { PyObject *__pyx_save_exc_type, *__pyx_save_exc_value, *__pyx_save_exc_tb; __Pyx_ExceptionSave(&__pyx_save_exc_type, &__pyx_save_exc_value, &__pyx_save_exc_tb); __Pyx_XGOTREF(__pyx_save_exc_type); __Pyx_XGOTREF(__pyx_save_exc_value); __Pyx_XGOTREF(__pyx_save_exc_tb); /*try:*/ { /* "traits/protocols/_speedups.pyx":72 * * try: * from ExtensionClass import ExtensionClass # <<<<<<<<<<<<<< * __ECType = ExtensionClass * except ImportError: */ __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L2_error;} __Pyx_GOTREF(((PyObject *)__pyx_t_2)); __Pyx_INCREF(((PyObject *)__pyx_n_s__ExtensionClass)); PyList_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_n_s__ExtensionClass)); __Pyx_GIVEREF(((PyObject *)__pyx_n_s__ExtensionClass)); __pyx_t_1 = __Pyx_Import(((PyObject *)__pyx_n_s__ExtensionClass), ((PyObject *)__pyx_t_2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L2_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0; __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__ExtensionClass); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L2_error;} __Pyx_GOTREF(__pyx_t_2); if (PyObject_SetAttr(__pyx_m, __pyx_n_s__ExtensionClass, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L2_error;} __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "traits/protocols/_speedups.pyx":73 * try: * from ExtensionClass import ExtensionClass * __ECType = ExtensionClass # <<<<<<<<<<<<<< * except ImportError: * __ECType = type */ __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__ExtensionClass); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; __pyx_clineno = __LINE__; goto __pyx_L2_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_GOTREF(__pyx_v_9enthought_6traits_9protocols_9_speedups___ECType); __Pyx_DECREF(__pyx_v_9enthought_6traits_9protocols_9_speedups___ECType); __Pyx_GIVEREF(__pyx_t_1); __pyx_v_9enthought_6traits_9protocols_9_speedups___ECType = __pyx_t_1; __pyx_t_1 = 0; } __Pyx_XDECREF(__pyx_save_exc_type); __pyx_save_exc_type = 0; __Pyx_XDECREF(__pyx_save_exc_value); __pyx_save_exc_value = 0; __Pyx_XDECREF(__pyx_save_exc_tb); __pyx_save_exc_tb = 0; goto __pyx_L9_try_end; __pyx_L2_error:; __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; /* "traits/protocols/_speedups.pyx":74 * from ExtensionClass import ExtensionClass * __ECType = ExtensionClass * except ImportError: # <<<<<<<<<<<<<< * __ECType = type * */ __pyx_t_4 = PyErr_ExceptionMatches(__pyx_builtin_ImportError); if (__pyx_t_4) { __Pyx_AddTraceback("traits.protocols._speedups"); if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L4_except_error;} __Pyx_GOTREF(__pyx_t_1); __Pyx_GOTREF(__pyx_t_2); __Pyx_GOTREF(__pyx_t_3); /* "traits/protocols/_speedups.pyx":75 * __ECType = ExtensionClass * except ImportError: * __ECType = type # <<<<<<<<<<<<<< * * _marker = object() */ __Pyx_INCREF(((PyObject *)((PyObject*)(&PyType_Type)))); __Pyx_GOTREF(__pyx_v_9enthought_6traits_9protocols_9_speedups___ECType); __Pyx_DECREF(__pyx_v_9enthought_6traits_9protocols_9_speedups___ECType); __Pyx_GIVEREF(((PyObject *)((PyObject*)(&PyType_Type)))); __pyx_v_9enthought_6traits_9protocols_9_speedups___ECType = ((PyObject *)((PyObject*)(&PyType_Type))); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; goto __pyx_L3_exception_handled; } __pyx_L4_except_error:; __Pyx_XGIVEREF(__pyx_save_exc_type); __Pyx_XGIVEREF(__pyx_save_exc_value); __Pyx_XGIVEREF(__pyx_save_exc_tb); __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb); goto __pyx_L1_error; __pyx_L3_exception_handled:; __Pyx_XGIVEREF(__pyx_save_exc_type); __Pyx_XGIVEREF(__pyx_save_exc_value); __Pyx_XGIVEREF(__pyx_save_exc_tb); __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb); __pyx_L9_try_end:; } /* "traits/protocols/_speedups.pyx":77 * __ECType = type * * _marker = object() # <<<<<<<<<<<<<< * __conform = PyString_InternFromString("__conform__") * __adapt = PyString_InternFromString("__adapt__") */ __pyx_t_3 = PyObject_Call(__pyx_builtin_object, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_GOTREF(__pyx_v_9enthought_6traits_9protocols_9_speedups__marker); __Pyx_DECREF(__pyx_v_9enthought_6traits_9protocols_9_speedups__marker); __Pyx_GIVEREF(__pyx_t_3); __pyx_v_9enthought_6traits_9protocols_9_speedups__marker = __pyx_t_3; __pyx_t_3 = 0; /* "traits/protocols/_speedups.pyx":78 * * _marker = object() * __conform = PyString_InternFromString("__conform__") # <<<<<<<<<<<<<< * __adapt = PyString_InternFromString("__adapt__") * __class = PyString_InternFromString("__class__") */ __pyx_t_3 = PyString_InternFromString(__pyx_k____conform__); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_GOTREF(__pyx_v_9enthought_6traits_9protocols_9_speedups___conform); __Pyx_DECREF(__pyx_v_9enthought_6traits_9protocols_9_speedups___conform); __Pyx_GIVEREF(__pyx_t_3); __pyx_v_9enthought_6traits_9protocols_9_speedups___conform = __pyx_t_3; __pyx_t_3 = 0; /* "traits/protocols/_speedups.pyx":79 * _marker = object() * __conform = PyString_InternFromString("__conform__") * __adapt = PyString_InternFromString("__adapt__") # <<<<<<<<<<<<<< * __class = PyString_InternFromString("__class__") * __mro = PyString_InternFromString("__mro__") */ __pyx_t_3 = PyString_InternFromString(__pyx_k____adapt__); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_GOTREF(__pyx_v_9enthought_6traits_9protocols_9_speedups___adapt); __Pyx_DECREF(__pyx_v_9enthought_6traits_9protocols_9_speedups___adapt); __Pyx_GIVEREF(__pyx_t_3); __pyx_v_9enthought_6traits_9protocols_9_speedups___adapt = __pyx_t_3; __pyx_t_3 = 0; /* "traits/protocols/_speedups.pyx":80 * __conform = PyString_InternFromString("__conform__") * __adapt = PyString_InternFromString("__adapt__") * __class = PyString_InternFromString("__class__") # <<<<<<<<<<<<<< * __mro = PyString_InternFromString("__mro__") * */ __pyx_t_3 = PyString_InternFromString(__pyx_k____class__); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); if (PyObject_SetAttr(__pyx_m, __pyx_n_s____class, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; /* "traits/protocols/_speedups.pyx":81 * __adapt = PyString_InternFromString("__adapt__") * __class = PyString_InternFromString("__class__") * __mro = PyString_InternFromString("__mro__") # <<<<<<<<<<<<<< * * */ __pyx_t_3 = PyString_InternFromString(__pyx_k____mro__); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __Pyx_GOTREF(__pyx_v_9enthought_6traits_9protocols_9_speedups___mro); __Pyx_DECREF(__pyx_v_9enthought_6traits_9protocols_9_speedups___mro); __Pyx_GIVEREF(__pyx_t_3); __pyx_v_9enthought_6traits_9protocols_9_speedups___mro = __pyx_t_3; __pyx_t_3 = 0; /* "traits/protocols/_speedups.pyx":92 * # Fundamental Adapters * * def NO_ADAPTER_NEEDED(obj, protocol=None): # <<<<<<<<<<<<<< * """Assume 'obj' implements 'protocol' directly""" * return obj */ __pyx_t_3 = PyCFunction_NewEx(&__pyx_mdef_9enthought_6traits_9protocols_9_speedups_NO_ADAPTER_NEEDED, NULL, __pyx_n_s_15); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); if (PyObject_SetAttr(__pyx_m, __pyx_n_s__NO_ADAPTER_NEEDED, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; /* "traits/protocols/_speedups.pyx":96 * return obj * * def DOES_NOT_SUPPORT(obj, protocol=None): # <<<<<<<<<<<<<< * """Prevent 'obj' from supporting 'protocol'""" * return None */ __pyx_t_3 = PyCFunction_NewEx(&__pyx_mdef_9enthought_6traits_9protocols_9_speedups_1DOES_NOT_SUPPORT, NULL, __pyx_n_s_15); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); if (PyObject_SetAttr(__pyx_m, __pyx_n_s__DOES_NOT_SUPPORT, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; /* "traits/protocols/_speedups.pyx":190 * * * def adapt(obj, protocol, default=_marker, factory=_marker): # <<<<<<<<<<<<<< * """PEP 246-alike: Adapt 'obj' to 'protocol', return 'default' * */ __Pyx_INCREF(__pyx_v_9enthought_6traits_9protocols_9_speedups__marker); __pyx_k_6 = __pyx_v_9enthought_6traits_9protocols_9_speedups__marker; __Pyx_GIVEREF(__pyx_v_9enthought_6traits_9protocols_9_speedups__marker); __Pyx_INCREF(__pyx_v_9enthought_6traits_9protocols_9_speedups__marker); __pyx_k_7 = __pyx_v_9enthought_6traits_9protocols_9_speedups__marker; __Pyx_GIVEREF(__pyx_v_9enthought_6traits_9protocols_9_speedups__marker); __pyx_t_3 = PyCFunction_NewEx(&__pyx_mdef_9enthought_6traits_9protocols_9_speedups_2adapt, NULL, __pyx_n_s_15); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); if (PyObject_SetAttr(__pyx_m, __pyx_n_s__adapt, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; /* "traits/protocols/_speedups.pyx":198 * return _adapt(obj,protocol,default,factory) * * def Protocol__call__(self, ob, default=_marker): # <<<<<<<<<<<<<< * """Adapt to this protocol""" * return _adapt(ob,self,default,_marker) */ __Pyx_INCREF(__pyx_v_9enthought_6traits_9protocols_9_speedups__marker); __pyx_k_8 = __pyx_v_9enthought_6traits_9protocols_9_speedups__marker; __Pyx_GIVEREF(__pyx_v_9enthought_6traits_9protocols_9_speedups__marker); __pyx_t_3 = PyCFunction_NewEx(&__pyx_mdef_9enthought_6traits_9protocols_9_speedups_3Protocol__call__, NULL, __pyx_n_s_15); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 198; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); if (PyObject_SetAttr(__pyx_m, __pyx_n_s__Protocol__call__, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 198; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; /* "traits/protocols/_speedups.pyx":217 * * * def classicMRO(ob, extendedClassic=False): # <<<<<<<<<<<<<< * * if PyClass_Check(ob): */ __pyx_t_3 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __pyx_k_9 = __pyx_t_3; __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_3 = PyCFunction_NewEx(&__pyx_mdef_9enthought_6traits_9protocols_9_speedups_4classicMRO, NULL, __pyx_n_s_15); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); if (PyObject_SetAttr(__pyx_m, __pyx_n_s__classicMRO, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; /* "traits/protocols/_speedups.pyx":250 * * * def extClassMRO(ob, extendedClassic=False): # <<<<<<<<<<<<<< * mro = [] * buildECMRO(ob, mro) */ __pyx_t_3 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __pyx_k_11 = __pyx_t_3; __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_3 = PyCFunction_NewEx(&__pyx_mdef_9enthought_6traits_9protocols_9_speedups_5extClassMRO, NULL, __pyx_n_s_15); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); if (PyObject_SetAttr(__pyx_m, __pyx_n_s__extClassMRO, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; /* "traits/protocols/_speedups.pyx":260 * * * def getMRO(ob, extendedClassic=False): # <<<<<<<<<<<<<< * * if PyClass_Check(ob): */ __pyx_t_3 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); __pyx_k_12 = __pyx_t_3; __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_3 = PyCFunction_NewEx(&__pyx_mdef_9enthought_6traits_9protocols_9_speedups_6getMRO, NULL, __pyx_n_s_15); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); if (PyObject_SetAttr(__pyx_m, __pyx_n_s__getMRO, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; /* "traits/protocols/_speedups.pyx":285 * * * def Protocol__adapt__(self, obj): # <<<<<<<<<<<<<< * * cdef void *tmp */ __pyx_t_3 = PyCFunction_NewEx(&__pyx_mdef_9enthought_6traits_9protocols_9_speedups_7Protocol__adapt__, NULL, __pyx_n_s_15); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_3); if (PyObject_SetAttr(__pyx_m, __pyx_n_s__Protocol__adapt__, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; /* "traits/protocols/_speedups.pyx":1 * """C Speedups for commonly-used operations""" # <<<<<<<<<<<<<< * * __all__ = [ */ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(((PyObject *)__pyx_t_3)); if (PyObject_SetAttr(__pyx_m, __pyx_n_s____test__, ((PyObject *)__pyx_t_3)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0; goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); if (__pyx_m) { __Pyx_AddTraceback("init traits.protocols._speedups"); Py_DECREF(__pyx_m); __pyx_m = 0; } else if (!PyErr_Occurred()) { PyErr_SetString(PyExc_ImportError, "init traits.protocols._speedups"); } __pyx_L0:; __Pyx_RefNannyFinishContext(); #if PY_MAJOR_VERSION < 3 return; #else return __pyx_m; #endif } /* Runtime support code */ static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) { PyObject *result; result = PyObject_GetAttr(dict, name); if (!result) PyErr_SetObject(PyExc_NameError, name); return result; } static void __Pyx_RaiseDoubleKeywordsError( const char* func_name, PyObject* kw_name) { PyErr_Format(PyExc_TypeError, #if PY_MAJOR_VERSION >= 3 "%s() got multiple values for keyword argument '%U'", func_name, kw_name); #else "%s() got multiple values for keyword argument '%s'", func_name, PyString_AS_STRING(kw_name)); #endif } static int __Pyx_ParseOptionalKeywords( PyObject *kwds, PyObject **argnames[], PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, const char* function_name) { PyObject *key = 0, *value = 0; Py_ssize_t pos = 0; PyObject*** name; PyObject*** first_kw_arg = argnames + num_pos_args; while (PyDict_Next(kwds, &pos, &key, &value)) { name = first_kw_arg; while (*name && (**name != key)) name++; if (*name) { values[name-argnames] = value; } else { #if PY_MAJOR_VERSION < 3 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) { #else if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) { #endif goto invalid_keyword_type; } else { for (name = first_kw_arg; *name; name++) { #if PY_MAJOR_VERSION >= 3 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) && PyUnicode_Compare(**name, key) == 0) break; #else if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) && _PyString_Eq(**name, key)) break; #endif } if (*name) { values[name-argnames] = value; } else { /* unexpected keyword found */ for (name=argnames; name != first_kw_arg; name++) { if (**name == key) goto arg_passed_twice; #if PY_MAJOR_VERSION >= 3 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) && PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice; #else if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) && _PyString_Eq(**name, key)) goto arg_passed_twice; #endif } if (kwds2) { if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; } else { goto invalid_keyword; } } } } } return 0; arg_passed_twice: __Pyx_RaiseDoubleKeywordsError(function_name, **name); goto bad; invalid_keyword_type: PyErr_Format(PyExc_TypeError, "%s() keywords must be strings", function_name); goto bad; invalid_keyword: PyErr_Format(PyExc_TypeError, #if PY_MAJOR_VERSION < 3 "%s() got an unexpected keyword argument '%s'", function_name, PyString_AsString(key)); #else "%s() got an unexpected keyword argument '%U'", function_name, key); #endif bad: return -1; } static void __Pyx_RaiseArgtupleInvalid( const char* func_name, int exact, Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found) { Py_ssize_t num_expected; const char *number, *more_or_less; if (num_found < num_min) { num_expected = num_min; more_or_less = "at least"; } else { num_expected = num_max; more_or_less = "at most"; } if (exact) { more_or_less = "exactly"; } number = (num_expected == 1) ? "" : "s"; PyErr_Format(PyExc_TypeError, #if PY_VERSION_HEX < 0x02050000 "%s() takes %s %d positional argument%s (%d given)", #else "%s() takes %s %zd positional argument%s (%zd given)", #endif func_name, more_or_less, num_expected, number, num_found); } static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) { PyObject *tmp_type, *tmp_value, *tmp_tb; PyThreadState *tstate = PyThreadState_GET(); tmp_type = tstate->curexc_type; tmp_value = tstate->curexc_value; tmp_tb = tstate->curexc_traceback; tstate->curexc_type = type; tstate->curexc_value = value; tstate->curexc_traceback = tb; Py_XDECREF(tmp_type); Py_XDECREF(tmp_value); Py_XDECREF(tmp_tb); } static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) { PyThreadState *tstate = PyThreadState_GET(); *type = tstate->curexc_type; *value = tstate->curexc_value; *tb = tstate->curexc_traceback; tstate->curexc_type = 0; tstate->curexc_value = 0; tstate->curexc_traceback = 0; } #if PY_MAJOR_VERSION < 3 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) { Py_XINCREF(type); Py_XINCREF(value); Py_XINCREF(tb); /* First, check the traceback argument, replacing None with NULL. */ if (tb == Py_None) { Py_DECREF(tb); tb = 0; } else if (tb != NULL && !PyTraceBack_Check(tb)) { PyErr_SetString(PyExc_TypeError, "raise: arg 3 must be a traceback or None"); goto raise_error; } /* Next, replace a missing value with None */ if (value == NULL) { value = Py_None; Py_INCREF(value); } #if PY_VERSION_HEX < 0x02050000 if (!PyClass_Check(type)) #else if (!PyType_Check(type)) #endif { /* Raising an instance. The value should be a dummy. */ if (value != Py_None) { PyErr_SetString(PyExc_TypeError, "instance exception may not have a separate value"); goto raise_error; } /* Normalize to raise , */ Py_DECREF(value); value = type; #if PY_VERSION_HEX < 0x02050000 if (PyInstance_Check(type)) { type = (PyObject*) ((PyInstanceObject*)type)->in_class; Py_INCREF(type); } else { type = 0; PyErr_SetString(PyExc_TypeError, "raise: exception must be an old-style class or instance"); goto raise_error; } #else type = (PyObject*) Py_TYPE(type); Py_INCREF(type); if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { PyErr_SetString(PyExc_TypeError, "raise: exception class must be a subclass of BaseException"); goto raise_error; } #endif } __Pyx_ErrRestore(type, value, tb); return; raise_error: Py_XDECREF(value); Py_XDECREF(type); Py_XDECREF(tb); return; } #else /* Python 3+ */ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) { if (tb == Py_None) { tb = 0; } else if (tb && !PyTraceBack_Check(tb)) { PyErr_SetString(PyExc_TypeError, "raise: arg 3 must be a traceback or None"); goto bad; } if (value == Py_None) value = 0; if (PyExceptionInstance_Check(type)) { if (value) { PyErr_SetString(PyExc_TypeError, "instance exception may not have a separate value"); goto bad; } value = type; type = (PyObject*) Py_TYPE(value); } else if (!PyExceptionClass_Check(type)) { PyErr_SetString(PyExc_TypeError, "raise: exception class must be a subclass of BaseException"); goto bad; } PyErr_SetObject(type, value); if (tb) { PyThreadState *tstate = PyThreadState_GET(); PyObject* tmp_tb = tstate->curexc_traceback; if (tb != tmp_tb) { Py_INCREF(tb); tstate->curexc_traceback = tb; Py_XDECREF(tmp_tb); } } bad: return; } #endif static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) { PyObject *local_type, *local_value, *local_tb; PyObject *tmp_type, *tmp_value, *tmp_tb; PyThreadState *tstate = PyThreadState_GET(); local_type = tstate->curexc_type; local_value = tstate->curexc_value; local_tb = tstate->curexc_traceback; tstate->curexc_type = 0; tstate->curexc_value = 0; tstate->curexc_traceback = 0; PyErr_NormalizeException(&local_type, &local_value, &local_tb); if (unlikely(tstate->curexc_type)) goto bad; #if PY_MAJOR_VERSION >= 3 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) goto bad; #endif *type = local_type; *value = local_value; *tb = local_tb; Py_INCREF(local_type); Py_INCREF(local_value); Py_INCREF(local_tb); tmp_type = tstate->exc_type; tmp_value = tstate->exc_value; tmp_tb = tstate->exc_traceback; tstate->exc_type = local_type; tstate->exc_value = local_value; tstate->exc_traceback = local_tb; /* Make sure tstate is in a consistent state when we XDECREF these objects (XDECREF may run arbitrary code). */ Py_XDECREF(tmp_type); Py_XDECREF(tmp_value); Py_XDECREF(tmp_tb); return 0; bad: *type = 0; *value = 0; *tb = 0; Py_XDECREF(local_type); Py_XDECREF(local_value); Py_XDECREF(local_tb); return -1; } static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) { PyThreadState *tstate = PyThreadState_GET(); *type = tstate->exc_type; *value = tstate->exc_value; *tb = tstate->exc_traceback; Py_XINCREF(*type); Py_XINCREF(*value); Py_XINCREF(*tb); } static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) { PyObject *tmp_type, *tmp_value, *tmp_tb; PyThreadState *tstate = PyThreadState_GET(); tmp_type = tstate->exc_type; tmp_value = tstate->exc_value; tmp_tb = tstate->exc_traceback; tstate->exc_type = type; tstate->exc_value = value; tstate->exc_traceback = tb; Py_XDECREF(tmp_type); Py_XDECREF(tmp_value); Py_XDECREF(tmp_tb); } static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) { PyObject *py_import = 0; PyObject *empty_list = 0; PyObject *module = 0; PyObject *global_dict = 0; PyObject *empty_dict = 0; PyObject *list; py_import = __Pyx_GetAttrString(__pyx_b, "__import__"); if (!py_import) goto bad; if (from_list) list = from_list; else { empty_list = PyList_New(0); if (!empty_list) goto bad; list = empty_list; } global_dict = PyModule_GetDict(__pyx_m); if (!global_dict) goto bad; empty_dict = PyDict_New(); if (!empty_dict) goto bad; module = PyObject_CallFunctionObjArgs(py_import, name, global_dict, empty_dict, list, NULL); bad: Py_XDECREF(empty_list); Py_XDECREF(py_import); Py_XDECREF(empty_dict); return module; } static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject *d) { PyObject *r = PyObject_GetAttr(o, n); if (!r) { if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad; PyErr_Clear(); r = d; Py_INCREF(d); } return r; bad: return NULL; } static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject* x) { const unsigned char neg_one = (unsigned char)-1, const_zero = 0; const int is_unsigned = neg_one > const_zero; if (sizeof(unsigned char) < sizeof(long)) { long val = __Pyx_PyInt_AsLong(x); if (unlikely(val != (long)(unsigned char)val)) { if (!unlikely(val == -1 && PyErr_Occurred())) { PyErr_SetString(PyExc_OverflowError, (is_unsigned && unlikely(val < 0)) ? "can't convert negative value to unsigned char" : "value too large to convert to unsigned char"); } return (unsigned char)-1; } return (unsigned char)val; } return (unsigned char)__Pyx_PyInt_AsUnsignedLong(x); } static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject* x) { const unsigned short neg_one = (unsigned short)-1, const_zero = 0; const int is_unsigned = neg_one > const_zero; if (sizeof(unsigned short) < sizeof(long)) { long val = __Pyx_PyInt_AsLong(x); if (unlikely(val != (long)(unsigned short)val)) { if (!unlikely(val == -1 && PyErr_Occurred())) { PyErr_SetString(PyExc_OverflowError, (is_unsigned && unlikely(val < 0)) ? "can't convert negative value to unsigned short" : "value too large to convert to unsigned short"); } return (unsigned short)-1; } return (unsigned short)val; } return (unsigned short)__Pyx_PyInt_AsUnsignedLong(x); } static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject* x) { const unsigned int neg_one = (unsigned int)-1, const_zero = 0; const int is_unsigned = neg_one > const_zero; if (sizeof(unsigned int) < sizeof(long)) { long val = __Pyx_PyInt_AsLong(x); if (unlikely(val != (long)(unsigned int)val)) { if (!unlikely(val == -1 && PyErr_Occurred())) { PyErr_SetString(PyExc_OverflowError, (is_unsigned && unlikely(val < 0)) ? "can't convert negative value to unsigned int" : "value too large to convert to unsigned int"); } return (unsigned int)-1; } return (unsigned int)val; } return (unsigned int)__Pyx_PyInt_AsUnsignedLong(x); } static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject* x) { const char neg_one = (char)-1, const_zero = 0; const int is_unsigned = neg_one > const_zero; if (sizeof(char) < sizeof(long)) { long val = __Pyx_PyInt_AsLong(x); if (unlikely(val != (long)(char)val)) { if (!unlikely(val == -1 && PyErr_Occurred())) { PyErr_SetString(PyExc_OverflowError, (is_unsigned && unlikely(val < 0)) ? "can't convert negative value to char" : "value too large to convert to char"); } return (char)-1; } return (char)val; } return (char)__Pyx_PyInt_AsLong(x); } static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject* x) { const short neg_one = (short)-1, const_zero = 0; const int is_unsigned = neg_one > const_zero; if (sizeof(short) < sizeof(long)) { long val = __Pyx_PyInt_AsLong(x); if (unlikely(val != (long)(short)val)) { if (!unlikely(val == -1 && PyErr_Occurred())) { PyErr_SetString(PyExc_OverflowError, (is_unsigned && unlikely(val < 0)) ? "can't convert negative value to short" : "value too large to convert to short"); } return (short)-1; } return (short)val; } return (short)__Pyx_PyInt_AsLong(x); } static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject* x) { const int neg_one = (int)-1, const_zero = 0; const int is_unsigned = neg_one > const_zero; if (sizeof(int) < sizeof(long)) { long val = __Pyx_PyInt_AsLong(x); if (unlikely(val != (long)(int)val)) { if (!unlikely(val == -1 && PyErr_Occurred())) { PyErr_SetString(PyExc_OverflowError, (is_unsigned && unlikely(val < 0)) ? "can't convert negative value to int" : "value too large to convert to int"); } return (int)-1; } return (int)val; } return (int)__Pyx_PyInt_AsLong(x); } static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject* x) { const signed char neg_one = (signed char)-1, const_zero = 0; const int is_unsigned = neg_one > const_zero; if (sizeof(signed char) < sizeof(long)) { long val = __Pyx_PyInt_AsLong(x); if (unlikely(val != (long)(signed char)val)) { if (!unlikely(val == -1 && PyErr_Occurred())) { PyErr_SetString(PyExc_OverflowError, (is_unsigned && unlikely(val < 0)) ? "can't convert negative value to signed char" : "value too large to convert to signed char"); } return (signed char)-1; } return (signed char)val; } return (signed char)__Pyx_PyInt_AsSignedLong(x); } static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject* x) { const signed short neg_one = (signed short)-1, const_zero = 0; const int is_unsigned = neg_one > const_zero; if (sizeof(signed short) < sizeof(long)) { long val = __Pyx_PyInt_AsLong(x); if (unlikely(val != (long)(signed short)val)) { if (!unlikely(val == -1 && PyErr_Occurred())) { PyErr_SetString(PyExc_OverflowError, (is_unsigned && unlikely(val < 0)) ? "can't convert negative value to signed short" : "value too large to convert to signed short"); } return (signed short)-1; } return (signed short)val; } return (signed short)__Pyx_PyInt_AsSignedLong(x); } static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject* x) { const signed int neg_one = (signed int)-1, const_zero = 0; const int is_unsigned = neg_one > const_zero; if (sizeof(signed int) < sizeof(long)) { long val = __Pyx_PyInt_AsLong(x); if (unlikely(val != (long)(signed int)val)) { if (!unlikely(val == -1 && PyErr_Occurred())) { PyErr_SetString(PyExc_OverflowError, (is_unsigned && unlikely(val < 0)) ? "can't convert negative value to signed int" : "value too large to convert to signed int"); } return (signed int)-1; } return (signed int)val; } return (signed int)__Pyx_PyInt_AsSignedLong(x); } static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject* x) { const int neg_one = (int)-1, const_zero = 0; const int is_unsigned = neg_one > const_zero; if (sizeof(int) < sizeof(long)) { long val = __Pyx_PyInt_AsLong(x); if (unlikely(val != (long)(int)val)) { if (!unlikely(val == -1 && PyErr_Occurred())) { PyErr_SetString(PyExc_OverflowError, (is_unsigned && unlikely(val < 0)) ? "can't convert negative value to int" : "value too large to convert to int"); } return (int)-1; } return (int)val; } return (int)__Pyx_PyInt_AsLong(x); } static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) { const unsigned long neg_one = (unsigned long)-1, const_zero = 0; const int is_unsigned = neg_one > const_zero; #if PY_VERSION_HEX < 0x03000000 if (likely(PyInt_Check(x))) { long val = PyInt_AS_LONG(x); if (is_unsigned && unlikely(val < 0)) { PyErr_SetString(PyExc_OverflowError, "can't convert negative value to unsigned long"); return (unsigned long)-1; } return (unsigned long)val; } else #endif if (likely(PyLong_Check(x))) { if (is_unsigned) { if (unlikely(Py_SIZE(x) < 0)) { PyErr_SetString(PyExc_OverflowError, "can't convert negative value to unsigned long"); return (unsigned long)-1; } return PyLong_AsUnsignedLong(x); } else { return PyLong_AsLong(x); } } else { unsigned long val; PyObject *tmp = __Pyx_PyNumber_Int(x); if (!tmp) return (unsigned long)-1; val = __Pyx_PyInt_AsUnsignedLong(tmp); Py_DECREF(tmp); return val; } } static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject* x) { const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG)-1, const_zero = 0; const int is_unsigned = neg_one > const_zero; #if PY_VERSION_HEX < 0x03000000 if (likely(PyInt_Check(x))) { long val = PyInt_AS_LONG(x); if (is_unsigned && unlikely(val < 0)) { PyErr_SetString(PyExc_OverflowError, "can't convert negative value to unsigned PY_LONG_LONG"); return (unsigned PY_LONG_LONG)-1; } return (unsigned PY_LONG_LONG)val; } else #endif if (likely(PyLong_Check(x))) { if (is_unsigned) { if (unlikely(Py_SIZE(x) < 0)) { PyErr_SetString(PyExc_OverflowError, "can't convert negative value to unsigned PY_LONG_LONG"); return (unsigned PY_LONG_LONG)-1; } return PyLong_AsUnsignedLongLong(x); } else { return PyLong_AsLongLong(x); } } else { unsigned PY_LONG_LONG val; PyObject *tmp = __Pyx_PyNumber_Int(x); if (!tmp) return (unsigned PY_LONG_LONG)-1; val = __Pyx_PyInt_AsUnsignedLongLong(tmp); Py_DECREF(tmp); return val; } } static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) { const long neg_one = (long)-1, const_zero = 0; const int is_unsigned = neg_one > const_zero; #if PY_VERSION_HEX < 0x03000000 if (likely(PyInt_Check(x))) { long val = PyInt_AS_LONG(x); if (is_unsigned && unlikely(val < 0)) { PyErr_SetString(PyExc_OverflowError, "can't convert negative value to long"); return (long)-1; } return (long)val; } else #endif if (likely(PyLong_Check(x))) { if (is_unsigned) { if (unlikely(Py_SIZE(x) < 0)) { PyErr_SetString(PyExc_OverflowError, "can't convert negative value to long"); return (long)-1; } return PyLong_AsUnsignedLong(x); } else { return PyLong_AsLong(x); } } else { long val; PyObject *tmp = __Pyx_PyNumber_Int(x); if (!tmp) return (long)-1; val = __Pyx_PyInt_AsLong(tmp); Py_DECREF(tmp); return val; } } static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) { const PY_LONG_LONG neg_one = (PY_LONG_LONG)-1, const_zero = 0; const int is_unsigned = neg_one > const_zero; #if PY_VERSION_HEX < 0x03000000 if (likely(PyInt_Check(x))) { long val = PyInt_AS_LONG(x); if (is_unsigned && unlikely(val < 0)) { PyErr_SetString(PyExc_OverflowError, "can't convert negative value to PY_LONG_LONG"); return (PY_LONG_LONG)-1; } return (PY_LONG_LONG)val; } else #endif if (likely(PyLong_Check(x))) { if (is_unsigned) { if (unlikely(Py_SIZE(x) < 0)) { PyErr_SetString(PyExc_OverflowError, "can't convert negative value to PY_LONG_LONG"); return (PY_LONG_LONG)-1; } return PyLong_AsUnsignedLongLong(x); } else { return PyLong_AsLongLong(x); } } else { PY_LONG_LONG val; PyObject *tmp = __Pyx_PyNumber_Int(x); if (!tmp) return (PY_LONG_LONG)-1; val = __Pyx_PyInt_AsLongLong(tmp); Py_DECREF(tmp); return val; } } static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) { const signed long neg_one = (signed long)-1, const_zero = 0; const int is_unsigned = neg_one > const_zero; #if PY_VERSION_HEX < 0x03000000 if (likely(PyInt_Check(x))) { long val = PyInt_AS_LONG(x); if (is_unsigned && unlikely(val < 0)) { PyErr_SetString(PyExc_OverflowError, "can't convert negative value to signed long"); return (signed long)-1; } return (signed long)val; } else #endif if (likely(PyLong_Check(x))) { if (is_unsigned) { if (unlikely(Py_SIZE(x) < 0)) { PyErr_SetString(PyExc_OverflowError, "can't convert negative value to signed long"); return (signed long)-1; } return PyLong_AsUnsignedLong(x); } else { return PyLong_AsLong(x); } } else { signed long val; PyObject *tmp = __Pyx_PyNumber_Int(x); if (!tmp) return (signed long)-1; val = __Pyx_PyInt_AsSignedLong(tmp); Py_DECREF(tmp); return val; } } static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject* x) { const signed PY_LONG_LONG neg_one = (signed PY_LONG_LONG)-1, const_zero = 0; const int is_unsigned = neg_one > const_zero; #if PY_VERSION_HEX < 0x03000000 if (likely(PyInt_Check(x))) { long val = PyInt_AS_LONG(x); if (is_unsigned && unlikely(val < 0)) { PyErr_SetString(PyExc_OverflowError, "can't convert negative value to signed PY_LONG_LONG"); return (signed PY_LONG_LONG)-1; } return (signed PY_LONG_LONG)val; } else #endif if (likely(PyLong_Check(x))) { if (is_unsigned) { if (unlikely(Py_SIZE(x) < 0)) { PyErr_SetString(PyExc_OverflowError, "can't convert negative value to signed PY_LONG_LONG"); return (signed PY_LONG_LONG)-1; } return PyLong_AsUnsignedLongLong(x); } else { return PyLong_AsLongLong(x); } } else { signed PY_LONG_LONG val; PyObject *tmp = __Pyx_PyNumber_Int(x); if (!tmp) return (signed PY_LONG_LONG)-1; val = __Pyx_PyInt_AsSignedLongLong(tmp); Py_DECREF(tmp); return val; } } #include "compile.h" #include "frameobject.h" #include "traceback.h" static void __Pyx_AddTraceback(const char *funcname) { PyObject *py_srcfile = 0; PyObject *py_funcname = 0; PyObject *py_globals = 0; PyCodeObject *py_code = 0; PyFrameObject *py_frame = 0; #if PY_MAJOR_VERSION < 3 py_srcfile = PyString_FromString(__pyx_filename); #else py_srcfile = PyUnicode_FromString(__pyx_filename); #endif if (!py_srcfile) goto bad; if (__pyx_clineno) { #if PY_MAJOR_VERSION < 3 py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, __pyx_clineno); #else py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, __pyx_clineno); #endif } else { #if PY_MAJOR_VERSION < 3 py_funcname = PyString_FromString(funcname); #else py_funcname = PyUnicode_FromString(funcname); #endif } if (!py_funcname) goto bad; py_globals = PyModule_GetDict(__pyx_m); if (!py_globals) goto bad; py_code = PyCode_New( 0, /*int argcount,*/ #if PY_MAJOR_VERSION >= 3 0, /*int kwonlyargcount,*/ #endif 0, /*int nlocals,*/ 0, /*int stacksize,*/ 0, /*int flags,*/ __pyx_empty_bytes, /*PyObject *code,*/ __pyx_empty_tuple, /*PyObject *consts,*/ __pyx_empty_tuple, /*PyObject *names,*/ __pyx_empty_tuple, /*PyObject *varnames,*/ __pyx_empty_tuple, /*PyObject *freevars,*/ __pyx_empty_tuple, /*PyObject *cellvars,*/ py_srcfile, /*PyObject *filename,*/ py_funcname, /*PyObject *name,*/ __pyx_lineno, /*int firstlineno,*/ __pyx_empty_bytes /*PyObject *lnotab*/ ); if (!py_code) goto bad; py_frame = PyFrame_New( PyThreadState_GET(), /*PyThreadState *tstate,*/ py_code, /*PyCodeObject *code,*/ py_globals, /*PyObject *globals,*/ 0 /*PyObject *locals*/ ); if (!py_frame) goto bad; py_frame->f_lineno = __pyx_lineno; PyTraceBack_Here(py_frame); bad: Py_XDECREF(py_srcfile); Py_XDECREF(py_funcname); Py_XDECREF(py_code); Py_XDECREF(py_frame); } static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { while (t->p) { #if PY_MAJOR_VERSION < 3 if (t->is_unicode) { *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); } else if (t->intern) { *t->p = PyString_InternFromString(t->s); } else { *t->p = PyString_FromStringAndSize(t->s, t->n - 1); } #else /* Python 3+ has unicode identifiers */ if (t->is_unicode | t->is_str) { if (t->intern) { *t->p = PyUnicode_InternFromString(t->s); } else if (t->encoding) { *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); } else { *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); } } else { *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); } #endif if (!*t->p) return -1; ++t; } return 0; } /* Type Conversion Functions */ static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { int is_true = x == Py_True; if (is_true | (x == Py_False) | (x == Py_None)) return is_true; else return PyObject_IsTrue(x); } static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) { PyNumberMethods *m; const char *name = NULL; PyObject *res = NULL; #if PY_VERSION_HEX < 0x03000000 if (PyInt_Check(x) || PyLong_Check(x)) #else if (PyLong_Check(x)) #endif return Py_INCREF(x), x; m = Py_TYPE(x)->tp_as_number; #if PY_VERSION_HEX < 0x03000000 if (m && m->nb_int) { name = "int"; res = PyNumber_Int(x); } else if (m && m->nb_long) { name = "long"; res = PyNumber_Long(x); } #else if (m && m->nb_int) { name = "int"; res = PyNumber_Long(x); } #endif if (res) { #if PY_VERSION_HEX < 0x03000000 if (!PyInt_Check(res) && !PyLong_Check(res)) { #else if (!PyLong_Check(res)) { #endif PyErr_Format(PyExc_TypeError, "__%s__ returned non-%s (type %.200s)", name, name, Py_TYPE(res)->tp_name); Py_DECREF(res); return NULL; } } else if (!PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "an integer is required"); } return res; } static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { Py_ssize_t ival; PyObject* x = PyNumber_Index(b); if (!x) return -1; ival = PyInt_AsSsize_t(x); Py_DECREF(x); return ival; } static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { #if PY_VERSION_HEX < 0x02050000 if (ival <= LONG_MAX) return PyInt_FromLong((long)ival); else { unsigned char *bytes = (unsigned char *) &ival; int one = 1; int little = (int)*(unsigned char*)&one; return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0); } #else return PyInt_FromSize_t(ival); #endif } static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) { unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x); if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) { return (size_t)-1; } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) { PyErr_SetString(PyExc_OverflowError, "value too large to convert to size_t"); return (size_t)-1; } return (size_t)val; } #endif /* Py_PYTHON_H */ traits-4.1.0/traits/protocols/_speedups.pyx0000644000175100001440000002227511674463323022107 0ustar ischnellusers00000000000000"""C Speedups for commonly-used operations""" __all__ = [ 'NO_ADAPTER_NEEDED', 'DOES_NOT_SUPPORT', 'adapt', 'Protocol__adapt__', 'metamethod', 'classicMRO', 'getMRO', 'Protocol__call__', ] cdef extern from "Python.h": int PyType_Check(object ob) int PyClass_Check(object ob) int PyInstance_Check(object ob) int PyObject_TypeCheck(object ob, object tp) int PyObject_IsInstance(object inst, object cls) int PyErr_ExceptionMatches(void *exc) void *PyExc_AttributeError void *PyObject_GetAttr(object ob, object attr) void PyErr_Clear() object PyString_InternFromString(char *v) object PyMethod_New(object func, object self, object cls) ctypedef struct PyTupleObject: void *ob_item # we don't use this, but we can't use 'pass' here ctypedef struct PyListObject: void *ob_item # we don't use this, but we can't use 'pass' here ctypedef struct PyTypeObject: PyTupleObject *tp_mro ctypedef struct PyObject: PyTypeObject *ob_type ctypedef struct PyClassObject: PyTupleObject *cl_bases ctypedef struct PyInstanceObject: PyClassObject *in_class int PyObject_IsSubclass(PyClassObject *derived, object cls) int PyList_Append(PyListObject *list, object item) except -1 int PyTuple_GET_SIZE(PyTupleObject *p) int PyList_GET_SIZE(PyListObject *p) int PyTuple_Check(object op) int PyList_Check(object op) # These macros return borrowed references, so we make them void * # When Pyrex casts them to objects, it will incref them void * PyTuple_GET_ITEM(PyTupleObject *p, int pos) void * PyList_GET_ITEM(PyListObject *p, int pos) PyTypeObject PyInstance_Type PyTypeObject PyBaseObject_Type void Py_DECREF(PyObject *p) object __Pyx_GetExcValue() cdef object _marker, __conform, __adapt, __mro, __ECType from sys import exc_info, exc_clear # Since we can't do "from future import absolute_import", we use __import__ # directly. Fake the globals dictionary with just the relevant information. In # an extension module, globals() returns the globals dictionary of the last # pure Python module that was executing. AdaptationFailure = __import__( 'protocols', globals=dict(__name__=__name__), fromlist=['AdaptationFailure'], level=1 ).AdaptationFailure try: from ExtensionClass import ExtensionClass __ECType = ExtensionClass except ImportError: __ECType = type _marker = object() __conform = PyString_InternFromString("__conform__") __adapt = PyString_InternFromString("__adapt__") __class = PyString_InternFromString("__class__") __mro = PyString_InternFromString("__mro__") # Fundamental Adapters def NO_ADAPTER_NEEDED(obj, protocol=None): """Assume 'obj' implements 'protocol' directly""" return obj def DOES_NOT_SUPPORT(obj, protocol=None): """Prevent 'obj' from supporting 'protocol'""" return None cdef class metamethod: """Wrapper for metaclass method that might be confused w/instance method""" cdef object func def __init__(self, func): self.func = func def __get__(self, ob, typ): if ob is None: return self return PyMethod_New(self.func, ob, typ) def __set__(self, ob, value): raise AttributeError("Read-only attribute") def __delete__(self, ob): raise AttributeError("Read-only attribute") cdef object _adapt(obj, protocol, default, factory): # We use nested 'if' blocks here because using 'and' causes Pyrex to # convert the return values to Python ints, and then back to booleans! cdef object tmp ### This code is superfluous and actually prevents certain old style code (like ### the Python VTK bindings) from working correctly... ### if PyType_Check(protocol): ### if PyObject_TypeCheck(obj, protocol): ### return obj ### ### if PyClass_Check(protocol): ### if PyInstance_Check(obj): ### if PyObject_IsInstance(obj,protocol): ### return obj if PyObject_IsInstance(obj,protocol): return obj try: meth = getattr(obj, __conform) try: result = meth(protocol) if result is not None: return result except TypeError, e: if exc_info()[2].tb_next is not None: raise except AttributeError, e: # Call exc_clear() instead of PyErr_Clear to make sure that the # sys.exc_* objects are also removed. This has caused some frames to # live too long. exc_clear() try: meth = getattr(protocol, __adapt) try: result = meth(obj) if result is not None: return result except TypeError: if exc_info()[2].tb_next is not None: raise except AttributeError, e: exc_clear() if default is _marker: if factory is not _marker: from warnings import warn warn("The 'factory' argument to 'adapt()' will be removed in 1.0", DeprecationWarning, 1) return factory(obj, protocol) raise AdaptationFailure("Can't adapt", obj, protocol) return default def adapt(obj, protocol, default=_marker, factory=_marker): """PEP 246-alike: Adapt 'obj' to 'protocol', return 'default' If 'default' is not supplied and no implementation is found, raise 'AdaptationFailure'.""" return _adapt(obj,protocol,default,factory) def Protocol__call__(self, ob, default=_marker): """Adapt to this protocol""" return _adapt(ob,self,default,_marker) cdef buildClassicMRO(PyClassObject *cls, PyListObject *list): cdef PyTupleObject *bases cdef int i PyList_Append(list, cls) bases = cls.cl_bases if bases: for i from 0 <= i < PyTuple_GET_SIZE(bases): tmp = PyTuple_GET_ITEM(bases, i) buildClassicMRO(tmp, list) def classicMRO(ob, extendedClassic=False): if PyClass_Check(ob): mro = [] buildClassicMRO(ob, mro) if extendedClassic: PyList_Append(mro, &PyInstance_Type) PyList_Append(mro, &PyBaseObject_Type) return mro raise TypeError("Not a classic class", ob) cdef buildECMRO(object cls, PyListObject *list): PyList_Append(list, cls) for i in cls.__bases__: buildECMRO(i, list) def extClassMRO(ob, extendedClassic=False): mro = [] buildECMRO(ob, mro) if extendedClassic: PyList_Append(mro, &PyInstance_Type) PyList_Append(mro, &PyBaseObject_Type) return mro def getMRO(ob, extendedClassic=False): if PyClass_Check(ob): return classicMRO(ob,extendedClassic) elif PyType_Check(ob): return ob.__mro__ elif PyObject_TypeCheck(ob,__ECType): return extClassMRO(ob, extendedClassic) return ob, def Protocol__adapt__(self, obj): cdef void *tmp cdef int i if PyInstance_Check(obj): cls = ((obj).in_class) else: # We use __class__ instead of type to support proxies try: cls = getattr(obj, __class) except AttributeError: # Some object have no __class__; use their type cls = (obj).ob_type mro = None if PyType_Check(cls): # It's a type, we can use its mro directly tmp = ((cls).tp_mro) if tmp != NULL: mro = tmp if mro is None: if PyClass_Check(cls): # It's a classic class, build up its MRO mro = [] buildClassicMRO(cls, mro) PyList_Append(mro, &PyInstance_Type) PyList_Append(mro, &PyBaseObject_Type) else: # Fallback to getting __mro__ (for e.g. security proxies/ExtensionClass) try: mro = getattr(cls, __mro) except Exception: # No __mro__? Is it an ExtensionClass? if PyObject_TypeCheck(cls,__ECType): # Yep, toss out the error and compute a reasonable MRO mro = extClassMRO(cls, 1) else: raise get = self._Protocol__adapters.get if PyTuple_Check(mro): #print "tuple",mro for i from 0 <= i < PyTuple_GET_SIZE(mro): cls = PyTuple_GET_ITEM(mro, i) factory=get(cls) if factory is not None: return factory[0](obj) elif PyList_Check(mro): #print "list",mro for i from 0 <= i < PyList_GET_SIZE(mro): cls = PyList_GET_ITEM(mro, i) factory=get(cls) if factory is not None: return factory[0](obj) else: #print "other",mro for cls in mro: factory=get(cls) if factory is not None: return factory[0](obj) traits-4.1.0/traits/protocols/api.py0000644000175100001440000000113411674463323020470 0ustar ischnellusers00000000000000"""Trivial Interfaces and Adaptation from PyProtocols. This package is a direct copy of a subset of the files from Phillip J. Eby's PyProtocols package. They are only included here to help remove dependencies on external packages from the Traits package. The only significant change is the inclusion of a setup.py file. """ from __future__ import absolute_import from .protocols import (adapt, declareAdapterForType, declareAdapterForProtocol, declareAdapterForObject, advise, declareImplementation, declareAdapter, adviseObject, InterfaceClass, Protocol, addClassAdvisor, AdaptationFailure) traits-4.1.0/traits/protocols/advice.py0000644000175100001440000002017111674463323021154 0ustar ischnellusers00000000000000from __future__ import absolute_import from types import ClassType, FunctionType, InstanceType import sys __all__ = [ 'addClassAdvisor', 'isClassAdvisor', 'metamethod', 'supermeta', 'minimalBases', 'determineMetaclass', 'getFrameInfo', 'getMRO', 'classicMRO', 'mkRef', 'StrongRef' ] def metamethod(func): """Wrapper for metaclass method that might be confused w/instance method""" return property(lambda ob: func.__get__(ob,ob.__class__)) try: from ExtensionClass import ExtensionClass except ImportError: ClassicTypes = ClassType else: ClassicTypes = ClassType, ExtensionClass def classicMRO(ob, extendedClassic=False): stack = [] push = stack.insert pop = stack.pop push(0,ob) while stack: cls = pop() yield cls p = len(stack) for b in cls.__bases__: push(p,b) if extendedClassic: yield InstanceType yield object def getMRO(ob, extendedClassic=False): if isinstance(ob,ClassicTypes): return classicMRO(ob,extendedClassic) elif isinstance(ob,type): return ob.__mro__ return ob, try: from ._speedups import metamethod, getMRO, classicMRO except ImportError: pass # property-safe 'super()' for Python 2.2; 2.3 can use super() instead def supermeta(typ,ob): starttype = type(ob) mro = starttype.__mro__ if typ not in mro: starttype = ob mro = starttype.__mro__ mro = iter(mro) for cls in mro: if cls is typ: mro = [cls.__dict__ for cls in mro] break else: raise TypeError("Not sub/supertypes:", starttype, typ) typ = type(ob) class theSuper(object): def __getattribute__(self,name): for d in mro: if name in d: descr = d[name] try: descr = descr.__get__ except AttributeError: return descr else: return descr(ob,typ) return object.__getattribute__(self,name) return theSuper() def getFrameInfo(frame): """Return (kind,module,locals,globals) for a frame 'kind' is one of "exec", "module", "class", "function call", or "unknown". """ f_locals = frame.f_locals f_globals = frame.f_globals sameNamespace = f_locals is f_globals hasModule = '__module__' in f_locals hasName = '__name__' in f_globals sameName = hasModule and hasName sameName = sameName and f_globals['__name__']==f_locals['__module__'] module = hasName and sys.modules.get(f_globals['__name__']) or None namespaceIsModule = module and module.__dict__ is f_globals if not namespaceIsModule: # some kind of funky exec kind = "exec" elif sameNamespace and not hasModule: kind = "module" elif sameName and not sameNamespace: kind = "class" elif not sameNamespace: kind = "function call" else: # How can you have f_locals is f_globals, and have '__module__' set? # This is probably module-level code, but with a '__module__' variable. kind = "unknown" return kind,module,f_locals,f_globals def addClassAdvisor(callback, depth=2): """Set up 'callback' to be passed the containing class upon creation This function is designed to be called by an "advising" function executed in a class suite. The "advising" function supplies a callback that it wishes to have executed when the containing class is created. The callback will be given one argument: the newly created containing class. The return value of the callback will be used in place of the class, so the callback should return the input if it does not wish to replace the class. The optional 'depth' argument to this function determines the number of frames between this function and the targeted class suite. 'depth' defaults to 2, since this skips this function's frame and one calling function frame. If you use this function from a function called directly in the class suite, the default will be correct, otherwise you will need to determine the correct depth yourself. This function works by installing a special class factory function in place of the '__metaclass__' of the containing class. Therefore, only callbacks *after* the last '__metaclass__' assignment in the containing class will be executed. Be sure that classes using "advising" functions declare any '__metaclass__' *first*, to ensure all callbacks are run.""" frame = sys._getframe(depth) kind, module, caller_locals, caller_globals = getFrameInfo(frame) if kind not in ("class", "exec"): raise SyntaxError( "Advice must be in the body of a class statement" ) previousMetaclass = caller_locals.get('__metaclass__') defaultMetaclass = caller_globals.get('__metaclass__', ClassType) def advise(name,bases,cdict): if '__metaclass__' in cdict: del cdict['__metaclass__'] if previousMetaclass is None: if bases: # find best metaclass or use global __metaclass__ if no bases meta = determineMetaclass(bases) else: meta = defaultMetaclass elif isClassAdvisor(previousMetaclass): # special case: we can't compute the "true" metaclass here, # so we need to invoke the previous metaclass and let it # figure it out for us (and apply its own advice in the process) meta = previousMetaclass else: meta = determineMetaclass(bases, previousMetaclass) newClass = meta(name,bases,cdict) # this lets the callback replace the class completely, if it wants to return callback(newClass) # introspection data only, not used by inner function advise.previousMetaclass = previousMetaclass advise.callback = callback # install the advisor caller_locals['__metaclass__'] = advise def isClassAdvisor(ob): """True if 'ob' is a class advisor function""" return isinstance(ob,FunctionType) and hasattr(ob,'previousMetaclass') def determineMetaclass(bases, explicit_mc=None): """Determine metaclass from 1+ bases and optional explicit __metaclass__""" meta = [getattr(b,'__class__',type(b)) for b in bases] if explicit_mc is not None: # The explicit metaclass needs to be verified for compatibility # as well, and allowed to resolve the incompatible bases, if any meta.append(explicit_mc) if len(meta)==1: # easy case return meta[0] candidates = minimalBases(meta) # minimal set of metaclasses if not candidates: # they're all "classic" classes return ClassType elif len(candidates)>1: # We could auto-combine, but for now we won't... raise TypeError("Incompatible metatypes",bases) # Just one, return it return candidates[0] def minimalBases(classes): """Reduce a list of base classes to its ordered minimum equivalent""" classes = [c for c in classes if c is not ClassType] candidates = [] for m in classes: for n in classes: if issubclass(n,m) and m is not n: break else: # m has no subclasses in 'classes' if m in candidates: candidates.remove(m) # ensure that we're later in the list candidates.append(m) return candidates from weakref import ref class StrongRef(object): """Like a weakref, but for non-weakrefable objects""" __slots__ = 'referent' def __init__(self,referent): self.referent = referent def __call__(self): return self.referent def __hash__(self): return hash(self.referent) def __eq__(self,other): return self.referent==other def __repr__(self): return 'StrongRef(%r)' % self.referent def mkRef(ob,*args): """Return either a weakref or a StrongRef for 'ob' Note that extra args are forwarded to weakref.ref() if applicable.""" try: return ref(ob,*args) except TypeError: return StrongRef(ob) traits-4.1.0/traits/protocols/README.txt0000644000175100001440000001270311674463323021047 0ustar ischnellusers00000000000000The files contained in this directory are from the pyprotocols project (http://peak.telecommunity.com/PyProtocols.html). Copyright (C) 2003, Phillip J. Eby This project's original licensing terms (as stated in the upstream README.txt) are compatible with the enthought software licensing terms. +++++++++ Upstream README.txt ++++++++++++++++++++++++++++++++++++++++++++++++++ PyProtocols Release 0.9.3 (release candidate 1) Copyright (C) 2003 by Phillip J. Eby. All rights reserved. This software may be used under the same terms as Zope or Python. THERE ARE ABSOLUTELY NO WARRANTIES OF ANY KIND. Package Description Do you hate having to write lots of if-then logic to test what type something is? Wouldn't it be nice if you could just declare "I want this object to have this behavior" and magically convert whatever value you have, to the type you need? PyProtocols lets you do just that, cleanly, quickly, and robustly -- even with built-in types or other people's classes. PyProtocols extends the PEP 246 adapt() function with a new "declaration API" that lets you easily define your own interfaces and adapters, and declare what adapters should be used to adapt what types, objects, or interfaces. In addition to its own Interface type, PyProtocols can also use Twisted and Zope's Interface types. (Of course, since Twisted and Zope interfaces aren't as flexible, only a subset of the PyProtocols API works with them. Specific limitations are listed in the documentation.) If you're familiar with Interface objects in Zope, Twisted, or PEAK, the Interface objects in PyProtocols are very similar. But, they can also do many things that no other Python interface types can do. For example, PyProtocols supports "subsetting" of interfaces, where you can declare that one interface is a subset of another existing interface. This is like declaring that somebody else's existing interface is actually a subclass of the new interface. Twisted and Zope don't allow this, which makes them very hard to use if you're trying to define interfaces like "Read-only Mapping" as a subset of "Mapping Object". Unlike Zope and Twisted, PyProtocols also doesn't force you to use a particular interface coding style or even a specific interface type. You can use its built-in interface types, or define your own. If there's another Python package out there with interface types that you'd like to use (CORBA? COM?), you can even create your own adapters to make them work with the PyProtocols API. PyProtocols is also the only interface package that supports automatic "transitive adaptation". That is, if you define an adapter from interface A to interface B, and another from B to C, PyProtocols automatically creates and registers a new adapter from A to C for you. If you later declare an explicit adapter from A to C, it silently replaces the automatically created one. PyProtocols may be used, modified, and distributed under the same terms and conditions as Python or Zope. Version 0.9.3 Release Notes For **important** notes on upgrading from previous releases, and information about changes coming in 1.0, please see the UPGRADING.txt file. For the complete list of changes from 0.9.2, please see the CHANGES.txt file. Note that the 0.9.x release series is now in "maintenance mode", and no new features will be added in future 0.9.x releases. From now on, new features will only be added to the 1.x releases, beginning with 1.0a1 later this year. If you'd like to use Zope interfaces with PyProtocols, you must use Zope X3 beta 1 or later, as PyProtocols' Zope support uses the latest Zope interface declaration API. If you'd like to use Twisted interfaces with PyProtocols, you must use Twisted 1.0.5 or later. Obtaining the Package and Documentation Please see the "PyProtocols Home Page":http://peak.telecommunity.com/PyProtocols.html for download links, CVS links, reference manuals, etc. Installation Instructions Python 2.2.2 or better is required. To install, just unpack the archive, go to the directory containing 'setup.py', and run:: python setup.py install PyProtocols will be installed in the 'site-packages' directory of your Python installation. (Unless directed elsewhere; see the "Installing Python Modules" section of the Python manuals for details on customizing installation locations, etc.). (Note: for the Win32 installer release, just run the .exe file.) If you wish to run the associated test suite, you can also run:: python setup.py test which will verify the correct installation and functioning of the package. PyProtocols includes an optional speed-enhancing module written in Pyrex and C. If you do not have a C compiler available, you can disable installation of the C module by invoking 'setup.py' with '--without-speedups', e.g.:: python setup.py --without-speedups install or:: python setup.py --without-speedups test You do not need to worry about this if you are using the Win32 binary installer, since it includes a pre-compiled speedups module. Note: if you have installed Pyrex on your Python path, be sure it is Pyrex version 0.7.2. You do *not* have to have Pyrex installed, even to build the C extension, but if you do have it installed, make sure it's up to date before building the C extension. traits-4.1.0/traits/protocols/generate.py0000644000175100001440000001303611674463323021515 0ustar ischnellusers00000000000000"""Autogenerated protocols from type+method names, URI, sequence, etc.""" from __future__ import absolute_import #from interfaces import Protocol, allocate_lock, Interface from .protocols import (Protocol, allocate_lock, Interface, declareAdapterForProtocol, declareAdapterForType, declareAdapter, adapt, NO_ADAPTER_NEEDED) from .advice import metamethod, supermeta #from api import declareAdapterForProtocol, declareAdapterForType #from api import declareAdapter, adapt #from adapters import NO_ADAPTER_NEEDED __all__ = [ 'protocolForType', 'protocolForURI', 'sequenceOf', 'IBasicSequence', 'URIProtocol', 'TypeSubset', 'WeakSubset', 'ADAPT_SEQUENCE', 'SequenceProtocol' ] class URIProtocol(Protocol): """Protocol representing a URI, UUID, or other unique textual identifier""" def __init__(self,uri): self.URI = uri Protocol.__init__(self) def __repr__(self): return "URIProtocol(%r)" % self.URI def __reduce__(self): return protocolForURI, (self.URI,) class TypeSubset(Protocol): """Protocol representing some set of a type's methods""" def __init__(self,baseType,methods): self.baseType = baseType self.methods = methods Protocol.__init__(self) def __repr__(self): return "TypeSubset(%r,%r)" % (self.baseType,self.methods) def __reduce__(self): return protocolForType, (self.baseType, self.methods, False) class WeakSubset(TypeSubset,object): """TypeSubset that accepts any object with the right attributes""" __metaclass__ = type # new-style so we can use super() def __adapt__(self,ob): result = supermeta(TypeSubset,self).__adapt__(ob) if result is not None: return result for name in self.methods: if not hasattr(ob,name): return None else: return ob __adapt__ = metamethod(__adapt__) def __repr__(self): return "WeakSubset(%r,%r)" % (self.baseType,self.methods) def __reduce__(self): return protocolForType, (self.baseType, self.methods, True) class SequenceProtocol(Protocol): """Protocol representing a "sequence of" some base protocol""" def __init__(self,baseProtocol): self.baseProtocol = baseProtocol Protocol.__init__(self) def __repr__(self): return "sequenceOf(%r)" % self.baseProtocol def __reduce__(self): return sequenceOf, (self.baseProtocol,) class IBasicSequence(Interface): """Non-string, iterable object sequence""" def __iter__(): """Return an iterator over the sequence""" declareAdapter( NO_ADAPTER_NEEDED, provides=[IBasicSequence], forTypes=[list,tuple] ) def ADAPT_SEQUENCE(ob, proto): """Convert iterable 'ob' into list of objects implementing 'proto'""" marker = object() out = [] proto = proto.baseProtocol # get the protocol to adapt to for item in ob: item = adapt(item,proto, marker) if item is marker: return None # can't adapt unless all members adapt out.append(item) return out __registryLock = allocate_lock() registry = {} def protocolForURI(uri): """Return a unique protocol object representing the supplied URI/UUID""" __registryLock.acquire() try: try: return registry[uri] except KeyError: proto = registry[uri] = URIProtocol(uri) return proto finally: __registryLock.release() def protocolForType(baseType, methods=(), implicit=False): """Return a protocol representing a subset of methods of a specific type""" # Normalize 'methods' to a sorted tuple w/no duplicate names methods = dict([(k,k) for k in methods]).keys() methods.sort() methods = tuple(methods) key = baseType, methods, (not not implicit) # ensure implicit is true/false return __protocolForType(key) def sequenceOf(baseProtocol): """Return a protocol representing an sequence of a given base protocol""" key = (sequenceOf, baseProtocol) __registryLock.acquire() try: try: return registry[key] except KeyError: proto = registry[key] = SequenceProtocol(baseProtocol) declareAdapterForProtocol( proto, lambda o: ADAPT_SEQUENCE(o,proto), IBasicSequence ) return proto finally: __registryLock.release() def __protocolForType(key): """Recursive implementation of protocolForType; assumes standardized key""" __registryLock.acquire() try: try: return registry[key] except KeyError: baseType, methods, implicit = key if implicit: proto = WeakSubset(baseType,methods) else: proto = TypeSubset(baseType,methods) registry[key] = proto finally: __registryLock.release() # declare that proto implies all subset-method protocols if len(methods)>1: for method in methods: subset = tuple([m for m in methods if m!=method]) implied = __protocolForType((baseType, subset, implicit)) declareAdapterForProtocol(implied, NO_ADAPTER_NEEDED, proto) # declare that explicit form implies implicit form if implicit: impliedBy = __protocolForType((baseType, methods, False)) declareAdapterForProtocol(proto, NO_ADAPTER_NEEDED, impliedBy) # declare that baseType implements this protocol declareAdapterForType(proto, NO_ADAPTER_NEEDED, baseType) return proto traits-4.1.0/traits/protocols/__init__.py0000644000175100001440000000055511674463323021464 0ustar ischnellusers00000000000000"""Trivial Interfaces and Adaptation from PyProtocols. This package is a subset of the files from Phillip J. Eby's PyProtocols package. They are only included here to help remove dependencies on external packages from the Traits package. The code has been reorganized to address circular imports that were discovered when explicit relative imports were added. """ traits-4.1.0/traits/protocols/protocols.py0000644000175100001440000006411111674463323021747 0ustar ischnellusers00000000000000"""Basic Adapters and Adapter Operations""" from __future__ import absolute_import, generators __all__ = [ 'NO_ADAPTER_NEEDED','DOES_NOT_SUPPORT', 'Adapter', 'minimumAdapter', 'composeAdapters', 'updateWithSimplestAdapter', 'StickyAdapter', 'AdaptationFailure', 'bindAdapter', 'adapt', 'declareAdapterForType', 'declareAdapterForProtocol', 'declareAdapterForObject', 'advise', 'declareImplementation', 'declareAdapter', 'adviseObject', 'Protocol', 'InterfaceClass', 'Interface', 'AbstractBase', 'AbstractBaseMeta', 'IAdapterFactory', 'IProtocol', 'IAdaptingProtocol', 'IOpenProtocol', 'IOpenProvider', 'IOpenImplementor', 'IImplicationListener', 'Attribute', 'Variation' ] from types import FunctionType, ClassType, MethodType try: PendingDeprecationWarning except NameError: class PendingDeprecationWarning(Warning): 'Base class for warnings about features which will be deprecated in the future.' class AdaptationFailure(NotImplementedError,TypeError): """A suitable implementation/adapter could not be found""" _marker = object() # Fundamental Adapters def NO_ADAPTER_NEEDED(obj, protocol=None): """Assume 'obj' implements 'protocol' directly""" return obj def DOES_NOT_SUPPORT(obj, protocol=None): """Prevent 'obj' from supporting 'protocol'""" return None try: from ._speedups import NO_ADAPTER_NEEDED, DOES_NOT_SUPPORT except ImportError: pass def _getProto(self): from warnings import warn warn("The 'protocol' attribute of Adapter subclass %s is being used" % (self.__class__,), DeprecationWarning, 2) return self.__dict__['protocol'] def _setProto(self,proto): self.__dict__['protocol'] = proto class Adapter(object): """Convenient base class for adapters""" protocol = property(_getProto,_setProto) def __init__(self, ob, proto): self.subject = ob self.protocol = proto class StickyAdapter(object): """Adapter that attaches itself to its subject for repeated use""" attachForProtocols = () protocol = property(_getProto,_setProto) def __init__(self, ob, proto): self.subject = ob self.protocol = proto # Declare this instance as a per-instance adaptation for the # given protocol provides = list(self.attachForProtocols) if proto is not None and proto not in provides: provides.append(proto) # from protocols.api import declareAdapter declareAdapter(lambda s: self, provides, forObjects=[ob]) # Adapter "arithmetic" def minimumAdapter(a1,a2,d1=0,d2=0): """Shortest route to implementation, 'a1' @ depth 'd1', or 'a2' @ 'd2'? Assuming both a1 and a2 are interchangeable adapters (i.e. have the same source and destination protocols), return the one which is preferable; that is, the one with the shortest implication depth, or, if the depths are equal, then the adapter that is composed of the fewest chained adapters. If both are the same, then prefer 'NO_ADAPTER_NEEDED', followed by anything but 'DOES_NOT_SUPPORT', with 'DOES_NOT_SUPPORT' being least preferable. If there is no unambiguous choice, and 'not a1 is a2', TypeError is raised. """ if d1=maxargs: newAdapter = lambda ob: adapter(ob,proto) newAdapter.__adapterCount__ = getattr( adapter,'__adapterCount__',1 ) newAdapter.__unbound_adapter__ = adapter if f not in (Adapter.__init__.im_func, StickyAdapter.__init__.im_func): from warnings import warn warn("Adapter %r to protocol %r needs multiple arguments" % (adapter,proto), PendingDeprecationWarning, 6) return newAdapter return adapter def updateWithSimplestAdapter(mapping, key, adapter, depth): """Replace 'mapping[key]' w/'adapter' @ 'depth', return true if changed""" new = adapter old = mapping.get(key) if old is not None: old, oldDepth = old new = minimumAdapter(old,adapter,oldDepth,depth) if old is new and depth>=oldDepth: return False mapping[key] = new, depth return True """Implement Interfaces and define the interfaces used by the package""" #import api from .advice import metamethod, classicMRO, mkRef #from adapters \ # import composeAdapters, updateWithSimplestAdapter, NO_ADAPTER_NEEDED, \ # DOES_NOT_SUPPORT from types import InstanceType # Thread locking support: try: from thread import allocate_lock except ImportError: try: from dummy_thread import allocate_lock except ImportError: class allocate_lock(object): __slots__ = () def acquire(*args): pass def release(*args): pass # Trivial interface implementation: class Protocol: """Generic protocol w/type-based adapter registry""" def __init__(self): self.__adapters = {} self.__implies = {} self.__listeners = None self.__lock = allocate_lock() def getImpliedProtocols(self): # This is messy so it can clean out weakrefs, but this method is only # called for declaration activities and is thus not at all # speed-critical. It's more important that we support weak refs to # implied protocols, so that dynamically created subset protocols can # be garbage collected. out = [] add = out.append self.__lock.acquire() # we might clean out dead weakrefs try: for k,v in self.__implies.items(): proto = k() if proto is None: del self.__implies[k] else: add((proto,v)) return out finally: self.__lock.release() def addImpliedProtocol(self,proto,adapter=NO_ADAPTER_NEEDED,depth=1): self.__lock.acquire() try: key = mkRef(proto) if not updateWithSimplestAdapter( self.__implies, key, adapter, depth ): return self.__implies[key][0] finally: self.__lock.release() # Always register implied protocol with classes, because they should # know if we break the implication link between two protocols for klass,(baseAdapter,d) in self.__adapters.items(): # api.declareAdapterForType( declareAdapterForType( proto,composeAdapters(baseAdapter,self,adapter),klass,depth+d ) if self.__listeners: for listener in self.__listeners.keys(): # Must use keys()! listener.newProtocolImplied(self, proto, adapter, depth) return adapter addImpliedProtocol = metamethod(addImpliedProtocol) def registerImplementation(self,klass,adapter=NO_ADAPTER_NEEDED,depth=1): self.__lock.acquire() try: if not updateWithSimplestAdapter( self.__adapters,klass,adapter,depth ): return self.__adapters[klass][0] finally: self.__lock.release() if adapter is DOES_NOT_SUPPORT: # Don't register non-support with implied protocols, because # "X implies Y" and "not X" doesn't imply "not Y". In effect, # explicitly registering DOES_NOT_SUPPORT for a type is just a # way to "disinherit" a superclass' claim to support something. return adapter for proto, (extender,d) in self.getImpliedProtocols(): # api.declareAdapterForType( declareAdapterForType( proto, composeAdapters(adapter,self,extender), klass, depth+d ) return adapter registerImplementation = metamethod(registerImplementation) def registerObject(self, ob, adapter=NO_ADAPTER_NEEDED,depth=1): # Object needs to be able to handle registration # if api.adapt(ob,IOpenProvider).declareProvides(self,adapter,depth): if adapt(ob,IOpenProvider).declareProvides(self,adapter,depth): if adapter is DOES_NOT_SUPPORT: return # non-support doesn't imply non-support of implied # Handle implied protocols for proto, (extender,d) in self.getImpliedProtocols(): # api.declareAdapterForObject( declareAdapterForObject( proto, composeAdapters(adapter,self,extender), ob, depth+d ) registerObject = metamethod(registerObject) def __adapt__(self, obj): get = self.__adapters.get try: typ = obj.__class__ except AttributeError: typ = type(obj) try: mro = typ.__mro__ except AttributeError: # Note: this adds 'InstanceType' and 'object' to end of MRO mro = classicMRO(typ,extendedClassic=True) for klass in mro: factory=get(klass) if factory is not None: return factory[0](obj) try: from ._speedups import Protocol__adapt__ as __adapt__ except ImportError: pass __adapt__ = metamethod(__adapt__) def addImplicationListener(self, listener): self.__lock.acquire() try: if self.__listeners is None: from weakref import WeakKeyDictionary self.__listeners = WeakKeyDictionary() self.__listeners[listener] = 1 finally: self.__lock.release() addImplicationListener = metamethod(addImplicationListener) # def __call__(self, ob, default=api._marker): def __call__(self, ob, default=_marker): """Adapt to this protocol""" # return api.adapt(ob,self,default) return adapt(ob,self,default) # Use faster __call__ method, if possible # XXX it could be even faster if the __call__ were in the tp_call slot # XXX directly, but Pyrex doesn't have a way to do that AFAIK. try: from ._speedups import Protocol__call__ except ImportError: pass else: from new import instancemethod Protocol.__call__ = instancemethod(Protocol__call__, None, Protocol) class AbstractBaseMeta(Protocol, type): """Metaclass for 'AbstractBase' - a protocol that's also a class (Note that this should not be used as an explicit metaclass - always subclass from 'AbstractBase' or 'Interface' instead.) """ def __init__(self, __name__, __bases__, __dict__): type.__init__(self, __name__, __bases__, __dict__) Protocol.__init__(self) for b in __bases__: if isinstance(b,AbstractBaseMeta) and b.__bases__<>(object,): self.addImpliedProtocol(b) def __setattr__(self,attr,val): # We could probably support changing __bases__, as long as we checked # that no bases are *removed*. But it'd be a pain, since we'd # have to do callbacks, remove entries from our __implies registry, # etc. So just punt for now. if attr=='__bases__': raise TypeError( "Can't change interface __bases__", self ) type.__setattr__(self,attr,val) __call__ = type.__call__ class AbstractBase(object): """Base class for a protocol that's a class""" __metaclass__ = AbstractBaseMeta class InterfaceClass(AbstractBaseMeta): """Metaclass for 'Interface' - a non-instantiable protocol (Note that this should not be used as an explicit metaclass - always subclass from 'AbstractBase' or 'Interface' instead.) """ def __call__(self, *__args, **__kw): if self.__init__ is Interface.__init__: return Protocol.__call__(self,*__args, **__kw) else: return type.__call__(self,*__args, **__kw) def getBases(self): return [ b for b in self.__bases__ if isinstance(b,AbstractBaseMeta) and b.__bases__<>(object,) ] class Interface(object): __metaclass__ = InterfaceClass class Variation(Protocol): """A variation of a base protocol - "inherits" the base's adapters See the 'LocalProtocol' example in the reference manual for more info. """ def __init__(self, baseProtocol, context = None): self.baseProtocol = baseProtocol self.context = context # Note: Protocol is a ``classic'' class, so we don't use super() Protocol.__init__(self) # api.declareAdapterForProtocol(self,NO_ADAPTER_NEEDED,baseProtocol) declareAdapterForProtocol(self,NO_ADAPTER_NEEDED,baseProtocol) def __repr__(self): if self.context is None: return "Variation(%r)" % self.baseProtocol return "Variation(%r,%r)" % (self.baseProtocol, self.context) # Semi-backward compatible 'interface.Attribute' class Attribute(object): """Attribute declaration; should we get rid of this?""" def __init__(self,doc,name=None,value=None): self.__doc__ = doc self.name = name self.value = value def __get__(self,ob,typ=None): if ob is None: return self if not self.name: raise NotImplementedError("Abstract attribute") try: return ob.__dict__[self.name] except KeyError: return self.value def __set__(self,ob,val): if not self.name: raise NotImplementedError("Abstract attribute") ob.__dict__[self.name] = val def __delete__(self,ob): if not self.name: raise NotImplementedError("Abstract attribute") del ob.__dict__[self.name] def __repr__(self): return "Attribute: %s" % self.__doc__ # Interfaces and adapters for declaring protocol/type/object relationships class IAdapterFactory(Interface): """Callable that can adapt an object to a protocol""" def __call__(ob): """Return an implementation of protocol for 'ob'""" class IProtocol(Interface): """Object usable as a protocol by 'adapt()'""" def __hash__(): """Protocols must be usable as dictionary keys""" def __eq__(other): """Protocols must be comparable with == and !=""" def __ne__(other): """Protocols must be comparable with == and !=""" class IAdaptingProtocol(IProtocol): """A protocol that potentially knows how to adapt some object to itself""" def __adapt__(ob): """Return 'ob' adapted to protocol, or 'None'""" class IConformingObject(Interface): """An object that potentially knows how to adapt to a protocol""" def __conform__(protocol): """Return an implementation of 'protocol' for self, or 'None'""" class IOpenProvider(Interface): """An object that can be told how to adapt to protocols""" def declareProvides(protocol, adapter=NO_ADAPTER_NEEDED, depth=1): """Register 'adapter' as providing 'protocol' for this object Return a true value if the provided adapter is the "shortest path" to 'protocol' for the object, or false if a shorter path already existed. """ class IOpenImplementor(Interface): """Object/type that can be told how its instances adapt to protocols""" def declareClassImplements(protocol, adapter=NO_ADAPTER_NEEDED, depth=1): """Register 'adapter' as implementing 'protocol' for instances""" class IOpenProtocol(IAdaptingProtocol): """A protocol that be told what it implies, and what supports it Note that these methods are for the use of the declaration APIs only, and you should NEVER call them directly.""" def addImpliedProtocol(proto, adapter=NO_ADAPTER_NEEDED, depth=1): """'adapter' provides conversion from this protocol to 'proto'""" def registerImplementation(klass, adapter=NO_ADAPTER_NEEDED, depth=1): """'adapter' provides protocol for instances of klass""" def registerObject(ob, adapter=NO_ADAPTER_NEEDED, depth=1): """'adapter' provides protocol for 'ob' directly""" def addImplicationListener(listener): """Notify 'listener' whenever protocol has new implied protocol""" class IImplicationListener(Interface): def newProtocolImplied(srcProto, destProto, adapter, depth): """'srcProto' now implies 'destProto' via 'adapter' at 'depth'""" """Adapter and Declaration API""" from sys import _getframe, exc_info, modules from types import ClassType ClassTypes = ( ClassType, type ) #from adapters \ # import NO_ADAPTER_NEEDED, DOES_NOT_SUPPORT, AdaptationFailure # #from adapters \ # import bindAdapter from .advice import addClassAdvisor, getFrameInfo #from interfaces \ # import IOpenProtocol, IOpenProvider, IOpenImplementor, Protocol, \ # InterfaceClass, Interface def adapt(obj, protocol, default=_marker, factory=_marker): """PEP 246-alike: Adapt 'obj' to 'protocol', return 'default' If 'default' is not supplied and no implementation is found, the result of 'factory(obj,protocol)' is returned. If 'factory' is also not supplied, 'NotImplementedError' is then raised.""" if isinstance(protocol,ClassTypes) and isinstance(obj,protocol): return obj try: _conform = obj.__conform__ except AttributeError: pass else: try: result = _conform(protocol) if result is not None: return result except TypeError: if exc_info()[2].tb_next is not None: raise try: _adapt = protocol.__adapt__ except AttributeError: pass else: try: result = _adapt(obj) if result is not None: return result except TypeError: if exc_info()[2].tb_next is not None: raise if default is _marker: if factory is not _marker: from warnings import warn warn("The 'factory' argument to 'adapt()' will be removed in 1.0", DeprecationWarning, 2) return factory(obj, protocol) raise AdaptationFailure("Can't adapt", obj, protocol) return default try: from ._speedups import adapt except ImportError: pass # Fundamental, explicit interface/adapter declaration API: # All declarations should end up passing through these three routines. def declareAdapterForType(protocol, adapter, typ, depth=1): """Declare that 'adapter' adapts instances of 'typ' to 'protocol'""" adapter = bindAdapter(adapter,protocol) adapter = adapt(protocol, IOpenProtocol).registerImplementation( typ, adapter, depth ) oi = adapt(typ, IOpenImplementor, None) if oi is not None: oi.declareClassImplements(protocol,adapter,depth) def declareAdapterForProtocol(protocol, adapter, proto, depth=1): """Declare that 'adapter' adapts 'proto' to 'protocol'""" adapt(protocol, IOpenProtocol) # src and dest must support IOpenProtocol adapt(proto, IOpenProtocol).addImpliedProtocol(protocol, bindAdapter(adapter,protocol), depth) def declareAdapterForObject(protocol, adapter, ob, depth=1): """Declare that 'adapter' adapts 'ob' to 'protocol'""" adapt(protocol,IOpenProtocol).registerObject(ob,bindAdapter(adapter,protocol),depth) # Bootstrap APIs to work with Protocol and InterfaceClass, without needing to # give Protocol a '__conform__' method that's hardwired to IOpenProtocol. # Note that InterfaceClass has to be registered first, so that when the # registration propagates to IAdaptingProtocol and IProtocol, InterfaceClass # will already be recognized as an IOpenProtocol, preventing infinite regress. IOpenProtocol.registerImplementation(InterfaceClass) # VERY BAD!! IOpenProtocol.registerImplementation(Protocol) # NEVER DO THIS!! # From this line forward, the declaration APIs can work. Use them instead! # Interface and adapter declarations - convenience forms, explicit targets def declareAdapter(factory, provides, forTypes=(), forProtocols=(), forObjects=() ): """'factory' is an IAdapterFactory providing 'provides' protocols""" for protocol in provides: for typ in forTypes: declareAdapterForType(protocol, factory, typ) for proto in forProtocols: declareAdapterForProtocol(protocol, factory, proto) for ob in forObjects: declareAdapterForObject(protocol, factory, ob) def declareImplementation(typ, instancesProvide=(), instancesDoNotProvide=()): """Declare information about a class, type, or 'IOpenImplementor'""" for proto in instancesProvide: declareAdapterForType(proto, NO_ADAPTER_NEEDED, typ) for proto in instancesDoNotProvide: declareAdapterForType(proto, DOES_NOT_SUPPORT, typ) def adviseObject(ob, provides=(), doesNotProvide=()): """Tell an object what it does or doesn't provide""" for proto in provides: declareAdapterForObject(proto, NO_ADAPTER_NEEDED, ob) for proto in doesNotProvide: declareAdapterForObject(proto, DOES_NOT_SUPPORT, ob) # And now for the magic function... def advise(**kw): kw = kw.copy() frame = _getframe(1) kind, module, caller_locals, caller_globals = getFrameInfo(frame) if kind=="module": moduleProvides = kw.setdefault('moduleProvides',()) del kw['moduleProvides'] for k in kw: raise TypeError( "Invalid keyword argument for advising modules: %s" % k ) adviseObject(module, provides=moduleProvides ) return elif kind!="class": raise SyntaxError( "protocols.advise() must be called directly in a class or" " module body, not in a function or exec." ) classProvides = kw.setdefault('classProvides',()) classDoesNotProvide = kw.setdefault('classDoesNotProvide',()) instancesProvide = kw.setdefault('instancesProvide',()) instancesDoNotProvide = kw.setdefault('instancesDoNotProvide',()) asAdapterForTypes = kw.setdefault('asAdapterForTypes',()) asAdapterForProtocols = kw.setdefault('asAdapterForProtocols',()) protocolExtends = kw.setdefault('protocolExtends',()) protocolIsSubsetOf = kw.setdefault('protocolIsSubsetOf',()) factoryMethod = kw.setdefault('factoryMethod',None) equivalentProtocols = kw.setdefault('equivalentProtocols',()) map(kw.__delitem__,"classProvides classDoesNotProvide instancesProvide" " instancesDoNotProvide asAdapterForTypes asAdapterForProtocols" " protocolExtends protocolIsSubsetOf factoryMethod equivalentProtocols" .split()) for k in kw: raise TypeError( "Invalid keyword argument for advising classes: %s" % k ) def callback(klass): if classProvides or classDoesNotProvide: adviseObject(klass, provides=classProvides, doesNotProvide=classDoesNotProvide ) if instancesProvide or instancesDoNotProvide: declareImplementation(klass, instancesProvide=instancesProvide, instancesDoNotProvide=instancesDoNotProvide ) if asAdapterForTypes or asAdapterForProtocols: if not instancesProvide: raise TypeError( "When declaring an adapter, you must specify what" " its instances will provide." ) if factoryMethod: factory = getattr(klass,factoryMethod) else: factory = klass declareAdapter(factory, instancesProvide, forTypes=asAdapterForTypes, forProtocols=asAdapterForProtocols ) elif factoryMethod: raise TypeError( "'factoryMethod' is only used when declaring an adapter type" ) if protocolExtends: declareAdapter(NO_ADAPTER_NEEDED, protocolExtends, forProtocols=[klass] ) if protocolIsSubsetOf: declareAdapter(NO_ADAPTER_NEEDED, [klass], forProtocols=protocolIsSubsetOf ) if equivalentProtocols: declareAdapter( NO_ADAPTER_NEEDED, equivalentProtocols, forProtocols=[klass] ) declareAdapter( NO_ADAPTER_NEEDED, [klass], forProtocols=equivalentProtocols ) return klass addClassAdvisor(callback) traits-4.1.0/traits/protocols/classic.py0000644000175100001440000001226611674463323021350 0ustar ischnellusers00000000000000"""Declaration support for Python built-in types""" from __future__ import absolute_import __all__ = ['ProviderMixin'] from types import FunctionType, ModuleType, InstanceType, ClassType from .protocols import (IImplicationListener, IOpenProvider, NO_ADAPTER_NEEDED, advise, updateWithSimplestAdapter, composeAdapters, declareAdapterForObject) from new import instancemethod from .advice import getMRO, metamethod, mkRef class ProviderMixin: """Mixin to support per-instance declarations""" advise( instancesProvide=[IOpenProvider, IImplicationListener] ) def declareProvides(self,protocol,adapter=NO_ADAPTER_NEEDED,depth=1): registry = self.__dict__.get('__protocols_provided__') if registry is None: self.__protocols_provided__ = registry = {} if updateWithSimplestAdapter(registry,protocol,adapter,depth): adapt(protocol,IOpenProtocol).addImplicationListener(self) return True declareProvides = metamethod(declareProvides) def newProtocolImplied(self, srcProto, destProto, adapter, depth): registry = self.__dict__.get('__protocols_provided__',()) if srcProto not in registry: return baseAdapter, d = registry[srcProto] adapter = composeAdapters(baseAdapter,srcProto,adapter) declareAdapterForObject( destProto, adapter, self, depth+d ) newProtocolImplied = metamethod(newProtocolImplied) def __conform__(self,protocol): for cls in getMRO(self): conf = cls.__dict__.get('__protocols_provided__',()) if protocol in conf: return conf[protocol][0](self) __conform__ = metamethod(__conform__) class conformsRegistry(dict): """Helper type for objects and classes that need registration support""" def __call__(self, protocol): # This only gets called for non-class objects if protocol in self: subject = self.subject() if subject is not None: return self[protocol][0](subject) def findImplementation(self, subject, protocol, checkSelf=True): for cls in getMRO(subject): conf = cls.__dict__.get('__conform__') if conf is None: continue if not isinstance(conf,conformsRegistry): raise TypeError( "Incompatible __conform__ in base class", conf, cls ) if protocol in conf: return conf[protocol][0](subject) def newProtocolImplied(self, srcProto, destProto, adapter, depth): subject = self.subject() if subject is None or srcProto not in self: return baseAdapter, d = self[srcProto] adapter = composeAdapters(baseAdapter,srcProto,adapter) declareAdapterForObject( destProto, adapter, subject, depth+d ) def __hash__(self): # Need this because dictionaries aren't hashable, but we need to # be referenceable by a weak-key dictionary return id(self) def __get__(self,ob,typ=None): if ob is not None: raise AttributeError( "__conform__ registry does not pass to instances" ) # Return a bound method that adds the retrieved-from class to the return instancemethod(self.findImplementation, typ, type(typ)) def __getstate__(self): return self.subject(), self.items() def __setstate__(self,(subject,items)): self.clear() self.update(dict(items)) self.subject = mkRef(subject) class MiscObjectsAsOpenProvider(object): """Supply __conform__ registry for funcs, modules, & classic instances""" advise( instancesProvide=[IOpenProvider], asAdapterForTypes=[ FunctionType, ModuleType, InstanceType, ClassType, type, object ] ) def __init__(self,ob): obs = list(getMRO(ob)) for item in obs: try: reg = item.__dict__.get('__conform__') if reg is None and obs==[ob]: # Make sure we don't obscure a method from the class! reg = getattr(item,'__conform__',None) except AttributeError: raise TypeError( "Only objects with dictionaries can use this adapter", ob ) if reg is not None and not isinstance(reg,conformsRegistry): raise TypeError( "Incompatible __conform__ on adapted object", ob, reg ) reg = ob.__dict__.get('__conform__') if reg is None: reg = ob.__conform__ = self.newRegistry(ob) self.ob = ob self.reg = reg def declareProvides(self, protocol, adapter=NO_ADAPTER_NEEDED, depth=1): if updateWithSimplestAdapter(self.reg, protocol, adapter, depth): adapt(protocol,IOpenProtocol).addImplicationListener(self.reg) return True def newRegistry(self,subject): # Create a registry that's also set up for inheriting declarations reg = conformsRegistry() reg.subject = mkRef(subject) return reg traits-4.1.0/traits/protocols/adapters.py0000644000175100001440000000042011674463323021517 0ustar ischnellusers00000000000000"""Basic Adapters and Adapter Operations""" from __future__ import absolute_import from .protocols import (NO_ADAPTER_NEEDED, DOES_NOT_SUPPORT, Adapter, minimumAdapter, composeAdapters, updateWithSimplestAdapter, StickyAdapter, AdaptationFailure, bindAdapter) traits-4.1.0/traits/api.py0000644000175100001440000001055711674463323016455 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # # Copyright (c) 2005, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in enthought/LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # # Author: David C. Morrill # Date: 12/06/2005 # #------------------------------------------------------------------------------ """ Pseudo-package for all of the core symbols from Traits and TraitsUI. Use this module for importing Traits names into your namespace. For example:: from traits.api import HasTraits """ from __future__ import absolute_import from .trait_base import Uninitialized, Undefined, Missing, Self, python_version from .trait_errors import TraitError, TraitNotificationError, DelegationError from .trait_notifiers import (push_exception_handler, pop_exception_handler, TraitChangeNotifyWrapper) from .category import Category from .traits import (CTrait, Trait, Property, TraitFactory, Default, Color, RGBColor, Font) from .trait_types import (Any, Generic, Int, Long, Float, Complex, Str, Title, Unicode, Bool, CInt, CLong, CFloat, CComplex, CStr, CUnicode, CBool, String, Regex, Code, HTML, Password, Callable, This, self, Function, Method, Class, Module, Python, ReadOnly, Disallow, missing, Constant, Delegate, DelegatesTo, PrototypedFrom, Expression, PythonValue, File, Directory, Range, Enum, Tuple, List, CList, Set, CSet, Dict, Instance, AdaptedTo, AdaptsTo, Event, Button, ToolbarButton, Either, Type, Symbol, WeakRef, Date, Time, false, true, undefined) from .trait_types import (ListInt, ListFloat, ListStr, ListUnicode, ListComplex, ListBool, ListFunction, ListMethod, ListClass, ListInstance, ListThis, DictStrAny, DictStrStr, DictStrInt, DictStrLong, DictStrFloat, DictStrBool, DictStrList) from .trait_types import (BaseInt, BaseLong, BaseFloat, BaseComplex, BaseStr, BaseUnicode, BaseBool, BaseCInt, BaseCLong, BaseCFloat, BaseCComplex, BaseCStr, BaseCUnicode, BaseCBool, BaseFile, BaseDirectory, BaseRange, BaseEnum, BaseTuple, BaseInstance) from .trait_types import UUID from .has_traits import (method, HasTraits, HasStrictTraits, HasPrivateTraits, Interface, SingletonHasTraits, SingletonHasStrictTraits, SingletonHasPrivateTraits, MetaHasTraits, Vetoable, VetoableEvent, implements, traits_super, on_trait_change, cached_property, property_depends_on) from .trait_handlers import (BaseTraitHandler, TraitType, TraitHandler, TraitRange, TraitString, TraitCoerceType, TraitCastType, TraitInstance, ThisClass, TraitClass, TraitFunction, TraitEnum, TraitPrefixList, TraitMap, TraitPrefixMap, TraitCompound, TraitList, TraitListObject, TraitListEvent, TraitSetObject, TraitSetEvent, TraitDict, TraitDictObject, TraitDictEvent, TraitTuple, NO_COMPARE, OBJECT_IDENTITY_COMPARE, RICH_COMPARE) from .trait_value import (BaseTraitValue, TraitValue, SyncValue, TypeValue, DefaultValue) from .adapter import Adapter, adapts from .trait_numeric import Array, CArray try: from . import has_traits as has_traits #--------------------------------------------------------------------------- # Patch the main traits module with the correct definition for the # ViewElements class: # NOTE: We do this in a try..except block because traits.ui depends on # the pyface module (part of the TraitsGUI package) which may not # necessarily be installed. Not having TraitsGUI means that the 'ui' # features of traits will not work. #--------------------------------------------------------------------------- from traitsui import view_elements has_traits.ViewElements = view_elements.ViewElements #------------------------------------------------------------------------------- # Patch the main traits module with the correct definition for the # ViewElement and ViewSubElement class: #------------------------------------------------------------------------------- has_traits.ViewElement = view_elements.ViewElement except ImportError: pass traits-4.1.0/traits/traits_listener.py0000644000175100001440000013623111674463323021115 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # Copyright (c) 2007, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in enthought/LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # # Author: David C. Morrill # Date: 03/05/2007 # #------------------------------------------------------------------------------- """ Defines classes used to implement and manage various trait listener patterns. """ #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from __future__ import absolute_import import re import string import weakref from weakref import WeakKeyDictionary from string import whitespace from types import MethodType from .has_traits import HasPrivateTraits from .trait_base import Undefined, Uninitialized from .traits import Property from .trait_types import Str, Int, Bool, Instance, List, Enum, Any from .trait_errors import TraitError from .trait_notifiers import TraitChangeNotifyWrapper #--------------------------------------------------------------------------- # Constants: #--------------------------------------------------------------------------- # The name of the dictionary used to store active listeners TraitsListener = '__traits_listener__' # End of String marker EOS = '\0' # Types of traits that can be listened to ANYTRAIT_LISTENER = '_register_anytrait' SIMPLE_LISTENER = '_register_simple' LIST_LISTENER = '_register_list' DICT_LISTENER = '_register_dict' SET_LISTENER = '_register_set' # Mapping from trait default value types to listener types type_map = { 5: LIST_LISTENER, 6: DICT_LISTENER, 9: SET_LISTENER } # Listener types: ANY_LISTENER = 0 SRC_LISTENER = 1 DST_LISTENER = 2 ListenerType = { 0: ANY_LISTENER, 1: DST_LISTENER, 2: DST_LISTENER, 3: SRC_LISTENER, 4: SRC_LISTENER } # Invalid destination ( object, name ) reference marker (i.e. ambiguous): INVALID_DESTINATION = ( None, None ) # Regular expressions used by the parser: simple_pat = re.compile( r'^([a-zA-Z_]\w*)(\.|:)([a-zA-Z_]\w*)$' ) name_pat = re.compile( r'([a-zA-Z_]\w*)\s*(.*)' ) # Characters valid in a traits name: name_chars = string.ascii_letters + string.digits + '_' #------------------------------------------------------------------------------- # Utility functions: #------------------------------------------------------------------------------- def indent ( text, first_line = True, n = 1, width = 4 ): """ Indent lines of text. Parameters ---------- text : str The text to indent. first_line : bool, optional If False, then the first line will not be indented. n : int, optional The level of indentation. width : int, optional The number of spaces in each level of indentation. Returns ------- indented : str """ lines = text.split( '\n' ) if not first_line: first = lines[0] lines = lines[1:] spaces = ' ' * (width * n) lines2 = [ spaces + x for x in lines ] if not first_line: lines2.insert( 0, first ) indented = '\n'.join( lines2 ) return indented #------------------------------------------------------------------------------- # Metadata filters: #------------------------------------------------------------------------------- def is_not_none ( value ): return (value is not None) def is_none ( value ): return (value is None) def not_event ( value ): return (value != 'event') #------------------------------------------------------------------------------- # 'ListenerBase' class: #------------------------------------------------------------------------------- class ListenerBase ( HasPrivateTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- # The handler to be called when any listened to trait is changed: #handler = Any # The dispatch mechanism to use when invoking the handler: #dispatch = Str # Does the handler go at the beginning (True) or end (False) of the # notification handlers list? #priority = Bool( False ) # The next level (if any) of ListenerBase object to be called when any of # our listened to traits is changed: #next = Instance( ListenerBase ) # The type of handler being used: #type = Enum( ANY_LISTENER, SRC_LISTENER, DST_LISTENER ) # Should changes to this item generate a notification to the handler? # notify = Bool # Should registering listeners for items reachable from this listener item # be deferred until the associated trait is first read or set? # deferred = Bool #--------------------------------------------------------------------------- # Registers new listeners: #--------------------------------------------------------------------------- def register ( self, new ): """ Registers new listeners. """ raise NotImplementedError #--------------------------------------------------------------------------- # Unregisters any existing listeners: #--------------------------------------------------------------------------- def unregister ( self, old ): """ Unregisters any existing listeners. """ raise NotImplementedError #--------------------------------------------------------------------------- # Handles a trait change for a simple trait: #--------------------------------------------------------------------------- def handle ( self, object, name, old, new ): """ Handles a trait change for a simple trait. """ raise NotImplementedError #--------------------------------------------------------------------------- # Handles a trait change for a list trait: #--------------------------------------------------------------------------- def handle_list ( self, object, name, old, new ): """ Handles a trait change for a list trait. """ raise NotImplementedError #--------------------------------------------------------------------------- # Handles a trait change for a list traits items: #--------------------------------------------------------------------------- def handle_list_items ( self, object, name, old, new ): """ Handles a trait change for a list traits items. """ raise NotImplementedError #--------------------------------------------------------------------------- # Handles a trait change for a dictionary trait: #--------------------------------------------------------------------------- def handle_dict ( self, object, name, old, new ): """ Handles a trait change for a dictionary trait. """ raise NotImplementedError #--------------------------------------------------------------------------- # Handles a trait change for a dictionary traits items: #--------------------------------------------------------------------------- def handle_dict_items ( self, object, name, old, new ): """ Handles a trait change for a dictionary traits items. """ raise NotImplementedError #------------------------------------------------------------------------------- # 'ListenerItem' class: #------------------------------------------------------------------------------- class ListenerItem ( ListenerBase ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- # The name of the trait to listen to: name = Str # The name of any metadata that must be present (or not present): metadata_name = Str # Does the specified metadata need to be defined (True) or not defined # (False)? metadata_defined = Bool( True ) # The handler to be called when any listened-to trait is changed: handler = Any # A weakref 'wrapped' version of 'handler': wrapped_handler_ref = Any # The dispatch mechanism to use when invoking the handler: dispatch = Str # Does the handler go at the beginning (True) or end (False) of the # notification handlers list? priority = Bool( False ) # The next level (if any) of ListenerBase object to be called when any of # this object's listened-to traits is changed: next = Instance( ListenerBase ) # The type of handler being used: type = Enum( ANY_LISTENER, SRC_LISTENER, DST_LISTENER ) # Should changes to this item generate a notification to the handler? notify = Bool( True ) # Should registering listeners for items reachable from this listener item # be deferred until the associated trait is first read or set? deferred = Bool( False ) # Is this an 'any_trait' change listener, or does it create explicit # listeners for each individual trait? is_any_trait = Bool( False ) # Is the associated handler a special list handler that handles both # 'foo' and 'foo_items' events by receiving a list of 'deleted' and 'added' # items as the 'old' and 'new' arguments? is_list_handler = Bool( False ) # A dictionary mapping objects to a list of all current active # (*name*, *type*) listener pairs, where *type* defines the type of # listener, one of: (SIMPLE_LISTENER, LIST_LISTENER, DICT_LISTENER). active = Instance( WeakKeyDictionary, () ) #-- 'ListenerBase' Class Method Implementations ---------------------------- #--------------------------------------------------------------------------- # String representation: #--------------------------------------------------------------------------- def __repr__ ( self, seen = None ): """Returns a string representation of the object. Since the object graph may have cycles, we extend the basic __repr__ API to include a set of objects we've already seen while constructing a string representation. When this method tries to get the repr of a ListenerItem or ListenerGroup, we will use the extended API and build up the set of seen objects. The repr of a seen object will just be ''. """ if seen is None: seen = set() seen.add( self ) next_repr = 'None' next = self.next if next is not None: if next in seen: next_repr = '' else: next_repr = next.__repr__( seen ) return """%s( name = %r, metadata_name = %r, metadata_defined = %r, is_any_trait = %r, dispatch = %r, notify = %r, is_list_handler = %r, type = %r, next = %s, )""" % ( self.__class__.__name__, self.name, self.metadata_name, self.metadata_defined, self.is_any_trait, self.dispatch, self.notify, self.is_list_handler, self.type, indent( next_repr, False ) ) #--------------------------------------------------------------------------- # Registers new listeners: #--------------------------------------------------------------------------- def register ( self, new ): """ Registers new listeners. """ # Make sure we actually have an object to set listeners on and that it # has not already been registered (cycle breaking): if (new is None) or (new is Undefined) or (new in self.active): return INVALID_DESTINATION # Create a dictionary of {name: trait_values} that match the object's # definition for the 'new' object: name = self.name last = name[-1:] if last == '*': # Handle the special case of an 'anytrait' change listener: if self.is_any_trait: try: self.active[ new ] = [ ( '', ANYTRAIT_LISTENER ) ] return self._register_anytrait( new, '', False ) except TypeError: # This error can occur if 'new' is a list or other object # for which a weakref cannot be created as the dictionary # key for 'self.active': return INVALID_DESTINATION # Handle trait matching based on a common name prefix and/or # matching trait metadata: metadata = self._metadata if metadata is None: self._metadata = metadata = { 'type': not_event } if self.metadata_name != '': if self.metadata_defined: metadata[ self.metadata_name ] = is_not_none else: metadata[ self.metadata_name ] = is_none # Get all object traits with matching metadata: names = new.trait_names( **metadata ) # If a name prefix was specified, filter out only the names that # start with the specified prefix: name = name[:-1] if name != '': n = len( name ) names = [ aname for aname in names if name == aname[ : n ] ] # Create the dictionary of selected traits: bt = new.base_trait traits = dict( [ ( name, bt( name ) ) for name in names ] ) # Handle any new traits added dynamically to the object: new.on_trait_change( self._new_trait_added, 'trait_added' ) else: # Determine if the trait is optional or not: optional = (last == '?') if optional: name = name[:-1] # Else, no wildcard matching, just get the specified trait: trait = new.base_trait( name ) # Try to get the object trait: if trait is None: # Raise an error if trait is not defined and not optional: # fixme: Properties which are lists don't implement the # '..._items' sub-trait, which can cause a failure here when # used with an editor that sets up listeners on the items... if not optional: raise TraitError( "'%s' object has no '%s' trait" % ( new.__class__.__name__, name ) ) # Otherwise, just skip it: traits = {} else: # Create a result dictionary containing just the single trait: traits = { name: trait } # For each item, determine its type (simple, list, dict): self.active[ new ] = active = [] for name, trait in traits.items(): # Determine whether the trait type is simple, list, set or # dictionary: type = SIMPLE_LISTENER handler = trait.handler if handler is not None: type = type_map.get( handler.default_value_type, SIMPLE_LISTENER ) # Add the name and type to the list of traits being registered: active.append( ( name, type ) ) # Set up the appropriate trait listeners on the object for the # current trait: value = getattr( self, type )( new, name, False ) if len( traits ) == 1: return value return INVALID_DESTINATION #--------------------------------------------------------------------------- # Unregisters any existing listeners: #--------------------------------------------------------------------------- def unregister ( self, old ): """ Unregisters any existing listeners. """ if old is not None and old is not Uninitialized: try: active = self.active.pop( old, None ) if active is not None: for name, type in active: getattr( self, type )( old, name, True ) except TypeError: # An error can occur if 'old' is a list or other object for # which a weakref cannot be created and used an a key for # 'self.active': pass #--------------------------------------------------------------------------- # Handles a trait change for an intermediate link trait: #--------------------------------------------------------------------------- def handle_simple ( self, object, name, old, new ): """ Handles a trait change for an intermediate link trait. """ self.next.unregister( old ) self.next.register( new ) def handle_dst ( self, object, name, old, new ): """ Handles a trait change for an intermediate link trait when the notification is for the final destination trait. """ self.next.unregister( old ) object, name = self.next.register( new ) if old is not Uninitialized: if object is None: raise TraitError( "on_trait_change handler signature is " "incompatible with a change to an intermediate trait" ) wh = self.wrapped_handler_ref() if wh is not None: wh( object, name, old, getattr( object, name, Undefined ) ) #--------------------------------------------------------------------------- # Handles a trait change for a list (or set) trait: #--------------------------------------------------------------------------- def handle_list ( self, object, name, old, new ): """ Handles a trait change for a list (or set) trait. """ if old is not None and old is not Uninitialized: unregister = self.next.unregister for obj in old: unregister( obj ) register = self.next.register for obj in new: register( obj ) #--------------------------------------------------------------------------- # Handles a trait change for a list (or set) traits items: #--------------------------------------------------------------------------- def handle_list_items ( self, object, name, old, new ): """ Handles a trait change for items of a list (or set) trait. """ self.handle_list( object, name, new.removed, new.added ) def handle_list_items_special ( self, object, name, old, new ): """ Handles a trait change for items of a list (or set) trait with notification. """ wh = self.wrapped_handler_ref() if wh is not None: wh( object, name, new.removed, new.added ) #--------------------------------------------------------------------------- # Handles a trait change for a dictionary trait: #--------------------------------------------------------------------------- def handle_dict ( self, object, name, old, new ): """ Handles a trait change for a dictionary trait. """ if old is not Uninitialized: unregister = self.next.unregister for obj in old.values(): unregister( obj ) register = self.next.register for obj in new.values(): register( obj ) #--------------------------------------------------------------------------- # Handles a trait change for a dictionary traits items: #--------------------------------------------------------------------------- def handle_dict_items ( self, object, name, old, new ): """ Handles a trait change for items of a dictionary trait. """ self.handle_dict( object, name, new.removed, new.added ) if len( new.changed ) > 0: # If 'name' refers to the '_items' trait, then remove the '_items' # suffix to get the actual dictionary trait. # # fixme: Is there ever a case where 'name' *won't* refer to the # '_items' trait? if name.endswith('_items'): name = name[:-len('_items')] dict = getattr( object, name ) unregister = self.next.unregister register = self.next.register for key, obj in new.changed.items(): unregister( obj ) register( dict[ key ] ) #--------------------------------------------------------------------------- # Handles an invalid intermediate trait change to a handler that must be # applied to the final destination object.trait: #--------------------------------------------------------------------------- def handle_error ( self, obj, name, old, new ): """ Handles an invalid intermediate trait change to a handler that must be applied to the final destination object.trait. """ if old is not None and old is not Uninitialized: raise TraitError( "on_trait_change handler signature is " "incompatible with a change to an intermediate trait" ) #-- Event Handlers --------------------------------------------------------- #--------------------------------------------------------------------------- # Handles the 'handler' trait being changed: #--------------------------------------------------------------------------- def _handler_changed ( self, handler ): """ Handles the **handler** trait being changed. """ if self.next is not None: self.next.handler = handler #--------------------------------------------------------------------------- # Handles the 'wrapped_handler_ref' trait being changed: #--------------------------------------------------------------------------- def _wrapped_handler_ref_changed ( self, wrapped_handler_ref ): """ Handles the 'wrapped_handler_ref' trait being changed. """ if self.next is not None: self.next.wrapped_handler_ref = wrapped_handler_ref #--------------------------------------------------------------------------- # Handles the 'dispatch' trait being changed: #--------------------------------------------------------------------------- def _dispatch_changed ( self, dispatch ): """ Handles the **dispatch** trait being changed. """ if self.next is not None: self.next.dispatch = dispatch #--------------------------------------------------------------------------- # Handles the 'priority' trait being changed: #--------------------------------------------------------------------------- def _priority_changed ( self, priority ): """ Handles the **priority** trait being changed. """ if self.next is not None: self.next.priority = priority #-- Private Methods -------------------------------------------------------- #--------------------------------------------------------------------------- # Registers any 'anytrait' listener: #--------------------------------------------------------------------------- def _register_anytrait ( self, object, name, remove ): """ Registers any 'anytrait' listener. """ handler = self.handler() if handler is not Undefined: object._on_trait_change( handler, remove = remove, dispatch = self.dispatch, priority = self.priority ) return ( object, name ) #--------------------------------------------------------------------------- # Registers a handler for a simple trait: #--------------------------------------------------------------------------- def _register_simple ( self, object, name, remove ): """ Registers a handler for a simple trait. """ next = self.next if next is None: handler = self.handler() if handler is not Undefined: object._on_trait_change( handler, name, remove = remove, dispatch = self.dispatch, priority = self.priority ) return ( object, name ) tl_handler = self.handle_simple if self.notify: if self.type == DST_LISTENER: if self.dispatch != 'same': raise TraitError( "Trait notification dispatch type '%s' " "is not compatible with handler signature and " "extended trait name notification style" % self.dispatch ) tl_handler = self.handle_dst else: handler = self.handler() if handler is not Undefined: object._on_trait_change( handler, name, remove = remove, dispatch = self.dispatch, priority = self.priority ) object._on_trait_change( tl_handler, name, remove = remove, dispatch = 'extended', priority = self.priority ) if remove: return next.unregister( getattr( object, name ) ) if not self.deferred: return next.register( getattr( object, name ) ) return ( object, name ) #--------------------------------------------------------------------------- # Registers a handler for a list trait: #--------------------------------------------------------------------------- def _register_list ( self, object, name, remove ): """ Registers a handler for a list trait. """ next = self.next if next is None: handler = self.handler() if handler is not Undefined: object._on_trait_change( handler, name, remove = remove, dispatch = self.dispatch, priority = self.priority ) if self.is_list_handler: object._on_trait_change( self.handle_list_items_special, name + '_items', remove = remove, dispatch = self.dispatch, priority = self.priority ) elif self.type == ANY_LISTENER: object._on_trait_change( handler, name + '_items', remove = remove, dispatch = self.dispatch, priority = self.priority ) return ( object, name ) tl_handler = self.handle_list tl_handler_items = self.handle_list_items if self.notify: if self.type == DST_LISTENER: tl_handler = tl_handler_items = self.handle_error else: handler = self.handler() if handler is not Undefined: object._on_trait_change( handler, name, remove = remove, dispatch = self.dispatch, priority = self.priority ) if self.is_list_handler: object._on_trait_change( self.handle_list_items_special, name + '_items', remove = remove, dispatch = self.dispatch, priority = self.priority ) elif self.type == ANY_LISTENER: object._on_trait_change( handler, name + '_items', remove = remove, dispatch = self.dispatch, priority = self.priority ) object._on_trait_change( tl_handler, name, remove = remove, dispatch = 'extended', priority = self.priority ) object._on_trait_change( tl_handler_items, name + '_items', remove = remove, dispatch = 'extended', priority = self.priority ) if remove: handler = next.unregister elif self.deferred: return INVALID_DESTINATION else: handler = next.register for obj in getattr( object, name ): handler( obj ) return INVALID_DESTINATION # Handle 'sets' the same as 'lists': # Note: Currently the behavior of sets is almost identical to that of lists, # so we are able to share the same code for both. This includes some 'duck # typing' that occurs with the TraitListEvent and TraitSetEvent, that define # 'removed' and 'added' attributes that behave similarly enough (from the # point of view of this module) that they can be treated as equivalent. If # the behavior of sets ever diverges from that of lists, then this code may # need to be changed. _register_set = _register_list #--------------------------------------------------------------------------- # Registers a handler for a dictionary trait: #--------------------------------------------------------------------------- def _register_dict ( self, object, name, remove ): """ Registers a handler for a dictionary trait. """ next = self.next if next is None: handler = self.handler() if handler is not Undefined: object._on_trait_change( handler, name, remove = remove, dispatch = self.dispatch, priority = self.priority ) if self.type == ANY_LISTENER: object._on_trait_change( handler, name + '_items', remove = remove, dispatch = self.dispatch, priority = self.priority ) return ( object, name ) tl_handler = self.handle_dict tl_handler_items = self.handle_dict_items if self.notify: if self.type == DST_LISTENER: tl_handler = tl_handler_items = self.handle_error else: handler = self.handler() if handler is not Undefined: object._on_trait_change( handler, name, remove = remove, dispatch = self.dispatch, priority = self.priority ) if self.type == ANY_LISTENER: object._on_trait_change( handler, name + '_items', remove = remove, dispatch = self.dispatch, priority = self.priority ) object._on_trait_change( tl_handler, name, remove = remove, dispatch = self.dispatch, priority = self.priority ) object._on_trait_change( tl_handler_items, name + '_items', remove = remove, dispatch = self.dispatch, priority = self.priority ) if remove: handler = next.unregister elif self.deferred: return INVALID_DESTINATION else: handler = next.register for obj in getattr( object, name ).values(): handler( obj ) return INVALID_DESTINATION #--------------------------------------------------------------------------- # Handles new traits being added to an object being monitored: #--------------------------------------------------------------------------- def _new_trait_added ( self, object, name, new_trait ): """ Handles new traits being added to an object being monitored. """ # Set if the new trait matches our prefix and metadata: if new_trait.startswith( self.name[:-1] ): trait = object.base_trait( new_trait ) for meta_name, meta_eval in self._metadata.items(): if not meta_eval( getattr( trait, meta_name ) ): return # Determine whether the trait type is simple, list, set or # dictionary: type = SIMPLE_LISTENER handler = trait.handler if handler is not None: type = type_map.get( handler.default_value_, SIMPLE_LISTENER ) # Add the name and type to the list of traits being registered: self.active[ object ].append( ( new_trait, type ) ) # Set up the appropriate trait listeners on the object for the # new trait: getattr( self, type )( object, new_trait, False ) #------------------------------------------------------------------------------- # 'ListenerGroup' class: #------------------------------------------------------------------------------- def _set_value ( self, name, value ): for item in self.items: setattr( item, name, value ) def _get_value ( self, name ): # Use the attribute on the first item. If there are no items, return None. if self.items: return getattr( self.items[0], name ) else: return None ListProperty = Property( fget = _get_value, fset = _set_value ) class ListenerGroup ( ListenerBase ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- # The handler to be called when any listened-to trait is changed handler = Property # A weakref 'wrapped' version of 'handler': wrapped_handler_ref = Property # The dispatch mechanism to use when invoking the handler: dispatch = Property # Does the handler go at the beginning (True) or end (False) of the # notification handlers list? priority = ListProperty # The next level (if any) of ListenerBase object to be called when any of # this object's listened-to traits is changed next = ListProperty # The type of handler being used: type = ListProperty # Should changes to this item generate a notification to the handler? notify = ListProperty # Should registering listeners for items reachable from this listener item # be deferred until the associated trait is first read or set? deferred = ListProperty # The list of ListenerBase objects in the group items = List( ListenerBase ) #-- Property Implementations ----------------------------------------------- def _set_handler ( self, handler ): if self._handler is None: self._handler = handler for item in self.items: item.handler = handler def _set_wrapped_handler_ref ( self, wrapped_handler_ref ): if self._wrapped_handler_ref is None: self._wrapped_handler_ref = wrapped_handler_ref for item in self.items: item.wrapped_handler_ref = wrapped_handler_ref def _set_dispatch ( self, dispatch ): if self._dispatch is None: self._dispatch = dispatch for item in self.items: item.dispatch = dispatch #-- 'ListenerBase' Class Method Implementations ---------------------------- #--------------------------------------------------------------------------- # String representation: #--------------------------------------------------------------------------- def __repr__ ( self, seen = None ): """Returns a string representation of the object. Since the object graph may have cycles, we extend the basic __repr__ API to include a set of objects we've already seen while constructing a string representation. When this method tries to get the repr of a ListenerItem or ListenerGroup, we will use the extended API and build up the set of seen objects. The repr of a seen object will just be ''. """ if seen is None: seen = set() seen.add( self ) lines = [ '%s(items = [' % self.__class__.__name__ ] for item in self.items: lines.extend( indent( item.__repr__( seen ), True ).split( '\n' ) ) lines[-1] += ',' lines.append( '])' ) return '\n'.join( lines ) #--------------------------------------------------------------------------- # Registers new listeners: #--------------------------------------------------------------------------- def register ( self, new ): """ Registers new listeners. """ for item in self.items: item.register( new ) return INVALID_DESTINATION #--------------------------------------------------------------------------- # Unregisters any existing listeners: #--------------------------------------------------------------------------- def unregister ( self, old ): """ Unregisters any existing listeners. """ for item in self.items: item.unregister( old ) #------------------------------------------------------------------------------- # 'ListenerParser' class: #------------------------------------------------------------------------------- class ListenerParser ( HasPrivateTraits ): #------------------------------------------------------------------------------- # Trait definitions: #------------------------------------------------------------------------------- # The string being parsed text = Str # The length of the string being parsed. len_text = Int # The current parse index within the string index = Int # The next character from the string being parsed next = Property # The next Python attribute name within the string: name = Property # The next non-whitespace character skip_ws = Property # Backspaces to the last character processed backspace = Property # The ListenerBase object resulting from parsing **text** listener = Instance( ListenerBase ) #-- Property Implementations ----------------------------------------------- def _get_next ( self ): index = self.index self.index += 1 if index >= self.len_text: return EOS return self.text[ index ] def _get_backspace ( self ): self.index = max( 0, self.index - 1 ) def _get_skip_ws ( self ): while True: c = self.next if c not in whitespace: return c def _get_name ( self ): match = name_pat.match( self.text, self.index - 1 ) if match is None: return '' self.index = match.start( 2 ) return match.group( 1 ) #-- object Method Overrides ------------------------------------------------ def __init__ ( self, text = '', **traits ): self.text = text super( ListenerParser, self ).__init__( **traits ) #-- Private Methods -------------------------------------------------------- #--------------------------------------------------------------------------- # Parses the text and returns the appropriate collection of ListenerBase # objects described by the text: #--------------------------------------------------------------------------- def parse ( self ): """ Parses the text and returns the appropriate collection of ListenerBase objects described by the text. """ # Try a simple case of 'name1.name2'. The simplest case of a single # Python name never triggers this parser, so we don't try to make that # a shortcut too. Whitespace should already have been stripped from the # start and end. # TODO: The use of regexes should be used throughout all of the parsing # functions to speed up all aspects of parsing. match = simple_pat.match( self.text ) if match is not None: return ListenerItem( name = match.group( 1 ), notify = match.group(2) == '.', next = ListenerItem( name = match.group( 3 ) ) ) return self.parse_group( EOS ) #--------------------------------------------------------------------------- # Parses the contents of a group: #--------------------------------------------------------------------------- def parse_group ( self, terminator = ']' ): """ Parses the contents of a group. """ items = [] while True: items.append( self.parse_item( terminator ) ) c = self.skip_ws if c is terminator: break if c != ',': if terminator == EOS: self.error( "Expected ',' or end of string" ) else: self.error( "Expected ',' or '%s'" % terminator ) if len( items ) == 1: return items[0] return ListenerGroup( items = items ) #--------------------------------------------------------------------------- # Parses a single, complete listener item/group string: #--------------------------------------------------------------------------- def parse_item ( self, terminator ): """ Parses a single, complete listener item or group string. """ c = self.skip_ws if c == '[': result = self.parse_group() c = self.skip_ws else: name = self.name if name != '': c = self.next result = ListenerItem( name = name ) if c in '+-': result.name += '*' result.metadata_defined = (c == '+') cn = self.skip_ws result.metadata_name = metadata = self.name if metadata != '': cn = self.skip_ws result.is_any_trait = ((c == '-') and (name == '') and (metadata == '')) c = cn if result.is_any_trait and (not ((c == terminator) or ((c == ',') and (terminator == ']')))): self.error( "Expected end of name" ) elif c == '?': if len( name ) == 0: self.error( "Expected non-empty name preceding '?'" ) result.name += '?' c = self.skip_ws cycle = (c == '*') if cycle: c = self.skip_ws if c in '.:': result.notify = (c == '.') next = self.parse_item( terminator ) if cycle: last = result while last.next is not None: last = last.next last.next = lg = ListenerGroup( items = [ next, result ] ) result = lg else: result.next = next return result if c == '[': if (self.skip_ws == ']') and (self.skip_ws == terminator): self.backspace result.is_list_handler = True else: self.error( "Expected '[]' at the end of an item" ) else: self.backspace if cycle: result.next = result return result #--------------------------------------------------------------------------- # Parses the metadata portion of a listener item: #--------------------------------------------------------------------------- def parse_metadata ( self, item ): """ Parses the metadata portion of a listener item. """ self.skip_ws item.metadata_name = name = self.name if name == '': self.backspace #--------------------------------------------------------------------------- # Raises a syntax error: #--------------------------------------------------------------------------- def error ( self, msg ): """ Raises a syntax error. """ raise TraitError( "%s at column %d of '%s'" % ( msg, self.index, self.text ) ) #-- Event Handlers --------------------------------------------------------- #--------------------------------------------------------------------------- # Handles the 'text' trait being changed: #--------------------------------------------------------------------------- def _text_changed ( self ): self.index = 0 self.len_text = len( self.text ) self.listener = self.parse() #------------------------------------------------------------------------------- # 'ListenerNotifyWrapper' class: #------------------------------------------------------------------------------- class ListenerNotifyWrapper ( TraitChangeNotifyWrapper ): #-- TraitChangeNotifyWrapper Method Overrides ------------------------------ def __init__ ( self, handler, owner, id, listener, target=None): self.type = ListenerType.get( self.init( handler, weakref.ref( owner, self.owner_deleted ), target ) ) self.id = id self.listener = listener def listener_deleted ( self, ref ): owner = self.owner() if owner is not None: dict = owner.__dict__.get( TraitsListener ) listeners = dict.get( self.id ) listeners.remove( self ) if len( listeners ) == 0: del dict[ self.id ] if len( dict ) == 0: del owner.__dict__[ TraitsListener ] # fixme: Is the following line necessary, since all registered # notifiers should be getting the same 'listener_deleted' call: self.listener.unregister( owner ) self.object = self.owner = self.listener = None def owner_deleted ( self, ref ): self.object = self.owner = None #------------------------------------------------------------------------------- # 'ListenerHandler' class: #------------------------------------------------------------------------------- class ListenerHandler ( object ): def __init__ ( self, handler ): if type( handler ) is MethodType: object = handler.im_self if object is not None: self.object = weakref.ref( object, self.listener_deleted ) self.name = handler.__name__ return self.handler = handler def __call__ ( self ): result = getattr( self, 'handler', None ) if result is not None: return result return getattr( self.object(), self.name ) def listener_deleted ( self, ref ): self.handler = Undefined traits-4.1.0/traits/category.py0000644000175100001440000001062311674463323017513 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # # Copyright (c) 2005, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in enthought/LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # # Author: David C. Morrill # Date: 11/06/2004 # #------------------------------------------------------------------------------ """ Adds a "category" capability to Traits-based classes, similar to that provided by the Cocoa (Objective-C) environment for the Macintosh. You can use categories to extend an existing HasTraits class, as an alternative to subclassing. An advantage of categories over subclassing is that you can access the added members on instances of the original class, without having to change them to instances of a subclass. Unlike subclassing, categories do not allow overriding trait attributes. """ #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from __future__ import absolute_import from .has_traits import MetaHasTraits, MetaHasTraitsObject #------------------------------------------------------------------------------- # 'MetaCategory' class: #------------------------------------------------------------------------------- class MetaCategory ( MetaHasTraits ): def __new__ ( cls, class_name, bases, class_dict ): # Make sure the correct usage is being applied: if len( bases ) > 2: raise TypeError, \ "Correct usage is: class FooCategory(Category,Foo):" # Process any traits-related information in the class dictionary: MetaCategoryObject( cls, class_name, bases, class_dict, True ) # Move all remaining items in our class dictionary to the base class's # dictionary: if len( bases ) == 2: category_class = bases[1] for name, value in class_dict.items(): if not hasattr( category_class, name ): setattr( category_class, name, value ) del class_dict[ name ] # Finish building the class using the updated class dictionary: return type.__new__( cls, class_name, bases, class_dict ) #------------------------------------------------------------------------------- # 'MetaCategoryObject' class: #------------------------------------------------------------------------------- class MetaCategoryObject ( MetaHasTraitsObject ): #--------------------------------------------------------------------------- # Adds the traits meta-data to the class: #--------------------------------------------------------------------------- def add_traits_meta_data ( self, bases, class_dict, base_traits, class_traits, instance_traits, prefix_traits, listeners, view_elements, implements_class ): if len( bases ) == 2: # Update the class and each of the existing subclasses: bases[1]._add_trait_category( base_traits, class_traits, instance_traits, prefix_traits, listeners, view_elements, implements_class ) else: MetaHasTraitsObject.add_traits_meta_data( self, bases, class_dict, base_traits, class_traits, instance_traits, prefix_traits, listeners, view_elements, implements_class ) #------------------------------------------------------------------------------- # 'Category' class: #------------------------------------------------------------------------------- class Category ( object ): """ Used for defining "category" extensions to existing classes. To define a class as a category, specify "Category," followed by the name of the base class name in the base class list. The following example demonstrates defining a category:: from traits.api import HasTraits, Str, Category class Base(HasTraits): x = Str("Base x") y = Str("Base y") class BaseExtra(Category, Base): z = Str("BaseExtra z") """ __metaclass__ = MetaCategory traits-4.1.0/traits/has_dynamic_views.py0000644000175100001440000003602711674463323021400 0ustar ischnellusers00000000000000#----------------------------------------------------------------------------- # # Copyright (c) 2006, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in enthought/LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # # Author: Dave Peterson # #----------------------------------------------------------------------------- """ Provides a framework that assembles Traits UI Views at run time, when the view is requested, rather than at the time a class is written. This capability is particularly useful when the object being 'viewed' with a Traits UI is part of a plug-in application -- such as Envisage. In general, this capability allows: * The GUI for an object can be extendable by contributions other than from the original code writer. * The view can be dynamic in that the elements it is composed of can change each time it is requested. * Registration of a handler can be associated with the view contributions. Either the original object writer, or a contributor, can use this framework to declare one or more dynamic views that are composed of sub-elements that only need to exist at the time the view is requested. Users of this framework create a dynamic view by registering a DynamicView declaration. That declaration includes a name that forms the basis for the metadata attributes that are used to identify and order the desired view sub-elements into the view's composition. In addition, the declaration includes any data to be passed into the constructor of the dynamic view and the id that should be used to persist the user's customization of the view. Additionally, this framework allows sub-elements themselves to also be dynamically composed of further sub-elements. For example, a dynamic view could be composed of two sub-elements: 1. The first is a dynamically composed HFlow, which represents a toolbar that can be extended through contributions of toolbar buttons. 2. The second could be a dynamic tabset where each page is also a contribution. Programmers include dynamic sub-elements within their dynamic views by contributing a DynamicViewSubElement into that view. When the framework comes across this contribution while building the view, it replaces that DynamicViewSubElement with a fully initialized Traits ViewSubElement composed in a manner similar to how the elements of the View itself were composed. Each contribution to a dynamic view or sub-element must be an instance of a Traits ViewSubElement and must have associated metadata like the following for each dynamic view or sub-element it will display in: __order : A float value. The framework uses only ViewSubElements with this metadata instantiated when building the dynamic view or sub-element with the specified name. The elements are sorted by ascending order of this value using the standard list sort function. __priority : A float value. The framework resolves any overloading of an order value by picking the first element encountered that has the highest priority value. The other elements with the same view order are not displayed at all. In addition, dynamic view contributions can also provide a 'handler', which behaves like a normal Traits Handler. That is, it can contain methods that are called when model values change and can access the Traits UIInfo object representing the actual UI instances. To provide a handler, append the following metadata to your view sub-element: __handler : A HasTraits instance. The framework will connect listeners to call the handler methods as part of the handler for the dynamic view. """ from __future__ import absolute_import # Enthought library imports: from traitsui.delegating_handler import DelegatingHandler # Local imports: from .has_traits import HasTraits from .trait_types import Any, Bool, Dict, Instance, Str from traitsui.api import View, ViewSubElement, ViewElement # Set up a logger: import logging logger = logging.getLogger( __name__ ) #------------------------------------------------------------------------------- # 'DynamicViewSubElement' class: #------------------------------------------------------------------------------- class DynamicViewSubElement ( ViewSubElement ): """ Declares a dynamic sub-element of a dynamic view. """ #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- #-- Public 'DynamicViewSubElement' Interface ------------------------------- # Keyword arguments passed in during construction of the actual # ViewSubElement instance. keywords = Dict # The class of the actual ViewSubElement we are dynamically creating. # FIXME: Should be the 'Class' trait but I couldn't get that to work. klass = Any # The name of this dynamic sub-element. This controls the metadata # names identifying the sub-elements that compose this element. name = Str #------------------------------------------------------------------------------- # 'DynamicView' class: #------------------------------------------------------------------------------- class DynamicView ( HasTraits ): """ Declares a dynamic view. """ #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- #-- Public 'DynamicView' Interface ----------------------------------------- # The ID of the view. This is the ID that the view's preferences will be # saved under. id = Str # The name of the view. This is the name that should be requested when # calling edit_traits() or configure_traits(). name = Str # Keyword arguments passed in during construction of the actual view # instance. keywords = Dict # Indicates whether this view should be the default traits view for objects # it is contributed to. use_as_default = Bool( False ) #------------------------------------------------------------------------------- # 'HasDynamicViews' class: #------------------------------------------------------------------------------- class HasDynamicViews ( HasTraits ): """ Provides of a framework that builds Traits UI Views at run time, when the view is requested, rather than at the time a class is written. """ #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- #-- Protected 'HasDynamicViews' Interface ---------------------------------- # The registry of dynamic views. The key is the view name and the value # is the declaration of the dynamic view. _dynamic_view_registry = Dict( Str, Instance( DynamicView ) ) #--------------------------------------------------------------------------- # 'HasTraits' interface: #--------------------------------------------------------------------------- #-- Public Interface ------------------------------------------------------- def trait_view ( self, name = None, view_element = None ): """ Gets or sets a ViewElement associated with an object's class. Extended here to build dynamic views and sub-elements. """ result = None # If a view element was passed instead of a name or None, do not handle # this as a request for a dynamic view and let the standard Traits # trait_view method be called with it. Otherwise, compose the dynamic # view here. if not isinstance( name, ViewElement ): # If this is a request for the default view, see if one of our # dynamic views should be the default view: if (view_element is None) and (name is None or len( name ) < 1): for dname, declaration in self._dynamic_view_registry.items(): if declaration.use_as_default: result = self._compose_dynamic_view( dname ) break # Otherwise, handle if this is a request for a dynamic view: elif ((view_element is None) and (name in self._dynamic_view_registry)): result = self._compose_dynamic_view(name) # If we haven't created a dynamic view so far, then do the standard # traits thing to retrieve the UI element: if result is None: result = super( HasDynamicViews, self ).trait_view( name, view_element ) return result #--------------------------------------------------------------------------- # 'HasDynamicViews' interface: #--------------------------------------------------------------------------- #-- Public Interface ------------------------------------------------------- def declare_dynamic_view ( self, declaration ): """ A convenience method to add a new dynamic view declaration to this instance. """ self._dynamic_view_registry[ declaration.name ] = declaration #-- Protected Interface ---------------------------------------------------- def _build_dynamic_sub_element ( self, definition, sub_elements ): """ Returns the fully composed ViewSubElement from the sub-element contributions to the dynamic sub-element identified by the definition. """ logger.debug( '\tBuilding dynamic sub-element [%s] with elements [%s]', definition.name, sub_elements ) return definition.klass( *sub_elements, **definition.keywords ) def _build_dynamic_view (self, declaration, sub_elements, handler ): """ Returns a Traits View representing the specified dynamic view composed out of the provided view sub-elements. Implemented as a separate method to allow implementors to override the way in which the instantiated view is configured. """ logger.debug( '\tBuilding dynamic view [%s] with elements [%s]', declaration.name, sub_elements ) return View( # The view id allows the user's customization of this view, if any, # to be persisted when the view is closed and then that persisted # configuration to be applied when the view is next shown: id = declaration.id, # Include the specified handler: handler = handler, # Build the view out of the sub-elements: *sub_elements, # Include the declaration's keywords. **declaration.keywords ) def _compose_dynamic_sub_element ( self, definition ): """ Returns a dynamic UI element composed from its contributed parts. """ logger.debug( 'Composing dynamic sub-element named [%s] for [%s]', definition.name, self ) # Retrieve the set of elements that make up this sub-element: elements = self._get_dynamic_elements( definition.name ) # Build the sub-element: return self._build_dynamic_sub_element( definition, elements ) def _compose_dynamic_view ( self, name ): """ Returns a dynamic view composed from its contributed parts. """ logger.debug( 'Composing dynamic view [%s] for [%s]', name, self ) # Retrieve the declaration of this dynamic view: declaration = self._dynamic_view_registry[ name ] # Retrieve the set of elements that make up the view: elements = self._get_dynamic_elements( declaration.name ) # Build a handler that delegates to the contribution handlers if any # exist: handler = None handlers = self._get_dynamic_handlers( declaration.name, elements ) if len( handlers ) > 0: handler = DelegatingHandler( sub_handlers = handlers ) # Build the view: return self._build_dynamic_view( declaration, elements, handler ) def _get_dynamic_elements ( self, name ): """ Returns a list of the current elements meant to go into the composition of a dynamic view or sublement with the specified name. """ # Determine the metadata names used to find the sub-elements included # within this dynamic element: name = name.replace(' ', '_') order_trait_name = '_%s_order' % name priority_trait_name = '_%s_priority' % name # Now find all of the current sub-elements that we will use when # composing our element: all_elements = [ self.trait_view( g ) for g in self.trait_views( klass = ViewSubElement ) ] elements = [ e for e in all_elements if hasattr( e, order_trait_name ) and (getattr( e, order_trait_name ) is not None) ] # Filter out any overridden elements. This means taking out the # element with the lower priority whenever two elements have the # same order value: filtered = {} for e in elements: order = getattr( e, order_trait_name ) priority = getattr( e, priority_trait_name ) or 0 current = filtered.setdefault( order, e ) if current is not e: current_priority = getattr( current, priority_trait_name ) if current_priority < priority: filtered[ order ] = e # Sort the contributed elements by their display ordering values: ordering = filtered.keys() ordering.sort() elements = [ filtered[ order ] for order in ordering ] # Replace any dynamic sub-element with their full composition. # NOTE: We can't do this in the override of 'trait_view' because # then we get into infinite loops when a dynamic view subelement is # found as a child: for i in range( len( elements ) ): if isinstance( elements[i], DynamicViewSubElement ): e = elements.pop( i ) composed = self._compose_dynamic_sub_element( e ) elements.insert( i, composed ) return elements def _get_dynamic_handlers( self, name, elements ): """ Return a list of the handlers associated with the current elements meant to go into the dynamic view of the specified name. """ # Determine the metadata name used to declare a handler: name = name.replace(' ', '_') handler_name = '_%s_handler' % name handlers = [ getattr(e, handler_name) for e in elements if hasattr( e, handler_name ) and (getattr( e, handler_name ) is not None) ] logger.debug( '\tFound sub-handlers: %s', handlers ) return handlers traits-4.1.0/traits/trait_numeric.py0000644000175100001440000003242511674463323020547 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # # Copyright (c) 2005, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in enthought/LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # # Author: David C. Morrill # Date: 12/13/2004 # #------------------------------------------------------------------------------ """ Trait definitions related to the numpy library. """ #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from __future__ import absolute_import import warnings from .trait_base import SequenceTypes from .trait_errors import TraitError from .trait_handlers import TraitType, OBJECT_IDENTITY_COMPARE from .trait_types import Str, Any, Int as TInt, Float as TFloat #------------------------------------------------------------------------------- # Deferred imports from numpy: #------------------------------------------------------------------------------- ndarray = None asarray = None #------------------------------------------------------------------------------- # numpy dtype mapping: #------------------------------------------------------------------------------- def dtype2trait ( dtype ): """ Get the corresponding trait for a numpy dtype. """ import numpy if dtype.char in numpy.typecodes['Float']: return TFloat elif dtype.char in numpy.typecodes['AllInteger']: return TInt elif dtype.char[0] == 'S': return Str else: return Any #------------------------------------------------------------------------------- # 'AbstractArray' trait base class: #------------------------------------------------------------------------------- class AbstractArray ( TraitType ): """ Abstract base class for defining numpy-based arrays. """ def __init__ ( self, dtype = None, shape = None, value = None, coerce = False, typecode = None, **metadata ): """ Returns an AbstractArray trait. """ global ndarray, asarray try: import numpy except ImportError: raise TraitError( "Using Array or CArray trait types requires the " "numpy package to be installed." ) from numpy import array, asarray, ndarray, zeros # Mark this as being an 'array' trait: metadata[ 'array' ] = True # Normally use object identity to detect array values changing: metadata.setdefault( 'comparison_mode', OBJECT_IDENTITY_COMPARE ) if typecode is not None: warnings.warn( 'typecode is a deprecated argument; use dtype ' 'instead', DeprecationWarning ) if (dtype is not None) and (dtype != typecode): raise TraitError( 'Inconsistent usage of the dtype and ' 'typecode arguments; use dtype alone.' ) else: dtype = typecode if dtype is not None: try: # Convert the argument into an actual numpy dtype object: dtype = numpy.dtype( dtype ) except TypeError: raise TraitError( 'could not convert %r to a numpy dtype' % dtype ) if shape is not None: if isinstance( shape, SequenceTypes ): for item in shape: if ((item is None) or (type( item ) is int) or (isinstance( item, SequenceTypes ) and (len( item ) == 2) and (type( item[0] ) is int) and (item[0] >= 0) and ((item[1] is None) or ((type( item[1] ) is int) and (item[0] <= item[1]))))): continue raise TraitError, "shape should be a list or tuple" else: raise TraitError, "shape should be a list or tuple" if value is None: if dtype is None: # Compatibility with the default of Traits 2.0 dt = int else: dt = dtype if shape is None: value = zeros( ( 0, ), dt ) else: size = [] for item in shape: if item is None: item = 1 elif type( item ) in SequenceTypes: # XXX: what is this supposed to do? item = item[0] size.append( item ) value = zeros( size, dt ) self.dtype = dtype self.shape = shape self.coerce = coerce super( AbstractArray, self ).__init__( value, **metadata ) def validate ( self, object, name, value ): """ Validates that the value is a valid array. """ try: # Make sure the value is an array: type_value = type( value ) if not isinstance( value, ndarray ): if not isinstance( value, SequenceTypes ): self.error( object, name, value ) if self.dtype is not None: value = asarray( value, self.dtype ) else: value = asarray( value ) # Make sure the array is of the right type: if ((self.dtype is not None) and (value.dtype != self.dtype)): if self.coerce: value = value.astype( self.dtype ) else: # XXX: this also coerces. value = asarray( value, self.dtype ) # If no shape requirements, then return the value: trait_shape = self.shape if trait_shape is None: return value # Else make sure that the value's shape is compatible: value_shape = value.shape if len( trait_shape ) == len( value_shape ): for i, dim in enumerate( value_shape ): item = trait_shape[i] if item is not None: if type( item ) is int: if dim != item: break elif ((dim < item[0]) or ((item[1] is not None) and (dim > item[1]))): break else: return value except: pass self.error( object, name, value ) def info ( self ): """ Returns descriptive information about the trait. """ dtype = shape = '' if self.shape is not None: shape = [] for item in self.shape: if item is None: item = '*' elif type( item ) is not int: if item[1] is None: item = '%d..' % item[0] else: item = '%d..%d' % item shape.append( item ) shape = ' with shape %s' % ( tuple( shape ), ) if self.dtype is not None: # FIXME: restore nicer descriptions of dtypes. dtype = ' of %s values' % self.dtype return 'an array%s%s' % ( dtype, shape ) def get_editor ( self, trait = None ): """ Returns the default UI editor for the trait. """ editor = None auto_set = False if self.auto_set is None: auto_set = True enter_set = self.enter_set or False if self.shape is not None and len( self.shape ) == 2: from traitsui.api import ArrayEditor editor = ArrayEditor( auto_set=auto_set, enter_set=enter_set ) else: from traitsui.api import TupleEditor if self.dtype is None: types = Any else: types = dtype2trait( self.dtype ) editor = TupleEditor( types = types, labels = self.labels or [], cols = self.cols or 1, auto_set = auto_set, enter_set = enter_set ) return editor #-- Private Methods -------------------------------------------------------- def get_default_value ( self ): """ Returns the default value constructor for the type (called from the trait factory. """ return ( 7, ( self.copy_default_value, ( self.validate( None, None, self.default_value ), ), None ) ) def copy_default_value ( self, value ): """ Returns a copy of the default value (called from the C code on first reference to a trait with no current value). """ return value.copy() #------------------------------------------------------------------------------- # 'Array' trait: #------------------------------------------------------------------------------- class Array ( AbstractArray ): """ Defines a trait whose value must be a numpy array. """ def __init__ ( self, dtype = None, shape = None, value = None, typecode = None, **metadata ): """ Returns an Array trait. Parameters ---------- dtype : a numpy dtype (e.g., int32) The type of elements in the array; if omitted, no type-checking is performed on assigned values. shape : a tuple Describes the required shape of any assigned value. Wildcards and ranges are allowed. The value None within the *shape* tuple means that the corresponding dimension is not checked. (For example, ``shape=(None,3)`` means that the first dimension can be any size, but the second must be 3.) A two-element tuple within the *shape* tuple means that the dimension must be in the specified range. The second element can be None to indicate that there is no upper bound. (For example, ``shape=((3,5),(2,None))`` means that the first dimension must be in the range 3 to 5 (inclusive), and the second dimension must be at least 2.) value : numpy array A default value for the array Default Value ------------- *value* or ``zeros(min(shape))``, where ``min(shape)`` refers to the minimum shape allowed by the array. If *shape* is not specified, the minimum shape is (0,). Description ----------- An Array trait allows only upcasting of assigned values that are already numpy arrays. It automatically casts tuples and lists of the right shape to the specified *dtype* (just like numpy's **array** does). """ super( Array, self ).__init__( dtype, shape, value, False, typecode = typecode, **metadata ) #------------------------------------------------------------------------------- # 'CArray' trait: #------------------------------------------------------------------------------- class CArray ( AbstractArray ): """ Defines a trait whose value must be a numpy array, with casting allowed. """ def __init__ ( self, dtype = None, shape = None, value = None, typecode = None, **metadata ): """ Returns a CArray trait. Parameters ---------- dtype : a numpy dtype (e.g., int32) The type of elements in the array shape : a tuple Describes the required shape of any assigned value. Wildcards and ranges are allowed. The value None within the *shape* tuple means that the corresponding dimension is not checked. (For example, ``shape=(None,3)`` means that the first dimension can be any size, but the second must be 3.) A two-element tuple within the *shape* tuple means that the dimension must be in the specified range. The second element can be None to indicate that there is no upper bound. (For example, ``shape=((3,5),(2,None))`` means that the first dimension must be in the range 3 to 5 (inclusive), and the second dimension must be at least 2.) value : numpy array A default value for the array Default Value ------------- *value* or ``zeros(min(shape))``, where ``min(shape)`` refers to the minimum shape allowed by the array. If *shape* is not specified, the minimum shape is (0,). Description ----------- The trait returned by CArray() is similar to that returned by Array(), except that it allows both upcasting and downcasting of assigned values that are already numpy arrays. It automatically casts tuples and lists of the right shape to the specified *dtype* (just like numpy's **array** does). """ super( CArray, self ).__init__( dtype, shape, value, True, typecode = typecode, **metadata ) traits-4.1.0/traits/interface_checker.py0000644000175100001440000001601611674463323021324 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # # Copyright (c) 2008, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in enthought/LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # # Author: Martin Chilvers # Date: 03/20/2008 # #------------------------------------------------------------------------------ """ An attempt at type-safe casting. """ #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from __future__ import absolute_import from types import FunctionType from inspect import getargspec, getmro from .has_traits import HasTraits #------------------------------------------------------------------------------- # Logging: #------------------------------------------------------------------------------- import logging logger = logging.getLogger( __name__ ) #------------------------------------------------------------------------------- # Constants: #------------------------------------------------------------------------------- # Message templates for interface errors. BAD_SIGNATURE = ("The '%s' class signature for the '%s' method is different " "from that of the '%s' interface.") MISSING_METHOD = ("The '%s' class does not implement the '%s' method of the " "'%s' interface.") MISSING_TRAIT = ("The '%s' class does not implement the %s trait(s) of the " "'%s' interface.") #------------------------------------------------------------------------------- # 'InterfaceError' class: #------------------------------------------------------------------------------- class InterfaceError ( Exception ): """ The exception raised if a class does not really implement an interface. """ pass #------------------------------------------------------------------------------- # 'InterfaceChecker' class: #------------------------------------------------------------------------------- class InterfaceChecker ( HasTraits ): """ Checks that interfaces are actually implemented. """ #--------------------------------------------------------------------------- # 'InterfaceChecker' interface: #--------------------------------------------------------------------------- def check_implements ( self, cls, interfaces, error_mode ): """ Checks that the class implements the specified interfaces. 'interfaces' can be a single interface or a list of interfaces. """ # If a single interface was specified then turn it into a list: try: iter( interfaces ) except TypeError: interfaces = [ interfaces ] # If the class has traits then check that it implements all traits and # methods on the specified interfaces: if issubclass( cls, HasTraits ): for interface in interfaces: if not self._check_has_traits_class( cls, interface, error_mode ): return False # Otherwise, just check that the class implements all methods on the # specified interface: else: for interface in interfaces: if not self._check_non_has_traits_class( cls, interface, error_mode ): return False return True #--------------------------------------------------------------------------- # Private interface: #--------------------------------------------------------------------------- def _check_has_traits_class ( self, cls, interface, error_mode ): """ Checks that a 'HasTraits' class implements an interface. """ return (self._check_traits( cls, interface, error_mode ) and self._check_methods( cls, interface, error_mode )) def _check_non_has_traits_class ( self, cls, interface, error_mode ): """ Checks that a non-'HasTraits' class implements an interface. """ return self._check_methods( cls, interface, error_mode ) def _check_methods ( self, cls, interface, error_mode ): """ Checks that a class implements the methods on an interface. """ cls_methods = self._get_public_methods( cls ) interface_methods = self._get_public_methods( interface ) for name in interface_methods: if name not in cls_methods: return self._handle_error( MISSING_METHOD % ( self._class_name( cls ), name, self._class_name( interface ) ), error_mode ) # Check that the method signatures are the same: cls_argspec = getargspec( cls_methods[ name ] ) interface_argspec = getargspec( interface_methods[ name ] ) if cls_argspec != interface_argspec: return self._handle_error( BAD_SIGNATURE % ( self._class_name( cls ), name, self._class_name( interface ) ), error_mode ) return True def _check_traits ( self, cls, interface, error_mode ): """ Checks that a class implements the traits on an interface. """ missing = set( interface.class_traits() ).difference( set( cls.class_traits() ) ) if len( missing ) > 0: return self._handle_error( MISSING_TRAIT % ( self._class_name( cls ), `list( missing )`[1:-1], self._class_name( interface ) ), error_mode ) return True def _get_public_methods ( self, cls ): """ Returns all public methods on a class. Returns a dictionary containing all public methods keyed by name. """ public_methods = {} for c in getmro( cls ): # Stop when we get to 'HasTraits'!: if c is HasTraits: break for name, value in c.__dict__.items(): if ((not name.startswith( '_' )) and (type( value ) is FunctionType)): public_methods[ name ] = value return public_methods def _class_name ( self, cls ): return cls.__name__ def _handle_error ( self, msg, error_mode ): if error_mode > 1: raise InterfaceError( msg ) if error_mode == 1: logger.warning( msg ) return False # A default interface checker: checker = InterfaceChecker() def check_implements ( cls, interfaces, error_mode = 0 ): """ Checks that the class implements the specified interfaces. 'interfaces' can be a single interface or a list of interfaces. """ return checker.check_implements( cls, interfaces, error_mode ) traits-4.1.0/traits/testing/0000755000175100001440000000000011674463323016777 5ustar ischnellusers00000000000000traits-4.1.0/traits/testing/dependencies/0000755000175100001440000000000011674463323021425 5ustar ischnellusers00000000000000traits-4.1.0/traits/testing/dependencies/ImportManager.py0000644000175100001440000002170411674463323024550 0ustar ischnellusers00000000000000""" This code was found on http://www.webwareforpython.org/. The only modifications are for the explicit purpose of tracking circular dependencies. """ """ImportManager Manages imported modules and protects against concurrent imports. Keeps lists of all imported Python modules and templates as well as other config files used by Webware for Python. For modules which are not directly imported, ImportManager can use ImportSpy to keep track of them. This can be used to detect changes in source files, templates or config files in order to reload them automatically by the AutoReloadingAppServer. The use of ImportSpy can be suppressed with the``UseImportSpy`` setting. """ #from Common import * import os import sys import imp class ImportLock: """Lock for multi-threaded imports. Provides a lock for protecting against concurrent imports. This is necessary because WebKit is multithreaded and uses its own import hook. This class abstracts the difference between using the Python interpreter's global import lock, and using our own RLock. The global lock is the correct solution, but is only available in Python since version 2.2.3. If it's not available, we fall back to using an RLock (which is not as good, but better than nothing). """ def __init__(self): """Create the lock. Aliases the `acquire` and `release` methods to `imp.acquire_lock` and `imp.release_lock` (if available), or to acquire and release our own RLock. """ if hasattr(imp, 'acquire_lock'): self.acquire = imp.acquire_lock self.release = imp.release_lock else: # fallback for Python < 2.3 from threading import RLock self._lock = RLock() self.acquire = self._lock.acquire self.release = self._lock.release class ImportManager(object): """The import manager. Keeps track of the Python modules and other system files that have been imported and are used by Webware. """ _imp = _spy = None def __init__(self): """Create import hook.""" assert not self._imp, "Only one instance of ImportManager is possible." self._imp = True # Object.__init__(self) self._lock = ImportLock() self._fileList = {} self._moduleFiles = {} self._otherFiles = set() self._notifyHook = None def load_module(self, name, file, filename, info): """Replaces imp.load_module.""" try: try: self._lock.acquire() mod = imp.load_module(name, file, filename, info) finally: self._lock.release() self.recordModule(mod) except: # Also record filepaths which weren't successfully loaded, which # may happen due to a syntax error in a servlet, because we also # want to know when such a file is modified: self.recordFile(filename) raise return mod def find_module(self, name, path=None): """Replaces imp.find_module.""" return imp.find_module(name, path) def activateImportSpy(self): """Activate ImportSpy to keep track of modules loaded elsewhere.""" if not self._spy: from ImportSpy import activate self._spy = activate(self) return self._spy def fileList(self, update=True): """Return the list of tracked files.""" if not self._spy and update: # Update list of files of imported modules moduleNames = [] for modname in sys.modules: if not self._moduleFiles.has_key(modname): moduleNames.append(modname) if moduleNames: self.recordModules(moduleNames) return self._fileList def notifyOfNewFiles(self, hook): """Register notification hook. Called by someone else to register that they'd like to be know when a new file is imported. """ self._notifyHook = hook def watchFile(self, path, modname=None, getmtime=os.path.getmtime): """Add more files to watch without importing them.""" modtime = getmtime(path) self._fileList[path] = modtime if modname: self._moduleFiles[modname] = path else: self._otherFiles.add(path) # send notification that this file was imported if self._notifyHook: self._notifyHook(path, modtime) def recordModule(self, mod, isfile=os.path.isfile): """Record a module.""" modname = getattr(mod, '__name__', None) if not modname or not sys.modules.has_key(modname): return fileList = self._fileList # __orig_file__ is used for PSP, Kid and Cheetah templates; we want # to record the source filenames, not the auto-generated modules: f = getattr(mod, '__orig_file__', None) if f and not fileList.has_key(f): try: if isfile(f): self.watchFile(f, modname) except OSError: pass else: f = getattr(mod, '__file__', None) if f and not fileList.has_key(f): # record the .py file corresponding to each .pyc or .pyo if f[-4:].lower() in ['.pyc', '.pyo']: f = f[:-1] try: if isfile(f): self.watchFile(f, modname) else: self.watchFile(os.path.join(f, '__init__.py')) except OSError: pass def recordModules(self, moduleNames=None): """Record a list of modules (or all modules).""" if moduleNames is None: moduleNames = sys.modules.keys() for modname in moduleNames: mod = sys.modules[modname] self.recordModule(mod) def recordFile(self, filename, isfile=os.path.isfile): """Record a file.""" if isfile(filename): self.watchFile(filename) def fileUpdated(self, filename, update=True, getmtime=os.path.getmtime): """Check whether file has been updated.""" fileList = self.fileList(update) try: mtime = fileList[filename] except KeyError: return True try: newmtime = getmtime(filename) except OSError: return True if mtime < newmtime: fileList[filename] = newmtime for modname, modfile in self._moduleFiles.items(): if modfile == filename: break else: return True # it's not a module, we must reload mod = sys.modules.get(modname, None) if not mod or not getattr(mod, '__donotreload__', None): return True # it's a module that needs to be reloaded return False def updatedFile(self, update=True, getmtime=os.path.getmtime): """Check whether one of the files has been updated.""" fileList = self.fileList(update) for filename, mtime in fileList.items(): try: newmtime = getmtime(filename) except OSError: return filename if mtime < newmtime: fileList[filename] = newmtime for modname, modfile in self._moduleFiles.items(): if modfile == filename: break else: return filename # it's not a module, we must reload mod = sys.modules.get(modname, None) if not mod or not getattr(mod, '__donotreload__', None): return filename # it's a module that needs to be reloaded return False def delModules(self, includePythonModules=False, excludePrefixes=[]): """Delete imported modules. Deletes all the modules that the ImportSpy has ever imported unless they are part of WebKit. This in support of DebugAppServer's useful (yet imperfect) support for AutoReload. """ moduleFiles = self._moduleFiles moduleNames = moduleFiles.keys() fileList = self._fileList for modname in moduleNames: if modname == __name__: continue filename = self._moduleFiles[modname] if not includePythonModules: if not filename or filename.startswith(sys.prefix): continue for prefix in excludePrefixes: if modname.startswith(prefix): break else: try: del sys.modules[modname] except KeyError: pass try: del moduleFiles[modname] except KeyError: pass try: del fileList[filename] except KeyError: pass traits-4.1.0/traits/testing/dependencies/circular_test.py0000644000175100001440000000440711674463323024647 0ustar ischnellusers00000000000000import ImportSpy import ImportManager import sys import os import getopt def usage(): print "usage: %s [--chart] [-p] input" % sys.argv[0] def generate_dot(parent, dependents): # omit standardy python modules import distutils.sysconfig dirs_to_omit = [ os.path.realpath(os.path.join(distutils.sysconfig.get_python_lib(), '..')) ] if 'win32' == sys.platform: for i in range(len(dirs_to_omit)): dir = dirs_to_omit[i] dirs_to_omit[i] = dir.lower() s = '' for d in dependents: try: __import__(d) file = sys.modules[d].__file__ if 'win32' == sys.platform: file = file.lower() if os.path.dirname(file) not in dirs_to_omit: s += ' "' + parent + '" -> "' + d + '";\n' else: print "omitting " + d except Exception, ex: print "importing %s failed" % d return s def generate_dot_file(top, dep_map, filename): s = 'digraph dependencies {\n' s += generate_dot(top, dep_map.keys()) for key,value in dep_map.items(): s += generate_dot(key, value) s += '}\n' f = open(filename, "w") f.write(s) f.close() def main(): try: opts, args = getopt.getopt(sys.argv[1:], "p", ["chart"]) except getopt.GetoptError, ex: print ex usage() sys.exit(65) if len(args) != 1: usage() sys.exit(65) package_flag = False chart_flag = False for opt,arg in opts: if opt == "-p": package_flag = True if opt == "--chart": chart_flag = True import_manager = ImportManager.ImportManager() import_manager.notifyOfNewFiles(ImportSpy.circular_tester) ImportSpy.activate(import_manager) if package_flag: __import__(args[0]) else: #todo: tinker with __name__ execfile(args[0]) sys.path_hooks = sys.path_hooks[:-1] if chart_flag: dot_file = "dependencies.dot" generate_dot_file(args[0], ImportSpy.dependency_map, dot_file) #try to find 'dot' import subprocess if 0 == subprocess.call('dot -T svg -o %s %s' % (args[0] + ".svg", dot_file)): os.unlink(dot_file) if __name__ == "__main__": main() traits-4.1.0/traits/testing/dependencies/ImportSpy.py0000644000175100001440000001411511674463323023747 0ustar ischnellusers00000000000000""" This code was found on http://www.webwareforpython.org/. The only modifications are for the explicit purpose of tracking circular dependencies. """ """ImportSpy Keeps track of modules not imported directly by Webware for Python. This module helps save the filepath of every module which is imported. This is used by the `AutoReloadingAppServer` (see doc strings for more information) to restart the server if any source files change. Other than keeping track of the filepaths, the behaviour of this module loader is identical to Python's default behaviour. If the system supports FAM (file alteration monitor) and python-fam is installed, then the need for reloading can be monitored very effectively with the use of ImportSpy. Otherwise, ImportSpy will not have much benefit. Note that ImportSpy is based on the new import hooks of Python 2.3 described in PEP 302, falling back to the old ihooks module if the new hooks are not available. In some cases this may become problematic, when other templating systems are used with Webware which are also using ihook support to load their templates, or if they are using zipimports. Therefore, it is possible to suppress the use of ImportSpy by setting `UseImportSpy` in AppServer.config to False. """ try: # if possible, use new (PEP 302) import hooks from sys import path_hooks, path_importer_cache except ImportError: path_hooks = None import os.path import sys incomplete_imports = [] find_module_chain = [] dependency_map = {} indent = 0 debug = False def path_could_be_package(path, package): parts = package.split('.') parts.reverse() for part in parts: basename, ext = os.path.splitext(os.path.basename(path)) if ext == ".so": if basename != part: part += "module" elif basename != part: return False path = os.path.dirname(path) return True def circular_tester(path, modtime): if len(find_module_chain) == 0: return elif path_could_be_package(path, find_module_chain[-1]): return for m in incomplete_imports: try: n,p,d = ImportSpy._imp.find_module(m) except ImportError: print " import stack: " + str(incomplete_imports) sys.exit(65) if path_hooks is not None: from os.path import isdir class ImportSpy(object): """New style import tracker.""" _imp = None def __init__(self, path=None): """Create importer.""" assert self._imp if path and isdir(path): self.path = path else: raise ImportError def find_module(self, fullname): """Replaces imp.find_module.""" global indent if debug: print ' '*indent + "Find module(self, %s)" % fullname indent += 1 try: self.file, self.filename, self.info = self._imp.find_module( fullname.split('.')[-1], [self.path]) if (os.path.isdir(self.filename)): find_module_chain.append(fullname) except ImportError: self.file = None if self.file: find_module_chain.append(fullname) indent -= 1 return self else: indent -= 1 return None def load_module(self, fullname): """Replaces imp.load_module.""" global indent global find_module_chain if debug: print ' '*indent + "Load module %s" % fullname indent += 1 # build the dependency map if len(find_module_chain) > 1: parent = find_module_chain[-2] if dependency_map.has_key(parent): dependency_map[parent].append(fullname) else: dependency_map[parent] = [fullname] else: if len(incomplete_imports) == 0: # this is a top level node pass else: parent = incomplete_imports[-1] if dependency_map.has_key(parent): dependency_map[parent].append(fullname) else: dependency_map[parent] = [fullname] incomplete_imports.append(fullname) mod = self._imp.load_module(fullname, self.file, self.filename, self.info) incomplete_imports.remove(fullname) find_module_chain = [] indent -= 1 if debug: print ' '*indent + "Complete loading %s" % fullname if mod: mod.__loader__ = self return mod def activate(imp_manager): """Activate ImportSpy.""" assert not ImportSpy._imp ImportSpy._imp = imp_manager path_hooks.append(ImportSpy) path_importer_cache.clear() imp_manager.recordModules() return 'new import hooks' else: # Python < 2.3, fall back to using the old ihooks module import ihooks class ImportSpy(ihooks.ModuleLoader): """Old style import tracker.""" _imp = None def __init__(self): """Create import hook.""" assert self._imp ihooks.ModuleLoader.__init__(self) self._lock = self._imp._lock imp = ihooks.ModuleImporter(loader=self) ihooks.install(imp) self._imp.recordModules() def load_module(self, name, stuff): """Replaces imp.load_module.""" file, filename, info = stuff try: try: self._lock.acquire() mod = ihooks.ModuleLoader.load_module(self, name, stuff) finally: self._lock.release() self._imp.recordModule(mod) except: self._imp.recordFile(filename) raise return mod def activate(imp_manager): """Activate ImportSpy.""" assert not ImportSpy._imp ImportSpy._imp = imp_manager ImportSpy() return 'ihooks' traits-4.1.0/traits/testing/dependencies/deptrack.py0000644000175100001440000001170511674463323023600 0ustar ischnellusers00000000000000import os import sys import subprocess import pickle import operator dependent_pickle_name = "dependents.pickle" def get_dependent(module_name): if os.path.exists(dependent_pickle_name): dep_map = pickle.load(open(dependent_pickle_name, "r")) if dep_map.has_key(module_name): return dep_map[module_name] return None def store_dependent(module_name, module): if os.path.exists(dependent_pickle_name): dep_map = pickle.load(open(dependent_pickle_name, "r")) else: dep_map = {} dep_map[module_name] = module pickle.dump(dep_map, open(dependent_pickle_name, "w")) def print_dependencies(module_name): dep_map = pickle.load(open(dependent_pickle_name, "r")) print dep_map[module_name].pretty_print(0) def generate_dot_file(filename): s = 'digraph dependencies {\n' dep_map = pickle.load(open(dependent_pickle_name, "r")) for key,value in dep_map.items(): s += value.generate_dot() s += '}\n' f = open(filename, "w") f.write(s) f.close() class Dependent(object): def __init__(self, name, path, script=False): self.name = name self.path = path if script: self.dependents = self._exec_script() else: self.dependents = self._find_dependencies_subprocess() store_dependent(self.name, self) def _exec_script(self): global_dict = globals() global_dict['__name__'] = self.name global_dict['__file__'] = self.path global_dict['sys.argv'] = self.path before = sys.modules.keys() sys.path.append(os.path.dirname(self.path)) execfile(self.path, global_dict) after = sys.modules.keys() dependents = [] for key in after: if key not in before: m = sys.modules[key] if (m is not None) and ('__path__' in dir(m)): dependent = get_dependent(m.__name__) if (dependent is None): new_dependent = Dependent(m.__name__, m.__path__) dependents.append(new_dependent) store_dependent(m.__name__, new_dependent) return dependents def _find_dependencies_subprocess(self): dependent = get_dependent(self.name) if dependent is None: # put something in the map now & pickle it so # subprocesses wont get stuck in a loop store_dependent(self.name, '') subprocess.call([sys.executable, sys.argv[0], "-m", self.name]) store_dependent(self.name, self) f = open(self.name + ".pickle", "r") return pickle.load(f) else: return d.dependents def __str__(self): return self.__format_str__(0) def pretty_print(self, indent): s = operator.repeat(' ', indent) + self.name + "\n" indent = indent + 2 for d in self.dependents: s += operator.repeat(' ', indent) + d.name + "\n" for d in self.dependents: s += d.pretty_print(indent) + "\n" #trim the last newline off return s[:-1] def generate_dot(self): s = '' for d in self.dependents: s += ' "' + self.name + '" -> "' + d.name + '";\n' return s def find_dependencies_script(filename): script = Dependent(os.path.basename(filename).split(".")[0], filename, script=True) store_dependent(script.name, script) return def find_dependencies_module(module): dependents = [] before = sys.modules.keys() try: __import__(module) except: print "[ERROR] importing %s failed" % module after = sys.modules.keys() for key in after: if key not in before: m = sys.modules[key] if (m is not None) and ('__path__' in dir(m)): dependent = get_dependent(m.__name__) if (dependent is None): new_dependent = Dependent(m.__name__, m.__path__) dependents.append(new_dependent) store_dependent(m.__name__, new_dependent) f = open(module + ".pickle", "w") pickle.dump(dependents, f) return dependents def clean_pickles(): import glob pickles = glob.glob("*.pickle") for pickle in pickles: os.unlink(pickle) def usage(): print "usage:" print " %s: <-m|-s> [[-o] [filename]]" % sys.argv[0] sys.exit(65) if __name__ == "__main__": if len(sys.argv) < 3: usage() if "-m" == sys.argv[1]: dependencies = find_dependencies_module(sys.argv[2]) elif "-s" == sys.argv[1]: clean_pickles() find_dependencies_script(sys.argv[2]) else: usage() if len(sys.argv) > 3: if sys.argv[3] == '-o': if len(sys.argv) > 4: generate_dot_file(sys.argv[4]) else: name,ext = os.path.splitext(sys.argv[2]) print_dependencies(name) else: usage() # only clean the pickles up if its a script, so the module subprocesses can find # them later # # TODO: add a command line flag for keeping the pickles # elif "-s" == sys.argv[1]: clean_pickles() traits-4.1.0/traits/testing/api.py0000644000175100001440000000014211674463323020117 0ustar ischnellusers00000000000000from doctest_tools import doctest_for_module from nose_tools import deprecated, performance, skip traits-4.1.0/traits/testing/nose_tools.py0000644000175100001440000000245511674463323021543 0ustar ischnellusers00000000000000"Non-standard functions for the 'nose' testing framework." try: from nose import DeprecatedTest, SkipTest from nose.tools import make_decorator def skip(f): """ Decorator to indicate a test should be skipped. """ def g(*args, **kw): raise SkipTest() return make_decorator(f)(g) def deprecated(f): """ Decorator to indicate a test is deprecated. """ def g(*args, **kw): raise DeprecatedTest() return make_decorator(f)(g) except ImportError: # Define stubs in case nose isn't installed. import warnings def skip(f): """ Stub replacement for marking a unit test to be skipped in the absence of 'nose'. """ warnings.warn("skipping unit tests requires the package 'nose'") return f def deprecated(f): """ Stub replacement for marking a unit test deprecated in the absence of 'nose'. """ warnings.warn("skipping deprecated unit tests requires the package 'nose'") return f def performance(f): """ Decorator to add an attribute to the test to mark it as a performance-measuring test. """ f.performance = True return f #### EOF ####################################################################### traits-4.1.0/traits/testing/__init__.py0000644000175100001440000000071211674463323021110 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # Copyright (c) 2005 by Enthought, Inc. # All rights reserved. #------------------------------------------------------------------------------ """ Scripts related to running unit tests, based on testoob. Part of the ETSDevTools project of the Enthought Tool Suite. These scripts also allow running test suites in separate processes and aggregating the results. """ traits-4.1.0/traits/testing/doctest_tools.py0000644000175100001440000000326511674463323022244 0ustar ischnellusers00000000000000""" Tools for having doctest and unittest work together more nicely. Eclipse's PyDev plugin will run your unittest files for you very nicely. The doctest_for_module function allows you to easily run the doctest for a module along side your standard unit tests within Eclipse. """ # Standard library imports import doctest import unittest import sys def doctest_for_module(module): """ Create a TestCase from a module's doctests that will be run by the standard unittest.main(). Example tests/test_foo.py:: import unittest import foo from traits.testing.api import doctest_for_module class FooTestCase(unittest.TestCase): ... class FooDocTest(doctest_for_module(foo)): pass if __name__ == "__main__": # This will run and report both FooTestCase and the doctests in # module foo. unittest.main() Alternatively, you can say:: FooDocTest = doctest_for_module(foo) instead of:: class FooDocTest(doctest_for_module(foo)): pass """ class C(unittest.TestCase): def test_dummy(self): pass # Make the test case loader find us def run(self, result=None): # doctest doesn't like nose.result.TextTestResult objects, # so we try to determine if thats what we're dealing # with and use its internal result attribute instead if hasattr(result, 'result'): doctest.DocTestSuite(module).run(result.result) else: doctest.DocTestSuite(module).run(result) return C traits-4.1.0/traits/trait_errors.py0000644000175100001440000001076411674463323020423 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # # Copyright (c) 2005, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in enthought/LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # # Author: David C. Morrill # Date: 06/21/2002 # #------------------------------------------------------------------------------ """ Defines the standard exceptions raised by the Traits package. """ #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from __future__ import absolute_import import exceptions from types import InstanceType from .trait_base import class_of #------------------------------------------------------------------------------- # Utilities #------------------------------------------------------------------------------- def repr_type(obj): """ Return a string representation of a value and its type for readable error messages. """ the_type = type(obj) if the_type is InstanceType: # Old-style class. the_type = obj.__class__ msg = '%r %r' % (obj, the_type) return msg #------------------------------------------------------------------------------- # 'TraitError' class: #------------------------------------------------------------------------------- class TraitError ( exceptions.Exception ): def __init__ ( self, args = None, name = None, info = None, value = None ): if name is None: # If the given args is not a tuple then assume that the user intended # it to be the single item in a one-element tuple. if not isinstance(args, tuple): args = args, self.args = args else: # Save the information, in case the 'args' object is not the correct # one, and we need to regenerate the message later: self.name = name self.info = info self.value = value self.desc = None self.prefix = 'The' self.set_desc( None, args ) def set_desc ( self, desc, object = None ): if hasattr( self, 'desc' ): if desc is not None: self.desc = desc if object is not None: self.object = object self.set_args() def set_prefix ( self, prefix ): if hasattr( self, 'prefix' ): self.prefix = prefix self.set_args() def set_args ( self ): if self.desc is None: extra = '' else: extra = ' specifies %s and' % self.desc obj = getattr( self, 'object', None ) # Note: self.args must be a tuple so be sure to leave the trailing # commas. the_type = type(self.value) if the_type is InstanceType: the_type = self.value.__class__ if obj is not None: self.args = ("%s '%s' trait of %s instance%s must be %s, " "but a value of %s was specified." % ( self.prefix, self.name, class_of(obj), extra, self.info, repr_type(self.value))), else: self.args = ("%s '%s' trait%s must be %s, but a value of %s was " "specified." % (self.prefix, self.name, extra, self.info, repr_type(self.value))), #------------------------------------------------------------------------------- # 'TraitNotificationError' class: #------------------------------------------------------------------------------- class TraitNotificationError ( exceptions.Exception ): pass #------------------------------------------------------------------------------- # 'DelegationError' class: #------------------------------------------------------------------------------- class DelegationError ( TraitError ): def __init__ ( self, args ): # .args must be a tuple. self.args = args, #------------------------------------------------------------------------------- # Export the defined exceptions to the C-base traits module: #------------------------------------------------------------------------------- from . import ctraits ctraits._exceptions( TraitError, DelegationError ) traits-4.1.0/traits/ctraits.c0000644000175100001440000062256311674463323017155 0ustar ischnellusers00000000000000/****************************************************************************** * * Description: C based implementation of the Traits package * * Copyright (c) 2005, Enthought, Inc. * All rights reserved. * * This software is provided without warranty under the terms of the BSD * license included in enthought/LICENSE.txt and may be redistributed only * under the conditions described in the aforementioned license. The license * is also available online at http://www.enthought.com/licenses/BSD.txt * * Thanks for using Enthought open source! * * Author: David C. Morrill * Date: 06/15/2004 * ******************************************************************************/ /*----------------------------------------------------------------------------- | Includes: +----------------------------------------------------------------------------*/ #include "Python.h" #include "structmember.h" /*----------------------------------------------------------------------------- | Constants: +----------------------------------------------------------------------------*/ static PyObject * class_traits; /* == "__class_traits__" */ static PyObject * listener_traits; /* == "__listener_traits__" */ static PyObject * editor_property; /* == "editor" */ static PyObject * class_prefix; /* == "__prefix__" */ static PyObject * trait_added; /* == "trait_added" */ static PyObject * empty_tuple; /* == () */ static PyObject * Undefined; /* Global 'Undefined' value */ static PyObject * Uninitialized; /* Global 'Uninitialized' value */ static PyObject * TraitError; /* TraitError exception */ static PyObject * DelegationError; /* DelegationError exception */ static PyObject * TraitListObject; /* TraitListObject class */ static PyObject * TraitSetObject; /* TraitSetObject class */ static PyObject * TraitDictObject; /* TraitDictObject class */ static PyObject * TraitValue; /* TraitValue class */ static PyObject * adapt; /* PyProtocols 'adapt' function */ static PyObject * validate_implements; /* 'validate implementation' function */ static PyObject * is_callable; /* Marker for 'callable' value */ static PyObject * _HasTraits_monitors; /* Object creation monitors. */ static PyObject * _trait_notification_handler; /* User supplied trait */ /* notification handler (intended for use by debugging tools) */ static PyTypeObject * ctrait_type; /* Python-level CTrait type reference */ /*----------------------------------------------------------------------------- | Macro definitions: +----------------------------------------------------------------------------*/ /* The following macro is automatically defined in Python 2.4 and later: */ #ifndef Py_VISIT #define Py_VISIT(op) \ do { \ if (op) { \ int vret = visit((PyObject *)(op), arg); \ if (vret) return vret; \ } \ } while (0) #endif /* The following macro is automatically defined in Python 2.4 and later: */ #ifndef Py_CLEAR #define Py_CLEAR(op) \ do { \ if (op) { \ PyObject *tmp = (PyObject *)(op); \ (op) = NULL; \ Py_DECREF(tmp); \ } \ } while (0) #endif #define DEFERRED_ADDRESS(ADDR) 0 #define PyTrait_CheckExact(op) ((op)->ob_type == ctrait_type) #define PyHasTraits_Check(op) PyObject_TypeCheck(op, &has_traits_type) #define PyHasTraits_CheckExact(op) ((op)->ob_type == &has_traits_type) /* Trait method related: */ #define TP_DESCR_GET(t) \ (PyType_HasFeature(t, Py_TPFLAGS_HAVE_CLASS) ? (t)->tp_descr_get : NULL) #define OFF(x) offsetof(trait_method_object, x) /* Notification related: */ #define has_notifiers(tnotifiers,onotifiers) \ ((((tnotifiers) != NULL) && (PyList_GET_SIZE((tnotifiers))>0)) || \ (((onotifiers) != NULL) && (PyList_GET_SIZE((onotifiers))>0))) /* Field accessors: */ #define trait_method_GET_NAME(meth) \ (((trait_method_object *) meth)->tm_name) #define trait_method_GET_FUNCTION(meth) \ (((trait_method_object *) meth)->tm_func) #define trait_method_GET_SELF(meth) \ (((trait_method_object *) meth)->tm_self) #define trait_method_GET_TRAITS(meth) \ (((trait_method_object *) meth)->tm_traits) #define trait_method_GET_CLASS(meth) \ (((trait_method_object *) meth)->tm_class) /* Python version dependent macros: */ #if ( (PY_MAJOR_VERSION == 2) && (PY_MINOR_VERSION < 3) ) #define PyMODINIT_FUNC void #define PyDoc_VAR(name) static char name[] #define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str) #ifdef WITH_DOC_STRINGS #define PyDoc_STR(str) str #else #define PyDoc_STR(str) "" #endif #endif #if (PY_VERSION_HEX < 0x02050000) typedef int Py_ssize_t; #endif /*----------------------------------------------------------------------------- | Forward declarations: +----------------------------------------------------------------------------*/ static PyTypeObject trait_type; static PyTypeObject trait_method_type; static PyTypeObject has_traits_type; /*----------------------------------------------------------------------------- | 'ctraits' module doc string: +----------------------------------------------------------------------------*/ PyDoc_STRVAR( ctraits__doc__, "The ctraits module defines the CHasTraits and CTrait C extension types that\n" "define the core performance oriented portions of the Traits package." ); /*----------------------------------------------------------------------------- | HasTraits behavior modification flags: +----------------------------------------------------------------------------*/ /* Object has been initialized: */ #define HASTRAITS_INITED 0x00000001 /* Do not send notifications when a trait changes value: */ #define HASTRAITS_NO_NOTIFY 0x00000002 /* Requests that no event notifications be sent when this object is assigned to a trait: */ #define HASTRAITS_VETO_NOTIFY 0x00000004 /*----------------------------------------------------------------------------- | 'CHasTraits' instance definition: | | Note: traits are normally stored in the type's dictionary, but are added to | the instance's traits dictionary 'trait_dict' when the traits are defined | dynamically or 'on_trait_change' is called on an instance of the trait. | | All 'anytrait_changed' notification handlers are stored in the instance's | 'notifiers' list. +----------------------------------------------------------------------------*/ typedef struct { PyObject_HEAD /* Standard Python object header */ PyDictObject * ctrait_dict; /* Class traits dictionary */ PyDictObject * itrait_dict; /* Instance traits dictionary */ PyListObject * notifiers; /* List of 'any trait changed' notification handlers */ int flags; /* Behavior modification flags */ PyObject * obj_dict; /* Object attribute dictionary ('__dict__') */ /* NOTE: 'obj_dict' field MUST be last field */ } has_traits_object; static int call_notifiers ( PyListObject *, PyListObject *, has_traits_object *, PyObject *, PyObject *, PyObject * new_value ); /*----------------------------------------------------------------------------- | 'CTrait' flag values: +----------------------------------------------------------------------------*/ /* The trait is a Property: */ #define TRAIT_PROPERTY 0x00000001 /* Should the delegate be modified (or the original object)? */ #define TRAIT_MODIFY_DELEGATE 0x00000002 /* Should a simple object identity test be performed (or a rich compare)? */ #define TRAIT_OBJECT_IDENTITY 0x00000004 /* Make 'setattr' store the original unvalidated value */ #define TRAIT_SETATTR_ORIGINAL_VALUE 0x00000008 /* Send the 'post_setattr' method the original unvalidated value */ #define TRAIT_POST_SETATTR_ORIGINAL_VALUE 0x00000010 /* Can a 'TraitValue' be assigned to override the trait definition? */ #define TRAIT_VALUE_ALLOWED 0x00000020 /* Is this trait a special 'TraitValue' trait that uses a property? */ #define TRAIT_VALUE_PROPERTY 0x00000040 /* Does this trait have an associated 'mapped' trait? */ #define TRAIT_IS_MAPPED 0x00000080 /* Should any old/new value test be performed before generating notifications? */ #define TRAIT_NO_VALUE_TEST 0x00000100 /*----------------------------------------------------------------------------- | 'CTrait' instance definition: +----------------------------------------------------------------------------*/ typedef struct _trait_object a_trait_object; typedef PyObject * (*trait_getattr)( a_trait_object *, has_traits_object *, PyObject * ); typedef int (*trait_setattr)( a_trait_object *, a_trait_object *, has_traits_object *, PyObject *, PyObject * ); typedef int (*trait_post_setattr)( a_trait_object *, has_traits_object *, PyObject *, PyObject * ); typedef PyObject * (*trait_validate)( a_trait_object *, has_traits_object *, PyObject *, PyObject * ); typedef PyObject * (*delegate_attr_name_func)( a_trait_object *, has_traits_object *, PyObject * ); typedef struct _trait_object { PyObject_HEAD /* Standard Python object header */ int flags; /* Flag bits */ trait_getattr getattr; /* Get trait value handler */ trait_setattr setattr; /* Set trait value handler */ trait_post_setattr post_setattr; /* Optional post 'setattr' handler */ PyObject * py_post_setattr; /* Python-based post 'setattr' hndlr */ trait_validate validate; /* Validate trait value handler */ PyObject * py_validate; /* Python-based validate value handler */ int default_value_type; /* Type of default value: see the 'default_value_for' function */ PyObject * default_value; /* Default value for trait */ PyObject * delegate_name; /* Optional delegate name */ /* Also used for 'property get' */ PyObject * delegate_prefix; /* Optional delegate prefix */ /* Also used for 'property set' */ delegate_attr_name_func delegate_attr_name; /* Optional routine to return*/ /* the computed delegate attribute name */ PyListObject * notifiers; /* Optional list of notification handlers */ PyObject * handler; /* Associated trait handler object */ /* NOTE: The 'obj_dict' field MUST be last */ PyObject * obj_dict; /* Standard Python object dictionary */ } trait_object; /* Forward declarations: */ static void trait_clone ( trait_object *, trait_object * ); static PyObject * has_traits_getattro ( has_traits_object * obj, PyObject * name ); static int has_traits_setattro ( has_traits_object * obj, PyObject * name, PyObject * value ); static PyObject * get_trait ( has_traits_object * obj, PyObject * name, int instance ); static int trait_property_changed ( has_traits_object * obj, PyObject * name, PyObject * old_value, PyObject * new_value ); static int setattr_event ( trait_object * traito, trait_object * traitd, has_traits_object * obj, PyObject * name, PyObject * value ); static int setattr_disallow ( trait_object * traito, trait_object * traitd, has_traits_object * obj, PyObject * name, PyObject * value ); /*----------------------------------------------------------------------------- | Raise a TraitError: +----------------------------------------------------------------------------*/ static PyObject * raise_trait_error ( trait_object * trait, has_traits_object * obj, PyObject * name, PyObject * value ) { PyObject * result = PyObject_CallMethod( trait->handler, "error", "(OOO)", obj, name, value ); Py_XDECREF( result ); return NULL; } /*----------------------------------------------------------------------------- | Raise a fatal trait error: +----------------------------------------------------------------------------*/ static int fatal_trait_error ( void ) { PyErr_SetString( TraitError, "Non-trait found in trait dictionary" ); return -1; } /*----------------------------------------------------------------------------- | Raise an "attribute is not a string" error: +----------------------------------------------------------------------------*/ static int invalid_attribute_error ( void ) { PyErr_SetString( PyExc_TypeError, "attribute name must be string" ); return -1; } /*----------------------------------------------------------------------------- | Raise an "invalid trait definition" error: +----------------------------------------------------------------------------*/ static int bad_trait_error ( void ) { PyErr_SetString( TraitError, "Invalid argument to trait constructor." ); return -1; } /*----------------------------------------------------------------------------- | Raise an "cant set items error" error: +----------------------------------------------------------------------------*/ static PyObject * cant_set_items_error ( void ) { PyErr_SetString( TraitError, "Can not set a collection's '_items' trait." ); return NULL; } /*----------------------------------------------------------------------------- | Raise an "invalid trait definition" error: +----------------------------------------------------------------------------*/ static int bad_trait_value_error ( void ) { PyErr_SetString( TraitError, "Result of 'as_ctrait' method was not a 'CTraits' instance." ); return -1; } /*----------------------------------------------------------------------------- | Raise an invalid delegate error: +----------------------------------------------------------------------------*/ static int bad_delegate_error ( has_traits_object * obj, PyObject * name ) { if ( PyString_Check( name ) ) { PyErr_Format( DelegationError, "The '%.400s' attribute of a '%.50s' object delegates to an attribute which is not a defined trait.", PyString_AS_STRING( name ), obj->ob_type->tp_name ); return -1; } return invalid_attribute_error(); } /*----------------------------------------------------------------------------- | Raise an invalid delegate error: +----------------------------------------------------------------------------*/ static int bad_delegate_error2 ( has_traits_object * obj, PyObject * name ) { if ( PyString_Check( name ) ) { PyErr_Format( DelegationError, "The '%.400s' attribute of a '%.50s' object has a delegate which does not have traits.", PyString_AS_STRING( name ), obj->ob_type->tp_name ); return -1; } return invalid_attribute_error(); } /*----------------------------------------------------------------------------- | Raise a delegation recursion error: +----------------------------------------------------------------------------*/ static int delegation_recursion_error ( has_traits_object * obj, PyObject * name ) { if ( PyString_Check( name ) ) { PyErr_Format( DelegationError, "Delegation recursion limit exceeded while setting the '%.400s' attribute of a '%.50s' object.", PyString_AS_STRING( name ), obj->ob_type->tp_name ); return -1; } return invalid_attribute_error(); } static int delegation_recursion_error2 ( has_traits_object * obj, PyObject * name ) { if ( PyString_Check( name ) ) { PyErr_Format( DelegationError, "Delegation recursion limit exceeded while getting the definition of the '%.400s' trait of a '%.50s' object.", PyString_AS_STRING( name ), obj->ob_type->tp_name ); return -1; } return invalid_attribute_error(); } /*----------------------------------------------------------------------------- | Raise an attempt to delete read-only attribute error: +----------------------------------------------------------------------------*/ static int delete_readonly_error ( has_traits_object * obj, PyObject * name ) { if ( PyString_Check( name ) ) { PyErr_Format( TraitError, "Cannot delete the read only '%.400s' attribute of a '%.50s' object.", PyString_AS_STRING( name ), obj->ob_type->tp_name ); return -1; } return invalid_attribute_error(); } /*----------------------------------------------------------------------------- | Raise an attempt to set a read-only attribute error: +----------------------------------------------------------------------------*/ static int set_readonly_error ( has_traits_object * obj, PyObject * name ) { if ( PyString_Check( name ) ) { PyErr_Format( TraitError, "Cannot modify the read only '%.400s' attribute of a '%.50s' object.", PyString_AS_STRING( name ), obj->ob_type->tp_name ); return -1; } return invalid_attribute_error(); } /*----------------------------------------------------------------------------- | Raise an attempt to set an undefined attribute error: +----------------------------------------------------------------------------*/ static int set_disallow_error ( has_traits_object * obj, PyObject * name ) { if ( PyString_Check( name ) ) { PyErr_Format( TraitError, "Cannot set the undefined '%.400s' attribute of a '%.50s' object.", PyString_AS_STRING( name ), obj->ob_type->tp_name ); return -1; } return invalid_attribute_error(); } /*----------------------------------------------------------------------------- | Raise an attempt to delete a property error: +----------------------------------------------------------------------------*/ static int set_delete_property_error ( has_traits_object * obj, PyObject * name ) { if ( PyString_Check( name ) ) { PyErr_Format( TraitError, "Cannot delete the '%.400s' property of a '%.50s' object.", PyString_AS_STRING( name ), obj->ob_type->tp_name ); return -1; } return invalid_attribute_error(); } /*----------------------------------------------------------------------------- | Raise an undefined attribute error: +----------------------------------------------------------------------------*/ static void unknown_attribute_error ( has_traits_object * obj, PyObject * name ) { PyErr_Format( PyExc_AttributeError, "'%.50s' object has no attribute '%.400s'", obj->ob_type->tp_name, PyString_AS_STRING( name ) ); } /*----------------------------------------------------------------------------- | Raise a '__dict__' must be set to a dictionary error: +----------------------------------------------------------------------------*/ static int dictionary_error ( void ) { PyErr_SetString( PyExc_TypeError, "__dict__ must be set to a dictionary." ); return -1; } /*----------------------------------------------------------------------------- | Raise an exception when a trait method argument is of the wrong type: +----------------------------------------------------------------------------*/ static PyObject * argument_error ( trait_object * trait, PyObject * meth, int arg, PyObject * obj, PyObject * name, PyObject * value ) { PyObject * arg_num = PyInt_FromLong( arg ); if ( arg_num != NULL ) { PyObject * result = PyObject_CallMethod( trait->handler, "arg_error", "(OOOOO)", meth, arg_num, obj, name, value ); Py_XDECREF( result ); Py_XDECREF( arg_num ); } return NULL; } /*----------------------------------------------------------------------------- | Raise an exception when a trait method keyword argument is the wrong type: +----------------------------------------------------------------------------*/ static PyObject * keyword_argument_error ( trait_object * trait, PyObject * meth, PyObject * obj, PyObject * name, PyObject * value ) { PyObject * result = PyObject_CallMethod( trait->handler, "keyword_error", "(OOOO)", meth, obj, name, value ); Py_XDECREF( result ); return NULL; } /*----------------------------------------------------------------------------- | Raise an exception when a trait method keyword argument is the wrong type: +----------------------------------------------------------------------------*/ static PyObject * dup_argument_error ( trait_object * trait, PyObject * meth, int arg, PyObject * obj, PyObject * name ) { PyObject * arg_num = PyInt_FromLong( arg ); if ( arg_num != NULL ) { PyObject * result = PyObject_CallMethod( trait->handler, "dup_arg_error", "(OOOO)", meth, arg_num, obj, name ); Py_XDECREF( result ); Py_XDECREF( arg_num ); } return NULL; } /*----------------------------------------------------------------------------- | Raise an exception when a required trait method argument is missing: +----------------------------------------------------------------------------*/ static PyObject * missing_argument_error ( trait_object * trait, PyObject * meth, int arg, PyObject * obj, PyObject * name ) { PyObject * arg_num = PyInt_FromLong( arg ); if ( arg_num != NULL ) { PyObject * result = PyObject_CallMethod( trait->handler, "missing_arg_error", "(OOOO)", meth, arg_num, obj, name ); Py_XDECREF( result ); Py_XDECREF( arg_num ); } return NULL; } /*----------------------------------------------------------------------------- | Raise an exception when a required trait method argument is missing: +----------------------------------------------------------------------------*/ static PyObject * too_may_args_error ( PyObject * name, int wanted, int received ) { switch ( wanted ) { case 0: PyErr_Format( PyExc_TypeError, "%.400s() takes no arguments (%.3d given)", PyString_AS_STRING( name ), received ); break; case 1: PyErr_Format( PyExc_TypeError, "%.400s() takes exactly 1 argument (%.3d given)", PyString_AS_STRING( name ), received ); break; default: PyErr_Format( PyExc_TypeError, "%.400s() takes exactly %.3d arguments (%.3d given)", PyString_AS_STRING( name ), wanted, received ); break; } return NULL; } /*----------------------------------------------------------------------------- | Raise an exception when a trait method argument is of the wrong type: +----------------------------------------------------------------------------*/ static void invalid_result_error ( trait_object * trait, PyObject * meth, PyObject * obj, PyObject * value ) { PyObject * result = PyObject_CallMethod( trait->handler, "return_error", "(OOO)", meth, obj, value ); Py_XDECREF( result ); } /*----------------------------------------------------------------------------- | Gets/Sets a possibly NULL (or callable) value: +----------------------------------------------------------------------------*/ static PyObject * get_callable_value ( PyObject * value ) { PyObject * tuple, * temp; if ( value == NULL ) value = Py_None; else if ( PyCallable_Check( value ) ) value = is_callable; else if ( PyTuple_Check( value ) && (PyInt_AsLong( PyTuple_GET_ITEM( value, 0 ) ) == 10) ) { tuple = PyTuple_New( 3 ); if ( tuple != NULL ) { PyTuple_SET_ITEM( tuple, 0, temp = PyTuple_GET_ITEM( value, 0 ) ); Py_INCREF( temp ); PyTuple_SET_ITEM( tuple, 1, temp = PyTuple_GET_ITEM( value, 1 ) ); Py_INCREF( temp ); PyTuple_SET_ITEM( tuple, 2, is_callable ); Py_INCREF( is_callable ); value = tuple; } } Py_INCREF( value ); return value; } static PyObject * get_value ( PyObject * value ) { if ( value == NULL ) value = Py_None; Py_INCREF( value ); return value; } static int set_value ( PyObject ** field, PyObject * value ) { Py_INCREF( value ); Py_XDECREF( *field ); *field = value; return 0; } /*----------------------------------------------------------------------------- | Returns the result of calling a specified 'class' object with 1 argument: +----------------------------------------------------------------------------*/ static PyObject * call_class ( PyObject * class, trait_object * trait, has_traits_object * obj, PyObject * name, PyObject * value ) { PyObject * result; PyObject * args = PyTuple_New( 4 ); if ( args == NULL ) return NULL; PyTuple_SET_ITEM( args, 0, trait->handler ); PyTuple_SET_ITEM( args, 1, (PyObject *) obj ); PyTuple_SET_ITEM( args, 2, name ); PyTuple_SET_ITEM( args, 3, value ); Py_INCREF( trait->handler ); Py_INCREF( obj ); Py_INCREF( name ); Py_INCREF( value ); result = PyObject_Call( class, args, NULL ); Py_DECREF( args ); return result; } /*----------------------------------------------------------------------------- | Attempts to get the value of a key in a 'known to be a dictionary' object: +----------------------------------------------------------------------------*/ static PyObject * dict_getitem ( PyDictObject * dict, PyObject *key ) { long hash; assert( PyDict_Check( dict ) ); if ( !PyString_CheckExact( key ) || ((hash = ((PyStringObject *) key)->ob_shash) == -1) ) { hash = PyObject_Hash( key ); if ( hash == -1 ) { PyErr_Clear(); return NULL; } } return (dict->ma_lookup)( dict, key, hash )->me_value; } /*----------------------------------------------------------------------------- | Gets the definition of the matching prefix based trait for a specified name: | | - This should always return a trait definition unless a fatal Python error | occurs. | - The bulk of the work is delegated to a Python implemented method because | the implementation is complicated in C and does not need to be executed | very often relative to other operations. | +----------------------------------------------------------------------------*/ static trait_object * get_prefix_trait ( has_traits_object * obj, PyObject * name, int is_set ) { PyObject * trait = PyObject_CallMethod( (PyObject *) obj, "__prefix_trait__", "(Oi)", name, is_set ); if ( trait != NULL ) { assert( obj->ctrait_dict != NULL ); PyDict_SetItem( (PyObject *) obj->ctrait_dict, name, trait ); Py_DECREF( trait ); if ( has_traits_setattro( obj, trait_added, name ) < 0 ) return NULL; trait = get_trait( obj, name, 0 ); Py_DECREF( trait ); } return (trait_object *) trait; } /*----------------------------------------------------------------------------- | Assigns a special TraitValue to a specified trait attribute: +----------------------------------------------------------------------------*/ static int setattr_value ( trait_object * trait, has_traits_object * obj, PyObject * name, PyObject * value ) { PyDictObject * dict; PyObject * trait_new, * result, * obj_dict; PyObject * trait_old = NULL; PyObject * value_old = NULL; trait_new = PyObject_CallMethod( value, "as_ctrait", "(O)", trait ); if ( trait_new == NULL ) goto error2; if ( (trait_new != Py_None) && (!PyTrait_CheckExact( trait_new )) ) { Py_DECREF( trait_new ); return bad_trait_value_error(); } dict = obj->itrait_dict; if ( (dict != NULL) && ((trait_old = dict_getitem( dict, name )) != NULL) && ((((trait_object *) trait_old)->flags & TRAIT_VALUE_PROPERTY) != 0) ) { result = PyObject_CallMethod( trait_old, "_unregister", "(OO)", obj, name ); if ( result == NULL ) goto error1; Py_DECREF( result ); } if ( trait_new == Py_None ) { if ( trait_old != NULL ) { PyDict_DelItem( (PyObject *) dict, name ); } goto success; } if ( dict == NULL ) { obj->itrait_dict = dict = (PyDictObject *) PyDict_New(); if ( dict == NULL ) goto error1; } if ( (((trait_object *) trait_new)->flags & TRAIT_VALUE_PROPERTY) != 0 ) { if ( (value_old = has_traits_getattro( obj, name )) == NULL ) goto error1; obj_dict = obj->obj_dict; if ( obj_dict != NULL ) PyDict_DelItem( obj_dict, name ); } if ( PyDict_SetItem( (PyObject *) dict, name, trait_new ) < 0 ) goto error0; if ( (((trait_object *) trait_new)->flags & TRAIT_VALUE_PROPERTY) != 0 ) { result = PyObject_CallMethod( trait_new, "_register", "(OO)", obj, name ); if ( result == NULL ) goto error0; Py_DECREF( result ); if ( trait_property_changed( obj, name, value_old, NULL ) ) goto error0; Py_DECREF( value_old ); } success: Py_DECREF( trait_new ); return 0; error0: Py_XDECREF( value_old ); error1: Py_DECREF( trait_new ); error2: return -1; } /*----------------------------------------------------------------------------- | Handles the 'setattr' operation on a 'CHasTraits' instance: +----------------------------------------------------------------------------*/ static int has_traits_setattro ( has_traits_object * obj, PyObject * name, PyObject * value ) { trait_object * trait; if ( (obj->itrait_dict == NULL) || ((trait = (trait_object *) dict_getitem( obj->itrait_dict, name )) == NULL) ) { trait = (trait_object *) dict_getitem( obj->ctrait_dict, name ); if ( (trait == NULL) && ((trait = get_prefix_trait( obj, name, 1 )) == NULL) ) return -1; } if ( ((trait->flags & TRAIT_VALUE_ALLOWED) != 0) && (PyObject_IsInstance( value, TraitValue ) > 0) ) { return setattr_value( trait, obj, name, value ); } return trait->setattr( trait, trait, obj, name, value ); } /*----------------------------------------------------------------------------- | Allocates a CTrait instance: +----------------------------------------------------------------------------*/ PyObject * has_traits_new ( PyTypeObject * type, PyObject * args, PyObject * kwds ) { has_traits_object * obj = (has_traits_object *) type->tp_alloc( type, 0 ); if ( obj != NULL ) { if (type->tp_dict == NULL) { PyErr_SetString(PyExc_RuntimeError, "No tp_dict"); return NULL; } obj->ctrait_dict = (PyDictObject *) PyDict_GetItem( type->tp_dict, class_traits ); if (obj->ctrait_dict == NULL) { PyErr_SetString(PyExc_RuntimeError, "No ctrait_dict"); return NULL; } if (!PyDict_Check( (PyObject *) obj->ctrait_dict ) ) { PyErr_SetString(PyExc_RuntimeError, "ctrait_dict not a dict"); return NULL; } Py_INCREF( obj->ctrait_dict ); } return (PyObject *) obj; } int has_traits_init ( PyObject * obj, PyObject * args, PyObject * kwds ) { PyObject * key; PyObject * value; PyObject * klass; PyObject * handler; PyObject * handler_args; int n; int has_listeners; Py_ssize_t i = 0; /* Make sure no non-keyword arguments were specified: */ if ( !PyArg_ParseTuple( args, "" ) ) return -1; /* Make sure all of the object's listeners have been set up: */ has_listeners = (PyMapping_Size( PyDict_GetItem( obj->ob_type->tp_dict, listener_traits ) ) > 0); if ( has_listeners ) { value = PyObject_CallMethod( obj, "_init_trait_listeners", "()" ); if ( value == NULL ) return -1; Py_DECREF( value ); } /* Set any traits specified in the constructor: */ if ( kwds != NULL ) { while ( PyDict_Next( kwds, &i, &key, &value ) ) { if ( has_traits_setattro( (has_traits_object *) obj, key, value ) == -1 ) return -1; } } /* Make sure all post constructor argument assignment listeners have been set up: */ if ( has_listeners ) { value = PyObject_CallMethod( obj, "_post_init_trait_listeners", "()" ); if ( value == NULL ) return -1; Py_DECREF( value ); } /* Notify any interested monitors that a new object has been created: */ for ( i = 0, n = PyList_GET_SIZE( _HasTraits_monitors ); i < n; i++ ) { value = PyList_GET_ITEM( _HasTraits_monitors, i ); assert( PyTuple_Check( value ) ); assert( PyTuple_GET_SIZE( value ) == 2 ); klass = PyTuple_GET_ITEM( value, 0 ); handler = PyTuple_GET_ITEM( value, 1 ); if ( PyObject_IsInstance( obj, klass ) > 0 ) { handler_args = PyTuple_New( 1 ); PyTuple_SetItem( handler_args, 0, obj ); Py_INCREF( obj ); PyObject_Call( handler, handler_args, NULL ); Py_DECREF( handler_args ); } } /* Call the 'traits_init' method to finish up initialization: */ value = PyObject_CallMethod( obj, "traits_init", "()" ); if ( value == NULL ) return -1; Py_DECREF( value ); /* Indicate that the object has finished being initialized: */ ((has_traits_object *) obj)->flags |= HASTRAITS_INITED; return 0; } /*----------------------------------------------------------------------------- | Object clearing method: +----------------------------------------------------------------------------*/ static int has_traits_clear ( has_traits_object * obj ) { Py_CLEAR( obj->ctrait_dict ); Py_CLEAR( obj->itrait_dict ); Py_CLEAR( obj->notifiers ); Py_CLEAR( obj->obj_dict ); return 0; } /*----------------------------------------------------------------------------- | Deallocates an unused 'CHasTraits' instance: +----------------------------------------------------------------------------*/ static void has_traits_dealloc ( has_traits_object * obj ) { PyObject_GC_UnTrack(obj); Py_TRASHCAN_SAFE_BEGIN(obj); has_traits_clear( obj ); obj->ob_type->tp_free( (PyObject *) obj ); Py_TRASHCAN_SAFE_END(obj); } /*----------------------------------------------------------------------------- | Garbage collector traversal method: +----------------------------------------------------------------------------*/ static int has_traits_traverse ( has_traits_object * obj, visitproc visit, void * arg ) { Py_VISIT( obj->ctrait_dict ); Py_VISIT( obj->itrait_dict ); Py_VISIT( obj->notifiers ); Py_VISIT( obj->obj_dict ); return 0; } /*----------------------------------------------------------------------------- | Returns whether an object's '__dict__' value is defined or not: +----------------------------------------------------------------------------*/ static int has_value_for ( has_traits_object * obj, PyObject * name ) { PyObject * uname; long hash; int rc; PyDictObject * dict = (PyDictObject *) obj->obj_dict; if ( dict == NULL ) return 0; assert( PyDict_Check( dict ) ); if ( PyString_CheckExact( name ) ) { if ( (hash = ((PyStringObject *) name)->ob_shash) == -1 ) hash = PyObject_Hash( name ); return ((dict->ma_lookup)( dict, name, hash )->me_value != NULL); } if ( PyString_Check( name ) ) { hash = PyObject_Hash( name ); if ( hash == -1 ) { PyErr_Clear(); return 0; } return ((dict->ma_lookup)( dict, name, hash )->me_value != NULL ); } #ifdef Py_USING_UNICODE if ( !PyUnicode_Check( name ) ) return 0; uname = PyUnicode_AsEncodedString( name, NULL, NULL ); if ( uname == NULL ) { PyErr_Clear(); return 0; } hash = PyObject_Hash( uname ); if ( hash == -1 ) { Py_DECREF( uname ); PyErr_Clear(); return 0; } rc = ((dict->ma_lookup)( dict, uname, hash )->me_value != NULL); Py_DECREF( uname ); return rc; #else return 0; #endif } /*----------------------------------------------------------------------------- | Handles the 'getattr' operation on a 'CHasTraits' instance: +----------------------------------------------------------------------------*/ static PyObject * has_traits_getattro ( has_traits_object * obj, PyObject * name ) { /* The following is a performance hack to short-circuit the normal look-up when the value is in the object's dictionary. */ trait_object * trait; PyObject * value; PyObject * uname; long hash; PyDictObject * dict = (PyDictObject *) obj->obj_dict; if ( dict != NULL ) { assert( PyDict_Check( dict ) ); if ( PyString_CheckExact( name ) ) { if ( (hash = ((PyStringObject *) name)->ob_shash) == -1 ) hash = PyObject_Hash( name ); value = (dict->ma_lookup)( dict, name, hash )->me_value; if ( value != NULL ) { Py_INCREF( value ); return value; } } else { if ( PyString_Check( name ) ) { hash = PyObject_Hash( name ); if ( hash == -1 ) return NULL; value = (dict->ma_lookup)( dict, name, hash )->me_value; if ( value != NULL ) { Py_INCREF( value ); return value; } } else { #ifdef Py_USING_UNICODE if ( PyUnicode_Check( name ) ) { uname = PyUnicode_AsEncodedString( name, NULL, NULL ); if ( uname == NULL ) return NULL; } else { invalid_attribute_error(); return NULL; } hash = PyObject_Hash( uname ); if ( hash == -1 ) { Py_DECREF( uname ); return NULL; } value = (dict->ma_lookup)( dict, uname, hash )->me_value; Py_DECREF( uname ); if ( value != NULL ) { Py_INCREF( value ); return value; } #else invalid_attribute_error(); return NULL; #endif } } } /* End of performance hack */ if ( ((obj->itrait_dict != NULL) && ((trait = (trait_object *) dict_getitem( obj->itrait_dict, name )) != NULL)) || ((trait = (trait_object *) dict_getitem( obj->ctrait_dict, name )) != NULL) ) { return trait->getattr( trait, obj, name ); } if ( (value = PyObject_GenericGetAttr( (PyObject *) obj, name )) != NULL ) return value; PyErr_Clear(); if ( (trait = get_prefix_trait( obj, name, 0 )) != NULL ) return trait->getattr( trait, obj, name ); return NULL; } /*----------------------------------------------------------------------------- | Returns (and optionally creates) a specified instance or class trait: +----------------------------------------------------------------------------*/ static PyObject * get_trait ( has_traits_object * obj, PyObject * name, int instance ) { int i, n; PyDictObject * itrait_dict; trait_object * trait; trait_object * itrait; PyListObject * notifiers; PyListObject * inotifiers; PyObject * item; /* If there already is an instance specific version of the requested trait, then return it: */ itrait_dict = obj->itrait_dict; if ( itrait_dict != NULL ) { trait = (trait_object *) dict_getitem( itrait_dict, name ); if ( trait != NULL ) { assert( PyTrait_CheckExact( trait ) ); Py_INCREF( trait ); return (PyObject *) trait; } } /* If only an instance trait can be returned (but not created), then return None: */ if ( instance == 1 ) { Py_INCREF( Py_None ); return Py_None; } /* Otherwise, get the class specific version of the trait (creating a trait class version if necessary): */ assert( obj->ctrait_dict != NULL ); trait = (trait_object *) dict_getitem( obj->ctrait_dict, name ); if ( trait == NULL ) { if ( instance == 0 ) { Py_INCREF( Py_None ); return Py_None; } if ( (trait = get_prefix_trait( obj, name, 0 )) == NULL ) return NULL; } assert( PyTrait_CheckExact( trait ) ); /* If an instance specific trait is not needed, return the class trait: */ if ( instance <= 0 ) { Py_INCREF( trait ); return (PyObject *) trait; } /* Otherwise, create an instance trait dictionary if it does not exist: */ if ( itrait_dict == NULL ) { obj->itrait_dict = itrait_dict = (PyDictObject *) PyDict_New(); if ( itrait_dict == NULL ) return NULL; } /* Create a new instance trait and clone the class trait into it: */ itrait = (trait_object *) PyType_GenericAlloc( ctrait_type, 0 ); trait_clone( itrait, trait ); itrait->obj_dict = trait->obj_dict; Py_XINCREF( itrait->obj_dict ); /* Copy the class trait's notifier list into the instance trait: */ if ( (notifiers = trait->notifiers) != NULL ) { n = PyList_GET_SIZE( notifiers ); itrait->notifiers = inotifiers = (PyListObject *) PyList_New( n ); if ( inotifiers == NULL ) return NULL; for ( i = 0; i < n; i++ ) { item = PyList_GET_ITEM( notifiers, i ); PyList_SET_ITEM( inotifiers, i, item ); Py_INCREF( item ); } } /* Add the instance trait to the instance's trait dictionary and return the instance trait if successful: */ if ( PyDict_SetItem( (PyObject *) itrait_dict, name, (PyObject *) itrait ) >= 0 ) return (PyObject *) itrait; /* Otherwise, indicate that an error ocurred updating the dictionary: */ return NULL; } /*----------------------------------------------------------------------------- | Returns (and optionally creates) a specified instance or class trait: | | The legal values for 'instance' are: | 2: Return instance trait (force creation if it does not exist) | 1: Return existing instance trait (do not create) | 0: Return existing instance or class trait (do not create) | -1: Return instance trait or force create class trait (i.e. prefix trait) | -2: Return the base trait (after all delegation has been resolved) +----------------------------------------------------------------------------*/ static PyObject * _has_traits_trait ( has_traits_object * obj, PyObject * args ) { has_traits_object * delegate; has_traits_object * temp_delegate; trait_object * trait; PyObject * name; PyObject * daname; PyObject * daname2; PyObject * dict; int i, instance; /* Parse arguments, which specify the trait name and whether or not an instance specific version of the trait is needed or not: */ if ( !PyArg_ParseTuple( args, "Oi", &name, &instance ) ) return NULL; trait = (trait_object *) get_trait( obj, name, instance ); if ( (instance >= -1) || (trait == NULL) ) return (PyObject *) trait; /* Follow the delegation chain until we find a non-delegated trait: */ delegate = obj; Py_INCREF( delegate ); daname = name; Py_INCREF( daname ); for ( i = 0; ; ) { if ( trait->delegate_attr_name == NULL ) { Py_DECREF( delegate ); Py_DECREF( daname ); return (PyObject *) trait; } dict = delegate->obj_dict; if ( ((dict == NULL) || ((temp_delegate = (has_traits_object *) PyDict_GetItem( dict, trait->delegate_name )) == NULL)) && ((temp_delegate = (has_traits_object *) has_traits_getattro( delegate, trait->delegate_name )) == NULL) ) break; Py_DECREF( delegate ); delegate = temp_delegate; Py_INCREF( delegate ); if ( !PyHasTraits_Check( delegate ) ) { bad_delegate_error2( obj, name ); break; } daname2 = trait->delegate_attr_name( trait, obj, daname ); Py_DECREF( daname ); daname = daname2; Py_DECREF( trait ); if ( ((delegate->itrait_dict == NULL) || ((trait = (trait_object *) dict_getitem( delegate->itrait_dict, daname )) == NULL)) && ((trait = (trait_object *) dict_getitem( delegate->ctrait_dict, daname )) == NULL) && ((trait = get_prefix_trait( delegate, daname2, 0 )) == NULL) ) { bad_delegate_error( obj, name ); break; } if ( trait->ob_type != ctrait_type ) { fatal_trait_error(); break; } if ( ++i >= 100 ) { delegation_recursion_error2( obj, name ); break; } Py_INCREF( trait ); } Py_DECREF( delegate ); Py_DECREF( daname ); return NULL; } /*----------------------------------------------------------------------------- | Calls notifiers when a trait 'property' is explicitly changed: +----------------------------------------------------------------------------*/ static int trait_property_changed ( has_traits_object * obj, PyObject * name, PyObject * old_value, PyObject * new_value ) { trait_object * trait; PyListObject * tnotifiers; PyListObject * onotifiers; int null_new_value; int rc = 0; if ( (trait = (trait_object *) get_trait( obj, name, -1 )) == NULL ) return -1; tnotifiers = trait->notifiers; onotifiers = obj->notifiers; Py_DECREF( trait ); if ( has_notifiers( tnotifiers, onotifiers ) ) { null_new_value = (new_value == NULL); if ( null_new_value ) { new_value = has_traits_getattro( obj, name ); if ( new_value == NULL ) return -1; } rc = call_notifiers( tnotifiers, onotifiers, obj, name, old_value, new_value ); if ( null_new_value ) { Py_DECREF( new_value ); } } return rc; } /*----------------------------------------------------------------------------- | Calls notifiers when a trait 'property' is explicitly changed: +----------------------------------------------------------------------------*/ static PyObject * _has_traits_property_changed ( has_traits_object * obj, PyObject * args ) { PyObject * name, * old_value; PyObject * new_value = NULL; /* Parse arguments, which specify the name of the changed trait, the previous value, and the new value: */ if ( !PyArg_ParseTuple( args, "OO|O", &name, &old_value, &new_value ) ) return NULL; if ( trait_property_changed( obj, name, old_value, new_value ) ) return NULL; Py_INCREF( Py_None ); return Py_None; } /*----------------------------------------------------------------------------- | Handles firing a traits 'xxx_items' event: +----------------------------------------------------------------------------*/ static PyObject * _has_traits_items_event ( has_traits_object * obj, PyObject * args ) { PyObject * name; PyObject * event_object; PyObject * event_trait; PyObject * result; trait_object * trait; int can_retry = 1; if ( !PyArg_ParseTuple( args, "OOO", &name, &event_object, &event_trait ) ) return NULL; if ( !PyTrait_CheckExact( event_trait ) ) { bad_trait_value_error(); return NULL; } if ( !PyString_Check( name ) ) { invalid_attribute_error(); return NULL; } retry: if ( ((obj->itrait_dict == NULL) || ((trait = (trait_object *) dict_getitem( obj->itrait_dict, name )) == NULL)) && ((trait = (trait_object *) dict_getitem( obj->ctrait_dict, name )) == NULL) ) { add_trait: if ( !can_retry ) return cant_set_items_error(); result = PyObject_CallMethod( (PyObject *) obj, "add_trait", "(OO)", name, event_trait ); if ( result == NULL ) return NULL; Py_DECREF( result ); can_retry = 0; goto retry; } if ( trait->setattr == setattr_disallow ) goto add_trait; if ( trait->setattr( trait, trait, obj, name, event_object ) < 0 ) return NULL; Py_INCREF( Py_None ); return Py_None; } /*----------------------------------------------------------------------------- | Enables/Disables trait change notification for the object: +----------------------------------------------------------------------------*/ static PyObject * _has_traits_change_notify ( has_traits_object * obj, PyObject * args ) { int enabled; /* Parse arguments, which specify the new trait notification enabled/disabled state: */ if ( !PyArg_ParseTuple( args, "i", &enabled ) ) return NULL; if ( enabled ) { obj->flags &= (~HASTRAITS_NO_NOTIFY); } else { obj->flags |= HASTRAITS_NO_NOTIFY; } Py_INCREF( Py_None ); return Py_None; } /*----------------------------------------------------------------------------- | Enables/Disables trait change notifications when this object is assigned to | a trait: +----------------------------------------------------------------------------*/ static PyObject * _has_traits_veto_notify ( has_traits_object * obj, PyObject * args ) { int enabled; /* Parse arguments, which specify the new trait notification veto enabled/disabled state: */ if ( !PyArg_ParseTuple( args, "i", &enabled ) ) return NULL; if ( enabled ) { obj->flags |= HASTRAITS_VETO_NOTIFY; } else { obj->flags &= (~HASTRAITS_VETO_NOTIFY); } Py_INCREF( Py_None ); return Py_None; } /*----------------------------------------------------------------------------- | This method is called at the end of a HasTraits constructor and the | __setstate__ method to perform any final object initialization needed. +----------------------------------------------------------------------------*/ static PyObject * _has_traits_init ( has_traits_object * obj ) { Py_INCREF( Py_None ); return Py_None; } /*----------------------------------------------------------------------------- | Returns whether or not the object has finished being initialized: +----------------------------------------------------------------------------*/ static PyObject * _has_traits_inited ( has_traits_object * obj, PyObject * args ) { int traits_inited = -1; if ( !PyArg_ParseTuple( args, "|i", &traits_inited ) ) return NULL; if ( traits_inited > 0 ) obj->flags |= HASTRAITS_INITED; if ( obj->flags & HASTRAITS_INITED ) { Py_INCREF( Py_True ); return Py_True; } Py_INCREF( Py_False ); return Py_False; } /*----------------------------------------------------------------------------- | Returns the instance trait dictionary: +----------------------------------------------------------------------------*/ static PyObject * _has_traits_instance_traits ( has_traits_object * obj, PyObject * args ) { if ( !PyArg_ParseTuple( args, "" ) ) return NULL; if ( obj->itrait_dict == NULL ) obj->itrait_dict = (PyDictObject *) PyDict_New(); Py_XINCREF( obj->itrait_dict ); return (PyObject *) obj->itrait_dict; } /*----------------------------------------------------------------------------- | Returns (and optionally creates) the anytrait 'notifiers' list: +----------------------------------------------------------------------------*/ static PyObject * _has_traits_notifiers ( has_traits_object * obj, PyObject * args ) { PyObject * result; PyObject * list; int force_create; if ( !PyArg_ParseTuple( args, "i", &force_create ) ) return NULL; result = (PyObject *) obj->notifiers; if ( result == NULL ) { result = Py_None; if ( force_create && ((list = PyList_New( 0 )) != NULL) ) { obj->notifiers = (PyListObject *) (result = list); Py_INCREF( result ); } } Py_INCREF( result ); return result; } /*----------------------------------------------------------------------------- | Returns the object's instance dictionary: +----------------------------------------------------------------------------*/ static PyObject * get_has_traits_dict ( has_traits_object * obj, void * closure ) { PyObject * obj_dict = obj->obj_dict; if ( obj_dict == NULL ) { obj->obj_dict = obj_dict = PyDict_New(); if ( obj_dict == NULL ) return NULL; } Py_INCREF( obj_dict ); return obj_dict; } /*----------------------------------------------------------------------------- | Sets the object's dictionary: +----------------------------------------------------------------------------*/ static int set_has_traits_dict ( has_traits_object * obj, PyObject * value, void * closure ) { if ( !PyDict_Check( value ) ) return dictionary_error(); return set_value( &obj->obj_dict, value ); } /*----------------------------------------------------------------------------- | 'CHasTraits' instance methods: +----------------------------------------------------------------------------*/ static PyMethodDef has_traits_methods[] = { { "trait_property_changed", (PyCFunction) _has_traits_property_changed, METH_VARARGS, PyDoc_STR( "trait_property_changed(name,old_value[,new_value])" ) }, { "trait_items_event", (PyCFunction) _has_traits_items_event, METH_VARARGS, PyDoc_STR( "trait_items_event(event_trait,name,items_event)" ) }, { "_trait_change_notify", (PyCFunction) _has_traits_change_notify, METH_VARARGS, PyDoc_STR( "_trait_change_notify(boolean)" ) }, { "_trait_veto_notify", (PyCFunction) _has_traits_veto_notify, METH_VARARGS, PyDoc_STR( "_trait_veto_notify(boolean)" ) }, { "traits_init", (PyCFunction) _has_traits_init, METH_NOARGS, PyDoc_STR( "traits_init()" ) }, { "traits_inited", (PyCFunction) _has_traits_inited, METH_VARARGS, PyDoc_STR( "traits_inited([True])" ) }, { "_trait", (PyCFunction) _has_traits_trait, METH_VARARGS, PyDoc_STR( "_trait(name,instance) -> trait" ) }, { "_instance_traits", (PyCFunction) _has_traits_instance_traits, METH_VARARGS, PyDoc_STR( "_instance_traits() -> dict" ) }, { "_notifiers", (PyCFunction) _has_traits_notifiers, METH_VARARGS, PyDoc_STR( "_notifiers(force_create) -> list" ) }, { NULL, NULL }, }; /*----------------------------------------------------------------------------- | 'CHasTraits' property definitions: +----------------------------------------------------------------------------*/ static PyGetSetDef has_traits_properties[] = { { "__dict__", (getter) get_has_traits_dict, (setter) set_has_traits_dict }, { 0 } }; /*----------------------------------------------------------------------------- | 'CHasTraits' type definition: +----------------------------------------------------------------------------*/ static PyTypeObject has_traits_type = { PyObject_HEAD_INIT( DEFERRED_ADDRESS( &PyType_Type ) ) 0, "traits.ctraits.CHasTraits", sizeof( has_traits_object ), 0, (destructor) has_traits_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ (getattrofunc) has_traits_getattro, /* tp_getattro */ (setattrofunc) has_traits_setattro, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,/* tp_flags */ 0, /* tp_doc */ (traverseproc) has_traits_traverse, /* tp_traverse */ (inquiry) has_traits_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ has_traits_methods, /* tp_methods */ 0, /* tp_members */ has_traits_properties, /* tp_getset */ DEFERRED_ADDRESS( &PyBaseObject_Type ), /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ sizeof( has_traits_object ) - sizeof( PyObject * ), /* tp_dictoffset */ has_traits_init, /* tp_init */ DEFERRED_ADDRESS( PyType_GenericAlloc ), /* tp_alloc */ has_traits_new /* tp_new */ }; /*----------------------------------------------------------------------------- | Returns the default value associated with a specified trait: +----------------------------------------------------------------------------*/ static PyObject * default_value_for ( trait_object * trait, has_traits_object * obj, PyObject * name ) { PyObject * result = NULL, * value, * dv, * kw, * tuple; switch ( trait->default_value_type ) { case 0: case 1: result = trait->default_value; Py_INCREF( result ); break; case 2: result = (PyObject *) obj; Py_INCREF( obj ); break; case 3: return PySequence_List( trait->default_value ); case 4: return PyDict_Copy( trait->default_value ); case 5: return call_class( TraitListObject, trait, obj, name, trait->default_value ); case 6: return call_class( TraitDictObject, trait, obj, name, trait->default_value ); case 7: dv = trait->default_value; kw = PyTuple_GET_ITEM( dv, 2 ); if ( kw == Py_None ) kw = NULL; return PyObject_Call( PyTuple_GET_ITEM( dv, 0 ), PyTuple_GET_ITEM( dv, 1 ), kw ); case 8: if ( (tuple = PyTuple_New( 1 )) == NULL ) return NULL; PyTuple_SET_ITEM( tuple, 0, (PyObject *) obj ); Py_INCREF( obj ); result = PyObject_Call( trait->default_value, tuple, NULL ); Py_DECREF( tuple ); if ( (result != NULL) && (trait->validate != NULL) ) { value = trait->validate( trait, obj, name, result ); Py_DECREF( result ); return value; } break; case 9: return call_class( TraitSetObject, trait, obj, name, trait->default_value ); } return result; } /*----------------------------------------------------------------------------- | Returns the value assigned to a standard Python attribute: +----------------------------------------------------------------------------*/ static PyObject * getattr_python ( trait_object * trait, has_traits_object * obj, PyObject * name ) { return PyObject_GenericGetAttr( (PyObject *) obj, name ); } /*----------------------------------------------------------------------------- | Returns the value assigned to a generic Python attribute: +----------------------------------------------------------------------------*/ static PyObject * getattr_generic ( trait_object * trait, has_traits_object * obj, PyObject * name ) { return PyObject_GenericGetAttr( (PyObject *) obj, name ); } /*----------------------------------------------------------------------------- | Returns the value assigned to an event trait: +----------------------------------------------------------------------------*/ static PyObject * getattr_event ( trait_object * trait, has_traits_object * obj, PyObject * name ) { PyErr_Format( PyExc_AttributeError, "The %.400s trait of a %.50s instance is an 'event', which is write only.", PyString_AS_STRING( name ), obj->ob_type->tp_name ); return NULL; } /*----------------------------------------------------------------------------- | Returns the value assigned to a standard trait: +----------------------------------------------------------------------------*/ static PyObject * getattr_trait ( trait_object * trait, has_traits_object * obj, PyObject * name ) { int rc; PyListObject * tnotifiers; PyListObject * onotifiers; PyObject * result; PyObject * dict = obj->obj_dict; if ( dict == NULL ) { dict = PyDict_New(); if ( dict == NULL ) return NULL; obj->obj_dict = dict; } if ( PyString_Check( name ) ) { if ( (result = default_value_for( trait, obj, name )) != NULL ) { if ( PyDict_SetItem( dict, name, result ) >= 0 ) { rc = 0; if ( (trait->post_setattr != NULL) && ((trait->flags & TRAIT_IS_MAPPED) == 0) ) rc = trait->post_setattr( trait, obj, name, result ); if (rc == 0) { tnotifiers = trait->notifiers; onotifiers = obj->notifiers; if ( has_notifiers( tnotifiers, onotifiers ) ) rc = call_notifiers( tnotifiers, onotifiers, obj, name, Uninitialized, result ); } if ( rc == 0 ) return result; } Py_DECREF( result ); } if ( PyErr_ExceptionMatches( PyExc_KeyError ) ) PyErr_SetObject( PyExc_AttributeError, name ); return NULL; } #ifdef Py_USING_UNICODE if ( PyUnicode_Check( name ) ) { name = PyUnicode_AsEncodedString( name, NULL, NULL ); if ( name == NULL ) return NULL; } else { invalid_attribute_error(); return NULL; } if ( (result = default_value_for( trait, obj, name )) != NULL ) { if ( PyDict_SetItem( dict, name, result ) >= 0 ) { rc = 0; if ( (trait->post_setattr != NULL) && ((trait->flags & TRAIT_IS_MAPPED) == 0) ) rc = trait->post_setattr( trait, obj, name, result ); if (rc == 0) { tnotifiers = trait->notifiers; onotifiers = obj->notifiers; if ( has_notifiers( tnotifiers, onotifiers ) ) rc = call_notifiers( tnotifiers, onotifiers, obj, name, Uninitialized, result ); } if ( rc == 0 ) { Py_DECREF( name ); return result; } } Py_DECREF( result ); } if ( PyErr_ExceptionMatches( PyExc_KeyError ) ) PyErr_SetObject( PyExc_AttributeError, name ); Py_DECREF( name ); return NULL; #else invalid_attribute_error(); return NULL; #endif } /*----------------------------------------------------------------------------- | Returns the value assigned to a delegated trait: +----------------------------------------------------------------------------*/ static PyObject * getattr_delegate ( trait_object * trait, has_traits_object * obj, PyObject * name ) { PyTypeObject * tp; PyObject * delegate_attr_name; PyObject * delegate; PyObject * result; PyObject * dict = obj->obj_dict; if ( (dict == NULL) || ((delegate = PyDict_GetItem( dict, trait->delegate_name )) == NULL) ){ // Handle the case when the delegate is not in the instance dictionary // (could be a method that returns the real delegate): delegate = has_traits_getattro( obj, trait->delegate_name ); if ( delegate == NULL ) return NULL; } else { Py_INCREF( delegate ); } if ( PyString_Check( name ) ) { delegate_attr_name = trait->delegate_attr_name( trait, obj, name ); tp = delegate->ob_type; if ( tp->tp_getattro != NULL ) { result = (*tp->tp_getattro)( delegate, delegate_attr_name ); goto done2; } if ( tp->tp_getattr != NULL ) { result = (*tp->tp_getattr)( delegate, PyString_AS_STRING( delegate_attr_name ) ); goto done2; } PyErr_Format( DelegationError, "The '%.50s' object has no attribute '%.400s' because its %.50s delegate has no attribute '%.400s'.", obj->ob_type->tp_name, PyString_AS_STRING( name ), tp->tp_name, PyString_AS_STRING( delegate_attr_name ) ); result = NULL; goto done2; } #ifdef Py_USING_UNICODE if ( PyUnicode_Check( name ) ) { name = PyUnicode_AsEncodedString( name, NULL, NULL ); if ( name == NULL ) { Py_DECREF( delegate ); return NULL; } } else { invalid_attribute_error(); Py_DECREF( delegate ); return NULL; } delegate_attr_name = trait->delegate_attr_name( trait, obj, name ); tp = delegate->ob_type; if ( tp->tp_getattro != NULL ) { result = (*tp->tp_getattro)( delegate, delegate_attr_name ); goto done; } if ( tp->tp_getattr != NULL ) { result = (*tp->tp_getattr)( delegate, PyString_AS_STRING( delegate_attr_name ) ); goto done; } PyErr_Format( DelegationError, "The '%.50s' object has no attribute '%.400s' because its %.50s delegate has no attribute '%.400s'.", obj->ob_type->tp_name, PyString_AS_STRING( name ), tp->tp_name, PyString_AS_STRING( delegate_attr_name ) ); result = NULL; done: Py_DECREF( name ); done2: Py_DECREF( delegate_attr_name ); Py_DECREF( delegate ); return result; #else invalid_attribute_error(); Py_DECREF( delegate ); return NULL; done2: Py_DECREF( delegate_attr_name ); Py_DECREF( delegate ); return result; #endif } /*----------------------------------------------------------------------------- | Raises an exception when a disallowed trait is accessed: +----------------------------------------------------------------------------*/ static PyObject * getattr_disallow ( trait_object * trait, has_traits_object * obj, PyObject * name ) { if ( PyString_Check( name ) ) unknown_attribute_error( obj, name ); else invalid_attribute_error(); return NULL; } /*----------------------------------------------------------------------------- | Returns the value of a constant trait: +----------------------------------------------------------------------------*/ static PyObject * getattr_constant ( trait_object * trait, has_traits_object * obj, PyObject * name ) { Py_INCREF( trait->default_value ); return trait->default_value; } /*----------------------------------------------------------------------------- | Assigns a value to a specified property trait attribute: +----------------------------------------------------------------------------*/ static PyObject * getattr_property0 ( trait_object * trait, has_traits_object * obj, PyObject * name ) { return PyObject_Call( trait->delegate_name, empty_tuple, NULL ); } static PyObject * getattr_property1 ( trait_object * trait, has_traits_object * obj, PyObject * name ) { PyObject * result; PyObject * args = PyTuple_New( 1 ); if ( args == NULL ) return NULL; PyTuple_SET_ITEM( args, 0, (PyObject *) obj ); Py_INCREF( obj ); result = PyObject_Call( trait->delegate_name, args, NULL ); Py_DECREF( args ); return result; } static PyObject * getattr_property2 ( trait_object * trait, has_traits_object * obj, PyObject * name ) { PyObject * result; PyObject * args = PyTuple_New( 2 ); if ( args == NULL ) return NULL; PyTuple_SET_ITEM( args, 0, (PyObject *) obj ); Py_INCREF( obj ); PyTuple_SET_ITEM( args, 1, name ); Py_INCREF( name ); result = PyObject_Call( trait->delegate_name, args, NULL ); Py_DECREF( args ); return result; } static PyObject * getattr_property3 ( trait_object * trait, has_traits_object * obj, PyObject * name ) { PyObject * result; PyObject * args = PyTuple_New( 3 ); if ( args == NULL ) return NULL; PyTuple_SET_ITEM( args, 0, (PyObject *) obj ); Py_INCREF( obj ); PyTuple_SET_ITEM( args, 1, name ); Py_INCREF( name ); PyTuple_SET_ITEM( args, 2, (PyObject *) trait ); Py_INCREF( trait ); result = PyObject_Call( trait->delegate_name, args, NULL ); Py_DECREF( args ); return result; } static trait_getattr getattr_property_handlers[] = { getattr_property0, getattr_property1, getattr_property2, getattr_property3 }; /*----------------------------------------------------------------------------- | Assigns a value to a specified standard Python attribute: +----------------------------------------------------------------------------*/ static int setattr_python ( trait_object * traito, trait_object * traitd, has_traits_object * obj, PyObject * name, PyObject * value ) { int rc; PyObject * dict = obj->obj_dict; if ( value != NULL ) { if ( dict == NULL ) { dict = PyDict_New(); if ( dict == NULL ) return -1; obj->obj_dict = dict; } if ( PyString_Check( name ) ) { if ( PyDict_SetItem( dict, name, value ) >= 0 ) return 0; if ( PyErr_ExceptionMatches( PyExc_KeyError ) ) PyErr_SetObject( PyExc_AttributeError, name ); return -1; } #ifdef Py_USING_UNICODE if ( PyUnicode_Check( name ) ) { name = PyUnicode_AsEncodedString( name, NULL, NULL ); if ( name == NULL ) return -1; } else return invalid_attribute_error(); rc = PyDict_SetItem( dict, name, value ); if ( (rc < 0) && PyErr_ExceptionMatches( PyExc_KeyError ) ) PyErr_SetObject( PyExc_AttributeError, name ); Py_DECREF( name ); return rc; #else return invalid_attribute_error(); #endif } if ( dict != NULL ) { if ( PyString_Check( name ) ) { if ( PyDict_DelItem( dict, name ) >= 0 ) return 0; if ( PyErr_ExceptionMatches( PyExc_KeyError ) ) unknown_attribute_error( obj, name ); return -1; } #ifdef Py_USING_UNICODE if ( PyUnicode_Check( name ) ) { name = PyUnicode_AsEncodedString( name, NULL, NULL ); if ( name == NULL ) return -1; } else return invalid_attribute_error(); rc = PyDict_DelItem( dict, name ); if ( (rc < 0) && PyErr_ExceptionMatches( PyExc_KeyError ) ) unknown_attribute_error( obj, name ); Py_DECREF( name ); return rc; #else return invalid_attribute_error(); #endif } if ( PyString_Check( name ) ) { unknown_attribute_error( obj, name ); return -1; } return invalid_attribute_error(); } /*----------------------------------------------------------------------------- | Assigns a value to a specified generic Python attribute: +----------------------------------------------------------------------------*/ static int setattr_generic ( trait_object * traito, trait_object * traitd, has_traits_object * obj, PyObject * name, PyObject * value ) { return PyObject_GenericSetAttr( (PyObject *) obj, name, value ); } /*----------------------------------------------------------------------------- | Call all notifiers for a specified trait: +----------------------------------------------------------------------------*/ static int call_notifiers ( PyListObject * tnotifiers, PyListObject * onotifiers, has_traits_object * obj, PyObject * name, PyObject * old_value, PyObject * new_value ) { int i, n, new_value_has_traits; PyObject * result, * item, * temp; int rc = 0; PyObject * arg_temp = Py_None; PyObject * user_args = NULL; PyObject * args = PyTuple_New( 4 ); if ( args == NULL ) return -1; new_value_has_traits = PyHasTraits_Check( new_value ); PyTuple_SET_ITEM( args, 0, (PyObject *) obj ); PyTuple_SET_ITEM( args, 1, name ); PyTuple_SET_ITEM( args, 2, old_value ); PyTuple_SET_ITEM( args, 3, new_value ); Py_INCREF( obj ); Py_INCREF( name ); Py_INCREF( old_value ); Py_INCREF( new_value ); // Do nothing if the user has explicitly requested no traits notifications // to be sent. if ( (obj->flags & HASTRAITS_NO_NOTIFY) != 0 ) goto exit2; if ( _trait_notification_handler != NULL ) { user_args = PyTuple_New( 2 ); if ( user_args == NULL ) { Py_DECREF( args ); return -1; } PyTuple_SET_ITEM( user_args, 0, arg_temp ); PyTuple_SET_ITEM( user_args, 1, args ); Py_INCREF( arg_temp ); Py_INCREF( args ); } if ( tnotifiers != NULL ) { n = PyList_GET_SIZE( tnotifiers ); temp = NULL; if ( n > 1 ) { temp = PyList_New( n ); if ( temp == NULL ) { rc = -1; goto exit2; } for ( i = 0; i < n; i++ ) { item = PyList_GET_ITEM( tnotifiers, i ); PyList_SET_ITEM( temp, i, item ); Py_INCREF( item ); } tnotifiers = (PyListObject *) temp; } for ( i = 0; i < n; i++ ) { if ( new_value_has_traits && (((has_traits_object *) new_value)->flags & HASTRAITS_VETO_NOTIFY) ) { goto exit; } if ( (_trait_notification_handler != NULL) && (user_args != NULL) ){ Py_DECREF( arg_temp ); arg_temp = PyList_GET_ITEM( tnotifiers, i ); Py_INCREF( arg_temp ); PyTuple_SET_ITEM( user_args, 0, arg_temp ); result = PyObject_Call( _trait_notification_handler, user_args, NULL ); } else { result = PyObject_Call( PyList_GET_ITEM( tnotifiers, i ), args, NULL ); } if ( result == NULL ) { rc = -1; goto exit; } Py_DECREF( result ); } Py_XDECREF( temp ); } temp = NULL; if ( onotifiers != NULL ) { n = PyList_GET_SIZE( onotifiers ); if ( n > 1 ) { temp = PyList_New( n ); if ( temp == NULL ) { rc = -1; goto exit2; } for ( i = 0; i < n; i++ ) { item = PyList_GET_ITEM( onotifiers, i ); PyList_SET_ITEM( temp, i, item ); Py_INCREF( item ); } onotifiers = (PyListObject *) temp; } for ( i = 0; i < n; i++ ) { if ( new_value_has_traits && (((has_traits_object *) new_value)->flags & HASTRAITS_VETO_NOTIFY) ) { break; } if ( (_trait_notification_handler != NULL) && (user_args != NULL) ){ Py_DECREF( arg_temp ); arg_temp = PyList_GET_ITEM( onotifiers, i ); Py_INCREF( arg_temp ); PyTuple_SET_ITEM( user_args, 0, arg_temp ); result = PyObject_Call( _trait_notification_handler, user_args, NULL ); } else { result = PyObject_Call( PyList_GET_ITEM( onotifiers, i ), args, NULL ); } if ( result == NULL ) { rc = -1; goto exit; } Py_DECREF( result ); } } exit: Py_XDECREF( temp ); exit2: Py_XDECREF( user_args ); Py_DECREF( args ); return rc; } /*----------------------------------------------------------------------------- | Assigns a value to a specified event trait attribute: +----------------------------------------------------------------------------*/ static int setattr_event ( trait_object * traito, trait_object * traitd, has_traits_object * obj, PyObject * name, PyObject * value ) { int rc = 0; PyListObject * tnotifiers; PyListObject * onotifiers; if ( value != NULL ) { if ( traitd->validate != NULL ) { value = traitd->validate( traitd, obj, name, value ); if ( value == NULL ) return -1; } else { Py_INCREF( value ); } tnotifiers = traito->notifiers; onotifiers = obj->notifiers; if ( has_notifiers( tnotifiers, onotifiers ) ) rc = call_notifiers( tnotifiers, onotifiers, obj, name, Undefined, value ); Py_DECREF( value ); } return rc; } /*----------------------------------------------------------------------------- | Assigns a value to a specified normal trait attribute: +----------------------------------------------------------------------------*/ static int setattr_trait ( trait_object * traito, trait_object * traitd, has_traits_object * obj, PyObject * name, PyObject * value ) { int rc; int changed; int do_notifiers; trait_post_setattr post_setattr; PyListObject * tnotifiers = NULL; PyListObject * onotifiers = NULL; PyObject * old_value = NULL; PyObject * original_value; PyObject * new_value; PyObject * dict = obj->obj_dict; changed = (traitd->flags & TRAIT_NO_VALUE_TEST); if ( value == NULL ) { if ( dict == NULL ) return 0; if ( PyString_Check( name ) ) { old_value = PyDict_GetItem( dict, name ); if ( old_value == NULL ) return 0; Py_INCREF( old_value ); if ( PyDict_DelItem( dict, name ) < 0 ) { Py_DECREF( old_value ); return -1; } Py_INCREF( name ); notify: rc = 0; if ( (obj->flags & HASTRAITS_NO_NOTIFY) == 0 ) { tnotifiers = traito->notifiers; onotifiers = obj->notifiers; if ( (tnotifiers != NULL) || (onotifiers != NULL) ) { value = traito->getattr( traito, obj, name ); if ( value == NULL ) { Py_DECREF( old_value ); Py_DECREF( name ); return -1; } if ( !changed ) { changed = (old_value != value ); if ( changed && ((traitd->flags & TRAIT_OBJECT_IDENTITY) == 0) ) { changed = PyObject_RichCompareBool( old_value, value, Py_NE ); if ( changed == -1 ) { PyErr_Clear(); } } } if ( changed ) { if ( traitd->post_setattr != NULL ) rc = traitd->post_setattr( traitd, obj, name, value ); if ( (rc == 0) && has_notifiers( tnotifiers, onotifiers ) ) rc = call_notifiers( tnotifiers, onotifiers, obj, name, old_value, value ); } Py_DECREF( value ); } } Py_DECREF( name ); Py_DECREF( old_value ); return rc; } #ifdef Py_USING_UNICODE if ( PyUnicode_Check( name ) ) { name = PyUnicode_AsEncodedString( name, NULL, NULL ); if ( name == NULL ) { return -1; } } else { return invalid_attribute_error(); } old_value = PyDict_GetItem( dict, name ); if ( old_value == NULL ) { Py_DECREF( name ); return 0; } Py_INCREF( old_value ); if ( PyDict_DelItem( dict, name ) < 0 ) { Py_DECREF( old_value ); Py_DECREF( name ); return -1; } goto notify; #else return invalid_attribute_error(); #endif } original_value = value; // If the object's value is Undefined, then do not call the validate // method (as the object's value has not yet been set). if ( ( traitd->validate != NULL ) && ( value != Undefined ) ) { value = traitd->validate( traitd, obj, name, value ); if ( value == NULL ) { return -1; } } else { Py_INCREF( value ); } if ( dict == NULL ) { obj->obj_dict = dict = PyDict_New(); if ( dict == NULL ) { Py_DECREF( value ); return -1; } } if ( !PyString_Check( name ) ) { #ifdef Py_USING_UNICODE if ( PyUnicode_Check( name ) ) { name = PyUnicode_AsEncodedString( name, NULL, NULL ); if ( name == NULL ) { Py_DECREF( value ); return -1; } } else { Py_DECREF( value ); return invalid_attribute_error(); } #else Py_DECREF( value ); return invalid_attribute_error(); #endif } else { Py_INCREF( name ); } new_value = (traitd->flags & TRAIT_SETATTR_ORIGINAL_VALUE)? original_value: value; old_value = NULL; tnotifiers = traito->notifiers; onotifiers = obj->notifiers; do_notifiers = has_notifiers( tnotifiers, onotifiers ); post_setattr = traitd->post_setattr; if ( (post_setattr != NULL) || do_notifiers ) { old_value = PyDict_GetItem( dict, name ); if ( old_value == NULL ) { if ( traitd != traito ) { old_value = traito->getattr( traito, obj, name ); } else { old_value = default_value_for( traitd, obj, name ); } if ( old_value == NULL ) { Py_DECREF( name ); Py_DECREF( value ); return -1; } } else { Py_INCREF( old_value ); } if ( !changed ) { changed = (old_value != value); if ( changed && ((traitd->flags & TRAIT_OBJECT_IDENTITY) == 0) ) { changed = PyObject_RichCompareBool( old_value, value, Py_NE ); if ( changed == -1 ) { PyErr_Clear(); } } } } if ( PyDict_SetItem( dict, name, new_value ) < 0 ) { if ( PyErr_ExceptionMatches( PyExc_KeyError ) ) PyErr_SetObject( PyExc_AttributeError, name ); Py_XDECREF( old_value ); Py_DECREF( name ); Py_DECREF( value ); return -1; } rc = 0; if ( changed ) { if ( post_setattr != NULL ) rc = post_setattr( traitd, obj, name, (traitd->flags & TRAIT_POST_SETATTR_ORIGINAL_VALUE)? original_value: value ); if ( (rc == 0) && do_notifiers ) rc = call_notifiers( tnotifiers, onotifiers, obj, name, old_value, new_value ); } Py_XDECREF( old_value ); Py_DECREF( name ); Py_DECREF( value ); return rc; } /*----------------------------------------------------------------------------- | Assigns a value to a specified delegate trait attribute: +----------------------------------------------------------------------------*/ static int setattr_delegate ( trait_object * traito, trait_object * traitd, has_traits_object * obj, PyObject * name, PyObject * value ) { PyObject * dict; PyObject * daname; PyObject * daname2; PyObject * temp; has_traits_object * delegate; has_traits_object * temp_delegate; int i, result; /* Follow the delegation chain until we find a non-delegated trait: */ daname = name; Py_INCREF( daname ); delegate = obj; for ( i = 0; ; ) { dict = delegate->obj_dict; if ( (dict != NULL) && ((temp_delegate = (has_traits_object *) PyDict_GetItem( dict, traitd->delegate_name )) != NULL) ) { delegate = temp_delegate; } else { // Handle the case when the delegate is not in the instance // dictionary (could be a method that returns the real delegate): delegate = (has_traits_object *) has_traits_getattro( delegate, traitd->delegate_name ); if ( delegate == NULL ) { Py_DECREF( daname ); return -1; } Py_DECREF( delegate ); } // Verify that 'delegate' is of type 'CHasTraits': if ( !PyHasTraits_Check( delegate ) ) { Py_DECREF( daname ); return bad_delegate_error2( obj, name ); } daname2 = traitd->delegate_attr_name( traitd, obj, daname ); Py_DECREF( daname ); daname = daname2; if ( ((delegate->itrait_dict == NULL) || ((traitd = (trait_object *) dict_getitem( delegate->itrait_dict, daname )) == NULL)) && ((traitd = (trait_object *) dict_getitem( delegate->ctrait_dict, daname )) == NULL) && ((traitd = get_prefix_trait( delegate, daname, 1 )) == NULL) ) { Py_DECREF( daname ); return bad_delegate_error( obj, name ); } if ( traitd->ob_type != ctrait_type ) { Py_DECREF( daname ); return fatal_trait_error(); } if ( traitd->delegate_attr_name == NULL ) { if ( traito->flags & TRAIT_MODIFY_DELEGATE ) { result = traitd->setattr( traitd, traitd, delegate, daname, value ); } else { result = traitd->setattr( traito, traitd, obj, name, value ); if ( result >= 0 ) { temp = PyObject_CallMethod( (PyObject *) obj, "_remove_trait_delegate_listener", "(Oi)", name, value != NULL ); if ( temp == NULL ) { result = -1; } else { Py_DECREF( temp ); } } } Py_DECREF( daname ); return result; } if ( ++i >= 100 ) return delegation_recursion_error( obj, name ); } } /*----------------------------------------------------------------------------- | Assigns a value to a specified property trait attribute: +----------------------------------------------------------------------------*/ static int setattr_property0 ( trait_object * traito, trait_object * traitd, has_traits_object * obj, PyObject * name, PyObject * value ) { PyObject * result; if ( value == NULL ) return set_delete_property_error( obj, name ); result = PyObject_Call( traitd->delegate_prefix, empty_tuple, NULL ); if ( result == NULL ) return -1; Py_DECREF( result ); return 0; } static int setattr_property1 ( trait_object * traito, trait_object * traitd, has_traits_object * obj, PyObject * name, PyObject * value ) { PyObject * result; PyObject * args; if ( value == NULL ) return set_delete_property_error( obj, name ); args = PyTuple_New( 1 ); if ( args == NULL ) return -1; PyTuple_SET_ITEM( args, 0, value ); Py_INCREF( value ); result = PyObject_Call( traitd->delegate_prefix, args, NULL ); Py_DECREF( args ); if ( result == NULL ) return -1; Py_DECREF( result ); return 0; } static int setattr_property2 ( trait_object * traito, trait_object * traitd, has_traits_object * obj, PyObject * name, PyObject * value ) { PyObject * result; PyObject * args; if ( value == NULL ) return set_delete_property_error( obj, name ); args = PyTuple_New( 2 ); if ( args == NULL ) return -1; PyTuple_SET_ITEM( args, 0, (PyObject *) obj ); PyTuple_SET_ITEM( args, 1, value ); Py_INCREF( obj ); Py_INCREF( value ); result = PyObject_Call( traitd->delegate_prefix, args, NULL ); Py_DECREF( args ); if ( result == NULL ) return -1; Py_DECREF( result ); return 0; } static int setattr_property3 ( trait_object * traito, trait_object * traitd, has_traits_object * obj, PyObject * name, PyObject * value ) { PyObject * result; PyObject * args; if ( value == NULL ) return set_delete_property_error( obj, name ); args = PyTuple_New( 3 ); if ( args == NULL ) return -1; PyTuple_SET_ITEM( args, 0, (PyObject *) obj ); PyTuple_SET_ITEM( args, 1, name ); PyTuple_SET_ITEM( args, 2, value ); Py_INCREF( obj ); Py_INCREF( name ); Py_INCREF( value ); result = PyObject_Call( traitd->delegate_prefix, args, NULL ); Py_DECREF( args ); if ( result == NULL ) return -1; Py_DECREF( result ); return 0; } /*----------------------------------------------------------------------------- | Validates then assigns a value to a specified property trait attribute: +----------------------------------------------------------------------------*/ static int setattr_validate_property ( trait_object * traito, trait_object * traitd, has_traits_object * obj, PyObject * name, PyObject * value ) { int result; PyObject * validated = traitd->validate( traitd, obj, name, value ); if ( validated == NULL ) return -1; result = ((trait_setattr) traitd->post_setattr)( traito, traitd, obj, name, validated ); Py_DECREF( validated ); return result; } static PyObject * setattr_validate0 ( trait_object * trait, has_traits_object * obj, PyObject * name, PyObject * value ) { return PyObject_Call( trait->py_validate, empty_tuple, NULL ); } static PyObject * setattr_validate1 ( trait_object * trait, has_traits_object * obj, PyObject * name, PyObject * value ) { PyObject * validated; PyObject * args = PyTuple_New( 1 ); if ( args == NULL ) return NULL; PyTuple_SET_ITEM( args, 0, value ); Py_INCREF( value ); validated = PyObject_Call( trait->py_validate, args, NULL ); Py_DECREF( args ); return validated; } static PyObject * setattr_validate2 ( trait_object * trait, has_traits_object * obj, PyObject * name, PyObject * value ) { PyObject * validated; PyObject * args = PyTuple_New( 2 ); if ( args == NULL ) return NULL; PyTuple_SET_ITEM( args, 0, (PyObject *) obj ); PyTuple_SET_ITEM( args, 1, value ); Py_INCREF( obj ); Py_INCREF( value ); validated = PyObject_Call( trait->py_validate, args, NULL ); Py_DECREF( args ); return validated; } static PyObject * setattr_validate3 ( trait_object * trait, has_traits_object * obj, PyObject * name, PyObject * value ) { PyObject * validated; PyObject * args = PyTuple_New( 3 ); if ( args == NULL ) return NULL; PyTuple_SET_ITEM( args, 0, (PyObject *) obj ); PyTuple_SET_ITEM( args, 1, name ); PyTuple_SET_ITEM( args, 2, value ); Py_INCREF( obj ); Py_INCREF( name ); Py_INCREF( value ); validated = PyObject_Call( trait->py_validate, args, NULL ); Py_DECREF( args ); return validated; } trait_validate setattr_validate_handlers[] = { setattr_validate0, setattr_validate1, setattr_validate2, setattr_validate3 }; /*----------------------------------------------------------------------------- | Raises an exception when attempting to assign to a disallowed trait: +----------------------------------------------------------------------------*/ static int setattr_disallow ( trait_object * traito, trait_object * traitd, has_traits_object * obj, PyObject * name, PyObject * value ) { return set_disallow_error( obj, name ); } /*----------------------------------------------------------------------------- | Assigns a value to a specified read-only trait attribute: +----------------------------------------------------------------------------*/ static int setattr_readonly ( trait_object * traito, trait_object * traitd, has_traits_object * obj, PyObject * name, PyObject * value ) { PyObject * dict; PyObject * result; if ( value == NULL ) return delete_readonly_error( obj, name ); if ( traitd->default_value != Undefined ) return set_readonly_error( obj, name ); dict = obj->obj_dict; if ( dict == NULL ) return setattr_python( traito, traitd, obj, name, value ); if ( !PyString_Check( name ) ) { #ifdef Py_USING_UNICODE if ( PyUnicode_Check( name ) ) { name = PyUnicode_AsEncodedString( name, NULL, NULL ); if ( name == NULL ) return -1; } else return invalid_attribute_error(); #else return invalid_attribute_error(); #endif } else Py_INCREF( name ); result = PyDict_GetItem( dict, name ); Py_DECREF( name ); if ( (result == NULL) || (result == Undefined) ) return setattr_python( traito, traitd, obj, name, value ); return set_readonly_error( obj, name ); } /*----------------------------------------------------------------------------- | Generates exception on attempting to assign to a constant trait: +----------------------------------------------------------------------------*/ static int setattr_constant ( trait_object * traito, trait_object * traitd, has_traits_object * obj, PyObject * name, PyObject * value ) { if ( PyString_Check( name ) ) { PyErr_Format( TraitError, "Cannot modify the constant '%.400s' attribute of a '%.50s' object.", PyString_AS_STRING( name ), obj->ob_type->tp_name ); return -1; } return invalid_attribute_error(); } /*----------------------------------------------------------------------------- | Initializes a CTrait instance: +----------------------------------------------------------------------------*/ static trait_getattr getattr_handlers[] = { getattr_trait, getattr_python, getattr_event, getattr_delegate, getattr_event, getattr_disallow, getattr_trait, getattr_constant, getattr_generic, /* The following entries are used by the __getstate__ method: */ getattr_property0, getattr_property1, getattr_property2, getattr_property3, /* End of __getstate__ method entries */ NULL }; static trait_setattr setattr_handlers[] = { setattr_trait, setattr_python, setattr_event, setattr_delegate, setattr_event, setattr_disallow, setattr_readonly, setattr_constant, setattr_generic, /* The following entries are used by the __getstate__ method: */ setattr_property0, setattr_property1, setattr_property2, setattr_property3, /* End of __setstate__ method entries */ NULL }; static int trait_init ( trait_object * trait, PyObject * args, PyObject * kwds ) { int kind; if ( !PyArg_ParseTuple( args, "i", &kind ) ) return -1; if ( (kind >= 0) && (kind <= 8) ) { trait->getattr = getattr_handlers[ kind ]; trait->setattr = setattr_handlers[ kind ]; return 0; } return bad_trait_error(); } /*----------------------------------------------------------------------------- | Object clearing method: +----------------------------------------------------------------------------*/ static int trait_clear ( trait_object * trait ) { Py_CLEAR( trait->default_value ); Py_CLEAR( trait->py_validate ); Py_CLEAR( trait->py_post_setattr ); Py_CLEAR( trait->delegate_name ); Py_CLEAR( trait->delegate_prefix ); Py_CLEAR( trait->notifiers ); Py_CLEAR( trait->handler ); Py_CLEAR( trait->obj_dict ); return 0; } /*----------------------------------------------------------------------------- | Deallocates an unused 'CTrait' instance: +----------------------------------------------------------------------------*/ static void trait_dealloc ( trait_object * trait ) { PyObject_GC_UnTrack(trait); Py_TRASHCAN_SAFE_BEGIN(trait); trait_clear( trait ); trait->ob_type->tp_free( (PyObject *) trait ); Py_TRASHCAN_SAFE_END(trait); } /*----------------------------------------------------------------------------- | Garbage collector traversal method: +----------------------------------------------------------------------------*/ static int trait_traverse ( trait_object * trait, visitproc visit, void * arg ) { Py_VISIT( trait->default_value ); Py_VISIT( trait->py_validate ); Py_VISIT( trait->py_post_setattr ); Py_VISIT( trait->delegate_name ); Py_VISIT( trait->delegate_prefix ); Py_VISIT( (PyObject *) trait->notifiers ); Py_VISIT( trait->handler ); Py_VISIT( trait->obj_dict ); return 0; } /*----------------------------------------------------------------------------- | Casts a 'CTrait' which attempts to validate the argument passed as being a | valid value for the trait: +----------------------------------------------------------------------------*/ static PyObject * _trait_cast ( trait_object * trait, PyObject * args ) { PyObject * obj; PyObject * name; PyObject * value; PyObject * result; PyObject * info; switch ( PyTuple_GET_SIZE( args ) ) { case 1: obj = name = Py_None; value = PyTuple_GET_ITEM( args, 0 ); break; case 2: name = Py_None; obj = PyTuple_GET_ITEM( args, 0 ); value = PyTuple_GET_ITEM( args, 1 ); break; case 3: obj = PyTuple_GET_ITEM( args, 0 ); name = PyTuple_GET_ITEM( args, 1 ); value = PyTuple_GET_ITEM( args, 2 ); break; default: PyErr_Format( PyExc_TypeError, #if PY_VERSION_HEX >= 0x02050000 "Trait cast takes 1, 2 or 3 arguments (%zd given).", #else "Trait cast takes 1, 2 or 3 arguments (%u given).", #endif PyTuple_GET_SIZE( args ) ); return NULL; } if ( trait->validate == NULL ) { Py_INCREF( value ); return value; } result = trait->validate( trait, (has_traits_object *) obj, name, value ); if ( result == NULL ) { PyErr_Clear(); info = PyObject_CallMethod( trait->handler, "info", NULL ); if ( (info != NULL) && PyString_Check( info ) ) PyErr_Format( PyExc_ValueError, "Invalid value for trait, the value should be %s.", PyString_AS_STRING( info ) ); else PyErr_Format( PyExc_ValueError, "Invalid value for trait." ); Py_XDECREF( info ); } return result; } /*----------------------------------------------------------------------------- | Handles the 'getattr' operation on a 'CHasTraits' instance: +----------------------------------------------------------------------------*/ static PyObject * trait_getattro ( trait_object * obj, PyObject * name ) { PyObject * value = PyObject_GenericGetAttr( (PyObject *) obj, name ); if ( value != NULL ) return value; PyErr_Clear(); Py_INCREF( Py_None ); return Py_None; } /*----------------------------------------------------------------------------- | Sets the value of the 'default_value' field of a CTrait instance: +----------------------------------------------------------------------------*/ static PyObject * _trait_default_value ( trait_object * trait, PyObject * args ) { int value_type; PyObject * value; if ( PyArg_ParseTuple( args, "" ) ) { if ( trait->default_value == NULL ) return Py_BuildValue( "iO", 0, Py_None ); return Py_BuildValue( "iO", trait->default_value_type, trait->default_value ); } if ( !PyArg_ParseTuple( args, "iO", &value_type, &value ) ) return NULL; PyErr_Clear(); if ( (value_type < 0) || (value_type > 9) ) { PyErr_Format( PyExc_ValueError, "The default value type must be 0..9, but %d was specified.", value_type ); return NULL; } Py_INCREF( value ); Py_XDECREF( trait->default_value ); trait->default_value_type = value_type; trait->default_value = value; Py_INCREF( Py_None ); return Py_None; } /*----------------------------------------------------------------------------- | Gets the default value of a CTrait instance for a specified object and trait | name: +----------------------------------------------------------------------------*/ static PyObject * _trait_default_value_for ( trait_object * trait, PyObject * args ) { PyObject * object; PyObject * name; if ( !PyArg_ParseTuple( args, "OO", &object, &name ) ) return NULL; if ( ((trait->flags & TRAIT_PROPERTY) != 0) || has_value_for( (has_traits_object *) object, name ) ) return default_value_for( trait, (has_traits_object *) object, name ); return trait->getattr( trait, (has_traits_object *) object, name ); } /*----------------------------------------------------------------------------- | Calls a Python-based trait validator: +----------------------------------------------------------------------------*/ static PyObject * validate_trait_python ( trait_object * trait, has_traits_object * obj, PyObject * name, PyObject * value ) { PyObject * result; PyObject * args = PyTuple_New( 3 ); if ( args == NULL ) return NULL; Py_INCREF( obj ); Py_INCREF( name ); Py_INCREF( value ); PyTuple_SET_ITEM( args, 0, (PyObject *) obj ); PyTuple_SET_ITEM( args, 1, name ); PyTuple_SET_ITEM( args, 2, value ); result = PyObject_Call( trait->py_validate, args, NULL ); Py_DECREF( args ); return result; } /*----------------------------------------------------------------------------- | Calls the specified validator function: +----------------------------------------------------------------------------*/ static PyObject * call_validator ( PyObject * validator, has_traits_object * obj, PyObject * name, PyObject * value ) { PyObject * result; PyObject * args = PyTuple_New( 3 ); if ( args == NULL ) return NULL; PyTuple_SET_ITEM( args, 0, (PyObject *) obj ); PyTuple_SET_ITEM( args, 1, name ); PyTuple_SET_ITEM( args, 2, value ); Py_INCREF( obj ); Py_INCREF( name ); Py_INCREF( value ); result = PyObject_Call( validator, args, NULL ); Py_DECREF( args ); return result; } /*----------------------------------------------------------------------------- | Calls the specified type convertor: +----------------------------------------------------------------------------*/ static PyObject * type_converter ( PyObject * type, PyObject * value ) { PyObject * result; PyObject * args = PyTuple_New( 1 ); if ( args == NULL ) return NULL; PyTuple_SET_ITEM( args, 0, value ); Py_INCREF( value ); result = PyObject_Call( type, args, NULL ); Py_DECREF( args ); return result; } /*----------------------------------------------------------------------------- | Verifies a Python value is of a specified type (or None): +----------------------------------------------------------------------------*/ static PyObject * validate_trait_type ( trait_object * trait, has_traits_object * obj, PyObject * name, PyObject * value ) { PyObject * type_info = trait->py_validate; int kind = PyTuple_GET_SIZE( type_info ); if ( ((kind == 3) && (value == Py_None)) || PyObject_TypeCheck( value, (PyTypeObject *) PyTuple_GET_ITEM( type_info, kind - 1 ) ) ) { Py_INCREF( value ); return value; } return raise_trait_error( trait, obj, name, value ); } /*----------------------------------------------------------------------------- | Verifies a Python value is an instance of a specified type (or None): +----------------------------------------------------------------------------*/ static PyObject * validate_trait_instance ( trait_object * trait, has_traits_object * obj, PyObject * name, PyObject * value ) { PyObject * type_info = trait->py_validate; int kind = PyTuple_GET_SIZE( type_info ); if ( ((kind == 3) && (value == Py_None)) || (PyObject_IsInstance( value, PyTuple_GET_ITEM( type_info, kind - 1 ) ) > 0) ) { Py_INCREF( value ); return value; } return raise_trait_error( trait, obj, name, value ); } /*----------------------------------------------------------------------------- | Verifies a Python value is of a the same type as the object being assigned | to (or None): +----------------------------------------------------------------------------*/ static PyObject * validate_trait_self_type ( trait_object * trait, has_traits_object * obj, PyObject * name, PyObject * value ) { if ( ((PyTuple_GET_SIZE( trait->py_validate ) == 2) && (value == Py_None)) || PyObject_TypeCheck( value, obj->ob_type ) ) { Py_INCREF( value ); return value; } return raise_trait_error( trait, obj, name, value ); } /*----------------------------------------------------------------------------- | Verifies a Python value is an int within a specified range: +----------------------------------------------------------------------------*/ static PyObject * validate_trait_int ( trait_object * trait, has_traits_object * obj, PyObject * name, PyObject * value ) { register PyObject * low; register PyObject * high; long exclude_mask; long int_value; PyObject * type_info = trait->py_validate; if ( PyInt_Check( value ) ) { int_value = PyInt_AS_LONG( value ); low = PyTuple_GET_ITEM( type_info, 1 ); high = PyTuple_GET_ITEM( type_info, 2 ); exclude_mask = PyInt_AS_LONG( PyTuple_GET_ITEM( type_info, 3 ) ); if ( low != Py_None ) { if ( (exclude_mask & 1) != 0 ) { if ( int_value <= PyInt_AS_LONG( low ) ) goto error; } else { if ( int_value < PyInt_AS_LONG( low ) ) goto error; } } if ( high != Py_None ) { if ( (exclude_mask & 2) != 0 ) { if ( int_value >= PyInt_AS_LONG( high ) ) goto error; } else { if ( int_value > PyInt_AS_LONG( high ) ) goto error; } } Py_INCREF( value ); return value; } error: return raise_trait_error( trait, obj, name, value ); } /*----------------------------------------------------------------------------- | Verifies a Python value is a float within a specified range: +----------------------------------------------------------------------------*/ static PyObject * validate_trait_float ( trait_object * trait, has_traits_object * obj, PyObject * name, PyObject * value ) { register PyObject * low; register PyObject * high; long exclude_mask; double float_value; PyObject * type_info = trait->py_validate; if ( !PyFloat_Check( value ) ) { if ( !PyInt_Check( value ) ) goto error; float_value = (double) PyInt_AS_LONG( value ); value = PyFloat_FromDouble( float_value ); if ( value == NULL ) goto error; Py_INCREF( value ); } else { float_value = PyFloat_AS_DOUBLE( value ); } low = PyTuple_GET_ITEM( type_info, 1 ); high = PyTuple_GET_ITEM( type_info, 2 ); exclude_mask = PyInt_AS_LONG( PyTuple_GET_ITEM( type_info, 3 ) ); if ( low != Py_None ) { if ( (exclude_mask & 1) != 0 ) { if ( float_value <= PyFloat_AS_DOUBLE( low ) ) goto error; } else { if ( float_value < PyFloat_AS_DOUBLE( low ) ) goto error; } } if ( high != Py_None ) { if ( (exclude_mask & 2) != 0 ) { if ( float_value >= PyFloat_AS_DOUBLE( high ) ) goto error; } else { if ( float_value > PyFloat_AS_DOUBLE( high ) ) goto error; } } Py_INCREF( value ); return value; error: return raise_trait_error( trait, obj, name, value ); } /*----------------------------------------------------------------------------- | Verifies a Python value is in a specified enumeration: +----------------------------------------------------------------------------*/ static PyObject * validate_trait_enum ( trait_object * trait, has_traits_object * obj, PyObject * name, PyObject * value ) { PyObject * type_info = trait->py_validate; if ( PySequence_Contains( PyTuple_GET_ITEM( type_info, 1 ), value ) > 0 ) { Py_INCREF( value ); return value; } return raise_trait_error( trait, obj, name, value ); } /*----------------------------------------------------------------------------- | Verifies a Python value is in a specified map (i.e. dictionary): +----------------------------------------------------------------------------*/ static PyObject * validate_trait_map ( trait_object * trait, has_traits_object * obj, PyObject * name, PyObject * value ) { PyObject * type_info = trait->py_validate; if ( PyDict_GetItem( PyTuple_GET_ITEM( type_info, 1 ), value ) != NULL ) { Py_INCREF( value ); return value; } return raise_trait_error( trait, obj, name, value ); } /*----------------------------------------------------------------------------- | Verifies a Python value is in a specified prefix map (i.e. dictionary): +----------------------------------------------------------------------------*/ static PyObject * validate_trait_prefix_map ( trait_object * trait, has_traits_object * obj, PyObject * name, PyObject * value ) { PyObject * type_info = trait->py_validate; PyObject * mapped_value = PyDict_GetItem( PyTuple_GET_ITEM( type_info, 1 ), value ); if ( mapped_value != NULL ) { Py_INCREF( mapped_value ); return mapped_value; } return call_validator( PyTuple_GET_ITEM( trait->py_validate, 2 ), obj, name, value ); } /*----------------------------------------------------------------------------- | Verifies a Python value is a tuple of a specified type and content: +----------------------------------------------------------------------------*/ static PyObject * validate_trait_tuple_check ( PyObject * traits, has_traits_object * obj, PyObject * name, PyObject * value ) { trait_object * itrait; PyObject * bitem, * aitem, * tuple; int i, j, n; if ( PyTuple_Check( value ) ) { n = PyTuple_GET_SIZE( traits ); if ( n == PyTuple_GET_SIZE( value ) ) { tuple = NULL; for ( i = 0; i < n; i++ ) { bitem = PyTuple_GET_ITEM( value, i ); itrait = (trait_object *) PyTuple_GET_ITEM( traits, i ); if ( itrait->validate == NULL ) { aitem = bitem; Py_INCREF( aitem ); } else aitem = itrait->validate( itrait, obj, name, bitem ); if ( aitem == NULL ) { PyErr_Clear(); Py_XDECREF( tuple ); return NULL; } if ( tuple != NULL ) PyTuple_SET_ITEM( tuple, i, aitem ); else if ( aitem != bitem ) { tuple = PyTuple_New( n ); if ( tuple == NULL ) return NULL; for ( j = 0; j < i; j++ ) { bitem = PyTuple_GET_ITEM( value, j ); Py_INCREF( bitem ); PyTuple_SET_ITEM( tuple, j, bitem ); } PyTuple_SET_ITEM( tuple, i, aitem ); } else Py_DECREF( aitem ); } if ( tuple != NULL ) return tuple; Py_INCREF( value ); return value; } } return NULL; } static PyObject * validate_trait_tuple ( trait_object * trait, has_traits_object * obj, PyObject * name, PyObject * value ) { PyObject * result = validate_trait_tuple_check( PyTuple_GET_ITEM( trait->py_validate, 1 ), obj, name, value ); if ( result != NULL ) return result; return raise_trait_error( trait, obj, name, value ); } /*----------------------------------------------------------------------------- | Verifies a Python value is of a specified (possibly coercable) type: +----------------------------------------------------------------------------*/ static PyObject * validate_trait_coerce_type ( trait_object * trait, has_traits_object * obj, PyObject * name, PyObject * value ) { int i, n; PyObject * type2; PyObject * type_info = trait->py_validate; PyObject * type = PyTuple_GET_ITEM( type_info, 1 ); if ( PyObject_TypeCheck( value, (PyTypeObject *) type ) ) { Py_INCREF( value ); return value; } n = PyTuple_GET_SIZE( type_info ); for ( i = 2; i < n; i++ ) { type2 = PyTuple_GET_ITEM( type_info, i ); if ( type2 == Py_None ) break; if ( PyObject_TypeCheck( value, (PyTypeObject *) type2 ) ) { Py_INCREF( value ); return value; } } for ( i++; i < n; i++ ) { type2 = PyTuple_GET_ITEM( type_info, i ); if ( PyObject_TypeCheck( value, (PyTypeObject *) type2 ) ) return type_converter( type, value ); } return raise_trait_error( trait, obj, name, value ); } /*----------------------------------------------------------------------------- | Verifies a Python value is of a specified (possibly castable) type: +----------------------------------------------------------------------------*/ static PyObject * validate_trait_cast_type ( trait_object * trait, has_traits_object * obj, PyObject * name, PyObject * value ) { PyObject * result; PyObject * type_info = trait->py_validate; PyObject * type = PyTuple_GET_ITEM( type_info, 1 ); if ( PyObject_TypeCheck( value, (PyTypeObject *) type ) ) { Py_INCREF( value ); return value; } if ( (result = type_converter( type, value )) != NULL ) return result; return raise_trait_error( trait, obj, name, value ); } /*----------------------------------------------------------------------------- | Verifies a Python value satisifies a specified function validator: +----------------------------------------------------------------------------*/ static PyObject * validate_trait_function ( trait_object * trait, has_traits_object * obj, PyObject * name, PyObject * value ) { PyObject * result; result = call_validator( PyTuple_GET_ITEM( trait->py_validate, 1 ), obj, name, value ); if ( result != NULL ) return result; PyErr_Clear(); return raise_trait_error( trait, obj, name, value ); } /*----------------------------------------------------------------------------- | Attempts to 'adapt' an object to a specified interface: +----------------------------------------------------------------------------*/ static PyObject * validate_trait_adapt ( trait_object * trait, has_traits_object * obj, PyObject * name, PyObject * value ) { PyObject * result; PyObject * args; PyObject * type; PyObject * type_info = trait->py_validate; long mode, rc; if ( value == Py_None ) { if ( PyInt_AS_LONG( PyTuple_GET_ITEM( type_info, 3 ) ) ) { Py_INCREF( value ); return value; } return raise_trait_error( trait, obj, name, value ); } type = PyTuple_GET_ITEM( type_info, 1 ); mode = PyInt_AS_LONG( PyTuple_GET_ITEM( type_info, 2 ) ); if ( mode == 2 ) { args = PyTuple_New( 3 ); if ( args == NULL ) return NULL; PyTuple_SET_ITEM( args, 2, Py_None ); Py_INCREF( Py_None ); } else { args = PyTuple_New( 2 ); if ( args == NULL ) return NULL; } PyTuple_SET_ITEM( args, 0, value ); PyTuple_SET_ITEM( args, 1, type ); Py_INCREF( value ); Py_INCREF( type ); result = PyObject_Call( adapt, args, NULL ); if ( result != NULL ) { if ( result != Py_None ) { if ( (mode > 0) || (result == value) ) { Py_DECREF( args ); return result; } Py_DECREF( result ); goto check_implements; } Py_DECREF( result ); result = PyObject_Call( validate_implements, args, NULL ); rc = PyInt_AS_LONG( result ); Py_DECREF( args ); Py_DECREF( result ); if ( rc ) { Py_INCREF( value ); return value; } result = default_value_for( trait, obj, name ); if ( result != NULL ) return result; PyErr_Clear(); return raise_trait_error( trait, obj, name, value ); } PyErr_Clear(); check_implements: result = PyObject_Call( validate_implements, args, NULL ); rc = PyInt_AS_LONG( result ); Py_DECREF( args ); Py_DECREF( result ); if ( rc ) { Py_INCREF( value ); return value; } return raise_trait_error( trait, obj, name, value ); } /*----------------------------------------------------------------------------- | Verifies a Python value satisifies a complex trait definition: +----------------------------------------------------------------------------*/ static PyObject * validate_trait_complex ( trait_object * trait, has_traits_object * obj, PyObject * name, PyObject * value ) { int i, j, k, kind; long int_value, exclude_mask, mode, rc; double float_value; PyObject * low, * high, * result, * type_info, * type, * type2, * args; PyObject * list_type_info = PyTuple_GET_ITEM( trait->py_validate, 1 ); int n = PyTuple_GET_SIZE( list_type_info ); for ( i = 0; i < n; i++ ) { type_info = PyTuple_GET_ITEM( list_type_info, i ); switch ( PyInt_AsLong( PyTuple_GET_ITEM( type_info, 0 ) ) ) { case 0: /* Type check: */ kind = PyTuple_GET_SIZE( type_info ); if ( ((kind == 3) && (value == Py_None)) || PyObject_TypeCheck( value, (PyTypeObject *) PyTuple_GET_ITEM( type_info, kind - 1 ) ) ) goto done; break; case 1: /* Instance check: */ kind = PyTuple_GET_SIZE( type_info ); if ( ((kind == 3) && (value == Py_None)) || (PyObject_IsInstance( value, PyTuple_GET_ITEM( type_info, kind - 1 ) ) > 0) ) goto done; break; case 2: /* Self type check: */ if ( ((PyTuple_GET_SIZE( type_info ) == 2) && (value == Py_None)) || PyObject_TypeCheck( value, obj->ob_type ) ) goto done; break; case 3: /* Integer range check: */ if ( PyInt_Check( value ) ) { int_value = PyInt_AS_LONG( value ); low = PyTuple_GET_ITEM( type_info, 1 ); high = PyTuple_GET_ITEM( type_info, 2 ); exclude_mask = PyInt_AS_LONG( PyTuple_GET_ITEM( type_info, 3 ) ); if ( low != Py_None ) { if ( (exclude_mask & 1) != 0 ) { if ( int_value <= PyInt_AS_LONG( low ) ) break; } else { if ( int_value < PyInt_AS_LONG( low ) ) break; } } if ( high != Py_None ) { if ( (exclude_mask & 2) != 0 ) { if ( int_value >= PyInt_AS_LONG( high ) ) break; } else { if ( int_value > PyInt_AS_LONG( high ) ) break; } } goto done; } break; case 4: /* Floating point range check: */ if ( !PyFloat_Check( value ) ) { if ( !PyInt_Check( value ) ) break; float_value = (double) PyInt_AS_LONG( value ); value = PyFloat_FromDouble( float_value ); if ( value == NULL ) { PyErr_Clear(); break; } } else { float_value = PyFloat_AS_DOUBLE( value ); Py_INCREF( value ); } low = PyTuple_GET_ITEM( type_info, 1 ); high = PyTuple_GET_ITEM( type_info, 2 ); exclude_mask = PyInt_AS_LONG( PyTuple_GET_ITEM( type_info, 3 ) ); if ( low != Py_None ) { if ( (exclude_mask & 1) != 0 ) { if ( float_value <= PyFloat_AS_DOUBLE( low ) ) break; } else { if ( float_value < PyFloat_AS_DOUBLE( low ) ) break; } } if ( high != Py_None ) { if ( (exclude_mask & 2) != 0 ) { if ( float_value >= PyFloat_AS_DOUBLE( high ) ) break; } else { if ( float_value > PyFloat_AS_DOUBLE( high ) ) break; } } goto done2; case 5: /* Enumerated item check: */ if ( PySequence_Contains( PyTuple_GET_ITEM( type_info, 1 ), value ) > 0 ) goto done; break; case 6: /* Mapped item check: */ if ( PyDict_GetItem( PyTuple_GET_ITEM( type_info, 1 ), value ) != NULL ) goto done; PyErr_Clear(); break; case 8: /* Perform 'slow' validate check: */ result = PyObject_CallMethod( PyTuple_GET_ITEM( type_info, 1 ), "slow_validate", "(OOO)", obj, name, value ); if ( result != NULL ) return result; PyErr_Clear(); break; case 9: /* Tuple item check: */ result = validate_trait_tuple_check( PyTuple_GET_ITEM( type_info, 1 ), obj, name, value ); if ( result != NULL ) return result; PyErr_Clear(); break; case 10: /* Prefix map item check: */ result = PyDict_GetItem( PyTuple_GET_ITEM( type_info, 1 ), value ); if ( result != NULL ) { Py_INCREF( result ); return result; } result = call_validator( PyTuple_GET_ITEM( type_info, 2 ), obj, name, value ); if ( result != NULL ) return result; PyErr_Clear(); break; case 11: /* Coercable type check: */ type = PyTuple_GET_ITEM( type_info, 1 ); if ( PyObject_TypeCheck( value, (PyTypeObject *) type ) ) goto done; k = PyTuple_GET_SIZE( type_info ); for ( j = 2; j < k; j++ ) { type2 = PyTuple_GET_ITEM( type_info, j ); if ( type2 == Py_None ) break; if ( PyObject_TypeCheck( value, (PyTypeObject *) type2 ) ) goto done; } for ( j++; j < k; j++ ) { type2 = PyTuple_GET_ITEM( type_info, j ); if ( PyObject_TypeCheck( value, (PyTypeObject *) type2 ) ) return type_converter( type, value ); } break; case 12: /* Castable type check */ type = PyTuple_GET_ITEM( type_info, 1 ); if ( PyObject_TypeCheck( value, (PyTypeObject *) type ) ) goto done; if ( (result = type_converter( type, value )) != NULL ) return result; PyErr_Clear(); break; case 13: /* Function validator check: */ result = call_validator( PyTuple_GET_ITEM( type_info, 1 ), obj, name, value ); if ( result != NULL ) return result; PyErr_Clear(); break; /* case 14: Python-based validator check: */ /* case 15..18: Property 'setattr' validate checks: */ case 19: /* PyProtocols 'adapt' check: */ if ( value == Py_None ) { if ( PyInt_AS_LONG( PyTuple_GET_ITEM( type_info, 3 ) ) ) goto done; break; } type = PyTuple_GET_ITEM( type_info, 1 ); mode = PyInt_AS_LONG( PyTuple_GET_ITEM( type_info, 2 ) ); if ( mode == 2 ) { args = PyTuple_New( 3 ); if ( args == NULL ) return NULL; PyTuple_SET_ITEM( args, 2, Py_None ); Py_INCREF( Py_None ); } else { args = PyTuple_New( 2 ); if ( args == NULL ) return NULL; } PyTuple_SET_ITEM( args, 0, value ); PyTuple_SET_ITEM( args, 1, type ); Py_INCREF( value ); Py_INCREF( type ); result = PyObject_Call( adapt, args, NULL ); if ( result != NULL ) { if ( result != Py_None ) { if ( (mode == 0) && (result != value) ) { Py_DECREF( result ); goto check_implements; } Py_DECREF( args ); return result; } Py_DECREF( result ); result = PyObject_Call( validate_implements, args, NULL ); rc = PyInt_AS_LONG( result ); Py_DECREF( args ); Py_DECREF( result ); if ( rc ) goto done; result = default_value_for( trait, obj, name ); if ( result != NULL ) return result; PyErr_Clear(); break; } PyErr_Clear(); check_implements: result = PyObject_Call( validate_implements, args, NULL ); rc = PyInt_AS_LONG( result ); Py_DECREF( args ); Py_DECREF( result ); if ( rc ) goto done; break; default: /* Should never happen...indicates an internal error: */ goto error; } } error: return raise_trait_error( trait, obj, name, value ); done: Py_INCREF( value ); done2: return value; } /*----------------------------------------------------------------------------- | Sets the value of the 'validate' field of a CTrait instance: +----------------------------------------------------------------------------*/ static trait_validate validate_handlers[] = { validate_trait_type, validate_trait_instance, validate_trait_self_type, validate_trait_int, validate_trait_float, validate_trait_enum, validate_trait_map, validate_trait_complex, NULL, validate_trait_tuple, validate_trait_prefix_map, validate_trait_coerce_type, validate_trait_cast_type, validate_trait_function, validate_trait_python, /* The following entries are used by the __getstate__ method... */ setattr_validate0, setattr_validate1, setattr_validate2, setattr_validate3, /* ...End of __getstate__ method entries */ validate_trait_adapt }; static PyObject * _trait_set_validate ( trait_object * trait, PyObject * args ) { PyObject * validate; PyObject * v1, * v2, * v3; int n, kind; if ( !PyArg_ParseTuple( args, "O", &validate ) ) return NULL; if ( PyCallable_Check( validate ) ) { kind = 14; goto done; } if ( PyTuple_CheckExact( validate ) ) { n = PyTuple_GET_SIZE( validate ); if ( n > 0 ) { kind = PyInt_AsLong( PyTuple_GET_ITEM( validate, 0 ) ); switch ( kind ) { case 0: /* Type check: */ if ( (n <= 3) && PyType_Check( PyTuple_GET_ITEM( validate, n - 1 ) ) && ((n == 2) || (PyTuple_GET_ITEM( validate, 1 ) == Py_None)) ) goto done; break; case 1: /* Instance check: */ if ( (n <= 3) && ((n == 2) || (PyTuple_GET_ITEM( validate, 1 ) == Py_None)) ) goto done; break; case 2: /* Self type check: */ if ( (n == 1) || ((n == 2) && (PyTuple_GET_ITEM( validate, 1 ) == Py_None)) ) goto done; break; case 3: /* Integer range check: */ if ( n == 4 ) { v1 = PyTuple_GET_ITEM( validate, 1 ); v2 = PyTuple_GET_ITEM( validate, 2 ); v3 = PyTuple_GET_ITEM( validate, 3 ); if ( ((v1 == Py_None) || PyInt_Check( v1 )) && ((v2 == Py_None) || PyInt_Check( v2 )) && PyInt_Check( v3 ) ) goto done; } break; case 4: /* Floating point range check: */ if ( n == 4 ) { v1 = PyTuple_GET_ITEM( validate, 1 ); v2 = PyTuple_GET_ITEM( validate, 2 ); v3 = PyTuple_GET_ITEM( validate, 3 ); if ( ((v1 == Py_None) || PyFloat_Check( v1 )) && ((v2 == Py_None) || PyFloat_Check( v2 )) && PyInt_Check( v3 ) ) goto done; } break; case 5: /* Enumerated item check: */ if ( n == 2 ) { v1 = PyTuple_GET_ITEM( validate, 1 ); if ( PyTuple_CheckExact( v1 ) ) goto done; } break; case 6: /* Mapped item check: */ if ( n == 2 ) { v1 = PyTuple_GET_ITEM( validate, 1 ); if ( PyDict_Check( v1 ) ) goto done; } break; case 7: /* TraitComplex item check: */ if ( n == 2 ) { v1 = PyTuple_GET_ITEM( validate, 1 ); if ( PyTuple_CheckExact( v1 ) ) goto done; } break; /* case 8: 'Slow' validate check: */ case 9: /* TupleOf item check: */ if ( n == 2 ) { v1 = PyTuple_GET_ITEM( validate, 1 ); if ( PyTuple_CheckExact( v1 ) ) goto done; } break; case 10: /* Prefix map item check: */ if ( n == 3 ) { v1 = PyTuple_GET_ITEM( validate, 1 ); if ( PyDict_Check( v1 ) ) goto done; } break; case 11: /* Coercable type check: */ if ( n >= 2 ) goto done; break; case 12: /* Castable type check: */ if ( n == 2 ) goto done; break; case 13: /* Function validator check: */ if ( n == 2 ) { v1 = PyTuple_GET_ITEM( validate, 1 ); if ( PyCallable_Check( v1 ) ) goto done; } break; /* case 14: Python-based validator check: */ /* case 15..18: Property 'setattr' validate checks: */ case 19: /* PyProtocols 'adapt' check: */ /* Note: We don't check the 'class' argument (item[1]) because some old-style code creates classes that are not strictly classes or types (e.g. VTK), and yet they work correctly with the rest of the Instance code */ if ( (n == 4) && PyInt_Check( PyTuple_GET_ITEM( validate, 2 ) ) && PyBool_Check( PyTuple_GET_ITEM( validate, 3 ) ) ) { goto done; } break; } } } PyErr_SetString( PyExc_ValueError, "The argument must be a tuple or callable." ); return NULL; done: trait->validate = validate_handlers[ kind ]; Py_INCREF( validate ); Py_XDECREF( trait->py_validate ); trait->py_validate = validate; Py_INCREF( Py_None ); return Py_None; } /*----------------------------------------------------------------------------- | Gets the value of the 'validate' field of a CTrait instance: +----------------------------------------------------------------------------*/ static PyObject * _trait_get_validate ( trait_object * trait ) { if ( trait->validate != NULL ) { Py_INCREF( trait->py_validate ); return trait->py_validate; } Py_INCREF( Py_None ); return Py_None; } /*----------------------------------------------------------------------------- | Validates that a particular value can be assigned to an object trait: +----------------------------------------------------------------------------*/ static PyObject * _trait_validate ( trait_object * trait, PyObject * args ) { PyObject * object, * name, * value; if ( !PyArg_ParseTuple( args, "OOO", &object, &name, &value ) ) return NULL; if ( trait->validate == NULL ) { Py_INCREF( value ); return value; } return trait->validate( trait, (has_traits_object *)object, name, value ); } /*----------------------------------------------------------------------------- | Calls a Python-based trait post_setattr handler: +----------------------------------------------------------------------------*/ static int post_setattr_trait_python ( trait_object * trait, has_traits_object * obj, PyObject * name, PyObject * value ) { PyObject * result; PyObject * args = PyTuple_New( 3 ); if ( args == NULL ) return -1; Py_INCREF( obj ); Py_INCREF( name ); Py_INCREF( value ); PyTuple_SET_ITEM( args, 0, (PyObject *) obj ); PyTuple_SET_ITEM( args, 1, name ); PyTuple_SET_ITEM( args, 2, value ); result = PyObject_Call( trait->py_post_setattr, args, NULL ); Py_DECREF( args ); if ( result == NULL ) return -1; Py_DECREF( result ); return 0; } /*----------------------------------------------------------------------------- | Returns the various forms of delegate names: +----------------------------------------------------------------------------*/ static PyObject * delegate_attr_name_name ( trait_object * trait, has_traits_object * obj, PyObject * name ) { Py_INCREF( name ); return name; } static PyObject * delegate_attr_name_prefix ( trait_object * trait, has_traits_object * obj, PyObject * name ) { Py_INCREF( trait->delegate_prefix ); return trait->delegate_prefix; } static PyObject * delegate_attr_name_prefix_name ( trait_object * trait, has_traits_object * obj, PyObject * name ) { char * p; int prefix_len = PyString_GET_SIZE( trait->delegate_prefix ); int name_len = PyString_GET_SIZE( name ); int total_len = prefix_len + name_len; PyObject * result = PyString_FromStringAndSize( NULL, total_len ); if ( result == NULL ) { Py_INCREF( Py_None ); return Py_None; } p = PyString_AS_STRING( result ); memcpy( p, PyString_AS_STRING( trait->delegate_prefix ), prefix_len ); memcpy( p + prefix_len, PyString_AS_STRING( name ), name_len ); return result; } static PyObject * delegate_attr_name_class_name ( trait_object * trait, has_traits_object * obj, PyObject * name ) { PyObject * prefix, * result; char * p; int prefix_len, name_len, total_len; prefix = PyObject_GetAttr( (PyObject *) obj->ob_type, class_prefix ); // fixme: Should verify that prefix is a string... if ( prefix == NULL ) { PyErr_Clear(); Py_INCREF( name ); return name; } prefix_len = PyString_GET_SIZE( prefix ); name_len = PyString_GET_SIZE( name ); total_len = prefix_len + name_len; result = PyString_FromStringAndSize( NULL, total_len ); if ( result == NULL ) { Py_INCREF( Py_None ); return Py_None; } p = PyString_AS_STRING( result ); memcpy( p, PyString_AS_STRING( prefix ), prefix_len ); memcpy( p + prefix_len, PyString_AS_STRING( name ), name_len ); Py_DECREF( prefix ); return result; } /*----------------------------------------------------------------------------- | Sets the value of the 'post_setattr' field of a CTrait instance: +----------------------------------------------------------------------------*/ static delegate_attr_name_func delegate_attr_name_handlers[] = { delegate_attr_name_name, delegate_attr_name_prefix, delegate_attr_name_prefix_name, delegate_attr_name_class_name, NULL }; static PyObject * _trait_delegate ( trait_object * trait, PyObject * args ) { PyObject * delegate_name; PyObject * delegate_prefix; int prefix_type; int modify_delegate; if ( !PyArg_ParseTuple( args, "O!O!ii", &PyString_Type, &delegate_name, &PyString_Type, &delegate_prefix, &prefix_type, &modify_delegate ) ) return NULL; if ( modify_delegate ) { trait->flags |= TRAIT_MODIFY_DELEGATE; } else { trait->flags &= (~TRAIT_MODIFY_DELEGATE); } trait->delegate_name = delegate_name; trait->delegate_prefix = delegate_prefix; Py_INCREF( delegate_name ); Py_INCREF( delegate_prefix ); if ( (prefix_type < 0) || (prefix_type > 3) ) prefix_type = 0; trait->delegate_attr_name = delegate_attr_name_handlers[ prefix_type ]; Py_INCREF( Py_None ); return Py_None; } /*----------------------------------------------------------------------------- | Sets the value of the 'comparison' mode of a CTrait instance: +----------------------------------------------------------------------------*/ static PyObject * _trait_rich_comparison ( trait_object * trait, PyObject * args ) { int compare_type; if ( !PyArg_ParseTuple( args, "i", &compare_type ) ) return NULL; trait->flags &= (~(TRAIT_NO_VALUE_TEST | TRAIT_OBJECT_IDENTITY)); if ( compare_type == 0 ) trait->flags |= TRAIT_OBJECT_IDENTITY; Py_INCREF( Py_None ); return Py_None; } /*----------------------------------------------------------------------------- | Sets the appropriate value comparison mode flags of a CTrait instance: +----------------------------------------------------------------------------*/ static PyObject * _trait_comparison_mode ( trait_object * trait, PyObject * args ) { int comparison_mode; if ( !PyArg_ParseTuple( args, "i", &comparison_mode ) ) return NULL; trait->flags &= (~(TRAIT_NO_VALUE_TEST | TRAIT_OBJECT_IDENTITY)); switch ( comparison_mode ) { case 0: trait->flags |= TRAIT_NO_VALUE_TEST; break; case 1: trait->flags |= TRAIT_OBJECT_IDENTITY; default: break; } Py_INCREF( Py_None ); return Py_None; } /*----------------------------------------------------------------------------- | Sets the value of the 'value allowed' mode of a CTrait instance: +----------------------------------------------------------------------------*/ static PyObject * _trait_value_allowed ( trait_object * trait, PyObject * args ) { int value_allowed; if ( !PyArg_ParseTuple( args, "i", &value_allowed ) ) return NULL; if ( value_allowed ) { trait->flags |= TRAIT_VALUE_ALLOWED; } else { trait->flags &= (~TRAIT_VALUE_ALLOWED); } Py_INCREF( Py_None ); return Py_None; } /*----------------------------------------------------------------------------- | Sets the value of the 'value trait' mode of a CTrait instance: +----------------------------------------------------------------------------*/ static PyObject * _trait_value_property ( trait_object * trait, PyObject * args ) { int value_trait; if ( !PyArg_ParseTuple( args, "i", &value_trait ) ) return NULL; if ( value_trait ) { trait->flags |= TRAIT_VALUE_PROPERTY; } else { trait->flags &= (~TRAIT_VALUE_PROPERTY); } Py_INCREF( Py_None ); return Py_None; } /*----------------------------------------------------------------------------- | Sets the value of the 'setattr_original_value' flag of a CTrait instance: +----------------------------------------------------------------------------*/ static PyObject * _trait_setattr_original_value ( trait_object * trait, PyObject * args ) { int original_value; if ( !PyArg_ParseTuple( args, "i", &original_value ) ) return NULL; if ( original_value != 0 ) { trait->flags |= TRAIT_SETATTR_ORIGINAL_VALUE; } else { trait->flags &= (~TRAIT_SETATTR_ORIGINAL_VALUE); } Py_INCREF( trait ); return (PyObject *) trait; } /*----------------------------------------------------------------------------- | Sets the value of the 'post_setattr_original_value' flag of a CTrait | instance (used in the processing of 'post_settattr' calls): +----------------------------------------------------------------------------*/ static PyObject * _trait_post_setattr_original_value ( trait_object * trait, PyObject * args ) { int original_value; if ( !PyArg_ParseTuple( args, "i", &original_value ) ) return NULL; if ( original_value != 0 ) { trait->flags |= TRAIT_POST_SETATTR_ORIGINAL_VALUE; } else { trait->flags &= (~TRAIT_POST_SETATTR_ORIGINAL_VALUE); } Py_INCREF( trait ); return (PyObject *) trait; } /*----------------------------------------------------------------------------- | Sets the value of the 'is_mapped' flag of a CTrait instance (used in the | processing of the default value of a trait with a 'post_settattr' handler): +----------------------------------------------------------------------------*/ static PyObject * _trait_is_mapped ( trait_object * trait, PyObject * args ) { int is_mapped; if ( !PyArg_ParseTuple( args, "i", &is_mapped ) ) return NULL; if ( is_mapped != 0 ) { trait->flags |= TRAIT_IS_MAPPED; } else { trait->flags &= (~TRAIT_IS_MAPPED); } Py_INCREF( trait ); return (PyObject *) trait; } /*----------------------------------------------------------------------------- | Sets the 'property' value fields of a CTrait instance: +----------------------------------------------------------------------------*/ static trait_setattr setattr_property_handlers[] = { setattr_property0, setattr_property1, setattr_property2, setattr_property3, /* The following entries are used by the __getstate__ method__: */ (trait_setattr) post_setattr_trait_python, NULL }; static PyObject * _trait_property ( trait_object * trait, PyObject * args ) { PyObject * get, * set, * validate, * result, * temp; int get_n, set_n, validate_n; if ( PyTuple_GET_SIZE( args ) == 0 ) { if ( trait->flags & TRAIT_PROPERTY ) { result = PyTuple_New( 3 ); if ( result != NULL ) { PyTuple_SET_ITEM( result, 0, temp = trait->delegate_name ); Py_INCREF( temp ); PyTuple_SET_ITEM( result, 1, temp = trait->delegate_prefix ); Py_INCREF( temp ); PyTuple_SET_ITEM( result, 2, temp = trait->py_validate ); Py_INCREF( temp ); Py_INCREF( result ); return result; } return NULL; } else { Py_INCREF( Py_None ); return Py_None; } } if ( !PyArg_ParseTuple( args, "OiOiOi", &get, &get_n, &set, &set_n, &validate, &validate_n ) ) return NULL; if ( !PyCallable_Check( get ) || !PyCallable_Check( set ) || ((validate != Py_None) && !PyCallable_Check( validate )) || (get_n < 0) || (get_n > 3) || (set_n < 0) || (set_n > 3) || (validate_n < 0) || (validate_n > 3) ) { PyErr_SetString( PyExc_ValueError, "Invalid arguments." ); return NULL; } trait->flags |= TRAIT_PROPERTY; trait->getattr = getattr_property_handlers[ get_n ]; if ( validate != Py_None ) { trait->setattr = setattr_validate_property; trait->post_setattr = (trait_post_setattr) setattr_property_handlers[ set_n ]; trait->validate = setattr_validate_handlers[ validate_n ]; } else trait->setattr = setattr_property_handlers[ set_n ]; trait->delegate_name = get; trait->delegate_prefix = set; trait->py_validate = validate; Py_INCREF( get ); Py_INCREF( set ); Py_INCREF( validate ); Py_INCREF( Py_None ); return Py_None; } /*----------------------------------------------------------------------------- | Clones one trait into another: +----------------------------------------------------------------------------*/ static void trait_clone ( trait_object * trait, trait_object * source ) { trait->flags = source->flags; trait->getattr = source->getattr; trait->setattr = source->setattr; trait->post_setattr = source->post_setattr; trait->py_post_setattr = source->py_post_setattr; trait->validate = source->validate; trait->py_validate = source->py_validate; trait->default_value_type = source->default_value_type; trait->default_value = source->default_value; trait->delegate_name = source->delegate_name; trait->delegate_prefix = source->delegate_prefix; trait->delegate_attr_name = source->delegate_attr_name; trait->handler = source->handler; Py_XINCREF( trait->py_post_setattr ); Py_XINCREF( trait->py_validate ); Py_XINCREF( trait->delegate_name ); Py_XINCREF( trait->default_value ); Py_XINCREF( trait->delegate_prefix ); Py_XINCREF( trait->handler ); } static PyObject * _trait_clone ( trait_object * trait, PyObject * args ) { trait_object * source; if ( !PyArg_ParseTuple( args, "O!", ctrait_type, &source ) ) return NULL; trait_clone( trait, source ); Py_INCREF( Py_None ); return Py_None; } /*----------------------------------------------------------------------------- | Returns (and optionally creates) the trait 'notifiers' list: +----------------------------------------------------------------------------*/ static PyObject * _trait_notifiers ( trait_object * trait, PyObject * args ) { PyObject * result; PyObject * list; int force_create; if ( !PyArg_ParseTuple( args, "i", &force_create ) ) return NULL; result = (PyObject *) trait->notifiers; if ( result == NULL ) { result = Py_None; if ( force_create && ((list = PyList_New( 0 )) != NULL) ) trait->notifiers = (PyListObject *) (result = list); } Py_INCREF( result ); return result; } /*----------------------------------------------------------------------------- | Converts a function to an index into a function table: +----------------------------------------------------------------------------*/ static int func_index ( void * function, void ** function_table ) { int i; for ( i = 0; function != function_table[i]; i++ ); return i; } /*----------------------------------------------------------------------------- | Gets the pickleable state of the trait: +----------------------------------------------------------------------------*/ static PyObject * _trait_getstate ( trait_object * trait, PyObject * args ) { PyObject * result; if ( !PyArg_ParseTuple( args, "" ) ) return NULL; result = PyTuple_New( 15 ); if ( result == NULL ) return NULL; PyTuple_SET_ITEM( result, 0, PyInt_FromLong( func_index( (void *) trait->getattr, (void **) getattr_handlers ) ) ); PyTuple_SET_ITEM( result, 1, PyInt_FromLong( func_index( (void *) trait->setattr, (void **) setattr_handlers ) ) ); PyTuple_SET_ITEM( result, 2, PyInt_FromLong( func_index( (void *) trait->post_setattr, (void **) setattr_property_handlers ) ) ); PyTuple_SET_ITEM( result, 3, get_callable_value( trait->py_post_setattr )); PyTuple_SET_ITEM( result, 4, PyInt_FromLong( func_index( (void *) trait->validate, (void **) validate_handlers ) ) ); PyTuple_SET_ITEM( result, 5, get_callable_value( trait->py_validate ) ); PyTuple_SET_ITEM( result, 6, PyInt_FromLong( trait->default_value_type ) ); PyTuple_SET_ITEM( result, 7, get_value( trait->default_value ) ); PyTuple_SET_ITEM( result, 8, PyInt_FromLong( trait->flags ) ); PyTuple_SET_ITEM( result, 9, get_value( trait->delegate_name ) ); PyTuple_SET_ITEM( result, 10, get_value( trait->delegate_prefix ) ); PyTuple_SET_ITEM( result, 11, PyInt_FromLong( func_index( (void *) trait->delegate_attr_name, (void **) delegate_attr_name_handlers ) ) ); PyTuple_SET_ITEM( result, 12, get_value( NULL ) ); /* trait->notifiers */ PyTuple_SET_ITEM( result, 13, get_value( trait->handler ) ); PyTuple_SET_ITEM( result, 14, get_value( trait->obj_dict ) ); return result; } /*----------------------------------------------------------------------------- | Restores the pickled state of the trait: +----------------------------------------------------------------------------*/ static PyObject * _trait_setstate ( trait_object * trait, PyObject * args ) { PyObject * ignore, * temp, *temp2; int getattr_index, setattr_index, post_setattr_index, validate_index, delegate_attr_name_index; if ( !PyArg_ParseTuple( args, "(iiiOiOiOiOOiOOO)", &getattr_index, &setattr_index, &post_setattr_index, &trait->py_post_setattr, &validate_index, &trait->py_validate, &trait->default_value_type, &trait->default_value, &trait->flags, &trait->delegate_name, &trait->delegate_prefix, &delegate_attr_name_index, &ignore, &trait->handler, &trait->obj_dict ) ) return NULL; trait->getattr = getattr_handlers[ getattr_index ]; trait->setattr = setattr_handlers[ setattr_index ]; trait->post_setattr = (trait_post_setattr) setattr_property_handlers[ post_setattr_index ]; trait->validate = validate_handlers[ validate_index ]; trait->delegate_attr_name = delegate_attr_name_handlers[ delegate_attr_name_index ]; /* Convert any references to callable methods on the handler back into bound methods: */ temp = trait->py_validate; if ( PyInt_Check( temp ) ) trait->py_validate = PyObject_GetAttrString( trait->handler, "validate" ); else if ( PyTuple_Check( temp ) && (PyInt_AsLong( PyTuple_GET_ITEM( temp, 0 ) ) == 10) ) { temp2 = PyObject_GetAttrString( trait->handler, "validate" ); Py_INCREF( temp2 ); Py_DECREF( PyTuple_GET_ITEM( temp, 2 ) ); PyTuple_SET_ITEM( temp, 2, temp2 ); } if ( PyInt_Check( trait->py_post_setattr ) ) trait->py_post_setattr = PyObject_GetAttrString( trait->handler, "post_setattr" ); Py_INCREF( trait->py_post_setattr ); Py_INCREF( trait->py_validate ); Py_INCREF( trait->default_value ); Py_INCREF( trait->delegate_name ); Py_INCREF( trait->delegate_prefix ); Py_INCREF( trait->handler ); Py_INCREF( trait->obj_dict ); Py_INCREF( Py_None ); return Py_None; } /*----------------------------------------------------------------------------- | Returns the current trait dictionary: +----------------------------------------------------------------------------*/ static PyObject * get_trait_dict ( trait_object * trait, void * closure ) { PyObject * obj_dict = trait->obj_dict; if ( obj_dict == NULL ) { trait->obj_dict = obj_dict = PyDict_New(); if ( obj_dict == NULL ) return NULL; } Py_INCREF( obj_dict ); return obj_dict; } /*----------------------------------------------------------------------------- | Sets the current trait dictionary: +----------------------------------------------------------------------------*/ static int set_trait_dict ( trait_object * trait, PyObject * value, void * closure ) { if ( !PyDict_Check( value ) ) return dictionary_error(); return set_value( &trait->obj_dict, value ); } /*----------------------------------------------------------------------------- | Returns the current trait handler (if any): +----------------------------------------------------------------------------*/ static PyObject * get_trait_handler ( trait_object * trait, void * closure ) { return get_value( trait->handler ); } /*----------------------------------------------------------------------------- | Sets the current trait dictionary: +----------------------------------------------------------------------------*/ static int set_trait_handler ( trait_object * trait, PyObject * value, void * closure ) { return set_value( &trait->handler, value ); } /*----------------------------------------------------------------------------- | Returns the current post_setattr (if any): +----------------------------------------------------------------------------*/ static PyObject * get_trait_post_setattr ( trait_object * trait, void * closure ) { return get_value( trait->py_post_setattr ); } /*----------------------------------------------------------------------------- | Sets the value of the 'post_setattr' field of a CTrait instance: +----------------------------------------------------------------------------*/ static int set_trait_post_setattr ( trait_object * trait, PyObject * value, void * closure ) { if ( !PyCallable_Check( value ) ) { PyErr_SetString( PyExc_ValueError, "The assigned value must be callable." ); return -1; } trait->post_setattr = post_setattr_trait_python; return set_value( &trait->py_post_setattr, value ); } /*----------------------------------------------------------------------------- | 'CTrait' instance methods: +----------------------------------------------------------------------------*/ static PyMethodDef trait_methods[] = { { "__getstate__", (PyCFunction) _trait_getstate, METH_VARARGS, PyDoc_STR( "__getstate__()" ) }, { "__setstate__", (PyCFunction) _trait_setstate, METH_VARARGS, PyDoc_STR( "__setstate__(state)" ) }, { "default_value", (PyCFunction) _trait_default_value, METH_VARARGS, PyDoc_STR( "default_value(default_value)" ) }, { "default_value_for", (PyCFunction) _trait_default_value_for, METH_VARARGS, PyDoc_STR( "default_value_for(object,name)" ) }, { "set_validate", (PyCFunction) _trait_set_validate, METH_VARARGS, PyDoc_STR( "set_validate(validate_function)" ) }, { "get_validate", (PyCFunction) _trait_get_validate, METH_NOARGS, PyDoc_STR( "get_validate()" ) }, { "validate", (PyCFunction) _trait_validate, METH_VARARGS, PyDoc_STR( "validate(object,name,value)" ) }, { "delegate", (PyCFunction) _trait_delegate, METH_VARARGS, PyDoc_STR( "delegate(delegate_name,prefix,prefix_type,modify_delegate)" ) }, { "rich_comparison", (PyCFunction) _trait_rich_comparison, METH_VARARGS, PyDoc_STR( "rich_comparison(rich_comparison_boolean)" ) }, { "comparison_mode", (PyCFunction) _trait_comparison_mode, METH_VARARGS, PyDoc_STR( "comparison_mode(comparison_mode_enum)" ) }, { "value_allowed", (PyCFunction) _trait_value_allowed, METH_VARARGS, PyDoc_STR( "value_allowed(value_allowed_boolean)" ) }, { "value_property", (PyCFunction) _trait_value_property, METH_VARARGS, PyDoc_STR( "value_property(value_trait_boolean)" ) }, { "setattr_original_value", (PyCFunction) _trait_setattr_original_value, METH_VARARGS, PyDoc_STR( "setattr_original_value(original_value_boolean)" ) }, { "post_setattr_original_value", (PyCFunction) _trait_post_setattr_original_value, METH_VARARGS, PyDoc_STR( "post_setattr_original_value(original_value_boolean)" ) }, { "is_mapped", (PyCFunction) _trait_is_mapped, METH_VARARGS, PyDoc_STR( "is_mapped(is_mapped_boolean)" ) }, { "property", (PyCFunction) _trait_property, METH_VARARGS, PyDoc_STR( "property([get,set,validate])" ) }, { "clone", (PyCFunction) _trait_clone, METH_VARARGS, PyDoc_STR( "clone(trait)" ) }, { "cast", (PyCFunction) _trait_cast, METH_VARARGS, PyDoc_STR( "cast(value)" ) }, { "_notifiers", (PyCFunction) _trait_notifiers, METH_VARARGS, PyDoc_STR( "_notifiers(force_create)" ) }, { NULL, NULL }, }; /*----------------------------------------------------------------------------- | 'CTrait' property definitions: +----------------------------------------------------------------------------*/ static PyGetSetDef trait_properties[] = { { "__dict__", (getter) get_trait_dict, (setter) set_trait_dict }, { "handler", (getter) get_trait_handler, (setter) set_trait_handler }, { "post_setattr", (getter) get_trait_post_setattr, (setter) set_trait_post_setattr }, { 0 } }; /*----------------------------------------------------------------------------- | 'CTrait' type definition: +----------------------------------------------------------------------------*/ static PyTypeObject trait_type = { PyObject_HEAD_INIT( DEFERRED_ADDRESS( &PyType_Type ) ) 0, "traits.ctraits.cTrait", sizeof( trait_object ), 0, (destructor) trait_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ (getattrofunc) trait_getattro, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,/* tp_flags */ 0, /* tp_doc */ (traverseproc) trait_traverse, /* tp_traverse */ (inquiry) trait_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ trait_methods, /* tp_methods */ 0, /* tp_members */ trait_properties, /* tp_getset */ DEFERRED_ADDRESS( &PyBaseObject_Type ), /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ sizeof( trait_object ) - sizeof( PyObject * ), /* tp_dictoffset */ (initproc) trait_init, /* tp_init */ DEFERRED_ADDRESS( PyType_GenericAlloc ), /* tp_alloc */ DEFERRED_ADDRESS( PyType_GenericNew ) /* tp_new */ }; /*----------------------------------------------------------------------------- | Sets the global 'Undefined' and 'Uninitialized' values: +----------------------------------------------------------------------------*/ static PyObject * _ctraits_undefined ( PyObject * self, PyObject * args ) { if ( !PyArg_ParseTuple( args, "OO", &Undefined, &Uninitialized ) ) return NULL; Py_INCREF( Undefined ); Py_INCREF( Uninitialized ); Py_INCREF( Py_None ); return Py_None; } /*----------------------------------------------------------------------------- | Sets the global 'TraitError' and 'DelegationError' exception types: +----------------------------------------------------------------------------*/ static PyObject * _ctraits_exceptions ( PyObject * self, PyObject * args ) { if ( !PyArg_ParseTuple( args, "OO", &TraitError, &DelegationError ) ) return NULL; Py_INCREF( TraitError ); Py_INCREF( DelegationError ); Py_INCREF( Py_None ); return Py_None; } /*----------------------------------------------------------------------------- | Sets the global 'TraitListObject', TraitSetObject and 'TraitDictObject' | classes: +----------------------------------------------------------------------------*/ static PyObject * _ctraits_list_classes ( PyObject * self, PyObject * args ) { if ( !PyArg_ParseTuple( args, "OOO", &TraitListObject, &TraitSetObject, &TraitDictObject ) ) return NULL; Py_INCREF( TraitListObject ); Py_INCREF( TraitSetObject ); Py_INCREF( TraitDictObject ); Py_INCREF( Py_None ); return Py_None; } /*----------------------------------------------------------------------------- | Sets the global 'TraitValue' class: +----------------------------------------------------------------------------*/ static PyObject * _ctraits_value_class ( PyObject * self, PyObject * args ) { if ( !PyArg_ParseTuple( args, "O", &TraitValue ) ) return NULL; Py_INCREF( TraitValue ); Py_INCREF( Py_None ); return Py_None; } /*----------------------------------------------------------------------------- | Sets the global 'adapt' reference to the PyProtocols 'adapt' function: +----------------------------------------------------------------------------*/ static PyObject * _ctraits_adapt ( PyObject * self, PyObject * args ) { if ( !PyArg_ParseTuple( args, "O", &adapt ) ) return NULL; Py_INCREF( adapt ); Py_INCREF( Py_None ); return Py_None; } /*----------------------------------------------------------------------------- | Sets the global 'validate_implements' reference to the Python level | function: +----------------------------------------------------------------------------*/ static PyObject * _ctraits_validate_implements ( PyObject * self, PyObject * args ) { if ( !PyArg_ParseTuple( args, "O", &validate_implements ) ) return NULL; Py_INCREF( validate_implements ); Py_INCREF( Py_None ); return Py_None; } /*----------------------------------------------------------------------------- | Sets the global 'ctrait_type' class reference: +----------------------------------------------------------------------------*/ static PyObject * _ctraits_ctrait ( PyObject * self, PyObject * args ) { if ( !PyArg_ParseTuple( args, "O", &ctrait_type ) ) return NULL; Py_INCREF( ctrait_type ); Py_INCREF( Py_None ); return Py_None; } /*----------------------------------------------------------------------------- | Sets the global 'trait_notification_handler' function, and returns the | previous value: +----------------------------------------------------------------------------*/ static PyObject * _ctraits_trait_notification_handler ( PyObject * self, PyObject * args ) { PyObject * result = _trait_notification_handler; if ( !PyArg_ParseTuple( args, "O", &_trait_notification_handler ) ) { return NULL; } if ( _trait_notification_handler == Py_None ) { _trait_notification_handler = NULL; } else { Py_INCREF( _trait_notification_handler ); } if ( result == NULL ) { Py_INCREF( Py_None ); result = Py_None; } return result; } /*----------------------------------------------------------------------------- | 'CTrait' instance methods: +----------------------------------------------------------------------------*/ static PyMethodDef ctraits_methods[] = { { "_undefined", (PyCFunction) _ctraits_undefined, METH_VARARGS, PyDoc_STR( "_undefined(Undefined,Uninitialized)" ) }, { "_exceptions", (PyCFunction) _ctraits_exceptions, METH_VARARGS, PyDoc_STR( "_exceptions(TraitError,DelegationError)" ) }, { "_list_classes", (PyCFunction) _ctraits_list_classes, METH_VARARGS, PyDoc_STR( "_list_classes(TraitListObject,TraitSetObject,TraitDictObject)" ) }, { "_value_class", (PyCFunction) _ctraits_value_class, METH_VARARGS, PyDoc_STR( "_value_class(TraitValue)" ) }, { "_adapt", (PyCFunction) _ctraits_adapt, METH_VARARGS, PyDoc_STR( "_adapt(PyProtocols._speedups.adapt)" ) }, { "_validate_implements", (PyCFunction) _ctraits_validate_implements, METH_VARARGS, PyDoc_STR( "_validate_implements(validate_implements)" )}, { "_ctrait", (PyCFunction) _ctraits_ctrait, METH_VARARGS, PyDoc_STR( "_ctrait(CTrait_class)" ) }, { "_trait_notification_handler", (PyCFunction) _ctraits_trait_notification_handler, METH_VARARGS, PyDoc_STR( "_trait_notification_handler(handler)" ) }, { NULL, NULL }, }; /*----------------------------------------------------------------------------- | Trait method object definition: +----------------------------------------------------------------------------*/ typedef struct { PyObject_HEAD PyObject * tm_name; /* The name of the method */ PyObject * tm_func; /* The callable object implementing the method*/ PyObject * tm_self; /* The instance it is bound to, or NULL */ PyObject * tm_traits; /* Tuple containing return/arguments traits */ PyObject * tm_class; /* The class that asked for the method */ PyObject * tm_weakreflist; /* List of weak references */ } trait_method_object; /*----------------------------------------------------------------------------- | Instance method objects are used for two purposes: | (a) as bound instance methods (returned by instancename.methodname) | (b) as unbound methods (returned by ClassName.methodname) | In case (b), tm_self is NULL +----------------------------------------------------------------------------*/ static trait_method_object * free_list; /*----------------------------------------------------------------------------- | Creates a new trait method instance: +----------------------------------------------------------------------------*/ static PyObject * create_trait_method ( PyObject * name, PyObject * func, PyObject * self, PyObject * traits,PyObject * class_obj ) { register trait_method_object * im; assert( PyCallable_Check( func ) ); im = free_list; if ( im != NULL ) { free_list = (trait_method_object *)(im->tm_self); PyObject_INIT( im, &trait_method_type ); } else { // fixme: Should we use this form of New if the other 'fixme's are // commented out?... im = PyObject_GC_New( trait_method_object, &trait_method_type ); if ( im == NULL ) return NULL; } im->tm_weakreflist = NULL; Py_INCREF( name ); im->tm_name = name; Py_INCREF( func ); im->tm_func = func; Py_XINCREF( self ); im->tm_self = self; Py_INCREF( traits ); im->tm_traits = traits; Py_XINCREF( class_obj ); im->tm_class = class_obj; // fixme: The following line doesn't link into a separate DLL: //_PyObject_GC_TRACK( im ); return (PyObject *) im; } /*----------------------------------------------------------------------------- | Gets the value of a trait method attribute: | | The getattr() implementation for trait method objects is similar to | PyObject_GenericGetAttr(), but instead of looking in __dict__ it | asks tm_self for the attribute. Then the error handling is a bit | different because we want to preserve the exception raised by the | delegate, unless we have an alternative from our class. +----------------------------------------------------------------------------*/ static PyObject * trait_method_getattro ( PyObject * obj, PyObject * name ) { trait_method_object *im = (trait_method_object *) obj; PyTypeObject * tp = obj->ob_type; PyObject * descr = NULL, * res; descrgetfunc f = NULL; if ( PyType_HasFeature( tp, Py_TPFLAGS_HAVE_CLASS ) ) { if ( tp->tp_dict == NULL ) { if ( PyType_Ready(tp) < 0 ) return NULL; } descr = _PyType_Lookup( tp, name ); } f = NULL; if ( descr != NULL ) { f = TP_DESCR_GET( descr->ob_type ); if ( (f != NULL) && PyDescr_IsData( descr ) ) return f( descr, obj, (PyObject *) obj->ob_type ); } res = PyObject_GetAttr( im->tm_func, name ); if ( (res != NULL) || !PyErr_ExceptionMatches( PyExc_AttributeError ) ) return res; if ( f != NULL ) { PyErr_Clear(); return f( descr, obj, (PyObject *) obj->ob_type ); } if ( descr != NULL ) { PyErr_Clear(); Py_INCREF( descr ); return descr; } assert( PyErr_Occurred() ); return NULL; } /*----------------------------------------------------------------------------- | Creates a new trait method: +----------------------------------------------------------------------------*/ static PyObject * trait_method_new ( PyTypeObject * type, PyObject * args, PyObject * kw ) { PyObject * name; PyObject * func; PyObject * traits; if ( !PyArg_UnpackTuple( args, "traitmethod", 3, 3, &name, &func, &traits ) ) return NULL; if ( !PyCallable_Check( func ) ) { PyErr_SetString( PyExc_TypeError, "second argument must be callable" ); return NULL; } // fixme: Should we sanity check the 'traits' argument here?... return create_trait_method( name, func, NULL, traits, NULL ); } /*----------------------------------------------------------------------------- | Deallocates a trait method: +----------------------------------------------------------------------------*/ static void trait_method_dealloc ( register trait_method_object * tm ) { // fixme: The following line complements the _PyObject_GC_TRACK( im ) // line commented out above... //_PyObject_GC_UNTRACK( tm ); if ( tm->tm_weakreflist != NULL ) PyObject_ClearWeakRefs( (PyObject *) tm ); Py_DECREF( tm->tm_name ); Py_DECREF( tm->tm_func ); Py_XDECREF( tm->tm_self ); Py_DECREF( tm->tm_traits ); Py_XDECREF( tm->tm_class ); tm->tm_self = (PyObject *) free_list; free_list = tm; } /*----------------------------------------------------------------------------- | Compare two trait methods: +----------------------------------------------------------------------------*/ static int trait_method_compare ( trait_method_object * a, trait_method_object * b ) { if ( a->tm_self != b->tm_self ) return (a->tm_self < b->tm_self) ? -1 : 1; return PyObject_Compare( a->tm_func, b->tm_func ); } /*----------------------------------------------------------------------------- | Returns the string representation of a trait method: +----------------------------------------------------------------------------*/ static PyObject * trait_method_repr ( trait_method_object * a ) { PyObject * self = a->tm_self; PyObject * func = a->tm_func; PyObject * klass = a->tm_class; PyObject * funcname = NULL, * klassname = NULL, * result = NULL; char * sfuncname = "?", * sklassname = "?"; funcname = PyObject_GetAttrString( func, "__name__" ); if ( funcname == NULL ) { if ( !PyErr_ExceptionMatches( PyExc_AttributeError ) ) return NULL; PyErr_Clear(); } else if ( !PyString_Check( funcname ) ) { Py_DECREF( funcname ); funcname = NULL; } else sfuncname = PyString_AS_STRING( funcname ); if ( klass == NULL ) klassname = NULL; else { klassname = PyObject_GetAttrString( klass, "__name__" ); if (klassname == NULL) { if ( !PyErr_ExceptionMatches( PyExc_AttributeError ) ) return NULL; PyErr_Clear(); } else if ( !PyString_Check( klassname ) ) { Py_DECREF( klassname ); klassname = NULL; } else sklassname = PyString_AS_STRING( klassname ); } if ( self == NULL ) result = PyString_FromFormat( "", sklassname, sfuncname ); else { /* fixme: Shouldn't use repr() here! */ PyObject * selfrepr = PyObject_Repr( self ); if ( selfrepr == NULL ) goto fail; if ( !PyString_Check( selfrepr ) ) { Py_DECREF( selfrepr ); goto fail; } result = PyString_FromFormat( "", sklassname, sfuncname, PyString_AS_STRING( selfrepr ) ); Py_DECREF( selfrepr ); } fail: Py_XDECREF( funcname ); Py_XDECREF( klassname ); return result; } /*----------------------------------------------------------------------------- | Computes the hash of a trait method: +----------------------------------------------------------------------------*/ static long trait_method_hash ( trait_method_object * a ) { long x, y; if ( a->tm_self == NULL ) x = PyObject_Hash( Py_None ); else x = PyObject_Hash( a->tm_self ); if ( x == -1 ) return -1; y = PyObject_Hash( a->tm_func ); if ( y == -1 ) return -1; return x ^ y; } /*----------------------------------------------------------------------------- | Garbage collector traversal method: +----------------------------------------------------------------------------*/ static int trait_method_traverse ( trait_method_object * tm, visitproc visit, void * arg ) { Py_VISIT( tm->tm_func ); Py_VISIT( tm->tm_self ); Py_VISIT( tm->tm_traits ); Py_VISIT( tm->tm_class ); return 0; } /*----------------------------------------------------------------------------- | Garbage collector object clearing method: +----------------------------------------------------------------------------*/ static int trait_method_clear ( trait_method_object * tm ) { Py_CLEAR( tm->tm_func ); Py_CLEAR( tm->tm_self ); Py_CLEAR( tm->tm_traits ); Py_CLEAR( tm->tm_class ); return 0; } /*----------------------------------------------------------------------------- | Returns the class name of the class: +----------------------------------------------------------------------------*/ static void getclassname ( PyObject * class, char * buf, int bufsize ) { PyObject * name; assert( bufsize > 1 ); strcpy( buf, "?" ); /* Default outcome */ if ( class == NULL ) return; name = PyObject_GetAttrString( class, "__name__" ); if ( name == NULL ) { /* This function cannot return an exception: */ PyErr_Clear(); return; } if ( PyString_Check( name ) ) { strncpy( buf, PyString_AS_STRING( name ), bufsize ); buf[ bufsize - 1 ] = '\0'; } Py_DECREF( name ); } /*----------------------------------------------------------------------------- | Returns the class name of an instance: +----------------------------------------------------------------------------*/ static void getinstclassname ( PyObject * inst, char * buf, int bufsize ) { PyObject *class; if ( inst == NULL ) { assert( (bufsize > 0) && ((size_t) bufsize > strlen( "nothing" )) ); strcpy( buf, "nothing" ); return; } class = PyObject_GetAttrString( inst, "__class__" ); if ( class == NULL ) { /* This function cannot return an exception */ PyErr_Clear(); class = (PyObject *)(inst->ob_type); Py_INCREF( class ); } getclassname( class, buf, bufsize ); Py_XDECREF( class ); } /*----------------------------------------------------------------------------- | Calls the trait methods and type checks the arguments and result: +----------------------------------------------------------------------------*/ static PyObject * trait_method_call ( PyObject * meth, PyObject * arg, PyObject * kw ) { PyObject * class, * result, * self, * new_arg, * func, * value = NULL, * traits, * valid_result, * name = NULL, * dv, * tkw, * tuple; trait_object * trait; int from, to, to_args, traits_len, ntraits, ti; int nargs = PyTuple_GET_SIZE( arg ); /* Determine if this is an 'unbound' method call: */ if ( (self = trait_method_GET_SELF( meth )) == NULL ) { char clsbuf[256]; char instbuf[256]; int ok; /* Unbound methods must be called with an instance of the class (or a derived class) as first argument: */ from = 1; class = trait_method_GET_CLASS( meth ); if (class == NULL) { PyErr_Format(PyExc_TypeError, "unable to determine the class for the method %s", PyString_AS_STRING(trait_method_GET_NAME(meth))); return NULL; } if ( nargs >= 1 ) { self = PyTuple_GET_ITEM( arg, 0 ); assert( self != NULL ); ok = PyObject_IsInstance( self, class ); if ( ok > 0 ) { to_args = nargs; goto build_args; } else if ( ok < 0 ) return NULL; } func = trait_method_GET_FUNCTION( meth ); getclassname( class, clsbuf, sizeof( clsbuf ) ); getinstclassname( self, instbuf, sizeof( instbuf ) ); PyErr_Format( PyExc_TypeError, "unbound method %s%s must be called with " "%s instance as first argument " "(got %s%s instead)", PyString_AS_STRING( trait_method_GET_NAME( meth ) ), PyEval_GetFuncDesc( func ), clsbuf, instbuf, (self == NULL)? "" : " instance" ); return NULL; } from = 0; to_args = nargs + 1; build_args: /* Build the argument list, type checking all arguments as needed: */ traits = trait_method_GET_TRAITS( meth ); traits_len = PyTuple_GET_SIZE( traits ); ntraits = traits_len >> 1; if ( to_args > ntraits ) return too_may_args_error( trait_method_GET_NAME( meth ), ntraits, to_args ); new_arg = PyTuple_New( ntraits ); if ( new_arg == NULL ) return NULL; Py_INCREF( self ); PyTuple_SET_ITEM( new_arg, 0, self ); for ( to = 1, ti = 3; from < nargs; to++, from++, ti += 2 ) { value = PyTuple_GET_ITEM( arg, from ); assert( value != NULL ); name = PyTuple_GET_ITEM( traits, ti ); trait = (trait_object *) PyTuple_GET_ITEM( traits, ti + 1 ); if ( kw != NULL ) { if ( PyDict_GetItem( kw, name ) != NULL ) { Py_DECREF( new_arg ); return dup_argument_error( trait, meth, from + 1, self, name ); } } if ( trait->validate == NULL ) { Py_INCREF( value ); PyTuple_SET_ITEM( new_arg, to, value ); continue; } value = trait->validate( trait, (has_traits_object *) self, name, value ); if ( value != NULL ) { PyTuple_SET_ITEM( new_arg, to, value ); continue; } Py_DECREF( new_arg ); return argument_error( trait, meth, from + 1, self, name, PyTuple_GET_ITEM( arg, from ) ); } /* Substitute default values for any missing arguments: */ for ( ; ti < traits_len; to++, from++, ti += 2 ) { trait = (trait_object *) PyTuple_GET_ITEM( traits, ti + 1 ); if ( kw != NULL ) { name = PyTuple_GET_ITEM( traits, ti ); value = PyDict_GetItem( kw, name ); if ( value != NULL ) { if ( trait->validate != NULL ) { valid_result = trait->validate( trait, (has_traits_object *) self, name, value ); if ( valid_result == NULL ) { Py_DECREF( new_arg ); return keyword_argument_error( trait, meth, self, name, value ); } value = valid_result; } else Py_INCREF( value ); PyTuple_SET_ITEM( new_arg, to, value ); if ( PyDict_DelItem( kw, name ) < 0 ) { Py_DECREF( new_arg ); return NULL; } continue; } } switch ( trait->default_value_type ) { case 0: value = trait->default_value; Py_INCREF( value ); break; case 1: Py_DECREF( new_arg ); return missing_argument_error( trait, meth, from + 1, self, PyTuple_GET_ITEM( traits, ti ) ); case 2: value = (PyObject *) self; Py_INCREF( value ); break; case 3: case 5: value = PySequence_List( trait->default_value ); if ( value == NULL ) { Py_DECREF( new_arg ); return NULL; } break; case 4: case 6: value = PyDict_Copy( trait->default_value ); if ( value == NULL ) { Py_DECREF( new_arg ); return NULL; } break; case 7: dv = trait->default_value; tkw = PyTuple_GET_ITEM( dv, 2 ); if ( tkw == Py_None ) tkw = NULL; value = PyObject_Call( PyTuple_GET_ITEM( dv, 0 ), PyTuple_GET_ITEM( dv, 1 ), tkw ); if ( value == NULL ) { Py_DECREF( new_arg ); return NULL; } break; case 8: if ( (tuple = PyTuple_New( 1 )) == NULL ) { Py_DECREF( new_arg ); return NULL; } PyTuple_SET_ITEM( tuple, 0, self ); Py_INCREF( self ); Py_INCREF( tuple ); value = PyObject_Call( trait->default_value, tuple, NULL ); Py_DECREF( tuple ); if ( value == NULL ) { Py_DECREF( new_arg ); return NULL; } if ( trait->validate != NULL ) { result = trait->validate( trait, (has_traits_object *) self, name, value ); Py_DECREF( value ); if ( result == NULL ) { Py_DECREF( new_arg ); return NULL; } value = result; } break; } PyTuple_SET_ITEM( new_arg, to, value ); } /* Invoke the method: */ result = PyObject_Call( trait_method_GET_FUNCTION( meth ), new_arg, kw ); Py_DECREF( new_arg ); /* Type check the method result (if valid and it was requested): */ if ( result != NULL ) { trait = (trait_object *) PyTuple_GET_ITEM( traits, 0 ); if ( trait->validate != NULL ) { valid_result = trait->validate( trait, (has_traits_object *) self, Py_None, result ); if ( valid_result != NULL ) { Py_DECREF( result ); return valid_result; } invalid_result_error( trait, meth, self, result ); Py_DECREF( result ); return NULL; } } /* Finally, return the result: */ return result; } /*----------------------------------------------------------------------------- | 'get' handler that converts from 'unbound' to 'bound' method: +----------------------------------------------------------------------------*/ static PyObject * trait_method_descr_get ( PyObject * meth, PyObject * obj, PyObject * cls ) { return create_trait_method( trait_method_GET_NAME( meth ), trait_method_GET_FUNCTION( meth ), (obj == Py_None)? NULL: obj, trait_method_GET_TRAITS( meth ), cls ); } /*----------------------------------------------------------------------------- | Descriptors for trait method attributes: +----------------------------------------------------------------------------*/ static PyMemberDef trait_method_memberlist[] = { { "tm_name", T_OBJECT, OFF( tm_name ), READONLY | RESTRICTED, "the name of the method" }, { "tm_func", T_OBJECT, OFF( tm_func ), READONLY | RESTRICTED, "the function (or other callable) implementing a method" }, { "tm_self", T_OBJECT, OFF( tm_self ), READONLY | RESTRICTED, "the instance to which a method is bound; None for unbound methods" }, { "tm_traits", T_OBJECT, OFF( tm_traits ), READONLY | RESTRICTED, "the traits associated with a method" }, { "tm_class", T_OBJECT, OFF( tm_class ), READONLY | RESTRICTED, "the class associated with a method" }, { NULL } /* Sentinel */ }; /*----------------------------------------------------------------------------- | 'CTraitMethod' __doc__ string: +----------------------------------------------------------------------------*/ PyDoc_STRVAR( trait_method_doc, "traitmethod(function, traits)\n\ \n\ Create a type checked instance method object."); /*----------------------------------------------------------------------------- | 'CTraitMethod' type definition: +----------------------------------------------------------------------------*/ static PyTypeObject trait_method_type = { PyObject_HEAD_INIT( DEFERRED_ADDRESS( &PyType_Type ) ) 0, "traitmethod", sizeof( trait_method_object ), 0, (destructor) trait_method_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ (cmpfunc) trait_method_compare, /* tp_compare */ (reprfunc) trait_method_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ (hashfunc) trait_method_hash, /* tp_hash */ trait_method_call, /* tp_call */ 0, /* tp_str */ (getattrofunc) trait_method_getattro, /* tp_getattro */ DEFERRED_ADDRESS( PyObject_GenericSetAttr ), /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ trait_method_doc, /* tp_doc */ (traverseproc) trait_method_traverse, /* tp_traverse */ (inquiry) trait_method_clear, /* tp_clear */ 0, /* tp_richcompare */ offsetof( trait_method_object, tm_weakreflist ), /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ trait_method_memberlist, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ trait_method_descr_get, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ trait_method_new, /* tp_new */ }; /*----------------------------------------------------------------------------- | Performs module and type initialization: +----------------------------------------------------------------------------*/ PyMODINIT_FUNC initctraits ( void ) { PyObject * tmp; /* Create the 'ctraits' module: */ PyObject * module = Py_InitModule3( "ctraits", ctraits_methods, ctraits__doc__ ); if ( module == NULL ) return; /* Create the 'CHasTraits' type: */ has_traits_type.tp_base = &PyBaseObject_Type; has_traits_type.tp_alloc = PyType_GenericAlloc; if ( PyType_Ready( &has_traits_type ) < 0 ) return; Py_INCREF( &has_traits_type ); if ( PyModule_AddObject( module, "CHasTraits", (PyObject *) &has_traits_type ) < 0 ) return; /* Create the 'CTrait' type: */ trait_type.tp_base = &PyBaseObject_Type; trait_type.tp_alloc = PyType_GenericAlloc; trait_type.tp_new = PyType_GenericNew; if ( PyType_Ready( &trait_type ) < 0 ) return; Py_INCREF( &trait_type ); if ( PyModule_AddObject( module, "cTrait", (PyObject *) &trait_type ) < 0 ) return; /* Create the 'CTraitMethod' type: */ trait_method_type.tp_base = &PyBaseObject_Type; trait_method_type.tp_setattro = PyObject_GenericSetAttr; if ( PyType_Ready( &trait_method_type ) < 0 ) return; Py_INCREF( &trait_method_type ); if ( PyModule_AddObject( module, "CTraitMethod", (PyObject *) &trait_method_type ) < 0 ) return; /* Create the 'HasTraitsMonitor' list: */ tmp = PyList_New( 0 ); Py_INCREF( tmp ); if ( PyModule_AddObject( module, "_HasTraits_monitors", (PyObject*) tmp) < 0 ) { return; } _HasTraits_monitors = tmp; /* Predefine a Python string == "__class_traits__": */ class_traits = PyString_FromString( "__class_traits__" ); /* Predefine a Python string == "__listener_traits__": */ listener_traits = PyString_FromString( "__listener_traits__" ); /* Predefine a Python string == "editor": */ editor_property = PyString_FromString( "editor" ); /* Predefine a Python string == "__prefix__": */ class_prefix = PyString_FromString( "__prefix__" ); /* Predefine a Python string == "trait_added": */ trait_added = PyString_FromString( "trait_added" ); /* Create an empty tuple: */ empty_tuple = PyTuple_New( 0 ); /* Create the 'is_callable' marker: */ is_callable = PyInt_FromLong( -1 ); } traits-4.1.0/traits/etsconfig/0000755000175100001440000000000011674463323017303 5ustar ischnellusers00000000000000traits-4.1.0/traits/etsconfig/tests/0000755000175100001440000000000011674463323020445 5ustar ischnellusers00000000000000traits-4.1.0/traits/etsconfig/tests/etsconfig_test_case.py0000644000175100001440000001221111674463323025027 0ustar ischnellusers00000000000000""" Tests the 'ETSConfig' configuration object. """ # Standard library imports. import os, time, unittest # Enthought library imports. from traits.etsconfig.api import ETSConfig class ETSConfigTestCase(unittest.TestCase): """ Tests the 'ETSConfig' configuration object. """ ########################################################################### # 'TestCase' interface. ########################################################################### #### public methods ####################################################### def setUp(self): """ Prepares the test fixture before each test method is called. """ return def tearDown(self): """ Called immediately after each test method has been called. """ return ########################################################################### # 'ETSConfigTestCase' interface. ########################################################################### #### public methods ####################################################### def test_application_data(self): """ application data """ dirname = ETSConfig.application_data self.assertEqual(os.path.exists(dirname), True) self.assertEqual(os.path.isdir(dirname), True) return def test_set_application_data(self): """ set application data """ old = ETSConfig.application_data ETSConfig.application_data = 'foo' self.assertEqual('foo', ETSConfig.application_data) ETSConfig.application_data = old self.assertEqual(old, ETSConfig.application_data) return def test_application_data_is_idempotent(self): """ application data is idempotent """ # Just do the previous test again! self.test_application_data() return def test_write_to_application_data_directory(self): """ write to application data directory """ ETSConfig.company = 'Blah' dirname = ETSConfig.application_data path = os.path.join(dirname, 'dummy.txt') data = str(time.time()) f = file(path, 'w') f.write(data) f.close() self.assertEqual(os.path.exists(path), True) f = file(path) result = f.read() f.close() os.remove(path) self.assertEqual(data, result) return def test_default_company(self): """ default company """ self.assertEqual(ETSConfig.company, 'Enthought') return def test_set_company(self): """ set company """ old = ETSConfig.company ETSConfig.company = 'foo' self.assertEqual('foo', ETSConfig.company) ETSConfig.company = old self.assertEqual(old, ETSConfig.company) return def _test_default_application_home(self): """ application home """ # This test is only valid when run with the 'main' at the end of this # file: "python app_dat_locator_test_case.py", in which case the # app_name will be the directory this file is in ('tests'). app_home = ETSConfig.application_home (dirname, app_name) = os.path.split(app_home) self.assertEqual(dirname, ETSConfig.application_data) self.assertEqual(app_name, 'tests') def test_user_data(self): """ user data """ dirname = ETSConfig.user_data self.assertEqual(os.path.exists(dirname), True) self.assertEqual(os.path.isdir(dirname), True) return def test_set_user_data(self): """ set user data """ old = ETSConfig.user_data ETSConfig.user_data = 'foo' self.assertEqual('foo', ETSConfig.user_data) ETSConfig.user_data = old self.assertEqual(old, ETSConfig.user_data) return def test_user_data_is_idempotent(self): """ user data is idempotent """ # Just do the previous test again! self.test_user_data() return def test_write_to_user_data_directory(self): """ write to user data directory """ ETSConfig.company = 'Blah' dirname = ETSConfig.user_data path = os.path.join(dirname, 'dummy.txt') data = str(time.time()) f = file(path, 'w') f.write(data) f.close() self.assertEqual(os.path.exists(path), True) f = file(path) result = f.read() f.close() os.remove(path) self.assertEqual(data, result) return # For running as an individual set of tests. if __name__ == '__main__': # Add the non-default test of application_home...non-default because it must # be run using this module as a script to be valid. suite = unittest.TestLoader().loadTestsFromTestCase(ETSConfigTestCase) suite.addTest(ETSConfigTestCase('_test_default_application_home')) unittest.TextTestRunner(verbosity=2).run(suite) #### EOF ###################################################################### traits-4.1.0/traits/etsconfig/api.py0000644000175100001440000000004011674463323020420 0ustar ischnellusers00000000000000from etsconfig import ETSConfig traits-4.1.0/traits/etsconfig/etsconfig.py0000644000175100001440000003526511674463323021651 0ustar ischnellusers00000000000000""" Enthought Tool Suite configuration information. """ # Standard library imports. import sys import os from os import path class ETSConfig(object): """ Enthought Tool Suite configuration information. This class should not use ANY other package in the tool suite so that it will always work no matter which other packages are present. """ ########################################################################### # 'object' interface. ########################################################################### #### operator methods ##################################################### def __init__(self): """ Constructor. Note that this constructor can only ever be called from within this module, since we don't expose the class. """ # Shadow attributes for properties. self._application_data = None self._application_home = None self._company = None self._toolkit = None self._kiva_backend = None self._user_data = None return ########################################################################### # 'ETSConfig' interface. ########################################################################### #### properties ########################################################### def get_application_data(self, create=False): """ Return the application data directory path. **Parameters** create: create the corresponding directory or not **Notes** This is a directory that applications and packages can safely write non-user accessible data to i.e. configuration information, preferences etc. Do not put anything in here that the user might want to navigate to e.g. projects, user data files etc. The actual location differs between operating systems. """ if self._application_data is None: self._application_data = \ self._initialize_application_data(create=create) return self._application_data def _get_application_data(self): """ Property getter, see get_application_data's docstring. """ return self.get_application_data(create=True) def _set_application_data(self, application_data): """ Property setter. """ self._application_data = application_data return def get_application_home(self, create=False): """ Return the application home directory path. **Parameters** create: create the corresponding directory or not **Notes** This is a directory named after the current, running application that imported this module that applications and packages can safely write non-user accessible data to i.e. configuration information, preferences etc. It is a sub-directory of self.application_data, named after the directory that contains the "main" python script that started the process. For example, if application foo is started with a script named "run.py" in a directory named "foo", then the application home would be: /foo, regardless of if it was launched with "python /run.py" or "cd ; python run.py" This is useful for library modules used in apps that need to store state, preferences, etc. for the specific app only, and not for all apps which use that library module. If the library module uses ETSConfig.application_home, they can store prefs for the app all in one place and do not need to know the details of where each app might reside. Do not put anything in here that the user might want to navigate to e.g. projects, user home files etc. The actual location differs between operating systems. """ if self._application_home is None: self._application_home = path.join( self.get_application_data(create=create), self._get_application_dirname()) return self._application_home application_data = property(_get_application_data, _set_application_data) def _get_application_home(self): """ Property getter, see get_application_home's docstring. """ return self.get_application_home(create=True) def _set_application_home(self, application_home): """ Property setter. """ self._application_home = application_home return application_home = property(_get_application_home, _set_application_home) def _get_company(self): """ Property getter. """ if self._company is None: self._company = self._initialize_company() return self._company def _set_company(self, company): """ Property setter for the company name. """ self._company = company return company = property(_get_company, _set_company) def _get_toolkit(self): """ Property getter for the GUI toolkit. The value returned is, in order of preference: the value set by the application; the value passed on the command line using the '-toolkit' option; the value specified by the 'ETS_TOOLKIT' environment variable; otherwise the empty string. """ if self._toolkit is None: self._toolkit = self._initialize_toolkit() return self._toolkit.split('.')[0] def _set_toolkit(self, toolkit): """ Property setter for the GUI toolkit. The toolkit can be set more than once, but only if it is the same one each time. An application that is written for a particular toolkit can explicitly set it before any other module that gets the value is imported. """ if self._toolkit and self._toolkit != toolkit: raise ValueError, "cannot set toolkit to %s because it has "\ "already been set to %s" % (toolkit, self._toolkit) self._toolkit = toolkit return toolkit = property(_get_toolkit, _set_toolkit) def _get_enable_toolkit(self): """ Deprecated: This property is no longer used. Property getter for the Enable backend. The value returned is, in order of preference: the value set by the application; the value passed on the command line using the '-toolkit' option; the value specified by the 'ENABLE_TOOLKIT' environment variable; otherwise the empty string. """ from warnings import warn warn('Use of the enable_toolkit attribute is deprecated.') return self.toolkit def _set_enable_toolkit(self, toolkit): """ Deprecated. Property setter for the Enable toolkit. The toolkit can be set more than once, but only if it is the same one each time. An application that is written for a particular toolkit can explicitly set it before any other module that gets the value is imported. """ from warnings import warn warn('Use of the enable_toolkit attribute is deprecated.') return enable_toolkit = property(_get_enable_toolkit, _set_enable_toolkit) def _get_kiva_backend(self): """ Property getter for the Kiva backend. The value returned is dependent on the value of the toolkit property. If toolkit specifies a kiva backend using the extended syntax: [.] then the value of the property will be whatever was specified. Otherwise the value will be a reasonable default for the given enable backend. """ if self._toolkit is None: raise AttributeError, "The kiva_backend attribute is dependent on toolkit, which has not been set." if self._kiva_backend is None: try: self._kiva_backend = self._toolkit.split('.')[1] except IndexError: # Pick a reasonable default based on the toolkit if self.toolkit == "wx": self._kiva_backend = "quartz" if sys.platform == "darwin" else "image" elif self.toolkit == "qt4": self._kiva_backend = "image" elif self.toolkit == "pyglet": self._kiva_backend = "gl" else: self._kiva_backend = "image" return self._kiva_backend kiva_backend = property(_get_kiva_backend) def _get_user_data(self): """ Property getter. This is a directory that users can safely write user accessible data to i.e. user-defined functions, edited functions, etc. The actual location differs between operating systems. """ if self._user_data is None: self._user_data = self._initialize_user_data() return self._user_data def _set_user_data(self, user_data): """ Property setter. """ self._user_data = user_data return user_data = property(_get_user_data, _set_user_data) #### private methods ##################################################### # fixme: In future, these methods could allow the properties to be set # via the (as yet non-existent) preference/configuration mechanism. This # would allow configuration via (in order of precedence):- # # - a configuration file # - environment variables # - the command line def _get_application_dirname(self): """ Return the name of the directory (not a path) that the "main" Python script which started this process resides in, or "" if it could not be determined or is not appropriate. For example, if the script that started the current process was named "run.py" in a directory named "foo", and was launched with "python run.py", the name "foo" would be returned (this assumes the directory name is the name of the app, which seems to be as good of an assumption as any). """ dirname = "" main_mod = sys.modules.get('__main__', None) if main_mod is not None: if hasattr(main_mod, '__file__'): main_mod_file = path.abspath(main_mod.__file__) dirname = path.basename(path.dirname(main_mod_file)) return dirname def _initialize_application_data(self, create=True): """ Initializes the (default) application data directory. """ if sys.platform == 'win32': environment_variable = 'APPDATA' directory_name = self.company else: environment_variable = 'HOME' directory_name = '.' + self.company.lower() # Lookup the environment variable. parent_directory = os.environ.get(environment_variable, None) if parent_directory is None or parent_directory == '/root': import tempfile from warnings import warn parent_directory = tempfile.gettempdir() user = os.environ.get('USER', None) if user is not None: directory_name += "_%s" % user warn('Environment variable "%s" not set, setting home directory to %s' % \ (environment_variable, parent_directory)) application_data = os.path.join(parent_directory, directory_name) if create: # If a file already exists with this name then make sure that it is # a directory! if os.path.exists(application_data): if not os.path.isdir(application_data): raise ValueError('File "%s" already exists' % application_data) # Otherwise, create the directory. else: os.makedirs(application_data) return application_data def _initialize_company(self): """ Initializes the (default) company. """ return 'Enthought' def _initialize_toolkit(self): """ Initializes the toolkit. """ # We handle the command line option even though it doesn't have the # highest precedence because we always want to remove it from the # command line. if '-toolkit' in sys.argv: opt_idx = sys.argv.index('-toolkit') try: opt_toolkit = sys.argv[opt_idx + 1] except IndexError: raise ValueError, "the -toolkit command line argument must be followed by a toolkit name" # Remove the option. del sys.argv[opt_idx:opt_idx + 1] else: opt_toolkit = None if self._toolkit is not None: toolkit = self._toolkit elif opt_toolkit is not None: toolkit = opt_toolkit else: toolkit = os.environ.get('ETS_TOOLKIT', '') return toolkit def _initialize_user_data(self): """ Initializes the (default) user data directory. """ # We check what the os.path.expanduser returns parent_directory = os.path.expanduser('~') directory_name = self.company if sys.platform == 'win32': # Check if the usr_dir is C:\\John Doe\\Documents and Settings. # If yes, then we should modify the usr_dir to be 'My Documents'. # If no, then the user must have modified the os.environ # variables and the directory chosen is a desirable one. desired_dir = os.path.join(parent_directory, 'My Documents') if os.path.exists(desired_dir): parent_directory = desired_dir else: directory_name = directory_name.lower() # The final directory. usr_dir = os.path.join(parent_directory, directory_name) # If a file already exists with this name then make sure that it is # a directory! if os.path.exists(usr_dir): if not os.path.isdir(usr_dir): raise ValueError('File "%s" already exists' % usr_dir) # Otherwise, create the directory. else: os.makedirs(usr_dir) return usr_dir # We very purposefully only have one object and do not export the class. We # could have just made everything class methods, but that always seems a bit # gorpy, especially with properties etc. ETSConfig = ETSConfig() #### EOF ###################################################################### traits-4.1.0/traits/etsconfig/__init__.py0000644000175100001440000000053411674463323021416 0ustar ischnellusers00000000000000#----------------------------------------------------------------------------- # # Copyright (c) 2007 by Enthought, Inc. # All rights reserved. # #----------------------------------------------------------------------------- """ Supports sharing settings across projects or programs on the same system. Part of the EnthoughtBase project. """ traits-4.1.0/traits/adapter.py0000644000175100001440000002047011674463323017317 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------- # # Copyright (c) 2007, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in /LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # # Author: Martin Chilvers # Date: 07/18/2007 # #------------------------------------------------------------------------------- """ An extension to PyProtocols to simplify the declaration of adapters. """ #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from __future__ import absolute_import # Standard library imports: import weakref # Traits imports: from .has_traits import HasTraits from .trait_types import Any, Bool, Expression # PyProtocols imports: from .protocols.api import addClassAdvisor, declareAdapter, declareImplementation, Protocol #------------------------------------------------------------------------------- # 'Adapter' class: #------------------------------------------------------------------------------- class Adapter ( HasTraits ): """ The base class for all traits adapters. In Traits, an *adapter* is a special type of class whose role is to transform some type of object which does not implement a specific interface, or set of interfaces, into one that does. This class is provided as a convenience. If you subclass this class, the only things you need to add to the subclass definition are: * An implements() function call declaring which interfaces the adapter class implements on behalf of the object is is adapting. * A declaration for the **adaptee** trait, usually as an Instance of a particular class. * The actual implementations of the interfaces declared in the implements() call. Usually the implementation code is written in terms of the **adaptee** trait. """ #-- Trait Definitions ------------------------------------------------------ # The object that is being adapted. adaptee = Any #-- Constructor ------------------------------------------------------------ def __init__ ( self, adaptee ): """ Constructor. We have to declare an explicit constructor because adapters are created by PyProtocols itself, which knows nothing about traits. """ super( Adapter, self ).__init__() self.adaptee = adaptee #------------------------------------------------------------------------------- # 'DefaultAdapterFactory' class: #------------------------------------------------------------------------------- class DefaultAdapterFactory ( HasTraits ): """ An adapter factory for producing cached or categorized adapters. """ #-- 'DefaultAdapterFactory' Interface -------------------------------------- # The adapter class that this factory creates instances of klass = Any # Does the factory generate cached adapters? # If an adapter is cached then the factory will produce at most one # adapter per instance. cached = Bool( False ) # An expression that is used to select which instances of a particular # type can be adapted by this factory. # # The expression is evaluated in a namespace that contains a single name # 'adaptee', which is bound to the object that this factory is attempting # to adapt (e.g. 'adaptee.is_folder'). when = Expression #-- Private Interface ------------------------------------------------------ # If this is a cached adapter factory, then this mapping will contain # the adapters keyed by weak references to the adapted objects. _adapters = Any #------------------------------------------------------------------------------- # 'IAdapterFactory' interface: #------------------------------------------------------------------------------- def __call__ ( self, object ): """ Creates an adapter for the specified object. Returns **None** if the factory cannot perform the required adaptation. """ namespace = { 'adaptee': object } if eval( self.when_, namespace, namespace ): if self.cached: adapter = self._adapters.get( object ) if adapter is None: self._adapters[ object ] = adapter = self.klass( object ) return adapter return self.klass( object ) return None #--------------------------------------------------------------------------- # Private interface: #--------------------------------------------------------------------------- def __adapters_default ( self ): """ Trait initializer. """ return weakref.WeakKeyDictionary() #------------------------------------------------------------------------------- # 'adapts' function: #------------------------------------------------------------------------------- def adapts ( from_, to, extra = None, factory = None, cached = False, when = '' ): """ A class advisor for declaring adapters. Parameters ---------- ``from_`` : type or interface What the adapter adapts *from*, or a list of such types or interfaces (the '_' suffix is used because 'from' is a Python keyword). to : type or interface What the adapter adapts *to*, or a list of such types or interfaces. factory : callable An (optional) factory for actually creating the adapters. This is any callable that takes a single argument which is the object to be adapted. The factory should return an adapter if it can perform the adaptation and **None** if it cannot. The following arguments are ignored if *factory* is specified: cached : Boolean Should the adapters be cached? If an adapter is cached, then the factory will produce at most one adapter per instance. when : A Python expression Selects which instances of a particular type can be adapted by this factory. The expression is evaluated in a namespace that contains a single name *adaptee*, which is bound to the object to be adapted (e.g., 'adaptee.is_folder'). """ if extra is not None: adapter, from_, to = from_, to, extra else: adapter = None def callback ( klass ): """ Called when the class has been created. """ # What the adapter adapts from: if type( from_ ) is not list: for_items = [ from_ ] else: for_items = from_ # The things we adapt from have to be split into two lists for # PyProtocols, one containing Python types (i.e. classes) and one # containing protocols (i.e. interfaces): for_types = [] for_protocols = [] for item in for_items: if isinstance( item, Protocol ): for_protocols.append( item ) else: for_types.append( item ) # What the adapter adapts to: if type( to ) is not list: provides = [ to ] else: provides = to # Tell PyProtocols that the adapter class implements the protocols that # it adapts to: declareImplementation( klass, instancesProvide = provides ) # If a factory was specified then use it: if factory is not None: f = factory # If the adapter is cached or has a 'when' expression then create a # default factory: elif cached or (when != ''): f = DefaultAdapterFactory( klass = klass, cached = cached, when = when or 'True' ) # Otherwise, just use the adapter class itself: else: f = klass # Tell PyProtocols about the factory: declareAdapter( f, provides, forProtocols = for_protocols, forTypes = for_types ) return klass if adapter is not None: callback( adapter ) else: addClassAdvisor( callback ) traits-4.1.0/traits/trait_value.py0000644000175100001440000001742711674463323020226 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # # Copyright (c) 2008, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in enthought/LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # # Author: David C. Morrill # Original Date: 04/01/2008 # #------------------------------------------------------------------------------ """ Defines the TraitValue class, used for creating special, dynamic trait values. """ #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from __future__ import absolute_import from .trait_base import Undefined from .traits import CTrait from .has_traits import HasTraits, HasPrivateTraits from .trait_errors import TraitError from .trait_types import Tuple, Dict, Any, Str, Instance, Event, Callable from .trait_handlers import TraitType, _read_only, _write_only, _arg_count #------------------------------------------------------------------------------- # 'BaseTraitValue' class: #------------------------------------------------------------------------------- class BaseTraitValue ( HasPrivateTraits ): # Subclasses can define this trait as a property: # value = Property #-- Public Methods --------------------------------------------------------- def as_ctrait ( self, original_trait ): """ Returns the low-level C-based trait for this TraitValue. """ notifiers = original_trait._notifiers( 0 ) if self._ctrait is not None: if (notifiers is None) or (len( notifiers ) == 0): return self._ctrait trait = CTrait( 0 ) trait.clone( self._ctrait ) else: trait = self._as_ctrait( original_trait ) if ((trait is not None) and (notifiers is not None) and (len( notifiers ) > 0)): trait._notifiers( 1 ).extend( notifiers ) return trait #-- Private Methods -------------------------------------------------------- def _as_ctrait ( self, original_trait ): """ Returns the low-level C-based trait for this TraitValue. """ value_trait = self.trait( 'value' ) if value_trait is None: return None if value_trait.type != 'property': raise TraitError( "Invalid TraitValue specified." ) metadata = { 'type': 'property', '_trait_value': self } getter, setter, validate = value_trait.property() read_only = (getter is _read_only) if not read_only: getter = self._getter metadata[ 'transient' ] = True if setter is not _write_only: if read_only: setter = self._read_only_setter else: setter = self._setter metadata[ 'transient' ] = True return self._property_trait( getter, setter, validate, metadata ) def _property_trait ( self, getter, setter, validate, metadata ): """ Returns a properly constructed 'property' trait. """ n = 0 if validate is not None: n = _arg_count( validate ) trait = CTrait( 4 ) trait.property( getter, _arg_count( getter ), setter, _arg_count( setter ), validate, n ) trait.value_allowed( True ) trait.value_property( True ) trait.__dict__ = metadata return trait def _getter ( self, object, name ): return self.value def _setter ( self, object, name, value ): old_value = self.value self.value = value new_value = self.value if new_value != old_value: object.trait_property_changed( name, old_value, new_value ) def _read_only_setter ( self, object, name, value ): self.value = value object.trait_property_changed( name, Undefined, value ) #------------------------------------------------------------------------------- # 'TraitValue' class: #------------------------------------------------------------------------------- class TraitValue ( BaseTraitValue ): #: The callable used to define a default value: default = Callable #: The positional arguments to pass to the callable default value: args = Tuple #: The keyword arguments to pass to the callable default value: kw = Dict #: The trait to use as the new trait type: type = Any #: The object to delegate the new value to: delegate = Instance( HasTraits ) #: The name of the trait on the delegate object to get the new value from: name = Str #-- Private Methods -------------------------------------------------------- def _as_ctrait ( self, original_trait ): """ Returns the low-level C-based trait for this TraitValue. """ if self.default is not None: trait = CTrait( 0 ) trait.clone( original_trait ) if original_trait.__dict__ is not None: trait.__dict__ = original_trait.__dict__.copy() trait.default_value( 7, ( self.default, self.args, self.kw ) ) elif self.type is not None: type = self.type try: rc = issubclass( type, TraitType ) except: rc = False if rc: type = type( *self.args, **self.kw ) if not isinstance( type, TraitType ): raise TraitError( ("The 'type' attribute of a TraitValue " "instance must be a TraitType instance or subclass, but a " "value of %s was specified.") % self.trait ) self._ctrait = trait = type.as_ctrait() trait.value_allowed( True ) elif self.delegate is None: return None else: if self.name == '': raise TraitError( "You must specify a non-empty string " "value for the 'name' attribute when using the " "'delegate' trait of a TraitValue instance." ) metadata = { 'type': 'property', '_trait_value': self, 'transient': True } getter = self._delegate_getter setter = self._delegate_setter validate = None self.add_trait( 'value', Event() ) self.delegate.on_trait_change( self._delegate_modified, self.name ) trait = self._property_trait( getter, setter, validate, metadata ) return trait def _delegate_getter ( self, object, name ): return getattr( self.delegate, self.name ) def _delegate_setter ( self, object, name, value ): setattr( self.delegate, self.name, value ) #-- Traits Event Handlers -------------------------------------------------- def _delegate_modified ( self ): self.value = True #-- Helper Function Definitions ------------------------------------------------ def SyncValue ( delegate, name ): return TraitValue( delegate = delegate, name = name ) def TypeValue ( type ): return TraitValue( type = type ) def DefaultValue ( default, args = (), kw = {} ): return TraitValue( default = default, args = args, kw = kw ) #------------------------------------------------------------------------------- # Tell the C-based traits module about the 'BaseTraitValue' class: #------------------------------------------------------------------------------- from . import ctraits ctraits._value_class( BaseTraitValue ) traits-4.1.0/traits/README.txt0000644000175100001440000000316111674463323017021 0ustar ischnellusers00000000000000Introduction ------------ 'Traits' is a Python package for creating 'manifestly'-typed Python attributes. Installation ------------ The Traits package is installed using the standard Python 'distutils' package. Enter the following command in the 'traits-1.0' directory: python setup.py install This will perform a normal install of the Traits package into your Python installation. Refer to the Python 'distutils' documentation for more installation options. Download -------- The Traits package is available as part of the Enthought Tool Suite (ETS), available from: http://code.enthought.com/ets/ To install ETS using Enthought's egg-based 'Enstaller', download and run: http://code.enthought.com/enstaller/run_enstaller.py License ------- The 'traits' package is available under a BSD style license. Contact ------- If you encounter any problems using the 'traits' package, or have any comments or suggestions about the package, please contact the primary author: David C. Morrill dmorrill@enthought.com For discussion of the Traits package, as well as other tools in the Enthought Tool Suite, use the enthought-dev mailing list: https://mail.enthought.com/mailman/listinfo/enthought-dev http://dir.gmane.org/gmane.comp.python.enthought.devel Prerequisites ------------- The base Traits package should work on any platform supporting Python >= 2.4 The user interface capabilities of the traits package require additional Python packages to be installed. The UI toolkit backend that is actively maintained is wxPython. To use it, install a version >= 2.4 (available from: http://www.wxpython.org). traits-4.1.0/traits/traits.py0000644000175100001440000013432111674463323017206 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # # Copyright (c) 2005, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in enthought/LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # # Author: David C. Morrill # Original Date: 06/21/2002 # # Rewritten as a C-based type extension: 06/21/2004 # #------------------------------------------------------------------------------ """ Defines the 'core' traits for the Traits package. A trait is a type definition that can be used for normal Python object attributes, giving the attributes some additional characteristics: Initialization: Traits have predefined values that do not need to be explicitly initialized in the class constructor or elsewhere. Validation: Trait attributes have flexible, type-checked values. Delegation: Trait attributes' values can be delegated to other objects. Notification: Trait attributes can automatically notify interested parties when their values change. Visualization: Trait attributes can automatically construct (automatic or programmer-defined) user interfaces that allow their values to be edited or displayed) .. note:: 'trait' is a synonym for 'property', but is used instead of the word 'property' to differentiate it from the Python language 'property' feature. """ #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from __future__ import absolute_import from types import (NoneType, IntType, LongType, FloatType, ComplexType, StringType, UnicodeType, ListType, TupleType, DictType, FunctionType, ClassType, MethodType, InstanceType, TypeType) from . import trait_handlers from .ctraits import cTrait from .trait_errors import TraitError from .trait_base import (SequenceTypes, Self, Undefined, Missing, TypeTypes, add_article, enumerate, BooleanType) from .trait_handlers import (TraitHandler, TraitInstance, TraitFunction, TraitCoerceType, TraitCastType, TraitEnum, TraitCompound, TraitMap, TraitString, ThisClass, TraitType, _arg_count, _read_only, _write_only, _undefined_get, _undefined_set) #------------------------------------------------------------------------------- # Constants: #------------------------------------------------------------------------------- # Mapping from 'ctrait' default value types to a string representation: KindMap = { 0: 'value', 1: 'value', 2: 'self', 3: 'list', 4: 'dict', 5: 'list', 6: 'dict', 7: 'factory', 8: 'method' } #------------------------------------------------------------------------------- # Editor factory functions: #------------------------------------------------------------------------------- PasswordEditor = None MultilineTextEditor = None SourceCodeEditor = None HTMLTextEditor = None PythonShellEditor = None DateEditor = None TimeEditor = None def password_editor ( auto_set=True, enter_set=False ): """ Factory function that returns an editor for passwords. """ global PasswordEditor if PasswordEditor is None: from traitsui.api import TextEditor PasswordEditor = TextEditor( password = True , auto_set = auto_set, enter_set = enter_set ) return PasswordEditor def multi_line_text_editor ( auto_set=True, enter_set=False ): """ Factory function that returns a text editor for multi-line strings. """ global MultilineTextEditor if MultilineTextEditor is None: from traitsui.api import TextEditor MultilineTextEditor = TextEditor( multi_line = True, auto_set = auto_set, enter_set = enter_set ) return MultilineTextEditor def code_editor ( ): """ Factory function that returns an editor that treats a multi-line string as source code. """ global SourceCodeEditor if SourceCodeEditor is None: from traitsui.api import CodeEditor SourceCodeEditor = CodeEditor() return SourceCodeEditor def html_editor ( ): """ Factory function for an "editor" that displays a multi-line string as interpreted HTML. """ global HTMLTextEditor if HTMLTextEditor is None: from traitsui.api import HTMLEditor HTMLTextEditor = HTMLEditor() return HTMLTextEditor def shell_editor ( ): """ Factory function that returns a Python shell for editing Python values. """ global PythonShellEditor if PythonShellEditor is None: from traitsui.api import ShellEditor PythonShellEditor = ShellEditor() return PythonShellEditor def time_editor ( ): """ Factory function that returns a Time editor for editing Time values. """ global TimeEditor if TimeEditor is None: from traitsui.api import TimeEditor TimeEditor = TimeEditor() return TimeEditor def date_editor ( ): """ Factory function that returns a Date editor for editing Date values. """ global DateEditor if DateEditor is None: from traitsui.api import DateEditor DateEditor = DateEditor() return DateEditor #------------------------------------------------------------------------------- # 'CTrait' class (extends the underlying cTrait c-based type): #------------------------------------------------------------------------------- class CTrait ( cTrait ): """ Extends the underlying C-based cTrait type. """ #--------------------------------------------------------------------------- # Allows a derivative trait to be defined from this one: #--------------------------------------------------------------------------- def __call__ ( self, *args, **metadata ): handler = self.handler if isinstance( handler, TraitType ): dict = (self.__dict__ or {}).copy() dict.update( metadata ) return handler( *args, **dict ) metadata.setdefault( 'parent', self ) return Trait( *(args + ( self, )), **metadata ) #--------------------------------------------------------------------------- # (Python) property definitions: #--------------------------------------------------------------------------- def __get_default ( self ): kind, value = self.default_value() if kind in ( 2, 7, 8 ): return Undefined if kind in ( 4, 6 ): return value.copy() if kind in ( 3, 5 ): return value[:] return value default = property( __get_default ) def __get_default_kind ( self ): return KindMap[ self.default_value()[0] ] default_kind = property( __get_default_kind ) def __get_trait_type ( self ): handler = self.handler if handler is not None: return handler else: from .trait_types import Any return Any trait_type = property( __get_trait_type ) def __get_inner_traits ( self ): handler = self.handler if handler is not None: return handler.inner_traits() return () inner_traits = property( __get_inner_traits ) #--------------------------------------------------------------------------- # Returns whether or not this trait is of a specified trait type: #--------------------------------------------------------------------------- def is_trait_type ( self, trait_type ): """ Returns whether or not this trait is of a specified trait type. """ return isinstance( self.trait_type, trait_type ) #--------------------------------------------------------------------------- # Returns the user interface editor associated with the trait: #--------------------------------------------------------------------------- def get_editor ( self ): """ Returns the user interface editor associated with the trait. """ from traitsui.api import EditorFactory # See if we have an editor: editor = self.editor if editor is None: # Else see if the trait handler has an editor: handler = self.handler if handler is not None: editor = handler.get_editor( self ) # If not, give up and use a default text editor: if editor is None: from traitsui.api import TextEditor editor = TextEditor # If the result is not an EditoryFactory: if not isinstance( editor, EditorFactory ): # Then it should be a factory for creating them: args = () traits = {} if type( editor ) in SequenceTypes: for item in editor[:]: if type( item ) in SequenceTypes: args = tuple( item ) elif isinstance( item, dict ): traits = item if traits.get( 'trait', 0 ) is None: traits = traits.copy() traits[ 'trait' ] = self else: editor = item editor = editor( *args, **traits ) # Cache the result: self.editor = editor # Return the resulting EditorFactory object: return editor #--------------------------------------------------------------------------- # Returns the help text for a trait: #--------------------------------------------------------------------------- def get_help ( self, full = True ): """ Returns the help text for a trait. Parameters ---------- full : Boolean Indicates whether to return the value of the *help* attribute of the trait itself. Description ----------- If *full* is False or the trait does not have a **help** string, the returned string is constructed from the **desc** attribute on the trait and the **info** string on the trait's handler. """ if full: help = self.help if help is not None: return help handler = self.handler if handler is not None: info = 'must be %s.' % handler.info() else: info = 'may be any value.' desc = self.desc if self.desc is None: return info.capitalize() return 'Specifies %s and %s' % ( desc, info ) #--------------------------------------------------------------------------- # Returns a description of the trait: #--------------------------------------------------------------------------- def full_info ( self, object, name, value ): """ Returns a description of the trait. """ handler = self.handler if handler is not None: return handler.full_info( object, name, value ) return 'any value' #--------------------------------------------------------------------------- # Returns a description of the trait: #--------------------------------------------------------------------------- def info ( self ): """ Returns a description of the trait. """ handler = self.handler if handler is not None: return handler.info() return 'any value' #--------------------------------------------------------------------------- # Returns the pickleable form of a CTrait object: #--------------------------------------------------------------------------- def __reduce_ex__ ( self, protocol ): return ( __newobj__, ( self.__class__, 0 ), self.__getstate__() ) #--------------------------------------------------------------------------- # Registers listeners on an assigned 'TraitValue' object's 'value' # property: #--------------------------------------------------------------------------- def _register ( self, object, name ): """ Registers listeners on an assigned 'TraitValue' object's 'value' property. """ def handler ( ): object.trait_property_changed( name, None ) tv = self._trait_value handlers = tv._handlers if handlers is None: tv._handlers = handlers = {} handlers[ ( id( object ), name ) ] = handler tv.on_trait_change( handler, 'value' ) #--------------------------------------------------------------------------- # Unregisters listeners on an assigned 'TraitValue' object's 'value' # property: #--------------------------------------------------------------------------- def _unregister ( self, object, name ): """ Unregisters listeners on an assigned 'TraitValue' object's 'value' property. """ tv = self._trait_value handlers = tv._handlers key = ( id( object ), name ) handler = handlers.get( key ) if handler is not None: del handlers[ key ] tv.on_trait_change( handler, 'value', remove = True ) # Make sure the Python-level version of the trait class is known to all # interested parties: from . import ctraits ctraits._ctrait( CTrait ) #------------------------------------------------------------------------------- # Constants: #------------------------------------------------------------------------------- ConstantTypes = ( NoneType, IntType, LongType, FloatType, ComplexType, StringType, UnicodeType ) PythonTypes = ( StringType, UnicodeType, IntType, LongType, FloatType, ComplexType, ListType, TupleType, DictType, FunctionType, MethodType, ClassType, InstanceType, TypeType, NoneType ) CallableTypes = ( FunctionType, MethodType ) TraitTypes = ( TraitHandler, CTrait ) DefaultValues = { StringType: '', UnicodeType: u'', IntType: 0, LongType: 0L, FloatType: 0.0, ComplexType: 0j, ListType: [], TupleType: (), DictType: {}, BooleanType: False } DefaultValueSpecial = [ Missing, Self ] DefaultValueTypes = [ ListType, DictType ] #------------------------------------------------------------------------------- # Function used to unpickle new-style objects: #------------------------------------------------------------------------------- def __newobj__ ( cls, *args ): """ Unpickles new-style objects. """ return cls.__new__( cls, *args ) #------------------------------------------------------------------------------- # Returns the type of default value specified: #------------------------------------------------------------------------------- def _default_value_type ( default_value ): try: return DefaultValueSpecial.index( default_value ) + 1 except: try: return DefaultValueTypes.index( type( default_value ) ) + 3 except: return 0 #------------------------------------------------------------------------------- # 'TraitFactory' class: #------------------------------------------------------------------------------- class TraitFactory ( object ): ### Need a docstring here. #--------------------------------------------------------------------------- # Initializes the object: #--------------------------------------------------------------------------- def __init__ ( self, maker_function = None ): if maker_function is not None: self.maker_function = maker_function self.__doc__ = maker_function.__doc__ #--------------------------------------------------------------------------- # Creates a CTrait instance: #--------------------------------------------------------------------------- def __call__ ( self, *args, **metadata ): return self.maker_function( *args, **metadata ) class TraitImportError ( TraitFactory ): """ Defines a factory class for deferring import problems until encountering code that actually tries to use the unimportable trait. """ #--------------------------------------------------------------------------- # Initializes the object: #--------------------------------------------------------------------------- def __init__ ( self, message ): self.message = message #--------------------------------------------------------------------------- # Creates a CTrait instance: #--------------------------------------------------------------------------- def __call__ ( self, *args, **metadata ): raise TraitError( self.message ) #------------------------------------------------------------------------------- # Returns a trait created from a TraitFactory instance: #------------------------------------------------------------------------------- _trait_factory_instances = {} def trait_factory ( trait ): global _trait_factory_instances tid = id( trait ) if tid not in _trait_factory_instances: _trait_factory_instances[ tid ] = trait() return _trait_factory_instances[ tid ] #------------------------------------------------------------------------------- # Casts a CTrait or TraitFactory to a CTrait but returns None if it is neither: #------------------------------------------------------------------------------- def trait_cast ( something ): """ Casts a CTrait, TraitFactory or TraitType to a CTrait but returns None if it is none of those. """ if isinstance( something, CTrait ): return something if isinstance( something, TraitFactory ): return trait_factory( something ) if isinstance( something, type ) and issubclass( something, TraitType ): return something().as_ctrait() if isinstance( something, TraitType ): return something.as_ctrait() return None #------------------------------------------------------------------------------- # Attempts to cast a value to a trait. Returns either a trait or the original # value: #------------------------------------------------------------------------------- def try_trait_cast ( something ): """ Attempts to cast a value to a trait. Returns either a trait or the original value. """ return trait_cast( something ) or something #------------------------------------------------------------------------------- # Returns a trait derived from its input: #------------------------------------------------------------------------------- def trait_from ( something ): """ Returns a trait derived from its input. """ from .trait_types import Any if isinstance( something, CTrait ): return something if something is None: something = Any if isinstance( something, TraitFactory ): return trait_factory( something ) if isinstance( something, type ) and issubclass( something, TraitType ): return something().as_ctrait() if isinstance( something, TraitType ): return something.as_ctrait() return Trait( something ) # Patch the reference to 'trait_from' in 'trait_handlers.py': trait_handlers.trait_from = trait_from #--- 'instance' traits --------------------------------------------------------- class _InstanceArgs ( object ): def __init__ ( self, factory, args, kw ): self.args = ( factory, ) + args self.kw = kw #--- 'creates a run-time default value' ---------------------------------------- class Default ( object ): """ Generates a value the first time it is accessed. A Default object can be used anywhere a default trait value would normally be specified, to generate a default value dynamically. """ def __init__ ( self, func = None, args = (), kw = None ): self.default_value = ( func, args, kw ) #------------------------------------------------------------------------------- # Factory function for creating C-based traits: #------------------------------------------------------------------------------- def Trait ( *value_type, **metadata ): """ Creates a trait definition. Parameters ---------- This function accepts a variety of forms of parameter lists: +-------------------+---------------+-------------------------------------+ | Format | Example | Description | +===================+===============+=====================================+ | Trait(*default*) | Trait(150.0) | The type of the trait is inferred | | | | from the type of the default value, | | | | which must be in *ConstantTypes*. | +-------------------+---------------+-------------------------------------+ | Trait(*default*, | Trait(None, | The trait accepts any of the | | *other1*, | 0, 1, 2, | enumerated values, with the first | | *other2*, ...) | 'many') | value being the default value. The | | | | values must be of types in | | | | *ConstantTypes*, but they need not | | | | be of the same type. The *default* | | | | value is not valid for assignment | | | | unless it is repeated later in the | | | | list. | +-------------------+---------------+-------------------------------------+ | Trait([*default*, | Trait([None, | Similar to the previous format, but | | *other1*, | 0, 1, 2, | takes an explicit list or a list | | *other2*, ...]) | 'many']) | variable. | +-------------------+---------------+-------------------------------------+ | Trait(*type*) | Trait(Int) | The *type* parameter must be a name | | | | of a Python type (see | | | | *PythonTypes*). Assigned values | | | | must be of exactly the specified | | | | type; no casting or coercion is | | | | performed. The default value is the | | | | appropriate form of zero, False, | | | | or emtpy string, set or sequence. | +-------------------+---------------+-------------------------------------+ | Trait(*class*) |:: | Values must be instances of *class* | | | | or of a subclass of *class*. The | | | class MyClass:| default value is None, but None | | | pass | cannot be assigned as a value. | | | foo = Trait( | | | | MyClass) | | +-------------------+---------------+-------------------------------------+ | Trait(None, |:: | Similar to the previous format, but | | *class*) | | None *can* be assigned as a value. | | | class MyClass:| | | | pass | | | | foo = Trait( | | | | None, MyClass)| | +-------------------+---------------+-------------------------------------+ | Trait(*instance*) |:: | Values must be instances of the | | | | same class as *instance*, or of a | | | class MyClass:| subclass of that class. The | | | pass | specified instance is the default | | | i = MyClass() | value. | | | foo = | | | | Trait(i) | | +-------------------+---------------+-------------------------------------+ | Trait(*handler*) | Trait( | Assignment to this trait is | | | TraitEnum ) | validated by an object derived from | | | | **traits.TraitHandler**. | +-------------------+---------------+-------------------------------------+ | Trait(*default*, | Trait(0.0, 0.0| This is the most general form of | | { *type* | | 'stuff', | the function. The notation: | | *constant* | | TupleType) | ``{...|...|...}+`` means a list of | | *dict* | *class* || | one or more of any of the items | | *function* | | | listed between the braces. Thus, the| | *handler* | | | most general form of the function | | *trait* }+ ) | | consists of a default value, | | | | followed by one or more of several | | | | possible items. A trait defined by | | | | multiple items is called a | | | | "compound" trait. | +-------------------+---------------+-------------------------------------+ All forms of the Trait function accept both predefined and arbitrary keyword arguments. The value of each keyword argument becomes bound to the resulting trait object as the value of an attribute having the same name as the keyword. This feature lets you associate metadata with a trait. The following predefined keywords are accepted: desc : string Describes the intended meaning of the trait. It is used in exception messages and fly-over help in user interfaces. label : string Provides a human-readable name for the trait. It is used to label user interface editors for traits. editor : instance of a subclass of traits.api.Editor Object to use when creating a user interface editor for the trait. See the "Traits UI User Guide" for more information on trait editors. comparison_mode : integer Indicates when trait change notifications should be generated based upon the result of comparing the old and new values of a trait assignment: * 0 (NO_COMPARE): The values are not compared and a trait change notification is generated on each assignment. * 1 (OBJECT_IDENTITY_COMPARE): A trait change notification is generated if the old and new values are not the same object. * 2 (RICH_COMPARE): A trait change notification is generated if the old and new values are not equal using Python's 'rich comparison' operator. This is the default. rich_compare : Boolean (DEPRECATED: Use comparison_mode instead) Indicates whether the basis for considering a trait attribute value to have changed is a "rich" comparison (True, the default), or simple object identity (False). This attribute can be useful in cases where a detailed comparison of two objects is very expensive, or where you do not care whether the details of an object change, as long as the same object is used. """ return _TraitMaker( *value_type, **metadata ).as_ctrait() # Handle circular module dependencies: trait_handlers.Trait = Trait #------------------------------------------------------------------------------- # '_TraitMaker' class: #------------------------------------------------------------------------------- class _TraitMaker ( object ): # Ctrait type map for special trait types: type_map = { 'event': 2, 'constant': 7 } #--------------------------------------------------------------------------- # Initialize the object: #--------------------------------------------------------------------------- def __init__ ( self, *value_type, **metadata ): metadata.setdefault( 'type', 'trait' ) self.define( *value_type, **metadata ) #--------------------------------------------------------------------------- # Define the trait: #--------------------------------------------------------------------------- def define ( self, *value_type, **metadata ): default_value_type = -1 default_value = handler = clone = None if len( value_type ) > 0: default_value = value_type[0] value_type = value_type[1:] if ((len( value_type ) == 0) and (type( default_value ) in SequenceTypes)): default_value, value_type = default_value[0], default_value if len( value_type ) == 0: default_value = try_trait_cast( default_value ) if default_value in PythonTypes: handler = TraitCoerceType( default_value ) default_value = DefaultValues.get( default_value ) elif isinstance( default_value, CTrait ): clone = default_value default_value_type, default_value = clone.default_value() metadata[ 'type' ] = clone.type elif isinstance( default_value, TraitHandler ): handler = default_value default_value = None elif default_value is ThisClass: handler = ThisClass() default_value = None else: typeValue = type( default_value ) if isinstance(default_value, basestring): string_options = self.extract( metadata, 'min_len', 'max_len', 'regex' ) if len( string_options ) == 0: handler = TraitCastType( typeValue ) else: handler = TraitString( **string_options ) elif typeValue in TypeTypes: handler = TraitCastType( typeValue ) else: metadata.setdefault( 'instance_handler', '_instance_changed_handler' ) handler = TraitInstance( default_value ) if default_value is handler.aClass: default_value = DefaultValues.get( default_value ) else: enum = [] other = [] map = {} self.do_list( value_type, enum, map, other ) if (((len( enum ) == 1) and (enum[0] is None)) and ((len( other ) == 1) and isinstance( other[0], TraitInstance ))): enum = [] other[0].allow_none() metadata.setdefault( 'instance_handler', '_instance_changed_handler' ) if len( enum ) > 0: if (((len( map ) + len( other )) == 0) and (default_value not in enum)): enum.insert( 0, default_value ) other.append( TraitEnum( enum ) ) if len( map ) > 0: other.append( TraitMap( map ) ) if len( other ) == 0: handler = TraitHandler() elif len( other ) == 1: handler = other[0] if isinstance( handler, CTrait ): clone, handler = handler, None metadata[ 'type' ] = clone.type elif isinstance( handler, TraitInstance ): metadata.setdefault( 'instance_handler', '_instance_changed_handler' ) if default_value is None: handler.allow_none() elif isinstance( default_value, _InstanceArgs ): default_value_type = 7 default_value = ( handler.create_default_value, default_value.args, default_value.kw ) elif (len( enum ) == 0) and (len( map ) == 0): aClass = handler.aClass typeValue = type( default_value ) if typeValue is dict: default_value_type = 7 default_value = ( aClass, (), default_value ) elif not isinstance( default_value, aClass ): if typeValue is not tuple: default_value = ( default_value, ) default_value_type = 7 default_value = ( aClass, default_value, None ) else: for i, item in enumerate( other ): if isinstance( item, CTrait ): if item.type != 'trait': raise TraitError, ("Cannot create a complex " "trait containing %s trait." % add_article( item.type ) ) handler = item.handler if handler is None: break other[i] = handler else: handler = TraitCompound( other ) # Save the results: self.handler = handler self.clone = clone if default_value_type < 0: if isinstance( default_value, Default ): default_value_type = 7 default_value = default_value.default_value else: if (handler is None) and (clone is not None): handler = clone.handler if handler is not None: default_value_type = handler.default_value_type if default_value_type < 0: try: default_value = handler.validate( None, '', default_value ) except: pass if default_value_type < 0: default_value_type = _default_value_type( default_value ) self.default_value_type = default_value_type self.default_value = default_value self.metadata = metadata.copy() #--------------------------------------------------------------------------- # Determine the correct TraitHandler for each item in a list: #--------------------------------------------------------------------------- def do_list ( self, list, enum, map, other ): for item in list: if item in PythonTypes: other.append( TraitCoerceType( item ) ) else: item = try_trait_cast( item ) typeItem = type( item ) if typeItem in ConstantTypes: enum.append( item ) elif typeItem in SequenceTypes: self.do_list( item, enum, map, other ) elif typeItem is DictType: map.update( item ) elif typeItem in CallableTypes: other.append( TraitFunction( item ) ) elif item is ThisClass: other.append( ThisClass() ) elif isinstance( item, TraitTypes ): other.append( item ) else: other.append( TraitInstance( item ) ) #--------------------------------------------------------------------------- # Returns a properly initialized 'CTrait' instance: #--------------------------------------------------------------------------- def as_ctrait ( self ): metadata = self.metadata trait = CTrait( self.type_map.get( metadata.get( 'type' ), 0 ) ) clone = self.clone if clone is not None: trait.clone( clone ) if clone.__dict__ is not None: trait.__dict__ = clone.__dict__.copy() trait.default_value( self.default_value_type, self.default_value ) handler = self.handler if handler is not None: trait.handler = handler validate = getattr( handler, 'fast_validate', None ) if validate is None: validate = handler.validate trait.set_validate( validate ) post_setattr = getattr( handler, 'post_setattr', None ) if post_setattr is not None: trait.post_setattr = post_setattr trait.is_mapped( handler.is_mapped ) # Note: The use of 'rich_compare' metadata is deprecated; use # 'comparison_mode' metadata instead: rich_compare = metadata.get( 'rich_compare' ) if rich_compare is not None: trait.rich_comparison( rich_compare is True ) comparison_mode = metadata.get( 'comparison_mode' ) if comparison_mode is not None: trait.comparison_mode( comparison_mode ) trait.value_allowed( metadata.get( 'trait_value', False ) is True ) if len( metadata ) > 0: if trait.__dict__ is None: trait.__dict__ = metadata else: trait.__dict__.update( metadata ) return trait #--------------------------------------------------------------------------- # Extract a set of keywords from a dictionary: #--------------------------------------------------------------------------- def extract ( self, from_dict, *keys ): to_dict = {} for key in keys: if key in from_dict: to_dict[ key ] = from_dict[ key ] del from_dict[ key ] return to_dict #------------------------------------------------------------------------------- # Factory function for creating C-based trait properties: #------------------------------------------------------------------------------- def Property ( fget = None, fset = None, fvalidate = None, force = False, handler = None, trait = None, **metadata ): """ Returns a trait whose value is a Python property. Parameters ---------- fget : function The "getter" function for the property fset : function The "setter" function for the property fvalidate : function The validation function for the property force : Boolean Indicates whether to use only the function definitions spedficied by **fget** and **fset**, and not look elsewhere on the class. handler : function A trait handler function for the trait trait : a trait definition or value that can be converted to a trait A trait definition that constrains the values of the property trait Description ----------- If no getter or setter functions are specified (and **force** is not True), it is assumed that they are defined elsewhere on the class whose attribute this trait is assigned to. For example:: class Bar(HasTraits): foo = Property(Float) # Shadow trait attribute _foo = Float def _set_foo(self,x): self._foo = x def _get_foo(self): return self._foo You can use the **depends_on** metadata attribute to indicate that the property depends on the value of another trait. The value of **depends_on** is an extended name specifier for traits that the property depends on. The property will a trait change notification if any of the traits specified by **depends_on** change. For example:: class Wheel ( Part ): axle = Instanced( Axle ) position = Property( depends_on = 'axle.chassis.position' ) For details of the extended trait name syntax, refer to the on_trait_change() method of the HasTraits class. """ metadata[ 'type' ] = 'property' # If no parameters specified, must be a forward reference (if not forced): if (not force) and (fset is None): sum = ((fget is not None) + (fvalidate is not None) + (trait is not None)) if sum <= 1: if sum == 0: return ForwardProperty( metadata ) handler = None if fget is not None: trait = fget if trait is not None: trait = trait_cast( trait ) if trait is not None: fvalidate = handler = trait.handler if fvalidate is not None: fvalidate = handler.validate if (fvalidate is not None) or (trait is not None): if 'editor' not in metadata: if (trait is not None) and (trait.editor is not None): metadata[ 'editor' ] = trait.editor return ForwardProperty( metadata, fvalidate, handler ) if fget is None: metadata[ 'transient' ] = True if fset is None: fget = _undefined_get fset = _undefined_set else: fget = _write_only elif fset is None: fset = _read_only metadata[ 'transient' ] = True if trait is not None: trait = trait_cast( trait ) handler = trait.handler if (fvalidate is None) and (handler is not None): fvalidate = handler.validate if ('editor' not in metadata) and (trait.editor is not None): metadata[ 'editor' ] = trait.editor metadata.setdefault( 'depends_on', getattr( fget, 'depends_on', None ) ) if ((metadata.get( 'depends_on' ) is not None) and getattr( fget, 'cached_property', False )): metadata.setdefault( 'cached', True ) n = 0 trait = CTrait( 4 ) trait.__dict__ = metadata.copy() if fvalidate is not None: n = _arg_count( fvalidate ) trait.property( fget, _arg_count( fget ), fset, _arg_count( fset ), fvalidate, n ) trait.handler = handler return trait Property = TraitFactory( Property ) class ForwardProperty ( object ): """ Used to implement Property traits where accessor functions are defined implicitly on the class. """ def __init__ ( self, metadata, validate = None, handler = None ): self.metadata = metadata.copy() self.validate = validate self.handler = handler #------------------------------------------------------------------------------- # Dictionary used to handle return type mapping special cases: #------------------------------------------------------------------------------- SpecialNames = { ### 'int': trait_factory( Int ), ### 'long': trait_factory( Long ), ### 'float': trait_factory( Float ), ### 'complex': trait_factory( Complex ), ### 'str': trait_factory( Str ), ### 'unicode': trait_factory( Unicode ), ### 'bool': trait_factory( Bool ), ### 'list': trait_factory( List ), ### 'tuple': trait_factory( Tuple ), ### 'dict': trait_factory( Dict ) } #-- Date Trait definition ---------------------------------------------------- #Date = Instance(datetime.date, metadata = { 'editor': date_editor }) #-- Time Trait definition ---------------------------------------------------- #Time = Instance(datetime.time, metadata = { 'editor': time_editor }) #------------------------------------------------------------------------------- # Create predefined, reusable trait instances: #------------------------------------------------------------------------------- # Generic trait with 'object' behavior: generic_trait = CTrait( 8 ) #------------------------------------------------------------------------------- # User interface related color and font traits: #------------------------------------------------------------------------------- def Color ( *args, **metadata ): """ Returns a trait whose value must be a GUI toolkit-specific color. Description ----------- For wxPython, the returned trait accepts any of the following values: * A wx.Colour instance * A wx.ColourPtr instance * an integer whose hexadecimal form is 0x*RRGGBB*, where *RR* is the red value, *GG* is the green value, and *BB* is the blue value Default Value ------------- For wxPython, 0x000000 (that is, white) """ from traitsui.toolkit_traits import ColorTrait return ColorTrait( *args, **metadata ) Color = TraitFactory( Color ) def RGBColor ( *args, **metadata ): """ Returns a trait whose value must be a GUI toolkit-specific RGB-based color. Description ----------- For wxPython, the returned trait accepts any of the following values: * A tuple of the form (*r*, *g*, *b*), in which *r*, *g*, and *b* represent red, green, and blue values, respectively, and are floats in the range from 0.0 to 1.0 * An integer whose hexadecimal form is 0x*RRGGBB*, where *RR* is the red value, *GG* is the green value, and *BB* is the blue value Default Value ------------- For wxPython, (0.0, 0.0, 0.0) (that is, white) """ from traitsui.toolkit_traits import RGBColorTrait return RGBColorTrait( *args, **metadata ) RGBColor = TraitFactory( RGBColor ) def Font ( *args, **metadata ): """ Returns a trait whose value must be a GUI toolkit-specific font. Description ----------- For wxPython, the returned trait accepts any of the following: * a wx.Font instance * a wx.FontPtr instance * a string describing the font, including one or more of the font family, size, weight, style, and typeface name. Default Value ------------- For wxPython, 'Arial 10' """ from traitsui.toolkit_traits import FontTrait return FontTrait( *args, **metadata ) Font = TraitFactory( Font ) traits-4.1.0/traits/ustr_trait.py0000644000175100001440000001442111674463323020076 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # # Copyright (c) 2008, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in enthought/LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # # Author: David C. Morrill # Date: 08/21/2008 # #------------------------------------------------------------------------------ """ Defines the UStr type and HasUniqueStrings mixin class for efficiently creating lists of objects containing traits whose string values must be unique within the list. """ #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from __future__ import absolute_import from .trait_base import is_str from .has_traits import HasTraits from .trait_value import TraitValue, TypeValue from .trait_types import List from .trait_handlers import TraitType, NoDefaultSpecified #------------------------------------------------------------------------------- # 'UStr' class: #------------------------------------------------------------------------------- class UStr ( TraitType ): """ Trait type that ensures that a value assigned to a trait is unique within the list it belongs to. """ # The type value to assign to restore the original list item type when a # list item is removed from the monitored list: str_type = TraitValue() # The informational text describing the trait: info_text = 'a unique string' def __init__ ( self, owner, list_name, str_name, default_value = NoDefaultSpecified, **metadata ): """ Initializes the type. """ super( UStr, self ).__init__( default_value, **metadata ) self.owner = owner self.list_name = list_name self.str_name = str_name self.ustr_type = TypeValue( self ) self.names = dict( [ ( getattr( item, str_name ), item ) for item in getattr( owner, list_name ) ] ) self.roots = {} self.available = {} owner.on_trait_change( self._items_modified, list_name + '[]' ) def validate ( self, object, name, value ): """ Ensures that a value being assigned to a trait is a unique string. """ if isinstance( value, basestring ): names = self.names old_name = getattr( object, name ) if names.get( old_name ) is object: self._remove( old_name ) if value not in names: names[ value ] = object return value available = self.available.get( value ) while True: if available is None: new_value = None break index = available.pop() if len( available ) == 0: del self.available[ value ] available = None new_value = '%s_%d' % ( value, index ) if new_value not in names: break if new_value is None: self.roots[ value ] = index = \ self.roots.setdefault( value, 1 ) + 1 new_value = '%s_%d' % ( value, index ) names[ new_value ] = object return new_value self.error( object, name, value ) def _remove ( self, name ): """ Removes a specified name. """ self.names.pop( name, None ) col = name.rfind( '_' ) if col >= 0: try: index = int( name[ col + 1: ] ) prefix = name[ : col ] if prefix in self.roots: if prefix not in self.available: self.available[ prefix ] = set() self.available[ prefix ].add( index ) except: pass def _items_modified ( self, object, name, removed, added ): """ Handles items being added to or removed from the monitored list. """ str_name = self.str_name str_type = self.str_type ustr_type = self.ustr_type for item in removed: setattr( item, str_name, str_type ) self._remove( getattr( item, str_name ) ) for item in added: setattr( item, str_name, ustr_type ) setattr( item, str_name, getattr( item, str_name ) ) #------------------------------------------------------------------------------- # 'HasUniqueStrings' class: #------------------------------------------------------------------------------- class HasUniqueStrings ( HasTraits ): """ Mixin or base class for objects containing lists with items containing string valued traits that must be unique. List traits within the class that contain items which have string traits which must be unique should indicate this by attaching metadata of the form:: unique_string = 'trait1, trait2, ..., traitn' where each 'traiti' value is the name of a trait within each list item that must contain unique string data. For example:: usa = List( State, unique_string = 'name, abbreviation' ) """ #-- Private Traits --------------------------------------------------------- # List of UStr traits that have been attached to object list traits: _ustr_traits = List #-- HasTraits Object Initializer ------------------------------------------- def traits_init ( self ): """ Adds any UStrMonitor objects to list traits with 'unique_string' metadata. """ super( HasUniqueStrings, self ).traits_init() for name, trait in self.traits( unique_string = is_str ).items(): for str_name in trait.unique_string.split( ',' ): self._ustr_traits.append( UStr( self, name, str_name.strip() ) ) items = getattr( self, name ) if len( items ) > 0: setattr( self, name, [] ) setattr( self, name, items ) traits-4.1.0/traits/trait_base.py0000644000175100001440000004511111674463323020013 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # # Copyright (c) 2005, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in enthought/LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # # Thanks for using Enthought open source! # # Author: David C. Morrill # Date: 06/21/2002 # # Refactored into a separate module: 07/04/2003 # #------------------------------------------------------------------------------ """ Defines common, low-level capabilities needed by the Traits package. """ #------------------------------------------------------------------------------- # Imports: #------------------------------------------------------------------------------- from __future__ import absolute_import import os import sys from os import getcwd from os.path import dirname, exists, join from string import lowercase, uppercase from types import (ListType, TupleType, DictType, StringType, UnicodeType, IntType, LongType, FloatType, ComplexType, ClassType, TypeType) # Set the Python version being used: vi = sys.version_info python_version = vi[0] + (float( vi[1] ) / 10.0) try: from traits.etsconfig.api import ETSConfig except: # If the ETSConfig package is not available, fake it: class ETSConfig ( object ): #----------------------------------------------------------------------- # 'object' interface: #----------------------------------------------------------------------- def __init__ ( self ): """ Constructor. Note that this constructor can only ever be called from within this module, since we don't expose the class. """ # Shadow attributes for properties: self._application_data = None self._toolkit = None return #----------------------------------------------------------------------- # 'ETSConfig' interface: #----------------------------------------------------------------------- #-- Property Implementations ------------------------------------------- def _get_application_data ( self ): """ Property getter. This is a directory that applications and packages can safely write non-user accessible data to i.e. configuration information, preferences etc. Do not put anything in here that the user might want to navigate to (e.g. projects, user data files, etc). The actual location differs between operating systems. """ if self._application_data is None: self._application_data = self._initialize_application_data() return self._application_data def _set_application_data ( self, application_data ): """ Property setter. """ self._application_data = application_data application_data = property( _get_application_data, _set_application_data ) def _get_toolkit ( self ): """ Property getter for the GUI toolkit. The value returned is, in order of preference: the value set by the application; the value passed on the command line using the '-toolkit' option; the value specified by the 'ETS_TOOLKIT' environment variable; otherwise the empty string. """ if self._toolkit is None: self._toolkit = self._initialize_toolkit() return self._toolkit def _set_toolkit ( self, toolkit ): """ Property setter for the GUI toolkit. The toolkit can be set more than once, but only if it is the same one each time. An application that is written for a particular toolkit can explicitly set it before any other module that gets the value is imported. """ if self._toolkit and (self._toolkit != toolkit): raise ValueError( 'Cannot set toolkit to %s because it has ' 'already been set to %s' % ( toolkit, self._toolkit ) ) self._toolkit = toolkit return toolkit = property( _get_toolkit, _set_toolkit ) #-- Private Methods ---------------------------------------------------- def _initialize_application_data ( self ): """ Initializes the (default) application data directory. """ if sys.platform == 'win32': environment_variable = 'APPDATA' directory_name = 'Enthought' else: environment_variable = 'HOME' directory_name = '.enthought' # Lookup the environment variable: parent_directory = os.environ.get( environment_variable, None ) if parent_directory is None: raise ValueError( 'Environment variable "%s" not set' % environment_variable ) application_data = os.path.join( parent_directory, directory_name ) # If a file already exists with this name then make sure that it is # a directory! if os.path.exists( application_data ): if not os.path.isdir( application_data ): raise ValueError( 'File "%s" already exists' % application_data ) # Otherwise, create the directory: else: os.makedirs( application_data ) return application_data def _initialize_toolkit ( self ): """ Initializes the toolkit. """ # We handle the command line option even though it doesn't have the # highest precedence because we always want to remove it from the # command line: if '-toolkit' in sys.argv: opt_idx = sys.argv.index( '-toolkit' ) try: opt_toolkit = sys.argv[ opt_idx + 1 ] except IndexError: raise ValueError( 'The -toolkit command line argument must ' 'be followed by a toolkit name' ) # Remove the option: del sys.argv[ opt_idx: opt_idx + 1 ] else: opt_toolkit = None if self._toolkit is not None: toolkit = self._toolkit elif opt_toolkit is not None: toolkit = opt_toolkit else: toolkit = os.environ.get( 'ETS_TOOLKIT', '' ) return toolkit ETSConfig = ETSConfig() #------------------------------------------------------------------------------- # Provide Python 2.3+ compatible definitions (if necessary): #------------------------------------------------------------------------------- try: from types import BooleanType except ImportError: BooleanType = IntType def _enumerate ( seq ): for i in xrange( len( seq) ): yield i, seq[i] try: enumerate = enumerate except: enumerate = _enumerate del _enumerate #------------------------------------------------------------------------------- # Constants: #------------------------------------------------------------------------------- ClassTypes = ( ClassType, TypeType ) SequenceTypes = ( ListType, TupleType ) ComplexTypes = ( float, int ) TypeTypes = ( StringType, UnicodeType, IntType, LongType, FloatType, ComplexType, ListType, TupleType, DictType, BooleanType ) TraitNotifier = '__trait_notifier__' # The standard Traits property cache prefix: TraitsCache = '_traits_cache_' #------------------------------------------------------------------------------- # Singleton 'Uninitialized' object: #------------------------------------------------------------------------------- Uninitialized = None class _Uninitialized(object): """ The singleton value of this class represents the uninitialized state of a trait and is specified as the 'old' value in the trait change notification that occurs when the value of a trait is read before being set. """ def __new__(cls): if Uninitialized is not None: return Uninitialized else: self = object.__new__(cls) return self def __repr__(self): return '' def __reduce_ex__(self, protocol): return (_Uninitialized, ()) #: When the first reference to a trait is a 'get' reference, the default value of #: the trait is implicitly assigned and returned as the value of the trait. #: Because of this implicit assignment, a trait change notification is #: generated with the Uninitialized object as the 'old' value of the trait, and #: the default trait value as the 'new' value. This allows other parts of the #: traits package to recognize the assignment as the implicit default value #: assignment, and treat it specially. Uninitialized = _Uninitialized() #------------------------------------------------------------------------------- # Singleton 'Undefined' object (used as undefined trait name and/or value): #------------------------------------------------------------------------------- Undefined = None class _Undefined(object): """ Singleton 'Undefined' object (used as undefined trait name and/or value) """ def __new__(cls): if Undefined is not None: return Undefined else: self = object.__new__(cls) return self def __repr__(self): return '' def __reduce_ex__(self, protocol): return (_Undefined, ()) def __eq__(self, other): return type(self) is type(other) def __ne__(self, other): return type(self) is not type(other) #: Singleton object that indicates that a trait attribute has not yet had a #: value set (i.e., its value is undefined). This object is used instead of #: None, because None often has other meanings, such as that a value is not #: used. When a trait attribute is first assigned a value, and its associated #: trait notification handlers are called, Undefined is passed as the *old* #: parameter, to indicate that the attribute previously had no value. Undefined = _Undefined() # Tell the C-base code about singleton 'Undefined' and 'Uninitialized' objects: from . import ctraits ctraits._undefined( Undefined, Uninitialized ) #------------------------------------------------------------------------------- # Singleton 'Missing' object (used as missing method argument marker): #------------------------------------------------------------------------------- class Missing ( object ): """ Singleton 'Missing' object (used as missing method argument marker). """ def __repr__ ( self ): return '' #: Singleton object that indicates that a method argument is missing from a #: type-checked method signature. Missing = Missing() #------------------------------------------------------------------------------- # Singleton 'Self' object (used as object reference to current 'object'): #------------------------------------------------------------------------------- class Self ( object ): """ Singleton 'Self' object (used as object reference to current 'object'). """ def __repr__ ( self ): return '' #: Singleton object that references the current 'object'. Self = Self() #------------------------------------------------------------------------------- # Define a special 'string' coercion function: #------------------------------------------------------------------------------- def strx ( arg ): """ Wraps the built-in str() function to raise a TypeError if the argument is not of a type in StringTypes. """ if type( arg ) in StringTypes: return str( arg ) raise TypeError #------------------------------------------------------------------------------- # Constants: #------------------------------------------------------------------------------- StringTypes = ( StringType, UnicodeType, IntType, LongType, FloatType, ComplexType ) #------------------------------------------------------------------------------- # Define a mapping of coercable types: #------------------------------------------------------------------------------- # Mapping of coercable types. CoercableTypes = { LongType: ( 11, long, int ), FloatType: ( 11, float, int ), ComplexType: ( 11, complex, float, int ), UnicodeType: ( 11, unicode, str ) } #------------------------------------------------------------------------------- # Return a string containing the class name of an object with the correct # article (a or an) preceding it (e.g. 'an Image', 'a PlotValue'): #------------------------------------------------------------------------------- def class_of ( object ): """ Returns a string containing the class name of an object with the correct indefinite article ('a' or 'an') preceding it (e.g., 'an Image', 'a PlotValue'). """ if isinstance( object, basestring ): return add_article( object ) return add_article( object.__class__.__name__ ) #------------------------------------------------------------------------------- # Return a string containing the right article (i.e. 'a' or 'an') prefixed to # a specified string: #------------------------------------------------------------------------------- def add_article ( name ): """ Returns a string containing the correct indefinite article ('a' or 'an') prefixed to the specified string. """ if name[:1].lower() in 'aeiou': return 'an ' + name return 'a ' + name #---------------------------------------------------------------------------- # Return a 'user-friendly' name for a specified trait: #---------------------------------------------------------------------------- def user_name_for ( name ): """ Returns a "user-friendly" version of a string, with the first letter capitalized and with underscore characters replaced by spaces. For example, ``user_name_for('user_name_for')`` returns ``'User name for'``. """ name = name.replace( '_', ' ' ) result = '' last_lower = False for c in name: if (c in uppercase) and last_lower: result += ' ' last_lower = (c in lowercase) result += c return result.capitalize() #------------------------------------------------------------------------------- # Gets the path to the traits home directory: #------------------------------------------------------------------------------- _traits_home = None def traits_home ( ): """ Gets the path to the Traits home directory. """ global _traits_home if _traits_home is None: _traits_home = verify_path( join( ETSConfig.application_data, 'traits' ) ) return _traits_home #------------------------------------------------------------------------------- # Verify that a specified path exists, and try to create it if it doesn't: #------------------------------------------------------------------------------- def verify_path ( path ): """ Verify that a specified path exists, and try to create it if it does not exist. """ if not exists( path ): try: os.mkdir( path ) except: pass return path #------------------------------------------------------------------------------- # Returns the name of the module the caller's caller is located in: #------------------------------------------------------------------------------- def get_module_name ( level = 2 ): """ Returns the name of the module that the caller's caller is located in. """ return sys._getframe( level ).f_globals.get( '__name__', '__main__' ) #------------------------------------------------------------------------------- # Returns a resource path calculated from the caller's stack: #------------------------------------------------------------------------------- def get_resource_path ( level = 2 ): """Returns a resource path calculated from the caller's stack. """ module = sys._getframe( level ).f_globals.get( '__name__', '__main__' ) if module != '__main__': # Return the path to the module: try: return dirname( getattr( sys.modules.get( module ), '__file__' ) ) except: # Apparently 'module' is not a registered module...treat it like # '__main__': pass # '__main__' is not a real module, so we need a work around: for path in [ dirname( sys.argv[0] ), getcwd() ]: if exists( path ): break return path #------------------------------------------------------------------------------- # Returns the value of an extended object attribute name of the form: # name[.name2[.name3...]]: #------------------------------------------------------------------------------- def xgetattr( object, xname, default = Undefined ): """ Returns the value of an extended object attribute name of the form: name[.name2[.name3...]]. """ names = xname.split( '.' ) for name in names[:-1]: if default is Undefined: object = getattr( object, name ) else: object = getattr( object, name, None ) if object is None: return default if default is Undefined: return getattr( object, names[-1] ) return getattr( object, names[-1], default ) #------------------------------------------------------------------------------- # Sets the value of an extended object attribute name of the form: # name[.name2[.name3...]]: #------------------------------------------------------------------------------- def xsetattr( object, xname, value ): """ Sets the value of an extended object attribute name of the form: name[.name2[.name3...]]. """ names = xname.split( '.' ) for name in names[:-1]: object = getattr( object, name ) setattr( object, names[-1], value ) #------------------------------------------------------------------------------- # Traits metadata selection functions: #------------------------------------------------------------------------------- def is_none ( value ): return (value is None) def not_none ( value ): return (value is not None) def not_false ( value ): return (value is not False) def not_event ( value ): return (value != 'event') def is_str ( value ): return isinstance( value, basestring ) traits-4.1.0/traits/util/0000755000175100001440000000000011674463323016277 5ustar ischnellusers00000000000000traits-4.1.0/traits/util/home_directory.py0000644000175100001440000000263311674463323021671 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # Copyright (c) 2005, 2006 by Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in enthought/LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # Thanks for using Enthought open source! # # Author: Enthought, Inc. # Description: #------------------------------------------------------------------------------ import os def get_home_directory(): """ Determine the user's home directory.""" # 'HOME' should work on most Unixes, and 'USERPROFILE' works on at # least Windows XP ;^) # # FIXME: Is this really better than the following?? # path = os.path.expanduser('~') # The above seems to work on both Windows and Unixes though the docs # indicate it might not work as well on Macs. for name in ['HOME', 'USERPROFILE']: if os.environ.has_key(name): # Make sure that the path ends with a path seperator. path = os.environ[name] if path[-1] != os.path.sep: path += os.path.sep break # If all else fails, the current directory will do. else: path = '' return path traits-4.1.0/traits/util/clean_strings.py0000644000175100001440000000521611674463323021510 0ustar ischnellusers00000000000000#----------------------------------------------------------------------------- # # Copyright (c) 2006 by Enthought, Inc. # All rights reserved. # #----------------------------------------------------------------------------- """ Provides functions that munge strings to avoid characters that would be problematic in certain situations. """ # Standard library imports. import copy import datetime import keyword import re def clean_filename(name): """ Munge a string to avoid characters that might be problematic as a filename in some filesystems. """ # The only acceptable characters are alphanumeric (in the current locale) # plus a period and dash. wordparts = re.split('[^\w\.\-]+', name) # Filter out empty strings at the beginning or end of the list. wordparts = filter(None, wordparts) # Make sure this is an ASCII-encoded string, not a Unicode string. filename = '_'.join(wordparts).encode('ascii') return filename def clean_timestamp(dt=None, microseconds=False): """ Return a timestamp that has been cleansed of characters that might cause problems in filenames, namely colons. If no datetime object is provided, then uses the current time. Description ----------- The timestamp is in ISO-8601 format with the following exceptions: * Colons ':' are replaced by underscores '_'. * Microseconds are not displayed if the 'microseconds' parameter is False. Parameters ---------- dt : None or datetime.datetime object If None, then the current time is used. microseconds : bool Display microseconds or not. Returns ------- A string timestamp. """ if dt is None: dt = datetime.datetime.now() else: # Operate on a copy. dt = copy.copy(dt) if not microseconds: # The microseconds are largely uninformative but annoying. dt = dt.replace(microsecond=0) stamp = dt.isoformat().replace(':', '_') return stamp def python_name(name): """ Attempt to make a valid Python identifier out of a name. """ if len(name) > 0: # Replace spaces with underscores. name = name.replace(' ', '_').lower() # If the name is a Python keyword then prefix it with an # underscore. if keyword.iskeyword(name): name = '_' + name # If the name starts with a digit then prefix it with an # underscore. if name[0].isdigit(): name = '_' + name return name ### EOF ###################################################################### traits-4.1.0/traits/util/resource.py0000644000175100001440000001635011674463323020505 0ustar ischnellusers00000000000000#------------------------------------------------------------------------------ # Copyright (c) 2005, Enthought, Inc. # All rights reserved. # # This software is provided without warranty under the terms of the BSD # license included in enthought/LICENSE.txt and may be redistributed only # under the conditions described in the aforementioned license. The license # is also available online at http://www.enthought.com/licenses/BSD.txt # Thanks for using Enthought open source! # # Author: Enthought, Inc. # Description: #------------------------------------------------------------------------------ """ Utility functions for managing and finding resources (ie. images/files etc). get_path : Returns the absolute path of a class or instance create_unique_name : Creates a name with a given prefix that is not in a given list of existing names. The separator between the prefix and the rest of the name can also be specified (default is a '_') find_resource: Given a setuptools project specification string ('MyProject>=2.1') and a partial path leading from the projects base directory to the desired resource, will return either an opened file object or, if specified, a full path to the resource. """ # Standard library imports. import inspect, os, sys from distutils.sysconfig import get_python_lib def get_path(path): """ Returns an absolute path for the specified path. 'path' can be a string, class or instance. """ if type(path) is not str: # Is this a class or an instance? if inspect.isclass(path): klass = path else: klass = path.__class__ # Get the name of the module that the class was loaded from. module_name = klass.__module__ # Look the module up. module = sys.modules[module_name] if module_name == '__main__': dirs = [os.path.dirname(sys.argv[0]), os.getcwd()] for d in dirs: if os.path.exists(d): path = d break else: # Get the path to the module. path = os.path.dirname(module.__file__) return path def create_unique_name(prefix, names, separator='_'): """ Creates a name starting with 'prefix' that is not in 'names'. """ i = 1 name = prefix while name in names: name = prefix + separator + str(i) i += 1 return name def find_resource(project, resource_path, alt_path=None, return_path=False): """ Returns a file object or file path pointing to the desired resource. Parameters ---------- project : string The name of the project to look for the resource in. Can be the name or a requirement string. Ex: 'MyProject', 'MyProject>1.0', 'MyProject==1.1' resource_path : string The path to the file from inside the package. If the file desired is MyProject/data/image.jpg, resource_path would be 'data/image.jpg'. alt_path : string The path to the resource relative to the location of the application's top-level script (the one with __main__). If this function is called in code/scripts/myscript.py and the resource is code/data/image.jpg, the alt_path would be '../data/image.jpg'. This path is only used if the resource cannot be found using setuptools. return_path : bool Determines whether the function should return a file object or a full path to the resource. Returns ------- file : file object or file path A file object containing the resource. If return_path is True, 'file' will be the full path to the resource. If the file is not found or cannot be opened, None is returned. Description ----------- This function will find a desired resource file and return an opened file object. The main method of finding the resource uses the pkg_resources resource_stream method, which searches your working set for the installed project specified and appends the resource_path given to the project path, leading it to the file. If setuptools is not installed or it cannot find/open the resource, find_resource will use the sys.path[0] to find the resource if alt_path is defined. """ try: # Get the image using the pkg_resources resource_stream module, which # will find the file by getting the Chaco install path and appending the # image path. This method works in all cases as long as setuptools is # installed. If setuptools isn't installed, the backup sys.path[0] # method is used. from pkg_resources import resource_stream, working_set, Requirement # Get a requirement for the project requirement = Requirement.parse(project) if return_path: dist = working_set.find(requirement) full_path = os.path.join(dist.location, resource_path) # If the path exists, return it if os.path.exists(full_path): return full_path else: raise else: return resource_stream(requirement, resource_path) except: # Setuptools was either not installed, or it failed to find the file. # First check to see if the package was installed using egginst by # looking for the file at: site-packages\\resouce_path full_path = os.path.join(get_python_lib(), resource_path) if os.path.exists(full_path): if return_path: return full_path else: return open(full_path, 'rb') # Get the image using sys.path[0], which is the directory that the # running script lives in. The path to the file is then constructed by # navigating from the script's location. This method only works if this # script is called directly from the command line using # 'python %SOMEPATH%/