Skip to content

Commit 69c5f4c

Browse files
authored
Merge pull request #300 from ppizarror/fix-ascii-py2
Fix ascii py2
2 parents 43ae2ea + 357954d commit 69c5f4c

16 files changed

+222
-95
lines changed

docs/_source/themes.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ Background Color/Images
6969
-----------------------
7070

7171
Theme background can be both a color or an image. All colors can be defined
72-
using a tuple or an list of 3 or 4 numbers between 0 and 255. The format of
72+
using a tuple or a list of 3 or 4 numbers between 0 and 255. The format of
7373
the numbers are:
7474

7575
.. code-block:: python

pygame_menu/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
# Import modules that require pygame
4646
if __pygame_version__ is not None:
4747
"""
48-
BaseImage: Provides basic image loading an manipulation with pygame
48+
BaseImage: Provides basic image loading and manipulation with pygame
4949
"""
5050
import pygame_menu.baseimage
5151

pygame_menu/baseimage.py

+6-8
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
https://github.com/ppizarror/pygame-menu
55
66
BASEIMAGE
7-
Provides a class to perform basic image loading an manipulation with pygame.
7+
Provides a class to perform basic image loading and manipulation with pygame.
88
99
NOTE: pygame-menu v3 will not provide new widgets or functionalities, consider
1010
upgrading to the latest version.
@@ -44,7 +44,7 @@
4444
_Path = None
4545

4646
import pygame
47-
from pygame_menu.utils import assert_vector2
47+
from pygame_menu.utils import assert_vector2, isinstance_str
4848

4949
# Example image paths
5050
__images_path__ = path.join(path.dirname(path.abspath(__file__)), 'resources', 'images', '{0}')
@@ -74,7 +74,7 @@
7474
class BaseImage(object):
7575
"""
7676
Object that loads an image, stores as a surface, transform it and
77-
let write the image to an surface.
77+
let write the image to a surface.
7878
7979
:param image_path: Path of the image to be loaded. It can be a string or :py:class:`pathlib.Path` on ``Python 3+``
8080
:type image_path: str, :py:class:`pathlib.Path`
@@ -92,12 +92,10 @@ def __init__(self,
9292
drawing_offset=(0, 0),
9393
load_from_file=True
9494
):
95-
if _Path is None:
96-
assert isinstance(image_path, str)
97-
else:
98-
assert isinstance(image_path, (str, _Path))
95+
if _Path is not None:
9996
if isinstance(image_path, _Path):
10097
image_path = str(image_path)
98+
assert isinstance_str(image_path)
10199
assert isinstance(load_from_file, bool)
102100

103101
_, file_extension = path.splitext(image_path)
@@ -340,7 +338,7 @@ def pick_channels(self, channels):
340338
:return: Self reference
341339
:rtype: BaseImage
342340
"""
343-
if isinstance(channels, str):
341+
if isinstance_str(channels):
344342
channels = [channels]
345343
assert isinstance(channels, (list, tuple))
346344
assert 1 <= len(channels) <= 3, 'maximum size of channels can be 3'

pygame_menu/examples/game_selector.py

-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ def play_function(difficulty, font, test=False):
100100
"""
101101
assert isinstance(difficulty, (tuple, list))
102102
difficulty = difficulty[0]
103-
assert isinstance(difficulty, str)
104103

105104
# Define globals
106105
global main_menu

pygame_menu/menu.py

+19-17
Original file line numberDiff line numberDiff line change
@@ -127,23 +127,23 @@ def __init__(self,
127127
):
128128
assert isinstance(height, (int, float))
129129
assert isinstance(width, (int, float))
130-
# assert isinstance(title, str)
130+
assert _utils.isinstance_str(title)
131131

132132
assert isinstance(center_content, bool)
133133
assert isinstance(column_force_fit_text, bool)
134134
assert isinstance(column_max_width, (tuple, type(None), (int, float), list))
135135
assert isinstance(columns, int)
136136
assert isinstance(enabled, bool)
137137
assert isinstance(joystick_enabled, bool)
138-
assert isinstance(menu_id, str)
138+
assert _utils.isinstance_str(menu_id)
139139
assert isinstance(menu_position, (tuple, list))
140140
assert isinstance(mouse_enabled, bool)
141141
assert isinstance(mouse_motion_selection, bool)
142142
assert isinstance(mouse_visible, bool)
143143
assert isinstance(overflow, (tuple, list, bool))
144144
assert isinstance(rows, (int, type(None)))
145145
assert isinstance(screen_dimension, (tuple, list, type(None)))
146-
assert isinstance(theme, _themes.Theme), 'theme bust be an pygame_menu.themes.Theme object instance'
146+
assert isinstance(theme, _themes.Theme), 'theme bust be a pygame_menu.themes.Theme object instance'
147147
assert isinstance(touchscreen_enabled, bool)
148148
assert isinstance(touchscreen_motion_selection, bool)
149149

@@ -468,7 +468,7 @@ def add_button(self,
468468

469469
# Get ID
470470
button_id = kwargs.pop('button_id', '')
471-
assert isinstance(button_id, str), 'id must be a string'
471+
assert _utils.isinstance_str(button_id), 'id must be a string'
472472

473473
# Change action if certain events
474474
if action == _events.PYGAME_QUIT or action == _events.PYGAME_WINDOWCLOSE:
@@ -708,7 +708,7 @@ def add_label(self,
708708
:return: Widget object, or List of widgets if the text overflows
709709
:rtype: :py:class:`pygame_menu.widgets.Label`, list[:py:class:`pygame_menu.widgets.Label`]
710710
"""
711-
assert isinstance(label_id, str)
711+
assert _utils.isinstance_str(label_id)
712712
assert isinstance(max_char, int)
713713
assert isinstance(selectable, bool)
714714
assert max_char >= -1
@@ -929,7 +929,9 @@ def add_text_input(self,
929929
:return: Widget object
930930
:rtype: :py:class:`pygame_menu.widgets.TextInput`
931931
"""
932-
assert isinstance(default, (str, int, float))
932+
if not isinstance(default, (int, float)):
933+
assert _utils.isinstance_str(default), \
934+
'default value must be a string, an integer or a float value'
933935

934936
# Filter widget attributes to avoid passing them to the callbacks
935937
attributes = self._filter_widget_attributes(kwargs)
@@ -1042,7 +1044,7 @@ def _filter_widget_attributes(self, kwargs):
10421044
"""
10431045
attributes = {}
10441046
align = kwargs.pop('align', self._theme.widget_alignment)
1045-
assert isinstance(align, str)
1047+
assert _utils.isinstance_str(align)
10461048
attributes['align'] = align
10471049

10481050
background_is_color = False
@@ -1077,7 +1079,7 @@ def _filter_widget_attributes(self, kwargs):
10771079
attributes['font_color'] = font_color
10781080

10791081
font_name = kwargs.pop('font_name', self._theme.widget_font)
1080-
assert isinstance(font_name, str)
1082+
assert _utils.isinstance_str(font_name)
10811083
attributes['font_name'] = font_name
10821084

10831085
font_size = kwargs.pop('font_size', self._theme.widget_font_size)
@@ -1111,7 +1113,7 @@ def _filter_widget_attributes(self, kwargs):
11111113
attributes['shadow_color'] = shadow_color
11121114

11131115
shadow_position = kwargs.pop('shadow_position', self._theme.widget_shadow_position)
1114-
assert isinstance(shadow_position, str)
1116+
assert _utils.isinstance_str(shadow_position)
11151117
attributes['shadow_position'] = shadow_position
11161118

11171119
shadow_offset = kwargs.pop('shadow_offset', self._theme.widget_shadow_offset)
@@ -1212,7 +1214,7 @@ def select_widget(self, widget):
12121214
:type widget: :py:class:`pygame_menu.widgets.core.widget.Widget`, str
12131215
:return: None
12141216
"""
1215-
if isinstance(widget, str):
1217+
if _utils.isinstance_str(widget):
12161218
widget = self.get_widget(widget_id=widget)
12171219
assert isinstance(widget, _widgets.core.Widget)
12181220
if not widget.is_selectable:
@@ -1234,7 +1236,7 @@ def remove_widget(self, widget):
12341236
:type widget: :py:class:`pygame_menu.widgets.core.widget.Widget`, str
12351237
:return: None
12361238
"""
1237-
if isinstance(widget, str):
1239+
if _utils.isinstance_str(widget):
12381240
widget = self.get_widget(widget_id=widget)
12391241
assert isinstance(widget, _widgets.core.Widget)
12401242
try:
@@ -1475,7 +1477,7 @@ def _build_widget_surface(self):
14751477
sx = self._scroll.get_scrollbar_thickness(_locals.ORIENTATION_HORIZONTAL, real=True)
14761478
sy = self._scroll.get_scrollbar_thickness(_locals.ORIENTATION_VERTICAL, real=True)
14771479

1478-
# Remove the thick of the scrollbar to avoid displaying an horizontal one
1480+
# Remove the thick of the scrollbar to avoid displaying a horizontal one
14791481
# If overflow in both axis
14801482
if max_x > self._width and max_y > self._height - menubar_height:
14811483
width, height = max_x + sy * 0.5, max_y + sx * 0.25
@@ -1524,7 +1526,7 @@ def _check_id_duplicated(self, widget_id):
15241526
:type widget_id: str
15251527
:return: None
15261528
"""
1527-
assert isinstance(widget_id, str)
1529+
assert _utils.isinstance_str(widget_id)
15281530
for widget in self._widgets: # type: _widgets.core.Widget
15291531
if widget.get_id() == widget_id:
15301532
raise IndexError('widget ID="{0}" already exists on the menu'.format(widget_id))
@@ -2541,7 +2543,7 @@ def get_widget(self, widget_id, recursive=False):
25412543
:return: Widget object
25422544
:rtype: :py:class:`pygame_menu.widgets.core.widget.Widget`, None
25432545
"""
2544-
assert isinstance(widget_id, str)
2546+
assert _utils.isinstance_str(widget_id)
25452547
assert isinstance(recursive, bool)
25462548
for widget in self._widgets: # type: _widgets.core.Widget
25472549
if widget.get_id() == widget_id:
@@ -2651,7 +2653,7 @@ def set_attribute(self, key, value):
26512653
:type value: any
26522654
:return: None
26532655
"""
2654-
assert isinstance(key, str)
2656+
assert _utils.isinstance_str(key)
26552657
self._attributes[key] = value
26562658

26572659
def get_attribute(self, key, default=None):
@@ -2665,7 +2667,7 @@ def get_attribute(self, key, default=None):
26652667
:return: Attribute data
26662668
:rtype: any
26672669
"""
2668-
assert isinstance(key, str)
2670+
assert _utils.isinstance_str(key)
26692671
if not self.has_attribute(key):
26702672
return default
26712673
return self._attributes[key]
@@ -2679,7 +2681,7 @@ def has_attribute(self, key):
26792681
:return: True if exists
26802682
:rtype: bool
26812683
"""
2682-
assert isinstance(key, str)
2684+
assert _utils.isinstance_str(key)
26832685
return key in self._attributes.keys()
26842686

26852687
def remove_attribute(self, key):

pygame_menu/sound.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
AUDIO_ALLOW_CHANNELS_CHANGE = False
4949
AUDIO_ALLOW_FREQUENCY_CHANGE = False
5050

51+
from pygame_menu.utils import isinstance_str
52+
5153
# Sound types
5254
SOUND_TYPE_CLICK_MOUSE = '__pygame_menu_sound_click_mouse__'
5355
SOUND_TYPE_CLOSE_MENU = '__pygame_menu_sound_close_menu__'
@@ -118,7 +120,7 @@ def __init__(self,
118120
assert isinstance(size, int)
119121
assert isinstance(channels, int)
120122
assert isinstance(buffer, int)
121-
assert isinstance(devicename, str)
123+
assert isinstance_str(devicename)
122124
assert isinstance(allowedchanges, int)
123125
assert isinstance(force_init, bool)
124126
assert frequency > 0, 'frequency must be greater than zero'
@@ -227,8 +229,9 @@ def set_sound(self, sound_type, sound_file, volume=0.5, loops=0, maxtime=0, fade
227229
:return: The status of the sound load, *True* if the sound was loaded
228230
:rtype: bool
229231
"""
230-
assert isinstance(sound_type, str)
231-
assert isinstance(sound_file, (str, type(None)))
232+
assert isinstance_str(sound_type)
233+
if sound_file is not None:
234+
assert isinstance_str(sound_file)
232235
assert isinstance(volume, float)
233236
assert isinstance(loops, int)
234237
assert isinstance(maxtime, (int, float))

pygame_menu/themes.py

+64-29
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class Theme(object):
7171
:type focus_background_color: tuple, list
7272
:param menubar_close_button: Draw a back-box button on header to close the menu, if user moves through nested submenus this buttons turns to a back-arrow
7373
:type menubar_close_button: bool
74-
:param scrollarea_outer_margin: Outer scroll area margin (px), the tuple is added to computed scroll area width/height, it can add an margin to bottom/right scrolls after widgets. If value less than 1 use percentage of width/height. Default *(0,0)*. It cannot be negative values
74+
:param scrollarea_outer_margin: Outer scroll area margin (px), the tuple is added to computed scroll area width/height, it can add a margin to bottom/right scrolls after widgets. If value less than 1 use percentage of width/height. Default *(0,0)*. It cannot be negative values
7575
:type scrollarea_outer_margin: tuple, list
7676
:param scrollbar_color: Scrollbars color
7777
:type scrollbar_color: tuple, list
@@ -399,54 +399,89 @@ def _get(params, key, allowed_types=None, default=None):
399399
"""
400400
Return a value from a dictionary.
401401
402-
:param params: parameters dictionary
402+
Custom types (str)
403+
- alignment pygame-menu alignment (locals)
404+
- callable Is callable type, same as ``"function"``
405+
- color Check color
406+
- color_image Color or :py:class:`pygame_menu.baseimage.BaseImage`
407+
- color_image_none Color, :py:class:`pygame_menu.baseimage.BaseImage`, or None
408+
- color_none Color or None
409+
- cursor Cursor object (pygame)
410+
- font Font type
411+
- image Value must be ``BaseImage``
412+
- none None only
413+
- position pygame-menu position (locals)}
414+
- tuple2 Only valid numeric tuples ``(x, y)`` or ``[x, y]``
415+
- type Type-class (bool, str, etc...)
416+
417+
:param params: Parameters dictionary
403418
:type params: dict
404-
:param key: key to look for
419+
:param key: Key to look for
405420
:type key: str
406-
:param allowed_types: list of allowed types
421+
:param allowed_types: List of allowed types
407422
:type allowed_types: any
408-
:param default: default value to return
423+
:param default: Default value to return
409424
:type default: any
410425
:return: The value associated to the key
411426
:rtype: any
412427
"""
413-
if key not in params:
414-
return default
415-
416-
value = params.pop(key)
417-
if allowed_types:
428+
value = params.pop(key, default)
429+
if allowed_types is not None:
430+
other_types = [] # Contain other types to check from
418431
if not isinstance(allowed_types, (tuple, list)):
419432
allowed_types = (allowed_types,)
420433
for val_type in allowed_types:
421-
if val_type == 'color':
422-
_utils.assert_color(value)
423-
elif val_type == 'color_none':
424-
if value is None:
425-
return value
434+
435+
if val_type == 'alignment':
436+
_utils.assert_alignment(value)
437+
438+
elif val_type == callable or val_type == 'function' or val_type == 'callable':
439+
assert _utils.is_callable(value), \
440+
'value must be callable type'
441+
442+
elif val_type == 'color':
426443
_utils.assert_color(value)
444+
427445
elif val_type == 'color_image':
428-
if isinstance(value, BaseImage):
429-
return value
430-
_utils.assert_color(value)
446+
if not isinstance(value, BaseImage):
447+
_utils.assert_color(value)
448+
431449
elif val_type == 'color_image_none':
432-
if value is None:
433-
return value
434-
elif isinstance(value, BaseImage):
435-
return value
436-
_utils.assert_color(value)
450+
if not (value is None or isinstance(value, BaseImage)):
451+
_utils.assert_color(value)
452+
453+
elif val_type == 'color_none':
454+
if value is not None:
455+
_utils.assert_color(value)
456+
457+
elif val_type == 'image':
458+
assert isinstance(value, BaseImage), \
459+
'value must be BaseImage type'
460+
461+
elif val_type == 'none':
462+
assert value is None
463+
437464
elif val_type == 'position':
438465
_utils.assert_position(value)
439-
elif val_type == 'alignment':
440-
_utils.assert_alignment(value)
466+
467+
elif val_type == 'type':
468+
assert isinstance(value, type), \
469+
'value is not type-class'
470+
441471
elif val_type == 'tuple2':
442472
_utils.assert_vector2(value)
443473

444-
all_types = ('color', 'color_none', 'color_image', 'color_image_none',
445-
'position', 'alignment', 'tuple2')
446-
others = tuple(t for t in allowed_types if t not in all_types)
447-
if others:
474+
else: # Unknown type
475+
assert isinstance(val_type, type), \
476+
'allowed type "{0}" is not a type-class'.format(val_type)
477+
other_types.append(val_type)
478+
479+
# Check other types
480+
if len(other_types) > 0:
481+
others = tuple(other_types)
448482
msg = 'Theme.{} type shall be in {} types (got {})'.format(key, others, type(value))
449483
assert isinstance(value, others), msg
484+
450485
return value
451486

452487

0 commit comments

Comments
 (0)