Conditions | 31 |
Total Lines | 293 |
Lines | 0 |
Ratio | 0 % |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like Orange.canvas.main() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | """ |
||
83 | def main(argv=None): |
||
84 | if argv is None: |
||
85 | argv = sys.argv |
||
86 | |||
87 | usage = "usage: %prog [options] [workflow_file]" |
||
88 | parser = optparse.OptionParser(usage=usage) |
||
89 | |||
90 | parser.add_option("--no-discovery", |
||
91 | action="store_true", |
||
92 | help="Don't run widget discovery " |
||
93 | "(use full cache instead)") |
||
94 | parser.add_option("--force-discovery", |
||
95 | action="store_true", |
||
96 | help="Force full widget discovery " |
||
97 | "(invalidate cache)") |
||
98 | parser.add_option("--clear-widget-settings", |
||
99 | action="store_true", |
||
100 | help="Remove stored widget setting") |
||
101 | parser.add_option("--no-welcome", |
||
102 | action="store_true", |
||
103 | help="Don't show welcome dialog.") |
||
104 | parser.add_option("--no-splash", |
||
105 | action="store_true", |
||
106 | help="Don't show splash screen.") |
||
107 | parser.add_option("-l", "--log-level", |
||
108 | help="Logging level (0, 1, 2, 3, 4)", |
||
109 | type="int", default=1) |
||
110 | parser.add_option("--no-redirect", |
||
111 | action="store_true", |
||
112 | help="Do not redirect stdout/err to canvas output view.") |
||
113 | parser.add_option("--style", |
||
114 | help="QStyle to use", |
||
115 | type="str", default=None) |
||
116 | parser.add_option("--stylesheet", |
||
117 | help="Application level CSS style sheet to use", |
||
118 | type="str", default="orange.qss") |
||
119 | parser.add_option("--qt", |
||
120 | help="Additional arguments for QApplication", |
||
121 | type="str", default=None) |
||
122 | |||
123 | (options, args) = parser.parse_args(argv[1:]) |
||
124 | |||
125 | levels = [logging.CRITICAL, |
||
126 | logging.ERROR, |
||
127 | logging.WARN, |
||
128 | logging.INFO, |
||
129 | logging.DEBUG] |
||
130 | |||
131 | # Fix streams before configuring logging (otherwise it will store |
||
132 | # and write to the old file descriptors) |
||
133 | fix_win_pythonw_std_stream() |
||
134 | |||
135 | # Try to fix fonts on OSX Mavericks |
||
136 | fix_osx_10_9_private_font() |
||
137 | |||
138 | # File handler should always be at least INFO level so we need |
||
139 | # the application root level to be at least at INFO. |
||
140 | root_level = min(levels[options.log_level], logging.INFO) |
||
141 | rootlogger = logging.getLogger(canvas.__name__) |
||
142 | rootlogger.setLevel(root_level) |
||
143 | |||
144 | # Standard output stream handler at the requested level |
||
145 | stream_hander = logging.StreamHandler() |
||
146 | stream_hander.setLevel(level=levels[options.log_level]) |
||
147 | rootlogger.addHandler(stream_hander) |
||
148 | |||
149 | log.info("Starting 'Orange Canvas' application.") |
||
150 | |||
151 | qt_argv = argv[:1] |
||
152 | |||
153 | if options.style is not None: |
||
154 | qt_argv += ["-style", options.style] |
||
155 | |||
156 | if options.qt is not None: |
||
157 | qt_argv += shlex.split(options.qt) |
||
158 | |||
159 | qt_argv += args |
||
160 | |||
161 | log.debug("Starting CanvasApplicaiton with argv = %r.", qt_argv) |
||
162 | app = CanvasApplication(qt_argv) |
||
163 | |||
164 | # NOTE: config.init() must be called after the QApplication constructor |
||
165 | config.init() |
||
166 | |||
167 | clear_settings_flag = os.path.join( |
||
168 | config.widget_settings_dir(), "DELETE_ON_START") |
||
169 | |||
170 | if options.clear_widget_settings or \ |
||
171 | os.path.isfile(clear_settings_flag): |
||
172 | log.info("Clearing widget settings") |
||
173 | shutil.rmtree( |
||
174 | config.widget_settings_dir(), |
||
175 | ignore_errors=True) |
||
176 | |||
177 | file_handler = logging.FileHandler( |
||
178 | filename=os.path.join(config.log_dir(), "canvas.log"), |
||
179 | mode="w" |
||
180 | ) |
||
181 | |||
182 | file_handler.setLevel(root_level) |
||
183 | rootlogger.addHandler(file_handler) |
||
184 | |||
185 | # intercept any QFileOpenEvent requests until the main window is |
||
186 | # fully initialized. |
||
187 | # NOTE: The QApplication must have the executable ($0) and filename |
||
188 | # arguments passed in argv otherwise the FileOpen events are |
||
189 | # triggered for them (this is done by Cocoa, but QApplicaiton filters |
||
190 | # them out if passed in argv) |
||
191 | |||
192 | open_requests = [] |
||
193 | |||
194 | def onrequest(url): |
||
195 | log.info("Received an file open request %s", url) |
||
196 | open_requests.append(url) |
||
197 | |||
198 | app.fileOpenRequest.connect(onrequest) |
||
199 | |||
200 | settings = QSettings() |
||
201 | |||
202 | stylesheet = options.stylesheet |
||
203 | stylesheet_string = None |
||
204 | |||
205 | if stylesheet != "none": |
||
206 | if os.path.isfile(stylesheet): |
||
207 | stylesheet_string = open(stylesheet, "rb").read() |
||
208 | else: |
||
209 | if not os.path.splitext(stylesheet)[1]: |
||
210 | # no extension |
||
211 | stylesheet = os.path.extsep.join([stylesheet, "qss"]) |
||
212 | |||
213 | pkg_name = canvas.__name__ |
||
214 | resource = "styles/" + stylesheet |
||
215 | |||
216 | if pkg_resources.resource_exists(pkg_name, resource): |
||
217 | stylesheet_string = \ |
||
218 | pkg_resources.resource_string(pkg_name, resource).decode() |
||
219 | |||
220 | base = pkg_resources.resource_filename(pkg_name, "styles") |
||
221 | |||
222 | pattern = re.compile( |
||
223 | r"^\s@([a-zA-Z0-9_]+?)\s*:\s*([a-zA-Z0-9_/]+?);\s*$", |
||
224 | flags=re.MULTILINE |
||
225 | ) |
||
226 | |||
227 | matches = pattern.findall(stylesheet_string) |
||
228 | |||
229 | for prefix, search_path in matches: |
||
230 | QDir.addSearchPath(prefix, os.path.join(base, search_path)) |
||
231 | log.info("Adding search path %r for prefix, %r", |
||
232 | search_path, prefix) |
||
233 | |||
234 | stylesheet_string = pattern.sub("", stylesheet_string) |
||
235 | |||
236 | else: |
||
237 | log.info("%r style sheet not found.", stylesheet) |
||
238 | |||
239 | # Add the default canvas_icons search path |
||
240 | dirpath = os.path.abspath(os.path.dirname(canvas.__file__)) |
||
241 | QDir.addSearchPath("canvas_icons", os.path.join(dirpath, "icons")) |
||
242 | |||
243 | canvas_window = CanvasMainWindow() |
||
244 | canvas_window.setWindowIcon(config.application_icon()) |
||
245 | |||
246 | if stylesheet_string is not None: |
||
247 | canvas_window.setStyleSheet(stylesheet_string) |
||
248 | |||
249 | if not options.force_discovery: |
||
250 | reg_cache = cache.registry_cache() |
||
251 | else: |
||
252 | reg_cache = None |
||
253 | |||
254 | widget_discovery = qt.QtWidgetDiscovery(cached_descriptions=reg_cache) |
||
255 | |||
256 | widget_registry = qt.QtWidgetRegistry() |
||
257 | |||
258 | widget_discovery.found_category.connect( |
||
259 | widget_registry.register_category |
||
260 | ) |
||
261 | widget_discovery.found_widget.connect( |
||
262 | widget_registry.register_widget |
||
263 | ) |
||
264 | |||
265 | want_splash = \ |
||
266 | settings.value("startup/show-splash-screen", True, type=bool) and \ |
||
267 | not options.no_splash |
||
268 | |||
269 | if want_splash: |
||
270 | pm, rect = config.splash_screen() |
||
271 | splash_screen = SplashScreen(pixmap=pm, textRect=rect) |
||
272 | splash_screen.setFont(QFont("Helvetica", 12)) |
||
273 | color = QColor("#FFD39F") |
||
274 | |||
275 | def show_message(message): |
||
276 | splash_screen.showMessage(message, color=color) |
||
277 | |||
278 | widget_discovery.discovery_start.connect(splash_screen.show) |
||
279 | widget_discovery.discovery_process.connect(show_message) |
||
280 | widget_discovery.discovery_finished.connect(splash_screen.hide) |
||
281 | |||
282 | log.info("Running widget discovery process.") |
||
283 | |||
284 | cache_filename = os.path.join(cache_dir(), "widget-registry.pck") |
||
285 | if options.no_discovery: |
||
286 | widget_registry = pickle.load(open(cache_filename, "rb")) |
||
287 | widget_registry = qt.QtWidgetRegistry(widget_registry) |
||
288 | else: |
||
289 | widget_discovery.run(config.widgets_entry_points()) |
||
290 | # Store cached descriptions |
||
291 | cache.save_registry_cache(widget_discovery.cached_descriptions) |
||
292 | pickle.dump(WidgetRegistry(widget_registry), |
||
293 | open(cache_filename, "wb")) |
||
294 | set_global_registry(widget_registry) |
||
295 | canvas_window.set_widget_registry(widget_registry) |
||
296 | canvas_window.show() |
||
297 | canvas_window.raise_() |
||
298 | |||
299 | want_welcome = \ |
||
300 | settings.value("startup/show-welcome-screen", True, type=bool) \ |
||
301 | and not options.no_welcome |
||
302 | |||
303 | # Process events to make sure the canvas_window layout has |
||
304 | # a chance to activate (the welcome dialog is modal and will |
||
305 | # block the event queue, plus we need a chance to receive open file |
||
306 | # signals when running without a splash screen) |
||
307 | app.processEvents() |
||
308 | |||
309 | app.fileOpenRequest.connect(canvas_window.open_scheme_file) |
||
310 | |||
311 | if want_welcome and not args and not open_requests: |
||
312 | canvas_window.welcome_dialog() |
||
313 | |||
314 | elif args: |
||
315 | log.info("Loading a scheme from the command line argument %r", |
||
316 | args[0]) |
||
317 | canvas_window.load_scheme(args[0]) |
||
318 | elif open_requests: |
||
319 | log.info("Loading a scheme from an `QFileOpenEvent` for %r", |
||
320 | open_requests[-1]) |
||
321 | canvas_window.load_scheme(open_requests[-1].toLocalFile()) |
||
322 | |||
323 | stdout_redirect = \ |
||
324 | settings.value("output/redirect-stdout", True, type=bool) |
||
325 | |||
326 | stderr_redirect = \ |
||
327 | settings.value("output/redirect-stderr", True, type=bool) |
||
328 | |||
329 | # cmd line option overrides settings / no redirect is possible |
||
330 | # under ipython |
||
331 | if options.no_redirect or running_in_ipython(): |
||
332 | stderr_redirect = stdout_redirect = False |
||
333 | |||
334 | output_view = canvas_window.output_view() |
||
335 | |||
336 | if stdout_redirect: |
||
337 | stdout = TextStream() |
||
338 | stdout.stream.connect(output_view.write) |
||
339 | if sys.stdout is not None: |
||
340 | # also connect to original fd |
||
341 | stdout.stream.connect(sys.stdout.write) |
||
342 | else: |
||
343 | stdout = sys.stdout |
||
344 | |||
345 | if stderr_redirect: |
||
346 | error_writer = output_view.formated(color=Qt.red) |
||
347 | stderr = TextStream() |
||
348 | stderr.stream.connect(error_writer.write) |
||
349 | if sys.stderr is not None: |
||
350 | # also connect to original fd |
||
351 | stderr.stream.connect(sys.stderr.write) |
||
352 | else: |
||
353 | stderr = sys.stderr |
||
354 | |||
355 | if stderr_redirect: |
||
356 | sys.excepthook = ExceptHook() |
||
357 | sys.excepthook.handledException.connect(output_view.parent().show) |
||
358 | |||
359 | with redirect_stdout(stdout), redirect_stderr(stderr): |
||
360 | log.info("Entering main event loop.") |
||
361 | try: |
||
362 | status = app.exec_() |
||
363 | except BaseException: |
||
364 | log.error("Error in main event loop.", exc_info=True) |
||
365 | |||
366 | canvas_window.deleteLater() |
||
367 | app.processEvents() |
||
368 | app.flush() |
||
369 | del canvas_window |
||
370 | |||
371 | # Collect any cycles before deleting the QApplication instance |
||
372 | gc.collect() |
||
373 | |||
374 | del app |
||
375 | return status |
||
376 | |||
380 |
This can be caused by one of the following:
1. Missing Dependencies
This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.
2. Missing __init__.py files
This error could also result from missing
__init__.py
files in your module folders. Make sure that you place one file in each sub-folder.