24
24
__author__ = "CoolCat467"
25
25
__license__ = "GNU General Public License Version 3"
26
26
27
+ import importlib
27
28
import sys
28
29
import time
29
30
import traceback
@@ -62,7 +63,7 @@ def set_title(title: str) -> None:
62
63
63
64
def get_required_config (
64
65
values : dict [str , str ],
65
- bind_defaults : dict [str , str ],
66
+ bind_defaults : dict [str , str | None ],
66
67
extension_title : str ,
67
68
) -> str :
68
69
"""Get required configuration file data."""
@@ -79,7 +80,9 @@ def get_required_config(
79
80
config += "\n "
80
81
# Get key bindings data
81
82
settings = "\n " .join (
82
- f"{ event } = { key } " for event , key in bind_defaults .items ()
83
+ f"{ event } = { key } "
84
+ for event , key in bind_defaults .items ()
85
+ if key is not None
83
86
)
84
87
if settings :
85
88
config += f"\n [{ extension_title } _cfgBindings]\n { settings } "
@@ -89,7 +92,7 @@ def get_required_config(
89
92
def check_installed (
90
93
extension : str ,
91
94
version : str ,
92
- cls : type [BaseExtension ] | None ,
95
+ cls : type [BaseExtension ] | None = None ,
93
96
) -> bool :
94
97
"""Make sure extension installed. Return True if installed correctly."""
95
98
# Get list of system extensions
@@ -108,31 +111,31 @@ def check_installed(
108
111
109
112
if cls is None :
110
113
# Import extension
111
- module = __import__ (extension )
114
+ module = importlib . import_module (extension )
112
115
113
116
# Get extension class
114
117
if not hasattr (module , extension ):
115
118
print (
116
- f"ERROR: Somehow, { __title__ } was installed improperly, "
117
- f"no { __title__ } class found in module. Please report "
119
+ f"ERROR: Somehow, { extension } was installed improperly, "
120
+ f"no { extension } class found in module. Please report "
118
121
"this on github." ,
119
122
file = sys .stderr ,
120
123
)
121
- sys . exit ( 1 )
124
+ return False
122
125
123
126
cls = getattr (module , extension )
124
- if not issubclass (cls , BaseExtension ):
125
- raise ValueError (f"Expected BaseExtension subclass, got { cls !r} " )
126
-
127
- # Get extension class keybinding defaults
128
- required_config = get_required_config (
129
- getattr (cls , "values" , {}),
130
- getattr (cls , "bind_defaults" , {}),
131
- extension ,
132
- )
127
+ # if not issubclass(cls, BaseExtension):
128
+ # raise ValueError(f"Expected BaseExtension subclass, got {cls!r}")
133
129
134
130
# If this extension not in there,
135
131
if extension not in extensions :
132
+ # Get extension class keybinding defaults
133
+ required_config = get_required_config (
134
+ getattr (cls , "values" , {}),
135
+ getattr (cls , "bind_defaults" , {}),
136
+ extension ,
137
+ )
138
+
136
139
# Tell user how to add it to system list.
137
140
print (f"{ extension } not in system registered extensions!" )
138
141
print (
@@ -266,11 +269,12 @@ def ensure_section_exists(section: str) -> bool:
266
269
267
270
def ensure_values_exist_in_section (
268
271
section : str ,
269
- values : dict [str , str ],
272
+ values : dict [str , str | None ] | dict [ str , str ],
270
273
) -> bool :
271
274
"""For each key in values, make sure key exists. Return if edited.
272
275
273
- If not, create and set to value.
276
+ If key does not exist and default value is not None, create and set
277
+ to value.
274
278
"""
275
279
need_save = False
276
280
for key , default in values .items ():
@@ -287,7 +291,10 @@ def ensure_values_exist_in_section(
287
291
288
292
289
293
def ask_save_dialog (parent : Text ) -> bool :
290
- """Ask to save dialog stolen from idlelib.runscript.ScriptBinding."""
294
+ """Ask to save dialog. Return if ok to save.
295
+
296
+ Stolen from idlelib.runscript.ScriptBinding.
297
+ """
291
298
msg = "Source Must Be Saved\n " + 5 * " " + "OK to Save?"
292
299
confirm : bool = messagebox .askokcancel (
293
300
title = "Save Before Run or Check" ,
@@ -359,7 +366,7 @@ def temporary_overwrite(
359
366
360
367
361
368
def extension_log (content : str ) -> None :
362
- """Log content to extension log."""
369
+ """Log content to extension log file ."""
363
370
if not LOGS_PATH .exists ():
364
371
LOGS_PATH .mkdir (exist_ok = True )
365
372
log_file = LOGS_PATH / f"{ TITLE } .log"
@@ -419,17 +426,19 @@ class BaseExtension:
419
426
)
420
427
421
428
# Extend the file and format menus.
422
- menudefs : ClassVar = []
429
+ menudefs : ClassVar [
430
+ Sequence [tuple [str , Sequence [tuple [str , str ] | None ]]]
431
+ ] = ()
423
432
424
433
# Default values for configuration file
425
- values : ClassVar = {
434
+ values : ClassVar [ dict [ str , str ]] = {
426
435
"enable" : "True" ,
427
436
"enable_editor" : "True" ,
428
437
"enable_shell" : "False" ,
429
438
}
430
439
431
440
# Default key binds for configuration file
432
- bind_defaults : ClassVar = {}
441
+ bind_defaults : ClassVar [ dict [ str , str | None ]] = {}
433
442
434
443
def __init__ (
435
444
self ,
@@ -449,9 +458,18 @@ def __init__(
449
458
comment_prefix = f"{ self .__class__ .__name__ } "
450
459
self .comment_prefix = f"# { comment_prefix } : "
451
460
452
- # Bind non-keyboard triggered events, as IDLE only binds
453
- # keyboard events automatically.
454
- for bind_name , key in self .bind_defaults .items ():
461
+ self .bind_non_keyboard (self .bind_defaults )
462
+
463
+ def __repr__ (self ) -> str :
464
+ """Return representation of self."""
465
+ return f"{ self .__class__ .__name__ } ({ self .editwin !r} )"
466
+
467
+ def bind_non_keyboard (self , bind_defaults : dict [str , str | None ]) -> None :
468
+ """Bind non-keyboard triggered events.
469
+
470
+ IDLE only binds keyboard events automatically.
471
+ """
472
+ for bind_name , key in bind_defaults .items ():
455
473
if key is not None :
456
474
continue
457
475
bind_func_name = bind_name .replace ("-" , "_" ) + "_event"
@@ -462,10 +480,6 @@ def __init__(
462
480
raise ValueError (f"{ bind_func_name } should be callable" )
463
481
self .text .bind (f"<<{ bind_name } >>" , bind_func )
464
482
465
- def __repr__ (self ) -> str :
466
- """Return representation of self."""
467
- return f"{ self .__class__ .__name__ } ({ self .editwin !r} )"
468
-
469
483
@classmethod
470
484
def ensure_bindings_exist (cls ) -> bool :
471
485
"""Ensure key bindings exist in user extensions configuration.
0 commit comments