In a plugin I'm writing in Python for Sublime Text I've discovered a difference between Sublime Text v.2 and v.3. [I'm porting the plugin backwards to work with v.2 having written it with v.3.]
In the sublime.View
class the method add_regions()
takes various flags. To get a selection region outline in v.2 sublime.DRAW_OUTLINED
is used, in v.3 sublime.DRAW_NO_FILL
is used - it seems the developer has simply renamed DRAW_OUTLINED
to DRAW_NO_FILL
in v.3 as they both do the same thing.
After trying various approaches I resolved the situation when I realized that, although not documented in the API, sublime.DRAW_OUTLINED
is also available in v.3 (although sublime.DRAW_NO_FILL
is not available in v.2.)
However I'd quite like to know what approaches would be available to me had the developer not kept sublime.DRAW_OUTLINED
in his v.3 code.
My approaches both centered around using the version number of the class.
Firstly:
sub_text_ver = sublime.version()
if sub_text_ver < 3000:
flags = sublime.DRAW_OUTLINED | sublime.DRAW_EMPTY_AS_OVERWRITE
else:
flags = sublime.DRAW_NO_FILL | sublime.DRAW_EMPTY_AS_OVERWRITE
# Code continues...
Secondly:
sub_text_ver = sublime.version()
if sub_text_ver < 3000:
flags = self.get_regions_flags_sub_text_v2()
else:
flags = self.get_regions_flags_sub_text_v3()
# Code continues to end of method and then...
def get_regions_flags_sub_text_v2(self):
return sublime.DRAW_OUTLINED | sublime.DRAW_EMPTY_AS_OVERWRITE
def get_regions_flags_sub_text_v3(self):
return sublime.DRAW_NO_FILL | sublime.DRAW_EMPTY_AS_OVERWRITE
Both gave me a traceback error like this:
Traceback (most recent call last):
File "./ExpandSelectionByRegex.py", line 155, in on_change
File "./ExpandSelectionByRegex.py", line 177, in get_regions_flags_sub_text_v3
AttributeError: 'module' object has no attribute 'DRAW_NO_FILL'
I would like to know what approaches I could have taken to sort this out. Would I have been forced to have two different files for the plugin, one for each version of Sublime Text? Could it have been resolved in one file with two different classes? Could it have been resolved in the same class? I feel that it's best to learn about these kind of things when you encounter them, rather than shelving them just because the current situation was resolved. [Clearly I am not the most experienced Python programmer.] Thanks.
I would suggest using try
and except
statements do exception handling to make sure you get the right module attribute:
try:
flags = sublime.DRAW_NO_FILL | sublime.DRAW_EMPTY_AS_OVERWRITE
except AttributeError: # DRAW_NO_FILL was previously named DRAW_OUTLINED
flags = sublime.DRAW_OUTLINED | sublime.DRAW_EMPTY_AS_OVERWRITE
This is known as the "Easier to Ask Forgiveness than Permission" (EAFP) style of programming. You write some code you know will raise an exception in some situations, and write a try
/except
structure to handle that exception with an alternative bit of code. EAFP style is usually preferred in Python over the "Look Before You Leap" (LBYL) style you were trying for with your if
statements, though there are some situations where LBYL is easier.