There are a variety of different ways you can approach it. A relatively simple way would be to toggle and then untoggle the comment, like this:
self.view.run_command('toggle_comment')
ss = map(self.view.substr, self.view.sel())
self.view.run_command('toggle_comment')
print('uncommented=%r' % list(ss))
This assumes the selection covers a commented area. You can refine the selection by doing something like:
z = view.find_by_selector('comment')
for s in view.sel():
commented_regions = filter(s.intersects, z)
This will have the unfortunate side effect of marking the view dirty. The cleanest approach would be to duplicate the code in the comment module and modify it to edit a string instead of the view. It would be maybe 100 lines of code. You don’t have to copy everything (import it and reuse functions like build_comment_data).
Another idea, and this may be a bad one, is to temporarily put the string into a scratch buffer. This will avoid modifying the current view. Something like:
v = self.view.window().new_file()
v.set_scratch(True)
v.set_syntax_file(self.view.settings().get('syntax'))
v.insert(edit, 0, self.view.substr(self.view.sel()[0]))
v.sel().add(sublime.Region(0, v.size()))
v.run_command('toggle_comment')
s = v.substr(sublime.Region(0, v.size()))
v.close()
print('uncommented=%r' % s)
Again this assumes the current selection is commented, you would need to filter it if desired.
Anyways, I hope this gives you some ideas. Personally, I wouldn’t be afraid of duplicating some of the logic in comment.py.