1
0
Fork 0
mirror of https://github.com/shlomif/PySolFC.git synced 2025-04-05 00:02:29 -04:00

Get rid of trailing space.

This commit is contained in:
Shlomi Fish 2013-05-22 12:57:18 +03:00
parent c12d0c669b
commit 4da89ccc8c
38 changed files with 432 additions and 403 deletions

View file

@ -62,4 +62,4 @@ mo:
test: test:
@rm -f tests/individually-importing/*.py # To avoid stray files @rm -f tests/individually-importing/*.py # To avoid stray files
python scripts/gen_individual_importing_tests.py python scripts/gen_individual_importing_tests.py
runprove tests/board_gen/*.py tests/individually-importing/*.py runprove tests/style/*.t tests/board_gen/*.py tests/individually-importing/*.py

6
README
View file

@ -43,9 +43,9 @@ Install Extras.
--------------- ---------------
** Music ** ** Music **
- Copy some music files (mp3 for example) to ~/.PySolFC/music/ - Copy some music files (mp3 for example) to ~/.PySolFC/music/
- Original PySol music can be download from: - Original PySol music can be download from:
ftp://ibiblio.org/pub/linux/games/solitaires/pysol-music-4.40.tar.gz ftp://ibiblio.org/pub/linux/games/solitaires/pysol-music-4.40.tar.gz
** Cardsets ** ** Cardsets **

View file

@ -14,7 +14,7 @@
# #
# (1): Find out how many free colors are left in the colormap and # (1): Find out how many free colors are left in the colormap and
# don't allocate too many colors. # don't allocate too many colors.
# (2): Implement HSV color selection. # (2): Implement HSV color selection.
# #
# Make sure namespaces exist # Make sure namespaces exist
@ -56,11 +56,11 @@ proc ::tk::dialog::color:: {args} {
set data(BARS_WIDTH) 160 set data(BARS_WIDTH) 160
# PLGN_WIDTH is the number of pixels wide of the triangular selection # PLGN_WIDTH is the number of pixels wide of the triangular selection
# polygon. This also results in the definition of the padding on the # polygon. This also results in the definition of the padding on the
# left and right sides which is half of PLGN_WIDTH. Make this number even. # left and right sides which is half of PLGN_WIDTH. Make this number even.
set data(PLGN_HEIGHT) 10 set data(PLGN_HEIGHT) 10
# PLGN_HEIGHT is the height of the selection polygon and the height of the # PLGN_HEIGHT is the height of the selection polygon and the height of the
# selection rectangle at the bottom of the color bar. No restrictions. # selection rectangle at the bottom of the color bar. No restrictions.
set data(PLGN_WIDTH) 10 set data(PLGN_WIDTH) 10
@ -230,7 +230,7 @@ proc ::tk::dialog::color::BuildDialog {w} {
bind [::tk::AmpWidget ttk::label $box.label -text $l: -width $maxWidth \ bind [::tk::AmpWidget ttk::label $box.label -text $l: -width $maxWidth \
-anchor ne] <<AltUnderlined>> [list focus $box.entry] -anchor ne] <<AltUnderlined>> [list focus $box.entry]
ttk::entry $box.entry -textvariable \ ttk::entry $box.entry -textvariable \
::tk::dialog::color::[winfo name $w]($color,intensity) \ ::tk::dialog::color::[winfo name $w]($color,intensity) \
-width 4 -width 4
@ -297,7 +297,7 @@ proc ::tk::dialog::color::BuildDialog {w} {
# #
set sep [ttk::separator $w.sep] set sep [ttk::separator $w.sep]
set botFrame [ttk::frame $w.bot] set botFrame [ttk::frame $w.bot]
set maxWidth [::tk::mcmaxamp &OK &Cancel] set maxWidth [::tk::mcmaxamp &OK &Cancel]
set maxWidth [expr {$maxWidth<8?8:$maxWidth}] set maxWidth [expr {$maxWidth<8?8:$maxWidth}]
@ -308,7 +308,7 @@ proc ::tk::dialog::color::BuildDialog {w} {
set data(okBtn) $botFrame.ok set data(okBtn) $botFrame.ok
set data(cancelBtn) $botFrame.cancel set data(cancelBtn) $botFrame.cancel
grid x $botFrame.ok x $botFrame.cancel x -sticky e grid x $botFrame.ok x $botFrame.cancel x -sticky e
grid configure $botFrame.ok -pady 8 grid configure $botFrame.ok -pady 8
grid configure $botFrame.cancel -padx 10 -pady 8 grid configure $botFrame.cancel -padx 10 -pady 8
@ -329,12 +329,12 @@ proc ::tk::dialog::color::BuildDialog {w} {
# Sets the current selection of the dialog box # Sets the current selection of the dialog box
# #
proc ::tk::dialog::color::SetRGBValue {w color} { proc ::tk::dialog::color::SetRGBValue {w color} {
upvar ::tk::dialog::color::[winfo name $w] data upvar ::tk::dialog::color::[winfo name $w] data
set data(red,intensity) [lindex $color 0] set data(red,intensity) [lindex $color 0]
set data(green,intensity) [lindex $color 1] set data(green,intensity) [lindex $color 1]
set data(blue,intensity) [lindex $color 2] set data(blue,intensity) [lindex $color 2]
RedrawColorBars $w all RedrawColorBars $w all
# Now compute the new x value of each colorbars pointer polygon # Now compute the new x value of each colorbars pointer polygon
@ -350,7 +350,7 @@ proc ::tk::dialog::color::SetRGBValue {w color} {
# #
proc ::tk::dialog::color::XToRgb {w x} { proc ::tk::dialog::color::XToRgb {w x} {
upvar ::tk::dialog::color::[winfo name $w] data upvar ::tk::dialog::color::[winfo name $w] data
set x [expr {($x * $data(intensityIncr))/ $data(colorbarWidth)}] set x [expr {($x * $data(intensityIncr))/ $data(colorbarWidth)}]
if {$x > 255} { set x 255 } if {$x > 255} { set x 255 }
return $x return $x
@ -362,13 +362,13 @@ proc ::tk::dialog::color::XToRgb {w x} {
# #
proc ::tk::dialog::color::RgbToX {w color} { proc ::tk::dialog::color::RgbToX {w color} {
upvar ::tk::dialog::color::[winfo name $w] data upvar ::tk::dialog::color::[winfo name $w] data
return [expr {($color * $data(colorbarWidth)/ $data(intensityIncr))}] return [expr {($color * $data(colorbarWidth)/ $data(intensityIncr))}]
} }
# ::tk::dialog::color::DrawColorScale -- # ::tk::dialog::color::DrawColorScale --
# #
# Draw color scale is called whenever the size of one of the color # Draw color scale is called whenever the size of one of the color
# scale canvases is changed. # scale canvases is changed.
# #
@ -393,7 +393,7 @@ proc ::tk::dialog::color::DrawColorScale {w c {create 0}} {
if {[info exists data($c,index)]} { if {[info exists data($c,index)]} {
$sel delete $data($c,index) $sel delete $data($c,index)
} }
# Draw the selection polygons # Draw the selection polygons
CreateSelector $w $sel $c CreateSelector $w $sel $c
$sel bind $data($c,index) <ButtonPress-1> \ $sel bind $data($c,index) <ButtonPress-1> \
@ -426,7 +426,7 @@ proc ::tk::dialog::color::DrawColorScale {w c {create 0}} {
# l is the canvas index of the first colorbar. # l is the canvas index of the first colorbar.
set l $data(lines,$c,start) set l $data(lines,$c,start)
} }
# Draw the color bars. # Draw the color bars.
set highlightW [expr {[$col cget -highlightthickness] + [$col cget -bd]}] set highlightW [expr {[$col cget -highlightthickness] + [$col cget -bd]}]
for {set i 0} { $i < $data(NUM_COLORBARS)} { incr i} { for {set i 0} { $i < $data(NUM_COLORBARS)} { incr i} {
@ -493,7 +493,7 @@ proc ::tk::dialog::color::RedrawFinalColor {w} {
set color [format "#%02x%02x%02x" $data(red,intensity) \ set color [format "#%02x%02x%02x" $data(red,intensity) \
$data(green,intensity) $data(blue,intensity)] $data(green,intensity) $data(blue,intensity)]
$data(finalCanvas) configure -background $color $data(finalCanvas) configure -background $color
set data(finalColor) $color set data(finalColor) $color
set data(selection) $color set data(selection) $color
@ -513,7 +513,7 @@ proc ::tk::dialog::color::RedrawColorBars {w colorChanged} {
upvar ::tk::dialog::color::[winfo name $w] data upvar ::tk::dialog::color::[winfo name $w] data
switch $colorChanged { switch $colorChanged {
red { red {
DrawColorScale $w green DrawColorScale $w green
DrawColorScale $w blue DrawColorScale $w blue
} }
@ -543,7 +543,7 @@ proc ::tk::dialog::color::RedrawColorBars {w colorChanged} {
# Handles a mousedown button event over the selector polygon. # Handles a mousedown button event over the selector polygon.
# Adds the bindings for moving the mouse while the button is # Adds the bindings for moving the mouse while the button is
# pressed. Sets the binding for the button-release event. # pressed. Sets the binding for the button-release event.
# #
# Params: sel is the selector canvas window, color is the color of the strip. # Params: sel is the selector canvas window, color is the color of the strip.
# #
proc ::tk::dialog::color::StartMove {w sel color x delta {dontMove 0}} { proc ::tk::dialog::color::StartMove {w sel color x delta {dontMove 0}} {
@ -555,7 +555,7 @@ proc ::tk::dialog::color::StartMove {w sel color x delta {dontMove 0}} {
} }
# ::tk::dialog::color::MoveSelector -- # ::tk::dialog::color::MoveSelector --
# #
# Moves the polygon selector so that its middle point has the same # Moves the polygon selector so that its middle point has the same
# x value as the specified x. If x is outside the bounds [0,255], # x value as the specified x. If x is outside the bounds [0,255],
# the selector is set to the closest endpoint. # the selector is set to the closest endpoint.
@ -576,7 +576,7 @@ proc ::tk::dialog::color::MoveSelector {w sel color x delta} {
set diff [expr {$x - $data($color,x)}] set diff [expr {$x - $data($color,x)}]
$sel move $data($color,index) $diff 0 $sel move $data($color,index) $diff 0
set data($color,x) [expr {$data($color,x) + $diff}] set data($color,x) [expr {$data($color,x) + $diff}]
# Return the x value that it was actually set at # Return the x value that it was actually set at
return $x return $x
} }
@ -589,10 +589,10 @@ proc ::tk::dialog::color::MoveSelector {w sel color x delta} {
# x is the x-coord of the mouse. # x is the x-coord of the mouse.
# #
proc ::tk::dialog::color::ReleaseMouse {w sel color x delta} { proc ::tk::dialog::color::ReleaseMouse {w sel color x delta} {
upvar ::tk::dialog::color::[winfo name $w] data upvar ::tk::dialog::color::[winfo name $w] data
set x [MoveSelector $w $sel $color $x $delta] set x [MoveSelector $w $sel $color $x $delta]
# Determine exactly what color we are looking at. # Determine exactly what color we are looking at.
set data($color,intensity) [XToRgb $w $x] set data($color,intensity) [XToRgb $w $x]
@ -606,8 +606,8 @@ proc ::tk::dialog::color::ReleaseMouse {w sel color x delta} {
# #
proc ::tk::dialog::color::ResizeColorBars {w} { proc ::tk::dialog::color::ResizeColorBars {w} {
upvar ::tk::dialog::color::[winfo name $w] data upvar ::tk::dialog::color::[winfo name $w] data
if { ($data(BARS_WIDTH) < $data(NUM_COLORBARS)) || if { ($data(BARS_WIDTH) < $data(NUM_COLORBARS)) ||
(($data(BARS_WIDTH) % $data(NUM_COLORBARS)) != 0)} { (($data(BARS_WIDTH) % $data(NUM_COLORBARS)) != 0)} {
set data(BARS_WIDTH) $data(NUM_COLORBARS) set data(BARS_WIDTH) $data(NUM_COLORBARS)
} }
@ -631,7 +631,7 @@ proc ::tk::dialog::color::HandleSelEntry {w} {
set data(selection) $data(finalColor) set data(selection) $data(finalColor)
return return
} }
set R [expr {[lindex $color 0]/0x100}] set R [expr {[lindex $color 0]/0x100}]
set G [expr {[lindex $color 1]/0x100}] set G [expr {[lindex $color 1]/0x100}]
set B [expr {[lindex $color 2]/0x100}] set B [expr {[lindex $color 2]/0x100}]
@ -664,7 +664,7 @@ proc ::tk::dialog::color::HandleRGBEntry {w} {
SetRGBValue $w "$data(red,intensity) \ SetRGBValue $w "$data(red,intensity) \
$data(green,intensity) $data(blue,intensity)" $data(green,intensity) $data(blue,intensity)"
} }
# mouse cursor enters a color bar # mouse cursor enters a color bar
# #

View file

@ -14,7 +14,7 @@
# #
# (1): Find out how many free colors are left in the colormap and # (1): Find out how many free colors are left in the colormap and
# don't allocate too many colors. # don't allocate too many colors.
# (2): Implement HSV color selection. # (2): Implement HSV color selection.
# #
# Make sure namespaces exist # Make sure namespaces exist
@ -56,11 +56,11 @@ proc ::tk::dialog::color:: {args} {
set data(BARS_WIDTH) 160 set data(BARS_WIDTH) 160
# PLGN_WIDTH is the number of pixels wide of the triangular selection # PLGN_WIDTH is the number of pixels wide of the triangular selection
# polygon. This also results in the definition of the padding on the # polygon. This also results in the definition of the padding on the
# left and right sides which is half of PLGN_WIDTH. Make this number even. # left and right sides which is half of PLGN_WIDTH. Make this number even.
set data(PLGN_HEIGHT) 10 set data(PLGN_HEIGHT) 10
# PLGN_HEIGHT is the height of the selection polygon and the height of the # PLGN_HEIGHT is the height of the selection polygon and the height of the
# selection rectangle at the bottom of the color bar. No restrictions. # selection rectangle at the bottom of the color bar. No restrictions.
set data(PLGN_WIDTH) 10 set data(PLGN_WIDTH) 10
@ -230,7 +230,7 @@ proc ::tk::dialog::color::BuildDialog {w} {
bind [::tk::AmpWidget ttk::label $box.label -text $l: -width $maxWidth \ bind [::tk::AmpWidget ttk::label $box.label -text $l: -width $maxWidth \
-anchor ne] <<AltUnderlined>> [list focus $box.entry] -anchor ne] <<AltUnderlined>> [list focus $box.entry]
ttk::entry $box.entry -textvariable \ ttk::entry $box.entry -textvariable \
::tk::dialog::color::[winfo name $w]($color,intensity) \ ::tk::dialog::color::[winfo name $w]($color,intensity) \
-width 4 -width 4
@ -297,7 +297,7 @@ proc ::tk::dialog::color::BuildDialog {w} {
# #
set sep [ttk::separator $w.sep] set sep [ttk::separator $w.sep]
set botFrame [ttk::frame $w.bot] set botFrame [ttk::frame $w.bot]
set maxWidth [::tk::mcmaxamp &OK &Cancel] set maxWidth [::tk::mcmaxamp &OK &Cancel]
set maxWidth [expr {$maxWidth<8?8:$maxWidth}] set maxWidth [expr {$maxWidth<8?8:$maxWidth}]
@ -308,7 +308,7 @@ proc ::tk::dialog::color::BuildDialog {w} {
set data(okBtn) $botFrame.ok set data(okBtn) $botFrame.ok
set data(cancelBtn) $botFrame.cancel set data(cancelBtn) $botFrame.cancel
grid x $botFrame.ok x $botFrame.cancel x -sticky e grid x $botFrame.ok x $botFrame.cancel x -sticky e
grid configure $botFrame.ok -pady 8 grid configure $botFrame.ok -pady 8
grid configure $botFrame.cancel -padx 10 -pady 8 grid configure $botFrame.cancel -padx 10 -pady 8
@ -329,12 +329,12 @@ proc ::tk::dialog::color::BuildDialog {w} {
# Sets the current selection of the dialog box # Sets the current selection of the dialog box
# #
proc ::tk::dialog::color::SetRGBValue {w color} { proc ::tk::dialog::color::SetRGBValue {w color} {
upvar ::tk::dialog::color::[winfo name $w] data upvar ::tk::dialog::color::[winfo name $w] data
set data(red,intensity) [lindex $color 0] set data(red,intensity) [lindex $color 0]
set data(green,intensity) [lindex $color 1] set data(green,intensity) [lindex $color 1]
set data(blue,intensity) [lindex $color 2] set data(blue,intensity) [lindex $color 2]
RedrawColorBars $w all RedrawColorBars $w all
# Now compute the new x value of each colorbars pointer polygon # Now compute the new x value of each colorbars pointer polygon
@ -350,7 +350,7 @@ proc ::tk::dialog::color::SetRGBValue {w color} {
# #
proc ::tk::dialog::color::XToRgb {w x} { proc ::tk::dialog::color::XToRgb {w x} {
upvar ::tk::dialog::color::[winfo name $w] data upvar ::tk::dialog::color::[winfo name $w] data
set x [expr {($x * $data(intensityIncr))/ $data(colorbarWidth)}] set x [expr {($x * $data(intensityIncr))/ $data(colorbarWidth)}]
if {$x > 255} { set x 255 } if {$x > 255} { set x 255 }
return $x return $x
@ -362,13 +362,13 @@ proc ::tk::dialog::color::XToRgb {w x} {
# #
proc ::tk::dialog::color::RgbToX {w color} { proc ::tk::dialog::color::RgbToX {w color} {
upvar ::tk::dialog::color::[winfo name $w] data upvar ::tk::dialog::color::[winfo name $w] data
return [expr {($color * $data(colorbarWidth)/ $data(intensityIncr))}] return [expr {($color * $data(colorbarWidth)/ $data(intensityIncr))}]
} }
# ::tk::dialog::color::DrawColorScale -- # ::tk::dialog::color::DrawColorScale --
# #
# Draw color scale is called whenever the size of one of the color # Draw color scale is called whenever the size of one of the color
# scale canvases is changed. # scale canvases is changed.
# #
@ -393,7 +393,7 @@ proc ::tk::dialog::color::DrawColorScale {w c {create 0}} {
if {[info exists data($c,index)]} { if {[info exists data($c,index)]} {
$sel delete $data($c,index) $sel delete $data($c,index)
} }
# Draw the selection polygons # Draw the selection polygons
CreateSelector $w $sel $c CreateSelector $w $sel $c
$sel bind $data($c,index) <ButtonPress-1> \ $sel bind $data($c,index) <ButtonPress-1> \
@ -426,7 +426,7 @@ proc ::tk::dialog::color::DrawColorScale {w c {create 0}} {
# l is the canvas index of the first colorbar. # l is the canvas index of the first colorbar.
set l $data(lines,$c,start) set l $data(lines,$c,start)
} }
# Draw the color bars. # Draw the color bars.
set highlightW [expr {[$col cget -highlightthickness] + [$col cget -bd]}] set highlightW [expr {[$col cget -highlightthickness] + [$col cget -bd]}]
for {set i 0} { $i < $data(NUM_COLORBARS)} { incr i} { for {set i 0} { $i < $data(NUM_COLORBARS)} { incr i} {
@ -493,7 +493,7 @@ proc ::tk::dialog::color::RedrawFinalColor {w} {
set color [format "#%02x%02x%02x" $data(red,intensity) \ set color [format "#%02x%02x%02x" $data(red,intensity) \
$data(green,intensity) $data(blue,intensity)] $data(green,intensity) $data(blue,intensity)]
$data(finalCanvas) configure -background $color $data(finalCanvas) configure -background $color
set data(finalColor) $color set data(finalColor) $color
set data(selection) $color set data(selection) $color
@ -513,7 +513,7 @@ proc ::tk::dialog::color::RedrawColorBars {w colorChanged} {
upvar ::tk::dialog::color::[winfo name $w] data upvar ::tk::dialog::color::[winfo name $w] data
switch $colorChanged { switch $colorChanged {
red { red {
DrawColorScale $w green DrawColorScale $w green
DrawColorScale $w blue DrawColorScale $w blue
} }
@ -543,7 +543,7 @@ proc ::tk::dialog::color::RedrawColorBars {w colorChanged} {
# Handles a mousedown button event over the selector polygon. # Handles a mousedown button event over the selector polygon.
# Adds the bindings for moving the mouse while the button is # Adds the bindings for moving the mouse while the button is
# pressed. Sets the binding for the button-release event. # pressed. Sets the binding for the button-release event.
# #
# Params: sel is the selector canvas window, color is the color of the strip. # Params: sel is the selector canvas window, color is the color of the strip.
# #
proc ::tk::dialog::color::StartMove {w sel color x delta {dontMove 0}} { proc ::tk::dialog::color::StartMove {w sel color x delta {dontMove 0}} {
@ -555,7 +555,7 @@ proc ::tk::dialog::color::StartMove {w sel color x delta {dontMove 0}} {
} }
# ::tk::dialog::color::MoveSelector -- # ::tk::dialog::color::MoveSelector --
# #
# Moves the polygon selector so that its middle point has the same # Moves the polygon selector so that its middle point has the same
# x value as the specified x. If x is outside the bounds [0,255], # x value as the specified x. If x is outside the bounds [0,255],
# the selector is set to the closest endpoint. # the selector is set to the closest endpoint.
@ -576,7 +576,7 @@ proc ::tk::dialog::color::MoveSelector {w sel color x delta} {
set diff [expr {$x - $data($color,x)}] set diff [expr {$x - $data($color,x)}]
$sel move $data($color,index) $diff 0 $sel move $data($color,index) $diff 0
set data($color,x) [expr {$data($color,x) + $diff}] set data($color,x) [expr {$data($color,x) + $diff}]
# Return the x value that it was actually set at # Return the x value that it was actually set at
return $x return $x
} }
@ -589,10 +589,10 @@ proc ::tk::dialog::color::MoveSelector {w sel color x delta} {
# x is the x-coord of the mouse. # x is the x-coord of the mouse.
# #
proc ::tk::dialog::color::ReleaseMouse {w sel color x delta} { proc ::tk::dialog::color::ReleaseMouse {w sel color x delta} {
upvar ::tk::dialog::color::[winfo name $w] data upvar ::tk::dialog::color::[winfo name $w] data
set x [MoveSelector $w $sel $color $x $delta] set x [MoveSelector $w $sel $color $x $delta]
# Determine exactly what color we are looking at. # Determine exactly what color we are looking at.
set data($color,intensity) [XToRgb $w $x] set data($color,intensity) [XToRgb $w $x]
@ -606,8 +606,8 @@ proc ::tk::dialog::color::ReleaseMouse {w sel color x delta} {
# #
proc ::tk::dialog::color::ResizeColorBars {w} { proc ::tk::dialog::color::ResizeColorBars {w} {
upvar ::tk::dialog::color::[winfo name $w] data upvar ::tk::dialog::color::[winfo name $w] data
if { ($data(BARS_WIDTH) < $data(NUM_COLORBARS)) || if { ($data(BARS_WIDTH) < $data(NUM_COLORBARS)) ||
(($data(BARS_WIDTH) % $data(NUM_COLORBARS)) != 0)} { (($data(BARS_WIDTH) % $data(NUM_COLORBARS)) != 0)} {
set data(BARS_WIDTH) $data(NUM_COLORBARS) set data(BARS_WIDTH) $data(NUM_COLORBARS)
} }
@ -631,7 +631,7 @@ proc ::tk::dialog::color::HandleSelEntry {w} {
set data(selection) $data(finalColor) set data(selection) $data(finalColor)
return return
} }
set R [expr {[lindex $color 0]/0x100}] set R [expr {[lindex $color 0]/0x100}]
set G [expr {[lindex $color 1]/0x100}] set G [expr {[lindex $color 1]/0x100}]
set B [expr {[lindex $color 2]/0x100}] set B [expr {[lindex $color 2]/0x100}]
@ -664,7 +664,7 @@ proc ::tk::dialog::color::HandleRGBEntry {w} {
SetRGBValue $w "$data(red,intensity) \ SetRGBValue $w "$data(red,intensity) \
$data(green,intensity) $data(blue,intensity)" $data(green,intensity) $data(blue,intensity)"
} }
# mouse cursor enters a color bar # mouse cursor enters a color bar
# #

View file

@ -330,7 +330,7 @@ proc ::ttk::dialog::file::Create {win class} {
set f1 [ttk::frame $w.f1 -class Toolbar] set f1 [ttk::frame $w.f1 -class Toolbar]
set data(bgLabel) [ttk::label $f1.bg -style Toolbutton] set data(bgLabel) [ttk::label $f1.bg -style Toolbutton]
set data(upBtn) [ttk::button $f1.up -style Toolbutton] set data(upBtn) [ttk::button $f1.up -style Toolbutton]
$data(upBtn) configure -image {::ttk::dialog::image::up $data(upBtn) configure -image {::ttk::dialog::image::up
disabled ::ttk::dialog::image::upbw} \ disabled ::ttk::dialog::image::upbw} \
-command [list ::ttk::dialog::file::UpDirCmd $win] -command [list ::ttk::dialog::file::UpDirCmd $win]
set data(prevBtn) [ttk::button $f1.prev -style Toolbutton] set data(prevBtn) [ttk::button $f1.prev -style Toolbutton]
@ -671,7 +671,7 @@ proc ::ttk::dialog::file::Update {w} {
lappend dlist [list $f dir] lappend dlist [list $f dir]
} }
# Make the file list # Make the file list
set flist "" set flist ""
set filter $data(filter) set filter $data(filter)
if {[string equal $filter *]} { if {[string equal $filter *]} {
@ -695,8 +695,8 @@ proc ::ttk::dialog::file::Update {w} {
set flist [sort $w [concat $flist $dlist]] set flist [sort $w [concat $flist $dlist]]
set dlist "" set dlist ""
} }
set t $data(dirArea) set t $data(dirArea)
$t configure -state normal $t configure -state normal
$t delete 1.0 end $t delete 1.0 end
foreach f $dlist { foreach f $dlist {
@ -735,7 +735,7 @@ proc ::ttk::dialog::file::Update {w} {
} else { } else {
set groups($gid) "" set groups($gid) ""
} }
} }
} }
catch {set uid $users($uid)} catch {set uid $users($uid)}
catch {set gid $groups($gid)} catch {set gid $groups($gid)}
@ -902,9 +902,9 @@ proc ::ttk::dialog::file::setopt {w option var} {
set dataName [winfo name $w] set dataName [winfo name $w]
upvar ::ttk::dialog::file::$dataName data upvar ::ttk::dialog::file::$dataName data
upvar #0 $var value upvar #0 $var value
set data($option) $value set data($option) $value
UpdateWhenIdle $w UpdateWhenIdle $w
} }
proc ::ttk::dialog::file::UpDirCmd {w} { proc ::ttk::dialog::file::UpDirCmd {w} {
@ -1371,7 +1371,7 @@ proc ::ttk::dialog::file::treeCreate {w} {
pack $f2 -side top -fill both -expand 1 pack $f2 -side top -fill both -expand 1
$data(text) image create end -padx 1 \ $data(text) image create end -padx 1 \
-image ::ttk::dialog::image::folder -image ::ttk::dialog::image::folder
$data(text) insert end " /" name $data(text) insert end " /" name
$data(text) configure -state disabled $data(text) configure -state disabled

View file

@ -330,7 +330,7 @@ proc ::ttk::dialog::file::Create {win class} {
set f1 [ttk::frame $w.f1 -class Toolbar] set f1 [ttk::frame $w.f1 -class Toolbar]
set data(bgLabel) [ttk::label $f1.bg -style Toolbutton] set data(bgLabel) [ttk::label $f1.bg -style Toolbutton]
set data(upBtn) [ttk::button $f1.up -style Toolbutton] set data(upBtn) [ttk::button $f1.up -style Toolbutton]
$data(upBtn) configure -image {::ttk::dialog::image::up $data(upBtn) configure -image {::ttk::dialog::image::up
disabled ::ttk::dialog::image::upbw} \ disabled ::ttk::dialog::image::upbw} \
-command [list ::ttk::dialog::file::UpDirCmd $win] -command [list ::ttk::dialog::file::UpDirCmd $win]
set data(prevBtn) [ttk::button $f1.prev -style Toolbutton] set data(prevBtn) [ttk::button $f1.prev -style Toolbutton]
@ -671,7 +671,7 @@ proc ::ttk::dialog::file::Update {w} {
lappend dlist [list $f dir] lappend dlist [list $f dir]
} }
# Make the file list # Make the file list
set flist "" set flist ""
set filter $data(filter) set filter $data(filter)
if {[string equal $filter *]} { if {[string equal $filter *]} {
@ -695,8 +695,8 @@ proc ::ttk::dialog::file::Update {w} {
set flist [sort $w [concat $flist $dlist]] set flist [sort $w [concat $flist $dlist]]
set dlist "" set dlist ""
} }
set t $data(dirArea) set t $data(dirArea)
$t configure -state normal $t configure -state normal
$t delete 1.0 end $t delete 1.0 end
foreach f $dlist { foreach f $dlist {
@ -735,7 +735,7 @@ proc ::ttk::dialog::file::Update {w} {
} else { } else {
set groups($gid) "" set groups($gid) ""
} }
} }
} }
catch {set uid $users($uid)} catch {set uid $users($uid)}
catch {set gid $groups($gid)} catch {set gid $groups($gid)}
@ -902,9 +902,9 @@ proc ::ttk::dialog::file::setopt {w option var} {
set dataName [winfo name $w] set dataName [winfo name $w]
upvar ::ttk::dialog::file::$dataName data upvar ::ttk::dialog::file::$dataName data
upvar #0 $var value upvar #0 $var value
set data($option) $value set data($option) $value
UpdateWhenIdle $w UpdateWhenIdle $w
} }
proc ::ttk::dialog::file::UpDirCmd {w} { proc ::ttk::dialog::file::UpDirCmd {w} {
@ -1371,7 +1371,7 @@ proc ::ttk::dialog::file::treeCreate {w} {
pack $f2 -side top -fill both -expand 1 pack $f2 -side top -fill both -expand 1
$data(text) image create end -padx 1 \ $data(text) image create end -padx 1 \
-image ::ttk::dialog::image::folder -image ::ttk::dialog::image::folder
$data(text) insert end " /" name $data(text) insert end " /" name
$data(text) configure -state disabled $data(text) configure -state disabled

View file

@ -36,7 +36,7 @@ set myMenuMotion 0
# ::tk::MenuNextEntry -- # ::tk::MenuNextEntry --
# Activate the next higher or lower entry in the posted menu, # Activate the next higher or lower entry in the posted menu,
# wrapping around at the ends. Disabled entries are skipped. # wrapping around at the ends. Disabled entries are skipped.
# #
# Arguments: # Arguments:
# menu - Menu window that received the keystroke. # menu - Menu window that received the keystroke.
# count - 1 means go to the next lower entry, # count - 1 means go to the next lower entry,
@ -98,7 +98,7 @@ proc ::tk::MenuNextEntry {menu count} {
# This procedure is invoked to handle "left" and "right" traversal # This procedure is invoked to handle "left" and "right" traversal
# motions in menus. It traverses to the next menu in a menu bar, # motions in menus. It traverses to the next menu in a menu bar,
# or into or out of a cascaded menu. # or into or out of a cascaded menu.
# #
# Arguments: # Arguments:
# menu - The menu that received the keyboard # menu - The menu that received the keyboard
# event. # event.
@ -253,13 +253,13 @@ proc ::tk::MenuFirstEntry menu {
# state - Modifier state (tells whether buttons are down). # state - Modifier state (tells whether buttons are down).
proc ::tk::MenuMotion {menu x y state} { proc ::tk::MenuMotion {menu x y state} {
global ::tk::Priv global ::tk::Priv
if {$menu eq $::tk::Priv(window)} { if {$menu eq $::tk::Priv(window)} {
if {[$menu cget -type] eq "menubar"} { if {[$menu cget -type] eq "menubar"} {
if {[info exists ::tk::Priv(focus)] && $menu ne $::tk::Priv(focus)} { if {[info exists ::tk::Priv(focus)] && $menu ne $::tk::Priv(focus)} {
$menu activate @$x,$y $menu activate @$x,$y
::tk::GenerateMenuSelect $menu ::tk::GenerateMenuSelect $menu
} }
} else { } else {
$menu activate @$x,$y $menu activate @$x,$y
::tk::GenerateMenuSelect $menu ::tk::GenerateMenuSelect $menu
@ -329,7 +329,7 @@ proc ::tk::MenuButtonDown menu {
grab -global $menu grab -global $menu
} }
} }
} }
set myPriv(id) "" set myPriv(id) ""
set myPriv(delay) 170 set myPriv(delay) 170

View file

@ -11,7 +11,7 @@ namespace eval tile::theme::blue {
variable I variable I
array set I [tile::LoadImages \ array set I [tile::LoadImages \
[file join [file dirname [info script]] blue] *.gif] [file join [file dirname [info script]] blue] *.gif]
variable colors variable colors
array set colors { array set colors {
-frame "#6699cc" -frame "#6699cc"
@ -72,12 +72,12 @@ namespace eval tile::theme::blue {
style configure Toolbutton \ style configure Toolbutton \
-width 0 -relief flat -borderwidth 2 -padding 4 \ -width 0 -relief flat -borderwidth 2 -padding 4 \
-background $colors(-frame) -foreground #000000 ; -background $colors(-frame) -foreground #000000 ;
style map Toolbutton -background [list active $colors(-selectbg)] style map Toolbutton -background [list active $colors(-selectbg)]
style map Toolbutton -foreground [list active $colors(-selectfg)] style map Toolbutton -foreground [list active $colors(-selectfg)]
style map Toolbutton -relief { style map Toolbutton -relief {
disabled flat disabled flat
selected sunken selected sunken
pressed sunken pressed sunken
active raised active raised
} }

View file

@ -23,7 +23,7 @@ namespace eval ttk::theme::blue {
variable I variable I
array set I [LoadImages \ array set I [LoadImages \
[file join [file dirname [info script]] blue] *.gif] [file join [file dirname [info script]] blue] *.gif]
variable colors variable colors
array set colors { array set colors {
-frame "#6699cc" -frame "#6699cc"
@ -88,12 +88,12 @@ namespace eval ttk::theme::blue {
ttk::style configure Toolbutton \ ttk::style configure Toolbutton \
-width 0 -relief flat -borderwidth 2 -padding 4 \ -width 0 -relief flat -borderwidth 2 -padding 4 \
-background $colors(-frame) -foreground #000000 ; -background $colors(-frame) -foreground #000000 ;
ttk::style map Toolbutton -background [list active $colors(-selectbg)] ttk::style map Toolbutton -background [list active $colors(-selectbg)]
ttk::style map Toolbutton -foreground [list active $colors(-selectfg)] ttk::style map Toolbutton -foreground [list active $colors(-selectfg)]
ttk::style map Toolbutton -relief { ttk::style map Toolbutton -relief {
disabled flat disabled flat
selected sunken selected sunken
pressed sunken pressed sunken
active raised active raised
} }

View file

@ -7,7 +7,7 @@ namespace eval tile::theme::clearlooks {
variable I variable I
array set I [tile::LoadImages \ array set I [tile::LoadImages \
[file join [file dirname [info script]] clearlooks] *.gif] [file join [file dirname [info script]] clearlooks] *.gif]
variable colors variable colors
array set colors { array set colors {

View file

@ -19,7 +19,7 @@ namespace eval ttk::theme::clearlooks {
variable I variable I
array set I [LoadImages \ array set I [LoadImages \
[file join [file dirname [info script]] clearlooks] *.gif] [file join [file dirname [info script]] clearlooks] *.gif]
variable colors variable colors
array set colors { array set colors {

View file

@ -11,7 +11,7 @@ PySolFC \- a collection of more than 1000 solitaire games
.SH "DESCRIPTION" .SH "DESCRIPTION"
.IX Header "DESCRIPTION" .IX Header "DESCRIPTION"
\&\fBPySolFC\fR is a collection of more than 1000 solitaire card games. \&\fBPySolFC\fR is a collection of more than 1000 solitaire card games.
It stands for PySol Fan Club Edition, as it is a fork of It stands for PySol Fan Club Edition, as it is a fork of
(the now unmaintained) PySol Solitaire. (the now unmaintained) PySol Solitaire.
.PP .PP
There are games that use the 52 card International Pattern deck, There are games that use the 52 card International Pattern deck,

View file

@ -7230,7 +7230,7 @@ not restricted and there are no "free" cells.
<h3>Rules</h3> <h3>Rules</h3>
<p> <p>
All cards are dealt to 9 piles at the start of the game, each first rank card All cards are dealt to 9 piles at the start of the game, each first rank card
starting a new pile. starting a new pile.
<p> <p>
Piles build from first rank to fourth, and an empty space cannot be filled. Piles build from first rank to fourth, and an empty space cannot be filled.
<h1>Yukon</h1> <h1>Yukon</h1>

View file

@ -20,7 +20,7 @@ completely filled. At that point, move to Phase Two. Please note that
you cannot begin Phase Two unless Tableau is completely filled. At any you cannot begin Phase Two unless Tableau is completely filled. At any
point, you can return to Phase One, but remember that you cannot go back point, you can return to Phase One, but remember that you cannot go back
to Phase Two unless the tableau is once again filled. An exception to to Phase Two unless the tableau is once again filled. An exception to
this rule is if the stock and waste are empty. this rule is if the stock and waste are empty.
<p> <p>
Phase One -- Click on the Stock to move a card into the empty Waste pile. If Phase One -- Click on the Stock to move a card into the empty Waste pile. If

View file

@ -15,6 +15,6 @@ not restricted and there are no "free" cells.
<h3>Rules</h3> <h3>Rules</h3>
<p> <p>
All cards are dealt to 9 piles at the start of the game, each first rank card All cards are dealt to 9 piles at the start of the game, each first rank card
starting a new pile. starting a new pile.
<p> <p>
Piles build from first rank to fourth, and an empty space cannot be filled. Piles build from first rank to fourth, and an empty space cannot be filled.

View file

@ -168,29 +168,29 @@ class UnknownType(Exception):
pass pass
class Builder: class Builder:
def build(self, o): def build(self, o):
m = getattr(self, 'build_' + o.__class__.__name__, None) m = getattr(self, 'build_' + o.__class__.__name__, None)
if m is None: if m is None:
raise UnknownType(o.__class__.__name__) raise UnknownType(o.__class__.__name__)
return m(o) return m(o)
def build_List(self, o): def build_List(self, o):
return map(self.build, o.getChildren()) return map(self.build, o.getChildren())
def build_Const(self, o): def build_Const(self, o):
return o.value return o.value
def build_Dict(self, o): def build_Dict(self, o):
d = {} d = {}
i = iter(map(self.build, o.getChildren())) i = iter(map(self.build, o.getChildren()))
for el in i: for el in i:
d[el] = i.next() d[el] = i.next()
return d return d
def build_Tuple(self, o): def build_Tuple(self, o):
return tuple(self.build_List(o)) return tuple(self.build_List(o))
def build_Name(self, o): def build_Name(self, o):
if o.name == 'None': if o.name == 'None':
return None return None
@ -198,10 +198,10 @@ class Builder:
return True return True
if o.name == 'False': if o.name == 'False':
return False return False
# An undefinted Name # An undefinted Name
raise UnknownType('Undefined Name') raise UnknownType('Undefined Name')
def build_Add(self, o): def build_Add(self, o):
real, imag = map(self.build_Const, o.getChildren()) real, imag = map(self.build_Const, o.getChildren())
try: try:
@ -211,14 +211,14 @@ class Builder:
if not isinstance(imag, complex) or imag.real != 0.0: if not isinstance(imag, complex) or imag.real != 0.0:
raise UnknownType('Add') raise UnknownType('Add')
return real+imag return real+imag
def build_Getattr(self, o): def build_Getattr(self, o):
parent = self.build(o.expr) parent = self.build(o.expr)
return getattr(parent, o.attrname) return getattr(parent, o.attrname)
def build_UnarySub(self, o): def build_UnarySub(self, o):
return -self.build_Const(o.getChildren()[0]) return -self.build_Const(o.getChildren()[0])
def build_UnaryAdd(self, o): def build_UnaryAdd(self, o):
return self.build_Const(o.getChildren()[0]) return self.build_Const(o.getChildren()[0])
@ -229,7 +229,7 @@ def unrepr(s):
def _splitlines(instring): def _splitlines(instring):
"""Split a string on lines, without losing line endings or truncating.""" """Split a string on lines, without losing line endings or truncating."""
class ConfigObjError(SyntaxError): class ConfigObjError(SyntaxError):
""" """
@ -406,7 +406,7 @@ class InterpolationEngine(object):
(e.g., if we interpolated "$$" and returned "$"). (e.g., if we interpolated "$$" and returned "$").
""" """
raise NotImplementedError raise NotImplementedError
class ConfigParserInterpolation(InterpolationEngine): class ConfigParserInterpolation(InterpolationEngine):
"""Behaves like ConfigParser.""" """Behaves like ConfigParser."""
@ -450,18 +450,18 @@ interpolation_engines = {
class Section(dict): class Section(dict):
""" """
A dictionary-like object that represents a section in a config file. A dictionary-like object that represents a section in a config file.
It does string interpolation if the 'interpolation' attribute It does string interpolation if the 'interpolation' attribute
of the 'main' object is set to True. of the 'main' object is set to True.
Interpolation is tried first from this object, then from the 'DEFAULT' Interpolation is tried first from this object, then from the 'DEFAULT'
section of this object, next from the parent and its 'DEFAULT' section, section of this object, next from the parent and its 'DEFAULT' section,
and so on until the main object is reached. and so on until the main object is reached.
A Section will behave like an ordered dictionary - following the A Section will behave like an ordered dictionary - following the
order of the ``scalars`` and ``sections`` attributes. order of the ``scalars`` and ``sections`` attributes.
You can use this to change the order of members. You can use this to change the order of members.
Iteration follows the order: scalars, then sections. Iteration follows the order: scalars, then sections.
""" """
@ -537,14 +537,14 @@ class Section(dict):
def __setitem__(self, key, value, unrepr=False): def __setitem__(self, key, value, unrepr=False):
""" """
Correctly set a value. Correctly set a value.
Making dictionary values Section instances. Making dictionary values Section instances.
(We have to special case 'Section' instances - which are also dicts) (We have to special case 'Section' instances - which are also dicts)
Keys must be strings. Keys must be strings.
Values need only be strings (or lists of strings) if Values need only be strings (or lists of strings) if
``main.stringify`` is set. ``main.stringify`` is set.
`unrepr`` must be set when setting a value to a dictionary, without `unrepr`` must be set when setting a value to a dictionary, without
creating a new sub-section. creating a new sub-section.
""" """
@ -645,7 +645,7 @@ class Section(dict):
""" """
A version of clear that also affects scalars/sections A version of clear that also affects scalars/sections
Also clears comments and configspec. Also clears comments and configspec.
Leaves other attributes alone : Leaves other attributes alone :
depth/main/parent are not affected depth/main/parent are not affected
""" """
@ -701,10 +701,10 @@ class Section(dict):
def dict(self): def dict(self):
""" """
Return a deepcopy of self as a dictionary. Return a deepcopy of self as a dictionary.
All members that are ``Section`` instances are recursively turned to All members that are ``Section`` instances are recursively turned to
ordinary dictionaries - by calling their ``dict`` method. ordinary dictionaries - by calling their ``dict`` method.
>>> n = a.dict() >>> n = a.dict()
>>> n == a >>> n == a
1 1
@ -728,7 +728,7 @@ class Section(dict):
def merge(self, indict): def merge(self, indict):
""" """
A recursive update - useful for merging config files. A recursive update - useful for merging config files.
>>> a = '''[section1] >>> a = '''[section1]
... option1 = True ... option1 = True
... [[subsection]] ... [[subsection]]
@ -748,16 +748,16 @@ class Section(dict):
if (key in self and isinstance(self[key], dict) and if (key in self and isinstance(self[key], dict) and
isinstance(val, dict)): isinstance(val, dict)):
self[key].merge(val) self[key].merge(val)
else: else:
self[key] = val self[key] = val
def rename(self, oldkey, newkey): def rename(self, oldkey, newkey):
""" """
Change a keyname to another, without changing position in sequence. Change a keyname to another, without changing position in sequence.
Implemented so that transformations can be made on keys, Implemented so that transformations can be made on keys,
as well as on values. (used by encode and decode) as well as on values. (used by encode and decode)
Also renames comments. Also renames comments.
""" """
if oldkey in self.scalars: if oldkey in self.scalars:
@ -784,30 +784,30 @@ class Section(dict):
call_on_sections=False, **keywargs): call_on_sections=False, **keywargs):
""" """
Walk every member and call a function on the keyword and value. Walk every member and call a function on the keyword and value.
Return a dictionary of the return values Return a dictionary of the return values
If the function raises an exception, raise the errror If the function raises an exception, raise the errror
unless ``raise_errors=False``, in which case set the return value to unless ``raise_errors=False``, in which case set the return value to
``False``. ``False``.
Any unrecognised keyword arguments you pass to walk, will be pased on Any unrecognised keyword arguments you pass to walk, will be pased on
to the function you pass in. to the function you pass in.
Note: if ``call_on_sections`` is ``True`` then - on encountering a Note: if ``call_on_sections`` is ``True`` then - on encountering a
subsection, *first* the function is called for the *whole* subsection, subsection, *first* the function is called for the *whole* subsection,
and then recurses into it's members. This means your function must be and then recurses into it's members. This means your function must be
able to handle strings, dictionaries and lists. This allows you able to handle strings, dictionaries and lists. This allows you
to change the key of subsections as well as for ordinary members. The to change the key of subsections as well as for ordinary members. The
return value when called on the whole subsection has to be discarded. return value when called on the whole subsection has to be discarded.
See the encode and decode methods for examples, including functions. See the encode and decode methods for examples, including functions.
.. caution:: .. caution::
You can use ``walk`` to transform the names of members of a section You can use ``walk`` to transform the names of members of a section
but you mustn't add or delete members. but you mustn't add or delete members.
>>> config = '''[XXXXsection] >>> config = '''[XXXXsection]
... XXXXkey = XXXXvalue'''.splitlines() ... XXXXkey = XXXXvalue'''.splitlines()
>>> cfg = ConfigObj(config) >>> cfg = ConfigObj(config)
@ -867,11 +867,11 @@ class Section(dict):
def decode(self, encoding): def decode(self, encoding):
""" """
Decode all strings and values to unicode, using the specified encoding. Decode all strings and values to unicode, using the specified encoding.
Works with subsections and list values. Works with subsections and list values.
Uses the ``walk`` method. Uses the ``walk`` method.
Testing ``encode`` and ``decode``. Testing ``encode`` and ``decode``.
>>> m = ConfigObj(a) >>> m = ConfigObj(a)
>>> m.decode('ascii') >>> m.decode('ascii')
@ -911,7 +911,7 @@ class Section(dict):
""" """
Encode all strings and values from unicode, Encode all strings and values from unicode,
using the specified encoding. using the specified encoding.
Works with subsections and list values. Works with subsections and list values.
Uses the ``walk`` method. Uses the ``walk`` method.
""" """
@ -943,17 +943,17 @@ class Section(dict):
Accepts a key as input. The corresponding value must be a string or Accepts a key as input. The corresponding value must be a string or
the objects (``True`` or 1) or (``False`` or 0). We allow 0 and 1 to the objects (``True`` or 1) or (``False`` or 0). We allow 0 and 1 to
retain compatibility with Python 2.2. retain compatibility with Python 2.2.
If the string is one of ``True``, ``On``, ``Yes``, or ``1`` it returns If the string is one of ``True``, ``On``, ``Yes``, or ``1`` it returns
``True``. ``True``.
If the string is one of ``False``, ``Off``, ``No``, or ``0`` it returns If the string is one of ``False``, ``Off``, ``No``, or ``0`` it returns
``False``. ``False``.
``as_bool`` is not case sensitive. ``as_bool`` is not case sensitive.
Any other input will raise a ``ValueError``. Any other input will raise a ``ValueError``.
>>> a = ConfigObj() >>> a = ConfigObj()
>>> a['a'] = 'fish' >>> a['a'] = 'fish'
>>> a.as_bool('a') >>> a.as_bool('a')
@ -983,10 +983,10 @@ class Section(dict):
def as_int(self, key): def as_int(self, key):
""" """
A convenience method which coerces the specified value to an integer. A convenience method which coerces the specified value to an integer.
If the value is an invalid literal for ``int``, a ``ValueError`` will If the value is an invalid literal for ``int``, a ``ValueError`` will
be raised. be raised.
>>> a = ConfigObj() >>> a = ConfigObj()
>>> a['a'] = 'fish' >>> a['a'] = 'fish'
>>> a.as_int('a') >>> a.as_int('a')
@ -1005,10 +1005,10 @@ class Section(dict):
def as_float(self, key): def as_float(self, key):
""" """
A convenience method which coerces the specified value to a float. A convenience method which coerces the specified value to a float.
If the value is an invalid literal for ``float``, a ``ValueError`` will If the value is an invalid literal for ``float``, a ``ValueError`` will
be raised. be raised.
>>> a = ConfigObj() >>> a = ConfigObj()
>>> a['a'] = 'fish' >>> a['a'] = 'fish'
>>> a.as_float('a') >>> a.as_float('a')
@ -1022,7 +1022,7 @@ class Section(dict):
3.2000000000000002 3.2000000000000002
""" """
return float(self[key]) return float(self[key])
class ConfigObj(Section): class ConfigObj(Section):
"""An object to read, create, and write config files.""" """An object to read, create, and write config files."""
@ -1129,7 +1129,7 @@ class ConfigObj(Section):
def __init__(self, infile=None, options=None, **kwargs): def __init__(self, infile=None, options=None, **kwargs):
""" """
Parse or create a config file object. Parse or create a config file object.
``ConfigObj(infile=None, options=None, **kwargs)`` ``ConfigObj(infile=None, options=None, **kwargs)``
""" """
if infile is None: if infile is None:
@ -1257,31 +1257,31 @@ class ConfigObj(Section):
self.configspec = None self.configspec = None
else: else:
self._handle_configspec(defaults['configspec']) self._handle_configspec(defaults['configspec'])
def __repr__(self): def __repr__(self):
return 'ConfigObj({%s})' % ', '.join( return 'ConfigObj({%s})' % ', '.join(
[('%s: %s' % (repr(key), repr(self[key]))) for key in [('%s: %s' % (repr(key), repr(self[key]))) for key in
(self.scalars + self.sections)]) (self.scalars + self.sections)])
def _handle_bom(self, infile): def _handle_bom(self, infile):
""" """
Handle any BOM, and decode if necessary. Handle any BOM, and decode if necessary.
If an encoding is specified, that *must* be used - but the BOM should If an encoding is specified, that *must* be used - but the BOM should
still be removed (and the BOM attribute set). still be removed (and the BOM attribute set).
(If the encoding is wrongly specified, then a BOM for an alternative (If the encoding is wrongly specified, then a BOM for an alternative
encoding won't be discovered or removed.) encoding won't be discovered or removed.)
If an encoding is not specified, UTF8 or UTF16 BOM will be detected and If an encoding is not specified, UTF8 or UTF16 BOM will be detected and
removed. The BOM attribute will be set. UTF16 will be decoded to removed. The BOM attribute will be set. UTF16 will be decoded to
unicode. unicode.
NOTE: This method must not be called with an empty ``infile``. NOTE: This method must not be called with an empty ``infile``.
Specifying the *wrong* encoding is likely to cause a Specifying the *wrong* encoding is likely to cause a
``UnicodeDecodeError``. ``UnicodeDecodeError``.
``infile`` must always be returned as a list of lines, but may be ``infile`` must always be returned as a list of lines, but may be
passed in as a single string. passed in as a single string.
""" """
@ -1374,7 +1374,7 @@ class ConfigObj(Section):
def _decode(self, infile, encoding): def _decode(self, infile, encoding):
""" """
Decode infile to unicode. Using the specified encoding. Decode infile to unicode. Using the specified encoding.
if is a string, it also needs converting to a list. if is a string, it also needs converting to a list.
""" """
if isinstance(infile, StringTypes): if isinstance(infile, StringTypes):
@ -1581,7 +1581,7 @@ class ConfigObj(Section):
""" """
Given a section and a depth level, walk back through the sections Given a section and a depth level, walk back through the sections
parents to see if the depth level matches a previous section. parents to see if the depth level matches a previous section.
Return a reference to the right section, Return a reference to the right section,
or raise a SyntaxError. or raise a SyntaxError.
""" """
@ -1598,7 +1598,7 @@ class ConfigObj(Section):
def _handle_error(self, text, ErrorClass, infile, cur_index): def _handle_error(self, text, ErrorClass, infile, cur_index):
""" """
Handle an error according to the error settings. Handle an error according to the error settings.
Either raise the error or store it. Either raise the error or store it.
The error will have occured at ``cur_index`` The error will have occured at ``cur_index``
""" """
@ -1622,19 +1622,19 @@ class ConfigObj(Section):
def _quote(self, value, multiline=True): def _quote(self, value, multiline=True):
""" """
Return a safely quoted version of a value. Return a safely quoted version of a value.
Raise a ConfigObjError if the value cannot be safely quoted. Raise a ConfigObjError if the value cannot be safely quoted.
If multiline is ``True`` (default) then use triple quotes If multiline is ``True`` (default) then use triple quotes
if necessary. if necessary.
Don't quote values that don't need it. Don't quote values that don't need it.
Recursively quote members of a list and return a comma joined list. Recursively quote members of a list and return a comma joined list.
Multiline is ``False`` for lists. Multiline is ``False`` for lists.
Obey list syntax for empty and single member lists. Obey list syntax for empty and single member lists.
If ``list_values=False`` then the value is only quoted if it contains If ``list_values=False`` then the value is only quoted if it contains
a ``\n`` (is multiline). a ``\n`` (is multiline).
If ``write_empty_values`` is set, and the value is an empty string, it If ``write_empty_values`` is set, and the value is an empty string, it
won't be quoted. won't be quoted.
""" """
@ -1778,7 +1778,7 @@ class ConfigObj(Section):
def _handle_configspec(self, configspec): def _handle_configspec(self, configspec):
"""Parse the configspec.""" """Parse the configspec."""
# FIXME: Should we check that the configspec was created with the # FIXME: Should we check that the configspec was created with the
# correct settings ? (i.e. ``list_values=False``) # correct settings ? (i.e. ``list_values=False``)
if not isinstance(configspec, ConfigObj): if not isinstance(configspec, ConfigObj):
try: try:
@ -1831,9 +1831,9 @@ class ConfigObj(Section):
section_keys = configspec.sections section_keys = configspec.sections
scalar_keys = configspec.scalars scalar_keys = configspec.scalars
except AttributeError: except AttributeError:
section_keys = [entry for entry in configspec section_keys = [entry for entry in configspec
if isinstance(configspec[entry], dict)] if isinstance(configspec[entry], dict)]
scalar_keys = [entry for entry in configspec scalar_keys = [entry for entry in configspec
if not isinstance(configspec[entry], dict)] if not isinstance(configspec[entry], dict)]
if '__many__' in section_keys and len(section_keys) > 1: if '__many__' in section_keys and len(section_keys) > 1:
# FIXME: can we supply any useful information here ? # FIXME: can we supply any useful information here ?
@ -1893,9 +1893,9 @@ class ConfigObj(Section):
def write(self, outfile=None, section=None): def write(self, outfile=None, section=None):
""" """
Write the current ConfigObj as a file Write the current ConfigObj as a file
tekNico: FIXME: use StringIO instead of real files tekNico: FIXME: use StringIO instead of real files
>>> filename = a.filename >>> filename = a.filename
>>> a.filename = 'test.ini' >>> a.filename = 'test.ini'
>>> a.write() >>> a.write()
@ -1995,34 +1995,34 @@ class ConfigObj(Section):
section=None): section=None):
""" """
Test the ConfigObj against a configspec. Test the ConfigObj against a configspec.
It uses the ``validator`` object from *validate.py*. It uses the ``validator`` object from *validate.py*.
To run ``validate`` on the current ConfigObj, call: :: To run ``validate`` on the current ConfigObj, call: ::
test = config.validate(validator) test = config.validate(validator)
(Normally having previously passed in the configspec when the ConfigObj (Normally having previously passed in the configspec when the ConfigObj
was created - you can dynamically assign a dictionary of checks to the was created - you can dynamically assign a dictionary of checks to the
``configspec`` attribute of a section though). ``configspec`` attribute of a section though).
It returns ``True`` if everything passes, or a dictionary of It returns ``True`` if everything passes, or a dictionary of
pass/fails (True/False). If every member of a subsection passes, it pass/fails (True/False). If every member of a subsection passes, it
will just have the value ``True``. (It also returns ``False`` if all will just have the value ``True``. (It also returns ``False`` if all
members fail). members fail).
In addition, it converts the values from strings to their native In addition, it converts the values from strings to their native
types if their checks pass (and ``stringify`` is set). types if their checks pass (and ``stringify`` is set).
If ``preserve_errors`` is ``True`` (``False`` is default) then instead If ``preserve_errors`` is ``True`` (``False`` is default) then instead
of a marking a fail with a ``False``, it will preserve the actual of a marking a fail with a ``False``, it will preserve the actual
exception object. This can contain info about the reason for failure. exception object. This can contain info about the reason for failure.
For example the ``VdtValueTooSmallError`` indeicates that the value For example the ``VdtValueTooSmallError`` indeicates that the value
supplied was too small. If a value (or section) is missing it will supplied was too small. If a value (or section) is missing it will
still be marked as ``False``. still be marked as ``False``.
You must have the validate module to use ``preserve_errors=True``. You must have the validate module to use ``preserve_errors=True``.
You can then use the ``flatten_errors`` function to turn your nested You can then use the ``flatten_errors`` function to turn your nested
results dictionary into a flattened list of failures - useful for results dictionary into a flattened list of failures - useful for
displaying meaningful error messages. displaying meaningful error messages.
@ -2138,17 +2138,17 @@ class SimpleVal(object):
""" """
A simple validator. A simple validator.
Can be used to check that all members expected are present. Can be used to check that all members expected are present.
To use it, provide a configspec with all your members in (the value given To use it, provide a configspec with all your members in (the value given
will be ignored). Pass an instance of ``SimpleVal`` to the ``validate`` will be ignored). Pass an instance of ``SimpleVal`` to the ``validate``
method of your ``ConfigObj``. ``validate`` will return ``True`` if all method of your ``ConfigObj``. ``validate`` will return ``True`` if all
members are present, or a dictionary with True/False meaning members are present, or a dictionary with True/False meaning
present/missing. (Whole missing sections will be replaced with ``False``) present/missing. (Whole missing sections will be replaced with ``False``)
""" """
def __init__(self): def __init__(self):
self.baseErrorClass = ConfigObjError self.baseErrorClass = ConfigObjError
def check(self, check, member, missing=False): def check(self, check, member, missing=False):
"""A dummy check method, always returns the value unchanged.""" """A dummy check method, always returns the value unchanged."""
if missing: if missing:
@ -2160,34 +2160,34 @@ def flatten_errors(cfg, res, levels=None, results=None):
""" """
An example function that will turn a nested dictionary of results An example function that will turn a nested dictionary of results
(as returned by ``ConfigObj.validate``) into a flat list. (as returned by ``ConfigObj.validate``) into a flat list.
``cfg`` is the ConfigObj instance being checked, ``res`` is the results ``cfg`` is the ConfigObj instance being checked, ``res`` is the results
dictionary returned by ``validate``. dictionary returned by ``validate``.
(This is a recursive function, so you shouldn't use the ``levels`` or (This is a recursive function, so you shouldn't use the ``levels`` or
``results`` arguments - they are used by the function. ``results`` arguments - they are used by the function.
Returns a list of keys that failed. Each member of the list is a tuple : Returns a list of keys that failed. Each member of the list is a tuple :
:: ::
([list of sections...], key, result) ([list of sections...], key, result)
If ``validate`` was called with ``preserve_errors=False`` (the default) If ``validate`` was called with ``preserve_errors=False`` (the default)
then ``result`` will always be ``False``. then ``result`` will always be ``False``.
*list of sections* is a flattened list of sections that the key was found *list of sections* is a flattened list of sections that the key was found
in. in.
If the section was missing then key will be ``None``. If the section was missing then key will be ``None``.
If the value (or section) was missing then ``result`` will be ``False``. If the value (or section) was missing then ``result`` will be ``False``.
If ``validate`` was called with ``preserve_errors=True`` and a value If ``validate`` was called with ``preserve_errors=True`` and a value
was present, but failed the check, then ``result`` will be the exception was present, but failed the check, then ``result`` will be the exception
object returned. You can use this as a string that describes the failure. object returned. You can use this as a string that describes the failure.
For example *The value "3" is of the wrong type*. For example *The value "3" is of the wrong type*.
>>> import validate >>> import validate
>>> vtor = validate.Validator() >>> vtor = validate.Validator()
>>> my_ini = ''' >>> my_ini = '''

View file

@ -17,110 +17,110 @@
# Comments, suggestions and bug reports welcome. # Comments, suggestions and bug reports welcome.
""" """
The Validator object is used to check that supplied values The Validator object is used to check that supplied values
conform to a specification. conform to a specification.
The value can be supplied as a string - e.g. from a config file. The value can be supplied as a string - e.g. from a config file.
In this case the check will also *convert* the value to In this case the check will also *convert* the value to
the required type. This allows you to add validation the required type. This allows you to add validation
as a transparent layer to access data stored as strings. as a transparent layer to access data stored as strings.
The validation checks that the data is correct *and* The validation checks that the data is correct *and*
converts it to the expected type. converts it to the expected type.
Some standard checks are provided for basic data types. Some standard checks are provided for basic data types.
Additional checks are easy to write. They can be Additional checks are easy to write. They can be
provided when the ``Validator`` is instantiated or provided when the ``Validator`` is instantiated or
added afterwards. added afterwards.
The standard functions work with the following basic data types : The standard functions work with the following basic data types :
* integers * integers
* floats * floats
* booleans * booleans
* strings * strings
* ip_addr * ip_addr
plus lists of these datatypes plus lists of these datatypes
Adding additional checks is done through coding simple functions. Adding additional checks is done through coding simple functions.
The full set of standard checks are : The full set of standard checks are :
* 'integer': matches integer values (including negative) * 'integer': matches integer values (including negative)
Takes optional 'min' and 'max' arguments : :: Takes optional 'min' and 'max' arguments : ::
integer() integer()
integer(3, 9) # any value from 3 to 9 integer(3, 9) # any value from 3 to 9
integer(min=0) # any positive value integer(min=0) # any positive value
integer(max=9) integer(max=9)
* 'float': matches float values * 'float': matches float values
Has the same parameters as the integer check. Has the same parameters as the integer check.
* 'boolean': matches boolean values - ``True`` or ``False`` * 'boolean': matches boolean values - ``True`` or ``False``
Acceptable string values for True are : Acceptable string values for True are :
true, on, yes, 1 true, on, yes, 1
Acceptable string values for False are : Acceptable string values for False are :
false, off, no, 0 false, off, no, 0
Any other value raises an error. Any other value raises an error.
* 'ip_addr': matches an Internet Protocol address, v.4, represented * 'ip_addr': matches an Internet Protocol address, v.4, represented
by a dotted-quad string, i.e. '1.2.3.4'. by a dotted-quad string, i.e. '1.2.3.4'.
* 'string': matches any string. * 'string': matches any string.
Takes optional keyword args 'min' and 'max' Takes optional keyword args 'min' and 'max'
to specify min and max lengths of the string. to specify min and max lengths of the string.
* 'list': matches any list. * 'list': matches any list.
Takes optional keyword args 'min', and 'max' to specify min and Takes optional keyword args 'min', and 'max' to specify min and
max sizes of the list. max sizes of the list.
* 'int_list': Matches a list of integers. * 'int_list': Matches a list of integers.
Takes the same arguments as list. Takes the same arguments as list.
* 'float_list': Matches a list of floats. * 'float_list': Matches a list of floats.
Takes the same arguments as list. Takes the same arguments as list.
* 'bool_list': Matches a list of boolean values. * 'bool_list': Matches a list of boolean values.
Takes the same arguments as list. Takes the same arguments as list.
* 'ip_addr_list': Matches a list of IP addresses. * 'ip_addr_list': Matches a list of IP addresses.
Takes the same arguments as list. Takes the same arguments as list.
* 'string_list': Matches a list of strings. * 'string_list': Matches a list of strings.
Takes the same arguments as list. Takes the same arguments as list.
* 'mixed_list': Matches a list with different types in * 'mixed_list': Matches a list with different types in
specific positions. List size must match specific positions. List size must match
the number of arguments. the number of arguments.
Each position can be one of : Each position can be one of :
'integer', 'float', 'ip_addr', 'string', 'boolean' 'integer', 'float', 'ip_addr', 'string', 'boolean'
So to specify a list with two strings followed So to specify a list with two strings followed
by two integers, you write the check as : :: by two integers, you write the check as : ::
mixed_list('string', 'string', 'integer', 'integer') mixed_list('string', 'string', 'integer', 'integer')
* 'pass': This check matches everything ! It never fails * 'pass': This check matches everything ! It never fails
and the value is unchanged. and the value is unchanged.
It is also the default if no check is specified. It is also the default if no check is specified.
* 'option': This check matches any from a list of options. * 'option': This check matches any from a list of options.
You specify this check with : :: You specify this check with : ::
option('option 1', 'option 2', 'option 3') option('option 1', 'option 2', 'option 3')
You can supply a default value (returned if no value is supplied) You can supply a default value (returned if no value is supplied)
using the default keyword argument. using the default keyword argument.
You specify a list argument for default using a list constructor syntax in You specify a list argument for default using a list constructor syntax in
the check : :: the check : ::
checkname(arg1, arg2, default=list('val 1', 'val 2', 'val 3')) checkname(arg1, arg2, default=list('val 1', 'val 2', 'val 3'))
A badly formatted set of arguments will raise a ``VdtParamError``. A badly formatted set of arguments will raise a ``VdtParamError``.
""" """
@ -261,7 +261,7 @@ except NameError:
def dottedQuadToNum(ip): def dottedQuadToNum(ip):
""" """
Convert decimal dotted quad string to long integer Convert decimal dotted quad string to long integer
>>> dottedQuadToNum('1 ') >>> dottedQuadToNum('1 ')
1L 1L
>>> dottedQuadToNum(' 1.2') >>> dottedQuadToNum(' 1.2')
@ -279,10 +279,10 @@ def dottedQuadToNum(ip):
Traceback (most recent call last): Traceback (most recent call last):
ValueError: Not a good dotted-quad IP: 255.255.255.256 ValueError: Not a good dotted-quad IP: 255.255.255.256
""" """
# import here to avoid it when ip_addr values are not used # import here to avoid it when ip_addr values are not used
import socket, struct import socket, struct
try: try:
return struct.unpack('!L', return struct.unpack('!L',
socket.inet_aton(ip.strip()))[0] socket.inet_aton(ip.strip()))[0]
@ -297,7 +297,7 @@ def dottedQuadToNum(ip):
def numToDottedQuad(num): def numToDottedQuad(num):
""" """
Convert long int to dotted quad string Convert long int to dotted quad string
>>> numToDottedQuad(-1L) >>> numToDottedQuad(-1L)
Traceback (most recent call last): Traceback (most recent call last):
ValueError: Not a good numeric IP: -1 ValueError: Not a good numeric IP: -1
@ -315,10 +315,10 @@ def numToDottedQuad(num):
Traceback (most recent call last): Traceback (most recent call last):
ValueError: Not a good numeric IP: 4294967296 ValueError: Not a good numeric IP: 4294967296
""" """
# import here to avoid it when ip_addr values are not used # import here to avoid it when ip_addr values are not used
import socket, struct import socket, struct
# no need to intercept here, 4294967295L is fine # no need to intercept here, 4294967295L is fine
try: try:
return socket.inet_ntoa( return socket.inet_ntoa(
@ -330,10 +330,10 @@ class ValidateError(Exception):
""" """
This error indicates that the check failed. This error indicates that the check failed.
It can be the base class for more specific errors. It can be the base class for more specific errors.
Any check function that fails ought to raise this error. Any check function that fails ought to raise this error.
(or a subclass) (or a subclass)
>>> raise ValidateError >>> raise ValidateError
Traceback (most recent call last): Traceback (most recent call last):
ValidateError ValidateError
@ -453,18 +453,18 @@ class Validator(object):
""" """
Validator is an object that allows you to register a set of 'checks'. Validator is an object that allows you to register a set of 'checks'.
These checks take input and test that it conforms to the check. These checks take input and test that it conforms to the check.
This can also involve converting the value from a string into This can also involve converting the value from a string into
the correct datatype. the correct datatype.
The ``check`` method takes an input string which configures which The ``check`` method takes an input string which configures which
check is to be used and applies that check to a supplied value. check is to be used and applies that check to a supplied value.
An example input string would be: An example input string would be:
'int_range(param1, param2)' 'int_range(param1, param2)'
You would then provide something like: You would then provide something like:
>>> def int_range_check(value, min, max): >>> def int_range_check(value, min, max):
... # turn min and max from strings to integers ... # turn min and max from strings to integers
... min = int(min) ... min = int(min)
@ -487,7 +487,7 @@ class Validator(object):
... if not value <= max: ... if not value <= max:
... raise VdtValueTooBigError(value) ... raise VdtValueTooBigError(value)
... return value ... return value
>>> fdict = {'int_range': int_range_check} >>> fdict = {'int_range': int_range_check}
>>> vtr1 = Validator(fdict) >>> vtr1 = Validator(fdict)
>>> vtr1.check('int_range(20, 40)', '30') >>> vtr1.check('int_range(20, 40)', '30')
@ -495,25 +495,25 @@ class Validator(object):
>>> vtr1.check('int_range(20, 40)', '60') >>> vtr1.check('int_range(20, 40)', '60')
Traceback (most recent call last): Traceback (most recent call last):
VdtValueTooBigError: the value "60" is too big. VdtValueTooBigError: the value "60" is too big.
New functions can be added with : :: New functions can be added with : ::
>>> vtr2 = Validator() >>> vtr2 = Validator()
>>> vtr2.functions['int_range'] = int_range_check >>> vtr2.functions['int_range'] = int_range_check
Or by passing in a dictionary of functions when Validator Or by passing in a dictionary of functions when Validator
is instantiated. is instantiated.
Your functions *can* use keyword arguments, Your functions *can* use keyword arguments,
but the first argument should always be 'value'. but the first argument should always be 'value'.
If the function doesn't take additional arguments, If the function doesn't take additional arguments,
the parentheses are optional in the check. the parentheses are optional in the check.
It can be written with either of : :: It can be written with either of : ::
keyword = function_name keyword = function_name
keyword = function_name() keyword = function_name()
The first program to utilise Validator() was Michael Foord's The first program to utilise Validator() was Michael Foord's
ConfigObj, an alternative to ConfigParser which supports lists and ConfigObj, an alternative to ConfigParser which supports lists and
can validate a config file using a config schema. can validate a config file using a config schema.
@ -569,14 +569,14 @@ class Validator(object):
def check(self, check, value, missing=False): def check(self, check, value, missing=False):
""" """
Usage: check(check, value) Usage: check(check, value)
Arguments: Arguments:
check: string representing check to apply (including arguments) check: string representing check to apply (including arguments)
value: object to be checked value: object to be checked
Returns value, converted to correct type if necessary Returns value, converted to correct type if necessary
If the check fails, raises a ``ValidateError`` subclass. If the check fails, raises a ``ValidateError`` subclass.
>>> vtor.check('yoda', '') >>> vtor.check('yoda', '')
Traceback (most recent call last): Traceback (most recent call last):
VdtUnknownCheckError: the check "yoda" is unknown. VdtUnknownCheckError: the check "yoda" is unknown.
@ -656,7 +656,7 @@ class Validator(object):
def _pass(self, value): def _pass(self, value):
""" """
Dummy check that always passes Dummy check that always passes
>>> vtor.check('', 0) >>> vtor.check('', 0)
0 0
>>> vtor.check('', '0') >>> vtor.check('', '0')
@ -668,11 +668,11 @@ class Validator(object):
def _is_num_param(names, values, to_float=False): def _is_num_param(names, values, to_float=False):
""" """
Return numbers from inputs or raise VdtParamError. Return numbers from inputs or raise VdtParamError.
Lets ``None`` pass through. Lets ``None`` pass through.
Pass in keyword argument ``to_float=True`` to Pass in keyword argument ``to_float=True`` to
use float for the conversion rather than int. use float for the conversion rather than int.
>>> _is_num_param(('', ''), (0, 1.0)) >>> _is_num_param(('', ''), (0, 1.0))
[0, 1] [0, 1]
>>> _is_num_param(('', ''), (0, 1.0), to_float=True) >>> _is_num_param(('', ''), (0, 1.0), to_float=True)
@ -706,10 +706,10 @@ def is_integer(value, min=None, max=None):
A check that tests that a given value is an integer (int, or long) A check that tests that a given value is an integer (int, or long)
and optionally, between bounds. A negative value is accepted, while and optionally, between bounds. A negative value is accepted, while
a float will fail. a float will fail.
If the value is a string, then the conversion is done - if possible. If the value is a string, then the conversion is done - if possible.
Otherwise a VdtError is raised. Otherwise a VdtError is raised.
>>> vtor.check('integer', '-1') >>> vtor.check('integer', '-1')
-1 -1
>>> vtor.check('integer', '0') >>> vtor.check('integer', '0')
@ -761,17 +761,17 @@ def is_float(value, min=None, max=None):
""" """
A check that tests that a given value is a float A check that tests that a given value is a float
(an integer will be accepted), and optionally - that it is between bounds. (an integer will be accepted), and optionally - that it is between bounds.
If the value is a string, then the conversion is done - if possible. If the value is a string, then the conversion is done - if possible.
Otherwise a VdtError is raised. Otherwise a VdtError is raised.
This can accept negative values. This can accept negative values.
>>> vtor.check('float', '2') >>> vtor.check('float', '2')
2.0 2.0
From now on we multiply the value to avoid comparing decimals From now on we multiply the value to avoid comparing decimals
>>> vtor.check('float', '-6.8') * 10 >>> vtor.check('float', '-6.8') * 10
-68.0 -68.0
>>> vtor.check('float', '12.2') * 10 >>> vtor.check('float', '12.2') * 10
@ -809,14 +809,14 @@ def is_float(value, min=None, max=None):
return value return value
bool_dict = { bool_dict = {
True: True, 'on': True, '1': True, 'true': True, 'yes': True, True: True, 'on': True, '1': True, 'true': True, 'yes': True,
False: False, 'off': False, '0': False, 'false': False, 'no': False, False: False, 'off': False, '0': False, 'false': False, 'no': False,
} }
def is_boolean(value): def is_boolean(value):
""" """
Check if the value represents a boolean. Check if the value represents a boolean.
>>> vtor.check('boolean', 0) >>> vtor.check('boolean', 0)
0 0
>>> vtor.check('boolean', False) >>> vtor.check('boolean', False)
@ -855,7 +855,7 @@ def is_boolean(value):
>>> vtor.check('boolean', 'up') >>> vtor.check('boolean', 'up')
Traceback (most recent call last): Traceback (most recent call last):
VdtTypeError: the value "up" is of the wrong type. VdtTypeError: the value "up" is of the wrong type.
""" """
if isinstance(value, StringTypes): if isinstance(value, StringTypes):
try: try:
@ -877,7 +877,7 @@ def is_ip_addr(value):
""" """
Check that the supplied value is an Internet Protocol address, v.4, Check that the supplied value is an Internet Protocol address, v.4,
represented by a dotted-quad string, i.e. '1.2.3.4'. represented by a dotted-quad string, i.e. '1.2.3.4'.
>>> vtor.check('ip_addr', '1 ') >>> vtor.check('ip_addr', '1 ')
'1' '1'
>>> vtor.check('ip_addr', ' 1.2') >>> vtor.check('ip_addr', ' 1.2')
@ -915,11 +915,11 @@ def is_ip_addr(value):
def is_list(value, min=None, max=None): def is_list(value, min=None, max=None):
""" """
Check that the value is a list of values. Check that the value is a list of values.
You can optionally specify the minimum and maximum number of members. You can optionally specify the minimum and maximum number of members.
It does no check on list members. It does no check on list members.
>>> vtor.check('list', ()) >>> vtor.check('list', ())
() ()
>>> vtor.check('list', []) >>> vtor.check('list', [])
@ -956,9 +956,9 @@ def is_list(value, min=None, max=None):
def is_string(value, min=None, max=None): def is_string(value, min=None, max=None):
""" """
Check that the supplied value is a string. Check that the supplied value is a string.
You can optionally specify the minimum and maximum number of members. You can optionally specify the minimum and maximum number of members.
>>> vtor.check('string', '0') >>> vtor.check('string', '0')
'0' '0'
>>> vtor.check('string', 0) >>> vtor.check('string', 0)
@ -991,11 +991,11 @@ def is_string(value, min=None, max=None):
def is_int_list(value, min=None, max=None): def is_int_list(value, min=None, max=None):
""" """
Check that the value is a list of integers. Check that the value is a list of integers.
You can optionally specify the minimum and maximum number of members. You can optionally specify the minimum and maximum number of members.
Each list member is checked that it is an integer. Each list member is checked that it is an integer.
>>> vtor.check('int_list', ()) >>> vtor.check('int_list', ())
[] []
>>> vtor.check('int_list', []) >>> vtor.check('int_list', [])
@ -1013,11 +1013,11 @@ def is_int_list(value, min=None, max=None):
def is_bool_list(value, min=None, max=None): def is_bool_list(value, min=None, max=None):
""" """
Check that the value is a list of booleans. Check that the value is a list of booleans.
You can optionally specify the minimum and maximum number of members. You can optionally specify the minimum and maximum number of members.
Each list member is checked that it is a boolean. Each list member is checked that it is a boolean.
>>> vtor.check('bool_list', ()) >>> vtor.check('bool_list', ())
[] []
>>> vtor.check('bool_list', []) >>> vtor.check('bool_list', [])
@ -1037,11 +1037,11 @@ def is_bool_list(value, min=None, max=None):
def is_float_list(value, min=None, max=None): def is_float_list(value, min=None, max=None):
""" """
Check that the value is a list of floats. Check that the value is a list of floats.
You can optionally specify the minimum and maximum number of members. You can optionally specify the minimum and maximum number of members.
Each list member is checked that it is a float. Each list member is checked that it is a float.
>>> vtor.check('float_list', ()) >>> vtor.check('float_list', ())
[] []
>>> vtor.check('float_list', []) >>> vtor.check('float_list', [])
@ -1059,11 +1059,11 @@ def is_float_list(value, min=None, max=None):
def is_string_list(value, min=None, max=None): def is_string_list(value, min=None, max=None):
""" """
Check that the value is a list of strings. Check that the value is a list of strings.
You can optionally specify the minimum and maximum number of members. You can optionally specify the minimum and maximum number of members.
Each list member is checked that it is a string. Each list member is checked that it is a string.
>>> vtor.check('string_list', ()) >>> vtor.check('string_list', ())
[] []
>>> vtor.check('string_list', []) >>> vtor.check('string_list', [])
@ -1084,11 +1084,11 @@ def is_string_list(value, min=None, max=None):
def is_ip_addr_list(value, min=None, max=None): def is_ip_addr_list(value, min=None, max=None):
""" """
Check that the value is a list of IP addresses. Check that the value is a list of IP addresses.
You can optionally specify the minimum and maximum number of members. You can optionally specify the minimum and maximum number of members.
Each list member is checked that it is an IP address. Each list member is checked that it is an IP address.
>>> vtor.check('ip_addr_list', ()) >>> vtor.check('ip_addr_list', ())
[] []
>>> vtor.check('ip_addr_list', []) >>> vtor.check('ip_addr_list', [])
@ -1114,20 +1114,20 @@ def is_mixed_list(value, *args):
Check that the value is a list. Check that the value is a list.
Allow specifying the type of each member. Allow specifying the type of each member.
Work on lists of specific lengths. Work on lists of specific lengths.
You specify each member as a positional argument specifying type You specify each member as a positional argument specifying type
Each type should be one of the following strings : Each type should be one of the following strings :
'integer', 'float', 'ip_addr', 'string', 'boolean' 'integer', 'float', 'ip_addr', 'string', 'boolean'
So you can specify a list of two strings, followed by So you can specify a list of two strings, followed by
two integers as : two integers as :
mixed_list('string', 'string', 'integer', 'integer') mixed_list('string', 'string', 'integer', 'integer')
The length of the list must match the number of positional The length of the list must match the number of positional
arguments you supply. arguments you supply.
>>> mix_str = "mixed_list('integer', 'float', 'ip_addr', 'string', 'boolean')" >>> mix_str = "mixed_list('integer', 'float', 'ip_addr', 'string', 'boolean')"
>>> check_res = vtor.check(mix_str, (1, 2.0, '1.2.3.4', 'a', True)) >>> check_res = vtor.check(mix_str, (1, 2.0, '1.2.3.4', 'a', True))
>>> check_res == [1, 2.0, '1.2.3.4', 'a', True] >>> check_res == [1, 2.0, '1.2.3.4', 'a', True]
@ -1147,10 +1147,10 @@ def is_mixed_list(value, *args):
>>> vtor.check(mix_str, 0) >>> vtor.check(mix_str, 0)
Traceback (most recent call last): Traceback (most recent call last):
VdtTypeError: the value "0" is of the wrong type. VdtTypeError: the value "0" is of the wrong type.
This test requires an elaborate setup, because of a change in error string This test requires an elaborate setup, because of a change in error string
output from the interpreter between Python 2.2 and 2.3 . output from the interpreter between Python 2.2 and 2.3 .
>>> res_seq = ( >>> res_seq = (
... 'passed an incorrect value "', ... 'passed an incorrect value "',
... 'yoda', ... 'yoda',
@ -1182,7 +1182,7 @@ def is_mixed_list(value, *args):
def is_option(value, *options): def is_option(value, *options):
""" """
This check matches the value to any of a set of options. This check matches the value to any of a set of options.
>>> vtor.check('option("yoda", "jedi")', 'yoda') >>> vtor.check('option("yoda", "jedi")', 'yoda')
'yoda' 'yoda'
>>> vtor.check('option("yoda", "jedi")', 'jed') >>> vtor.check('option("yoda", "jedi")', 'jed')
@ -1201,7 +1201,7 @@ def is_option(value, *options):
def _test(value, *args, **keywargs): def _test(value, *args, **keywargs):
""" """
A function that exists for test purposes. A function that exists for test purposes.
>>> checks = [ >>> checks = [
... '3, 6, min=1, max=3, test=list(a, b, c)', ... '3, 6, min=1, max=3, test=list(a, b, c)',
... '3', ... '3',
@ -1253,221 +1253,221 @@ if __name__ == '__main__':
""" """
TODO TODO
==== ====
Consider which parts of the regex stuff to put back in Consider which parts of the regex stuff to put back in
Can we implement a timestamp datatype ? (check DateUtil module) Can we implement a timestamp datatype ? (check DateUtil module)
ISSUES ISSUES
====== ======
If we could pull tuples out of arguments, it would be easier If we could pull tuples out of arguments, it would be easier
to specify arguments for 'mixed_lists'. to specify arguments for 'mixed_lists'.
CHANGELOG CHANGELOG
========= =========
2006/12/17 2006/12/17
---------- ----------
By Nicola Larosa By Nicola Larosa
Fixed validate doc to talk of ``boolean`` instead of ``bool``, changed the Fixed validate doc to talk of ``boolean`` instead of ``bool``, changed the
``is_bool`` function to ``is_boolean`` (Sourceforge bug #1531525). ``is_bool`` function to ``is_boolean`` (Sourceforge bug #1531525).
2006/04/23 2006/04/23
---------- ----------
Addressed bug where a string would pass the ``is_list`` test. (Thanks to Addressed bug where a string would pass the ``is_list`` test. (Thanks to
Konrad Wojas.) Konrad Wojas.)
2005/12/16 2005/12/16
---------- ----------
Fixed bug so we can handle keyword argument values with commas. Fixed bug so we can handle keyword argument values with commas.
We now use a list constructor for passing list values to keyword arguments We now use a list constructor for passing list values to keyword arguments
(including ``default``) : :: (including ``default``) : ::
default=list("val", "val", "val") default=list("val", "val", "val")
Added the ``_test`` test. {sm;:-)} Added the ``_test`` test. {sm;:-)}
0.2.1 0.2.1
2005/12/12 2005/12/12
---------- ----------
Moved a function call outside a try...except block. Moved a function call outside a try...except block.
2005/08/25 2005/08/25
---------- ----------
Most errors now prefixed ``Vdt`` Most errors now prefixed ``Vdt``
``VdtParamError`` no longer derives from ``VdtError`` ``VdtParamError`` no longer derives from ``VdtError``
Finalised as version 0.2.0 Finalised as version 0.2.0
2005/08/21 2005/08/21
---------- ----------
By Nicola Larosa By Nicola Larosa
Removed the "length" argument for lists and strings, and related tests Removed the "length" argument for lists and strings, and related tests
2005/08/16 2005/08/16
---------- ----------
By Nicola Larosa By Nicola Larosa
Deleted the "none" and "multiple" types and checks Deleted the "none" and "multiple" types and checks
Added the None value for all types in Validation.check Added the None value for all types in Validation.check
2005/08/14 2005/08/14
---------- ----------
By Michael Foord By Michael Foord
Removed timestamp. Removed timestamp.
By Nicola Larosa By Nicola Larosa
Fixed bug in Validator.check: when a value that has a default is also Fixed bug in Validator.check: when a value that has a default is also
specified in the config file, the default must be deleted from fun_kwargs specified in the config file, the default must be deleted from fun_kwargs
anyway, otherwise the check function will get a spurious "default" keyword anyway, otherwise the check function will get a spurious "default" keyword
argument argument
Added "ip_addr_list" check Added "ip_addr_list" check
2005/08/13 2005/08/13
---------- ----------
By Nicola Larosa By Nicola Larosa
Updated comments at top Updated comments at top
2005/08/11 2005/08/11
---------- ----------
By Nicola Larosa By Nicola Larosa
Added test for interpreter version: raises RuntimeError if earlier than Added test for interpreter version: raises RuntimeError if earlier than
2.2 2.2
Fixed last is_mixed_list test to work on Python 2.2 too Fixed last is_mixed_list test to work on Python 2.2 too
2005/08/10 2005/08/10
---------- ----------
By Nicola Larosa By Nicola Larosa
Restored Python2.2 compatibility by avoiding usage of dict.pop Restored Python2.2 compatibility by avoiding usage of dict.pop
2005/08/07 2005/08/07
---------- ----------
By Nicola Larosa By Nicola Larosa
Adjusted doctests for Python 2.2.3 compatibility, one test still fails Adjusted doctests for Python 2.2.3 compatibility, one test still fails
for trivial reasons (string output delimiters) for trivial reasons (string output delimiters)
2005/08/05 2005/08/05
---------- ----------
By Michael Foord By Michael Foord
Added __version__, __all__, and __docformat__ Added __version__, __all__, and __docformat__
Replaced ``basestring`` with ``types.StringTypes`` Replaced ``basestring`` with ``types.StringTypes``
2005/07/28 2005/07/28
---------- ----------
By Nicola Larosa By Nicola Larosa
Reformatted final docstring in ReST format, indented it for easier folding Reformatted final docstring in ReST format, indented it for easier folding
2005/07/20 2005/07/20
---------- ----------
By Nicola Larosa By Nicola Larosa
Added an 'ip_addr' IPv4 address value check, with tests Added an 'ip_addr' IPv4 address value check, with tests
Updated the tests for mixed_list to include IP addresses Updated the tests for mixed_list to include IP addresses
Changed all references to value "tests" into value "checks", including Changed all references to value "tests" into value "checks", including
the main Validator method, and all code tests the main Validator method, and all code tests
2005/07/19 2005/07/19
---------- ----------
By Nicola Larosa By Nicola Larosa
Added even more code tests Added even more code tests
Refined the mixed_list check Refined the mixed_list check
2005/07/18 2005/07/18
---------- ----------
By Nicola Larosa By Nicola Larosa
Introduced more VdtValueError subclasses Introduced more VdtValueError subclasses
Collapsed the ``_function_test`` and ``_function_parse`` methods into the Collapsed the ``_function_test`` and ``_function_parse`` methods into the
``check`` one ``check`` one
Refined the value checks, using the new VdtValueError subclasses Refined the value checks, using the new VdtValueError subclasses
Changed "is_string" to use "is_list" Changed "is_string" to use "is_list"
Added many more code tests Added many more code tests
Changed the "bool" value type to "boolean" Changed the "bool" value type to "boolean"
Some more code cleanup Some more code cleanup
2005/07/17 2005/07/17
---------- ----------
By Nicola Larosa By Nicola Larosa
Code tests converted to doctest format and placed in the respective Code tests converted to doctest format and placed in the respective
docstrings, so they are automatically checked, and easier to update docstrings, so they are automatically checked, and easier to update
Changed local vars "min" and "max" to "min_len", "max_len", "min_val" and Changed local vars "min" and "max" to "min_len", "max_len", "min_val" and
"max_val", to avoid shadowing the builtin functions (but left function "max_val", to avoid shadowing the builtin functions (but left function
parameters alone) parameters alone)
Uniformed value check function names to is_* convention Uniformed value check function names to is_* convention
``date`` type name changed to ``timestamp`` ``date`` type name changed to ``timestamp``
Avoided some code duplication in list check functions Avoided some code duplication in list check functions
Some more code cleanup Some more code cleanup
2005/07/09 2005/07/09
---------- ----------
Recoded the standard functions Recoded the standard functions
2005/07/08 2005/07/08
---------- ----------
Improved paramfinder regex Improved paramfinder regex
Ripped out all the regex stuff, checks, and the example functions Ripped out all the regex stuff, checks, and the example functions
(to be replaced !) (to be replaced !)
2005/07/06 2005/07/06
---------- ----------
By Nicola Larosa By Nicola Larosa
Code cleanup Code cleanup
""" """

View file

@ -595,7 +595,7 @@ class Well(Game):
self.sg.talonstacks = [s.talon] + s.wastes self.sg.talonstacks = [s.talon] + s.wastes
self.sg.openstacks = s.foundations + s.rows self.sg.openstacks = s.foundations + s.rows
self.sg.dropstacks = s.rows + s.wastes + s.reserves self.sg.dropstacks = s.rows + s.wastes + s.reserves
def startGame(self): def startGame(self):
for i in range(10): for i in range(10):

View file

@ -831,7 +831,7 @@ class Junction(Game):
Foundation_Class = StackWrapper(DieRussische_Foundation, max_cards=8) Foundation_Class = StackWrapper(DieRussische_Foundation, max_cards=8)
def createGame(self, rows=7): def createGame(self, rows=7):
l, s = Layout(self), self.s l, s = Layout(self), self.s
self.setSize(l.XM+10*l.XS, l.YM+3*l.YS+12*l.YOFFSET) self.setSize(l.XM+10*l.XS, l.YM+3*l.YS+12*l.YOFFSET)

View file

@ -991,7 +991,7 @@ class NapoleonTakesMoscow(Game, FirTree_GameMethods):
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()
def startGame(self): def startGame(self):
self.s.talon.dealRow(rows=self.s.reserves, frames=0) self.s.talon.dealRow(rows=self.s.reserves, frames=0)
for i in range(3): for i in range(3):

View file

@ -436,7 +436,7 @@ class Cone(Gypsy):
s.foundations.append(SS_FoundationStack(x, y, self, suit=i, s.foundations.append(SS_FoundationStack(x, y, self, suit=i,
mod=13, max_cards=26)) mod=13, max_cards=26))
y += l.YS y += l.YS
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()

View file

@ -993,7 +993,7 @@ class SevenDevils(Klondike):
RowStack_Class = StackWrapper(SevenDevils_RowStack, max_move=1) RowStack_Class = StackWrapper(SevenDevils_RowStack, max_move=1)
def createGame(self): def createGame(self):
l, s = Layout(self), self.s l, s = Layout(self), self.s
self.setSize(l.XM + 10*l.XS, l.YM+3*l.YS+12*l.YOFFSET) self.setSize(l.XM + 10*l.XS, l.YM+3*l.YS+12*l.YOFFSET)

View file

@ -56,7 +56,7 @@ class PileOn_RowStack(RK_RowStack):
class PileOn(Game): class PileOn(Game):
Hint_Class = DefaultHint Hint_Class = DefaultHint
##Hint_Class = CautiousDefaultHint ##Hint_Class = CautiousDefaultHint
TWIDTH = 4 TWIDTH = 4
NSTACKS = 15 NSTACKS = 15
PLAYCARDS = 4 PLAYCARDS = 4

View file

@ -808,7 +808,7 @@ class Applegate(Game):
Hint_Class = YukonType_Hint Hint_Class = YukonType_Hint
def createGame(self): def createGame(self):
# create layout # create layout
l, s = Layout(self), self.s l, s = Layout(self), self.s
self.setSize(l.XM+8*l.XS, l.YM+max(l.YS+16*l.YOFFSET, 4*l.YS)) self.setSize(l.XM+8*l.XS, l.YM+max(l.YS+16*l.YOFFSET, 4*l.YS))

View file

@ -116,7 +116,7 @@ class Sultan(Game):
class SultanPlus(Sultan): class SultanPlus(Sultan):
def createGame(self): def createGame(self):
Sultan.createGame(self, reserves=8) Sultan.createGame(self, reserves=8)
# ************************************************************************ # ************************************************************************
# * Boudoir # * Boudoir
@ -947,7 +947,7 @@ class Adela(Game):
s.rows.append(stack) s.rows.append(stack)
stack.CARD_YOFFSET = 0 stack.CARD_YOFFSET = 0
x += l.XS x += l.XS
l.defaultStackGroups() l.defaultStackGroups()

View file

@ -108,7 +108,7 @@ class TakeAway(Game):
# ************************************************************************ # ************************************************************************
class FourStacks_RowStack(AC_RowStack): class FourStacks_RowStack(AC_RowStack):
getBottomImage = Stack._getReserveBottomImage getBottomImage = Stack._getReserveBottomImage
class FourStacks(Game): class FourStacks(Game):
def createGame(self): def createGame(self):

View file

@ -92,7 +92,7 @@ class WaveMotion(Game):
if len(s.cards) != 13 or not isSameSuitSequence(s.cards): if len(s.cards) != 13 or not isSameSuitSequence(s.cards):
return False return False
return True return True
shallHighlightMatch = Game._shallHighlightMatch_SS shallHighlightMatch = Game._shallHighlightMatch_SS
@ -112,7 +112,7 @@ class Flourish(WaveMotion):
if len(s.cards) != 13 or not isAlternateColorSequence(s.cards): if len(s.cards) != 13 or not isAlternateColorSequence(s.cards):
return False return False
return True return True
shallHighlightMatch = Game._shallHighlightMatch_AC shallHighlightMatch = Game._shallHighlightMatch_AC

View file

@ -71,8 +71,8 @@ class Images:
self._xshadow = [] # horizontal shadow of card self._xshadow = [] # horizontal shadow of card
self._pil_shadow = {} # key: (width, height) self._pil_shadow = {} # key: (width, height)
self._highlight = [] # highlight of card (tip) self._highlight = [] # highlight of card (tip)
self._highlight_index = 0 # self._highlight_index = 0 #
self._highlighted_images = {} # key: (suit, rank) self._highlighted_images = {} # key: (suit, rank)
def destruct(self): def destruct(self):
pass pass

View file

@ -36,7 +36,7 @@ def hideTkConsole(root):
root.tk.call('console', 'hide') root.tk.call('console', 'hide')
except TclError: except TclError:
pass pass
def setupApp(app): def setupApp(app):
""" """
Perform setup for the OSX application bundle. Perform setup for the OSX application bundle.

View file

@ -535,7 +535,7 @@ class MfxCanvas(gnomecanvas.Canvas):
pass pass
def updateAll(self): def updateAll(self):
print 'Canvas - updateAll', print 'Canvas - updateAll',
for i in self._all_items: for i in self._all_items:
i._item.hide() i._item.hide()
self.update_now() self.update_now()

View file

@ -121,7 +121,7 @@ class _PysolPixmap:
if outline: if outline:
# FIXME # FIXME
pass pass
def clone(self): def clone(self):
pixbuf = self.pixbuf.copy() pixbuf = self.pixbuf.copy()

View file

@ -326,7 +326,7 @@ class MfxSimpleEntry(_MyDialog):
self.quit() self.quit()

View file

@ -912,7 +912,7 @@ class Stack:
self.CARD_XOFFSET = xoffset self.CARD_XOFFSET = xoffset
self.CARD_YOFFSET = yoffset self.CARD_YOFFSET = yoffset
self.INIT_CARD_YOFFSET = yoffset self.INIT_CARD_YOFFSET = yoffset
#print '* resize offset:', self.INIT_CARD_XOFFSET, #print '* resize offset:', self.INIT_CARD_XOFFSET,
# move cards # move cards
for c in self.cards: for c in self.cards:
cx, cy = self.getPositionFor(c) cx, cy = self.getPositionFor(c)

View file

@ -473,7 +473,7 @@ class CardsetInfoDialog(MfxDialog):
self.y_offset.grid(row=1, column=0, sticky='ew', self.y_offset.grid(row=1, column=0, sticky='ew',
padx=padx, pady=pady) padx=padx, pady=pady)
row += 1 row += 1
##bg = top_frame["bg"] ##bg = top_frame["bg"]
bg = 'white' bg = 'white'
text_w = Tkinter.Text(frame, bd=1, relief="sunken", wrap="word", text_w = Tkinter.Text(frame, bd=1, relief="sunken", wrap="word",

View file

@ -56,7 +56,7 @@ Tkinter.Tk._loadtk = _loadttk(Tkinter.Tk._loadtk)
def _format_optdict(optdict, script=False, ignore=None): def _format_optdict(optdict, script=False, ignore=None):
"""Formats optdict to a tuple to pass it to tk.call. """Formats optdict to a tuple to pass it to tk.call.
E.g. (script=False): E.g. (script=False):
{'foreground': 'blue', 'padding': [1, 2, 3, 4]} returns: {'foreground': 'blue', 'padding': [1, 2, 3, 4]} returns:
('-foreground', 'blue', '-padding', '1 2 3 4')""" ('-foreground', 'blue', '-padding', '1 2 3 4')"""
@ -90,7 +90,7 @@ def _format_optdict(optdict, script=False, ignore=None):
def _format_mapdict(mapdict, script=False): def _format_mapdict(mapdict, script=False):
"""Formats mapdict to pass it to tk.call. """Formats mapdict to pass it to tk.call.
E.g. (script=False): E.g. (script=False):
{'expand': [('active', 'selected', 'grey'), ('focus', [1, 2, 3, 4])]} {'expand': [('active', 'selected', 'grey'), ('focus', [1, 2, 3, 4])]}
@ -1198,7 +1198,7 @@ class Treeview(Widget):
def get_children(self, item=None): def get_children(self, item=None):
"""Returns a tuple of children belonging to item. """Returns a tuple of children belonging to item.
If item is not specified, returns root children.""" If item is not specified, returns root children."""
return self.tk.call(self._w, "children", item or '') or () return self.tk.call(self._w, "children", item or '') or ()
@ -1480,7 +1480,7 @@ class Treeview(Widget):
class LabeledScale(Frame, object): class LabeledScale(Frame, object):
"""A Ttk Scale widget with a Ttk Label widget indicating its """A Ttk Scale widget with a Ttk Label widget indicating its
current value. current value.
The Ttk Scale can be accessed through instance.scale, and Ttk Label The Ttk Scale can be accessed through instance.scale, and Ttk Label
can be accessed through instance.label""" can be accessed through instance.label"""

View file

@ -84,7 +84,7 @@ kw = {
'pysollib.games.mahjongg'], 'pysollib.games.mahjongg'],
'data_files' : data_files, 'data_files' : data_files,
} }
if os.name == 'nt': if os.name == 'nt':
kw['windows'] = [{'script': 'pysol.py', kw['windows'] = [{'script': 'pysol.py',
'icon_resources': [(1, 'data/pysol.ico')], }] 'icon_resources': [(1, 'data/pysol.ico')], }]

View file

@ -59,7 +59,7 @@ PLIST = dict(
CFBundleIdentifier = 'net.sourceforge.pysolfc', CFBundleIdentifier = 'net.sourceforge.pysolfc',
CFBundleName = PACKAGE, CFBundleName = PACKAGE,
CFBundleVersion = '%s' % VERSION, CFBundleVersion = '%s' % VERSION,
CFBundleShortVersionString = '%s' % VERSION, CFBundleShortVersionString = '%s' % VERSION,
NSHumanReadableCopyright = "Copyright (C) 1998-2003 Markus F.X.J. Oberhumer", NSHumanReadableCopyright = "Copyright (C) 1998-2003 Markus F.X.J. Oberhumer",
) )
APP = ['pysol.py'] APP = ['pysol.py']

View file

@ -0,0 +1,29 @@
#!/usr/bin/perl
use strict;
use warnings;
use Test::More;
eval "use Test::TrailingSpace";
if ($@)
{
plan skip_all => "Test::TrailingSpace required for trailing space test.";
}
else
{
plan tests => 1;
}
my $finder = Test::TrailingSpace->new(
{
root => '.',
filename_regex => qr/(?:(?:\.(?:t|pm|pl|PL|yml|json|arc|vim|py|tcl))|README|Changes|LICENSE|MANIFEST|AUTHORS|COPYING)\z/,
},
);
# TEST
$finder->no_trailing_space(
"No trailing space was found."
);